概述:爬坑日记。这两天做一个mini版电商,也就是小程序线上交易。在对接微信支付的时候出了点状况,记录一下。
项目对接的微信官方SDK。
其实也简单,配置依赖,将Demo里的配置类CV下改改就行了。
<dependency>
<groupId>com.github.binarywang</groupId>
<artifactId>weixin-java-miniapp</artifactId>
<version>4.1.0</version>
</dependency>
<dependency>
<groupId>com.github.binarywang</groupId>
<artifactId>weixin-java-pay</artifactId>
<version>4.1.0</version>
</dependency>
项目application.properties里配置小程序与商户信息。项目启动正常,后面就正常的走流程。
结果到了统一下单,一直提示签名错误。
步骤一:校验签名
步骤二:检查请求参数是否正确
步骤三:检查商户号密钥是否正确
验证结果
页面验证正确,但是调微信接口就提示错误。
到这里就很纳闷,然后跑去看skd源码,因为之前写过微信app支付和公众号支付,对这块还算比较熟悉,自己去覆写签名算法,结果还是提示错误。
后面想想微信SDK签名不该有问题吧,写个测试类,扒出微信的签名结果和自己写的签名结果对比。
@Test
public void generateSign() {
String expectSign = "xxxxxxx";
String appid = "xxxxxx";
String body = "商户名称-商品";
String mch_id = "xxxx";
String nonce_str = "xxxx";
String notify_url = "https://xxxxx/v1/trade/notify";
String openid = "xxxxxxx";
String out_trade_no = "xx";
String sign_type = "MD5";
String spbill_create_ip = "xxxxxx";
String total_fee = "xxxxx";
String trade_type = "JSAPI";
String signKey = "32个x";
SortedMap<String, String> params = new TreeMap<>();
params.put("appid", appid);
params.put("body", body);
params.put("mch_id", mch_id);
params.put("nonce_str", nonce_str);
params.put("notify_url", notify_url);
params.put("openid", openid);
params.put("out_trade_no", out_trade_no);
params.put("sign_type", sign_type);
params.put("spbill_create_ip", spbill_create_ip);
params.put("total_fee", total_fee);
params.put("trade_type", trade_type);
Assert.assertEquals(expectSign, Utils.WxPayUtil.generateSign(params, signKey));
System.out.println("2 pass");
String sign = SignUtils.createSign(params, sign_type, signKey, new String[0]);
Assert.assertEquals(expectSign, sign);
System.out.println("3 pass");
}
签名结果一致,能证明算法是没有问题的。我自己就是在步骤一纠结了很久。
步骤二就是得验证请求微信接口的参数和签名的参数是否一致,因为报错后控制台有参数打印,比对后是没有问题的,也没有编码问题,毕竟是官方SDK嘛。
排除法,只能是第三种情况了,商户号秘钥这块有问题。
检查了下,确实有大问题。
key设置路径:微信商户平台(pay.weixin.qq.com)-->账户中心-->账户设置-->API安全-->设置API密钥
我设置的是APIv3的秘钥,APIv2的秘钥没有设置。
微信提示的是签名错误,没注意到这个秘钥问题(希望智能一丢丢,小声bb)。
项目用的最新版SDK,当时设置秘钥的时候想当然是APIv3。还跑去看了下源码,咦有V3诶,实际上调用的是unifiedOrder哈,和那个V3没一毛钱关系。
解决方法就是设置APIv2秘钥,当然这里我设置的和APIv3保持一致,项目里的配置就不用更改。
设置完等一段时间,调微信下单成功。
至此,河清海晏,时和岁丰。