关于微信退款报ValidationException的问题解决

简述

        相信很多小伙伴都对接过支付,最常见的莫过于支付宝支付和微信支付,但二者相差的不是一星半点;两个平台对接下来,给我的感觉就是,支付宝在想办法让我们开发变得简单;而微信似乎怕我们盗取了它的技术一样,把各种事弄得复杂,找技术客服问就是各种给人发文档;虽然微信已经提供了sdk,但是官网demo有些示例是错的,有些东西也不告诉你怎么用,这不,我这付款是正常的,退款就报错,关键是钱还给退了,回调也是退款成功,虽然说事儿是干成了,但咱身为程序猿,总不能放着异常不管吧,这不,绞尽脑汁,终于解决了报错。特此分享,让后面的小伙伴们少走弯路。

话不多说,咱们直接开始!

// 初始化商户配置
RSAConfig config = new RSAConfig.Builder()
        .merchantId(MCHID) // 商户id
        .privateKeyFromPath(PRIVATE_KEY_PATH) // 商户私钥文件路径
        .merchantSerialNumber(SERIAL_NO) // 商户证书序列号
        .wechatPayCertificatesFromPath(APICLIENT_CERT_PATH) // 商户证书路径
        .build();
// 初始化服务
refundService = new RefundService.Builder().config(config).build();
CreateRequest createRequest = new CreateRequest();
    .
    . // 业务参数此处省略
    .   
Refund refundResult = refundService.create(createRequest);

        相信很多小伙伴也是像我这么用的,当然这么用常规情况是没问题的,我用的证书和私钥也都是微信商户平台下载的;但问题就是证书现在会过期,需要我们自己去更新(这里可以参考微信官方证书相关文档),不然退款等需要证书的接口调用的时候就会报ValidationException(我就是上了这个鬼当了😭😭):

com.wechat.pay.java.core.exception.ValidationException: Validate response failed,the WechatPay signature is incorrect.   

        先看官方demo代码:

public static void main(String[] args) {
    // 初始化商户配置
    RSAConfig rsaConfig =
        new RSAConfig.Builder()
            .merchantId(merchantId)
            // 使用 com.wechat.pay.java.core.util 中的函数从本地文件中加载商户私钥,商户私钥会用来生成请求的签名
            .privateKeyFromPath(privateKeyPath)
            .merchantSerialNumber(merchantSerialNumber)
            .wechatPayCertificatesFromPath(wechatPayCertificatePath)
            .build();

    // 初始化证书服务
    service = new CertificateService.Builder().config(rsaConfig).build();
    // 设置商户apiV3密钥,apiV3密钥用于解密下载证书
    // ... 调用接口
  }

  /** 下载证书 */
  public static List<X509Certificate> downloadCertificate() {
    return service.downloadCertificate(apiV3Key.getBytes(StandardCharsets.UTF_8));
  }

        代码中,RSAConfig需要配置四个参数,其中包含证书文件路径,但我现在证书是过期了的,这样不会报ValidationException吧,然而结果就是该报还是会报😂😂;就微信官方demo都在搞事情呗🤣🤣,于是我就想啊、想啊,查啊、查啊;灵光一闪,既然这里给了证书就报异常,那我不给呢,于是就把RSAConfig换成了RSAAutoCertificateConfig,相比之下后者不需要传入证书路径,但需要传入密钥,这样就能顺利拿到证书了,代码如下:

// 初始化商户配置
    Config rsaConfig =
        new RSAAutoCertificateConfig.Builder()
            .merchantId(merchantId)
            // 使用 com.wechat.pay.java.core.util 中的函数从本地文件中加载商户私钥,商户私钥会用来生成请求的签名
            .privateKeyFromPath(privateKeyPath)
            .merchantSerialNumber(merchantSerialNumber)
            .apiV3Key(apiV3Key)
            .build();

    // 初始化证书服务
    service = new CertificateService.Builder().config(rsaConfig).build();
    // 设置商户apiV3密钥,apiV3密钥用于解密下载证书
    // ... 调用接口
    List<X509Certificate> certs = service.downloadCertificate(apiV3Key.getBytes(StandardCharsets.UTF_8));

        现在我们拿到证书了,但是X509Certificate这个玩意儿还不能直接用,需要转换为.pem文件才能使用,这里我们可以转换为字符串,之后写入文件保存服务器,官方的建议是定时去更新证书,我问了微信支付客服,客服建议大于12小时更新一次;于是我24小时更新一次。更新代码如下:

StringWriter sw = new StringWriter();
try (PEMWriter pw = new PEMWriter(sw)) {
    pw.writeObject(certs.get(0)); // 取接口获取到的证书内容
}
File file = new File(APICLIENT_CERT_PATH); // 服务器存放证书的文件路径
fileWriter = new FileWriter(file);
fileWriter.write(sw.toString());
fileWriter.flush();
fileWriter.close();

         我的上述代码是放在定时任务中之行,每天执行一次更新证书,做完这些,退款等需要证书的接口就能恢复正常啦🥳🥳

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值