> ## Documentation Index
> Fetch the complete documentation index at: https://docs.dodopayments.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Checkout Sessions

> Create secure, hosted checkout experiences that handle the complete payment flow for both one-time purchases and subscriptions with full customization control.

<CardGroup cols={2}>
  <Card title="Quick Start Guide" icon="rocket" href="#creating-your-first-checkout-session">
    Get your first checkout session running in under 5 minutes
  </Card>

  <Card title="API Reference & Live Testing" icon="code" href="/api-reference/checkout-sessions/create">
    Explore the full API documentation and interactively test Checkout Session requests and responses.
  </Card>

  <Card title="Preview Checkout" icon="eye" href="/api-reference/checkout-sessions/preview">
    Calculate pricing, taxes, and totals before creating a session.
  </Card>
</CardGroup>

<Info>
  **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.
</Info>

## Prerequisites

<Steps>
  <Step title="Dodo Payments Account">
    You'll need an active Dodo Payments merchant account with API access.
  </Step>

  <Step title="API Credentials">
    Generate your API credentials from the Dodo Payments dashboard:
  </Step>

  <Step title="Products Setup">
    Create your products in the Dodo Payments dashboard before implementing checkout sessions.
  </Step>
</Steps>

## Creating Your First Checkout Session

<Tabs>
  <Tab title="Node.js SDK">
    ```javascript expandable theme={null}
    import DodoPayments from 'dodopayments';

    // Initialize the Dodo Payments client
    const 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 route
    app.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' });
      }
    });
    ```
  </Tab>

  <Tab title="Python SDK">
    ```python expandable theme={null}
    import os
    from dodopayments import DodoPayments

    # Initialize the Dodo Payments client
    client = 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 route
    from flask import Flask, jsonify, request

    app = 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
    ```
  </Tab>

  <Tab title="REST API">
    ```javascript expandable theme={null}
    // Direct API call using fetch - useful for any JavaScript environment
    async 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 checkout
    createCheckoutSession().then(session => {
      window.location.href = session.checkout_url;
    });
    ```
  </Tab>
</Tabs>

### API Response

All methods above return the same response structure:

```json theme={null}
{
  "session_id": "cks_Gi6KGJ2zFJo9rq9Ukifwa",
  "checkout_url": "https://test.checkout.dodopayments.com/session/cks_Gi6KGJ2zFJo9rq9Ukifwa"
}
```

<Steps>
  <Step title="Get the checkout URL">
    Extract the `checkout_url` from the API response.
  </Step>

  <Step title="Redirect your customer">
    Direct your customer to the checkout URL to complete their purchase.

    ```javascript theme={null}
    // Redirect immediately
    window.location.href = session.checkout_url;

    // Or open in new window
    window.open(session.checkout_url, '_blank');
    ```

    <Tip>
      **Alternative Integration Options**: Instead of redirecting, you can embed the checkout directly in your page using [Overlay Checkout](/developer-resources/overlay-checkout) (modal overlay) or [Inline Checkout](/developer-resources/inline-checkout) (fully embedded). Both options use the same checkout session URL.
    </Tip>
  </Step>

  <Step title="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](#request-body) for the full list.
  </Step>
</Steps>

## Request Body

<CardGroup cols={2}>
  <Card title="Required Fields" icon="asterisk">
    Essential fields needed for every checkout session
  </Card>

  <Card title="Optional Fields" icon="gear">
    Additional configuration to customize your checkout experience
  </Card>
</CardGroup>

### Required Fields

<ParamField body="product_cart" type="array" required>
  Array of products to include in the checkout session. Each product must have a valid `product_id` from your Dodo Payments dashboard.

  <Tip>
    **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.
  </Tip>

  <Expandable title="Product Cart Item Properties">
    <ParamField body="product_id" type="string" required>
      The unique identifier of the product from your Dodo Payments dashboard.

      **Example:** `"prod_123abc456def"`
    </ParamField>

    <ParamField body="quantity" type="integer" required>
      Quantity of the product.

      **Example:** `1` for single item, `3` for multiple quantities
    </ParamField>

    <ParamField body="addons" type="array">
      Array of addons to attach to the product. Only valid if the product is a subscription.

      <Expandable title="Addon item properties">
        <ParamField body="addon_id" type="string" required />

        <ParamField body="quantity" type="integer" required />
      </Expandable>
    </ParamField>

    <ParamField body="amount" type="integer">
      Amount the customer pays if pay\_what\_you\_want is enabled. If disabled, this field will be ignored.

      **Formato**: Representado na menor denominação da moeda (por exemplo, centavos para USD). Por exemplo, para cobrar \$1.00, passe `100`.
    </ParamField>

    <ParamField body="credit_entitlements" type="array">
      Substituições por sessão de checkout para direitos de crédito já associados a este produto. Use isso para conceder um número diferente de créditos para esta única sessão — por exemplo, um pacote promocional que concede 1.000 créditos de API em vez dos 500 padrão do produto — sem criar um produto separado.

      <Info>
        Cada `credit_entitlement_id` deve já estar anexado ao produto. Este campo substitui apenas o `credits_amount` concedido quando esta sessão é cumprida; as configurações de direito a crédito em nível de produto (expiração, acúmulo, etc.) ainda se aplicam.
      </Info>

      <Expandable title="Credit entitlement override properties">
        <ParamField body="credit_entitlement_id" type="string" required>
          ID do direito a crédito a ser substituído. Deve já estar anexado ao produto.
        </ParamField>

        <ParamField body="credits_amount" type="string" required>
          Número de créditos a serem concedidos para esta sessão de checkout, substituindo o `credits_amount` em nível de produto. Deve ser maior que zero.
        </ParamField>
      </Expandable>
    </ParamField>
  </Expandable>
