按 PRD 2.3/2.4/2.5 落地套餐退款的方式矩阵与原路渠道退款: - 退款申请派生并冻结权威实收金额(线上取原成功支付记录,钱包/线下取订单实际收款), 提交人不可填写或修改;按来源支付方式生成可选方式矩阵并在创建、提交、执行前重复校验。 - 审批切换为「每次提交一条不可变审批尝试记录 + 独立企业微信审批实例」,业务标识取尝试 记录主键;终态消费按尝试记录优先、退款申请兜底双读,兼容存量无实例与已关联实例申请。 新增活动退款部分唯一索引 (order_id) WHERE status IN (1,5,6)。 - 本地人工终审保持既有开关,补齐通过入口的 approval_instance_id IS NULL 守卫,使三个 入口一致拒绝已关联审批实例的申请;重提按尝试模式重写(仅已拒绝/已退回/原路失败且无异常)。 - 权益时点:企微通过事务写退款终态、按方式确定的订单态、钱包回款、员工账单冲销与可靠 失效事实;套餐失效/接续/停机仍由既有可靠机制最终一致执行,不把外部调用放入资金事务。 订单支付状态按方式置位:凭证退款与退回原钱包在企微通过时置已退款,原路须渠道明确成功。 - 按官方契约实现微信直连 v3、微信 v2(双向证书)、富友(/commonRefund 与 /refundQuery)、 支付宝四类原路退款;能力只由服务商类型与退款必需凭证完整性决定,无人工开关。 渠道请求号在提交时冻结到尝试记录,并以 channel_submitted_at 条件认领保证资金动作至多 提交一次(重复投递只查询不二次提交);不向任何渠道传递退款结果通知地址。 - 新增 refund:channel:recovery 恢复任务只查询回填;本地查询窗口超期(富友 72 小时、 微信 v2 7 天)转原路退款失败、渠道状态已失败、分类超时未知并置异常转人工,不放行自动 重提以避免重复退款。 - 同步退款 DTO/导出/审计资源与审计查询关联、商户凭证文档,并修正 fuiou 集成契约文档。 迁移 000218(退款尝试与渠道退款事实)、000219(微信 v2 客户端证书凭证)成对提供, 未修改既有迁移;测试库 junhong_cmp_test 完成 up/down/up 与行为核对,未调用真实渠道。
73 lines
5.5 KiB
Go
73 lines
5.5 KiB
Go
package model
|
||
|
||
import "gorm.io/gorm"
|
||
|
||
// 支付渠道类型常量
|
||
const (
|
||
ProviderTypeWechat = "wechat" // 微信直连(v3 API)
|
||
ProviderTypeWechatV2 = "wechat_v2" // 微信直连(v2 API,仅需 APIv2Key,无需证书序列号)
|
||
ProviderTypeFuiou = "fuiou" // 富友
|
||
)
|
||
|
||
// 支付宝支付过期默认分钟数
|
||
const DefaultAliPayExpireMinutes = 30
|
||
|
||
// WechatConfig 微信参数配置模型
|
||
// 管理微信公众号 OAuth、小程序、微信直连支付、富友支付等多套配置
|
||
// 同一时间只有一条记录处于 is_active=true(全局唯一生效配置)
|
||
type WechatConfig struct {
|
||
gorm.Model
|
||
BaseModel `gorm:"embedded"`
|
||
|
||
Name string `gorm:"column:name;type:varchar(100);not null;comment:配置名称" json:"name"`
|
||
Description *string `gorm:"column:description;type:text;comment:配置描述" json:"description,omitempty"`
|
||
ProviderType string `gorm:"column:provider_type;type:varchar(20);not null;comment:支付渠道类型(wechat-微信直连,fuiou-富友)" json:"provider_type"`
|
||
IsActive bool `gorm:"column:is_active;type:boolean;not null;default:false;comment:是否激活(全局唯一)" json:"is_active"`
|
||
|
||
// OAuth 公众号
|
||
OaAppID string `gorm:"column:oa_app_id;type:varchar(100);not null;default:'';comment:公众号AppID" json:"oa_app_id"`
|
||
OaAppSecret string `gorm:"column:oa_app_secret;type:varchar(200);not null;default:'';comment:公众号AppSecret" json:"oa_app_secret"`
|
||
OaToken string `gorm:"column:oa_token;type:varchar(200);default:'';comment:公众号Token" json:"oa_token"`
|
||
OaAesKey string `gorm:"column:oa_aes_key;type:varchar(200);default:'';comment:公众号AES加密Key" json:"oa_aes_key"`
|
||
OaOAuthRedirectURL string `gorm:"column:oa_oauth_redirect_url;type:varchar(500);default:'';comment:OAuth回调地址" json:"oa_oauth_redirect_url"`
|
||
|
||
// OAuth 小程序
|
||
MiniappAppID string `gorm:"column:miniapp_app_id;type:varchar(100);default:'';comment:小程序AppID" json:"miniapp_app_id"`
|
||
MiniappAppSecret string `gorm:"column:miniapp_app_secret;type:varchar(200);default:'';comment:小程序AppSecret" json:"miniapp_app_secret"`
|
||
|
||
// 支付-微信直连
|
||
WxMchID string `gorm:"column:wx_mch_id;type:varchar(100);default:'';comment:微信商户号" json:"wx_mch_id"`
|
||
WxAPIV3Key string `gorm:"column:wx_api_v3_key;type:varchar(200);default:'';comment:微信APIv3密钥" json:"wx_api_v3_key"`
|
||
WxAPIV2Key string `gorm:"column:wx_api_v2_key;type:varchar(200);default:'';comment:微信APIv2密钥" json:"wx_api_v2_key"`
|
||
WxCertContent string `gorm:"column:wx_cert_content;type:text;default:'';comment:微信支付证书内容" json:"wx_cert_content"`
|
||
WxKeyContent string `gorm:"column:wx_key_content;type:text;default:'';comment:微信支付密钥内容" json:"wx_key_content"`
|
||
WxSerialNo string `gorm:"column:wx_serial_no;type:varchar(200);default:'';comment:微信证书序列号" json:"wx_serial_no"`
|
||
WxNotifyURL string `gorm:"column:wx_notify_url;type:varchar(500);default:'';comment:微信支付回调地址" json:"wx_notify_url"`
|
||
// v2 退款接口(/secapi/pay/refund)请求需要双向证书,仅 APIv2 密钥不足以退款。
|
||
WxClientCertContent string `gorm:"column:wx_client_cert_content;type:text;default:'';comment:微信支付API客户端证书内容(apiclient_cert.pem)" json:"wx_client_cert_content"`
|
||
WxClientKeyContent string `gorm:"column:wx_client_key_content;type:text;default:'';comment:微信支付API客户端证书私钥内容(apiclient_key.pem)" json:"wx_client_key_content"`
|
||
|
||
// 支付-富友
|
||
FyInsCd string `gorm:"column:fy_ins_cd;type:varchar(50);default:'';comment:富友机构号" json:"fy_ins_cd"`
|
||
FyMchntCd string `gorm:"column:fy_mchnt_cd;type:varchar(50);default:'';comment:富友商户号" json:"fy_mchnt_cd"`
|
||
FyTermID string `gorm:"column:fy_term_id;type:varchar(50);default:'';comment:富友终端号" json:"fy_term_id"`
|
||
FyPrivateKey string `gorm:"column:fy_private_key;type:text;default:'';comment:富友私钥" json:"fy_private_key"`
|
||
FyPublicKey string `gorm:"column:fy_public_key;type:text;default:'';comment:富友公钥" json:"fy_public_key"`
|
||
FyAPIURL string `gorm:"column:fy_api_url;type:varchar(500);default:'';comment:富友API地址" json:"fy_api_url"`
|
||
FyNotifyURL string `gorm:"column:fy_notify_url;type:varchar(500);default:'';comment:富友支付回调地址" json:"fy_notify_url"`
|
||
|
||
// 支付-支付宝(与微信/富友并存,provider_type 不新增 alipay)
|
||
AliAppID string `gorm:"column:ali_app_id;type:varchar(100);not null;default:'';comment:支付宝应用ID" json:"ali_app_id"`
|
||
AliPrivateKey string `gorm:"column:ali_private_key;type:text;not null;default:'';comment:支付宝应用私钥(敏感)" json:"ali_private_key"`
|
||
AliPublicKey string `gorm:"column:ali_public_key;type:text;not null;default:'';comment:支付宝公钥(用于验签)" json:"ali_public_key"`
|
||
AliNotifyURL string `gorm:"column:ali_notify_url;type:varchar(500);not null;default:'';comment:支付宝异步通知地址" json:"ali_notify_url"`
|
||
AliReturnURL string `gorm:"column:ali_return_url;type:varchar(500);not null;default:'';comment:支付宝同步跳转地址" json:"ali_return_url"`
|
||
AliProduction bool `gorm:"column:ali_production;type:boolean;not null;default:false;comment:是否生产环境" json:"ali_production"`
|
||
AliPayExpireMinutes int `gorm:"column:ali_pay_expire_minutes;type:integer;not null;default:30;comment:支付过期分钟数" json:"ali_pay_expire_minutes"`
|
||
}
|
||
|
||
// TableName 指定表名
|
||
func (WechatConfig) TableName() string {
|
||
return "tb_wechat_config"
|
||
}
|