feat(v2): gateway 经 Picker 路由选账户 + retry 换号(ExcludeAccounts);替换首个 enabled
This commit is contained in:
+25
-13
@@ -37,15 +37,15 @@ type WebhookEnqueuer interface {
|
||||
type Gateway struct {
|
||||
orders *store.OrderStore
|
||||
providers *provider.Registry
|
||||
accounts *accounts.Registry
|
||||
picker accounts.Picker
|
||||
products ProductResolver
|
||||
webhook WebhookEnqueuer
|
||||
region string
|
||||
}
|
||||
|
||||
func New(orders *store.OrderStore, providers *provider.Registry, accts *accounts.Registry,
|
||||
func New(orders *store.OrderStore, providers *provider.Registry, picker accounts.Picker,
|
||||
products ProductResolver, webhook WebhookEnqueuer, region string) *Gateway {
|
||||
return &Gateway{orders: orders, providers: providers, accounts: accts,
|
||||
return &Gateway{orders: orders, providers: providers, picker: picker,
|
||||
products: products, webhook: webhook, region: region}
|
||||
}
|
||||
|
||||
@@ -80,13 +80,17 @@ func (g *Gateway) CreateOrder(ctx context.Context, in CreateOrderInput) (*OrderR
|
||||
if err != nil {
|
||||
return nil, err // ErrUnknownMethod
|
||||
}
|
||||
accts := g.accounts.EnabledFor(in.Method, g.region)
|
||||
if len(accts) == 0 {
|
||||
return nil, ErrNoAccount
|
||||
}
|
||||
acct := accts[0] // 路由策略(round_robin/weighted/…)在 P5;P2 取首个 enabled。
|
||||
|
||||
outNo := util.NewOutTradeNo("pay")
|
||||
acct, err := g.picker.Pick(in.Method, g.region, accounts.PickHint{
|
||||
OutTradeNo: outNo, AmountMinor: amountMinor,
|
||||
})
|
||||
if err != nil {
|
||||
if errors.Is(err, accounts.ErrNoAccount) {
|
||||
return nil, ErrNoAccount
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err := g.orders.CreateOrder(&model.OrderV2{
|
||||
OutTradeNo: outNo, BizSystem: in.BizSystem, BizRef: in.BizRef,
|
||||
Subject: subject, AmountMinor: amountMinor, Currency: currency,
|
||||
@@ -150,11 +154,19 @@ func (g *Gateway) RetryOrder(ctx context.Context, outTradeNo, method string) (*O
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
accts := g.accounts.EnabledFor(method, g.region)
|
||||
if len(accts) == 0 {
|
||||
return nil, ErrNoAccount
|
||||
tried, err := g.orders.AttemptAccountIDs(outTradeNo, method)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
acct, err := g.picker.Pick(method, g.region, accounts.PickHint{
|
||||
OutTradeNo: outTradeNo, AmountMinor: o.AmountMinor, ExcludeAccounts: tried,
|
||||
})
|
||||
if err != nil {
|
||||
if errors.Is(err, accounts.ErrNoAccount) {
|
||||
return nil, ErrNoAccount
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
acct := accts[0]
|
||||
|
||||
if _, err := g.orders.ExpirePendingAttempts(outTradeNo); err != nil {
|
||||
return nil, err
|
||||
|
||||
Reference in New Issue
Block a user