الانتقال إلى المحتوى الرئيسي

استرجاع أو تصحيح عملية بيع

فاتورة المبيعات بعد إصدارها لا تتغير ولا تُحذف. ولإرجاع مبلغ للعميل، أو خصمه مما عليه، أو تصحيح خطأ، تصدر عليها إشعاراً دائناً بـ POST /v1/credit-notes. ويحتاج المفتاح الصلاحية credit_notes:write.

الإشعار الدائن يخص بنوداً من فاتورة واحدة، ويأخذ منها الفرع والعميل والأسعار، وترجع البضاعة المشمولة به إلى المخزون. ويذهب المبلغ بإحدى طريقتين:

ما ترسلهإجمالي الإشعار
refund مع paymentMethodIdيُرجع للعميل عن طريق طريقة الدفع هذه
بدون refundيُخصم مما على العميل في الفاتورة، وما يزيد على ذلك يبقى رصيداً دائناً له

قيم number للإشعارات في الأمثلة من تأليفنا، لأن كل تاجر يحدد ترقيمه بنفسه.

ويوضح reason لهيئة الزكاة والضريبة والجمارك سبب الإشعار: cancellation (إلغاء البيع كله أو جزء منه)، أو refund (إرجاع منتجات أو خدمات وإعادة المبلغ)، أو informationChange (تصحيح بيانات خاطئة في الفاتورة).

إرجاع المبلغ لعميل فرد​

العميل الفرد في تسجيل عملية بيع دفع 115 ريالاً لغسلة لم تتم. أصدر إشعاراً على البند وأرجع له المبلغ:

curl https://api.kosoor.com.sa/v1/credit-notes \
-H "Authorization: Bearer ksr_test_..." \
-H "Idempotency-Key: 5c6d7e8f-9a0b-4c1d-8e2f-3a4b5c6d7e8f" \
-H "Content-Type: application/json" \
-d '{
"invoiceId": "b1c2d3e4-f5a6-4b7c-8d9e-0f1a2b3c4d5e",
"reason": "refund",
"lines": [
{ "itemId": "7c8d9e0f-1a2b-4c3d-8e4f-5a6b7c8d9e0f", "quantity": 1 }
],
"refund": { "paymentMethodId": "5e6f7a8b-9c0d-4e1f-a2b3-c4d5e6f7a8b9" },
"notes": "Booking cancelled by the customer",
"referenceId": "refund-20417"
}'

الرد 201 Created:

{
"id": "e4f5a6b7-c8d9-4e0f-9a1b-3c4d5e6f7a8b",
"object": "creditNote",
"number": "CN-0007",
"invoiceId": "b1c2d3e4-f5a6-4b7c-8d9e-0f1a2b3c4d5e",
"customerId": "5a4db0c5-0000-4000-8000-000000000001",
"branchId": "9a0b1c2d-3e4f-4a5b-8c6d-7e8f9a0b1c2d",
"issueDate": "2026-11-08",
"reason": "refund",
"currency": "SAR",
"lines": [
{
"itemId": "7c8d9e0f-1a2b-4c3d-8e4f-5a6b7c8d9e0f",
"name": "Full wash",
"description": null,
"quantity": 1,
"unitPrice": 100,
"unitDiscount": 0,
"vatRate": 15,
"vatAmount": 15,
"lineTotal": 115
}
],
"subtotal": 100,
"discountTotal": 0,
"vatTotal": 15,
"total": 115,
"refund": {
"paymentMethodId": "5e6f7a8b-9c0d-4e1f-a2b3-c4d5e6f7a8b9",
"amount": 115
},
"notes": "Booking cancelled by the customer",
"referenceId": "refund-20417",
"metadata": {},
"createdVia": "api",
"zatca": {
"kind": "simplified",
"status": "pending",
"uuid": null,
"counter": null,
"hash": null,
"qr": null,
"submittedAt": null,
"clearedAt": null,
"reportedAt": null,
"errors": []
}
}

الفاتورة مبسطة، فالإشعار مبسط أيضاً: تُبلَّغ به الهيئة بعد الرد، ثم يصبح reported. ويوضح refund.amount المبلغ الذي أُرجع.

العميل الفرد لا يحمل رصيداً. فبدون refund لا يصدر له إشعار إلا في حدود المستحق عليه في الفاتورة، وما زاد على ذلك يرجع 400 invalid_parameter على refund. لذلك العميل الفرد الذي دفع المبلغ كاملاً يُرجع له دائماً بـ refund.

خصم المبلغ من حساب شركة​

الشركة في تسجيل عملية بيع لم تدفع فاتورتها البالغة 230 ريالاً بعد، وأُلغيت إحدى الغسلتين. أصدر إشعاراً على وحدة واحدة بدون refund، فيُخصم مما على الشركة:

