🎨 #3694 统一各模块微信接口请求的基础地址字段命名为apiHostUrl,并完善Spring Boot starter配置支持

This commit is contained in:
水依寒
2025-09-04 09:17:36 +08:00
committed by GitHub
parent 1eefd11e03
commit 8447caa75f
20 changed files with 175 additions and 28 deletions

View File

@ -119,6 +119,8 @@ public abstract class AbstractWxChannelConfiguration {
config.setAesKey(aesKey); config.setAesKey(aesKey);
} }
config.setStableAccessToken(useStableAccessToken); config.setStableAccessToken(useStableAccessToken);
config.setApiHostUrl(StringUtils.trimToNull(wxChannelSingleProperties.getApiHostUrl()));
config.setAccessTokenUrl(StringUtils.trimToNull(wxChannelSingleProperties.getAccessTokenUrl()));
} }
private void configHttp(WxChannelDefaultConfigImpl config, WxChannelMultiProperties.ConfigStorage storage) { private void configHttp(WxChannelDefaultConfigImpl config, WxChannelMultiProperties.ConfigStorage storage) {

View File

@ -40,4 +40,16 @@ public class WxChannelSingleProperties implements Serializable {
* 是否使用稳定版 Access Token * 是否使用稳定版 Access Token
*/ */
private boolean useStableAccessToken = false; private boolean useStableAccessToken = false;
/**
* 自定义API主机地址用于替换默认的 https://api.weixin.qq.com
* 例如http://proxy.company.com:8080
*/
private String apiHostUrl;
/**
* 自定义获取AccessToken地址用于向自定义统一服务获取AccessToken
* 例如http://proxy.company.com:8080/oauth/token
*/
private String accessTokenUrl;
} }

View File

@ -16,6 +16,8 @@ public abstract class AbstractWxChannelConfigStorageConfiguration {
config.setAesKey(StringUtils.trimToNull(properties.getAesKey())); config.setAesKey(StringUtils.trimToNull(properties.getAesKey()));
config.setMsgDataFormat(StringUtils.trimToNull(properties.getMsgDataFormat())); config.setMsgDataFormat(StringUtils.trimToNull(properties.getMsgDataFormat()));
config.setStableAccessToken(properties.isUseStableAccessToken()); config.setStableAccessToken(properties.isUseStableAccessToken());
config.setApiHostUrl(StringUtils.trimToNull(properties.getApiHostUrl()));
config.setAccessTokenUrl(StringUtils.trimToNull(properties.getAccessTokenUrl()));
WxChannelProperties.ConfigStorage configStorageProperties = properties.getConfigStorage(); WxChannelProperties.ConfigStorage configStorageProperties = properties.getConfigStorage();
config.setHttpProxyHost(configStorageProperties.getHttpProxyHost()); config.setHttpProxyHost(configStorageProperties.getHttpProxyHost());

View File

@ -46,6 +46,18 @@ public class WxChannelProperties {
*/ */
private boolean useStableAccessToken = false; private boolean useStableAccessToken = false;
/**
* 自定义API主机地址用于替换默认的 https://api.weixin.qq.com
* 例如http://proxy.company.com:8080
*/
private String apiHostUrl;
/**
* 自定义获取AccessToken地址用于向自定义统一服务获取AccessToken
* 例如http://proxy.company.com:8080/oauth/token
*/
private String accessTokenUrl;
/** /**
* 存储策略 * 存储策略
*/ */

View File

@ -139,6 +139,9 @@ public abstract class AbstractWxCpConfiguration {
if (StringUtils.isNotBlank(msgAuditLibPath)) { if (StringUtils.isNotBlank(msgAuditLibPath)) {
config.setMsgAuditLibPath(msgAuditLibPath); config.setMsgAuditLibPath(msgAuditLibPath);
} }
if (StringUtils.isNotBlank(wxCpSingleProperties.getBaseApiUrl())) {
config.setBaseApiUrl(wxCpSingleProperties.getBaseApiUrl());
}
} }
private void configHttp(WxCpDefaultConfigImpl config, WxCpMultiProperties.ConfigStorage storage) { private void configHttp(WxCpDefaultConfigImpl config, WxCpMultiProperties.ConfigStorage storage) {

View File

@ -43,4 +43,10 @@ public class WxCpSingleProperties implements Serializable {
* 微信企业号应用 会话存档类库路径 * 微信企业号应用 会话存档类库路径
*/ */
private String msgAuditLibPath; private String msgAuditLibPath;
/**
* 自定义企业微信服务器baseUrl用于替换默认的 https://qyapi.weixin.qq.com
* 例如http://proxy.company.com:8080
*/
private String baseApiUrl;
} }

View File

@ -48,6 +48,12 @@ public class WxCpProperties {
*/ */
private String msgAuditLibPath; private String msgAuditLibPath;
/**
* 自定义企业微信服务器baseUrl用于替换默认的 https://qyapi.weixin.qq.com
* 例如http://proxy.company.com:8080
*/
private String baseApiUrl;
/** /**
* 配置存储策略,默认内存 * 配置存储策略,默认内存
*/ */

View File

@ -37,6 +37,9 @@ public abstract class AbstractWxCpConfigStorageConfiguration {
if (StringUtils.isNotBlank(msgAuditLibPath)) { if (StringUtils.isNotBlank(msgAuditLibPath)) {
config.setMsgAuditLibPath(msgAuditLibPath); config.setMsgAuditLibPath(msgAuditLibPath);
} }
if (StringUtils.isNotBlank(properties.getBaseApiUrl())) {
config.setBaseApiUrl(properties.getBaseApiUrl());
}
WxCpProperties.ConfigStorage storage = properties.getConfigStorage(); WxCpProperties.ConfigStorage storage = properties.getConfigStorage();
String httpProxyHost = storage.getHttpProxyHost(); String httpProxyHost = storage.getHttpProxyHost();

View File

@ -125,6 +125,8 @@ public abstract class AbstractWxMaConfiguration {
} }
config.setMsgDataFormat(properties.getMsgDataFormat()); config.setMsgDataFormat(properties.getMsgDataFormat());
config.useStableAccessToken(useStableAccessToken); config.useStableAccessToken(useStableAccessToken);
config.setApiHostUrl(StringUtils.trimToNull(properties.getApiHostUrl()));
config.setAccessTokenUrl(StringUtils.trimToNull(properties.getAccessTokenUrl()));
} }
private void configHttp(WxMaDefaultConfigImpl config, WxMaMultiProperties.ConfigStorage storage) { private void configHttp(WxMaDefaultConfigImpl config, WxMaMultiProperties.ConfigStorage storage) {

View File

@ -42,4 +42,16 @@ public class WxMaSingleProperties implements Serializable {
* 是否使用稳定版 Access Token * 是否使用稳定版 Access Token
*/ */
private boolean useStableAccessToken = false; private boolean useStableAccessToken = false;
/**
* 自定义API主机地址用于替换默认的 https://api.weixin.qq.com
* 例如http://proxy.company.com:8080
*/
private String apiHostUrl;
/**
* 自定义获取AccessToken地址用于向自定义统一服务获取AccessToken
* 例如http://proxy.company.com:8080/oauth/token
*/
private String accessTokenUrl;
} }

View File

@ -19,6 +19,8 @@ public abstract class AbstractWxMaConfigStorageConfiguration {
config.setAesKey(StringUtils.trimToNull(properties.getAesKey())); config.setAesKey(StringUtils.trimToNull(properties.getAesKey()));
config.setMsgDataFormat(StringUtils.trimToNull(properties.getMsgDataFormat())); config.setMsgDataFormat(StringUtils.trimToNull(properties.getMsgDataFormat()));
config.useStableAccessToken(properties.isUseStableAccessToken()); config.useStableAccessToken(properties.isUseStableAccessToken());
config.setApiHostUrl(StringUtils.trimToNull(properties.getApiHostUrl()));
config.setAccessTokenUrl(StringUtils.trimToNull(properties.getAccessTokenUrl()));
WxMaProperties.ConfigStorage configStorageProperties = properties.getConfigStorage(); WxMaProperties.ConfigStorage configStorageProperties = properties.getConfigStorage();
config.setHttpProxyHost(configStorageProperties.getHttpProxyHost()); config.setHttpProxyHost(configStorageProperties.getHttpProxyHost());

View File

@ -49,6 +49,18 @@ public class WxMaProperties {
*/ */
private boolean useStableAccessToken = false; private boolean useStableAccessToken = false;
/**
* 自定义API主机地址用于替换默认的 https://api.weixin.qq.com
* 例如http://proxy.company.com:8080
*/
private String apiHostUrl;
/**
* 自定义获取AccessToken地址用于向自定义统一服务获取AccessToken
* 例如http://proxy.company.com:8080/oauth/token
*/
private String accessTokenUrl;
/** /**
* 存储策略 * 存储策略
*/ */

View File

@ -4,6 +4,7 @@ import com.binarywang.spring.starter.wxjava.open.properties.WxOpenProperties;
import me.chanjar.weixin.common.util.http.apache.ApacheHttpClientBuilder; import me.chanjar.weixin.common.util.http.apache.ApacheHttpClientBuilder;
import me.chanjar.weixin.common.util.http.apache.DefaultApacheHttpClientBuilder; import me.chanjar.weixin.common.util.http.apache.DefaultApacheHttpClientBuilder;
import me.chanjar.weixin.open.api.impl.WxOpenInMemoryConfigStorage; import me.chanjar.weixin.open.api.impl.WxOpenInMemoryConfigStorage;
import org.apache.commons.lang3.StringUtils;
/** /**
* @author yl * @author yl
@ -31,6 +32,10 @@ public abstract class AbstractWxOpenConfigStorageConfiguration {
config.setRetrySleepMillis(retrySleepMillis); config.setRetrySleepMillis(retrySleepMillis);
config.setMaxRetryTimes(maxRetryTimes); config.setMaxRetryTimes(maxRetryTimes);
// 设置URL配置
config.setApiHostUrl(StringUtils.trimToNull(properties.getApiHostUrl()));
config.setAccessTokenUrl(StringUtils.trimToNull(properties.getAccessTokenUrl()));
// 设置自定义的HttpClient超时配置 // 设置自定义的HttpClient超时配置
ApacheHttpClientBuilder clientBuilder = config.getApacheHttpClientBuilder(); ApacheHttpClientBuilder clientBuilder = config.getApacheHttpClientBuilder();
if (clientBuilder == null) { if (clientBuilder == null) {

View File

@ -40,6 +40,18 @@ public class WxOpenProperties {
*/ */
private String aesKey; private String aesKey;
/**
* 自定义API主机地址用于替换默认的 https://api.weixin.qq.com
* 例如http://proxy.company.com:8080
*/
private String apiHostUrl;
/**
* 自定义获取AccessToken地址用于向自定义统一服务获取AccessToken
* 例如http://proxy.company.com:8080/oauth/token
*/
private String accessTokenUrl;
/** /**
* 存储策略. * 存储策略.
*/ */

View File

@ -50,15 +50,18 @@ public class WxPayAutoConfiguration {
payConfig.setSubMchId(StringUtils.trimToNull(this.properties.getSubMchId())); payConfig.setSubMchId(StringUtils.trimToNull(this.properties.getSubMchId()));
payConfig.setKeyPath(StringUtils.trimToNull(this.properties.getKeyPath())); payConfig.setKeyPath(StringUtils.trimToNull(this.properties.getKeyPath()));
payConfig.setUseSandboxEnv(this.properties.isUseSandboxEnv()); payConfig.setUseSandboxEnv(this.properties.isUseSandboxEnv());
payConfig.setNotifyUrl(StringUtils.trimToNull(this.properties.getNotifyUrl()));
//以下是apiv3以及支付分相关 //以下是apiv3以及支付分相关
payConfig.setServiceId(StringUtils.trimToNull(this.properties.getServiceId())); payConfig.setServiceId(StringUtils.trimToNull(this.properties.getServiceId()));
payConfig.setPayScoreNotifyUrl(StringUtils.trimToNull(this.properties.getPayScoreNotifyUrl())); payConfig.setPayScoreNotifyUrl(StringUtils.trimToNull(this.properties.getPayScoreNotifyUrl()));
payConfig.setPayScorePermissionNotifyUrl(StringUtils.trimToNull(this.properties.getPayScorePermissionNotifyUrl()));
payConfig.setPrivateKeyPath(StringUtils.trimToNull(this.properties.getPrivateKeyPath())); payConfig.setPrivateKeyPath(StringUtils.trimToNull(this.properties.getPrivateKeyPath()));
payConfig.setPrivateCertPath(StringUtils.trimToNull(this.properties.getPrivateCertPath())); payConfig.setPrivateCertPath(StringUtils.trimToNull(this.properties.getPrivateCertPath()));
payConfig.setCertSerialNo(StringUtils.trimToNull(this.properties.getCertSerialNo())); payConfig.setCertSerialNo(StringUtils.trimToNull(this.properties.getCertSerialNo()));
payConfig.setApiV3Key(StringUtils.trimToNull(this.properties.getApiv3Key())); payConfig.setApiV3Key(StringUtils.trimToNull(this.properties.getApiv3Key()));
payConfig.setPublicKeyId(StringUtils.trimToNull(this.properties.getPublicKeyId())); payConfig.setPublicKeyId(StringUtils.trimToNull(this.properties.getPublicKeyId()));
payConfig.setPublicKeyPath(StringUtils.trimToNull(this.properties.getPublicKeyPath())); payConfig.setPublicKeyPath(StringUtils.trimToNull(this.properties.getPublicKeyPath()));
payConfig.setApiHostUrl(StringUtils.trimToNull(this.properties.getApiHostUrl()));
wxPayService.setConfig(payConfig); wxPayService.setConfig(payConfig);
return wxPayService; return wxPayService;

View File

@ -59,11 +59,21 @@ public class WxPayProperties {
*/ */
private String apiv3Key; private String apiv3Key;
/**
* 微信支付异步回调地址通知url必须为直接可访问的url不能携带参数
*/
private String notifyUrl;
/** /**
* 微信支付分回调地址 * 微信支付分回调地址
*/ */
private String payScoreNotifyUrl; private String payScoreNotifyUrl;
/**
* 微信支付分授权回调地址
*/
private String payScorePermissionNotifyUrl;
/** /**
* apiv3 商户apiclient_key.pem * apiv3 商户apiclient_key.pem
*/ */
@ -90,4 +100,10 @@ public class WxPayProperties {
*/ */
private boolean useSandboxEnv; private boolean useSandboxEnv;
/**
* 自定义API主机地址用于替换默认的 https://api.mch.weixin.qq.com
* 例如http://proxy.company.com:8080
*/
private String apiHostUrl;
} }

View File

@ -65,6 +65,16 @@ public class WxOpenInMemoryConfigStorage implements WxOpenConfigStorage {
*/ */
private int maxRetryTimes = 5; private int maxRetryTimes = 5;
/**
* 自定义API主机地址用于替换默认的 https://api.weixin.qq.com
*/
private String apiHostUrl;
/**
* 自定义获取AccessToken地址用于向自定义统一服务获取AccessToken
*/
private String accessTokenUrl;
private ApacheHttpClientBuilder apacheHttpClientBuilder; private ApacheHttpClientBuilder apacheHttpClientBuilder;
private Map<String, Token> authorizerRefreshTokens = new ConcurrentHashMap<>(); private Map<String, Token> authorizerRefreshTokens = new ConcurrentHashMap<>();
@ -290,6 +300,13 @@ public class WxOpenInMemoryConfigStorage implements WxOpenConfigStorage {
this.accessTokenLock = wxOpenConfigStorage.getLockByKey(appId + ":accessTokenLock"); this.accessTokenLock = wxOpenConfigStorage.getLockByKey(appId + ":accessTokenLock");
this.jsapiTicketLock = wxOpenConfigStorage.getLockByKey(appId + ":jsapiTicketLock"); this.jsapiTicketLock = wxOpenConfigStorage.getLockByKey(appId + ":jsapiTicketLock");
this.cardApiTicketLock = wxOpenConfigStorage.getLockByKey(appId + ":cardApiTicketLock"); this.cardApiTicketLock = wxOpenConfigStorage.getLockByKey(appId + ":cardApiTicketLock");
// 自动获取外层配置的URL设置
if (wxOpenConfigStorage instanceof WxOpenInMemoryConfigStorage) {
WxOpenInMemoryConfigStorage parentConfig = (WxOpenInMemoryConfigStorage) wxOpenConfigStorage;
this.apiHostUrl = parentConfig.getApiHostUrl();
this.accessTokenUrl = parentConfig.getAccessTokenUrl();
}
} }
@Override @Override
@ -637,5 +654,25 @@ public class WxOpenInMemoryConfigStorage implements WxOpenConfigStorage {
public void setHostConfig(WxMpHostConfig hostConfig) { public void setHostConfig(WxMpHostConfig hostConfig) {
this.hostConfig = hostConfig; this.hostConfig = hostConfig;
} }
@Override
public String getApiHostUrl() {
return this.apiHostUrl;
}
@Override
public void setApiHostUrl(String apiHostUrl) {
this.apiHostUrl = apiHostUrl;
}
@Override
public String getAccessTokenUrl() {
return this.accessTokenUrl;
}
@Override
public void setAccessTokenUrl(String accessTokenUrl) {
this.accessTokenUrl = accessTokenUrl;
}
} }
} }

View File

@ -54,7 +54,7 @@ public class WxPayConfig {
/** /**
* 微信支付接口请求地址域名部分. * 微信支付接口请求地址域名部分.
*/ */
private String payBaseUrl = DEFAULT_PAY_BASE_URL; private String apiHostUrl = DEFAULT_PAY_BASE_URL;
/** /**
* http请求连接超时时间. * http请求连接超时时间.
@ -272,12 +272,12 @@ public class WxPayConfig {
* *
* @return 微信支付接口请求地址域名 * @return 微信支付接口请求地址域名
*/ */
public String getPayBaseUrl() { public String getApiHostUrl() {
if (StringUtils.isEmpty(this.payBaseUrl)) { if (StringUtils.isEmpty(this.apiHostUrl)) {
return DEFAULT_PAY_BASE_URL; return DEFAULT_PAY_BASE_URL;
} }
return this.payBaseUrl; return this.apiHostUrl;
} }
@SneakyThrows @SneakyThrows
@ -375,7 +375,7 @@ public class WxPayConfig {
} else { } else {
certificatesVerifier = VerifierBuilder.build( certificatesVerifier = VerifierBuilder.build(
this.getCertSerialNo(), this.getMchId(), this.getApiV3Key(), merchantPrivateKey, wxPayHttpProxy, this.getCertSerialNo(), this.getMchId(), this.getApiV3Key(), merchantPrivateKey, wxPayHttpProxy,
this.getCertAutoUpdateTime(), this.getPayBaseUrl(), this.getPublicKeyId(), publicKey); this.getCertAutoUpdateTime(), this.getApiHostUrl(), this.getPublicKeyId(), publicKey);
} }
WxPayV3HttpClientBuilder wxPayV3HttpClientBuilder = WxPayV3HttpClientBuilder.create() WxPayV3HttpClientBuilder wxPayV3HttpClientBuilder = WxPayV3HttpClientBuilder.create()

View File

@ -217,9 +217,9 @@ public abstract class BaseWxPayServiceImpl implements WxPayService {
if (StringUtils.isNotBlank(this.getConfig().getApiV3Key())) { if (StringUtils.isNotBlank(this.getConfig().getApiV3Key())) {
throw new WxRuntimeException("微信支付V3 目前不支持沙箱模式!"); throw new WxRuntimeException("微信支付V3 目前不支持沙箱模式!");
} }
return this.getConfig().getPayBaseUrl() + "/xdc/apiv2sandbox"; return this.getConfig().getApiHostUrl() + "/xdc/apiv2sandbox";
} }
return this.getConfig().getPayBaseUrl(); return this.getConfig().getApiHostUrl();
} }
@Override @Override

View File

@ -936,7 +936,7 @@ public class BaseWxPayServiceImplTest {
WxPayOrderQueryV3Request request = new WxPayOrderQueryV3Request(); WxPayOrderQueryV3Request request = new WxPayOrderQueryV3Request();
request.setOutTradeNo("n1ZvYqjAg3D3LUBa"); request.setOutTradeNo("n1ZvYqjAg3D3LUBa");
WxPayConfig config = this.payService.getConfig(); WxPayConfig config = this.payService.getConfig();
config.setPayBaseUrl("http://api.mch.weixin.qq.com"); config.setApiHostUrl("http://api.mch.weixin.qq.com");
config.setHttpProxyHost("12.11.1.113"); config.setHttpProxyHost("12.11.1.113");
config.setHttpProxyPort(8015); config.setHttpProxyPort(8015);
WxPayOrderQueryV3Result result = this.payService.queryOrderV3(request); WxPayOrderQueryV3Result result = this.payService.queryOrderV3(request);