How FCAnalytics counts.
The rules behind every number on an FCAnalytics dashboard, written out in the order they are applied. Nothing here is a rounding or an estimate: each rule is a line of code, and you can check any figure against the orders in your own WooCommerce admin.
1. Which orders count as paid
An imported order is paid when its WooCommerce status is processing, completed or refunded. Every revenue, profit, customer and product figure is built from paid orders only.
- Pending, failed, cancelled, on-hold and checkout-draft orders are not paid. They are kept as checkout started and feed the funnel's checkout step and the abandoned-cart screens.
- Trashed, draft and auto-draft records are ignored entirely.
- A fully refunded order stays a paid order with its refund subtracted, so it contributes zero revenue but still appears in the order count. This matches the built-in WooCommerce Analytics rule that the refunded status cannot be excluded.
2. How refunds are handled
Each order carries a refund total, read from the refunds WooCommerce recorded against it. Paid revenue is the order total minus that refund total. If the order's status is refunded, the refund total is at least the full order total, whatever the individual refund lines say. Refunds are dated by the order they belong to, not by the day the refund was issued, so revenue for a past period can go down after a later refund. The built-in WooCommerce Revenue report does the opposite and shows refunds on the day they occurred; this is the most common reason the two disagree for a given week.
3. Paid revenue
Paid revenue for a period is the sum of (order total minus refund total) across paid orders created in the period. The order total is the amount WooCommerce charged, so it includes shipping charged to the customer and tax. Average order value is paid revenue divided by the number of paid orders.
4. Cost rules
Four costs are subtracted from paid revenue. All four are set by the store owner in Settings, Costs; FCAnalytics never guesses a cost.
- Product cost. Entered per product (table or CSV). An order's product cost is the sum of unit cost multiplied by quantity across its line items. A product with no cost entered contributes zero, and the Products dashboard shows which products have no cost, so a margin that looks too good usually means missing costs.
- Payment fees. Order total multiplied by the fee percentage, plus the fixed fee, for every paid order. Refunded amounts are not deducted from the fee base.
- Shipping cost. Either the shipping lines on each order or a flat amount per order, as selected by the owner.
- Ad spend. Monthly amounts per channel, prorated to the period as described in rule 6.
Net profit = paid revenue minus product costs minus payment fees minus shipping cost minus ad spend. Margin = net profit divided by paid revenue, multiplied by 100. A product is flagged as low margin when its margin is under 15 percent and it sold at least one unit in the period.
5. Periods, time zone and comparison
Dashboards show the last 7, 30, 90 or 365 days. A period starts at midnight in the store's time zone on its first day and ends at the current minute, so the last day is partial and the first day is complete. The comparison period is the same number of days immediately before the period and is used for every percentage change shown on a card. Daily charts group orders by their date in the store's time zone. A user can switch their own view to UTC in their profile; the store's time zone is read from WooCommerce at connection time.
6. Ad spend proration
Ad spend is entered for a calendar month and a channel. For any period, the amount counted is the month's entry multiplied by the share of that month's seconds that fall inside the period. A 30-day period that covers the last 10 days of one month and the first 20 of the next therefore takes one third of the first month's entry and two thirds of the second's. The attribution dashboard uses the same proration per channel to compute profit and return after spend.
7. Attribution mapping
Every imported order carries the WooCommerce order attribution meta captured at checkout (available for orders placed while the feature is enabled, which it is by default since WooCommerce 8.5). FCAnalytics turns it into one channel label per order with these rules, applied in order:
- If the UTM medium is email, newsletter or e-mail, the channel is Email.
- If a UTM source is present: a source containing "google" is Google Ads when the medium is cpc, ppc, paid, paidsearch or ads, otherwise Organic search; facebook, fb or meta is Facebook Ads; instagram or ig is Instagram; tiktok is TikTok; pinterest is Pinterest; klaviyo or mailchimp is Email; bing is Bing Ads; any other source is kept as its own channel, capitalized.
- Without a UTM source, WooCommerce's source type decides: organic is Organic search; referral is Social when the referrer is a social network, otherwise Referral; admin (orders created in the WordPress admin) is Manual.
- Everything else, including direct visits and orders with no attribution meta at all, is Direct.
The model is last-click because WooCommerce records last-click; FCAnalytics does not infer earlier touches. Campaign and device are stored as WooCommerce recorded them.
8. Funnel sources
The funnel has five steps. Sessions, product views and add-to-cart come only from the tracking snippet, which reports events with a random session id; each step counts distinct sessions that reached it. Checkout started counts imported orders of every status except trashed and draft records, and purchase counts paid orders. When no snippet events exist for the period, the funnel shows the last two steps and says so; conversion rate (paid orders divided by sessions) is then not shown rather than shown as zero.
9. Abandoned carts and recovery
- An unpaid order counts as an open cart once it is more than one hour old, so a shopper still paying is not counted.
- The abandonment step is payment for pending, failed, cancelled and on-hold orders and shipping for checkout-draft orders created by the block checkout. With the snippet, a session that added to cart but never reached checkout counts as abandoned at the cart step.
- A cart is recovered when a paid order is placed by an email address that had an unpaid checkout-started order in the seven days before. Recovered revenue is the paid revenue of those orders.
10. Customers and segments
Customers are built from paid orders grouped by billing email, so guest checkouts count and a person who used two addresses appears twice. Lifetime value is the average of total spent (minus refunds) per customer. A customer is new in a period when their first paid order falls inside it and returning otherwise; repeat rate is returning customers divided by all customers who ordered in the period. VIP means five or more paid orders. At risk means the last paid order is between 90 and 365 days old. Cohorts group customers by the month of their first paid order and show the share that ordered again in each later month.
11. Import and sync cadence
- First import: products first, then orders newest first, then customers built from the orders, then costs. It runs in the background and resumes if the browser tab is closed.
- Sync: every 15 minutes FCAnalytics requests orders and products modified since the last successful sync, 100 records per page, and recalculates. A status change, refund or edit on an old order is picked up at the next sync.
- Failure: after three failed attempts in a row the store is marked as in error, the owner is emailed once and the dashboards keep the last good numbers. Retry now in the app runs a manual sync.
- The connection is read-only. Nothing in the store is ever modified.
What this page does not cover
Illustrative figures on the features page and in the public demo are sample data, not customer results. FCAnalytics does not publish benchmarks from customer stores. For setup steps see how it works; for shorter answers see the FAQ.
Check the rules against your own orders.
Connect a store, open the Profit dashboard and compare any figure with your WooCommerce admin. 14-day trial, no card required.