Direct API (Biometric Pix)
Early preview of upcoming product
The following documentation is an early preview of Belvo's upcoming Biometric Pix product. As such:
- Parameter key names, values, and structure may change before the final product is implemented.
- Certain documentation (such as the instructions to download and setup the Belvo Payments Web SDK) is still in progress.
However, the general flow of information and required steps will not change.
With Belvo's Biometric Pix, collecting payments from users becomes seamless, removing the need for users to navigate to their financial institution to approve each individual payment request.
The first step in enabling biometric payment collection is to enroll the user’s device with their institution. During enrollment, key data about the device and the user's biometric information is securely registered with their institution, ensuring that future payments can be confirmed using biometric authentication alone.
Once enrollment is complete, you can start requesting payments directly from the user’s device.
In this guide, we’ll take you through each step, from device enrollment to successfully initiating a payment request.
Prerequisites
- Please make sure you have completed all the steps in our dedicated prerequisites article before continuing this guide.
- Install the Belvo Payments Web SDK in your node project
Enrollment
Enrollment is the process of registering a user’s device in their institution to allow for biometric payments for a given merchant. During the process, you will use a combination of the Belvo Payments Web SDK and API to retrieve key details about the device as well as the actual biometric signature.
Enrollment Flow
In the diagram below, you can see the overall enrollment flow.
- Your user selects the financial institution where they want to enroll their device (basically, the bank that they want to use to make biometric payments).
- Your application collects details about the user’s device (using the Belvo Payments Web SDK).
- You send these details to Belvo using Belvo’s API.
- The institution processes the device details and generates a unique URL for your user to be redirected to. Once they are redirected to their institution, they will provide their authorization for the enrollment and are then redirected back to your application.
- Once your user authorizes their device and your application, the institution generates a cryptographic challenge that is used to gather the user’s biometric data. Your will receive this challenge as a webhook notification and you will need to use the information in prompt your user to provide their biometric data (using the Belvo Payments Web SDK).
- After your user has provided their biometric data, you will need to send the encrypted information to the Belvo API do complete the enrollment process.
- Once the institution confirms the information, you will receive a webhook notification indicating that the enrollment was successful.
Enrolling a user device
User and Customer Creation
Before you begin the enrollment process:
- Make sure your user has an account with your application.
- You have created a customer for your user using Belvo’s API.
To enroll a user’s device:
1️⃣ Prompt user for institution
In your widget, prompt your user to select the institution where they want to enroll the device in. Use the List all payment institutions request to get a list of all the possible institutions. Once the user selects the institution, save the id
of the institution (required in the Begin enrollment step).
2️⃣ Collect Enrollment Information
In your application, initiate the collectEnrollmentInformation(accountTenure)
method from the Belvo Payments Web SDK to collect the risk signals of the user’s device. The accountTenure
must be the date that your user created an account with your application, in YYYY-MM-DD
format.
// Method
collectEnrollmentInformation(accountTenure)
// Example
BelvoPaymentsAtoms.biometricPix.collectEnrollmentInformation("2023-06-23")
The collectEnrollmentInformation
method will return an enrollmentInformation
object. Save this as a JSON-compliant object as it will be required in the following step.
{
deviceId: 'visitorUniqueId',
osVersion: 'Unix 7.1.0',
userTimeZoneOffset: '-03:00',
language: 'pt',
screenDimensions: {
height: 768,
width: 1024
},
accountTenure: '2023-06-23'
}
{
"deviceId": "visitorUniqueId",
"osVersion": "Unix 7.1.0",
"userTimeZoneOffset": "-03:00",
"language": "pt",
"screenDimensions": {
"height": 768,
"width": 1024
},
"accountTenure": "2023-06-23"
}
3️⃣ Begin enrollment
Once you have collected the enrollment information, you can begin the enrollment process with the user’s institution. You will need to make a POST Enroll a new user device request with the following payload:
In the response payload, you will receive a redirect_url
that you need to display to your user (or redirect them automatically) so that they can be redirected to their institution to confirm their enrollment.
{
"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": "BROWSER",
"name": "First Enrollment",
"callback_url": "https://example.com/enrollment-in-progress",
"redirect_url": "https://www.user-banking-institituon.com/?enrollment_request=true...",
"risk_signals": "*****"
}
}
Parameter | Type | Description | Example |
---|---|---|---|
id | string | Belvo’s unique ID for the enrollment. | 82666cde-3f80-4350-b0f7-24cb8e9294c9 |
created_by | string | The Belvo ID of the merchant that created the enrollment. | 56689ef8-4c92-44ae-b2c1-60505da4a7e1 |
created_at | string (date-time) | The ISO-8601 timestamp of when the data point was created in Belvo's database. | 2024-11-26T11:20:57.389056Z |
updated_at | string (date-time) | The ISO-8601 timestamp of when the enrollment was last updated. | 2024-11-26T11:20:57.389056Z` |
type | string | The type of enrollment. For Biometric Pix, this must be set to open_finance_biometric_pix . | open_finance_biometric_pix |
status | string | The status of the enrollment. | PENDING |
details | object | Details regarding the Biometric Pix enrollment. | - |
details.status | string | The status of the Biometric Pix enrollment. For details regarding the possible states, see our dedicated Enrollment Entity Model and States article. | AWAITING_ACCOUNT_HOLDER_VALIDATION |
details.customer | string | The Belvo customer.id you provided for the device enrollment. | f78b14f3-5c1a-409a-966f-7b052b067cf0 |
details.institution | string | The Belvo institution.id you provided for the device enrollment. | 188716fb-39ad-44a7-a992-6c278d2b24a4 |
details.platform | string | The device platform, as provided for the device enrollment. | BROWSER |
details.name | string (null) | The human-readable name for the enrollment. This is useful for when you display all the enrollments your user has made using your application. | My first enrollment |
details.callback_url | string | The URL to redirect your user to after the enrollment process is completed. | https://example.com/enrollment-in-progress |
details.redirect_url | string | The URL you need to redirect your user to so that they can confirm the enrollment in their chosen institution. | https://www.user-banking-institituon.com/?enrollment_request=true... |
details.risk_signals | string | An obfuscated string (****** ) used to indicate that risk signals have been provided. | ***** |
4️⃣ Redirect your user
Redirect your user their institution so that they can confirm that enrollment process. During the process, they will need to log in to their institution, review the enrollment request, and then authorize the enrollment. Once the user authorizes the enrollment, the institution will redirect them back to your application.
Once the user provides their authorization, the institution will begin evaluating the provided risk signals. Once accepted, the institution will generate a biometric challenge and Belvo will send a webhook with details.
5️⃣ Wait for Biometric Options webhook
Once the institution has accepted the risk signals and generated a biometric challenge, Belvo will send a webhook with the following payload:
{
"webhook_id": "9994137d-f1d4-4c7f-8da3-4eb7a35a66bd",
"webhook_type": "ENROLLMENTS",
"webhook_code": "STATUS_UPDATE",
"object_id": "69e93051-22cc-423f-b35d-2083e56e4320",
"data": {
"status": "PENDING",
"metadata": null,
"details": {
"status": "AWAITING_ENROLLMENT"
},
"fido_options": { // Save this entire object as a JavaScript-compliant object
"rp": {
"id": "belvo.com",
"name": "Belvo"
},
"user": {
"id": "cba3fb04-5b0f-44c0-83d8-fed7db98d8d9",
"name": "Mock User",
"displayName": "Mock User"
},
"challenge": "R3JlZXRpbmdzIGZyb20gQmVsdm8h",
"pubKeyCredParams": [
{
"alg": -7,
"type": "public-key"
}
],
"timeout": 0,
"excludeCredentials": [
{
"id": "AAABBB-ID",
"type": "public-key"
}
],
"authenticatorSelection": {
"authenticatorAttachment": "platform, cross-platform",
"userVerification": "discouraged, preferred, required",
"requireResidentKey": true,
"residentKey": "111-ID"
},
"attestation": "none, indirect, direct, enterprise",
"attestationFormats": [
"packed, tpm, android-key, android-safetynet, fido-u2f, apple, none"
],
"extensions": {
"someAdditionalProp1": {}
}
}
}
}
Once you receive the webhook, save the entire fido_options
object (converted as a JavaScript-compliant object), as it will be used as the requestEnrollmentConfirmation(biometricRegistrationRequest)
method.
6️⃣ Prompt for biometric data
In your application, use the requestEnrollmentConfirmation(biometricRegistrationRequest)
to automatically prompt your user to provide their biometric details. The biometricRegistrationRequest
object is the fido_options
object you received in the webhook.
Additional fields
You may receive additional fields in the
fido_options
object that are not included in the example below. However, just send through all the fields that you receive and our Web SDK will parse the required ones.
// Method
requestEnrollmentConfirmation(biometricRegistrationRequest)
// Example
BelvoPaymentsAtoms.biometricPix.requestEnrollmentConfirmation({
rp: { id: 'belvo.com', name: 'Belvo' },
user: { id: 'cba3fb04-5b0f-44c0-83d8-fed7db98d8d9', name: 'Mock User', displayName: 'My First Biometric User' },
challenge: 'R3JlZXRpbmdzIGZyb20gQmVsdm8h',
pubKeyCredParams: [{ alg: -7, type: 'public-key' }],
attestation: 'direct',
accountTenure: '2023-06-23'
}))
The requestEnrollmentConfirmation
method will return an biometricRegistrationConfirmation
object. Save this as a JSON-compliant object as it will be required in the following step.
{
authenticatorAttachment: 'cross-platform',
id: '447Q86f_XlFK0IBPVdf-giJUXs8pwmFCqqp0M3Q2PqM',
rawId: 'base64',
type: 'public-key'
response: {
attestationObject: 'YXR0ZXN0YXRpb25PYmplY3RFeGFtcGxlSGVyZQ==',
clientDataJson: 'YXR0ZXN0YXRpb25PYmplY3RFeGFtcGxl'
}
}
{
"authenticatorAttachment": "cross-platform",
"id": "447Q86f_XlFK0IBPVdf-giJUXs8pwmFCqqp0M3Q2PqM",
"rawId": "base64",
"type": "public-key",
"response": {
"attestationObject": "YXR0ZXN0YXRpb25PYmplY3RFeGFtcGxlSGVyZQ==",
"clientDataJson": "YXR0ZXN0YXRpb25PYmplY3RFeGFtcGxl"
}
}
7️⃣ Complete enrollment
Once you have the biometricRegistrationConfirmation
object, you will need to make a POST Complete device enrollment request with the following payload:
// /payments/br/enrollments/{enrollment_id}/confirm/
{
"confirmation_data": {
"authenticatorAttachment": "cross-platform",
"id": "WDNUd3Bpb3cwRlBsRUNySkcrbTZKbVpFNUQwZXRBSEM5OFF6K1RITHBlaz0=",
"rawId": "X3Twpiow0FPlECrJG+m6JmZE5D0etAHC98Qz+THLpek=",
"type": "public-key",
"response": {
"attestationObject": "YXR0ZXN0YXRpb25PYmplY3RFeGFtcGxlSGVyZQ==",
"clientDataJSON": "YXR0ZXN0YXRpb25PYmplY3RFeGFtcGxl"
}
}
}
Belvo will respond with a 204 - No Content
. The information is forwarded to the institution to complete the enrollment process.
8️⃣ Wait for the confirmation webhook
Once the institution confirms the enrollment, you will receive an ENROLLMENTS
STATUS_UPDATE
webhook indicating that the process is complete.
{
"webhook_id": "9994137d-f1d4-4c7f-8da3-4eb7a35a66bd",
"webhook_type": "ENROLLMENTS",
"webhook_code": "STATUS_UPDATE",
"object_id": "69e93051-22cc-423f-b35d-2083e56e4320",
"data": {
"status": "SUCCEEDED",
"metadata": null,
"details": {
"status": "AUTHORIZED"
}
}
}
With a confirmed enrollment, you can now begin to request payments!
Payments
Once you have completed an enrollment for a user device, you can start making payments requests. Biometric Pix payment requests use a combination of the Belvo Payments Web SDK and API.
Payment flow
In the diagram below, you can see the overall flow for a Biometric Pix payment.
- Your user selects a previously-authorized enrollment from which they want to make a payment.
- You create a Payment Intent, using the
id
of the enrollment. The institution generates a cryptographic challenge that is used to gather the user’s biometric data. - Your application collects details about the user’s device and prompts for the user's biometric data (using the Belvo Payments Web SDK).
- You send through the collected details (using Belvo's API) to authorize the transaction. The institution will process the payments with the provided details.
Depending on the type of payment intent (immediate, scheduled, or recurring), you will receive webhook notifications regarding the status of the payment.
- For immediate payments, please see the Data flow overview section of our Pix via Open Finance guide.
- For scheduled and recurring payments, please see the Data flow overview section of our Scheduled and Recurring Pix guide.
Making a payment
To make a Biometric Pix payment request:
1️⃣ Prompt user to choose enrollment
Use the List all enrollments API method to request all the enrollments your user has made using your application. Prompt your user to select the enrollment they want to use to make the payment. Save the id
of that enrollment (used in the Create Payment Intent step).
2️⃣ Create a Payment Intent
With the enrollment.id
, you can then make a POST request to /payments/br/payment-intents/
with the following payload:
{
"amount": "1234.12",
"description": "Shoe payment",
"statement_description": "Super Shoe Store - Brown Sneakers",
"allowed_payment_method_types": [
"open_finance_biometric_pix"
],
"payment_method_details": {
"open_finance_biometric_pix": {
"beneficiary_bank_account": "a80d5a9d-20ae-479a-8dd7-ff3443bcbbfc",
"enrollment": "82666cde-3f80-4350-b0f7-24cb8e9294c9",
}
},
"confirm": true,
}
You will receive a 201 - Created
response, with the following key objects:
{
"payment_method_details": {
"open_finance_biometric_pix": {
"beneficiary_bank_account": "a80d5a9d-20ae-479a-8dd7-ff3443bcbbfc",
"enrollment": "82666cde-3f80-4350-b0f7-24cb8e9294c9"
}
},
"payment_method_information": {
"open_finance_biometric_pix": {
"provider_request_id": "d53af921-7be8-4513-a5a6-dd65746898ef",
"fido_options": { // Save this object as a JavaScript-compliant object
"challenge": "RXhhbXBsZUNoYWxsZW5nZUZvclBheW1lbnQ=",
"timeout": 180000,
"rpId": "belvo.com",
"allowCredentials": [{ "id": "QUFBQkJCLUlE", "type": "public-key" }],
"userVerification": "required",
"extensions": {
"someAdditionalProp1": {}
}
}
}
},
"status": "REQUIRES_ACTION"
}
Once you receive the webhook, save the entire fido_options
object (converted as a JavaScript-compliant object), as it will be used as the requestPaymentAuthorization(paymentRequestObject)
method.
{
"challenge": "RXhhbXBsZUNoYWxsZW5nZUZvclBheW1lbnQ=",
"timeout": 180000,
"rpId": "belvo.com",
"allowCredentials": [{ "id": "QUFBQkJCLUlE", "type": "public-key" }],
"userVerification": "required",
"extensions": {
"someAdditionalProp1": {}
}
}
{
challenge: 'RXhhbXBsZUNoYWxsZW5nZUZvclBheW1lbnQ=',
timeout: 180000,
rpId: 'belvo.com',
allowCredentials: [{ id: 'QUFBQkJCLUlE', type: 'public-key' }],
userVerification: 'required',
extensions: {
someAdditionalProp1: {}
}
}
3️⃣ Collect Risk Signals and Prompt Biometric Challenge
To complete the payment request, in your application you will need to use the Belvo Payments Web SDK to:
- Collect the device risk signals:
collectEnrollmentInformation(accountTenure)
. - Prompt your user to provide their biometric scan:
requestPaymentAuthorization(paymentRequestObject)
.
Collect Risk Signals
You must collect the risk signals for each payment intent request.
In your application, initiate the collectEnrollmentInformation(accountTenure)
method from the Belvo Payments Web SDK to collect the risk signals of the user’s device. The accountTenure
must be the date that your user created an account with your application, in YYYY-MM-DD
format.
// Method
collectEnrollmentInformation(accountTenure)
// Example
BelvoPaymentsAtoms.biometricPix.collectEnrollmentInformation("2023-06-23")
The collectEnrollmentInformation
method will return an enrollmentInformation
object. Save this as a JSON-compliant object as it will be required in the following step.
{
deviceId: 'visitorUniqueId',
osVersion: 'Unix 7.1.0',
userTimeZoneOffset: '-03:00',
language: 'pt',
screenDimensions: {
height: 768,
width: 1024
},
accountTenure: '2023-06-23'
}
{
"deviceId": "visitorUniqueId",
"osVersion": "Unix 7.1.0",
"userTimeZoneOffset": "-03:00",
"language": "pt",
"screenDimensions": {
"height": 768,
"width": 1024
},
"accountTenure": "2023-06-23"
}
Collect Biometric Data
In your application, initiate the requestPaymentAuthorization(biometricPaymentRequest)
method from the Belvo Web SDK to prompt the biometric challenge on your users device. In the biometricPaymentRequest
, provide the JavaScript-compliant fido_options
object you received in the 201 Response from the Payment Intent request.
// Method
requestPaymentAuthorization(biometricPaymentRequest)
// Example
BelvoPaymentsAtoms.biometricPix.requestPaymentAuthorization({
challenge: 'Y2hhbGxlbmdlMg==',
timeout: 60000,
rpId: 'bio.localhost',
allowCredentials: [
{
id: 'X3Twpiow0FPlECrJG+m6JmZE5D0etAHC98Qz+THLpek=',
type: 'public-key',
transports: ['internal']
}
],
userVerification: 'preferred'
}
)
The requestPaymentAuthorization
method will return a biometricAuthorization
object. Save this as a JSON-compliant object as it will be required in the following step.
{
id: "WDNUd3Bpb3cwRlBsRUNySkcrbTZKbVpFNUQwZXRBSEM5OFF6K1RITHBlaz0=",
rawId: "X3Twpiow0FPlECrJG+m6JmZE5D0etAHC98Qz+THLpek=",
response: {
authenticatorData: "5KApO/fUiPm1wr+26+0W4DGfCJIhocf+sRR4PEKSdIoFAAAAAA==",
clientDataJSON: "eyJ0eXBlIjoid2ViYXV0aG4uZ2V0IiwiY2hhbGxlbmdlIjoiWTJoaGJHeGxibWRsTWciLCJvcmlnaW4iOiJodHRwczovL2Jpby5sb2NhbGhvc3QiLCJjcm9zc09yaWdpbiI6ZmFsc2V9",
signature: "MEUCIDK2IonpPp78LiQkFxl6w9lgSGpf8Zn2UaCdweE7d9DdAiEAyZIsMEUlVBIs0RNk4G2EVPaL8La+IBcUTSQZmIUcfBg=",
userHandle: "dXNlcmlk"
},
type: "public-key"
}
{
"id": "WDNUd3Bpb3cwRlBsRUNySkcrbTZKbVpFNUQwZXRBSEM5OFF6K1RITHBlaz0=",
"rawId": "X3Twpiow0FPlECrJG+m6JmZE5D0etAHC98Qz+THLpek=",
"response": {
"authenticatorData": "5KApO/fUiPm1wr+26+0W4DGfCJIhocf+sRR4PEKSdIoFAAAAAA==",
"clientDataJSON": "eyJ0eXBlIjoid2ViYXV0aG4uZ2V0IiwiY2hhbGxlbmdlIjoiWTJoaGJHeGxibWRsTWciLCJvcmlnaW4iOiJodHRwczovL2Jpby5sb2NhbGhvc3QiLCJjcm9zc09yaWdpbiI6ZmFsc2V9",
"signature": "MEUCIDK2IonpPp78LiQkFxl6w9lgSGpf8Zn2UaCdweE7d9DdAiEAyZIsMEUlVBIs0RNk4G2EVPaL8La+IBcUTSQZmIUcfBg=",
"userHandle": "dXNlcmlk"
},
"type": "public-key"
}
4️⃣ Send through risk signals and biometric data
Once you have collected the enrollmentInformation
and biometricAuthorization
, make a POST Complete a Biometric Pix Payment Intent request with the following payload:
{
"risk_signals": {}, // The enrollmentInformation object
"assertion": {}, // The biometricAuthorization object
}
{
"risk_signals": {
"deviceId": "visitorUniqueId",
"osVersion": "Unix 7.1.0",
"userTimeZoneOffset": "-03:00",
"language": "pt",
"screenDimensions": {
"height": 768,
"width": 1024
},
"accountTenure": "2023-06-23"
},
"assertion": {
"id": "WDNUd3Bpb3cwRlBsRUNySkcrbTZKbVpFNUQwZXRBSEM5OFF6K1RITHBlaz0=",
"rawId": "X3Twpiow0FPlECrJG+m6JmZE5D0etAHC98Qz+THLpek=",
"response": {
"authenticatorData": "5KApO/fUiPm1wr+26+0W4DGfCJIhocf+sRR4PEKSdIoFAAAAAA==",
"clientDataJSON": "eyJ0eXBlIjoid2ViYXV0aG4uZ2V0IiwiY2hhbGxlbmdlIjoiWTJoaGJHeGxibWRsTWciLCJvcmlnaW4iOiJodHRwczovL2Jpby5sb2NhbGhvc3QiLCJjcm9zc09yaWdpbiI6ZmFsc2V9",
"signature": "MEUCIDK2IonpPp78LiQkFxl6w9lgSGpf8Zn2UaCdweE7d9DdAiEAyZIsMEUlVBIs0RNk4G2EVPaL8La+IBcUTSQZmIUcfBg=",
"userHandle": "dXNlcmlk"
},
"type": "public-key"
}
}
Parameter | Type | Description |
---|---|---|
risk_signals | Object | The JSON-compliantenrollmentInformation object you received using the collectEnrollmentInformation method. |
assertion | Object | The JSON-compliant biometricAuthorization object your received using the requestPaymentAuthorization method. |
You will receive a 204 - No Content
response, indicating that the payload was forwarded to the user’s institution for confirmation.
5️⃣ Listen for Payment Intent status updates
Depending on whether you created an immediate, scheduled, or recurring payment intent, you will receive different notifications regarding the status of the payment intent.
- For immediate Pix payments, please see the Payment Statuses and Notifications section of our Pix via Open Finance guide.
- For scheduled and recurring Pix payments, please see the Payment Statuses and Notifications section of our Scheduled and Recurring Pix guide.
Done!
By following these steps, you have successfully created a Biometric Pix Payment Request!
Updated 6 days ago