Merchant Callbacks tell Bolt what to do during checkout. Transaction webhooks tell your server what happened afterwards. You need both, they are configured in different places, and they do not share a URL.

Callbacks are not webhooks

They are stored separately, so a webhook endpoint does not fall back to your Universal Merchant API URL. Configuring callbacks and expecting webhooks to arrive at the same URL results in a checkout that works and an order record that never appears.
Do not look for transaction webhooks under Administration > API > Merchant Callbacks. The callback type dropdown there has no transaction webhook option. Webhooks live under Administration > Developers > Webhooks.

If you cannot see the Webhooks page

The page is filtered out of navigation rather than returning an error, so an account without access sees nothing at all rather than a permission message. Three things restrict it:
  • Write access to webhook settings. Without it the navigation item is hidden.
  • Marketplace sub-merchant accounts cannot configure webhooks.
  • Without the v2 webhooks capability a division is limited to a single endpoint.
Custom cart divisions have the v2 capability by default. See prerequisites and readiness.

One endpoint receives everything

There is no event picker when you add an endpoint. It is subscribed to every event Bolt emits, so your handler must switch on both the notification type and the object it concerns, and acknowledge the rest. These are the values that appear in the payload. The Merchant Dashboard displays uppercase forms of the same names, such as PAYMENT and ORDER_CREATED, so the same event can look like two different things depending on where you read it. Return a 2xx for events you do not handle. An unacknowledged delivery is retried.

A pending payment sends two notifications

When a transaction becomes pending, Bolt sends a pending notification for the transaction object and, separately, an order_created notification for the order object. One state change, two deliveries. A handler that keys only on “did something happen for this order” will process the same transition twice. Key on the object and type together, and make your handler idempotent on the order reference.

Configuring over the API

Webhooks can be created without the dashboard:
cURL
List what is registered with GET /v1/webhooks, and callbacks with GET /v1/merchant/callbacks. Both require division_id, which is the second segment of your publishable key. See prerequisites.
POST /v1/merchant/callbacks can set a callback URL but cannot clear one. An empty URL is rejected rather than treated as a removal, so recovering from a bad callback URL means overwriting it with a working one or using the dashboard. Webhook subscriptions are not affected by this.

Verifying webhooks

Webhooks are signed the same way callbacks are. See verifying the request came from Bolt.