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

# Android

> Abra o checkout hospedado do Dodo Payments a partir de um app Android em uma Custom Tab com o SDK oficial para Android e obtenha um resultado de checkout tipado a partir de uma única chamada.

> [!NOTE]
>
> Esta página aborda o SDK de checkout para Android, `com.dodopayments.api:checkout-android`, que abre o checkout hospedado do Dodo Payments dentro do seu app. Para chamar a API do Dodo Payments a partir do seu servidor, use o [SDK Kotlin de backend](https://docs.dodopayments.com/developer-resources/sdks/kotlin.md).

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

> **[Mobile Integration Guide](https://docs.dodopayments.com/developer-resources/mobile-integration.md)**
>
> Práticas recomendadas para fluxos de checkout mobile.

O SDK para Android abre o checkout hospedado do Dodo Payments em uma Custom Tab (`androidx.browser.customtabs`) e retorna um `CheckoutResult` tipado quando o cliente conclui ou sai do checkout. Seu backend cria a sessão de checkout e envia seu `checkout_url` para o app. O SDK não contém código de rede nem armazena uma chave de API, portanto nunca chama a API do Dodo Payments.

**Requisitos:** `minSdk` 23, Kotlin e Java 17. O SDK depende apenas de `androidx.activity`, `androidx.browser` e `kotlinx-coroutines-android`.

## Instalação

**1. Add the Dependency**

Adicione o SDK do Maven Central ao `build.gradle.kts` do módulo do seu app:

```kotlin build.gradle.kts theme={null}
dependencies {
    implementation("com.dodopayments.api:checkout-android:1.1.0")
}
```

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

**2. Register a Callback URL Scheme**

Defina o esquema de callback como um placeholder de manifesto do Gradle. O próprio manifesto do SDK declara o filtro de intenção da atividade de redirecionamento com o placeholder `${dodoCallbackScheme}`, portanto esta propriedade é a única etapa de configuração. Você não precisa adicionar nenhum XML de manifesto:

```kotlin build.gradle.kts theme={null}
android {
    defaultConfig {
        manifestPlaceholders["dodoCallbackScheme"] = "myapp"
    }
}
```

Use o mesmo esquema em `CheckoutParams.returnUrl`, por exemplo `myapp://checkout/return`, e defina a mesma URL 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, e ignora a query string. A URL não precisa carregar uma página real.

> [!NOTE]
>
> Se você omitir o placeholder, o build falhará com um erro de placeholder não resolvido. Se o placeholder não corresponder ao esquema de `returnUrl`, o SDK lançará `PLATFORM_ERROR` antes de abrir o checkout.

## Uso

O SDK oferece duas formas de iniciar o checkout: um activity result launcher e uma função suspend. Ambos retornam o mesmo `CheckoutResult`.

**Launcher (Recommended)**

Registre o contrato com `registerForActivityResult` e inicie-o:

```kotlin theme={null}
import com.dodopayments.checkout.CheckoutParams
import com.dodopayments.checkout.CheckoutStatus
import com.dodopayments.checkout.DodoCheckout

// showSuccess(), showFailure(), showExpired(), and reconcileAbandonedSession()
// are your own functions. See Abandoned Sessions for what to reconcile.
private val checkoutLauncher =
    registerForActivityResult(DodoCheckout.contract()) { result ->
        when (result.status) {
            CheckoutStatus.SUCCEEDED -> showSuccess(result.paymentId)
            CheckoutStatus.FAILED -> showFailure()
            CheckoutStatus.CANCELLED -> reconcileAbandonedSession() // outcome unknown, not a failure
            CheckoutStatus.PENDING -> reconcileAbandonedSession()
            CheckoutStatus.EXPIRED -> showExpired()
        }
    }

checkoutLauncher.launch(
    CheckoutParams(
        checkoutUrl = checkoutUrl, // from your backend's checkout session
        returnUrl = "myapp://checkout/return"
    )
)
```

> [!TIP]
>
> Use este estilo quando possível. O Android entrega o resultado por meio do `ActivityResultRegistry`, portanto o resultado sobrevive à morte do processo.

**Suspend Function**

Chame `DodoCheckout.start` a partir de um escopo de coroutine:

```kotlin theme={null}
import androidx.lifecycle.lifecycleScope
import com.dodopayments.checkout.CheckoutParams
import com.dodopayments.checkout.CheckoutStatus
import com.dodopayments.checkout.DodoCheckout
import kotlinx.coroutines.launch

// showSuccess(), showFailure(), showExpired(), and reconcileAbandonedSession()
// are your own functions. See Abandoned Sessions for what to reconcile.
lifecycleScope.launch {
    val result = DodoCheckout.start(
        activity = this@MyActivity,
        params = CheckoutParams(
            checkoutUrl = checkoutUrl, // from your backend's checkout session
            returnUrl = "myapp://checkout/return"
        ),
        onEvent = { event -> println(event.name) } // logging only
    )

    when (result.status) {
        CheckoutStatus.SUCCEEDED -> showSuccess(result.paymentId)
        CheckoutStatus.FAILED -> showFailure()
        CheckoutStatus.CANCELLED -> reconcileAbandonedSession() // outcome unknown, not a failure
        CheckoutStatus.PENDING -> reconcileAbandonedSession()
        CheckoutStatus.EXPIRED -> showExpired()
    }
}
```

`onEvent` recebe eventos `checkout.opened`, `checkout.return_received` e `checkout.closed`. Use-os apenas para logging, nunca para decidir o resultado.

> [!WARNING]
>
> Este estilo aguarda um `CompletableDeferred` em memória, portanto o resultado **não** sobrevive à morte do processo. `onEvent` está disponível apenas neste estilo, não com o launcher.

## O que o resultado significa

O SDK cria `CheckoutResult` a partir dos parâmetros de query na URL de retorno.

> [!WARNING]
>
> O campo `status` é uma indicação da UI, não uma prova de pagamento. Antes de conceder acesso, confirme o pagamento no seu backend com um webhook ou com o endpoint Get Payment Detail.

**status** `CheckoutStatus` *required*

Um dos cinco valores:

* `SUCCEEDED`: a URL de retorno contém `status=succeeded` (pagamento único) ou `status=active` (assinatura).
* `FAILED`: o pagamento foi recusado (`status=failed`).
* `CANCELLED`: o cliente fechou a Custom Tab antes de a URL de retorno chegar. O SDK não conhece o resultado, e o pagamento pode ter sido concluído; portanto, não exiba uma tela de falha. Em vez disso, faça a reconciliação da [sessão abandonada](#abandoned-sessions).
* `PENDING`: o pagamento é liquidado posteriormente (`status=processing` ou qualquer valor de `payment_status`), ou o parâmetro `status` estava ausente ou não era reconhecido. Faça a reconciliação como em `CANCELLED`.
* `EXPIRED`: a sessão de checkout expirou (`status=expired`).

**paymentId** `String?`

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

**subscriptionId** `String?`

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

**licenseKeys** `List\<String\>?`

O parâmetro de query `license_key`. Definido quando o checkout inclui produtos com license key.

**customerEmail** `String?`

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

**raw** `Map\<String, String\>`

Cada parâmetro de query da URL de retorno, literalmente.

## Verificar o pagamento

> **[Webhooks](https://docs.dodopayments.com/developer-resources/webhooks.md)**
>
> Monitore eventos de pagamento em tempo real.

> **[Get Payment Detail](https://docs.dodopayments.com/api-reference/payments/get-payments-1.md)**
>
> Consulte o status do pagamento sob demanda.

Conceda acesso somente depois que um desses métodos confirmar o pagamento, por exemplo, com o webhook `payment.succeeded` ou `subscription.active`. Não dependa apenas de `CheckoutResult.status`.

## Personalização da aparência

Para alterar a barra de ferramentas, os botões e o esquema de cores da Custom Tab, passe um `BrowserCustomization` como `customization` em `CheckoutParams`. Todos os campos são opcionais e têm como padrão `null`. Para um campo `null`, o SDK não define essa opção, então o navegador que hospeda a Custom Tab aplica seu próprio padrão.

**toolbarColor** `Int?`

Cor de fundo da barra de ferramentas, como um inteiro ARGB `Color`.

**navigationBarColor** `Int?`

Cor da barra de navegação, como um inteiro ARGB `Color`.

**navigationBarDividerColor** `Int?`

Cor do divisor acima da barra de navegação, como um inteiro ARGB `Color`.

**closeButtonStyle** `CloseButtonStyle?`

`DEFAULT` exibe o ícone de sistema "X". `BACK` exibe uma seta de voltar desenhada pelo SDK.

**closeButtonPosition** `CloseButtonPosition?`

O lado da barra de ferramentas onde o botão de fechar aparece: `START` ou `END`.

**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 conforme 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** `ColorScheme?`

`LIGHT` ou `DARK` força essa aparência independentemente da configuração do sistema do dispositivo. `SYSTEM` segue a configuração do sistema.

Este exemplo reutiliza `checkoutLauncher` de [Uso](#usage):

```kotlin theme={null}
import android.graphics.Color
import com.dodopayments.checkout.BrowserCustomization
import com.dodopayments.checkout.CheckoutParams

checkoutLauncher.launch(
    CheckoutParams(
        checkoutUrl = checkoutUrl,
        returnUrl = "myapp://checkout/return",
        customization = BrowserCustomization(
            toolbarColor = Color.parseColor("#6366F1"),
            closeButtonStyle = BrowserCustomization.CloseButtonStyle.BACK,
            colorScheme = BrowserCustomization.ColorScheme.DARK,
        )
    )
)
```

## Erros

`DodoCheckout.start` lança `CheckoutError` somente em caso de uso incorreto ou falha da plataforma. Leia o motivo em `CheckoutError.code`:

* `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. Somente um checkout pode ser executado por vez.
* `PLATFORM_ERROR`: uma falha inesperada da plataforma, incluindo um esquema `returnUrl` que não corresponde ao seu placeholder `dodoCallbackScheme`.

Um cliente que cancela ou um pagamento recusado sempre gera um resultado (`CANCELLED` ou `FAILED`), nunca um erro lançado. Com o launcher, os erros de validação são lançados por `launcher.launch(...)`. Uma falha da plataforma após o lançamento não pode ser lançada pelo callback de resultado da activity, portanto o launcher retorna `CANCELLED` com o código de erro em `raw["error"]`.

## Sessões abandonadas

O SDK registra a sessão de checkout quando o checkout começa e limpa o registro somente quando o checkout termina com `SUCCEEDED`, `FAILED` ou `EXPIRED`. O registro permanece quando o app é encerrado durante o checkout e depois de um resultado `CANCELLED` ou `PENDING`, pois, nesses casos, o SDK não conhece o resultado. Verifique-o na próxima inicialização do app e depois de cada resultado `CANCELLED` ou `PENDING`:

```kotlin theme={null}
// context is any Context, such as your Activity.
DodoCheckout.getAbandonedSession(context)?.let { abandoned ->
    // Ask your backend for the outcome of abandoned.sessionId, and show it.
    // Clear the record only after the outcome is final:
    DodoCheckout.clearAbandonedSession(context)
}
```

`abandoned.sessionId` é o ID da sessão de checkout, que começa com `cks_`. `abandoned.createdAt` é o horário em que o checkout começou, como um timestamp epoch em milissegundos. Seu backend pode consultar a sessão com [Get Checkout Session](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)**
>
> Práticas recomendadas para fluxos de checkout mobile.

> **[Kotlin SDK](https://docs.dodopayments.com/developer-resources/sdks/kotlin.md)**
>
> SDK de backend para operações no servidor.


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