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.
PrimerSelectionSession is the observable session that drives payment-method selection. It exposes the available methods, the current selection, search and filtering state, and vaulted-card actions (including CVV recapture) as a single @Published state value, and provides the methods that mutate that state. A single PrimerSelectionSession backs both PrimerPaymentMethods (the list of available methods) and PrimerVaultedPaymentMethods (saved methods). Both views resolve the same session from the environment supplied by the .primerCheckoutSession(_:) modifier, so you rarely construct or hold it yourself — you read it from the slots those views hand you.
PrimerSelectionSession is a @MainActor, ObservableObject final class available on iOS 15.0 and later (@available(iOS 15.0, *)). Observe it with @ObservedObject and call its methods from the main actor.

Declaration

@available(iOS 15.0, *)
@MainActor
public final class PrimerSelectionSession: ObservableObject {
  @Published public private(set) var state: PrimerPaymentMethodSelectionState
  public var vaultedPaymentMethods: [PrimerHeadlessUniversalCheckout.VaultedPaymentMethod] { get }
}
The session is created and injected by the SDK. The slots of PrimerPaymentMethods and PrimerVaultedPaymentMethods receive it directly, so you do not initialize it yourself.

Properties

PropertyTypeDescription
statePrimerPaymentMethodSelectionStateThe latest selection state, bridged from the underlying selection scope. Read-only (@Published public private(set)) — drive UI from it and call the session’s methods to change it.
vaultedPaymentMethods[PrimerHeadlessUniversalCheckout.VaultedPaymentMethod]Get-only. Saved (vaulted) payment methods, loaded once during checkout initialization. Returns an empty array when none are available.
state is the snapshot you render from; vaultedPaymentMethods is the raw list of saved cards. Selection of a vaulted method is reflected back through state.selectedVaultedPaymentMethod.

Methods

MethodDescription
select(_ method: CheckoutPaymentMethod)Selects a payment method, starting its flow (card form, redirect, native wallet, etc.).
cancel()Cancels the current selection flow.
selectVaulted(_ method: PrimerHeadlessUniversalCheckout.VaultedPaymentMethod)Marks a vaulted method as selected so a subsequent submit targets it.
delete(_ method: PrimerHeadlessUniversalCheckout.VaultedPaymentMethod)Routes to the delete-confirmation screen for a vaulted method.
showAll()Navigates to the full list of saved payment methods.
updateCvvInput(_ cvv: String)Updates and validates the CVV for the selected vaulted card during CVV recapture. Drives state.cvvInput, state.isCvvValid, and state.cvvError.

select(_:)

public func select(_ method: CheckoutPaymentMethod)
Selects a payment method to begin its payment flow. Call this from a method row’s tap handler. The selected method is reflected in state.selectedPaymentMethod.
ParameterTypeDescription
methodCheckoutPaymentMethodThe payment method the user chose. Typically the value passed into the method slot of PrimerPaymentMethods.

cancel()

public func cancel()
Cancels the in-progress selection flow.

selectVaulted(_:)

public func selectVaulted(_ method: PrimerHeadlessUniversalCheckout.VaultedPaymentMethod)
Marks a saved payment method as selected. The selection is reflected in state.selectedVaultedPaymentMethod; a subsequent submit pays with this method. If the card requires CVV recapture, state.requiresCvvInput becomes true.
ParameterTypeDescription
methodPrimerHeadlessUniversalCheckout.VaultedPaymentMethodThe saved method to select.

delete(_:)

public func delete(_ method: PrimerHeadlessUniversalCheckout.VaultedPaymentMethod)
Routes to the delete-confirmation screen for a saved payment method.
ParameterTypeDescription
methodPrimerHeadlessUniversalCheckout.VaultedPaymentMethodThe saved method to remove.

showAll()

public func showAll()
Navigates to the full list of saved payment methods (the “show all saved methods” action).

updateCvvInput(_:)

public func updateCvvInput(_ cvv: String)
Updates and validates the CVV entered for the selected vaulted card during CVV recapture. The result is published through state.cvvInput, state.isCvvValid, and state.cvvError.
ParameterTypeDescription
cvvStringThe current CVV text from your input field.

PrimerPaymentMethodSelectionState

PrimerPaymentMethodSelectionState is the immutable snapshot published by state. It conforms to Equatable. Every stored property is public internal(set) — readable from your code but mutated only by the SDK, so treat it as read-only and call the session’s methods to change selection.
@available(iOS 15.0, *)
public struct PrimerPaymentMethodSelectionState: Equatable {
  public internal(set) var paymentMethods: [CheckoutPaymentMethod]
  public internal(set) var isLoading: Bool
  public internal(set) var selectedPaymentMethod: CheckoutPaymentMethod?
  public internal(set) var searchQuery: String
  public internal(set) var filteredPaymentMethods: [CheckoutPaymentMethod]
  public internal(set) var error: String?
  public internal(set) var selectedVaultedPaymentMethod: PrimerHeadlessUniversalCheckout.VaultedPaymentMethod?
  public internal(set) var isVaultPaymentLoading: Bool
  public internal(set) var requiresCvvInput: Bool
  public internal(set) var cvvInput: String
  public internal(set) var isCvvValid: Bool
  public internal(set) var cvvError: String?
  public internal(set) var isPaymentMethodsExpanded: Bool
}

