Full SDK (Android)


👍

SDK recomendado

Recomendamos o uso do Android Seamless SDK para uma experiência de integração tranquila. Essa opção oferece uma solução de pagamento flexível com componentes de IU pré-criados e opções de personalização.

Esta página fornece um guia para o Yuno Full SDK para Android, que oferece uma solução de pagamento completa com uma interface de usuário personalizável. Ele fornece recursos avançados como gerenciamento de métodos de pagamento, prevenção de fraudes e fluxos de checkout contínuos, tornando-o mais rico em recursos do que o nosso Headless SDK, que é específico para os principais recursos de processamento de pagamentos.

Requisitos

Antes de iniciar o Yuno Android SDK, verifique se o seu projeto atende aos requisitos técnicos. Além disso, certifique-se de que os pré-requisitos a seguir estejam em vigor:

  1. Você deve ter uma conta Yuno ativa
  2. Você precisa de suas credenciais de API da Yuno (account_id, public-api-keye private-secret-key), que você pode obter no Seção de desenvolvedores do painel do Yuno. Essas credenciais são necessárias para autenticar solicitações à API da Yuno. A API é usada para:
  • Criar um checkout_sessionque inicializa o fluxo de pagamento
  • Criar o pagamento associado à sessão
  1. Antes de criar um pagamento, você deve primeiro criar um cliente usando o endpoint Criar cliente

Etapa 1: Inclua a biblioteca em seu projeto

Inclua o arquivo Yuno SDK em seu projeto por meio do Gradle. Em seguida, adicione a fonte do repositório:

maven { url "https://yunopayments.jfrog.io/artifactory/snapshots-libs-release" }
📘

Versão do SDK

Acesse as notas de versão ou o repositório do Yuno Android SDK para verificar a versão mais recente do SDK disponível.

Em seguida, inclua o seguinte código no arquivo build.gradle para adicionar a dependência do Yuno SDK ao aplicativo:

dependencies {
    implementation 'com.yuno.payments:android-sdk:{last_version}'
}

Permissões

O Yuno SDK inclui, por padrão, o INTERNET que é necessária para fazer solicitações de rede.

<uses-permission android:name="android.permission.INTERNET" />

Etapa 2: Initialize o SDK com a chave pública

Recupere suas chaves públicas de API no painel do Yuno.

Se você não tiver implementado um aplicativo personalizado, crie um. Na seção onCreate() de sua classe de aplicativo, chame a função initialize (Yuno.initialize):

class CustomApplication : Application() {
  override fun onCreate() {
    super.onCreate()
    Yuno.initialize(
      this,
      "<your-public-api-key>",
      config: YunoConfig,
    )
  }
}
📘

Credenciais

Consulte a página de credenciais para obter mais informações: https://docs.y.uno/reference/authentication

Use a classe de dados YunoConfig para personalizar o comportamento do SDK. Inclua essa configuração ao chamar Yuno.initialize(). As opções disponíveis são:

classe de dados YunoConfig(
    val cardFlow: CardFormType  CardFormType.ONE_STEP,
    val saveCardEnabled: Boolean = false,
    val cardFormDeployed: Boolean = false,
    val language: YunoLanguage? = null,
    val styles: YunoStyles? = null,
    val cardNumberPlaceholder: String? = null, // Opcional: texto personalizado para o campo do número do cartão
    val hideCardholderName: Boolean? = null // Opcional: defina como verdadeiro para ocultar o campo do nome do titular do cartão
)

Parâmetros

A tabela a seguir descreve cada personalização disponível:

Opção de personalizaçãoDescrição
cardFlowÉ uma configuração opcional que define o fluxo do cartão de pagamento e de registro. Por padrão, o CardFormType.ONE_STEP é usada. Verifique a Opções de renderização para obter mais informações.
saveCardEnabledAtiva a caixa de seleção Salvar cartão nos fluxos de cartão. Consulte a seção Salvar cartão para obter mais informações.
cardFormDeployedEssa opção está disponível apenas para o Full SDK. Se TRUESe o cartão for usado, o sistema apresentará o formulário de cartão implantado na lista de métodos de pagamento. Se FALSEapresenta o formulário normal do cartão em outra tela.
languageDefine o idioma a ser usado nos formulários de pagamento. Você pode defini-lo como uma das opções de idioma disponíveis:
  • es (espanhol)
  • en (inglês)
  • pt (português)
  • fil (filipino)
  • id (indonésio)
  • ms (malaio)
  • th (tailandês)
  • zh-TW (chinês (tradicional, Taiwan))
  • zh-CN (chinês (simplificado, China))
  • vi (vietnamita)
  • fr (francês)
  • pl (polonês)
  • it (italiano)
  • de (alemão)
  • ru (russo)
  • tr (turco)
  • nl (holandês)
  • sv (sueco)
  • ko (coreano)
  • ja (japonês)
