微信支付的V3版本使用的是RSA加密,从前的V2版本使用的是MD5加密。今天在调试微信小程序的时候,始终无法调起微信支付,提示“支付签名验证失败”
问题排查思路:
1. 先调起其它接口,如统一下单、订单查询、关单接口等,如果调起其它接口正常,则代表各种参数都正常,如证书、商户号、密钥等都正确。
统一下单接、关单、查单接口可以参考【Java教程】微信支付V3版本_哔哩哔哩_bilibili
同一商户的微信小程序的appId和APP应用的appId不同,但商户号和证书密钥等参数都相同
2.签名串需要严格区分大小写,注意字符串最后还要拼接“\n”
不同API的下单地址不同,参数有少量差别
APP下单地址:https://api.mch.weixin.qq.com/v3/pay/transactions/app
小程序下单地址:https://api.mch.weixin.qq.com/v3/pay/transactions/jsapi
两种API的最后一级不同。
另外小程序获取预支付id需要用户登录的openId,且下单付款的用户必须和登录的用户是一个
APP签名串
wx8888888888888888
1414561699123
5K8264ILTKCH16CQ2502SI8ZNMTM67VS
WX1217752501201407033233368018
JSAPI签名串
wx8888888888888888
1414561699
5K8264ILTKCH16CQ2502SI8ZNMTM67VS
prepay_id=wx201410272009395522657a690389285100
两种API的前三个串都是appId、时间戳、随机字符串,app时间戳单位是毫秒,小程序是秒
不同的是,app的第四个串是预支付id,而小程序的签名串需要在预支付id前写一个prepay_id=
注意能获取到预支付信息prepay_id不代表能调起应用成功
3.签名方法不同
我在调起app的时候一次就成功付款了,以至于没有怀疑过签名算法有问题,卡了四个多小时就是不知道为什么,最后终于让我发现了这个坑
在微信的官方demo里
com.wechat.pay.contrib.apache.httpclient.util.RsaCryptoUtil.encryptOAEP(String message, X509Certificate certificate)
第一次就是用这个方法给app做签名串的,没有任何问题,后来迁移到小程序就不行了,
小程序不能用这个方法,要用
String sign(byte[] message) {
Signature sign = Signature.getInstance("SHA256withRSA");
sign.initSign(你的私钥privateKey);
sign.update(message);
return Base64.getEncoder().encodeToString(sign.sign());
}