OFPI inflow payments

Start collecting payments with our OFPI solution πŸ’³

With Belvo's Open Finance Payment Initiation (OFPI), you can collect payments from your customers and optimize their payment experience. In this guide, we’ll show you how to:

  • collect payments from your customers
  • track the status of your payment requests

OFPI flow

  1. Create a customer
    A customer is a user (an individual or a business) that you request payments from. You will need to create a customer every time one of your users wants to pay for the first time. Once you create the customer, Belvo will assign a unique ID to that customer which you will need to use to collect all future payments from them.

πŸ‘

Tip!

Whenever your user signs up for your application, you can already request the information required to create a customer. Once they complete your sign-up process, you can automatically create a customer in Belvo.

  1. Register your customer's bank account
    Register your customer's bank account. This is the beneficiary account that will collect successful payments.

  2. Create a payment link
    A payment link is a shareable URL that will start a fully responsive hosted widget that guides your user through the payment process. You need to provide some basic information (such as the amount, the account that will receive the funds, and a description) and then just share the URL with the user. Simple, elegant, and headache-free.

  3. Your user completes payment in the widget
    The Payment Link Widget will guide your user through the necessary steps to complete the payment, including choosing their bank and confirming the details, being redirected to their institution to finalize the process, and then being redirected back to the widget and your application.

  4. Receive a webhook confirming payment
    You’ll get notified every time money is successfully transferred to your account. πŸ˜‰

Create a customer

To create a customer, you need to make a POST Create a new customer call with the following core information:

{
  "customer_type": "INDIVIDUAL",
  "identifier": "69700150844",
  "identifier_type": "CPF",
  "name": "Caetano Veloso",
  "country": "BRA",
  "email": "[email protected]",
}
{
  "customer_type": "BUSINESS",
  "identifier": "12300399900",
  "identifier_type": "CNPJ",
  "name": "Music Production Brazil",
  "country": "BRA",
  "email": "[email protected]",
}

You’ll receive the following response from our API, confirming that the customer was created. Make sure to save the id you receive, as this ID is required when creating a payment link πŸ€“.

{
  "id": "49f244ef-06cd-49cf-ad0c-f43796e370ad",
  "created_at": "2020-04-23T21:30:20.336854+00:00",
  "created_by": "1c83ead8-6665-429c-a17a-ddc76cb3a95e",
  "customer_type": "INDIVIDUAL",
  "name": "Caetano Veloso",
  "country": "BRA",
  "email": "[email protected]",
  "identifier": "23******00",
  "identifier_type": "CPF",
}
{
  "id": "49f244ef-06cd-49cf-ad0c-f43796e370ad",
  "created_at": "2020-04-23T21:30:20.336854+00:00",
  "created_by": "1c83ead8-6665-429c-a17a-ddc76cb3a95e",
  "customer_type": "BUSINESS",
  "name": "Music Production Brazil",
  "country": "BRA",
  "email": "[email protected]",
  "identifier": "12300399900",
  "identifier_type": "CNPJ",
}

Now, with the customer.id you’ve just received, you can go ahead and create a payment link.

πŸ“˜

Need more info? Check out our API reference! πŸ€“

Register your customer's bank account

Depending on your business model, you might want to set your customer's bank account as the beneficiary account. This can be either an INDIVIDUAL or a BUSINESS account and will collect all successful payments. To register your customer's bank account, you need to make a POST Create a new bank account call to our Bank Accounts resource.

{
  "institution": "c20ce907-5ab0-463a-917e-df5b802e8d42",
  "holder": {
    "type": "INDIVIDUAL",
    "information": {
        "identifier_type": "CPF",
        "first_name": "Caetano",
        "last_name": "Veloso",
        "identifier": "69700150844"
          }
     },
   "details": {
        "country": "BRA",
        "account_type": "CHECKINGS",
        "agency": "0111",
        "number": "12344-0"
     }
}
{
  "institution": "c20ce907-5ab0-463a-917e-df5b802e8d42",
  "holder": {
    "type": "BUSINESS",
    "information": {
        "identifier_type": "CNPJ",
        "name": "Caetano Veloso Entertainment Universe",
        "identifier": "12300399900"
          }
     },
   "details": {
        "country": "BRA",
        "account_type": "CHECKINGS",
        "agency": "0111",
        "number": "12344-0"
     }
}

You’ll receive the following response from our API. Make sure you save the id from the response - you’ll use it as the beneficiary_bank_account in the future when you create payment links. πŸ€“.

