首先說注意幾點,其實要說難不難,都是細節問題
- 進行簽名的參數注意大小寫
- 簽名用的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