---
name: dtc-contribution-margin
description: Calculates contribution margin by sales channel (Shopify, Amazon, TikTok Shop) from exports or warehouse tables the user provides, after confirming the revenue, refund date, time zone and cost definitions. Use when a DTC brand asks for margin or profit by channel, or asks why channel margins disagree.
---

# DTC Contribution Margin by Channel

Calculate contribution margin for each sales channel from the user's own data. Confirm every definition first. Do not guess a rule the user has not stated; ask, and write down the answer.

## Definition used

```
net sales           = gross sales - discounts - returns (sales reversals)      excludes tax and shipping
net revenue         = net sales + shipping charged - shipping refunded          before tax
contribution margin = net revenue - product cost - fulfillment - payment and marketplace fees
```

Contribution margin is before marketing. If the user wants ad spend subtracted, call the result **contribution after marketing** and show both. Fixed costs (rent, salaries, software) stay out.

## Step 1: Confirm the definitions

Ask these before calculating. Put the answers in a short "Definitions used" block at the top of the output.

1. **Period and date basis.** Which months or days? Do refunds count on the **refund (processed) date**, which lowers the month the refund happened, or on the **order date**, which ties the refund back to the order's cohort and restates past months? Both are valid. Name the measure to match, for example "net sales by activity date" or "order-cohort net sales, as of refresh".
2. **Time zone.** Which zone cuts the day? Shopify uses the store time zone, but some finance and payout reports differ. Amazon, TikTok Shop and ad accounts may each use another. Pick one reporting zone and convert everything to it.
3. **Revenue rule.** Is shipping charged included? Are gift card sales, test orders, cancelled orders and replacements in or out? Are platform subsidies (for example, a marketplace-funded shipping incentive or promotional rebate) revenue, a cost reduction or their own line?
4. **Product cost.** Is there a dated cost table, or one cost per SKU? Which date picks the cost (order date, ship date)? What currency? A single static cost gives old orders today's cost; flag it if that is all there is.
5. **Fulfillment.** 3PL invoices, shipping labels, marketplace fulfillment fees? Packaging only if it rises with each order.
6. **Fees.** Payment processor fees, marketplace referral and fulfillment fees, TikTok Shop fees. For Amazon, which source: posted fee events, the settlement report, or estimates?
7. **Owner.** Who approves the definition, usually finance, and what total should it tie to (Shopify net sales for the same dates, the closed month in the ledger)?

If the user does not know an answer, offer the default above, say it is an assumption, and label the output with it.

## Step 2: Check the inputs

Ask for exports or table names for each channel. Typical inputs:

- **Shopify**: orders, order lines, refunds and refund lines, shipping lines, payment fees (Shopify Payments or processor report).
- **Amazon**: order data plus fees. Fees live in three places: posted financial events (fee components by SKU between settlements), the settlement report (what was in the actual payout), and FBA reports and fee estimates (planning values, storage estimates, reimbursements). Use posted fees for SKU margin. Use settlement for cash. Never treat estimated fees or the storage fee estimate as charged costs.
- **TikTok Shop**: orders and the settlement or statement export with fees and subsidies.
- **Costs**: product cost table, 3PL or shipping invoices.

Check the grain of each file. Say what one row means (order, order line, refund line, fee event, settlement line).

## Step 3: Build the channel and order keys

**Separate three fields:**

- **Sales channel**: where checkout happened.
- **Fulfillment provider**: who shipped it (for example, Amazon MCF).
- **Source system**: where this record came from.

A TikTok Shop purchase can appear as a TikTok order, a linked Shopify order and an Amazon MCF fulfillment record. That is one sale, not three. Link copies to one business order key using the connector's documented origin fields or direct cross-platform references. Do not match on ID prefixes. Amount and timestamp can suggest a match but are not proof; put uncertain matches in an exception list, do not delete them.

**Assign costs by the sales channel of the order**, not by who sent the invoice. Marketplace fulfillment fees on a website order belong to the website channel.

Keep acquisition channel (the ad that brought the customer) separate from sales channel.

## Step 4: Map products and costs

- Map each source product to a canonical product using source system, account, and native ID. SKU text alone is not unique across stores and marketplaces.
- Record units per sold pack. A two-pack costs two units of product.
- For bundles, use a component table with quantities. Keep sales at the sellable line.
- Apply cost by an explicit date rule.
- **Unknown cost is not zero.** Report margin on known-cost sales with its coverage, and list sales and units excluded for missing cost.

## Step 5: Run the duplicate checks

Before summing:

1. No duplicate business order keys at order level.
2. Row count, quantity and merchandise sales are the same before and after each join. Two cost rows on one line, or order lines joined to shipments, multiply amounts.
3. Aggregate each source to its own grain (order, line, shipment, fee event) before joining.
4. Refunds deduplicate on the refund or event ID, not order ID or amount. One order can have several partial refunds of the same amount.
5. Shipping refunds are not subtracted from a merchandise measure that excludes shipping, and are not counted twice when two integrations report them.

## Step 6: Calculate

For each channel and period:

| Line | Shopify | Amazon | TikTok Shop | Total |
|---|---:|---:|---:|---:|
| Gross sales | | | | |
| Discounts | | | | |
| Returns | | | | |
| Net sales | | | | |
| Shipping charged less refunded | | | | |
| Net revenue | | | | |
| Product cost | | | | |
| Fulfillment | | | | |
| Payment and marketplace fees | | | | |
| **Contribution margin** | | | | |
| Contribution margin % of net revenue | | | | |
| Orders | | | | |
| Cost coverage % | | | | |

Compute the total from summed dollars, not by averaging channel percentages.

If the user supplies warehouse tables, write the SQL and show it. Use only the column names the user gives you; ask if a column is missing rather than inventing one.

## Step 7: Tie out and flag what may move

- Compare net sales per channel with the platform's own report for the same dates, time zone and status rules. Show the difference.
- Recent Amazon orders may be missing from financial events (a lag of up to about 48 hours) and fees are estimated until they settle, so recent margin can change. Say which days are not final.
- Deferred marketplace transactions are another reason a period total and a payout differ.

## Output format

1. **Definitions used**: the answers from Step 1, with assumptions marked.
2. **Contribution margin by channel**: the table from Step 6.
3. **Checks**: results of Step 5 and the tie-out, with any differences.
4. **Exceptions**: unmatched orders, missing costs, uncertain channel links, with their sales value.
5. **What could change**: unsettled fees, late refunds, open cohorts.

Keep numbers to what the data shows. Do not add industry benchmarks. These definitions are a starting point, not accounting advice; finance owns the final rule.

Built by Greyfield Data (greyfielddata.com). Free to use and adapt.