{
  "id": "b2ee0c2f-cbd5-40b9-98c3-3d9856cb0365",
  "created_at": "2020-04-23T21:30:20.336854+00:00",
  "created_by": "62053a72-e2d5-4c95-a578-6b16616900ac",
  "customer": "49f244ef-06cd-49cf-ad0c-f43796e370ad",
  "institution": "c20ce907-5ab0-463a-917e-df5b802e8d42",
  "details": {
    "country": "BRA",
    "account_type": "CHECKINGS",
    "agency": "0111",
    "number": "12344-0"
  },
  "holder": {
    "type": "INDIVIDUAL",
    "information": {
      "identifier_type": "CPF",
      "first_name": "Caetano",
      "last_name": "Veloso",
      "identifier": "69700150844"
    }
  }
}
{
  "id": "1c83ead8-6665-429c-a17a-ddc76cb3a95e",
  "created_at": "2020-04-23T21:30:20.336854+00:00",
  "created_by": "62053a72-e2d5-4c95-a578-6b16616900ac",
  "customer": "49f244ef-06cd-49cf-ad0c-f43796e370ad",
  "institution": "f512d996-583a-4a91-8b5b-eba2e103b068",
  "details": {
    "country": "BRA",
    "account_type": "CHECKINGS",
    "agency": "0444",
    "number": "45722-0"
  },
  "holder": {
    "type": "BUSINESS",
    "information": {
      "identifier_type": "CNPJ",
      "name": "Caetano Veloso Entertainment Universe",
      "identifier": "12300399900"
    }
  }
}

πŸ“˜

Register your organization’s bank account

If you want to register your organization's bank account to be the beneficiary account instead, check our OFPI Prerequisites guide for more info. :blush:

Create a payment link

To create a payment link, you need to make a POST Create a payment link call with the following core information:

{
     "allowed_payment_method_types": [
          "open_finance"
     ],
     "payment_method_details": {
          "open_finance": {
               "beneficiary_bank_account": "account_uuid"
          }
     },
     "callback_urls": {
          "cancel": "url_to_redirect_to_if_process_cancelled",
          "success": "url_to_redirect_to_if_process_successful"
     },
     "provider": "belvo",   
     "description": "payment_description",
     "customer": "the_customer_uuid",
     "amount": "amount_to_pay_as_a_float",
     "expires_in": "payment_link_expiration_time"
}

{
     "allowed_payment_method_types": [
          "open_finance"
     ],
     "payment_method_details": {
          "open_finance": {
               "beneficiary_bank_account": "a80d5a9d-20ae-479a-8dd7-ff3443bcbbfc"
          }
     },
     "callback_urls": {
          "cancel": "https://www.acmecorp.com/checkout/3487548/cancel",
          "success": "https://www.acmecorp.com/checkout/3487548/success"
     },
		 "provider": "belvo",	
     "description": "Awesome training Sneaker",
     "customer": "49f244ef-06cd-49cf-ad0c-f43796e370ad",
     "amount": "1000.00",
     "expires_in": "7d"  
}
'

🚧

For amount, you can only use digits 0-9, with a . as a decimal separator, and up to 2 decimals points. Otherwise, our API will return a 400 Invalid Error.

You'll receive a response containing a unique link (the payment_url) that you can share with your user and be guided through the payment process.

{
  "id": "1c83ead8-6665-429c-a17a-ddc76cb3a95e",
  "created_at": "2022-02-09T08:45:50.406032Z",
  "created_by": "62053a72-e2d5-4c95-a578-6b16616900ac",
  "payment_url": "https://pay.belvo.io/YggaKvPbM5aJhksu1BEwDI5FKTcUc5wZqNB-wH7MFGU",
  "access_token": "YggaKvPbM5aJhksu1BEwDI5FKTcUc5wZqNB-wH7MFGU",
  "callback_urls": {
    "cancel": "https://www.acmecorp.com/checkout/3487548/cancel",
    "success": "https://www.acmecorp.com/checkout/3487548/success"
  },
  "payment_intent": "1c83ead8-6665-429c-a17a-ddc76cb3a95e",
  "status": "ACTIVE",
  "updated_at": "2022-02-09T08:45:50.406032Z",
  "expires_in":"7d",
  "expires_at":"2022-02-09T08:45:50.406032Z"
}

πŸ‘

Tip!

Make sure to store the payment_intent.id you receive in the response, you can use it later to relate the payment intent with the payment transaction that confirms the payment.

Done! Now that you’ve created the payment link, you can share it with your customer. They’ll use this URL to start the Payment Link Widget that will guide them through the payment process. πŸŽ‰

πŸ“˜