</ParamField>

<Tip>
  **Encontre seus IDs de Produto**: Você pode encontrar os IDs de produtos no painel do Dodo Payments em Produtos → Ver Detalhes, ou usando o [API Listar Produtos](/api-reference/products/get-products).
</Tip>

### Campos Opcionais

Configure estes campos para personalizar a experiência de checkout e adicionar lógica de negócios ao seu fluxo de pagamento.

<AccordionGroup>
  <Accordion title="Customer Information">
    <ParamField body="customer" type="object">
      Informações do cliente. Você pode anexar um cliente existente usando seu ID ou criar um novo registro de cliente durante o checkout.

      <Tabs>
        <Tab title="Attach Existing Customer">
          Anexe um cliente existente à sessão de checkout usando seu ID.

          <Expandable title="Existing Customer Properties">
            <ParamField body="customer_id" type="string" required>
              O identificador único de um cliente existente. Use isso para anexar a sessão de checkout a um cliente existente, em vez de criar um novo.
            </ParamField>
          </Expandable>
        </Tab>

        <Tab title="New Customer">
          Crie um novo registro de cliente durante o checkout.

          <Expandable title="New Customer Properties">
            <ParamField body="email" type="string" required>
              Endereço de email do cliente. Necessário ao criar um novo cliente.
            </ParamField>

            <ParamField body="name" type="string">
              Nome completo do cliente conforme deve aparecer em recibos e faturas.

              **Exemplo**: `"John Doe"` ou `"Jane Smith"`
            </ParamField>

            <ParamField body="phone_number" type="string">
              Número de telefone do cliente em formato internacional. Necessário para alguns métodos de pagamento e prevenção de fraudes.

              **Formato**: Inclua o código do país, por exemplo, `"+1234567890"` para números dos EUA
            </ParamField>
          </Expandable>
        </Tab>
      </Tabs>
    </ParamField>

    <ParamField body="billing_address" type="object">
      Informações de endereço de cobrança para cálculo preciso de impostos, prevenção de fraudes e conformidade regulatória.

      <Info>
        Quando `confirm` é definido como `true`, todos os campos de endereço de cobrança se tornam obrigatórios para a criação bem-sucedida da sessão.
      </Info>

      <Expandable title="Billing address object properties">
        <ParamField body="street" type="string">
          Endereço completo incluindo número da casa, nome da rua e número do apartamento/unidade, se aplicável.

          **Exemplo**: `"123 Main St, Apt 4B"` ou `"456 Oak Avenue"`
        </ParamField>

        <ParamField body="city" type="string">
          Nome da cidade ou município.

          **Exemplo**: `"San Francisco"`, `"New York"`, `"London"`
        </ParamField>

        <ParamField body="state" type="string">
          Nome do estado, província ou região. Use nomes completos ou abreviações padrão.

          **Exemplo**: `"California"` ou `"CA"`, `"Ontario"` ou `"ON"`
        </ParamField>

        <ParamField body="country" type="string" required>
          Código ISO de país de duas letras (ISO 3166-1 alpha-2). Este campo é sempre necessário quando endereço\_de\_cobrança é fornecido.

          **Exemplos**: `"US"` (Estados Unidos), `"CA"` (Canadá), `"GB"` (Reino Unido), `"DE"` (Alemanha)

          <Card title="Country Code Reference" icon="globe" href="/api-reference/misc/supported-countries">
            Veja a lista completa de países suportados e seus códigos ISO
          </Card>
        </ParamField>

        <ParamField body="zipcode" type="string">
          Código postal, CEP ou equivalente com base nos requisitos do país.

          **Exemplos**: `"94102"` (EUA), `"M5V 3A8"` (Canadá), `"SW1A 1AA"` (Reino Unido)
        </ParamField>
      </Expandable>
    </ParamField>
  </Accordion>

  <Accordion title="Payment Configuration">
    <ParamField body="allowed_payment_method_types" type="array">
      Controle quais métodos de pagamento estão disponíveis para clientes durante o checkout. Isso ajuda a otimizar para mercados específicos ou requisitos de negócios.

      **Opções Disponíveis**: `credit`, `debit`, `upi_collect`, `apple_pay`, `google_pay`, `amazon_pay`, `klarna`, `affirm`, `afterpay_clearpay`, `cashapp`, `multibanco`, `bancontact_card`, `eps`, `ideal`, `przelewy24`, `paypal`, `sunbit`

      <Warning>
        **Crítico**: Sempre inclua `credit` e `debit` como opções de fallback para evitar falhas no checkout quando métodos de pagamento preferidos não estão disponíveis.
      </Warning>

      **Exemplo**:

      ```json expandable theme={null}
      ["apple_pay", "google_pay", "credit", "debit"]
      ```
    </ParamField>

    <ParamField body="billing_currency" type="string">
      Substitua a seleção de moeda padrão com uma moeda de cobrança fixa. Usado códigos de moeda ISO 4217.

      **Moedas Suportadas**: `USD`, `EUR`, `GBP`, `CAD`, `AUD`, `INR`, e mais

      **Exemplo**: `"USD"` para Dólares Americanos, `"EUR"` para Euros

      <Note>
        Este campo só é efetivo quando o precificação adaptativa está ativado. Se a precificação adaptativa estiver desativada, a moeda padrão do produto será usada.
      </Note>
    </ParamField>

    <ParamField body="show_saved_payment_methods" type="boolean" default="false">
      Exiba métodos de pagamento salvos anteriormente para clientes retornantes, melhorando a velocidade do checkout e a experiência do usuário.
    </ParamField>
  </Accordion>

  <Accordion title="Session Management">
    <ParamField body="return_url" type="string">
      URL para redirecionar os clientes após a conclusão do pagamento. O aplicativo Dodo Payments anexa os seguintes parâmetros de consulta ao seu URL ao redirecionar:

      | Parâmetro         | Tipo     | Condição                                                                                          |
      | ----------------- | -------- | ------------------------------------------------------------------------------------------------- |
      | `payment_id`      | `string` | Sempre presente para pagamentos únicos                                                            |
      | `subscription_id` | `string` | Sempre presente para pagamentos de assinatura                                                     |
      | `status`          | `string` | Sempre presente                                                                                   |
      | `license_key`     | `string` | Presente se o produto tiver chaves de licença ativadas. Separado por vírgulas se múltiplas chaves |
      | `email`           | `string` | Presente se o cliente tiver um email registrado                                                   |

      **Exemplos de URLs de redirecionamento:**

      ```text theme={null}
      # One-time payment with license key
      https://yoursite.com/return?payment_id=pay_xxx&status=succeeded&license_key=LK-001&email=customer%40example.com

      # Subscription payment with multiple license keys
      https://yoursite.com/return?subscription_id=sub_xxx&status=active&license_key=LK-001,LK-002&email=customer%40example.com

      # Payment without license keys
      https://yoursite.com/return?payment_id=pay_xxx&status=succeeded&email=customer%40example.com
      ```

      <Tip>
        Use os parâmetros de consulta `license_key` e `email` para exibir chaves de licença ou enviar uma confirmação imediatamente em sua página de retorno, sem precisar de uma chamada de API extra.
      </Tip>
    </ParamField>

    <ParamField body="cancel_url" type="string">
      URL para redirecionar clientes quando clicam no botão voltar ou cancelam a sessão de checkout. Se não for fornecido, o botão voltar não será exibido.

      <Tip>
        Defina um `cancel_url` para dar aos clientes um caminho claro para retornar ao seu site sem completar a compra. Isso melhora a experiência de checkout e reduz atritos.
      </Tip>
    </ParamField>

    <ParamField body="confirm" type="boolean" default="false">
      Se verdadeiro, finaliza todos os detalhes da sessão imediatamente. A API lançará um erro se dados obrigatórios estiverem ausentes.
    </ParamField>

    <ParamField body="discount_codes" type="array">
      Aplique um ou mais códigos de desconto empilhados à sessão de checkout. Os códigos são aplicados **na ordem do array** (o primeiro código reduz o preço base, o segundo reduz o preço já com desconto e assim por diante), até um máximo de **20** códigos por sessão.

      ```typescript theme={null}
      discount_codes: ['WELCOME10', 'BLACKFRIDAY20']
      ```

      <Info>
        O campo singular `discount_code` abaixo está **obsoleto** mas ainda totalmente suportado — integrações existentes continuam funcionando sem alterações. Não pode ser combinado com `discount_codes` na mesma solicitação. Migre para `discount_codes` quando conveniente para aproveitar as vantagens da empilhamento.
      </Info>
    </ParamField>

    <ParamField body="discount_code" type="string" deprecated>
      **Obsoleto** — prefira `discount_codes` para novas integrações. Este campo ainda funciona para compatibilidade com versões anteriores, mas não pode ser combinado com `discount_codes` na mesma solicitação.
    </ParamField>

    <ParamField body="metadata" type="object">
      Pares de chave-valor personalizados para armazenar informações adicionais sobre a sessão.
    </ParamField>

    <ParamField body="force_3ds" type="boolean">
      Substitua o comportamento padrão do 3DS do comerciante para esta sessão.
    </ParamField>

    <ParamField body="minimal_address" type="boolean" default="false">
      Habilite o modo de coleta mínima de endereço. Quando habilitado, o checkout coleta apenas:

      * **País**: Sempre necessário para determinação de impostos
      * **Código Postal/CEP**: Apenas em regiões onde é necessário para cálculo de imposto sobre vendas, IVA ou GST

      Isso reduz significativamente o atrito no checkout eliminando campos de formulário desnecessários.

      <Tip>
        Habilite o endereço mínimo para a conclusão mais rápida do checkout. A coleta completa de endereço permanece disponível para empresas que exigem detalhes completos de cobrança.
      </Tip>
    </ParamField>
  </Accordion>

  <Accordion title="UI Customization & Features">
    <ParamField body="customization" type="object">
      Personalize a aparência e o comportamento da interface de checkout.

      <Expandable title="Customization object properties">
        <ParamField body="theme" type="string" default="system">
          Tema para a interface de checkout. Opções: `light`, `dark` ou `system`.
        </ParamField>

        <ParamField body="show_order_details" type="boolean" default="true">
          Exibir seção de detalhes do pedido na interface de checkout.
        </ParamField>

        <ParamField body="show_on_demand_tag" type="boolean" default="true">
          Mostrar a tag "sob demanda" para produtos aplicáveis.
        </ParamField>

        <ParamField body="force_language" type="string">
          Force a interface de checkout a renderizar em um idioma específico. Por padrão, o checkout detecta automaticamente o idioma do navegador do cliente.

          **Códigos de idiomas suportados:**
          `ar` (Árabe), `ca` (Catalão), `de` (Alemão), `en` (Inglês), `es` (Espanhol), `fr` (Francês), `he` (Hebraico), `id` (Indonésio), `it` (Italiano), `ja` (Japonês), `ko` (Coreano), `ms` (Malaio), `nl` (Holandês), `pl` (Polonês), `pt` (Português), `ro` (Romeno), `ru` (Russo), `sv` (Sueco), `th` (Tailandês), `tr` (Turco), `zh` (Chinês)

          **Exemplo**: `"es"` para Espanhol, `"ja"` para Japonês
        </ParamField>
      </Expandable>
    </ParamField>

    <ParamField body="feature_flags" type="object">
      Configure recursos e comportamentos específicos para a sessão de checkout.

      <Expandable title="Feature flags object properties">
        <ParamField body="allow_currency_selection" type="boolean" default="true">
          Permita que os clientes selecionem sua moeda preferida durante o checkout.
        </ParamField>

        <ParamField body="allow_discount_code" type="boolean" default="true">
          Mostrar campo de entrada de código de desconto na interface de checkout.
        </ParamField>

        <ParamField body="allow_editing_addons" type="boolean" default="false">
          Permitir que os clientes adicionem ou removam complementos em um produto de assinatura durante o checkout. Aplica-se apenas a produtos de assinatura.
        </ParamField>

        <ParamField body="allow_phone_number_collection" type="boolean" default="true">
          Coletar números de telefone dos clientes durante o checkout.
        </ParamField>

        <ParamField body="allow_tax_id" type="boolean" default="true">
          Permitir que os clientes insiram números de identificação fiscal.
        </ParamField>

        <ParamField body="always_create_new_customer" type="boolean" default="false">
          Forçar a criação de um novo registro de cliente em vez de atualizar os existentes.
        </ParamField>

        <ParamField body="allow_customer_editing_email" type="boolean">
          Permitir que os clientes editem seu endereço de e-mail durante o checkout.
        </ParamField>

        <ParamField body="allow_customer_editing_name" type="boolean">
          Permitir que os clientes editem seu nome durante o checkout.
        </ParamField>

        <ParamField body="allow_customer_editing_street" type="boolean">
          Permitir que os clientes editem o endereço da rua durante o checkout.
        </ParamField>

        <ParamField body="allow_customer_editing_city" type="boolean">
          Permitir que os clientes editem a cidade durante o checkout.
        </ParamField>

        <ParamField body="allow_customer_editing_state" type="boolean">
          Permitir que os clientes editem o estado durante o checkout.
        </ParamField>

        <ParamField body="allow_customer_editing_country" type="boolean">
          Permitir que os clientes editem o país durante o checkout.
        </ParamField>

        <ParamField body="allow_customer_editing_zipcode" type="boolean">
          Permitir que os clientes editem o CEP durante o checkout.
        </ParamField>

        <ParamField body="redirect_immediately" type="boolean" default="false">
          Pular a página padrão de sucesso de pagamento e redirecionar os clientes imediatamente para seu `return_url` após a conclusão do pagamento.

          <Tip>
            Use isso quando você tiver uma página de sucesso personalizada que proporcione uma melhor experiência ao usuário ou para aplicativos móveis e fluxos de checkout incorporados.
          </Tip>
        </ParamField>
      </Expandable>
    </ParamField>
  </Accordion>

  <Accordion title="Custom Fields">
    <ParamField body="custom_fields" type="array">
      Coletar informações adicionais dos clientes durante o checkout com campos de formulário personalizados. Você pode definir até 5 campos personalizados por sessão de checkout. As respostas dos clientes estão incluídas nas cargas úteis do webhook e disponíveis via API.

      <Expandable title="Custom field object properties">
        <ParamField body="key" type="string" required>
          Identificador único para este campo. Usado como chave nas cargas úteis do webhook e nas respostas da API.

          **Exemplo**: `"company_name"`, `"referral_source"`, `"team_size"`
        </ParamField>

        <ParamField body="label" type="string" required>
          Etiqueta de exibição mostrada ao cliente no formulário de checkout.

          **Exemplo**: `"Company Name"`, `"How did you hear about us?"`, `"Team Size"`
        </ParamField>

        <ParamField body="field_type" type="string" required>
          Tipo de campo que determina as regras de validação de entrada.

          **Tipos disponíveis**:

          * `text` - Entrada de texto de uma linha
          * `number` - Entrada numérica
          * `email` - Endereço de e-mail com validação
          * `url` - URL com validação
          * `date` - Seletor de data
          * `dropdown` - Selecionar a partir de opções predefinidas
          * `boolean` - Alternar Sim/Não
        </ParamField>

        <ParamField body="required" type="boolean" default="false">
          Se este campo precisa ser preenchido antes de o checkout ser concluído.
        </ParamField>

        <ParamField body="placeholder" type="string">
          Texto do placeholder exibido no campo de entrada.
        </ParamField>

        <ParamField body="options" type="array">
          Lista de opções para o tipo de campo `dropdown`. Necessário quando `field_type` é `dropdown`, ignorado para outros tipos.

          **Exemplo**: `["Google", "Twitter", "Friend referral", "Other"]`
        </ParamField>
      </Expandable>
    </ParamField>

    <Info>
      As respostas dos clientes aos campos personalizados estão incluídas em:

      * **Webhooks**: `payment.succeeded`, `subscription.active` e outros eventos relevantes contêm o array `custom_field_responses`
      * **Respostas da API**: Objetos de pagamento e assinatura incluem `custom_field_responses`
    </Info>
  </Accordion>

  <Accordion title="Subscription Configuration">
    <ParamField body="subscription_data" type="object">
      Configuração adicional para sessões de checkout contendo produtos de assinatura.

      <Expandable title="Subscription data object properties">
        <ParamField body="trial_period_days" type="integer">
          Número de dias para o período de teste antes da primeira cobrança. Deve estar entre 0 e 10.000 dias.
        </ParamField>

        <ParamField body="on_demand" type="object">
          Configuração de assinatura sob demanda para faturamento baseado em uso ou medido.

          <Expandable title="On-demand object properties">
            <ParamField body="mandate_only" type="boolean" required>
              Se definido como verdadeiro, não realiza nenhuma cobrança e apenas autoriza os detalhes do método de pagamento para uso futuro.
            </ParamField>

            <ParamField body="product_price" type="integer">
              Preço do produto para a cobrança inicial ao cliente. Se não especificado, será usado o preço armazenado do produto.

              **Formato**: Representado na menor denominação da moeda (por exemplo, centavos para USD). Por exemplo, para cobrar \$1,00, passe `100`.
            </ParamField>

            <ParamField body="product_currency" type="string">
              Moeda opcional do preço do produto. Se não especificado, o padrão é a moeda do produto.
            </ParamField>

            <ParamField body="product_description" type="string">
              Descrição opcional do produto substituída para faturamento e itens de linha. Se não especificado, será usada a descrição armazenada do produto.
            </ParamField>

            <ParamField body="adaptive_currency_fees_inclusive" type="boolean">
              Se as taxas de câmbio adaptativas devem ser incluídas no preço do produto (verdadeiro) ou adicionadas separadamente (falso). Ignorado se o preço adaptativo não estiver ativado.
            </ParamField>
          </Expandable>
        </ParamField>
      </Expandable>
    </ParamField>
  </Accordion>
