feat(pay-v2): P8 Task2 PaidEvent.Kind + SubscriptionProvider + Stripe 订阅 Checkout/取消
This commit is contained in:
@@ -6,6 +6,7 @@ import (
|
||||
"crypto/sha256"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"strings"
|
||||
@@ -26,11 +27,19 @@ func fakeStripeAPI(t *testing.T) *httptest.Server {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
switch {
|
||||
case r.Method == http.MethodPost && strings.HasPrefix(r.URL.Path, "/v1/checkout/sessions"):
|
||||
// 创建 session
|
||||
fmt.Fprint(w, `{"id":"cs_test_123","object":"checkout.session","url":"https://checkout.stripe.com/c/pay/cs_test_123","amount_total":2999,"currency":"usd","payment_status":"unpaid"}`)
|
||||
// 创建 session。一次性(mode=payment)与订阅(mode=subscription)共用此分支,
|
||||
// 靠 form body 是否带 "subscription" 区分,回不同 id 供各自用例断言。
|
||||
b, _ := io.ReadAll(r.Body)
|
||||
if strings.Contains(string(b), "subscription") {
|
||||
fmt.Fprint(w, `{"id":"cs_sub_123","object":"checkout.session","url":"https://checkout.stripe.com/c/pay/cs_sub_123","mode":"subscription","amount_total":2999,"currency":"usd","payment_status":"unpaid"}`)
|
||||
} else {
|
||||
fmt.Fprint(w, `{"id":"cs_test_123","object":"checkout.session","url":"https://checkout.stripe.com/c/pay/cs_test_123","amount_total":2999,"currency":"usd","payment_status":"unpaid"}`)
|
||||
}
|
||||
case r.Method == http.MethodGet && strings.Contains(r.URL.Path, "/v1/checkout/sessions/cs_test_123"):
|
||||
// 查询 session — 已付
|
||||
fmt.Fprint(w, `{"id":"cs_test_123","object":"checkout.session","amount_total":2999,"currency":"usd","payment_status":"paid"}`)
|
||||
case r.Method == http.MethodDelete && strings.Contains(r.URL.Path, "/v1/subscriptions/sub_cancel_ok"):
|
||||
fmt.Fprint(w, `{"id":"sub_cancel_ok","object":"subscription","status":"canceled"}`)
|
||||
default:
|
||||
http.Error(w, `{"error":{"message":"not found"}}`, http.StatusNotFound)
|
||||
}
|
||||
@@ -47,6 +56,41 @@ func newStripe(t *testing.T, ts *httptest.Server) *st.Provider {
|
||||
return st.New(sc, whSecret)
|
||||
}
|
||||
|
||||
func TestCreateSubscriptionCheckout(t *testing.T) {
|
||||
ts := fakeStripeAPI(t)
|
||||
defer ts.Close()
|
||||
p := newStripe(t, ts)
|
||||
|
||||
sess, err := p.CreateSubscriptionCheckout(context.Background(), provider.CreateRequest{
|
||||
OutTradeNo: "PAY-S1", Subject: "Pro Monthly", AmountMinor: 2999, Currency: "USD",
|
||||
ReturnURL: "https://x/return", Metadata: map[string]string{"pay_sub_id": "SUB-1"},
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("create sub checkout: %v", err)
|
||||
}
|
||||
if sess.RenderType != provider.RenderRedirect || sess.ProviderRef != "cs_sub_123" {
|
||||
t.Fatalf("session = %+v", sess)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCancelSubscription(t *testing.T) {
|
||||
ts := fakeStripeAPI(t)
|
||||
defer ts.Close()
|
||||
p := newStripe(t, ts)
|
||||
if err := p.CancelSubscription(context.Background(), "sub_cancel_ok"); err != nil {
|
||||
t.Fatalf("cancel: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCapabilitiesRecurring(t *testing.T) {
|
||||
ts := fakeStripeAPI(t)
|
||||
defer ts.Close()
|
||||
c := newStripe(t, ts).Capabilities()
|
||||
if !c.SupportsRecurring || c.RecurringKind != provider.RecurringKindGatewayScheduled {
|
||||
t.Fatalf("caps = %+v", c)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCreateCheckoutRedirect(t *testing.T) {
|
||||
ts := fakeStripeAPI(t)
|
||||
defer ts.Close()
|
||||
|
||||
Reference in New Issue
Block a user