Create a cheque directly — POST /api/cheque-log/external

One endpoint records an externally printed cheque from your system with no screen and no preview. Its fields with literal rules, the guards that raise 422, the 201 response, and what to know about duplicates and images.

Last updated: 2026-09-21

On this page

When to use it

When your system prints the cheque itself (or does not print at all) and you want a row in the cheque log with its initial status for follow-up in the app. No preview, no printing — to print from the app’s screen use the Dynamics flow.

Route: POST /api/cheque-log/external — alias POST /api/cheque-logs (audited under the first name).

Fields

Field Literal rule Required Default
bank_name required|string|max:255
template_name nullable|string|max:255 null
cheque_type IN or OUT null ⟹ no status
cheque_date · stub_date nullable|date null
recipient_name · place · signed_by · reason · reference_number · stub_name · stub_reason nullable|string|max:255 null
amount_text · note · liner_text nullable|string null
amount nullable|numeric — ≤ 13 integer digits, fraction per currency null
stub_amount nullable|numeric — ≤ 8 digits null
currency nullable|string|max:10 EGP
cheque_number nullable|string|max:50 + unique per bank among printed null
company_id nullable|integer|exists:companies,id the key’s company — if sent and different ⟹ 422
bank_account_id · cheque_book_id · cheque_leaf_id · partner_id nullable|integer|exists null
liner_enabled · two_lines boolean false
image nullable|image|max:200048 (KB)
image_base64 nullable|string
save_cheque_image nullable|boolean false
external_source · external_id nullable|string null — the optional idempotency key

Contract notes:

  • cheque_status_id is silently ignored — the status derives from cheque_type: OUT ⟹ being issued · IN ⟹ in wallet · unknown ⟹ no status (which you don’t want — always send the direction).
  • bank_id is accepted but not read here — the bank resolves from bank_name alone by exact match after trimming; send the name exactly as /api/banks returns it.
  • The image is not stored unless save_cheque_image: true with image_base64/image — and without a watermark.

Guards that raise 422

Case Message (Arabic)
Number belongs to a cheque-book leaf هذا الرقم يخص دفتر شيكات — اطبعه من وضع الدفتر
Number reserved in an open batch الرقم :number محجوز في دفعة مفتوحة (الدفعة #:batch) — اطبعها أو ألغِها أولًا.
Duplicate on the same bank رقم الشيك {N} مستعمَل بالفعل على بنك {البنك} — اختر رقمًا آخر
Amount too large القيمة كبيرة جدًا — لا يزيد الجزء الصحيح عن 13 خانة.
Fraction digits كسر المبلغ يتجاوز خانات {العملة} (خانتان عشريتان).
Reference from another company المستفيد لا يتبع شركة الشيك. · الحساب البنكي المختار لا يتبع شركة الشيك. · دفتر الشيكات المختار … · ورقة الشيك المختار …
Key without a company مفتاح الـAPI غير منسوب لشركة — عيّن شركته من شاشة «التكامل ← مفاتيح API».
company_id contradicts the key الحمولة تطلب شركة «…» بينما مفتاح الـAPI منسوب لشركة «…» — احذف الحقل أو استعمل مفتاح الشركة الصحيحة.

Example

bash
curl -s -X POST "APP_URL/api/cheque-log/external" \
  -H "X-API-KEY: KEY" -H "Content-Type: application/json" -H "Accept: application/json" \
  -d '{
        "bank_name": "بنك مصر",
        "template_name": "بنك مصر - نموذج 1",
        "cheque_type": "OUT",
        "recipient_name": "شركة النيل للتوريدات",
        "amount": 1250.50,
        "currency": "EGP",
        "cheque_date": "2026-10-15",
        "cheque_number": "100200",
        "reference_number": "PV-1001",
        "reason": "دفعة مورّد",
        "signed_by": "خالد عبد الرحمن"
      }'

201:

json
{
  "success": true,
  "message": "تم الحفظ بنجاح",
  "data": { "id": 4321, "bank_name": "بنك مصر", "cheque_number": "100200", "amount": "1250.500", "…": "the full cheque_logs row" },
  "image_saved": false
}

data is the full row (100+ columns, including lifecycle columns that are empty now) — rely on id, cheque_number, bank_name, amount, cheque_date, currency, and do not build on the rest.

Errors

Status Body
422 {"message":"Validation failed","errors":{"cheque_number":["…"]}} — messages in Arabic
500 {"message":"Error saving cheque log","error":"…"}
503 · 401 · 403 · 429 from the key ladder

Stamped server-side

printed_at = now() · printed_by = null · initial status from the direction · and company_id = the key’s company, always. The payload is checked against it: a different company_id, or a reference (account · book · leaf · partner) from another company ⟹ 422. No fallback and no default company on the key path.

The row is confirmed — and idempotency

The row is created printed and confirmed (the paper left outside the app): its number cannot be edited afterwards, like any confirmed cheque, and it enters confirmed reports and reminders — so send the number right the first time.

Three duplicate guards (since 1.8.0):

  1. Cheque number per bank: a second call with the same number ⟹ 422 “already used” — treat it as a prior success in your logic.
  2. External key (optional): send external_source + external_id (as in Dynamics) — a resend returns the existing row with 200 and "reused": true, no new row (Dynamics uses action: "reused" instead).
  3. A row stamped for another company, or a final row (damaged · cancelled · reissued) ⟹ 422 instead of an update.

Recommendation: send both cheque_number and external_id.

اطلب نسختك التجريبية مجانًا