Configuration and the manual resolution tray for the LiquidaciĂłn de Cisterneros
(driver settlement) module. Paths are relative to the /api/v1 prefix; these are
back-office endpoints requiring a super-admin token.
Requires a super-admin bearer token (see Admin auth). Super-admin only.
See Common errors.
| Method | URI | Access | Description |
|---|---|---|---|
GET |
/admin/settlements/config |
Super admin | Read the settlement config |
PATCH |
/admin/settlements/config |
Super admin | Update the settlement config |
GET |
/admin/settlements/receipts |
Super admin | List receipts of any status |
GET |
/admin/settlements/receipts/{id} |
Super admin | Full detail of one receipt |
GET |
/admin/settlements/tray |
Super admin | List FAILED receipts awaiting manual resolution |
POST |
/admin/settlements/receipts/{id}/retry |
Super admin | Re-disperse a failed receipt (new payout order) |
POST |
/admin/settlements/receipts/{id}/mark-external |
Super admin | Mark a failed receipt paid outside AgĂĽita |
POST |
/admin/settlements/receipts/{id}/annul |
Super admin | Annul a failed receipt and release the reservation |
{
"cutoff_enabled": false,
"cutoff_time": "02:00",
"payout_enabled": false,
"payout_time": "10:00",
"min_balance_usd": 0.5,
"min_balance_cents": 50,
"active_days": [false, true, false, true, false, true, false],
"iva_prc": 16,
"timezone": "-04:00"
}
| Field | Type | Notes |
|---|---|---|
cutoff_enabled |
boolean | Whether the receipt-generation (corte) process is on. |
cutoff_time |
string H:i |
Wall-clock time (in timezone) the corte runs. |
payout_enabled |
boolean | Whether the dispersion (pago) process is on. |
payout_time |
string H:i |
Wall-clock time (in timezone) the pago runs. |
min_balance_usd |
number | Minimum settleable balance, in USD. |
min_balance_cents |
integer | Same minimum, in USD cents. |
active_days |
array[7] boolean | Days both processes run, indexed by weekday 0=Sun … 6=Sat. |
iva_prc |
number | IVA percentage applied to AgĂĽita's commission. |
timezone |
string | UTC offset (±HH:MM) or IANA identifier for the wall-clock times. |
Response 200 — { "config": { … } } (see the config object).
Partial update; every field is optional. Only the sent fields change; unsent fields keep their stored value.
Request body
| Field | Type | Required | Rules |
|---|---|---|---|
cutoff_enabled |
boolean | no | — |
cutoff_time |
string | no | H:i (24h) |
payout_enabled |
boolean | no | — |
payout_time |
string | no | H:i (24h); must be strictly after the effective cutoff_time |
min_balance |
number | no | USD; ≥ 0.5 |
active_days |
array | no | exactly 7 booleans |
active_days.* |
boolean | no | — |
iva_prc |
number | no | 0–100 |
timezone |
string | no | a ±HH:MM UTC offset or a valid IANA identifier |
The payout_time > cutoff_time invariant compares the effective values: a field not sent
uses its current stored value.
Response 200
{
"config": { "…": "see the config object" },
"audit_entry": {
"key": "settlement_config",
"old_values": { "cutoff_enabled": false },
"new_values": { "cutoff_enabled": true },
"created_at": "2026-07-29T19:16:35.000000Z"
}
}
audit_entry records only the fields that changed (previous and new values). A no-op
update (all values equal the stored config) returns "audit_entry": null and writes no
audit row.
Errors
| Status | Body | When |
|---|---|---|
422 |
{ "error": "ValidationError", "details": { "fieldErrors": { "payout_time": ["…"] } } } |
payout_time is not strictly after the effective cutoff_time, or any field fails its rules. |
Page-based list of settlement receipts, any status, newest first.
Query params
| Param | Type | Required | Rules |
|---|---|---|---|
status |
string | no | one of GENERATED, IN_PAYMENT, PAID, FAILED, PAID_EXTERNALLY, VOIDED |
driver_id |
integer | no | — |
fiscal_period |
string | no | — |
date_from |
date | no | filters on issued_at |
date_to |
date | no | filters on issued_at; must be ≥ date_from |
q |
string | no | ≤ 80; matches receipt_number or beneficiary_name |
limit |
integer | no | 1–100 (default 25) |
page |
integer | no | ≥ 1 |
Response 200
{
"items": [
{
"id": 12,
"receipt_number": "2026-0000042",
"driver_id": 5,
"driver_name": "Cisternero Test",
"fiscal_period": "2026-07",
"status": "PAID",
"payout_method": "PAGO_MOVIL",
"net_usd": 85.0,
"payable_usd": 85.0,
"total_paid_bs_cents": 340000,
"bank_reference": "FAKE-REF-13",
"failure_reason": null,
"issued_at": "2026-07-31T10:00:00+00:00",
"paid_at": "2026-07-31T14:05:00+00:00",
"voided_at": null,
"created_at": "2026-07-31T10:00:00+00:00"
}
],
"meta": { "total": 1, "per_page": 25, "current_page": 1, "last_page": 1 }
}
Full detail of one receipt: the breakdown totals (USD via _usd, Bs raw via _bs_cents), the
frozen beneficiary/payout snapshot, its lines, its payout orders (each with its attempts), and
its manual resolution-tray audit trail.
Response 200
{
"receipt": {
"id": 12,
"receipt_number": "2026-0000042",
"driver_id": 5,
"city_id": 1,
"fiscal_period": "2026-07",
"status": "PAID",
"failure_reason": null,
"bank_reference": "FAKE-REF-13",
"cutoff_from": null,
"cutoff_to": "2026-07-31T10:00:00+00:00",
"issued_at": "2026-07-31T10:00:00+00:00",
"subtotal_usd": 100.0,
"discount_usd": 0,
"orders_total_usd": 100.0,
"commission_usd": -15.0,
"net_usd": 85.0,
"payable_usd": 85.0,
"net_bs_cents": 340000,
"total_paid_bs_cents": 340000,
"remuneration_base_usd": 15.0,
"remuneration_usd": 15.0,
"iva_prc": "16.00",
"iva_usd": 2.4,
"remuneration_total_usd": 17.4,
"beneficiary_name": "Cisternero Test",
"beneficiary_id_number": "12345678",
"payout_method": "PAGO_MOVIL",
"payout_account": "+584241234567",
"beneficiary_bank_code": null,
"beneficiary_account_type": null,
"paid_at": "2026-07-31T14:05:00+00:00",
"voided_at": null,
"created_at": "2026-07-31T10:00:00+00:00",
"lines": [
{
"id": 1, "line_number": 1, "type": "ORDER", "order_id": 40,
"order_date": "2026-07-30", "description": "…",
"subtotal_usd": 50.0, "discount_usd": 0, "order_total_usd": 50.0,
"commission_usd": -7.5, "net_usd": 42.5,
"exchange_rate_amount": "40.000", "total_bs_cents": 170000
}
],
"payout_orders": [
{
"id": 13, "idempotency_key": "settlement_payout:12", "method": "PAGO_MOVIL",
"provider": "sypago", "amount_bs_cents": 340000, "status": "CONFIRMED",
"reference": "FAKE-REF-13", "transaction_id": null, "attempt_count": 1,
"last_error": null, "sent_at": "…", "confirmed_at": "…", "failed_at": null,
"attempts": [
{ "attempt_no": 1, "provider_code": "OK", "result": "confirmed", "created_at": "…" }
]
}
],
"receipt_changes": [
{
"action": "retry", "admin_id": 3, "admin_name": "Ada Admin",
"from_status": "FAILED", "to_status": "PAID", "reason": null, "created_at": "…"
}
]
}
}
lines[].type is ORDER for a delivered order or ADJUSTMENT for anything else in
the window: manual wallet adjustments and promotion movements (PROMO_BONUS,
PROMO_REIMBURSEMENT). ADJUSTMENT lines carry order_id: null and
subtotal_usd, order_total_usd and commission_usd at 0, so they never enter
the receipt's commission or IVA base.
Errors
| Status | Body | When |
|---|---|---|
404 |
{ "error": "ReceiptNotFound" } |
No receipt with that id. |
Receipts that dispersion (pago) or reconciliation left in FAILED land here for a
super-admin to resolve. Each action is audited (status transition + reason + admin).
failure_kind classifies why a receipt is FAILED:
failure_kind |
Meaning |
|---|---|
business |
The provider rejected the payment (money confirmed not sent). Safe to retry. |
deadline |
Reconciliation timed out (failure_reason = "reconcile_deadline_exceeded"); the money status is unknown. Retry is blocked — use mark-external or annul. |
Page-based list of FAILED receipts, newest first.
Query params
| Param | Type | Required | Rules |
|---|---|---|---|
failure_kind |
string | no | business or deadline |
limit |
integer | no | 1–100 (default 25) |
page |
integer | no | ≥ 1 |
Response 200
{
"items": [
{
"id": 12,
"receipt_number": "2026-0000042",
"driver_id": 5,
"driver_name": "Cisternero Test",
"payout_method": "PAGO_MOVIL",
"net_usd": 85.0,
"payable_usd": 85.0,
"total_paid_bs_cents": 340000,
"failure_reason": "Cuenta inválida",
"failure_kind": "business",
"provider_code": "RJCT",
"attempts": 1,
"failed_at": "2026-07-31T14:05:00+00:00",
"created_at": "2026-07-31T10:00:00+00:00"
}
],
"meta": { "total": 1, "per_page": 25, "current_page": 1, "last_page": 1 }
}
Fields per item: id, receipt_number, driver_id, driver_name, payout_method
(PAGO_MOVIL|BANK_TRANSFER|null), net_usd, payable_usd, total_paid_bs_cents
(bolĂvares), failure_reason, failure_kind, provider_code (latest attempt, nullable),
attempts (count on the latest order), failed_at (nullable), created_at.
Re-disperse a FAILED receipt. Mints a new payout order (fresh idempotency key); the
old order is never re-opened. No request body.
Response 200
{
"receipt": { "id": 12, "receipt_number": "2026-0000042", "status": "PAID", "bank_reference": "FAKE-REF-13", "failure_reason": null, "paid_at": "…", "voided_at": null },
"order": { "id": 13, "status": "CONFIRMED", "idempotency_key": "settlement_payout:12:r1" },
"audit_entry": { "action": "retry", "from_status": "FAILED", "to_status": "PAID", "reason": null, "created_at": "…" }
}
receipt.status / order.status reflect the dispersion outcome: a synchronous confirm →
PAID / CONFIRMED; an acknowledgement → IN_PAYMENT / SENT.
Errors
| Status | Body | When |
|---|---|---|
404 |
{ "error": "ReceiptNotFound" } |
No receipt with that id. |
409 |
{ "error": "ReceiptNotFailed" } |
The receipt is not in FAILED. |
409 |
{ "error": "RetryUnsafeDeadline" } |
The receipt failed by reconciliation deadline (failure_kind = "deadline"); use mark-external or annul. |
Record that a FAILED receipt was paid to the driver outside AgĂĽita. Settles the wallet and
sets status = PAID_EXTERNALLY with the external reference in bank_reference.
Request body
| Field | Type | Required | Rules |
|---|---|---|---|
reason |
string | yes | ≤ 500 |
reference |
string | yes | ≤ 191 (external payment reference) |
Response 200 — { "receipt": { …, "status": "PAID_EXTERNALLY", "bank_reference": "MANUAL-REF-123" }, "audit_entry": { "action": "mark_external", … } }
Errors
| Status | Body | When |
|---|---|---|
404 |
{ "error": "ReceiptNotFound" } |
No receipt with that id. |
409 |
{ "error": "ReceiptNotFailed" } |
The receipt is not in FAILED. |
422 |
{ "error": "ValidationError", "details": { "fieldErrors": { … } } } |
reason or reference missing/invalid. |
Annul a FAILED receipt: status = VOIDED and the reserved payout is released back to the
driver's withdrawable balance (no money is sent).
Request body
| Field | Type | Required | Rules |
|---|---|---|---|
reason |
string | yes | ≤ 500 |
Response 200 — { "receipt": { …, "status": "VOIDED", "voided_at": "…" }, "audit_entry": { "action": "annul", … } }
Errors
| Status | Body | When |
|---|---|---|
404 |
{ "error": "ReceiptNotFound" } |
No receipt with that id. |
409 |
{ "error": "ReceiptNotFailed" } |
The receipt is not in FAILED. |
422 |
{ "error": "ValidationError", "details": { "fieldErrors": { "reason": ["…"] } } } |
reason missing/invalid. |