> ## 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 Inline

> Incorpore o checkout do Dodo Payments diretamente em seu site para uma experiência de pagamento integrada e personalizada.

## Visão Geral

O checkout inline permite que você crie experiências de checkout totalmente integradas que se misturam perfeitamente com seu site ou aplicativo. Ao contrário do [checkout em sobreposição](/developer-resources/overlay-checkout), que se abre como um modal sobre sua página, o checkout inline incorpora o formulário de pagamento diretamente no layout da sua página.

Usando o checkout inline, você pode:

* Criar experiências de checkout que estão totalmente integradas ao seu aplicativo ou site
* Permitir que o Dodo Payments capture com segurança as informações do cliente e de pagamento em um quadro de checkout otimizado
* Exibir itens, totais e outras informações do Dodo Payments em sua página
* Usar métodos e eventos da SDK para construir experiências de checkout avançadas

<Frame>
  <img src="https://mintcdn.com/dodopayments/HpxJAc8zNlxzewa_/images/inline-checkout/cover.png?fit=max&auto=format&n=HpxJAc8zNlxzewa_&q=85&s=99c1a92ef01680248a421d3f057b02cd" alt="Imagem de Capa do Checkout Embutido" style={{ maxHeight: '500px', width: 'auto' }} width="839" height="565" data-path="images/inline-checkout/cover.png" />
</Frame>

## Como Funciona

O checkout inline funciona incorporando um quadro seguro do Dodo Payments em seu site ou aplicativo.

O quadro de checkout lida com a coleta de informações do cliente e a captura de detalhes de pagamento. Sua página exibe a lista de itens, totais e opções para alterar o que está no checkout. A SDK permite que sua página e o quadro de checkout interajam entre si.

O Dodo Payments cria automaticamente uma assinatura quando um checkout é concluído, pronto para você provisionar.

<Note>
  O frame de checkout embutido lida com todas as informações de pagamento sensíveis de forma segura, garantindo conformidade PCI sem certificação adicional do seu lado.
</Note>

## O Que Faz um Bom Checkout Inline?

É importante que os clientes saibam de quem estão comprando, o que estão comprando e quanto estão pagando.

Para construir um checkout inline que seja compatível e otimizado para conversão, sua implementação deve incluir:

<Frame caption="Example inline checkout layout showing required elements">
  <img src="https://mintcdn.com/dodopayments/HpxJAc8zNlxzewa_/images/inline-checkout/example.png?fit=max&auto=format&n=HpxJAc8zNlxzewa_&q=85&s=c7c00fb01b76f7fb3d9831fc922b9fe9" alt="Exemplo de checkout embutido com elementos obrigatórios rotulados" style={{ maxHeight: '500px', width: 'auto' }} width="839" height="565" data-path="images/inline-checkout/example.png" />
</Frame>

1. **Informações recorrentes**: Se for recorrente, com que frequência ocorre e o total a ser pago na renovação. Se for um teste, quanto tempo dura o teste.
2. **Descrições dos itens**: Uma descrição do que está sendo comprado.
3. **Totais da transação**: Totais da transação, incluindo subtotal, total de impostos e total geral. Certifique-se de incluir a moeda também.
4. **Rodapé do Dodo Payments**: O quadro completo do checkout inline, incluindo o rodapé do checkout que contém informações sobre o Dodo Payments, nossos termos de venda e nossa política de privacidade.
5. **Política de reembolso**: Um link para sua política de reembolso, se for diferente da política padrão de reembolso do Dodo Payments.

<Warning>
  Sempre exiba o frame completo do checkout embutido, incluindo o rodapé. Remover ou ocultar informações legais viola os requisitos de conformidade.
</Warning>

## Jornada do Cliente

O fluxo de checkout é determinado pela configuração da sua sessão de checkout. Dependendo de como você configura a sessão de checkout, os clientes experimentarão um checkout que pode apresentar todas as informações em uma única página ou em várias etapas.

