Learn how to configure the card-on-file component.
At minimum, the card-on-file component can be created with default settings to display all saved card tokens:
import SwiftUI
import PXPCheckoutSDK
let pxpCheckout = try PxpCheckout.initialize(config: CheckoutConfig(
environment: .test,
session: SessionData(
sessionId: "your-session-id",
hmacKey: "your-hmac-key",
encryptionKey: "your-encryption-key"
),
transactionData: TransactionData(
amount: Decimal(10),
currency: "USD",
entryType: .ecom,
intent: TransactionIntentData(card: .authorisation),
merchantTransactionId: "unique-transaction-id",
merchantTransactionDate: { Date() }
),
merchantShopperId: "shopper-id",
ownerType: "MerchantGroup",
ownerId: "your-owner-id"
))
// Create card-on-file component
let cardOnFileComponent = try pxpCheckout.create(.cardOnFile, componentConfig: CardOnFileComponentConfig()) as! CardOnFileComponent
// Render component in SwiftUI
cardOnFileComponent.buildContent()For more complex implementations, you can configure filtering, sorting, and display options:
// Create additional components for card-on-file
var cvcConfig = CardCvcComponentConfig(label: "Security code")
cvcConfig.isRequired = true
var expiryConfig = CardExpiryDateComponentConfig(label: "Expiry date")
// Create card-on-file with advanced configuration
var config = CardOnFileComponentConfig()
// Filtering options
config.limitTokens = 5
config.filterBy = FilterByConfig(
excludeExpiredTokens: true,
schemes: [.visa, .mastercard],
fundingSource: "Credit",
issuerCountryCode: "USA",
ownerType: "Consumer"
)
// Sorting options
config.orderBy = OrderByConfig(
expiryDate: OrderByDirectionConfig(
direction: "asc",
priority: 1
),
scheme: OrderByValueConfig(
valuesOrder: [.visa, .mastercard, .americanExpress],
priority: 2
),
fundingSource: OrderByValueConfig(
valuesOrder: ["Credit", "Debit"],
priority: 3
),
lastUsageDate: OrderByLastUsageDateConfig(
direction: "desc",
orderByField: "lastSuccessfulPurchaseDate",
priority: 4
)
)
// UI configuration
config.isExpiryDateEditable = true
config.isCvcRequired = true
config.allowDeleteToken = true
// Nested components
config.cvcComponentConfig = cvcConfig
config.expiryDateComponentConfig = expiryConfig
let cardOnFileComponent = try pxpCheckout.create(.cardOnFile, componentConfig: config) as! CardOnFileComponentPayout support: The card-on-file component supports card payouts (disbursements) where funds are sent to a cardholder's card. Each saved card token includes lastSuccessfulPayoutDate, allowing you to:
- Sort cards by most recent payout activity
- Display cards familiar to payout recipients
- Build streamlined disbursement flows
Common payout use cases include marketplace seller payments, insurance settlements, refunds, and prize distributions. Use intent: TransactionIntentData(card: .payout) in your transaction data configuration.
| Property | Description |
|---|---|
limitTokensInt? | The maximum number of tokens to display in the component. For example, if set to 5 then only the first five card tokens are displayed. Defaults to nil. |
filterByFilterByConfig? | The filtering options for saved card tokens. Allows you to narrow down which saved cards are displayed based on various criteria. Defaults to nil. |
filterBy.excludeExpiredTokensBool? | Whether to exclude tokens associated with expired cards. When true, cards past their expiry date are hidden from the list. Defaults to false. |
filterBy.schemes[TokenScheme]? | The list of card schemes to include. For example, [.visa, .mastercard] shows only Visa and Mastercard tokens. Defaults to nil. |
filterBy.fundingSourceString? | The funding source type to include. For example "Credit" or "Debit" filters to show only cards of that type. Defaults to nil. |
filterBy.issuerCountryCodeString? | The issuer country code to include. Filters tokens by the country where the card was issued. Defaults to nil. |
filterBy.ownerTypeString? | The owner type to include. For example "Consumer" or "Commercial" filters by card ownership type. Defaults to nil. |
orderByOrderByConfig? | The ordering options for saved card tokens. Controls how tokens are sorted and displayed. Multiple ordering rules can be applied with priority values. Defaults to nil. |
orderBy.expiryDateOrderByDirectionConfig? | The configuration for ordering by expiry date. Defaults to nil. |
orderBy.expiryDate.directionString? | The direction to order by expiry date. Possible values:
nil. |
orderBy.expiryDate.priorityInt? | The priority of this ordering rule. Lower numbers are applied first. Defaults to nil. |
orderBy.schemeOrderByValueConfig<TokenScheme>? | The configuration for ordering by card scheme. Allows custom ordering like Visa first, then Mastercard. Defaults to nil. |
orderBy.scheme.valuesOrder[TokenScheme]? | The card scheme order. Tokens matching earlier schemes in the array appear first. Defaults to nil. |
orderBy.scheme.priorityInt? | The priority of this ordering rule. Lower numbers are applied first. Defaults to nil. |
orderBy.fundingSourceOrderByValueConfig<String>? | The configuration for ordering by funding source. Allows prioritising credit vs debit cards. Defaults to nil. |
orderBy.fundingSource.valuesOrder[String]? | The funding source order. Tokens matching earlier values appear first. Possible values:
nil. |
orderBy.fundingSource.priorityInt? | The priority of this ordering rule. Lower numbers are applied first. Defaults to nil. |
orderBy.ownerTypeOrderByValueConfig<String>? | The configuration for ordering by owner type. Allows prioritising consumer vs commercial cards. Defaults to nil. |
orderBy.ownerType.valuesOrder[String]? | The owner type order. Tokens matching earlier values appear first. Possible values:
nil. |
orderBy.ownerType.priorityInt? | The priority of this ordering rule. Lower numbers are applied first. Defaults to nil. |
orderBy.issuerCountryCodeOrderByDirectionConfig? | The configuration for ordering by issuer country code. Allows alphabetical sorting by country. Defaults to nil. |
orderBy.issuerCountryCode.directionString? | The direction to order by country code. Possible values:
nil. |
orderBy.issuerCountryCode.priorityInt? | The priority of this ordering rule. Lower numbers are applied first. Defaults to nil. |
orderBy.lastUsageDateOrderByLastUsageDateConfig? | The configuration for ordering by last usage date. Shows most/least recently used cards first. Defaults to nil. |
orderBy.lastUsageDate.directionString? | The direction to order by last usage. Possible values:
nil. |
orderBy.lastUsageDate.orderByFieldString? | The field to order by when sorting by last usage. Choose based on your transaction type:"lastSuccessfulPurchaseDate": Sort by most recent purchase/authorisation (default for payment flows)"lastSuccessfulPayoutDate": Sort by most recent payout/disbursement (recommended for .payout intent flows)For mixed flows or when unspecified, the SDK sorts by the most recent activity across both fields. Defaults to nil. |
orderBy.lastUsageDate.priorityInt? | The priority of this ordering rule. Lower numbers are applied first. Defaults to nil. |
transactionInitiatorTypeTransactionInitiatorType? | The transaction initiator type. Indicates whether the transaction is customer-initiated or merchant-initiated. Defaults to nil. |
isExpiryDateEditableBool? | Whether the expiry date field can be edited by the cardholder. When true, users can update the expiry date if their card has been renewed. Defaults to false. |
isCvcRequiredBool? | Whether CVC is required when selecting a token. When true, users must enter the security code even for saved cards. This applies to all tokens. Defaults to false. |
allowDeleteTokenBool? | Whether to allow cardholders to delete a token (previously saved card). When true, a delete button appears for each saved card. Defaults to false. |
cvcComponentConfigCardCvcComponentConfig? | The configuration for the standalone card CVC component. Used when isCvcRequired is true. See Card CVC. Defaults to nil. |
expiryDateComponentConfigCardExpiryDateComponentConfig? | The configuration for the standalone card expiry date component. Used when isExpiryDateEditable is true. See Card expiry date. Defaults to nil. |
The card-on-file component renders saved cards with built-in SwiftUI styling.
You can override the default appearance by providing custom styles, images, and text labels:
// Custom text labels
config.expiredText = "Card expired"
config.validThruText = "Valid until"
config.deleteErrorMessage = "Unable to delete card. Please try again."
config.deleteSuccessMessage = "Card has been removed successfully."
config.updateErrorMessage = "Unable to update card information. Please try again."
config.updateSuccessMessage = "Card information updated successfully."
// Custom styling
config.styles = CardOnFileStyles(
backgroundColor: Color(.systemGray6),
borderColor: Color(.systemGray3),
borderRadius: 8,
padding: 20
)
config.inputStyles = FieldInputStyle(
cornerRadius: 5,
backgroundColor: Color(.secondarySystemBackground)
)
// Custom icons
config.iconDeleteSrc = Image(systemName: "trash")
config.iconSaveSrc = Image(systemName: "checkmark")
config.iconCancelSrc = Image(systemName: "xmark")
config.iconEditSrc = Image(systemName: "pencil")
// Custom card brand images
config.cardBrandImages = CardBrandImages(
visaSrc: Image("BrandVisa"),
mastercardSrc: Image("BrandMastercard"),
amexSrc: Image("BrandAmex")
)
config.useTransparentCardBrandImage = true
// Accessibility labels
config.editCardInformationAccessibilityLabel = "Edit card information button"
config.saveCardInformationAccessibilityLabel = "Save card information button"
config.cancelEditCardInformationAccessibilityLabel = "Cancel edit card information button"
config.deleteCardButtonAccessibilityLabel = "Delete card button"
config.cardNumberAccessibilityLabel = "Card number"
config.cardExpiryDateAccessibilityLabel = "Card expiry date"
// Delete modal configuration
config.deleteModal = DeleteModalConfig(
dialogAccessibilityLabel: "Delete card dialog",
bodyText: "Are you sure you want to delete this payment method?",
cancelButtonText: "No, keep it",
deleteButtonText: "Yes, delete it"
)| Property | Description |
|---|---|
stylesCardOnFileStyles? | List container, token rows, typography, and message styles. |
styles.backgroundColorColor? | List background. |
styles.borderColorColor? | List border colour. |
styles.borderRadiusCGFloat? | List corner radius. |
styles.paddingCGFloat? | List inner padding. |
styles.gapCGFloat? | Spacing between token rows. |
styles.tokenContainerStyleCardTokenContainerStyle? | Normal, selected, and expired row styling. |
styles.cardNumberStyleCardTokenTextStyle? | Masked PAN text. |
styles.expiredTextStyleCardTokenTextStyle? | Expired label. |
styles.validThruLabelStyleCardTokenTextStyle? | “Valid thru” label. |
styles.expiryDateValueStyleCardTokenTextStyle? | Expiry value. |
styles.successMessageStyleCardOnFileMessageStyle? | Success banner. |
styles.errorMessageStyleCardOnFileMessageStyle? | Error banner. |
inputStylesFieldInputStyle? | Shared base for CVC and expiry inputs; per-component configs override when set. |
cardBrandImagesCardBrandImages? | SwiftUI Image per brand (visaSrc, mastercardSrc, amexSrc, cupSrc, dinersSrc, discoverSrc, jcbSrc). |
iconDeleteSrcImage? | Delete control icon. |
iconSaveSrcImage? | Save control icon. |
iconCancelSrcImage? | Cancel control icon. |
iconEditSrcImage? | Edit control icon. |
useTransparentCardBrandImageBool? | Prefer transparent brand artwork. Defaults to true. |
expiredTextString? | Copy for expired cards. |
validThruTextString? | “Valid thru” label override. |
deleteErrorMessageString? | Delete failure message. |
deleteSuccessMessageString? | Delete success message. |
updateErrorMessageString? | Update failure message. |
updateSuccessMessageString? | Update success message. |
deleteModalDeleteModalConfig? | Delete confirmation content and optional CardOnFileModalStyle, button styles, iconWarning. |
editCardInformationAccessibilityLabelString? | VoiceOver label for edit. |
saveCardInformationAccessibilityLabelString? | VoiceOver label for save. |
cancelEditCardInformationAccessibilityLabelString? | VoiceOver label for cancel. |
deleteCardButtonAccessibilityLabelString? | VoiceOver label for delete. |
cardNumberAccessibilityLabelString? | VoiceOver label for masked number. |
cardExpiryDateAccessibilityLabelString? | VoiceOver label for expiry. |
The card-on-file component provides event handlers to manage token retrieval, rendering, updates, and deletions:
config.onPreRenderTokens = { response in
response.gatewayTokens.map {
CardTokenMapping(id: $0.gatewayTokenId, isCvcRequired: true)
}
+ response.schemeTokens.map {
CardTokenMapping(id: $0.schemeTokenId, isCvcRequired: true)
}
}
config.onRetrieveTokensSuccess = { response in
// Optional: analytics or UI state
}
config.onRetrieveTokensFailed = { failure in
// Show error UI
}
config.onSelectToken = { token in
// token.maskedPrimaryAccountNumber, token.cardScheme, etc.
}
config.onPreDeleteToken = { token in
// Return true to proceed (after your own confirmation if needed)
true
}
config.onDeleteTokenSuccess = { _ in }
config.onDeleteTokenFailed = { _ in }
config.onUpdateTokenSuccess = { _ in }
config.onUpdateTokenFailed = { _ in }
config.onValidationError = { error in
// e.g. invalid expiry while editing
}
config.tokenLabelBuilder = { token in
"\(token.cardScheme.displayName) \(token.maskedPrimaryAccountNumber)"
}
config.tokenItemBuilder = { elements in
AnyView(
HStack {
elements.tokenImageView
VStack(alignment: .leading) {
elements.tokenLabelView
elements.expiryDateView
}
Spacer()
elements.editButtonView
elements.deleteButtonView
}
)
}| Callback | Description |
|---|---|
onPreRenderTokens: ((RetrieveCardTokensResponseSuccess) -> [CardTokenMapping])? | Called to map and order tokens before UI builds. Returns an array of CardTokenMapping where each can set id and per-token isCvcRequired. Allows custom filtering and ordering logic. |
onRetrieveTokensSuccess: ((RetrieveCardTokensResponseSuccess) -> Void)? | Called when the token list is successfully retrieved from the API. Receives the response with all available tokens. |
onRetrieveTokensFailed: ((RetrieveCardTokensResponseFailed) -> Void)? | Called when token list retrieval fails. Receives the failure response with error details. |
onSelectToken: ((BaseCardToken) -> Void)? | Called when user selects a token. This includes initial auto-selection and re-selection after token deletion. Receives the selected token details. |
onPreDeleteToken: ((BaseCardToken) async -> Bool)? | Called before a token is deleted. Return false to cancel deletion, true to proceed. Use for custom confirmation flows. |
onDeleteTokenSuccess: ((DeleteCardTokenResponseSuccess) -> Void)? | Called when a token is successfully removed. Receives the deletion response. |
onDeleteTokenFailed: ((DeleteCardTokenResponseFailed) -> Void)? | Called when token deletion fails. Receives the API error details. |
onUpdateTokenSuccess: ((UpdateCardTokenResponseSuccess) -> Void)? | Called when an expiry date update succeeds. Receives the update response. |
onUpdateTokenFailed: ((UpdateCardTokenResponseFailed) -> Void)? | Called when an expiry date update fails. Receives the API error details. |
onValidationError: ((BaseSdkException) -> Void)? | Called when validation issues occur (for example, invalid expiry format during editing). Receives the validation exception. |
tokenItemBuilder: ((CardTokenBuilderElements) -> AnyView)? | Custom SwiftUI layout builder for each token row. Receives pre-built views: tokenImageView, tokenLabelView, expiryDateView, editButtonView, deleteButtonView. Return your custom AnyView layout. |
tokenLabelBuilder: ((BaseCardToken) -> String)? | Custom label text builder for the default layout. Receives the token details and returns a single-line string. |
BaseCardToken exposes fields such as maskedPrimaryAccountNumber, cardExpiryMonth, cardExpiryYear, fundingSource, ownerType, issuerName, issuerCountryCode, lastSuccessfulPurchaseDate, lastSuccessfulPayoutDate, and cardScheme.
For shared event patterns and types, see Events.
Returns SwiftUI content for the card-on-file list:
cardOnFileComponent.buildContent()Releases components created from the checkout instance:
PxpCheckout.unmount()To charge a saved card, link this component to Card submit: set cardSubmitConfig.cardOnFileComponent and cardSubmitConfig.useCardOnFile = true. The submit component performs validation and reads the selected token and CVC internally — you don't need to call getValue or validate from your app code.
A straightforward implementation showing saved payment methods:
var config = CardOnFileComponentConfig()
config.limitTokens = 5
config.filterBy = FilterByConfig(excludeExpiredTokens: true)
config.onSelectToken = { token in
print("Selected:", token.maskedPrimaryAccountNumber)
}
config.onRetrieveTokensFailed = { _ in
// Show error
}
let cardOnFile = try pxpCheckout.create(.cardOnFile, componentConfig: config) as! CardOnFileComponentDisplay only specific card types in a custom order:
var config = CardOnFileComponentConfig()
config.filterBy = FilterByConfig(
excludeExpiredTokens: true,
schemes: [.visa, .mastercard],
fundingSource: "Credit",
issuerCountryCode: "USA"
)
config.orderBy = OrderByConfig(
lastUsageDate: OrderByLastUsageDateConfig(
orderByField: "lastSuccessfulPurchaseDate",
direction: "desc",
priority: 1
),
scheme: OrderByValueConfig(valuesOrder: [.visa, .mastercard], priority: 2)
)
config.limitTokens = 3Allow users to edit and delete their saved cards:
var config = CardOnFileComponentConfig()
config.isExpiryDateEditable = true
config.isCvcRequired = true
config.allowDeleteToken = true
var cvcConfig = CardCvcComponentConfig(label: "Security code")
cvcConfig.applyMask = true
cvcConfig.showMaskToggle = true
config.cvcComponentConfig = cvcConfig
config.expiryDateComponentConfig = CardExpiryDateComponentConfig(label: "Expiry date")
config.onPreDeleteToken = { token in
// Present UIAlertController or SwiftUI confirmation; return whether to delete
true
}Configure a custom deletion confirmation modal:
config.deleteModal = DeleteModalConfig(
dialogAccessibilityLabel: "Confirm deletion",
bodyText: "Remove this payment method?",
cancelButtonText: "Cancel",
deleteButtonText: "Delete",
modalStyle: CardOnFileModalStyle(
backgroundColor: .white,
borderRadius: 12,
bodyPadding: 16,
shadowRadius: 16
),
deleteButtonStyle: CardOnFileDeleteButtonStyle(
backgroundColor: .red,
textColor: .white,
height: 44,
borderRadius: 8
),
cancelButtonStyle: CardOnFileCancelButtonStyle(
backgroundColor: .white,
textColor: .primary,
height: 44,
borderRadius: 8,
borderColor: .gray,
borderWidth: 1
)
)Use a custom SwiftUI layout for token display:
config.tokenItemBuilder = { elements in
AnyView(
VStack(alignment: .leading, spacing: 8) {
HStack {
elements.tokenImageView
elements.tokenLabelView
Spacer()
elements.editButtonView
elements.deleteButtonView
}
elements.expiryDateView
}
.padding()
.background(RoundedRectangle(cornerRadius: 10).stroke(Color.gray.opacity(0.3)))
)
}Integrate card-on-file with the card submit component for payment processing:
let cofConfig = CardOnFileComponentConfig()
cofConfig.isCvcRequired = true
let cof = try pxpCheckout.create(.cardOnFile, componentConfig: cofConfig) as! CardOnFileComponent
var submitConfig = CardSubmitComponentConfig()
submitConfig.cardOnFileComponent = cof
submitConfig.useCardOnFile = true
submitConfig.submitText = "Pay with saved card"
submitConfig.onPreAuthorisation = { _ async in TransactionInitiationData() }
submitConfig.onPostAuthorisation = { _ in }
let submit = try pxpCheckout.create(.cardSubmit, componentConfig: submitConfig) as! CardSubmitComponent
VStack {
cof.buildContent()
submit.buildContent()
}Display saved cards for recipients to receive funds:
let transactionData = TransactionData(
amount: Decimal(string: "250.00")!,
currency: "USD",
entryType: .ecom,
intent: TransactionIntentData(card: .payout), // Set to payout for disbursements
merchantTransactionId: "payout-\(UUID().uuidString)",
merchantTransactionDate: { Date() }
)
let checkoutConfig = CheckoutConfig(
environment: .test,
session: sessionData,
transactionData: transactionData,
merchantShopperId: "recipient-shopper-id",
ownerType: "MerchantGroup",
ownerId: "your-owner-id",
onGetShopper: { async in TransactionShopper(id: "recipient-shopper-id") }
)
let pxpCheckout = try PxpCheckout.initialize(config: checkoutConfig)
var config = CardOnFileComponentConfig()
config.limitTokens = 5
// Filter and sort for payout flows
config.filterBy = FilterByConfig(excludeExpiredTokens: true)
// Prioritise cards used for recent payouts
config.orderBy = OrderByConfig(
lastUsageDate: OrderByLastUsageDateConfig(
orderByField: "lastSuccessfulPayoutDate", // Sort by payout activity
direction: "desc",
priority: 1
)
)
config.isExpiryDateEditable = true
config.isCvcRequired = true
config.onSelectToken = { token in
print("Payout card selected:", token.maskedPrimaryAccountNumber)
print("Last payout:", token.lastSuccessfulPayoutDate.isEmpty ? "None" : token.lastSuccessfulPayoutDate)
}
config.onRetrieveTokensFailed = { error in
print("Failed to load payout cards:", error.message)
// Show error message to user
}
let cardOnFileComponent = try pxpCheckout.create(.cardOnFile, componentConfig: config) as! CardOnFileComponent
// Continue with card submit component for payout execution...Use orderByField: "lastSuccessfulPayoutDate" to prioritise cards the recipient has successfully used for previous payouts. This builds trust and reduces friction by showing familiar payout destinations first.
For setup and lifecycle, see Implementation. For validation behaviour on linked fields, see Data validation.