The Payment Element, and the rules worth knowing before you wire production.
parameter_unknown, not ignored./check? Set
body ip to the shopper.ev: or
wp:v1:); raw digits are rejected.three_ds.session_id, never client cavv/eci, and never alongside a
wallet.risk_decision_token only rejects mismatches./check so the decision token can
bind the card.pk_ in the browser with allowed domains set;
sk_ never here. Merchant and mode come from the key, not the body.onSuccess with succeeded or
processing, and onError with
card_declined. Never show a raw fraud reason to a buyer.processing. Wait for the
charge.succeeded webhook. The buyer may close the tab.
Canonical list: 27-integration-hard-rules.md. View Source for what this
page deliberately does not contain.
Card fields, wallets and the 3-D Secure challenge are all inside this frame.
Test cards: 4111 1111 1111 1111 approves, and so do the other
sandbox test numbers in the testing guide. A decline needs an amount under 1.00,
which this fixed-amount demo cannot produce. The same card at the same amount
within 20 minutes is refused as a duplicate, so switch cards between tries.
Any future expiry, CVV 123.
In the frame (not your page): card entry, encryption, wallets, device signals, the 3DS challenge.
On our servers, always: pre-screen, scoring, device intelligence, the 3DS decision, the block gate. On every charge, with or without a decision token.
Derived server-side (body ignored if you send it): charge IP, is_mit, is_new_card, whether the 3DS cryptogram is real.
In your page: the mount call and your own UI. That is all, and it is the point.
Allowed domains must be set on the publishable key
(Settings → Developers → API keys), or the frame renders blank.
Update the list on the key without rolling the secret. Parent pages must be
https://. http://localhost and
http://127.0.0.1 are the local exception.
Verify the charge.succeeded webhook signature and fulfil from it,
not from onSuccess.