General best practices

Best practices for integrating Bill Payment, including the recommended flow, minimum payload, scheduling rules, idempotency, and webhooks.

Use these recommendations to reduce duplicate payments, maintain traceability, and correctly handle asynchronous Bill Payment updates.

Avoid duplicate payments

Implement idempotency control in your application before sending a payment request.

For each operation:

  • keep a unique identifier in your system;
  • send this identifier in externalReference when you need to correlate operations;
  • store the bill.id associated with the payment;
  • before creating a new attempt, check whether the operation has already been registered.

In case of a timeout or communication failure, do not immediately resend the same bill. First, check whether the payment has already been created through the events received. Use API queries only when you need to reconcile or recover the state of the operation.

Keep the payload traceable

Send only the fields required for the scenario being executed and log the final payload sent to the API.

A payment without optional fields can be created with only identificationField:

{
"identificationField": "83660000001084301380074119002551100010601813"
}

Include optional fields only when they are required for the payment.

See the Create a bill payment endpoint.

To make audits and investigations easier, keep the association between:

  • your internal reference;
  • externalReference, when used;
  • bill.id;
  • the payload sent;
  • the current state of the operation.

Track processing through Webhooks

Use the Bill Payment Webhooks as the main mechanism to track processing changes.

Each event has its own id. Since Webhooks use the at least once model, the same event may be delivered more than once. Persist this id and prevent a new delivery from executing the same business rule again.

Use bill.id to locate the corresponding payment in your system.

When you receive BILL_FAILED, check bill.failReasons before deciding whether a new attempt should be made.

See the Bill Payment events.

See how to implement idempotency in Webhooks.

Do not retry without identifying the cause

A new attempt must take the result of the previous operation into account.

Before resending:

  • confirm whether the payment has already been created;
  • identify the cause when you receive BILL_FAILED;
  • fix data, balance, or payment condition errors before trying again;
  • avoid creating another operation just because your application did not receive a conclusive response.

To interpret errors returned during creation or processing, see Common errors and exceptions — Bill Payment.

Do not hardcode a single processing time

Processing times and conditions vary according to the type and amount of the bank slip and may change.

Avoid implementing a single cutoff time as a global rule of the integration. Keep these validations updatable and check the current rules before defining the application's behavior.

See Immediate payment vs. Scheduled payment.

Validate in the Sandbox

Use the Sandbox to validate payloads, error handling, and Webhooks.

Do not use real third-party bank slips in Production to test the integration's behavior or retry strategies.

The Sandbox has its own behavior and does not perform real bank clearing.

See how to test Bill Payment in the Sandbox.

Next steps


Did this page help you?