# Introduction **Belvo's Pix Automático** is a recurring payment method established by the Central Bank of Brazil that simplifies how recurring Pix transfers are initiated by allowing them to be processed automatically after a one-time authorization from the end-user (payer). Once authorized, the merchant can initiate subsequent recurring payments without requiring individual approval for each transaction. These recurring payments can be configured for either fixed or variable amounts, depending on the specific business logic. Fixed versus Variable Payments With Pix Automatico, you can select to either request payments for the same amount from your user each time (Fixed) or establish a variable amount (Variable). - Fixed = Stable recurring subscriptions (such as Netfllix, Spotify, gyms) - Variable = Metered subscriptions (such as electricity, water, gas) In this guide, you’ll learn: 1. The prerequisites you need to complete before doing anything else. 2. How to set up a Payment Authorization 3. How to request payment from your customers (Charges) ## Prerequisites Version Header The Payment Authorization resource requires that you send through the `X-Belvo-API-Resource-Version` header set to `Payments-BR.V2`. Make sure you have completed all the steps in our dedicated prerequisites article before continuing this guide. The guide will take you through how to: - Set up webhooks (required as our payment solutions utilize webhooks to inform you regarding the progress of your payments, any errors that occur, and when a payment is completed successfully). - Create a benficiary bank accout (required for receiving payment funds). - Set up a return (callback) URL (required as after your user authorizes their payment they need to be redirected to your application). ## General flow overview API Version As you can see in the diagram below, the data flow for creating a payment using Pix Automatico involves: 1. Creating a Payment Authorization. 2. Redirecting your user to the `authorization_url` so that they can confirm that Payment Authorization. Once confirmed, they are redirect to the `return_url` you provided. 3. Waiting for a `PAYMENT_AUTHORIZATION` webhook with the `status` set to `AUTHORIZED`. 4. Requesting the Charge at least two days before the payment should occur. 5. On the day of the payment, waiting for a `CHARGES` webhook with the `status` set to `SETTLED`. Sequence diagram of the required API calls and webhooks sent during the Pix Automatico process ## Creating a Payment Authorization A Payment Authorization is the consent that your user gives you to charge (debit money from) their accounts. You need to perform one Payment Authorization per ‘contract’ (for example, if your company does both electricity and water but they are billed separately, then you will create two separate Payment Authorizations). Fixed ```curl Payment Authorization Request URL POST /payment-authorizations/ ``` Fixed Pix Automatico { "payment_method": "PIX_OF_AUTOMATIC_FIXED", "description": "Monthly gym subscription payment", "external_id": "c169a8a9-e9f5-48db-9f4a-818caef9356b", "return_url": "https://merchant.com/return", "payer": { "customer": { "identifier": "12345678901", "name": "João da Silva", "external_id": "4b8a81a0-e33c-45a6-8567-479efb105f73" }, "institution": "ef685cf7-d143-4671-a1e5-4d1d019a3f5c", "representative_identifier": "12345678901234" }, "beneficiary": { "type": "BANK_ACCOUNT", "target": { "holder": { "identifier": "12345678901122", "name": "Frangos Enlatados" }, "details": { "account_type": "CHECKINGS", "agency": "0444", "institution": "f512d996-583a-4a91-8b5b-eba2e103b068", "number": "457220" }, "external_id": "4b8a81a0-e33c-45a6-8567-479efb105f73", "metadata": { "internal_reference_id": "GGq73487w2" } } }, "payment_method_configuration": { "amount": 3000.01, "statement_description": "Monthly Gym - Premium Plan", "frequency": "MONTHLY", "start_date": "2025-06-01", "end_date": "2026-06-01", "contract_id": "PREMIUMPLAN123456", "contract_debtor": { "identifier": "12345678901", "name": "João da Silva" }, "retries": true, "first_payment": { "date": "2025-05-15", "amount": 3000.01 } }, "metadata": { "internal_reference_id": "GGq73487w2" } } Variable ```curl Payment Authorization Request URL POST /payment-authorizations/ ``` Variable Pix Automatico { "payment_method": "PIX_OF_AUTOMATIC_VARIABLE", "description": "Monthly gym subscription payment", "external_id": "c169a8a9-e9f5-48db-9f4a-818caef9356b", "return_url": "https://merchant.com/return", "payer": { "customer": { "identifier": "12345678901", "name": "João da Silva", "external_id": "4b8a81a0-e33c-45a6-8567-479efb105f73" }, "institution": "ef685cf7-d143-4671-a1e5-4d1d019a3f5c", "representative_identifier": "12345678901234" }, "beneficiary": { "type": "BANK_ACCOUNT", "target": { "holder": { "identifier": "12345678901122", "name": "Frangos Enlatados" }, "details": { "account_type": "CHECKINGS", "agency": "0444", "institution": "f512d996-583a-4a91-8b5b-eba2e103b068", "number": "457220" }, "external_id": "4b8a81a0-e33c-45a6-8567-479efb105f73", "metadata": { "internal_reference_id": "GGq73487w2" } } }, "payment_method_configuration": { "minimum_amount": 10000.01, "maximum_amount": 50000.5, "statement_description": "Monthly Gym - Premium Plan", "frequency": "MONTHLY", "start_date": "2025-06-01", "end_date": "2026-06-01", "contract_id": "PREMIUMPLAN123456", "contract_debtor": { "identifier": "12345678901", "name": "João da Silva" }, "retries": true, "first_payment": { "date": "2025-05-15", "amount": 3000.02 } }, "metadata": { "internal_reference_id": "GGq73487w2" } } On a successful API request, Belvo responds with a `201 - OK`. You will need to redirect your user to the `authorization_url` that you receive in the response so that they can authorize the payments in their institution. Once they go through the authorization process in their institution’s application, they will then be redirected back to `return_url` you provided. Fixed Example Fixed Payment Authorization Response { "id": "9fc68b84-f2d6-4142-b2ad-9d2d1ad70432", "created_at": "2025-05-20T09:55:02Z", "updated_at": "2025-05-20T09:55:02Z", "status": "AWAITING_AUTHORIZATION", "status_reason_code": null, "status_reason_message": null, "status_updated_at": "2025-05-20T09:55:02Z", "authorized_at": "2025-05-20T09:55:02Z", "external_id": "c169a8a9-e9f5-48db-9f4a-818caef9356b", "description": "Internal description used by the merchant only", "return_url": "https://merchant.com/return", "payment_method": "PIX_OF_AUTOMATIC_FIXED", "payer": { "customer": "533e7a9b-e6c7-4bd4-be79-3a3c3bd78044", "institution": "770932b4-8f1f-4b0f-8470-1c605903fdb2", "representative_identifier": "12345678901122" }, "beneficiary": { "type": "BANK_ACCOUNT", "target": "b6278377-f710-4d1a-a026-7bab757256d0" }, "payment_method_configuration": { "amount": "10000.05", "statement_description": "Description to show on the bank statement", "frequency": "WEEKLY", "start_date": "2025-06-01", "end_date": null, "contract_id": "id-with-max-len-35", "contract_debtor": { "identifier": "12345678901", "name": "João da Silva" }, "retries": true, "authorization_url": "url_to_redirect_user" // [!code highlight] } } Variable Example Variable Payment Authorization Response { "id": "9fc68b84-f2d6-4142-b2ad-9d2d1ad70432", "created_at": "2025-05-20T09:55:02Z", "updated_at": "2025-05-20T09:55:02Z", "status": "AWAITING_AUTHORIZATION", "status_reason_code": null, "status_reason_message": null, "status_updated_at": "2025-05-20T09:55:02Z", "authorized_at": "2025-05-20T09:55:02Z", "external_id": "c169a8a9-e9f5-48db-9f4a-818caef9356b", "description": "Internal description used by the merchant only", "return_url": "https://merchant.com/return", "payment_method": "PIX_OF_AUTOMATIC_VARIABLE", "payer": { "customer": "533e7a9b-e6c7-4bd4-be79-3a3c3bd78044", "institution": "770932b4-8f1f-4b0f-8470-1c605903fdb2", "representative_identifier": "12345678901122" }, "beneficiary": { "type": "BANK_ACCOUNT", "target": "b6278377-f710-4d1a-a026-7bab757256d0" }, "payment_method_configuration": { "minimum_amount": "10000.01", "maximum_amount": "50000.5", "statement_description": "Description to show on the bank statement", "frequency": "WEEKLY", "start_date": "2025-06-01", "end_date": null, "contract_id": "id-with-max-len-35", "contract_debtor": { "identifier": "12345678901", "name": "João da Silva" }, "retries": true, "authorization_url": "url_to_redirect_user" // [!code highlight] } } The Payment Authorization process, including redirecting and getting all the required confirmations, must be completed within 60 minutes. After 60 minutes, the authorization is automatically set to `FAILED`. Once the user confirms the authorization, you will need to listen for a a `PAYMENT_AUTHORIZATION` webhook with the `status` set to `AUTHORIZED`. When you receive this webhook, the authorization process is complete. Charging Your Customer Now that you have the Payment Authorization, you can start charging your customer! ## Charging Your Customer Once you have a Payment Authorization with the status `AUTHORIZED`, for each payment you want to retrieve from your customer you need to create a **Charge**. What is a Charge? A **Charge** represents the individual payment (debit) that your customer will make. Charge Request Rules When you request a Charge, there are a couple of rules you need to follow: 1. The request must be made **between two and ten days** from when the Charge should occur. For example, if you want to debit your customer’s account on 30.05.2025, you need to make the request between the 20.05.2025 and 28.05.2025. 2. Only one Charge can be made in a payment ‘cycle’. For example, if the `frequency` in the Payment Authorization is `WEEKLY`, then you can only Charge your customer once per week. This means that you can only make **one** request in the payment cycle. 3. The `date` of the Charge. This date must align with the `frequency` in the Payment Authorization. For example, if the `frequency` is `MONTHLY` and the `start_date` is `2025-06-01`, then each `date` that you provide must be according to this frequency and date (for example, `2025-06-01`, `2025-07-01`, `2025-08-01`). **Note: If the day falls on a weekend or a bank holiday, you must change the `date` to be the first business day that occurs after the original date.** To request a Charge, you will need to make the following request: ```curl Charge Request URL POST /payment-authorizations/payment_authorization_id/charges/ ``` ```json Charge Request Body { "amount": 10000.05, "date": "2025-06-01", "statement_description": "Description to show on the bank statement", } ``` On a successful Charge request, you will receive this response: Example Charge Response { "id": "0d3ffb69-f83b-456e-ad8e-208d0998d71d", "created_at": "2022-02-09T08:45:50.406032Z", "status_updated_at": "2025-06-09T08:45:50.406032Z", "status": "PENDING", "status_reason_code": null, "status_reason_message": null, "amount": "100.12", "date": "2025-06-09", "end_to_end_id": "1234567890abcdef", "statement_description": "Super Shoe Store - Brown Sneakers", "external_id": "4b8a81a0-e33c-45a6-8567-479efb105f73", "beneficiary": { "bank_account": { "id": "088bc38f-1430-40c5-a5d2-80bd67189d11", "holder": { "name": "Jane Smith", "identifier": "12345678901" }, "details": { "institution": "f47ac10b-58cc-4372-a567-0e02b2c3d479", "agency": "5678", "number": "987654321", "account_type": "SAVINGS", "code": "678901" } } }, "payer": { "bank_account": { "holder": { "identifier": "12345678902" }, "details": { "institution": "f9f40aa0-a864-45d6-a5d4-43ce9d28dd0b", "code": "123345", "account_type": "CHECKING", "agency": "1234", "number": "123456789" } } }, "metadata": { "internal_reference_id": "GGq73487w2" } } On the day of the payment, you will need to listen for a `CHARGES` webhook with the status set to `SETTLED` , which will indicate that payment was completed. Done! And that's it! Now, each time that you need to make to request a payment from a client, you just need to make another Charge request! ## Additional Resources ### Changing the bank account for a individual Charge There might be a situation where you need to request that the payment goes to a bank account other than the one you initially provided in the Payment Authorization. And with Pix Automatico, that’s possible! However, the bank account you provide **must** be associated with the same CNPJ and Company Name as with the initial Payment Authorization. For example, if in the initial Bank account was registered to `Frangos Enlatados` with the CNPJ of `12345678901122`, then the new bank account must be registered to the exact same name and CNPJ identifier. Otherwise, when you make the request, the Open Finance Network will throw an error. To request a Charge with a different bank account, you will need to make the following request: With Bank Account Details ```curl Charge Request URL POST /payments/br/payment-authorizations/{payment_authorization_id}/charges/ ``` Charge with Bank Account Details { "amount": 100.01, "date": "2025-05-15", "statement_description": "Monthly Gym - Premium Plan", "beneficiary": { "holder": { "identifier": "12345678901122", "name": "Frangos Enlatados" }, "details": { "account_type": "CHECKINGS", "agency": "0444", "institution": "f512d996-583a-4a91-8b5b-eba2e103b068", "number": "457220" }, "external_id": "4b8a81a0-e33c-45a6-8567-479efb105f73", "metadata": { "internal_reference_id": "GGq73487w2" } } } With Bank Account ID ```curl Charge Request URL POST /payments/br/payment-authorizations/{payment_authorization_id}/charges/ ``` Charge with Bank Account ID { "amount": 100.01, "date": "2025-05-15", "statement_description": "Monthly Gym - Premium Plan", "beneficiary": { "target": "046f9af7-1813-4830-b4e6-5231e8111ca1" } } ### Retrying a Charge In the case that a Charge fails, you will receive a webhook on the day indicating which Charge failed. If the Payment Authorization allows for retries (`retries: true`), then you are able to retry the payment and attempt to debit the user’s account again. Regarding retries, keep in mind the following: - Per each payment cycle, you can retry the payment up to three times. - You can schedule a retry for the day after the request. For example, if the original Charge fails on 01.06.2025, you can retry the Charge with the `date` set to `02.06.2025`. - Retried Charges are linked 1-to-1 with another Charge. See the Linked Charges section below for a detailed explanation. - For weekly cycles, the latest you can do the initial retry is **five** days (exclusive) after the first failed Charge. For example, if the original date of the Charge was 01.06.2025, you have up to 06.06.2025 to retry the payment. - For all other cycles, the latest you can do the initial retry is **seven** days (exclusive) after the first failed Charge. For example, if the original date of the Charge was 01.07.2025, you have up to 08.07.2025 to retry the payment. To retry a Charge, you will need to make the following request: ```curl Retry a Charge Request URL POST /payments/br/payment-authorizations/{payment_authorization_id}/charges/{charge_id}/retry/ ``` ```json Retry a Charge Request Body { "date": "2025-06-30" // The date you want to retry the Charge on, in YYYY-MM-DD format. Must be at least one day in the future. } ``` On a successful retry, you will receive a new Charge ID (and object). Please see the Linked Charges section below for a detailed explanation. ### Linked Charges Belvo uses a doubly linked list structure to represent the lifecycle of a Charge and its retries, allowing you to track all the individual attempts associated with a Charge. Each time a Charge is retried, a new Charge is generated and links to the previous Charge. You can navigate through these Charges using the `previous` and `next` fields. In the example below, the Charge has been retried three times: Explanation of doubly linked lists for Charges in Belvo 1. The original Charge (`1546`) failed. The `previous` parameter is set to `null` (indicating it is the first Charge). The `next` parameter is set to `3444`. 2. The first retry (`3444`) failed. The `previous` parameter is set to `1546` . The `next` parameter is set to `8342`. 3. The second retry (`8342`) failed. The `previous` parameter is set to `3444` . The `next` parameter is set to `9977`. 4. The third retry (9977) failed. The `previous` parameter is set to `8342` . The `next` parameter is set to `null` (indicated it is the last retry and no further retries where made). ### Cancelling an individual Charge Cancellation Time Restriction The latest you can cancel a scheduled Charge is by 22:00:00 (GMT-3) on the day before the Charge date. If you miss the cutoff time, you will receive an API error from Belvo and the payment will go through. To cancel an individual Charge, you need to send through the following request: ```shell Cancel Charge Request URL curl --request POST 'https://api.belvo.com/payments/br/payment-authorizations/{payment_authorization_id}/charges/{charge_id}/cancel/' \ -u SECRET_ID:SECRET_PASSWORD \ -H 'X-Belvo-API-Resource-Version: Payments-BR.V2' \ ``` If successful, Belvo responds with a `204 - No Content`. You will receive a webhook notification confirming the cancellation. ### Cancelling a Payment Authorization Cancellation Time Restrictions The latest you can cancel a Payment Authorization is by 22:00:00 (GMT-3) on the day before the next Charge date. If you miss the cutoff time, the Payment Authorzation will be cancelled, **but the Charge will still be processed**. To cancel a Payment Authorization, you need to send through the following request by 22:00 (Brasilia Time): ```shell Cancel Payment Authorization Request URL curl --request POST 'https://api.belvo.com/payments/br/payment-authorizations/{payment_authorization_id}/cancel/' \ -u SECRET_ID:SECRET_PASSWORD \ -H 'X-Belvo-API-Resource-Version: Payments-BR.V2' \ ``` If successful, Belvo responds with a `204 - No Content`. You will receive a webhook notification confirming the cancellation. ### Get details of a Charge When you receive a webhook notification regarding a Charge, you can request the details of the Charge using the following request: ```shell Get Charge Details Request URL curl --request GET 'https://api.belvo.com/payments/br/charges/{charge_id}/' \ -u SECRET_ID:SECRET_PASSWORD \ -H 'X-Belvo-API-Resource-Version: Payments-BR.V2' \ ``` ### Status Reason Codes and Messages When a Payment Authorization or Charge encounters an error, Belvo updates the `status` of the given resource. Additionally, Belvo also provides detailed information regarding the status change in the `status_reason_code` and `status_reason_message` parameters to help you understand what went wrong. Please see our dedicated Error Codes and Messages article for a detailed list of possible codes and messages.