- Modal flow — drop
PrimerCheckoutinto a.sheet,.fullScreenCover, orNavigationStackdestination and let the SDK render its prebuilt screens. - Inline embedding — hold a
PrimerCheckoutSessionas@StateObject, apply the.primerCheckoutSession(_:onCompletion:)modifier, and place composable views such asPrimerCardFormandPrimerPaymentMethodsdirectly in your own layout.
PrimerCheckoutState callback, so you drive navigation from the same .success / .dismissed / .failure cases regardless of how checkout is presented.
Primer Checkout requires iOS 15.0 or later — all checkout views and sessions are annotated
@available(iOS 15.0, *) and @MainActor. Some SwiftUI navigation hosts shown below require a newer OS than the SDK floor: NavigationStack and .navigationDestination(for:) require iOS 16.0+, and the .navigationDestination(item:) overload requires iOS 17.0+. On an iOS 15 deployment target, present checkout with .sheet or .fullScreenCover instead.Reading the completion state
Every entry point reports its terminal outcome throughPrimerCheckoutState. Switch on it to decide how navigation should react.
| Case | Associated value | Drives |
|---|---|---|
initializing | — | Loading; no navigation change |
ready | totalAmount: Int, currencyCode: String | Checkout is interactive |
success | PaymentResult | Dismiss and push a confirmation |
dismissed | — | User closed checkout; restore prior screen |
failure | PrimerError | Error is shown in-UI; usually keep checkout open |
Modal flow with PrimerCheckout
PrimerCheckout is a self-contained View that renders the SDK’s default screens. Use it whenever you want the fastest integration and do not need to recompose the UI.
Sheet presentation
Pushing onto a NavigationStack
Use a NavigationStack when checkout is one step inside a longer flow and you want a back button rather than a modal. NavigationStack(path:) and .navigationDestination(for:) require iOS 16.0+; on an iOS 15 target, use the sheet presentation above.
Inline embedding with PrimerCheckoutSession
To recompose the UI — for example, to place PrimerCardForm inside your own scroll view alongside an order summary — hold a PrimerCheckoutSession and wire it in with the .primerCheckoutSession(_:onCompletion:) modifier. The modifier injects the session into the environment, so any Primer composable placed under it resolves automatically.
@StateObject so it survives view updates. The modifier bootstraps it on appear and tears it down on disappear.
The modifier wires
session.cancel() to onDisappear, which also fires on transient disappearance (tab switch, push/pop, parent sheet re-present). The session resets to a restartable state and rebuilds itself when the view reappears — no extra handling required.Embedding the payment-method list
PrimerPaymentMethods resolves the same session from the environment, so you can compose a full selection-plus-card layout under a single modifier.
Driving navigation from the completion state
Whether modal or inline, route on the samePrimerCheckoutState cases: dismiss on .dismissed, advance on .success, and leave checkout in place on .failure so the SDK can present its own error UI.
The
.navigationDestination(item:) overload used above requires iOS 17.0+. On earlier targets, drive the same confirmation value through an isPresented-based .sheet or a .navigationDestination(isPresented:) binding instead.onCompletion closure on .primerCheckoutSession(_:onCompletion:) drives the navigation in identical fashion — pop the embedding screen on .dismissed, push a confirmation on .success.
See also
PrimerCheckoutSession
Own the inline session lifecycle and sub-sessions
PrimerCheckout
The prebuilt modal checkout view
PrimerCardForm
Compose the card form inline with slots
Handle payment result
React to checkout outcomes