Dodo Payments MRR, revenue and refunds in one dashboard
Connect a Dodo Payments key with Read access only. Sumly reads subscriptions, payments, refunds and lost disputes, and counts them without tax and after Dodo's fee.
Connected in three steps
A read-only key, pasted once. Sumly does the rest.
-
1
In Dodo Payments: Developer → API Keys → Create New Key. Name it Sumly.
-
2
Give it Read on Subscriptions, Payments, Refunds, Disputes, Products and Balances (Balances gives the fee and tax of each payment). Everything else: None.
-
3
Paste the key below. A dodo_test_ key reads test mode.
-
4
To trace payments to visits: payment links need nothing, the site script adds the visitor to them. For checkout sessions you create on your server, pass
metadata: { sumly_visitor_id: sumly.visitorId }.
Or let your coding assistant do it
Paste this into Claude Code, Cursor or Codex in your project. It fits the code to how your project is built, asks you for the dashboard steps and leaves the keys to you.
See what it says
Set up Dodo Payments for Sumly in this project.
Sumly (https://sumly.dev) shows revenue next to the visits and app users it came from. The full guide is https://sumly.dev/integrations/dodopayments; read it if anything below is unclear.
Steps:
1. In Dodo Payments: Developer → API Keys → Create New Key. Name it Sumly.
2. Give it Read on Subscriptions, Payments, Refunds, Disputes, Products and Balances (Balances gives the fee and tax of each payment). Everything else: None.
3. Paste the key into Sumly. A dodo_test_ key reads test mode.
4. To trace payments to visits: payment links need nothing, the site script adds the visitor to them. For checkout sessions you create on your server, pass `metadata: { sumly_visitor_id: sumly.visitorId }`.
So each payment shows which visit it came from: Payment links (checkout.dodopayments.com/buy/…) need nothing more: the site script adds the visitor to them as metadata_sumly_visitor_id, which Dodo keeps on the payment. For checkout sessions you create on your server, pass the sumly_vid cookie as metadata named sumly_visitor_id. Each payment then counts for the source, campaign and country of the visit that started it. In the EU and UK there is a visitor only after they agree.
Keep in mind: Built from Dodo's API reference and checked against responses shaped like it, not yet against a live Dodo account. Tell us if a number looks off. Dodo's payment list carries no fee or tax. Both come from the balance ledger, so give the key Read on Balances; without it payments still count without tax, but with no fee. A subscription counts at its price before tax. Discounts on a subscription are not taken off MRR, because Dodo's list does not say how much they take off.
How to work:
- Look at how this project is built first, and fit the code to its framework and its way of doing things; the examples above are a starting point, not something to paste as is.
- Steps that happen in a dashboard (Sumly, or Dodo Payments's own) are mine: tell me exactly what to click, then wait for me.
- The Dodo Payments key goes into Sumly (Projects and payments), not into this project: Sumly reads Dodo Payments itself. Your part in the code is only carrying the visitor into checkout, as above.
- Keys the code needs belong in environment variables, never in the code or the repository. Never ask me to paste a secret key into this chat; tell me which variable to set.
- Change only what this needs, show me the changes before you commit, and tell me how to check that it works.
What you see after connecting
Dodo Payments next to every other project and provider, on the same pages.
Overview
MRR, ARR, revenue per customer, paying customers, trials and the MRR set to cancel.
Payments without tax and after Dodo's fee, with the buyer's name and billing country.
Metrics over time, with churn, LTV and quick ratio.
Plans by product name, customers, the outlook and a CSV export.
With the visitor carried into checkout
Revenue by source and campaign, and ROI for each cost.
Which visit paid
Payment links (checkout.dodopayments.com/buy/…) need nothing more: the site script adds the visitor to them as metadata_sumly_visitor_id, which Dodo keeps on the payment. For checkout sessions you create on your server, pass the sumly_vid cookie as metadata named sumly_visitor_id. Each payment then counts for the source, campaign and country of the visit that started it. In the EU and UK there is a visitor only after they agree.
How attribution works →Counts toward your plan
Nothing: payments, customers and refunds never count toward your plan. Only the page views and app screens Sumly keeps do. Plans →
The details
What Sumly reads
- Subscriptions with their price before tax, trials and scheduled cancellations
- Succeeded payments, refunds and lost disputes
- The tax and fee on each payment, from the balance ledger
- Product names, for plans
When Sumly reads Dodo Payments
- Every 15 minutes, together with the other connections of the project. The first read takes three years of payments.
- Subscriptions are read whole each time, because their status and price change in place.
- Refunds and lost disputes are read by their own date, so a refund of an older payment is found too.
- With the webhook added, each payment, refund, dispute and subscription change is read again from Dodo the moment it happens.
How Dodo Payments money is counted
- Monthly value
- The subscription's recurring price before tax, spread over its billing interval: a twelfth for yearly plans, 52 ÷ 12 of a weekly one.
- Trials
- A subscription with trial days counts from the end of its trial. Until then it shows under trials.
- Cancellations
- A subscription set to cancel at its next billing date leaves MRR at once, though it stays paid up until then.
- On hold or paused
- On hold (a renewal failed) stops counting from the start of its current period; paused from the day it was paused. Past due still counts while Dodo retries.
- Tax
- Dodo is the merchant of record and pays the tax. Payments count what was paid, less tax.
- Fees
- The payment fee in Dodo's balance ledger, taken as the same share of the payment. Net revenue is after it.
- Refunds and disputes
- A refund counts without the tax that went back, on the day it was made. A lost dispute counts as the whole payment returned.
- Currency
- Payments in the currency the buyer paid, turned into euros at the ECB rate of that day. MRR converts at today's rate.
Good to know
- Built from Dodo's API reference and checked against responses shaped like it, not yet against a live Dodo account. Tell us if a number looks off.
- Dodo's payment list carries no fee or tax. Both come from the balance ledger, so give the key Read on Balances; without it payments still count without tax, but with no fee.
- A subscription counts at its price before tax. Discounts on a subscription are not taken off MRR, because Dodo's list does not say how much they take off.
Dodo Payments questions
Can Sumly change anything in Dodo Payments?
No. Give the key Read and nothing else; Sumly only reads with it and keeps it encrypted.
Which permissions does the key need?
Read on Subscriptions, Payments, Refunds, Disputes, Products and Balances. Balances is only for fees; without Products, plans have no names.
Do I need the webhook?
No. Sumly reads Dodo every 15 minutes either way. With the webhook, payments and cancellations show up within seconds.
Does Sumly read test mode?
A dodo_test_ key reads Dodo's test mode, so you can try the connection before going live.
Why is the webhook not signed?
It does not need to be: the address holds a secret of its own, and Sumly takes nothing from the call itself. It reads the payment or subscription it names again from Dodo with your key.
Other integrations
Try it with your own projects
Sign in with Google or a code by e-mail and connect your first project. Free for one project, and 14 days of a paid plan with no card.
Start freeOr look around first: open the live demo.