.on(name, handler) API at two levels:
- Instance events —
payrails.on(name, handler). Session-level and in-flight payment-attempt events (success,failed,pending,buttonClicked,requestStart,actionRequired,sessionExpired,deliveryAddressChanged). - Element events —
element.on(name, handler), whereelementis the object returned bypayrails.cardForm(),payrails.paymentButton(),payrails.googlePayButton(), and so on. Element events describe one rendered element (change,focus,blur,ready,saveInstrumentCheckboxChanged,preferredSchemeChanged,billingAddressChanged,validate,stateChanged,paymentOptionSelected).
.on() returns an unsubscribe function. Handlers may be async; the SDK awaits
each handler before proceeding. A handler that throws is logged and isolated
(other handlers still run). Payrails.init resets all subscriptions.
Init-time callback (the one exception)
The only bag callback that still exists isonClientInitialized, passed inside
PayrailsClientOptions.events on Payrails.init. It has no .on() form
because it fires during construction, before a .on(...) listener could
register.
Payrails instance is constructed, and again after a
successful session refresh (see sessionExpired). Its argument is the execution
response object (WorkflowExecutionResponse, e.g. execution.id).
Instance events — payrails.on(name, handler)
Every payment-attempt payload carries PaymentAttemptContext:
One listener fires for any element’s event in the session — filter with
event.paymentMethodCode / event.action if you need per-method behaviour.
success
Fires when authorization (or tokenization) completes successfully.
Payload: { …ctx, data? }. data carries the tokenization result on a
TOKENIZE success (notably for Google Pay / Apple Pay) and is absent for flows
that return nothing (e.g. AUTHORIZE).
failed
Fires when the attempt fails or is canceled.
Payload: { …ctx, data?: { code?, message? } } where code is an
AuthorizationFailureReasons value (VALIDATION_FAILED, AUTHORIZATION_ERROR,
AUTHENTICATION_ERROR, UNKNOWN_ERROR, USER_CANCELLED).
pending
Fires when the payment ends in a pending state (e.g. the result is not final yet
after a redirect or challenge).
Payload: { …ctx, data? }.
requestStart (cancelable)
Fires immediately before the authorize/tokenize request is sent.
Payload: { …ctx, preventDefault() }. Call preventDefault() to abort — the
SDK then fires failed with code: 'VALIDATION_FAILED'.
buttonClicked (cancelable)
Fires when the shopper clicks the payment button, before anything is submitted.
Payload: { …ctx, bin?, preventDefault() }. For card payments bin carries the
current BIN. Call preventDefault() to abort — the SDK then fires failed with
code: 'VALIDATION_FAILED'.
apmButton runs this gate after its form validates, and requestStart after
it, so preventDefault() on either blocks an APM attempt the same way it blocks
a card one.
sessionExpired
Fires when the SDK detects the client session has expired, when a payment
attempt fails because the session/vault token is no longer valid, or when an
approve-in-app payment (such as MB WAY) is declined, isn’t approved in time or
can’t be confirmed, so the shopper’s retry starts a new payment.
Payload: void. Handlers may return a fresh InitOptions
({ version, data }); the SDK awaits all handlers, re-inits from the first
non-null result, and then re-runs the init onClientInitialized callback.
deliveryAddressChanged (cancelable)
Fires when the shopper changes the shipping address inside an express-checkout
sheet (PayPal, Apple Pay).
Payload: { …ctx, deliveryAddress?, preventDefault() }. Call preventDefault()
to reject the address (the Apple Pay sheet shows an error and prompts for
another address; PayPal cancels the change).
- Apple Pay exposes only redacted fields (
city,postalCode,state,country.code) before the shopper authorizes; the full address is available onsuccess. Apple Pay requires a response within ~30 seconds — keep this handler fast. - On PayPal, the payload shape is
{ orderID?, paymentID?, paymentToken?, shippingAddress?: { city, countryCode, postalCode, state } }.
actionRequired (cancelable)
Fires when a payment attempt needs a shopper-facing action and the SDK is about
to perform its default behavior — navigating to a redirect URL or presenting the
3DS challenge (popup or redirect).
Payload (ActionRequiredEvent):
Element events — element.on(name, handler)
Element events are declared on the object returned by an element factory
(cardForm, paymentButton, googlePayButton, applePayButton,
paypalButton, dropin, dynamicElement, apmForm, apmButton, …). Every
element’s .on() accepts any element event name, so subscribing to one that an
element never emits compiles but never fires.
change
Fires on every input change.
Payload: { isValid, cardNetwork, bin?, billingAddress?, cardSchemes? }. On a
standalone secure field (collect element) the payload is
{ isValid, isEmpty, network, bin?, cardSchemes? } — note network, not
cardNetwork. On an APM form the payload is { isValid } only.
focus / blur
Fires when a card field gains / loses focus. Focusing the card form also clears
a cardList selection.
Payload: void.
ready
Fires when all secure fields have mounted and the form is interactive. On an APM
form it fires when the form’s frame has loaded.
Payload: void.
saveInstrumentCheckboxChanged
Fires when the shopper toggles the “save instrument” checkbox.
Payload: { checked: boolean }.
preferredSchemeChanged
Fires when the detected/selected card scheme changes for a co-branded card.
Payload: { preferredScheme: string, cardSchemes: CardScheme[] }.
billingAddressChanged
Fires when the shopper edits the billing address form.
Payload: { isValid: boolean, billingAddress? }.
validate
Fires when a pay button validates its form on click, before the payment request:
the card payment button with the card form, and the APM button with its APM
form.
Payload: { isValid, error?, fieldErrors? }. fieldErrors maps fields to their
validation errors. On the APM button, fieldErrors names the fields that
failed, and is omitted when the form is valid.
stateChanged
Fires when a payment button switches between enabled and disabled (e.g. as
card-form validity changes).
Payload: { state: 'enabled' | 'disabled' }.
Wallet availability (not an event)
Wallet availability is exposed asreadonly isAvailable: Promise<boolean> on
googlePayButton, applePayButton, and paypalButton — not as an event,
because it is a capability check that settles once. The promise never rejects;
it resolves to false on any check-side failure.
paymentOptionSelected
Fires when the shopper selects a payment option in the drop-in.
Payload: { paymentMethod?, instrument? }. paymentMethod is the selected
method’s configuration; instrument is set when a stored instrument was
selected.