Skip to content

Commit 04d8641

Browse files
Copilotbinarywang
andcommitted
实现支持一个商户号对应多个appId的功能
Co-authored-by: binarywang <1343140+binarywang@users.noreply.github.com>
1 parent da05ed3 commit 04d8641

File tree

4 files changed

+399
-0
lines changed

4 files changed

+399
-0
lines changed

weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/WxPayService.java

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,15 @@ public interface WxPayService {
7878
*/
7979
boolean switchover(String mchId, String appId);
8080

81+
/**
82+
* 仅根据商户号进行切换.
83+
* 适用于一个商户号对应多个appId的场景,切换时会匹配第一个符合该商户号的配置.
84+
*
85+
* @param mchId 商户标识
86+
* @return 切换是否成功 boolean
87+
*/
88+
boolean switchover(String mchId);
89+
8190
/**
8291
* 进行相应的商户切换.
8392
*
@@ -87,6 +96,15 @@ public interface WxPayService {
8796
*/
8897
WxPayService switchoverTo(String mchId, String appId);
8998

99+
/**
100+
* 仅根据商户号进行切换.
101+
* 适用于一个商户号对应多个appId的场景,切换时会匹配第一个符合该商户号的配置.
102+
*
103+
* @param mchId 商户标识
104+
* @return 切换成功 ,则返回当前对象,方便链式调用,否则抛出异常
105+
*/
106+
WxPayService switchoverTo(String mchId);
107+
90108
/**
91109
* 发送post请求,得到响应字节数组.
92110
*

weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/BaseWxPayServiceImpl.java

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,28 @@ public boolean switchover(String mchId, String appId) {
212212
return false;
213213
}
214214

215+
@Override
216+
public boolean switchover(String mchId) {
217+
// 先尝试精确匹配(针对只有mchId没有appId的配置)
218+
if (this.configMap.containsKey(mchId)) {
219+
WxPayConfigHolder.set(mchId);
220+
return true;
221+
}
222+
223+
// 尝试前缀匹配(查找以 mchId_ 开头的配置)
224+
String prefix = mchId + "_";
225+
for (String key : this.configMap.keySet()) {
226+
if (key.startsWith(prefix)) {
227+
WxPayConfigHolder.set(key);
228+
log.debug("根据mchId=【{}】找到配置key=【{}】", mchId, key);
229+
return true;
230+
}
231+
}
232+
233+
log.error("无法找到对应mchId=【{}】的商户号配置信息,请核实!", mchId);
234+
return false;
235+
}
236+
215237
@Override
216238
public WxPayService switchoverTo(String mchId, String appId) {
217239
String configKey = this.getConfigKey(mchId, appId);
@@ -222,6 +244,27 @@ public WxPayService switchoverTo(String mchId, String appId) {
222244
throw new WxRuntimeException(String.format("无法找到对应mchId=【%s】,appId=【%s】的商户号配置信息,请核实!", mchId, appId));
223245
}
224246

247+
@Override
248+
public WxPayService switchoverTo(String mchId) {
249+
// 先尝试精确匹配(针对只有mchId没有appId的配置)
250+
if (this.configMap.containsKey(mchId)) {
251+
WxPayConfigHolder.set(mchId);
252+
return this;
253+
}
254+
255+
// 尝试前缀匹配(查找以 mchId_ 开头的配置)
256+
String prefix = mchId + "_";
257+
for (String key : this.configMap.keySet()) {
258+
if (key.startsWith(prefix)) {
259+
WxPayConfigHolder.set(key);
260+
log.debug("根据mchId=【{}】找到配置key=【{}】", mchId, key);
261+
return this;
262+
}
263+
}
264+
265+
throw new WxRuntimeException(String.format("无法找到对应mchId=【%s】的商户号配置信息,请核实!", mchId));
266+
}
267+
225268
public String getConfigKey(String mchId, String appId) {
226269
return mchId + "_" + appId;
227270
}
Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
package com.github.binarywang.wxpay.service.impl;
2+
3+
import com.github.binarywang.wxpay.config.WxPayConfig;
4+
import com.github.binarywang.wxpay.service.WxPayService;
5+
6+
import java.util.HashMap;
7+
import java.util.Map;
8+
9+
/**
10+
* 手动验证多appId切换功能
11+
*/
12+
public class MultiAppIdSwitchoverManualTest {
13+
14+
public static void main(String[] args) {
15+
WxPayService payService = new WxPayServiceImpl();
16+
17+
String testMchId = "1234567890";
18+
String testAppId1 = "wx1111111111111111";
19+
String testAppId2 = "wx2222222222222222";
20+
String testAppId3 = "wx3333333333333333";
21+
22+
// 配置同一个商户号,三个不同的appId
23+
WxPayConfig config1 = new WxPayConfig();
24+
config1.setMchId(testMchId);
25+
config1.setAppId(testAppId1);
26+
config1.setMchKey("test_key_1");
27+
28+
WxPayConfig config2 = new WxPayConfig();
29+
config2.setMchId(testMchId);
30+
config2.setAppId(testAppId2);
31+
config2.setMchKey("test_key_2");
32+
33+
WxPayConfig config3 = new WxPayConfig();
34+
config3.setMchId(testMchId);
35+
config3.setAppId(testAppId3);
36+
config3.setMchKey("test_key_3");
37+
38+
Map<String, WxPayConfig> configMap = new HashMap<>();
39+
configMap.put(testMchId + "_" + testAppId1, config1);
40+
configMap.put(testMchId + "_" + testAppId2, config2);
41+
configMap.put(testMchId + "_" + testAppId3, config3);
42+
43+
payService.setMultiConfig(configMap);
44+
45+
// 测试1: 使用 mchId + appId 精确切换
46+
System.out.println("=== 测试1: 使用 mchId + appId 精确切换 ===");
47+
boolean success = payService.switchover(testMchId, testAppId1);
48+
System.out.println("切换结果: " + success);
49+
System.out.println("当前配置 - MchId: " + payService.getConfig().getMchId() + ", AppId: " + payService.getConfig().getAppId() + ", MchKey: " + payService.getConfig().getMchKey());
50+
assert success : "切换应该成功";
51+
assert testAppId1.equals(payService.getConfig().getAppId()) : "AppId应该是 " + testAppId1;
52+
System.out.println("✓ 测试1通过\n");
53+
54+
// 测试2: 仅使用 mchId 切换
55+
System.out.println("=== 测试2: 仅使用 mchId 切换 ===");
56+
success = payService.switchover(testMchId);
57+
System.out.println("切换结果: " + success);
58+
System.out.println("当前配置 - MchId: " + payService.getConfig().getMchId() + ", AppId: " + payService.getConfig().getAppId() + ", MchKey: " + payService.getConfig().getMchKey());
59+
assert success : "仅使用mchId切换应该成功";
60+
assert testMchId.equals(payService.getConfig().getMchId()) : "MchId应该是 " + testMchId;
61+
System.out.println("✓ 测试2通过\n");
62+
63+
// 测试3: 使用 switchoverTo 链式调用(精确匹配)
64+
System.out.println("=== 测试3: 使用 switchoverTo 链式调用(精确匹配) ===");
65+
WxPayService result = payService.switchoverTo(testMchId, testAppId2);
66+
System.out.println("返回对象: " + (result == payService ? "同一实例" : "不同实例"));
67+
System.out.println("当前配置 - MchId: " + payService.getConfig().getMchId() + ", AppId: " + payService.getConfig().getAppId() + ", MchKey: " + payService.getConfig().getMchKey());
68+
assert result == payService : "应该返回同一实例";
69+
assert testAppId2.equals(payService.getConfig().getAppId()) : "AppId应该是 " + testAppId2;
70+
System.out.println("✓ 测试3通过\n");
71+
72+
// 测试4: 使用 switchoverTo 链式调用(仅mchId)
73+
System.out.println("=== 测试4: 使用 switchoverTo 链式调用(仅mchId) ===");
74+
result = payService.switchoverTo(testMchId);
75+
System.out.println("返回对象: " + (result == payService ? "同一实例" : "不同实例"));
76+
System.out.println("当前配置 - MchId: " + payService.getConfig().getMchId() + ", AppId: " + payService.getConfig().getAppId() + ", MchKey: " + payService.getConfig().getMchKey());
77+
assert result == payService : "应该返回同一实例";
78+
assert testMchId.equals(payService.getConfig().getMchId()) : "MchId应该是 " + testMchId;
79+
System.out.println("✓ 测试4通过\n");
80+
81+
// 测试5: 切换到不存在的商户号
82+
System.out.println("=== 测试5: 切换到不存在的商户号 ===");
83+
success = payService.switchover("nonexistent_mch_id");
84+
System.out.println("切换结果: " + success);
85+
assert !success : "切换到不存在的商户号应该失败";
86+
System.out.println("✓ 测试5通过\n");
87+
88+
// 测试6: 切换到不存在的 appId
89+
System.out.println("=== 测试6: 切换到不存在的 appId ===");
90+
success = payService.switchover(testMchId, "wx9999999999999999");
91+
System.out.println("切换结果: " + success);
92+
assert !success : "切换到不存在的appId应该失败";
93+
System.out.println("✓ 测试6通过\n");
94+
95+
// 测试7: 添加新配置后切换
96+
System.out.println("=== 测试7: 添加新配置后切换 ===");
97+
String newAppId = "wx4444444444444444";
98+
WxPayConfig newConfig = new WxPayConfig();
99+
newConfig.setMchId(testMchId);
100+
newConfig.setAppId(newAppId);
101+
newConfig.setMchKey("test_key_4");
102+
payService.addConfig(testMchId, newAppId, newConfig);
103+
104+
success = payService.switchover(testMchId, newAppId);
105+
System.out.println("切换结果: " + success);
106+
System.out.println("当前配置 - MchId: " + payService.getConfig().getMchId() + ", AppId: " + payService.getConfig().getAppId() + ", MchKey: " + payService.getConfig().getMchKey());
107+
assert success : "切换到新添加的配置应该成功";
108+
assert newAppId.equals(payService.getConfig().getAppId()) : "AppId应该是 " + newAppId;
109+
System.out.println("✓ 测试7通过\n");
110+
111+
System.out.println("==================");
112+
System.out.println("所有测试通过! ✓");
113+
System.out.println("==================");
114+
}
115+
}

0 commit comments

Comments
 (0)