Concepts

Revenue and attribution

Where Rabolic revenue comes from (Dodo Payments webhooks or your server with a secret key), the one-revenue-source rule, currency conversion, linking payments to people, and first- and last-touch attribution.

Rabolic only counts revenue that a server confirmed. A page view or an app can't report a sale, so the numbers can be trusted.

Where revenue comes from

SourceHowEvents
Dodo PaymentsConnect it in Integrations → Payments with its webhook signing secret, then add the webhook URL Rabolic shows to DodoSuccessful payments and refunds arrive as $purchase and $refund
Your serverpurchase(), renewal() and refund() in @rabolic/node, or the HTTP API, with a secret key$purchase, $renewal, $refund with amount, currency, transaction_id, product

Payments from any other provider, including Stripe and in-app purchases, can be sent from your server. Rabolic has no Stripe, App Store or Google Play connection yet.

Revenue events sent with a publishable key are rejected (revenue_needs_secret_key). Purchase events sent from a browser or app never count as revenue.

One revenue source per project

A project's revenue comes from exactly one place:

  • With Dodo Payments connected, its webhooks are the revenue. Revenue events your server sends are still recorded as events, so funnels and journeys see them, but they add no revenue.
  • Without a provider, the revenue events your server sends are the revenue.

Why: the two paths describe the same payment with different ids, so they can't be matched reliably, and counting both would double your revenue.

Rabolic decides when it records each event. Connecting or removing a provider later doesn't rewrite past revenue.

Use Dodo Payments' webhooks if you sell through Dodo. Use purchase() from your server for any other provider.

Linking a payment to a person

  • From your server: pass the userId (or anonymousId) to purchase().
  • With Dodo Payments: put checkoutMetadata({ userId }) from @rabolic/node in the checkout session's metadata, or the anonymous id before someone has an account. The webhook then links the payment to the person.

A payment is recorded once per provider and transaction id. A webhook delivered twice, or a retried request from your server, is kept once.

Currency

  • Each project reports in its own currency, set in Project settings.
  • Each purchase is converted into the project's currency at the exchange rate of the day it happened, using the European Central Bank's daily reference rates. The original amount and currency are kept.
  • Organization totals are converted into the organization's roll-up currency the same way, day by day. Changing it recomputes from the stored originals and those days' rates.
  • A project without a revenue source shows no revenue, not 0.

Attribution

Rabolic credits each purchase to a channel in two models:

ModelCredits the purchase to
First touchThe channel of the buyer's first session
Last touchThe channel of their last session before the purchase
  • Each purchase is credited to one channel in each model, never split or counted twice.
  • Attribution looks back up to 90 days before the start of the date range. A purchase with no session in that time is credited to Direct.
  • The project's default model is set in Project settings → Project.

The numbers

Gross revenue, net revenue (gross minus refunds; store fees aren't deducted), refunds (on the day of the refund), purchases, average order value, paying users, revenue per user, revenue by platform and source, and lifetime value by first source. MRR is approximated from renewals in the last 30 days and shows only when there are renewals.

See Revenue in the dashboard.