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 后端代码就差不多了,前端拿到返回的字段调起支付接口。

Java后端可以通过调用微信支付的API来实现微信小程序支付功能。 首先,我们需要在微信支付商户平台注册并获取到商户、appid、appsecret等必要的信息。然后,在Java后端,我们可以使用SDK或者自行封装HTTP求来调用微信支付的API。 在用户选择微信支付后,前端会发送支付求到后端后端收到求后,需要进行以下操作: 1. 生成订单:根据业务需求,后端需要生成一个唯一的商户订单,并保存相关订单信息到数据库中。同时,需要计算订单的总金额、描述等参数。 2. 生成签名:根据微信支付要求,在生成订单后,后端需要根据商户、appid、订单、总金额等参数,生成一个签名值,确保求的合法性和安全性。 3. 调用支付API:将生成的订单信息、签名等参数通过HTTP求发送给微信支付后端API。此时,我们可以使用HttpClient等工具发送HTTP POST求,并将结果解析为JSON格式。 4. 处理支付结果:微信支付后端API返回的结果包含支付所需的各种参数,例如预支付交易会话标识prepay_id等。后端需要将这些参数返回给前端,前端根据这些参数发起小程序支付。 此外,为了确保支付的安全性,后端还应该对微信支付回调进行处理。微信支付成功后,会异步回调后端提供的回调接口,我们需要验证回调接口的合法性,判断回调的结果,并根据业务逻辑进行相应的处理。 总的来说,Java后端可以通过调用微信支付的API来实现小程序支付功能,包括生成订单、生成签名、调用支付API和处理支付回调等步骤。这样,用户在小程序中选择微信支付后,后端可以实现支付逻辑,并与微信支付后端进行交互,最终完成支付流程。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

xuxizhou1994

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值