Skip to main content
Primer Checkout iOS SDK is currently in beta (v3.0.0-beta.1). The API is subject to change before the stable release.
The Primer Checkout iOS SDK is built with SwiftUI, but it ships a UIKit entry point so you can integrate it from view-controller based apps without rewriting your navigation. PrimerCheckoutPresenter presents the managed checkout as a modal sheet from any UIViewController and delivers the result through a delegate. For most UIKit apps, the presenter is all you need. If you want full control over the layout, you can also embed the SwiftUI composable views (PrimerCardForm and PrimerPaymentMethods) inside a UIHostingController — see Embedding the composable views.
PrimerCheckoutPresenter is @available(iOS 15.0, *) and @MainActor. Call its static methods from the main thread — the default for UIKit lifecycle callbacks. For pure SwiftUI apps, use PrimerCheckout directly instead.

Present checkout

There are three steps:
  1. Assign the delegate on PrimerCheckoutPresenter.shared.
  2. Call presentCheckout(...), passing the client token and the view controller to present from.
  3. Implement PrimerCheckoutPresenterDelegate to handle the result.
PrimerCheckoutPresenter.shared.delegate is a weak reference. Keep the conforming object (here, the view controller) alive for as long as checkout is on screen, otherwise the callbacks will not fire.
Generate the clientToken from your backend with the client session API.

Presentation overloads

presentCheckout has several overloads that differ only in how much you configure and whether you supply the presenting view controller yourself. Every overload accepts an optional trailing completion closure that runs once the checkout UI has finished presenting.

Parameters

The automatic-detection overloads (no from: parameter) locate the top-most presenting view controller for you. If no presenting view controller can be found, they report a PrimerError through primerCheckoutPresenterDidFailWithError(_:). Assign the delegate before calling them.
The overloads that take primerSettings or primerTheme are not @objc compatible because of those Swift-only parameter types. From Objective-C, use the clientToken / clientToken:from: overloads, or configure settings globally through PrimerSettings.

Implement the delegate

Conform to PrimerCheckoutPresenterDelegate to receive results and lifecycle events. The three result methods are required; the 3DS lifecycle methods are optional thanks to default implementations in a protocol extension.

Required methods

The success callback delivers a PaymentResult. Switch on its status to route your UI:
The checkout dismisses itself automatically before delivering primerCheckoutPresenterDidCompleteWithSuccess(_:) or primerCheckoutPresenterDidFailWithError(_:). Use those callbacks to push your own confirmation or error screen. For the full payment-result model, see Handle payment result.

Optional 3DS lifecycle methods

Implement these only if you need to observe the 3-D Secure challenge lifecycle. Each has a default empty implementation, so you can omit any you do not need.

Dismiss programmatically

Call dismiss(animated:completion:) to close checkout from your own code (for example, after a timeout). This triggers primerCheckoutPresenterDidDismiss() on the delegate.

Check availability

Use the static properties to guard presentation:

Embedding the composable views

If the managed sheet does not match your UI, you can embed the SwiftUI composable views directly inside a UIKit screen with UIHostingController. Hold a PrimerCheckoutSession as a @StateObject, place PrimerCardForm and PrimerPaymentMethods under the .primerCheckoutSession(_:onCompletion:) modifier, and host that SwiftUI view in your view controller. First, define the SwiftUI content:
Then host it from your view controller and add it as a child:
The .primerCheckoutSession(_:onCompletion:) modifier must sit above the composable views in the hierarchy. It injects the per-feature sessions into the environment and bootstraps the session lifecycle (start() on appear, cancel() on disappear). Without it, PrimerCardForm and PrimerPaymentMethods cannot resolve a session and will not function.
With embedded composables you receive the outcome as a PrimerCheckoutState in the modifier’s onCompletion, rather than through the presenter delegate. The state-driven model is identical to a pure SwiftUI integration.

See also

PrimerCheckoutPresenter

The full UIKit entry-point API: overloads, delegate, and result types.

PrimerCheckoutState

The state model returned to embedded composable integrations.

Handle payment result

Route your UI based on the checkout outcome.

SwiftUI navigation

Presentation patterns for pure SwiftUI apps.