Webhook Event Format
When an event occurs in the banca.me system that matches your webhook subscription, we'll send an HTTP POST request to your configured endpoint with a JSON payload containing event details.
Event Structure​
All webhook events share a common structure:
{
"eventId": "evt_123456789abcdefghijk",
"data": {
"externalTrxId": "txr_abc123def456",
"loanAmount": 500000,
"interestRate": 0.015,
"periods": 3,
"installmentAmount": 170000,
"lastInstallmentAmount": 170000,
"state": "ACTIVE",
"transferDate": "2023-09-15T15:10:33Z",
"installments": [
{
"state": "PAID",
"period": 1,
"expirationDate": "2023-10-15T00:00:00Z"
},
{
"state": "ACTIVE",
"period": 2,
"expirationDate": "2023-11-15T00:00:00Z"
},
{
"state": "ACTIVE",
"period": 3,
"expirationDate": "2023-12-15T00:00:00Z"
}
]
}
}
Event Properties​
| Field | Type | Description |
|---|---|---|
eventId | string | Unique identifier for this event notification |
data | object | Event-specific payload containing loan details |
Data Structure​
The data field contains detailed information about the event. For loan events, it includes:
| Field | Type | Description |
|---|---|---|
externalTrxId | string | External transaction identifier |
loanAmount | number | Total amount of the loan |
interestRate | number | Interest rate (as a decimal) |
periods | number | Number of installments |
installmentAmount | number | Amount of each installment |
lastInstallmentAmount | number | Amount of the final installment |
state | string | Current state of the loan (e.g., "ACTIVE") |
transferDate | string | ISO 8601 date when the loan was funded |
installments | array | List of installment details |
Installment Properties​
Each item in the installments array contains:
| Field | Type | Description |
|---|---|---|
state | string | State of the installment (e.g., "ACTIVE") |
period | number | Installment number |
expirationDate | string | ISO 8601 date when payment is due |
Event States​
The state field in the data payload indicates the current status of the loan. This state can have one of the following values:
ACTIVE: Active loanPARTIAL_PREPAID: Partially prepaidPREPAID: Fully prepaidPAID: Loan fully paidREFINANCED: Refinanced loanSOFT_DEBT: Overdue debt (1 to 30 days)INTERMEDIATE_DEBT: Intermediate debt (31 to 89 days overdue)HARD_DEBT: Severe debt (90+ days overdue)RECOVERED: Recovered loanPUNISHED: Written-off loanOUTSOURCED: Outsourced loanCANCELED: Canceled loan
It's important to note that if you have received a webhook, the loan has already been approved. There's no need to verify the status to know if it's approved, as receiving the webhook itself confirms that the BNPL loan has been approved. The state provides additional information about the current situation of the loan.
Processing Events​
When processing events, your application should:
- Verify the webhook signature (see Validate Webhook Signatures)
- Check if the event has already been processed (using the
eventId) - Process the event data based on the state and other information
- Store relevant information in your database
Example: Processing a Loan Event​
Here's an example of how you might process a BNPL loan event:
function processLoanEvent(event) {
const { eventId, data } = event;
console.log(`Processing BNPL loan event ${eventId}, state: ${data.state}`);
// Since we already know the loan is approved (because we received the webhook),
// we can process directly based on the current loan status
// Update the loan status in our system
updateLoanStatus(data.externalTrxId, data.state);
// Calculate the payment schedule
const installments = data.installments.map((inst) => ({
number: inst.period,
amount:
inst.period === data.periods
? data.lastInstallmentAmount
: data.installmentAmount,
dueDate: new Date(inst.expirationDate),
status: inst.state,
}));
// Save the payment schedule
savePaymentSchedule(data.externalTrxId, installments);
// Notify the customer
notifyCustomer(data.externalTrxId, "loan_update", {
amount: data.loanAmount,
installments: data.periods,
state: data.state,
});
}
Handling Retries​
Banca.me will retry webhook deliveries once if your endpoint fails to respond with a 2XX status code. Your webhook handler should be designed to handle these retries appropriately:
- Implement idempotency by checking if an event has already been processed
- Respond with 200 OK even if you've already processed the event
- Log duplicate events for monitoring purposes
Note that banca.me performs only a single retry attempt. If your endpoint still fails to respond correctly after the retry, the event will not be delivered again. This makes it critical to ensure your endpoint is highly available and that you implement proper error handling.