Skip to main content

Payments API

Manage incoming and outgoing payments, including links to clients and installment groups.

Base URL: /api/payments

Authentication & Authorization

All endpoints require a valid session cookie (token). Role-based authorization is enforced server-side.

RoleGET /POST /PUT /:idDELETE /:id
super-admin
admin
finance
agent
client❌*

*Although the router lists client for GET /, the implementation explicitly returns 401 for clients. Treat it as not allowed.

Data Model

Payment (list shape)

Fields returned by GET / (joined across related tables):

{
"id": 123,
"accountType": "Bank",
"serviceType": "installment_payment", // or other service types
"amount": 15000.0,
"paymentType": "income" /* or "expense" */,
"description": "Payment for installment XYZ",
"clientId": 45,
"clientName": "John Smith",
"paymentDate": "2024-07-01T00:00:00.000Z",
"createdBy": "Jane Admin",
"company": "Acme Properties",
"status": "pending" /* "approved" | "declined" */,
"installmentGroupId": 987,
"installmentGroupName": "Project ABC",
"attachments": [
{ "attachment": "/path/or/url/file.pdf", "title": "Receipt" }
],
"assignedAgents": [
{ "agentId": 12 }, { "agentId": 34 }
]
}

Notes

  • The list endpoint includes attachments (from installments_attachments) and assignedAgents (from clients_agents).
  • Results are ordered by paymentDate descending.

Status semantics

  • pending: awaiting approval; when created for installment_payment, a notification is broadcast to super-admin users.
  • approved: accepted.
  • declined: if set by PUT /:id, the record is deleted (see update behavior).

Endpoints

GET /

List payments with optional filters.

Auth: admin, finance, agent, super-admin (clients receive 401).

Query Parameters

NameTypeRequiredDescription
querystringnoSubstring match on accountType.
companynumbernoCompany ID to restrict results. If omitted and caller is not super-admin, results are implicitly scoped to the caller’s allowed companies.
clientnumbernoFilter by clientId.
accountTypestringnoExact match on accountType.
statusenum(pending,declined,approved)noFilter by payment status.

Response — 200

[
{
"id": 1,
"accountType": "Bank",
"serviceType": "installment_payment",
"amount": 25000,
"paymentType": "income",
"description": "Payment for installment Project A",
"clientId": 5,
"clientName": "Client Name",
"paymentDate": "2024-06-20T00:00:00.000Z",
"createdBy": "Admin User",
"company": "Company X",
"status": "approved",
"installmentGroupId": 101,
"installmentGroupName": "Project A",
"attachments": [ { "attachment": "https://.../receipt.pdf", "title": "Receipt" } ],
"assignedAgents": [ { "agentId": 12 } ]
}
]

Errors

  • 401 when the caller is a client.

POST /

Create a payment. Special handling exists for serviceType = "installment_payment".

Auth: admin, finance, agent (clients receive 401).

Body

{
"accountType": "Bank", // required
"serviceType": "installment_payment", // required
"amount": 15000, // required (number)
"paymentType": "income", // required: "income" | "expense"
"description": "Optional text", // optional; if missing for installment payments, a default description is generated
"clientId": 45, // optional, recommended for client-linked payments
"paymentDate": "2024-07-01", // required; parsed into Date
"company": 3, // required (number)
"installmentGroupId": 987, // required when serviceType = "installment_payment"
"status": "pending", // optional; if "pending" for installment payments, triggers super-admin notification
"associatedEntity": "string-or-null" // optional; affects delete permissions
}

Behavior for serviceType = "installment_payment"

  • Validates installmentGroupId and resolves its project; returns 404 if not found.
  • If status is pending, sends a notification to super-admins containing amount, project, and creator name.
  • Returns 201 with { message, newPayment } (where newPayment is the DB-returned identifier object).

Behavior for other service types

  • Creates a standard payment record and returns 201 { message }.

Errors

  • 401 when the caller is a client.
  • 400 if installmentGroupId is missing for installment payments.
  • 404 if the referenced installment group does not exist.
  • 500 on server/database errors.

Example

curl -X POST \
-H 'Content-Type: application/json' \
--cookie "token=..." \
-d '{
"accountType": "Bank",
"serviceType": "installment_payment",
"amount": 15000,
"paymentType": "income",
"clientId": 45,
"paymentDate": "2025-01-15",
"company": 3,
"installmentGroupId": 987,
"status": "pending"
}' \
https://your.api/api/payments

PUT /:id

Update a payment. Setting status to declined deletes the record instead of updating it.

Auth: admin, finance, super-admin

Body (any subset)

{
"accountType": "Bank",
"serviceType": "installment_payment",
"amount": 20000,
"paymentType": "income",
"description": "Reworded description",
"clientId": 45,
"paymentDate": "2025-02-01",
"status": "approved" // or "declined" (which deletes)
}

Responses

  • 200 { message: "Payments updated successfully" } when updated normally.
  • If status = "declined": 200 { message: "Payments deleted successfully" } and the record is removed.
  • 404 if the payment does not exist.

Errors

  • 500 on server/database errors.

DELETE /:id

Delete a payment.

Auth: admin, finance, super-admin

Delete rules

  • If associatedEntity is falsy on the payment and the caller is not super-admin, the server responds:
    • 400 { message: "Cannot delete as it belongs to another entity" }
  • Otherwise, the record is deleted.

Responses

  • 200 { message: "Payments deleted successfully" }
  • 404 if the payment does not exist.

Errors

  • 500 on server/database errors.

Notes & Caveats

  • Clients cannot list payments even though the router includes client for GET /. The controller blocks it with a 401.
  • The list endpoint joins related data to return attachments and assignedAgents arrays per payment.
  • There is an internal getPaymentsById controller not currently wired in the router; if exposed, it would return a single raw payment row by ID.

Error Model

Standard JSON error payloads:

{ "message": "..." }

HTTP statuses used: 200, 201, 400, 401, 404, 500.

Changelog

  • v1.0: Initial documentation for Payments API (GET list, POST create, PUT update/delete-on-decline, DELETE with associatedEntity rule).