Skip to main content

Method states

A method the session offers but that cannot be used right now stays a PaymentItem with a non-null disabled: DisabledState. The state has a code, a displayable message, and five boolean behaviours that tell you how to render the method and whether it will come back. The vocabulary is the web SDK's DisabledState, so both platforms react the same way.

val state = item.disabled ?: return Enabled
when {
state.isFiltered -> Unit // never in paymentMethods: you will not see it
state.isTechnicallyDisabled -> HideOrGreyOut(state.message) // no UI can be mounted
state.isRecoverable -> Dim(state.message) // keep the element mounted, it comes back
else -> GreyOut(state.message) // amount-driven or SUBMITTING, lifts by itself
}

The five behaviours​

BehaviourPropertyMeaningExpected reaction
FilteredisFilteredThe item is removed from paymentMethods altogetherNothing to render. The method never existed for this session
Technically disabledisTechnicallyDisabledA hard runtime failure. rememberPaymentElement mounts no UI, and submit() reports Failed(MethodDisabled)Grey the row out with message, or hide it. Final for the session
Requires UI clearrequiresUiClearAny mounted UI for the item should be torn downrememberPaymentElement does it. If you drive a coordinator yourself, dispose it
RecoverableisRecoverableThe partner reported broken-for-now, not broken-for-goodDim the row, keep the element mounted. It comes back on its own with a Ready event
RecomputableisRecomputableRe-evaluated whenever the amount left to pay changesNothing: the state lifts by itself when the split moves. Everything outside this group is final

The codes​

Fourteen codes are shared with the web SDK. Eleven are declared on Android (DisabledState.Code); the last three describe browser situations and are absent.

CodeCauseFilteredTechnicalClear UIRecoverableRecomputableExpected action
METHOD_UNSTABLEThe platform suspended the method for this session (stable == false in your Purse configuration)✓None: not listed
AMOUNT_CONDITION_UNREACHABLEThe method's minimum amount exceeds the whole order: no split could ever enable it✓None: not listed
PLUGIN_INCOMPATIBLEThe plugin rejected this client or session in its eligibility check✓None: not listed
FATAL_ERROR_BEFORE_RENDERDeclared for parity; the Android SDK reports an /init failure as PARTNER_UI_FATAL_ERROR instead✓None
TOKEN_INIT_FAILEDA saved gift card's balance could not be read from the issuer this session✓✓Show the saved card as unavailable; offer to enter it again
PARTNER_UI_FATAL_ERRORThe partner's step failed for good: /init failed, the wallet or widget could not initialize, the partner reported a fatal error✓✓Grey out or hide the method with message; offer the others
PARTNER_UI_RECOVERABLE_ERRORThe partner reported a failure it expects to recover from✓✓Dim the method, keep its UI mounted; it re-enables itself
MIN_AMOUNT_NOT_METWhat is left to pay is under the method's minimum (a gift card took too much)✓✓Grey out with message; removing a gift card lifts it
MAX_AMOUNT_EXCEEDEDWhat is left to pay is over the method's maximum (primaries only)✓✓Grey out; applying a gift card lifts it
PAYMENT_FULFILLEDGift cards cover the whole amount: no primary is needed✓✓Grey out every primary; show a Pay button that calls submitPayment()
SUBMITTINGA payment is in flight: every otherwise enabled method is locked until submitPayment returnsShow a progress indicator; lifted whatever the outcome
PAYMENT_ELEMENT_FATAL_ERRORWeb only: the DOM element failed✓✓Not raised on Android
PAYMENT_ELEMENT_RENDER_FAILEDWeb only: the DOM element could not render✓✓Not raised on Android
DOES_NOT_BELONG_TO_CURRENT_SESSIONWeb only: an element outlived setSession. Android rebuilds such elements through itemGenerations✓✓Not raised on Android

The amount-driven states carry their context: MinAmountNotMet(minAmount, restToPay), MaxAmountExceeded(maxAmount, restToPay), AmountConditionUnreachable(minAmount, maxAmount, orderAmount). PartnerUiFatalError and PartnerUiRecoverableError carry the partner's reason.

Where states come from​

MomentStates set
Session build (init, setSession)METHOD_UNSTABLE, AMOUNT_CONDITION_UNREACHABLE, PLUGIN_INCOMPATIBLE (filtered out before you see the list)
Every change of remainingAmountToPayMIN_AMOUNT_NOT_MET, MAX_AMOUNT_EXCEEDED, PAYMENT_FULFILLED recomputed; PARTNER_UI_RECOVERABLE_ERROR re-evaluated
A partner event (InitFailed, ClientError, PartnerError)PARTNER_UI_FATAL_ERROR, or PARTNER_UI_RECOVERABLE_ERROR when the partner says it can recover
A saved gift card's background /initTOKEN_INIT_FAILED on that SavedSecondaryToken
submitPayment entered and returnedSUBMITTING overlaid, then lifted

Every transition is also reported to Purse's monitoring as HEADLESS_CHECKOUT_METHOD_DISABLED, at warning level for a technical failure and at info level for a nominal one (Events and monitoring).

Selecting a disabled method

setPrimary and setPrimaryToken refuse a disabled item with MethodDisabled (METHOD_DISABLED), whose disabled property is this state. Rendering the row from item.disabled avoids the exception altogether.