Payment Vouchers
Payment vouchers (سندات الصرف) are multi-line payment documents used for complex payments to business partners. Each voucher can contain multiple lines, each targeting a different GL account, payment method, or check number. When approved, the system automatically creates a balanced journal entry. The print endpoint provides enriched data with company info and amount in words (Arabic and English).
Purpose
- Record multi-line payments to business partners
- Support mixed payment methods within a single voucher (cash, check, bank transfer, card)
- Auto-generate voucher numbers via the sequence service
- Create journal entries automatically on approval
- Reverse journal entries on cancellation
- Provide printable voucher data with amount in words and company letterhead info
- Track cross-references to other documents (invoices, purchase orders, etc.)
Entity Attributes
Payment Voucher (Header)
| Field | Type | Description |
|---|---|---|
id | bigint | Primary key |
company_id | bigint | FK to companies |
branch_id | bigint? | FK to branches |
voucher_number | string | Auto-generated sequence number (e.g., PV-2026-0001) |
date | date | Voucher date |
partner_id | bigint? | FK to business_partners |
total_amount | decimal(12,3) | Total payment amount |
amount_in_words | string? | Amount written in words (stored value) |
payment_method | enum | Primary method: cash, check, bank_transfer, card, mixed |
paying_account_id | bigint? | FK to accounts (primary paying GL account) |
bank_account_id | bigint? | FK to bank_accounts |
check_number | string? | Check number (header level) |
check_date | date? | Check date |
check_bank | string? | Issuing bank name |
description | string? | English description |
description_ar | string? | Arabic description |
reference_type | string? | Related document type (e.g., invoice, purchase_order) |
reference_id | bigint? | Related document ID |
reference_number | string? | Related document number |
cost_center_id | bigint? | FK to cost_centers |
currency_id | bigint? | FK to currencies |
exchange_rate | decimal(12,6)? | Exchange rate if non-base currency |
status | enum | draft, approved, cancelled |
journal_entry_id | bigint? | FK to journal_entries (set on approval) |
created_by | bigint | FK to users |
approved_by | bigint? | FK to users |
approved_at | datetime? | Approval timestamp |
created_at | timestamp | Creation timestamp |
updated_at | timestamp | Last update timestamp |
deleted_at | timestamp? | Soft-delete timestamp |
Payment Voucher Line
| Field | Type | Description |
|---|---|---|
id | bigint | Primary key |
payment_voucher_id | bigint | FK to payment_vouchers |
account_id | bigint? | FK to accounts (expense/debit account) |
partner_account_id | bigint? | FK to accounts (partner's AP account) |
amount | decimal(12,3) | Line amount |
payment_method | enum? | Line-level payment method override |
bank_account_id | bigint? | Line-level bank account |
check_number | string? | Line-level check number |
description | string? | Line description |
Relationships
Lifecycle
API Endpoints
| Method | Path | Description |
|---|---|---|
GET | /api/accounting/payment-vouchers | List payment vouchers (paginated) |
POST | /api/accounting/payment-vouchers | Create a new payment voucher (draft) |
GET | /api/accounting/payment-vouchers/{id} | Get a single payment voucher with lines |
PUT | /api/accounting/payment-vouchers/{id} | Update a payment voucher (draft only) |
DELETE | /api/accounting/payment-vouchers/{id} | Soft-delete a payment voucher (draft only) |
POST | /api/accounting/payment-vouchers/{id}/approve | Approve and create journal entry |
POST | /api/accounting/payment-vouchers/{id}/cancel | Cancel and reverse journal entry |
GET | /api/accounting/payment-vouchers/{id}/print | Get printable voucher data |
Query Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
status | string | No | Filter by status: draft, approved, cancelled |
partner_id | integer | No | Filter by business partner |
branch_id | integer | No | Filter by branch |
date_from | date | No | Filter vouchers on or after this date |
date_to | date | No | Filter vouchers on or before this date |
page | integer | No | Page number (25 per page) |
Request/Response Examples
Create Payment Voucher
Request POST /api/accounting/payment-vouchers
bash
curl -X POST https://moon-erp.test/api/accounting/payment-vouchers \
-H "Authorization: Bearer {token}" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d '{
"date": "2026-02-23",
"partner_id": 5,
"total_amount": "3500.000",
"payment_method": "check",
"paying_account_id": 15,
"bank_account_id": 1,
"check_number": "CHK-00451",
"check_date": "2026-03-01",
"check_bank": "National Bank of Kuwait",
"description": "Supplier payment for Feb invoices",
"description_ar": "دفعة مورد لفواتير فبراير",
"cost_center_id": 2,
"currency_id": 1,
"branch_id": 1,
"lines": [
{
"account_id": 43,
"partner_account_id": 25,
"amount": "2000.000",
"description": "Invoice #INV-2026-0012"
},
{
"account_id": 44,
"partner_account_id": 25,
"amount": "1500.000",
"description": "Invoice #INV-2026-0015"
}
]
}'dart
final response = await http.post(
Uri.parse('https://moon-erp.test/api/accounting/payment-vouchers'),
headers: {
'Authorization': 'Bearer $token',
'Content-Type': 'application/json',
'Accept': 'application/json',
},
body: jsonEncode({
'date': '2026-02-23',
'partner_id': 5,
'total_amount': '3500.000',
'payment_method': 'check',
'paying_account_id': 15,
'bank_account_id': 1,
'check_number': 'CHK-00451',
'check_date': '2026-03-01',
'check_bank': 'National Bank of Kuwait',
'description': 'Supplier payment for Feb invoices',
'description_ar': 'دفعة مورد لفواتير فبراير',
'cost_center_id': 2,
'currency_id': 1,
'branch_id': 1,
'lines': [
{
'account_id': 43,
'partner_account_id': 25,
'amount': '2000.000',
'description': 'Invoice #INV-2026-0012',
},
{
'account_id': 44,
'partner_account_id': 25,
'amount': '1500.000',
'description': 'Invoice #INV-2026-0015',
},
],
}),
);Response 201 Created
json
{
"data": {
"id": 1,
"company_id": 1,
"branch_id": 1,
"voucher_number": "PV-2026-0001",
"date": "2026-02-23",
"partner_id": 5,
"partner": {
"id": 5,
"name": "Al Salam Trading",
"name_ar": "شركة السلام التجارية"
},
"total_amount": "3500.000",
"amount_in_words": null,
"payment_method": "check",
"payment_method_label": "Check",
"paying_account_id": 15,
"paying_account": {
"id": 15,
"code": "1201001",
"name": "NBK Main Account"
},
"bank_account_id": 1,
"check_number": "CHK-00451",
"check_date": "2026-03-01",
"check_bank": "National Bank of Kuwait",
"description": "Supplier payment for Feb invoices",
"description_en": "Supplier payment for Feb invoices",
"description_ar": "دفعة مورد لفواتير فبراير",
"reference_type": null,
"reference_id": null,
"reference_number": null,
"status": "draft",
"status_label": "Draft",
"journal_entry_id": null,
"cost_center_id": 2,
"currency_id": 1,
"exchange_rate": null,
"lines": [
{
"id": 1,
"account_id": 43,
"partner_account_id": 25,
"amount": "2000.000",
"payment_method": null,
"payment_method_label": null,
"bank_account_id": null,
"check_number": null,
"description": "Invoice #INV-2026-0012"
},
{
"id": 2,
"account_id": 44,
"partner_account_id": 25,
"amount": "1500.000",
"payment_method": null,
"payment_method_label": null,
"bank_account_id": null,
"check_number": null,
"description": "Invoice #INV-2026-0015"
}
],
"created_by": 1,
"approved_by": null,
"approved_at": null,
"created_at": "2026-02-23T10:00:00.000000Z",
"updated_at": "2026-02-23T10:00:00.000000Z"
}
}Print Payment Voucher
Request GET /api/accounting/payment-vouchers/1/print
Response 200 OK
json
{
"data": {
"voucher": {
"id": 1,
"voucher_number": "PV-2026-0001",
"date": "2026-02-23",
"partner": { "id": 5, "name": "Al Salam Trading" },
"total_amount": "3500.000",
"payment_method": "check",
"check_number": "CHK-00451",
"check_date": "2026-03-01",
"check_bank": "National Bank of Kuwait",
"status": "approved",
"lines": [
{ "account_id": 43, "amount": "2000.000", "description": "Invoice #INV-2026-0012" },
{ "account_id": 44, "amount": "1500.000", "description": "Invoice #INV-2026-0015" }
]
},
"company": {
"name": "Moon ERP Co.",
"name_ar": "شركة مون",
"address": "Kuwait City, Block 5",
"address_ar": "مدينة الكويت، قطعة 5",
"phone": "+965-12345678",
"email": "info@moonerp.com",
"tax_number": "123456789",
"commercial_register": "CR-2024-001",
"logo": "logo.png"
},
"branch": {
"name": "Main Branch",
"name_ar": "الفرع الرئيسي",
"address": "Kuwait City",
"phone": "+965-12345678"
},
"amount_in_words_en": "Three Thousand Five Hundred Kuwaiti Dinars",
"amount_in_words_ar": "ثلاثة آلاف وخمسمائة دينار كويتي",
"print_date": "2026-02-23",
"printed_by": "Admin"
}
}Generated Journal Entry
When a payment voucher is approved, the system creates a posted journal entry. The debit lines come from the voucher lines, and the credit goes to the paying account.
| Line | Account | Debit | Credit | Description |
|---|---|---|---|---|
| 1 | Line 1 account (e.g., Purchases) | 2,000.000 | -- | Invoice #INV-2026-0012 |
| 2 | Line 2 account (e.g., Services) | 1,500.000 | -- | Invoice #INV-2026-0015 |
| 3 | Paying account (e.g., NBK Main Account) | -- | 3,500.000 | Total payment |
Business Rules
| Rule | Description |
|---|---|
| Draft-only edits | Vouchers can only be updated or deleted while in draft status |
| Auto voucher number | voucher_number is auto-generated via the sequence service on creation |
| Lines replaced on update | When updating with lines, all existing lines are replaced with the new set |
| Approval creates JE | Approving a draft voucher creates a posted journal entry |
| Cancel reverses JE | Cancelling an approved voucher reverses the associated journal entry |
| Multi-line support | Each line can have its own account, amount, payment method, and check number |
| Mixed payments | Set payment_method to mixed when lines use different payment methods |
| Company scoped | All vouchers are filtered by the authenticated user's company |
| Print enrichment | The print endpoint returns company/branch info, amount in words (Arabic/English), and all relationships |
Permissions
| Permission | Description |
|---|---|
accounting.payment-vouchers.view | View payment vouchers and print |
accounting.payment-vouchers.create | Create new payment vouchers |
accounting.payment-vouchers.update | Update draft payment vouchers |
accounting.payment-vouchers.approve | Approve draft payment vouchers |
accounting.payment-vouchers.cancel | Cancel approved payment vouchers |