Skip to main content
A payment session and the card token it produces are both short-lived. Waiting too long between creating a session, tokenizing the card, and charging the token surfaces one of two different failures, depending on where the delay happened.
TL;DR: the session or the token from submit() went stale before you charged it → create the session right before mounting the card field, and charge the token immediately after.

When this happens

  • The session itself expires before the shopper finishes typing their card details (ttl_minutes, 5–60, set when you create the session).
  • The card token from a successful elements.submit() is transient (about 30 minutes) — the shopper stalls on a review page, or your server queues the charge instead of sending it right away.
  • The shopper switches cards mid-checkout, invalidating the token from an earlier submit().

What you see

What to do

1

Create the session per checkout attempt

Don’t create a session ahead of time and hold it — create it right before you mount the card field, so its TTL covers only the time the shopper actually needs to fill in the form.
2

Charge immediately after submit

Send the token from elements.submit() to your server and call purchase right away — don’t queue the charge or store the token for later.
3

Re-collect on a 410

If the charge itself returns token:transient-expired or token:data-purged, treat the token as unusable: create a new session, re-mount the card field, and have the shopper re-enter their card. Never retry the same charge with the same token.

Prevent it

  • Keep ttl_minutes short (30 or less) for a normal checkout — a longer TTL only makes sense if your flow has a legitimate reason to hold the session open.
  • If you add 3D Secure with Elements, keep the same session’s card token and 3DS reference paired — re-bind and re-authenticate together rather than reusing an old token with a new reference.

Test it

See Test your integration for sandbox test cards and scenarios.

Accept a card payment

The session-create-then-charge flow this page assumes.

Charge or authorize

Timeouts and retries on the charge call itself.
Last modified on September 15, 2026