Sequence for iterating results, and suspend functions for asynchronous calls.
Installation
Gradle (Kotlin DSL)
Add the dependency to yourbuild.gradle.kts:
build.gradle.kts
Maven
Add the dependency to yourpom.xml:
pom.xml
The SDK requires Java 8 or later. It runs on the JVM and on Android, and it ships ProGuard and R8 keep rules.
Quick Start
Create a client, then create a checkout session:fromEnv() connects to live mode unless DODO_PAYMENTS_BASE_URL or dodopayments.baseUrl says otherwise. To use test mode, see Test Mode. A test mode API key works only in test mode.
Core Features
Coroutines
The async client’s methods are
suspend functions that you call from a coroutine.Null Safety
Fields that can be missing are nullable types, not
Optional.Sequences
On the synchronous client,
autoPager() returns a Sequence that fetches more pages as you iterate. On the async client, it returns a Flow.Immutable Models
Model classes are immutable, and
toBuilder() returns a builder for a modified copy.Configuration
From Environment Variables
fromEnv() reads your settings from environment variables or system properties. System properties take precedence:
DODO_PAYMENTS_API_KEY or dodopayments.apiKey. The webhook signing secret comes from DODO_PAYMENTS_WEBHOOK_KEY or dodopayments.webhookKey, and the base URL from DODO_PAYMENTS_BASE_URL or dodopayments.baseUrl. Create one client and reuse it, because each client has its own connection pool and thread pools.
To verify a webhook, pass the raw request body and headers to client.webhooks().unwrap(UnwrapWebhookParams.builder().body(rawBody).headers(headers).build()), where headers is a com.dodopayments.api.core.http.Headers. It checks the signature with your webhook key and returns the parsed event, or throws DodoPaymentsWebhookException. Without headers, unwrap doesn’t verify the signature. client.webhooks().unsafeUnwrap(rawBody) parses the body without verifying it, so use it only for testing. See Webhooks.
Manual Configuration
Set each option on the builder:Test Mode
To use test mode (https://test.dodopayments.com), call testMode() on the builder:
Timeouts and Retries
By default, the client retries twice and times out after 1 minute. It retries connection errors and responses with status 408, 409, 429, or 500 and above, with exponential backoff. Set the defaults on the client, or passRequestOptions to a single call:
Common Operations
The examples in this section use theclient from Quick Start.
Create a Checkout Session
Create a checkout session, then redirect the customer to the returned checkout URL:checkoutUrl() returns a nullable String?. Each checkout URL works once and expires after 24 hours. For every session option, see Checkout Sessions.
Create a Product
Create a monthly subscription product priced at $29.99:price is in the smallest currency unit. discountBps sets the discount in basis points and replaces the deprecated discount field.
Activate License Key
Activate a license key for a device or installation. If the key has reached its activation limit, the API returns422 and the SDK throws UnprocessableEntityException. An inactive key returns 403 (PermissionDeniedException), and an unknown key returns 404 (NotFoundException):
Handle Subscriptions
Create a subscription, then charge it if it’s an on-demand subscription.billing requires only country, a two-letter ISO country code. Use AttachExistingCustomer to attach an existing customer, or NewCustomer to create one. charge is for on-demand subscriptions, and productPrice is in the smallest currency unit.Usage-Based Billing
Record Usage Events
Send a usage event for a customer. Meters that track the event’seventName aggregate it:
eventId is the idempotency key, so give each event a unique value. A request accepts up to 1,000 events.
Async Operations
Async Client
The async client has the same methods as the synchronous client, but most of them aresuspend functions. Call them from a coroutine:
client.async() on a synchronous client to get its async version.
Error Handling
For an error status, the SDK throws a subclass ofDodoPaymentsServiceException, which has statusCode(), headers(), and body(). The subclasses are BadRequestException (400), UnauthorizedException (401), PermissionDeniedException (403), NotFoundException (404), UnprocessableEntityException (422), RateLimitException (429), InternalServerException (5xx), and UnexpectedStatusCodeException for other statuses, such as 409:
DodoPaymentsIoException, and responses the SDK can’t interpret throw DodoPaymentsInvalidDataException. All SDK exceptions extend DodoPaymentsException.
Functional Error Handling
UseResult for functional error handling:
Android Integration
The Kotlin SDK is a server SDK. It authenticates with your secret API key, and anyone who has your APK can extract a key compiled into it, so never use it inside an Android app. To take payments in an Android app:- On your server, create the checkout session with this SDK (see Ktor Integration) and return its
checkout_url. - In the app, fetch that
checkout_urlfrom your server and open it with the Android SDK, which holds no API key.
Response Validation
By default, the SDK throwsDodoPaymentsInvalidDataException only when you read a property with an unexpected type. To check the whole response up front, enable validation for a request, or call validate() on a response:
Advanced Features
Proxy Configuration
To send requests through a proxy, pass ajava.net.Proxy to the builder:
Temporary Configuration
withOptions returns a client with modified settings that shares the original client’s connection and thread pools. The original client doesn’t change:
Ktor Integration
Create the client once and call it from a route:Resources
GitHub Repository
Source code, releases, and the full method list.
API Reference
Every endpoint, parameter, and response.
Discord Community
Ask questions and talk with other developers.
Report Issues
Report bugs or request features.
Support
For help with the Kotlin SDK:- Discord: Join the community server for real-time help.
- Email: Contact support@dodopayments.com.
- GitHub: Open an issue on the repository.