Skip to content
Last updated

Phase 2: Payment Creation (Direct API)

Beta

Smart Collections is currently in Beta. Some contracts on this page are still being confirmed with our engineering team, so treat them as provisional and expect refinements before general availability, including:

  • Webhook payloads and event codes
  • API reference updates for the Collection Instructions, Payment Authorization, and Charge endpoints
  • Field names and documentation improvements (terminology, diagrams)

Contact your Belvo account manager to join the Beta program.

In Phase 2 of Smart Collections, you collect the funds with Smart Transfers, Belvo's Payments product for moving money between accounts held by the same user. You create a Smart Transfers Payment Authorization once, and then trigger a Charge each time Phase 1 tells you there are enough funds.

The full step-by-step integration, with every field, response, and status, is in the Direct API (Smart Transfers) guide. This page only covers what's specific to using Smart Transfers together with Phase 1: Balance Checking.

Belvo Payments APIBelvo Aggregation APIYour applicationBelvo Payments APIBelvo Aggregation APIYour applicationYour user approves it at their bankPOST /payments/br/payment-authorizations/Webhook: PAYMENT_AUTHORIZATIONGET /payments/br/payment-authorizations/{id}/200 OK (status: AUTHORIZED)Webhook: item_ready_to_charge (data.amount)POST /payments/br/payment-authorizations/{id}/charges/201 CreatedWebhook: CHARGEGET /payments/br/payment-authorizations/{id}/charges/{charge_id}/200 OK (status: SETTLED or FAILED)

1. Create the Payment Authorization early

Create the Smart Transfers Payment Authorization in parallel with your Phase 1 Collection Instruction, so that it's already AUTHORIZED when item_ready_to_charge arrives. Follow Create a Payment Authorization, and keep these points in mind:

  • One authorization, many Charges. Create one authorization per user and reuse it for every Charge. Size total_allowed_amount, payment_transaction_limit, and periodic_limits to cover the items you expect to collect.
  • The beneficiary must be held by the user. Smart Transfers only moves funds between accounts held by the same person (same CPF) or company (same CNPJ root).
  • Use the same bank as the Link. Set payer.institution to the payments institution that matches the bank of the Link you monitor in Phase 1. Belvo can't check this for you, because the authorization doesn't reference the Link.

Charge the account you monitor

In Phase 1, Belvo checks the balance of every account the user shared in their data consent, and sends item_ready_to_charge as soon as any one of them has enough funds. The webhook doesn't say which account it was.

To make sure Charges debit the account you monitor, create the authorization with that account's details in payer.account_details (account_type, ispb, issuer, number). You can take issuer and number from the account's agency and number in Banking Aggregation. See Debit a specific account. Otherwise, your user chooses the account at their bank, and it may not be the one whose balance was checked.

2. Charge when item_ready_to_charge arrives

When you receive item_ready_to_charge, check that the authorization is AUTHORIZED, and then create a Charge against it:

  • Set amount to the webhook's data.amount.
  • Set date to today, so the funds are collected while they're available.
  • Set external_id to a UUID you store alongside the item. Belvo doesn't link Collection Instructions, authorizations, and Charges to each other, and a Charge's external_id must be a UUID, so the item's own external_id can only be reused if it's a UUID too.
Phase 1 is optional

You don't need a Collection Instruction to charge. With an AUTHORIZED Payment Authorization you can create a Charge at any time. Phase 1 is only needed when you want Belvo to tell you when the account has enough funds.

3. Follow the Charge

Belvo sends a CHARGE webhook each time the Charge's status changes. Fetch the Charge to read it: SETTLED means the funds left the user's account; FAILED means they didn't, and status_reason_code tells you why (for example, INSUFFICIENT_FUNDS if the balance dropped after Phase 1 checked it).

A failed Charge doesn't restart Phase 1

Once an item reaches item_ready_to_charge, Belvo stops monitoring it, even if the Charge you create later fails. To try again, create a new Collection Instruction for that amount. Reusing the same item external_id is fine.

Best practices

Correlate everything with your own IDs. Store the item id, the authorization id, and the Charge id (and your external_ids) together, so you can reconstruct which item each Charge settled.

Return 2XX from your webhook endpoints quickly. Process business logic asynchronously so you don't time out and trigger retries.

Reconcile items that never produce a Charge. Phase 1 sends no webhook when an item's windows end without enough funds. Track your items and follow up on any that go stale. You can check each item's status to see how it ended.

Avoid duplicate Charges. Smart Transfers doesn't support idempotency keys yet. If a Charge request times out, list the authorization's Charges and look for your external_id before you retry.