fix(upgrade): close payment and oidc compatibility gaps

This commit is contained in:
IanShaw027
2026-04-22 18:01:51 +08:00
parent 66b3acc274
commit 9de7a72cce
10 changed files with 232 additions and 44 deletions

View File

@@ -21,6 +21,8 @@ import (
type paymentOrderLifecycleQueryProvider struct {
lastQueryTradeNo string
queryCalls int
responses []*payment.QueryOrderResponse
resp *payment.QueryOrderResponse
}
@@ -48,6 +50,14 @@ func (p *paymentOrderLifecycleQueryProvider) CreatePayment(context.Context, paym
func (p *paymentOrderLifecycleQueryProvider) QueryOrder(_ context.Context, tradeNo string) (*payment.QueryOrderResponse, error) {
p.lastQueryTradeNo = tradeNo
p.queryCalls++
if len(p.responses) > 0 {
resp := p.responses[0]
if len(p.responses) > 1 {
p.responses = p.responses[1:]
}
return resp, nil
}
return p.resp, nil
}
@@ -234,6 +244,103 @@ func TestVerifyOrderByOutTradeNoBackfillsTradeNoFromPaidQuery(t *testing.T) {
require.Equal(t, user.ID, redeemRepo.useCalls[0].userID)
}
func TestVerifyOrderByOutTradeNoRetriesZeroAmountPaidQueryOnce(t *testing.T) {
ctx := context.Background()
client := newPaymentOrderLifecycleTestClient(t)
user, err := client.User.Create().
SetEmail("checkpaid-retry@example.com").
SetPasswordHash("hash").
SetUsername("checkpaid-retry-user").
Save(ctx)
require.NoError(t, err)
order, err := client.PaymentOrder.Create().
SetUserID(user.ID).
SetUserEmail(user.Email).
SetUserName(user.Username).
SetAmount(88).
SetPayAmount(88).
SetFeeRate(0).
SetRechargeCode("CHECKPAID-UPSTREAM-RETRY").
SetOutTradeNo("sub2_checkpaid_retry_zero_amount").
SetPaymentType(payment.TypeAlipay).
SetPaymentTradeNo("").
SetOrderType(payment.OrderTypeBalance).
SetStatus(OrderStatusPending).
SetExpiresAt(time.Now().Add(time.Hour)).
SetClientIP("127.0.0.1").
SetSrcHost("api.example.com").
Save(ctx)
require.NoError(t, err)
userRepo := &mockUserRepo{
getByIDUser: &User{
ID: user.ID,
Email: user.Email,
Username: user.Username,
Balance: 0,
},
}
userRepo.updateBalanceFn = func(ctx context.Context, id int64, amount float64) error {
require.Equal(t, user.ID, id)
if userRepo.getByIDUser != nil {
userRepo.getByIDUser.Balance += amount
}
return nil
}
redeemRepo := &paymentOrderLifecycleRedeemRepo{
codesByCode: map[string]*RedeemCode{
order.RechargeCode: {
ID: 1,
Code: order.RechargeCode,
Type: RedeemTypeBalance,
Value: order.Amount,
Status: StatusUnused,
},
},
}
redeemService := NewRedeemService(
redeemRepo,
userRepo,
nil,
nil,
nil,
client,
nil,
)
registry := payment.NewRegistry()
provider := &paymentOrderLifecycleQueryProvider{
responses: []*payment.QueryOrderResponse{
{
TradeNo: "upstream-trade-zero",
Status: payment.ProviderStatusPaid,
Amount: 0,
},
{
TradeNo: "upstream-trade-retry",
Status: payment.ProviderStatusPaid,
Amount: 88,
},
},
}
registry.Register(provider)
svc := &PaymentService{
entClient: client,
registry: registry,
redeemService: redeemService,
userRepo: userRepo,
providersLoaded: true,
}
got, err := svc.VerifyOrderByOutTradeNo(ctx, order.OutTradeNo, user.ID)
require.NoError(t, err)
require.Equal(t, 2, provider.queryCalls)
require.Equal(t, OrderStatusCompleted, got.Status)
require.Equal(t, "upstream-trade-retry", got.PaymentTradeNo)
}
func TestVerifyOrderByOutTradeNoRejectsPaidQueryWithZeroAmount(t *testing.T) {
ctx := context.Background()
client := newPaymentOrderLifecycleTestClient(t)