Order events webhooks
These events let you update systems that rely on order information. Subscribe to an order event in your dashboard webhooks settings, and Snipcart will POST the payload below to your endpoint whenever the event fires.
order.completed- a new order is completed.order.status.changed- the status of an order changes.order.paymentStatus.changed- the payment status of an order changes.order.trackingNumber.changed- the tracking number of an order changes.order.refund.created- an order is refunded.order.notification.created- a notification is added to an order.order.withdrawal.created- a withdrawal request is submitted.
Webhook envelope
Every order event shares the same top-level envelope:
| Field | Type | Notes |
|---|---|---|
eventName |
string | The event that fired, e.g. order.completed. |
mode |
string | Live or Test. |
createdOn |
datetime | When the event was raised. |
content |
object | The event payload - see each event below. |
Some events add extra top-level fields alongside content: order.status.changed and order.paymentStatus.changed add from/to, and order.trackingNumber.changed adds trackingNumber/trackingUrl. These are listed per event below.
The Order content
Four events - order.completed, order.status.changed, order.paymentStatus.changed, and order.trackingNumber.changed - deliver the full Order object as their content. Its commonly-used fields are documented below.
| Field | Type | Notes |
|---|---|---|
token |
string | Order token / unique id. |
invoiceNumber |
string | Invoice number (falls back to the token). |
parentToken |
string | For a recurring order, the original order's token. |
parentInvoiceNumber |
string | Invoice number of the parent order. |
email |
string | Customer email. |
status |
string | InProgress, Processed, Disputed, Shipped, Delivered, Pending, Cancelled, Dispatched. |
paymentStatus |
string | Paid, Deferred, PaidDeferred, ChargedBack, Refunded, Paidout, Pending, Failed, Expired, Cancelled, Open, Authorized. |
paymentMethod |
string | Display label of the payment method. |
mode |
string | Live or Test. |
currency |
string | ISO currency code (lowercase). |
lang |
string | Order language. |
creationDate |
datetime | |
modificationDate |
datetime | |
completionDate |
datetime | When the order was completed. |
billingAddress |
object | name, company, address1, address2, city, province, country, postalCode, phone. |
shippingAddress |
object | Same shape as billingAddress; null when the order isn't shipped. |
shippingAddressSameAsBilling |
boolean | |
user |
object | The customer. |
items |
object[] | Order line items. |
discounts |
object[] | Applied discounts. |
taxes |
object[] | Applied taxes. |
refunds |
object[] | Refunds issued on the order. |
withdrawals |
object[] | EU withdrawal requests on the order. |
hasPendingWithdrawal |
boolean | True when a withdrawal request is awaiting resolution. |
customFields |
object[] | Order custom fields. |
metadata |
object | Merchant metadata. |
shippingFees |
number | |
shippingMethod |
string | |
shippingLocalizedMethod |
string | Method name in the customer's language. |
shippingProvider |
string | |
trackingNumber |
string | |
trackingUrl |
string | |
cardHolderName |
string | |
creditCardLast4Digits |
string | |
cardType |
string | |
paymentDetails |
object | Gateway-specific payment details. |
paymentGatewayUsed |
string | |
subtotal |
number | Items total minus discounts. |
taxableTotal |
number | |
taxesTotal |
number | |
grandTotal |
number | |
finalGrandTotal |
number | Final total when adjusted. |
total |
number | finalGrandTotal when set, otherwise grandTotal. |
savedAmount |
number | Total discount amount. |
refundsAmount |
number | Total refunded. |
adjustedAmount |
number | Total minus refunds. |
totalWeight |
number | |
itemsCount |
number | Total item quantity. |
summary |
object | Payment summary (subtotal, taxes, total, ...). |
isRecurringOrder |
boolean | True for a recurring subscription order. |
subscriptionId |
guid | The subscription this order belongs to. |
hasSubscriptions |
boolean | |
notes |
string | |
taxProvider |
string |
Full example
The example shows the full payload; the table above documents the commonly-used fields.
{
"eventName": "order.completed",
"mode": "Test",
"createdOn": "2017-10-04T19:18:53.5703196Z",
"content": {
"discounts": [
{
"amountSaved": 10,
"discountId": "8dde2f91-4b86-4dec-b7d8-d04d26b603fb",
"name": "10$ off",
"combinable": true,
"trigger": "Code",
"code": "10_off",
"type": "FixedAmount",
"amount": 10,
"id": "18069573-f782-4201-bbd0-05fd908212db",
"creationDate": "2017-10-04T19:17:51.963Z",
"modificationDate": "2017-10-04T19:17:51.963Z"
}
],
"items": [
{
"paymentSchedule": {
"interval": "Day",
"intervalCount": 1,
"trialPeriodInDays": null,
"startsOn": "2017-10-04T00:00:00Z"
},
"token": "1912e4c1-d008-4c15-ab12-fe21a76d30d4",
"name": "Recurring plan",
"price": 20,
"quantity": 1,
"fileGuid": null,
"url": "/",
"id": "PLAN",
"initialData": "",
"description": "",
"categories": [],
"weight": null,
"image": "",
"originalPrice": null,
"uniqueId": "eb52e6e3-d8fa-4db4-b0a9-83c238ae1542",
"stackable": true,
"minQuantity": null,
"maxQuantity": null,
"addedOn": "2017-10-04T19:17:24Z",
"modificationDate": "2017-10-04T19:17:26Z",
"shippable": true,
"taxable": true,
"duplicatable": false,
"width": null,
"height": null,
"length": null,
"metadata": null,
"totalPrice": 30,
"totalWeight": 0,
"taxes": [],
"alternatePrices": {},
"customFields": [
{
"name": "Custom",
"displayValue": "Option 2",
"operation": "+10.00",
"type": "dropdown",
"options": "Option 1|Option 2[+10.00]|Option 3[+20.00]",
"required": false,
"value": "Option 2",
"optionsArray": [
"Option 1",
"Option 2",
"Option 3"
]
}
],
"unitPrice": 30,
"hasDimensions": false
},
{
"token": "1912e4c1-d008-4c15-ab12-fe21a76d30d4",
"name": "Bacon",
"price": 300,
"quantity": 1,
"fileGuid": null,
"url": "//localhost:3006",
"id": "2",
"initialData": "",
"description": "Some bacon",
"categories": [],
"weight": 20,
"image": "http://placecage.com/50/50",
"originalPrice": null,
"uniqueId": "9e0341a9-5d0f-498f-a4bd-1ae68c49b709",
"stackable": true,
"minQuantity": null,
"maxQuantity": null,
"addedOn": "2017-10-04T19:17:19Z",
"modificationDate": "2017-10-04T19:17:19Z",
"shippable": true,
"taxable": true,
"duplicatable": false,
"width": null,
"height": null,
"length": null,
"metadata": null,
"totalPrice": 300,
"totalWeight": 20,
"taxes": [],
"alternatePrices": {
"vip": 700
},
"customFields": [
{
"name": "Size",
"displayValue": "S",
"operation": null,
"type": "dropdown",
"options": "S|M|L",
"required": false,
"value": "S",
"optionsArray": [
"S",
"M",
"L"
]
},
{
"name": "Color",
"displayValue": "Red",
"operation": null,
"type": "dropdown",
"options": "Red|Blue|Green",
"required": false,
"value": "Red",
"optionsArray": [
"Red",
"Blue",
"Green"
]
},
{
"name": "Neck",
"displayValue": "V",
"operation": null,
"type": "dropdown",
"options": "V|O|Std",
"required": false,
"value": "V",
"optionsArray": [
"V",
"O",
"Std"
]
},
{
"name": "Texture",
"displayValue": "Cotton",
"operation": null,
"type": "dropdown",
"options": "Cotton|Lin|Std",
"required": false,
"value": "Cotton",
"optionsArray": [
"Cotton",
"Lin",
"Std"
]
},
{
"name": "Gift",
"displayValue": "false",
"operation": null,
"type": "checkbox",
"options": "true|false",
"required": false,
"value": "false",
"optionsArray": [
"true",
"false"
]
}
],
"unitPrice": 300,
"hasDimensions": false
}
],
"refunds": [],
"taxes": [],
"user": {
"id": "8de09cbc-4797-421e-841b-156954ddbb61",
"email": "geeks@snipcart.com",
"creationDate": "2017-09-22T14:56:05.433Z",
"mode": "Test",
"gravatarUrl": "https://www.gravatar.com/avatar/b2b4677d71645916cbce0a893f7f6076?s=70&d=https%3a%2f%2fcdn.snipcart.com%2fassets%2fimages%2favatar.jpg",
"billingAddress": {
"fullName": "Geeks Snipcart",
"firstName": "Geeks",
"name": "Snipcart",
"company": "Snipcart",
"address1": "226 rue St-Joseph E",
"address2": "",
"fullAddress": "226 rue St-Joseph E",
"city": "Quebec",
"country": "CA",
"postalCode": "G1K3A9",
"province": "QC",
"phone": "888 888 8888",
"vatNumber": null
},
"shippingAddress": {
"fullName": "Geeks Snipcart",
"firstName": "Geeks",
"name": "Snipcart",
"company": "Snipcart",
"address1": "226 rue St-Joseph E",
"address2": "",
"fullAddress": "226 rue St-Joseph E",
"city": "Quebec",
"country": "CA",
"postalCode": "G1K3A9",
"province": "QC",
"phone": "888 888 8888",
"vatNumber": null
}
},
"token": "1912e4c1-d008-4c15-ab12-fe21a76d30d4",
"isRecurringOrder": false,
"parentToken": null,
"parentInvoiceNumber": null,
"currency": "cad",
"creationDate": "2017-10-03T19:47:56Z",
"modificationDate": "2017-10-04T19:18:52Z",
"status": "Processed",
"paymentStatus": "Paid",
"email": "geeks@snipcart.com",
"billingAddress": {
"fullName": "Geeks Snipcart",
"firstName": "Geeks",
"name": "Snipcart",
"company": "Snipcart",
"address1": "226 rue St-Joseph E",
"address2": "",
"fullAddress": "226 rue St-Joseph E",
"city": "Quebec",
"country": "CA",
"postalCode": "G1K3A9",
"province": "QC",
"phone": "888 888 8888",
"vatNumber": null
},
"shippingAddress": {
"fullName": "Geeks Snipcart",
"firstName": "Geeks",
"name": "Snipcart",
"company": "Snipcart",
"address1": "226 rue St-Joseph E",
"address2": "",
"fullAddress": "226 rue St-Joseph E",
"city": "Quebec",
"country": "CA",
"postalCode": "G1K3A9",
"province": "QC",
"phone": "888 888 8888",
"vatNumber": null
},
"shippingAddressSameAsBilling": true,
"creditCardLast4Digits": "4242",
"trackingNumber": null,
"trackingUrl": null,
"shippingFees": 10,
"shippingProvider": null,
"shippingMethod": "Livraison",
"shippingRateUserDefinedId": "free_shipping",
"cardHolderName": "Geeks Snipcart",
"paymentMethod": "CreditCard",
"completionDate": "2017-10-04T19:18:30Z",
"cardType": "Visa",
"paymentGatewayUsed": "Test",
"taxProvider": "Default",
"lang": "en",
"refundsAmount": 0,
"adjustedAmount": 330,
"finalGrandTotal": 330,
"totalNumberOfItems": 0,
"invoiceNumber": "SNIP-1003",
"billingAddressComplete": true,
"shippingAddressComplete": true,
"shippingMethodComplete": true,
"rebateAmount": 10,
"subtotal": 320,
"itemsTotal": 330,
"taxableTotal": 330,
"grandTotal": 330,
"total": 330,
"totalWeight": 20,
"totalRebateRate": 0,
"customFields": [
{
"name": "Slug",
"displayValue": "Slug",
"operation": null,
"type": "textbox",
"options": "",
"required": true,
"value": "Slug",
"optionsArray": null
},
{
"name": "Average age",
"displayValue": "20-25",
"operation": null,
"type": "dropdown",
"options": "20-25|25-30|30-35",
"required": false,
"value": "20-25",
"optionsArray": [
"20-25",
"25-30",
"30-35"
]
},
{
"name": "Do you accept terms",
"displayValue": "true",
"operation": null,
"type": "checkbox",
"options": "true|false",
"required": true,
"value": "true",
"optionsArray": [
"true"
]
}
],
"shippingEnabled": true,
"numberOfItemsInOrder": 2,
"paymentTransactionId": "",
"metadata": {},
"taxesTotal": 0,
"itemsCount": 2,
"summary": {
"subtotal": 320,
"taxableTotal": 330,
"total": 330,
"payableNow": 330,
"paymentMethod": "CreditCard",
"taxes": [],
"adjustedTotal": 330,
"shipping": null
},
"ipAddress": "127.0.0.1",
"hasSubscriptions": true
}
}Events
order.completed
Fires when a new order has been completed successfully. Its content is the full Order object - see The Order content above.
{
"eventName": "order.completed",
"mode": "Live",
"createdOn": "2026-01-01T00:00:00Z",
"content": { "...": "the Order object - see The Order content" }
}order.status.changed
Fires when the status of an order changes from the dashboard or the API. Adds top-level from/to (order status) alongside the Order in content.
{
"eventName": "order.status.changed",
"mode": "Live",
"createdOn": "2026-01-01T00:00:00Z",
"from": "InProgress",
"to": "Processed",
"content": { "...": "the Order object - see The Order content" }
}order.paymentStatus.changed
Fires when the payment status of an order changes from the dashboard or the API. Adds top-level from/to (payment status) alongside the Order in content.
{
"eventName": "order.paymentStatus.changed",
"mode": "Live",
"createdOn": "2026-01-01T00:00:00Z",
"from": "Authorized",
"to": "Paid",
"content": { "...": "the Order object - see The Order content" }
}order.trackingNumber.changed
Fires when the tracking number of an order changes. Adds top-level trackingNumber/trackingUrl alongside the Order in content.
{
"eventName": "order.trackingNumber.changed",
"mode": "Live",
"createdOn": "2026-01-01T00:00:00Z",
"trackingNumber": "123",
"trackingUrl": "http://fedex.com",
"content": { "...": "the Order object - see The Order content" }
}order.notification.created
Fires when a notification is added to an order. The content carries the notification, not the Order:
orderTokenstring- the token of the order.notificationTypestring-"Invoice","Comment","TrackingNumber","OrderCancelled","Refund","OrderShipped","OrderReceived","OrderPaymentExpired","OrderStatusChanged","RecoveryCampaign","DigitalDownload","Logs"and"Other".sentByEmailbool- whether the customer was notified by email.sentByEmailOnDateTime- the send date of the email, if applicable.subjectstring- the subject of the email message, if applicable.messagestring- the message or comment on the notification.
{
"notificationType": "Comment",
"sentByEmailOn": null,
"sentByEmail": false,
"orderToken": "2e8fbc93-6a20-48f1-ad39-6797a61730b5",
"message": "<p>Backorder is expected on September 1st.</p>",
"subject": ""
}order.refund.created
Fires when an order is wholly or partially refunded. The content carries the refund:
orderTokenstring- the token of the refunded order.amountstring- the amount of the refund.commentstring- reason for the refund, if specified.notifiedCustomerByEmailbool- whether the customer was notified by email about the refund.currencystring- the currency of the order being refunded.
{
"orderToken": "62b31459-919e-4e6a-9c5d-764f5739cb9f",
"amount": 29.75,
"comment": "Requested by customer.",
"notifiedCustomerByEmail": true,
"currency": "CAD"
}order.withdrawal.created
Fires when a customer requests a withdrawal of their purchase. The content carries the withdrawal request:
idstring (GUID)- unique identifier for this withdrawal request. Use it to correlate with thewithdrawalIdon a laterorder.refund.createdevent.orderTokenstring- internal token of the order this withdrawal is for.orderInvoiceNumberstring- the customer-facing invoice number of the order.customerNamestring- the full name supplied by the customer in the withdrawal form (the EU "unequivocal statement").requestedAtstring (ISO 8601 datetime)- when the customer submitted the request.isPartialboolean-trueif the customer selected specific items;falsefor the full order.isOutsideWithdrawalPeriodboolean-trueif submitted more than 14 days after completion. The merchant decides whether to honour it.refundAmountnumber- the total the merchant will refund if accepted.resolutionstring- one ofPending,Accepted,Declined. AlwaysPendingon the initial event.confirmationNumberstring- human-readable identifier in the formWD-YYYYMMDD-XXXXXXXX.itemsarray- the line items requested for withdrawal (itemUniqueId,itemName,quantity,unitPrice,totalPrice). For a full withdrawal, every item on the order.
{
"eventName": "order.withdrawal.created",
"mode": "Live",
"content": {
"id": "5b8c9d10-7e2f-4a8b-9c2d-1e3f4a5b6c7d",
"orderToken": "abcd1234-5678-90ef-abcd-1234567890ef",
"orderInvoiceNumber": "SNIP-1057",
"customerName": "Marie Dubois",
"requestedAt": "2026-05-07T14:32:11Z",
"isPartial": true,
"isOutsideWithdrawalPeriod": false,
"refundAmount": 89.97,
"resolution": "Pending",
"confirmationNumber": "WD-20260507-5B8C9D10",
"items": [
{
"itemUniqueId": "11111111-2222-3333-4444-555555555555",
"itemName": "Wireless headphones",
"quantity": 1,
"unitPrice": 89.97,
"totalPrice": 89.97
}
]
}
}