Account Transfers
Account transfers move funds between two accounts (typically bank-to-bank or bank-to-cash) in a single operation. Each transfer automatically generates a balanced journal entry that debits the destination account and credits the source account.
Purpose
- Transfer money between bank accounts, cash accounts, or any combination
- Automatically create an auditable journal entry for every transfer
- Record the transfer date, amount, currency, and a bilingual description
- Maintain a complete history of inter-account movements
Entity Attributes
| Field | Type | Description |
|---|---|---|
id | integer | Primary key |
company_id | integer | Owning company (from authenticated user) |
from_account_id | integer | Source GL account (credited) |
to_account_id | integer | Destination GL account (debited) |
amount | decimal(12,3) | Transfer amount (min 0.001) |
currency_id | integer? | Currency of the transfer |
date | date | Transfer date |
description | string | Description (English) |
description_ar | string? | Description (Arabic) |
reference | string? | External reference number |
journal_entry_id | integer | Auto-generated journal entry |
created_by | integer | User who created the transfer |
created_at | datetime | Creation timestamp |
updated_at | datetime | Last update timestamp |
Relationships
API Endpoints
| Method | Path | Description |
|---|---|---|
GET | /api/accounting/transfers | List account transfers (paginated) |
POST | /api/accounting/transfers | Create a new transfer |
GET | /api/accounting/transfers/{id} | Get a specific transfer |
INFO
Transfers are immutable after creation. There is no PUT or DELETE endpoint. To reverse a transfer, reverse the associated journal entry.
Request/Response Examples
POST /api/accounting/transfers
Create a transfer from one bank account to another.
Request
json
{
"from_account_id": 15,
"to_account_id": 16,
"amount": "5000.000",
"currency_id": 1,
"date": "2026-02-15",
"description": "Transfer to USD account",
"description_ar": "تحويل إلى حساب الدولار",
"reference": "TRF-2026-0042"
}Response 201 Created
json
{
"data": {
"id": 12,
"company_id": 1,
"from_account_id": 15,
"from_account": {
"id": 15,
"code": "1201001",
"name": "NBK Main Account"
},
"to_account_id": 16,
"to_account": {
"id": 16,
"code": "1201002",
"name": "NBK USD Account"
},
"amount": "5000.000",
"currency_id": 1,
"date": "2026-02-15",
"description": "Transfer to USD account",
"description_en": "Transfer to USD account",
"description_ar": "تحويل إلى حساب الدولار",
"reference": "TRF-2026-0042",
"journal_entry_id": 87,
"journal_entry": {
"id": 87,
"entry_number": "JE-2026-0087",
"date": "2026-02-15",
"status": "posted"
},
"created_by": 1,
"created_at": "2026-02-15T10:30:00.000000Z",
"updated_at": "2026-02-15T10:30:00.000000Z"
}
}GET /api/accounting/transfers
Response 200 OK
json
{
"data": [
{
"id": 12,
"from_account_id": 15,
"from_account": {
"id": 15,
"code": "1201001",
"name": "NBK Main Account"
},
"to_account_id": 16,
"to_account": {
"id": 16,
"code": "1201002",
"name": "NBK USD Account"
},
"amount": "5000.000",
"date": "2026-02-15",
"description": "Transfer to USD account",
"reference": "TRF-2026-0042",
"journal_entry_id": 87,
"created_at": "2026-02-15T10:30:00.000000Z"
}
],
"meta": {
"current_page": 1,
"per_page": 25,
"total": 1
}
}Business Rules
| Rule | Description |
|---|---|
| Cash accounts only | Both accounts must be the company's own detail accounts classified as assets (cash & cash equivalents). Header accounts and non-asset accounts — revenue, expense, liability, equity — are rejected with 422 |
| Different accounts | from_account_id and to_account_id must be different |
| Positive amount | Amount must be at least 0.001 |
| Date required | Every transfer must have a date |
| Description required | English description is mandatory; Arabic is optional |
| Auto journal entry | A journal entry is created automatically: debit destination, credit source |
| Immutable | Transfers cannot be edited or deleted after creation |
| Company scoped | Transfers are always filtered by the authenticated user's company |
Generated Journal Entry
When a transfer is created, the system generates a journal entry with exactly two lines:
| Line | Account | Debit | Credit |
|---|---|---|---|
| 1 | Destination (to_account_id) | 5,000.000 | -- |
| 2 | Source (from_account_id) | -- | 5,000.000 |
The journal entry is created in posted status, so it immediately affects account balances.