Examine Events & Display statuses

Events and Display statuses provide two complementary ways to track the payment flow and determine what should be presented to the customer. Events deliver real-time payment flow directives, while Display statuses provide the current user-facing state through getStatus().

Subscribe with checkout.on(event, callback); an unsubscribe function is returned. There are only three Events and the whole payment flow arrives as directives inside next_action.

Events

Ready

Initialisation is complete: the bridge is up, the session configuration is loaded, and the feature types are verified. No feature exists yet. This is the right moment to render the Payment method selection.

Payload field Description
sessionConfig.payment_request { id, amount, currency, … } — payment request data for displaying the amount.
sessionConfig.features The list of features allowed for this session ({ type, config }).
sessionConfig.polling State polling parameters (interval_ms, max_attempts, disable_max_on) — informational; the SDK runs the polling itself.

Next_action: directives

Emitted for every directive. The redirect and acs_redirect directives are always executed by the SDK itself. Merchant overrides do not exist; for them the event is purely informational.

Three directives (awaiting_details, poll, complete) are synthesised locally from the payment state and are never sent by the backend as such.

Action.type Fields What Merchants should do?
awaiting_details Show the payment form.
poll Show a loader — the payment is processing, the SDK polls the state.
redirect url, method: 'GET' | 'POST', params?, target: '_self' | '_blank' Nothing — the SDK performs the navigation itself (APM / hosted pages; always full-page).
acs_redirect url, method, params Nothing — the SDK runs the 3-DS challenge itself (redirect or iframe — per challenge.acsMode). Covers both protocol versions (3DS1 and EMV 3DS2).
retry reason, resolutionGroup, messageKey?, message? The payment was declined, a retry is possible. Show the reason (message — ready-made EN text; for your own i18n map messageKey / reason / resolutionGroup) and bring the form back. The customer's next submit() is the retry. checkout.retry() — only if there is no form on the page.
auto_retry countdownSec, reason, resolutionGroup, messageKey?, message? The platform is already retrying the attempt on the server in countdownSec seconds. Show a countdown, keep the form locked. Do not call retry() — it would fork a parallel attempt.
complete status: 'success' | 'fail' | 'pending', resolution, resolutionGroup, messageKey?, message? (texts — on fail) Show the result screen. A UI signal only — fulfill obligations only after a server-side check (webhook / private API by paymentRequestId).

Error

Payload: {error: CheckoutError} — a typed error.

This is where asynchronous errors outside method promises land (e.g. the challenge fallback, polling failures); errors of the calls themselves (init, submit …) also arrive as the rejection of the corresponding promise.

Display statuses

checkout.getStatus() returns the backend-computed answer to "what to show the user" — you never interpret raw transaction statuses.

interface DisplayStatus {
  status:
    | 'awaiting_input'
    | 'processing'
    | 'action_required'
    | 'retry_available'
    | 'success'
    | 'fail'
    | 'pending';
  resolution: string | null; // reason code 
  resolutionGroup: string | null; // reason group 
  messageKey?: string | null; // translation key of the reason text
  message?: string | null; // ready-made EN text (for retry_available / fail)
}
Status Meaning
awaiting_input Show the payment form (corresponds to the awaiting_details directive).
processing Show a loader (corresponds to the poll directive).
action_required A 3DS challenge or redirect is in progress — the SDK is in control.
retry_available Declined, a retry is possible (the auto-retry countdown arrives in the auto_retry directive).
success Completed successfully (final).
fail Final decline (final).
pending Final but not yet confirmed (e.g. capture is in progress). Treat it as "the result will become clear" — your backend confirms the final outcome.

Did this page help you?