package payment import ( "strings" "testing" "kra/app/system/internal/biz" gopayAlipay "github.com/go-pay/gopay/alipay" "github.com/go-pay/gopay/douyin" ) func TestWechatV2ResponseRequiresBusinessSuccessCode(t *testing.T) { for _, values := range []map[string]string{ {"return_code": "SUCCESS"}, {"return_code": "SUCCESS", "result_code": "FAIL"}, {"return_code": "FAIL", "result_code": "SUCCESS"}, } { if err := validateWechatV2Response(values); err == nil { t.Fatalf("accepted unsuccessful response: %#v", values) } } if err := validateWechatV2Response(map[string]string{ "return_code": "SUCCESS", "result_code": "SUCCESS", }); err != nil { t.Fatalf("valid response rejected: %v", err) } } func TestPopulateDouyinPaymentAmountUsesSignedFieldPresence(t *testing.T) { amount := &douyin.AmountInfo{Total: 100, PayerTotal: 0, Currency: "CNY", PayerCurrency: "CNY"} result := &biz.PaymentResult{} if err := populateDouyinPaymentAmount(result, amount, []byte(`{"amount":{"total":100,"payer_total":0,"currency":"CNY","payer_currency":"CNY"}}`)); err != nil { t.Fatal(err) } if !result.AmountBreakdownKnown || result.PayerPaidAmount != 0 || result.CashPaidAmount != 0 || result.DiscountAmount != 100 { t.Fatalf("explicit zero payer_total was not preserved: %+v", result) } result = &biz.PaymentResult{} if err := populateDouyinPaymentAmount(result, amount, []byte(`{"amount":{"total":100,"currency":"CNY"}}`)); err != nil { t.Fatal(err) } if result.AmountBreakdownKnown || result.PayerPaidAmount != 0 || result.DiscountAmount != 0 { t.Fatalf("missing payer_total was treated as authoritative: %+v", result) } if err := populateDouyinPaymentAmount(&biz.PaymentResult{}, &douyin.AmountInfo{Total: 100, PayerTotal: 101}, []byte(`{"amount":{"total":100,"payer_total":101}}`)); err == nil { t.Fatal("accepted payer_total greater than total") } } func TestValidateDouyinMerchantIdentity(t *testing.T) { config := map[string]any{"merchant_id": "douyin-merchant", "app_id": "douyin-app"} if err := validateDouyinMerchantIdentity("douyin-merchant", "douyin-app", config, true); err != nil { t.Fatalf("valid identity rejected: %v", err) } for _, tc := range []struct { merchantID string appID string requireApp bool }{ {merchantID: "other", appID: "douyin-app", requireApp: true}, {merchantID: "douyin-merchant", appID: "other", requireApp: true}, {merchantID: "douyin-merchant", requireApp: true}, } { if err := validateDouyinMerchantIdentity(tc.merchantID, tc.appID, config, tc.requireApp); err == nil { t.Fatalf("accepted invalid identity: %+v", tc) } } if err := validateDouyinMerchantIdentity("douyin-merchant", "", config, false); err != nil { t.Fatalf("optional query appid rejected: %v", err) } } func TestAlipayRefundResultValidatesIdentityAndAmount(t *testing.T) { req := &biz.PaymentRefundRequest{ TradeNo: "T-ALIPAY", ProviderTradeNo: "P-ALIPAY", RefundNo: "R-ALIPAY", Amount: 123, Currency: "CNY", } valid := func() *gopayAlipay.TradeRefund { return &gopayAlipay.TradeRefund{ TradeNo: "P-ALIPAY", OutTradeNo: "T-ALIPAY", RefundFee: "1.23", RefundCurrency: "CNY", } } result, err := alipayRefundResult(req, valid(), []byte(`{"ok":true}`)) if err != nil { t.Fatal(err) } if result.Amount != 123 || result.Currency != "CNY" || result.ProviderTradeNo != "P-ALIPAY" { t.Fatalf("unexpected refund result: %+v", result) } for _, tc := range []struct { name string mutate func(*gopayAlipay.TradeRefund) want string }{ {name: "missing merchant order", mutate: func(r *gopayAlipay.TradeRefund) { r.OutTradeNo = "" }, want: "out_trade_no"}, {name: "mismatched merchant order", mutate: func(r *gopayAlipay.TradeRefund) { r.OutTradeNo = "OTHER" }, want: "out_trade_no"}, {name: "mismatched provider order", mutate: func(r *gopayAlipay.TradeRefund) { r.TradeNo = "OTHER" }, want: "trade_no"}, {name: "missing refund fee", mutate: func(r *gopayAlipay.TradeRefund) { r.RefundFee = "" }, want: "refund_fee"}, {name: "mismatched refund fee", mutate: func(r *gopayAlipay.TradeRefund) { r.RefundFee = "1.22" }, want: "金额不匹配"}, {name: "mismatched currency", mutate: func(r *gopayAlipay.TradeRefund) { r.RefundCurrency = "USD" }, want: "币种不匹配"}, } { t.Run(tc.name, func(t *testing.T) { response := valid() tc.mutate(response) _, err := alipayRefundResult(req, response, nil) if err == nil || !strings.Contains(err.Error(), tc.want) { t.Fatalf("invalid response error = %v, want %q", err, tc.want) } }) } }