一.获取客户资料(百度很简单)

#1.微信支付API秘钥 
      appsecret: d1056292feb*******439f32a0179baf918
      #2.微信商户ID
      mchid: 1618****679
      #3.微信小程序APPID
      appid: wxe7c9b******1efff47
      #4. 支付成功回调地址,如果是小程序可以不配置
      notifyPath: ********
      #5. 微信支付v3秘钥
      apiV3Key: d105629*******4439f32a0179baf918
      #6.  证书序列号
      merchantSerialNumber: 391CCADC***********711035E85E9D68A67
      #7.证书秘钥一个叫apiclient_key.pem文件(下载的证书里有这文件)

二.获取微信支付sdk

<dependency>
            <groupId>com.github.wechatpay-apiv3</groupId>
            <artifactId>wechatpay-apache-httpclient</artifactId>
            <version>0.3.0</version>
        </dependency>

三. 解析出来apiclient_key.pem文件中的证书秘钥备用

PrivateKey merchantPrivateKey = PemUtil.loadPrivateKey(new FileInputStream(ResourceUtils.getFile("classpath:apiclient_key.pem")));

四.把获取客户资料放入yml文件里写个类注入方便使用

py:
    info:
      #微信支付网关
      gateway: https:********
      #微信支付API秘钥
      appsecret: *********
      #微信商户ID
      mchid: *******
      #微信小程序APPID
      appid: *********
      # 支付成功回调地址,如果是小程序可以不配置
      notifyPath: **********
      # 微信支付v3秘钥
      apiV3Key: ****************
      #  证书序列号
      merchantSerialNumber: ****************
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;



@Configuration
@Data
@ConfigurationProperties(prefix = "wx.py.info")
public class WeiXinPayProperties {

    private String  gateway;
    private String appsecret;
    private String mchid;
    private String appid;
    private String notifyPath ;
    private String apiV3Key ;
    private String merchantSerialNumber ;
}

五.微信支付请求获取支付id
首先拿到自动装配好客户资料的类

@Autowired
    WeiXinPayProperties DD;

写一个获取openid工具类

private String getOpenid(String code) throws ParseException, IOException {
        CloseableHttpClient httpclient = HttpClients.createDefault();

        String url = "https://api.weixin.qq.com/sns/jscode2session?appid="+DD.getAppid()+"&secret="+DD.getAppsecret()+"&js_code="+code+"&grant_type=authorization_code";
        HttpGet get = new HttpGet(url);
        CloseableHttpResponse response = httpclient.execute(get);
        String result = EntityUtils.toString(response.getEntity(), "utf-8");
        JSONObject json = JSONObject.parseObject(result);
        if(!json.containsKey("errcode")) {
            String openid = json.getString("openid");
            return openid;
        }
        return "";
    }

最后请求微信服务器获取支付id(我也是醉了那么多代码只是为了获取调用微信支付所需要的支付id当然微信可能有其他考虑,但这样确实对新人不友好)封装成ResultInfo发给前端,让前端调用支付