<Steps>
  <Step title="Customer opens checkout">
    Você pode abrir o checkout embutido passando itens ou uma transação existente. Use o SDK para mostrar e atualizar informações na página e métodos do SDK para atualizar itens com base na interação do cliente.

    <img src="https://mintcdn.com/dodopayments/HpxJAc8zNlxzewa_/images/inline-checkout/1.png?fit=max&auto=format&n=HpxJAc8zNlxzewa_&q=85&s=b3def4e750c3c487196d22519503ae2a" alt="Página inicial do checkout com lista de itens e formulário de pagamento" style={{ maxHeight: '500px', width: 'auto' }} width="718" height="565" data-path="images/inline-checkout/1.png" />
  </Step>

  <Step title="Customer enters their details">
    O checkout inline primeiro pede aos clientes que insiram seu endereço de e-mail, selecionem seu país e (quando necessário) insiram seu CEP ou código postal. Esta etapa coleta todas as informações necessárias para determinar impostos e opções de pagamento disponíveis.

    Você pode preencher automaticamente os detalhes do cliente e apresentar endereços salvos para agilizar a experiência.
  </Step>

  <Step title="Customer selects payment method">
    Após inserir seus dados, os clientes são apresentados com os métodos de pagamento disponíveis e o formulário de pagamento. As opções podem incluir cartão de crédito ou débito, PayPal, Apple Pay, Google Pay e outros métodos de pagamento locais com base em sua localização.

    Exiba métodos de pagamento salvos, se disponíveis, para acelerar o checkout.

    <img src="https://mintcdn.com/dodopayments/HpxJAc8zNlxzewa_/images/inline-checkout/2.png?fit=max&auto=format&n=HpxJAc8zNlxzewa_&q=85&s=cbfa4958d0892feaa3aa474c4fe42c48" alt="Formulário de métodos de pagamento disponíveis e detalhes do cartão" style={{ maxHeight: '500px', width: 'auto' }} width="718" height="565" data-path="images/inline-checkout/2.png" />
  </Step>

  <Step title="Checkout completed">
    O Dodo Payments direciona cada pagamento para o melhor adquirente para aquela venda, garantindo a melhor chance possível de sucesso. Os clientes entram em um fluxo de sucesso que você pode construir.

    <img src="https://mintcdn.com/dodopayments/HpxJAc8zNlxzewa_/images/inline-checkout/3.png?fit=max&auto=format&n=HpxJAc8zNlxzewa_&q=85&s=b75ac3d25abf7dc18a226904af72641b" alt="Tela de sucesso com check de confirmação" style={{ maxHeight: '500px', width: 'auto' }} width="718" height="565" data-path="images/inline-checkout/3.png" />
  </Step>

  <Step title="Dodo Payments creates subscription">
    O Dodo Payments cria automaticamente uma assinatura para o cliente, pronta para você provisionar. O método de pagamento que o cliente usou é mantido em arquivo para renovações ou alterações de assinatura.

    <img src="https://mintcdn.com/dodopayments/HpxJAc8zNlxzewa_/images/inline-checkout/4.png?fit=max&auto=format&n=HpxJAc8zNlxzewa_&q=85&s=645d66da0aa02ac842384f85814c5922" alt="Assinatura criada com notificação de webhook" style={{ maxHeight: '500px', width: 'auto' }} width="718" height="565" data-path="images/inline-checkout/4.png" />
  </Step>
</Steps>

## Começo Rápido

Comece com o Checkout Inline da Dodo Payments em apenas algumas linhas de código:

```typescript theme={null}
import { DodoPayments } from "dodopayments-checkout";

// Initialize the SDK for inline mode
DodoPayments.Initialize({
  mode: "test",
  displayType: "inline",
  onEvent: (event) => {
    console.log("Checkout event:", event);
  },
});

// Open checkout in a specific container
DodoPayments.Checkout.open({
  checkoutUrl: "https://test.dodopayments.com/session/cks_123",
  elementId: "dodo-inline-checkout" // ID of the container element
});
```

<Tip>
  Certifique-se de ter um elemento contêiner com o `id` correspondente na sua página: `<div id="dodo-inline-checkout"></div>`.
</Tip>

## Guia de Integração Passo a Passo

