checkout-integration
Guide for starting hosted Checkout Sessions, payment links, and overlay or inline checkout for one-time and recurring products; use subscription-integration for post-checkout lifecycle management.
By dodopayments · 889 installs
npx skills add dodopayments/skills --skill checkout-integration
Source repository · Upstream listing
Dodo Payments Checkout Integration
Use client.checkoutSessions.create(...) to build hosted checkout pages or overlay checkout modals. This is the recommended path for all new payment integrations.
When to use this skill
Build a one time payment checkout flow
Create a subscription checkout with optional trial
Embed checkout in an overlay or inline modal
Collect customer billing info and custom fields at checkout
Apply discount codes or handle currency selection
Redirect customers after payment completes
Checkout Methods
Dodo Payments offers three ways to collect payment:
Method Best For Setup
Checkout Sessions (recommended) Most integrations; full control Server side SDK call
Static Payment Links No code sharing; reusable URLs Dashboard or direct URL
Overlay/Inline Checkout Checkout stays on your site Client side SDK
Legacy: Dynamic Payment Links created via POST /payments or POST /subscriptions are deprecated. Use Checkout Sessions instead.
Core Concepts
Amounts in smallest currency unit: All prices are in cents (or equivalent). A $10 USD charge is 1000 .
Checkout Session: A single use session that generates a hosted checkout URL. Expires after 24 hours (or 15 minutes if confirm=true ).
Return URL: Where the customer lands after payment. Dodo appends payment id (one time) or subscription id (subscription), status , and when available license key and email . It is a UI hint only, never proof of payment.
Entitlement on webhook: The browser redirect is not the source of truth. Always verify payment via webhook before granting access. See webhook integration skill for verification.
Create a Checkout Session
Basic One Time Payment
Response fields:
session id : Unique checkout session ID
checkout url : Hosted checkout URL (redirect customer here). Nullable when confirm=true
client secret : Present only if confirm=true
publishable key : Present only if confirm=true . Pair it with client secret for the inline SDK flow
payment id : Present only if confirm=true
publishable key is a per session value returned for confirm mode inline checkout. It is not a Stripe style
publishable API key — Dodo issues no such credential, and every API key is secret and server side only.
With Multiple Products
With Existing Customer
With Billing Address and Tax ID
With Discount Codes
With Subscription and Trial
With Custom Fields
With Metadata
Next.js App Router
Full guide: [references/server examples.md](references/server examples.md).
Covers:
API Route
Client Component
Success Page
Express.js
Full guide: [references/server examples.md](references/server examples.md).
Python (FastAPI)
Full guide: [references/server examples.md](references/server examples.md).
Overlay Checkout
Full guide: [references/overlay checkout.md](references/overlay checkout.md).
Covers:
Installation
Server Route
Browser Overlay and Inline Modes
Static Payment Links
No code shareable links. No server side API call needed.
Basic Format
In test mode the host is test.checkout.dodopayments.com (for example https://test.checkout.dodopayments.com/buy/{productid} ); a test mode product does not exist on the live host.
Example:
With Query Parameters
Supported parameters:
quantity : Item quantity
redirect url : Success redirect URL
email : Prefill customer email
fullName , firstName , lastName : Prefill name
country , city , state , zipCode , addressLine : Prefill address
paymentCurrency : Force currency
metadata : Custom metadata (e.g., metadata orderId=123 )
Retrieve and Preview Sessions
Retrieve Session Status
Preview Session (without creating)
Customization
Theme and Appearance
Feature Flags
Post Payment Flow
Return URL Handling
After payment, the customer is redirected to your return url with query parameters:
Query parameters:
payment id (one time payments) or subscription id (subscriptions)
status : succeeded (one time) or active (subscription) on success; failed if declined; processing (or a requires value) if it settles later; expired if the session expired
license key : present when the product issues license keys (comma separated if several)
email : present when the customer has an email on record
There is no session id parameter. Treat processing /missing status as "unknown" and wait for the webhook.
Verify Payment Server Side
Do not trust the browser redirect. Use the Express webhook route in
[references/server examples.md](references/server examples.md expressjs): it receives the raw signed body
before express.json() , fulfills one time purchases on verified payment.succeeded using
event.data.customer.customer id , and grants subscription access only on verified subscription.active .
Webhook signature verification is covered in the webhook integration skill.
Common Mistakes
1. Granting access from the return URL
The return URL redirect is not proof of payment. Never grant access or fulfill an order from its query
parameters; wait for a verified webhook event.
2. Using deprecated APIs
Do not use client.payments.create() or client.subscriptions.create() for new integrations. Both are deprecated. Use client.checkoutSessions.create() .
3. Forgetting the environment flag
The default is live mode . Always set environment: 'test mode' during development to avoid charging real cards.
4. Using the deprecated discount code
Use discount codes (an array). The singular discount code string is deprecated (still accepted for backward compatibility) and cannot be combined with discount codes in the same request.
5. Amounts in wrong unit
All amounts are in the smallest currency unit (cents for USD). $10 is 1000 , not 10 .
6. Reusing checkout URLs
Checkout URLs are single use. Create a new session for each checkout attempt.
7. Ignoring confirm=true behavior
When confirm=true , the session is finalized immediately and the checkout URL expires in 15 minutes instead of 24 hours. Use only when you have all required customer data.
8. Forgetting raw body for webhooks
Webhook signature verification requires the raw request body, not a re serialized JSON object. Mount the
webhook route with express.raw({ type: 'application/json' }) before express.json() .
9. Trusting a client supplied product id
Do not accept an arbitrary pdt id from the browser. Authenticate the user, accept a public plan slug,
map it to an allowlisted product id on the server, and reject quantities that are not positive integers.
Resources
[Checkout Sessions Integration Guide](https://docs.dodopayments.com/developer resources/integration guide)
[Checkout Sessions API Reference](https://docs.dodopayments.com/api reference/checkout sessions/create)
[Overlay Checkout](https://docs.dodopayments.com/developer resources/overlay checkout)
[Inline Checkout](https://docs.dodopayments.com/developer resources/inline checkout)
[Static Payment Links](https://docs.dodopayments.com/developer resources/integration guide)
[Webhook Integration](https://docs.dodopayments.com/developer resources/webhooks)