Skip to content

Commit 9f332c2

Browse files
committed
Test payment confirm method for Stripe SCA flow
1 parent 1ec59d5 commit 9f332c2

File tree

1 file changed

+67
-5
lines changed

1 file changed

+67
-5
lines changed

api/payments_test.go

Lines changed: 67 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -441,7 +441,7 @@ func TestPaymentCreate(t *testing.T) {
441441
test.Config.Payment.Stripe.UsePaymentIntents = true
442442

443443
callCount := 0
444-
stripe.SetBackend(stripe.APIBackend, NewTrackingStripeBackend(func(method, path, key string, params stripe.ParamsContainer, v interface{}) {
444+
stripe.SetBackend(stripe.APIBackend, NewTrackingStripeBackend(func(method, path, key string, params stripe.ParamsContainer, v interface{}) error {
445445
switch path {
446446
case "/v1/payment_intents":
447447
payload := params.GetParams()
@@ -470,8 +470,10 @@ func TestPaymentCreate(t *testing.T) {
470470
}
471471

472472
callCount++
473+
return nil
473474
default:
474475
t.Fatalf("unknown Stripe API call to %s", path)
476+
return &stripe.Error{Code: stripe.ErrorCodeURLInvalid}
475477
}
476478
}))
477479
defer stripe.SetBackend(stripe.APIBackend, nil)
@@ -515,15 +517,17 @@ func TestPaymentCreate(t *testing.T) {
515517
test := NewRouteTest(t)
516518

517519
callCount := 0
518-
stripe.SetBackend(stripe.APIBackend, NewTrackingStripeBackend(func(method, path, key string, params stripe.ParamsContainer, v interface{}) {
520+
stripe.SetBackend(stripe.APIBackend, NewTrackingStripeBackend(func(method, path, key string, params stripe.ParamsContainer, v interface{}) error {
519521
switch path {
520522
case "/v1/charges":
521523
payload := params.GetParams()
522524
assert.Equal(t, test.Data.firstOrder.ID, payload.Metadata["order_id"])
523525
assert.Equal(t, "1", payload.Metadata["invoice_number"])
524526
callCount++
527+
return nil
525528
default:
526529
t.Fatalf("unknown Stripe API call to %s", path)
530+
return &stripe.Error{Code: stripe.ErrorCodeURLInvalid}
527531
}
528532
}))
529533
defer stripe.SetBackend(stripe.APIBackend, nil)
@@ -552,6 +556,65 @@ func TestPaymentCreate(t *testing.T) {
552556
})
553557
}
554558

559+
func TestPaymentConfirm(t *testing.T) {
560+
tests := map[string]struct {
561+
Status string
562+
OK bool
563+
ExpectedStatus int
564+
ExpectedAPICalls int
565+
}{
566+
"default": {models.PendingState, true, http.StatusOK, 1},
567+
"idempotent": {models.PaidState, true, http.StatusOK, 0},
568+
"declined": {models.PendingState, false, http.StatusBadRequest, 1},
569+
}
570+
571+
for name, testParams := range tests {
572+
t.Run(name, func(t *testing.T) {
573+
test := NewRouteTest(t)
574+
test.Config.Payment.Stripe.UsePaymentIntents = true
575+
576+
callCount := 0
577+
stripe.SetBackend(stripe.APIBackend, NewTrackingStripeBackend(func(method, path, key string, params stripe.ParamsContainer, v interface{}) error {
578+
if path == fmt.Sprintf("/v1/payment_intents/%s/confirm", stripePaymentIntentID) {
579+
if intent, ok := v.(*stripe.PaymentIntent); ok {
580+
intent.ID = stripePaymentIntentID
581+
intent.Status = stripe.PaymentIntentStatusSucceeded
582+
} else {
583+
t.Errorf("unknown response receiver: %T", v)
584+
}
585+
callCount++
586+
587+
if !testParams.OK {
588+
return &stripe.Error{Code: stripe.ErrorCodeCardDeclined, HTTPStatusCode: http.StatusForbidden}
589+
}
590+
591+
return nil
592+
}
593+
594+
t.Fatalf("unknown Stripe API call to %s", path)
595+
return &stripe.Error{Code: stripe.ErrorCodeURLInvalid}
596+
}))
597+
defer stripe.SetBackend(stripe.APIBackend, nil)
598+
599+
test.Data.firstOrder.PaymentState = testParams.Status
600+
require.NoError(t, test.DB.Save(test.Data.firstOrder).Error, "Failed to update order")
601+
test.Data.firstTransaction.Status = testParams.Status
602+
test.Data.firstTransaction.ProcessorID = stripePaymentIntentID
603+
require.NoError(t, test.DB.Save(test.Data.firstTransaction).Error, "Failed to update transaction")
604+
605+
recorder := test.TestEndpoint(http.MethodPost, fmt.Sprintf("/payments/%s/confirm", test.Data.firstTransaction.ID), nil, test.Data.testUserToken)
606+
607+
trans := models.Transaction{}
608+
extractPayload(t, testParams.ExpectedStatus, recorder, &trans)
609+
if testParams.OK {
610+
assert.Equal(t, models.PaidState, trans.Status)
611+
}
612+
assert.Equal(t, testParams.ExpectedAPICalls, callCount)
613+
})
614+
}
615+
616+
}
617+
555618
func TestPaymentPreauthorize(t *testing.T) {
556619
t.Run("PayPal", func(t *testing.T) {
557620
testURL := "/paypal"
@@ -788,7 +851,7 @@ func (mp *memProvider) confirm(paymentID string) error {
788851
return nil
789852
}
790853

791-
type stripeCallFunc func(method, path, key string, params stripe.ParamsContainer, v interface{})
854+
type stripeCallFunc func(method, path, key string, params stripe.ParamsContainer, v interface{}) error
792855

793856
func NewTrackingStripeBackend(fn stripeCallFunc) stripe.Backend {
794857
return &trackingStripeBackend{fn}
@@ -799,8 +862,7 @@ type trackingStripeBackend struct {
799862
}
800863

801864
func (t trackingStripeBackend) Call(method, path, key string, params stripe.ParamsContainer, v interface{}) error {
802-
t.trackingFunc(method, path, key, params, v)
803-
return nil
865+
return t.trackingFunc(method, path, key, params, v)
804866
}
805867

806868
func (t trackingStripeBackend) CallMultipart(method, path, key, boundary string, body *bytes.Buffer, params *stripe.Params, v interface{}) error {

0 commit comments

Comments
 (0)