Webhooks structure

Webhook is a POST request sent to your app URL. Its body contains several fields, like: store ID, entity ID (product ID, order number, etc.), event type and more.

Learn about getting webhook fields in Best practices

Request headers

POST https://www.myapp.com/callback?eventtype=order.updated HTTP/1.1
Host: www.myapp.com
Content-Type: application/json; charset=UTF-8
Content-Length: 243
Cache-Control: no-cache
X-Ecwid-Webhook-Signature: MeV28XtFal4HCkYFvdilwckJinc6Dtp4ZWpPhm/pzd4=

Among the other headers, HTTP webhook request from Ecwid includes the X-Ecwid-Webhook-Signature header that can be used to verify the webhook.

See more details in the Webhooks best practices

Custom HTTP Headers

POST https://www.myapp.com/callback?eventtype=order.updated HTTP/1.1
Host: www.myapp.com
Content-Type: application/json; charset=UTF-8
Content-Length: 243
Cache-Control: no-cache
X-Ecwid-Webhook-Signature: MeV28XtFal4HCkYFvdilwckJinc6Dtp4ZWpPhm/pzd4=
Custom-Webhook-Header-Name: custom webhook header value

Webhooks also allow you to specify custom headers that Ecwid will use when sending a webhook to your endpoint.

For example, if you have only one endpoint and several applications sending webhooks to that endpoint, you may want to specify a custom HTTP header to know the application this webhook was sent to.

The custom HTTP headers specified for webhooks will be added to the default list of headers Ecwid is sending.

In case if a custom webhook HTTP header is duplicating a default header, Ecwid will send both the default and custom header in a request.

To setup custom HTTP headers for your app webhooks, please contact us.

Webhook request body

Unfinished orders webhook examples

{
  "eventId": "95ed494f-362d-4fca-933d-f5c7064b04bb",
  "eventCreated": 1634209655,
  "storeId": 1003,
  "entityId": 293225803, //internal order number
  "eventType": "unfinished_order.created",
  "data": {
    "orderId": "RA1SD", //order ID
    "cartId": "320AB5DE-5EA6-4419-A4CF-0B04D2913190"
  }
}
{
  "eventId": "95ed494f-362d-4fca-933d-f5c7064b04bb",
  "eventCreated": 1634209655,
  "storeId": 1003,
  "entityId": 293225803, //internal order number
  "eventType": "unfinished_order.updated",
  "data": {
    "orderId": "RA1SD", //order ID
    "cartId": "320AB5DE-5EA6-4419-A4CF-0B04D2913190"
  }
}
{
  "eventId": "95ed494f-362d-4fca-933d-f5c7064b04bb",
  "eventCreated": 1634209655,
  "storeId": 1003,
  "entityId": 293225803, //internal order number
  "eventType": "unfinished_order.deleted",
  "data": {
    "orderId": "RA1SD", //order ID
    "cartId": "320AB5DE-5EA6-4419-A4CF-0B04D2913190"
  }
}

Order webhook examples

{
  "eventId":"80aece08-40e8-4145-8764-6c2f0d38678",
  "eventCreated":1234567,
  "storeId":1003,
  "entityId":103878161, // deprecated field (internal number of the placed order)
  "eventType":"order.created",
  "data":{
    "orderId":"XJ12H", // this is the identifier of the placed order
    "newPaymentStatus":"PAID",
    "newFulfillmentStatus":"SHIPPED"
  }
}
{
  "eventId":"80aece08-40e8-4145-8764-6c2f0d38678",
  "eventCreated":1234567,
  "storeId":1003,
  "entityId":450012387, // deprecated field (internal Ecwid number of the updated order)
  "eventType":"order.updated",
  "data":{
    "orderID":"B8HGD", // this is the ID of the updated order
    "oldPaymentStatus":"PAID",
    "newPaymentStatus":"PAID",
    "oldFulfillmentStatus":"PROCESSING",
    "newFulfillmentStatus":"SHIPPED"
  }
}
{
  "eventId":"80aece08-40e8-4145-8764-6c2f0d38678",
  "eventCreated":1234567,
  "storeId":1003,
  "entityId":103878161, // deprecated field (internal number of the deleted order)
  "eventType":"order.deleted",
  "data":{
    "orderID":"XJ12H", // this is the ID of the deleted order
  }
}

Product webhook examples

{
  "eventId":"08a78904-4c1a-0aa0-953a-2e33c56236f1",
  "eventCreated":1469429915,
  "storeId":1003, 
  "entityId":667251253, // this is the id of the created product
  "eventType":"product.created"
}
{
  "eventId":"08a78904-0aa0-4c1a-953a-2e33c56236f0",
  "eventCreated":1469429912,
  "storeId":1003, 
  "entityId":66722483, // this is the id of the updated product
  "eventType":"product.updated"
}
{
  "eventId":"80aece08-40e8-4145-8764-6c2f0d38678",
  "eventCreated":1469429915,
  "storeId":1003, 
  "entityId":667251253, // this is the id of the deleted product
  "eventType":"product.deleted"
}

