5.13: Webhooks
In this section, we will guide you through the process of receiving real-time event notifications from the Golfdigg OTA API. When a subscribed event occurs, we will send an HTTP POST request to your registered endpoint URL.
5.13.1: Registering Your Webhook Endpoint
Webhook registration is currently handled manually. To register your endpoint URL, please contact Golfdigg support with the following information:
endpointUrl— The URL of your server that will receive webhook event POST requests.secret— A secret key of your choice, used to verify the authenticity of incoming webhook requests.
Note: Self-service webhook configuration via the admin web portal is planned for a future release.
5.13.2: Webhook Payload Format
When an event occurs, we will send an HTTP POST request to your registered endpointUrl with the following payload structure:
interface WebhookPayload<T> {
eventId: string; // Unique identifier for the event
eventType: string; // Type of the event (e.g., payment_success)
createdAt: string; // ISO 8601 timestamp of when the event was created
data: T; // Event-specific data object
}
| Field | Type | Description |
|---|---|---|
eventId | string | Unique identifier for this webhook event. |
eventType | string | The type of event that triggered this webhook. |
createdAt | string | ISO 8601 timestamp of when the event was created. |
data | object | The event payload. Structure varies by event type. |
5.13.3: Webhook Request Headers
Each webhook request sent to your endpoint will include the following custom headers for verification purposes:
| Header | Description |
|---|---|
X-Ota-Event-Id | The unique identifier of the event, matching the eventId field in the payload. |
X-Ota-Event-Sig | HMAC signature of the payload using your secret. Use this to verify the request integrity. |
X-Ota-Timestamp | Unix timestamp of when the request was sent. Use this to guard against replay attacks. |
Header Example:
X-Ota-Event-Id: payment_success_1780486622603299709
X-Ota-Event-Sig: e9ab4f74354451a993723b16dffd85face14078ecca21b0bbb7b22fc50e43fba
X-Ota-Timestamp: 1780486622
5.13.4: Event Types
payment_success
Triggered when an order has been successfully paid. The data field contains the full order details.
Data Model (OrderModelDto):
| Field | Type | Description |
|---|---|---|
id | string | Unique identifier of the order. |
status | string | Current status of the order (e.g., PAID). |
txNo | string | Transaction number for the order. |
agencyId | string | Identifier of the agency associated with the order. |
agencyName | string | Name of the agency. |
slotId | string | Identifier of the tee time slot. |
courseId | string | Identifier of the golf course. |
courseName | string | Name of the golf course. |
walletId | string | Identifier of the wallet used for the order. |
customerName | string | Name of the customer. |
customerEmail | string | Email of the customer. |
customerMobile | string | Mobile number of the customer. |
customerId | string | Identifier of the customer, if available. |
amount | int64 | Total amount of the order. |
priceAfterDiscount | int64 | Final price after any discounts applied. |
reserveId | string | Identifier of the associated reservation. |
reserve | object | Reservation details. See reserve model below. |
golfReserve | object | Golf-specific booking units (golfer, cart, caddie counts). |
additionGolfer | string[] | List of additional golfer identifiers, if any. |
paymentLink | string | Payment link URL, if applicable. May be null. |
createdAt | string | ISO 8601 timestamp of when the order was created. |
updatedAt | string | ISO 8601 timestamp of when the order was last updated. |
5.13.5: Payload Example (payment_success)
{
"eventId": "payment_success_1780486622603299709",
"eventType": "payment_success",
"createdAt": "2026-06-03T18:37:02.603318985+07:00",
"data": {
"id": "6a201150faa1002654967b93",
"status": "PAID",
"txNo": "ORDER-2026-06-03-802488541",
"agencyId": "68806539e318929087752315",
"agencyName": "Fang",
"slotId": "6a1d3bc8e4b07bcc9a2c785c",
"courseId": "5c9c8252ef0ab53dcf12e8d2",
"courseName": "331 GOLF CLUB-testtt",
"walletId": "68806539e318929087752316",
"customerName": "testApi-pay",
"customerEmail": "testApi-pay",
"customerMobile": "testApi-pay",
"customerId": "",
"amount": 360000,
"priceAfterDiscount": 360000,
"reserveId": "6a201150e4b0581f4a1b2660",
"reserve": {
"id": "6a201150e4b0581f4a1b2660",
"code": "G260603-00004",
"status": "BOOKING",
"golf": {
"slotTime": 1780452000000,
"slotTimeString": "2026-06-03T09:00:00+0700",
"persons": 3,
"carts": 3,
"caddies": 3
}
},
"golfReserve": {
"golfer": 3,
"cart": 3,
"caddie": 3
},
"additionGolfer": null,
"paymentLink": null,
"createdAt": "2026-06-03T11:34:40.712Z",
"updatedAt": "2026-06-03T11:34:40.712Z"
}
}
5.13.6: Verifying Webhook Signatures
To ensure that incoming webhook requests are genuinely from Golfdigg, you should verify the X-Ota-Event-Sig header using your registered secret. The signature is an HMAC-SHA256 hash of the raw request body signed with your secret key.
Verification Example (Node.js):
const crypto = require("crypto");
function verifyWebhookSignature(rawBody, secret, signature) {
const expectedSig = crypto
.createHmac("sha256", secret)
.update(rawBody)
.digest("hex");
return expectedSig === signature;
}
Note: Always use the raw request body (before JSON parsing) when computing the signature. Parsing and re-serializing the JSON may alter the byte order and cause signature verification to fail.
5.13.7: Responding to Webhook Events
Your endpoint must return an HTTP 2xx status code to acknowledge receipt of the webhook. If we do not receive a successful response, the delivery may be retried.
- Respond quickly — perform any heavy processing asynchronously.
- Return
200 OKas soon as the payload is received and validated.