Build Webhooks

Learn how to write the code that properly handles webhook notifications.

The first step to begin receiving event notifications with webhooks is to build a webhook endpoint on your server.

What is a Webhook Endpoint

Creating a webhook endpoint is no different from creating any other page on your website. It’s an HTTP or HTTPS endpoint on your server with a URL. If you’re still developing your endpoint on your local machine, it can be HTTP. After it’s publicly accessible, it must be HTTPS. You can use one endpoint to handle several different event types at once, or set up individual endpoints for specific events.

Step One: Identify the Events to Monitor

Identify the type of events and the event objects your webhook endpoint needs to parse.

Step Two: Create a Webhook Endpoint

Set up an HTTP endpoint on your local machine that can accept unauthenticated webhook requests with a POST method. You can use ngrok to expose your local server to the public internet when testing.

Step Three: Handle Requests from Tilled

Your endpoint must be configured to read event objects for the type of event notifications you want to receive. Tilled sends events to your webhook endpoint as part of a POST request with a JSON payload.

Check Event Objects

Each event is structured as an event object with a type, id, account_id, and related Tilled resource nested under data. Your endpoint must check the event type and parse the payload of each event.

 2  "id": "evt_qLX9Fqyspi8bk0j06yc7s",
 3  "account_id": "acct_QvlHDyOkQ44HFHsZGs0Gi",
 4  "type": "payment_intent.succeeded",
 5  "data": {
 6    "id": "pi_Hf068QvxJax26OBIKgmw9",
 7    "status": "succeeded",
 8    ...
 9  }

Return a 2xx Response

Your endpoint must quickly return a successful status code (2xx) prior to any complex logic that could cause a timeout. For example, you must return a 200 response before updating a customer’s order as paid in your accounting system.

Built-in Retries

Tilled webhooks have built-in retry methods for 3xx, 4xx, or 5xx response status codes (multiple attempts over several hours). If Tilled doesn’t quickly receive a 2xx response status code for an event, we mark the event as failed. You can query for missed events to reconcile the data over any time period.

Use webhook signatures to verify that Tilled generated a webhook request and that it didn't come from a server acting like Tilled.

Step Five: Get Started

Sample Code (Node)

 1// This example uses Express to receive webhooks
 2const express = require('express');
 3const app = express();
 4'/webhook', express.json({type: 'application/x-www-form-urlencoded'}), (request, response) => {
 6  const event = request.body;
 7  // Handle the event
 8  switch (event.type) {
 9    case 'payment_intent.succeeded':
10      const paymentIntent =;
11      // Then define and call a method to handle the successful payment intent.
12      // handlePaymentIntentSucceeded(paymentIntent);
13      break;
14    case 'payment_method.attached':
15      const paymentMethod =;
16      // Then define and call a method to handle the successful attachment of a PaymentMethod.
17      // handlePaymentMethodAttached(paymentMethod);
18      break;
19    // ... handle other event types
20    default:
21      console.log(`Unhandled event type ${event.type}`);
22  }
24  // Return a response to acknowledge receipt of the event
25  response.json({received: true});
28app.listen(8000, () => console.log('Running on port 8000'));