cardNumberPlaceholderEste campo opcional permite personalizar o texto do espaço reservado para o campo do número do cartão. Aceita caracteres alfanuméricos, espaços e caracteres UTF-8 para localização. Se não for fornecido, o SDK usa o espaço reservado padrão (“Número do cartão”). Essa personalização não afeta a formatação do cartão, o mascaramento, a lógica BIN ou a validação.
hideCardholderNameEste campo opcional permite ocultar o campo do nome do titular do cartão no formulário do cartão. Quando definido como true, o campo do nome do titular do cartão não é exibido. Quando não especificado ou definido como false, o campo do nome do titular do cartão é exibido (comportamento padrão). Ocultar o campo não afeta o PAN, a validade, a coleta do CVV, a lógica do BIN ou as validações 3DS/provedor. O comerciante é responsável por garantir que o nome do titular do cartão seja fornecido quando exigido pelo seu provedor de pagamentos.
stylesPermite a personalização da interface do usuário em todo o SDK. Use-o para definir estilos visuais globais, como família de fontes e aparência de botões (cor, preenchimento, raio, tipografia) por meio de um YunoStyles objeto. Para obter mais informações, consulte a seção styles seção.

Atualize seu manifesto para usar seu aplicativo:

<application android:name=".CustomApplication"></application>

Etapa 3: Criar a sessão de checkout

Cada pagamento requer um novo checkout_sessionque fornece acesso a todos os métodos de pagamento disponíveis para um cliente específico. Use o botão Criar sessão de checkout para obter um novo endpoint checkout_session. Essa sessão é então usada para iniciar o pagamento.

📘

Tratamento de retorno do navegador externo

Se o seu fluxo de pagamento enviar os usuários para um navegador externo (por exemplo, para autenticação 3DS ou redirecionamentos bancários), certifique-se de definir o callback_url ao criar sua sessão de checkout. Para obter um guia passo a passo sobre como lidar com o retorno ao seu aplicativo, consulte Manipular o retorno do navegador externo (callback_url).

Etapa 4: Inicie o processo de checkout

Ligue para o startCheckout dentro do método onCreate() da atividade que inicializa o SDK para iniciar um novo processo de pagamento com o Full SDK:

startCheckout(
 checkoutSession: "checkout_session",
 countryCode: "country_code_iso",
 callbackPaymentState: ((String?) -> Unit)?,
  merchantSessionId: String? = null
)

Parâmetros

Configure o checkout com as seguintes opções:

ParâmetroDescrição
checkoutSessionUm identificador exclusivo para a sessão de checkout associada ao pagamento. Ele é necessário para initialize o processo de pagamento e concede acesso aos métodos de pagamento disponíveis do cliente.
countryCodeCódigo do país onde o pagamento é realizado. Consulte Cobertura de países para obter uma lista completa dos países compatíveis e seus códigos.
callbackPaymentStateÉ uma função que retorna o processo de pagamento atual. Não é necessário enviar essa função se você não precisar do resultado.
merchantSessionIdUm identificador usado pelo comerciante para rastrear o pagamento.

A seguir estão os possíveis estados retornados pelo callbackPaymentState:

const val PAYMENT_STATE_SUCCEEDED =SUCCEEDED"
const val PAYMENT_STATE_FAIL = "FAIL" (Reprovado)
const val PAYMENT_STATE_PROCESSING = "PROCESSANDO"
const val PAYMENT_STATE_REJECT = "REJECT" (Rejeitado)
const val PAYMENT_STATE_INTERNAL_ERROR = "INTERNAL_ERROR"
const val PAYMENT_STATE_STATE_CANCELED_BY_USER = "CANCELED" (Cancelado pelo usuário)

