Skip to content

Order cancellation, returns and refunds

This page covers what happens when an order goes wrong: a cancellation, a return or a refund. Cancelling on the customer’s behalf has a current route. Only a v1 route exists for the other tasks, so v1 is the path for them.

Three pieces of your order flow:

  • a call that tells Zentail when a customer cancels on your channel,
  • a check on your order poll that picks up cancellations the seller made,
  • a check on the same poll that reads back returns and refunds.

When a customer cancels on your channel, tell Zentail with POST /v2/storefront/orders/cancel. We call this a customer-initiated cancellation.

{
"channelOrderId": "113-4567890-1234567",
"cancelQuantities": {
"88001": "1"
}
}
  • channelOrderId is your channel’s id for the order, the one you sent when you injected it. The seller is taken from your token.
  • cancelQuantities maps each Zentail lineItemId to the number of units to cancel. Leave out any line you are not cancelling. Each quantity is a JSON string, because this route sends every 64-bit integer as one.

A success returns an empty object. Zentail puts the cancelled units back into stock at the warehouses the line was routed to, so you don’t send a restock list. You don’t send a reason either.

An error comes back as a google.rpc.Status body with code, message and details. An order that doesn’t match channelOrderId returns NOT_FOUND.

Sometimes the seller cannot fulfil an order and cancels it in Zentail. We call this a merchant-initiated cancellation. Only a v1 route exists for this. The shipped-orders poll, GET /v2/storefront/orders/shipped, returns only shipped orders, and its order view has no cancel quantities.

So poll GET /v1/salesOrder with lastUpdatedTs and status=CANCELLED. On each order, read cancelQuantity on each line item in products to see which part of the order was cancelled. The order’s cancellationReason says why.

You can read returns and refunds. You cannot create them. There is no route for raising a return, issuing a refund or sending a replacement, so a seller still starts those on your channel. Zentail publishes the record of one that already exists, on the same GET /v1/salesOrder poll as step 2. Only a v1 route exists for this.

On the order:

Field What it carries
status RETURN_REQUESTED, RETURNED or REFUNDED, alongside the statuses you already handle
returnOrders One entry per return on the order, each with channelReturnId, requestTs, a cancelled flag and its returnItems
accounting.refund The total refunded, if the order was partly or wholly refunded

On each line item in products:

Field What it carries
status the same status values, per line item
refund the amount refunded for that line item
refundReason why

On each entry in a return’s returnItems: the SKU, the quantity being returned against the originalQuantity ordered, and the refundAmount.

Use these to reflect a return or refund your channel already knows about, and to reconcile against Zentail’s numbers.

API changelog · Built 0c509dd3