Need more info? Check out our API reference! πŸ€“

Widget Payment Process

You'll need to share the payment_url with your user so they can start Belvo’s Payment Link Widget (a fully responsive hosted widget for web and mobile applications). The widget will guide your user through the payment flow. When the Payment Link Widget starts up, your user will be:

  1. Asked to select their institution
  2. Asked to confirm the payment information
  3. Redirected to their institution to complete the payment process in their bank.

This is an example implementation of sharing the payment_url:

<html lang="en-US">
<head>
  <meta charset="utf-8">
  <title>Pay with Belvo</title>
</head>
<body>
	<!-->Simple link for a user to pay with Belvo <-->
  <a id="link" href="">Pay with Belvo</a>
  <script>
    // Sending a request to your backend so that you can send a request
    // to Belvo to generate the Payment Link
    fetch('https://yourawesomebackend.com/api').then(function (response) {
    // The API call was successful! Return the JSON response from Belvo.
    return response.json();
    }).then(function (data) {
    // This is the JSON from your backend
    console.log({ data });
    // Set the payment link URL that is shown to the user
    document.querySelector('#link').href = data.payment_url;
    }).catch(function (err) {
    // There was an error
    console.warn('Something went wrong. Please try again.', err);
    });
  </script>
</body>
</html>

πŸ“˜

To help you keep track of your user’s process within the Payment Link widget, Belvo sends payment intent status update webhook events. In the diagrams below we annotate which payment intent status event will be sent at which step of the process.

For more info, check our Payment intents webhook article.

1296

OFPI Payment Link Widget

Once your user confirms the payment in their institution, they’ll be redirected back to the Payment Link Widget and will see a "Processing" state while Belvo confirms the payment. Depending on the outcome from their institution, your user will either see a β€œPayment Confirmed” or a β€œPayment Failed” screen in the widget.

🚧

At the moment, the widget will display a generic error message. But we’re currently working on improving your experience and will be back soon with more in-depth explanations of all possible errors that can be displayed to the user. πŸ˜‰

1296

OFPI Payment Link Widget - Confirmation

Getting a payment intent succeeded webhook means that your user consented to the payment and that their bank authorized the transaction. You’ll receive the following notification:

{
  "webhook_id": "3b9a69f7-0f0a-455b-832d-49ad6fd4905c",
  "webhook_type": "PAYMENT_INTENTS",
  "webhook_code": "STATUS_UPDATE",
  "object_id": "d2e40773-19f6-48d1-93c3-3590ec0c74df",
  "data": {
    "status": "succeeded" // The status of the payment intent.
  }
}

Done! When Belvo confirms the payment was processed and that money was transferred to the beneficiary account, you’ll get a new webhook called Transactions. πŸŽ‰

What’s next? You can confirm the transfer of funds by listening to the Transactions webhook. With it, Belvo also returns the id you need to get details about a transaction.

How do you know that your payment has been completed?

We’ll inform you of every successful payment by sending you a Transactions webhook - a payment transaction is an actual transfer of funds from one account to another πŸ˜‰. This means that every time money has been successfully transferred to your account, you’ll receive the following notification:

{
  "webhook_id": "3b9a69f7-0f0a-455b-832d-49ad6fd4905c",
  "webhook_type": "TRANSACTIONS",
  "webhook_code": "OBJECT_CREATED",
  "object_id": "d2e40773-19f6-48d1-93c3-3590ec0c74df",
  "data": {}, //For OBJECT_CREATED webhooks, the data field returns an empty object.
}

You can also get details about a transaction by making a GET details call using the object_id of the transaction (which you receive in the webhook event).

{
  "id": "fd0f3303-cafb-47ea-9753-21155cb144ab",
  "created_at": "2020-04-23T21:30:20.336854+00:00",
  "created_by": "1c83ead8-6665-429c-a17a-ddc76cb3a95e",
  "amount": "500",
  "currency": "BRA",
  "description": "Awesome training Sneaker",
  "transaction_type": "INFLOW",
  "beneficiary": "a80d5a9d-20ae-479a-8dd7-ff3443bcbbfc",
  "payer": {},
  "payment_intent": "1c83ead8-6665-429c-a17a-ddc76cb3a95e",
  "customer": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
}

πŸ“˜

Need more info? Check out our API reference! πŸ€“

Summary

In this guide you learned how to:

  • register customers so you can start requesting payments from them
  • create a payment link you can share with your customers to start the Payment Link Widget
  • confirm that a payment is successful

πŸ‘

If you need any help, just reach out to our team at [email protected] and we’ll get right to it. πŸ™‚