Commerce · MCP
Order tools
Confirm an offline payment, cancel an unpaid order, add internal notes and record shipments with tracking, without moving money.
Overview
Five tools let a client work an order the way staff do on the order page, without ever moving money. They need commerce.write.orders (with commerce.read), issued as the edit permission Orders (Bestellingen) in Settings > API tokens, and exist since server version 1.5.0. They are also REST endpoints with the same payload. Each runs the staff action behind the order page, under the order's row lock, and the order's activity trail names the token.
| Tool | Scope | Purpose |
|---|---|---|
confirm_offline_payment |
commerce.write.orders |
Record that an unpaid order was paid outside the payment provider. |
cancel_unpaid_order |
commerce.write.orders |
Cancel an unpaid draft order and release its stock. |
add_order_note |
commerce.write.orders |
Add an internal note for staff. |
add_shipment |
commerce.write.orders |
Record a shipment with track and trace. |
update_shipment_tracking |
commerce.write.orders |
Correct the carrier or tracking of a shipment. |
No refunds, no paid cancellations, no customer data
No tool refunds money or cancels a paid order. The scope gives no customer details: internal notes (get_order internal_notes) and tracking codes are only returned with commerce.read.pii. Notes are free text that may describe the customer; they are never written to the change log (it keeps the note id). See Scopes and masking.
confirm_offline_payment
Input: the order id. Records that the full amount of an unpaid draft order (status awaiting-payment) was received outside the payment provider. The order is placed (status payment-offline), its stock is committed and, after the commit, the customer gets the order confirmation and the shop its notification. The order's activity trail names the token as approver.
- An order this already confirmed:
changed: false, no second mail. - Any other order (paid through the provider, cancelled, held for payment review) is
conflict. So is a draft whose online payment is still open at the provider. Staff in the admin may still confirm a bank transfer next to an abandoned online attempt; a token may not. - The tool is advertised with
openWorldHint: true, because it sends e-mail.
cancel_unpaid_order
Inputs: id and reason (customer_request, payment_not_received, duplicate_order, suspected_fraud or other). Cancels an unpaid draft order and releases its stock hold. Destructive: it cannot be undone.
- An already cancelled order:
changed: false. - A draft held for payment review (money may have arrived: settle it on the order page), a draft whose online payment is still open, and a placed or paid order are
conflict. Staff in the admin are refused the reviewed draft too, but may still cancel a draft with an open online payment.
Output of both tools: id, reference, fulfilment_state, status, placed_at, payment_state, changed, changes (status).
add_order_note
Inputs: id and body (up to 2000 characters). Adds an internal note for staff. It is stored as the text that was sent: never interpreted as HTML (angle brackets stay, every view escapes them), control characters removed, line breaks kept. Shown on the order's activity trail with the token id and a snapshot of its name; never to the customer and never in a customer mail. It is not the customer's own checkout note.
- Not idempotent: every call adds a note. An empty note is
invalid_argument. - Output:
order(id,reference,fulfilment_state),note(id,body,author,author_typetoken,created_at),changed(true),changes. - Read notes back with
get_order; that needscommerce.read.pii. - Notes are part of a data-subject access export and are deleted when the customer's data is erased.
add_shipment
| Name | Type | Required | Description |
|---|---|---|---|
id |
integer | Required | The order id. |
idempotency_key |
string | Required | 1 to 64 of A-Z a-z 0-9 . _ : -. The same key with the same carrier, tracking code and lines: changed: false, no second mail. With other data or on another order: conflict. |
carrier |
string | Required | A plain carrier name. |
tracking_code |
string | Optional | A plain code. Leave it out for letter post without track and trace. |
tracking_url |
string | Optional | https only, at most 500 characters, only together with a tracking_code. |
shipped_at |
string | Optional | ISO 8601 with an offset, not in the future, not before the order was placed. Default now. |
lines |
array | Optional | [{line_id, quantity}], physical lines of this order, each once. Omitted: everything still to ship. |
notify_customer |
boolean | Optional | Default true: the customer gets the shipping mail after the commit. false records it silently. |
- The order must be paid in full and not cancelled, held for review or fully refunded, and a quantity may be at most what is left to ship (
conflictotherwise). - The shipment names no staff member; the order's activity trail names the token.
- The tool is advertised with
openWorldHint: true, because it e-mails the customer.
update_shipment_tracking
Inputs: id, shipment_id and at least one of carrier, tracking_code, tracking_url (https; null removes it). It changes only those fields: status, lines and dates stay, no mail is sent. Equal values: changed: false. A shipment of another order is not_found; a cancelled shipment, or one created through a carrier integration (the carrier owns its tracking), is conflict. The shipment_id is fulfilment.shipments[].id of get_order.
Output of both shipment tools: order, shipment (id, carrier, tracking_code, tracking_url, status, shipped_at, notify_customer, lines), changed, changes. tracking_code and tracking_url are null without commerce.read.pii. The change log keeps a fingerprint (sha256:...) of a changed code or link, never the value.
Errors
invalid_argument: an empty note, anhttptracking link, a tracking link without a tracking code, a reason that is not in the list, or no field to change.not_found: an unknown order, or a shipment of another order.conflict: the order is not in a state the action allows; anidempotency_keyused with other data; a quantity above what is left.- The general write errors apply: see errors of the write tools.