refactor: 微信支付私钥从文件路径改为PEM内容存储

- privateKeyPath → privateKey,数据库存PEM内容而非路径
- SDK调用从 privateKeyFromPath() 改为 privateKey()
- application.yml/docker-compose.yml 环境变量同步改名
- web前端可直接粘贴或上传.pem文件内容
This commit is contained in:
zhaogd
2026-08-01 15:18:45 +08:00
parent 12c6fc4db4
commit ec1f300c53
5 changed files with 14 additions and 14 deletions

View File

@@ -32,7 +32,7 @@ services:
- WECHAT_PAY_MCH_ID= - WECHAT_PAY_MCH_ID=
- WECHAT_PAY_API_V3_KEY= - WECHAT_PAY_API_V3_KEY=
- WECHAT_PAY_CERT_SERIAL_NO= - WECHAT_PAY_CERT_SERIAL_NO=
- WECHAT_PAY_PRIVATE_KEY_PATH= - WECHAT_PAY_PRIVATE_KEY=
- WECHAT_PAY_NOTIFY_URL= - WECHAT_PAY_NOTIFY_URL=
depends_on: depends_on:
- redis - redis

View File

@@ -20,8 +20,8 @@ public class WechatPayConfig {
private String apiV3Key; private String apiV3Key;
/** 商户证书序列号 */ /** 商户证书序列号 */
private String certSerialNo; private String certSerialNo;
/** 商户私钥文件路径(apiclient_key.pem) */ /** 商户私钥(PEM 内容) */
private String privateKeyPath; private String privateKey;
/** 支付回调通知地址 */ /** 支付回调通知地址 */
private String notifyUrl; private String notifyUrl;
} }

View File

