Helpdesk

Integrations & webhooks

Send every paid order straight to your other tools — automatically, the moment a customer pays.

What this does

The moment a customer pays for one of your products, bookto sends the order details to every active webhook you have set up. This happens in real time, automatically — you don't have to do anything. You can use it to add buyers to your mailing list, log sales in a spreadsheet, send yourself a notification, or anything else your tools support.

Two keys, two purposes

Your Integrations page (in the dashboard, under Integrations) shows two different keys. They do opposite things — here's the difference in plain terms.

API key bk_… — incoming

You only need this if you connect through Zapier. You paste this key into Zapier so that Zapier is allowed to sign in to your bookto account. It is shown only once, right after you generate it — after that it can't be read again, so store it somewhere safe. If you generate a new one, the old key stops working immediately.

Signing secret — outgoing

This is created automatically for you. bookto uses it to "sign" every webhook it sends, so the receiver can confirm the message genuinely came from bookto and wasn't faked by someone else. You only need to look at this if you're building that check into your own server. If you connect via Zapier or just don't verify the signature, you can ignore it.

Two ways to connect

1. Your own webhook URL

If you have a URL that can receive data (your own server, or a tool like Make or n8n), paste it under Webhooks and click Add. That's it — no API key needed. bookto will start POSTing every paid order to that URL.

2. Through Zapier

Generate an API keyon the Integrations page and paste it into the bookto integration inside Zapier. Zapier then handles the webhook for you, and it will appear in your Webhooks list as "managed via Zapier". From there you can connect bookto to thousands of apps without writing any code.

Verifying the signature (for developers)

If you build your own server to receive webhooks, you can check that each request really came from bookto. Every POST includes these headers:

To verify: compute HMAC-SHA256(signing_secret, "<timestamp>.<raw JSON body>") and compare it to the signature header. They should match exactly. Use the raw, unparsed request body — not a re-stringified version.

import crypto from 'crypto'

// "signingSecret" is the value from your Integrations page.
// "rawBody" is the exact, unparsed request body (a string).
function isFromBookto(req, rawBody, signingSecret) {
  const timestamp = req.headers['x-bookto-timestamp']
  const signature = req.headers['x-bookto-signature'] // "sha256=<hex>"

  const expected =
    'sha256=' +
    crypto
      .createHmac('sha256', signingSecret)
      .update(timestamp + '.' + rawBody)
      .digest('hex')

  return signature === expected
}

What's in the payload

Every webhook sends the same JSON shape, so you can rely on it. Here's an example of what you'll receive:

{
  "event": "order.paid",
  "payment_provider": "mollie",
  "order_id": "…",
  "order_number": "ORD-…",
  "status": "paid",
  "created_at": "…",
  "paid_at": "…",
  "amount": {
    "total_incl": 1.21,
    "excl_vat": 1,
    "vat": 0.21,
    "vat_rate": 21,
    "currency": "EUR"
  },
  "vat_treatment": "standard",
  "product": { "name": "…" },
  "buyer": {
    "first_name": "…",
    "last_name": "…",
    "email": "…",
    "company": "…",
    "country": "BE"
  },
  "seller": { "id": "…", "entity": null },
  "is_test_order": false
}

Testing safely

A payment made in test mode also sends a webhook, marked with "is_test_order": true. That lets you try the whole flow without taking a real payment. A handy trick: paste a webhook.site URL into your Webhooks list to see exactly what bookto sends.

No duplicate notifications

Each paid order is delivered to your webhook only once, even if the payment provider repeats its own notification behind the scenes. You won't get the same order twice.

Still stuck?

Contact support →