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:- Assign the
delegateonPrimerCheckoutPresenter.shared. - Call
presentCheckout(...), passing the client token and the view controller to present from. - Implement
PrimerCheckoutPresenterDelegateto 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.clientToken from your backend with the client session API.
Presentation overloads
presentCheckout has several overloads that differ in how much you configure and whether you supply the presenting view controller yourself. Every overload accepts an optional completion closure (trailing-closure syntax works) that runs once the checkout UI has finished presenting.
Parameters
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. They use the same fallback settings as the other overloads that omit primerSettings. They also cannot take the shipping handlers.Implement the delegate
Conform toPrimerCheckoutPresenterDelegate to receive the checkout result. All three methods are required. A failed 3-D Secure challenge is reported like any other failure, through primerCheckoutPresenterDidFailWithError(_:checkoutData:).
PaymentResult. Switch on its status to route your UI:
The shopper can swipe the sheet down when
PrimerSettings.uiOptions.dismissalMechanism contains .gestures (the default), except while a payment is processing. A swipe on the success screen delivers primerCheckoutPresenterDidCompleteWithSuccess(_:). A swipe anywhere else, including the error screen after a failure was reported, delivers primerCheckoutPresenterDidDismiss().Dismiss programmatically
Calldismiss(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 withUIHostingController. Hold a PrimerCheckoutSession as a @StateObject, place PrimerCardForm and PrimerPaymentMethods under the .primerCheckoutSession(_:theme:onCompletion:) modifier, and host that SwiftUI view in your view controller.
First, define the SwiftUI content:
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.