异常信息
java.lang.IllegalStateException: The corresponding provider for the merchant already exists.
原因
这个错误是微信SDK抛出的,这是因为微信支付apiV3的RSAConfig重复build导致,即RSAConfig要保证是单例才不会导致报错。
// 要保证这个Config在服务中单例
private RSAAutoCertificateConfig config;
@Autowired
public void setConfig(){
config = new RSAAutoCertificateConfig.Builder()
.merchantId(mchId)
.privateKey(privateKey)
.merchantSerialNumber(mchSerialNo)
.apiV3Key(apiV3Key)
.build();
}
public Config getConfig(){
return this.config;
}
public NotificationConfig getNotificationConfig(){
return this.config;
}
参数说明
- mchId:商户号
- privateKey:商户号密钥
- mchSerialNo:商户证书号
- apiV3Key:apiV3密钥
建议
可以把商户配置参数使用数据库保存,服务启动的时候加载在缓存里面,缓存的key为mchId,value为config对象,这样可以实现一个服务多个直连商户号共存。文章来源:https://uudwc.com/A/DzOgr
package com.swkj.payment.test;
import com.swkj.common.base.enums.PaymentMchType;
import com.swkj.common.base.util.CollectionUtils;
import com.swkj.common.charge.model.po.paymentmch.PaymentMchPo;
import com.swkj.common.charge.service.paymentmch.PaymentMchService;
import com.swkj.common.core.wrapper.LambdaQueryWrapperX;
import com.wechat.pay.java.core.Config;
import com.wechat.pay.java.core.RSAAutoCertificateConfig;
import com.wechat.pay.java.core.notification.NotificationConfig;
import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.util.List;
import java.util.Map;
/**
* @Description:
* @Author: GE LIANG
* @Date: 2023/3/14 8:49
*/
public class PaymentServiceImpl {
// 本地缓存
private Map<String, RSAAutoCertificateConfig> configMap;
@Resource
PaymentMchService paymentMchService;
@PostConstruct
public void initConfig() {
LambdaQueryWrapperX<PaymentMchPo> wrapperX = new LambdaQueryWrapperX<>();
wrapperX.eq(PaymentMchPo::getMchTypeId, PaymentMchType.WECHAT.getValue());
List<PaymentMchPo> list = paymentMchService.list(wrapperX);
if (CollectionUtils.isEmpty(list)) {
return;
}
for (PaymentMchPo paymentMchPo : list) {
RSAAutoCertificateConfig config =
new RSAAutoCertificateConfig.Builder()
.merchantId(paymentMchPo.getMchId())
.privateKey(paymentMchPo.getPrivateKey())
// .privateKeyFromPath(wechatPaymentConfig.getPrivateKeyPath())
.merchantSerialNumber(paymentMchPo.getMchSerialNo())
.apiV3Key(paymentMchPo.getApiV3Key())
.build();
configMap.put(paymentMchPo.getAppId(), config);
}
}
/**
* @param appId 根据AppId获取Config
* @return
*/
public Config getWechatConfig(String appId) {
return configMap.get(appId);
}
/**
* @param appId 根据appId获取NotificationConfig
* @return
*/
public NotificationConfig getNotificationConfig(String appId) {
return configMap.get(appId);
}
}
PaymentMchPo 对应的sql结构文章来源地址https://uudwc.com/A/DzOgr
DROP TABLE IF EXISTS "public"."charge_payment_mch";
CREATE TABLE "public"."charge_payment_mch" (
"payment_mch_id" int8 NOT NULL,
"revision" int4 NOT NULL,
"created_by" int8 NOT NULL,
"created_time" timestamp(0) NOT NULL,
"updated_by" int8,
"updated_time" timestamp(0),
"mch_id" varchar(50) COLLATE "pg_catalog"."default",
"private_key" text COLLATE "pg_catalog"."default",
"mch_serial_no" varchar(256) COLLATE "pg_catalog"."default",
"api_v3_key" varchar(256) COLLATE "pg_catalog"."default",
"app_id" varchar(50) COLLATE "pg_catalog"."default"
)
;