This guide shows you how to consume OrderActionEvent for the order actions Mirakl Connect requests, which are to accept, ship, cancel, and refund an order, and to upload a document. You perform each action on the sales channel, and you report its outcome so that Mirakl Connect knows the action is done.
Some things happen to an order because a seller decided so inside Mirakl Connect, not because the channel changed. To accept a new order, to book its shipment, to cancel a line, and to issue a refund all start in Connect.
Mirakl Connect turns each decision into an OrderActionEvent and sends it to your connector to carry out on the channel. Your connector is what makes the seller's decision real on the channel, and its report back is what tells Mirakl Connect that the decision took effect.
Handle an OrderActionEvent whenever one arrives with a type on the order side: ACCEPT, CREATE_SHIPMENT, CANCEL, REFUND, or UPLOAD_DOCUMENT.
Returns covers the actions on the return side, which are ACCEPT_RETURN, UPDATE_RETURN_TRACKING_INFORMATION, ACKNOWLEDGE_RETURN_RECEPTION, and CLOSE_RETURN. Their mechanics are the same.
This guide is distinct from Sync orders into Connect. There, you report the state the channel produced. Here, you perform an action Mirakl Connect requested, and then you report both its outcome and the resulting state.
Every event arrives in the shared envelope, with an id, which is a ULID, a time, a type, and a data body. Deduplicate on the id, so that a repeat delivery does nothing twice. Persist the data.action_id, because it is how you report the outcome, and it must survive a restart.
The type names the action and selects the shape of data. The set of type values can grow, so plan for a value you do not know yet:
- Map each action to the closest action on the channel, and keep that mapping as accurate as you can.
- Report
FAILEDwithACTION_NOT_SUPPORTEDonly when the channel offers no action for thetype. - Report an outcome for every action you receive, so that no action stays pending.
The data of each order action carries the identifiers, which are action_id, channel_id, channel_store_id, and channel_order_id, plus what the action needs. It also carries the sub_channel_code when the order belongs to a sub-channel (read Naming the sub-channel of an order).
ACCEPT accepts or refuses the order's lines:
{
"type": "ACCEPT",
"data": {
"action_id": "1ba5fc4b-c4fd-4251-880b-3052e301bbd4",
"channel_id": "0024",
"channel_store_id": "2005",
"channel_order_id": "0024_COMMERCIAL_ID-A",
"order_lines": [
{ "channel_order_line_id": "0024_COMMERCIAL_ID-A-1", "accepted": true }
]
}
}CREATE_SHIPMENT ships the order, or a set of its lines, with a carrier. The carrier is optional, and it holds the display name of the carrier, not the channel_carrier_id you sent to upsertCarriers. warehouse_id is required only when the channel needs it:
{
"type": "CREATE_SHIPMENT",
"data": {
"action_id": "2cb6fd5c-d5fe-4362-991c-4163f412cce5",
"channel_id": "0024",
"channel_store_id": "2005",
"channel_order_id": "0024_COMMERCIAL_ID-A",
"carrier": "DHL Express",
"tracking_number": "1Z999AA1234567890",
"tracking_url": "https://tracking.carrier.com/123456",
"items": [
{ "channel_order_line_id": "0024_COMMERCIAL_ID-A-1", "id": "SELLER_ID_1", "quantity": 2 }
]
}
}When the channel requires a carrier and the event carries none, either send a default value the channel accepts, or report FAILED with MISSING_CARRIER.
CANCEL and REFUND carry the affected lines, in cancelations and in refunds. Each line carries a quantity, a reason, and the price and the shipping_price to cancel or refund, tax excluded, with taxes and shipping_taxes listed separately:
{
"type": "REFUND",
"data": {
"action_id": "3dc7fe6d-e60f-4473-aa2d-5274051523f6",
"channel_id": "0024",
"channel_store_id": "2005",
"channel_order_id": "0024_COMMERCIAL_ID-A",
"refunds": [
{
"channel_order_line_id": "0024_COMMERCIAL_ID-A-1",
"product_id": "SELLER_ID_1",
"quantity": 1,
"reason": "DEFECT",
"price": { "amount": 24.99, "currency": "EUR" },
"shipping_price": { "amount": 0, "currency": "EUR" }
}
]
}
}UPLOAD_DOCUMENT provides a document for you to place on the channel. Mirakl Connect gives a document_name, a document_type, which is RETURN_LABEL or CUSTOMER_INVOICE, and a document_download_url, which is a presigned link that expires. When the document belongs to a return, document_entity names that return, with type: RETURN and the channel_return_id as its id:
{
"type": "UPLOAD_DOCUMENT",
"data": {
"action_id": "4ed8af7e-f710-4584-bb3e-6385162634a7",
"channel_id": "0024",
"channel_store_id": "2005",
"channel_order_id": "0024_COMMERCIAL_ID-A",
"document_name": "return_label_RET-0024-001.pdf",
"document_type": "RETURN_LABEL",
"document_download_url": "https://storage.example.com/documents/4f690afa-6543-4f4b-a89f-81934e65ddd5?expires=1787059200&signature=247a2aa45f169edf4d187d54e7cc46e4",
"document_entity": { "type": "RETURN", "id": "RET-0024-001" }
}
}Download the document from document_download_url before the link expires, then upload it to the channel. A document that belongs to the order itself, and not to a return, carries no document_entity.
Carry the action out through the channel's own API. Guard it so that a repeat is safe: if Mirakl Connect delivers the same event twice, the channel operation must not happen twice, so no double shipment and no double refund. Tie the channel operation to the stored action_id, so that you can tell an action you already performed from a new one.
Report the final result once, when the action is complete, with PUT /v1/orders/actions/{action_id}.
On success:
{ "status": "SUCCESS" }On failure, send FAILED with one or more ActionError entries. Map the channel's refusal to the code that matches, and put the specifics in the message. The code is a bounded set:
INVALID_INPUT: the action carries data the channel refuses.DATA_NOT_FOUND: the order, the line, or the return the action names does not exist on the channel.UNEXPECTED: the channel failed for a reason your connector cannot classify.UNAVAILABLE: the channel was unreachable.TOO_MANY_REQUEST: the channel throttled the call.ACTION_NOT_SUPPORTED: the channel offers no action for thistype.ORDER_IN_WRONG_STATE: the order's state on the channel does not allow the action.RETURN_IN_WRONG_STATE: the return's state on the channel does not allow the action.CARRIER_NOT_SUPPORTED: the channel does not accept thecarrierof the action.MISSING_CARRIER: the channel requires a carrier, and the action carries none.WAREHOUSE_ID_NOT_FOUND: the channel does not know thewarehouse_id.WAREHOUSE_ID_REQUIRED: the channel requires awarehouse_id, and the action carries none.OTHER: none of the codes above fits.
{
"status": "FAILED",
"errors": [
{ "code": "ORDER_IN_WRONG_STATE", "message": "Cannot ship: order is already cancelled" }
]
}Three responses matter:
204confirms the report.400withACTION_ALREADY_FINALmeans that you already reported the action. Treat it as a benign confirmation, not as an error to retry around.404means that theaction_idis unknown, because it is incorrect, or because the order it belongs to was deleted. An action never expires. Mirakl Connect deletes it with its order, when the seller unlinks the store or when the order's retention period ends.
Reporting the outcome of an action does not update the status of the order. After an action changes the order's state, push the order's new state with upsertOrders. The action is not fully handled until you have reported both the outcome and the new state.
- To never report
FAILED. An action with no reported outcome hangs, and Mirakl Connect waits forever. Report the result of every action, whether it succeeded or failed. - To lose or reuse the
action_id. You must report the outcome against the exactaction_idfrom the event. Persist it on receipt. Without it, you cannot close the action, and a duplicate event can drive the channel operation twice. - To acknowledge the delivery instead of the action. To acknowledge the message on the queue confirms receipt only. It does not report the outcome.
updateActionStatusdoes that, sent once the action is really done. - To report the outcome but not re-sync.
updateActionStatusdoes not carry the order's new status. Follow an action that changes the state withupsertOrders, or the copy of the order in Connect drifts from the channel. - To collapse every failure into
OTHER. Thecodeis what Mirakl Connect and the seller act on. Map the failure to the specificActionError, such asORDER_IN_WRONG_STATE,MISSING_CARRIER, orWAREHOUSE_ID_REQUIRED, and reserveOTHERfor the failures that genuinely fit none of them.
- Sync orders into Connect: how to report the order state that an action produces.
- Returns: the actions on the return side, handled the same way.
- Orders: the order actions in context.