Create secure, hosted checkout experiences that handle the complete payment flow for both one-time purchases and subscriptions with full customization control.
Quick Start Guide
Get your first checkout session running in under 5 minutes
API Reference & Live Testing
Explore the full API documentation and interactively test Checkout Session requests and responses.
Preview Checkout
Calculate pricing, taxes, and totals before creating a session.
Session Validity: Checkout sessions are valid for 24 hours by default. If you pass confirm=true in your request, the session will only be valid for 15 minutes.
import DodoPayments from 'dodopayments';// Initialize the Dodo Payments clientconst client = new DodoPayments({ bearerToken: process.env.DODO_PAYMENTS_API_KEY, environment: 'test_mode', // defaults to 'live_mode'});async function createCheckoutSession() { try { const session = await client.checkoutSessions.create({ // Products to sell - use IDs from your Dodo Payments dashboard product_cart: [ { product_id: 'prod_123', // Replace with your actual product ID quantity: 1 } ], // Pre-fill customer information to reduce friction customer: { email: 'customer@example.com', name: 'John Doe', phone_number: '+1234567890' }, // Billing address for tax calculation and compliance billing_address: { street: '123 Main St', city: 'San Francisco', state: 'CA', country: 'US', // Required: ISO 3166-1 alpha-2 country code zipcode: '94102' }, // Where to redirect after successful payment return_url: 'https://yoursite.com/checkout/success', // Custom data for your internal tracking metadata: { order_id: 'order_123', source: 'web_app' } }); // Redirect your customer to this URL to complete payment console.log('Checkout URL:', session.checkout_url); console.log('Session ID:', session.session_id); return session; } catch (error) { console.error('Failed to create checkout session:', error); throw error; }}// Example usage in an Express.js routeapp.post('/create-checkout', async (req, res) => { try { const session = await createCheckoutSession(); res.json({ checkout_url: session.checkout_url }); } catch (error) { res.status(500).json({ error: 'Failed to create checkout session' }); }});
import osfrom dodopayments import DodoPayments# Initialize the Dodo Payments clientclient = DodoPayments( bearer_token=os.environ.get("DODO_PAYMENTS_API_KEY"), # This is the default and can be omitted environment="test_mode", # defaults to "live_mode")def create_checkout_session(): """ Create a checkout session for a single product with customer data pre-filled. Returns the session object containing checkout_url for customer redirection. """ try: session = client.checkout_sessions.create( # Products to sell - use IDs from your Dodo Payments dashboard product_cart=[ { "product_id": "prod_123", # Replace with your actual product ID "quantity": 1 } ], # Pre-fill customer information to reduce checkout friction customer={ "email": "customer@example.com", "name": "John Doe", "phone_number": "+1234567890" }, # Billing address for tax calculation and compliance billing_address={ "street": "123 Main St", "city": "San Francisco", "state": "CA", "country": "US", # Required: ISO 3166-1 alpha-2 country code "zipcode": "94102" }, # Where to redirect after successful payment return_url="https://yoursite.com/checkout/success", # Custom data for your internal tracking metadata={ "order_id": "order_123", "source": "web_app" } ) # Redirect your customer to this URL to complete payment print(f"Checkout URL: {session.checkout_url}") print(f"Session ID: {session.session_id}") return session except Exception as error: print(f"Failed to create checkout session: {error}") raise error# Example usage in a Flask routefrom flask import Flask, jsonify, requestapp = Flask(__name__)@app.route('/create-checkout', methods=['POST'])def create_checkout(): try: session = create_checkout_session() return jsonify({"checkout_url": session.checkout_url}) except Exception as error: return jsonify({"error": "Failed to create checkout session"}), 500
// Direct API call using fetch - useful for any JavaScript environmentasync function createCheckoutSession() { try { const response = await fetch('https://test.dodopayments.com/checkouts', { method: 'POST', headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${process.env.DODO_PAYMENTS_API_KEY}` }, body: JSON.stringify({ // Products to sell - use IDs from your Dodo Payments dashboard product_cart: [ { product_id: 'prod_123', // Replace with your actual product ID quantity: 1 } ], // Pre-fill customer information to reduce checkout friction customer: { email: 'customer@example.com', name: 'John Doe', phone_number: '+1234567890' }, // Billing address for tax calculation and compliance billing_address: { street: '123 Main St', city: 'San Francisco', state: 'CA', country: 'US', // Required: ISO 3166-1 alpha-2 country code zipcode: '94102' }, // Where to redirect after successful payment return_url: 'https://yoursite.com/checkout/success', // Custom data for your internal tracking metadata: { order_id: 'order_123', source: 'web_app' } }) }); if (!response.ok) { throw new Error(`HTTP error! status: ${response.status}`); } const session = await response.json(); // Redirect your customer to this URL to complete payment console.log('Checkout URL:', session.checkout_url); console.log('Session ID:', session.session_id); return session; } catch (error) { console.error('Failed to create checkout session:', error); throw error; }}// Example: Redirect user to checkoutcreateCheckoutSession().then(session => { window.location.href = session.checkout_url;});
Direct your customer to the checkout URL to complete their purchase.
// Redirect immediatelywindow.location.href = session.checkout_url;// Or open in new windowwindow.open(session.checkout_url, '_blank');
Alternative Integration Options: Instead of redirecting, you can embed the checkout directly in your page using Overlay Checkout (modal overlay) or Inline Checkout (fully embedded). Both options use the same checkout session URL.
3
Handle the return
After payment, customers are redirected to your return_url with query parameters including payment/subscription ID, status, customer email, and any license keys. See the return_url parameter docs for the full list.
Array of products to include in the checkout session. Each product must have a valid product_id from your Dodo Payments dashboard.
Mixed Checkout: You can combine one-time payment products and subscription products in the same checkout session. This enables powerful use cases like setup fees with subscriptions, hardware bundles with SaaS, and more.
Amount the customer pays if pay_what_you_want is enabled. If disabled, this field will be ignored.Formato: Representado en la denominación más baja de la moneda (por ejemplo, centavos para USD). Por ejemplo, para cobrar $1.00, pase 100.
Sobrescritura de créditos por sesión de compra ya adjuntos a este producto. Úselo para otorgar un número diferente de créditos para esta única sesión, por ejemplo, un paquete promocional que otorga 1,000 créditos API en lugar de los 500 predeterminados del producto, sin crear un producto separado.
Cada credit_entitlement_id debe estar ya adjunto al producto. Este campo solo sobrescribe el credits_amount otorgado cuando se cumple esta sesión; las configuraciones de créditos a nivel de producto (vencimiento, transferencia, etc.) aún se aplican.
Número de créditos a otorgar para esta sesión de compra, sobrescribiendo el credits_amount a nivel de producto. Debe ser mayor que cero.
Encuentra tus IDs de Producto: Puedes encontrar los IDs de producto en tu panel de Dodo Payments bajo Productos → Ver Detalles, o utilizando la API de Listado de Productos.
Número de teléfono del cliente en formato internacional. Requerido para algunos métodos de pago y prevención de fraudes.Formato: Incluir código de país, por ejemplo, "+1234567890" para números de EE.UU.
Dirección completa incluyendo número de la casa, nombre de la calle y número de apartamento/unidad si corresponde.Ejemplo: "123 Main St, Apt 4B" o "456 Oak Avenue"
Nombre del estado, provincia o región. Use nombres completos o abreviaturas estándar.Ejemplo: "California" o "CA", INLINE_CODE_PLACEHOLDER_03d80b84f8cbaa9_END o "ON"
Código de país ISO de dos letras (ISO 3166-1 alpha-2). Este campo es siempre obligatorio cuando se proporciona dirección de facturación.Ejemplos: "US" (Estados Unidos), "CA" (Canadá), "GB" (Reino Unido), "DE" (Alemania)
Country Code Reference
Ver lista completa de países soportados y sus códigos ISO
Controla qué métodos de pago están disponibles para los clientes durante la compra. Esto ayuda a optimizar para mercados específicos o requisitos de negocio.Opciones Disponibles: credit, debit, upi_collect, apple_pay, google_pay, amazon_pay, klarna, affirm, afterpay_clearpay, cashapp, multibanco, bancontact_card, eps, ideal, przelewy24, paypal, sunbit
Crítico: Siempre incluya credit y debit como opciones de respaldo para prevenir fallas en la compra cuando los métodos de pago preferidos no están disponibles.
Sobrescriba la selección de moneda predeterminada con una moneda de facturación fija. Utiliza códigos de moneda ISO 4217.Monedas soportadas: USD, EUR, GBP, CAD, AUD, INR, y másEjemplo: "USD" para dólares estadounidenses, "EUR" para euros
Este campo solo es efectivo cuando el precio adaptativo está habilitado. Si el precio adaptativo está deshabilitado, se usará la moneda predeterminada del producto.
URL para redirigir a los clientes tras la finalización del pago. Dodo Payments añade los siguientes parámetros de consulta a tu URL al redirigir:
Parámetro
Tipo
Condición
payment_id
string
Siempre presente para pagos únicos
subscription_id
string
Siempre presente para pagos de suscripción
status
string
Siempre presente
license_key
string
Presente si el producto tiene claves de licencia habilitadas. Separado por comas si hay múltiples claves
email
string
Presente si el cliente tiene un correo electrónico registrado
Ejemplos de URLs de redirección:
# One-time payment with license keyhttps://yoursite.com/return?payment_id=pay_xxx&status=succeeded&license_key=LK-001&email=customer%40example.com# Subscription payment with multiple license keyshttps://yoursite.com/return?subscription_id=sub_xxx&status=active&license_key=LK-001,LK-002&email=customer%40example.com# Payment without license keyshttps://yoursite.com/return?payment_id=pay_xxx&status=succeeded&email=customer%40example.com
Utilice los parámetros de consulta license_key e email para mostrar claves de licencia o enviar una confirmación inmediatamente en tu página de retorno, sin necesidad de una llamada API adicional.
URL para redirigir a los clientes cuando hacen clic en el botón de regreso o cancelan la sesión de compra. Si no se proporciona, no se mostrará el botón de regreso.
Establece un cancel_url para dar a los clientes una forma clara de regresar a tu sitio sin completar la compra. Esto mejora la experiencia de compra y reduce fricciones.
Aplicar uno o más códigos de descuento acumulativos a la sesión de compra. Los códigos se aplican en el orden del array (el primer código reduce el precio base, el segundo reduce el precio ya descontado, y así sucesivamente), hasta un máximo de 20 códigos por sesión.
discount_codes: ['WELCOME10', 'BLACKFRIDAY20']
El campo singular discount_code a continuación está obsoleto pero aún es plenamente compatible: las integraciones existentes continúan funcionando sin cambios. No se puede combinar con discount_codes en la misma solicitud. Migrar a discount_codes cuando sea conveniente para aprovechar el apilamiento.
Obsoleto — prefiera discount_codes para nuevas integraciones. Este campo aún funciona para compatibilidad con versiones anteriores, pero no se puede combinar con discount_codes en la misma solicitud.
Habilitar modo de recolección de dirección mínima. Cuando está habilitado, la compra solo recopila:
País: Siempre necesario para la determinación de impuestos
Código postal/ZIP: Solo en regiones donde es necesario para el cálculo de impuesto de ventas, IVA o GST
Esto reduce significativamente la fricción en la compra al eliminar campos de formulario innecesarios.
Habilitar dirección mínima para una finalización de compra más rápida. La recolección de dirección completa sigue disponible para empresas que requieren detalles completos de facturación.
Forzar que la interfaz de compra se muestre en un idioma específico. Por defecto, la compra autodetecta el idioma del navegador del cliente.Códigos de idioma soportados:ar (Árabe), ca (Catalán), de (Alemán), en (Inglés), es (Español), fr (Francés), he (Hebreo), id (Indonesio), it (Italiano), ja (Japonés), ko (Coreano), ms (Malayo), nl (Holandés), pl (Polaco), pt (Portugués), ro (Rumano), ru (Ruso), sv (Sueco), th (Tailandés), tr (Turco), zh (Chino)Ejemplo: "es" para Español, "ja" para Japonés
Habilitar modo de recolección de dirección mínima. Cuando está habilitado, la compra solo recopila:
País: Siempre necesario para la determinación de impuestos
Código postal/ZIP: Solo en regiones donde es necesario para el cálculo de impuesto de ventas, IVA o GST
Esto reduce significativamente la fricción en la compra al eliminar campos de formulario innecesarios.
Habilitar dirección mínima para una finalización de compra más rápida. La recolección de dirección completa sigue disponible para empresas que requieren detalles completos de facturación.
Saltar la página de éxito de pago predeterminada y redirigir a los clientes inmediatamente a tu return_url tras la finalización del pago.
Usa esto cuando tengas una página de éxito personalizada que ofrezca una mejor experiencia de usuario, o para aplicaciones móviles y flujos de compra integrados.
Recolectar información adicional de clientes durante la compra con campos de formulario personalizados. Puedes definir hasta 5 campos personalizados por sesión de compra. Las respuestas de los clientes se incluyen en las cargas útiles de los webhooks y están disponibles a través de la API.
Identificador único para este campo. Se utiliza como clave en cargas útiles de webhooks y respuestas API.Ejemplo: "company_name", "referral_source", "team_size"
Lista de opciones para el tipo de campo dropdown. Requerido cuando field_type es dropdown, ignorado para otros tipos.Ejemplo: ["Google", "Twitter", "Friend referral", "Other"]
Las respuestas del cliente a campos personalizados están incluidas en:
Webhooks: payment.succeeded, subscription.active y otras cargas útiles de eventos relevantes contienen el array custom_field_responses
Respuestas API: Los objetos de pago y suscripción incluyen custom_field_responses
Precio del producto para el cargo inicial al cliente. Si no se especifica, se usará el precio almacenado del producto.Formato: Representado en la denominación más baja de la moneda (por ejemplo, centavos para USD). Por ejemplo, para cobrar $1.00, pase 100.
Sobrescribir opcionalmente la descripción del producto para facturación y líneas de artículos. Si no se especifica, se usará la descripción almacenada del producto.
Si las tarifas de moneda adaptativa deben incluirse en el precio del producto (verdadero) o agregarse encima (falso). Ignorado si el precio adaptativo no está habilitado.
La sobrescritura billing_currency solo tiene efecto cuando la moneda adaptativa está habilitada en la configuración de tu cuenta. Si la moneda adaptativa está deshabilitada, este parámetro no tendrá efecto.
11. Usar Métodos de Pago Existentes para Compra Instantánea
Utiliza un método de pago guardado del cliente para crear una sesión de compra que se procese inmediatamente, omitiendo la recolección del método de pago:
const session = await client.checkoutSessions.create({ product_cart: [ { product_id: 'prod_premium_plan', quantity: 1 } ], customer: { customer_id: 'cus_123' // Required when using payment_method_id }, payment_method_id: 'pm_abc123', // Use customer's saved payment method confirm: true, // Required when using payment_method_id return_url: 'https://yourapp.com/success'});
Cuando uses payment_method_id, confirm debe estar configurado en true y debe proporcionarse un customer_id existente. El método de pago será validado para elegibilidad con la moneda del pago.
El método de pago debe pertenecer al cliente y ser compatible con la moneda del pago. Esto permite compras con un solo clic para clientes recurrentes.
Genera enlaces de pago acortados y compartibles con slugs personalizados:
const session = await client.checkoutSessions.create({ product_cart: [ { product_id: 'prod_monthly_subscription', quantity: 1 } ], short_link: true, // Generate a shortened payment link return_url: 'https://yourapp.com/success', customer: { email: 'customer@example.com', name: 'John Doe' }});// The checkout_url will be a shortened, cleaner linkconsole.log(session.checkout_url); // e.g., https://checkout.dodopayments.com/buy/abc123
Los enlaces cortos son perfectos para compartir por SMS, correo electrónico o redes sociales. Son más fáciles de recordar y generan más confianza que las URLs largas.
Usa redirect_immediately: true cuando tengas una página de éxito personalizada que ofrezca una mejor experiencia de usuario que la página de éxito de pago predeterminada. Esto es especialmente útil para aplicaciones móviles y flujos de compra integrados.
Cuando redirect_immediately está habilitado, los clientes son redirigidos a tu return_url inmediatamente tras la finalización del pago, omitiendo por completo la página de éxito predeterminada.
Usa force_language cuando conozcas el idioma preferido de tu cliente (por ejemplo, de la configuración de su cuenta) o cuando apuntas a mercados regionales específicos.
Las respuestas a campos personalizados se incluyen automáticamente en las cargas útiles de webhook (payment.succeeded, subscription.active, etc.) y pueden ser recuperadas a través de la API. Úsalas para enriquecer tu CRM, activar flujos de incorporación o personalizar la experiencia del cliente.
Tipos de campo disponibles:text, number, email, url, date, dropdown, boolean
Antes de crear una sesión de compra, puedes previsualizar el desglose de precios incluyendo impuestos, descuentos y totales. Esto es útil para mostrar precios precisos a los clientes antes de que procedan a la compra.
Anteriormente, al crear un enlace de pago con Enlaces Dinámicos, era necesario proporcionar la dirección de facturación completa del cliente.Con Sesiones de Compra, esto ya no es necesario. Simplemente puedes pasar la información que tengas, y nosotros nos encargaremos del resto. Por ejemplo:
Si solo conoces el país de facturación del cliente, solo proporciona eso.
El flujo de compra recogerá automáticamente los detalles que falten antes de mover al cliente a la página de pago.
Por otro lado, si ya tienes toda la información requerida y deseas saltar directamente a la página de pago, puedes pasar el conjunto completo de datos e incluir confirm=true en el cuerpo de tu solicitud.