Properties

PropertyTypeDescription
paymentMethods[CheckoutPaymentMethod]All available payment methods for the current session.
isLoadingBoolWhether the available payment methods are still loading.
selectedPaymentMethodCheckoutPaymentMethod?The currently selected available method, or nil.
searchQueryStringThe current search text applied to the method list.
filteredPaymentMethods[CheckoutPaymentMethod]The methods matching searchQuery.
errorString?An error message for the selection flow, or nil.
selectedVaultedPaymentMethodPrimerHeadlessUniversalCheckout.VaultedPaymentMethod?The currently selected saved method, or nil.
isVaultPaymentLoadingBoolWhether a payment with the selected vaulted method is in progress.
requiresCvvInputBoolWhether CVV input is required for the selected vaulted card.
cvvInputStringThe CVV value entered by the user.
isCvvValidBoolWhether the entered CVV is valid.
cvvErrorString?CVV validation error message, or nil.
isPaymentMethodsExpandedBoolWhether the payment methods section is expanded (showing all methods). Defaults to true; becomes false when the user selects a vaulted method or CVV input opens.
Because the state is Equatable, SwiftUI only re-renders observers when a meaningful field changes. Drive your custom rows and empty states directly from these properties rather than caching copies.

CheckoutPaymentMethod

paymentMethods and filteredPaymentMethods are arrays of CheckoutPaymentMethod, the model describing a single selectable method. It is documented in full on the PrimerPaymentMethods page; the key fields are id, type, name, icon, and the surcharge and styling properties.

Usage

Reading state and selecting a method

PrimerPaymentMethods hands each method slot a CheckoutPaymentMethod and an onSelect closure that calls select(_:) for you. To select outside a slot — for example from a custom header — call select(_:) on the session directly.
import SwiftUI
import PrimerSDK

struct CheckoutScreen: View {
  @StateObject private var session = PrimerCheckoutSession(clientToken: clientToken)

  var body: some View {
    ScrollView {
      PrimerPaymentMethods(
        method: { paymentMethod, onSelect in
          Button(action: onSelect) {
            HStack {
              if let icon = paymentMethod.icon {
                Image(uiImage: icon)
                  .resizable()
                  .scaledToFit()
                  .frame(width: 28, height: 28)
              }
              Text(paymentMethod.buttonText ?? paymentMethod.name)
              Spacer()
              if let surcharge = paymentMethod.formattedSurcharge {
                Text(surcharge).foregroundColor(.secondary)
              }
            }
            .padding()
          }
          .buttonStyle(.plain)
        }
      )
    }
    .primerCheckoutSession(session) { state in
      handle(state)
    }
  }
}

Working with vaulted methods and CVV recapture

When rendering saved methods, drive the UI from state and call the vaulted helpers on the session. If the selected card requires CVV recapture, state.requiresCvvInput is true; feed your CVV field through updateCvvInput(_:) and read state.isCvvValid / state.cvvError for validation feedback.
struct SavedMethodRow: View {
  @ObservedObject var session: PrimerSelectionSession
  let method: PrimerHeadlessUniversalCheckout.VaultedPaymentMethod

  var body: some View {
    VStack(alignment: .leading, spacing: 8) {
      HStack {
        Text(method.paymentMethodType)
        Spacer()
        Button("Use") { session.selectVaulted(method) }
        Button("Delete", role: .destructive) { session.delete(method) }
      }

      if session.state.requiresCvvInput,
         session.state.selectedVaultedPaymentMethod?.id == method.id {
        SecureField("CVV", text: Binding(
          get: { session.state.cvvInput },
          set: { session.updateCvvInput($0) }
        ))
        if let cvvError = session.state.cvvError {
          Text(cvvError).foregroundColor(.red).font(.caption)
        }
      }
    }
  }
}
Never mutate state directly — every property is internal(set). Change selection only through select(_:), selectVaulted(_:), delete(_:), showAll(), updateCvvInput(_:), and cancel().

See also

PrimerPaymentMethods

The slot-based view that renders the available payment methods.

PrimerVaultedPaymentMethods

Render and select saved (vaulted) payment methods.

PaymentMethodsDefaults

Default slot bodies used by the payment-method views.

PrimerCheckoutSession

The top-level session injected via .primerCheckoutSession(_:).