package stripe_test import ( "context" "fmt" "net/http" "net/http/httptest" "strings" "testing" gostripe "github.com/stripe/stripe-go/v79" "github.com/stripe/stripe-go/v79/client" "github.com/wangjia/pay/internal/provider" st "github.com/wangjia/pay/internal/provider/stripe" ) func fakeStripeRefundAPI(t *testing.T) *httptest.Server { return httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json") switch { case r.Method == http.MethodGet && strings.Contains(r.URL.Path, "/v1/checkout/sessions/cs_test_123"): // 未展开:payment_intent 是字符串 id,SDK 反序列化进 *PaymentIntent{ID} fmt.Fprint(w, `{"id":"cs_test_123","object":"checkout.session","payment_intent":"pi_test_456","amount_total":2999,"currency":"usd","payment_status":"paid"}`) case r.Method == http.MethodPost && strings.HasPrefix(r.URL.Path, "/v1/refunds"): fmt.Fprint(w, `{"id":"re_test_789","object":"refund","amount":2999,"currency":"usd","payment_intent":"pi_test_456","status":"succeeded"}`) default: http.Error(w, `{"error":{"message":"not found"}}`, http.StatusNotFound) } })) } func newStripeRefund(t *testing.T, ts *httptest.Server) *st.Provider { backends := &gostripe.Backends{ API: gostripe.GetBackendWithConfig(gostripe.APIBackend, &gostripe.BackendConfig{URL: gostripe.String(ts.URL)}), } return st.New(client.New("sk_test_x", backends), "whsec_test_secret") } func TestStripeRefundSuccess(t *testing.T) { ts := fakeStripeRefundAPI(t) defer ts.Close() p := newStripeRefund(t, ts) if !p.Capabilities().SupportsRefund { t.Fatal("stripe Capabilities.SupportsRefund 应为 true") } ref, status, err := p.Refund(context.Background(), "cs_test_123", "rf-999", 2999, "requested_by_customer") if err != nil { t.Fatalf("refund: %v", err) } if status != provider.PaidSucceeded || ref != "re_test_789" { t.Fatalf("refund result: ref=%s status=%s", ref, status) } }