</AccordionGroup>

## Exemplos de Uso

Aqui estão 10 exemplos abrangentes mostrando diferentes configurações de sessão de checkout para vários cenários de negócios:

### 1. Checkout Simples de Produto Único

```javascript expandable theme={null}
const session = await client.checkoutSessions.create({
  product_cart: [
    {
      product_id: 'prod_ebook_guide',
      quantity: 1
    }
  ],
  customer: {
    email: 'customer@example.com',
    name: 'John Doe'
  },
  return_url: 'https://yoursite.com/success'
});
```

### 2. Carrinho com Múltiplos Produtos

```javascript expandable theme={null}
const session = await client.checkoutSessions.create({
  product_cart: [
    {
      product_id: 'prod_laptop',
      quantity: 1
    },
    {
      product_id: 'prod_mouse',
      quantity: 2
    },
    {
      product_id: 'prod_warranty',
      quantity: 1
    }
  ],
  customer: {
    email: 'customer@example.com',
    name: 'John Doe',
    phone_number: '+1234567890'
  },
  billing_address: {
    street: '123 Tech Street',
    city: 'San Francisco',
    state: 'CA',
    country: 'US',
    zipcode: '94102'
  },
  return_url: 'https://electronics-store.com/order-confirmation'
});
```

### 3. Assinatura com Período de Teste

