收藏
回答

微信小程序虚拟支付中批量上传道具接口调用时“报支付签名(pay_sig)校验失败”是什么原因?

为什么调用时报:{"errcode" : 268490003,"errmsg" : "支付签名(pay_sig)校验失败 rid: 69d613a1-399abd25-5f3c9197"}


已经仔细排查了所有可能存在的问题,但问题依旧,生成签名时直接使用JSON字符串,不经过转换也试过了:

String jsonData= "{\"upload_item\":[{\"id\":\"0105\",\"item_url\":\"https://zszb-img.oss-cn-hangzhou.aliyuncs.com/zszb_v3/virtualImages/200X200.png\",\"name\":\"月卡(30天)\",\"price\":770,\"remark\":\"月卡(30天)\"}],\"env\":0}";


最终请求的接口地址为:

https://api.weixin.qq.com/xpay/start_upload_goods?access_token=102_lq4i3abHK0uBgAphxdyXQfVZ_BfgTlxHdYBflnthYBH37lvKmOqhRYGVnp5aDXB_v2KXDGOOaUil7jHsnaIZaic4QWJPIhbE-co8E7LolQ2QnWSy_rQfzGg7HGALFPjADAHBL&pay_sig=a3fbdde931ec17e065612611a41bf96754205940c0f7e01c138bf168aa00b5e5


上传的道具对象:

{
    "upload_item" : [ {
    "id" : "0105",
    "item_url" : "https://zszb-img.oss-cn-hangzhou.aliyuncs.com/zszb_v3/virtualImages/200X200.png",
    "name" : "月卡(30天)",
    "price" : 770,
    "remark" : "月卡(30天)"
    } ],
    "env" : 0
}


上传主方法:

private String uploadGoods(List<UploadGoodsInfo> uploadGoodsInfo,String accessToken,String appKey,int env) {
    Map<String,Object> reqMap = new LinkedHashMap<>();
    reqMap.put("upload_item",uploadGoodsInfo);
    reqMap.put("env",env);
    //生成支付签名
    String jsonData = JSON.toJSONString(reqMap);
    log.info("待签名的数据:{}",jsonData);"remark\":\"月卡(30天)\"}],\"env\":0}";
    String paySig = weiXinPayService.generatePaySign(appKey,"/xpay/start_upload_goods", jsonData);
    String url = BASE_WEIXING_PAY_URL + "start_upload_goods?access_token=" + accessToken + "&pay_sig=" + paySig;
    String resp = HttpUtil.post(url, jsonData);
    log.info("上传结果:{}",resp);
    return resp;
}
支付签名实现:
/**
 * 支付签名
 * @param appKey
 * @param uri
 * @param signData
 * @return
 */
public String generatePaySign(String appKey,String uri,String signData){
    logger.info("signData:{}",signData);
    HMac mac = SecureUtil.hmacSha256(appKey);
    //这里默认使用&拼接,官网示例中使用的是&amp;
    //为了避免歧义,在编写 HTML 代码时,需要把文本中单纯的 “&” 符号写成 &amp;。
    return mac.digestHex(uri +"&" + signData);
}

调用:
UploadGoodsInfo uploadGoodsInfo = new UploadGoodsInfo();
uploadGoodsInfo.setPrice(memberGoodsInfo.getMemberPrice());
uploadGoodsInfo.setId(memberGoodsInfo.getProductId());
uploadGoodsInfo.setName(memberGoodsInfo.getProductName());
uploadGoodsInfo.setRemark(memberGoodsInfo.getProductName());
uploadGoodsInfo.setItem_url("https://zszb-img.oss-cn-hangzhou.aliyuncs.com/zszb_v3/virtualImages/200X200.png");
log.info("正在上传商品:{}",uploadGoodsInfo.getName());
List<UploadGoodsInfo> uploadGoodsInfoList = new ArrayList<>();
uploadGoodsInfoList.add(uploadGoodsInfo);
String resp = uploadGoods(uploadGoodsInfoList,accessToken.getAccess_token(),virtualPayInfo.getAppKey(),virtualPayEnvironment.getVirtualEnvironment());
回答关注问题邀请回答
收藏

3 个回答

  • Memory (私信不回复)
    Memory (私信不回复)
    04-08

    微信虚拟支付的签名要求 signData(即 POST Body)必须是原始的 JSON 字符串。你代码看不出来是完全一致的

    04-08
    有用
    回复 2
    • 贺振军
      贺振军
      04-08
      那为什么我手写的JSON字符串报的是同样错?
      04-08
      回复
    • Memory (私信不回复)
      Memory (私信不回复)
      04-08回复贺振军
      你只是jsonData 看起来是对的,实际请求和计算的并不一致
      04-08
      回复
  • 智能回答 智能回答 本次回答由AI生成
    04-08
    有用
  • 贺振军
    贺振军
    04-08

    确认用于签名的jsonData与调用接口传的参数是完全一样的

    04-08
    有用
    回复
登录 后发表内容