payments · side by side
Dodo Payments vs Stripe for a Next.js app
Both fill the payments slot, so a generated repo carries one or the other, never both. Every line below is read out of the two manifests.
Short answer
Pick Dodo Payments if
Founders outside the US and EU, India especially, selling software worldwide. Dodo takes local payment methods: UPI in India, cards, Apple Pay and Google Pay. It remits sales tax as the seller, so you never register for VAT abroad.
Pick Stripe if
SaaS selling to businesses and consumers in many countries. Best when you need real invoices, dunning, proration and a tax story your accountant will accept.
Side by side
Price, obligations, and the surface each one adds. No row is written by hand. This is manifest.yaml, rendered.
| From the manifest | Option ADodo Payments | Option BStripe |
|---|---|---|
| In one line | Dodo Payments Merchant of record in 220+ countries and regions. Sales tax is Dodo's job. | Stripe Hosted Checkout, a customer portal you never build, and webhooks you test locally. |
| Pricing | Dodo Payments 4% + 40c per US card or wallet payment, no monthly fee. Non-US payments add 1.5% and subscriptions add 0.5%. Standard payouts are free, with a $5 fee under $1,000. USD SWIFT payouts for non-US businesses cost $25. Sales tax is included: Dodo is the seller. | Stripe 2.9% + 30c per successful US card charge. No setup or monthly fee. Stripe Billing adds 0.7% of billing volume. Stripe Tax is extra, charged per transaction where you are registered to collect. |
| Best for | Dodo Payments Founders outside the US and EU, India especially, selling software worldwide. Dodo takes local payment methods: UPI in India, cards, Apple Pay and Google Pay. It remits sales tax as the seller, so you never register for VAT abroad. | Stripe SaaS selling to businesses and consumers in many countries. Best when you need real invoices, dunning, proration and a tax story your accountant will accept. |
| Trade-offsVerbatim from the manifest | Dodo Payments
| Stripe
|
| Required companionsAdded for you, with a reason | Dodo Payments
| Stripe
|
| Recommended alongsideSuggested, never added for you | Dodo Payments
| Stripe
|
| Env vars you will manageEvery one documented in docs/onboard.md | Dodo Payments 9 variables · 2 required
| Stripe 9 variables · 3 required
|
| Dependencies added | Dodo Payments
| Stripe
|
| MCP serversWritten into .mcp.json | Dodo Payments None. No extra agent tools from this one. | Stripe
|
| Footprint in your repo | Dodo Payments 14 files, plus 3 injections into shared stack files | Stripe 10 files, plus 3 injections into shared stack files |
What changes in your repo
The paths each battery contributes, diffed. A path in the third list is written by both, so swapping rewrites that file rather than adding one.
Only with Dodo Payments (9)
scripts/1 file
billing/1 file
- dodo-test-webhook.ts
src/8 files
app/1 file
api/1 file
webhooks/1 file
dodo/1 file
- route.ts
lib/7 files
billing/7 files
- dodo-config.ts
- dodo-events.test.ts
- dodo-events.ts
- dodo-fixtures.ts
- dodo-objects.test.ts
- dodo-objects.ts
- dodo.ts
Only with Stripe (5)
src/5 files
app/1 file
api/1 file
webhooks/1 file
stripe/1 file
- route.ts
lib/4 files
billing/4 files
- stripe-objects.test.ts
- stripe-objects.ts
- stripe-provider.test.ts
- stripe.ts
Same path, different implementation (5)
scripts/3 files
billing/3 files
- prune-events.ts
- reconcile.ts
- sync-plans.ts
src/1 file
lib/1 file
billing/1 file
- provider.ts
tests/1 file
e2e/1 file
- billing-webhook.spec.ts
Shared stack files Dodo Payments injects into
- env-required
- legal-processors
- verify-checks
Shared stack files Stripe injects into
- env-required
- legal-processors
- verify-checks
Dodo Payments in your .env.local
# required
DODO_PAYMENTS_API_KEY=dodo_test_replace_me
DODO_PAYMENTS_WEBHOOK_KEY=whsec_replace_me
# optional
BILLING_PRICE_PRO_LIFETIME=
BILLING_PRICE_PRO_MONTHLY=
BILLING_PRICE_PRO_YEARLY=
BILLING_PRICE_TEAM_MONTHLY=
BILLING_PRICE_TEAM_YEARLY=
DODO_PAYMENTS_ENVIRONMENT=test_mode
DODO_TAX_CATEGORY=saas
Stripe in your .env.local
# required
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY=pk_test_replace_me
STRIPE_SECRET_KEY=sk_test_replace_me
STRIPE_WEBHOOK_SECRET=whsec_replace_me
# optional
BILLING_PRICE_PRO_LIFETIME=
BILLING_PRICE_PRO_MONTHLY=
BILLING_PRICE_PRO_YEARLY=
BILLING_PRICE_TEAM_MONTHLY=
BILLING_PRICE_TEAM_YEARLY=
STRIPE_AUTOMATIC_TAX=false
What changes for your agents
Each battery ships rules, skills, subagents and hooks that an agent loads before it touches the code that battery owns. Picking one is also picking how your agents behave in src/lib/billing/**.
Dodo Payments
2
Skills
2
Rules
6
Solution docs
Rules (2)
Dodo translates, the shared billing core writes, and nothing leaves the server
src/lib/pricing.ts · src/lib/billing/** · scripts/billing/** · src/app/api/webhooks/dodo/**
Verify every Dodo webhook, keep every handler idempotent
src/app/api/webhooks/dodo/** · src/lib/billing/provider.ts · src/lib/billing/dodo-events.ts · src/lib/billing/dodo-objects.ts · src/lib/billing/webhook.ts
Skills (2)
/add-product
Add or change a plan or price on Dodo Payments (monthly, yearly or one-time lifetime). Edit src/lib/pricing.ts, create the Dodo product, wire its env var, and prove checkout and the webhook end to end.
/test-webhook
Exercise the Dodo webhook endpoint. Send a signed fixture offline, forward real test-mode events with the Dodo CLI, buy a subscription and a one-time product, refund one, assert idempotency, and debug signature failures.
Subagents and hooks
None of its own. The foundation agents and guard hooks still ship.
Stripe
2
Skills
4
Rules
6
Solution docs
1
MCP servers
Rules (4)
Stripe translates, the shared billing core writes the store
src/lib/billing/** · scripts/billing/**
Plans live in pricing.ts, Stripe ids live in env, amounts never come from the client
src/lib/pricing.ts · src/lib/billing/** · scripts/billing/**
Stripe objects are server-only
src/lib/billing/** · src/app/api/webhooks/stripe/** · src/app/**
Verify every Stripe webhook, keep every handler idempotent
src/app/api/webhooks/stripe/** · src/lib/billing/provider.ts · src/lib/billing/webhook.ts
Skills (2)
/add-plan
Add or change a plan or price on Stripe (monthly, yearly or one-time lifetime). Edit src/lib/pricing.ts, create the Stripe price, wire its env var, and prove checkout and the webhook end to end.
/test-webhook
Exercise the Stripe webhook endpoint locally. Forward real events with the CLI, buy a subscription and a one-time price, refund one, assert idempotency, and debug signature failures.
Subagents and hooks
None of its own. The foundation agents and guard hooks still ship.
What each one already knows
Solution docs land in docs/solutions/ in your repo and are published here, so you can read the failure modes before you commit.
Dodo Payments (6)
- Selling software from outside the US, and why a merchant of record solves the payout problemIf your company is registered in India, Nigeria, Brazil or most of the world, the hard part is not accepting cards. It is getting paid, and staying compliant in a hundred countries you never visit.docs/solutions/dodo/merchant-of-record-payouts-outside-the-us.md
- One-time payments and subscriptions on Dodo Payments, side by sideDodo decides one-time or recurring from the product, and payment.succeeded fires for both. Tell them apart by the payment's subscriptions, store purchases separately, and let a refund take access back.docs/solutions/dodo/one-time-payments-with-dodo.md
- Refunds and chargebacks on Dodo, and what they should do to accessA refund or dispute webhook says which payment, not what was bought. Re-read the payment, derive the status from all its refunds and disputes, and never let a late event undo a refund.docs/solutions/dodo/refunds-and-disputes-bookkeeping.md
- Verifying Standard Webhooks signatures, the three headers and the two mistakesDodo signs id.timestamp.body with HMAC-SHA256. Verify the raw bytes, pass all three headers, and never write the comparison yourself.docs/solutions/dodo/standard-webhooks-signature-verification.md
- The Dodo subscription lifecycle, which event means what and who keeps accessactive, past_due, on_hold, paused, cancelled, failed, expired. Map each to access on purpose, re-read the subscription on every event, and let a grace period decide how failed renewals feel.docs/solutions/dodo/subscription-lifecycle-events.md
- Dodo test mode and live mode are two separate worldsDifferent API keys, webhook keys, product ids and customers. Nothing carries over, and the mismatch that hurts most is silent.docs/solutions/dodo/test-mode-vs-live-mode.md
Stripe (6)
- Free trials in Stripe that do not leak accesstrialing is an entitled status and trial_will_end is not a payment. Where trials are configured, which events actually matter, and how to stop one person taking ten trials.docs/solutions/stripe/free-trials-that-do-not-leak.md
- Idempotent Stripe webhooks, or claim the event id before you do the workStripe delivers at least once, retries for three days and arrives out of order. An event ledger claimed before the handler runs is what stops double grants and lost updates.docs/solutions/stripe/idempotent-stripe-webhooks.md
- One-time payments with Stripe Checkout, from lifetime deal to refundA lifetime deal is a payment-mode Checkout Session, not a subscription. Which id to key it on, when it is really paid, how a receipt goes out, and how a refund or dispute takes the access back.docs/solutions/stripe/one-time-payments-with-stripe-checkout.md
- Proration when a customer changes plan, and why you should let the portal do itUpgrades, downgrades and seat changes each want different proration behaviour. What Stripe actually does, how to preview the amount, and when to build the flow yourself.docs/solutions/stripe/proration-when-plans-change.md
- Reconciling after a missed Stripe webhookA customer paid and the app does not know. How to find the gap, replay or re-sync the affected subscriptions and one-time purchases, and build a reconciliation job so the next outage is boring.docs/solutions/stripe/reconciling-a-missed-webhook.md
- Stripe Tax, and when you legally need to careWith Stripe you are the merchant of record, so sales tax and VAT are your liability. What Stripe Tax does and does not do, the thresholds that trigger obligations, and when a merchant of record is the better answer.docs/solutions/stripe/stripe-tax-and-when-you-need-it.md
Which one to pick
From meta.bestFor and meta.tradeoffs. If a claim is not in the manifest, it is not on this page.
Pick Dodo Payments when
Founders outside the US and EU, India especially, selling software worldwide. Dodo takes local payment methods: UPI in India, cards, Apple Pay and Google Pay. It remits sales tax as the seller, so you never register for VAT abroad.
And accept that(5)
- Dodo is the seller on the customer's statement and invoice. The tax liability moves to Dodo, which is the point, but your brand is not what shows on the card line.
- Younger than Stripe or Paddle, and the SDK changes more often. The version is pinned; read the release notes before upgrading.
- The flat rate costs more than a direct card processor because it includes the tax work. At high volume, compare it with Stripe plus a tax vendor.
- Fewer billing tools than Stripe. Failed renewals are not retried unless you turn Payment Retries on. Check that the reports and dunning you need exist before you commit.
- Payouts follow a collect-then-remit cycle, not a card processor's rolling schedule. Plan your runway on the payout date, not the charge date.
Pick Stripe when
SaaS selling to businesses and consumers in many countries. Best when you need real invoices, dunning, proration and a tax story your accountant will accept.
And accept that(5)
- You are the merchant of record. You owe sales tax, VAT and GST yourself. Stripe Tax calculates and files, but the liability is yours. Merchant-of-record vendors (Polar, Dodo, Lemon Squeezy) take that liability, at a higher rate.
- Webhooks are mandatory. Every subscription change reaches you asynchronously, at least once and out of order. Skip idempotency and you will double-grant entitlements in production.
- Stripe is not available in every country, and some business types are not allowed. Check both before you build.
- The API is deeper than you need on day one. The failure mode is over-modelling billing before you have ten paying customers.
- The Stripe CLI's
stripe listenforwards real webhooks to localhost, so you test the full loop before you deploy.
Questions people actually ask
- Should I choose Dodo Payments or Stripe?
- Dodo Payments is best for founders outside the US and EU, India especially, selling software worldwide. Dodo takes local payment methods: UPI in India, cards, Apple Pay and Google Pay. It remits sales tax as the seller, so you never register for VAT abroad. Stripe is best for SaaS selling to businesses and consumers in many countries. Best when you need real invoices, dunning, proration and a tax story your accountant will accept. Both fill the payments slot, so a generated repo carries one or the other, never both.
- How much do Dodo Payments and Stripe cost?
- Dodo Payments: 4% + 40c per US card or wallet payment, no monthly fee. Non-US payments add 1.5% and subscriptions add 0.5%. Standard payouts are free, with a $5 fee under $1,000. USD SWIFT payouts for non-US businesses cost $25. Sales tax is included: Dodo is the seller. Stripe: 2.9% + 30c per successful US card charge. No setup or monthly fee. Stripe Billing adds 0.7% of billing volume. Stripe Tax is extra, charged per transaction where you are registered to collect.
- What changes in my repo if I switch from Dodo Payments to Stripe?
- Dodo Payments writes 14 files, 9 environment variables and 3 dependencies, and installs 2 path-scoped rules, 2 skills and 6 solution docs. Stripe writes 10 files, 9 environment variables and 2 dependencies, and installs 4 path-scoped rules, 2 skills and 6 solution docs.
Decide once, then build the repo that already knows the decision.
Either way you get that choice’s rules, skills and solution docs installed, plus the guard hooks, an onboarding doc for exactly these env vars, and the Compound Engineering loop. Free and MIT.