Category webhook examples

{
  "eventId":"08a78904-0aa0-4c1a-953a-2e33c56236f0",
  "eventCreated":1469429912,
  "storeId":1003, 
  "entityId":66722483, 
  "eventType":"category.created"
}
{
  "eventId":"08a78904-0aa0-4c1a-953a-2e123c236f0",
  "eventCreated":1469429912,
  "storeId":1003, 
  "entityId":66722483, 
  "eventType":"category.updated"
}
{
  "eventId":"08a78904-0aa0-4c1a-953a-2e33c562336f0",
  "eventCreated":1469429912,
  "storeId":1003, 
  "entityId":66722483, 
  "eventType":"category.deleted"
}

Application webhook examples

{
  "eventId":"80aece08-40e8-4145-8764-6c2f0d38678",
  "eventCreated":1234567,
  "storeId":1003,
  "entityId":"1003", // this is the id of a store that installed the app
  "eventType":"application.installed"
}
{
  "eventId":"80aece08-40e8-4145-8764-6c2f0d38678",
  "eventCreated":1234567,
  "storeId":1003,
  "entityId":"1003", // this is the id of a store where app subscription status was changed
  "eventType":"application.subscriptionStatusChanged",
  "data":{
    "oldSubscriptionStatus":"TRIAL",
    "newSubscriptionStatus":"ACTIVE"
    }
}
{
  "eventId":"80aece08-40e8-4145-8764-6c2f0d38678",
  "eventCreated":1234567,
  "storeId":1003,
  "entityId":"1003", // this is the id of a store that deleted the app
  "eventType":"application.uninstalled"
}

Store profile webhook examples

{
  "eventId":"80aece08-40e8-4145-8764-6c2f0d38678",
  "eventCreated":1494503041,
  "storeId":1421002,
  "entityId":1421002, // this is the id of a store that switched to a different Ecwid plan
  "eventType":"profile.subscriptionStatusChanged",
  "data":{
    "oldSubscriptionName":"ECWID_BUSINESS",
    "newSubscriptionName":"ECWID_UNLIMITED"
  }
}
{
  "eventId": "80aece08-40e8-4145-8764-6c2f0d38678",
  "eventCreated": 7891234567,
  "storeId": 1003,
  "entityId": 1003
  "eventType": "profile.updated"
}

Customer webhook examples

{
  "eventId": "80aece08-40e8-4145-8764-6c2f0d38678",
  "eventCreated": 7891234567,
  "storeId": 1003,
  "entityId": 1663830, // customer ID
  "eventType": "customer.created",
  "data": {
    "customerEmail":"[email protected]" // customer email
  }
}
{
  "eventId": "80aece08-40e8-4145-8764-6c2f0d38678",
  "eventCreated": 7891234567,
  "storeId": 1003,
  "entityId": 1663830, // customer ID
  "eventType": "customer.updated",
  "data": {
    "customerEmail":"[email protected]" // customer email
  }
}
{
  "eventId": "80aece08-40e8-4145-8764-6c2f0d38678",
  "eventCreated": 7891234567,
  "storeId": 1003,
  "entityId": 1663830, // customer ID
  "eventType": "customer.deleted",
  "data": {
    "customerEmail":"[email protected]" // customer email
  }
}

Discount coupons webhook example

{
  "eventId": "80aece08-40e8-4145-8764-6c2f0d38678",
  "eventCreated": 7891234567,
  "storeId": 1003,
  "entityId": 12345678, // discount coupon ID
  "eventType": "discount_coupon.created",
}
{
  "eventId": "80aece08-40e8-4145-8764-6c2f0d38678",
  "eventCreated": 7891234567,
  "storeId": 1003,
  "entityId": 12345678, // discount coupon ID
  "eventType": "discount_coupon.updated",
}
{
  "eventId": "80aece08-40e8-4145-8764-6c2f0d38678",
  "eventCreated": 7891234567,
  "storeId": 1003,
  "entityId": 12345678, // discount coupon ID
  "eventType": "discount_coupon.deleted",
}

Invoice webhook example

