About the eCommerce Orders API
The eCommerce Orders API allows apps or site owners to customize management of the order lifecycle, including viewing, updating, and canceling. In the dashboard, business staff can create new orders, view and edit existing orders, track fulfillment, and manage the payments cycle.
An order holds information about purchased items, price and tax summaries, shipping and billing information, any applied discounts, and the status of payment and fulfillment.
With the eCommerce Orders API you can:
- Get and search for orders.
- Update and cancel an order.
- Create an order for your records.
- Listen to events when an order is approved, updated, or canceled.
- Listen to events when an order's transactions are updated. This event is part of the Order Transactions API.
Before you begin
If you are migrating from the Stores Orders API, please refer to the following conversion tables:
- Stores to eCommerce Order Object Conversion Table.
- Stores to eCommerce Webhook Conversion Table.
eCommerce Orders: Sample Use Cases and Flows
This article shares some possible use cases your app could support, as well as a sample flow that could support each use case. This can be a helpful jumping off point as you plan your app's implementation.
Using an order ID across different eCommerce APIs
Some eCommerce functionality is accessible by using an order's ID and passing it to other eCommerce APIs. Here are a few examples:
- To retrieve transaction details for one or more orders, pass the order IDs to List Transactions For Multiple Orders.
- To add a record of payment, pass the order ID and payment details to Add Payments.
- To modify an order's payment status, pass its ID along with the relevant payment's ID to Update Payment Status. To modify up to 300 orders at once, pass their IDs along with the relevant payment IDs to Bulk Update Payment Statuses.
- To retrieve fulfillment details of up to 100 orders at once, pass the order IDs to List Fulfillments For Multiple Orders.
Record an external order
When an order is made on an external system, you may want to record it and its payment details on your app.
To record an external order:
- Call Create Order and pass all the details of the external order.
- Save the order
id
from the Create Order API's response. - Pass the order
id
, along with the external order's payments details, to Add Payments. This will add a record of the payment associated with the order.
Orders: Supported Filters and Sorting
The following table shows field support for filters and sorting for the Order object:
Field | Supported Filtering | Sortable |
---|---|---|
id | $eq , $ne , $in , $nin | |
number | $eq , $ne , $gt , $lt , $gte , $lte | Sortable |
status | $eq , $ne , $in , $nin | Sortable |
archived | $eq , $ne , $in , $exists , $startsWith | |
createdDate | $eq , $ne , $lt , $lte , $gte , $gt , $nin | Sortable |
updatedDate | $eq , $ne , $gt , $lt , $gte , $lte | Sortable |
lineItems.productName.original | $eq , $ne , $in , $nin , $hasSome , $hasAll | |
lineItems.catalogReference.appId | $eq , $ne , $in , $nin , $hasSome , $hasAll | |
lineItems.catalogReference.catalogItemId | $eq , $ne , $in , $nin , $hasSome , $hasAll | |
subscriptionInfo.id | $eq , $ne , $in , $nin | |
buyerInfo.email | $eq , $ne , $in , $exists , $startsWith | Sortable |
buyerInfo.contactId | $eq , $ne , $in , $nin | |
buyerInfo.memberId | $eq , $ne , $in , $nin | |
paymentStatus | $eq , $ne , $in , $nin | Sortable |
fulfillmentStatus | $eq , $ne , $in , $nin | Sortable |
priceSummary.total.amount | $eq , $ne , $gt , $lt , $gte , $lte | |
billingInfo.contactDetails.fullName | $eq , $ne , $in , $exists , $startsWith | |
shippingInfo.title | $eq , $ne , $in , $nin | |
shippingInfo.logistics.deliveryTime | $eq , $ne , $in , $exists , $startsWith | |
shippingInfo.region.name | $eq , $ne , $in , $nin | |
deliveryTimeSlotFromDate (See notes) | $eq , $ne , $in , $exists , $startsWith | |
deliveryTimeSlotToDate (See notes) | $eq , $ne , $in , $exists , $startsWith | |
createdBy.userId | $eq , $ne , $in , $nin | |
channelInfo.type | $eq , $ne , $in , $nin | |
channelInfo.externalOrderId | $eq , $ne , $in , $nin | |
seenByAHuman | $eq , $ne , $in , $exists , $startsWith | |
checkoutId | $eq , $ne , $in , $nin | |
paymentMethods (See notes) | $eq , $ne , $in , $nin , $hasSome , $hasAll | |
fulfillmentStatuses (See notes) | $eq , $ne , $in , $nin , $hasSome , $hasAll |
Notes:
deliveryTimeSlotFromDate
- shorthand for theshippingInfo.logistics.deliveryTimeSlot.from
field.deliveryTimeSlotToDate
- shorthand for theshippingInfo.logistics.deliveryTimeSlot.to
field.paymentMethods
- aggregate of theorderTransactions.payments.regularPaymentDetails.paymentMethod
field from the Order Transactions API.fulfillmentStatuses
- shorthand for thefulfillmentStatusesAggregate
field.
Related content: API Query Language, Search Orders
Stores to eCommerce Order Object Conversion
To help with migration to the eCommerce Orders API, refer to the table below for field changes between the Stores order object and the eCommerce order object.
Note that some fields are accessible via other eCommerce APIs like Order Transactions or Order Fulfillments. In these cases, the way to access the info is described in the third column.
The address object used in the eCommerce APIs is slightly different to the one used in the Stores APIs. For more details, refer to the address object conversion table.
The eCommerce Order Updated event fires when a Stores order and/or an eCommerce order is updated. For more details on webhooks, refer to the Webhook Conversion Table below.
Fields marked with an asterisk (*) signify little to no change in semantics or access.
Order Object Conversion Table
Stores Order Object | eCommerce Order Object | Notes |
---|---|---|
id * | id | |
number * | number | |
dateCreated | createdDate | |
buyerInfo.id | buyerInfo.contactId & buyerInfo.memberId | |
buyerInfo.id and buyerInfo.identityType: "MEMBER" | buyerInfo.memberId | |
buyerInfo.id and buyerInfo.identityType: "CONTACT" | buyerInfo.contactId | |
buyerInfo.firstName | billingInfo.contactDetails.firstName | |
buyerInfo.lastName | billingInfo.contactDetails.lastName | |
buyerInfo.phone | billingInfo.contactDetails.phone | |
buyerInfo.email * | buyerInfo.email | |
currency * | currency | |
weightUnit * | weightUnit | |
totals.subtotal | priceSummary.subtotal.amount | |
totals.shipping | priceSummary.shipping.amount | |
totals.tax | priceSummary.tax.amount | |
totals.discount | priceSummary.discount.amount | |
totals.total | priceSummary.total.amount | |
totals.weight | An order's total weight is equal to (lineItems[0].physicalProperties.weight X lineItems[0].quantity) + (lineItems[1].physicalProperties.weight X lineItems[1].quantity) and so on. | |
totals.quantity | An order's total line item quantity is equal to lineItems[0].quantity + lineItems[1].quantity + lineItems[2].quantity and so on. | |
totals.refund | Available via the Order Transactions API. | Pass the order ID to the List Transactions For Single Order endpoint to retrieve this info. |
totals.giftCard | Available via the Order Transactions API. | Pass the order ID to the List Transactions For Single Order endpoint to retrieve this info. |
billingInfo.paymentMethod | Available via the Order Transactions API. | Pass the order ID to the List Transactions For Single Order endpoint to retrieve this info. |
billingInfo.paymentProviderTransactionId | Available via the Order Transactions API. | Pass the order ID to the List Transactions For Single Order endpoint to retrieve this info. |
billingInfo.paymentGatewayTransactionId | Available via the Order Transactions API. | Pass the order ID to the List Transactions For Single Order endpoint to retrieve this info. |
billingInfo.paidDate | Available via the Order Transactions API. | Pass the order ID to the List Transactions For Single Order endpoint to retrieve this info. |
billingInfo.refundableByPaymentProvider | Available via the Order Transactions API. | Pass the order ID to the List Transactions For Single Order endpoint to retrieve this info. |
billingInfo.address * | billingInfo.address | Address object conversion table. |
shippingInfo.code * | shippingInfo.code | |
shippingInfo.deliverByDate | shippingInfo.logistics.deliverByDate | |
shippingInfo.deliveryOption | shippingInfo.title | |
shippingInfo.shippingRegion | shippingInfo.region.name | |
shippingInfo.shippingDetails.address | shippingInfo.logistics.shippingDestination.address | Address object conversion table. |
shippingInfo.shipmentDetails.discount | shippingInfo.cost.discount.amount | |
shippingInfo.shipmentDetails.tax | shippingInfo.cost.taxDetails.totalTax.amount | |
shippingInfo.shipmentDetails.priceData.taxIncludedInPrice | taxIncludedInPrices | |
shippingInfo.shipmentDetails.priceData.price | shippingInfo.cost.totalPriceAfterTax.amount | |
shippingInfo.pickupDetails.pickupAddress | shippingInfo.logistics.pickupDetails.address | Address object conversion table. |
shippingInfo.pickupDetails.pickupInstructions | shippingInfo.logistics.instructions | |
shippingInfo.estimatedDeliveryTime | shippingInfo.logistics.deliveryTime | |
buyerNote * | buyerNote | |
archived * | archived | |
paymentStatus * | paymentStatus | |
paymentStatus: PENDING | status: INITIALIZED | |
fulfillmentStatus * | fulfillmentStatus | For more info, pass an order ID to the List Fulfillments For Single Order endpoint. |
fulfillmentStatus: CANCELED | status: CANCELED | |
lineItems[i].index | lineItems[i].id | While the lineItems[i].index in Stores Orders was an int32 type, the eCommerce Order's lineItems[i].id field is of type GUID. |
lineItems[i].quantity * | lineItems[i].quantity | |
lineItems[i].name | lineItems[i].productName.original | |
lineItems[i].translatedName | lineItems[i].productName.translated | |
lineItems[i].productId | lineItems[i].catalogReference.catalogItemId | The catalogReference object links between eCommerce APIs and catalogs like Wix Stores. Learn more about eCommerce integration for Wix Stores. |
lineItems[i].lineItemType: "PHYSICAL" | lineItems[i].itemType.preset: "PHYSICAL" | |
lineItems[i].lineItemType: "DIGITAL" | lineItems[i].itemType.preset: "DIGITAL" | |
lineItems[i].lineItemType: "CUSTOM_AMOUNT_ITEM" | lineItems[i].itemType.custom and lineItems[i].catalogReference is empty. | |
lineItems[i].options | lineItems[i].descriptionLines | |
lineItems[i].customTextFields | lineItems[i].catalogReference.options | Within the catalogReference.options look for the customTextFields key. |
lineItems[i].weight | lineItems[i].physicalProperties.weight | |
lineItems[i].mediaItem.url | lineItems[i].image.url | |
lineItems[i].mediaItem.height | lineItems[i].image.height | |
lineItems[i].mediaItem.width | lineItems[i].image.width | |
lineItems[i].mediaItem.id | lineItems[i].image.id | |
lineItems[i].mediaItem.altText | lineItems[i].image.altText | |
lineItems[i].sku | lineItems[i].physicalProperties.sku | |
lineItems[i].notes | lineItems[i].descriptionLines[i].plainText.original | |
lineItems[i].variantId | lineItems[i].catalogReference.options | The catalogReference object links between eCommerce APIs and catalogs like Wix Stores. Learn more about eCommerce integration for Wix Stores. |
lineItems[i].fulfillerId * | lineItems[i].fulfillerId | |
lineItems[i].discount | lineItems[i].totalDiscount.amount | |
lineItems[i].tax | lineItems[i].taxDetails.totalTax.amount | |
lineItems[i].priceData.taxIncludedInPrice | taxIncludedInPrices | |
lineItems[i].priceData.price | lineItems[i].price.amount | |
lineItems[i].priceData.totalPrice | lineItems[i].totalPriceAfterTax.amount | |
activities[i].type * | activities[i].type | |
activities[i].TRACKING_LINK_WAS_SET | activities[i].TRACKING_LINK_SET | |
activities[i].INVOICE_WAS_SET | activities[i].INVOICE_ADDED | |
activities[i].INVOICE_WAS_SENT | activities[i].INVOICE_SENT | |
activities[i].author | activities[i].authorEmail | |
activities[i].message | activities[i].merchantComment.message | If activities.type = "MERCHANT_COMMENT" |
activities[i].timestamp | activities[i].createdDate | |
invoiceInfo | Not available in eCommerce order object. | Currently, this information is held in the Stores order object. |
fulfillments | Not available in eCommerce order object. | For more info, pass an order ID to the List Fulfillments For Single Order endpoint. |
discount.appliedCoupon.couponId | appliedDiscounts[i].coupon.id | Search the appliedDiscounts array for the coupon field; couponId is coupon.id |
discount.appliedCoupon.name | appliedDiscounts[i].coupon.name | Search the appliedDiscounts array for the coupon field; name is coupon.name |
discount.appliedCoupon.code | appliedDiscounts[i].coupon.code | Search the appliedDiscounts array for the coupon field; code is coupon.code |
customField.value | customFields[i].value.stringValue | Note: customFields is an array |
customField.title | customFields[i].title | |
customField.translatedTitle | customFields[i].translatedTitle | |
cartId | Not returned in the eCommerce order object. | Replaced by checkoutId |
buyerLanguage * | buyerLanguage | |
channelInfo.type * | channelInfo.type | |
channelInfo.externalOrderId * | channelInfo.externalOrderId | |
channelInfo.externalOrderUrl * | channelInfo.externalOrderUrl | |
enteredBy.id and enteredBy.identityType: "MEMBER" | createdBy.memberId | |
enteredBy.id and enteredBy.identityType: "USER" | createdBy.userId | |
enteredBy.id and enteredBy.identityType: "APP" | createdBy.appId | |
enteredBy.id and enteredBy.identityType: "CONTACT" | createdBy.visitorId | Previously, for a buyer that is not logged in, CONTACT type and ID were returned. in the eCommerce API, visitorId is returned. Note: the ID itself will also be different. |
lastUpdated | updatedDate | |
numericId | - | Removed due to added cursor paging functionality |
refunds | Not available in eCommerce order object. | Pass the order ID to the List Transactions For Single Order endpoint to retrieve this info. |
*Fields marked with an asterisk signify little to no change in semantics or access.
Webhook Conversion Table
The following table shows Stores Orders webhooks and their equivalents in the eCommerce Orders API that are triggered at the same time:
Stores Orders API | eCommerce Orders API |
---|---|
Order Paid Webhook | Payment Status Updated Webhook sent with order.paymentStatus = PAID |
Order Created Webhook | Order Approved Webhook |
Order Canceled Webhook | Order Canceled Webhook |
Order Refunded Webhook | Order Transactions Updated Webhook |
We've also updated the structure of the webhook/event payload. The event's order ID is now provided both at the top level as entityId
and as order.id
within the payload itself. The table below describes where to find the order ID or order entity in the new webhook payloads:
Stores Webhooks | eCommerce Webhooks |
---|---|
Order ID - order.id / orderId | All order webhook payloads - entityId |
Order Created - the payload itself is the order | Order Approved - actionEvent.body.order |
Order Paid/Canceled/Refunded - order | Order Canceled/Approved - actionEvent.body.order |
- | Order Updated - updatedEvent.currentEntity |
Address Object Conversion Table
The eCommerce APIs use a different address
object. Notably, fields related to contact information have been moved
to an adjacent contactDetails
object (for example, in order.shippingInfo
).
To help with conversion and migration, refer to the table below to check which fields have changed and how.
Note: in the eCommerce API, the buyer's email is only held in the buyerInfo
field in the eCommerce Order object.
Previous Address Object | eCommerce Address Field Location | Change |
---|---|---|
address.city | address.city | |
address.email | buyerInfo.email | |
address.zipCode | address.postalCode | Field name |
address.country | address.country | |
address.addressLine1 | address.addressLine | Field name |
address.addressLine2 | address.addressLine2 | |
address.street | address.streetAddress | Field name |
address.subdivision | address.subdivision | |
address.fullName.firstName | contactDetails.firstName | Moved to contactDetails object |
address.fullName.lastName | contactDetails.lastName | Moved to contactDetails object |
address.phone | contactDetails.phone | Moved to contactDetails object |
address.company | contactDetails.company | Moved to contactDetails object |
address.vatId | contactDetails.vatId | Moved to contactDetails object |
Edit Order/Draft Orders API Migration Guide
Notes:
- This migration is relevant for all apps that currently use the Stores Orders API.
- The Stores Orders API will soon be deprecated in favor of the eCommerce Orders API.
We’re introducing a new Wix eCommerce Orders API that enables business owners to meet new customer needs and provide better customer service. This will eventually replace the existing Stores Orders API. This quick guide will help you to make sure your app is ready for the migration.
New object and webhook structures
The structure of the eCommerce Order object is different from the Stores Order object. You can learn more about these structural changes here.
The webhook payload structure has also changed. To facilitate your move to these webhooks, have a look at the webhook conversion table.
Users can now edit orders
Customers occasionally make mistakes when placing an order, or they might simply want to make a change to an existing order. This could include adding items, updating prices, revising customer details, and more.
The new eCommerce service includes functionality that lets users edit existing orders. This will be known as Draft Orders when using our REST APIs, and as Edit Order in the dashboard.
When an existing order is edited, the Order Updated Webhook is triggered. This webhook returns the whole order object in the eCommerce order structure, but you can still pass the edited order’s ID to the Stores Orders endpoints if you’d like to fetch the order in the Stores structure.
Impact examples
If a Wix user edits an existing order, depending on your app type you might need your app to be aware of the change. Here are some examples:
- A user changes the quantity of a product item in an existing order. As a result, the number of items to be shipped has changed.
- A user changes the shipping address in an existing order.
- A user adds a new item to an existing order. As a result, the amount to be paid changes.
- A user changes the price of an item in an existing order. As a result, the total payable amount of the order, as well as the payment status can change.
How to add the new Order Updated webhook
- Go to your app in the Wix Developers Center.
- Go to the Webhooks tab in the side menu.
- Click + Add Webhook.
- Select an API Category > Wix eCommerce
- Find and select the Order Updated Webhook
- Add a Callback URL.
- Click Save.
How to test the impact on your app
Edit Order is not yet available publicly, but if you’d like to test the feature yourself and understand any implications it may have for your app, follow these steps:
- Install the EditThisCookie Chrome extension.
- Click + to add a new cookie, select
petri-ovr
and fill out the following fields:
- Value:
specs.stores.OrderEditPageComponent#true
- Domain:
.wix.com
- Secure: Check the box
- HttpOnly: Check the box
- Create a new Wix website with Wix Stores installed (testing this change only works on new sites).
- Refresh the Orders page.
- Navigate to an unfulfilled order in the dashboard.
- Click on the More Actions button in the top right corner.
- Click on Edit Order.
Note:
All orders, including changes committed by Edit Order, are still available in the Stores Orders APIs and webhooks. However, we highly recommend planning your transition to eCommerce Orders and Edit Order/Draft Orders, as the Stores Orders API will be deprecated in the coming months.
Create and manage eCommerce orders
- NOT_PAID - This can be an order made online, but not yet paid. In such cases order.status will be INITIALIZED.
- This status also applies when an offline order needs to be manually marked as paid. In such cases order.status will be APPROVED.
- PAID - All payments associated with this order are paid. For online payments: payment.regularPaymentDetails.status: APPROVED. For gift cards: payment.giftCardPaymentDetails.voided: false.
- PARTIALLY_REFUNDED - Order was refunded, but refund amount is less than order total price.
- FULLY_REFUNDED - Order fully refunded. Refund amount equals total price.
- PENDING - Payments received but not yet confirmed by the payment provider.
- PARTIALLY_PAID - At least one payment was received and approved, covering less than total price amount.
- INITIALIZED - Order was created, but not yet approved or declined.
- APPROVED - Order was approved. This happens when either the online payment succeeded or the order is an offline order. Once an order is approved, many side effects are triggered. For example, holding of stock in the inventory and sending of notification emails.
- CANCELED - Order was canceled by the user.
- The chosen shipping option is pickup point or store pickup.
- No shipping option is selected.
Retrieves an order with the provided ID.
To retrieve an order's payment and refund details, including amounts, payment methods, and payment statuses, pass the order ID to List Transactions For Single Order.
Permission Scopes
For app development, you must have one of the following permission scopes:Retrieves a list of orders, given the provided paging, filtering, and sorting.
Search Orders runs with these defaults, which you can override:
createdDate
is sorted inDESC
ordercursorPaging.limit
is100
filter: {"status": {"$ne": "INITIALIZED"}}
- other order statuses can be queried, but orders withstatus: "INITIALIZED"
are never returned
For field support for filters and sorting, see Orders: Supported Filters and Sorting.
To learn about working with Search endpoints, see API Query Language, and Sorting and Paging.
Permission Scopes
For app development, you must have one of the following permission scopes:Creates an order.
Notes:
- If an item is digital -
lineItems[i].itemType.preset: DIGITAL
- thenlineItems[i].digitalFile
must be provided. - If
lineItems[i].id
is passed, it must be either a valid GUID, or empty.
Permission Scopes
For app development, you must have one of the following permission scopes:Updates an order's properties.
Currently, the following fields can be updated:
order.buyerInfo.email
order.recipientInfo.address
order.recipientInfo.contactDetails
order.shippingInfo.logistics.shippingDestination.address
order.shippingInfo.logistics.shippingDestination.contactDetails
To update a field's value, include the new value in the order
object in the body params.
To remove a field's value, pass null
.
Note: Removing buyerInfo
or contactDetails
results in an error.
To update an order's payment status, use Update Payment Status.
Permission Scopes
For app development, you must have one of the following permission scopes:Cancels an order. The order.status
field changes to CANCELED
.
Permission Scopes
For app development, you must have one of the following permission scopes:Triggered when an order's payment status is updated to "PAID"
.
Permission Scopes
For app development, you must have one of the following permission scopes:Permission Scopes
For app development, you must have one of the following permission scopes:Triggered when an order is created. Learn more about webhook payload structure.
Permission Scopes
For app development, you must have one of the following permission scopes:Triggered when an order is canceled. Learn more about eCommerce webhook payload structure.
Permission Scopes
For app development, you must have one of the following permission scopes:Triggered when an order is created and its status is updated to "APPROVED"
.
Learn more about eCommerce webhook payload structure.