```javascript expandable theme={null}
const session = await client.checkoutSessions.create({
  product_cart: [
    {
      product_id: 'prod_monthly_plan',
      quantity: 1
    }
  ],
  subscription_data: {
    trial_period_days: 14
  },
  customer: {
    email: 'user@startup.com',
    name: 'Jane Smith'
  },
  return_url: 'https://saas-app.com/onboarding',
  metadata: {
    plan_type: 'professional',
    referral_source: 'google_ads'
  }
});
```

### 4. Checkout Pré-confirmado

<Note>
  Quando `confirm` é definido como `true`, o cliente será direcionado diretamente para a página de checkout, ignorando quaisquer etapas de confirmação.
</Note>

```javascript expandable theme={null}
const session = await client.checkoutSessions.create({
  product_cart: [
    {
      product_id: 'prod_premium_course',
      quantity: 1
    }
  ],
  customer: {
    email: 'student@university.edu',
    name: 'Alex Johnson',
    phone_number: '+1555123456'
  },
  billing_address: {
    street: '456 University Ave',
    city: 'Boston',
    state: 'MA',
    country: 'US',
    zipcode: '02134'
  },
  confirm: true,
  return_url: 'https://learning-platform.com/course-access',
  metadata: {
    course_category: 'programming',
    enrollment_date: '2024-01-15'
  }
});
```

