Testing a boleto integration against a real bank is slow and partly impossible. You need a business account, a real payer willing to pay a real charge, and for anything involving a due date you would have to wait for the date to arrive.
The Sandbox connector removes all of that. It issues boletos that look real and moves them through the status you choose by themselves, firing the same webhooks a real bank would.
Shaped, not spendable
Sandbox boletos carry a correctly-shaped digitable line, barcode and PIX payload — the right lengths and field structure, so your parsing and rendering are genuinely exercised. They are not valid payment instruments: the check digits are deliberately not computed. Nothing issued here can be paid at a real bank.
What it lets you test#
You do not send any request to move a boleto. The Sandbox performs each step by itself, 5 minutes apart, and fires a boleto/updated webhook every time, exactly as a bank's settlement notification would.
The transitions the real API refuses are refused here too. A PAID boleto cannot be cancelled, and nothing returns to OPEN — so a handler that assumes a status can only move forwards is validated rather than accidentally passing.
Choosing a scenario#
The scenario is set by the cents of the boleto amount:
| Amount ends in | What happens |
|---|---|
,00 (e.g. 100.00) | After 5 minutes → PAID for the full amount |
,01 | After 5 minutes → PAID for half the amount (partial payment: amountPaid is lower than amount) |
,02 | After 5 minutes → OVERDUE; 5 minutes later → PAID (paid after the due date) |
,03 | After 5 minutes → OVERDUE; 5 minutes later → PROTESTED |
,04 | After 5 minutes → CANCELLED |
,05 | After 5 minutes → OVERDUE, and it stays there |
| Any other cents | Stays OPEN — use it to test your own cancellation with POST /boletos//cancelAPI |
Cancelling a boleto before a scheduled step runs stops its scenario.
Getting started#
Prefer to click through it first?
The Pluggy Dashboard does all of this without code, under Payments → Boletos (Beta): create a Sandbox connection, issue a boleto with the cents of the scenario you want, and watch its status change. The requests below are the same ones it sends.
Create a Sandbox Boleto Connection
Use connector 8 (Pluggy Bank Business) and POST /boleto-connectionsAPI. No real credentials are involved:
{
"connectorId": 8,
"credentials": {}
}Issue a boleto with the amount for your scenario
Identical to any other institution — same request, same response shape. Amounts are in reais, and the cents pick the scenario. This one ends in ,01, so it will be paid short:
{
"boletoConnectionId": "{YOUR-SANDBOX-CONNECTION-ID}",
"boleto": {
"seuNumero": "TEST-001",
"amount": 123.01,
"dueDate": "2026-03-01",
"payer": {
"taxNumber": "12345678000199",
"name": "Example SA",
"addressState": "SP",
"addressZipCode": "01239030",
"addressCity": "São Paulo",
"addressStreet": "Rua Example"
}
}
}Wait for the webhooks
Five minutes later the Sandbox settles the boleto and a boleto/updated webhook reaches your endpoint, the same one a real bank's notification would produce. Scenarios with two steps send a second webhook five minutes after the first.
Check your handler ran
GET /boletos/API returns the boleto in its new state, with amountPaid, paidAt and paymentOrigin populated for paid boletos — the same fields, in the same places, as a boleto settled at a real bank.
A test worth writing#
The failure mode that costs the most is a webhook handler that reconciles against the wrong field or assumes payment is always in full. The Sandbox makes both cheap to cover:
| Case | How to produce it |
|---|---|
| Paid in full | Issue with an amount ending in ,00 |
| Paid short | Issue with an amount ending in ,01 |
| Paid after the due date | Issue with an amount ending in ,02 |
| Protested | Issue with an amount ending in ,03 |
| Cancelled by the bank | Issue with an amount ending in ,04 |
| Overdue and unpaid | Issue with an amount ending in ,05 |
| Cancelled by you before payment | Issue with any other cents, then call POST /boletos//cancelAPI |
| Duplicate webhook | Make your endpoint idempotent and deliver the same event to it twice yourself |
Move on to a real bank
When your handler survives all of these, point the same code at an Inter connection. Nothing but the connection id changes.
