Order Cancel

Friday, Dec 14, 2018

Order Cancellations

Order cancel is now live in Sandbox! See the full API spec here: https://docs.masonhub.co/api/v1#tag/Orders/paths/~1order_cancel_requests/post

Making cancelation requests for orders follows all the same precedents as making update request to orders.
Because orders go through a picking and packing lifecycle, there is a certain point at which orders can no longer be canceled. For that reason, any cancelations to orders are in actuality requests to cancel the order, to which the MasonHub API will eventually advise whether the cancelation was successful or unsuccessful.

For this reason, all cancelations are submitted in the form of a POST to the /order_cancel_requests endpoint. The body of the request is simply the customer identifier for the order (the Order ID).

Immediately after an order cancel request is submitted, the request is automatically in ‘pending’ status. This status will update after the request propagates to the distribution center, and it is determined whether the order can in fact be canceled or not. The most common reason an order cancel would fail would be because the order is already picked and packed, and is too far into fulfillment to be canceled.

Let’s walk through an example:

POST to https://sandbox.masonhub.co/{your-client-slug-here}/api/v1/order_cancel_requests

[
  {
    "customer_identifier": "129374"
  }
]

The API will do validation to make sure the order does in fact exist and is in a status eligible for cancelation.

You can now pull a list of OrderCancelRequests by making a GET request to /order_cancel_requests.

Or, if you want see an update on the OrderCancelRequest for a specific order, you can specify so with the cid attribute in the url parameters:

GET to https://sandbox.masonhub.co/{your-client-slug-here}/api/v1/order_cancel_requests?cid=129374

{
    "limit": 30,
    "offset": 0,
    "list_type": "detail",
    "include_counts": false,
    "data": [
        {
            "id": "cc69085d-4388-4ce5-a1db-ffb9f41352f7",
            "customer_order_id": "129374",
            "status": "pending",
            "created_at": "2018-12-14T22:36:44.282713Z",
            "updated_at": "2018-12-14T22:36:44.282714Z",
            "deleted_at": null
        }
    ]
}

Order Cancelation Callbacks

In addition to posting cancelation request, you can also post to the Data Factory to trigger cancelation resolutions and callbacks

There’s a new callback event you can now register for, called orderCancelResolution.
Full API spec details can be found here: https://docs.masonhub.co/api/v1#tag/Callback-Events/paths/~1orderCancelResolution/post

This callback will act as the asynchronous response from the MasonHub API to your client to advise on whether order cancel requests succeed or fail. Any desired order cancelations are made in the form of a request, because after an order is submitted and has reached the distribution center, it is possible that it is in a state that it can no longer be canceled (think… it’s already in a box with a shipping label on it).

The orderCancelResolution callback provides an end state to that request, and advises to your client API whether or not that cancelation succeeded or not. Because of the asynchronous nature of this request/response dialog, it’s important that your client system keep track of which cancelations you’ve submitted to MasonHub, so that you have a record of any changes that are outstanding and may or may not succeed before the order gets shipped.

Let’s look at an example.

First, you’ll need to register for this callback like all other callbacks, specifying the url and (optionally) bearer token to which the callback events will be posted.

POST to https://sandbox.masonhub.co/{your-client-slug-here}/api/v1/callbacks with message_type = orderCancelResolution

{
  "url": "https://api.clienturl.com/api/orderCancelResolution",
  "message_type": "orderCancelResolution",
  "token": "long_token_string_goes_here"
}

Now MasonHub will know where to send the update resolutions. Say you now post an order cancel request with a POST to https://sandbox.masonhub.co/{your-client-slug-here}/api/v1/order_cancel_requests. MasonHub will respond with an update identifier:

{
    "records_submitted": 1,
    "records_processed": 1,
    "records_failed": 0,
    "records_succeeded": 1,
    "results": [
        {
            "system_id": "0b744e29-b668-4486-85dd-82528b5da0dd",
            "customer_identifier": "12345",
            "status": "success",
            "uri": "https://sandbox.masonhub.co/test/api/v1/order_cancel_requests?cid=12345"
        }
    ]
}

