为什么调用时报:{"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);
//这里默认使用&拼接,官网示例中使用的是&
//为了避免歧义,在编写 HTML 代码时,需要把文本中单纯的 “&” 符号写成 &。
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());

微信虚拟支付的签名要求 signData(即 POST Body)必须是原始的 JSON 字符串。你代码看不出来是完全一致的
确认用于签名的jsonData与调用接口传的参数是完全一样的