# Guía de Biometric Pix (Usando Android SDK)
Próximo Lanzamiento
Esta documentación cubre características de nuestro próximo lanzamiento. Aunque la funcionalidad principal y el flujo de trabajo descritos aquí permanecerán sin cambios, puede que notes algunas mejoras antes del lanzamiento final, tales como:
- Actualizaciones y optimizaciones del Android SDK
- Mejoras en la documentación (enlaces, terminología, diagramas)
- Actualizaciones de referencia de la API para los endpoints de enrolamiento
Con Biometric Pix de Belvo, la recolección de pagos de los usuarios se vuelve fluida, eliminando la necesidad de que los usuarios naveguen a su institución financiera para aprobar cada solicitud de pago individual.
El primer paso para habilitar la recolección de pagos biométricos es **enrolar** el dispositivo del usuario con su institución. Durante el enrolamiento, los datos clave sobre el dispositivo y las credenciales de clave pública del usuario se registran de manera segura con su institución, asegurando que los pagos futuros puedan ser confirmados usando solo la autenticación biométrica.
Una vez que el enrolamiento está completo, puedes comenzar a solicitar pagos directamente desde el dispositivo del usuario.
En esta guía, te llevaremos a través de cada paso, desde el enrolamiento del dispositivo hasta iniciar con éxito una solicitud de pago en un dispositivo Android.
## Requisitos previos
Antes de continuar con esta guía, asegúrate de que:
1. Has generado tus Claves de la API de Pagos de Belvo
2. Configuraste Webhooks
3. Instalaste el SDK de Android de Belvo
- Instalación del SDK de Android de Belvo
**Requisitos mínimos**
- **Android SDK**: API 31 (Android 12) o superior
- **Compile SDK**: 35
- **Java Version**: 11
- **Kotlin**: Compatible con la última versión estable
**Instrucciones**
Para instalar el SDK de Android de Belvo, añade las siguientes dependencias del SDK a tu `build.gradle.kts` a nivel de aplicación:
```kotlin
dependencies {
implementation("com.belvo.biometricpixsdk:biometricpixsdk:1.0.0")
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.6.0")
}
```
Además, necesitarás añadir los siguientes permisos a tu archivo AndroidManifest.xml:
```xml
```
4. Habilitaste el intercambio de credenciales con Belvo
- Habilitación del intercambio de credenciales
Para completar la integración del SDK de Android de Belvo y habilitar el intercambio seguro de credenciales entre tu aplicación y el dominio de Belvo (`belvo.com`), necesitamos configurar un **Enlace de Activo Digital**.
Esta configuración crea una conexión confiable entre tu aplicación y `belvo.com`, permitiendo que tu aplicación acceda de manera segura a funciones del SDK de Belvo como el registro de Inscripción de usuario y la Autorización de Intención de Pago. Estos datos corresponden a la **sección `target`** de una entrada de [Enlaces de Activos Digitales](https://developers.google.com/digital-asset-links/v1/getting-started#quick-usage-example). Usamos estos datos para actualizar nuestro archivo `assetlinks.json` alojado en: `https://belvo.com/.well-known/assetlinks.json`
Necesitarás proporcionarnos la siguiente información de tu aplicación:
- El **nombre del paquete** de tu aplicación
- La **huella digital del certificado de firma SHA-256** de tu aplicación (consulta la [documentación oficial de Android sobre cómo obtener esta huella digital](https://developer.android.com/training/app-links/verify-android-applinks#web-assoc)).
Un ejemplo de tu objeto target debería verse así:
```json
{
"namespace": "android_app",
"package_name": "com.example.yourapp",
"sha256_cert_fingerprints": [
"12:34:56:78:9A:BC:DE:F0:12:34:56:78:9A:BC:DE:F0:12:34:56:78:9A:BC:DE:F0:12:34:56:78:9A:BC:DE:F0"
]
}
```
5. Compartiste el **FACETID** de tu aplicación con Belvo. Para obtener detalles sobre cómo generar el FACETID de tu aplicación, consulta nuestra guía de Generación de FACETID (Android SDK).
6. Además, para cada usuario que desees inscribir en el sistema Biometric Pix, **primero necesitarás crear un Cliente de Belvo.**
## Inscripción
La inscripción es el proceso de registrar el dispositivo de un usuario en su institución para permitir pagos biométricos para un comerciante determinado. Durante el proceso, utilizarás una **combinación** del SDK de Android de Belvo Payments y la API para obtener detalles clave sobre el dispositivo, así como los datos públicos biométricos.
1. **Listar Instituciones:** Solicita al usuario que seleccione su institución financiera deseada para inscribirse, utilizando la API de Belvo para mostrar las opciones disponibles.
2. **Inicializar SDK y Recopilar Señales de Riesgo:** Inicializa el SDK de Android de Belvo, solicita al usuario los permisos necesarios y recopila señales de riesgo, incluido el ID del dispositivo.
3. **Crear y Actualizar Inscripción:** Envía las señales de riesgo recopiladas, junto con el ID del cliente, el ID de la institución y una URL de callback, al servidor de Belvo para crear la inscripción. Luego, redirige al usuario a la aplicación de su institución para su aprobación. Una vez que sean redirigidos de vuelta a tu URL de callback con detalles, envía estos a Belvo para actualizar el estado de la inscripción.
4. **Consultar Opciones de FIDO:** Consulta continuamente la API de Belvo (`GET /enrollments/{id}/fido-registration-options/`) para obtener las opciones FIDO necesarias para el registro biométrico.
⚠️ **Estrategia de Consulta:** Recomendamos consultar nuestro servidor cada dos segundos durante un máximo de dos minutos. Si no se recibe respuesta dentro de este período, instruye al usuario para que lo intente de nuevo.
5. **Solicitar Biométricos:** Toma las opciones FIDO de la API de Belvo y utiliza el método `startRegistration()` del SDK de Android de Belvo para solicitar al usuario su gesto biométrico.
6. **Finalizar Inscripción:** Envía los datos públicos biométricos a Belvo usando `POST /enrollments/{id}/confirm/`. Después de eso, consulta `GET /enrollments/{id}/` hasta recibir una respuesta (estado de inscripción = `SUCCEEDED` o `FAILED`).
```mermaid
sequenceDiagram
autonumber
participant EndUser
participant ClientAppBackend
participant BiometricPixSDK
participant Payments
participant BankAPP
Note over EndUser,BankAPP: 0. Solicitar al usuario que seleccione la institución para inscribirse (API de Belvo)
ClientAppBackend ->> Payments: /institutions/
Payments -->> ClientAppBackend: Lista de instituciones
ClientAppBackend ->> EndUser: Mostrar lista de instituciones
EndUser -->> ClientAppBackend: Institución seleccionada
Note over EndUser,BankAPP: 1. Inicializar SDK y Recopilar Señales de Riesgo (SDK de Android)
ClientAppBackend ->> BiometricPixSDK: initialize()
BiometricPixSDK ->> EndUser: requestPermission()
EndUser -->> BiometricPixSDK: Otorga permiso para recopilar señales de riesgo
ClientAppBackend ->> BiometricPixSDK: collectRiskSignals(accountTenure)
BiometricPixSDK -->> ClientAppBackend: Devuelve riskSignals + deviceId (encriptado)
ClientAppBackend ->> ClientAppBackend: Persistir deviceId (encriptado)
Note over EndUser,BankAPP: 2. Enviar Señales de Riesgo a Belvo (API de Belvo)
ClientAppBackend ->> Payments: POST /enrollments/ (riskSignals, callback_url)
Payments -->> ClientAppBackend: 201 Created (enrollment_id, redirect_url)
ClientAppBackend ->> ClientAppBackend: Persistir enrollment_id asociado con deviceId (encriptado)
Note over EndUser,BankAPP: 3. Redirigir al usuario a su APP y actualizar inscripción
ClientAppBackend ->> EndUser: Redirigir a BankAPP (usando el redirect_url)
EndUser ->> BankAPP: Aprueba inscripción
BankAPP ->> ClientAppBackend: La institución redirige a callback_url con detalles en parámetros de consulta
ClientAppBackend ->> Payments: Actualizar inscripción con valores recibidos usando POST /enrollments/complete-redirection/
Payments -->> ClientAppBackend: Devuelve carga útil de inscripción actualizada
Note over EndUser,BankAPP: 4. Consultar API de Belvo para opciones de FIDO
ClientAppBackend ->> Payments: Consultar GET /enrollments/{id}/fido-registration-options/
Payments -->> ClientAppBackend: Devuelve fido_options
Note over EndUser,BankAPP: 5. Solicitar Biométricos (SDK de Android)
ClientAppBackend ->> BiometricPixSDK: startRegistration(fido_options)
BiometricPixSDK ->> EndUser: Solicitar datos biométricos
EndUser -->> BiometricPixSDK: Proporciona biométrico (cara/huella/PIN)
BiometricPixSDK -->> ClientAppBackend: attestationObject, clientDataJSON, credential
Note over EndUser,BankAPP: 6. Enviar biométricos para finalizar inscripción y consultar respuesta
ClientAppBackend ->> Payments: POST /enrollments/{id}/confirm/ (attestationObject, clientDataJSON, credential)
Payments -->> ClientAppBackend: 204 - No Content
ClientAppBackend ->> Payments: Consultar GET /enrollments/{id}/
Payments -->> ClientAppBackend: status = SUCCEEDED
```
## Solicitar al usuario que seleccione la institución para inscribirse (API de Belvo)
En tu aplicación, solicita a tu usuario que seleccione la institución donde desea inscribir el dispositivo. Utiliza la solicitud de Listar todas las instituciones de pago para obtener una lista de todas las posibles instituciones. Una vez que el usuario seleccione la institución, guarda el id de la institución (requerido en el paso de Enviar Señales de Riesgo a Belvo (API)).
## Inicializar SDK y Recopilar Señales de Riesgo (Android SDK)
A continuación, en tu aplicación, necesitarás realizar las siguientes llamadas:
### initialize()
Este método debe ser llamado en el método `onCreate()` de tu `Activity` antes de cualquier operación FIDO. Debes usar `createActivityResultCallback()` para obtener la función de callback adecuada para el parámetro `fidoLauncher`.
El método `initialize(fidoLauncher)` configura el manejo interno de resultados de actividad requerido para las operaciones biométricas FIDO2. Debe ser llamado una vez durante el ciclo de vida de la actividad para preparar el SDK para lanzar los prompts biométricos y recibir sus resultados.
En el ejemplo a continuación, puedes ver que en la variable `fidoLauncher` también usamos el `createActivityResultCallback()` del SDK de Android de Belvo. Este método devuelve una función de callback que debe ser utilizada al registrar el `ActivityResultLauncher` para operaciones FIDO. Actúa como el manejador interno del SDK para procesar los objetos `ActivityResult` recibidos de las actividades del sistema iniciadas por el flujo FIDO. Esto permite al SDK gestionar el estado de las operaciones biométricas sin problemas.
```kotlin
class MainActivity : ComponentActivity() {
private lateinit var biometricPixSDK: BiometricPixSDK
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
biometricPixSDK = BiometricPixSDK()
// Usa createActivityResultCallback() al configurar el launcher.
// Esta función lambda será utilizada internamente por el SDK para procesar los resultados FIDO.
val fidoLauncher = registerForActivityResult(
ActivityResultContracts.StartIntentSenderForResult(),
biometricPixSDK.createActivityResultCallback() // Esta lambda maneja todos los resultados de actividad FIDO
)
// Inicializa el SDK con el launcher configurado
biometricPixSDK.initialize(fidoLauncher)
}
}
```
Una vez que hayas inicializado el launcher, podemos proceder a solicitar el permiso del usuario para extraer señales de riesgo de su dispositivo usando el método `requestPermission()`.
### requestPermission()
Este método `requestPermission()` crea e inicia una solicitud de permisos para permisos de ubicación y estado del teléfono (`ACCESS_FINE_LOCATION`, `ACCESS_COARSE_LOCATION` y `READ_PHONE_STATE`). Maneja automáticamente el flujo de solicitud de permisos en tiempo de ejecución de Android y proporciona un callback con el resultado general. El método devuelve `ActivityResultLauncher>`: La instancia del lanzador de permisos. Aunque se devuelve, normalmente puedes ignorar este valor de retorno, ya que la interacción principal es a través del callback `onResult` después de llamar a la función.
```kotlin
// Agrega esto a tu MainActivity
biometricPixSDK.requestPermission(this) { granted ->
if (granted) {
// Todos los permisos requeridos han sido concedidos. El SDK está listo para su funcionalidad completa.
Log.d("BiometricSDK", "Todos los permisos necesarios han sido concedidos.")
} else {
// Manejar los permisos denegados.
// Informar al usuario sobre las funciones que pueden no estar disponibles o guiarlo a la configuración.
Log.e("BiometricSDK", "Permisos denegados. La funcionalidad del SDK puede estar limitada.")
}
```
Cuando el usuario concede su permiso, puedes entonces extraer las señales de riesgo del dispositivo usando `collectRiskSignals(accountTenure)`.
### collectRiskSignals(accountTenure)
El método `collectRiskSignals(accountTenure)` recopila datos completos de huellas digitales del dispositivo y señales de seguridad. Los datos recopilados incluyen ID del dispositivo, estado de seguridad, información de hardware y señales de comportamiento, que son cruciales para que la institución realice evaluaciones de riesgo y detección de fraude. El método devuelve un objeto RiskSignals que necesitas guardar y enviar a los servidores de Belvo en una llamada de API. Además, necesitas persistir el valor de `deviceId` que el objeto RiskSignals devuelve para que más tarde puedas asociarlo con el ID de Inscripción (más adelante, al listar Inscripciones, necesitas proporcionar el `deviceID` para recibir todas las Inscripciones).
Parámetro accountTenure
En el argumento `accountTenure`, debes pasar la fecha en que el usuario fue creado como Cliente en la API de Belvo, en formato `YYYY-MM-DD`.
Esto se deriva del timestamp created_at del Cliente, sin embargo, solo necesitas enviar los primeros 10 caracteres correspondientes al año, mes y día (`YYYY-MM-DD`). Una expresión regular útil para extraer esto del parámetro `created_at` podría ser: `\d{4}-\d{2}-\d{2}`.
```kotlin
// Añade esto después de tu clase MainActivity
val riskSignals = biometricPixSDK.collectRiskSignals(accountTenure)
val userDeviceId = riskSignals.deviceId
```
Una vez que tengas las señales de riesgo y el ID del dispositivo, puedes enviar esta información a Belvo utilizando el método Create Enrollment.
## Crear Inscripción Usando Señales de Riesgo (API)
```curl
POST /enrollments/
```
```json
// Cuerpo de la Solicitud
{
"type": "open_finance_biometric_pix",
"details": {
"customer": "{{created_customer_uuid}}",
"institution": "{{selected_institution_uuid}}",
"name": "Nombre para la inscripción",
"platform": "ANDROID",
"callback_url": "{{https://deeplink_to_your_application}}",
"risk_signals": {}
}
}
```
| Parámetro | Tipo | Descripción |
| --- | --- | --- |
| `type` | string (enum) | El tipo de inscripción. Para Biometric Pix, esto debe establecerse en `open_finance_biometric_pix`. |
| `details` | object | Detalles sobre la inscripción del dispositivo. |
| `details.customer` | string (uuid) | El ID de Belvo para tu usuario. |
| `details.institution` | string (uuid) | El ID de Belvo para la institución que tu usuario seleccionó para la inscripción. |
| `details.callback_url` | string (uri) | El deeplink a donde tu usuario debe ser redirigido en tu aplicación después de que aprueben la inscripción en la aplicación de su institución. Debe ser compatible con HTTPS. |
| `details.name` | string | Un nombre legible para la inscripción. |
| `details.platform` | string | La plataforma a la que se refiere esta inscripción. Para dispositivos Android, esto debe establecerse en `ANDROID`. |
| `details.risk_signals` | object | El objeto `RiskSignals` (convertido a JSON) que recibiste después de usar el método `collectRiskSignals`. |
Registra tu callback_url en assetlinks.json
El `callback_url` que proporciones **debe** estar registrado en tu archivo **assetlinks.json** bajo tu host de deeplink. Por ejemplo, si tu `callback_url` es `https://deeplink.quebom.com.br/callback/`, entonces debes tener un archivo `https://deeplink.quebom.com.br/.well-known/assetlinks.json` que contenga una `relation` que otorgue permiso para manejar todas las URLs y un `target` que contenga la huella digital pública. Por ejemplo:
```json
[{
"relation": ["delegate_permission/common.handle_all_urls"], // [!code highlight]
"target": {
"namespace": "android_app",
"package_name": "com.quebom",
"sha256_cert_fingerprints":[ // [!code highlight]
"82:65:61:6B:CC:E3:67:46:44:83:E8:D0:88:B8:33:EE:42:47:B9:60:B4:6F:B7:43:AE:21:F2:0F:F2:4B:E9:53" // [!code highlight]
] // [!code highlight]
}
}]
```
En la respuesta, recibirás un `redirect_url` que necesitas mostrar a tu usuario para que puedan ser redirigidos a su institución para confirmar su inscripción.
```json
// 201 Created
{
"id": "82666cde-3f80-4350-b0f7-24cb8e9294c9",
"created_by": "56689ef8-4c92-44ae-b2c1-60505da4a7e1",
"created_at": "2024-11-26T11:20:57.389056Z",
"updated_at": "2024-11-26T11:20:57.389056Z",
"type": "open_finance_biometric_pix",
"status": "PENDING",
"details": {
"status": "AWAITING_ACCOUNT_HOLDER_VALIDATION",
"customer": "f78b14f3-5c1a-409a-966f-7b052b067cf0",
"institution": "188716fb-39ad-44a7-a992-6c278d2b24a4",
"platform": "ANDROID",
"name": "First Enrollment",
"callback_url": "deeplink-to-your-application",
"redirect_url": "https://www.user-banking-institituon.com/?enrollment_request=true...", // [!code highlight]
"risk_signals": "*****"
}
}
```
## Redirigir al usuario a su APP y actualizar la inscripción
Ahora necesitas redirigir a tu usuario a su institución usando el `redirect_url` para que puedan confirmar el proceso de inscripción. Durante el proceso, iniciarán sesión en su institución, revisarán la solicitud de inscripción y luego la autorizarán. Una vez que el usuario autorice la inscripción, la institución los redirigirá de vuelta al `callback_url` que proporcionaste.
Ejemplo de Éxito
```json
https://redirect.clientApplication.com/
?state=
&code=
&id_token=
```
Ejemplo de Error
```json
https://redirect.clientApplication.com/
?state=
&error=
&error_description=
```
La institución pasará datos en los parámetros de consulta que debes enviar a Belvo usando la solicitud de API de **Update Enrollment State**. Recomendamos transformar los parámetros de consulta en un objeto JSON y enviarlo directamente a Belvo.
## Actualizar Estado de Inscripción
Con el valor de la cadena de consulta guardado como un objeto JSON, puedes hacer la siguiente solicitud:
```json
POST /enrollments/complete-redirection/
```
Ejemplo de Éxito
```json Cuerpo de Solicitud Exitosa
{
"state": "{{state}}",
"code": "{{code}}",
"id_token": "{{id_token}}",
}
```
En el caso de que sea un callback exitoso, en la respuesta de la solicitud el `status` de la inscripción seguirá configurado como `PENDING`.
```json Actualización de Estado de Inscripción Exitosa
// 200 OK
{
"id": "{{enrollment.id}}", // [!code highlight]
"type": "open_finance_biometric_pix",
"status": "PENDING", // [!code highlight]
"details": {
"callback_url": "https://merchant.com/enrollment-success/",
"customer": "{{customer.id}}",
"expires_at": "2022-10-31T00:00:00Z",
"institution": "uuid",
"name": "My Enrollment",
"payer_information": {
"bank_account": {
"institution_id": "{{institution.id}}",
"agency": "1234",
"number": "*****6789",
"account_type": "CHECKINGS"
}
},
"platform": "ANDROID",
"redirect_url": "https://example.com/redirect-enrollment/",
"risk_signals": "*******",
"status": "AWAITING_ACCOUNT_HOLDER_VALIDATION"
},
"external_id": null,
"metadata": {},
"status_reason_code": null,
"status_reason_message": null,
"created_by": "{{belvo_client.id}}",
"created_at": "{{timestamp}}",
"updated_at": "{{timestamp}}"
}
```
La institución ahora procesará los datos de inscripción y proporcionará a Belvo las Opciones FIDO que se requieren para generar el desafío biométrico. Necesitarás consultar nuestra API para recuperar estos datos y luego solicitar datos biométricos de tu usuario.
Ejemplo de Error
```json
{
"state": "{{state}}",
"error": "{{error}}",
"error_description": "{{error_description}}"
}
```
En el caso de que sea un callback de error, nuestra API aún responderá con un `200 - OK` con el `status` de la inscripción configurado como `FAILED`. Además, el `status_reason_code` y el `status_reason_message` se establecerán para proporcionar más información sobre el fallo.
```json Actualización de Estado de Inscripción Fallida
// 200 OK
{
"id": "{{enrollment.id}}", // [!code highlight]
"type": "open_finance_biometric_pix",
"status": "FAILED", // [!code highlight]
"details": {
"callback_url": "https://merchant.com/enrollment-success/",
"customer": "{{customer.id}}",
"expires_at": "2022-10-31T00:00:00Z",
"institution": "uuid",
"name": "My Enrollment",
"payer_information": {
"bank_account": {
"institution_id": "{{institution.id}}",
"agency": "1234",
"number": "*****6789",
"account_type": "CHECKINGS"
}
},
"platform": "ANDROID",
"redirect_url": "https://example.com/redirect-enrollment/",
"risk_signals": "*******",
"status": "AWAITING_ACCOUNT_HOLDER_VALIDATION"
},
"external_id": null,
"metadata": {},
"status_reason_code": "insufficient_funds", // [!code highlight]
"status_reason_message": "No funds", // [!code highlight]
"created_by": "{{belvo_client.id}}",
"created_at": "{{timestamp}}",
"updated_at": "{{timestamp}}"
}
```
## Consultar la API de Belvo para opciones FIDO (API)
Consejos para la consulta
Envía una solicitud cada dos segundos hasta que recibas una respuesta o pasen dos minutos sin respuesta. Si no recibes respuesta después de dos minutos, muestra una pantalla de “Intenta de nuevo” a tu usuario y reinicia el proceso. En segundo plano, la Inscripción cambiará a `status` = `FAILED`.
Después de recibir la respuesta exitosa de la solicitud **Update Enrollment State**, necesitas consultar el siguiente endpoint para recibir las opciones de registro FIDO necesarias para solicitar datos biométricos.
```kotlin
GET /enrollments/{enrollment_id}/fido-registration-options/
```
Recibirás la siguiente respuesta `200 - OK` de nuestra API. Asegúrate de guardar el objeto ya que es un parámetro requerido para el método `startRegistration` del SDK.
```json
// 200 OK
{
"rp": {
"id": "belvo.com",
"name": "Raidiam Mockbank - Pipeline NRJ"
},
"user": {
"id": "a5bd0ef9-f8ab-41a2-b968-489761a91de6",
"name": "Ralph Bragg",
"displayName": "Ralph Bragg"
},
"challenge": "R3dsT2REOE5oZ25JbVE",
"pubKeyCredParams": [
{
"alg": -257,
"type": "public-key"
},
{
"alg": -7,
"type": "public-key"
}
],
"extensions": {
"appid": "true"
}
}
```
## Solicitud de Datos Biométricos (Android SDK)
Con la carga útil recibida, necesitas usar el método **startRegistration()**. Este método inicia el registro de credenciales biométricas utilizando protocolos FIDO2. Procesa las opciones de registro FIDO (una cadena JSON) recibidas de tu servidor backend y lanza el flujo de autenticación biométrica nativa del dispositivo (por ejemplo, huella digital o escaneo facial).
```kotlin
import com.belvo.biometricpixsdk.models.FidoRegistrationCallback
import com.belvo.biometricpixsdk.extensions.encodedRawId
import com.belvo.biometricpixsdk.extensions.encodedAttestationObject
import com.belvo.biometricpixsdk.extensions.encodedClientDataJSON
import com.google.android.gms.fido.fido2.api.common.PublicKeyCredential
import com.google.android.gms.fido.fido2.api.common.AuthenticatorAssertionResponse
// Método
fun startRegistration(
context: Context, // Contexto de la aplicación o actividad
fidoResponseString: String, // Opciones de registro FIDO JSON del servidor
callback: FidoRegistrationCallback // Callback del resultado del registro
)
// Implementa la interfaz de callback
val registrationCallback = object : FidoRegistrationCallback {
override fun onSuccess(credential: PublicKeyCredential, response: AuthenticatorAttestationResponse) {
// Manejar el registro exitoso
val credentialId = credential.encodedId
val credentialRawId = credential.encodedRawId
val attestationObject = response.encodedAttestationObject
val clientDataJson = response.encodedClientDataJSON
// Envía los datos de la credencial (credentialId, credentialRawId, attestationObject y clientDataJson)
// a tu servidor para luego ser enviados a la API de Belvo para confirmar la Inscripción.
}
override fun onError(error: String) {
// Manejar el error de registro
Log.e("FIDO", "El registro falló: $error")
}
}
// Iniciar registro con la respuesta del servidor
biometricPixSDK.startRegistration(
context = requireContext(), // si se usa en un Fragment
fidoResponseString = fidoOptions, // Opciones de registro Fido recopiladas de GET /enrollments/{id}/fido-registration-options/
callback = registrationCallback
)
```
Necesitas almacenar los siguientes valores en variables ya que se utilizan para confirmar la Inscripción en el siguiente paso:
- `credentialId`
- `credentialRawId`
- `attestationObject`
- `clientDataJson`
## Enviar datos biométricos para finalizar la inscripción y consultar la respuesta (API)
Para completar el proceso de Inscripción, necesitarás enviar los valores que recibiste al siguiente endpoint:
```kotlin
POST /payments/br/enrollments/{enrollment_id}/confirm/
```
```json
// Cuerpo de la Solicitud
{
"confirmation_data": {
"authenticatorAttachment": "platform",
"id": "{{credentialId}}",
"rawId": "{{credentialRawId}}",
"type": "public-key",
"response": {
"attestationObject": "{{attestationObject}}",
"clientDataJSON": "{{clientDataJson}}"
}
}
}
```
| Parámetro | Tipo | Descripción |
| --- | --- | --- |
| `authenticatorAttachment` | string | El tipo de autenticador. Debe establecerse en `platform`. |
| `id` | string | El `credentialId` que recibiste del método `startRegistration()`. |
| `rawId` | string | El `credentialRawId` que recibiste del método `startRegistration()`. |
| `type` | string | El tipo de credencial FIDO que se está generando. Debe establecerse en `public-key`. |
| `response.attestationObject` | string | El `attestationObject` que recibiste del método `startRegistration()`. |
| `response.clientDataJSON` | string | El `clientDataJson` que recibiste del método `startRegistration()`. |
Belvo responderá con un `204 - No Content` y enviará la información a la institución para completar el proceso de inscripción.
Consejos para Consultas
Envía una solicitud cada dos segundos hasta que recibas una respuesta o pasen dos minutos sin respuesta. Si no recibes respuesta después de dos minutos, muestra una pantalla de “Intenta de nuevo” a tu usuario y reinicia el proceso. En segundo plano, la Inscripción pasará a `status` = `FAILED`.
Necesitarás consultar el siguiente endpoint hasta que recibas una respuesta de la API de Belvo. Una vez que recibas una respuesta, verifica el campo `status`.
```bash
GET /enrollments/{enrollment_id}/
```
Si el `status` es `SUCCEEDED`, ¡perfecto! ¡La inscripción está lista y puedes comenzar a realizar pagos!
## Realizar un Pago
Una vez que el dispositivo de un usuario está registrado con éxito, puedes iniciar solicitudes de pago utilizando sus credenciales biométricas almacenadas. Este proceso involucra:
1. Seleccionar un Registro
2. Crear una intención de pago
3. Recopilar datos de autenticación biométrica
4. Autorizar el pago
```mermaid
sequenceDiagram
autonumber
participant EndUser
participant ClientAppBackend
participant BiometricPixSDK
participant Payments
%% 1 - Creación de Intención de Pago usando registro autorizado
Note over EndUser,Payments: 1. Usuario selecciona Registro (API)
EndUser ->> ClientAppBackend: Hace clic en "Realizar Pago"
ClientAppBackend ->> Payments: GET /enrollments/?device_id=1234
Payments -->> ClientAppBackend: Devuelve lista de registros
ClientAppBackend -->> EndUser: Muestra lista de registros
EndUser ->> ClientAppBackend: Elige de la lista de registros
Note over EndUser,Payments: 2. Crear Intención de Pago (API)
ClientAppBackend ->> Payments: POST /payment-intents/ (enrollment_id)
Payments -->> ClientAppBackend: Devuelve datos de payment_intent (id, fido_options)
ClientAppBackend ->> ClientAppBackend: Persiste ID de Intención de Pago
%% 2 - Autorización de Intención de Pago usando AttestationObject + RiskSignals
Note over EndUser,Payments: 3. Recopilar datos biométricos (SDK)
ClientAppBackend ->> BiometricPixSDK: startSign(fido_options)
ClientAppBackend ->> BiometricPixSDK: collectRiskSignals(accountTenure)
BiometricPixSDK -->> ClientAppBackend: Devuelve credentialId, attestationObject, clientDataJSON, riskSignals
Note over EndUser,Payments: 4. Autorizar pago (API)
ClientAppBackend ->> Payments: POST /payment-intents/{id}/authorize/ (credentialId, attestationObject, clientDataJSON, riskSignals)
Payments -->> ClientAppBackend: 204 - No Content
ClientAppBackend ->> Payments: Poll GET /payment-intents/{id}/
Payments -->> ClientAppBackend: status = SUCCEEDED
ClientAppBackend ->> EndUser: Muestra pantalla de éxito
```
## **Seleccionar Inscripción (API)**
Utiliza el método de API Listar todas las inscripciones, con el parámetro de consulta requerido `device_id`, para solicitar todas las inscripciones que tu usuario ha realizado usando tu aplicación y su dispositivo actual. Muestra esta lista de inscripciones al usuario, permitiéndoles elegir qué inscripción usar para el pago. Guarda el `id` de esa inscripción (utilizado en el siguiente paso de Crear Intención de Pago).
```bash
GET /enrollments/?device_id={device_id}
```
## **Crear Payment Intent (API)**
Una vez que tengas la Inscripción seleccionada por el usuario, puedes crear un Payment Intent:
```shell
POST /payments/br/payment-intents/
```
```json
{
"amount": 0.13,
"allowed_payment_method_types": [
"open_finance_biometric_pix"
],
"customer": "{{customer.id}}",
"description": "Test Payment Intent with Enrollment",
"statement_description": "Description to show on statement",
"payment_method_details": {
"open_finance_biometric_pix": {
"beneficiary_bank_account": "{{bank_account.id}}",
"enrollment": "{{enrollment.id}}"
}
},
"confirm": true
}
```
| Parámetro | Tipo | Requerido | Descripción |
| --- | --- | --- | --- |
| `amount` | número | true | El monto a pagar. |
| `allowed_payment_method_types` | string | true | El tipo de método de pago. Debe establecerse en `open_finance_biometric_pix`. |
| `customer` | string (uuid) | true | El `id` del cliente del cual estás solicitando pagos. |
| `description` | string | true | Tu descripción para el pago. |
| `statement_description` | string | true | La descripción que aparecerá en el estado de cuenta del usuario. |
| `payment_method_details.open_finance_biometric_pix.beneficiary_bank_account` | string (uuid) | true | El `id` de la cuenta bancaria que recibirá los fondos. |
| `payment_method_details.open_finance_biometric_pix.enrollment` | string (uuid) | true | El `id` de la Inscripción que el usuario seleccionó. |
| `confirm` | booleano | true | Confirma que el pago está listo para ser procesado. Debe establecerse en `true`. |
En la respuesta, Belvo devolverá el `payment_intent.id` y el objeto `fido_options` que son necesarios para el siguiente paso de autenticación biométrica. Necesitas:
- Persistir el `payment_intent.id` en tu backend.
- Guardar el `fido_options` en una variable para ser usado en el siguiente paso en el SDK de Belvo.
```json
{
"id": "uuid", // [!code highlight]
"status": "PENDING",
"payment_method_information": {
"open_finance_biometric_pix": {
"provider": "belvo",
"consent_id": "urn:nubank:023230b9-1211-3420-bf6d-e7d56e87bdf1",
"fido_options": { // [!code highlight]
"rpId": "belvo.com",
"timeout": 300000,
"challenge": "oGW096Hvr8sVUIOf-10iqWI7ZfSx2GhoU359bBRK9h4",
"allowCredentials": [
{
"id": "AfD-uI4LUzJAuzyLBRrPncocLusMgZ8yHNuuUl-7NSFbBlqrW2rMF0D_Ao-orNqdX3YZVf8_wk1jj--HuNH1uKE",
"type": "public-key"
}
]
},
"end_to_end_id": "E432158152025061315009OzwiMmDSO7",
"external_payment_id": "bde3bb4d-5b48-4875-b69d-7f2beee4fb42",
"provider_request_id": "afc99a8b-e0c7-4a8b-85d7-193bd70e4cc0"
}
}
}
```
## Recopilar Datos Biométricos y Señales de Riesgo (SDK)
Necesitarás usar el método `initialize()` antes de `startSigning(fido_options)` y `collectRiskSignals(accountTenure)`. Por favor, consulta el ejemplo de código para más detalles.
Usando el `fido_options` recibido de la intención de pago, inicia el proceso de autenticación biométrica usando el método `startSigning(fido_options)` del Belvo Android SDK. El resultado de este método será los valores `credentialId`, `credentialRawId`, `authenticatorData`, `clientDataJson`, `signature` y `userHandle`, que usarás para confirmar el pago en el paso de Autorizar Pago.
Después del método `startSigning(fido_options)`, necesitas llamar a `collectRiskSignals(accountTenure)` para recopilar información sobre el dispositivo. El objeto `RiskSignals` devuelto es entonces requerido en el paso de Autorizar Pago.
```kotlin
import com.belvo.biometricpixsdk.BiometricPixSDK
import com.belvo.biometricpixsdk.models.FidoRegistrationCallback
import com.belvo.biometricpixsdk.extensions.encodedRawId
import com.belvo.biometricpixsdk.extensions.encodedClientDataJSON
import com.belvo.biometricpixsdk.extensions.encodedAuthenticatorData
import com.belvo.biometricpixsdk.extensions.encodedSignature
import com.belvo.biometricpixsdk.extensions.encodedUserHandle
import com.google.android.gms.fido.fido2.api.common.PublicKeyCredential
import com.google.android.gms.fido.fido2.api.common.AuthenticatorAssertionResponse
class ExampleActivity : ComponentActivity() {
private lateinit var biometricPixSDK: BiometricPixSDK
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
biometricPixSDK = BiometricPixSDK()
// Crea el lanzador FIDO con el callback de resultado de actividad del SDK
val fidoLauncher = registerForActivityResult(
ActivityResultContracts.StartIntentSenderForResult(),
biometricPixSDK.createActivityResultCallback() // Esta lambda maneja todos los resultados de actividad FIDO
)
// Inicializa el SDK con el lanzador configurado
biometricPixSDK.initialize(fidoLauncher)
}
fun startAuthenticationProcess(fidoOptions: String) {
// Implementa la interfaz de callback
val signingCallback = object : FidoAuthenticationCallback {
override fun onSuccess(credential: PublicKeyCredential, response: AuthenticatorAssertionResponse) {
// Maneja la autenticación exitosa
val credentialId = credential.encodedId
val credentialRawId = credential.encodedRawId
val authenticatorData = response.encodedAuthenticatorData
val clientDataJson = response.encodedClientDataJSON
val signature = response.encodedSignature
val userHandle = response.encodedUserHandle
// Envía los datos de credenciales a tu servidor para ser enviados a la API de Belvo
// para confirmar la autenticación
}
override fun onError(error: String) {
// Maneja el error de autenticación
Log.e("FIDO", "Firma fallida: $error")
}
}
// Inicia la autenticación con la respuesta del servidor
biometricPixSDK.startSigning(
context = this,
fidoResponseString = fidoOptions,
callback = signingCallback
)
}
override fun onDestroy() {
super.onDestroy()
biometricPixSDK.cleanup()
}
}
```
## Autorizar Pago (API)
Después de obtener toda la información requerida en el paso de Recolectar Datos Biométricos y Señales de Riesgo (SDK), ahora puedes autorizar el pago utilizando la API de Belvo.
```shell
POST /payment-intents/{payment_intent_id}/authorize/
```
- Belvo procesará la autorización. Necesitarás hacer sondeos a `GET /payment-intents/{id}/` hasta que el `status` de la intención de pago se convierta en `SUCCEEDED`.
**Estrategia de Sondeo:** Similar a la inscripción, recomendamos sondear el estado de la intención de pago (`GET /payment-intents/{payment_intent_id}/`) cada dos segundos por hasta dos minutos hasta que el estado sea `SUCCEEDED`. Si el estado no cambia o ocurre un error, informa al usuario y sugiere reintentar.
- Una vez que el pago sea exitoso, muestra una pantalla de confirmación al Usuario Final.
```json
// POST /payment-intents/{id}/authorize/ Ejemplo de Cuerpo de Solicitud
{
"risk_signals": {}, // El objeto de Señales de Riesgo recolectado
"assertion": {
"authenticatorAttachment": "platform",
"id": "{{credentialId}}",
"rawId": "{{credentialRawId}}",
"response": {
"authenticatorData": "{{authenticatorData}}",
"clientDataJSON": "{{clientDataJSON}}",
"signature:": "{{signature}}",
"userHandle": "{{userHandle}}"
},
"type": "public-key"
}
}
```
La API de Belvo devolverá un `204 - Not Content`. Después de esto, necesitas sondear el siguiente endpoint para obtener el estado final del pago:
```shell
GET /payment-intents/{payment_intent_id}/
```
Consejos de Sondeo
Envía una solicitud cada dos segundos hasta que recibas una respuesta o pasen dos minutos sin respuesta. Si no recibes respuesta después de dos minutos, muestra una pantalla de “Intenta de nuevo” a tu usuario y reinicia el proceso. En segundo plano, la Intención de Pago y el Cargo asociado pasarán al `status` = `FAILED`.