SuperAPI AI Directory

shopify-admin-refund-and-reorder

Office & productivity

View repository

Updated 10-15 09:36

About this skill

Purpose

Processes refunds and creates replacement orders without navigating the Shopify admin UI. This skill handles both the refund and the optional replacement draft order in a single workflow.

Prerequisites

  • Authenticated Shopify CLI session: shopify auth login --store <domain>
  • API scopes: read_orders, write_orders

Parameters

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)
refund_line_items array no all refundable Array of {line_item_id, quantity} to refund; if omitted, refunds all refundable quantities
reason string no other Refund reason: customer, fraud, inventory, declined, other
create_replacement bool no false If true, create a draft order with the same line items after refund
notify_customer bool no true Send refund notification email to customer

Safety

⚠️ Steps 2 and 3 execute irreversible financial mutations. refundCreate cannot be undone — once a refund is processed, the payment cannot be re-captured. draftOrderCreate creates a new draft order that must be invoiced and paid separately. Run with dry_run: true to verify the refund line items and amounts before committing. Verify refundableQuantity per line item from Step 1 before proceeding.

Workflow Steps

  1. OPERATION: order — query Inputs: id: <order_id> Expected output: Full order with displayFinancialStatus, lineItems (with refundableQuantity), transactions, customer, shippingAddress; verify order is refundable before proceeding

  2. OPERATION: refundCreate — mutation Inputs: input.orderId, input.refundLineItems (from parameter or all refundable), input.notify, input.note: <reason> Expected output: refund.id, refund.totalRefundedSet, userErrors

  3. OPERATION: draftOrderCreate — mutation (only if create_replacement: true) Inputs: input.lineItems (from original order line items), input.customerId, input.shippingAddress, input.note: "Replacement for order <name>" Expected output: draftOrder.id, draftOrder.name, draftOrder.invoiceUrl, userErrors

GraphQL Operations

# order:query — validated against api_version 2025-01
query OrderForRefund($id: ID!) {
  order(id: $id) {
    id
    name
    displayFinancialStatus
    displayFulfillmentStatus
    totalPriceSet {
      shopMoney { amount currencyCode }
    }
    lineItems(first: 50) {
      edges {
        node {
          id
          title
          quantity
          refundableQuantity
          variant {
            id
            sku
            price
          }
        }
      }
    }
    transactions(first: 10) {
      id
      kind
      status
      amountSet {
        shopMoney { amount currencyCode }
      }
      gateway
    }
    refunds {
      id
      createdAt
      totalRefundedSet {
        shopMoney { amount currencyCode }
      }
    }
    customer {
      id
      defaultEmailAddress {
        emailAddress
      }
      firstName
      lastName
    }
    shippingAddress {
      address1
      city
      province
      country
      zip
    }
  }
}
# refundCreate:mutation — validated against api_version 2025-01
mutation RefundCreate($input: RefundInput!) {
  refundCreate(input: $input) {
    refund {
      id
      createdAt
      totalRefundedSet {
        shopMoney { amount currencyCode }
      }
    }
    userErrors {
      field
      message
    }
  }
}
# draftOrderCreate:mutation — validated against api_version 2025-01
mutation DraftOrderCreate($input: DraftOrderInput!) {
  draftOrderCreate(input: $input) {
    draftOrder {
      id
      name
      invoiceUrl
    }
    userErrors {
      field
      message
    }
  }
}

Session Tracking

Claude MUST emit the following output at each stage. This is mandatory.

On start, emit:

╔══════════════════════════════════════════════╗
║  SKILL: refund-and-reorder                   ║
║  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>
  Refund ID:           <id>
  Amount refunded:     <amount> <currency>
  Replacement draft:   <draft order name or "none">
  Errors:              0
  Output:              none
══════════════════════════════════════════════

For format: json, emit:

{
  "skill": "refund-and-reorder",
  "store": "<domain>",
  "started_at": "<ISO8601>",
  "completed_at": "<ISO8601>",
  "dry_run": false,
  "steps": [
    { "step": 1, "operation": "OrderForRefund", "type": "query", "params_summary": "order <id>", "result_summary": "<status>", "skipped": false },
    { "step": 2, "operation": "RefundCreate", "type": "mutation", "params_summary": "<n> line items, reason: <reason>", "result_summary": "refund <id>", "skipped": false },
    { "step": 3, "operation": "DraftOrderCreate", "type": "mutation", "params_summary": "<n> line items, customer <id>", "result_summary": "draft <name>", "skipped": false }
  ],
  "outcome": {
    "order_name": "<name>",
    "refund_id": "<id>",
    "amount_refunded": "<amount>",
    "currency": "<currency>",
    "draft_order_name": "<name or null>",
    "draft_order_invoice_url": "<url or null>",
    "errors": 0,
    "output_file": null
  }
}

Output Format

No CSV output. The session completion summary reports the refund ID and amount. If create_replacement: true, the draft order name and invoice URL are included in the output.

Error Handling

Error Cause Recovery
refundableQuantity is 0 Line item already fully refunded Check order refund history
userErrors from refundCreate Invalid refund amounts or order not refundable Check displayFinancialStatus — must not be REFUNDED
userErrors from draftOrderCreate Invalid line items or customer Verify product variants still exist
Order not found Invalid order GID Use order-lookup-and-summary skill to find the correct order ID

Best Practices

  1. Always run dry_run: true first — Step 2 is irreversible. Verify refundableQuantity per line item in Step 1 output before committing.
  2. For partial refunds, specify refund_line_items explicitly — omitting it refunds all refundable items, which may not be intended.
  3. The create_replacement draft order is not automatically invoiced or fulfilled — share invoiceUrl with the customer for payment.
  4. Use notify_customer: false for internal corrections where the customer should not be alerted.
  5. Check displayFinancialStatus from Step 1 — if it is REFUNDED, there is nothing left to refund.