Files
Logan.Li 7d53c6ed3c 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、回调地址
- 菜单归入「审计与设置 → 支付配置」
2026-11-01 05:59:51 +08:00

130 lines
5.6 KiB
Go

package dto
// ============ 支付配置(微信支付 / 支付宝) ============
// PaymentFileInfo 已上传证书/密钥文件的可展示元信息(不含任何密钥内容) // Logan.Li
type PaymentFileInfo struct {
Configured bool `json:"configured"`
FileName string `json:"file_name"`
Fingerprint string `json:"fingerprint"` // SHA-256 指纹(前 16 位展示)
Subject string `json:"subject"` // 证书 CN / 密钥类型
NotBefore string `json:"not_before"` // 证书生效时间(pem 可解析时)
NotAfter string `json:"not_after"` // 证书到期时间
SizeBytes int64 `json:"size_bytes"`
ParseError string `json:"parse_error"`
}
// WechatPaymentView 微信支付配置(脱敏视图) // Logan.Li
type WechatPaymentView struct {
Enabled bool `json:"enabled"`
MchID string `json:"mch_id"`
AppID string `json:"app_id"`
APIv3KeyConfigured bool `json:"api_v3_key_configured"`
APIv3KeyMasked string `json:"api_v3_key_masked"` // 仅显示后 4 位
APIv3KeyLength int `json:"api_v3_key_length"`
SerialNo string `json:"serial_no"`
PayMethods []string `json:"pay_methods"` // native / h5 / jsapi
NotifyURL string `json:"notify_url"` // 只读
CertFile PaymentFileInfo `json:"cert_file"`
KeyFile PaymentFileInfo `json:"key_file"`
PlatformCertFile PaymentFileInfo `json:"platform_cert_file"`
Ready bool `json:"ready"`
Missing []string `json:"missing"`
}
// AlipayPaymentView 支付宝配置(脱敏视图) // Logan.Li
type AlipayPaymentView struct {
Enabled bool `json:"enabled"`
AppID string `json:"app_id"`
PrivateKeyConfigured bool `json:"private_key_configured"`
PrivateKeyMasked string `json:"private_key_masked"` // 指纹脱敏,绝不回显内容
PrivateKeySource string `json:"private_key_source"` // paste / upload / ""
PublicKeyConfigured bool `json:"public_key_configured"`
PublicKeyMasked string `json:"public_key_masked"`
Gateway string `json:"gateway"` // 默认 https://openapi.alipay.com/gateway.do
SignType string `json:"sign_type"` // 固定 RSA2
NotifyURL string `json:"notify_url"`
PrivateKeyFile PaymentFileInfo `json:"private_key_file"`
PublicKeyFile PaymentFileInfo `json:"public_key_file"`
Ready bool `json:"ready"`
Missing []string `json:"missing"`
}
// PaymentConfigView 支付配置整体视图(GET 返回,全部脱敏) // Logan.Li
type PaymentConfigView struct {
Mode string `json:"mode"` // test / live
Wechat WechatPaymentView `json:"wechat"`
Alipay AlipayPaymentView `json:"alipay"`
MasterKeyOrigin string `json:"master_key_origin"` // env / jwt_secret
EncryptionEnabled bool `json:"encryption_enabled"`
UpdatedAt string `json:"updated_at"`
}
// WechatPaymentUpdate 微信支付保存请求(空字符串 = 保持原值) // Logan.Li
type WechatPaymentUpdate struct {
Enabled *bool `json:"enabled"`
MchID *string `json:"mch_id"`
AppID *string `json:"app_id"`
APIv3Key string `json:"api_v3_key"` // 32 位;留空表示不修改
ClearAPIv3Key bool `json:"clear_api_v3_key"`
SerialNo *string `json:"serial_no"`
PayMethods []string `json:"pay_methods"`
}
// AlipayPaymentUpdate 支付宝保存请求(空字符串 = 保持原值) // Logan.Li
type AlipayPaymentUpdate struct {
Enabled *bool `json:"enabled"`
AppID *string `json:"app_id"`
PrivateKey string `json:"private_key"` // 可粘贴 PEM / 裸 base64
ClearPrivateKey bool `json:"clear_private_key"`
PublicKey string `json:"public_key"`
ClearPublicKey bool `json:"clear_public_key"`
Gateway *string `json:"gateway"`
SignType *string `json:"sign_type"`
}
// PaymentConfigUpdate 支付配置保存请求 // Logan.Li
type PaymentConfigUpdate struct {
Mode *string `json:"mode"` // test / live
Wechat *WechatPaymentUpdate `json:"wechat"`
Alipay *AlipayPaymentUpdate `json:"alipay"`
}
// PaymentUploadResponse 证书/密钥上传结果 // Logan.Li
type PaymentUploadResponse struct {
Kind string `json:"kind"`
File PaymentFileInfo `json:"file"`
Message string `json:"message"`
}
// PaymentTestRequest 连通性测试请求 // Logan.Li
type PaymentTestRequest struct {
Channel string `json:"channel"` // wechat / alipay / all(默认)
}
// PaymentTestResult 单渠道连通性测试结果 // Logan.Li
type PaymentTestResult struct {
Channel string `json:"channel"`
Status string `json:"status"` // ok / fail / skipped
OK bool `json:"ok"`
Message string `json:"message"`
HTTPStatus int `json:"http_status"`
Detail string `json:"detail"`
LatencyMS int64 `json:"latency_ms"`
}
// PaymentTestResponse 连通性测试整体结果 // Logan.Li
type PaymentTestResponse struct {
Results []PaymentTestResult `json:"results"`
}
// WechatPlatformCertItem 微信支付平台证书条目 // Logan.Li
type WechatPlatformCertItem struct {
SerialNo string `json:"serial_no"`
Subject string `json:"subject"`
NotBefore string `json:"not_before"`
NotAfter string `json:"not_after"`
SavedPath string `json:"-"` // 不回显绝对路径
IsSaved bool `json:"is_saved"`
}