### 5. Checkout com Sobrescrita de Moeda

<Note>
  A sobrescrita `billing_currency` só tem efeito quando a moeda adaptativa está ativada nas configurações da sua conta. Se a moeda adaptativa estiver desativada, esse parâmetro não terá efeito.
</Note>

```javascript expandable theme={null}
const session = await client.checkoutSessions.create({
  product_cart: [
    {
      product_id: 'prod_consulting_service',
      quantity: 1
    }
  ],
  customer: {
    email: 'client@company.co.uk',
    name: 'Oliver Williams'
  },
  billing_address: {
    street: '789 Business Park',
    city: 'London',
    state: 'England',
    country: 'GB',
    zipcode: 'SW1A 1AA'
  },
  billing_currency: 'GBP',
  feature_flags: {
    allow_currency_selection: true,
    allow_tax_id: true
  },
  return_url: 'https://consulting-firm.com/service-confirmation'
});
```

### 6. Métodos de Pagamento Salvos para Clientes Retornantes

```javascript expandable theme={null}
const session = await client.checkoutSessions.create({
  product_cart: [
    {
      product_id: 'prod_monthly_subscription',
      quantity: 1
    }
  ],
  customer: {
    email: 'returning.customer@example.com',
    name: 'Robert Johnson',
    phone_number: '+1555987654'
  },
  show_saved_payment_methods: true,
  feature_flags: {
    allow_phone_number_collection: true,
    always_create_new_customer: false
  },
  return_url: 'https://subscription-service.com/welcome-back',
  metadata: {
    customer_tier: 'premium',
    account_age: 'returning'
  }
});
```

