Skip to content

add stripe 3ds support - #1450

Open
pbennett1-godaddy wants to merge 21 commits into
mainfrom
add-stripe-3ds-support
Open

pbennett1-godaddy wants to merge 21 commits into
mainfrom
add-stripe-3ds-support

Conversation

@pbennett1-godaddy

@pbennett1-godaddy pbennett1-godaddy commented Sep 8, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Adds backward-compatible Stripe 3DS support to the React checkout card flow.

When checkout confirmation returns a valid PAYMENT_ACTION_REQUIRED GraphQL error from checkout-api, the frontend now:

  1. Preserves and validates the GraphQL error extensions.
  2. Keeps checkout locked while customer authentication is in progress.
  3. Calls stripe.handleNextAction with the returned client secret.
  4. Retries checkout confirmation using the resulting Stripe PaymentIntent ID.
  5. Completes tracking and redirects only after final confirmation succeeds.

Stripe next actions are only invoked when the response contains the complete expected contract:

  • code = PAYMENT_ACTION_REQUIRED
  • paymentResult.status = ACTION_REQUIRED
  • paymentResult.provider = STRIPE
  • nextStep.type = SDK_ACTION
  • nextStep.sdk = STRIPE_JS
  • nextStep.action = HANDLE_NEXT_ACTION
  • a non-empty nextStep.clientSecret

Existing payment success and error behavior remains unchanged for older checkout-api responses, non-Stripe providers, and malformed action-required responses. Stripe failures and repeated
action-required responses fail safely and unlock checkout without entering a retry loop.

The Stripe card button also uses the local payment-processing state to prevent duplicate submissions during tokenization and 3DS authentication.

Changeset

  • Changeset added (docs)

Added a patch changeset for @godaddy/react.

Test Plan

  • Added coverage verifying GraphQL error extensions, including nested paymentResult.nextStep, are preserved.
  • Added Stripe checkout integration coverage for:
    • valid 3DS response handling
    • calling stripe.handleNextAction with the client secret
    • retrying confirmation with the returned pi_* PaymentIntent ID
    • retaining existing behavior for legacy GraphQL errors
    • rejecting malformed action-required responses
    • unlocking checkout when Stripe authentication fails
  • Ran React package typecheck successfully:

pnpm --dir packages/react typecheck

  • Ran the React test suite successfully:

pnpm --dir packages/react test

Result: 58 test files passed, 578 tests passed.

  • Verified no whitespace errors with:

git diff --check

@pbennett1-godaddy
pbennett1-godaddy requested a review from a team as a code owner September 8, 2026 19:22
@changeset-bot

changeset-bot Bot commented Sep 8, 2026 •

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: a89eb45

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 2 packages
Name Type
@godaddy/react Patch
@godaddy/localizations Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

pbennett1-godaddy and others added 20 commits September 14, 2026 09:06
checkout-api returns a null draftOrder once an order is paid or awaiting
offline payment, so the paid-order redirect and lost-response recovery
never saw PAID, and a returning shopper with a paid order was sent to
returnUrl. Read CheckoutSession.orderStatus through a separate query and
redirect to successUrl when payment is PAID or PENDING (not CANCELED).
Without orderStatus (older API) the lookup fails quietly and the existing
returnUrl fallback applies.

The test API mock now nulls draftOrder for non-mutable orders, matching
checkout-api, so these paths are exercised as they behave in production.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
A blocked express confirmation returned without calling paymentFailed, so
the wallet sheet waited for an outcome that never came. It now fails the
sheet without tracking a payment error.

The order-status lookup ran on every checkout load and window focus. A
focus refetch counted as in-flight work and could block an express
confirmation started as a wallet popup closed. Fetch it only when the
draft order is unavailable (always the case for paid or pending orders),
never on focus; confirmation recovery still fills it directly.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

@wcole1-godaddy wcole1-godaddy left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed together with checkout-api #182, platform-applications-router #64, and applications-post-actions-service #7 as one feature.

Approving. Stripe next actions run only on the complete expected contract, the pending intent is retained across ambiguous failures and remounts, blocked express confirmations now close the wallet sheet (a89eb45), and the order-status lookup is lazy with focus refetch off. Legacy error handling is unchanged for older checkout-api responses. Analytics owners should note the new expressCheckoutCompleted event.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants