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).