Webhooks
In this guide, we will look at how to register and consume webhooks to integrate your app with Lightfunnels. With webhooks, your app can know when something happens in Lightfunnels, such as when a new order is created.
Registering webhooks
To register a new webhook, you need to have a URL in your app that Lightfunnels can call. You can configure a new webhook using the following GraphQL mutation:
GraphQL Query
# Query
mutation CreateWebhookMutation($node: WebhookInput!) {
createWebhook(node: $node) {
type
url
}
}
GraphQL Variables
{
"node": {
"type": "order/created",
"url": "https://yourapp.com/webhooks/order-created/{{account-id}}",
"settings": {}
}
}
The type
property refers to the event that you would like to listen to. Refer to event types for a list of available events.
Note that in the above, we pass the account ID
to the URL so your app knows to which account the webhook call corresponds to. This refers to the ID of the account in your own database.
In this example, we used the order/created
event. Now, whenever a new order is created, a webhook is fired off and your app receives all the information related to the new order. In the next section, we'll look at how to consume webhooks.
Consuming webhooks
When your app receives a webhook request from Lightfunnels, you should verify the authenticity of the request by validating the lightfunnels-hmac
from the header using your app secret
.
Here is an exampe code on how to authenticate the request using Note.js.
import crypto from "crypto";
// calculate the hmac
const localyCalculatedHmac = crypto
.createHmac("sha256", CLIENT_SECRET)
.update(event.body!, "utf8")
.digest("base64");
// check if the hmac is the same as the one in the lightfunnels-hmac header
const hmac = event.headers["lightfunnels-hmac"];
if(localyCalculatedHmac != hmac){
// this webhook is fishy, abort!
}
Event types
- Name
order/created
- Description
A new order was created.
- Name
order/confirmed
- Description
Order confirmation was sent.
Order payload
{
"id": 0,
"phone": "",
"name": "210",
"email": "no-reply@lightfunnels.com",
"sub_total": 33.39,
"total": 29.99,
"fulfillment_status": "fulfilled",
"financial_status": "paid",
"billing_address_country": "GB",
"billing_address_name": "Angeline Stathopoulos",
"billing_address_line2": "",
"billing_address_city": "London",
"billing_address_area": "Abbey Wood",
"billing_address_line1": "1-3 BRITANNIA WAY Reception",
"billing_address_zip": "NW10 7PR",
"billing_address_state": "London",
"shipping_address_city": "London",
"shipping_address_area": "Abbey Wood",
"shipping_address_line1": "1-3 BRITANNIA WAY Reception",
"shipping_address_zip": "NW10 7PR",
"shipping_address_name": "Angeline Stathopoulos",
"shipping_address_country": "GB",
"shipping_address_line2": "",
"shipping_address_state": "London",
"created_at": "2012-2012-12 12:12:12",
"customer": {
"id": 0,
"first_name": "Elhanan",
"last_name": "Gropper",
"custom": {}
},
"custom": {},
"funnel_id": 0,
"checkout_id": 0,
"items": [
{
"product_id": 100,
"price": 33.39,
"id": 0,
"title": "New T-shirt",
"sku": "nts",
"financial_status": "paid",
"type": "VariantSnapshot"
}
]
}
- Name
payment/created
- Description
A new payment was created.
- Name
payment/paid
- Description
Paid payment.
Payment payload
{
"id": 0,
"order_id": 0,
"paid": 20,
"refunded": 0,
"net_payment": 20,
"discount_value": 0,
"total": 20,
"customer": {
"id": 0,
"first_name": "Elhanan",
"last_name": "Aljoša",
"custom": {}
},
"sub_total": 20,
"items": [
{
"sku": "nts",
"id": 0,
"parent_id": 0,
"type": "VariantSnapshot",
"price": 10,
"title": "Order Item 1",
"tracking_number": "",
"tracking_link": "",
"fulfillment_status": "fulfilled",
"financial_status": "paid",
"file_id": 0,
"image": null
},
{
"sku": "nts",
"id": 0,
"parent_id": 0,
"type": "OrderBumpSnapshot",
"price": 10,
"title": "Order Item 2",
"tracking_number": "",
"tracking_link": "",
"fulfillment_status": "fulfilled",
"financial_status": "paid",
"file_id": 0,
"image": null
}
]
}
- Name
order-item/created
- Description
A new order item was created.
Order item payload
{
"price": 33.39,
"id": 0,
"title": "New T-shirt",
"sku": "nts",
"financial_status": "paid",
"type": "VariantSnapshot",
"order": {
"id": 0,
"phone": "",
"name": "210",
"email": "no-reply@lightfunnels.com",
"sub_total": 33.39,
"total": 29.99,
"fulfillment_status": "fulfilled",
"financial_status": "paid",
"billing_address_country": "GB",
"billing_address_name": "Angeline Stathopoulos",
"billing_address_line2": "",
"billing_address_city": "London",
"billing_address_area": "Abbey Wood",
"billing_address_line1": "1-3 BRITANNIA WAY Reception",
"billing_address_zip": "NW10 7PR",
"billing_address_state": "London",
"shipping_address_city": "London",
"shipping_address_area": "Abbey Wood",
"shipping_address_line1": "1-3 BRITANNIA WAY Reception",
"shipping_address_zip": "NW10 7PR",
"shipping_address_name": "Angeline Stathopoulos",
"shipping_address_country": "GB",
"shipping_address_line2": "",
"shipping_address_state": "London",
"created_at": "2012-2012-12 12:12:12",
"customer": {
"id": 0,
"first_name": "Elhanan",
"last_name": "Gropper",
"custom": {}
},
"custom": {},
"funnel_id": 0,
"checkout_id": 0
}
}
- Name
contact-form/created
- Description
A new contact form was created.
Contact form payload
{
"custom": {},
"message": "Message goes here",
"subject": "Subject goes here",
"email": "no-reply@lightfunnels.com",
"first_name": "Elhanan",
"last_name": "Aljoša"
}
- Name
contact/signup
- Description
A new sign up was made.
- Name
contact/updated
- Description
An existing customer was updated.
Customer payload
{
"id": 0,
"email": "no-reply@lightfunnels.com",
"phone": "",
"first_name": "Estrella",
"last_name": "Noland",
"account_id": 0,
"custom": {},
"tags": [
"tag1",
"tag2"
],
"accepts_marketing": true,
"created_at": "2022-05-30 20:15:08",
"address": {
"country": "GB",
"line1": "1-3 BRITANNIA WAY Reception",
"line2": "",
"city": "LONDON",
"zip": "NW10 7PR",
"state": "LONDON",
"email": "no-reply@lightfunnels.com",
"phone": "",
"first_name": "Elhanan",
"last_name": "Aljoša"
},
"billing_address": {
"country": "GB",
"line1": "1-3 BRITANNIA WAY Reception",
"line2": "",
"city": "LONDON",
"zip": "NW10 7PR",
"state": "LONDON",
"email": "no-reply@lightfunnels.com",
"phone": "",
"first_name": "Elhanan",
"last_name": "Aljoša"
}
}
- Name
checkout/created
- Description
A new checkout was created.
- Name
checkout/updated
- Description
An existing checkout was updated.
Checkout payload
{
"id": 0,
"phone": "+212000000",
"custom": {
"custom_field": "Hello world"
},
"first_name": "Elhanan",
"last_name": "Aljoša",
"email": "no-reply@lightfunnels.com",
"funnel_id": 0,
"step_id": 0,
"billing_address": {
"country": "GB",
"name": "Elhanan Aljoša",
"line2": "",
"city": "LONDON",
"line1": "1-3 BRITANNIA WAY Reception",
"zip": "NW10 7PR",
"state": "LONDON"
},
"shipping_address": {
"country": "GB",
"name": "Elhanan Aljoša",
"line2": "",
"city": "LONDON",
"line1": "1-3 BRITANNIA WAY Reception",
"zip": "NW10 7PR",
"state": "LONDON"
},
"items": [
{
"price": 33.39,
"id": 0,
"title": "New T-shirt Color:red",
"sku": "nts",
"options": [
{
"id": 0,
"value": "red"
}
]
}
]
}
- Name
product/updated
- Description
An existing product was updated.
- Name
product/created
- Description
A new product form was created.
- Name
product/deleted
- Description
A product was successfully deleted.
Product payload
{
"id": 0,
"account_id": 0
}
- Name
funnel/updated
- Description
An existing funnel was updated.
- Name
funnel/created
- Description
A new funnel was created.
- Name
funnel/deleted
- Description
A funnel was successfully deleted.
Funnel payload
{
"id": 0,
"account_id": 0
}
Security
To know for sure that a webhook was, in fact, sent by Lightfunnels instead of a malicious actor, you can verify the request signature. Each webhook request contains a header named x-Lightfunnels-signature
, and you can verify this signature by using your secret webhook key. The signature is an HMAC hash of the request payload hashed using your secret key. Here is an example of how to verify the signature in your app:
Verifying a request
const signature = req.headers['x-Lightfunnels-signature']
const hash = crypto.createHmac('sha256', secret).update(payload).digest('hex')
if (hash === signature) {
// Request is verified
} else {
// Request could not be verified
}
If your generated signature matches the x-Lightfunnels-signature
header, you can be sure that the request was truly coming from Lightfunnels. It's essential to keep your secret webhook key safe — otherwise, you can no longer be sure that a given webhook was sent by Lightfunnels. Don't commit your secret webhook key to GitHub!