网站建设 域名 空间网站快速收录软件
第一个问题,使用正常的V3支付,返回无可用的平台证书,请在商户平台-API安全申请使用微信支付公钥。
报错如下
httpResponseBody[{"code":"RESOURCE_NOT_EXISTS","message":"无可用的平台证书,请在商户平台-API安全申请使用微信支付公钥。可查看指引https://pay.weixin.qq.com/docs/merchant/products/platform-certificate/wxp-pub-key-guide.html"}]
解决办法:
首先因为因为我们使用了微信公钥调起支付,商户可使用微信支付的公钥验证应答和回调的签名,可使用微信支付公钥和公钥ID初始化。所以不能使用原来的RSAAutoCertificateConfig来创建支付配置,而要使用RSAPublicKeyConfig。支付的maven从0.2.12升级到0.2.14才有RSAPublicKeyConfig。
在微信支付Github也更新了最新的微信V3公钥支付的调用:wechatpay-java
- 旧依赖和代码
maven
<dependency><groupId>com.github.wechatpay-apiv3</groupId><artifactId>wechatpay-java</artifactId><version>0.2.12</version></dependency>
代码
Config config = new RSAAutoCertificateConfig.Builder().merchantId(merchantId).merchantSerialNumber(merchantSerialNumber).privateKeyFromPath(privateKeyPath).apiV3Key(apiV3Key).build();
- 新的依赖和代码
依赖
<dependency><groupId>com.github.wechatpay-apiv3</groupId><artifactId>wechatpay-java</artifactId><version>0.2.14</version>
</dependency>
代码
Config config =new RSAPublicKeyConfig.Builder().merchantId(merchantId).privateKeyFromPath(privateKeyPath).publicKeyFromPath(publicKeyPath).publicKeyId(publicKeyId).merchantSerialNumber(merchantSerialNumber).apiV3Key(apiV3Key).build();
第二个问题,以上改好发送获取支付的链接,报错:java.lang.IllegalArgumentException: Illegal base64 character 2d
异常部分有用完整报文:
java.lang.IllegalArgumentException: Illegal base64 character 2dat java.util.Base64$Decoder.decode0(Base64.java:714)at java.util.Base64$Decoder.decode(Base64.java:526)at java.util.Base64$Decoder.decode(Base64.java:549)at com.wechat.pay.java.core.util.PemUtil.loadPublicKeyFromString(PemUtil.java:90)at com.wechat.pay.java.core.util.PemUtil.loadPublicKeyFromPath(PemUtil.java:128)at com.wechat.pay.java.core.RSAPublicKeyConfig$Builder.publicKeyFromPath(RSAPublicKeyConfig.java:96)at com.zhjs.service.impl.TestPay.nativePay(TestPay.java:75)at com.zhjs.controller.TestController.test(TestController.java:32)at com.zhjs.controller.TestController$$FastClassBySpringCGLIB$$f90b7656.invoke(<generated>)at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218)
报错原因和解决办法
原因是:.publicKeyFromPath(publicKeyPath)输入公钥路径的时候我输入是apiclient_cert.pem,所以导致报错,用错证书了。
解决办法:去下载V3的公钥pub_key.pem。
下载的步骤如下图:
原代码:
/*** 公钥路径*/
private String publicKeyPath = "data/testPay/apiclient_cert.pem";
新代码
/*** 公钥路径*/
private String publicKeyPath = "data/testPay/pub_key.pem";
换成新的公钥pub_key.pem的路径就可以正常吊起支付了
完整代码
次测试使用的是Native下单
代码做个参考
public class TestPay {/*** 商户号*/private String merchantId = "xxxxxxx";/*** 私钥路径*/private String privateKeyPath = "data/testPay/apiclient_key.pem";/*** 公钥路径*/private String publicKeyPath = "data/testPay/pub_key.pem";/*** 商户APIv3密钥公钥*/private String publicKeyId = "xxxxxx";/*** 商户API证书序列号*/private String merchantSerialNumber = "xxxxxxxx";/*** APIv3密钥*/private String apiV3Key = "xxxxxxxxxx";/*** appid*/private String appId = "xxxxxxxx";/*** Native下单*/public Map<String, Object> nativePay() {//创建支付配置Config config =new RSAPublicKeyConfig.Builder().merchantId(merchantId).privateKeyFromPath(privateKeyPath).publicKeyFromPath(publicKeyPath).publicKeyId(publicKeyId).merchantSerialNumber(merchantSerialNumber).apiV3Key(apiV3Key).build();//1.0创建支付服务NativePayService service = new NativePayService.Builder().config(config).build();//2.0创建预支付请求体PrepayRequest prepayRequest = new PrepayRequest();prepayRequest.setAppid(appId); //appidprepayRequest.setMchid(merchantId); //商户号//2.1 商品描述prepayRequest.setDescription("test");//2.2 todo 商户订单号 随机生成Utility.generateRandomString(16)是随机生成的 换成你自己的prepayRequest.setOutTradeNo(Utility.generateRandomString(16));//2.3 支付超时时间prepayRequest.setTimeExpire(Utility.getTimeFactory());//2.4 todo 回调地址prepayRequest.setNotifyUrl("https://www.baidu.com/xxxxxx");//2.5 todo 附加信息 创建一个 JSON 对象 不需要可以删除JSONObject jsonObjectAttach = new JSONObject();jsonObjectAttach.put("orId", "xxx");jsonObjectAttach.put("orStatus", "xxxx");prepayRequest.setAttach(jsonObjectAttach.toJSONString());//2.6订单金额Amount amount = new Amount();//金额 1=0.01amount.setTotal(100);amount.setCurrency("CNY");prepayRequest.setAmount(amount);//3.0 调用接口PrepayResponse prepay = service.prepay(prepayRequest);//打印支付结果System.out.println(prepay);Map<String, Object> map = new HashMap<>();map.put("data",prepay.getCodeUrl());return map;}
}