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

# React Native

> Abra o checkout hospedado do Dodo Payments a partir de um app React Native ou Expo em uma visualização de navegador do sistema e obtenha um resultado de checkout tipado a partir de uma única chamada.

> [!NOTE]
>
> Esta página aborda o SDK oficial de checkout do Dodo Payments para React Native, `@dodopayments/react-native-checkout`. Ele abre o checkout hospedado do Dodo Payments em uma visualização de navegador nativa e retorna um resultado tipado. Um pacote mais antigo, `dodopayments-react-native-sdk` (sem escopo), tem uma API diferente. Esta página documenta somente o pacote com escopo.

> **[Checkout Sessions API](https://docs.dodopayments.com/developer-resources/checkout-session.md)**
>
> Crie o `checkout_url` que este SDK abre a partir do seu backend.

> **[Mobile Integration Guide](https://docs.dodopayments.com/developer-resources/mobile-integration.md)**
>
> Veja como este SDK se encaixa no fluxo completo de pagamentos móveis.

O SDK para React Native é um Turbo Module que encapsula os SDKs nativos de checkout para [iOS](https://docs.dodopayments.com/developer-resources/sdks/ios.md) e [Android](https://docs.dodopayments.com/developer-resources/sdks/android.md). Ele abre `SFSafariViewController` no iOS e uma Custom Tab no Android. Ele não armazena nenhuma chave de API e não possui lógica própria de checkout, portanto nunca chama a API do Dodo Payments. O checkout é executado na visualização do navegador. O SDK exibe e fecha essa visualização e lê o resultado da URL de retorno.

> [!WARNING]
>
> Este SDK oferece suporte somente à **New Architecture**. Ele requer React Native 0.77 ou posterior, iOS 16 ou posterior e Android `minSdk` 24. Seu app Android deve ser compilado com `compileSdk` 34 ou posterior.

## Instalação

**1. Install the Package**

**Android**

O pacote é vinculado automaticamente e obtém `com.dodopayments.api:checkout-android` do Maven Central.

```sh theme={null}
npm i @dodopayments/react-native-checkout
```

A dependência nativa é resolvida automaticamente, portanto nenhuma outra etapa de instalação é necessária.

**iOS**

```sh theme={null}
npm i @dodopayments/react-native-checkout
cd ios && pod install
```

O pacote inclui o core Swift, e o CocoaPods faz a instalação.

**Expo**

O SDK funciona somente em builds de desenvolvimento, não no Expo Go.

```sh theme={null}
npm i @dodopayments/react-native-checkout
```

Em seguida, configure o plugin em `app.json`, conforme mostrado na próxima etapa.

A [personalização da aparência](#appearance-customization) requer a versão 1.2.0 ou posterior.

**2. Register a Callback URL Scheme**

Registre um esquema de URL para que o sistema operacional encaminhe a URL de retorno do checkout de volta para o seu app.

**Android (Gradle)**

Defina o esquema como um manifest placeholder em `android/app/build.gradle`:

```groovy android/app/build.gradle theme={null}
android {
    defaultConfig {
        manifestPlaceholders["dodoCallbackScheme"] = "myapp"
    }
}
```

Substitua `"myapp"` pelo esquema do seu app.

**iOS (Info.plist)**

Adicione um tipo de URL a `ios/YourApp/Info.plist`:

```xml Info.plist theme={null}
<key>CFBundleURLTypes</key>
<array>
  <dict>
    <key>CFBundleURLName</key>
    <string>myapp</string>
    <key>CFBundleURLSchemes</key>
    <array>
      <string>myapp</string>
    </array>
  </dict>
</array>
```

Você também pode adicionar o tipo de URL no Xcode em **Info → URL Types**.

**Expo (both platforms)**

O plugin de configuração do pacote registra o esquema para ambas as plataformas durante `prebuild`. Passe o esquema como a opção `scheme` do plugin em `app.json`:

```json app.json theme={null}
{
  "expo": {
    "scheme": "myapp",
    "plugins": [
      [
        "@dodopayments/react-native-checkout",
        { "scheme": "myappcheckout" }
      ]
    ]
  }
}
```

O `scheme` do plugin deve corresponder ao esquema do `returnUrl` que você passar, por exemplo `myappcheckout://return`. Use um esquema diferente de `expo.scheme`. O Expo já registra `expo.scheme` em `MainActivity`, portanto reutilizá-lo pode enviar o retorno do checkout para a activity errada no Android, e o plugin avisa você. O plugin rejeita `http`, `https` e outros esquemas do sistema.

Recompile o projeto nativo depois de editar `app.json`:

```sh theme={null}
npx expo prebuild --clean
```

O plugin funciona somente em builds de desenvolvimento, não no Expo Go. No iOS, você ainda precisa do listener `Linking` em [Encaminhar a URL de retorno](#forwarding-the-return-url).

Se `android/app/build.gradle` não tiver um bloco `defaultConfig { }`, o plugin interromperá `prebuild` com um erro. Nesse caso, adicione o placeholder manualmente, conforme mostrado na aba Android.

Em todas as plataformas, defina a mesma URL usada como `return_url` da sessão de checkout quando o backend criar a sessão. O SDK compara a URL de retorno pelo esquema, host e caminho. A URL não precisa carregar uma página real.

## Uso

Chame `DodoCheckout.start` com o `checkout_url` do seu backend:

```typescript theme={null}
import { Linking } from 'react-native';
import { DodoCheckout } from '@dodopayments/react-native-checkout';

// Required for iOS's return-URL handling.
Linking.addEventListener('url', ({ url }) => DodoCheckout.handleOpenURL(url));

// showSuccess(), showFailure(), showExpired(), and reconcileAbandonedSession()
// are your own functions. See Abandoned Sessions for what to reconcile.
const result = await DodoCheckout.start({
  checkoutUrl,                          // from your backend's checkout session
  returnUrl: 'myapp://checkout/return', // scheme must be registered (see Installation)
  onEvent: (e) => console.log(e.type),  // logging only
});

switch (result.status) {
  case 'succeeded': showSuccess(result.paymentId); break;
  case 'failed':    showFailure(); break;
  case 'cancelled': await reconcileAbandonedSession(); break; // outcome unknown, not a failure
  case 'pending':   await reconcileAbandonedSession(); break;
  case 'expired':   showExpired(); break;
}
```

`onEvent` recebe eventos com um `type` de `checkout.opened`, `checkout.return_received` ou `checkout.closed`. Use-os somente para logging, nunca para decidir o resultado.

## Encaminhar a URL de retorno

O iOS precisa do listener `Linking` para lidar com a URL de retorno, porque `SFSafariViewController` não consegue capturar sua própria URL de retorno. No Android, `handleOpenURL` não faz nada e resolve `false`, porque o SDK do Android captura o redirect nativamente. Você pode registrar o listener em ambas as plataformas.

```typescript theme={null}
import { Linking } from 'react-native';
import { DodoCheckout } from '@dodopayments/react-native-checkout';

Linking.addEventListener('url', ({ url }) => {
  DodoCheckout.handleOpenURL(url);
});
```

No iOS, `handleOpenURL` resolve `true` quando a URL pertence ao checkout em andamento, e `false` para qualquer outra URL.

## O que o resultado significa

O SDK cria o resultado a partir dos parâmetros de consulta na URL de retorno.

> [!WARNING]
>
> `result.status` é uma indicação da UI, não uma prova de pagamento. Confirme todos os pagamentos a partir do seu backend, usando o webhook `payment.succeeded` ou `subscription.active`.

**status** `CheckoutStatus` *required*

Um dos cinco valores:

* `succeeded`: a URL de retorno tem `status=succeeded` (pagamento único) ou `status=active` (assinatura).
* `failed`: o pagamento foi recusado (`status=failed`).
* `cancelled`: o cliente fechou a visualização do navegador antes da chegada da URL de retorno. O SDK não sabe qual foi o resultado, e o pagamento pode ter sido concluído; portanto, não exiba uma tela de falha. Em vez disso, reconcilie a [sessão abandonada](#abandoned-sessions).
* `pending`: o pagamento é liquidado posteriormente (`status=processing` ou qualquer valor de `requires_*`), ou o parâmetro `status` estava ausente ou não foi reconhecido. Faça a reconciliação como em `cancelled`.
* `expired`: a sessão de checkout expirou (`status=expired`).

**paymentId** `string`

O parâmetro de consulta `payment_id`, quando a URL de retorno inclui um. Exiba-o na sua UI, mas não o use para conceder acesso. Consulte [Verificar o pagamento](#verify-the-payment).

**subscriptionId** `string`

O parâmetro de consulta `subscription_id`. Definido para checkouts de assinatura.

**licenseKeys** `string[]`

O parâmetro de consulta `license_key`. Definido quando o checkout inclui produtos com chaves de licença.

**customerEmail** `string`

O parâmetro de consulta `email`. Definido quando o checkout captura um endereço de e-mail.

**raw** `Record\<string, string\>`

Todos os parâmetros de consulta da URL de retorno, literalmente.

## Verificar o pagamento

> **[Webhooks](https://docs.dodopayments.com/developer-resources/webhooks.md)**
>
> O Dodo Payments chama seu backend quando um pagamento é concluído ou uma assinatura é ativada.

> **[Get Payment Detail](https://docs.dodopayments.com/api-reference/payments/get-payments-1.md)**
>
> Consulte `paymentId` usando sua secret key para verificar o status.

Conceda acesso somente depois que uma dessas opções confirmar o pagamento. Não dependa apenas de `result.status`.

## Personalização da aparência

Para alterar a barra de ferramentas, os botões e o esquema de cores do navegador do checkout, passe `customization` para `start(...)`. As Custom Tabs do Android e `SFSafariViewController` do iOS expõem controles nativos diferentes, portanto as opções são agrupadas em um objeto `android` e um objeto `ios`. Cada plataforma lê somente seu próprio objeto. Todos os campos são opcionais. Quando você omite um campo, a plataforma aplica seu próprio padrão.

> **Android — Custom Tab**
>
> **toolbarColor** `string`
>
> Cor de fundo da barra de ferramentas, como uma string hexadecimal: `"#RRGGBB"` ou `"#AARRGGBB"`.
>
> **navigationBarColor** `string`
>
> Cor da barra de navegação, como uma string hexadecimal.
>
> **navigationBarDividerColor** `string`
>
> Cor do divisor acima da barra de navegação, como uma string hexadecimal.
>
> **closeButtonStyle** `'default' | 'back'`
>
> `default` exibe o ícone "X" do sistema. `back` exibe uma seta de voltar desenhada pelo SDK.
>
> **closeButtonPosition** `'start' | 'end'`
>
> O lado da barra de ferramentas onde o botão de fechar aparece.
>
> **shareButtonEnabled** `boolean`
>
> Exibe o ícone de compartilhamento da barra de ferramentas. `false` o oculta.
>
> **showTitleEnabled** `boolean`
>
> Exibe o título da página abaixo da URL na barra de ferramentas.
>
> **urlBarHidingEnabled** `boolean`
>
> Oculta automaticamente a barra de ferramentas à medida que a página é rolada.
>
> **bookmarksButtonEnabled** `boolean`
>
> Exibe "Adicionar esta página aos favoritos" no menu de opções.
>
> **downloadsButtonEnabled** `boolean`
>
> Exibe "Baixar página" no menu de opções.
>
> **colorScheme** `'system' | 'light' | 'dark'`
>
> `light` ou `dark` força essa aparência independentemente da configuração do sistema do dispositivo. `system` segue a configuração do sistema.

> **iOS — SFSafariViewController**
>
> **dismissButtonStyle** `'done' | 'close' | 'cancel'`
>
> Estilo do botão de fechar. O iOS decide se ele será renderizado como um rótulo ou um ícone.
>
> **presentationStyle** `'pageSheet' | 'fullScreen'`
>
> `pageSheet` (o padrão) apresenta um cartão que o cliente pode deslizar para baixo para fechar. `fullScreen` cobre a tela inteira.
>
> **barCollapsingEnabled** `boolean`
>
> Permite que a barra de ferramentas seja recolhida à medida que a página é rolada. Ela só tem efeito visível quando `presentationStyle` é `fullScreen`. Com `pageSheet`, as barras permanecem fixas independentemente desta configuração.
>
> **colorScheme** `'system' | 'light' | 'dark'`
>
> `light` ou `dark` força essa aparência independentemente da configuração do sistema do dispositivo. `system` segue a configuração do sistema.

O iOS não tem uma opção de cor da barra de ferramentas, porque as propriedades tint do `SFSafariViewController` subjacente estão obsoletas desde o iOS 26.

```typescript theme={null}
const result = await DodoCheckout.start({
  checkoutUrl,
  returnUrl: 'myapp://checkout/return',
  customization: {
    android: { toolbarColor: '#6366F1', closeButtonStyle: 'back' },
    ios: { presentationStyle: 'fullScreen', colorScheme: 'dark' },
  },
});
```

## Erros

`start` rejeita com um `CheckoutError` somente em caso de uso incorreto ou falha da plataforma. Leia o motivo em `error.code`. Um cliente que cancela ou um pagamento recusado sempre gera um resultado, nunca uma rejeição.

* `INVALID_CHECKOUT_URL`: `checkoutUrl` não é uma URL de sessão de checkout `https` (caminho iniciado por `/session/`) em `checkout.dodopayments.com` ou `test.checkout.dodopayments.com`.
* `INVALID_RETURN_URL`: `returnUrl` não é uma URL absoluta com esquema e host.
* `ALREADY_IN_PROGRESS`: outro checkout está em execução. Apenas um checkout pode ser executado por vez.
* `PLATFORM_ERROR`: falha inesperada da plataforma. O SDK também informa qualquer erro nativo não reconhecido com este código.

## Sessões abandonadas

O SDK nativo registra a sessão de checkout quando o checkout é iniciado e limpa o registro somente quando o checkout termina com `succeeded`, `failed` ou `expired`. O registro permanece quando o app ou o bundle JavaScript é encerrado durante o checkout, o que faz perder a promise `start`, e após um resultado `cancelled` ou `pending`. Verifique sua existência na próxima montagem e após cada resultado `cancelled` ou `pending`:

```typescript theme={null}
import { DodoCheckout } from '@dodopayments/react-native-checkout';

const abandoned = await DodoCheckout.getAbandonedSession();
if (abandoned) {
  // Ask your backend for the outcome of abandoned.sessionId, and show it.
  // Clear the record only after the outcome is final:
  await DodoCheckout.clearAbandonedSession();
}
```

`abandoned.sessionId` é o ID da sessão de checkout, que começa com `cks_`. `abandoned.createdAt` é o `Date` em que o checkout foi iniciado. Seu backend pode consultar a sessão usando [Obter sessão de checkout](https://docs.dodopayments.com/api-reference/checkout-sessions/get-checkouts.md), que retorna `payment_id` e `payment_status`. Até que o pagamento alcance um status final, trate-o como pendente, não como falha.

## Relacionado

> **[Mobile Integration Guide](https://docs.dodopayments.com/developer-resources/mobile-integration.md)**
>
> O mesmo contrato para Android, iOS e Flutter.

> **[Expo Boilerplate](https://docs.dodopayments.com/developer-resources/expo-boilerplate.md)**
>
> Um exemplo completo de Expo com integração de checkout.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.