### 7. Checkout B2B com Coleta de ID Fiscal

```javascript expandable theme={null}
const session = await client.checkoutSessions.create({
  product_cart: [
    {
      product_id: 'prod_enterprise_license',
      quantity: 5
    }
  ],
  customer: {
    email: 'procurement@enterprise.com',
    name: 'Sarah Davis',
    phone_number: '+1800555000'
  },
  billing_address: {
    street: '1000 Corporate Blvd',
    city: 'New York',
    state: 'NY',
    country: 'US',
    zipcode: '10001'
  },
  feature_flags: {
    allow_tax_id: true,
    allow_phone_number_collection: true,
    always_create_new_customer: false
  },
  return_url: 'https://enterprise-software.com/license-delivery',
  metadata: {
    customer_type: 'enterprise',
    contract_id: 'ENT-2024-001',
    sales_rep: 'john.sales@company.com'
  }
});
```

### 8. Checkout com Tema Escuro com Códigos de Desconto Acumulados

```javascript expandable theme={null}
const session = await client.checkoutSessions.create({
  product_cart: [
    {
      product_id: 'prod_gaming_chair',
      quantity: 1
    }
  ],
  discount_codes: ['BLACKFRIDAY2024'],
  customization: {
    theme: 'dark',
    show_order_details: true,
    show_on_demand_tag: false
  },
  feature_flags: {
    allow_discount_code: true
  },
  customer: {
    email: 'gamer@example.com',
    name: 'Mike Chen'
  },
  return_url: 'https://gaming-store.com/order-complete'
});
```

### 9. Métodos de Pagamento Regionais (UPI para Índia)

Para informações detalhadas sobre configuração e teste do UPI, veja a página <a href="/features/payment-methods/india">Métodos de Pagamento na Índia</a>.

