新增收款商户、商户池轮询、微信授权配置独立管理;三类新支付 (C端套餐购买、C端资产钱包充值、代理在线预存款充值)无条件 经商户池选择并冻结路由,无旧综合配置回退。merchant_id 为空 历史支付继续按 payment_config_id 双读。凭证版本化加载与 ID+版本缓存保证轮换一致性。删除商户池新支付创建开关及全部 引用。
This commit is contained in:
@@ -6,6 +6,7 @@ import (
|
||||
|
||||
"gorm.io/gorm"
|
||||
|
||||
merchantpayment "github.com/break/junhong_cmp_fiber/internal/application/merchantpayment"
|
||||
"github.com/break/junhong_cmp_fiber/internal/model"
|
||||
"github.com/break/junhong_cmp_fiber/pkg/constants"
|
||||
"github.com/break/junhong_cmp_fiber/pkg/errors"
|
||||
@@ -14,6 +15,7 @@ import (
|
||||
// RecoverOnlinePaymentService 批量收敛长期缺少支付链接或待支付的代理在线充值。
|
||||
type RecoverOnlinePaymentService struct {
|
||||
db *gorm.DB
|
||||
runtime *merchantpayment.RuntimeLoader
|
||||
wechat OnlinePaymentPort
|
||||
alipay OnlinePaymentPort
|
||||
fuiou OnlinePaymentPort
|
||||
@@ -23,13 +25,13 @@ type RecoverOnlinePaymentService struct {
|
||||
}
|
||||
|
||||
// NewRecoverOnlinePaymentService 创建代理在线充值支付恢复用例。
|
||||
func NewRecoverOnlinePaymentService(db *gorm.DB, wechat, alipay, fuiou OnlinePaymentPort, confirm *ConfirmOnlinePaymentService, audit PaymentAuditWriter) *RecoverOnlinePaymentService {
|
||||
return &RecoverOnlinePaymentService{db: db, wechat: wechat, alipay: alipay, fuiou: fuiou, confirm: confirm, audit: audit, now: time.Now}
|
||||
func NewRecoverOnlinePaymentService(db *gorm.DB, runtime *merchantpayment.RuntimeLoader, wechat, alipay, fuiou OnlinePaymentPort, confirm *ConfirmOnlinePaymentService, audit PaymentAuditWriter) *RecoverOnlinePaymentService {
|
||||
return &RecoverOnlinePaymentService{db: db, runtime: runtime, wechat: wechat, alipay: alipay, fuiou: fuiou, confirm: confirm, audit: audit, now: time.Now}
|
||||
}
|
||||
|
||||
// ProcessBatch 按固定批次读取本地待处理事实并调用对应渠道收敛状态。
|
||||
func (s *RecoverOnlinePaymentService) ProcessBatch(ctx context.Context) (int, error) {
|
||||
if s == nil || s.db == nil || s.wechat == nil || s.alipay == nil || s.fuiou == nil || s.confirm == nil || s.audit == nil {
|
||||
if s == nil || s.db == nil || s.runtime == nil || s.wechat == nil || s.alipay == nil || s.fuiou == nil || s.confirm == nil || s.audit == nil {
|
||||
return 0, errors.New(errors.CodeServiceUnavailable, "代理在线充值支付恢复能力未配置")
|
||||
}
|
||||
now := s.now().UTC()
|
||||
@@ -52,7 +54,13 @@ func (s *RecoverOnlinePaymentService) ProcessBatch(ctx context.Context) (int, er
|
||||
for index := range payments {
|
||||
payment := &payments[index]
|
||||
recharge := recharges[payment.OrderID]
|
||||
config := recoveryConfig(payment, configs)
|
||||
config, configErr := s.recoveryConfig(ctx, payment, configs)
|
||||
if configErr != nil {
|
||||
if firstErr == nil {
|
||||
firstErr = configErr
|
||||
}
|
||||
continue
|
||||
}
|
||||
if recharge == nil || config == nil {
|
||||
if firstErr == nil {
|
||||
firstErr = errors.New(errors.CodeConflict, "待恢复支付单缺少充值单或创建配置")
|
||||
@@ -141,7 +149,7 @@ func (s *RecoverOnlinePaymentService) loadRecoveryFacts(ctx context.Context, pay
|
||||
configIDs := make([]uint, 0, len(payments))
|
||||
for index := range payments {
|
||||
rechargeIDs = append(rechargeIDs, payments[index].OrderID)
|
||||
if payments[index].PaymentConfigID != nil {
|
||||
if payments[index].MerchantID == nil && payments[index].PaymentConfigID != nil {
|
||||
configIDs = append(configIDs, *payments[index].PaymentConfigID)
|
||||
}
|
||||
}
|
||||
@@ -151,8 +159,10 @@ func (s *RecoverOnlinePaymentService) loadRecoveryFacts(ctx context.Context, pay
|
||||
}
|
||||
var configRows []model.WechatConfig
|
||||
if len(configIDs) > 0 {
|
||||
if err := s.db.WithContext(ctx).Where("id IN ?", configIDs).Find(&configRows).Error; err != nil {
|
||||
return nil, nil, errors.Wrap(errors.CodeDatabaseError, err, "批量查询代理充值创建配置失败")
|
||||
// merchant_id 为空仅为留存期内历史支付;独立 Change 删除旧路径前,
|
||||
// 必须按其 payment_config_id 读取,包括已软删除的原始配置。
|
||||
if err := s.db.WithContext(ctx).Unscoped().Where("id IN ?", configIDs).Find(&configRows).Error; err != nil {
|
||||
return nil, nil, errors.Wrap(errors.CodeDatabaseError, err, "批量查询代理充值历史配置失败")
|
||||
}
|
||||
}
|
||||
recharges := make(map[uint]*model.AgentRechargeRecord, len(rechargeRows))
|
||||
@@ -166,11 +176,27 @@ func (s *RecoverOnlinePaymentService) loadRecoveryFacts(ctx context.Context, pay
|
||||
return recharges, configs, nil
|
||||
}
|
||||
|
||||
func recoveryConfig(payment *model.Payment, configs map[uint]*model.WechatConfig) *model.WechatConfig {
|
||||
if payment.PaymentConfigID == nil {
|
||||
return nil
|
||||
// recoveryConfig 对冻结商户支付单按当前凭证版本加载;历史支付单保持 payment_config_id 路径。
|
||||
func (s *RecoverOnlinePaymentService) recoveryConfig(ctx context.Context, payment *model.Payment, configs map[uint]*model.WechatConfig) (*model.WechatConfig, error) {
|
||||
if payment.MerchantID != nil {
|
||||
merchant, err := s.runtime.LoadMerchant(ctx, *payment.MerchantID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// 仅微信直连(v3/v2)商户需要全局授权配置中的 AppID;富友商户不依赖该配置。
|
||||
var authorization *model.WechatAuthorization
|
||||
if merchant.ProviderType == model.ProviderTypeWechat || merchant.ProviderType == model.ProviderTypeWechatV2 {
|
||||
authorization, err = s.runtime.LoadAuthorization(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return merchantpayment.MerchantConfig(merchant, authorization)
|
||||
}
|
||||
return configs[*payment.PaymentConfigID]
|
||||
if payment.PaymentConfigID == nil {
|
||||
return nil, nil
|
||||
}
|
||||
return configs[*payment.PaymentConfigID], nil
|
||||
}
|
||||
|
||||
func (s *RecoverOnlinePaymentService) closePending(ctx context.Context, payment *model.Payment, recharge *model.AgentRechargeRecord) error {
|
||||
|
||||
Reference in New Issue
Block a user