Last updated

Biometric Pix Guide (Using Android SDK)

Upcoming Release

This documentation covers features from our upcoming release. While the core functionality and workflow described here will remain unchanged, you may notice some refinements before the final release, such as:

  • Android SDK updates and optimizations
  • Documentation improvements (links, terminology, diagrams)
  • API reference updates for enrollment endpoints

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 public key credentials 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 on an Android Device.

Prerequisites

Before continuing with this guide, make sure that:

  1. You have generated your Belvo Payments API Keys

  2. Setup Webhooks

  3. Installed the Belvo Android SDK

    • Installing the Belvo Android SDK

      Minimum Requirements

      • Android SDK: API 31 (Android 12) or higher
      • Compile SDK: 35
      • Java Version: 11
      • Kotlin: Compatible with latest stable version

      Instructions

      To install the Belvo Android SDK, add the following SDK dependencies to your app-level build.gradle.kts:

      dependencies {
          implementation("com.belvo.biometricpixsdk:biometricpixsdk:1.0.0")
          implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.6.0")
      }

      Additionally, you’ll need to add the following permissions to your AndroidManifest.xml file:

      <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
      <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
      <uses-permission android:name="android.permission.READ_PHONE_STATE" />
  4. Enabled credential sharing with Belvo

    • Enabling credentials sharing

      To complete the integration of the Belvo Android SDK and enable secure credential sharing between your app and Belvo’s domain (belvo.com), we need to configure a Digital Asset Link.

      Why is this necessary?

      This setup creates a trusted connection between your app and belvo.com, allowing your app to securely access Belvo SDK features like user Enrollment registration and Payment Intent Authorization. This data corresponds to the target section of a Digital Asset Links entry. We use this data to update our assetlinks.json file hosted at: https://belvo.com/.well-known/assetlinks.json

      You will need to provide us the following information from your app:

      An example of your target object should look like this:

      {
        "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. Addtionally, for each user that you want to enroll into the Biometric Pix system, you will first need to create a Belvo Customer.

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 Android SDK and API to retrieve key details about the device as well as the biometric public data.

  1. List Institutions: Prompt the user to select their desired financial institution to enroll in, using the Belvo API to display the available options.
  2. Initialize SDK and Collect Risk Signals: Initialize the Belvo Android SDK, prompt the user for necessary permissions, and collect risk signals, including the device ID.
  3. Create and Update Enrollment: Send the collected risk signals, along with the customer ID, institution ID, and a callback URL, to Belvo's server to create the enrollment. Then, redirect the user to their institution's app for approval. Once they're redirected back to your callback URL with details, send these to Belvo to update the enrollment state.
  4. Poll for FIDO Options: Continuously poll the Belvo API (GET /enrollments/{id}/fido-registration-options/) to retrieve the necessary FIDO options for biometric registration. ⚠️ Polling Strategy: We recommend polling our server every two seconds for up to two minutes. If no response is received within this timeframe, instruct the user to try again.
  5. Prompt for Biometrics: Take the FIDO options from Belvo's API and use the Belvo Android SDK startRegistration() method to prompt the user for their biometric gesture.
  6. Finalize Enrollment: Send the biometric public data to Belvo using POST /enrollments/{id}/confirm/. After that, poll GET /enrollments/{id}/ until a response is received (enrollment status = SUCCEEDED or FAILED).
EndUserClientAppBackendBiometricPixSDKPaymentsBankAPP0. Prompt the user to select the institution to enroll in (Belvo API)1. Initialize SDK and Collect Risk Signals (Android SDK)2. Send Risk Signals to Belvo (Belvo API)3. Redirect user to their APP and update enrollment4. Poll Belvo API for FIDO options5. Prompt for Biometrics (Android SDK)6. Send biometrics to finalize enrollment and poll for response/institutions/1List of institutions2Display list of institutions3Selected institution4initialize()5requestPermission()6Grants permission to collect risk signals7collectRiskSignals()8Returns riskSignals + deviceId (encrypted)9Persist deviceId (encrypted)10POST /enrollments/ (riskSignals, callback_url)11201 Created (enrollment_id, redirect_url)12Persist enrollment_id associated with deviceId (encrypted)13Redirect to BankAPP (using the redirect_url)14Approves enrollment15Institution redirects to callback_url with details in query parameters16Update enrollment with received values using PATCH /enrollments/callback/17Returns Enrollment updated payload18Poll GET /enrollments/{id}/fido-registration-options/19Returns fido_options20startRegistration(fido_options)21Request biometric data22Provides biometric (face/fingerprint/PIN)23attestationObject, clientDataJSON, credential24POST /enrollments/{id}/confirm/ (attestationObject, clientDataJSON, credential)25204 - No Content26Poll GET /enrollments/{id}/27status = SUCCEEDED28EndUserClientAppBackendBiometricPixSDKPaymentsBankAPP

Prompt the user to select the institution to enroll in (Belvo API)

In your application, 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 Send Risk Signals to Belvo (API) step).

