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.
Name | Type | Description |
---|---|---|
eventId | number | Unique webhook ID |
eventType | string | A description of an event that occured. |
eventCreated | timestamp | Unix timestamp of the occurred event. |
storeId | number | Store ID of the store where the event occured. |
entityId | number | Id 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
Name | Type | Description |
---|---|---|
orderId | string | The identifier of a created/updated/deleted order |
oldPaymentStatus | string | Payment status of order before changes occurred |
newPaymentStatus | string | Payment status of order after changes occurred |
oldFulfillmentStatus | string | Fulfillment status of order before changes occurred |
newFulfillmentStatus | string | Fulfillment status of an order after changes occurred |
oldSubscriptionName | string | Previous Ecwid store premium plan name |
newSubscriptionName | string | New Ecwid store premium plan name |
oldSubscriptionStatus | string | Previous application subscription status before changes occurred |
newSubscriptionStatus | string | New application subscription status after changes occurred |
customerEmail | string | Email of a customer |
Event types
unfinished_order.created
Unfinished order is createdunfinished_order.updated
Unfinished order is updatedunfinished_order.deleted
Unfinished order is deletedorder.created
New order is placedorder.updated
Order is changedorder.deleted
Order is deletedproduct.created
New product is createdproduct.updated
Product is updatedproduct.deleted
Product is deletedcategory.created
New category is createdcategory.updated
Category is updatedcategory.deleted
Category is deletedapplication.installed
Application is installedapplication.uninstalled
Application is deletedapplication.subscriptionStatusChanged
Application status changedprofile.updated
Store information updatedprofile.subscriptionStatusChanged
Store premium subscription status changedcustomer.created
Customer is createdcustomer.updated
Customer is updatedcustomer.deleted
Customer is deletedcustomer.personalDataRemovalRequest
Customer personal data removal request is madecustomer.personalDataExportRequest
Customer personal data export request is madeprofile.personalDataRemovalRequest
Store owner personal data removal request is madeprofile.personalDataExportRequest
Store owner personal data export request is madeinvoice.created
Invoice is createdinvoice.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.