| name | magento-fulfillment |
| description | Manage Magento order fulfillment documents via admin REST API. Covers invoices (search, get, create), shipments (search, get, create), credit memos, order email, and returns/RMA. Requires MAGENTO_ADMIN_TOKEN. |
| argument-hint | [invoice/shipment/creditmemo/return + order id or increment id] |
| allowed-tools | Bash(curl:*), Bash(echo:*), Bash(jq:*) |
| effort | high |
Magento Fulfillment Documents (REST)
Covers the post-placement order lifecycle: invoices → shipments → credit memos → returns.
Configuration
- Base:
${MAGENTO_BASE_URL}/rest/${MAGENTO_STORE_CODE:-default}/V1/
- Auth:
Authorization: Bearer ${MAGENTO_ADMIN_TOKEN}
Operation 1: Search Invoices
curl -s -g "${MAGENTO_BASE_URL}/rest/${MAGENTO_STORE_CODE:-default}/V1/invoices?searchCriteria[filterGroups][0][filters][0][field]=order_id&searchCriteria[filterGroups][0][filters][0][value]=${ORDER_ENTITY_ID}&searchCriteria[filterGroups][0][filters][0][conditionType]=eq" \
-H "Authorization: Bearer ${MAGENTO_ADMIN_TOKEN}" \
-H "Content-Type: application/json"
Common filters:
| What | Field | Condition |
|---|
| By order entity_id | order_id | eq |
| By invoice state | state | eq (1=pending, 2=paid, 3=canceled) |
| Date range | created_at | from/to |
Extract: increment_id, order_id, state, grand_total, created_at, items[].sku, items[].name, items[].qty
Operation 2: Get Invoice by ID
curl -s "${MAGENTO_BASE_URL}/rest/${MAGENTO_STORE_CODE:-default}/V1/invoices/${INVOICE_ID}" \
-H "Authorization: Bearer ${MAGENTO_ADMIN_TOKEN}" \
-H "Content-Type: application/json"
Operation 3: Create Invoice (Write — Confirm First)
Confirm: "I'll create an invoice for order #XXXXXX. This will capture payment. Confirm? (yes/no)"
Creates an invoice for the entire order (all items, all qty):
curl -s -X POST "${MAGENTO_BASE_URL}/rest/${MAGENTO_STORE_CODE:-default}/V1/order/${ORDER_ENTITY_ID}/invoice" \
-H "Authorization: Bearer ${MAGENTO_ADMIN_TOKEN}" \
-H "Content-Type: application/json" \
-d '{"capture": false, "notify": false}'
capture: true — attempt online payment capture (requires online payment method)
capture: false — offline invoice only
notify: true — send invoice email to customer
To invoice only specific items, include items array:
-d '{"capture": false, "notify": false, "items": [{"order_item_id": 5, "qty": 1}]}'
Response is the new invoice ID (integer) on success.
Operation 4: Search Shipments
curl -s -g "${MAGENTO_BASE_URL}/rest/${MAGENTO_STORE_CODE:-default}/V1/shipments?searchCriteria[filterGroups][0][filters][0][field]=order_id&searchCriteria[filterGroups][0][filters][0][value]=${ORDER_ENTITY_ID}&searchCriteria[filterGroups][0][filters][0][conditionType]=eq" \
-H "Authorization: Bearer ${MAGENTO_ADMIN_TOKEN}" \
-H "Content-Type: application/json"
Extract: increment_id, order_id, created_at, items[].sku, items[].qty, tracks[].track_number, tracks[].title (carrier), tracks[].carrier_code
Operation 5: Get Shipment by ID
curl -s "${MAGENTO_BASE_URL}/rest/${MAGENTO_STORE_CODE:-default}/V1/shipments/${SHIPMENT_ID}" \
-H "Authorization: Bearer ${MAGENTO_ADMIN_TOKEN}" \
-H "Content-Type: application/json"
Operation 6: Create Shipment (Write — Confirm First)
IMPORTANT: Always use POST /V1/order/{orderId}/ship, NOT POST /V1/shipment. The /V1/shipment endpoint can create duplicate shipments if called multiple times; the order-scoped endpoint validates against order state.
Confirm: "I'll create a shipment for order #XXXXXX with tracking [carrier: number]. Confirm? (yes/no)"
curl -s -X POST "${MAGENTO_BASE_URL}/rest/${MAGENTO_STORE_CODE:-default}/V1/order/${ORDER_ENTITY_ID}/ship" \
-H "Authorization: Bearer ${MAGENTO_ADMIN_TOKEN}" \
-H "Content-Type: application/json" \
-d '{
"notify": true,
"tracks": [
{
"track_number": "1Z999AA10123456784",
"title": "UPS",
"carrier_code": "ups"
}
]
}'
Common carrier_code values: ups, fedex, usps, dhl, custom.
To ship without tracking: omit the tracks array or pass "tracks": [].
To ship specific items: add "items": [{"order_item_id": 5, "qty": 1}].
Response is the new shipment ID on success.
Operation 7: Search Credit Memos
curl -s -g "${MAGENTO_BASE_URL}/rest/${MAGENTO_STORE_CODE:-default}/V1/creditmemos?searchCriteria[filterGroups][0][filters][0][field]=order_id&searchCriteria[filterGroups][0][filters][0][value]=${ORDER_ENTITY_ID}&searchCriteria[filterGroups][0][filters][0][conditionType]=eq" \
-H "Authorization: Bearer ${MAGENTO_ADMIN_TOKEN}" \
-H "Content-Type: application/json"
Extract: increment_id, order_id, state, grand_total, created_at, items[].sku, items[].qty, items[].row_total
Operation 8: Get Credit Memo by ID
curl -s "${MAGENTO_BASE_URL}/rest/${MAGENTO_STORE_CODE:-default}/V1/creditmemos/${CREDITMEMO_ID}" \
-H "Authorization: Bearer ${MAGENTO_ADMIN_TOKEN}" \
-H "Content-Type: application/json"
Note: Do NOT expose refund creation as an agent action. Magento has documented race conditions producing duplicate credit memos. Refunds must be initiated from the Admin UI.
Operation 9: Send Order Email (Write — Confirm First)
Confirm: "I'll send the order confirmation email for order #XXXXXX to the customer. Confirm? (yes/no)"
curl -s -X POST "${MAGENTO_BASE_URL}/rest/${MAGENTO_STORE_CODE:-default}/V1/orders/${ORDER_ENTITY_ID}/emails" \
-H "Authorization: Bearer ${MAGENTO_ADMIN_TOKEN}" \
-H "Content-Type: application/json"
Response is true on success.
Operation 10: Search Returns (RMA)
Returns are available on Magento Open Source 2.3+. If the endpoint returns 404, the RMA module may not be enabled.
curl -s -g "${MAGENTO_BASE_URL}/rest/${MAGENTO_STORE_CODE:-default}/V1/returns?searchCriteria[filterGroups][0][filters][0][field]=order_id&searchCriteria[filterGroups][0][filters][0][value]=${ORDER_ENTITY_ID}&searchCriteria[filterGroups][0][filters][0][conditionType]=eq&searchCriteria[pageSize]=10" \
-H "Authorization: Bearer ${MAGENTO_ADMIN_TOKEN}" \
-H "Content-Type: application/json"
Extract: entity_id, increment_id, order_id, status, created_at, items[].sku, items[].qty_requested, items[].reason
Operation 11: Get Return by ID
Full return detail:
curl -s "${MAGENTO_BASE_URL}/rest/${MAGENTO_STORE_CODE:-default}/V1/returns/${RETURN_ID}" \
-H "Authorization: Bearer ${MAGENTO_ADMIN_TOKEN}" \
-H "Content-Type: application/json"
Return shipping labels (if generated):
curl -s "${MAGENTO_BASE_URL}/rest/${MAGENTO_STORE_CODE:-default}/V1/returns/${RETURN_ID}/labels" \
-H "Authorization: Bearer ${MAGENTO_ADMIN_TOKEN}" \
-H "Content-Type: application/json"
Response Formatting
PII note: Fulfillment documents include customer addresses and emails. When displaying to support agents, mask emails (r***@e***.com), show street addresses as "[REDACTED]", and phone numbers as last 4 digits only (***-1234). Show city + state/country for context.
Invoice list:
Invoice #000000001 | paid | $36.39 | 2024-01-15
Items: Iris Workout Top (WS03-XS-Red) × 1
Shipment list:
Shipment #000000001 | 2024-01-16
Tracking: UPS 1Z999AA10123456784
Items: Iris Workout Top × 1
Credit memo:
Credit Memo #000000001 | refunded $36.39 | 2024-01-20
Items: Iris Workout Top × 1 | $29.00
Shipping refund: $5.00 | Tax refund: $2.39
Error Handling
"Cannot create invoice" / HTTP 400: Order may already be fully invoiced, or status doesn't allow it. Show the error.
"Cannot ship order" etc.: Order not in shippable state (check if invoice exists first for some payment methods).
- HTTP 404 on
/returns: RMA module may not be enabled on this store.
- Duplicate shipment concern: Always use
/order/{id}/ship not /shipment.
Decision Table
| User says | Action |
|---|
| "invoices for order 123" | Search invoices by order_id |
| "create invoice for order 123" | Confirm → POST /order/123/invoice |
| "has order 123 shipped?" | Search shipments by order_id |
| "create shipment with UPS tracking XYZ" | Confirm → POST /order/123/ship |
| "refund for order 123" | Search credit memos — DO NOT create via API |
| "send confirmation email for order 123" | Confirm → POST /orders/123/emails |
| "return request for order 123" | Search returns by order_id |
User Request
$ARGUMENTS