Documentation
Api
Webhooks
Back to FAQsDocumentation Home

Webhooks Guide

Webhooks let TicketNation notify your server in real time when important events happen — orders placed via your affiliate links, payments confirmed, commissions earned. Instead of polling our API, your server receives an HTTP POST request the moment an event occurs.

Overview

PropertyValue
MethodPOST
FormatJSON body
Signature HeaderX-TN-Signature
Expected ResponseHTTP 200 (any 2xx accepted)
Timeout10 seconds
Retry Attempts3 (on non-2xx or timeout)

Setting Up Your Webhook

  1. Log in to the Partner Dashboard
  2. Navigate to Settings → Webhooks
  3. Enter your publicly accessible HTTPS endpoint URL
  4. Select the events you want to receive
  5. Click Save Webhook
  6. Use Send Test Event to verify your endpoint is receiving payloads correctly

Your endpoint must be reachable from the internet. Local addresses (localhost, 127.0.0.1) will not work in production. Use a tool like ngrok for local development testing.


Webhook Events

order.created

Fired when a new order is placed via your affiliate link. The order is in PENDING status — payment has not yet been confirmed.

Use this to: Log new order activity, update your own dashboards.

{
  "id": "evt_8f3b2a1c4d",
  "event": "order.created",
  "isTest": false,
  "timestamp": "2025-04-15T08:30:00.000Z",
  "data": {
    "orderId": "ord_x9k2m7n4p",
    "amount": 1500,
    "currency": "PHP",
    "status": "PENDING"
  }
}

order.completed

Fired when payment is confirmed and tickets have been issued to the buyer.

Use this to: Trigger commission tracking, send custom confirmation emails, update CRM records.

{
  "id": "evt_9c4d3b2e1f",
  "event": "order.completed",
  "isTest": false,
  "timestamp": "2025-04-15T08:35:00.000Z",
  "data": {
    "orderId": "ord_x9k2m7n4p",
    "amount": 1500,
    "currency": "PHP",
    "status": "COMPLETED"
  }
}

order.failed

Fired when a payment attempt fails, is declined, or expires without payment.

Use this to: Alert your team, remove pending order from your system.

{
  "id": "evt_2a1b3c4d5e",
  "event": "order.failed",
  "isTest": false,
  "timestamp": "2025-04-15T08:40:00.000Z",
  "data": {
    "orderId": "ord_x9k2m7n4p",
    "amount": 1500,
    "currency": "PHP",
    "status": "FAILED",
    "reason": "Payment declined"
  }
}

commission.earned

Fired when a commission is calculated and recorded for your account. This fires after order.completed once commission rules are applied.

Use this to: Update your internal earnings records, trigger payout reports.

{
  "id": "evt_5f6g7h8i9j",
  "event": "commission.earned",
  "isTest": false,
  "timestamp": "2025-04-15T08:36:00.000Z",
  "data": {
    "commissionId": "comm_7r8s9t0u",
    "amount": 150,
    "currency": "PHP",
    "orderId": "ord_x9k2m7n4p"
  }
}

Payload Structure

Every webhook payload follows the same top-level structure:

FieldTypeDescription
idstringUnique delivery ID for this webhook event
eventstringEvent type (e.g. order.completed)
isTestbooleantrue when sent via "Send Test Event" in the dashboard
timestampstringISO 8601 UTC timestamp of when the event occurred
dataobjectEvent-specific payload (see each event above)

Signature Verification

Every webhook request includes an X-TN-Signature header. Always verify this signature before processing the payload to ensure the request genuinely came from TicketNation.

The signature is an HMAC-SHA256 hash of the raw request body, using your webhook secret as the key. Your secret is available in the Partner Dashboard under Settings → Webhooks.

Verification Example (Node.js)

const crypto = require('crypto');

function verifyWebhookSignature(rawBody, signature, secret) {
  const expectedSignature = crypto
    .createHmac('sha256', secret)
    .update(rawBody, 'utf8')
    .digest('hex');

  // Use timingSafeEqual to prevent timing attacks
  const sigBuffer = Buffer.from(signature);
  const expectedBuffer = Buffer.from(expectedSignature);

  if (sigBuffer.length !== expectedBuffer.length) return false;
  return crypto.timingSafeEqual(sigBuffer, expectedBuffer);
}

// Express.js example
app.post('/webhooks/ticketnation', express.raw({ type: 'application/json' }), (req, res) => {
  const signature = req.headers['x-tn-signature'];
  const secret = process.env.TN_WEBHOOK_SECRET;

  if (!verifyWebhookSignature(req.body, signature, secret)) {
    return res.status(401).send('Invalid signature');
  }

  const payload = JSON.parse(req.body);

  switch (payload.event) {
    case 'order.completed':
      // Handle completed order
      break;
    case 'commission.earned':
      // Record commission
      break;
  }

  // Respond quickly — process async if needed
  res.status(200).send('OK');
});

Important: Use express.raw() (not express.json()) to receive the raw request body. The signature is computed from the raw bytes — parsing JSON first will break verification.


Retry Logic

If your endpoint returns a non-2xx status code or times out (>10 seconds), TicketNation will retry the delivery:

AttemptDelay After Previous
1st retry30 seconds
2nd retry5 minutes
3rd retry50 minutes

After 3 failed retries the delivery is marked as failed. You can manually retry failed deliveries from the Delivery History tab in the Partner Dashboard.


Testing

Use the Send Test Event button in the Partner Dashboard (Settings → Webhooks) to send a sample payload with isTest: true to your endpoint. This lets you verify your endpoint is reachable and your parsing logic is correct without waiting for real orders.

You can also use the Delivery History table to inspect every delivery attempt, view the exact payload sent, and see your server's response status.


Security Best Practices

  • Always verify the X-TN-Signature header. Reject requests with invalid or missing signatures.
  • Use HTTPS. Never configure a plaintext http:// endpoint for production webhooks.
  • Respond quickly. Return 200 OK within 10 seconds. If processing takes longer, queue the job and respond immediately.
  • Be idempotent. The same event may be delivered more than once on retries. Use the id field to detect and deduplicate duplicate deliveries.
  • Rotate your secret periodically. Use the Regenerate Secret button in the dashboard and update your server configuration.

Need Help?

  • Developer Support: developers@ticketnation.ph
  • API Documentation: API Overview
  • Partner Dashboard: Settings → Webhooks
Back to FAQsNeed More Help?