<Steps>
  <Step title="Install the SDK">
    Instale o SDK de Checkout da Dodo Payments:

    <CodeGroup>
      ```bash npm theme={null}
      npm install dodopayments-checkout
      ```

      ```bash yarn theme={null}
      yarn add dodopayments-checkout
      ```

      ```bash pnpm theme={null}
      pnpm add dodopayments-checkout
      ```
    </CodeGroup>
  </Step>

  <Step title="Initialize the SDK for Inline Display">
    Inicialize o SDK e especifique `displayType: 'inline'`. Você também deve escutar o evento `checkout.breakdown` para atualizar sua interface com cálculos em tempo real de impostos e totais.

    ```typescript theme={null}
    import { DodoPayments } from "dodopayments-checkout";

    DodoPayments.Initialize({
      mode: "test",
      displayType: "inline",
      onEvent: (event) => {
        if (event.event_type === "checkout.breakdown") {
          const breakdown = event.data?.message;
          // Update your UI with breakdown.subTotal, breakdown.tax, breakdown.total, etc.
        }
      },
    });
    ```
  </Step>

  <Step title="Create a Container Element">
    Adicione um elemento ao seu HTML onde o quadro de checkout será injetado:

    ```html theme={null}
    <div id="dodo-inline-checkout"></div>
    ```
  </Step>

  <Step title="Open the Checkout">
    Chame `DodoPayments.Checkout.open()` com o `checkoutUrl` e o `elementId` do seu contêiner:

    ```typescript theme={null}
    DodoPayments.Checkout.open({
      checkoutUrl: "https://test.dodopayments.com/session/cks_123",
      elementId: "dodo-inline-checkout"
    });
    ```
  </Step>

  <Step title="Test Your Integration">
    1. Inicie seu servidor de desenvolvimento:

    ```bash theme={null}
    npm run dev
    ```

    2. Teste o fluxo de checkout:
       * Insira seu e-mail e detalhes de endereço no quadro inline.
       * Verifique se seu resumo de pedido personalizado é atualizado em tempo real.
       * Teste o fluxo de pagamento usando credenciais de teste.
       * Confirme se os redirecionamentos funcionam corretamente.

    <Check>
      Você deve ver eventos `checkout.breakdown` registrados no console do navegador se você adicionou um log no callback `onEvent`.
    </Check>
  </Step>

  <Step title="Go Live">
    Quando você estiver pronto para produção:

    1. Altere o modo para `'live'`:

    ```typescript theme={null}
    DodoPayments.Initialize({
      mode: "live",
      displayType: "inline",
      onEvent: (event) => {
        // Handle events
      }
    });
    ```

    2. Atualize suas URLs de checkout para usar sessões de checkout ao vivo do seu backend.
    3. Teste o fluxo completo em produção.
  </Step>
</Steps>

## Exemplo Completo em React

Este exemplo demonstra como implementar um resumo de pedido customizado junto ao checkout embutido, mantendo-os sincronizados usando o evento `checkout.breakdown`.

