How ProfitRoot verifies D2C margin.

Most tools present every uploaded number as truth. ProfitRoot separates what your data proves from what it merely calculates -- and refuses the numbers it can't back.

The core claim

A Shopify Orders export proves Net Sales, not Contribution Margin. Orders carry the revenue side -- gross, discounts, refunds, order and line counts. Every cost lane (COGS, payment fees, fulfillment, shipping, returns handling, ad spend) lives in a different file. Rendering margin from Orders alone would be fabrication, so a lane stays gated until its source is uploaded and reconciles.

What each source proves

SourceProvesUnlocksStatus
From Shopify
Shopify OrdersGross, discount, refund, net sales, orders, units, AOV, SKU mixRevenue BridgeReconciled
Product CostProduct COGS (unit cost x quantity)Gross MarginNeeds source
Shopify ProductsCatalog, product / variant namesProduct mix / catalog joinsUnavailable
Shopify PaymentsPayment fees, gross vs net settledPayment fees + cash receiptsNeeds source
Shopify InventoryOn-hand, stock movementInventory visibility (scenario)Scenario
Not from a Shopify export
3PL / CarrierFulfillment + shipping costLogistics cost-to-serveNeeds source
Ad SpendMedia spendCM after marketingUnavailable
Accounting (QuickBooks / Xero)Booked cost, blended lanesGL control tie-out / opexUnavailable

No source proves a cost lane from Orders alone -- COGS, payment fees, fulfillment, shipping, returns and ad spend each require their own file. Net Sales is the single reconciling line (order grain); AOV and CM% are derived from reconciled totals, never stored as if they were sources.

The reconciliation contract

Every source that reconciles runs a contract that compares a source total (read from the raw file) against the mapped total (what the parsed objects carry) and reports the residualand whether it passed. Three guards run at order grain, each proven to fire by a test:

A residual over tolerance, a missing required column, or a double-count is a hard halt -- no setting can downgrade it. Two coverage numbers are always shown together, row coverage and value coverage: a few excluded rows can hide a large excluded dollar amount, so neither number alone is honest.

The rules we hold

What we do not claim

We are specific about what ProfitRoot cannot do yet -- including what a real Shopify export taught us we had wrong. See Known limitations.