Now liveThe Skillselion MCP - thousands of ranked skills, loaded into your agent mid-task. No install.Get it →
40rty-ai avatar

Shopify Admin Return Cost Attribution

  • 2 installs
  • 173 repo stars
  • Updated June 26, 2026
  • 40rty-ai/shopify-admin-skills

shopify-admin-return-cost-attribution is a Claude Code skill that calculates the true cost of Shopify returns by reason and product, combining refunds, lost shipping, COGS write-offs, and restocking labor.

About

This skill quantifies the full cost of Shopify returns over a window, not just the refunded amount. It combines refund totals, lost shipping revenue, COGS for non-restockable items, and restocking labor into a per-reason and per-product return P&L. Merchants use it to decide which return reasons or product lines deserve fixes like better packaging, size guides, or listing accuracy. It is read-only.

  • Calculates the true cost of returns by reason and product, combining refund dollars, lost shipping, COGS write-offs, and
  • Read-only against the Shopify Admin GraphQL returns, orders, and inventoryItems queries
  • Builds a per-reason and per-product return P&L to prioritize operational fixes

Shopify Admin Return Cost Attribution by the numbers

  • 2 all-time installs (skills.sh)
  • Ranked #870 of 1,106 Finance & Trading skills by installs in the Skillselion catalog
  • Data as of Aug 1, 2026 (Skillselion catalog sync)
At a glance

shopify-admin-return-cost-attribution capabilities & compatibility

Free; requires an authenticated Shopify store session with read_orders, read_returns, and read_inventory scopes

Capabilities
return cost analysis · returns analytics · cogs analysis · data analysis
Works with
github
Use cases
data analysis
Pricing
Free
From the docs

What shopify-admin-return-cost-attribution says it does

calculates the true cost of returns by reason and product — refund dollars, restocking impact, shipping cost lost, and COGS impact for items written off.
SKILL.md
Combines refund totals, lost shipping revenue, COGS for non-restockable items (e.g., `DEFECTIVE`), and restocking labor into a per-reason and per-product return P&L.
SKILL.md
npx skills add https://github.com/40rty-ai/shopify-admin-skills --skill shopify-admin-return-cost-attribution

Add your badge

Show developers this skill is listed on Skillselion. Paste this into your README.

Listed on Skillselion
Installs2
repo stars173
Last updatedJune 26, 2026
Repository40rty-ai/shopify-admin-skills

What it does

Calculate the true cost of Shopify returns by reason and product, combining refunds, lost shipping, COGS write-offs, and restocking labor.

Who is it for?

Prioritizing which return reasons or product lines deserve operational fixes based on true cost

Skip if: Treating outputs as accounting truth without first calibrating the flat restocking-cost figure

When should I use this skill?

You want the full cost of returns, not just refund dollars, broken down by reason and product

What you get

A per-reason and per-product return P&L combining all cost components.

  • Per-reason and per-product return cost P&L report

By the numbers

  • 3 GraphQL query operations (returns, orders, inventoryItems)
  • Default lookback window of 90 days
  • Default flat restocking cost of $5.00 per line item

Files

SKILL.mdMarkdownGitHub ↗

Purpose

Quantifies the full cost of returns over a window — not just the refunded amount. Combines refund totals, lost shipping revenue, COGS for non-restockable items (e.g., DEFECTIVE), and restocking labor into a per-reason and per-product return P&L. Read-only. Use to prioritize which reasons or product lines deserve operational fixes — better packaging, size guides, listing accuracy.

Prerequisites

  • shopify store auth --store <domain> --scopes read_orders,read_returns,read_inventory
  • API scopes: read_orders, read_returns, read_inventory

Parameters

ParameterTypeRequiredDefaultDescription
storestringyesStore domain (e.g., mystore.myshopify.com)
formatstringnohumanOutput format: human or json
days_backintegerno90Lookback window for returns
group_bystringnoreasonAggregation level: reason, product, sku, or reason_x_product
min_returnsintegerno3Minimum returns per group to include in summary
writeoff_reasonsarrayno["DEFECTIVE"]Return reasons whose items are treated as non-restockable (full COGS write-off)
flat_restocking_costfloatno5.00Average labor cost per return line item to model restocking workload

Safety

ℹ️ Read-only skill — no mutations are executed. Cost figures are estimates derived from unitCost, refund totals, and flat_restocking_cost — calibrate the flat-cost figure to your operation before treating outputs as accounting truth.

Workflow Steps

1. OPERATION: returns — query Inputs: query: "created_at:>='<NOW - days_back days>'", first: 250, select returns with line item pricing, product/variant, inventoryItem.id Expected output: All returns in window with per-line-item pricing

2. OPERATION: orders — query Inputs: For each return's order.id, fetch refunds { totalRefundedSet refundLineItems { quantity subtotalSet totalTaxSet lineItem { id } } } Expected output: Refund amounts mappable to line items

