Loop webhooks explained: A guide for developers
Webhooks are an essential part of modern API-driven applications, allowing systems to send real-time notifications when specific events occur. A webhook payload is the structured data sent from one application to another whenever an event is triggered.
This article provides an overview of webhooks, explores various webhook events triggered by Loop, and includes example payloads.
What is a webhook payload?
Common data formats
How webhook payloads are delivered?
When are webhooks triggered?
Subscription topic with example payload
Order topic with example payload
Payment method topic with example payload
Flows topic with example payload
Subscription checkout topic with example payload
Frequently asked questions (FAQs)
Need help?
A webhook payload is the data sent in the body of an HTTP request when a webhook is triggered. It contains relevant details about the event, such as customer information, order status, or payment details. This payload is usually in JSON format, but it can also be XML or another structured data format.
Basic Structure of a Webhook Payload
A typical webhook payload includes the following components:
- Event Type: A unique identifier indicating the type of event (e.g., order.created, subscription.updated).
- Payload Data: The main data related to the event, such as user details, transaction amounts, or product information.
- Metadata: Additional contextual information, such as timestamps, request IDs, or authentication signatures.
Webhook payloads are primarily sent in JSON (JavaScript Object Notation) due to its lightweight and widely supported nature. However, some systems may use:
- XML (Extensible Markup Language)
- Form-encoded data (application/x-www-form-urlencoded)
- Plain text or custom formats
Webhook payloads are delivered via HTTP POST requests to a pre-configured URL. The receiving application must parse the payload and take appropriate action based on the event type.
Webhooks are triggered by specific events occurring in a system. These events vary depending on the use case, such as orders being placed, subscriptions being updated, or payments failing. Each webhook event carries a payload—a structured data object that contains relevant information about the event. The payload structure is similar for each entity ( subscription, order, paymentMethod, flows, subscriptionCheckout)
Below, we categorize common webhook event types and provide example payloads for each.
Following events are triggered for the topic subscription :
Example payload:
Following events are triggered for the order topic:
Example payload:
Following events are triggered for the topic paymentMethod:
Example payload:
Following events are triggered for the topic flow:
Example payload:
Following events are triggered for the topic subscriptionCheckout :
Example payload:
Ques. How to subscribe to a webhook?
Ans. You can subscribe to a webhook using the endpoint from admin api - subscribe webhook.
There is no need to worry. We are here to assist you. Please contact us at support@loopwork.co or feel free to reach out to us through the chat by clicking on the support beacon located at the bottom right corner.
Regards,
Loop Subscription Team 🙂
This article provides an overview of webhooks, explores various webhook events triggered by Loop, and includes example payloads.
Contents of the article
What is a webhook payload?
Common data formats
How webhook payloads are delivered?
When are webhooks triggered?
Subscription topic with example payload
Order topic with example payload
Payment method topic with example payload
Flows topic with example payload
Subscription checkout topic with example payload
Frequently asked questions (FAQs)
Need help?
What is a webhook payload?
A webhook payload is the data sent in the body of an HTTP request when a webhook is triggered. It contains relevant details about the event, such as customer information, order status, or payment details. This payload is usually in JSON format, but it can also be XML or another structured data format.
Basic Structure of a Webhook Payload
A typical webhook payload includes the following components:
- Event Type: A unique identifier indicating the type of event (e.g., order.created, subscription.updated).
- Payload Data: The main data related to the event, such as user details, transaction amounts, or product information.
- Metadata: Additional contextual information, such as timestamps, request IDs, or authentication signatures.
Common data formats
Webhook payloads are primarily sent in JSON (JavaScript Object Notation) due to its lightweight and widely supported nature. However, some systems may use:
- XML (Extensible Markup Language)
- Form-encoded data (application/x-www-form-urlencoded)
- Plain text or custom formats
How Webhook Payloads are Delivered?
Webhook payloads are delivered via HTTP POST requests to a pre-configured URL. The receiving application must parse the payload and take appropriate action based on the event type.
When are webhooks triggered?
Webhooks are triggered by specific events occurring in a system. These events vary depending on the use case, such as orders being placed, subscriptions being updated, or payments failing. Each webhook event carries a payload—a structured data object that contains relevant information about the event. The payload structure is similar for each entity ( subscription, order, paymentMethod, flows, subscriptionCheckout)
Below, we categorize common webhook event types and provide example payloads for each.
Subscription topic
Following events are triggered for the topic subscription :
Topic | Trigger explanation |
---|---|
subscription/created | This event will be triggered when a subscription is created. |
subscription/paused | This event will be triggered when a subscription is paused. |
subscription/updated | When a subscription is updated, this trigger covers everything that isn't specifically mentioned under a topic. For instance, it includes updates to contract notes, modifications to custom attributes, applied discounts on subscription, removed discount on subscription, shipping address updates etc. |
subscription/cancelled | This event will be triggered when a subscription is cancelled. |
subscription/resumed | This event will be triggered when a subscription is resumed. |
subscription/reactivated | This event will be triggered when a subscription is reactivated. |
subscription/delayed | This event will be triggered when a subscription is delayed. |
subscription/rescheduled | This event will be triggered when a subscription is rescheduled. |
subscription/expired | This event will be triggered when a subscription is expired. |
subscription/inventoryAction | This event will be triggered when an inventory action has occurred on a subscription contract. For instance, When an inventory action such as partially billed, delayed or skipped has occurred on a subscription contract due to low inventory. |
Example payload:
{
"payload": {
"id": 8888999,
"note": null,
"status": "ACTIVE",
"customer": {
"email": "customer@example.com",
"phone": "+44 7911 123456",
"lastName": "Smith",
"firstName": "John",
"shopifyId": 9876543210123
},
"pausedAt": null,
"createdAt": "2025-02-18T12:00:00.000Z",
"discounts": [],
"hasBundle": false,
"isPrepaid": false,
"lineItems": [
{
"id": 29876543,
"sku": "SHO12345",
"name": "Shoe Cleaner - White / New",
"price": "5.39",
"taxable": true,
"quantity": 1,
"basePrice": "5.99",
"shopifyId": "abc12345-6789-48d5-8e7a-af57a4f46e99",
"attributes": [],
"bundleName": null,
"productTitle": "Shoe Cleaner",
"variantImage": "https://cdn.shopify.com/s/files/example-image-shoe-cleaner.jpg",
"variantTitle": "White / New",
"pricingPolicy": {
"basePrice": {
"amount": "5.99",
"currencyCode": "GBP"
},
"cycleDiscounts": [
{
"afterCycle": 0,
"computedPrice": {
"amount": "5.39",
"currencyCode": "GBP"
},
"adjustmentType": "PERCENTAGE",
"adjustmentValue": {
"percentage": 10
}
}
]
},
"isOneTimeAdded": false,
"discountedPrice": "5.39",
"sellingPlanName": "6 Months",
"isOneTimeRemoved": false,
"productShopifyId": 7654321098765,
"requiresShipping": true,
"variantShopifyId": 9876543211234,
"bundleTransactionId": null,
"discountAllocations": [],
"sellingPlanShopifyId": 123456789
}
],
"shopifyId": 2233445566778,
"cancelledAt": null,
"currencyCode": "GBP",
"billingPolicy": {
"anchors": null,
"interval": "MONTH",
"maxCycles": null,
"minCycles": 6,
"intervalCount": 1
},
"deliveryPrice": 0,
"hasCustomPlan": false,
"nextOrderDate": "2025-04-18T12:00:00.000Z",
"shippingLines": {
"code": "Standard Shipping",
"title": "Standard Shipping (3-5 Business Days)"
},
"deliveryPolicy": {
"interval": "MONTH",
"intervalCount": 1
},
"willAutoResume": false,
"shippingAddress": {
"zip": "EC1A 1BB",
"city": "London",
"company": "John's Supplies",
"address1": "10 Baker Street",
"address2": "Suite 5B",
"lastName": "Smith",
"firstName": "John",
"countryCode": "GB",
"provinceCode": "ENG"
},
"customAttributes": [],
"cancellationReason": null,
"nextOrderDateEpoch": 1745000000,
"totalLineItemPrice": 5.39,
"cancellationComment": null,
"completedOrdersCount": 2,
"originOrderShopifyId": 33445566778899,
"totalLineItemDiscountedPrice": 5.39
},
"metaData": {
"myshopifyDomain": "customshop.myshopify.com"
}
}
Order topic
Following events are triggered for the order topic:
Trigger | Trigger explanation |
---|---|
order/upcoming | Triggered when an order is upcoming. |
order/processed | Triggered when an order is processed. |
order/partiallyProcessed | Triggered when an order is partially processed due to low inventory levels. |
order/outOfStock | Triggered when an order is out of stock. |
order/skipped | Triggered when an order is skipped. |
order/unskipped | Triggered when an order is un-skipped. |
order/paymentFailed | Triggered when an payment is failed for an order. |
Example payload:
{
"payload": {
"id": 9876543,
"note": null,
"status": "FAILED",
"customer": {
"email": "customer@example.com",
"phone": "+44 7890 123456",
"lastName": "Johnson",
"firstName": "Emma",
"shopifyId": 9876543210987
},
"lineItems": [
{
"sku": "MEMB001",
"name": "Exclusive Club Membership",
"price": 15,
"taxable": false,
"quantity": 1,
"shopifyId": null,
"properties": null,
"productTitle": "Exclusive Club Membership",
"variantImage": "https://cdn.shopify.com/s/files/example-membership.png",
"variantTitle": null,
"productShopifyId": 9876543212345,
"requiresShipping": false,
"variantShopifyId": 8765432123456
}
],
"shopifyId": null,
"totalPrice": "15.00",
"totalTaxes": "0.00",
"scheduledAt": "2025-01-10T10:00:00.000Z",
"currencyCode": "GBP",
"subscription": {
"id": 7654321,
"note": null,
"status": "ACTIVE",
"pausedAt": null,
"createdAt": "2024-12-10T10:00:00.000Z",
"discounts": [],
"hasBundle": false,
"isPrepaid": false,
"lineItems": [
{
"id": 54321678,
"sku": "MEMB001",
"name": "Exclusive Club Membership",
"price": "15.00",
"taxable": false,
"quantity": 1,
"basePrice": "15.00",
"shopifyId": "xyz12345-6789-4321-bcde-abcdef123456",
"attributes": [],
"bundleName": null,
"productTitle": "Exclusive Club Membership",
"variantImage": "https://cdn.shopify.com/s/files/example-membership.png",
"variantTitle": null,
"pricingPolicy": {
"basePrice": {
"amount": "15.0",
"currencyCode": "GBP"
},
"cycleDiscounts": [
{
"afterCycle": 0,
"computedPrice": {
"amount": "0.0",
"currencyCode": "GBP"
},
"adjustmentType": "PERCENTAGE",
"adjustmentValue": {
"percentage": 100
}
},
{
"afterCycle": 1,
"computedPrice": {
"amount": "15.0",
"currencyCode": "GBP"
},
"adjustmentType": "PERCENTAGE",
"adjustmentValue": {
"percentage": 0
}
}
]
},
"isOneTimeAdded": false,
"discountedPrice": "15.00",
"sellingPlanName": "£15/Month membership access to exclusive content and discounts.",
"isOneTimeRemoved": false,
"productShopifyId": 9876543211234,
"requiresShipping": false,
"variantShopifyId": 8765432123412,
"bundleTransactionId": null,
"discountAllocations": [],
"sellingPlanShopifyId": 5678901234
}
],
"shopifyId": 5678901234,
"cancelledAt": null,
"currencyCode": "GBP",
"billingPolicy": {
"anchors": null,
"interval": "MONTH",
"maxCycles": null,
"minCycles": 3,
"intervalCount": 1
},
"deliveryPrice": 0,
"hasCustomPlan": false,
"nextOrderDate": "2025-02-10T10:00:00.000Z",
"shippingLines": {
"code": null,
"title": null
},
"deliveryPolicy": {
"interval": "MONTH",
"intervalCount": 1
},
"willAutoResume": false,
"shippingAddress": null,
"customAttributes": [],
"cancellationReason": null,
"nextOrderDateEpoch": 1744500000,
"totalLineItemPrice": 15,
"cancellationComment": null,
"completedOrdersCount": 2,
"originOrderShopifyId": 2345678901234,
"totalLineItemDiscountedPrice": 15
},
"discountCodes": null,
"shippingLines": null,
"subtotalPrice": "15.00",
"paymentAttempt": {
"createdAt": "2025-01-09T09:30:00.000Z",
"errorCode": "insufficient_funds",
"shopifyId": 765432109876,
"updatedAt": "2025-01-09T09:30:00.000Z",
"retryDelay": "2",
"errorMessage": "Insufficient funds in your account.",
"idempotencyKey": "7654321-abc123",
"retryLeftCount": 2,
"retryAttemptCount": 1
},
"shippingAddress": null,
"chargeOffsetDays": null,
"customAttributes": null,
"skippedLineItems": [],
"totalShippingPrice": "0.00",
"totalDiscountAmount": "0.00",
"totalLineItemsPrice": "15.00",
"shippingPriceCurrencyCode": "GBP"
},
"metaData": {
"myshopifyDomain": "membershipstore.myshopify.com"
}
}
Payment method entity
Following events are triggered for the topic paymentMethod:
Trigger | Trigger explanantion |
---|---|
paymentMethod/updateRequested | Triggered when a customer request's payment method update request from loop. |
paymentMethod/updated | Triggered when customer's payment method is updated. |
paymentMethod/expiringSoon | Triggered when customer payment method is about to expire (3 days, 15 days, 30 days before payment method expiring) |
Example payload:
{
"payload": {
"id": 4456789,
"name": "John Doe",
"type": "CustomerCreditCard",
"brand": "mastercard",
"customer": {
"email": "customer@example.com",
"phone": "+44 7890 123456",
"lastName": "Doe",
"firstName": "John",
"shopifyId": 1234567890123
},
"riskLevel": "low",
"shopifyId": "a1b2c3d4e5f67890g123h456i789j0kl",
"customerId": 98765432,
"expiryYear": "27",
"lastDigits": "6789",
"expiryMonth": "09",
"customerShopifyId": 987654321098765,
"paypalAccountEmail": null
},
"metaData": {
"myshopifyDomain": "customerstore.myshopify.com"
}
}
Flow entity
Following events are triggered for the topic flow:
Trigger | Trigger explanantion |
---|---|
flow/completed | Triggered when a flow is successfully completed |
Example payload:
{
"payload": {
"id": 9876543,
"name": "Loyalty Program Order - Free Hydrating Face Moisturizer",
"subscription": {
"id": 8765432,
"note": null,
"status": "ACTIVE",
"pausedAt": null,
"createdAt": "2024-12-01T12:00:00.000Z",
"discounts": [],
"hasBundle": false,
"isPrepaid": false,
"lineItems": [
{
"id": 56789012,
"sku": "HFM12345",
"name": "Hydrating Face Moisturizer - Trial Size",
"price": "15.20",
"taxable": true,
"quantity": 1,
"basePrice": "16.00",
"shopifyId": "12345678-abcd-4d51-bc38-4940fa44abcd",
"attributes": [
{
"key": "_is_hidden",
"value": "true"
},
{
"key": "_type",
"value": "subscription-program"
}
],
"bundleName": null,
"productTitle": "Hydrating Face Moisturizer",
"variantImage": "https://cdn.shopify.com/s/files/example-image-moisturizer.png",
"variantTitle": "Trial Size",
"pricingPolicy": {
"basePrice": {
"amount": "16.0",
"currencyCode": "USD"
},
"cycleDiscounts": [
{
"afterCycle": 0,
"computedPrice": {
"amount": "0.0",
"currencyCode": "USD"
},
"adjustmentType": "PRICE",
"adjustmentValue": {
"amount": "0.0",
"currencyCode": "USD"
}
},
{
"afterCycle": 1,
"computedPrice": {
"amount": "15.20",
"currencyCode": "USD"
},
"adjustmentType": "PERCENTAGE",
"adjustmentValue": {
"percentage": 5
}
}
]
},
"isOneTimeAdded": false,
"discountedPrice": "15.20",
"sellingPlanName": "Full-size refill ships every 2 months.",
"isOneTimeRemoved": false,
"productShopifyId": 8765432109876,
"requiresShipping": true,
"variantShopifyId": 7654321098765,
"bundleTransactionId": null,
"discountAllocations": [],
"sellingPlanShopifyId": 234567890
},
{
"id": 12345678,
"sku": "FWB98765",
"name": "Face Wash Bar - Travel Size",
"price": "0.00",
"taxable": true,
"quantity": 1,
"basePrice": "12.00",
"shopifyId": "abcd1234-efgh-5678-ijkl-9876543210mn",
"attributes": [],
"bundleName": null,
"productTitle": "Face Wash Bar",
"variantImage": "https://cdn.shopify.com/s/files/example-image-facewash.png",
"variantTitle": "Travel Size",
"pricingPolicy": {
"basePrice": {
"amount": "12.0",
"currencyCode": "USD"
},
"cycleDiscounts": [
{
"afterCycle": 0,
"computedPrice": {
"amount": "0.0",
"currencyCode": "USD"
},
"adjustmentType": "PERCENTAGE",
"adjustmentValue": {
"percentage": 100
}
}
]
},
"isOneTimeAdded": true,
"discountedPrice": "0.00",
"sellingPlanName": "One-time purchase",
"isOneTimeRemoved": false,
"productShopifyId": 6543210987654,
"requiresShipping": true,
"variantShopifyId": 5432109876543,
"bundleTransactionId": null,
"discountAllocations": [],
"sellingPlanShopifyId": null
}
],
"shopifyId": 3456789012345,
"cancelledAt": null,
"currencyCode": "USD",
"billingPolicy": {
"anchors": null,
"interval": "MONTH",
"maxCycles": null,
"minCycles": 2,
"intervalCount": 1
},
"deliveryPrice": 5,
"hasCustomPlan": false,
"nextOrderDate": "2025-03-10T12:00:00.000Z",
"shippingLines": {
"code": "Standard Shipping (3 - 5 Business Days)",
"title": "Standard Shipping (3 - 5 Business Days)"
},
"deliveryPolicy": {
"interval": "MONTH",
"intervalCount": 1
},
"willAutoResume": false,
"shippingAddress": {
"zip": "10001",
"city": "New York",
"company": null,
"address1": "123 Wellness Street",
"address2": null,
"lastName": "Doe",
"firstName": "Emma",
"countryCode": "US",
"provinceCode": "NY"
},
"customAttributes": [
{
"key": "loyaltyProgramId",
"value": "lp-987654321"
},
{
"key": "deviceId",
"value": "abcd-1234-efgh-5678-ijkl-9876"
}
],
"cancellationReason": null,
"nextOrderDateEpoch": 1742000000,
"totalLineItemPrice": 15.20,
"cancellationComment": null,
"completedOrdersCount": 2,
"originOrderShopifyId": 5678901234567,
"totalLineItemDiscountedPrice": 15.20
}
},
"metaData": {
"myshopifyDomain": "premiumcare.myshopify.com"
}
}
Subscription checkout entity
Following events are triggered for the topic subscriptionCheckout :
Trigger | Trigger explanation |
---|---|
subscriptionCheckout/success | Triggered when a checkout order is placed successfully. |
subscriptionCheckout/failed | Triggered when a checkout order is failed. |
Example payload:
{
"payload": {
"lines": [
{
"type": "SUBSCRIPTION",
"price": 19.99,
"quantity": 2,
"productTitle": "Third Grade Curriculum",
"variantTitle": "Standard Edition",
"variantShopifyId": 123456789012345
}
],
"order": {
"id": 987654,
"note": "Mailing Address:\n First Name: John\n Last Name: Doe\n Address 1: 123 Main Street\n Address 2: Apt 4B\n City: New York\n State/Province: NY\n Country: US\n ZIP Code: 10001",
"status": "SUCCESS",
"lineItems": [
{
"sku": "TG-CUR-001",
"name": "Third Grade Curriculum",
"price": 19.99,
"taxable": true,
"quantity": 2,
"shopifyId": 112233445566,
"properties": [],
"productTitle": "Third Grade Curriculum",
"variantImage": "https://cdn.shopify.com/s/files/example-image.png",
"variantTitle": "Standard Edition",
"productShopifyId": 998877665544,
"requiresShipping": true,
"variantShopifyId": 123456789012345
}
],
"shopifyId": 556677889900,
"totalPrice": "43.98",
"totalTaxes": "3.99",
"scheduledAt": "2025-03-01T15:30:00.000Z",
"currencyCode": "USD",
"discountCodes": [
{
"code": "SPRING10",
"amount": "2.00"
}
],
"shippingLines": [
{
"price": "5.00",
"title": "Standard Shipping"
}
],
"subtotalPrice": "39.98",
"shippingAddress": {
"firstName": "John",
"lastName": "Doe",
"address1": "123 Main Street",
"address2": "Apt 4B",
"city": "New York",
"state": "NY",
"country": "US",
"zipCode": "10001"
},
"chargeOffsetDays": null,
"customAttributes": [],
"skippedLineItems": [],
"totalShippingPrice": "5.00",
"totalDiscountAmount": "2.00",
"totalLineItemsPrice": "39.98",
"shippingPriceCurrencyCode": "USD"
},
"discounts": [
{
"code": "SPRING10",
"amount": "2.00"
}
],
"subscription": {
"id": 7890123,
"note": "Mailing Address:\n First Name: John\n Last Name: Doe\n Address 1: 123 Main Street\n Address 2: Apt 4B\n City: New York\n State/Province: NY\n Country: US\n ZIP Code: 10001",
"status": "ACTIVE",
"pausedAt": null,
"createdAt": "2025-02-15T12:00:00.000Z",
"discounts": [],
"hasBundle": false,
"isPrepaid": false,
"lineItems": [
{
"id": 5678910,
"sku": "TG-CUR-001",
"name": "Third Grade Curriculum",
"price": "19.99",
"taxable": true,
"quantity": 2,
"basePrice": "19.99",
"shopifyId": "a1b2c3d4-e5f6-7890-1122-334455667788",
"attributes": [],
"bundleName": null,
"productTitle": "Third Grade Curriculum",
"variantImage": "https://cdn.shopify.com/s/files/example-image.png",
"variantTitle": "Standard Edition",
"pricingPolicy": {
"basePrice": {
"amount": "19.99",
"currencyCode": "USD"
},
"cycleDiscounts": [
{
"afterCycle": 0,
"computedPrice": {
"amount": "19.99",
"currencyCode": "USD"
},
"adjustmentType": "FIXED_AMOUNT",
"adjustmentValue": {
"amount": "0.00",
"currencyCode": "USD"
}
}
]
},
"isOneTimeAdded": false,
"discountedPrice": "19.99",
"sellingPlanName": "Quarterly Plan",
"isOneTimeRemoved": false,
"productShopifyId": 998877665544,
"requiresShipping": true,
"variantShopifyId": 123456789012345,
"bundleTransactionId": null,
"discountAllocations": [],
"sellingPlanShopifyId": 987654321
}
],
"shopifyId": 6677889900,
"cancelledAt": null,
"currencyCode": "USD",
"billingPolicy": {
"anchors": null,
"interval": "MONTH",
"maxCycles": null,
"minCycles": null,
"intervalCount": 1
},
"deliveryPrice": 5.00,
"hasCustomPlan": false,
"nextOrderDate": "2025-03-15T12:00:00.000Z",
"shippingLines": {
"code": "STANDARD",
"title": "Standard Shipping"
},
"deliveryPolicy": {
"interval": "MONTH",
"intervalCount": 1
},
"willAutoResume": true,
"shippingAddress": {
"firstName": "John",
"lastName": "Doe",
"address1": "123 Main Street",
"address2": "Apt 4B",
"city": "New York",
"state": "NY",
"country": "US",
"zipCode": "10001"
},
"customAttributes": [],
"cancellationReason": null,
"nextOrderDateEpoch": 1741000000,
"totalLineItemPrice": 39.98,
"cancellationComment": null,
"completedOrdersCount": 2,
"originOrderShopifyId": 556677889900,
"totalLineItemDiscountedPrice": 39.98
},
"idempotencyKey": "6677889900-XyZ12"
},
"metaData": {
"myshopifyDomain": "example-shop.myshopify.com"
}
}
Frequently asked questions (FAQs)
Ques. How to subscribe to a webhook?
Ans. You can subscribe to a webhook using the endpoint from admin api - subscribe webhook.
Need help?
There is no need to worry. We are here to assist you. Please contact us at support@loopwork.co or feel free to reach out to us through the chat by clicking on the support beacon located at the bottom right corner.
Regards,
Loop Subscription Team 🙂
Updated on: 18/02/2025
Thank you!