Skip to content

Payment Requests

Self-service payment request system where administrators submit outgoing payment requests linked to fiscal invoices, and the finance team reviews, approves, schedules, and tracks payments through a defined lifecycle — integrated with Zoho Books for invoice management and automatic payment status synchronization.

Overview

The Payment Requests module allows any authorized administrator to create payment requests (optionally linked to existing invoices), which then go through an approval workflow managed by the finance team. Requests can be linked to invoices from the Zoho invoicing system, or created manually with tax configuration. The module supports multi-country tax handling via dynamic tax options per Zoho organization.

Key Concepts

ConceptDescription
Payment requestA record requesting an outgoing payment to a provider, with optional invoice linkage, classification, and banking data
Request statusLifecycle state: pending, approved, rejected, programmed, paid, cancelled
Invoice linkageRequests can be linked to existing zoho_invoices records by UUID search, auto-filling provider and amount data
Payment classificationAccounting account from zoho_accounts tree, used to classify the expense in Zoho Books
Tax configurationDynamic tax options per Zoho organization via zoho_organization_taxes table, used when programming requests without a linked invoice
Provider bankingApproved providers show read-only bank data; unapproved providers require bank, CLABE, and supporting documents
Auto-paidAutomatic status transition to paid when the linked invoice is paid via STP or marked as paid manually
Slack notificationsDM to creator on status changes (approve, reject, program, pay); channel alert when a user corrects/resubmits a request

Data Flow

Main Flow: Create and Submit Payment Request

Flow: Approval and Programming

Flow: Automatic Payment Sync

Backend Structure

Route File

backend/routes/
└── finances.routes.js          # Payment request routes under /finances/payment-requests

Controller and Library

  • Controller: backend/controllers/finances.controller.js — HTTP handlers delegating to the payment requests utility.
  • Library: backend/libraries/payment-requests.util.js — Business logic for CRUD, status transitions, invoice creation, tax options, provider search, Slack notifications.
  • Constants: backend/constants/finances.constants.js — Status enum, transition map, event types, Slack channel.

Integration Points

  • backend/jobs/zoho-payments.jobs.js — Calls syncPaymentRequestStatus after STP payment completion.
  • backend/libraries/zoho.util.js — Calls syncPaymentRequestStatus in markAsPaid().
  • backend/jobs/zoho.jobs.jsprocessZohoBill uses override_account_id from linked payment requests.

Permissions

Permission nameUse
menu-payment-requestsAccess own requests (create, view, delete pending, resubmit rejected)
payment-requests-manageFinance team — manage all requests (approve, reject, program, cancel, edit)

Database

Tables

TablePurpose
payment_requestsRequest data: provider, amount, invoice linkage, status, banking, file URLs, audit fields
payment_request_eventsFull event history: status changes, edits, invoice linking, PDF uploads
zoho_organization_taxesTax options per Zoho organization (rate, code, type, zoho_tax_id)
zoho_invoicesLinked invoices (existing table)
zoho_invoice_issuersProvider/issuer data with bank details (existing table)
zoho_invoice_receiversReceiver/organization data (existing table)
zoho_accountsAccounting classification tree (existing table)

Key Fields (payment_requests)

ColumnDescription
statusOne of: pending, approved, rejected, programmed, paid, cancelled
invoice_idFK to zoho_invoices (nullable — null for manual requests)
receiver_idFK to zoho_invoice_receivers
account_idFK to zoho_accounts (payment classification)
created_byFK to users (request creator)
reviewed_byFK to users (admin who approved/rejected)
programmed_byFK to users (admin who scheduled payment)
payment_dateScheduled payment date (set when programmed)

Key Decisions

DecisionReasoningAlternatives Considered
Single approval levelSimplicity for V1; multi-level approval can be added laterMulti-level approval chain (complexity)
Invoice reclassification on programmingEnsures Zoho Books account matches the payment request classificationManual reclassification (error-prone)
Dynamic tax options from zoho_organization_taxesMulti-country support without hardcoded tax logicHardcoded per-country taxes (not scalable)
Fire-and-forget Slack notificationsStatus transitions are not blocked by notification failuresQueued notifications (more complex)
Scoped visibility (own vs all)Regular admins see only their requests; finance sees everythingSingle permission level (less secure)

Dependencies

  • Internal: Zoho util (invoice sync, vendor lookup), Auth (JWT, permissions), Slack util (notifications), Queue system (Bull for zoho_bill jobs).
  • External: Zoho Books API (invoice creation, reclassification), Slack API (DM and channel notifications), S3 (file storage).

Envia Admin