首先说注意几点,其实要说难不难,都是细节问题
- 进行签名的参数注意大小写
- 签名用的key是微信支付密钥,不是身份密钥
- 返回给前端的预订单号格式一定要注意
- 配置的安全域名一定是https的
1 微信配置安全域名,这里不多说,自行百度
2 后端引入微信支付依赖
<!-- 微信支付 --> <dependency> <groupId>com.github.wxpay</groupId> <artifactId>wxpay-sdk</artifactId> <version>0.0.3</version> </dependency>
3 前端向后端发请求支付,后端调用微信同一下单 api 接口,关键是签名,有十个参数是必须进行签名的,分别如下
-
body 支付项目描述
-
out_trade_no 我们自己生成的订单号
-
total_fee 支付金额,单位(分)
-
spbill_create_ip 付款客户的ip地址
-
notify_url 付款成功或失败的微信通知我们的地址,自己在后台创建一个回调地址
-
trade_type 因为我现在集成 jsapi 方式支付, 所以直接写 JSAPI 即可
-
openid jsapi 方式支付必须携带此参数
-
appid 公众号ID,微信支付平台获取,在申请支付时微信提供的
-
mch_id 商户号,微信支付平台获取,在申请支付时微信提供的
-
nonce_str 随机字符串,有个 WXPayUtil 类有提供,也可以自己随便输入也行
public PayDTO createUnifiedorder(MonitorTypeEnum type, String body, TradeType tradeType, String openid, String ip, String phone, String tradeNo) { log.info("进入微信支付"); Map<String, String> map = new HashMap<>(); map.put("body", body); // 参数1 map.put("out_trade_no", tradeNo); // 参数2 BigDecimal big = new BigDecimal(type.getFee()); map.put("total_fee", String.valueOf((int)(big.setScale(2,BigDecimal.ROUND_HALF_UP).doubleValue() * 100))); // 参数3 map.put("spbill_create_ip", ip); // 参数4 map.put("notify_url", notifyUrl); // 参数5 map.put("trade_type", tradeType.name()); // 参数6 map.put("openid", openid); // 参数7 try {
// MyWXPayConfig 类是自己创建的,实现了 WXPayConfig 接口,里面定义了 appid, mchid 和 key, 这个key是微信支付密钥,不是身份密钥,千万不要搞错 MyWXPayConfig config = new MyWXPayConfig();
// 这个类是微信提供的类,将上面的配置类传入即可 WXPay pay = new WXPay(config);
// 调用微信提供的统一下单接口,他会自动将另外的三个参数传入(appid, mch_id, nonce_str)进行签名后,调用微信统一下单 api 接口,生成预支付订单 Map<String, String> returnMap = pay.unifiedOrder(map); log.info("微信预支付请求参数【{}】",JSON.toJSONString(map)); log.info("微信预支付返回结果【{}】", JSON.toJSONString(returnMap)); String returnCode = returnMap.get("return_code"); String resultCode = returnMap.get("result_code");
// 判断生成预支付订单是否成功 if("SUCCESS".equalsIgnoreCase(resultCode) && "SUCCESS".equalsIgnoreCase(returnCode)) { String sign = returnMap.get("sign"); // 取出需要参数 String nonceStr = returnMap.get("nonce_str"); String appid = returnMap.get("appid"); String trade_type = returnMap.get("trade_type"); String mchId = returnMap.get("mch_id"); String prepayId = returnMap.get("prepay_id"); String timeStamp = String.valueOf(System.currentTimeMillis() / 1000); PayDTO dto = new PayDTO(); Map<String, String> map1 = new HashMap<>();
// 下面这几个参数是将返回给前端的字段进行签名并生成 sign 签名字段,然后字段连同签名一起返回给前端 map1.put("appId", appid); map1.put("timeStamp", timeStamp); map1.put("nonceStr", nonceStr); map1.put("package", "prepay_id=" +prepayId); // 这个预订单号格式要注意 map1.put("signType","MD5"); String sign2 = WXPayUtil.generateSignature(map1, config.getKey());
// 下面的参数是返回给前端的 dto.setNonceStr(nonceStr); dto.setAppid(appid); dto.setTradeType(trade_type); dto.setMchId(mchId); dto.setPrepayId(prepayId); dto.setTimeStamp(timeStamp); // 这个签名是传入前端的签名 dto.setSign(sign2); payTradeRecordService.updateTradeStatusByTradeNo(tradeNo, TradeStatusEnum.UNPAID); return dto; } } catch (Exception e) { log.error("生成微信签名错误", e); } return null; }
4 前端拿到后端返回的参数后,就可以调起微信支付的页面
// 请求微信支付 fetchPayUnifiedorder(type, body) { let _this = this if (this.openId) { // 有openId用jsapi支付 this.$http({ url: this.$http.adornUrl('/weChat/pay/unifiedorder'), method: 'POST', data: this.$http.adornData({ openId: this.openId, tradeType: 'JSAPI', body: body, type: type, phone: this.phone }) }).then(({ data }) => { if (data.code === 0) { let pay = data.pay
// 这个对象只有在微信内部打开的 h5 页面才有的对象 window.WeixinJSBridge.invoke('getBrandWCPayRequest', { 'appId': pay.appid, // 公众号名称,由商户传入 'timeStamp': pay.timeStamp, // 时间戳,自1970年以来的秒数 'nonceStr': pay.nonceStr, // 随机串 'package': `prepay_id=${pay.prepayId}`, // 这里需要注意 'signType': 'MD5', // 微信签名方式 'paySign': pay.sign // 微信签名 }, function (res) { console.log('支付返回结果', res) if (res.err_msg === 'get_brand_wcpay_request:ok') { // 支付成功后查询订单信息 _this.fetchPaySuccessOrder() } else { _this.$swal({ icon: 'error', title: '支付失败', showConfirmButton: false, timer: 1500 }) } }) } else { _this.$swal({ icon: 'error', title: data.msg, showConfirmButton: false, timer: 1500 }) } }) } else { this.$swal({ icon: 'warning', title: '对不起,目前仅支持在微信APP内打开的网页进行支付', showConfirmButton: false, timer: 1500 }) } }
不懂可以加我 QQ: 287475833