Skip to main content
Card fields validate as the shopper types and report state on every keystroke through the change event — there’s no separate “submit and see what’s wrong” step.
TL;DR: change fires with event.valid: false and an event.error → gate the Pay button on valid and show error.message inline.

When this happens

  • The shopper is still typing (incomplete number, expiry, or CVV).
  • The card number fails a brand/Luhn check, or the detected brand isn’t one you support.
  • The expiry date is invalid or already in the past.
  • The CVV doesn’t match the expected length for the detected brand.
  • On pre-15.4 Safari without BroadcastChannel, a split expiry/CVV field can’t relay its value to the primary field.

What you see

What to do

1

Gate the pay button on valid

Disable submission until every mounted field reports valid: true. event.error can still be null here — it’s only set once blur-time validation runs — so don’t gate on error being absent. Don’t rely on a separate manual validation pass.
2

Show the error only while it's present

event.error is null once the field becomes valid again — clear your inline message in that case rather than leaving a stale error visible.
3

Handle the Safari fallback

If you support split fields and see repeated expiry_missing/cvv_missing on older Safari, either advise the shopper to update their browser or switch to the combined card element, which doesn’t need cross-iframe relay.

Prevent it

  • Prefer the combined card element unless you specifically need a custom layout — it has no BroadcastChannel dependency and one fewer iframe to coordinate.
  • Advertise supported card brands with supportedBrands so shoppers see upfront which cards you accept, before they type a full number.

Card fields and events

Element types, create options, events, and Safari notes.

Accept a card payment

Where the change event fits in the full charge flow.
Last modified on September 15, 2026