Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,10 @@ public static class JsapiResult implements Serializable {
private String appId;
private String timeStamp;
private String nonceStr;
/**
* 由于package为java保留关键字,因此改为packageValue,序列化时会自动转换为package字段名
*/
@SerializedName("package")
private String packageValue;
private String signType;
private String paySign;
Expand All @@ -80,6 +84,10 @@ public static class AppResult implements Serializable {
private String appid;
private String partnerid;
private String prepayid;
/**
* 由于package为java保留关键字,因此改为packageValue,序列化时会自动转换为package字段名
*/
@SerializedName("package")
private String packageValue;
private String noncestr;
private String timestamp;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,10 @@ public static class JsapiResult implements Serializable {
private String appId;
private String timeStamp;
private String nonceStr;
/**
* 由于package为java保留关键字,因此改为packageValue,序列化时会自动转换为package字段名
*/
@SerializedName("package")
private String packageValue;
private String signType;
private String paySign;
Expand All @@ -89,6 +93,10 @@ public static class AppResult implements Serializable {
private String appid;
private String partnerid;
private String prepayid;
/**
* 由于package为java保留关键字,因此改为packageValue,序列化时会自动转换为package字段名
*/
@SerializedName("package")
private String packageValue;
private String noncestr;
private String timestamp;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,10 @@ public static class JsapiResult implements Serializable {
private String appId;
private String timeStamp;
private String nonceStr;
/**
* 由于package为java保留关键字,因此改为packageValue,序列化时会自动转换为package字段名
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

packageValue 这里的注释写“序列化时会自动转换为package字段名”,但实际是依赖 Gson 的 @SerializedName("package") 才会生效;如果调用方用其他 JSON 库(如 Jackson)仍可能输出 packageValue。考虑在注释里明确这是 Gson 序列化行为以避免误导。

Severity: low

Other Locations
  • weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayUnifiedOrderV3Result.java:116
  • weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/CombineTransactionsResult.java:77
  • weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/CombineTransactionsResult.java:97
  • weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/ecommerce/TransactionsResult.java:69
  • weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/ecommerce/TransactionsResult.java:88

Fix This in Augment

🤖 Was this useful? React with 👍 or 👎, or 🚀 if it prevented an incident/outage.

*/
@SerializedName("package")
private String packageValue;
private String signType;
private String paySign;
Expand Down Expand Up @@ -106,8 +110,14 @@ public static class AppResult implements Serializable {
private static final long serialVersionUID = 5465773025172875110L;

private String appid;
@SerializedName("partnerid")
private String partnerId;
@SerializedName("prepayid")
private String prepayId;
/**
* 由于package为java保留关键字,因此改为packageValue,序列化时会自动转换为package字段名
*/
@SerializedName("package")
private String packageValue;
private String noncestr;
Comment on lines 112 to 122
Copy link

Copilot AI Apr 7, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

WxPayUnifiedOrderV3Result.AppResult 目前只有 packageValue 增加了 @SerializedName("package");但同一个对象里 partnerId / prepayId 字段如果用 Gson 序列化,JSON key 会变成 partnerId / prepayId,而微信 APP 支付参数要求的是 partnerid / prepayid(同模块里 CombineTransactionsResult/TransactionsResult 的 AppResult 也使用了全小写字段名)。建议为 partnerId、prepayId 同样补充 @SerializedName("partnerid") / @SerializedName("prepayid")(或统一字段命名策略),避免调用方直接序列化该对象时仍不兼容微信端。

Copilot uses AI. Check for mistakes.
private String timestamp;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

import com.github.binarywang.wxpay.bean.result.enums.TradeTypeEnum;
import com.github.binarywang.wxpay.v3.util.SignUtils;
import com.google.gson.Gson;
import com.google.gson.JsonObject;
import org.testng.Assert;
import org.testng.annotations.Test;

Expand Down Expand Up @@ -200,9 +202,62 @@ public void testAppResultWithPrepayId() throws Exception {
}

/**
* 测试getJsapiPayInfo方法的空值验证
* 测试JsapiResult序列化为JSON时,packageValue字段名应为package(兼容微信官方API要求)
*/
@Test(expectedExceptions = IllegalArgumentException.class,
@Test
public void testJsapiResultJsonSerializationPackageFieldName() throws Exception {
String testPrepayId = "wx201410272009395522657a690389285100";
String testAppId = "wx8888888888888888";
KeyPair keyPair = generateKeyPair();
PrivateKey privateKey = keyPair.getPrivate();

WxPayUnifiedOrderV3Result.JsapiResult jsapiResult =
WxPayUnifiedOrderV3Result.getJsapiPayInfo(testPrepayId, testAppId, privateKey);

// 验证Java字段名仍为packageValue
Assert.assertEquals(jsapiResult.getPackageValue(), "prepay_id=" + testPrepayId);

// 验证JSON序列化后字段名为package(微信官方要求)
Gson gson = new Gson();
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这里用 new Gson() 来验证序列化字段名,可能与项目内实际使用的 Gson 配置(例如 WxGsonBuilder.create() 或统一的 GsonBuilder 实例)不一致。为避免后续 Gson 配置调整导致测试与真实序列化行为偏离,考虑复用项目里支付模块的 Gson 创建方式。

Severity: low

Fix This in Augment

🤖 Was this useful? React with 👍 or 👎, or 🚀 if it prevented an incident/outage.

JsonObject jsonObject = gson.toJsonTree(jsapiResult).getAsJsonObject();
Assert.assertTrue(jsonObject.has("package"), "JSON中应该包含package字段");
Assert.assertFalse(jsonObject.has("packageValue"), "JSON中不应该包含packageValue字段");
Assert.assertEquals(jsonObject.get("package").getAsString(), "prepay_id=" + testPrepayId);
}

/**
* 测试AppResult序列化为JSON时,packageValue字段名应为package(兼容微信官方API要求)
*/
@Test
public void testAppResultJsonSerializationPackageFieldName() throws Exception {
String testPrepayId = "wx201410272009395522657a690389285100";
String testAppId = "wx8888888888888888";
String testMchId = "1900000109";
KeyPair keyPair = generateKeyPair();
PrivateKey privateKey = keyPair.getPrivate();

WxPayUnifiedOrderV3Result.AppResult appResult =
WxPayUnifiedOrderV3Result.getAppPayInfo(testPrepayId, testAppId, testMchId, privateKey);

// 验证Java字段名仍为packageValue
Assert.assertEquals(appResult.getPackageValue(), "Sign=WXPay");

// 验证JSON序列化后字段名为package(微信官方要求)
Gson gson = new Gson();
JsonObject jsonObject = gson.toJsonTree(appResult).getAsJsonObject();
Assert.assertTrue(jsonObject.has("package"), "JSON中应该包含package字段");
Assert.assertFalse(jsonObject.has("packageValue"), "JSON中不应该包含packageValue字段");
Assert.assertEquals(jsonObject.get("package").getAsString(), "Sign=WXPay");
Comment on lines +239 to +250
Copy link

Copilot AI Apr 7, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

新增的 JSON 序列化测试目前只校验了 package/packageValue;但如果调用方直接用 Gson 序列化 AppResult,partnerId/prepayId 仍会输出为驼峰 key(partnerId/prepayId),与微信 APP 支付期望的 partnerid/prepayid 不一致。建议在同一组测试里也断言 partnerid/prepayid 的字段名与值(并在代码侧配合补齐 @SerializedName)。

Copilot uses AI. Check for mistakes.
// 验证JSON序列化后partnerid和prepayid字段名为全小写(微信官方要求)
Assert.assertTrue(jsonObject.has("partnerid"), "JSON中应该包含partnerid字段");
Assert.assertFalse(jsonObject.has("partnerId"), "JSON中不应该包含驼峰的partnerId字段");
Assert.assertEquals(jsonObject.get("partnerid").getAsString(), testMchId);
Assert.assertTrue(jsonObject.has("prepayid"), "JSON中应该包含prepayid字段");
Assert.assertFalse(jsonObject.has("prepayId"), "JSON中不应该包含驼峰的prepayId字段");
Assert.assertEquals(jsonObject.get("prepayid").getAsString(), testPrepayId);
}

@Test(expectedExceptions = IllegalArgumentException.class,
expectedExceptionsMessageRegExp = "prepayId, appId 和 privateKey 不能为空")
public void testGetJsapiPayInfoWithNullPrepayId() {
WxPayUnifiedOrderV3Result.getJsapiPayInfo(null, "appId", null);
Expand Down