المدفوعات
يسجّل POST /v1/payments المبلغ الذي دفعه العميل ويصدر سند القبض في طلب واحد. لا توجد مرحلة مسودة، والدفعة بعد إصدارها لا تُلغى، وإرجاع المال للعميل يكون بإشعار دائن.
الحقول المطلوبة
كل طلب يرسل customerId و branchId و paymentMethodId و amount. وقيمة amount أكبر من 0 وبمنزلتين عشريتين على الأكثر.
يمثّل branchId الفرع الذي استلم المبلغ. وتُرحّل طريقة الدفع إلى الخزينة المحددة لهذا الفرع، أو إلى خزينتها الافتراضية إذا لم يكن للفرع خزينة محددة. وإذا كانت هذه الخزينة تخدم فرعاً آخر فقط، فستُسجَّل الدفعة في ذلك الفرع، لذلك يُرفض الطلب بـ 422 payment_method_not_in_branch.
أما date فاختياري، وإذا لم يُرسل يُستخدم تاريخ اليوم بتوقيت السعودية. ويُقبل التاريخ السابق ما لم يكن التاجر قد أقفل تلك الفترة المحاسبية (422 period_locked)، أو كان قبل تاريخ فاتورة تسددها الدفعة (400 invalid_parameter على date).
ويقبل notes حتى 500 حرف، و referenceId حتى 100 حرف.
التخصيص على الفواتير
يحدد allocations الفواتير التي تسددها الدفعة، بحد أقصى 100 فاتورة:
{
"customerId": "3f1c2a6e-8b4d-4e2a-9c1f-5d7e8a9b0c12",
"branchId": "9a0b1c2d-3e4f-4a5b-8c6d-7e8f9a0b1c2d",
"paymentMethodId": "5e6f7a8b-9c0d-4e1f-a2b3-c4d5e6f7a8b9",
"amount": 150,
"allocations": [{ "invoiceId": "b1c2d3e4-f5a6-4b7c-8d9e-0f1a2b3c4d5e", "amount": 115 }]
}
| القاعدة | الخطأ |
|---|---|
مجموع المبالغ المخصصة لا يزيد على amount | 400 invalid_parameter على allocations |
| الفاتورة لا تتكرر | 400 invalid_parameter على allocations[i].invoiceId |
| الفاتورة موجودة، وهي فاتورة مبيعات صادرة لهذا العميل، وفي فرع يملك مفتاحك صلاحية عليه | 422 invoice_not_payable على allocations[i].invoiceId |
قيمة date للدفعة ليست قبل تاريخ الفاتورة | 400 invalid_parameter على date |
| المبلغ لا يزيد على المتبقي على الفاتورة | 422 allocation_exceeds_due على allocations[i].amount |
ما يتبقى بعد التخصيص، أو المبلغ كله إذا لم ترسل allocations، يبقى رصيداً دائناً للعميل، ويظهر في الرد في unallocatedAmount. وبعد الطلب تشمل قيمتا amountPaid و amountDue في GET /v1/sales-invoices/{id} المبلغ المخصص.
المفتاح المحدود ببعض الفروع لا يخصص الدفعة إلا لفواتير صادرة في هذه الفروع. والفاتورة من أي فرع آخر يرجع لها 422 invoice_not_payable، تماماً مثل معرّف فاتورة غير موجود، فلا يعرف المفتاح عنها أي شيء.
ولسداد فاتورة من فرع آخر، سجّل الدفعة بمفتاح يملك صلاحية على ذلك الفرع.
حالات رفض أخرى
| الخطأ | متى يرجع |
|---|---|
422 referenced_resource_not_found | العميل أو الفرع أو طريقة الدفع غير موجود، أو طريقة الدفع معطّلة، ويحدد param الحقل |
422 customer_inactive | العميل معطّل |
422 payment_method_not_in_branch | خزينة طريقة الدفع تخدم فرعاً آخر |
409 invoice_busy على allocations[i].invoiceId | طلب آخر على هذه الفاتورة استمر أكثر من 30 ثانية، فأعد إرسال الطلب |
409 invoice_busy بدون param | تسجيل دفعات أخرى استمر أكثر من 30 ثانية، فأعد إرسال الطلب |
409 reference_id_taken | قيمة referenceId مستخدمة لدفعة أخرى، ويحمل existingId معرّفها إذا كان مفتاحك يملك صلاحية قراءتها |
422 payment_not_recorded | رفضتها قاعدة ليس لها كود خاص، والرسالة توضح القاعدة |
الدفعة المرفوضة لا يُسجَّل منها أي شيء.
قراءة المدفوعات
يعرض GET /v1/payments كل دفعة صادرة في فروع المفتاح، أياً كانت القناة التي سجّلتها، ويوضح createdVia القناة. ويمكن التصفية بـ customerId و branchId و invoiceId و referenceId و dateFrom و dateTo، ويرجع invoiceId الدفعات التي خُصص منها مبلغ لتلك الفاتورة.
وتشمل القائمة الدفعة المسجّلة مع البيع (POST /v1/sales-invoices مع payment) لعميل من نوع شركة. أما البيع لعميل فرد مدفوعاً عند الإصدار فيبقى المبلغ فيه على الفاتورة نفسها، ويظهر في amountPaid، ولا تُنشأ له دفعة.
والدفعة المسجّلة من لوحة التحكم قد تحمل خصم سداد، وهو جزء من الدين تنازل عنه التاجر إضافة إلى المبلغ المدفوع. ويظهر في الرد في discount، ويمكن أن يصل مجموع التخصيص فيها إلى amount مع discount. وقيمة unallocatedAmount هي amount مع discount مطروحاً منها التخصيص. أما الدفعة المسجّلة عن طريق الـ API فقيمة discount فيها دائماً 0.
والدفعة المسجّلة بدون فرع تكون قيمة branchId فيها null، ولا يراها إلا مفتاح يملك صلاحية على كل الفروع.