Skip to content

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

FieldTypeDescription
idintegerPrimary key
company_idintegerOwning company (from authenticated user)
from_account_idintegerSource GL account (credited)
to_account_idintegerDestination GL account (debited)
amountdecimal(12,3)Transfer amount (min 0.001)
currency_idinteger?Currency of the transfer
datedateTransfer date
descriptionstringDescription (English)
description_arstring?Description (Arabic)
referencestring?External reference number
journal_entry_idintegerAuto-generated journal entry
created_byintegerUser who created the transfer
created_atdatetimeCreation timestamp
updated_atdatetimeLast update timestamp

Relationships

API Endpoints

MethodPathDescription
GET/api/accounting/transfersList account transfers (paginated)
POST/api/accounting/transfersCreate 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

RuleDescription
Cash accounts onlyBoth 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 accountsfrom_account_id and to_account_id must be different
Positive amountAmount must be at least 0.001
Date requiredEvery transfer must have a date
Description requiredEnglish description is mandatory; Arabic is optional
Auto journal entryA journal entry is created automatically: debit destination, credit source
ImmutableTransfers cannot be edited or deleted after creation
Company scopedTransfers 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:

LineAccountDebitCredit
1Destination (to_account_id)5,000.000--
2Source (from_account_id)--5,000.000

The journal entry is created in posted status, so it immediately affects account balances.

Moon ERP API Documentation