收藏
回答

wx.openBusinessView 商户签名校验失败?

这里是官方文档:https://pay.weixin.qq.com/doc/v3/merchant/4012587984

前端调用使用的也是businessType,调试了很多次,拉起支付分订单详情一直提示"商户签名校验失败",请求各位大佬帮分析下

代码片段,service_id 和 v2 密钥保密

/**
 * 获取 openBusinessView 所需参数
 */
@GetMapping("/business-view")
public ApiResult getBusinessViewParams(@RequestParam String outOrderNo) {
    try {
        Map params = new HashMap<>();
        params.put("mch_id", "1611641336");
        params.put("service_id", "我的service_id");
        params.put("out_order_no", outOrderNo);
        params.put("timestamp", String.valueOf(System.currentTimeMillis() / 1000));
        params.put("nonce_str", generateNonceStr());
        params.put("sign_type", "HMAC-SHA256");

        // 生成签名
        String sign = generateSignature(params);
        params.put("sign", sign);

        return ApiResult.success("success", params);
    } catch (Exception e) {
        return ApiResult.fail("生成参数失败: " + e.getMessage());
    }
}

/**
 * 生成 HMAC-SHA256 签名
 */
private String generateSignature(Map params) throws Exception {
    // 1. 过滤空值并排序
    List keys = params.keySet().stream()
            .filter(k -> !k.equals("sign") && StringUtils.hasText(params.get(k)))
            .sorted()
            .collect(Collectors.toList());

    // 2. 拼接签名字符串
    StringJoiner query = new StringJoiner("&");
    for (String key : keys) {
        query.add(key + "=" + params.get(key));
    }
    String stringSign = query.toString();

    // 3. 使用密钥加密
    Mac sha256 = Mac.getInstance("HmacSHA256");
    SecretKeySpec secretKey = new SecretKeySpec("我的 v2 密钥".getBytes(), "HmacSHA256");
    sha256.init(secretKey);
    byte[] bytes = sha256.doFinal(stringSign.getBytes(StandardCharsets.UTF_8));

    // 4. 转成十六进制
    return bytesToHex(bytes).toUpperCase();
}

/**
 * 生成随机字符串
 */
private String generateNonceStr() {
    return UUID.randomUUID().toString().replace("-", "").substring(0, 32);
}

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


渠道的结果片段:

mch_id: "1611641336"

nonce_str: "45566a3137424247956962a29b44ef8b"

out_order_no: "AIV20250523104335682fe0d74759e"

service_id: "00004000000000168722808608323064"

sign: "CDDD0719DB3ABDA897D447B9675A9BA63120273A07985535DD837F0A8E8DD480"

sign_type: "HMAC-SHA256"

timestamp: "1747971706"




最后一次编辑于  05-23
回答关注问题邀请回答
收藏

1 个回答

  • 北望沣渭
    北望沣渭
    05-23

    把 stringSign 打印出来看看末尾是不是多一个 & 符号?

    05-23
    有用
    回复 5
    • 凉白开
      凉白开
      05-23
      签名字符串: mch_id=1611641336&nonce_str=e3ab319cca014acd8d7801f1d3f4c95c&out_order_no=AIV20250523104335682fe0d74759e&service_id=xxx&sign_type=HMAC-SHA256×tamp=1747974384
      05-23
      回复
    • 凉白开
      凉白开
      05-23
      没有多余&
      05-23
      回复
    • 北望沣渭
      北望沣渭
      05-23回复凉白开
      是不是末尾少了&key=xxx ?
      05-23
      2
      回复
    • 北望沣渭
      北望沣渭
      05-23
      可参考这里的「数据签名」规则示例 https://wechatpay.im/guide/digital-signature#symmetric.backend
      05-23
      回复
    • 凉白开
      凉白开
      05-23回复北望沣渭
      解决了,是没有拼接 key 的问题,多谢大佬🙏
      05-23
      回复
登录 后发表内容