A tabela a seguir fornece informações adicionais sobre os possíveis estados:

EstadoDescriçãoAção adicional necessária
SUCCEEDEDO processo de transação ou pagamento foi concluído com êxito e sem erros.Não.
FAILA transação falhou devido a erros, como problemas de validação de dados, falhas de conexão com o servidor ou problemas técnicos/de rede.Sim. Investigue a causa da falha (validação, rede, servidor) e tome medidas corretivas.
PROCESSINGA transação está em andamento, aguardando aprovação ou verificação.Não.
REJECTA transação foi rejeitada por motivos como fundos insuficientes ou suspeita de atividade fraudulenta.Sim. Informe o usuário sobre a rejeição, forneça o motivo, se possível, e sugira ações.
INTERNAL_ERROROcorreu um erro interno inesperado no sistema que está lidando com o processo de pagamento.Sim. Requer intervenção técnica para analisar o sistema, corrigir problemas internos e tentar novamente ou informar o usuário.
CANCELEDO usuário cancelou voluntariamente a transação ou abandonou o processo de pagamento.Não.

Validação do status do pagamento

Esta seção explica como o SDK lida com o status do pagamento quando os usuários cancelam ou abandonam os fluxos de pagamento e como o status do SDK se relaciona com o status do pagamento no back-end nesses cenários.

Sincronizar métodos de pagamento (Google Pay)

Para métodos de pagamento síncronos, como o Google Pay, quando um usuário cancela ou fecha a interface do usuário da carteira antes de receber a resposta do provedor de serviços de pagamento (PSP):

  • Status do SDK: Devoluções CANCELED (CANCELLED)
  • Status do pagamento no backend: Restos mortais PENDING até ao tempo limite do PSP ou ao cancelamento pelo comerciante
  • Importante: O SDK não retornará REJECT ou PROCESSING nesse cenário

Isso garante que o pagamento no backend permaneça em estado pendente e possa ser tratado adequadamente pelo sistema do comerciante.

Formas de pagamento assíncronas (PIX e métodos baseados em QR)

Para métodos de pagamento assíncronos como o PIX, quando um usuário fecha a janela do código QR (clica em X) antes de concluir o pagamento:

  • Status do SDK: Devoluções PROCESSING, opcionalmente com um subestatuto, como CLOSED_BY_USER
  • Status do pagamento no backend: Restos mortais PENDING e o código QR permanece válido até ao seu prazo de validade.
  • Reutilização da sessão de checkout: reabrir a mesma sessão de checkout pode exibir o mesmo código QR válido.
  • Sem cancelamento automático: O pagamento PIX não é cancelado automaticamente quando o usuário fecha a janela do QR.

Esse comportamento permite que os usuários retornem ao fluxo de pagamento e concluam a transação usando o mesmo código QR antes que ele expire.

Pagamentos assíncronos expirados

Se um código QR PIX expirar naturalmente:

  • Status do backendAtualizado para EXPIRED
  • Status do SDK: endpoints de chamadas de retorno do SDK e endpoints de pesquisa EXPIRED de forma consistente

Isso garante que os comerciantes recebam informações precisas sobre o status quando um método de pagamento expirar.

Etapa 5: Adicionar a visualização do SDK ao checkout

Use o PaymentMethodListViewComponent para exibir os métodos de pagamento disponíveis ao implementar o Full SDK com o Jetpack Compose. Esse componente fornece retornos de chamada para notificar seu aplicativo quando ativar ou desativar o botão de pagamento e quando um método de pagamento registrado for removido com êxito.

Assinatura do componente

@Composable
fun PaymentMethodListViewComponent(
    activity: Activity,
    modifier: Modifier? = null,
    onPaymentSelected: (Boolean) -> Unit,
    onUnEnrollSuccess: (Boolean) -> Unit = {}
)