@PostMapping("pay")

    public  ResultInfo<Object>  pay(double totaFell , String code) throws IOException {
        try {
        //用户openid
        JSONObject order=new JSONObject();
        order.put("appid",DD.getAppid());
        order.put("mchid",DD.getMchid());
        order.put("description","买菜");//商品描述
        order.put("out_trade_no",new DateTime().toString("yyyyMMddHHmmssSSS"));//s商户服系统内部订单号
        order.put("notify_url ",DD.getNotifyPath());//通知地址

        JSONObject amount=new JSONObject();//支付金额js 单位分
        amount.put("total",(long)(totaFell*100));//转整型
        amount.put("currency","CNY");//z支付金额的货币类型
        order.put("amount",amount);
        JSONObject payer =new JSONObject();//支付者
        payer.put("openid","CNY");//z支付金额的货币类型
        payer.put("openid", this.getOpenid(code));
        order.put("payer", payer);

//文件流方式获取证书私钥
        PrivateKey merchantPrivateKey = PemUtil.loadPrivateKey(new FileInputStream(ResourceUtils.getFile("classpath:apiclient_key.pem")));
        //不需要传入微信支付证书了 签名验证器
       ScheduledUpdateCertificatesVerifier verifier = new ScheduledUpdateCertificatesVerifier(
                new WechatPay2Credentials("商户号", new PrivateKeySigner("商户API证书序列号", merchantPrivateKey)),
                "微信支付v3秘钥".getBytes("utf-8"));// Config.getWeixinMiniApiV3Key().getBytes("utf-8") 商户v3私钥

        WechatPayHttpClientBuilder builder = WechatPayHttpClientBuilder.create()
                .withMerchant("商户号", "商户API证书序列号", merchantPrivateKey)//merchantPrivateKey 证书私钥
                .withValidator(new WechatPay2Validator(verifier));//微信支付平台证书

        HttpClient httpClient = builder.build();
        HttpPost httpPost = new HttpPost("https://api.mch.weixin.qq.com/v3/pay/transactions/jsapi");
        httpPost.addHeader("Accept", "application/json");
        httpPost.addHeader("Content-type","application/json; charset=utf-8");
        httpPost.setEntity(new StringEntity(order.toJSONString(), "UTF-8"));
        // 后面跟使用Apache HttpClient一样
        HttpResponse response = httpClient.execute(httpPost);
        String bodyAsString = EntityUtils.toString(response.getEntity());//这里的返回值包含了支付id


        JSONObject bodyAsJSON = JSONObject.parseObject(bodyAsString);//把返回值转js备用
        //判读下微信返回值是否正确
		if(bodyAsJSON.containsKey("code")) {
            return new ResultInfo(1, bodyAsJSON.getString("message"));
       		 }

    final String prepay_id = bodyAsJSON.getString("prepay_id");
   
            final String timeStamp = String.valueOf(System.currentTimeMillis());
            final String nonceStr = RandomStringGenerator.getRandomStringByLength(32);
            StringBuffer stringBuffer = new StringBuffer();
            stringBuffer.append(DD.getAppid() + "\n");
            stringBuffer.append(timeStamp + "\n");
            stringBuffer.append(nonceStr + "\n");
            stringBuffer.append("prepay_id="+prepay_id+"\n");
            Signature signature = Signature.getInstance("SHA256withRSA");
            signature.initSign(merchantPrivateKey);
            signature.update(stringBuffer.toString().getBytes("UTF-8"));
            byte[] signBytes = signature.sign();
            String paySign = Base64.encodeBytes(signBytes);//工具类 网上找一下

            JSONObject params = new JSONObject();
            params.put("appId", DD.getAppid());
            params.put("timeStamp", timeStamp);
            params.put("nonceStr", nonceStr);
            params.put("prepay_id", prepay_id);
            params.put("signType", "RSA");
            params.put("paySign", paySign);

            return new ResultInfo<Object>(0, params);
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return null;

封装类ResultInfo

public class ResultInfo<T> {

	private int code; // 0操作成功
	private T data; // 返回的数据,正确的信息或错误描述信息


	public ResultInfo(){
		
	}
	public ResultInfo(T data){
		this.data = data;
	}
	public ResultInfo(int code, T data){
		this.code = code;
		this.data = data;
	}
	
	
	public int getCode() {
		return code;
	}

	public ResultInfo<T> setCode(int code) {
		this.code = code;
		return this;
	}

	public T getData() {
		return data;
	}

	public ResultInfo<T> setData(T data) {
		this.data = data;
		return this;
	}

}

工具类Base64

工具类 网上找一下

工具类 RandomStringGenerator

import java.util.Random;

/**
 * 随机字符串生成
 * @author zuoliangzhu
 *
 */
public class RandomStringGenerator {
	/**
     * 获取一定长度的随机字符串
     * @param length 指定字符串长度
     * @return 一定长度的字符串
     */
    public static String getRandomStringByLength(int length) {
        String base = "abcdefghijklmnopqrstuvwxyz0123456789";
        Random random = new Random();
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < length; i++) {
            int number = random.nextInt(base.length());
            sb.append(base.charAt(number));
        }
        return sb.toString();
    }
}

六,请求微信支付 我们的内网是不行的,微信服务器会拒绝访问,所以我们需要内网穿透,或者把项目部署在服务器上