Initialize SDK and Collect Risk Signals (Android SDK)

Next, in your application, you will need to make the following calls:

initialize()

This method must be called in your Activity's onCreate() method before any FIDO operations. You should use createActivityResultCallback() to obtain the proper callback function for the fidoLauncher parameter.

The initialize(fidoLauncher) method sets up the internal activity result handling required for FIDO2 biometric operations. It must be called once during the activity's lifecycle to prepare the SDK for launching biometric prompts and receiving their results.

In the example below, you can see that in the fidoLauncher variable that we also use the createActivityResultCallback() from Belvo’s Android SDK. This method returns a callback function that should be used when registering the ActivityResultLauncher for FIDO operations. It acts as the SDK's internal handler for processing the ActivityResult objects received from system activities initiated by the FIDO flow. This allows the SDK to manage the state of biometric operations seamlessly.

class MainActivity : ComponentActivity() {
    private lateinit var biometricPixSDK: BiometricPixSDK

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

        biometricPixSDK = BiometricPixSDK()

        // Use createActivityResultCallback() when setting up the launcher.
        // This lambda function will be internally used by the SDK to process FIDO results.
        val fidoLauncher = registerForActivityResult(
            ActivityResultContracts.StartIntentSenderForResult(),
            biometricPixSDK.createActivityResultCallback() // This lambda handles all FIDO activity results
        )

        // Initialize SDK with the configured launcher
        biometricPixSDK.initialize(fidoLauncher)
    }
}

Once you have initialized the launcher, we can proceed to request the user’s permission to extract risk signals from their device using the requestPermission() method**.**

requestPermission()

This requestPermission() method creates and launches a permission request for location and phone state permissions (ACCESS_FINE_LOCATION, ACCESS_COARSE_LOCATION, and READ_PHONE_STATE). It automatically handles the Android runtime permission request flow and provides a callback with the overall result. The method returns ActivityResultLauncher<Array<String>>: The permission launcher instance. While returned, typically you can ignore this return value, as the primary interaction is through the onResult callback after calling the function.

// Add this to your MainActivity

biometricPixSDK.requestPermission(this) { granted ->
    if (granted) {
        // All required permissions granted. SDK is ready for full functionality.
        Log.d("BiometricSDK", "All necessary permissions granted.")
    } else {
        // Handle denied permissions.
        // Inform the user about features that may be unavailable or guide them to settings.
        Log.e("BiometricSDK", "Permissions denied. SDK functionality may be limited.")
    }

When the user grants their permission, you can then extract the device’s risk signals using collectRiskSignals().

collectRiskSignals()

The collectRiskSignals() method gathers comprehensive device fingerprinting data and security signals. The collected data includes device ID, security status, hardware information, and behavioral signals, which are crucial for the institution to perform risk assessment and fraud detection. The method returns a RiskSignals object which you need save and forward on to Belvo’s servers in an API call. Additionally, you need to persist the value of deviceId that the the RiskSignals object returns so that later you can associate it with the Enrollment ID (later, when listing Enrollments, you need to provide the deviceID to receive all Enrollments).

// Add this after your MainActivity class

val riskSignals = biometricPixSDK.collectRiskSignals(this)
val userDeviceId = riskSignals.deviceId

Once you have the risk signals and device ID, you can forward this information to Belvo using Create Enrollment method.

Send Risk Signals to Belvo (API)

POST /enrollments/
// Request Body
{
    "type": "open_finance_biometric_pix",
    "details": {
        "customer": "{{created_customer_uuid}}",
        "institution": "{{selected_institution_uuid}}",
        "name": "Name for the enrollment",
        "platform": "ANDROID",
        "callback_url": "{{https://deeplink_to_your_application}}",
        "risk_signals": {}
    }
}
ParameterTypeDescription
typestring (enum)The type of enrollment. For Biometric Pix, this must be set to open_finance_biometric_pix.
detailsobjectDetails regarding the device enrollment.
details.customerstring (uuid)The Belvo ID for your user.
details.institutionstring (uuid)The Belvo ID for the institution your user selected for the enrollment.
details.callback_urlstring (uri)The deeplink to where your user should be redirected to in your application after they approve the enrollment in their institutions application. Must be HTTPS compliant.
details.namestringA human-readable name for the enrollment.
details.platformstringThe platform that this enrollment relates to. For Android devices, this must be set to ANDROID.
details.risk_signalsobjectThe RiskSignals object (converted to JSON) you received after using the collectRiskSignals method.

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.

// 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...", 
    "risk_signals": "*****"
  }
}