```tsx theme={null}
"use client";

import { useEffect, useState } from 'react';
import { DodoPayments, CheckoutBreakdownData } from 'dodopayments-checkout';

export default function CheckoutPage() {
  const [breakdown, setBreakdown] = useState<Partial<CheckoutBreakdownData>>({});

  useEffect(() => {
    // 1. Initialize the SDK
    DodoPayments.Initialize({
      mode: 'test',
      displayType: 'inline',
      onEvent: (event) => {
        // 2. Listen for the 'checkout.breakdown' event
        if (event.event_type === "checkout.breakdown") {
          const message = event.data?.message as CheckoutBreakdownData;
          if (message) setBreakdown(message);
        }
      }
    });

    // 3. Open the checkout in the specified container
    DodoPayments.Checkout.open({
      checkoutUrl: 'https://test.dodopayments.com/session/cks_123',
      elementId: 'dodo-inline-checkout'
    });

    return () => DodoPayments.Checkout.close();
  }, []);

  const format = (amt: number | null | undefined, curr: string | null | undefined) => 
    amt != null && curr ? `${curr} ${(amt/100).toFixed(2)}` : '0.00';

  const currency = breakdown.currency ?? breakdown.finalTotalCurrency ?? '';

  return (
    <div className="flex flex-col md:flex-row min-h-screen">
      {/* Left Side - Checkout Form */}
      <div className="w-full md:w-1/2 flex items-center">
        <div id="dodo-inline-checkout" className='w-full' />
      </div>

      {/* Right Side - Custom Order Summary */}
      <div className="w-full md:w-1/2 p-8 bg-gray-50">
        <h2 className="text-2xl font-bold mb-4">Order Summary</h2>
        <div className="space-y-2">
          {breakdown.subTotal && (
            <div className="flex justify-between">
              <span>Subtotal</span>
              <span>{format(breakdown.subTotal, currency)}</span>
            </div>
          )}
          {breakdown.discount && (
            <div className="flex justify-between">
              <span>Discount</span>
              <span>{format(breakdown.discount, currency)}</span>
            </div>
          )}
          {breakdown.tax != null && (
            <div className="flex justify-between">
              <span>Tax</span>
              <span>{format(breakdown.tax, currency)}</span>
            </div>
          )}
          <hr />
          {(breakdown.finalTotal ?? breakdown.total) && (
            <div className="flex justify-between font-bold text-xl">
              <span>Total</span>
              <span>{format(breakdown.finalTotal ?? breakdown.total, breakdown.finalTotalCurrency ?? currency)}</span>
            </div>
          )}
        </div>
      </div>
    </div>
  );
}

```

## Referência da API

### Configuração

#### Opções de Inicialização

```typescript theme={null}
interface InitializeOptions {
  mode: "test" | "live";
  displayType: "inline"; // Required for inline checkout
  onEvent: (event: CheckoutEvent) => void;
}
```

| Opção         | Tipo                    | Obrigatório | Descrição                                                     |
| ------------- | ----------------------- | ----------- | ------------------------------------------------------------- |
| `mode`        | `"test" \| "live"`      | Sim         | Modo de ambiente.                                             |
| `displayType` | `"inline" \| "overlay"` | Sim         | Deve ser definido como `"inline"` para incorporar o checkout. |
| `onEvent`     | `function`              | Sim         | Função de callback para lidar com eventos do checkout.        |

#### Opções de Checkout

```typescript theme={null}
export type FontSize = "xs" | "sm" | "md" | "lg" | "xl" | "2xl";
export type FontWeight = "normal" | "medium" | "bold" | "extraBold";

interface CheckoutOptions {
  checkoutUrl: string;
  elementId: string; // Required for inline checkout
  options?: {
    showTimer?: boolean;
    showSecurityBadge?: boolean;
    payButtonText?: string;
    fontSize?: FontSize;
    fontWeight?: FontWeight;
  };
}
```

| Opção                       | Tipo         | Obrigatório | Descrição                                                                                                                                                |
| --------------------------- | ------------ | ----------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `checkoutUrl`               | `string`     | Sim         | URL da sessão de checkout.                                                                                                                               |
| `elementId`                 | `string`     | Sim         | O `id` do elemento DOM onde o checkout deve ser renderizado.                                                                                             |
| `options.showTimer`         | `boolean`    | Não         | Mostrar ou ocultar o cronômetro do checkout. Padrão é `true`. Quando desativado, você receberá o evento `checkout.link_expired` quando a sessão expirar. |
| `options.showSecurityBadge` | `boolean`    | Não         | Mostrar ou ocultar o selo de segurança. Padrão é `true`.                                                                                                 |
| `options.payButtonText`     | `string`     | Não         | Texto personalizado para exibir no botão de pagamento.                                                                                                   |
| `options.fontSize`          | `FontSize`   | Não         | Tamanho global da fonte para o checkout.                                                                                                                 |
| `options.fontWeight`        | `FontWeight` | Não         | Peso global da fonte para o checkout.                                                                                                                    |

### Métodos

#### Abrir Checkout

Abre o quadro de checkout no contêiner especificado.

```typescript theme={null}
DodoPayments.Checkout.open({
  checkoutUrl: "https://test.dodopayments.com/session/cks_123",
  elementId: "dodo-inline-checkout"
});
```

