Skip to content

Checkout: add stripe-wallet payment method (Stripe Link via ExpressCheckoutElement) - #112007

Draft
martian77 wants to merge 7 commits into
trunkfrom
add/stripe-wallet-payment-method
Draft

Checkout: add stripe-wallet payment method (Stripe Link via ExpressCheckoutElement)#112007
martian77 wants to merge 7 commits into
trunkfrom
add/stripe-wallet-payment-method

Conversation

@martian77

@martian77 martian77 commented Jun 25, 2026

Copy link
Copy Markdown
Contributor

Part of SHILL-2099

Proposed Changes

  • Add a new stripe-wallet payment method backed by Stripe's ExpressCheckoutElement (ECE), scoped to Link only in this phase
  • Add WPCOM_Billing_Stripe_Walletstripe-wallet to both directions of the payment method name translation map and to the CheckoutPaymentMethodSlug / WPCOMPaymentMethod type unions
  • Add stripe-wallet-processor.ts implementing a deferred client-confirm flow: POST to /me/transactions with WPCOM_Billing_Stripe_Wallet → extract payment_intent_client_secret → call stripe.confirmPayment({ elements, clientSecret, redirect: 'if_required' }) → return success with order_id for pending-page polling
  • Nest a scoped <Elements> provider (deferred-intent mode: mode/amount/currency/setup_future_usage) inside the payment method's activeContent so ECE can render without touching the shared StripeHookProvider
  • Gate the method behind checkout/stripe-wallet feature flag (enabled in development and wpcalypso, off in production)

Why are these changes being made?

Stripe Link is an express wallet checkout that lets returning Stripe-networked users pay with a single click. The ExpressCheckoutElement is Stripe's modern unified surface for Link, Apple Pay, and Google Pay; this PR adds the frontend plumbing for the Link-only phase. The backend WPCOM_Billing_Stripe_Wallet processor is a companion piece tracked separately.

The deferred client-confirm pattern (server parks an unconfirmed PaymentIntent, client calls stripe.confirmPayment) was chosen to align with an open precedent from the Memberships team and to enable webhook-driven provisioning without a custom return-URL endpoint.

Testing Instructions

  • Requires the backend WPCOM_Billing_Stripe_Wallet processor to be in place before end-to-end testing is possible — that work is not yet merged
  • With the flag enabled locally (checkout/stripe-wallet: true) and a backend returning a mock payment_intent_client_secret, the ECE mounts under the payment method row and the Link button renders in Chrome (suppressed in Firefox with strict ETP — expected, not a bug)
  • Account alignment note: local dev with a US billing address routes to the US Stripe account where Link/ECE is configured; EU addresses route to the IE account which may not have Link active

Pre-merge Checklist

  • Has the general commit checklist been followed? (PCYsg-hS-p2)
  • Have you written new tests for your changes?
  • Have you tested the feature in Simple (P9HQHe-k8-p2), Atomic (P9HQHe-jW-p2), and self-hosted Jetpack sites (PCYsg-g6b-p2)?
  • Have you checked for TypeScript, React or other console errors?
  • For UI changes, have you tested the affected components in dark mode?
  • Have you tested accessibility for your changes? Ensure the feature remains usable with various user agents (e.g., browsers), interfaces (e.g., keyboard navigation), and assistive technologies (e.g., screen readers) (PCYsg-S3g-p2).
  • Have you used memoizing on expensive computations? More info in Memoizing with create-selector and Using memoizing selectors and Our Approach to Data
  • Have we added the "[Status] String Freeze" label as soon as any new strings were ready for translation (p4TIVU-5Jq-p2)?
    • For UI changes, have we tested the change in various languages (for example, ES, PT, FR, or DE)? The length of text and words vary significantly between languages.
  • For changes affecting Jetpack: Have we added the "[Status] Needs Privacy Updates" label if this pull request changes what data or activity we track or use (p4TIVU-aUh-p2)?

@github-actions

Copy link
Copy Markdown

Looks like one of the E2E tests has failed.

You can fix them following these steps:

  1. Check out this branch locally:
    gh pr checkout 112007
  2. Start Claude Code in the repo:
    claude
  3. Run the /fix-e2e-tests skill, passing this PR number:
    /fix-e2e-tests 112007
    

@martian77 martian77 self-assigned this Jun 25, 2026
@martian77
martian77 force-pushed the add/stripe-wallet-payment-method branch 2 times, most recently from 9b4524b to 9837cb7 Compare July 7, 2026 15:40
@martian77
martian77 force-pushed the add/stripe-wallet-payment-method branch from 9837cb7 to 8964e8b Compare July 9, 2026 11:18
@matticbot

matticbot commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

Here is how your PR affects size of JS and CSS bundles shipped to the user's browser:

Sections (~1074 bytes added 📈 [gzipped])

Details
name                               parsed_size           gzip_size
checkout                               +4558 B  (+0.2%)    +1074 B  (+0.2%)
a8c-for-agencies-marketplace           +4558 B  (+0.2%)    +1074 B  (+0.2%)
a8c-for-agencies-express-checkout      +4558 B  (+0.3%)    +1074 B  (+0.2%)
a8c-for-agencies-client                +4558 B  (+0.1%)    +1074 B  (+0.1%)
site-purchases                         +2133 B  (+0.1%)     +540 B  (+0.1%)
purchases                              +2133 B  (+0.1%)     +540 B  (+0.1%)
jetpack-cloud-partner-portal             +65 B  (+0.0%)      +23 B  (+0.0%)
a8c-for-agencies-purchases               +65 B  (+0.0%)      +23 B  (+0.0%)

Sections contain code specific for a given set of routes. Is downloaded and parsed only when a particular route is navigated to.

Async-loaded Components (~47 bytes added 📈 [gzipped])

Details
name                                                                              parsed_size           gzip_size
async-load-signup-steps-page-picker                                                    +231 B  (+0.0%)      +47 B  (+0.0%)
async-load-calypso-my-sites-checkout-purchase-modal-is-eligible-for-one-click...       +231 B  (+0.1%)      +47 B  (+0.0%)
async-load-calypso-blocks-upsell-nudge-purchase-modal-wrapper                          +231 B  (+0.0%)      +47 B  (+0.0%)

React components that are loaded lazily, when a certain part of UI is displayed for the first time.

Legend

What is parsed and gzip size?

Parsed Size: Uncompressed size of the JS and CSS files. This much code needs to be parsed and stored in memory.
Gzip Size: Compressed size of the JS and CSS files. This much data needs to be downloaded over network.

Generated by performance advisor bot at iscalypsofastyet.com.

@martian77
martian77 force-pushed the add/stripe-wallet-payment-method branch from 23d18a2 to 1d00372 Compare July 28, 2026 17:03
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