Parâmetros

  • activity: Activity
    • O atual Activity onde o componente está hospedado. Necessário para lidar corretamente com os fluxos de pagamento.
  • modifier: Modifier? (opcional)
    • Permite que você personalize o layout e a aparência (por exemplo, preenchimento, espaçamento). O padrão é null.
  • onPaymentSelected: (Boolean) -> Unit
    • Callback invocado sempre que um método de pagamento é selecionado ou desmarcado.
      • true → Um método é selecionado (ative o botão de pagamento).
      • false → Nenhum método está selecionado (desabilite o botão de pagamento).
  • onUnEnrollSuccess: (Boolean) -> Unit (opcional)
    • Callback invocado quando um método de pagamento armazenado é removido com êxito (cancelado).
      • true → Indica que a remoção foi bem-sucedida.
      • Pode ser usado para mostrar uma barra de lanches, atualizar a lista ou atualizar o estado da interface do usuário.

Exemplo

val coroutineScope = rememberCoroutineScope()
val snackbarHostState = remember { SnackbarHostState() }
var paymentMethodIsSelected by remember { mutableStateOf(false) }

Column(
    modifier = Modifier
        .weight(1f)
        .verticalScroll(rememberScrollState())
) {
    PaymentMethodListViewComponent(
        activity = activity,
       onPaymentSelected = { isSelected ->
            paymentMethodIsSelected = isSelected
        },
       onUnEnrollSuccess = { success ->
            if (success) {
                coroutineScope.launch {
                    snackbarHostState.showSnackbar(
                        mensagem = "Seu método de pagamento foi removido",
                    )
                }
            }
        },
    )
}

Importante

Sempre envolva o componente em um Column com .verticalScroll(rememberScrollState()). Sem isso, a lista de métodos de pagamento pode não ser renderizada ou rolada corretamente quando houver vários métodos disponíveis.

Etapa 6: Iniciar o processo de pagamento

Ligue para o startPayment() para iniciar um processo de pagamento:

startPayment(
    showStatusYuno: Booleano,
   callbackOTT: (String?) -> Unit = this:onTokenUpdated,
   callBackTokenWithInformation:OneTimeTokenModel?) -> Unit = this:onTokenComplete

)

Parâmetros

Configure o pagamento com as seguintes opções:

ParâmetroDescrição
showStatusYunoUm booleano que especifica se o status do pagamento deve ser exibido na interface do Yuno.
callbackOTTUma função obrigatória que retorna o token de uso único (OTT) atualizado necessário para concluir o processo de pagamento. Esse token é necessário para concluir o pagamento.
callBackTokenWithInformationUma função que fornece informações detalhadas sobre o token de uso único, envolvida em um OneTimeTokenModel permitindo o tratamento abrangente dos detalhes token .

Etapa 7: obtenha o token de uso único (OTT)

Depois que o cliente preencher os dados solicitados nos formulários de pagamento da Yuno, você obterá o token de uso único, um parâmetro necessário para criar um pagamento usando a API da Yuno.

O token de uso único será compartilhado pela Yuno usando o callbackOTT que você forneceu na Etapa 6 ao iniciar o pagamento. O token de uso único estará disponível na seção onActivityResult.

📘

Configuração do carregador

Enquanto o Yuno recebe as informações do cliente e compartilha o token de uso único, um carregador pode ser exibido para melhorar a experiência do usuário. O Yuno fornece um carregador padrão que pode ser usado imediatamente. No entanto, os comerciantes podem optar por implementar seu próprio carregador e são responsáveis por fazer as configurações necessárias.

Etapa 8: Criar o pagamento

Após receber o token único da Etapa 7crie o pagamento usando o Criar endpoint de pagamento. Use o checkout_session de Etapa 3 e o token de uso único para criar o pagamento.

A resposta do endpoint Criar pagamento incluirá o parâmetro sdk_action_requiredque define se ações adicionais são necessárias para concluir o pagamento com base no tipo de pagamento.

🚧

Continuar a integração do método de pagamento

Yuno requer você integra o continuePayment do SDK depois que o pagamento for criado, porque determinados métodos de pagamento assíncronos exigem uma ação adicional do cliente para serem concluídos. A API informará você sobre esse cenário por meio da função sdk_action_required da resposta, que será retornado como verdadeiro. O campo yuno.continuePayment() exibirá telas adicionais para os clientes, onde eles poderão executar as ações necessárias para concluir o pagamento sem que você precise lidar com cada cenário.

Etapa 9: Continuar o pagamento

