Skip to main content

Apple Pay Checkout Flow

Source: .agents/references/features/apple-pay-checkout-flow.md

Content

Apple Pay Checkout Flow

Purpose

Apple Pay uses Stripe Payment Element, but it cannot follow the same submit order as card, PayPal, Ebanx, or other wallet flows. The Apple Pay sheet must open from the user's click/tap activation.

Required Difference

  • Apple Pay: call elements.submit() immediately after the user submits checkout, before async checkout-state updates, form validation chains, or backend calls.
  • Other Stripe methods: validate/update checkout state first, then call elements.submit() before creating the payment method.
  • After Apple Pay wallet collection succeeds, reuse the normal Stripe path, but pass the local skip flag so the later Stripe handler does not call elements.submit() again.

Why

Browsers require Apple Pay to be invoked directly from a user activation event. If we move elements.submit() after awaited validation, checkout-state updates, or API calls, Safari can reject the sheet with an activation error. The early submit preserves the activation window; the later skip prevents double wallet collection.

Flow

Live Entrypoints

  • src/pages/checkout-global/hooks/useCompleteCheckout.js
  • src/pages/subscribe-plan/components/PlanPayment/PlanPaymentProvider.tsx
  • src/pages/[communityLink]/physical-products/components/checkout/paymentSection/CheckoutProductPaymentForm.tsx

Gotcha

Do not "clean up" Apple Pay by moving its elements.submit() next to the generic Stripe submit call. That breaks the user-activation contract even if the rest of the code still looks logically equivalent.