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-BR',
screenDimensions: {
height: 768,
width: 1024
},
accountTenure: '2023-06-23'
}
{
"deviceId": "visitorUniqueId",
"osVersion": "Unix 7.1.0",
"userTimeZoneOffset": "-03:00",
"language": "pt-BR",
"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 request to /payments/br/enrollments/
with the following payload:
{
"type": "open_finance_biometric_pix",
"details": {
"customer": "f78b14f3-5c1a-409a-966f-7b052b067cf0",
"institution": "188716fb-39ad-44a7-a992-6c278d2b24a4",
"name": "My first enrollment",
"platform": "BROWSER",
"risk_signals": {
"deviceId": "visitorUniqueId",
"osVersion": "Unix 7.1.0",
"userTimeZoneOffset": "-03:00",
"language": "pt-BR",
"screenDimensions": {
"height": 768,
"width": 1024
},
"accountTenure": "2023-06-23"
}
}
}
Parameter | Type | Description | Example |
---|---|---|---|
type | string | The type of enrollment. For Biometric Pix, this must be set to open_finance_biometric_pix . | open_finance_biometric_pix |
details | object | Details regarding the device enrollment. | - |
details.customer | string | The Belvo customer.id for your user. | f78b14f3-5c1a-409a-966f-7b052b067cf0 |
details.institution | string | The Belvo institution.id for the institution your user selected for the enrollment. | 188716fb-39ad-44a7-a992-6c278d2b24a4 |
details.name | string (null) | A human-readable name for the enrollment. | My first enrollment |
details.platform | string | The device platform. Note: This parameter will be provided by the Belvo Web SDK. | BROWSER |
details.risk_signals | object | The JSON-compliant enrollmentInformation object you received after using the collectEnrollmentInformation method. | { "deviceId": "visitorUniqueId", "osVersion": "Unix 7.1.0", "userTimeZoneOffset": "-03:00", "language": "pt-BR", "screenDimensions": { "height": 768, "width": 1024 }, "accountTenure": "2023-06-23" } |
In the response payload, you will receive a redirect_url
that you need to display to your user 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-10-30T11:28:47+0000",
"updated_at": "2024-10-30T11:29:01+0000",
"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",
"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-10-30T11:28:47+0000 |
updated_at | string (date-time) | The ISO-8601 timestamp of when the enrollment was last updated. | 2024-10-30T11:29:01+0000 |
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.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": {
"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.
// 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',
response: {
attestationObject: 'YXR0ZXN0YXRpb25PYmplY3RFeGFtcGxlSGVyZQ==',
clientDataJson: 'YXR0ZXN0YXRpb25PYmplY3RFeGFtcGxl',
type: 'public-key'
}
}
{
"authenticatorAttachment": "cross-platform",
"id": "447Q86f_XlFK0IBPVdf-giJUXs8pwmFCqqp0M3Q2PqM",
"rawId": "base64",
"response": {
"attestationObject": "YXR0ZXN0YXRpb25PYmplY3RFeGFtcGxlSGVyZQ==",
"clientDataJson": "YXR0ZXN0YXRpb25PYmplY3RFeGFtcGxl",
"type": "public-key"
}
}
7️⃣ Complete enrollment
Once you have the biometricRegistrationConfirmation
object, you will need to make a PATCH request to /payments/br/enrollments/{enrollment_id}/confirm/
with the following payload:
{
"confirmation_data": { // the JSON-compliant biometricRegistrationConfirmation object
"authenticatorAttachment": "cross-platform",
"id": "447Q86f_XlFK0IBPVdf-giJUXs8pwmFCqqp0M3Q2PqM",
"rawId": "base64",
"response": {
"attestationObject": "YXR0ZXN0YXRpb25PYmplY3RFeGFtcGxlSGVyZQ==",
"clientDataJson": "YXR0ZXN0YXRpb25PYmplY3RFeGFtcGxl",
"type": "public-key"
}
}
}
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": {
"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.
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-BR',
screenDimensions: {
height: 768,
width: 1024
},
accountTenure: '2023-06-23'
}
{
"deviceId": "visitorUniqueId",
"osVersion": "Unix 7.1.0",
"userTimeZoneOffset": "-03:00",
"language": "pt-BR",
"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: 'RXhhbXBsZUNoYWxsZW5nZUZvclBheW1lbnQ=',
timeout: 180000,
rpId: 'belvo.com',
allowCredentials: [
{
id: 'QUFBQkJCLUlE', // Base64
type: 'public-key'
}
],
userVerification: 'required'
})
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: 'cmVxdWVzdFBheW1lbnRBdXRob3JpemF0aW9uUmVzcG9uc2U=',
type: 'public-key'
}
{
"id": "cmVxdWVzdFBheW1lbnRBdXRob3JpemF0aW9uUmVzcG9uc2U=",
"type": "public-key"
}
4️⃣ Send through risk signals and biometric data
Once you have collected the enrollmentInformation
and biometricAuthorization
, make a POST call to /payments/br/payment-intents/{id}/authorize/
with the following payload:
{
"risk_signals": {},
"assertion": {},
}
{
"risk_signals": {
"deviceId": "visitorUniqueId",
"osVersion": "Unix 7.1.0",
"userTimeZoneOffset": "-03:00",
"language": "pt-BR",
"screenDimensions": {
"height": 768,
"width": 1024
},
"accountTenure": "2023-06-23"
},
"assertion": {
"id": "cmVxdWVzdFBheW1lbnRBdXRob3JpemF0aW9uUmVzcG9uc2U=",
"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!
FAQs
Do my users need to enroll each of their devices separately?
Yes. Each device your user will use to make biometric payments (phone, tablet, computer) must be enrolled separately.
Will my users need to re-enroll a device after an operating system update?
Yes. For security purposes, institutions will require users to re-enroll a device after its operating system has been updated.
In what situations will an institution reject or revoke an enrollment?
A financial institution may reject or revoke an enrollment if its risk model detects factors that could compromise the security of the payment.
Do I need to collect the risk signals for each Payment Intent request?
Yes. Financial institutions require the risk signals to be sent with each payment request as part of the risk modelling.
Are there any daily or transactional limits?
Yes. Currently:
- The daily transaction limit is set by the user's institution’s Pix limit.
- The per-transaction limit is set by the user, with a maximum of 500 BRL per transaction.
Can a user have more than one enrollment per financial institution?
Yes. Users may have multiple enrollments if they are paying using multiple devices.
Is there a limit on the number of enrollments a user can have?
At present, there is no limit on the total number of enrollments a user can have.
How long until an enrollment expires?
By default, an enrollment expires after 5 years. However, users can set a shorter or indefinite expiration period when granting authorization for an enrollment.
Can I revoke an enrollment?
Yes. Belvo is currently developing a solution to allow you to revoke an enrollment. Users can also revoke an enrollment directly with their financial institution.
Updated 3 days ago