```javascript expandable theme={null}
const session = await client.checkoutSessions.create({
  product_cart: [
    {
      product_id: 'prod_online_course_hindi',
      quantity: 1
    }
  ],
  allowed_payment_method_types: [
    'upi_collect',
    'credit',
    'debit'
  ],
  customer: {
    email: 'student@example.in',
    name: 'Priya Sharma',
    phone_number: '+919876543210'
  },
  billing_address: {
    street: 'MG Road',
    city: 'Bangalore',
    state: 'Karnataka',
    country: 'IN',
    zipcode: '560001'
  },
  billing_currency: 'INR',
  return_url: 'https://education-platform.in/course-access',
  metadata: {
    region: 'south_india',
    language: 'hindi'
  }
});
```

### 10. Checkout BNPL (Compre Agora Pague Depois)

Para informações detalhadas sobre configuração e teste do BNPL, veja a página <a href="/features/payment-methods/bnpl">Compre Agora Pague Depois (BNPL)</a>.

```javascript expandable theme={null}
const session = await client.checkoutSessions.create({
  product_cart: [
    {
      product_id: 'prod_luxury_watch',
      quantity: 1
    }
  ],
  allowed_payment_method_types: [
    'klarna',
    'afterpay_clearpay',
    'credit',
    'debit'
  ],
  customer: {
    email: 'fashion.lover@example.com',
    name: 'Emma Thompson',
    phone_number: '+1234567890'
  },
  billing_address: {
    street: '555 Fashion Ave',
    city: 'Los Angeles',
    state: 'CA',
    country: 'US',
    zipcode: '90210'
  },
  feature_flags: {
    allow_phone_number_collection: true
  },
  return_url: 'https://luxury-store.com/purchase-confirmation',
  metadata: {
    product_category: 'luxury',
    price_range: 'high_value'
  }
});
```

### 11. Usando Métodos de Pagamento Existentes para Checkout Instantâneo

Use um método de pagamento salvo do cliente para criar uma sessão de checkout que processa imediatamente, pulando a coleta do método de pagamento:

```javascript expandable theme={null}
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'
});
```

<Warning>
  Ao usar `payment_method_id`, `confirm` deve ser definido como `true` e um `customer_id` existente deve ser fornecido. O método de pagamento será validado para a moeda da transação.
</Warning>

<Info>
  O método de pagamento deve pertencer ao cliente e ser compatível com a moeda da transação. Isso permite compras com um clique para clientes retornantes.
</Info>

### 12. Links Curtos para URLs de Pagamento Mais Limpos

Gere links de pagamento encurtados e compartilháveis com slugs personalizados:

```javascript expandable theme={null}
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 link
console.log(session.checkout_url);  // e.g., https://checkout.dodopayments.com/buy/abc123
```

<Tip>
  Links curtos são perfeitos para compartilhamento via SMS, e-mail ou redes sociais. Eles são mais fáceis de lembrar e geram mais confiança do que URLs longas.
</Tip>

### 13. Pulando Página de Sucesso do Pagamento com Redirecionamento Imediato

Redirecione os clientes imediatamente após a conclusão do pagamento, pulando a página padrão de sucesso:

```javascript expandable theme={null}
const session = await client.checkoutSessions.create({
  product_cart: [
    {
      product_id: 'prod_digital_product',
      quantity: 1
    }
  ],
  feature_flags: {
    redirect_immediately: true  // Skip success page, redirect immediately
  },
  return_url: 'https://yourapp.com/success',
  customer: {
    email: 'customer@example.com',
    name: 'Jane Smith'
  }
});
```

<Tip>
  Use `redirect_immediately: true` quando você tiver uma página de sucesso personalizada que forneça uma melhor experiência ao usuário do que a página padrão de sucesso de pagamento. Isso é especialmente útil para aplicativos móveis e fluxos de checkout incorporados.
</Tip>

<Note>
  Quando `redirect_immediately` está habilitado, os clientes são redirecionados para seu `return_url` imediatamente após a conclusão do pagamento, pulando totalmente a página de sucesso padrão.
</Note>

### 14. Forçando um Idioma

Forçar o checkout a ser exibido em um idioma específico, substituindo a detecção de idioma do navegador do cliente:

```javascript expandable theme={null}
const session = await client.checkoutSessions.create({
  product_cart: [
    {
      product_id: 'prod_subscription',
      quantity: 1
    }
  ],
  customization: {
    force_language: 'ja'  // Force Japanese language
  },
  customer: {
    email: 'customer@example.jp',
    name: 'Tanaka Yuki'
  },
  return_url: 'https://yourapp.com/success'
});
```

<Tip>
  Use `force_language` quando você souber o idioma preferido do cliente (por exemplo, a partir das configurações da conta) ou ao segmentar mercados regionais específicos.
</Tip>

**Idiomas suportados:** Árabe (`ar`), Catalão (`ca`), Chinês (`zh`), Holandês (`nl`), Inglês (`en`), Francês (`fr`), Alemão (`de`), Hebraico (`he`), Indonésio (`id`), Italiano (`it`), Japonês (`ja`), Coreano (`ko`), Malaio (`ms`), Polonês (`pl`), Português (`pt`), Romeno (`ro`), Russo (`ru`), Espanhol (`es`), Sueco (`sv`), Tailandês (`th`), Turco (`tr`)