3. OPERATION: inventoryItems — query — batch unique inventoryItem.id from step 1; returns unitCost per item

4. Per line item compute: refund_amount (matched refundLineItem proportional to returned qty), shipping_loss (order shipping × line-item value share for full-order returns; else 0), cogs_writeoff (unitCost × qty only if returnReason in writeoff_reasons), restocking_labor (flat_restocking_cost × qty). Sum and aggregate by group_by.

GraphQL Operations

# returns:query — validated against api_version 2025-01
query ReturnsForCostAttribution($query: String!, $after: String) {
  returns(first: 250, after: $after, query: $query) {
    edges {
      node {
        id
        status
        createdAt
        totalQuantity
        order {
          id
          name
          totalShippingPriceSet { shopMoney { amount currencyCode } }
          totalPriceSet { shopMoney { amount currencyCode } }
        }
        returnLineItems(first: 50) {
          edges { node {
            id
            quantity
            returnReason
            fulfillmentLineItem { lineItem {
              id
              title
              quantity
              discountedTotalSet { shopMoney { amount currencyCode } }
              originalUnitPriceSet { shopMoney { amount currencyCode } }
              variant { id sku inventoryItem { id } }
              product { id title vendor }
            } }
          } }
        }
      }
    }
    pageInfo { hasNextPage endCursor }
  }
}
# orders:query — validated against api_version 2025-01
query OrderRefundsForReturns($query: String!, $after: String) {
  orders(first: 250, after: $after, query: $query) {
    edges {
      node {
        id
        name
        refunds {
          id
          createdAt
          totalRefundedSet { shopMoney { amount currencyCode } }
          refundLineItems(first: 50) {
            edges { node {
              quantity
              subtotalSet { shopMoney { amount currencyCode } }
              totalTaxSet { shopMoney { amount currencyCode } }
              lineItem { id }
            } }
          }
        }
      }
    }
    pageInfo { hasNextPage endCursor }
  }
}
# inventoryItems:query — validated against api_version 2025-01
query InventoryUnitCosts($ids: [ID!]!) {
  nodes(ids: $ids) {
    ... on InventoryItem {
      id
      unitCost { amount currencyCode }
      tracked
    }
  }
}

Session Tracking

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

On start, emit:

╔══════════════════════════════════════════════╗
║  SKILL: Return Cost Attribution              ║
║  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>

On completion, emit:

For format: human (default):

══════════════════════════════════════════════
RETURN COST ATTRIBUTION  (<days_back> days, group: <group_by>)
  Returns analyzed:    <n>
  Total return cost:   $<amount>  (refund <pct>%, shipping <pct>%, COGS <pct>%, labor <pct>%)

  Top cost drivers:
    <group>   Returns: <n>  Total: $<n>  Avg: $<n>  Top reason: <reason>
  Output: return_cost_<date>.csv
══════════════════════════════════════════════

For format: json, emit:

{
  "skill": "return-cost-attribution",
  "store": "<domain>",
  "period_days": 90,
  "group_by": "reason",
  "returns_analyzed": 0,
  "totals": {
    "total_cost": 0, "refund": 0, "shipping_loss": 0,
    "cogs_writeoff": 0, "restocking_labor": 0, "currency": "USD"
  },
  "groups": [],
  "output_file": "return_cost_<date>.csv"
}

Output Format

CSV file return_cost_<YYYY-MM-DD>.csv with columns: group_key, return_count, units, refund_amount, shipping_loss, cogs_writeoff, restocking_labor, total_cost, avg_cost_per_return, top_return_reason, currency

Error Handling

ErrorCauseRecovery
THROTTLEDAPI rate limit exceededWait 2 seconds, retry up to 3 times
Missing unitCostCost not recordedTreat COGS as 0 and flag the row
Refund not yet processedCustomer not yet refundedUse line item discounted total as estimate
Multiple refunds per returnPartial refund historySum refunds tied to the return's line items
No shipping costFree shippingShipping loss = 0

Best Practices

  • Use group_by: reason_x_product to surface lethal combos like DEFECTIVE × <hero SKU> — supplier-quality issues addressable at the source.
  • Re-run after unitCost updates; stale cost most often skews COGS write-off.
  • Pair with return-reason-analysis to compare "what returns most" with "what costs most" — they often diverge.

Related skills

FAQ

What cost components does it include?

Refund amount, lost shipping revenue, COGS write-off for non-restockable reasons like DEFECTIVE, and a flat restocking labor cost per line item.

Are the figures exact?

No; they are estimates derived from unitCost, refund totals, and a flat_restocking_cost that you should calibrate before treating outputs as accounting truth.

Finance & Tradingfinanceecommerce

This week in AI coding

Five minutes, every Monday - the tools, releases and tactics for developers.

unsubscribe anytime.