Skip to main content

Overview

An app is a program that a merchant installs into their Dodo Payments business. After the merchant approves the scopes that the app requests, the app calls the Dodo Payments API for that business and receives webhooks about it. This guide shows how to:
  • Create an app and get its credentials.
  • Run the OAuth authorization code flow with PKCE.
  • Keep tokens fresh.
  • Receive and verify webhooks.
  • Submit the app for review and list it publicly.
The App Marketplace is available only to businesses that have the app_marketplace feature enabled. Testers need the feature enabled too.

Create an App

1

Open the Apps Page

In the dashboard, open Apps, then the Created tab, and select Create app.
2

Fill In the App Details

Set the app name, the redirect URIs, the scopes the app needs, and the events it subscribes to. Write a short reason for each scope. The merchant reads these reasons on the consent screen.
3

Copy the Credentials

Copy the client ID and the client secret (it starts with dodo_cs_). The dashboard shows the secret one time.
Redirect URIs must use HTTPS, must match exactly, and are limited to 10 per app. A public app cannot use a loopback address or a private IP address.
If you rotate the client secret, the old secret stops working immediately. Update your servers before you rotate.

Live and Test Installs

Live and test installs are separate. A merchant installs your app once in live mode and once in test mode. Each install has its own tokens, its own scopes, and its own webhooks. Set resource to https://test.dodopayments.com for a test install or https://live.dodopayments.com for a live install. The API host for the install is the same URL. The examples on this page use the test host. For a live install, use the live host. Every authorization request must include one resource. A request with no resource fails with invalid_target.

Authorize a Business

The app uses the OAuth 2.0 authorization code flow with PKCE (S256) and the client secret. The authorization server is https://auth.dodopayments.com.
1

Create a PKCE Pair

Create a random code_verifier. Compute code_challenge as the Base64URL-encoded SHA-256 hash of the verifier.
2

Send the Merchant to the Authorize Endpoint

The merchant signs in. An owner or an admin of the business approves all scopes or none. The merchant sees the reason that you wrote for each scope.
3

Receive the Code

Dodo Payments redirects to your redirect_uri with code and state. Check that state matches the value that you sent.
4

Exchange the Code for Tokens

Send the client ID and secret with HTTP Basic authentication.
The response holds access_token, refresh_token, expires_in, and scope.
5

Call the API

A token works only for its own business and its own mode, and only for the granted scopes. A call outside the granted scopes returns 403.
Activation is asynchronous. Your app can receive the authorization code and call the API before the install is active, and before the app.installed webhook arrives. Do not wait for app.installed to start the token exchange. Use it to record the install.

Token Lifetimes

Refresh with the same Basic authentication:
Store the new refresh token and discard the old one. If you use an old refresh token a second time, Dodo Payments revokes the grant, and the install receives app.uninstalled.

Uninstall and Revocation

A merchant owner or admin can uninstall the app at any time. The install stays active if the person who installed it leaves the business. Revocation takes effect within 2 minutes. During that time, a token that was revoked can still work. After that time, the API returns 401. You can also revoke a token yourself at https://auth.dodopayments.com/oauth2/revoke.

Scopes

A scope has the form resource:read or resource:write, for example payments:read or refunds:write. The dashboard lists the scopes that you can assign when you create the app. Scopes that give access to money movement or customer data get extra attention in review. Request only the scopes that the app uses. If you add a scope later, existing installs keep their old scopes and the merchant sees a banner to approve the new scopes. Calls that need the new scope fail until the merchant approves.

Webhooks

An app has one webhook endpoint for live installs (webhook_url) and one for test installs (webhook_url_test). Test events are sent only if you set webhook_url_test. Without it, the app page shows a warning.

Which Events an App Receives

An app receives an event only if both of these are true:
  1. The app subscribed to the event type.
  2. The install granted the read scope of the resource that the event describes.
The dashboard shows the full list for each scope when you choose events. The app always receives these events for its own installs, with no scope check: app.installed, app.installation.updated, and app.uninstalled.
payment.* events need only payments:read, and they carry the full payload, including the customer name and email. The consent screen tells the merchant that payment access includes customer contact data. Handle this data under your privacy policy.

Payload

Every webhook has these fields at the top level:

Verify the Signature

Dodo Payments signs each message with Svix. Verify the webhook-id, webhook-timestamp, and webhook-signature headers against the raw request body, with the signing secret of your endpoint. The app webhook uses the same Svix headers and verification steps as a merchant webhook. See Webhooks for code examples in each language. Return a 2xx response quickly. Use webhook-id to ignore a message that you already processed.

Privacy Webhooks

An app that has customers scopes must handle three privacy events before it can be listed publicly:
  • customer.data_request
  • customer.redact
  • business.redact
Dodo Payments sends each event to your webhook_url, with the same payload fields as other app webhooks. When you receive one, delete or anonymize the data that the event names, then return a 2xx response. Finish each request within 30 days. business.redact is sent 48 hours after the app is uninstalled.

Review and Listing

A private app can be installed by its own business only. To list an app publicly, select Make public and submit it for review.
  • The review target is 5 business days.
  • Reviewers check the test credentials, redirect URIs, scopes and their reasons, the privacy policy and support URLs, the name and icon, and that your webhook endpoint returns 2xx for a test event.
  • If a reviewer rejects the app, you see the reason. Fix the issues and submit again.
  • A reviewer can suspend an app. A suspended app is hidden, its tokens are revoked, and its webhooks stop.

Change a Live App

When you edit a live app, the change goes to review. The live version, with its approved scopes, redirect URIs, and events, stays active until the change is approved. A rejected change does not affect the live version.
You cannot test a pending redirect URI. The authorization server uses the approved redirect URIs only. To test a new redirect URI, use a separate private app.

Test Before You List

Use the test link on the app page to let up to 25 other businesses install a private app or an app in review. Testers need the app_marketplace feature enabled. The app shows a Test app badge to them. If you rotate the test link, new businesses cannot join with the old link.

Rate Limits

Each pair of app and business is limited to 20 requests each second and 120 requests each minute. A call over the limit returns 429. Retry with a back-off.

Next Steps

Webhooks

Signature verification and retries.

API reference

All endpoints that an app can call.
Last modified on November 9, 2026