O Yuno requer a integração do continuePayment após a criação do pagamento, pois determinados métodos de pagamento assíncronos exigem ações adicionais do cliente para serem concluídos. A resposta do método Criar endpoint de pagamentoA lista de dados, da Etapa 8, incluirá um sdk_action_required campo. Se ele retornar TRUEvocê precisa chamar o continuePayment() para mostrar telas adicionais que permitam que o cliente conclua o pagamento. Caso contrário, essa etapa não é necessária. Chame o continuePayment método:

continuePayment(
   showPaymentStatus: Boolean = true,
   checkoutSession: String? = null,
   countryCode: String? = null,
   callbackPaymentState: ((String?) -> Unit)? = null
)

Para exibir suas telas de status de pagamento, envie FALSE no showPaymentStatus parâmetro. Em seguida, obtenha o estado do pagamento por meio de callback.

Integração do modo de renderização

O modo de renderização do Yuno SDK oferece flexibilidade avançada de interface do usuário, permitindo que os desenvolvedores integrem fluxos de pagamento com controle total sobre a interface do usuário, mantendo a funcionalidade full SDK . Esse modo retorna fragmentos que podem ser usados tanto com o Jetpack Compose quanto com visualizações XML tradicionais.

Função principal: startPaymentRender

O startPaymentRender inicializa o fluxo de pagamento no modo de renderização, oferecendo controle granular sobre a apresentação da interface do usuário.

fun Activity.startPaymentRender(
   checkoutSession: String? = null,
   countryCode: String? = null,
    coroutineScope: CoroutineScope,
   paymentSelected: PaymentSelected,
    listener: YunoPaymentRenderListener,
): YunoPaymentFragmentController

Parâmetros

ParâmetroTipoNecessárioDescrição
checkoutSessionString?NãoID da sessão de checkout criada anteriormente
countryCodeString?NãoCódigo do país para configurações regionais
coroutineScopeCoroutineScopeSimEscopo da rotina para operações assíncronas
paymentSelectedPaymentSelectedSimMétodo de pagamento selecionado
listenerYunoPaymentRenderListenerSimImplementação de ouvinte para receber eventos

Exemplo de implementação

class PaymentActivity : Activity() {

    private lateinit var fragmentController: YunoPaymentFragmentController

    private fun initializePayment() {
        fragmentController = startPaymentRender(
            checkoutSession = "your_checkout_session_id",
            countryCode = "US",
            coroutineScope = lifecycleScope,
            paymentSelected = PaymentSelected.CARD,
            listener = paymentRenderListener
        )
    }
}

YunoPaymentRenderListener interface

Implemente essa interface para receber todos os eventos e exibições do SDK durante o fluxo de pagamento:

class PaymentRenderListener : YunoPaymentRenderListener {

    override fun showView(fragment: Fragment) {
        supportFragmentManager.beginTransaction()
            .replace(R.id.payment_container, fragment)
            .commit()
    }

    override fun returnStatus(resultCode: Int, paymentStatus: String) {
        when (paymentStatus) {
            "SUCCEEDED" -> handleSuccessfulPayment()
            "FAIL" -> handleFailedPayment()
        }
    }

    override fun returnOneTimeToken(oneTimeToken: String, additionalData: OneTimeTokenModel?) {
        createPaymentInBackend(oneTimeToken) { result ->
            when (result) {
                is Success -> fragmentController.continuePayment()
                is Error -> handlePaymentError(result.error)
            }
        }
    }

    override fun loadingListener(isLoading: Boolean) {
        progressBar.visibility = if (isLoading) View.VISIBLE else View.GONE
    }
}

YunoPaymentFragmentController interface

Controle o fluxo de pagamento usando a instância do controlador retornada:

Métodos

  • submitForm(): Envia o formulário atual quando disponível
  • continuePayment(): Continua o fluxo de pagamento após o processamento OTT de back-end
fragmentController.submitForm()

fragmentControllercontinuePayment()

Benefícios da integração

Flexibilidade da interface do usuário

  • Compatível com Compose e XML: Funciona tanto com o Jetpack Compose quanto com as visualizações XML tradicionais
  • Controle total: Você decide onde e como exibir cada visualização
  • Integração personalizada: Fácil integração com o design do aplicativo existente

Controle de fluxo

  • Lógica de envio personalizada: Controle quando enviar formulários
  • Integração de back-end: Processe a OTT em seu backend antes de continuar