Redirect user to their APP and update enrollment

You now need to redirect your user to their institution using the redirect_url so that they can confirm the enrollment process. During the process, they will log in to their institution, review the enrollment request, and then authorize it. Once the user authorizes the enrollment, the institution will redirect them back to the callback_url you provided.

https://redirect.clientApplication.com/
	?state=<state>
	&code=<code>
	&id_token=<long_id_token>

The institution will pass data in the query parameters that you must forward on to Belvo using the Update Enrollment State API request. We recommend transforming the query parameters into a JSON object and sending it directly through to Belvo.

Update Enrollment State

With the value of the query string saved as a JSON object, you can make the following request:

PATCH /enrollments/callback/
{
    "state": "{{state}}",
    "code": "{{code}}",
    "id_token": "{{id_token}}",
}

In the case that it was a successful callback, in the request response the status of the enrollment will still be set to PENDING.

// 200 OK
{
    "id": "uuid",
    "type": "open_finance_biometric_pix",
    "status": "PENDING",  
    "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": "BROWSER",
        "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": "uuid",
    "created_at": <datetime>,
    "updated_at": <datetime>
}

The institution will now process the enrollment data and provide Belvo the FIDO Options that are required to generate the biometric challenge. You will need to poll our API to retrieve this data to then request biometric data from your user.

Poll Belvo API for FIDO options (API)

Polling Tips

Send a request every two seconds until you receive a response or two minutes pass with no response. If you do not receive response after two minutes, display a “Try again” screen to your user and restart the process. In the background, the Enrollment will transition to the state = FAILED.

After you receive the successful response from the Update Enrollment State request, you need to poll the endpoint below in order to receive the FIDO registration options required to prompt for biometric data.

GET /enrollments/{enrollment_id}/fido-registration-options/

You will receive the following 200 - OK response from our API. Make sure to save the object as it is a required parameter for the startRegistration SDK method.

// 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"
    }
}

Prompt for Biometrics (Android SDK)

With the payload received, you need to use the startRegistration() method. This method starts the biometric credential registration using FIDO2 protocols. It processes the FIDO registration options (a JSON string) received from your backend server and launches the device's native biometric authentication flow (e.g., fingerprint or face scan).

import com.belvo.biometricpixsdk.models.FidoRegistrationCallback
import com.belvo.biometricpixsdk.extensions.encodedId
import com.belvo.biometricpixsdk.extensions.encodedRawId
import com.google.android.gms.fido.fido2.api.common.PublicKeyCredential
import com.google.android.gms.fido.fido2.api.common.AuthenticatorAssertionResponse

// Method
fun startRegistration(
    context: Context, //Application or activity context
    fidoResponseString: String, //FIDO registration options JSON from server
    callback: FidoRegistrationCallback //Registration result callback
)

// Implement the callback interface
val registrationCallback = object : FidoRegistrationCallback {
    override fun onSuccess(credential: PublicKeyCredential, response: AuthenticatorAttestationResponse) {
        // Handle successful registration
        val credentialId = credential.encodedId
        val credentialRawId = credential.encodedRawId
        val attestationObject = response.attestationObject
        val clientDataJson = response.clientDataJSON
        
        // Send the credential data (credentialId, credentialRawId, attestationObject, and clientDataJson)
        // to your server to be then forwarded to the Belvo API to confirm the Enrollment.
        
    }
    
    override fun onError(error: String) {
        // Handle registration error
        Log.e("FIDO", "Registration failed: $error")
    }
}

