Skip to main content
Primer Checkout iOS SDK is currently in beta (v3.0.0-beta.8). The API is subject to change before the stable release.
PrimerCardForm is a SwiftUI View that renders a complete card payment form, composed from three section slots: card details, billing address, and submit button. Each section is a @ViewBuilder slot you can replace. The form resolves its PrimerCardFormSession from the environment. The .primerCheckoutSession(_:theme:onCompletion:) modifier provides it, so you can embed the form anywhere in your own SwiftUI layout. The modal PrimerCheckout renders its own card screen and does not take composable views.
Requires iOS 15.0+. PrimerCardForm is @available(iOS 15.0, *).

Signature

Parameters

Each slot receives the active PrimerCardFormSession, which exposes the published state and the field-update and submit() methods you need to drive custom UI.
Every slot is generic and defaults to a CardFormDefaults builder. Because the defaults are supplied per-parameter, you can override any single slot and leave the rest at their default styling — you never have to re-implement the whole form.

Default layout

The default form stacks the three slots vertically: When no card-form session is available, the form renders CardFormDefaults.unavailable() (an empty view) instead. This happens when the .primerCheckoutSession(_:theme:onCompletion:) modifier is missing, or when the checkout session is still initializing (its phase is not yet .ready). It also happens when the checkout session has no card payment method. While a payment is processing, the default submit button and the input fields rendered by CardFormDefaults are disabled automatically. This covers the cardDetails and billingAddress sections and the per-field builders, except cardNetwork(_:). The cardNetwork(_:) selector and views of your own inside a slot stay enabled, so disable them with session.state.isLoading.

Usage

Default form

Render the fully styled default card form with no arguments:
Place PrimerCardForm() inside a view that has the .primerCheckoutSession(_:theme:onCompletion:) modifier applied, so the form can resolve its PrimerCardFormSession from the environment.

Overriding a single slot

To customize one section, pass a labeled argument and leave the others at their defaults. Here only the submit button is replaced — cardDetails and billingAddress keep the default styling:
Always pass slots with their labels (cardDetails:, billingAddress:, submitButton:). Which slot a bare trailing closure such as PrimerCardForm { session in ... } fills depends on your Swift language mode. In Swift 6 mode it fills the first slot, cardDetails. In Swift 5 mode it fills the last slot, submitButton, and the compiler shows a trailing-closure matching warning.

Recomposing the card section from building blocks

You don’t have to discard the default fields when customizing a slot. Compose the default content with your own views using the per-field builders on CardFormDefaults:
You can also assemble the card section from the individual field building blocks — CardFormDefaults.cardNumber, expiryDate, cvv, and cardholderName:
See Card field components for the full set of field building blocks.

See also

PrimerCardFormSession

State, field-update methods, and submit() passed into every slot.

CardFormDefaults

Default section and field builders used by each slot.

Card field components

Individual field building blocks for recomposing the card section.

PrimerPaymentMethods

Render the list of available payment methods alongside the card form.