Payment Requests API
API endpoints for the Payment Requests module. All endpoints require JWT authentication (token_admin) and are prefixed with /finances/payment-requests.
Authentication
All endpoints require a valid admin JWT:
Authorization: Bearer <token>Access is restricted by permission (see Auth column per endpoint).
Endpoints Summary
| Method | Path | Auth | Description |
|---|---|---|---|
| GET | /finances/payment-requests | menu-payment-requests | List requests (scoped visibility) |
| GET | /finances/payment-requests/{id} | menu-payment-requests | Get request detail |
| POST | /finances/payment-requests | menu-payment-requests | Create request |
| PUT | /finances/payment-requests/{id} | menu-payment-requests | Update request |
| DELETE | /finances/payment-requests/{id} | menu-payment-requests | Delete pending request |
| PATCH | /finances/payment-requests/{id}/status | varies | Transition status |
| PATCH | /finances/payment-requests/{id}/invoice | payment-requests-manage | Link invoice |
| GET | /finances/payment-requests/search/invoice | menu-payment-requests | Search invoice by UUID |
| GET | /finances/payment-requests/search/provider | menu-payment-requests | Search provider by RFC |
| GET | /finances/payment-requests/catalog/accounts | menu-payment-requests | Get accounts tree |
| GET | /finances/payment-requests/catalog/banks | menu-payment-requests | Get bank catalog |
| GET | /finances/payment-requests/catalog/tax-options | menu-payment-requests | Get tax options by receiver |
| GET | /finances/payment-requests/{id}/invoice-taxes | menu-payment-requests | Get invoice tax breakdown |
Request Status Values
pending— Awaiting reviewapproved— Approved by financerejected— Rejected by finance (with reason)programmed— Scheduled for payment (with date)paid— Invoice paid (automatic)cancelled— Cancelled
Status Transition Map
| Current | Target | Who | Required Fields |
|---|---|---|---|
| pending | approved | Finance (payment-requests-manage) | — |
| pending | rejected | Finance | rejection_reason |
| pending | cancelled | Creator or Finance | — |
| rejected | pending | Creator (resubmit) | — |
| rejected | cancelled | Creator or Finance | — |
| approved | programmed | Finance | payment_date; items if no linked invoice |
| approved | cancelled | Finance | — |
| programmed | approved | Finance (unprogram) | — |
| programmed | paid | System (automatic) | — |
| programmed | cancelled | Finance | — |
GET /finances/payment-requests
List payment requests with scoped visibility and server-side pagination.
- Users with
menu-payment-requestsonly: returnsWHERE created_by = :userId - Users with
payment-requests-manage: returns all requests
Query Parameters
| Param | Type | Required | Description |
|---|---|---|---|
start | number | No | Pagination offset (default: 0) |
length | number | No | Page size (default: 100) |
sortBy | string | No | Sort column (default: id) |
sortType | string | No | ASC or DESC (default: DESC) |
status | string | No | Filter by status |
search | string | No | Search by provider name or UUID |
startDate | string | No | Created after (YYYY-MM-DD) |
endDate | string | No | Created before (YYYY-MM-DD) |
receiverId | number | No | Filter by receiver |
accountId | number | No | Filter by account |
Response (200)
{
"success": true,
"data": [...],
"recordsTotal": 50,
"recordsFiltered": 25
}GET /finances/payment-requests/{id}
Get a single payment request with full detail including event history.
Response (200)
Includes all request fields, joined names (created_by_name, reviewer, programmer), linked invoice status, issuer approval status, bank data, and full event history array.
Errors
| Code | Description |
|---|---|
| 403 | Not the creator and lacks payment-requests-manage |
| 404 | Payment request not found |
POST /finances/payment-requests
Create a new payment request in pending status.
Payload
| Field | Type | Required | Notes |
|---|---|---|---|
receiver_id | number | Yes | FK to zoho_invoice_receivers |
provider_name | string | Yes | Provider/vendor name |
amount | number | Yes | Positive, max 2 decimals |
signed_form_url | string | Yes | S3 URL for signed form |
invoice_id | number | No | FK to zoho_invoices |
issuer_id | number | No | FK to zoho_invoice_issuers |
provider_rfc | string | No | Tax ID for provider search |
account_id | number | No | FK to zoho_accounts |
city | string | No | Office/city |
department | string | No | Department |
payment_date | string | No | YYYY-MM-DD |
concept | string | No | Description |
currency | string | No | Derived from locale if omitted |
bank_id | number | No | FK to catalog_banks (unapproved providers) |
bank_account | string | No | CLABE (unapproved providers) |
bank_statement_url | string | No | S3 URL (unapproved providers) |
tax_certificate_url | string | No | S3 URL (unapproved providers) |
payment_pdf_url | string | No | S3 URL |
PATCH /finances/payment-requests/{id}/status
Transition a payment request to a new status. See transition map above.
Payload
| Field | Type | Required | Notes |
|---|---|---|---|
status | string | Yes | Target status |
rejection_reason | string | Conditional | Required for rejected |
payment_date | string | Conditional | Required for programmed (YYYY-MM-DD) |
items | array | Conditional | Required for programmed when no linked invoice |
The items array contains tax breakdown for manual invoice creation:
{
"items": [{
"name": "Service description",
"quantity": 1,
"unitAmount": 12931.03,
"taxes": [{
"tax": "002",
"type": "transfer",
"amount": 2068.97,
"zoho_tax_id": "5528319000000416283",
"factor": { "type": "rate", "amount": 0.16 }
}]
}]
}Side Effects
- approved: Sets
reviewed_by,utc_reviewed_at. Sends Slack DM to creator. - rejected: Sets
reviewed_by,utc_reviewed_at,rejection_reason. Sends Slack DM to creator with reason. - programmed: Sets
programmed_by,utc_programmed_at,payment_date. Creates invoice if none linked. Reclassifies existing invoice account. Sends Slack DM to creator with date. - cancelled: No additional side effects.
GET /finances/payment-requests/search/invoice
Search for an invoice by UUID. Returns invoice data with issuer/receiver details and checks for existing payment requests.
Query Parameters
| Param | Type | Required |
|---|---|---|
uuid | string | Yes |
Response (200)
{
"success": true,
"found": true,
"data": { "id": 456, "uuid": "...", "receiver_name": "...", ... },
"isPaid": false,
"hasExistingRequest": false,
"existingRequest": null
}GET /finances/payment-requests/catalog/tax-options
Get tax options for a receiver's Zoho organization, grouped by type.
Query Parameters
| Param | Type | Required |
|---|---|---|
receiverId | number | Yes |
Response (200)
Returns transferred, retained, retainedGroups, and transferredGroups arrays from zoho_organization_taxes.
GET /finances/payment-requests/{id}/invoice-taxes
Get tax breakdown from the linked invoice's items. Returns parsed items with numeric fields and a calculated summary.
Common Error Responses
Errors follow the Boom format:
{
"statusCode": 400,
"error": "Bad Request",
"message": "Descriptive error message"
}| Status | When |
|---|---|
| 400 | Validation failed or invalid business rule |
| 401 | Missing or invalid JWT |
| 403 | User lacks required permission |
| 404 | Resource not found |
| 409 | Conflict (e.g., duplicate invoice link) |
