Skip to main content
This guide covers the key decisions your team makes when you integrate Bank Transfer. It also gives the best practices for a reliable and compliant customer experience.

Product decisions


These are choices your product team makes in the customer-facing experience. They directly affect customer satisfaction and support volume.

Show the fee before the customer confirms

The initiate step returns the fee amount before any funds move. Use this window to show a clear confirmation screen:
This reduces complaints and cancellations from customers surprised by fees after the fact.

Handle operating hours gracefully

TED OUT is available Monday to Friday, 06:30–17:00 (Brasília time) by default. When a customer starts a transfer outside these hours, do not show only an error. Tell them when they can try again:
To avoid unnecessary round trips, validate operating hours on the client side before you call the API. You do not need to maintain your own holiday list. The plugin blocks weekends and BACEN holidays automatically, from its built-in holiday calendar for 2026 to 2028. When a holiday rejects a transfer, show that reason to the customer. Do not replicate the calendar on the client. Trust the plugin as the source of truth to avoid inconsistencies over time.

Communicate transfer limits before customers hit them

Show the customer’s remaining daily limit in your transfer UI. Show it before they attempt a transfer that the plugin rejects. The plugin counts amount + fee, and the day rolls over at 00:00 UTC (21:00 Brasília time). For example:

Show confirmation receipts after completion

After a TED OUT or P2P transfer completes, display (or offer to download) a receipt with:
  • Transfer date and time
  • Sender and recipient details
  • Amount, fee, and total
  • confirmationNumber (customer-facing reference)
  • controlNumber (JD SPB reference, for TED OUT and TED IN)
When you provide this information early, you reduce “did my transfer go through?” support contacts.

Keep customers informed in real time

Use webhooks to push transfer status updates to your UI as they happen. Do not make customers refresh or wonder if their transfer went through. See TED webhooks for setup.

Compliance decisions


These are requirements that apply to your integration regardless of your product choices.

LGPD and personal data

Transfer records contain personal data: customer names, CPF/CNPJ, and bank details. Make sure your privacy policy explicitly covers financial transaction data. Do not log CPF/CNPJ in plain text. Mask it in interfaces as ***.***.***-00. The plugin has no endpoint for LGPD right-to-erasure requests.

Data retention

The plugin never deletes or expires transfer records, so you own their retention. Retain transfer and audit data for at least 5 years, per BACEN record-keeping requirements for financial institutions.

Audit trail and reconciliation

Every transfer generates two reference numbers you must store: Keep both the transferId and confirmationNumber in your own records for reconciliation. For TED OUT and TED IN, also store the controlNumber.

Operating hours

BACEN mandates that TED operates Monday to Friday, 06:30–17:00 (Brasília time, UTC-3). The plugin enforces this window by default. An operator can change the window at runtime through the systemplane key operating_hours.window. Treat 06:30–17:00 as the norm and build your UX around it. See Handle operating hours gracefully above.
P2P transfers are not subject to operating hour restrictions and work 24/7.

Integration checklist


Before you go live, verify the following:
  • Idempotency keys on all write operations: Send a UUID v4 X-Idempotency header on every call to initiate, process, and cancel. This prevents duplicate transfers from retries or double-clicks.
  • Webhook endpoint live before launch: Deploy your webhook endpoint and make it reachable before you go live. Transfer events start firing immediately on the first real transaction.
  • Expiry handled: An initiated transfer expires at expiresAt: after 24 hours, or for TED OUT at the close of that day’s operating window. If your flow allows a customer to start a transfer and return later, handle the expiry case explicitly.
  • Read before you retry a 5xx: A 5xx leaves the outcome unknown. Read the transfer first, and retry with backoff (e.g., 2s, 4s, 8s) under a new X-Idempotency key only if the operation did not happen. JD SPB unavailability surfaces as 503 with BTF-1000 or BTF-1003. Midaz ledger unavailability surfaces as BTF-2000. Do not retry immediately in a loop.
  • Operating hours validated client-side: Check hours in the UI before you call the API. This reduces failed API calls and gives a better customer experience.
  • Both transferId and confirmationNumber stored: Required for reconciliation and audit. For TED OUT and TED IN, also store controlNumber.

Error handling


Use these error scenarios to map API errors to customer-friendly messages and define the correct recovery path. For the complete list of error codes and their meanings, see the TED error list.