### 15. Coletando Campos Personalizados

Colete informações adicionais dos clientes durante o checkout usando campos personalizados:

```javascript expandable theme={null}
const session = await client.checkoutSessions.create({
  product_cart: [
    {
      product_id: 'prod_saas_plan',
      quantity: 1
    }
  ],
  custom_fields: [
    {
      key: 'company_name',
      label: 'Company Name',
      field_type: 'text',
      required: true,
      placeholder: 'Acme Inc.'
    },
    {
      key: 'team_size',
      label: 'Team Size',
      field_type: 'dropdown',
      required: true,
      options: ['1-10', '11-50', '51-200', '201-500', '500+']
    },
    {
      key: 'referral_source',
      label: 'How did you hear about us?',
      field_type: 'dropdown',
      required: false,
      options: ['Google', 'Twitter', 'Friend referral', 'Blog post', 'Other']
    },
    {
      key: 'website',
      label: 'Company Website',
      field_type: 'url',
      required: false,
      placeholder: 'https://example.com'
    }
  ],
  customer: {
    email: 'buyer@company.com',
    name: 'Jane Doe'
  },
  return_url: 'https://yourapp.com/success'
});
```

<Info>
  As respostas dos campos personalizados são automaticamente incluídas nas cargas úteis do webhook (`payment.succeeded`, `subscription.active`, etc.) e podem ser recuperadas via API. Use-os para enriquecer seu CRM, acionar fluxos de integração ou personalizar a experiência do cliente.
</Info>

**Tipos de campo disponíveis:** `text`, `number`, `email`, `url`, `date`, `dropdown`, `boolean`

## Pré-visualização de Sessões de Checkout

Antes de criar uma sessão de checkout, você pode pré-visualizar a discriminação de preços incluindo impostos, descontos e totais. Isso é útil para exibir preços precisos aos clientes antes de procederem ao checkout.

<Tabs>
  <Tab title="Node.js SDK">
    ```javascript theme={null}
    const preview = await client.checkoutSessions.preview({
      product_cart: [
        { product_id: 'prod_123', quantity: 1 }
      ],
      billing_address: {
        country: 'US',
        state: 'CA',
        zipcode: '94102'
      },
      discount_codes: ['SAVE20']
    });

    console.log('Subtotal:', preview.subtotal);
    console.log('Tax:', preview.tax);
    console.log('Discount:', preview.discount);
    console.log('Total:', preview.total);
    ```
  </Tab>

  <Tab title="Python SDK">
    ```python theme={null}
    preview = client.checkout_sessions.preview(
        product_cart=[
            {"product_id": "prod_123", "quantity": 1}
        ],
        billing_address={
            "country": "US",
            "state": "CA",
            "zipcode": "94102"
        },
        discount_codes=["SAVE20"]
    )

    print(f"Subtotal: {preview.subtotal}")
    print(f"Tax: {preview.tax}")
    print(f"Discount: {preview.discount}")
    print(f"Total: {preview.total}")
    ```
  </Tab>
</Tabs>

<Card title="Preview API Reference" icon="code" href="/api-reference/checkout-sessions/preview">
  Veja a documentação completa do endpoint de pré-visualização.
</Card>

## Mudando de Links Dinâmicos para Sessões de Checkout

### Diferenças Principais

Anteriormente, ao criar um link de pagamento com Links Dinâmicos, era necessário fornecer o endereço completo de cobrança do cliente.

Com as Sessões de Checkout, isso não é mais necessário. Você pode simplesmente passar as informações que possui, e nós cuidaremos do resto. Por exemplo:

* Se você souber apenas o país de cobrança do cliente, basta fornecer isso.
* O fluxo de checkout irá coletar automaticamente os detalhes ausentes antes de mover o cliente para a página de pagamento.
* Por outro lado, se você já tiver todas as informações necessárias e quiser ir diretamente para a página de pagamento, você pode fornecer o conjunto completo de dados e incluir `confirm=true` no corpo da sua solicitação.

### Processo de Migração

Migrar de Links Dinâmicos para Sessões de Checkout é simples:

<Steps>
  <Step title="Update your integration">
    Atualize sua integração para usar o novo método de API ou SDK.
  </Step>

  <Step title="Adjust request payload">
    Ajuste a carga da solicitação de acordo com o formato das Sessões de Checkout.
  </Step>

  <Step title="That's it!">
    Sim. Nenhum tratamento adicional ou etapas especiais de migração são necessárias da sua parte.
  </Step>
</Steps>

## Referência de API Relacionada

<CardGroup cols={2}>
  <Card title="Create Checkout Session" icon="code" href="/api-reference/checkout-sessions/create">
    Referência completa da API para criar sessões de checkout com todos os parâmetros e opções disponíveis
  </Card>

  <Card title="Preview Checkout Session" icon="eye" href="/api-reference/checkout-sessions/preview">
    Referência da API para pré-visualizar preços, impostos e totais antes de criar uma sessão
  </Card>
</CardGroup>
