在微信商家平台,账户中心-API安全中,开启V3公钥,记录公钥ID,并下载公钥证书

项目里引入jar包,pom

<dependency>
    <groupId>com.github.wechatpay-apiv3</groupId>
    <artifactId>wechatpay-java</artifactId>
    <version>0.2.17</version>
</dependency>

以APP支付为例:

public String appPrepay(int orderFee,String orderNo,String notifyUrl,String desc,long orderId) {
// 可以根据实际情况使用publicKeyFromPath或publicKey加载公钥
Config config =
    new RSAPublicKeyConfig.Builder()
        .merchantId("1900007291") //微信支付的商户号
        .privateKeyFromPath("/Users/yourname/yourpath/apiclient_key.pem") // 商户API证书私钥的存放路径
        .publicKeyFromPath("/Users/yourname/yourpath/pub_key.pem") //微信支付公钥的存放路径
        .publicKeyId("PUB_KEY_ID_00000000000000000000000000000000") //微信支付公钥ID
        .merchantSerialNumber("5157F09EFDC096DE15EBE81A47057A72********") //商户API证书序列号
        .apiV3Key("F09E**") //APIv3密钥
        .build();
AppServiceExtension appServiceExtension = new AppServiceExtension.Builder().config(config).build();
    PrepayRequest appRequest = new PrepayRequest();
    Amount amount = new Amount();
    amount.setTotal(orderFee);
    appRequest.setAmount(amount);
    amount.setTotal(orderFee);
    appRequest.setAmount(amount);
    appRequest.setMchid(commonParamsService.getWxPayMchId());
    appRequest.setAppid(commonParamsService.getWxOpenPlatformAppId());
    appRequest.setOutTradeNo(orderNo);
    appRequest.setNotifyUrl(sysConfigService.getHooplyAppApiUri()+notifyUrl);
    appRequest.setDescription(desc);

    PrepayWithRequestPaymentResponse res = appServiceExtension.prepayWithRequestPayment(appRequest);
    
    return res;
}

回调,微信商家证书切换过程中,如果回调切换为到100%则需要支持证书与公钥验签,即使下单时已经将公钥ID放入请求头中,回调也会有概率使用证书验签,所以在未到100%之前要兼容两种方式验签,

public Transaction paymentsNotifyPl(HttpServletRequest request) throws IOException {
        String body = getRequestBody(request);
        String wechatpayNonce = request.getHeader("Wechatpay-Nonce");
        String wechatSignature = request.getHeader("Wechatpay-Signature");
        String wechatTimestamp = request.getHeader("Wechatpay-Timestamp");
        String serialNumber = request.getHeader("Wechatpay-Serial");
        String wechatpaySignatureType = request.getHeader("Wechatpay-Signature-Type");
        log.info("wechatpayNonce:{},wechatSignature:{},wechatTimestamp:{},serialNumber:{},wechatpaySignatureType:{}",wechatpayNonce,wechatSignature,wechatTimestamp,serialNumber,wechatpaySignatureType);
        // 构造 RequestParam
        RequestParam requestParam = new RequestParam.Builder()
                .serialNumber(serialNumber)
                .nonce(wechatpayNonce)
                .signature(wechatSignature)
                .timestamp(wechatTimestamp)
                .body(body)
                .build();

// 如果已经初始化了 NotificationConfig,可直接使用
// 没有的话,则构造一个。以下多种 Config 根据情况选择一种即可:

//         1. 如果你使用的是微信支付公私钥,则使用 RSAPublicKeyNotificationConfig
        NotificationConfig config = new RSACombinedNotificationConfig.Builder()
                .merchantId(commonParamsService.getWxPayMchId())
                .privateKeyFromPath(commonParamsService.getWxV3PaymentPrivateKeyPath())
                .merchantSerialNumber(commonParamsService.getWxV3MerchantSerialNumber())
                .publicKeyFromPath(commonParamsService.getWxV3WechatpayPublicKeyPath())
                .publicKeyId(commonParamsService.getWxV3WechatpayPublicKeyId())
                .apiV3Key(commonParamsService.getWxV3ApiV3Key())
                .build();

        // 初始化 NotificationParser
        NotificationParser parser = new NotificationParser(config);

        try {
            Transaction transaction = parser.parse(requestParam, Transaction.class);
       
            return transaction;
        } catch (ValidationException e) {
            // 签名验证失败,返回 401 UNAUTHORIZED 状态码
            log.error("sign verification failed", e);
            throw new DistRuntimeException(HttpStatus.UNAUTHORIZED.value(),"sign verification failed");
        } catch (MalformedMessageException e) {
            log.error("MalformedMessageException", e);
            throw new DistRuntimeException(HttpStatus.BAD_REQUEST.value(),"MalformedMessageException");
        }
    }

Logo

开源鸿蒙跨平台开发社区汇聚开发者与厂商,共建“一次开发,多端部署”的开源生态,致力于降低跨端开发门槛,推动万物智联创新。

更多推荐