PrimerCheckoutSession owner wired into your view hierarchy with the .primerCheckoutSession(_:theme:onCompletion:) modifier, plus composable views (PrimerCardForm, PrimerPaymentMethods, PrimerVaultedPaymentMethods) whose slots default to the *Defaults building blocks. Click any view, slot, or field to see its parameters, lifecycle phases, and copyable Swift code examples.
Two ways to integrate
PrimerCheckoutSession is the iOS analog of Android’s PrimerCheckoutHost. Where Android wraps your layout in a composable host, iOS injects the session into the SwiftUI environment with a view modifier — child views read their per-feature session (PrimerCardFormSession, PrimerSelectionSession) from EnvironmentValues.
Slots and defaults
Every composable view exposes slots that default to a matching*Defaults namespace builder. PrimerCardForm and PrimerPaymentMethods slots are @ViewBuilder closures; PrimerVaultedPaymentMethods slots return AnyView, so wrap custom content in AnyView(...). Override one slot and the rest keep their default rendering — you never re-implement an entire view.
CardFormDefaults also exposes per-field building blocks for recomposing the card section one field at a time: cardNumber, expiryDate, cvv, cardholderName, cardNetwork, plus the billing fields firstName, lastName, phoneNumber, addressLine1, addressLine2, city, state, postalCode, countryCode. Every block except cardNetwork is self-hiding — it renders nothing unless its field is part of the active CardFormConfiguration. cardNetwork is not tied to the configuration: it renders only when more than one card network is detected for the entered card number. cardNumber already shows the co-badged network selector inside the card number field. If you add cardNetwork next to it, two selectors appear. Field presence is Dashboard-driven; visual styling comes from the PrimerCheckoutTheme design tokens.
Sessions and state
Composable views are driven by observable sessions injected into the environment by.primerCheckoutSession(_:theme:onCompletion:). Observe them with @ObservedObject and read their published properties.
The outcome of the flow is delivered through the modifier’s
onCompletion closure as a PrimerCheckoutState. .failure is delivered once per failed attempt: when a payment fails or a refresh() fails, the checkout stays usable so the shopper can retry. A failure while the checkout is still loading ends the flow, and nothing more is delivered. .success or .dismissed is delivered at most once, after which nothing more is delivered. .initializing and .ready are never delivered to onCompletion. Read the lifecycle from PrimerCheckoutSession.phase and clientSession.
PrimerCardFormState
Composing custom UI
Hold the session as a@StateObject, place the composable views in your layout, and attach the modifier. The child views resolve their per-feature session from the environment — you do not pass a session into them.
Related
- API overview — Full iOS Checkout API reference
- PrimerCheckoutSession — The session owner and the
.primerCheckoutSessionmodifier - PrimerCardForm — Slot-based card form
- Design Tokens Explorer — Explore theme tokens
- Card Form Layout Builder — Build card form layouts