// Start registration with server response
biometricPixSDK.startRegistration(
    context = requireContext(), // if it's used in a Fragment
    fidoResponseString = fidoOptions, // Fido registration options collected from GET /enrollments/{id}/fido-registration-options/
    callback = registrationCallback
)

You need to store the following values in variables as they are used to confirm the Enrollment in the following step:

  • credentialId
  • credentialRawId
  • attestationObject
  • clientDataJson

Send biometrics to finalize enrollment and poll for response (API)

To complete the Enrollment process you will need to send the values you received to the following endpoint:

POST /payments/br/enrollments/{enrollment_id}/confirm/
// Request Body
{
  "confirmation_data": {
    "authenticatorAttachment": "platform",
    "id": "{{credentialId}}",
    "rawId": "{{credentialRawId}}",
    "type": "public-key",
    "response": {
      "attestationObject": "{{attestationObject}}",
      "clientDataJSON": "{{clientDataJson}}"
    }
  }
}
ParameterTypeDescription
authenticatorAttachmentstringThe type of authenticator. Must be set to platform.
idstringThe credentialId you received from the startRegistration() method.
rawIdstringThe credentialRawId you received from the startRegistration() method.
typestringThe type of FIDO credential being generated. Must be set to public-key.
response.attestationObjectstringThe attestationObject you received from the startRegistration() method.
response.clientDataJSONstringThe clientDataJson you received from the startRegistration() method.

Belvo will respond with a 204 - No Content and forward the information to the institution to complete the enrollment process.

Polling Tips

Send a request every two seconds until you receive a response or two minutes pass with no response. If you do not receive response after two minutes, display a “Try again” screen to your user and restart the process. In the background, the Enrollment will transition to the state = FAILED.

You will need to poll the following endpoint until you receive a response from Belvo’s API. Once you receive a response, check the status field.

GET /enrollments/{enrollment_id}/

If the status is SUCCEEDED, perfect! The enrollment is ready and you can start making payments!

Making a Payment

Once a user's device is successfully enrolled, you can initiate payment requests using their stored biometric credentials. This process involves:

  1. Selecting an Enrollment
  2. Creating a payment intent
  3. Collecting biometric authentication data
  4. Authorizing the payment
EndUserClientAppBackendBiometricPixSDKPayments1. User selects Enrollment (API)2. Create Payment Intent (API)3. Collect biometric data (SDK)4. Authorize payment (API)Clicks "Realizar Pagamento"1GET /enrollments/?device_id=12342Returns list of enrollments3Show list of enrollments4Chooses from enrollment list5POST /payment-intents/ (enrollment_id)6Returns payment_intent data (id, fido_options)7Persist Payment Intent ID8startSign(fido_options)9collectRiskSignals()10Returns credentialId, attestationObject, clientDataJSON, riskSignals11POST /payment-intents/{id}/authorize/ (credentialId, attestationObject, clientDataJSON, riskSignals)12204 - No Content13Poll GET /payment-intents/{id}/14status = SUCCEEDED15Show success screen16EndUserClientAppBackendBiometricPixSDKPayments

Select Enrollment (API)

Use the List all enrollments API method, with the required device_id query parameter, to request all the enrollments your user has made using your application and their current device. Display this list of enrollments to the user, allowing them to choose which enrollment to use for the payment. Save the id of that enrollment (used in the following Create Payment Intent step).

GET /enrollments/?device_id={device_id}

Create Payment Intent (API)

Once you have the user’s selected Enrollment, you can create a Payment Intent:

POST /payments/br/payment-intents/
{
    "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
}
ParameterTypeRequiredDescription
amountnumbertrueThe amount to pay.
allowed_payment_method_typesstringtrueThe type of payment method. Must be set to open_finance_biometric_pix.
customerstring (uuid)trueThe id of the customer from whom you are requesting payments.
descriptionstringtrueYour description for the payment.
statement_descriptionstringtrueThe description that will appear on your user’s bank account statement.
payment_method_details.open_finance_biometric_pix.beneficiary_bank_accountstring (uuid)trueThe id of the bank account that will receive the funds.
payment_method_details.open_finance_biometric_pix.enrollmentstring (uuid)trueThe id of the Enrollment the user selected.
confirmbooleantrueConfirms that the payment is ready to be processed. Must be set to true.

