feat(payment): 后台「支付配置」支持微信支付与支付宝凭据管理

后端:
- 新增 payment_configs 单行配置表;APIv3 密钥、应用私钥/公钥以 AES-256-GCM 密文入库(enc:v1 前缀,主密钥取 PAYMENT_SECRET_KEY,缺省回退 JWT_SECRET 派生)
- 证书/私钥落 PAYMENT_CERT_DIR(默认 /data/payment-certs),目录 0700 / 文件 0600,不经任何静态路由暴露
- 接口:GET/PUT /api/admin/payment/config、POST /upload(PEM 校验 + 微信证书序列号自动回填)、POST /test(真打官方接口:微信 /v3/certificates 签名校验、支付宝 alipay.trade.query 签名校验)、POST /wechat/platform-certs(APIv3 密钥解密平台证书并落盘)
- 未配置凭据时测试返回 skipped 而不是 500;敏感字段在返回体里一律脱敏

前端:
- /payments 改为「通用设置 + 微信支付 / 支付宝 / Waffo 海外支付」页签(原 Waffo 页整页迁到 views/payments/Waffo.vue)
- 微信:mchid、AppID、APIv3 密钥(密码框 + 掩码回显 + 更换/清除)、证书序列号、支付方式多选、三项证书上传、自动获取平台证书
- 支付宝:app_id、应用私钥(粘贴/上传)、支付宝公钥、网关、RSA2、回调地址
- 菜单归入「审计与设置 → 支付配置」
This commit is contained in:
Logan.Li committed 2026-11-01 05:59:51 +08:00
1 parent 630f2819cb
commit 7d53c6ed3c
21 files changed
+3090 -6

No files matched your search

+39
View File
@@ -0,0 +1,39 @@
package model
import "time"
// PaymentConfig 支付渠道配置(单行表,固定使用 ID=1)。
// 敏感字段(APIv3 密钥、应用私钥)以 AES-GCM 密文入库,绝不存明文。 // Logan.Li
type PaymentConfig struct {
ID uint `json:"id" gorm:"primaryKey"`
Mode string `json:"mode" gorm:"size:10;default:'test'"` // test / live
// ============ 微信支付(APIv3) ============
WechatEnabled bool `json:"wechat_enabled" gorm:"default:false"`
WechatMchID string `json:"wechat_mch_id" gorm:"size:64"`
WechatAppID string `json:"wechat_app_id" gorm:"size:64"`
WechatAPIv3KeyEnc string `json:"-" gorm:"column:wechat_apiv3_key_enc;type:text"` // AES-GCM 密文
WechatSerialNo string `json:"wechat_serial_no" gorm:"size:128"` // 商户 API 证书序列号
WechatCertPath string `json:"-" gorm:"column:wechat_cert_path;size:512"` // apiclient_cert.pem 落地路径
WechatKeyPath string `json:"-" gorm:"column:wechat_key_path;size:512"` // apiclient_key.pem 落地路径
WechatPlatformCertPath string `json:"-" gorm:"column:wechat_platform_cert_path;size:512"`
WechatPayMethods string `json:"wechat_pay_methods" gorm:"size:64;default:'native'"` // 逗号分隔 native,h5,jsapi
// ============ 支付宝(开放平台) ============
AlipayEnabled bool `json:"alipay_enabled" gorm:"default:false"`
AlipayAppID string `json:"alipay_app_id" gorm:"size:64"`
AlipayPrivateKeyEnc string `json:"-" gorm:"column:alipay_private_key_enc;type:text"` // AES-GCM 密文(粘贴来源)
AlipayPublicKeyEnc string `json:"-" gorm:"column:alipay_public_key_enc;type:text"` // AES-GCM 密文(粘贴来源)
AlipayPrivateKeyPath string `json:"-" gorm:"column:alipay_private_key_path;size:512"`
AlipayPublicKeyPath string `json:"-" gorm:"column:alipay_public_key_path;size:512"`
AlipayGateway string `json:"alipay_gateway" gorm:"size:255"`
AlipaySignType string `json:"alipay_sign_type" gorm:"size:20;default:'RSA2'"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
}
// TableName 指定表名 // Logan.Li
func (PaymentConfig) TableName() string {
return "payment_configs"
}