Note here that the presence of “status”: “success” refers to the fact that the MasonHub API successfully received the cancel request, not that it already took affect. The other thing you may want to keep track of is the system_id of the cancel request. That UUID will eventually be sent back on the order cancel request resolution callback, so you can reference exactly which cancel the callback is in reference to.

Eventually, MasonHub will send the orderCancelResolution callback. It will be posted to the url you registered in the callback, and the body will look something like this:

{
  "callback_url": "https://client.com/api/orderUpdateResolution",
  "message_type": "orderCancelResolution",
  "message_id": "0896116f-e54b-4756-9d3e-1b0c4a25d821",
  "data": [
    {
      "id": "0b744e29-b668-4486-85dd-82528b5da0dd",
      "customer_order_id": "12345",
      "status": "success",
      "created_at": "2018-08-05T17:32:28Z",
      "updated_at": "2018-08-05T17:32:28Z",
      "deleted_at": null
    }
  ]
}

You can see the id specified in the callback corresponds with the system_id that was returned on the initial cancel request. Once you receive this callback, you can process it on your side and consider the order successfully canceled, not to be fulfilled.

It is possible the cancel request will fail, and it will be noted as such on the callback:

{
  "callback_url": "https://client.com/api/orderUpdateResolution",
  "message_type": "orderCancelResolution",
  "message_id": "0896116f-e54b-4756-9d3e-1b0c4a25d821",
  "data": [
    {
      "id": "0b744e29-b668-4486-85dd-82528b5da0dd",
      "customer_order_id": "12345",
      "status": "failure",
      "reason": "Order already packed"
      "created_at": "2018-08-05T17:32:28Z",
      "updated_at": "2018-08-05T17:32:28Z",
      "deleted_at": null
    }
  ]
}

Cancel Order Update Data Factory

Along with the orderCancelResolutions, you can now trigger resolutions by posting to /data_factory/resolveOrderCancel. Full API documentation here: https://docs.masonhub.co/api/v1#tag/DataFactory/paths/~1data_factory~1resolveOrderCancel/post

A new endpoint has been added to the Data Factory so that you can trigger cancel resolutions at will. If we expand on the example above, suppose you just made a cancel request to an order, and the MasonHub API responded with the following:

{
    "records_submitted": 1,
    "records_processed": 1,
    "records_failed": 0,
    "records_succeeded": 1,
    "results": [
        {
            "system_id": "0b744e29-b668-4486-85dd-82528b5da0dd",
            "customer_identifier": "12345",
            "status": "success",
            "uri": "https://sandbox.masonhub.co/test/api/v1/order_cancel_requests?cid=12345"
        }
    ]
}

If you perform a GET on this particular cancel request, you’ll see it’ll be in ‘pending’ status:

GET to https://sandbox.masonhub.co/{your-client-slug-here}/api/v1/order_cancel_requests?cid=12345

{
    "limit": 1,
    "offset": 0,
    "list_type": "detail",
    "data": [
        {
            "id": "0b744e29-b668-4486-85dd-82528b5da0dd ",
            "customer_order_id": "12345",
            "status": "pending",
            "created_at": "2018-12-14T22:36:44.282713Z",
            "updated_at": "2018-12-14T22:36:44.282714Z",
            "deleted_at": null
        }
    ]
}

Using the new Data Factory resolveOrderCancel endpoint, you can tell the sandbox environment to resolve that cnacel to either a success or failure status:

POST to https://sandbox.masonhub.co/{your-client-slug-here}/api/v1/data_factory/resolveOrderCancel with body:

[
	{
		"order_cancel_request_id": "0b744e29-b668-4486-85dd-82528b5da0dd",
		"resolution": "success"
	}
]

As is probably expected, if you specify a resolution of “success”, the information in the order cancel request will now persist on the order, and will be show a status of ‘canceled’ when you do a GET for the order information. This will also kick off the orderCancelResolution callback message to your API. Alternatively, you can set a resolution of “failure”, and the cancel will fail, and you will receive an orderCancelResolution callback message notifying your system of the unsuccessful request.


As always, don’t be afraid to reach out to Chris or Andy with any questions.