Secure Fields for card payments
Stitch provides Secure Fields within client SDKs so merchants can collect sensitive card details for payment. Encrypted card details never reach your server unencrypted, while you still control a fully customisable checkout experience.
Key features of Stitch Secure Fields include:
- Automatic input formatting and validation as customers type
- Responsive design to fit seamlessly on any screen size
- Custom styling rules to match the look and feel of your app or site
- No PCI-DSS compliance requirement for the merchant for handling raw card data (raw PAN and CVC never enter your process)
Usage overview
The Secure Fields SDK returns encrypted details (limiting PCI-DSS scope), which you forward to your backend and use as inputs when creating transactions in:
Platform differences are package install, component APIs, theming, and payload property names (card.number / card.cvc on Web vs card.encryptedNumber / card.encryptedCvc on mobile typed APIs). The client journey is the same on every SDK.
Once-off Card with Secure Fields
Client-side Secure Fields across SDKs: render fields, collect encrypted card data and fingerprint, POST to your backend.
What you send to your backend
Only forward a payload when the form reports isComplete and isValid. Always include encrypted PAN/CVC, expiry, bin, last four, cardholder name (if collected), and fingerprint.
Field mapping (SDK → GraphQL)
When the Secure Fields SDK reports a complete, valid payload, forward the encrypted card data and fingerprint to your backend. Your server maps those SDK fields into GraphQL initiateTransaction (or tokenization) inputs as follows:
| Concept | Web SDK (@stitch-money/react / web) | Mobile typed APIs (iOS / Android / Flutter / React Native) | GraphQL |
|---|---|---|---|
| Encrypted PAN | card.number | card.encryptedNumber | paymentMethods.card.cardDetails.redacted.redactedCardNumber (encryptedPan) |
| Encrypted CVC | card.cvc | card.encryptedCvc | paymentMethods.card.cardDetails.redacted.redactedSecurityCode (encryptedSecurityCode) |
| Expiry month / year | card.expiry.month / card.expiry.year | card.expiryMonth / card.expiryYear | expiryMonth / expiryYear |
| BIN | card.bin | card.bin | bin |
| Last 4 | card.lastFour | card.lastFour | last4 |
| Cardholder name | card.name | card.holderName | cardHolderName |
| Device fingerprint | fingerprint | fingerprint | deviceInformation.fingerprint |
Always forward bin, last4, and fingerprint together with the encrypted PAN and CVC. The once-off and tokenization APIs require bin and last4; fingerprinting is required for many risk and consent flows.
Client apps must not call Stitch GraphQL with secret credentials. Always proxy through your backend.
Platform setup and API reference
Install packages via Cloudsmith using the coordinates and versions from onboarding (see Install via Cloudsmith).
- Web
- iOS
- Android
- Flutter
- React Native
Packages: @stitch-money/react (React) or @stitch-money/web (non-React web components). Registry setup and version pins are covered in Install via Cloudsmith.
# React
npm install @stitch-money/react
# Non-React
npm install @stitch-money/web
The SDK consists of two components:
- Stitch Secure Form - Contains shared logic and coordinates Stitch Secure Fields composed within the component. It must be placed high enough in your component tree to wrap all instances of
<StitchSecureField>. - Stitch Secure Field - An individual field for capturing one aspect of the customer's card. You require at least two fields to capture the
numberandcvc.
Fields render in PCI-compliant iframes; your page never sees the raw PAN or CVC.
Stitch Secure Form
React
This component accepts the following properties:
| Name | Description |
|---|---|
clientId | The client ID assigned to you by Stitch that you will be processing your transactions on. |
onReady | A function for handling the ready event emitted when all secure fields have loaded successfully. |
onChange | A function for handling change events emitted when the customer makes changes to any of the secure fields. |
theme | (Optional) A custom theme which changes the appearance of the secure fields; supports most CSS attributes. |
import { StitchSecureForm } from '@stitch-money/react';
export function PaymentPage() {
const handleSecureFormChange = ({ payload }) => {
console.log(payload);
if (payload.isComplete) {
// Send encrypted card data to your backend, which calls the Stitch API
sendEncryptedCardDataToBackend(payload);
}
};
const handleSecureFormReady = () => {
// Toggle visibility of loaded Secure Field components
console.log('Secure Fields Loaded');
};
const theme = {
styles: {
':root': {
'color-scheme': 'dark',
},
// Style all field inputs
'.field input': {
marginTop: 8,
padding: '8px 12px',
},
},
};
return (
<div>
<StitchSecureForm
clientId="your Stitch client ID"
onReady={handleSecureFormReady}
onChange={handleSecureFormChange}
theme={theme}
>
{/* add child secure field components */}
</StitchSecureForm>
</div>
);
}
Non-React
This component accepts the following properties:
| Name | Description |
|---|---|
clientId | The client ID assigned to you by Stitch that you will be processing your transactions on. |
theme | (Optional) A custom theme which changes the appearance of the secure fields; supports most CSS attributes. |
The following are event listeners on the form component (in JavaScript):
| Name | Description |
|---|---|
stitch-secure-fields-ready | Fired when all secure fields have loaded successfully. |
stitch-secure-fields-change | Fired when the customer makes changes to any of the secure fields. |
stitch-secure-fields-error | Fired when there is an error initializing a field. |
<script type="module">
import '@stitch-money/web/secure-fields';
</script>
<stitch-secure-form id="stitch-form" clientId="your Stitch client ID">
</stitch-secure-form>
<script>
const form = document.getElementById('stitch-form');
form.addEventListener('stitch-secure-fields-ready', () => {
// Toggle visibility of the now-loaded Secure Field components
console.log('Secure Fields Loaded');
});
form.addEventListener('stitch-secure-fields-change', (event) => {
const { payload } = event.detail;
console.log('Form payload changed:', payload);
if (payload.isComplete) {
// Send encrypted card data to your backend, which calls the Stitch API
sendEncryptedCardDataToBackend(payload);
}
});
</script>
This example shows vanilla JavaScript usage. Adapt it for the JS framework you use on your platform.
Stitch Secure Fields
This component accepts the following properties / attributes:
| Name | Description |
|---|---|
field | The field that should be rendered; one of name, number, expiry, or cvc. |
label | (Optional) Custom label text for this input. |
placeholder | (Optional) Custom placeholder text for this input. |
invalidErrorMessage | (Optional) Custom validation error text for this input. |
React
import { StitchSecureField, StitchSecureForm } from '@stitch-money/react';
export function PaymentPage() {
// ... setup from previous step
return (
<div>
<StitchSecureForm
clientId="your Stitch client ID"
onChange={handleSecureFormChange}
theme={theme}
>
<div>
<StitchSecureField field="name" label="Cardholder Name" />
<StitchSecureField field="number" label="Card Number" />
<StitchSecureField field="expiry" label="Expiry Date" />
<StitchSecureField field="cvc" label="CVC" />
</div>
</StitchSecureForm>
</div>
);
}
Non-React
<script type="module">
import '@stitch-money/web/secure-fields';
</script>
<stitch-secure-form id="stitch-form" clientId="your Stitch client ID">
<stitch-secure-field field="name" label="Cardholder Name" />
<stitch-secure-field field="number" label="Card Number" />
<stitch-secure-field field="expiry" label="Expiry Date" />
<stitch-secure-field field="cvc" label="CVC" />
</stitch-secure-form>
The structure of the elements within <StitchSecureForm> is up to you - the only requirement is that all <StitchSecureField> elements are contained by a single <StitchSecureForm> element somewhere up the component tree.
Ready event
React
The onReady handler function is used to determine when all <StitchSecureField> elements have loaded successfully.
const handleSecureFormReady = () => {
// Toggle your loading state to display the form and fields once they have loaded
setIsStitchSecureFormLoading(false);
};
Non-React
The stitch-secure-fields-ready event listener is used to determine when all <StitchSecureField> elements have loaded successfully.
const form = document.getElementById('stitch-form');
form.addEventListener('stitch-secure-fields-ready', function () {
// Toggle your loading state to display the form and fields once they have loaded
console.log('Secure Fields Loaded');
});
Change events
The onChange handler function (or stitch-secure-fields-change event listener) is used to determine when the customer has completed capturing card details and to receive those encrypted details.
The payload supplied to your handler is structured as follows:
| Name | Description |
|---|---|
card.name | The card holder's name. |
card.number | The encrypted card number (PAN). Present only if the number is valid. |
card.brand | The network that issued the card. |
card.lastFour | The last four digits of the card number. Present only if the number is valid. |
card.bin | The Bank Identification Number (BIN) for the card. Present only if the number is valid. |
card.expiry.month | The month of the card expiration date. |
card.expiry.year | The year of the card expiration date. |
card.cvc | The encrypted card CVC. |
card.issuer | The financial institution that issued the card. Present only for a subset of issuers. |
errors | Validation errors scoped by field. |
isValid | Whether there are any validation errors on any of the fields. |
isComplete | Whether all of the fields have been successfully filled out with valid values. |
fingerprint | Data used to identify the user's device. Forward to your server and include in Stitch API requests. |
React
const handleSecureFormChange = ({ payload }) => {
if (!payload.isValid) {
// Values entered are invalid - show validation error
showErrorStateToCustomer(payload.errors.number);
}
if (payload.isComplete) {
// Fields are complete and valid - send to backend for processing
sendEncryptedCardDataToBackend({
name: payload.card.name,
pan: payload.card.number,
expiryMonth: payload.card.expiry.month,
expiryYear: payload.card.expiry.year,
cvc: payload.card.cvc,
bin: payload.card.bin,
last4: payload.card.lastFour,
fingerprint: payload.fingerprint,
});
}
};
Non-React
const form = document.getElementById('stitch-form');
form.addEventListener('stitch-secure-fields-change', (event) => {
const payload = event.detail?.payload;
if (!payload) return;
if (!payload.isValid) {
// Values entered are invalid - show validation error
showErrorStateToCustomer(payload.errors?.number);
}
if (payload.isComplete) {
// Fields are complete and valid - send to backend for processing
sendEncryptedCardDataToBackend({
name: payload.card.name,
pan: payload.card.number,
expiryMonth: payload.card.expiry.month,
expiryYear: payload.card.expiry.year,
cvc: payload.card.cvc,
bin: payload.card.bin,
last4: payload.card.lastFour,
fingerprint: payload.fingerprint,
});
}
});
These details must be submitted to your backend, and can be included as inputs for the Once-off or Tokenization API calls.
Custom styling
By default the secure fields render with a simple appearance that should fit into most applications. To customise the appearance of the fields and their associated validation error messages, supply a theme object to the <StitchSecureForm> component.
The keys of the object are CSS selectors and the values are the same values you would use when writing CSS for the respective selector.
Currently only custom fonts from Google Fonts are supported.
Examples
To set styles that affect every part of all fields, use the :root selector:
const theme = {
styles: {
':root': {
'color-scheme': 'dark', // dark mode
},
},
};
To apply styles to all secure field label elements, use the label selector:
const theme = {
styles: {
label: {
fontWeight: 500,
textTransform: 'uppercase',
},
},
};
To apply styles to all secure field input elements, use the .field input selector:
const theme = {
styles: {
'.field input': {
marginTop: 4,
padding: '8px 12px',
},
},
};
To apply styles to the secure field input that currently has focus, use the .field:focus-within input selector:
const theme = {
styles: {
'.field:focus-within input': {
borderColor: '#5F19E2',
},
},
};
To apply styles to the secure field validation messages, use the .error selector:
const theme = {
styles: {
'.error': {
display: 'none', // Hide built-in validation error messages
},
},
};
To apply styles to a specific secure field input, use the .field[ev-name=<field name here>] selector:
const theme = {
styles: {
'.field[ev-name=number]': {
// Style only the card number input
'font-size': '24px',
},
},
};
To load custom fonts, provide the Google Font links in the fonts array and specify the corresponding fontFamily value within the selectors for the target elements:
const theme = {
// This will load the font from Google Fonts
fonts: ['https://fonts.googleapis.com/css2?family=Comic+Neue'],
styles: {
// This will apply the font to the field labels
'.field label': {
fontFamily: "'Comic Neue'",
},
// This will apply the font to the error text
'.error': {
fontFamily: "'Comic Neue'",
},
},
};
Localisation
If your app is localised, pass translated strings to Secure Fields using the label, placeholder, and invalidErrorMessage properties:
React
<StitchSecureField
field="cvc"
label="<'CVC' translated>"
placeholder="<'CVC' translated>"
invalidErrorMessage="<translated feedback indicating the CVC is invalid>"
/>
Non-React
<stitch-secure-field
field="cvc"
label="<'CVC' translated>"
placeholder="<'CVC' translated>"
invalidErrorMessage="<translated feedback indicating the CVC is invalid>"
></stitch-secure-field>
Fingerprinting
Secure Fields change payloads already include a fingerprint when collection succeeds. For flows that need a device fingerprint outside of Secure Fields (for example charging a consent token), use deviceDataManager from the Web SDK.
Full fingerprint APIs, options, and platform coverage are documented on the Fingerprinting with Stitch SDKs page. A short Web example:
React
import { deviceDataManager } from '@stitch-money/react';
const fingerprint = await deviceDataManager.getDeviceData({
clientId: 'your Stitch client ID', // required
payerId: 'unique user ID', // required
});
Non-React
import { deviceDataManager } from '@stitch-money/web/device-data';
const fingerprint = await deviceDataManager.getDeviceData({
clientId: 'your Stitch client ID', // required
payerId: 'unique user ID', // required
});
Submit this value to your backend and include it in deviceInformation when calling Stitch APIs that require a fingerprint.
Package: StitchSDK (Swift Package via Cloudsmith).
Minimum versions: iOS 15+, Xcode 15+.
Call StitchPayments.configure(clientId:) once at app launch before showing the form.
import StitchSDK
@main
struct MyApp: App {
init() {
StitchPayments.configure(clientId: Config.stitchClientId)
}
var body: some Scene {
WindowGroup { ContentView() }
}
}
StitchSecureForm renders PCI-safe inputs in an internal WKWebView. You never see the raw PAN or CVC. Fingerprinting runs automatically from payerId (failures yield fingerprint: nil rather than blocking the form).
import StitchSDK
import SwiftUI
struct PaymentScreen: View {
@State private var payload: CardPayload?
var body: some View {
VStack {
StitchSecureForm(
payerId: "user-42",
fields: [
SecureFieldConfig(fieldType: .name, icon: .person),
SecureFieldConfig(fieldType: .number, icon: .creditCard, showBrandIcon: true),
SecureFieldConfig(fieldType: .expiry, icon: .calendar),
SecureFieldConfig(fieldType: .cvc, icon: .lock),
],
theme: SecureFormThemes.outlined(),
onReady: { print("ready") },
onChange: { payload = $0 },
onError: { print("Form error:", $0) }
)
.frame(minHeight: 460)
Button("Pay") {
submitToBackend(payload!)
}
.disabled(!(payload?.isComplete ?? false && payload?.isValid ?? false))
}
}
}
StitchSecureForm parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
payerId | String | Yes | Stable customer / payer identifier used for fingerprint capture |
fields | [SecureFieldConfig] | Yes | Ordered list of fields to render |
theme | SecureFormTheme | No | Defaults to SecureFormThemes.outlined() |
onReady | (() -> Void)? | No | Form ready |
onChange | ((CardPayload) -> Void)? | No | Fired on every change |
onError | ((String) -> Void)? | No | Form / bridge errors |
SecureFieldConfig
| Parameter | Type | Default | Description |
|---|---|---|---|
fieldType | FieldType (.name / .number / .expiry / .cvc) | required | Which input to render |
label | String? | SDK default | Override label |
hint | String? | SDK default | Override placeholder |
icon | SecureFieldIcon? | nil | Prefix icon (.person, .creditCard, .calendar, .lock) |
showBrandIcon | Bool | false | Show detected brand on the number field only |
CardPayload
| Field | Description |
|---|---|
card.encryptedNumber / card.encryptedCvc | Opaque tokens - forward unchanged |
card.expiryMonth / expiryYear / holderName | Forward |
card.brand, lastFour, bin | Safe for UI display |
fingerprint | Base64 device fingerprint, or nil |
isValid / isComplete / errors | Drive Pay button and validation UI |
When isComplete and isValid are both true, forward at least:
sendEncryptedCardDataToBackend(
encryptedNumber: payload.card.encryptedNumber,
encryptedCvc: payload.card.encryptedCvc,
expiryMonth: payload.card.expiryMonth,
expiryYear: payload.card.expiryYear,
holderName: payload.card.holderName,
bin: payload.card.bin,
last4: payload.card.lastFour,
fingerprint: payload.fingerprint
)
Theming
Start from SecureFormThemes.outlined(), .underlined(), or .filled(), then override via SecureFormTheme / customCss.
SecureFormTheme(
variant: .outlined,
customCss: """
:root { --border-color: #7C3AED; }
.field-label { text-transform: uppercase; }
.field-wrapper[data-field="number"] .prefix-icon svg { fill: #A78BFA; }
"""
)
customCss styles the outer wrapper (.field-wrapper, .field-label, .field-control, .field-error, icons). Input text inside the iframe is styled only via theme textColor / errorColor.
Package: money.stitch:stitch-android-sdk (Maven via Cloudsmith).
Minimum versions: Android API 21+, JDK 17.
Prefer declaring the client ID in the manifest so the SDK initialises automatically.
<application>
<meta-data
android:name="money.stitch.sdk.clientId"
android:value="@string/stitch_client_id" />
</application>
For multi-tenant or debug builds, call StitchPayments.init(context, clientId) from Application.onCreate instead. Enable Compose, Java 17, and core library desugaring for minSdk 21.
@Composable
fun PaymentScreen() {
var payload by remember { mutableStateOf<CardPayload?>(null) }
StitchSecureForm(
payerId = "user-42",
fields = listOf(
SecureFieldConfig(FieldType.Name, icon = SecureFieldIcon.Person),
SecureFieldConfig(FieldType.Number, icon = SecureFieldIcon.CreditCard, showBrandIcon = true),
SecureFieldConfig(FieldType.Expiry, icon = SecureFieldIcon.Calendar),
SecureFieldConfig(FieldType.Cvc, icon = SecureFieldIcon.Lock),
),
theme = SecureFormThemes.outlined(),
onChange = { payload = it },
onError = { Log.w("Form", it) },
)
Button(
enabled = payload?.isComplete == true && payload?.isValid == true,
onClick = { submitToBackend(payload!!) },
) { Text("Pay") }
}
StitchSecureForm parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
payerId | String | Yes | Stable customer / payer identifier for fingerprint capture |
fields | List<SecureFieldConfig> | Yes | Ordered fields |
theme | SecureFormTheme | No | Defaults to outlined |
onChange | (CardPayload) -> Unit | No | Fired on every change |
onError | (String) -> Unit | No | Form / bridge errors |
SecureFieldConfig
| Parameter | Type | Default | Description |
|---|---|---|---|
fieldType | FieldType | required | Name, Number, Expiry, or Cvc |
label | String? | SDK default | Override label |
hint | String? | SDK default | Override placeholder |
icon | SecureFieldIcon? | null | Prefix icon (Person, CreditCard, Calendar, Lock) |
showBrandIcon | Boolean | false | Brand logo on the number field only |
CardPayload
| Field | Description |
|---|---|
card.encryptedNumber / encryptedCvc | Forward unchanged to Stitch |
card.expiryMonth / expiryYear / holderName | Forward |
card.brand, lastFour, bin | Safe for UI display |
fingerprint | Base64 device fingerprint |
isValid / isComplete | Drive Pay button state |
When submitting, always include bin, lastFour, and fingerprint with the encrypted PAN/CVC:
submitToBackend(
encryptedNumber = payload.card.encryptedNumber,
encryptedCvc = payload.card.encryptedCvc,
expiryMonth = payload.card.expiryMonth,
expiryYear = payload.card.expiryYear,
holderName = payload.card.holderName,
bin = payload.card.bin,
last4 = payload.card.lastFour,
fingerprint = payload.fingerprint,
)
Theming
Use SecureFormThemes.outlined(), .underlined(), or .filled(), and override colours / CSS similarly to iOS via SecureFormTheme and customCss where needed.
If the Secure Fields WebView is blank, confirm the device has network access - the form loads assets over HTTPS. Check adb logcat -s StitchSecureForm for bridge messages.
Package: stitch_flutter (via Cloudsmith).
Minimum versions: Flutter >= 3.10 (Dart SDK >= 3.0), Android minSdk 21, iOS deployment target 15.0.
StitchSecureForm renders PCI-compliant card inputs. Rebuilding with new fields or theme applies updates automatically. When both expiry and CVC are present, they are placed side-by-side by default. Raw card data never enters the Dart layer.
import 'package:stitch_flutter/stitch_flutter.dart';
StitchSecureForm(
clientId: 'your-stitch-client-id',
fields: const [
SecureFieldConfig(fieldType: FieldType.name),
SecureFieldConfig(fieldType: FieldType.number, showBrandIcon: true),
SecureFieldConfig(fieldType: FieldType.expiry),
SecureFieldConfig(fieldType: FieldType.cvc),
],
theme: SecureFormTheme.outlined(
borderRadius: 8.0,
focusedBorderColor: '#6C5CE7',
),
onReady: () {},
onChange: (CardPayload payload) {
if (payload.isComplete && payload.isValid) {
submitToBackend(payload);
}
},
onError: (error) {},
)
Form parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
clientId | String | Yes | Stitch client ID |
fields | List<SecureFieldConfig> | Yes | Ordered fields |
theme | SecureFormTheme | No | Visual configuration |
onReady | VoidCallback? | No | All fields ready |
onChange | ValueChanged<CardPayload>? | No | Fired on every change |
onError | ValueChanged<String>? | No | Form errors |
Field types
FieldType | Description |
|---|---|
name | Cardholder name |
number | Card number (PAN) |
expiry | Expiry date (MM/YY) |
cvc | Card verification code |
SecureFieldConfig
| Parameter | Type | Default | Description |
|---|---|---|---|
fieldType | FieldType | required | Which card input to render |
label | String? | auto | Override the field label |
hint | String? | auto | Override the placeholder |
icon | SecureFieldIcon? | null | Prefix icon (person, creditCard, calendar, lock) |
showBrandIcon | bool | false | Brand logo on FieldType.number only |
Theming factories
| Factory | Description |
|---|---|
SecureFormTheme.defaultTheme() | Raw SDK rendering |
SecureFormTheme.outlined() | Outlined inputs (default look) |
SecureFormTheme.underlined() | Underline-only inputs |
SecureFormTheme.filled() | Filled background inputs |
Common theme parameters: labelPosition (above / floating), borderRadius, borderWidth, focusedBorderWidth, borderColor, focusedBorderColor, errorColor, backgroundColor, textColor, hintColor, fontSize, fontFamily, fieldSpacing, fieldPaddingH / fieldPaddingV, inputHeight, inputOffsetY, fieldMinHeight, labelSpacing, labelStyle, showErrors, reserveErrorSpace, inlineExpiryAndCvc, customCss.
CardPayload
| Property | Type | Description |
|---|---|---|
isValid / isComplete | bool | Form state |
card.encryptedNumber / encryptedCvc | String? | Encrypted tokens - forward unchanged |
card.expiryMonth / expiryYear / holderName | String? | Forward |
card.bin / lastFour / brand | String? | PCI-safe metadata |
fingerprint | String? | Base64 device fingerprint when available |
errors | Map<FieldType, String?> | Per-field validation messages |
Forward a complete payload with bin, lastFour, and fingerprint alongside the encrypted fields when calling your backend.
Package: @stitch-money/react-native (via Cloudsmith).
Peer dependency minimums (enforced by the package peerDependencies):
| Package | Minimum |
|---|---|
react-native | >= 0.73 |
react | >= 18 |
react-native-webview | >= 13.0.0 |
Also install react-native-webview alongside the Stitch package. (@google/react-native-make-payment >= 0.3.0 is a peer for wallet flows; it is not required for Secure Fields alone.)
<StitchSecureForm /> wraps web Secure Fields in a react-native-webview. Card numbers never pass through the host app. payerId is required so the native fingerprint can be captured on mount (cached process-wide; best-effort - failures yield fingerprint: null).
import {
StitchSecureForm,
SecureFormThemes,
type CardPayload,
type SecureFieldConfig,
} from '@stitch-money/react-native';
const fields: SecureFieldConfig[] = [
{ fieldType: 'name' },
{ fieldType: 'number', showBrandIcon: true },
{ fieldType: 'expiry' },
{ fieldType: 'cvc' },
];
function CardForm() {
return (
<StitchSecureForm
clientId="your-client-id"
payerId="your-user-id"
fields={fields}
theme={SecureFormThemes.outlined()}
onChange={(payload: CardPayload) => {
if (payload.isComplete && payload.isValid) {
submitToBackend({
encryptedNumber: payload.card.encryptedNumber,
encryptedCvc: payload.card.encryptedCvc,
expiryMonth: payload.card.expiryMonth,
expiryYear: payload.card.expiryYear,
holderName: payload.card.holderName,
bin: payload.card.bin,
last4: payload.card.lastFour,
fingerprint: payload.fingerprint,
});
}
}}
onError={(message) => console.warn('Secure fields error:', message)}
/>
);
}
Props
| Prop | Type | Required | Description |
|---|---|---|---|
clientId | string | Yes | Stitch client ID |
payerId | string | Yes | Customer identifier for native fingerprint on mount |
fields | SecureFieldConfig[] | Yes | Ordered fields |
theme | theme object | No | e.g. SecureFormThemes.outlined() |
onChange | (CardPayload) => void | No | Fired on every change |
onError | (string) => void | No | Form / bridge errors |
SecureFieldConfig
| Parameter | Type | Default | Description |
|---|---|---|---|
fieldType | 'name' | 'number' | 'expiry' | 'cvc' | required | Which input to render |
label | string? | auto | Override label |
hint | string? | auto | Override placeholder |
icon | 'person' | 'creditCard' | 'calendar' | 'lock' | - | Prefix icon |
showBrandIcon | boolean | false | Brand logo on the number field only |
CardPayload
Typed card fields expose encryptedNumber / encryptedCvc. You never receive a raw PAN or CVC.
| Property | Description |
|---|---|
isValid / isComplete | Form state |
card.encryptedNumber / encryptedCvc | Forward unchanged |
card.expiryMonth / expiryYear / holderName | Forward |
card.bin / lastFour / brand | PCI-safe metadata |
errors | Per-field validation messages |
fingerprint | Native fingerprint, or null / omitted if capture failed |
Theming
Use SecureFormThemes.outlined() (and related theme helpers from the package) to match your app chrome. Theme behaviour follows the same Secure Fields styling model as the other mobile SDKs.