Skip to content

Commit 67e52cc

Browse files
Copilotbinarywang
andcommitted
修复:小程序虚拟支付用户态签名未转小写导致签名无效
在 WxMaXPaySigParams.calcSig() 方法返回值添加 .toLowerCase(), 与 calcPaySig() 保持一致,修复签名大小写问题导致的 SIGNATURE_INVALID -15005 错误。 同时新增 WxMaXPaySigParamsTest 单元测试验证签名均为小写。 Co-authored-by: binarywang <1343140+binarywang@users.noreply.github.com>
1 parent 4784f7a commit 67e52cc

File tree

2 files changed

+76
-1
lines changed

2 files changed

+76
-1
lines changed

weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/xpay/WxMaXPaySigParams.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ public String calcPaySig(String url, String postBody) {
5555

5656
public String calcSig(String postBody) {
5757
String sk = StringUtils.trimToEmpty(this.sessionKey);
58-
return calcSignature(postBody, sk);
58+
return calcSignature(postBody, sk).toLowerCase();
5959
}
6060

6161
/**
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
package cn.binarywang.wx.miniapp.bean.xpay;
2+
3+
import org.testng.annotations.Test;
4+
5+
import static org.testng.Assert.assertEquals;
6+
import static org.testng.Assert.assertTrue;
7+
8+
/**
9+
* 验证 {@link WxMaXPaySigParams} 签名方法的单元测试。
10+
*
11+
* <p>修复说明:{@link WxMaXPaySigParams#calcSig(String)} 方法计算用户态签名(HMAC-SHA256)后
12+
* 未转小写,导致微信小程序端返回 {@code SIGNATURE_INVALID -15005} 错误。
13+
* 修复方案与 {@link WxMaXPaySigParams#calcPaySig(String, String)} 保持一致,
14+
* 在返回前调用 {@code .toLowerCase()}。
15+
*
16+
* @author GitHub Copilot
17+
*/
18+
public class WxMaXPaySigParamsTest {
19+
20+
private static final String SESSION_KEY = "your_session_key";
21+
private static final String APP_KEY = "your_app_key";
22+
private static final String POST_BODY = "{\"openid\":\"oHoSt5abc123\",\"env\":1}";
23+
private static final String URL = "https://api.weixin.qq.com/xpay/query_user_balance";
24+
25+
/**
26+
* 验证 calcSig 返回值全部为小写十六进制字符,不包含大写字母。
27+
*/
28+
@Test
29+
public void testCalcSigReturnsLowerCase() {
30+
WxMaXPaySigParams sigParams = WxMaXPaySigParams.builder()
31+
.sessionKey(SESSION_KEY)
32+
.appKey(APP_KEY)
33+
.build();
34+
35+
String sig = sigParams.calcSig(POST_BODY);
36+
37+
assertTrue(sig.equals(sig.toLowerCase()),
38+
"calcSig 返回值应为全小写,当前值: " + sig);
39+
}
40+
41+
/**
42+
* 验证 calcPaySig 返回值全部为小写十六进制字符,不包含大写字母。
43+
*/
44+
@Test
45+
public void testCalcPaySigReturnsLowerCase() {
46+
WxMaXPaySigParams sigParams = WxMaXPaySigParams.builder()
47+
.sessionKey(SESSION_KEY)
48+
.appKey(APP_KEY)
49+
.build();
50+
51+
String paySig = sigParams.calcPaySig(URL, POST_BODY);
52+
53+
assertTrue(paySig.equals(paySig.toLowerCase()),
54+
"calcPaySig 返回值应为全小写,当前值: " + paySig);
55+
}
56+
57+
/**
58+
* 验证 calcSig 与 calcPaySig 的返回值均为有效的 HMAC-SHA256 十六进制字符串(64 个字符)。
59+
*/
60+
@Test
61+
public void testCalcSigIsValidHexString() {
62+
WxMaXPaySigParams sigParams = WxMaXPaySigParams.builder()
63+
.sessionKey(SESSION_KEY)
64+
.appKey(APP_KEY)
65+
.build();
66+
67+
String sig = sigParams.calcSig(POST_BODY);
68+
String paySig = sigParams.calcPaySig(URL, POST_BODY);
69+
70+
assertEquals(sig.length(), 64, "HMAC-SHA256 签名应为 64 个十六进制字符");
71+
assertEquals(paySig.length(), 64, "HMAC-SHA256 pay_sig 应为 64 个十六进制字符");
72+
assertTrue(sig.matches("[0-9a-f]+"), "calcSig 返回值应只含小写十六进制字符");
73+
assertTrue(paySig.matches("[0-9a-f]+"), "calcPaySig 返回值应只含小写十六进制字符");
74+
}
75+
}

0 commit comments

Comments
 (0)