0xtrails@0.19.0 or later. Access is arranged through Polygon Checkout; the stripe prop fails at quote time until a Stripe merchant key is mapped to your Trails project.
Quick start
stripe prop forces pay mode and derives the destination server-side, so the destination props (toAddress, toAmount, toChainId, toToken, toCalldata, actions, and the advanced settlement prop) must be left unset. Passing any of them alongside stripe throws at render.
Use
TrailsWidget from 0xtrails for Stripe checkout. The focused <Pay /> component requires a to destination, which conflicts with the server-derived one, and does not expose onPaymentCreated.How it works
All Stripe knowledge lives in the Trails API. The SDK forwards a settlement request through the normal quote flow, and the API creates and arms a Stripe PaymentIntent, allocates the USDC deposit address, and derives the destination from it. Trails routes the shopper’s token into that deposit, and the settle step is tracked on the intent receipt until Stripe attributes the deposit. No Stripe key ever reaches the browser, and no merchant backend is required to take a payment. The wire types shipped earlier in@0xtrails/api@0.18.5.
Origins must be EVM chains; settlement quotes are not supported from non-EVM (edge) origins.
The stripe prop
Changing
amountCents while orderRef stays the same keeps the checkout reference: the API cancels the armed payment and re-arms it at the new amount. When orderRef is omitted, one checkout reference spans the lifetime of the stripe prop, so set the prop to undefined between purchases on a long-lived mount.
Use getStripeSettlementChainIds(mode) to validate a chain taken from untrusted input before passing it as chainId:
Callbacks
QuoteSettlementInfo has provider, reference (the Stripe PaymentIntent id), currency, amountCents, amountUsd, livemode and chainId.
IntentSettlement adds the live state: status (raw Stripe status), settled, failed, terminal, and externalUrl (the Stripe-hosted receipt once available). Key terminality on terminal, never on the status string. terminal can be true with both settled and failed false when the payment was retired with an unknown outcome, so gate fulfillment on settled alone.
Flow
- The widget quotes with a
settlementdescriptor instead of a destination. The API creates and arms a Stripe PaymentIntent for the checkout reference and returns the derived destination.onPaymentCreatedfires. - The shopper picks any token on any chain and confirms once. Trails swaps, bridges and deposits USDC to the Stripe-allocated address.
- The intent reaches its terminal on-chain status. The pending screen shows a single processing state instead of per-hop steps.
- Stripe attributes the deposit, usually within one to two minutes. The receipt’s
settlement.settledflips, the receipt screen shows the Stripe receipt link, andonSuccessfires.
Bounded waits
Settlement tracking fails open rather than holding checkout forever. If the payment stays pending past the hold window,onSuccess fires with the pending settlement attached (settled: false) and polling continues slowly in the background. A failed payment releases the same way with settlement.failed set. The windows are exported as constants (INTENT_SETTLEMENT_POLL_MS, INTENT_SETTLEMENT_PENDING_HOLD_MS) if you need to mirror them.
Verify before you fulfill
Read the intent receipt with theGetIntentReceipt endpoint and compare settlement to the order:
Tracking settlement outside the widget
An order confirmation page that outlives the widget can poll the receipt itself withuseIntentSettlement. See Settlement in the hooks reference for the hook, its state shape and a full example.
Presentation
Thestripe prop implies merchantCheckout, which renders the widget as a payment step rather than a standalone transfer tool: one processing state while pending, and a receipt that keeps only the payment receipt links (no explorer link, completion time or “Start new transaction”). Set merchantCheckout={false} to keep the standalone presentation, or set it to true on any other integration to borrow the checkout look.
The recipient selector is read-only for settlement checkouts, since the deposit address belongs to Stripe.
Headless
Everything the widget does is available to headless integrations:useQuoteaccepts asettlementoption (QuoteSettlementParams:provider: 'stripe',amountCents,checkoutRef,orderRef?,chainId?) and the quote result carriessettlement. The hook still needs atowithchain,tokenandrecipientbefore it quotes; pass the settlement chain and its USDC address as placeholders (the widget uses the USDC contract address as the recipient). The SDK strips them from the request and the API derives the real destination from the armed payment. Do not passto.calls,to.calldata,actionsorfrom.amount: settlement quotes are exact-output and the hook throws on those.- The advanced
settlementwidget prop takes the same params directly when you manage the checkout reference lifecycle yourself. useIntentSettlementandgetTrailsClientcover receipt polling.
QuoteIntent and GetIntentReceipt.
Test mode
With a Stripe test-mode merchant key, deposits settle on Base Sepolia only andstripe.testMode must be set. Requesting any other chainId under a test key is rejected before a payment is created. Treat test-mode checkouts as an integration check, not a pricing check.
Compared with the Stripe onramp
The onramp is the reverse direction: a card funds crypto into an intent. The two can be combined, so a checkout with thestripe prop can still offer the Stripe onramp tile as one way for the shopper to fund the payment. See the Stripe overview for a side-by-side comparison.