{
"eventId":"08a78904-4c1a-0aa0-953a-2e33c56236f1",
"eventCreated":1469429915,
"storeId":1003, 
"entityId":667251253, // Invoice internal ID 
"eventType":"invoice.created",
"data":{
"orderId":"GH781" // order ID
}
{
"eventId":"08a78904-4c1a-0aa0-953a-2e33c56236f1",
"eventCreated":1469429915,
"storeId":1003, 
"entityId":667251253, // Invoice internal ID
"eventType":"invoice.deleted",
"data":{
"orderId":"GH781" // order ID
}

The request body is a JSON object with the following fields:

📘

Fields sent with all webhook requests are highlighted in bold.

NameTypeDescription
eventIdnumberUnique webhook ID
eventTypestringA description of an event that occured.
eventCreatedtimestampUnix timestamp of the occurred event.
storeIdnumberStore ID of the store where the event occured.
entityIdnumberId of the updated entity. Can contain productId, categoryId, storeId depending on the eventType. unfinished_order.* events contain Ecwid's internal order number.
data<WebhookData>It's an optional field that describes specific changes made to an entity. It's provided for order.* and application.subscriptionStatusChanged event types. For example, for 'order' it can be payment/fulfillment status change.

The eventType field is duplicated in GET parameters of a request. This allows you to filter our the webhooks you don't want to handle on server-side right away.

For example, if you only need to listen to order updates, you can just reply 200 OK to every request containing products updates, e.g. https://www.myapp.com/callback?eventtype=product.updated, and avoid further processing.

WebhookData

NameTypeDescription
orderIdstringThe identifier of a created/updated/deleted order
oldPaymentStatusstringPayment status of order before changes occurred
newPaymentStatusstringPayment status of order after changes occurred
oldFulfillmentStatusstringFulfillment status of order before changes occurred
newFulfillmentStatusstringFulfillment status of an order after changes occurred
oldSubscriptionNamestringPrevious Ecwid store premium plan name
newSubscriptionNamestringNew Ecwid store premium plan name
oldSubscriptionStatusstringPrevious application subscription status before changes occurred
newSubscriptionStatusstringNew application subscription status after changes occurred
customerEmailstringEmail of a customer

Event types

  • unfinished_order.created Unfinished order is created
  • unfinished_order.updated Unfinished order is updated
  • unfinished_order.deleted Unfinished order is deleted
  • order.created New order is placed
  • order.updated Order is changed
  • order.deleted Order is deleted
  • product.created New product is created
  • product.updated Product is updated
  • product.deleted Product is deleted
  • category.created New category is created
  • category.updated Category is updated
  • category.deleted Category is deleted
  • application.installed Application is installed
  • application.uninstalled Application is deleted
  • application.subscriptionStatusChanged Application status changed
  • profile.updated Store information updated
  • profile.subscriptionStatusChanged Store premium subscription status changed
  • customer.created Customer is created
  • customer.updated Customer is updated
  • customer.deleted Customer is deleted
  • customer.personalDataRemovalRequest Customer personal data removal request is made
  • customer.personalDataExportRequest Customer personal data export request is made
  • profile.personalDataRemovalRequest Store owner personal data removal request is made
  • profile.personalDataExportRequest Store owner personal data export request is made
  • invoice.created Invoice is created
  • invoice.deleted Invoice is deleted

All order-related webhooks require read_orders access scope, all product- and category-related webhooks require read_catalog access scope, all customer-related webhooks require read_customers access scope to be requested from the store.

Webhooks' structure FAQ

Q: What is an unfinished order and how it works?

The typical process of ordering in Ecwid store is:

  • customer adds products to cart
  • goes to the checkout pages
  • fills in shipping and billing details
  • goes to payment processor and pays for order
  • customer returns to store

An unfinished order (or abandoned cart) is created when a customer goes to payment processor or order confirmation page. In case if customer pays for their order, then it is placed among other successful orders in store sales history. However, if customer fails to make a payment and never completes the order, then it will stay as unfinished order.

There is a separate tab in Ecwid control panel > My Sales > Abandoned carts where merchants can see all those orders and their details. unfinished_order.* webhook event types are providing timely updates about unfinished orders in Ecwid store.

Here's how the process works in technical terms:

  • when customer goes to payment processor, unfinished_order.created webhook is sent
    (if customer was able to pay for an order within 1 second of that, order.created is sent instead)
  • if customer paid later for their order, Ecwid sends order.created webhook after it happens

Webhooks about unfinished orders can be a great help for applications, which goal is track cart abandonment and get back those lost sales.

Recommendations

We recommend this workflow:

  • app recieves unfinished_order.created webhook about order A
  • app waits for order.created webhook about order A for 5-10 minutes
  • in case if there was no order.created webhook received, consider this order unfinished

After that, application can send an email to that person, following up on that unfinished order or provide some other functionality.

Q: When 'unfinished_order.deleted' event type is sent?

When a merchant deletes an unfinished order in their Ecwid control panel, hidden field in order details becomes true. After that update unfinished_order.updated webhook is sent. So the details of this order are still available to be accessed via REST API.

To completely delete an unfinished order, make a delete order request to Ecwid API. If your app is set up to receive unfinished_order.deleted webhooks, Ecwid will send that webhook to endpoint of your application.

Q: How can I know if order status was changed?

Webhooks in Ecwid have a specific field for that: data. This field provides information about changes to both payment and fulfilment status of orders.

Contents of data field also lets you know the details about old status (before the changes) and the new one (after the changes) at all times. For example, your application can send a note to your warehouse if it received a webhook about order payment status changes from Awaiting payment to Paid.

Q: How can I know the current app subscription status of a store?

Once you received application.subscriptionStatusChanged webhook, you can make a request to Application status to get the current subscription status of your app in that store.