# Pix Biometria Guide (Android SDK - Simplified Integration) Próximo Lançamento Esta documentação cobre recursos do nosso próximo lançamento. Embora a funcionalidade principal e o fluxo de trabalho descritos aqui permaneçam inalterados, você pode notar algumas melhorias antes do lançamento final. Com o Pix Biometria da Belvo, coletar pagamentos de usuários se torna simples, eliminando a necessidade de os usuários navegarem até sua instituição financeira para aprovar cada solicitação de pagamento individualmente. Este guia demonstra a integração usando os métodos de conveniência do SDK Android da Belvo. O SDK lida com a comunicação de backend, fluxos OAuth e registro FIDO internamente, proporcionando um caminho de integração simplificado. O primeiro passo para habilitar a coleta de pagamentos biométricos é **registrar** o dispositivo do usuário com sua instituição. Durante o registro, dados chave sobre o dispositivo e as credenciais de chave pública do usuário são registrados de forma segura com sua instituição, garantindo que pagamentos futuros possam ser confirmados usando apenas autenticação biométrica. Uma vez concluído o registro, você pode começar a solicitar pagamentos diretamente do dispositivo do usuário. ## Pré-requisitos Antes de começar, certifique-se de que você: 1. **Gerou suas Chaves de API do Belvo Payments** 2. **Configurou Webhooks** para receber atualizações de status de pagamento e inscrição 3. **Gerou um Token de Acesso SDK** (veja abaixo) 4. **Instalou o Belvo Android SDK** ### Token de Acesso do SDK Autenticação do SDK O SDK do Pix Biometria requer um token de acesso para autenticar solicitações da API. Gere este token a partir do seu servidor backend e passe-o para o SDK durante a inicialização. Gere um token de acesso do SDK a partir do seu backend: ```bash POST https://api.belvo.com/payments/api/widget-token/ Authorization: Basic Content-Type: application/json ``` ```json { "access": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...", "refresh": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." } ``` Melhores Práticas para Tokens Nunca codifique tokens diretamente no seu aplicativo. Sempre os gere no lado do servidor e implemente lógica segura de armazenamento e atualização. ### Instalação do SDK **Requisitos Mínimos:** - Android API Level 24 (Android 7.0) ou superior - Kotlin 1.9.0 ou superior **Adicione ao seu `build.gradle.kts` (nível do Módulo):** ```kotlin dependencies { implementation("com.belvo:biometric-pix-core:1.0.0") } ``` **Sincronize seu projeto** e você está pronto para começar! ### Configuração do App **Adicione permissões ao `AndroidManifest.xml`:** ```xml ``` **Adicione suporte a App Links para callbacks OAuth:** ```xml ``` **Compartilhe o nome do seu pacote e a impressão digital do certificado SHA-256 com a Belvo:** ```bash # Obtenha sua impressão digital SHA-256 keytool -list -v -keystore ~/.android/debug.keystore -alias androiddebugkey -storepass android -keypass android # Formato para compartilhar com a Belvo: # Package: com.yourcompany.appname # SHA-256: AA:BB:CC:DD:EE:FF:... ``` ## Permissões e Inicialização do SDK Tempo de Permissão As permissões **devem** ser solicitadas antes da inicialização do SDK. Além disso, a solicitação de permissão só pode ser chamada a partir de um contexto de Activity. **Passo 1: Solicite Permissões Primeiro** ```kotlin import com.belvo.biometricpixsdk.BiometricPixSDK import androidx.activity.ComponentActivity class EnrollmentActivity : ComponentActivity() { private lateinit var sdk: BiometricPixSDK override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) // DEVE solicitar permissões ANTES de inicializar o SDK requestPermissions() } private fun requestPermissions() { BiometricPixSDK.requestPermission(this) { granted -> if (granted) { // Permissões concedidas, agora inicialize o SDK initializeSDK() } else { // Lidar com a negação de permissão showError("Permissão de localização é necessária para o cadastro") } } } private fun initializeSDK() { // Inicializar APÓS as permissões serem concedidas sdk = BiometricPixSDK( context = this, accessToken = getAccessToken() // Do seu backend ) // Agora pronto para prosseguir com o cadastro } override fun onDestroy() { super.onDestroy() if (::sdk.isInitialized) { sdk.cleanup() } } } ``` Gerenciamento de Recursos Sempre chame `cleanup()` quando terminar de usar o SDK (por exemplo, quando a activity for destruída ou o usuário fizer logout) para liberar adequadamente os recursos e limpar tarefas em segundo plano. ## Fluxo de Cadastro (6 Etapas) O processo de cadastro registra o dispositivo de um usuário com sua instituição para pagamentos biométricos. ```mermaid sequenceDiagram autonumber participant User participant YourApp participant BiometricPixSDK participant BelvoAPI participant Institution Note over YourApp,BiometricPixSDK: Chamada 1: getPaymentInstitutions() User->>YourApp: Inicia o cadastro YourApp->>BiometricPixSDK: getPaymentInstitutions() BiometricPixSDK->>BelvoAPI: Buscar instituições BelvoAPI-->>BiometricPixSDK: Lista de instituições BiometricPixSDK-->>YourApp: List<Institution> YourApp->>User: Exibir seletor de instituição User-->>YourApp: Seleciona instituição Note over YourApp,BiometricPixSDK: Chamada 2: createEnrollment() + openRedirectUrl() YourApp->>BiometricPixSDK: createEnrollment(cpf, institution, accountTenure, callbackUrl) BiometricPixSDK->>BiometricPixSDK: Coletar sinais de risco internamente BiometricPixSDK->>BelvoAPI: POST /enrollments/ BelvoAPI-->>BiometricPixSDK: Cadastro criado (redirect_url) BiometricPixSDK-->>YourApp: Objeto de Cadastro YourApp->>BiometricPixSDK: openRedirectUrl(context, redirect_url) BiometricPixSDK->>Institution: Abrir app da instituição User->>Institution: Aprovar cadastro no app da instituição Institution-->>YourApp: Callback OAuth (code, state, id_token) Note over YourApp,BiometricPixSDK: Chamada 3: completeEnrollmentAfterRedirection() YourApp->>BiometricPixSDK: completeEnrollmentAfterRedirection(callbackUrl) BiometricPixSDK->>BelvoAPI: POST /enrollments/complete-redirection/ BelvoAPI-->>BiometricPixSDK: Cadastro atualizado BiometricPixSDK-->>YourApp: Objeto de Cadastro Note over YourApp,BiometricPixSDK: Chamada 4: getFidoRegistrationOptions() YourApp->>BiometricPixSDK: getFidoRegistrationOptions(enrollmentId) BiometricPixSDK->>BelvoAPI: Consultar opções FIDO (auto-retry) BelvoAPI-->>BiometricPixSDK: Opções de registro FIDO BiometricPixSDK-->>YourApp: FidoRegistrationOptions Note over YourApp,BiometricPixSDK: Chamada 5: startRegistration() YourApp->>BiometricPixSDK: startRegistration(fidoOptions, callback) BiometricPixSDK->>User: Solicitar biometria (impressão digital/rosto) User-->>BiometricPixSDK: Fornece biometria BiometricPixSDK-->>YourApp: Credencial via callback Note over YourApp,BiometricPixSDK: Chamada 6: confirmEnrollment() YourApp->>BiometricPixSDK: confirmEnrollment(enrollmentId, credential) BiometricPixSDK->>BelvoAPI: POST /enrollments/{id}/confirm/ BelvoAPI->>Institution: Registrar credencial FIDO Institution-->>BelvoAPI: Registro confirmado BelvoAPI-->>BiometricPixSDK: Cadastro SUCEDIDO BiometricPixSDK-->>YourApp: Sucesso (Boolean) YourApp->>User: Mostrar tela de sucesso ``` ### Passo 1: Obter Instituições de Pagamento Busque a lista de instituições que suportam pagamentos biométricos: ```kotlin import com.belvo.biometricpixsdk.BiometricPixSDK import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import kotlinx.coroutines.launch class EnrollmentViewModel( private val sdk: BiometricPixSDK ) : ViewModel() { private val _institutions = MutableStateFlow>(emptyList()) val institutions: StateFlow> = _institutions fun loadInstitutions() { viewModelScope.launch { try { _institutions.value = sdk.getPaymentInstitutions() } catch (e: Exception) { // Tratar erro (rede, autenticação, etc.) _error.value = "Falha ao carregar instituições: ${e.message}" } } } } ``` **Exibir instituições para o usuário:** ```kotlin @Composable fun InstitutionPickerScreen( viewModel: EnrollmentViewModel ) { val institutions by viewModel.institutions.collectAsState() LazyColumn { items(institutions) { institution -> InstitutionItem( institution = institution, onClick = { viewModel.selectInstitution(institution) } ) } } LaunchedEffect(Unit) { viewModel.loadInstitutions() } } @Composable fun InstitutionItem( institution: Institution, onClick: () -> Unit ) { Row( modifier = Modifier .fillMaxWidth() .clickable(onClick = onClick) .padding(16.dp) ) { AsyncImage( model = institution.iconLogo, contentDescription = institution.displayName, modifier = Modifier.size(40.dp) ) Spacer(modifier = Modifier.width(16.dp)) Text(text = institution.displayName) } } ``` ### Passo 2: Criar Inscrição e Abrir o App da Instituição Crie a inscrição e imediatamente abra o app da instituição: ```kotlin fun startEnrollment() { val institution = _selectedInstitution.value ?: return viewModelScope.launch { try { // Criar inscrição val enrollment = sdk.createEnrollment( cpf = userCPF, // CPF do usuário institution = institution.id, // ID da instituição selecionada accountTenure = customerCreatedDate, // Formato "YYYY-MM-DD" callbackUrl = "https://yourdomain.com/callback" ) // Salvar ID da inscrição e ID do dispositivo para uso posterior _enrollmentId.value = enrollment.id _deviceId.value = enrollment.details.riskSignals.deviceId // Imediatamente abrir o app da instituição usando a URL de redirecionamento enrollment.details.redirectUrl?.let { url -> sdk.openRedirectUrl(context, url) } ?: run { _error.value = "Nenhuma URL de redirecionamento recebida da inscrição" } } catch (e: Exception) { _error.value = "Falha na criação da inscrição: ${e.message}" } } } ``` Formato de Duração da Conta O parâmetro `accountTenure` deve ser a data em que o usuário foi criado como Cliente Belvo, no formato `YYYY-MM-DD`. Extraia isso do timestamp `created_at` do Cliente (primeiros 10 caracteres). O método `openRedirectUrl()` do SDK lida com a abertura do app da instituição automaticamente. A instituição redirecionará de volta para o seu `callbackUrl` com parâmetros OAuth. ### Passo 5: Completar o Cadastro Após Redirecionamento Trate o callback OAuth na sua atividade e complete o cadastro: ```kotlin // No seu MainActivity override fun onNewIntent(intent: Intent?) { super.onNewIntent(intent) intent?.data?.let { uri -> handleEnrollmentCallback(uri) } } fun handleEnrollmentCallback(uri: Uri) { viewModelScope.launch { try { val enrollment = sdk.completeEnrollmentAfterRedirection( callbackUrl = uri.toString() // SDK analisa os parâmetros automaticamente ) // Verifique se foi bem-sucedido when (enrollment.status) { "PENDING" -> { // Sucesso - prossiga para o registro FIDO getFidoOptions(enrollment.id) } "FAILED" -> { // Trate a falha _error.value = "${enrollment.statusReasonCode}: ${enrollment.statusReasonMessage}" } } } catch (e: Exception) { _error.value = "Falha ao completar o cadastro: ${e.message}" } } } ``` Alternativa: Parâmetros Manuais Se preferir analisar a URL de callback você mesmo, pode passar os parâmetros individualmente: ```kotlin val enrollment = sdk.completeEnrollmentAfterRedirection( state = stateParam, code = codeParam, idToken = idTokenParam ) ``` ### Passo 4: Obter Opções de Registro FIDO Recupere as opções FIDO necessárias para o registro biométrico. O SDK faz a verificação automaticamente por até 5 minutos: ```kotlin fun getFidoOptions(enrollmentId: String) { viewModelScope.launch { // O SDK verifica automaticamente a cada 1 segundo por até 5 minutos val fidoOptions = sdk.getFidoRegistrationOptions(enrollmentId) if (fidoOptions != null) { // Opções FIDO recebidas, prossiga para o registro biométrico startBiometricRegistration(fidoOptions) } else { // Tempo de verificação esgotado (5 minutos se passaram) _error.value = "Tempo esgotado aguardando as opções FIDO. Por favor, tente novamente." } } } ``` Verificação Automática O método `getFidoRegistrationOptions()` lida com toda a lógica de verificação automaticamente. Ele verifica a cada 1 segundo por até 5 minutos, então você não precisa implementar nenhuma lógica de tentativa novamente. ### Passo 5: Registrar Biometria e Confirmar Solicite ao usuário os dados biométricos e confirme o registro: ```kotlin class EnrollmentViewModel( private val sdk: BiometricPixSDK ) : ViewModel() { private var enrollmentId: String? = null fun startBiometricRegistration(fidoOptions: FidoRegistrationOptions) { try { sdk.startRegistration( fidoOptions = fidoOptions.toJsonString(), callback = object : FidoRegistrationCallback { override fun onSuccess(credential: PublicKeyCredential, response: AuthenticatorAttestationResponse) { // SDK lida com a criação do payload automaticamente confirmEnrollment(credential, response) } override fun onError(error: String) { _error.value = "Registro biométrico falhou: $error" } } ) } catch (e: Exception) { _error.value = "Falha ao iniciar o registro: ${e.message}" } } private fun confirmEnrollment( credential: PublicKeyCredential, response: AuthenticatorAttestationResponse ) { val enrollmentId = this.enrollmentId ?: return viewModelScope.launch { val success = sdk.confirmEnrollment( enrollmentId = enrollmentId, credential = credential, response = response ) if (success) { _state.value = EnrollmentState.Success } else { _error.value = "Confirmação de registro falhou" } } } } ``` Registro Completo! O dispositivo agora está registrado e pronto para pagamentos biométricos. ## Fluxo de Pagamento (4 Etapas) Uma vez inscrito, iniciar pagamentos requer quatro chamadas de método: ```mermaid sequenceDiagram autonumber participant User participant YourApp participant BiometricPixSDK participant BelvoAPI participant Institution Note over YourApp,BiometricPixSDK: Chamada 1: listEnrollments() User->>YourApp: Inicia pagamento YourApp->>BiometricPixSDK: listEnrollments(deviceId) BiometricPixSDK->>BelvoAPI: GET /enrollments/?device_id=... BelvoAPI-->>BiometricPixSDK: List<Enrollment> BiometricPixSDK-->>YourApp: Lista de inscrições YourApp->>User: Exibir seletor de inscrição User-->>YourApp: Seleciona inscrição Note over YourApp,BiometricPixSDK: Chamada 2: createPaymentIntent() YourApp->>BiometricPixSDK: createPaymentIntent(payload) BiometricPixSDK->>BelvoAPI: POST /payment-intents/ BelvoAPI-->>BiometricPixSDK: PaymentIntent (com opções FIDO) BiometricPixSDK-->>YourApp: Objeto PaymentIntent Note over YourApp,BiometricPixSDK: Chamada 3: startSigning() + collectRiskSignals() YourApp->>BiometricPixSDK: startSigning(fidoOptions, callback) BiometricPixSDK->>User: Solicitar biometria (impressão digital/rosto) User-->>BiometricPixSDK: Fornece biometria BiometricPixSDK-->>YourApp: Asserção via callback YourApp->>BiometricPixSDK: collectRiskSignals(accountTenure) BiometricPixSDK-->>YourApp: RiskSignals Note over YourApp,BiometricPixSDK: Chamada 4: authorizePaymentIntent() YourApp->>BiometricPixSDK: authorizePaymentIntent(paymentIntentId, payload) BiometricPixSDK->>BelvoAPI: POST /payment-intents/{id}/authorize/ BelvoAPI->>Institution: Processar pagamento Institution-->>BelvoAPI: Pagamento confirmado BelvoAPI-->>BiometricPixSDK: Pagamento SUCCEEDED BiometricPixSDK-->>YourApp: Sucesso na autorização (Boolean) YourApp->>User: Mostrar confirmação de pagamento ``` ### Passo 1: Listar Inscrições Busque todas as inscrições para o dispositivo atual e permita que o usuário selecione uma: ```kotlin class PaymentViewModel( private val sdk: BiometricPixSDK ) : ViewModel() { private val _enrollments = MutableStateFlow>(emptyList()) val enrollments: StateFlow> = _enrollments fun loadEnrollments(deviceId: String) { viewModelScope.launch { try { _enrollments.value = sdk.listEnrollments(deviceId) } catch (e: Exception) { _error.value = "Falha ao carregar inscrições: ${e.message}" } } } } ``` **Exibir inscrições para o usuário:** ```kotlin @Composable fun EnrollmentSelectionScreen( viewModel: PaymentViewModel ) { val enrollments by viewModel.enrollments.collectAsState() LazyColumn { items(enrollments) { enrollment -> enrollment.institution?.let { institution -> EnrollmentItem( enrollment = enrollment, institution = institution, onClick = { viewModel.selectEnrollment(enrollment) } ) } } } LaunchedEffect(Unit) { viewModel.loadEnrollments(savedDeviceId) } } @Composable fun EnrollmentItem( enrollment: Enrollment, institution: Institution, onClick: () -> Unit ) { Row( modifier = Modifier .fillMaxWidth() .clickable(onClick = onClick) .padding(16.dp) ) { AsyncImage( model = institution.iconLogo, contentDescription = institution.displayName, modifier = Modifier.size(40.dp) ) Spacer(modifier = Modifier.width(16.dp)) Column { Text(text = institution.displayName) Text( text = "Status: ${enrollment.status}", style = MaterialTheme.typography.bodySmall, color = MaterialTheme.colorScheme.onSurfaceVariant ) } } } ``` ### Passo 2: Criar Intenção de Pagamento Crie uma intenção de pagamento com todos os detalhes do pagamento: ```kotlin fun createPayment( amount: Double, enrollmentId: String, beneficiaryAccountId: String ) { val payload = CreatePaymentIntentPayload( amount = amount, customer = Customer(identifier = userCPF), // CPF do usuário description = "Pagamento por serviços", statementDescription = "Compra ACME Corp", allowedPaymentMethodTypes = listOf("open_finance_biometric_pix"), paymentMethodDetails = PaymentMethodDetails( openFinanceBiometricPix = OpenFinanceBiometricPixPaymentMethodDetails( beneficiaryBankAccount = beneficiaryAccountId, enrollment = enrollmentId ) ), confirm = true ) viewModelScope.launch { try { val paymentIntent = sdk.createPaymentIntent(payload) // Salvar ID da intenção de pagamento _paymentIntentId.value = paymentIntent.id // Extrair opções FIDO para o próximo passo paymentIntent.paymentMethodInformation?.openFinanceBiometricPix?.fidoOptions?.let { fidoOptions -> promptForBiometric(fidoOptions) } } catch (e: Exception) { _error.value = "Falha ao criar intenção de pagamento: ${e.message}" } } } ``` ### Passo 3: Coletar Sinais Biométricos e de Risco Solicite a autenticação biométrica e colete sinais de risco: ```kotlin class PaymentViewModel( private val sdk: BiometricPixSDK ) : ViewModel() { private var paymentIntentId: String? = null private var riskSignals: RiskSignals? = null private var assertionResponse: AssertionResponse? = null fun promptForBiometric(fidoOptions: FidoOptions) { try { sdk.startSigning( fidoOptions = fidoOptions.toJsonString(), fallbackCredential = null, // Opcional: forneça se você tiver um callback = object : FidoAuthenticationCallback { override fun onSuccess(response: AssertionResponse) { // Armazene a resposta de asserção assertionResponse = response // Colete sinais de risco collectRiskSignals() } override fun onError(error: String) { _error.value = "Falha na autenticação biométrica: $error" } } ) } catch (e: Exception) { _error.value = "Falha ao iniciar a assinatura: ${e.message}" } } private fun collectRiskSignals() { try { riskSignals = sdk.collectRiskSignals( accountTenure = customerCreatedDate // "YYYY-MM-DD" ) // Assim que tivermos tanto a asserção quanto os sinais de risco, autorize o pagamento if (assertionResponse != null && riskSignals != null) { authorizePayment() } } catch (e: Exception) { _error.value = "Falha ao coletar sinais de risco: ${e.message}" } } } ``` ### Passo 4: Autorizar Pagamento Autorize o pagamento com os dados coletados: ```kotlin private fun authorizePayment() { val paymentIntentId = this.paymentIntentId ?: return val riskSignals = this.riskSignals ?: return val assertion = this.assertionResponse ?: return val payload = AuthorizePaymentIntentPayload( platform = "android", riskSignals = riskSignals, assertion = assertion ) viewModelScope.launch { val success = sdk.authorizePaymentIntent( paymentIntentId = paymentIntentId, payload = payload ) if (success) { _state.value = PaymentState.Success } else { _error.value = "Falha na autorização do pagamento" } } } ``` Fluxo de Pagamento Completo! O pagamento agora está autorizado e em processamento. Você precisa monitorar eventos de webhook para acompanhar seu status final. ## Tratamento de Erros Todos os métodos do SDK que realizam operações de rede podem lançar exceções. Certifique-se de tratá-las adequadamente: ```kotlin try { val institutions = sdk.getPaymentInstitutions() // Sucesso } catch (e: BiometricPixSDKException) { when (e) { is BiometricPixSDKException.NetworkError -> { // Tratar problemas de rede Log.e(TAG, "Erro de rede: ${e.message}") } is BiometricPixSDKException.AuthenticationError -> { // Tratar token inválido ou expirado Log.e(TAG, "Falha na autenticação - o token pode estar expirado") } is BiometricPixSDKException.InvalidParametersError -> { // Tratar entrada inválida Log.e(TAG, "Parâmetros inválidos: ${e.message}") } is BiometricPixSDKException.UnknownError -> { // Tratar erros desconhecidos Log.e(TAG, "Erro: ${e.message}") } } } catch (e: Exception) { Log.e(TAG, "Erro inesperado: ${e.message}") } ``` ## Webhooks Embora o SDK gerencie a maior parte do fluxo de trabalho, você ainda deve escutar notificações de webhook para lidar com atualizações assíncronas: - **Mudanças no status de inscrição:** tipo de webhook `ENROLLMENTS` - **Mudanças no status de pagamento:** tipo de webhook `PAYMENT_INTENTS` Para a documentação completa de webhooks, veja Webhooks de Pagamentos (Brasil). ## Referência de Método SDK ### Inicialização **`BiometricPixSDK(context: Context, accessToken: String)`** - Cria uma nova instância do SDK com o contexto e o access token fornecidos - Deve ser inicializado uma vez e reutilizado em todo o seu aplicativo - Access token obtido a partir do endpoint `/payments/api/widget-token/` **`cleanup()`** - Libera os recursos do SDK e limpa as tarefas em segundo plano - Chame em `onCleared()` ou quando o usuário fizer logout ### Métodos de Inscrição **`getPaymentInstitutions(): List`** - Busca todas as instituições que suportam pagamentos biométricos - Retorna uma lista de objetos `Institution` com `id`, `displayName`, `iconLogo`, etc. - Lança exceções em erros de rede ou autenticação **`createEnrollment(cpf: String, institution: String, accountTenure: String, callbackUrl: String): Enrollment`** - Cria a inscrição e coleta sinais de risco automaticamente - `cpf`: Número de CPF do usuário - `institution`: ID da instituição de `getPaymentInstitutions()` - `accountTenure`: Data de criação do cliente no formato "YYYY-MM-DD" - `callbackUrl`: Deep link para callback OAuth (deve ser registrado como App Link) - Retorna um objeto `Enrollment` com `id`, `redirect_url`, `device_id` **`openRedirectUrl(context: Context, url: String)`** - Abre o aplicativo da instituição usando o URL de redirecionamento fornecido - Lida com o redirecionamento automaticamente, incluindo deep linking - Deve ser chamado imediatamente após `createEnrollment()` com o `redirect_url` da resposta de inscrição - `context`: Contexto da Activity ou Application - `url`: O URL de redirecionamento do objeto de inscrição **`completeEnrollmentAfterRedirection(callbackUrl: String): Enrollment`** - Completa a inscrição após o callback OAuth da instituição - Analisa automaticamente os parâmetros OAuth do URL completo de callback - Alternativa: `completeEnrollmentAfterRedirection(state: String, code: String, idToken: String)` **`getFidoRegistrationOptions(enrollmentId: String): FidoRegistrationOptions?`** - Faz polling para opções FIDO (tentativa automática: intervalo de 1 segundo, timeout de 5 minutos) - Retorna `FidoRegistrationOptions` quando pronto - Retorna `null` se o polling expirar **`startRegistration(fidoOptions: String, callback: FidoRegistrationCallback)`** - Inicia o fluxo de registro biométrico (reconhecimento de impressão digital/face) - `fidoOptions`: String JSON de `FidoRegistrationOptions.toJsonString()` - `callback`: Interface para receber callbacks de sucesso/erro **`confirmEnrollment(enrollmentId: String, credential: PublicKeyCredential, response: AuthenticatorAttestationResponse): Boolean`** - Confirma a inscrição com credencial FIDO - Retorna `true` em caso de sucesso, `false` em caso de falha ### Métodos de Pagamento **`listEnrollments(deviceId: String): List`** - Busca todas as inscrições para um dispositivo - Retorna uma lista de objetos `Enrollment` com dados enriquecidos da instituição - Filtre por `status == "SUCCEEDED"` para mostrar apenas inscrições ativas **`createPaymentIntent(payload: CreatePaymentIntentPayload): PaymentIntent`** - Cria uma intenção de pagamento - Retorna `PaymentIntent` com `id` e `paymentMethodInformation.openFinanceBiometricPix.fidoOptions` **`startSigning(fidoOptions: String, fallbackCredential: String?, callback: FidoAuthenticationCallback)`** - Inicia a autenticação biométrica para pagamento - `fallbackCredential`: Credencial opcional para cenários de tentativa novamente - `callback`: Interface para receber a resposta de asserção **`collectRiskSignals(accountTenure: String): RiskSignals`** - Coleta impressões digitais do dispositivo e sinais de segurança - `accountTenure`: Data de criação do cliente no formato "YYYY-MM-DD" - Retorna objeto `RiskSignals` para carga de autorização **`authorizePaymentIntent(paymentIntentId: String, payload: AuthorizePaymentIntentPayload): Boolean`** - Autoriza pagamento com asserção biométrica e sinais de risco - Retorna `sim` em caso de sucesso, `false` em caso de falha