fix payment visible methods and resume recovery

This commit is contained in:
IanShaw027
2026-04-21 00:14:05 +08:00
parent 5d58c7c6fb
commit 16be82b959
6 changed files with 201 additions and 19 deletions

View File

@@ -20,6 +20,18 @@ func (s *PaymentConfigService) GetAvailableMethodLimits(ctx context.Context) (*M
return nil, fmt.Errorf("query provider instances: %w", err)
}
typeInstances := pcGroupByPaymentType(instances)
if s.settingRepo != nil {
vals, err := s.settingRepo.GetMultiple(ctx, []string{
SettingPaymentVisibleMethodAlipayEnabled,
SettingPaymentVisibleMethodAlipaySource,
SettingPaymentVisibleMethodWxpayEnabled,
SettingPaymentVisibleMethodWxpaySource,
})
if err != nil {
return nil, fmt.Errorf("query visible method settings: %w", err)
}
typeInstances = pcApplyVisibleMethodRouting(typeInstances, vals, buildVisibleMethodSourceAvailability(instances))
}
resp := &MethodLimitsResponse{
Methods: make(map[string]MethodLimits, len(typeInstances)),
}
@@ -31,6 +43,40 @@ func (s *PaymentConfigService) GetAvailableMethodLimits(ctx context.Context) (*M
return resp, nil
}
func pcApplyVisibleMethodRouting(typeInstances map[string][]*dbent.PaymentProviderInstance, vals map[string]string, available map[string]bool) map[string][]*dbent.PaymentProviderInstance {
if len(typeInstances) == 0 {
return typeInstances
}
filtered := make(map[string][]*dbent.PaymentProviderInstance, len(typeInstances))
for paymentType, instances := range typeInstances {
visibleMethod := NormalizeVisibleMethod(paymentType)
switch visibleMethod {
case payment.TypeAlipay, payment.TypeWxpay:
if !visibleMethodShouldBeExposed(visibleMethod, vals, available) {
continue
}
targetProviderKey, ok := VisibleMethodProviderKeyForSource(visibleMethod, vals[visibleMethodSourceSettingKey(visibleMethod)])
if !ok {
continue
}
matching := make([]*dbent.PaymentProviderInstance, 0, len(instances))
for _, inst := range instances {
if inst.ProviderKey == targetProviderKey {
matching = append(matching, inst)
}
}
if len(matching) == 0 {
continue
}
filtered[paymentType] = matching
default:
filtered[paymentType] = instances
}
}
return filtered
}
// GetMethodLimits returns per-payment-type limits from enabled provider instances.
func (s *PaymentConfigService) GetMethodLimits(ctx context.Context, types []string) ([]MethodLimits, error) {
instances, err := s.entClient.PaymentProviderInstance.Query().

View File

@@ -1,6 +1,7 @@
package service
import (
"context"
"testing"
dbent "github.com/Wei-Shaw/sub2api/ent"
@@ -299,3 +300,73 @@ func TestPcInstanceTypeLimits(t *testing.T) {
}
})
}
func TestGetAvailableMethodLimitsRespectsVisibleMethodRouting(t *testing.T) {
ctx := context.Background()
client := newPaymentConfigServiceTestClient(t)
_, err := client.PaymentProviderInstance.Create().
SetProviderKey(payment.TypeAlipay).
SetName("Official Alipay").
SetConfig("{}").
SetSupportedTypes("alipay").
SetLimits(`{"alipay":{"singleMin":10,"singleMax":100}}`).
SetEnabled(true).
Save(ctx)
if err != nil {
t.Fatalf("create official alipay instance: %v", err)
}
_, err = client.PaymentProviderInstance.Create().
SetProviderKey(payment.TypeEasyPay).
SetName("EasyPay Alipay").
SetConfig("{}").
SetSupportedTypes("alipay").
SetLimits(`{"alipay":{"singleMin":20,"singleMax":200}}`).
SetEnabled(true).
Save(ctx)
if err != nil {
t.Fatalf("create easypay alipay instance: %v", err)
}
_, err = client.PaymentProviderInstance.Create().
SetProviderKey(payment.TypeWxpay).
SetName("Official WeChat").
SetConfig("{}").
SetSupportedTypes("wxpay").
SetLimits(`{"wxpay":{"singleMin":30,"singleMax":300}}`).
SetEnabled(true).
Save(ctx)
if err != nil {
t.Fatalf("create official wxpay instance: %v", err)
}
svc := &PaymentConfigService{
entClient: client,
settingRepo: &paymentConfigSettingRepoStub{
values: map[string]string{
SettingPaymentVisibleMethodAlipayEnabled: "true",
SettingPaymentVisibleMethodAlipaySource: VisibleMethodSourceEasyPayAlipay,
SettingPaymentVisibleMethodWxpayEnabled: "false",
SettingPaymentVisibleMethodWxpaySource: VisibleMethodSourceOfficialWechat,
},
},
}
resp, err := svc.GetAvailableMethodLimits(ctx)
if err != nil {
t.Fatalf("GetAvailableMethodLimits returned error: %v", err)
}
alipayLimits, ok := resp.Methods[payment.TypeAlipay]
if !ok {
t.Fatalf("expected visible alipay limits, got %v", resp.Methods)
}
if alipayLimits.SingleMin != 20 || alipayLimits.SingleMax != 200 {
t.Fatalf("alipay limits = %+v, want easypay-only min=20 max=200", alipayLimits)
}
if _, ok := resp.Methods[payment.TypeWxpay]; ok {
t.Fatalf("wxpay should be hidden when visible method is disabled, got %v", resp.Methods[payment.TypeWxpay])
}
if resp.GlobalMin != 20 || resp.GlobalMax != 200 {
t.Fatalf("global range = (%v, %v), want (20, 200)", resp.GlobalMin, resp.GlobalMax)
}
}