Skip to main content
The SDK uses an event-driven architecture. Subscribe to events to react to payment state changes, errors, and telemetry data.

Subscribing to Events

// Listen to an event
pos.on('payment.confirmed', (event) => {
  console.log('Paid!', event.session.id);
});

// Listen once
pos.once('payment.created', (event) => {
  console.log('Session started:', event.session.id);
});

// Unsubscribe
const handler = (event) => console.log(event);
pos.on('payment.failed', handler);
pos.off('payment.failed', handler);

Payment Events

These are the primary events you should handle in your integration.

payment.created

Fired when a payment session is opened and the deposit address is ready.
pos.on('payment.created', (event) => {
  // event.session: POSSession — full session with address and QR code
  // event.correlationId: string — unique ID for this payment flow
});

payment.received

Fired when crypto has been received on-chain but the fiat payout is still processing.
pos.on('payment.received', (event) => {
  // event.sessionId: string
  // event.correlationId: string
});

payment.confirmed

Fired when payout is complete. This is the signal to fulfill the order.
pos.on('payment.confirmed', (event) => {
  // event.session: POSSession — includes final amounts, rate used
  // event.correlationId: string
});
Always verify payment status from your backend API before fulfilling. Use this event to trigger a server-side check, not to directly deliver goods.

payment.failed

Fired when payment processing fails.
pos.on('payment.failed', (event) => {
  // event.sessionId: string
  // event.reason: string — human-readable failure reason
  // event.code: string — machine-readable error code
  // event.correlationId: string
});

payment.expired

Fired when the payment session times out before crypto is received.
pos.on('payment.expired', (event) => {
  // event.sessionId: string
  // event.correlationId: string
});

payment.cancelled

Fired when the customer closes the checkout modal.
pos.on('payment.cancelled', (event) => {
  // event.sessionId: string
  // event.correlationId: string
});

payment.status_changed

Fired on every status transition during polling. Useful for updating UI state.
pos.on('payment.status_changed', (event) => {
  // event.result: SessionStatusResult — { sessionId, status, polledAt }
  // event.previousStatus: SessionStatus | null
  // event.correlationId: string
});

SDK Lifecycle Events

sdk.initialized

Fired after pos.init() completes successfully.
pos.on('sdk.initialized', (event) => {
  // event.merchantId: string
  // event.sdkVersion: string
  // event.timestamp: string
});

sdk.terminated

Fired after pos.terminate() completes.
pos.on('sdk.terminated', (event) => {
  // event.reason: string
  // event.timestamp: string
});

state.transition

Fired on every state machine transition. Useful for debugging.
pos.on('state.transition', (event) => {
  // event.from: SDKState
  // event.to: SDKState
  // event.timestamp: string
  // event.correlationId: string
});

Fraud Events

fraud.review_started

Fired when the fraud engine begins evaluating a payment.
pos.on('fraud.review_started', (event) => {
  // event.sessionId: string
  // event.signals: FraudSignal[] — detected fraud indicators
  // event.correlationId: string
});

fraud.review_completed

Fired when the fraud evaluation finishes.
pos.on('fraud.review_completed', (event) => {
  // event.sessionId: string
  // event.score: number — 0-100 fraud score
  // event.action: 'allow' | 'block' | 'review'
  // event.correlationId: string
});

API & Infrastructure Events

These events are useful for debugging and observability.

api.request / api.response / api.error

pos.on('api.request', (event) => {
  // event.method, event.url, event.correlationId, event.attempt
});

pos.on('api.response', (event) => {
  // event.status, event.url, event.correlationId, event.durationMs
});

pos.on('api.error', (event) => {
  // event.url, event.status, event.message, event.correlationId, event.attempt
});

circuit_breaker.opened / circuit_breaker.closed

Fired when the API client circuit breaker trips or recovers.
pos.on('circuit_breaker.opened', (event) => {
  // event.service: string — which service tripped
  // event.failureCount: number
});

pos.on('circuit_breaker.closed', (event) => {
  // event.service: string
});

Session Status Values

The SessionStatus type represents where a payment is in its lifecycle:
StatusDescription
pendingSession created, waiting for crypto
paidCrypto received on-chain
payout_pendingFiat payout is being processed
paid_outFiat payout completed successfully
payout_failedFiat payout failed
expiredSession timed out
cancelledSession cancelled by customer or merchant
refundedPayment was refunded

SDK States

The internal state machine tracks the SDK’s lifecycle:
StateDescription
BOOTSTRAPPINGSDK is initializing
INITIALIZEDinit() completed, ready for use
CONFIG_VALIDATEDConfiguration has been validated
PAYMENT_CREATINGCreating a payment session
ADDRESS_GENERATEDDeposit address ready
WAITING_FOR_PAYMENTPolling for crypto arrival
PAYMENT_RECEIVEDCrypto detected on-chain
FRAUD_REVIEWFraud engine is evaluating
CONFIRMEDPayment confirmed and payout complete
FAILEDPayment failed
EXPIREDSession expired
CANCELLEDSession cancelled
TERMINATEDSDK shut down
Check the current state at any time:
const state = pos.getState(); // e.g. 'INITIALIZED'