Collection Flow
This document describes the complete collection lifecycle for the BNPL White-Label system — from listing active loans and invoices to payment processing, renegotiation, and webhook notifications.
Overview
After loan disbursement (application status FUNDED), the collection system manages:
- Loan & invoice tracking — list loans, payment plans, and monthly invoices
- Payment generation — PIX QR Codes and Boletos for invoice or installment payment
- Batch payments — pay multiple invoices at once with automatic discount
- Balance & settlement — outstanding balance and early settlement calculation
- Renegotiation — simulate and create renegotiation for overdue installments
- Webhooks — receive notifications when installment or invoice statuses change
Invoice vs Payment Plan
This is one of the most common questions from integration partners. Understanding the difference is essential.
A Payment Plan and an Invoice serve different purposes:
| Payment Plan | Invoice (Fatura) | |
|---|---|---|
| Scope | One loan only | All loans of a customer |
| Created when | Loan is disbursed (FUNDED) | Monthly, automatically |
| Contains | All installments of that specific loan | Installments from all loans due in the same month |
| Used for | Tracking repayment of a single purchase | Generating a single monthly payment for the customer |
| Analogy | Individual purchase receipt | Credit card monthly statement |
Visual example:
Customer bought 2 items on BNPL:
Loan A: Sneakers (4x R$100)
└── Payment Plan A
├── Installment A1 (Feb) ✅ PAID
├── Installment A2 (Mar) ◄──────────┐
├── Installment A3 (Apr) │ grouped into
└── Installment A4 (May) │
│
Loan B: Headphones (3x R$150) │
└── Payment Plan B │
├── Installment B1 (Mar) ◄──────────┤
├── Installment B2 (Apr) │
└── Installment B3 (May) │
▼
┌─────────────────────┐
│ March Invoice │
│ R$ 100 + R$ 150 │
│ = R$ 250 total │
│ Due: March 15 │
│ (single PIX/Boleto) │
└─────────────────────┘
The customer pays one invoice per month (R$ 250) instead of paying each loan separately.
Collection Endpoints
Loans
| Endpoint | Method | Description |
|---|---|---|
/person/{person_id}/loans | GET | List loans with nested payment plans and installments |
Invoices
| Endpoint | Method | Description |
|---|---|---|
/invoices | GET | List invoices (filterable by status, period) |
/invoices/{invoice_id} | GET | Get invoice details with breakdown by loan |
/invoices/{invoice_id}/payment-method | POST | Generate PIX or Boleto for an invoice |
/invoices/batch-payment | POST | Pay invoices in batch with automatic discount |
Payment Plans & Installments
| Endpoint | Method | Description |
|---|---|---|
/payment-plans | GET | List payment plans for a customer |
/installments | GET | List installments for a payment plan |
Charges & Balance
| Endpoint | Method | Description |
|---|---|---|
/charging | POST | Create charge (PIX or Boleto) for specific installments |
/application/{id}/outstanding-balance | GET | Get outstanding balance with early settlement calculation |
Renegotiation
| Endpoint | Method | Description |
|---|---|---|
/renegotiation/simulate | POST | Simulate renegotiation options (discount, new terms) |
/renegotiation | POST | Create renegotiation |
/renegotiation/{renegotiation_id} | GET | Get renegotiation details |
Webhooks
All webhook endpoints are in the Webhook section of the API Reference.
| Endpoint | Method | Description |
|---|---|---|
/webhooks/payment | POST | Payment confirmation from payment provider |
/webhooks/installment-status | POST | Installment status change notification (from QI Tech) |
/webhooks/invoice-status | POST | Invoice status change notification |
/webhooks/application-status | POST | Application status change notification |
/webhooks/refund-status | POST | Refund status change notification |
Collection Modes
The system supports two collection modes:
Invoice Mode (Recommended)
Loans are grouped into monthly invoices (faturas), similar to a credit card statement. The customer receives a single invoice per month containing all installments due in that period.
Customer has 3 active loans:
Loan A: 4x R$ 100 (installments due on the 15th)
Loan B: 3x R$ 150 (installments due on the 15th)
Loan C: 6x R$ 50 (installments due on the 15th)
March Invoice:
├── Loan A — Installment 2/4: R$ 100.00
├── Loan B — Installment 1/3: R$ 150.00
└── Loan C — Installment 3/6: R$ 50.00
────────────────────────────────────────
Total: R$ 300.00 | Due: March 15
Flow:
GET /invoices?person_id={id}&status=OPEN— list open invoicesGET /invoices/{invoice_id}— show invoice detail with per-loan breakdownPOST /invoices/{invoice_id}/payment-methodwith{"payment_method": "PIX"}— generate PIX QR Code- Customer pays → webhook notifies → invoice status updates
Standalone Mode
Each loan is serviced individually. Installments are charged separately per loan using the /charging endpoint.
Flow:
GET /payment-plans?person_id={id}— list active payment plansGET /installments?payment_plan_id={id}— list installmentsPOST /charging— generate PIX or Boleto for specific installments- Customer pays →
POST /webhooks/payment→ installment status updates
Main Flow: Invoice Payment
┌──────────────────┐
│ Customer │
│ opens app │
└────────┬─────────┘
│
│ 1. List active loans
▼
┌──────────────────────────────┐
│ GET /person/{id}/loans │
│ Returns loans + payment │
│ plans + installments │
└────────┬─────────────────────┘
│
│ 2. List open invoices
▼
┌──────────────────────────────┐
│ GET /invoices │
│ ?person_id={id}&status=OPEN │
│ Returns monthly invoices │
└────────┬─────────────────────┘
│
│ 3. Customer selects invoice
▼
┌──────────────────────────────┐
│ GET /invoices/{id} │
│ Detail with per-loan │
│ breakdown of items │
└────────┬─────────────────────┘
│
│ 4. Generate payment
▼
┌──────────────────────────────┐
│ POST /invoices/{id}/ │
│ payment-method │
│ {"payment_method": "PIX"} │
│ │
│ Returns: │
│ • pix_qr_code │
│ • pix_qr_code_base64 │
│ • pix_copy_paste │
│ • expires_at │
└────────┬─────────────────────┘
│
│ 5. Customer pays via PIX
▼
┌──────────────────────────────┐
│ Payment Provider confirms │
│ │
│ POST /webhooks/payment │
│ POST /webhooks/ │
│ installment-status │
│ POST /webhooks/ │
│ invoice-status │
└────────┬─────────────────────┘
│
▼
┌──────────────────────────────┐
│ Invoice status → PAID │
│ Installments → PAID │
│ Payment plan updated │
└──────────────────────────────┘
Batch Payment Flow
Customers can pay multiple invoices at once with an automatic early-payment discount.
┌──────────────────────────────┐
│ GET /invoices │
│ ?person_id={id} │
│ Returns: 3 open invoices │
│ • March: R$ 300.00 │
│ • April: R$ 300.00 │
│ • May: R$ 250.00 │
└────────┬─────────────────────┘
│
│ Customer selects all 3
▼
┌──────────────────────────────┐
│ POST /invoices/batch-payment │
│ │
│ Request: │
│ invoice_ids: [mar, apr, may]│
│ payment_method: PIX │
│ │
│ Response: │
│ original_amount: R$ 850.00 │
│ discount_amount: R$ 25.50 │
│ final_amount: R$ 824.50 │
│ pix_qr_code: "..." │
└──────────────────────────────┘
Overdue Payment Flow
When installments become overdue, the system applies two phases: a grace period (OVERDUE_GRACE) where the BNPL limit is zeroed but no fines apply, followed by a penalty period (OVERDUE_PENALTY) where fines (multa, max 2%) and daily late interest (juros mora, max 1%/month) are applied.
┌──────────────────────────────┐
│ Installment past due date │
│ │
│ Webhook received: │
│ POST /webhooks/ │
│ installment-status │
│ new_status: OVERDUE_GRACE │
│ (BNPL limit zeroed, no fine) │
└────────┬─────────────────────┘
│
│ Grace period expires
▼
┌──────────────────────────────┐
│ POST /webhooks/ │
│ installment-status │
│ new_status: OVERDUE_PENALTY │
│ │
│ Invoice also updates: │
│ POST /webhooks/invoice-status│
│ new_status: OVERDUE_PENALTY │
│ │
│ fine_amount: 2% of overdue │
│ interest: 0.033%/day │
└────────┬─────────────────────┘
│
│ Check outstanding balance
▼
┌──────────────────────────────┐
│ GET /application/{id}/ │
│ outstanding-balance │
│ │
│ Returns: │
│ outstanding_balance: 285.48 │
│ remaining_principal: 278.48 │
│ fine_amount: 2.00 │
│ late_interest: 5.00 │
│ early_settlement: 270.00 │
│ pending_installments: 2 │
└────────┬─────────────────────┘
│
│ Option A: Pay overdue invoice directly
│ Option B: Renegotiate
▼
┌──────────────────────────────┐
│ POST /renegotiation/simulate │
│ │
│ Returns options: │
│ Opt 1: Pay now, 15% off │
│ → R$ 242.66 │
│ Opt 2: Split 2x, 5% off │
│ → 2x R$ 135.60 │
└────────┬─────────────────────┘
│
│ Customer selects option
▼
┌──────────────────────────────┐
│ POST /renegotiation │
│ │
│ Returns: │
│ renegotiation_id │
│ final_amount │
│ pix_qr_code (for payment) │
│ status: PENDING_PAYMENT │
└────────┬─────────────────────┘
│
│ Customer pays → status: PAID
▼
┌──────────────────────────────┐
│ GET /renegotiation/{id} │
│ status: PAID │
│ │
│ Original installments │
│ are settled automatically │
└──────────────────────────────┘
Outstanding Balance & Early Settlement
For customers wanting to pay off their loan early (liquidacao antecipada):
GET /application/{id}/outstanding-balance?calculation_date=2026-03-15
Response:
{
"application_id": "6ffd813a-1e88-4a4a-a892-758ca310e607",
"calculation_date": "2026-03-15",
"remaining_principal": 278.48,
"remaining_interest": 5.00,
"fine_amount": 0,
"late_interest": 0,
"outstanding_balance": 283.48,
"pending_installments": 3,
"early_settlement_amount": 270.00,
"early_settlement_discount": 13.48
}The early_settlement_amount reflects the discounted value for paying off the entire loan before the original term.
Installment Statuses
Installment statuses are aligned with QI Tech's payment infrastructure:
| Status | Description |
|---|---|
PENDING | Awaiting payment, not yet due |
WAITING_PAYMENT | Payment initiated but not yet confirmed by the financial institution |
PAID | Paid on time and in full |
PAID_EARLY | Paid before the due date (may qualify for discount) |
PAID_PARTIAL | Partially paid on or before due date |
OVERDUE_GRACE | Past due date without payment; BNPL limit is zeroed but no fines or interest applied yet |
OVERDUE_PENALTY | Past due date beyond the grace period; fines and interest accrue daily |
PAID_OVERDUE | Paid in full after due date (includes fine and late interest) |
PAID_PARTIAL_OVERDUE | Partially paid after due date |
Common transitions:
PENDING→PAID(normal on-time payment)PENDING→OVERDUE_GRACE(missed due date, no fines yet, BNPL limit zeroed)OVERDUE_GRACE→OVERDUE_PENALTY(grace period expired, fines and interest apply)OVERDUE_GRACE→PAID(payment received during grace period, no fines)PENDING→PAID_EARLY(paid before due date)OVERDUE_PENALTY→PAID_OVERDUE(late payment with fine/interest)
Invoice Statuses
| Status | Description |
|---|---|
OPEN | Invoice is open and accepting payments within the billing period |
CLOSED | Billing period ended; invoice is finalized and awaiting payment |
PAID | Invoice fully paid |
PARTIALLY_PAID | Partial payment received; remaining balance is due |
OVERDUE_GRACE | Past due date; BNPL limit is zeroed but no fines or interest applied yet |
OVERDUE_PENALTY | Past due date beyond the grace period; fines and interest are being applied |
Webhook Events
The system sends/receives five types of webhook notifications:
Payment Webhook (POST /webhooks/payment)
POST /webhooks/payment)Called by the payment provider (QI Tech) when a PIX or Boleto payment is confirmed.
{
"person_id": "ff0024e6-d11e-4700-b7f3-b3d201624e62",
"installment_id": "inst-002",
"amount": 139.24,
"payment_method": "PIX",
"external_payment_id": "pay-ext-12345",
"payment_date": "2026-03-13"
}Installment Status Webhook (POST /webhooks/installment-status)
POST /webhooks/installment-status)Called by QI Tech when an installment status changes (e.g., PENDING → OVERDUE_GRACE).
{
"person_id": "ff0024e6-d11e-4700-b7f3-b3d201624e62",
"webhook_type": "installment.status_change",
"installment_id": "inst-002",
"previous_status": "PENDING",
"new_status": "OVERDUE_GRACE",
"event_datetime": "2026-03-14T00:00:01Z",
"data": {
"amount": 139.24,
"paid_amount": 0,
"due_date": "2026-03-13",
"fine_amount": 0,
"interest_amount": 0
}
}Invoice Status Webhook (POST /webhooks/invoice-status)
POST /webhooks/invoice-status)Triggered when an invoice transitions between states.
{
"person_id": "ff0024e6-d11e-4700-b7f3-b3d201624e62",
"webhook_type": "invoice.status_change",
"invoice_id": "inv-2026-03-001",
"previous_status": "OPEN",
"new_status": "PAID",
"event_datetime": "2026-03-13T14:30:00Z",
"data": {
"total_amount": 278.48,
"paid_amount": 278.48,
"due_date": "2026-03-15",
"payment_method": "PIX"
}
}Application Status Webhook (POST /webhooks/application-status)
POST /webhooks/application-status)Triggered when an application transitions between states (e.g., SUBMITTED_TO_FI → FUNDED). Useful for tracking application progress when a create or charge request times out.
{
"person_id": "ff0024e6-d11e-4700-b7f3-b3d201624e62",
"webhook_type": "application.status_change",
"application_id": "6ffd813a-1e88-4a4a-a892-758ca310e607",
"previous_status": "SUBMITTED_TO_FI",
"new_status": "FUNDED",
"event_datetime": "2026-01-20T12:00:00Z"
}Refund Status Webhook (POST /webhooks/refund-status)
POST /webhooks/refund-status)Triggered when a refund transitions between states. Includes a reason field when status is ACTION_REQUIRED, indicating the partner needs to collect corrected data from the customer.
{
"person_id": "ff0024e6-d11e-4700-b7f3-b3d201624e62",
"webhook_type": "refund.status_change",
"application_id": "6ffd813a-1e88-4a4a-a892-758ca310e607",
"refund_id": "9abc1234-def5-6789-abcd-ef0123456789",
"partner_reference_id": "partner-refund-001",
"previous_status": "PENDING",
"new_status": "ACTION_REQUIRED",
"event_datetime": "2026-01-22T11:00:00Z",
"data": {
"refund_amount": 0,
"refund_type": "FULL",
"offset_amount": 500,
"reason": "INVALID_PIX_KEY"
}
}Integration with QI Tech
The collection system integrates with QI Tech's banking infrastructure:
| QI Tech API | Used For |
|---|---|
| Debt Simulation | Calculate installment schedules, interest, IOF |
| Payment Generation | Create PIX QR Codes and Boletos |
| Payment Notification | Webhook callbacks when payments are confirmed |
| Installment Management | Track installment statuses, calculate fines and late interest |
References:
Error Handling
| Error Code | Description | Resolution |
|---|---|---|
PERSON_NOT_FOUND | Customer not found | Verify person_id |
INVOICE_NOT_FOUND | Invoice doesn't exist | Verify invoice_id |
INVOICE_ALREADY_PAID | Invoice is already fully paid | No action needed |
PAYMENT_PLAN_NOT_FOUND | Payment plan doesn't exist | Verify payment_plan_id |
INSTALLMENT_NOT_FOUND | Installment doesn't exist | Verify installment_id |
INVALID_INSTALLMENT_STATE | Installment in invalid state for this operation | Check current status first |
RENEGOTIATION_NOT_ELIGIBLE | Installments not eligible for renegotiation | Only overdue installments can be renegotiated |
DUPLICATE_PAYMENT | Payment already processed | Idempotency — safe to ignore |
Example error response:
{
"error": "INVALID_INSTALLMENT_STATE",
"message": "One or more installments are already paid",
"timestamp": "2026-01-21T10:00:00Z"
}Updated 3 months ago
