Skip to main content

Card-Present Device Webhook Events

Overview

The gateway emits two card-present (NEXGO / XTMS) device lifecycle events so downstream systems can react to terminal binding completion instead of polling device provisioning status.

Both events fire asynchronously through the standard webhook delivery pipeline (signed HMAC body with delivery retries). Subscribe via the Webhooks page in the merchant dashboard.

Delivery semantics: at-least-once. A repeated reconcile sweep over the same terminal may re-publish after the publisher's idempotency window. Consumers should treat (locationId, gatewayDeviceId, serialNumber, status) as the business idempotency key.

Event types

card_present_device.synced

Fires when a pending binding transitions to BOUND after binding reconciliation. After XTMS confirms ownership, the card-present service attempts to submit the Easy Deploy template configured in the admin portal for the terminal's device model (NEXGO N92, EF20, N62), falling back to the provider-wide default for other models. Template delivery is tracked separately and does not change the verified binding status.

{
  "eventId": "evt_01HX...",
  "eventType": "card_present_device.synced",
  "timestamp": "2026-06-19T00:00:00Z",
  "organizationId": "org_01HX...",
  "locationId": "loc_01HX...",
  "provider": "NEXGO",
  "serialNumber": "SN-1234",
  "gatewayDeviceId": "terminal-SN-1234",
  "status": "BOUND",
  "syncedAt": "2026-06-19T00:00:00Z"
}

card_present_device.bind_failed

Fires when a binding reaches a terminal failure after binding reconciliation (a non-deferrable XTMS error, or the device is already bound elsewhere). A retryable PENDING_CLOUD_SYNC deferral does not emit — only a terminal FAILED outcome does, so consumers can surface a real failure instead of an indefinite pending state.

{
  "eventId": "evt_01HX...",
  "eventType": "card_present_device.bind_failed",
  "timestamp": "2026-06-19T00:00:00Z",
  "organizationId": "org_01HX...",
  "locationId": "loc_01HX...",
  "provider": "NEXGO",
  "serialNumber": "SN-1234",
  "gatewayDeviceId": "terminal-SN-1234",
  "status": "FAILED",
  "syncedAt": "2026-06-19T00:00:00Z",
  "failureReason": "Device SN-1234 is already bound to another merchant"
}

eventId, eventType, timestamp, organizationId and locationId are the delivery envelope; the other fields are the event payload. The SDKs decode the events as WebhookEvent.CardPresentDeviceSynced / WebhookEvent.CardPresentDeviceBindFailed (Kotlin) and CardPresentDeviceSyncedEvent / CardPresentDeviceBindFailedEvent (TypeScript).