Skip to main content

Customize

Style the card fields, choose which fields to render, restrict accepted brands, and configure privacy behavior. All configuration is passed to SecureFieldsConfig at initialization — the SDK has no runtime API to change styles, placeholders or fields after SecureFieldsManager is created.

Apply styles

Pass a SecureFieldsStyle in SecureFieldsConfig. Styles are applied to all fields at once.

SecureFieldsConfig(
tenantId: "${TENANT_ID}",
environment: .sandbox,
style: SecureFieldsStyle(
font: UIFont.systemFont(ofSize: 16, weight: .regular),
textColor: UIColor.label,
placeholderColor: UIColor.placeholderText,
tintColor: UIColor.systemBlue,
keyboardAppearance: .default
)
)

Style properties

PropertyTypeDefaultDescription
fontUIFont.systemFont(ofSize: 16)Text font for all inputs
textColorUIColor.labelInput text color
placeholderColorUIColor.placeholderTextPlaceholder text color
tintColorUIColor.systemBlueCursor and selection highlight color
keyboardAppearanceUIKeyboardAppearance.defaultLight or dark keyboard

Set placeholders

Pass a SecureFieldsPlaceholders in SecureFieldsConfig:

SecureFieldsConfig(
tenantId: "${TENANT_ID}",
environment: .sandbox,
placeholders: SecureFieldsPlaceholders(
pan: "1234 5678 9012 3456",
cvv: "CVV",
expDate: "MM/YY",
holderName: "Cardholder name"
)
)

A per-field placeholder set in fields (below) takes precedence over this object.

Configure fields

SecureFieldsConfig.fields takes a SecureFieldsFieldsConfig that decides which fields exist and, for each, an optional placeholder and accessibilityLabel. Presence decides rendering: a field left out is hidden, takes no part in form validity, and is absent from the tokenization request. The default is .all.

SecureFieldsConfig(
tenantId: "${TENANT_ID}",
environment: .sandbox,
fields: SecureFieldsFieldsConfig(
pan: .init(placeholder: "1234 5678 9012 3456", accessibilityLabel: "Card number"),
expDate: .init(placeholder: "MM/YY"),
cvv: .init(placeholder: "CVV", accessibilityLabel: "Security code")
)
)

accessibilityLabel is applied as the view's VoiceOver label. The field's value stays hidden from the accessibility API regardless.

Available fields

FieldRequiredDescription
cvvYesCard verification value
panNoPrimary account number. Requires expDate
expDateNoExpiration date
holderNameNoCardholder name

cvv is the only required field. Omit the others to render a CVV-only form — for example, when the customer has a stored card and only needs to re-enter the security code. manager.configuredFields lists the fields present so your layout can mount exactly those views.

A PAN field requires an expiry field

SecureFieldsFieldsConfig refuses a pan without an expDate at init time: the gateway rejects a card without an expiry, and submit() has no expiry override to supply one.

CVV-only form

let secureFields = SecureFieldsManager(
config: SecureFieldsConfig(
tenantId: "${TENANT_ID}",
environment: .sandbox,
brands: [.amex], // the saved card's brand → the CVV field expects 4 digits
fields: .cvvOnly // or SecureFieldsFieldsConfig(cvv: .init(placeholder: "CVV"))
)
)
view.addSubview(secureFields.cvvView) // the only view to mount

In this mode:

  • No BIN lookup runs, so the brand comes from you. brands sets the CVV length at init: one configured brand applies as-is ([.amex] → 4 digits), several accept the union of their lengths ([.visa, .amex] → 3 or 4). Name it later with secureFields.selectBrand(.amex); expectedLengths(for: .cvv) tells you which length is expected. secureFieldsBrandsDetected never fires.
  • secureFieldsFormValidityChanged follows the CVV alone.
  • submit() sends the CVV on its own — no card block — and ignores selectedNetwork and saveToken with a console warning. See Submit a CVV-only form.
  • TokenizationResult.bin, lastFourDigits and selectedNetwork are nil and detectedBrands is empty. vaultFormToken is the token to send to your backend, as for a full form.
Not available in CVV-only mode

The Oney date-of-birth input: the CVV field stays in digit mode whatever brands contains.

Restrict accepted brands

Pass brands in SecureFieldsConfig to limit which card networks are accepted. The SDK filters BIN lookup results against this list, in your order — the order expresses a commercial preference: for a co-branded card, the first configured brand that matches is pre-selected in the brand selector, and secureFieldsBrandsDetected reports brands in that same order.

SecureFieldsConfig(
tenantId: "${TENANT_ID}",
environment: .sandbox,
brands: [.carteBancaire, .visa, .mastercard, .oney] // CB preferred over VISA for co-branded cards
)

Brand names that cross a JSON boundary (a React Native / Flutter bridge, a server-pushed config) can use the vault API vocabulary as well: CardBrand(apiValue:) accepts both the enum raw values ("AMEX") and the API scheme names ("AMERICAN_EXPRESS").

Supported brands

BrandCardBrand casePAN formatCVV
Visa.visa4-4-4-4 (16 digits)3 digits
Mastercard.mastercard4-4-4-4 (16 digits)3 digits
American Express.amex4-6-5 (15 digits)4 digits
Maestro.maestro4-4-4-4 (16 digits)3 digits
Carte Bancaire.carteBancaire4-4-4-4 (16 digits)3 digits
Oney.oney4-4-4-4-3 (19 digits)Date of birth

PAN length and CVV length are driven by the BIN lookup API response, not hardcoded in the SDK. CardBrand.allCases is the default if brands is omitted.

Oney switches CVV to a date picker

When .oney is the selected brand, the CVV field switches to date-of-birth input mode (a date picker, stored as YYYY-MM-DD). The date never goes on the wire — the tokenization request simply omits cvv — and the SDK hands it back to you in TokenizationResult.birthDate, as on web and Android.

Layout

Each field is exposed as an opaque UIView. Embed them anywhere in your view hierarchy — Auto Layout or frame-based layout both work. Fields typically look correct at a height of 44–56pt. Mount only the views listed in secureFields.configuredFields; a view whose field is not configured is hidden and inert.

view.addSubview(secureFields.panContainer) // SecurePANContainer: UIView, includes brand selector
view.addSubview(secureFields.cvvView) // UIView
view.addSubview(secureFields.expDateView) // UIView
view.addSubview(secureFields.holderNameView) // UIView
PropertyTypeDescription
panContainerSecurePANContainerPAN input + optional brand selector for co-branded cards
cvvViewUIViewCVV / date-of-birth input
expDateViewUIViewExpiry date (MM/YY)
holderNameViewUIViewCardholder name (free text)

The underlying UITextField subclasses are internal to the SDK and cannot be accessed through any cast.

Require the cardholder name

The cardholder name is optional at tokenization and does not count toward form validity by default — so a layout that never mounts holderNameView can still reach a valid form. If your checkout requires it, opt in:

SecureFieldsConfig(
tenantId: "${TENANT_ID}",
environment: .sandbox,
requiresHolderName: true
)

With the flag set, secureFieldsFormValidityChanged stays false and submit() fails with .fieldsIncomplete until the cardholder name is non-empty. The flag has no effect when fields leaves holderName out.

Privacy overlay

The SDK automatically places a UIBlurEffect overlay over all card fields when the app enters the background or screen recording starts, preventing card numbers from appearing in app-switcher thumbnails or screen recordings.

This is on by default. Disable it only if your app handles backgrounding separately:

secureFields.obscuresOnBackground = false

See Security and compliance for the full list of privacy protections.