Você também pode passar opções adicionais para personalizar o comportamento do checkout:

```typescript theme={null}
DodoPayments.Checkout.open({
  checkoutUrl: "https://test.dodopayments.com/session/cks_123",
  elementId: "dodo-inline-checkout",
  options: {
    showTimer: false,
    showSecurityBadge: false,
    payButtonText: "Pay Now",
  },
});
```

#### Fechar Checkout

Remove programaticamente o quadro de checkout e limpa os listeners de eventos.

```typescript theme={null}
DodoPayments.Checkout.close();
```

#### Verificar Status

Retorna se o quadro de checkout está atualmente injetado.

```typescript theme={null}
const isOpen = DodoPayments.Checkout.isOpen();
// Returns: boolean
```

### Eventos

O SDK fornece eventos em tempo real através do callback `onEvent`. Para checkout embutido, `checkout.breakdown` é particularmente útil para sincronizar sua UI.

| Tipo de Evento                        | Descrição                                                                                                                                 |
| ------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- |
| `checkout.opened`                     | Quadro de checkout foi carregado.                                                                                                         |
| `checkout.form_ready`                 | Formulário de checkout está pronto para receber entrada do usuário. Útil para ocultar estados de carregamento e mostrar a UI de checkout. |
| `checkout.breakdown`                  | Disparado quando preços, impostos ou descontos são atualizados.                                                                           |
| `checkout.customer_details_submitted` | Detalhes do cliente foram enviados.                                                                                                       |
| `checkout.pay_button_clicked`         | Disparado quando o cliente clica no botão de pagamento. Útil para análises e rastreamento de funis de conversão.                          |
| `checkout.redirect`                   | O checkout realizará um redirecionamento (por exemplo, para uma página de banco).                                                         |
| `checkout.error`                      | Ocorreu um erro durante o checkout.                                                                                                       |
| `checkout.link_expired`               | Disparado quando a sessão de checkout expira. Apenas recebido quando `showTimer` está configurado para `false`.                           |

#### Dados de Detalhamento do Checkout

O evento `checkout.breakdown` fornece os seguintes dados:

```typescript theme={null}
interface CheckoutBreakdownData {
  subTotal?: number;          // Amount in cents
  discount?: number;         // Amount in cents
  tax?: number;              // Amount in cents
  total?: number;            // Amount in cents
  currency?: string;         // e.g., "USD"
  finalTotal?: number;       // Final amount including adjustments
  finalTotalCurrency?: string; // Currency for the final total
}
```

#### Compreendendo o Evento de Detalhamento

O evento `checkout.breakdown` é a principal forma de manter a UI do seu aplicativo em sincronia com o estado do checkout do Dodo Payments.

**Quando ocorre:**

* **Na inicialização**: Imediatamente após o quadro de checkout ser carregado e pronto.
* **Na mudança de endereço**: Sempre que o cliente seleciona um país ou insere um código postal que resulta em recalcular imposto.

**Detalhes dos Campos:**

| Campo                | Descrição                                                                                                                                                                |
| -------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `subTotal`           | A soma de todos os itens de linha na sessão antes de quaisquer descontos ou impostos serem aplicados.                                                                    |
| `discount`           | O valor total de todos os descontos aplicados.                                                                                                                           |
| `tax`                | O valor do imposto calculado. No modo `inline`, isso atualiza dinamicamente conforme o usuário interage com os campos de endereço.                                       |
| `total`              | O resultado matemático de `subTotal - discount + tax` na moeda base da sessão.                                                                                           |
| `currency`           | O código da moeda ISO (por exemplo, `"USD"`) para o subtotal padrão, valores de desconto e impostos.                                                                     |
| `finalTotal`         | O valor real cobrado ao cliente. Isso pode incluir ajustes adicionais de câmbio ou tarifas de método de pagamento local que não fazem parte da divisão básica de preços. |
| `finalTotalCurrency` | A moeda na qual o cliente está realmente pagando. Isso pode diferir de `currency` se a paridade de poder de compra ou conversão de moeda local estiver ativa.            |

