From shopify-admin-skills
Cancels unfulfilled Shopify orders with optional inventory restock, payment refund, and customer notification via validated GraphQL workflow. For fraud handling, out-of-stock, or customer-requested cancellations.
npx claudepluginhub 40rty-ai/shopify-admin-skills --plugin shopify-admin-skillsThis skill uses the workspace's default tool permissions.
Cancels an unfulfilled or partially-unfulfilled order with configurable restock, refund, and customer notification options — without navigating the Shopify admin. Useful for fraud exception handling, out-of-stock cancellations, or customer-requested cancellations before dispatch. Cannot cancel orders that are already fully fulfilled.
Processes full or partial refunds on Shopify orders via GraphQL mutations and optionally creates replacement draft orders. Useful for customer support workflows bypassing admin UI.
Guides Shopify order management via GraphQL: lifecycle, FulfillmentOrder, returns/refunds, draft orders, editing, transactions, metafields, risk analysis.
Manages Shopify orders, customers, and fulfillments via GraphQL Admin API. Query orders, process fulfillments, handle customer records, create draft orders.
Share bugs, ideas, or general feedback.
Cancels an unfulfilled or partially-unfulfilled order with configurable restock, refund, and customer notification options — without navigating the Shopify admin. Useful for fraud exception handling, out-of-stock cancellations, or customer-requested cancellations before dispatch. Cannot cancel orders that are already fully fulfilled.
shopify auth login --store <domain>read_orders, write_orders| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| store | string | yes | — | Store domain (e.g., mystore.myshopify.com) |
| format | string | no | human | Output format: human or json |
| dry_run | bool | no | false | Preview operations without executing mutations |
| order_id | string | yes | — | GID of the order (e.g., gid://shopify/Order/12345) |
| reason | string | no | OTHER | Cancel reason: CUSTOMER, DECLINED, FRAUD, INVENTORY, STAFF, OTHER |
| restock | bool | no | true | Restock inventory for cancelled line items |
| refund | bool | no | true | Issue refund for any captured payments |
| notify_customer | bool | no | true | Send cancellation email to customer |
| staff_note | string | no | — | Internal note recorded on the cancellation |
⚠️ Steps 2 executes
orderCancelwhich is irreversible. A cancelled order cannot be reopened. Ifrefund: true, any captured payment is automatically refunded. Ifrestock: true, inventory quantities are immediately restored. Run withdry_run: trueto verify the order state and confirm it is cancellable before committing.
OPERATION: order — query
Inputs: id: <order_id>
Expected output: Order name, displayFulfillmentStatus, displayFinancialStatus, cancelledAt (must be null), fulfillmentOrders.status (must be OPEN or ON_HOLD — abort if any fulfillment order is IN_PROGRESS or CLOSED)
OPERATION: orderCancel — mutation
Inputs: orderId, reason, restock, refund, notifyCustomer, staffNote
Expected output: orderCancelUserErrors — empty on success; order is now cancelled with cancelledAt timestamp
# order:query — validated against api_version 2025-01
query OrderForCancel($id: ID!) {
order(id: $id) {
id
name
displayFulfillmentStatus
displayFinancialStatus
cancelledAt
totalPriceSet {
shopMoney { amount currencyCode }
}
lineItems(first: 50) {
edges {
node {
id
title
quantity
variant {
id
sku
inventoryQuantity
}
}
}
}
fulfillmentOrders(first: 5) {
edges {
node {
id
status
}
}
}
customer {
id
defaultEmailAddress {
emailAddress
}
firstName
lastName
}
}
}
# orderCancel:mutation — validated against api_version 2025-01
mutation OrderCancel(
$orderId: ID!
$reason: OrderCancelReason!
$restock: Boolean!
$refund: Boolean!
$notifyCustomer: Boolean!
$staffNote: String
) {
orderCancel(
orderId: $orderId
reason: $reason
restock: $restock
refund: $refund
notifyCustomer: $notifyCustomer
staffNote: $staffNote
) {
orderCancelUserErrors {
field
message
}
userErrors {
field
message
}
}
}
Claude MUST emit the following output at each stage. This is mandatory.
On start, emit:
╔══════════════════════════════════════════════╗
║ SKILL: cancel-and-restock ║
║ Store: <store domain> ║
║ Started: <YYYY-MM-DD HH:MM UTC> ║
╚══════════════════════════════════════════════╝
After each step, emit:
[N/TOTAL] <QUERY|MUTATION> <OperationName>
→ Params: <brief summary of key inputs>
→ Result: <count or outcome>
If dry_run: true, prefix every mutation step with [DRY RUN] and do not execute it.
On completion, emit:
For format: human (default):
══════════════════════════════════════════════
OUTCOME SUMMARY
Order: <name>
Cancellation reason: <reason>
Restocked: <true|false>
Refund issued: <true|false>
Customer notified: <true|false>
Errors: 0
Output: none
══════════════════════════════════════════════
For format: json, emit:
{
"skill": "cancel-and-restock",
"store": "<domain>",
"started_at": "<ISO8601>",
"completed_at": "<ISO8601>",
"dry_run": false,
"steps": [
{ "step": 1, "operation": "OrderForCancel", "type": "query", "params_summary": "order <id>", "result_summary": "<status>", "skipped": false },
{ "step": 2, "operation": "OrderCancel", "type": "mutation", "params_summary": "reason: <reason>, restock: <bool>, refund: <bool>, notifyCustomer: <bool>", "result_summary": "cancelled at <timestamp>", "skipped": false }
],
"outcome": {
"order_name": "<name>",
"reason": "<reason>",
"restocked": true,
"refund_issued": true,
"customer_notified": true,
"errors": 0,
"output_file": null
}
}
No CSV output. The session summary reports the cancellation result inline. If restock: true, list the variant SKUs and quantities restored.
| Error | Cause | Recovery |
|---|---|---|
cancelledAt is not null | Order is already cancelled | No action needed |
Fulfillment order status: IN_PROGRESS | Order is being picked/packed | Contact warehouse to stop — cannot cancel programmatically once IN_PROGRESS |
orderCancelUserErrors | Order has already been fully fulfilled | Use refund-and-reorder skill instead |
| Order not found | Invalid order GID | Use order-lookup-and-summary skill to find the correct ID |
dry_run: true first — check displayFulfillmentStatus and fulfillment order statuses before committing to a cancel.reason: FRAUD for high-risk orders — this reason is logged in Shopify's fraud analytics.PAID), set refund: true — an uncredited cancellation will cause customer disputes.format: json to capture each result for audit logging.