val controller = rememberCardFormController(checkout)val state by controller.state.collectAsStateWithLifecycle()MyPayButton( enabled = !state.isLoading, onClick = { controller.submit() },)
Android’s isLoading only covers card form submission. There is no unified checkout-level processing state across all payment methods. For PrimerCheckoutSheet, swipe dismissal can be controlled via PrimerSettings.uiOptions.dismissalMechanism, but the back button is always active.
Each PrimerCardForm slot receives the active PrimerCardFormSession. Read session.state.isLoading and session.state.isValid directly to drive button state — the session republishes its state on every change.
val controller = rememberCardFormController(checkout)val state by controller.state.collectAsStateWithLifecycle()BackHandler(enabled = state.isLoading) { // Intercept back press during payment processing}
BackHandler only intercepts the system back gesture. For PrimerCheckoutSheet, swipe-to-dismiss is configured separately via PrimerSettings.uiOptions.dismissalMechanism. The SDK does not block the back button during processing.
Surface the session’s loading state with the submit slot, then bind it to .interactiveDismissDisabled() on the enclosing sheet:
@StateObject private var checkoutSession: PrimerCheckoutSession@State private var isLoading = falseinit(clientToken: String) { _checkoutSession = StateObject( wrappedValue: PrimerCheckoutSession(clientToken: clientToken) )}var body: some View { ScrollView { PrimerCardForm(submitButton: { cardSession in SubmitButton(session: cardSession, isLoading: $isLoading) }) } .interactiveDismissDisabled(isLoading) .primerCheckoutSession(checkoutSession)}struct SubmitButton: View { @ObservedObject var session: PrimerCardFormSession @Binding var isLoading: Bool var body: some View { Button("Pay") { session.submit() } .disabled(!session.state.isValid || session.state.isLoading) .onChange(of: session.state.isLoading) { isLoading = $0 } }}
.interactiveDismissDisabled() stops the shopper from swiping away the sheet that holds PrimerCardForm while a card payment runs. This includes the time before your onBeforePaymentCreate handler decides. Primer’s own sheets block swipe-to-dismiss while a payment is processing: the processing screen that .primerCheckoutSession presents, PrimerCheckout in a sheet, and PrimerCheckoutPresenter.