Skip to content

Payment Update Flow

Jonathan Flynn edited this page May 24, 2022 · 10 revisions

Upon clicking the 'Update Payment Method' Button For card

  1. startCardUpdate() function is called.
  2. A null check is made on the recaptcha token state, if null, "Recaptcha is incomplete" error message is shown.
  3. A Stripe SetupIntent object is created via our backend endpoint '/api/payment/card', with the recaptcha token being passed as a parameter. This is the first request in the flow when processing a payment with Stripe. The setupIntent object returned contains an id and a client_secret.
  4. stripe.createPaymentMethod() is then called and used to generate a PaymentMethod object(https://stripe.com/docs/api/payment_methods/object) which validates the card.
  5. The PaymentMethod object is then passed along with the SetupIntents client secret to stripe.confirmCardSetup() to authenticate the user. This allows Zuora to take future payments from this card. All communication to Stripe's API's is now complete and the rest involves storing the new details in Zuora via our own API's.
  6. executePaymentUpdate() is called. The PaymentMethod from the SetupIntent is passed to 'api/payment' to store the new card details for the appropriate subscription in Zuora.

note: A button loader is used during Stripe validation (the first 5 steps above). As soon as executePaymentUpdate() is called, the overlay loader shows.

For direct debit

  1. If the checkbox has been checked by the user, the details are validated via our endpoint 'api/payment/validate/dd'.
  2. The same executePaymentUpdate() as used on the card form is then called.

After executePaymentUpdate() has finished updating records in zuora, the user is redirected to the confirmation page.

Error states For card

Incorrect card details and invalid or expired cards will show error messages provided by Stripe. Failure to create a setupIntent will replace the card form with a generic error screen. Once all Stripe calls have passed and the Overlay loader is showing, any subsequent errors in our own APIs will re-direct the user to a failure screen.

Exceptions sent to Sentry

error.value: "Non-Error exception captured with keys: code, message, type".
This exception is due to non-complete StripeElements fields, e.g.: incomplete card number. The response body should look like so:
{ code: incomplete_cvc, message: Le code de sécurité de votre carte est incomplet., type: validation_error }

example in Sentry

error.value: "Non-Error exception captured with keys: code, doc_url, message, payment_method"
error.value: "Non-Error exception captured with keys: code, decline_code, doc_url, message"
These are due to an error returned from the proper validation check further down the code in the stripe.createPaymentMethod function. The response body should look like so:
{ code: [Filtered], doc_url: [Filtered], message: [Filtered], payment_method: { billing_details: [Object], card: [Object], created: 1653390336, customer: None, id: pm_0L2vYRItVxyc3Q6nvpOXYxiR, livemode: True, object: payment_method, type: card }, setup_intent: { cancellation_reason: None, client_secret: [Filtered], created: 1653390334, description: None, id: seti_0L2vYQItVxyc3Q6n98P92Hyi, last_setup_error: [Object], livemode: True, next_action: None, object: setup_intent, payment_method: None, payment_method_types: [Array], status: requires_payment_method, usage: off_session }, type: invalid_request_error }

example in Sentry

Stripe client library and the API endpoints they use under the hood

To see which Stripe API endpoints functions like createPaymentMethod and confirmCardSetup are using under the hood, have a look at the updatePayment tests within the Cypress folder.

Clone this wiki locally