**Dicas de Integração Chave:**

1. **Formatação de Moeda**: Os preços são sempre retornados como números inteiros na menor unidade de moeda (por exemplo, centavos para USD, ienes para JPY). Para exibi-los, divida por 100 (ou a potência de 10 apropriada) ou use uma biblioteca de formatação como `Intl.NumberFormat`.
2. **Tratamento de Estados Iniciais**: Quando o checkout carrega pela primeira vez, `tax` e `discount` podem ser `0` ou `null` até que o usuário forneça suas informações de cobrança ou aplique um código. Sua UI deve lidar com esses estados graciosamente (por exemplo, mostrando um traço `—` ou ocultando a linha).
3. **O "Total Final" vs "Total"**: Enquanto `total` fornece o cálculo do preço padrão, `finalTotal` é a fonte da verdade para a transação. Se `finalTotal` estiver presente, ele reflete exatamente o que será cobrado no cartão do cliente, incluindo quaisquer ajustes dinâmicos.
4. **Feedback em Tempo Real**: Use o campo `tax` para mostrar aos usuários que os impostos estão sendo calculados em tempo real. Isso proporciona uma sensação "ao vivo" à sua página de checkout e reduz o atrito durante a etapa de entrada de endereço.

## Opções de Implementação

### Instalação via Gerenciador de Pacotes