curl https://api.kosoor.com.sa/v1/credit-notes \
-H "Authorization: Bearer ksr_test_..." \
-H "Idempotency-Key: 1f2e3d4c-5b6a-4978-8a9b-0c1d2e3f4a5b" \
-H "Content-Type: application/json" \
-d '{
"invoiceId": "c2d3e4f5-a6b7-4c8d-9e0f-1a2b3c4d5e6f",
"reason": "cancellation",
"lines": [
{ "itemId": "8d9e0f1a-2b3c-4d4e-9f5a-6b7c8d9e0f1a", "quantity": 1 }
],
"referenceId": "cancel-20418-1"
}'

الرد 201 Created:

{
"id": "f5a6b7c8-d9e0-4f1a-8b2c-4d5e6f7a8b9c",
"object": "creditNote",
"number": "CN-0008",
"invoiceId": "c2d3e4f5-a6b7-4c8d-9e0f-1a2b3c4d5e6f",
"customerId": "5a4db0c5-0000-4000-8000-000000000002",
"branchId": "9a0b1c2d-3e4f-4a5b-8c6d-7e8f9a0b1c2d",
"issueDate": "2026-11-08",
"reason": "cancellation",
"currency": "SAR",
"lines": [
{
"itemId": "8d9e0f1a-2b3c-4d4e-9f5a-6b7c8d9e0f1a",
"name": "Fleet wash",
"description": "Plates ABC 1234 and XYZ 5678",
"quantity": 1,
"unitPrice": 100,
"unitDiscount": 0,
"vatRate": 15,
"vatAmount": 15,
"lineTotal": 115
}
],
"subtotal": 100,
"discountTotal": 0,
"vatTotal": 15,
"total": 115,
"refund": null,
"notes": null,
"referenceId": "cancel-20418-1",
"metadata": {},
"createdVia": "api",
"zatca": {
"kind": "standard",
"status": "cleared",
"uuid": "a9b0c1d2-e3f4-4a5b-8c6d-7e8f9a0b1c2d",
"counter": 19,
"hash": "ZHXx9tKJ0Zr2b/RlF8NG4LYnWT15u5Rq0/+tYkccjjk=",
"qr": "ARBTYW5kYm94IE1lcmNoYW50Ag8zOTk5OTk5OTk5MDAwMDMDFDIwMjYtMTEtMDhUMDg6MTU6MDRaBAYxMTUuMDAFBTE1LjAw",
"submittedAt": "2026-11-08T08:15:03.902Z",
"clearedAt": "2026-11-08T08:15:04.611Z",
"reportedAt": null,
"errors": []
}
}

قيمة refund هي null، فلم يُرجع أي مبلغ. وتنقص قيمة amountDue في الفاتورة من 230 إلى 115. ولو كانت الشركة قد دفعت المبلغ كاملاً، لبقيت الـ 115 رصيداً دائناً لها.

الفاتورة ضريبية، فاعتمدت الهيئة الإشعار قبل الرد. والفاتورة التي لم تعتمدها الهيئة بعد لا يصدر عليها إشعار، ويرجع الطلب 409 invoice_not_cleared. أعد المحاولة عندما يعرض GET /v1/sales-invoices/{id} القيمة zatca.status: "cleared".

تصحيح خطأ​

الفاتورة التي فيها بيانات خاطئة، مثل عميل غير صحيح، تُصحَّح بطلبين:

  1. أصدر إشعاراً على كل بنودها بـ reason: "informationChange". وإذا كان العميل قد دفع فأرسل refund لإرجاع المبلغ، أو اتركه رصيداً دائناً إذا كان العميل شركة.
  2. أصدر فاتورة جديدة بالبيانات الصحيحة، كما في تسجيل عملية بيع.

الحد الأقصى للإشعار​

مجموع الإشعارات على الفاتورة لا يتجاوز إجماليها، ولا تتجاوز كمية أي صنف ما بيع منه. والاسترجاع من نقطة البيع أو من لوحة التحكم يُحسب أيضاً. وما زاد على ذلك يرجع 422 credit_exceeds_invoice. وكذلك لا يتجاوز المبلغ المرجع ما حُصّل على الفاتورة، مطروحاً منه ما أُرجع منها سابقاً (422 refund_exceeds_collected).

عندما يرفض الـ API الطلب​

الخطأماذا تفعل
409 invoice_not_clearedالفاتورة الضريبية ما زالت pending، فأعد المحاولة بعد أن تصبح cleared
422 invoice_not_creditableرفضت الهيئة الفاتورة، أو كانت مستوردة، ويصححها التاجر من لوحة التحكم
422 loyalty_refund_blockedأعد المحاولة مرة واحدة بعد دقائق، فإن رُفض مرة أخرى يصدر التاجر الإشعار من لوحة التحكم
422 used_subscription_not_refundableالبيع اشتراك استُخدمت منه زيارات، ويتولاه التاجر من لوحة التحكم
422 refund_method_not_supportedدُفعت الفاتورة ببطاقة عبر المتجر الإلكتروني للتاجر، ولا يستطيع الـ API إرجاع المبلغ إلى البطاقة
409 invoice_busyطلب آخر على الفاتورة استمر أكثر من 30 ثانية، فأعد إرسال الطلب

كل القواعد وكل الأخطاء في صفحة الإشعارات الدائنة.