Run your workspace
Revenue attribution
Revenue attribution answers the question every price objection hides behind: what did the AI employee actually contribute? Instead of "you had 93 conversations", the platform records every business outcome β a WooCommerce order, a Calendly booking, a lead marked won β and links orders back to the conversations that drove them, in two honest tiers that are never summed together.
The two tiers
| Tier | Requires | Window |
|---|---|---|
| Direct | The assistant recommended a product, the visitor clicked its card, and an order containing that product followed. Every direct euro has a visible chain of evidence: conversation β click event β order line. | 7 days (configurable) |
| Influenced | The same visitor had a conversation before ordering, but the specific product can't be tied to specific advice. Reported as context, never as proof. | 30 days (configurable) |
An order that qualifies for both tiers counts once β as direct. When several conversations precede an order, the last touch wins for influenced; for direct, the click-bearing conversation wins even when a later click-less one exists (evidence beats recency). No identity match means the order stays unmatched β there is no fuzzy guessing, by design.
How an order is linked to a conversation
Identity keys, strongest first:
- Conversation cookie β at checkout the WordPress
plugin stamps the widget's own first-party cookies
(
pb_anon_id,pitchbar_conv_id) onto the order as meta. Same browser, deterministic. - Visitor id β the widget's 1-year anonymous id, matched through the visitor record.
- Logged-in customer β the plugin's ShopperToken
already carries
wp_user_idonto the conversation; the order's customer id matches across devices. - Hashed e-mail β the order's billing e-mail as a
sha256hash, compared against captured leads. The raw address never leaves the shop and is never stored on the outcome row.
Honesty rules, built in
- Direct and influenced totals are never added into one figure.
- Refunds and cancellations reduce or reverse attributed value automatically; the original value stays on the row for audit.
- A recorded match is never rewritten by a webhook retry, a later conversation, or a window change β windows apply to new orders only.
- Unmatched is a correct answer, not a failure.
Requirements
- WooCommerce shops need the WordPress plugin v2.1.0+, which adds the order hooks and the checkout identity stamping.
- Calendly bookings and leads marked won in the inbox create conversation-linked outcomes automatically β no extra setup.
Reading the numbers (Phase A)
Phase A collects silently β there is no dashboard yet. The audit surface is an artisan command, run per agent:
php artisan attribution:report --agent=<uuid> --days=30
It prints per-tier totals, the count of unmatched and reversed orders, booking / won-lead counts, and one evidence line per direct match so each attributed order can be verified by hand against the real shop before any client sees a number.
Configuration
| Env | Default | Meaning |
|---|---|---|
ATTRIBUTION_DIRECT_WINDOW_DAYS |
7 | Max days between the product click and the order. |
ATTRIBUTION_INFLUENCED_WINDOW_DAYS |
30 | Max days between the conversation and the order. |