|
|
@@ -2,11 +2,13 @@ package com.ruoyi.app.utils.omg;
|
|
|
|
|
|
import org.junit.jupiter.api.Test;
|
|
|
|
|
|
+import java.util.Comparator;
|
|
|
import java.util.LinkedHashMap;
|
|
|
import java.util.Map;
|
|
|
|
|
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
|
|
import static org.junit.jupiter.api.Assertions.assertFalse;
|
|
|
+import static org.junit.jupiter.api.Assertions.assertNotEquals;
|
|
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
|
|
|
|
|
class OmgCheckMacValueTest {
|
|
|
@@ -51,4 +53,53 @@ class OmgCheckMacValueTest {
|
|
|
params.put("CheckMacValue", "0".repeat(64));
|
|
|
assertFalse(OmgCheckMacValue.verify(params, "key", "iv"));
|
|
|
}
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 回归 bugB(2026-08-12):OMG QueryTradeInfo 响应字段大小写混合,服务端 CheckMacValue 按
|
|
|
+ * 大小写不敏感排序计算。旧实现用 Comparator.naturalOrder()(ASCII 大小写敏感)排序,混合字段下
|
|
|
+ * 与 OMG 分歧 → 验签失败(生产订单 991786433092835 实测 receivedCMV==ci_inc 坐实)。
|
|
|
+ *
|
|
|
+ * <p>本用例构造同形响应(首字母大写的 AlipayID/CustomField1/MerchantID 与首字母小写的
|
|
|
+ * amount/auth_code/card4no/eci/gwsr/process_date/red_dan 并存),先用「大小写不敏感」生成 OMG 侧
|
|
|
+ * 签名,再断言 verify() 通过。修复前 verify 走 naturalOrder 会算出不同签名而失败。
|
|
|
+ */
|
|
|
+ @Test
|
|
|
+ void verifiesQueryTradeInfoResponseWithCaseInsensitiveKeyOrder() {
|
|
|
+ Map<String, String> resp = new LinkedHashMap<>();
|
|
|
+ resp.put("MerchantID", "1000031");
|
|
|
+ resp.put("MerchantTradeNo", "OMG10C9AA21B1814EE29");
|
|
|
+ resp.put("TradeAmt", "97");
|
|
|
+ resp.put("TradeDate", "2026/08/11 17:06:42");
|
|
|
+ resp.put("TradeNo", "2608111706428239");
|
|
|
+ resp.put("TradeStatus", "10200095");
|
|
|
+ resp.put("ItemName", "order 991786433092835");
|
|
|
+ resp.put("HandlingCharge", "0");
|
|
|
+ resp.put("PaymentTypeChargeFee", "0");
|
|
|
+ // §2 额外回传(空值),首字母大小写混合 —— 触发排序分歧的关键
|
|
|
+ resp.put("AlipayID", "");
|
|
|
+ resp.put("CustomField1", "");
|
|
|
+ resp.put("amount", "");
|
|
|
+ resp.put("auth_code", "");
|
|
|
+ resp.put("card4no", "");
|
|
|
+ resp.put("eci", "");
|
|
|
+ resp.put("gwsr", "");
|
|
|
+ resp.put("process_date", "");
|
|
|
+ resp.put("red_dan", "");
|
|
|
+
|
|
|
+ String key = "5294y06JbISpM5x9";
|
|
|
+ String iv = "v77hoKGq4kWxNNIS";
|
|
|
+
|
|
|
+ // OMG 侧签名:大小写不敏感排序,保留空值字段
|
|
|
+ String omgCmv = OmgCheckMacValue.generate(resp, key, iv,
|
|
|
+ String.CASE_INSENSITIVE_ORDER, false);
|
|
|
+ // 前置断言:本字段集必须使两种排序产生不同签名,否则用例无法锁定该 bug
|
|
|
+ String sensitiveCmv = OmgCheckMacValue.generate(resp, key, iv,
|
|
|
+ Comparator.naturalOrder(), false);
|
|
|
+ assertNotEquals(sensitiveCmv, omgCmv,
|
|
|
+ "测试字段集必须使大小写敏感/不敏感排序产生不同签名,否则用例无效");
|
|
|
+
|
|
|
+ resp.put("CheckMacValue", omgCmv);
|
|
|
+ assertTrue(OmgCheckMacValue.verify(resp, key, iv),
|
|
|
+ "verify 必须按大小写不敏感排序以匹配 OMG 服务端算法");
|
|
|
+ }
|
|
|
}
|