Overview
The unified revenue ledger is the native record of every paid sale β regardless of source. A charge paid in the conversation, a WhatsApp catalog order, a Hotmart sale, a manual order or an API order all converge to one canonical order (the CRM orders registry). The moment that order is paid, Conversa Labs credits the seller (the order owner) exactly once: gamification points, commission and the revenue shown in the report.
Before this, each money path credited differently (or not at all): a catalog or Hotmart sale might earn nobody points or commission, while a charge credited its author. The unified ledger fixes that with one revenue axis and exactly-once counting β the same sale is never counted twice.
Prerequisites
- The Sales & Gamification module enabled on the account.
- The
unified_revenue_ledgerfeature enabled on the account (it is dark-shipped, default off β the operator enables it). With it off, behavior is identical to before. - The CRM orders registry (
orders_registry) enabled so charges and commerce orders also converge to the single order β this is what suppresses the legacy crediting and guarantees a single count. - The sales-management permission (
sales_manage) β or an admin β to read the ledger and export. - Real paid sales flowing (charges, catalog, Hotmart, manual orders) so there is something to count.
Step by step
- Enable the feature
unified_revenue_ledger(andorders_registry) on the account. - Ensure sales are flowing from any source β convergence is automatic through the order feeders.
- Open the Revenue view in the Sales dashboard/wallboard.
- Pick a period (defaults to the last 30 days).
- Read the groupings β total per currency, by source, by gateway, by seller and by affiliate.
- Export to CSV to reconcile revenue outside the platform.
Settings & options
What the ledger groups
Over the paid orders in the period (by paid_at), revenue is summed and grouped:
| Grouping | What it brings |
|---|---|
| Total per currency | Total revenue per currency β it never sums across currencies |
| By source | Revenue by the order source: manual, webhook, api, payments, commerce |
| By gateway | Revenue by the money gateway (asaas, mercado_pago, hotmart, native, catalogβ¦) |
| By seller | Revenue by the order owner (the credited seller) |
| By affiliate | Revenue by the attributed affiliate (dual attribution) |
Exactly-once counting (no double count)
Crediting happens on the order axis when an order exists, and on the legacy path only when no order is produced:
unified_revenue_ledger |
orders_registry |
Who credits | Result |
|---|---|---|---|
| Off | any | Legacy path (charge/commerce) | identical to before |
| On | On | order.paid (the order) β legacy suppressed |
once, on the order |
| On | Off | Legacy (no order is produced) | once, on the charge/commerce |
Seller attribution (fallback)
The order owner is resolved in a cascade: deal β contact β assignee β creator. A charge without a deal still attributes to the user who created it (the charge's creator field), so no paid sale ends up "ownerless".
External-sale attribution
External sales (catalog, Hotmart, Kiwify and other gateways) arrive from the gateway and often reach
a buyer contact who is not in anyone's portfolio. Without a rule, that paid sale would be
"seller-less". The per-account external_attribution_mode setting decides how the seller is
auto-resolved in that case:
| Mode | What it does |
|---|---|
off (default) |
No automatic credit β the external sale stays seller-less until a manual attribution |
last_conversation |
Credits the agent who last handled the buyer (the contact's last conversation) |
distribution |
Credits according to the active distribution rules (the same as lead distribution) |
When the mode resolves a seller, the buyer's portfolio is durably claimed for that seller β so the
contact's next sales already arrive with an owner. The default is off: no automatic credit until
you explicitly choose last_conversation or distribution.
Manual seller (re)attribution. A manager (sales-management permission) can, from the order,
link an external sale to a seller or move the credit between agents. The switch reverses the
previous owner's points and commission and credits the new owner; the affiliate credit is
untouched. Leaving the seller blank unassigns the order. Every change is audited (the
order_reattributed event), preserving the record of who was credited and why.
Refund (clawback)
When an order is refunded, the credit is reversed on the order source β for the seller and the affiliate β keeping the ledger true to the money actually received.
CSV export
One row per paid order, with the columns: order_id, paid_at, source, gateway, owner_id,
affiliate_id, amount, currency. Amounts are in major units (e.g. 4970.50 = R$ 4,970.50).
Permissions and visibility
- Reading the ledger and exporting require the sales-management permission.
- The read honors per-seller isolation: under portfolio/privacy, a manager sees only their cascade; a rep sees only their own portfolio.
Use cases
- The manager reads revenue by seller to recognize who sold the most in the period.
- Finance exports the CSV to reconcile paid revenue against the commission statement.
- Leadership compares revenue by source (Hotmart Γ catalog Γ charge) and by gateway.
- Revenue by affiliate feeds the affiliate program tracking (dual attribution).
Tips, limits & best practices
- Money is in major units (decimal), the same convention as Payments/Catalog β never divide by 100.
- The ledger never sums across currencies: each currency is its own row.
- Enabling the feature credits sales going forward β there is no automatic retroactive re-credit. To reprocess Hotmart history, use the operator backfill.
- Enable both features (
unified_revenue_ledger+orders_registry): that combination is what suppresses the legacy path and prevents double counting.
Troubleshooting
- Empty ledger: there are no paid orders in the period, or the feature is off. Confirm the feature is enabled and that paid sales exist.
- Double numbers:
orders_registryis probably off, so the legacy path and the order path credit together. Enable the orders registry. - Seller shows as null: the order had no resolvable owner (no deal, contact, assignee or creator). Check attribution at the source.
- External sale seller-less or credited to the wrong seller: if
external_attribution_modeisoff, external sales stay ownerless β chooselast_conversationordistribution, or do a manual re-attribution (sales-management) from the order. - Refund not reflected: the order refund event did not fire. Confirm the refund flow in the gateway/Payments.
- Export blocked: you lack the sales-management permission. Ask an admin.