Skip to main content
Scopes are the central building block of Primer Checkout. Each scope is a typed protocol that exposes the state, actions, and customization points for a specific part of the checkout.

Scope hierarchy

All scopes

ScopePurposeState type
PrimerCheckoutScopeTop-level checkout managementPrimerCheckoutState
PrimerPaymentMethodSelectionScopePayment method list and selectionPrimerPaymentMethodSelectionState
PrimerCardFormScopeCard form fields and validationPrimerCardFormState
PrimerApplePayScopeApple Pay button and availabilityPrimerApplePayState
PrimerPayPalScopePayPal payment flowPrimerPayPalState
PrimerKlarnaScopeKlarna multi-step flowPrimerKlarnaState
PrimerAchScopeACH multi-step flowPrimerAchState
PrimerWebRedirectScopeWeb redirect payment flow (e.g., Twint)PrimerWebRedirectState
PrimerFormRedirectScopeForm-based redirect flow (e.g., BLIK, MBWay)PrimerFormRedirectState
PrimerQRCodeScopeQR code display and polling (e.g., PromptPay)PrimerQRCodeState
PrimerSelectCountryScopeCountry picker (accessed via PrimerCardFormScope.selectCountry)PrimerSelectCountryState

Accessing scopes

Via the scope closure

The scope parameter on PrimerCheckout provides access to the PrimerCheckoutScope:
PrimerCheckout(
  clientToken: clientToken,
  scope: { checkoutScope in
    // Access payment method selection directly
    let selection = checkoutScope.paymentMethodSelection

    // Access payment method scopes by type
    if let cardScope: PrimerCardFormScope = checkoutScope.getPaymentMethodScope(PrimerCardFormScope.self) {
      // Customize card form
    }
  }
)

Getting payment method scopes

Use getPaymentMethodScope with a type parameter:
// By scope type
let cardScope: PrimerCardFormScope? = checkoutScope.getPaymentMethodScope(PrimerCardFormScope.self)

// By payment method type enum
let applePayScope: PrimerApplePayScope? = checkoutScope.getPaymentMethodScope(for: .applePay)

// By payment method type string
let paypalScope: PrimerPayPalScope? = checkoutScope.getPaymentMethodScope(for: "PAYPAL")

Type aliases

Scopes use type aliases for customization closures:
AliasSignatureUsed by
Component() -> any ViewsplashScreen, loadingScreen, cardInputSection
ContainerComponent(@escaping () -> any View) -> any Viewcontainer
ErrorComponent(String) -> any ViewerrorScreen
PaymentMethodItemComponent(CheckoutPaymentMethod) -> any ViewpaymentMethodItem
CountryItemComponent(PrimerCountry, @escaping () -> Void) -> any ViewcountryItem
CategoryHeaderComponent(String) -> any ViewcategoryHeader
CardFormScreenComponent(any PrimerCardFormScope) -> any ViewCard form screen
PaymentMethodSelectionScreenComponent(PrimerPaymentMethodSelectionScope) -> any ViewSelection screen
WebRedirectScreenComponent(any PrimerWebRedirectScope) -> any ViewWeb redirect screen
WebRedirectButtonComponent(any PrimerWebRedirectScope) -> any ViewWeb redirect payButton
FormRedirectScreenComponent(any PrimerFormRedirectScope) -> any ViewForm redirect screen
FormRedirectButtonComponent(any PrimerFormRedirectScope) -> any ViewForm redirect submitButton
FormRedirectFormSectionComponent(any PrimerFormRedirectScope) -> any ViewForm redirect formSection
QRCodeScreenComponent(any PrimerQRCodeScope) -> any ViewQR code screen

Base protocol

All payment method scopes conform to PrimerPaymentMethodScope:
@MainActor
protocol PrimerPaymentMethodScope: AnyObject {
  associatedtype State: Equatable

  var state: AsyncStream<State> { get }
  var presentationContext: PresentationContext { get }   // default: .fromPaymentSelection
  var dismissalMechanism: [DismissalMechanism] { get }  // default: []

  func start()
  func submit()
  func cancel()
  func onBack()
  func onDismiss()
}

See also

State and events

Observe state changes for each scope

Layout customization

Customize UI using scope properties

PrimerCheckoutScope API

Full API reference