ConfirmCancellations reports that you have pulled work back on your side, draining it from ListNeedToCancel.
You call thissales:orders:fulfillment:self
const url = 'https://api.zentail.com/v2/shipping/fulfillment_orders/confirm_cancellations';const options = { method: 'POST', headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'}, body: '{"confirmations":[{"fulfillmentOrderId":"example","lines":[{"lineItemId":"example","quantity":1}],"alreadyShipped":true}]}'};
try { const response = await fetch(url, options); const data = await response.json(); console.log(data);} catch (error) { console.error(error);}curl --request POST \ --url https://api.zentail.com/v2/shipping/fulfillment_orders/confirm_cancellations \ --header 'Authorization: Bearer <token>' \ --header 'Content-Type: application/json' \ --data '{ "confirmations": [ { "fulfillmentOrderId": "example", "lines": [ { "lineItemId": "example", "quantity": 1 } ], "alreadyShipped": true } ] }'Confirm only what you actually cancelled. If a unit has already shipped and
cannot be recalled, say so with already_shipped rather than confirming —
Zentail needs to know the difference to keep the customer order right.
Authorizations
Section titled “Authorizations”Request Bodyrequired
Section titled “Request Bodyrequired”object
One entry per cancellation request you have carried out. Required and server-capped, like every batch on this contract.
object
Which cancellation request you are answering, from ListNeedToCancel.
Not supported yet. Sending any line fails the entry rather than being widened to the whole request, because treating a partial confirmation as a full one would cancel units you did not. Omit it to confirm the whole request, which is the only shape ListNeedToCancel asks for today.
object
Which line of the fulfillment order, echoed from FulfillmentOrderLine. A SKU is not accepted here: one SKU can appear on two lines.
How many units of that line are in this package. At least one, and never more than the line still owes — across the whole request, so naming one line twice is summed before it is checked.
Set when you could not cancel because the units are already on their way. Zentail keeps the customer order truthful rather than showing a cancellation that did not happen; report the shipment through ConfirmShipments as normal.
Examplegenerated
{ "confirmations": [ { "fulfillmentOrderId": "example", "lines": [ { "lineItemId": "example", "quantity": 1 } ], "alreadyShipped": true } ]}Responses
Section titled “ Responses ”A successful response.
object
One result per confirmation sent, matched on fulfillment_order_id. An entry that failed is still in ListNeedToCancel on the next poll.
object
The confirmation this answers, echoed back.
True when the request is drained, which includes a replay (already_recorded set) and a report of already_shipped — you answered the question you were asked. False is a real failure, and the request will be re-offered.
Why it failed, in prose, for logs and support. Empty on success. Two failures are worth handling rather than retrying: no outstanding request for this order, and an order that has already shipped or been rejected.
True when this cancellation was already recorded. Treat as success.
Examplegenerated
{ "results": [ { "fulfillmentOrderId": "example", "success": true, "errorMessage": "example", "alreadyRecorded": true } ]}default
Section titled “default”An unexpected error response.
object
object
Examplegenerated
{ "code": 1, "message": "example", "details": [ { "@type": "example" } ]}