Exemplo de integração completa

class PaymentActivity : ComponentActivity() {

    private lateinit var fragmentController: YunoPaymentFragmentController

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        fragmentController = startPaymentRender(
            checkoutSession = checkoutSessionId,
            countryCode = "US",
            coroutineScope = lifecycleScope,
            paymentSelected = PaymentSelected.CARD,
            listener = object : YunoPaymentRenderListener {
                override fun showView(fragment: Fragment) {
                    supportFragmentManager.beginTransaction()
                        .replace(R.id.payment_fragment_container, fragment)
                        .commit()
                }

                override fun returnOneTimeToken(oneTimeToken: String, additionalData: OneTimeTokenModel?) {
                    processPaymentToken(oneTimeToken) {
                        fragmentController.continuePayment()
                    }
                }

                override fun returnStatus(resultCode: Int, paymentStatus: String) {
                    handlePaymentResult(paymentStatus)
                }

                override fun loadingListener(isLoading: Boolean) {
                    updateLoadingState(isLoading)
                }
            }
        )
    }
}
🚧

Gerenciamento do ciclo de vida

Certifique-se de que o CoroutineScope está vinculado ao ciclo de vida da atividade/fragmento para evitar vazamentos de memória e garantir a limpeza adequada.

Recursos complementares

O Yuno Android SDK fornece serviços e configurações adicionais que você pode usar para melhorar a experiência do cliente. Use as personalizações do SDK para alterar a aparência do SDK de acordo com sua marca ou para configurar o carregador:

Click to Pay (CTP) com Passkey

Diferentemente de outros processos, quando um usuário conclui um pagamento usando a CTP Passkey, o Token único (OTT) não será recebido por meio dos métodos usuais de retorno de chamada. A OTT será entregue por meio do método URL do deeplink na Intent. Seu aplicativo deve lê-lo a partir do IntentCrie o pagamento em seu back-end e, em seguida, continue o fluxo com o SDK.

⚠️

Importante

É essenciais para incluir um callback_url ao criar a sessão de checkout para pagamentos CTP Passkey. Esse URL deve corresponder ao esquema de deeplink configurado em seu AndroidManifest. Por exemplo:

{
  "callback_url": "myapp://pay/ctp"
}

O callback_url é usado para redirecionar o cliente de volta ao seu aplicativo após a conclusão do processo de autenticação Passkey.

1. AndroidManifest (deeplink)

Adicionar um intent-filter para sua atividade principal em AndroidManifest.xml:

<activity android:name=".CheckoutActivity" android:exported="true">
  <intent-filter>
    <action android:name="android.intent.action.VIEW" />
    <category android:name="android.intent.category.DEFAULT" />
    <category android:name="android.intent.category.BROWSABLE" />
    <!-- Adjust to your actual scheme/host -->
    <data android:scheme="myapp" android:host="pay" android:pathPrefix="/ctp" />
  </intent-filter>
</activity>

Ajuste o scheme, hoste pathPrefix para corresponder à configuração do seu aplicativo.

2. Manipular a intenção

Em sua atividade, trate o Intent em ambos onCreate() e onNewIntent():

class CheckoutActivity : AppCompatActivity() {
    
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        initYuno()
        startCheckout()
        // Initialize your SDK / UI
        handleDeeplink(intent)
    }

    override fun onNewIntent(intent: Intent) {
        super.onNewIntent(intent)
        setIntent(intent)
        handleDeeplink(intent)
    }

    private fun handleDeeplink(intent: Intent?) {
        val uri = intent?.data ?: return

        when {
            // Cancellation or error
            uri.getBooleanQueryParameter("has_error", false) -> {
                val message = uri.getQueryParameter("message") ?: "Operation canceled"
                showError(message)
            }

            // Success: OTT received in URL
            uri.getQueryParameter("one_time_token") != null -> {
                val ott = extractOtt(uri) ?: return
                val checkoutSession = extractCheckoutSession(uri)

                // 1) Send the OTT to your backend to create the payment
                createPaymentOnBackend(ott) { success ->
                    if (success && checkoutSession != null) {
                        // 2) Then continue the flow in the SDK
                        continuePayment(
                            checkoutSession = checkoutSession,
                            countryCode = currentCountry
                        ) { result ->
                            // Handle payment state
                        }
                    }
                }
            }
        }
    }
    
    private fun extractOtt(uri: Uri): String? =
        uri.getQueryParameter("one_time_token")

    private fun extractCheckoutSession(uri: Uri): String? =
        uri.getQueryParameter("checkout_session")
            ?: uri.getQueryParameter("checkoutSession")
}

