芋道框架中提供统一的支付中心,提供微信、支付宝等支付渠道的支付、退款等能力,方便业务模块进行快速接入,无需关注各种繁琐的支付 API。
这里主要讲述的是微信小程序支付,芋道文档中有的这里不再详细描述。
一、前言
在一次芋道项目中使用微信小程序支付发现现有的微信支付V3不再支持使用平台证书,而是使用微信支付公钥。但是芋道框架现在还未更新,使用的仍是平台证书进行验签的。这里对芋道的代码进行的一点更改,使之使用微信支付公钥进行验签。
错误信息:
二、解决问题
在芋道中调用的支付接口是/pay/order/submit
为了方便这里直接是在代码中配置的,而不是在后台系统中进行配置的。
为了使用v3版本的平台证书进行验签,这里修改原有的微信支付抽象类中的doInit方法
# 微信支付抽象类中原有的doInit方法
/**
* 初始化 client 客户端
*
* @param tradeType 交易类型
*/
protected void doInit(String tradeType) {
// 创建 config 配置
WxPayConfig payConfig = new WxPayConfig();
BeanUtil.copyProperties(config, payConfig, "keyContent", "privateKeyContent");
payConfig.setTradeType(tradeType);
// weixin-pay-java 无法设置内容,只允许读取文件,所以这里要创建临时文件来解决
if (Objects.equals(config.getApiVersion(), API_VERSION_V2)) {
payConfig.setKeyPath(FileUtils.createTempFile(Base64.decode(config.getKeyContent())).getPath());
} else if (Objects.equals(config.getApiVersion(), API_VERSION_V3)) {
payConfig.setPrivateKeyPath(FileUtils.createTempFile(config.getPrivateKeyContent()).getPath());
}
// 创建 client 客户端
client = new WxPayServiceImpl();
client.setConfig(payConfig);
}
修改后的doInit方法
protected void doInit() {
WxPayConfig payConfig = new WxPayConfig();
payConfig.setUseSandboxEnv(false);
this.client = new WxPayServiceImpl();
//appId
payConfig.setAppId("wx123456789");
//商户号
payConfig.setMchId("123456789");
//微信支付 API V3 的密钥
payConfig.setApiV3Key("safdasdasdad");
//商户私钥文件的路径
payConfig.setPrivateKeyPath("classpath:xxx/apiclient_key.pem");
//商户证书文件的路径
payConfig.setPrivateCertPath("classpath:xxx/apiclient_cert.pem");
//商户证书的序列号
payConfig.setCertSerialNo("34168923612189361823");
//商户证书的 .p12 文件路径
payConfig.setKeyPath("classpath:xxx/apiclient_cert.p12");
//微信支付平台公钥文件的路径
payConfig.setPublicKeyPath("classpath:xxx/pub_key.pem");
//微信支付平台公钥的ID
payConfig.setPublicKeyId("PUB_KEY_ID_123456789");
//将配置好的 payConfig 对象设置到 client 中,client 是微信支付服务的客户端实例。
client.setConfig(payConfig);
// 注入自定义Verifier(仅V3模式需要)
if (StrUtil.isNotEmpty(config.getWxPayPublicKey())) {
WxPayPublicKeyVerifier verifier = new WxPayPublicKeyVerifier(config.getWxPayPublicKey());
try {
java.lang.reflect.Field verifierField = client.getClass().getDeclaredField("verifier");
verifierField.setAccessible(true);
verifierField.set(client, verifier);
} catch (Exception e) {
log.error("注入微信支付公钥Verifier失败", e);
}
}
}
修改doInit方法后注意需要将所有用到这个方法的变成无参的
经过上述对doInit的修改可以保证微信支付的临时使用,但是后需还是需要修改,不能把这个密钥,文件直接放到代码中进行硬编码。
有什么问题,可以在评论区留言!