Instale via npm, yarn ou pnpm conforme mostrado no [Guia de Integração Passo a Passo](#step-by-step-integration-guide).

### Implementação via CDN

Para integração rápida sem uma etapa de build, você pode usar nosso CDN:

```html theme={null}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Dodo Payments Inline Checkout</title>
    
    <!-- Load DodoPayments -->
    <script src="https://cdn.jsdelivr.net/npm/dodopayments-checkout@latest/dist/index.js"></script>
    <script>
        // Initialize the SDK
        DodoPaymentsCheckout.DodoPayments.Initialize({
            mode: "test",
            displayType: "inline",
            onEvent: (event) => {
                console.log('Checkout event:', event);
            }
        });
    </script>
</head>
<body>
    <div id="dodo-inline-checkout"></div>

    <script>
        // Open the checkout
        DodoPaymentsCheckout.DodoPayments.Checkout.open({
            checkoutUrl: "https://test.dodopayments.com/session/cks_123",
            elementId: "dodo-inline-checkout"
        });
    </script>
</body>
</html>
```

## Atualizar Método de Pagamento

O checkout embutido suporta **atualizações de método de pagamento** para assinaturas. Quando um cliente precisa atualizar seu método de pagamento -- seja para uma assinatura ativa ou para reativar uma assinatura em espera -- você pode renderizar o fluxo de atualização diretamente no layout da sua página.

### Como Funciona

1. Chame a [API de Atualização de Método de Pagamento](/features/subscription#update-payment-method-for-active-subscription) para obter um `payment_link`:

```typescript theme={null}
const response = await client.subscriptions.updatePaymentMethod('sub_123', {
  type: 'new',
  return_url: 'https://example.com/return'
});
```

2. Passe o `payment_link` retornado como o `checkoutUrl` para abrir o checkout embutido:

```typescript theme={null}
DodoPayments.Checkout.open({
  checkoutUrl: response.payment_link,
  elementId: "dodo-inline-checkout"
});
```

O quadro embutido renderiza apenas o formulário de coleta de método de pagamento. Os clientes podem inserir novos detalhes do cartão ou selecionar um método de pagamento salvo sem sair da sua página.

### Para Assinaturas em Espera

Ao atualizar o método de pagamento de uma assinatura em status `on_hold`, o Dodo Payments cria automaticamente uma cobrança para quaisquer dívidas remanescentes. Monitore os webhooks `payment.succeeded` e `subscription.active` para confirmar a reativação.

```typescript theme={null}
const response = await client.subscriptions.updatePaymentMethod('sub_123', {
  type: 'new',
  return_url: 'https://example.com/return'
});

if (response.payment_id) {
  // Charge created for remaining dues
  // Open inline checkout for payment collection
  DodoPayments.Checkout.open({
    checkoutUrl: response.payment_link,
    elementId: "dodo-inline-checkout"
  });
}
```

<Tip>
  Você também pode usar um método de pagamento salvo existente, em vez de coletar novos detalhes, passando `type: 'existing'` com um `payment_method_id` para a API de Atualização de Método de Pagamento.
</Tip>

## Tratamento de Erros

O SDK fornece informações detalhadas sobre erros através do sistema de eventos. Sempre implemente tratamento adequado de erros em seu callback `onEvent`:

```typescript theme={null}
DodoPayments.Initialize({
  mode: "test",
  displayType: "inline",
  onEvent: (event: CheckoutEvent) => {
    if (event.event_type === "checkout.error") {
      console.error("Checkout error:", event.data?.message);
      // Handle error appropriately
    }
  }
});
```

<Warning>
  Sempre trate o evento `checkout.error` para proporcionar uma boa experiência ao usuário quando problemas ocorrerem.
</Warning>

## Melhores Práticas

1. **Design Responsivo**: Certifique-se de que seu elemento contêiner tenha largura e altura suficientes. O iframe normalmente se expande para preencher seu contêiner.
2. **Sincronização**: Use o evento `checkout.breakdown` para manter seu resumo de pedido personalizado ou tabelas de preços em sincronia com o que o usuário vê no frame de checkout.
3. **Estados de Esqueleto**: Mostre um indicador de carregamento em seu contêiner até que o evento `checkout.opened` seja disparado.
4. **Limpeza**: Chame `DodoPayments.Checkout.close()` quando seu componente desmontar para limpar o iframe e os listeners de eventos.

<Info>
  Para implementações em modo escuro, é recomendado usar `#0d0d0d` como a cor de fundo para uma integração visual ótima com o frame de checkout embutido.
</Info>

## Validação de Status de Pagamento

<Warning>
  Não confie apenas nos eventos de checkout embutido para determinar o sucesso ou falha do pagamento. Sempre implemente validação no lado do servidor usando webhooks e/ou polling.
</Warning>

### Por Que a Validação no Lado do Servidor é Essencial

Embora os eventos de checkout embutido forneçam feedback em tempo real, eles **não** devem ser sua única fonte de verdade para o status de pagamento. Problemas de rede, falhas no navegador ou usuários fechando a página podem fazer com que eventos sejam perdidos. Para garantir validação de pagamento confiável:

1. **Seu servidor deve ouvir eventos de webhook** - Dodo Payments envia webhooks para alterações de status de pagamento
2. **Implemente um mecanismo de polling** - Sua interface deve verificar seu servidor por atualizações de status
3. **Combine ambas as abordagens** - Use webhooks como fonte principal e polling como um retaguarda

### Arquitetura Recomendada

```mermaid theme={null}
flowchart TB
    subgraph Frontend["Your Frontend"]
        IC[Inline Checkout<br/>Dodo iframe]
        CP[Your Checkout Page]
        IC -->|events| CP
    end

    subgraph Server["Your Server"]
        WH[Webhook Handler]
        DB[(Database)]
        API[Status API]
        WH --> DB
        API --> DB
    end

    subgraph Dodo["Dodo Payments"]
        PP[Payment Processor]
    end

    CP -->|Poll for status| API
    PP -->|Webhooks| WH
    IC -.->|Payment request| PP
```

### Passos de Implementação

**1. Ouça eventos de checkout** - Quando o usuário clica em pagar, comece a preparar a verificação do status:

```typescript theme={null}
onEvent: (event) => {
  if (event.event_type === 'checkout.pay_button_clicked') {
    // Start polling your server for confirmed status
    startPolling();
  }
}
```

**2. Faça polling em seu servidor** - Crie um endpoint que verifica seu banco de dados para o status de pagamento (atualizado por webhooks):

```typescript theme={null}
// Poll every 2 seconds until status is confirmed
const interval = setInterval(async () => {
  const { status } = await fetch(`/api/payments/${paymentId}/status`).then(r => r.json());
  if (status === 'succeeded' || status === 'failed') {
    clearInterval(interval);
    handlePaymentResult(status);
  }
}, 2000);
```

**3. Trate webhooks no lado do servidor** - Atualize seu banco de dados quando o Dodo enviar webhooks `payment.succeeded` ou `payment.failed`. Consulte nossa [documentação de Webhooks](/developer-resources/webhooks) para detalhes.

## Solução de Problemas

<AccordionGroup>
  <Accordion title="Checkout frame is not appearing">
    * Verifique se `elementId` coincide com o `id` de um `div` que realmente existe no DOM.
    * Certifique-se de que `displayType: 'inline'` foi passado para `Initialize`.
    * Verifique se `checkoutUrl` é válido.
  </Accordion>

  <Accordion title="Taxes are not updating in my UI">
    * Certifique-se de que está ouvindo o evento `checkout.breakdown`.
    * Impostos são calculados apenas depois que o usuário insere um país e código postal válidos no quadro de checkout.
  </Accordion>
</AccordionGroup>

## Ativando Carteiras Digitais

Para informações detalhadas sobre configuração do Apple Pay, Google Pay e outras carteiras digitais, consulte a página <a href="/features/payment-methods/digital-wallets">Carteiras Digitais</a>.

### Configuração Rápida para Apple Pay

<Steps>
  <Step title="Download domain association file">
    Baixe o [arquivo de associação de domínio do Apple Pay](https://checkout.dodopayments.com/.well-known/apple-developer-merchantid-domain-association).
  </Step>

  <Step title="Request activation">
    Envie um e-mail para **[support@dodopayments.com](mailto:support@dodopayments.com)** com a URL do seu domínio de produção e solicite a ativação do Apple Pay.
  </Step>

  <Step title="Test after confirmation">
    Uma vez confirmado, verifique se o Apple Pay aparece no checkout e teste todo o fluxo.
  </Step>
</Steps>

<Warning>
  O Apple Pay requer verificação de domínio antes de aparecer em produção. Entre em contato com o suporte antes de lançar se você planeja oferecer Apple Pay.
</Warning>

## Suporte a Navegadores

O SDK de Checkout do Dodo Payments suporta os seguintes navegadores:

* Chrome (mais recente)
* Firefox (mais recente)
* Safari (mais recente)
* Edge (mais recente)
* IE11+

## Checkout Embutido vs Overlay

Escolha o tipo de checkout certo para seu caso de uso:

| Recurso                    | Checkout Embutido                                            | Checkout Overlay                      |
| -------------------------- | ------------------------------------------------------------ | ------------------------------------- |
| Profundidade de integração | Totalmente incorporado na página                             | Modal sobre a página                  |
| Controle de layout         | Controle total                                               | Limitado                              |
| Branding                   | Integrado                                                    | Separado da página                    |
| Esforço de implementação   | Maior                                                        | Menor                                 |
| Melhor para                | Páginas de checkout personalizadas, fluxos de alta conversão | Integração rápida, páginas existentes |

<Tip>
  Use o **checkout embutido** quando quiser máximo controle sobre a experiência de checkout e integração de marca. Use o **checkout overlay** para integração mais rápida com mudanças mínimas em suas páginas existentes.
</Tip>

## Recursos Relacionados

<CardGroup cols={2}>
  <Card title="Overlay Checkout" icon="layer-group" href="/developer-resources/overlay-checkout">
    Use o checkout overlay para integração rápida baseada em modal.
  </Card>

  <Card title="Checkout Sessions API" icon="code" href="/api-reference/checkout-sessions/create">
    Crie sessões de checkout para potencializar suas experiências de checkout.
  </Card>

  <Card title="Webhooks" icon="webhook" href="/developer-resources/webhooks">
    Trate eventos de pagamento no lado do servidor com webhooks.
  </Card>

  <Card title="Integration Guide" icon="book" href="/developer-resources/integration-guide">
    Guia completo para integrar Dodo Payments.
  </Card>
</CardGroup>

Para mais ajuda, visite nossa [comunidade no Discord](https://discord.gg/bYqAp4ayYh) ou entre em contato com nossa equipe de suporte ao desenvolvedor.
