Skip to main content

Callbacks

The Terminal API uses webhooks to notify your application about payment session and payment object events. This allows you to receive real-time updates about transaction status changes.

Webhook Configuration

Webhooks are configured through the Xendit Dashboard. You’ll need to provide a webhook URL where notifications will be sent.
Make sure your webhook endpoint is publicly accessible and can handle POST requests with JSON payloads.

Authentication

All webhook requests include authentication headers to verify the source:
x-callback-token
string
required
Webhook verification token - can get from dashboard
webhook-id
string
required
Unique identifier for the webhook request

Payment Session Callbacks

These callbacks are triggered by payment session events.

Endpoint

POST <Webhook URL provided by Partner via Xendit dashboard>

Events

terminal_session.completed

Payment session has been completed successfully

terminal_session.voided

Payment session has been voided

terminal_session.canceled

Payment session has been canceled

Payload Structure

event
string
The event enum: terminal_session.completed, terminal_session.voided, terminal_session.canceled
business_id
string
Xendit business ID
created_at
DateTime
Timestamp for webhook notification creation
data
object
Payment session data
data.business_id
string
Xendit-generated identifier for business that owns the transaction
data.reference_id
string
Merchant’s reference ID
data.payment_session_id
string
Payment Session ID
data.country
string
Country where the payment happened
data.currency
string
ISO 4217 Alpha-3 code
data.amount
number
Amount of session
data.payment_details
object
Payment details
data.payment_details.terminal_id
string
Terminal’s id
data.payment_details.order_id
string
Merchant’s Order ID
data.status
string
Payment status
data.metadata
object
A set of key-value pairs that can be used to store custom, unstructured information about the object
data.created
DateTime
The timestamp indicates when the resource was created
data.updated
DateTime
The timestamp indicates when the resource was last modified

Example Payment Session Callback

{
  "event": "terminal_session.completed",
  "business_id": "biz_1234567890",
  "created_at": "2025-01-27T10:45:00Z",
  "data": {
    "business_id": "biz_1234567890",
    "reference_id": "order-123",
    "payment_session_id": "ps_1234567890abcdef",
    "country": "ID",
    "currency": "IDR",
    "amount": 100000,
    "payment_details": {
      "terminal_id": "TERM001",
      "order_id": "ORDER123"
    },
    "status": "COMPLETED",
    "metadata": {
      "store_id": "store_001"
    },
    "created": "2025-01-27T10:30:00Z",
    "updated": "2025-01-27T10:45:00Z"
  }
}

Payment Object Callbacks

These callbacks are triggered by payment object events.

Endpoint

POST <Webhook URL provided by Partner via Xendit dashboard>

Events

terminal_payment.succeeded

Payment has been successfully processed

terminal_payment.voided

Payment has been voided

Payload Structure

event
string
The event enum: terminal_payment.succeeded, terminal_payment.voided
business_id
string
Xendit business ID
created_at
DateTime
Timestamp for webhook notification creation
data
object
Payment object data
data.business_id
string
Xendit-generated identifier for business that owns the transaction
data.reference_id
string
Merchant’s reference ID
data.payment_id
string
Payment ID
data.country
string
Country where the payment happened
data.currency
string
ISO 4217 Alpha-3 code
data.request_amount
number
Amount of payment
data.payment_details
object
Payment details
data.payment_details.terminal_id
string
Terminal’s id
data.payment_details.order_id
string
Merchant’s Order ID
data.status
string
Payment status
data.metadata
object
A set of key-value pairs that can be used to store custom, unstructured information about the object
data.created
DateTime
The timestamp indicates when the resource was created
data.updated
DateTime
The timestamp indicates when the resource was last modified

Example Payment Object Callback

{
  "event": "terminal_payment.succeeded",
  "business_id": "biz_1234567890",
  "created_at": "2025-01-27T10:45:00Z",
  "data": {
    "business_id": "biz_1234567890",
    "reference_id": "order-123",
    "payment_id": "pay_1234567890abcdef",
    "country": "ID",
    "currency": "IDR",
    "request_amount": 100000,
    "payment_details": {
      "terminal_id": "TERM001",
      "order_id": "ORDER123"
    },
    "status": "SUCCEEDED",
    "metadata": {
      "store_id": "store_001"
    },
    "created": "2025-01-27T10:35:00Z",
    "updated": "2025-01-27T10:45:00Z"
  }
}

Response Handling

Your webhook endpoint should respond with appropriate HTTP status codes:

Success

HTTP status code = 200Indicates successful processing of the webhook

Error

HTTP status code != 200Indicates an error in processing the webhook

Error Response Format

If you need to return an error, include the following fields in your response:
error_code
string
Error code
message
string
Providing additional information about the response

Example Error Response

{
  "error_code": "PROCESSING_ERROR",
  "message": "Unable to process webhook due to database connection issue"
}

Best Practices

Idempotency

Implement idempotency to handle duplicate webhook deliveries

Retry Logic

Xendit will retry failed webhooks, so ensure your endpoint can handle retries

Security

Always verify the webhook signature using the x-callback-token

Logging

Log all webhook events for debugging and audit purposes