3. Criar o pagamento (backend)

Depois de extrair o OTT do deeplink, crie o pagamento em seu backend usando o endpoint Create Payment.

Depois de receber uma resposta bem-sucedida de seu backend (pagamento criado), continue o fluxo no SDK chamando continuePayment().

4. Funções auxiliares

Crie funções auxiliares para extrair parâmetros do URI do Intent:

private fun extractOtt(uri: Uri): String? =
    uri.getQueryParameter("one_time_token")

private fun extractCheckoutSession(uri: Uri): String? =
    uri.getQueryParameter("checkout_session")
        ?: uri.getQueryParameter(checkoutSession")
💡

Dica

Em ambientes de controle de qualidade, registre o URL completo para verificar os nomes dos parâmetros.

5. Testes rápidos

Você pode testar o fluxo CTP Passkey usando esses exemplos de URLs de deepplink:

  • Sucesso: myapp://pay/ctp?one_time_token=OTT_123&checkout_session=CHK_456
  • Erro: myapp://pay/ctp?has_error=true&message=User%20canceled
  • Continuação: myapp://pay/ctp

6. Lista de controle

Use esta lista de verificação para garantir a integração adequada da CTP Passkey:

  • callback_url incluído ao criar a sessão de checkout (deve corresponder ao esquema de deeplink)
  • intent-filter configurado corretamente (esquema/host/caminho)
  • handleDeeplink implementado em ambos onCreate() e onNewIntent()
  • ✅ Extrair ambos one_time_token e checkout_session parâmetros
  • Criar pagamento no backend com OTT ➜ chamar continuePayment(...)
  • Alça has_error e message parâmetros para cenários de erro
⚠️

Importante

A OTT irá não ser recebido através do callbackOTT para pagamentos CTP Passkey. Em vez disso, você deve extrair o token dos parâmetros Intent URI.

styles

Com o styles opção de personalização, você pode definir estilos visuais globais por meio de um YunoStyles objeto. Ele permite que você aplique uma marca consistente em todo o SDK, personalizando a aparência e a tipografia do botão.

classe de dados YunoStyles(
    val buttonStyles: YunoButtonStyles? = null,
    val fontFamily: FontFamily? = null
)
ParâmetroDescrição
buttonStylesPersonaliza os botões principais exibidos no SDK.
fontFamilyDefine a família de fontes usada em todos os elementos de texto do SDK.

O YunoButtonStyles permite que você defina configurações específicas para a aparência do botão:

classe de dados YunoButtonStyles(
    val backgroundColor: Color? = null,
    val contentColor: Color? = null,
    val cornerRadius: Dp? = null,
    val elevation: Dp? = null,
    val padding: Dp? = null,
    val fontFamily: FontFamily? = null,
    val fontSize: TextUnit? = null,
    val fontStyle: FontStyle? = null
)

Para usar o styles opção de personalização, use o YunoConfig descrita na Etapa 2.

Carregador

A funcionalidade do carregador é controlada por meio do keepLoader no parâmetro YunoConfig que está documentada em linha na seção de configuração do SDK acima.

Salvar o cartão para pagamentos futuros

Você pode exibir uma caixa de seleção para salvar ou registrar cartões usando cardSaveEnable: true. Os exemplos a seguir mostram a caixa de seleção para ambas as renderizações do formulário de cartão:

Opções de renderização

Você pode escolher entre duas opções de renderização de formulário de cartão. As capturas de tela a seguir mostram a diferença entre cardFormType ONE_STEP e STEP_BY_STEP:

Personalizações do SDK

Você pode alterar a aparência do SDK para que corresponda à sua marca. Para obter mais informações, consulte a página de personalizações do SDK.

📘

Aplicativo de demonstração

Além dos exemplos de código fornecidos, você pode acessar o repositório da Yuno para obter uma implementação completa dos SDKs do Android da Yuno.