Skip to main content
This guide shows you how to build your own card form field by field: create a collect container, mount individual secure input elements into your page, validate them, and collect the card data as an encrypted payload - or save it as a reusable payment instrument. Secure fields are pre-built form elements hosted by Payrails and injected into your web page as iframes. Sensitive card data never touches your front-end application, which reduces your PCI compliance scope.

1. Create a collect container

Create a container for the secure fields with the collectContainer() method of the Payrails client:
You choose how the fields end up on the page by how you mount them:
  • mount each element individually wherever you want on the page (element.mount(selector)) — use this when you control the markup around every field, or
  • mount the container once with container.mount(selector) to render all created elements into a single wrapper.
The container accepts an optional containerId and fonts — see How to customize the checkout’s appearance for font loading.
Styling happens per element via appearance (step 2).

2. Create collect elements

Create one element per field with createCollectElement(options):
The options object:
The type field takes a Payrails ElementType. Each type applies the appropriate formatting and validations to the field:
  • CARD_NUMBER
  • CARDHOLDER_NAME
  • CVV
  • EXPIRATION_MONTH
  • EXPIRATION_YEAR
  • EXPIRATION_DATE
The format values accepted for EXPIRATION_DATE are:
  • MM/YY (default)
  • MM/YYYY
  • YY/MM
  • YYYY/MM
The format values accepted for EXPIRATION_YEAR are:
  • YY (default)
  • YYYY
If format is not specified, or an invalid value is passed, the default is used. For the appearance rules syntax, class names, and state modifiers (.payrails-input--invalid, …) see How to customize the checkout’s appearance.

3. Mount the elements to the DOM

Create placeholder <div> elements with unique id attributes where the fields should render:
Then mount each element into its placeholder:
Use unmount() to remove an element from the DOM:

4. React to element events (optional)

Every element exposes the typed on(eventName, handler) method shared by all SDK elements; secure fields emit 'change', 'focus', 'blur', and 'ready' . on() returns an unsubscribe function:

5. Validate and collect the data

When the form is ready to be submitted, you can first validate all fields:
Then call collect() on the container. All created elements must be mounted. The card data is encrypted inside the secure iframes and returned as an opaque payload - the raw values are never exposed to your code:
collect() rejects with a validation error when a field is incomplete or invalid.

6. Save the card as a payment instrument (optional)

To store the collected card for later payments, call tokenize() instead of collect(). It collects and encrypts the data, then saves it to Payrails as a payment instrument for the customer (holder) the SDK session was initialized for:
The response contains the new instrument’s id, status, and card metadata such as data.bin, data.network, and data.suffix.

End-to-end example

Default validations

Every element type has a set of built-in validations:
  • CARD_NUMBER: card number validation with checksum (Luhn algorithm) and card-scheme-aware length and formatting. A valid 16 digit card number is formatted as XXXX XXXX XXXX XXXX.
  • CARDHOLDER_NAME: name should be 2 or more symbols; valid characters match the pattern ^([a-zA-Z\\ \\,\\.\\-\\']{2,})$.
  • CVV: 3–4 digits.
  • EXPIRATION_DATE: any date starting from the current month, in the configured format (default MM/YY).
  • EXPIRATION_MONTH: a valid month (01–12).
  • EXPIRATION_YEAR: the current year or later, in the configured format(default YY).

UI errors for collect elements

You can display custom error messages on the elements with setError and resetError. setError(error: string) overrides any current error on the element with the custom message. The message stays visible until resetError() is called on the same element. resetError() clears the custom error message set by setError.

Last modified on September 30, 2026