116 lines
4.5 KiB
Go
116 lines
4.5 KiB
Go
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)
|
|
}
|
|
})
|
|
}
|
|
}
|