Skip to content

Commit 488706b

Browse files
authored
🎨 #2040 【微信支付】增加多商户切换的支持
1 parent eb46a10 commit 488706b

File tree

3 files changed

+153
-3
lines changed

3 files changed

+153
-3
lines changed
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
package com.github.binarywang.wxpay.config;
2+
3+
/**
4+
* 微信支付配置策略.
5+
*
6+
* @author zenghao
7+
* @date 2021/3/12
8+
*/
9+
public class WxPayConfigHolder {
10+
11+
private static final ThreadLocal<String> THREAD_LOCAL = ThreadLocal.withInitial(() -> "default");
12+
13+
/**
14+
* 获取当前微信支付配置策略.
15+
* @return 当前微信支付配置策略
16+
*/
17+
public static String get() {
18+
return THREAD_LOCAL.get();
19+
}
20+
21+
/**
22+
* 设置当前微信支付配置策略.
23+
* @param label 策略名称
24+
*/
25+
public static void set(final String label) {
26+
THREAD_LOCAL.set(label);
27+
}
28+
29+
/**
30+
* 此方法需要用户根据自己程序代码,在适当位置手动触发调用,本SDK里无法判断调用时机.
31+
*/
32+
public static void remove() {
33+
THREAD_LOCAL.remove();
34+
}
35+
}

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

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,53 @@ public interface WxPayService {
3535
*/
3636
String getPayBaseUrl();
3737

38+
/**
39+
* Map里 加入新的 {@link WxPayConfig},适用于动态添加新的微信公众号配置.
40+
*
41+
* @param mchId 商户号id
42+
* @param wxPayConfig 新的微信配置
43+
*/
44+
void addConfig(String mchId, WxPayConfig wxPayConfig);
45+
46+
/**
47+
* 从 Map中 移除 {@link String mchId} 所对应的 {@link WxPayConfig},适用于动态移除微信公众号配置.
48+
*
49+
* @param mchId 对应公众号的标识
50+
*/
51+
void removeConfig(String mchId);
52+
53+
/**
54+
* 注入多个 {@link WxPayConfig} 的实现. 并为每个 {@link WxPayConfig} 赋予不同的 {@link String mchId} 值
55+
* 随机采用一个{@link String mchId}进行Http初始化操作
56+
*
57+
* @param wxPayConfigs WxPayConfig map
58+
*/
59+
void setMultiConfig(Map<String, WxPayConfig> wxPayConfigs);
60+
61+
/**
62+
* 注入多个 {@link WxPayConfig} 的实现. 并为每个 {@link WxPayConfig} 赋予不同的 {@link String label} 值
63+
*
64+
* @param wxPayConfigs WxPayConfig map
65+
* @param defaultMchId 设置一个{@link WxPayConfig} 所对应的{@link String mchId}进行Http初始化
66+
*/
67+
void setMultiConfig(Map<String, WxPayConfig> wxPayConfigs, String defaultMchId);
68+
69+
/**
70+
* 进行相应的公众号切换.
71+
*
72+
* @param mchId 公众号标识
73+
* @return 切换是否成功 boolean
74+
*/
75+
boolean switchover(String mchId);
76+
77+
/**
78+
* 进行相应的公众号切换.
79+
*
80+
* @param mchId 公众号标识
81+
* @return 切换成功 ,则返回当前对象,方便链式调用,否则抛出异常
82+
*/
83+
WxPayService switchoverTo(String mchId);
84+
3885
/**
3986
* 发送post请求,得到响应字节数组.
4087
*

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

Lines changed: 71 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
import com.github.binarywang.wxpay.bean.request.*;
1414
import com.github.binarywang.wxpay.bean.result.*;
1515
import com.github.binarywang.wxpay.config.WxPayConfig;
16+
import com.github.binarywang.wxpay.config.WxPayConfigHolder;
1617
import com.github.binarywang.wxpay.constant.WxPayConstants;
1718
import com.github.binarywang.wxpay.constant.WxPayConstants.SignType;
1819
import com.github.binarywang.wxpay.constant.WxPayConstants.TradeType;
@@ -21,6 +22,7 @@
2122
import com.github.binarywang.wxpay.util.SignUtils;
2223
import com.github.binarywang.wxpay.util.XmlConfig;
2324
import com.google.common.base.Joiner;
25+
import com.google.common.collect.ImmutableMap;
2426
import com.google.common.collect.Maps;
2527
import jodd.io.ZipUtil;
2628
import me.chanjar.weixin.common.error.WxRuntimeException;
@@ -65,7 +67,7 @@ public abstract class BaseWxPayServiceImpl implements WxPayService {
6567
private final MarketingMediaService marketingMediaService = new MarketingMediaServiceImpl(this);
6668
private final MarketingFavorService marketingFavorService = new MarketingFavorServiceImpl(this);
6769

68-
protected WxPayConfig config;
70+
protected Map<String, WxPayConfig> configMap;
6971

7072
@Override
7173
public EntPayService getEntPayService() {
@@ -119,12 +121,78 @@ public void setEntPayService(EntPayService entPayService) {
119121

120122
@Override
121123
public WxPayConfig getConfig() {
122-
return this.config;
124+
if (this.configMap.size() == 1) {
125+
// 只有一个商户号,直接返回其配置即可
126+
return this.configMap.values().iterator().next();
127+
}
128+
return this.configMap.get(WxPayConfigHolder.get());
123129
}
124130

125131
@Override
126132
public void setConfig(WxPayConfig config) {
127-
this.config = config;
133+
final String defaultMchId = config.getMchId();
134+
this.setMultiConfig(ImmutableMap.of(defaultMchId, config), defaultMchId);
135+
}
136+
137+
@Override
138+
public void addConfig(String mchId, WxPayConfig wxPayConfig) {
139+
synchronized (this) {
140+
if (this.configMap == null) {
141+
this.setConfig(wxPayConfig);
142+
} else {
143+
WxPayConfigHolder.set(mchId);
144+
this.configMap.put(mchId, wxPayConfig);
145+
}
146+
}
147+
}
148+
149+
@Override
150+
public void removeConfig(String mchId) {
151+
synchronized (this) {
152+
if (this.configMap.size() == 1) {
153+
this.configMap.remove(mchId);
154+
log.warn("已删除最后一个商户号配置:{},须立即使用setConfig或setMultiConfig添加配置", mchId);
155+
return;
156+
}
157+
if (WxPayConfigHolder.get().equals(mchId)) {
158+
this.configMap.remove(mchId);
159+
final String defaultMpId = this.configMap.keySet().iterator().next();
160+
WxPayConfigHolder.set(defaultMpId);
161+
log.warn("已删除默认商户号配置,商户号【{}】被设为默认配置", defaultMpId);
162+
return;
163+
}
164+
this.configMap.remove(mchId);
165+
}
166+
}
167+
168+
@Override
169+
public void setMultiConfig(Map<String, WxPayConfig> wxPayConfigs) {
170+
this.setMultiConfig(wxPayConfigs, wxPayConfigs.keySet().iterator().next());
171+
}
172+
173+
@Override
174+
public void setMultiConfig(Map<String, WxPayConfig> wxPayConfigs, String defaultMchId) {
175+
this.configMap = Maps.newHashMap(wxPayConfigs);
176+
WxPayConfigHolder.set(defaultMchId);
177+
}
178+
179+
@Override
180+
public boolean switchover(String mchId) {
181+
if (this.configMap.containsKey(mchId)) {
182+
WxPayConfigHolder.set(mchId);
183+
return true;
184+
}
185+
log.error("无法找到对应【{}】的商户号配置信息,请核实!", mchId);
186+
return false;
187+
}
188+
189+
@Override
190+
public WxPayService switchoverTo(String mchId) {
191+
if (this.configMap.containsKey(mchId)) {
192+
WxPayConfigHolder.set(mchId);
193+
return this;
194+
}
195+
throw new WxRuntimeException(String.format("无法找到对应【%s】的商户号配置信息,请核实!", mchId));
128196
}
129197

130198
@Override

0 commit comments

Comments
 (0)