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 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 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 toPrimerCheckoutPresenterDelegate 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
PaymentResult. Switch on its status to route your UI:
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
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(_: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.