收藏
回答

前端虚拟支付调用报错“requestVirtualPayment:fail SIGNATURE_”?

前端代码:

api.createRechargeOrder(this.data.selectedOptionId, this.data.bookId, this.data.chapterIndex).then(res => {
        const payParams = res.data;
        // 虚拟支付
        wx.requestVirtualPayment({
          signData: payParams.signData,
          mode: 'short_series_goods',
          paySig: payParams.paySig,
          signature: payParams.signature,
          success() {
            // xxxxxxxxxxxxxxxxxxx
          },
          fail(e) {
            // xxxxxxxxxxxxxxxxxxxxxxxxxx
          },
        })
      })


后端Java代码(createRechargeOrder 调用的方法):

public WxVirtualPayResultDto createVirtualPayOrder(Long productId, BigDecimal goodsPrice, String orderNo, Long userId, String sessionKey) {
    String signData = getSignData(productId, goodsPrice, orderNo, userId);
    String paySig = getPaySig(signData);
    String signature = getSignature(sessionKey, signData);
    WxVirtualPayResultDto wxVirtualPayResultDto = new WxVirtualPayResultDto();
    wxVirtualPayResultDto.setSignature(signature);
    wxVirtualPayResultDto.setPaySig(paySig);
    wxVirtualPayResultDto.setSignData(signData);
    wxVirtualPayResultDto.setOrderNo(orderNo);
    return wxVirtualPayResultDto;
}

private String getSignData(Long productId, BigDecimal goodsPrice, String orderNo, Long userId) {
    int priceInCent = goodsPrice.multiply(new BigDecimal("100"))
            .setScale(0, RoundingMode.HALF_UP)
            .intValue();
    String signData = "{\"offerId\":\"%s\",\"buyQuantity\":1,\"env\":%d,\"currencyType\":\"CNY\",\"productId\":\"%d\",\"goodsPrice\":%d,\"outTradeNo\":\"%s\",\"attach\":\"%s\"}";
    return signData.formatted(offerId, env, productId, priceInCent, orderNo, userId);
}

private String getPaySig(String signData) {
    try {
        String dataToSign = "uri=requestVirtualPayment&signData=" + signData;
        Mac mac = Mac.getInstance("HmacSHA256");
        SecretKeySpec secretKeySpec = new SecretKeySpec(
                env == 0 ? appKey.getBytes(StandardCharsets.UTF_8) : sandboxAppKey.getBytes(StandardCharsets.UTF_8),
                "HmacSHA256"
        );
        mac.init(secretKeySpec);
        byte[] hmacBytes = mac.doFinal(dataToSign.getBytes(StandardCharsets.UTF_8));
        return bytesToHex(hmacBytes);
    } catch (Exception e) {
        throw new RuntimeException("HMAC-SHA256 签名失败", e);
    }
}

private String getSignature(String sessionKey, String signData) {
    try {
        Mac mac = Mac.getInstance("HmacSHA256");
        SecretKeySpec secretKeySpec = new SecretKeySpec(
                sessionKey.getBytes(StandardCharsets.UTF_8),
                "HmacSHA256"
        );
        mac.init(secretKeySpec);
        byte[] hmacBytes = mac.doFinal(signData.getBytes(StandardCharsets.UTF_8));
        return bytesToHex(hmacBytes);
    } catch (Exception e) {
        throw new RuntimeException("HMAC-SHA256 签名失败", e);
    }
}

private static String bytesToHex(byte[] bytes) {
    StringBuilder sb = new StringBuilder();
    for (byte b : bytes) {
        sb.append(String.format("%02x", b));
    }
    return sb.toString();
}


前端报错:

errCode: -15005
errMsg"requestVirtualPayment:fail SIGNATURE_INVALID"
errno: -15005


用户态签名signature错误

但我不清楚我 signature 哪里有问题,请教大佬们帮我检查一下。

回答关注问题邀请回答
收藏

3 个回答

  • 路亚爱CV
    路亚爱CV
    03-30

    解决了吗?PHP也是报的这个

    03-30
    有用
    回复 1
    • Salieri
      Salieri
      04-13
      多检查一下签名这些流程,实在理不清楚,建议从头开始看文档,一步步来。
      04-13
      回复
  • 发飙的蜗牛
    发飙的蜗牛
    03-07
    node写的也是requestVirtualPayment:fail SIGNATURE_INVALID"
    


    03-07
    有用
    回复 1
    • Salieri
      Salieri
      04-13
      多检查一下签名这些流程,实在理不清楚,建议从头开始看文档,一步步来。
      04-13
      回复
  • K
    K
    03-03

    解决了嘛

    03-03
    有用
    回复 1
    • Salieri
      Salieri
      04-13
      多检查一下签名这些流程,实在理不清楚,建议从头开始看文档,一步步来。
      04-13
      回复
登录 后发表内容