Skip to main content
Secure fields are PCI-compliant card inputs (card number, expiry, CVV) that the SDK renders inside isolated iframes. Unlike the SDK’s built-in form, you create and place each field independently in your own layout, with your own labels and styling. Raw card data never touches your page.
This is the Web-only granular, per-field API. If you’d rather let the SDK render its own pre-built card form instead of laying out each input yourself, use the Payment Methods List: the SDK composes and renders the form into your elementSelector, with the same PCI guarantees and less layout work.
Secure fields work for both payment (checkoutSession) and enrollment (customerSession). The fields inherit everything (session, country, language, callbacks) from the Transaction that creates them. There is no second configuration surface.

Quick start

start() tokenizes the mounted fields, creates the payment, handles 3DS, and reports the result through onStatus. The fields supply the card number, expiry, and CVV. Those never leave the iframes. Non-PCI details (holderName, and optionally installment, customer, or vaultOnSuccess) travel on start() via paymentMethod.data.
Passing number, expirationMonth, expirationYear, or securityCode in paymentMethod.data.card while secure fields are mounted throws: the iframes own the PCI data.

Managed vs manual

By default the SDK creates the payment. Provide createPayment on the config to POST the token from your own backend instead:
Always read token.checkout_session from the token instead of reusing the session you created the transaction with. After a declined payment the SDK rotates the session automatically. The token always carries the one it actually tokenized against.
Either way the SDK handles 3DS and reports through onStatus.

Declined payments and retry

When a card payment is DECLINED or fails with ERROR and the response is retryable, the SDK prepares the retry for you:
  1. The checkout session is cloned server-side and rotated into the mounted fields automatically.
  2. Field-level errors (invalid card number, invalid CVV, insufficient funds) are painted inside the matching iframes.
  3. In manual mode (createPayment on the config), onStatus receives the DECLINED / ERROR result so your page can re-enable its Pay button. In managed mode the SDK does not call onStatus for that attempt. The shopper sees the field errors and can submit again.
A decline that is not retryable reaches onStatus in both modes and closes the checkout session. The fields stay mounted with what the user typed. To retry, just call start() again: it is repeatable while secure fields are mounted, and the new attempt tokenizes against the rotated session. You do no session bookkeeping. Once the payment is final (approved, or declined without a retry), the checkout session is closed and start() throws. To take another payment, create a new checkout session on your backend and call transaction.updateCheckoutSession(newSession). The mounted fields pick it up and start() works again. Re-enable your Pay button when the start() promise settles. That works in both modes:
Disable your Pay button while a start() is in flight. Calling start() again before the previous attempt finishes throws: two tokenizations would mean two payments.

Enrollment

With a customerSession, secure fields vault a card instead of charging it. The flow is identical: create, mount, start().

Installments

Enable installments when creating the fields:
Pass the option on the first secureFields() call. The transaction keeps one secure-fields instance. Later calls return it, and a call with a different installmentEnable throws. To change the option, call transaction.unmount() and create the fields again. Available plans arrive on the pan field’s onChange as the user types: data.installments, data.fullInstallmentsInfo, and data.isInstallmentLoading. Render your own selector from that data and pass the chosen plan on start():

Fields

Create each field by name, then mount it into any element in your layout.

Field options

Pass options to create to label, style, and observe a field.

Field methods

Each field returned by create (or fetched later with getElement({ name })) exposes:

Instance members

To point the transaction at a new checkout session, call transaction.updateCheckoutSession(): the mounted fields pick it up automatically.

Notes

  • One completion path. Tokenization, payment creation, 3DS, and status all live inside start(): there is no generateToken or continuePayment() to sequence yourself. To create the payment from your own backend, use manual mode (createPayment). The SDK still owns 3DS and the result.
  • PCI scope is unchanged. Raw card data stays inside the SDK’s iframes; your code never reads it.
  • One card surface per page. Create secure fields on one transaction at a time. Wallet buttons and the payment methods list from getPaymentMethodsViews can share the page and the transaction: a CARD start() routes to your fields, wallet buttons drive themselves.