In the response, Belvo will return the payment_intent.id and the fido_options object that are required for the next step of biometric authentication. You need to:

  • Persist the payment_intent.id on your backend.
  • Save the fido_options in a variable to be used in the next step in the Belvo SDK.
{
  "id": "uuid", 
  "status": "PENDING",
  "payment_method_information": {
	  "open_finance_biometric_pix": {
	      "provider": "belvo",
	      "consent_id": "urn:nubank:023230b9-1211-3420-bf6d-e7d56e87bdf1",
	      "fido_options": { 
	          "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"
	  }
	}
}

Collect Biometric Data and Risk Signals (SDK)

You will need to use the initialize() method before startSigning(fido_options) and collectRiskSignals(). Please see the code example for more details.

Using the fido_options received from the payment intent, initiate the biometric authentication process using the startSigning(fido_options) method of the Belvo Android SDK. The result from this method will be the credentialId, credentialRawId, authenticatorData, clientDataJson, signature and userHandle values, which you will use to confirm the payment in the Authorize Payment step.

After the startSigning(fido_options) method, you need to call the collectRiskSignals() to collect information about the device. The returned RiskSignals object is then required in the Authorize Payment step.

import com.belvo.biometricpixsdk.BiometricPixSDK
import com.belvo.biometricpixsdk.models.FidoRegistrationCallback
import com.belvo.biometricpixsdk.extensions.encodedId
import com.belvo.biometricpixsdk.extensions.encodedRawId
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()

        // Create the FIDO launcher with the SDK's activity result callback
        val fidoLauncher = registerForActivityResult(
            ActivityResultContracts.StartIntentSenderForResult(),
            biometricPixSDK.createActivityResultCallback() // This lambda handles all FIDO activity results
        )

        // Initialize SDK with the configured launcher
        biometricPixSDK.initialize(fidoLauncher)
    }

    fun startAuthenticationProcess(fidoOptions: String) {
        // Implement the callback interface
        val signingCallback = object : FidoAuthenticationCallback {
            override fun onSuccess(credential: PublicKeyCredential, response: AuthenticatorAssertionResponse) {
                // Handle successful authentication
                val credentialId = credential.encodedId
                val credentialRawId = credential.encodedRawId
                val authenticatorData = response.encodedAuthenticatorData
                val clientDataJson = response.encodedClientDataJSON
                val signature = response.encodedSignature
                val userHandle = response.encodedUserHandle
                
                // Send the credential data to your server to be forwarded to the Belvo API
                // to confirm the authentication
            }
            
            override fun onError(error: String) {
                // Handle authentication error
                Log.e("FIDO", "Signing failed: $error")
            }
        }

        // Start authentication with server response
        biometricPixSDK.startSigning(
            context = this,
            fidoResponseString = fidoOptions,
            callback = signingCallback
        )
    }

    override fun onDestroy() {
        super.onDestroy()
        biometricPixSDK.cleanup()
    }
}

Authorize Payment (API)

After retrieving all the required information in the Collect Biometric Data and Risk Signals (SDK) step, you can now authorize the payment using Belvo's API.

POST /payment-intents/{payment_intent_id}/authorize/
  • Belvo will process the authorization. You will need to poll GET /payment-intents/{id}/ until the status of the payment intent becomes SUCCEEDED.

    Polling Strategy: Similar to enrollment, we recommend polling the payment intent status (GET /payment-intents/{payment_intent_is}/) every two seconds for up to two minutes until the status is SUCCEEDED. If the status does not change or an error occurs, inform the user and suggest retrying.

  • Once the payment is successful, display a confirmation screen to the End User.

// POST /payment-intents/{id}/authorize/ Request Body Example
{
  "risk_signals": {}, // The Risk Signals object collected
  "assertion": {
    "authenticatorAttachment": "platform",
    "id": "{{credentialId}}",
    "rawId": "{{credentialRawId}}",
    "response": {
      "authenticatorData": "{{authenticatorData}}",
      "clientDataJSON": "{{clientDataJSON}}",
      "signature:": "{{signature}}",
      "userHandle": "{{userHandle}}"
      
    },
    "type": "public-key"
  }
}

Belvo's API will return a 204 - Not Content. After which, you need to poll the following endpoint in order to retrieve the final status of the payment:

GET /payment-intents/{payment_intent_id}/
Polling Tips

Send a request every two seconds until you receive a response or two minutes pass with no response. If you do not receive response after two minutes, display a “Try again” screen to your user and restart the process. In the background, the Payment Intent and associated Charge will transition to the state = FAILED.