@@ -44,8 +44,8 @@ public class WechatPayConfigEntity implements Serializable {
/** 证书序列号 */ /** 证书序列号 */
private String certSerialNo; private String certSerialNo;
/** 私钥文件路径 */ /** 商户私钥(PEM 内容) */
private String privateKeyPath; private String privateKey;
/** 回调通知URL */ /** 回调通知URL */
private String notifyUrl; private String notifyUrl;

View File

@@ -68,7 +68,7 @@ public class WechatPayServiceImpl implements WechatPayService {
@Autowired @Autowired
private JdbcTemplate jdbcTemplate; private JdbcTemplate jdbcTemplate;
/** SDK 配置缓存:按 mchId+certSerialNo+apiV3Key+privateKeyPath 缓存 */ /** SDK 配置缓存:按 mchId+certSerialNo+apiV3Key+privateKey 缓存 */
private final ConcurrentHashMap<String, Config> sdkConfigCache = new ConcurrentHashMap<>(); private final ConcurrentHashMap<String, Config> sdkConfigCache = new ConcurrentHashMap<>();
// ==================== 支付下单 ==================== // ==================== 支付下单 ====================
@@ -551,8 +551,8 @@ public class WechatPayServiceImpl implements WechatPayService {
if (StringUtils.isBlank(getCertSerialNo(dbCfg))) { if (StringUtils.isBlank(getCertSerialNo(dbCfg))) {
throw new ASException("微信支付配置缺少 certSerialNo"); throw new ASException("微信支付配置缺少 certSerialNo");
} }
if (StringUtils.isBlank(getPrivateKeyPath(dbCfg))) { if (StringUtils.isBlank(getPrivateKey(dbCfg))) {
throw new ASException("微信支付配置缺少 privateKeyPath"); throw new ASException("微信支付配置缺少 privateKey");
} }
if (StringUtils.isBlank(getNotifyUrl(dbCfg))) { if (StringUtils.isBlank(getNotifyUrl(dbCfg))) {
throw new ASException("微信支付配置缺少 notifyUrl"); throw new ASException("微信支付配置缺少 notifyUrl");
@@ -601,7 +601,7 @@ public class WechatPayServiceImpl implements WechatPayService {
} }
/** /**
* 获取或创建 SDK 配置实例(按商户号+证书+密钥+私钥路径缓存) * 获取或创建 SDK 配置实例(按商户号+证书+密钥+私钥缓存)
*/ */
private Config getOrCreateConfig(WechatPayConfigEntity cfg) { private Config getOrCreateConfig(WechatPayConfigEntity cfg) {
String cacheKey = buildCacheKey(cfg); String cacheKey = buildCacheKey(cfg);
@@ -617,7 +617,7 @@ public class WechatPayServiceImpl implements WechatPayService {
logger.info("初始化微信支付 RSAAutoCertificateConfig: mchId={}", getMchId(cfg)); logger.info("初始化微信支付 RSAAutoCertificateConfig: mchId={}", getMchId(cfg));
Config config = new RSAAutoCertificateConfig.Builder() Config config = new RSAAutoCertificateConfig.Builder()
.merchantId(getMchId(cfg)) .merchantId(getMchId(cfg))
.privateKeyFromPath(getPrivateKeyPath(cfg)) .privateKey(getPrivateKey(cfg))
.merchantSerialNumber(getCertSerialNo(cfg)) .merchantSerialNumber(getCertSerialNo(cfg))
.apiV3Key(getApiV3Key(cfg)) .apiV3Key(getApiV3Key(cfg))
.build(); .build();
@@ -627,7 +627,7 @@ public class WechatPayServiceImpl implements WechatPayService {
} }
private String buildCacheKey(WechatPayConfigEntity cfg) { private String buildCacheKey(WechatPayConfigEntity cfg) {
return getMchId(cfg) + "|" + getCertSerialNo(cfg) + "|" + getApiV3Key(cfg) + "|" + getPrivateKeyPath(cfg); return getMchId(cfg) + "|" + getCertSerialNo(cfg) + "|" + getApiV3Key(cfg) + "|" + getPrivateKey(cfg);
} }
private String getAppId(WechatPayConfigEntity cfg) { private String getAppId(WechatPayConfigEntity cfg) {
@@ -646,8 +646,8 @@ public class WechatPayServiceImpl implements WechatPayService {
return cfg != null && StringUtils.isNotBlank(cfg.getCertSerialNo()) ? cfg.getCertSerialNo() : wechatPayConfig.getCertSerialNo(); return cfg != null && StringUtils.isNotBlank(cfg.getCertSerialNo()) ? cfg.getCertSerialNo() : wechatPayConfig.getCertSerialNo();
} }
private String getPrivateKeyPath(WechatPayConfigEntity cfg) { private String getPrivateKey(WechatPayConfigEntity cfg) {
return cfg != null && StringUtils.isNotBlank(cfg.getPrivateKeyPath()) ? cfg.getPrivateKeyPath() : wechatPayConfig.getPrivateKeyPath(); return cfg != null && StringUtils.isNotBlank(cfg.getPrivateKey()) ? cfg.getPrivateKey() : wechatPayConfig.getPrivateKey();
} }
private String getNotifyUrl(WechatPayConfigEntity cfg) { private String getNotifyUrl(WechatPayConfigEntity cfg) {

View File

@@ -85,7 +85,7 @@ renren:
mch-id: ${WECHAT_PAY_MCH_ID:} mch-id: ${WECHAT_PAY_MCH_ID:}
api-v3-key: ${WECHAT_PAY_API_V3_KEY:} api-v3-key: ${WECHAT_PAY_API_V3_KEY:}
cert-serial-no: ${WECHAT_PAY_CERT_SERIAL_NO:} cert-serial-no: ${WECHAT_PAY_CERT_SERIAL_NO:}
private-key-path: ${WECHAT_PAY_PRIVATE_KEY_PATH:} private-key: ${WECHAT_PAY_PRIVATE_KEY:}
notify-url: ${WECHAT_PAY_NOTIFY_URL:} notify-url: ${WECHAT_PAY_NOTIFY_URL:}
# 橘视厅媒资接口配置(对应 Android 端 ApiConfig.kt) # 橘视厅媒资接口配置(对应 Android 端 ApiConfig.kt)