Skip to main content
This guide shows you how to mount a PCI-compliant card form, wire it to a payment button, and handle the payment result. The card form and the payment button are two separate elements created from the same payrails client. The client wires them together for you: the button stays disabled until the form is valid, and clicking it validates the form, encrypts the card data, and starts the authorization.

1. Add containers to your page

2. Mount the card form

By default the form renders a card number field, separate expiry month and expiry year fields, and a CVV field. The most commonly used CardFormOptions: For the full option and event list see the payrails reference and the events reference.

3. Mount the payment button

The button starts disabled and enables automatically once the card form is valid. Pass disabledByDefault: false if you want it clickable immediately (the form is still validated on click). While the payment is in flight the button shows a loading indicator and carries the .payrails-button--loading class.

4. Handle the payment result

Payment outcomes are instance events — subscribe on the payrails client:
  • success — the payment was authorized.
  • failed — the payment failed. e.data?.code is one of the AuthorizationFailureReasons values (VALIDATION_FAILED, AUTHORIZATION_ERROR, AUTHENTICATION_ERROR, USER_CANCELLED, UNKNOWN_ERROR), importable from @payrails/web-sdk.
  • pending — the authorization is still processing and no further shopper action is required.
One listener fires for every payment method in the session; if your page mounts other payment elements too, filter with e.paymentMethodCode === 'card'. 3D Secure challenges are handled by the SDK automatically; to observe or take over the challenge, subscribe to payrails.on('actionRequired', ...) - see the events reference.

5. React to form and button state (optional)

Two button-specific events help you build custom UI around the flow:
To gate the payment right before it starts (e.g. run a last check and cancel), use the cancelable instance events:
To move focus to the first invalid field yourself (for example from your own “Pay” flow), call cardForm.focus(). cardForm.isValid exposes the current validity synchronously.
Last modified on September 30, 2026