Java 后端微信小程序支付demo (網上說的坑里面基本上都有)


Java 后端微信小程序支付

一、遇到的問題

1. 商戶號該產品權限未開通,請前往商戶平台>產品中心檢查后重試

2.簽名錯誤

3.已經調起微信統一下單接口,可以拿到預支付ID,但是前端支付的時候出現 支付驗證簽名失敗

網上的問題基本上就是這三類下面說解決方案。

第一個問題:商戶號的問題,微信app支付與微信小程序支付的商戶號不同,微信app內支付與微信開放平台內的商戶號綁定,微信小程序支付是與微信公眾平台內的商戶號綁定。

第二個問題:簽名錯誤, 第一次簽名需要的appid mchid key 分別對應的是小程序的appid、微信公眾平台綁定的商戶號、以及商戶平台的密鑰(重要的事情說三遍:商戶平台的!商戶平台的!商戶平台的!)。

這里重點說下商戶平台的密鑰(當時就是因為密鑰的問題耽誤了不少時間):具體請看圖(商戶平台--->賬戶中心--->API安全---->設置密鑰)

第三個問題:支付驗證簽名失敗 這個就得需要嚴格執行小程序支付文檔中的生成簽名的規則。參數字段大小寫、順序一定要對(切記,切記,切記)

如果能把以上都注意到了,那基本上沒什么問題了。下面是我自己寫的demo供大家參考,有什么問題可以留言。

二、demo 事例

1.下載商戶的證書(在問題2的截圖中已經展示下載的位置)放在resources下的cert目錄下(cert目錄需要自己手動建)

2.實現微信的 WXPayConfig接口

 1 package com.ieou.franky.payCenter.common;
 2 
 3 import com.github.wxpay.sdk.WXPayConfig;
 4 import org.apache.commons.io.IOUtils;
 5 
 6 import java.io.ByteArrayInputStream;
 7 import java.io.InputStream;
 8 
 9 public class MiniprogramConfig implements WXPayConfig{
10 
11     private byte[] certData;
12 
13     public MiniprogramConfig() throws Exception {
14         InputStream certStream = Thread.currentThread().getContextClassLoader().getResourceAsStream("cert/miniProgram/apiclient_cert.p12");
15         this.certData = IOUtils.toByteArray(certStream);
16         certStream.close();
17     }
18 
19     @Override
20     public String getAppID() {
21         return "wx6db448a73f8a6666";
22     }  //小程序appid
23 
24     @Override
25     public String getMchID() {
26         return "1500669999";
27     }  //商戶號
28 
29     /** 商戶平台-賬戶中心-API安全中的密鑰 */
30     @Override
31     public String getKey() {
32         return "1add1a30ac87aa77yyy2db72f57a237577777";
33     }
34 
35     @Override
36     public InputStream getCertStream() {
37         return new ByteArrayInputStream(this.certData);
38     }
39 
40     @Override
41     public int getHttpConnectTimeoutMs() {
42         return 0;
43     }
44 
45     @Override
46     public int getHttpReadTimeoutMs() {
47         return 0;
48     }
49 }

3.調用微信統一下單接口並且實現簽名

 1 private Map<String, String> createMiniProgramTradePay(WxpayTradeAppPayModel model,String notifyUrl) throws Exception {
 2         MiniprogramConfig config = new MiniprogramConfig();
 3 
 4         WXPay wxpay = new WXPay(config);
 5 
 6         Map<String, String> data = new HashMap<>();
 7         data.put("appid",config.getAppID());
 8         data.put("mch_id",config.getMchID());
 9         data.put("body",model.getBody());
10         data.put("out_trade_no", model.getOutTradeNo());
11         data.put("device_info", "");
12         data.put("fee_type", "CNY");
13         data.put("total_fee", model.getTotalFee());
14         data.put("spbill_create_ip", "127.0.0.1");
15         data.put("notify_url", notifyUrl);
16         data.put("trade_type", "JSAPI");
17         data.put("openid",model.getOpenId());
18 //        data.put("nonce_str","1add1a30ac87aa2db72f57a2375d8fec");
19         String sign = WXPayUtil.generateSignature(data, config.getKey());
20         data.put("sign",sign);
21 
22         Map<String, String> resp = wxpay.unifiedOrder(data);
23         if ("SUCCESS".equals(resp.get("return_code"))) {
24             //再次簽名
25             /** 重要的事情說三遍  小程序支付 所有的字段必須大寫 駝峰模式 嚴格按照小程序支付文檔
26              *https://pay.weixin.qq.com/wiki/doc/api/wxa/wxa_api.php?chapter=7_7&index=3#
27              * ******* 我當初就因為timeStamp中S沒大寫弄了3個小時 **********
28              * */
29             Map<String, String> reData = new HashMap<>();
30             reData.put("appId", config.getAppID());
31             reData.put("nonceStr", resp.get("nonce_str"));
32             String newPackage = "prepay_id=" + resp.get("prepay_id");
33             reData.put("package", newPackage);
34             reData.put("signType","MD5");
35             reData.put("timeStamp", String.valueOf(System.currentTimeMillis() / 1000));
36 
37             String newSign = WXPayUtil.generateSignature(reData, config.getKey());
38             resp.put("paySign",newSign);
39             resp.put("timeStamp", reData.get("timeStamp"));
40             return resp;
41         } else {
42             throw new FrankyErrorException(resp.get("return_msg"));
43         }
44 
45     }

說明:這里只是說明小程序支付與微信app內支付的不同和遇到的問題,有關里面用到微信的SDK,請看上一篇文章。

到這一步java 后端代碼就差不多了,前端拿到返回的字段調起支付接口。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM