diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxSignQueryResult.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxSignQueryResult.java
index 524159719..af19aec60 100644
--- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxSignQueryResult.java
+++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxSignQueryResult.java
@@ -112,7 +112,7 @@ public class WxSignQueryResult extends BaseWxPayResult implements Serializable {
contractDisplayAccount = readXmlString(d, "contract_display_account");
contractState = readXmlInteger(d, "contract_state");
contractSignedTime = readXmlString(d, "contract_signed_time");
- contractExpiredTime = readXmlString(d, "contrace_Expired_time");
+ contractExpiredTime = readXmlString(d, "contract_expired_time");
contractTerminatedTime = readXmlString(d, "contract_terminated_time");
contractTerminatedMode = readXmlInteger(d, "contract_termination_mode");
contractTerminationRemark = readXmlString(d, "contract_termination_remark");
diff --git a/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/bean/result/WxSignQueryResultTest.java b/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/bean/result/WxSignQueryResultTest.java
new file mode 100644
index 000000000..52df2b6e2
--- /dev/null
+++ b/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/bean/result/WxSignQueryResultTest.java
@@ -0,0 +1,125 @@
+package com.github.binarywang.wxpay.bean.result;
+
+import com.github.binarywang.wxpay.util.XmlConfig;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+/**
+ * WxSignQueryResult 单元测试
+ *
+ * @author Binary Wang
+ */
+public class WxSignQueryResultTest {
+
+ /**
+ * 测试 XML 解析,特别是 contract_expired_time 字段
+ */
+ @Test
+ public void testFromXML() {
+ /*
+ * xml样例字符串来自于官方文档
+ * https://pay.weixin.qq.com/doc/v2/merchant/4011987640
+ */
+ String xmlString = "\n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " 203\n" +
+ " 66\n" +
+ " \n" +
+ " 123\n" +
+ " \n" +
+ " \n" +
+ " 1\n" +
+ " 2015-07-01 10:00:00\n" +
+ " 2015-07-01 10:00:00\n" +
+ " 2015-07-01 10:00:00\n" +
+ " 3\n" +
+ " \n" +
+ " 0\n" +
+ " \n" +
+ " \n" +
+ "";
+
+ // 启用 fastMode 以覆盖 WxSignQueryResult#loadXml 分支
+ XmlConfig.fastMode = true;
+ try {
+ WxSignQueryResult result = WxSignQueryResult.fromXML(xmlString, WxSignQueryResult.class);
+
+ // 验证基本字段
+ Assert.assertEquals(result.getReturnCode(), "SUCCESS");
+ Assert.assertEquals(result.getResultCode(), "SUCCESS");
+ Assert.assertEquals(result.getMchId(), "80000000");
+ Assert.assertEquals(result.getAppid(), "wx426b3015555b46be");
+
+ // 验证签约相关字段
+ Assert.assertEquals(result.getContractId(), "203");
+ Assert.assertEquals(result.getPlanId(), "66");
+ Assert.assertEquals(result.getOpenId(), "oHZx6uMbIG46UXQ3SKxVYEgw1LZs");
+ Assert.assertEquals(result.getRequestSerial().longValue(), 123L);
+ Assert.assertEquals(result.getContractCode(), "1005");
+ Assert.assertEquals(result.getContractDisplayAccount(), "test");
+ Assert.assertEquals(result.getContractState().intValue(), 1);
+
+ // 重点测试时间字段,特别是 contract_expired_time
+ Assert.assertEquals(result.getContractSignedTime(), "2015-07-01 10:00:00");
+ Assert.assertEquals(result.getContractExpiredTime(), "2015-07-01 10:00:00");
+ Assert.assertEquals(result.getContractTerminatedTime(), "2015-07-01 10:00:00");
+
+ // 验证其他字段
+ Assert.assertEquals(result.getContractTerminatedMode().intValue(), 3);
+ Assert.assertEquals(result.getContractTerminationRemark(), "delete ....");
+ } finally {
+ // 恢复默认值
+ XmlConfig.fastMode = false;
+ }
+ }
+
+ /**
+ * 测试 XML 解析 - 只包含必填字段
+ */
+ @Test
+ public void testFromXML_RequiredFieldsOnly() {
+ String xmlString = "\n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " Wx15463511252015071056489715\n" +
+ " 123\n" +
+ " 1695\n" +
+ " \n" +
+ " \n" +
+ " 0\n" +
+ " 2015-07-01 10:00:00\n" +
+ " 2016-07-01 10:00:00\n" +
+ " \n" +
+ " \n" +
+ "";
+
+ // 启用 fastMode 以覆盖 WxSignQueryResult#loadXml 分支
+ XmlConfig.fastMode = true;
+ try {
+ WxSignQueryResult result = WxSignQueryResult.fromXML(xmlString, WxSignQueryResult.class);
+
+ // 验证必填字段
+ Assert.assertEquals(result.getReturnCode(), "SUCCESS");
+ Assert.assertEquals(result.getResultCode(), "SUCCESS");
+ Assert.assertEquals(result.getContractId(), "Wx15463511252015071056489715");
+ Assert.assertEquals(result.getPlanId(), "123");
+ Assert.assertEquals(result.getContractState().intValue(), 0);
+
+ // 验证 contract_expired_time 字段能正确解析
+ Assert.assertEquals(result.getContractExpiredTime(), "2016-07-01 10:00:00");
+
+ // 验证非必填字段为 null
+ Assert.assertNull(result.getContractTerminatedTime());
+ Assert.assertNull(result.getContractTerminatedMode());
+ Assert.assertNull(result.getContractTerminationRemark());
+ } finally {
+ // 恢复默认值
+ XmlConfig.fastMode = false;
+ }
+ }
+}