调用微信虚拟支付 `query_order` 接口时,始终返回**支付签名(pay_sig)校验失败**(错误rid: 69aa8f50-74f4c3df-45f16563),已核对AppKey(沙箱/正式环境匹配)、uri、参数值均无误,请求帮忙排查签名生成逻辑问题。
### 关键代码片段
```java
TreeMap requestMap = new TreeMap<>();
requestMap.put("openid", openid);
requestMap.put("env", env);
requestMap.put("order_id", payOrder.getOutTradeNo());
String postData = JSONObject.toJSONString(requestMap, SerializerFeature.DisableCircularReferenceDetect);
String uri = "/xpay/query_order";
String paySig = VirtualPayApiUtil.generatePaySig(uri, postData, appKey);
public static String generatePaySig(String uri, String postBody, String appKey) {
String needSignMsg = uri + '&' + postBody;
return HmacUtils.hmacSha256Hex(appKey, needSignMsg);
}
String resStr = virtualPayFeignClient.queryOrder(token.getAccessToken(), paySig, requestMap);
```**
* 查询订单接口
* query_order
*
* @param accessToken 访问令牌
* @param paySig 支付签名
* @param requestBody 请求体
* @return 订单信息
*/
@RequestMapping(
value = "/xpay/query_order",
method = RequestMethod.POST,
consumes = MediaType.APPLICATION_JSON_VALUE,
produces = MediaType.APPLICATION_JSON_VALUE
)
String queryOrder(@RequestParam("access_token") String accessToken,
@RequestParam("pay_sig") String paySig,
@RequestBody TreeMap requestBody);
### 已排查的问题
1. ✅ AppKey与env匹配:env=1使用沙箱AppKey,env=0使用正式AppKey,无混用;
2. ✅ uri正确性:严格使用 `/xpay/query_order`,无多余参数/路径;
3. ✅ 请求体序列化:使用TreeMap保证字段顺序(openid→env→order_id),JSON序列化无空格/换行;
4. ✅ 签名算法:按官方伪代码实现 `paySig = to_hex(hmac_sha256(appKey,uri + '&' + signData))`;
5. ✅ 参数完整性:openid、env、order_id均非空,与订单数据一致。
这个问题解决了吗,我也遇到了同样的问题,同样的签名算法
Map<String, Object> mapSignData = new LinkedHashMap<>(); mapSignData.put("openid", memberVirtualOrder.getOpenId()); mapSignData.put("env", virtualPayEnvironment.getVirtualEnvironment()); mapSignData.put("order_id", memberVirtualOrder.getOrderId()); logger.info("微信签名数据:{}", mapSignData); String paySig = generatePaySign(virtualPayInfo.getAppKey(),"/xpay/query_order", JSON.toJSONString(mapSignData));这个签名传参和计算,在生成小程序虚拟支付参数时完全正常,下单也成功了,就是调这个接口就出现了签名验证失败的问题
你都用 AI 了,不会让他给你运行一遍你的代码么?
FeignClient 会序列化 json,你计算是postData,请求时是requestMap,经过FeignClient ,还能保持一致?
官方文档用的是这个签名方法
https://developers.weixin.qq.com/miniprogram/dev/platform-capabilities/business-capabilities/virtual-payment.html#%E6%94%AF%E4%BB%98%E7%AD%BE%E5%90%8D-2
https://developers.weixin.qq.com/miniprogram/dev/platform-capabilities/business-capabilities/virtual-payment.html#query-order