Developer API · بيتا

افعل كل ما يفعله التطبيق، بالقواعد نفسها، من برنامجك أنت.

يربط Kumpara Developer API المتاجر الإلكترونية وأنظمة ERP وبرامج المحاسبة ووسطاء المتاجر بـ Kumpara. تستدعي واجهة /v1 النواة نفسها التي يستدعيها التطبيق: الضوابط نفسها والقيود نفسها والحساب الضريبي نفسه.

  • آمن دفتريًا: كل حركة مالية في معاملة واحدة، وكل تصحيح قيد عكسي
  • المستندات الإلكترونية ضمنه: الإصدار والإلغاء وصندوق الوارد والاستعلام والرصيد
  • مصمَّم لتركيا: استقطاع على مستوى البند، ورموز إعفاء الضريبة، وتعدد العملات ولقطة سعر الصرف

واجهة Developer API في بيتا مغلقة حاليًا؛ لم يُفتح الوصول العام بعد ولا نَعِد بتاريخ. يحصل المشاركون على عنوانهم ومفاتيحهم منّا.

74
نهاية فعّالة من جهات التعامل إلى المستندات، جميعها محمية بالصلاحيات.
28
صلاحية منفصلة تمنح المفتاح ما يحتاجه فقط.
3
دفاتر بالإضافة فقط جهات التعامل والنقد والمخزون: بلا UPDATE/DELETE.
1
مفتاح = شركة واحدة تسرّب البيانات بين الشركات غير ممكن معماريًا.

ما الذي يمكنك بناؤه؟

كل ما يلي يُبنى بنهايات تعمل اليوم — وليست وعودًا مستقبلية.

أدِر سلسلة الطلب كاملة

أنشئ الطلب، واشحن إشعار التسليم، وأصدر الفاتورة واعتمدها، وسوِّ التحصيل في الاستدعاء نفسه. الشحن والفوترة الجزئية مدعومان.

مزامنة المحاسبة وERP

يعطيك تدفق GET /v1/changes نوع السجل المتغيّر ومعرّفه، وتقرأ التفاصيل من نهايته. ولا يفرّق التدفق بين التطبيق والجوال والـ API.

اكتب مستويات المخزون بقيمة مطلقة

يكتب POST /v1/stock-levels/actions/set نتيجة الجرد مباشرة، ويتحوّل الفرق إلى حركة تسوية.

أصدر الفواتير الإلكترونية

استدعاء واحد يحوّل الفاتورة المعتمدة إلى مستند إلكتروني، ويُختار السيناريو على الخادم. وتزامن صندوق الوارد وتنزّل XML/PDF.

اقرأ وضع العميل من مصدر واحد

الرصيد وحده لا يكفي: قيود الدفتر والبنود المفتوحة وتقادم الذمم نهايات منفصلة. وتسوّي التحصيلات على الفواتير المفتوحة.

انقل الأرصدة الافتتاحية

للأرصدة الافتتاحية للعملاء وللمخزون نهايات خاصة، ولكل منها نظير عكسي؛ فالدفاتر بالإضافة فقط.

أول فاتورة في خمس خطوات

كل عملية كتابة تحمل ثلاثة ترويسات: Authorization وIdempotency-Key وContent-Type.

  1. 1

    أنشئ مفتاحًا

    في التطبيق: الإعدادات ← مفاتيح API. اختر اسمًا وشركة وصلاحيات. يُعرض المفتاح مرة واحدة.

  2. 2

    تحقّق من هويتك

    يعيد GET /v1/me المنشأة والشركة والبيئة والصلاحيات المرتبطة بالمفتاح.

  3. 3

    أنشئ جهة التعامل

    طابِق بالرقم الضريبي أو رمز الحساب: يُحدَّث الموجود ويُنشأ المفقود.

  4. 4

    أصدر الفاتورة واعتمدها

    بـ approve: true يتمّ الإنشاء والاعتماد في معاملة واحدة: الرقم والمديونية وخروج المخزون معًا.

  5. 5

    سوِّ التحصيل

    تمرّر الفاتورة عند إنشاء الدفعة: يُكتب دفتر النقد ودفتر العميل والتسوية في معاملة واحدة.

بداية سريعة

١. تحقّق من مفتاحك

كل طلب يحمل ترويسة Authorization: Bearer. أول استدعاء يخبرك بالمنشأة والشركة المرتبطتين بالمفتاح وبالصلاحيات التي يحملها:

curl -s "https://api.kumpara.net/v1/me" \
  -H "Authorization: Bearer kp_live_a1b2c3d4_…"

ثم يخبرك GET /v1/capabilities هل المستندات الإلكترونية موصولة لهذه الشركة، وكم بقي من الرصيد، وما العملة الأساسية.

٢. طابِق جهة التعامل بمفتاحك أنت

curl -s -X POST "https://api.kumpara.net/v1/contacts/actions/upsert?matchBy=taxNumber" \
  -H "Authorization: Bearer kp_live_…" \
  -H "Idempotency-Key: contact-4711-2026-09-23" \
  -H "Content-Type: application/json" \
  -d '{ "name": "Örnek Gıda Ltd. Şti.", "type": "customer", "taxNumber": "1234567890" }'

يخبرك الحقل created في الاستجابة هل أُنشئ سجل جديد أم حُدّث سجل قائم. ويقبل matchBy القيمتين taxNumber أو code فقط.

٣. أصدر الفاتورة واعتمدها

لا يوجد حقل مبلغ في بند الفاتورة. أنت ترسل الكمية والسعر والخصم ونسبة الضريبة، ويحسب الخادم الباقي.

curl -s -X POST "https://api.kumpara.net/v1/sales-invoices" \
  -H "Authorization: Bearer kp_live_…" \
  -H "Idempotency-Key: order-88213-invoice" \
  -H "Content-Type: application/json" \
  -d '{ "contactId": "6f1c…", "currency": "TRY", "approve": true,
        "lines": [ { "productId": "9a3e…", "quantity": 10, "unitPrice": 250, "vatRate": 20 } ] }'

تنفّذ approve: true الإنشاء والاعتماد في معاملة واحدة. وهذه حركة مالية، لذا يحتاج المفتاح إلى sales:approve إلى جانب sales:write.

٤. سجّل التحصيل وأغلق الفاتورة

curl -s -X POST "https://api.kumpara.net/v1/payments" \
  -H "Authorization: Bearer kp_live_…" \
  -H "Idempotency-Key: payment-88213" \
  -H "Content-Type: application/json" \
  -d '{ "contactId": "6f1c…", "cashAccountId": "2b77…", "direction": "incoming",
        "amount": 3060, "invoiceType": "sales_invoice", "invoiceId": "c41b…" }'

٥. اسحب التغييرات

curl -s "https://api.kumpara.net/v1/changes?since=2026-09-23T06:00:00Z&types=sales_invoice,payment" \
  -H "Authorization: Bearer kp_live_…"

في الاستدعاء التالي مرّر meta.checkpoint كـ since؛ الحدّ حصري فلا يعود السجل نفسه مرتين. ونوصي بتداخل خمس دقائق، فالقراءة عملية متكرّرة الأثر والتكرار غير ضار.

العقد الأساسي

الهوية والصلاحيات

يُرسل المفتاح في Authorization: Bearer kp_live_… (أو X-Api-Key). ولا تُخزَّن قيمته الصريحة؛ يحتفظ Kumpara ببصمة SHA-256 والبادئة فقط. كل مفتاح مقيَّد بشركة واحدة، ولا يمكن معماريًا أن تعود بيانات شركة أخرى. ولا يمكن لصلاحيات المفتاح أن تتجاوز دور المستخدم الذي أنشأه.

الصلاحيات على شكل {مورد}:{إجراء} وعددها ثمانٍ وعشرون: read للعرض، وwrite للإنشاء والتعديل، وapprove للاعتماد والإلغاء والعكس، وissue/cancel/incoming للمستندات الإلكترونية. وتعيد النهاية غير المصرّح بها 403 insufficient_scope مع اسم الصلاحية الناقصة.

تكرار الأثر (Idempotency)

كل عملية كتابة تتطلب Idempotency-Key. يُخزَّن المفتاح داخل المعاملة نفسها التي تكتب السجل. والطلب الثاني بالمفتاح ذاته لا يكرّر العمل. وتأتي الاستجابة بإحدى صورتين: 409 idempotency_replayed (تقرأ السجل المُنشأ بـ GET)، أو 200 مع جسم الاستجابة الأولى وراية replayed: true. وكلتاهما تعني «نُفِّذت العملية سابقًا»، وعلى عميلك أن يعدّ كلتيهما نجاحًا.

المال وسعر الصرف والأنواع الرقمية

تُخزَّن المبالغ بنوع numeric(19,4) وتعود في JSON كسلسلة نصية، فلا يحدث تقريب عائم. ولا يُفصل المبلغ عن عملته أبدًا.

يحمل كل بند مالي لقطة سعر الصرف الخاصة به: originalAmount وoriginalCurrency وexchangeRate وbaseAmount وbaseCurrency. وحتى لو تغيّرت الأسعار لاحقًا لا يتغيّر المستند السابق. ويمكنك تمرير السعر في exchangeRate؛ وإن لم تمرّره استُخدم 1.

الترقيم

تُرقَّم القوائم بـ cursor بلا offset، وتحمل الاستجابة meta.nextCursor وmeta.hasMore. وحجم الصفحة pageSize افتراضيًا 50 وحدّه 200. وللفروق استخدم معامل الاستعلام updatedAfter أو تدفق /v1/changes.

الأخطاء

الأخطاء بصيغة RFC 9457 application/problem+json وتحمل حقل code ثابتًا: 400 تعذّرت قراءة الطلب، 401 مفتاح غير صالح (unauthorized)، 403 صلاحية ناقصة، 404 سجل غير موجود، 409 تعارض، 422 مخالفة قاعدة عمل، 429 تجاوز الحد.

الحدود ومعرّف الطلب

القراءة والكتابة في سلّتين منفصلتين: افتراضيًا 600 قراءة و120 كتابة في الدقيقة لكل مفتاح، مع ترويسات RateLimit-* في كل استجابة. وتحمل كل استجابة X-Request-Id. والعقد كاملًا منشور بصيغة OpenAPI 3: https://api.kumpara.net/v1/openapi.json.

الموارد

الجدول أدناه هو كامل الواجهة العاملة اليوم. أما المعاملات الكاملة والأجسام ومخططات الاستجابة فموجودة في OpenAPI: https://api.kumpara.net/v1/docs.

المجال النهايات الرئيسية الصلاحيات
السياق GET /v1/me, GET /v1/capabilities me:read
بطاقة جهة التعامل GET · POST /v1/contacts, POST /v1/contacts/actions/upsert contacts:read · contacts:write
وضع جهة التعامل GET /v1/contacts/{id}/balance, …/ledger-entries, …/open-items, GET /v1/aging contacts:read
المنتجات والمتغيرات GET · POST /v1/products, POST /v1/products/{id}/variants products:read · products:write
المخزون GET /v1/stock-levels, POST /v1/stock-levels/actions/set, GET /v1/stock-movements stock:read · stock:write
الطلبات GET · POST /v1/orders, POST /v1/orders/{id}/actions/cancel sales:read · sales:write
إشعارات التسليم GET · POST /v1/delivery-notes, …/actions/ship sales:read · sales:write
فواتير المبيعات GET · POST /v1/sales-invoices, …/{id}/actions/approve, …/{id}/actions/cancel sales:read · sales:write · sales:approve
فواتير المشتريات GET · POST /v1/purchase-invoices, …/{id}/actions/approve purchase:*
التحصيلات والدفعات GET · POST /v1/payments, POST /v1/payments/{id}/actions/allocate payments:read · payments:write
الصندوق والبنك GET /v1/cash-accounts, …/{id}/ledger-entries cash:read
الشيكات والسندات GET /v1/cheques cheques:read
المستندات الإلكترونية POST /v1/sales-invoices/{id}/actions/issue-e-document, GET /v1/e-documents, GET /v1/incoming-e-documents edocuments:*
الفهارس المرجعية GET /v1/warehouses, GET /v1/categories, GET /v1/reference/{type} catalog:read
تدفق التغييرات GET /v1/changes changes:read

كيف تترابط سلسلة المستندات. يقبل جسم إشعار التسليم orderId، ويقبل جسم الفاتورة orderId و deliveryNoteIds[]، وتتطابق البنود عبر orderLineId وdeliveryNoteLineId. والكمية المتبقية ليست عدّادًا مخزَّنًا بل تُشتقّ من الفواتير غير الملغاة.

خروج المخزون يحدث في مكان واحد. لا يخصم الشحن واعتماد الفاتورة البضاعة مرتين: إجمالي الخروج هو max(Σ الشحنات, Σ الفواتير المعتمدة)، ويكتب كل مستند فرقه فقط.

ليس بعد — ضمن خارطة الطريق

نذكر ما هو غير متاح أيضًا كي لا تبني على افتراض خاطئ.

Webhooks قريبًا

الطريق العملي اليوم هو استطلاع GET /v1/changes؛ الصلاحية موجودة في الفهرس لكن النهاية غير منشورة.

بيئة اختبار معزولة قريبًا

بادئة kp_test_ مجرد تسمية اليوم وتكتب في بياناتك الحقيقية. أنشئ شركة منفصلة للتجريب.

ETag / If-Match قريبًا

لا يُضاف التحكّم بالتزامن ناقصًا دون عمود الإصدار الذي يعتمد عليه؛ فانطباع الحماية أسوأ من غيابها.

OAuth 2.1 وفهرس التطبيقات قريبًا

خلال البيتا ينشئ عميلك مفتاحًا ضيّق الصلاحيات من لوحته؛ وتدفّق شاشة الموافقة ضمن الخطة.

تحويل المستند الوارد إلى فاتورة شراء قريبًا

تعمل قراءة صندوق الوارد والردّ عليه وتجاهله؛ أما مطابقة البنود بالمنتجات فتتم في التطبيق حاليًا.

نهايات التقارير والتصدير قريبًا

يعمل تقادم الذمم (GET /v1/aging)؛ أما الأرباح والضريبة والتصدير غير المتزامن فغير متاحة بعد.

الأمان والعزل وحماية البيانات

العزل يتم على مستوى قاعدة البيانات. ما يفصل منشأة عن أخرى ليس مرشّحًا في التطبيق بل طبقة أمان الصفوف في PostgreSQL نفسها. يتصل طلب الـ API بدور أقلّ امتيازًا، ويُكتب السياق في قاعدة البيانات عند فتح الاتصال، فلا يمكن لاستعلام خاطئ أن يعيد صفّ منشأة أخرى. ويأتي فصل الشركات فوق ذلك: المفتاح مقيَّد بشركة واحدة.

المفتاح لا يُخزَّن. تُحفظ بصمة SHA-256 والبادئة (kp_live_a1b2c3d4) فقط. وتظهر القيمة الصريحة مرة واحدة عند الإنشاء؛ وإن فقدتها فلا يمكن استرجاعها بل تُصدر مفتاحًا جديدًا. ولا تُكتب المفاتيح في السجلات، والإلغاء يسري فورًا.

لا تصعيد للصلاحيات. لا تتجاوز صلاحيات المفتاح دور من أنشأه. وإنشاء فاتورة بـ approve: true يحتاج sales:approve إلى جانب sales:write، وإلا رُفض الطلب بدل حفظه مسوّدة بصمت.

كل إجراء يترك أثرًا. تُسجَّل كل كتابة عبر الـ API في سجل التدقيق ببادئة المفتاح كفاعل (api:kp_live_a1b2c3d4)، ويكتب التطبيق والجوال والـ API في السجل نفسه.

البيانات الشخصية بصلاحية ضيّقة. تعود حقول مثل رقم الهوية والـ IBAN والاسم والعنوان مُقنَّعة إلى المفاتيح التي لا تملك صلاحية pii:read — تبقى الأحرف الأربعة الأخيرة ظاهرة وتستمر النهاية في العمل. فإن لم يحتجها تكاملك فلا تمنحها؛ فأفضل حماية ألّا تغادر البيانات أصلًا.

كيف تحفظ المفتاح. على الخادم، في متغيّر بيئة أو مدير أسرار؛ ولا تضعه في الشيفرة أو المتصفح أو تطبيق الجوال. وأصدر مفتاحًا لكل تكامل. وعند فتح طلب دعم شارك requestId وIdempotency-Key، ولا تشارك مفتاحك أبدًا.

أسئلة يطرحها المطوّرون

أي باقة تتضمّن الـ API؟

الوصول غير مقيّد بالباقة. تختلف الباقات في حدود الطلبات والحصص وهي قابلة للضبط. خلال البيتا يُمنح الوصول بطلب.

هل أحسب المبالغ بنفسي وأرسلها؟

لا؛ الخادم هو المرجع الوحيد. أنت ترسل الكمية والسعر ونسبة الخصم ونسبة الضريبة ورمز الاستقطاع والعملة، ويحسب الخادم إجماليات البند والضريبة المستقطعة والمبلغ الأساسي ورقم المستند.

هل يُنشئ تكرار الطلب سجلًا مكرّرًا؟

لا. كل عملية كتابة تتطلب Idempotency-Key، ويُخزَّن المفتاح داخل المعاملة نفسها التي تكتب السجل. والطلب الثاني بالمفتاح ذاته لا يكرّر العمل: إمّا تتلقّى 409 idempotency_replayed فتقرأ السجل بـ GET، وإمّا 200 مع جسم الاستجابة الأولى وراية replayed: true. وكلتاهما تُعدّ نجاحًا.

هل يمكنني تعديل فاتورة معتمدة؟

لا، المستند المعتمد غير قابل للتعديل. طريق التصحيح هو الإلغاء ثم مستند جديد؛ والإلغاء يكتب قيودًا عكسية. لا يوجد UPDATE/DELETE في الدفاتر.

هل ألتقط التغييرات التي تتم من داخل التطبيق؟

نعم. لا يفرّق تدفق GET /v1/changes بين مصدر التغيير: التطبيق والجوال والـ API تصل إلى التدفق نفسه، وهو يعطي نوع السجل ومعرّفه فقط.

هل توجد بيئة اختبار منفصلة؟

ليس بعد، ونقولها صراحة. مفتاح kp_test_ اليوم مجرد تسمية ويكتب في بياناتك الحقيقية. للتجريب أنشئ شركة منفصلة؛ والبيئة المعزولة ضمن خارطة الطريق.

هل توجد Webhooks؟

ليس بعد. الطريق العملي اليوم هو استطلاع GET /v1/changes: مرّر آخر meta.checkpoint تلقيته كـ since في الطلب التالي. الـ Webhooks ضمن خارطة الطريق.

ماذا عن المنشآت متعددة الشركات؟

كل مفتاح مقيّد بشركة واحدة ولا يرى سوى بياناتها. في التكامل متعدد الشركات تُنشئ مفتاحًا لكل شركة.

هل إنشاء فاتورة يستهلك رصيدًا؟

لا. يُستهلك الرصيد في حركة المستندات الإلكترونية فقط: كل مستند صادر أو وارد يساوي رصيدًا واحدًا. أما ما تنشئه داخل النظام فلا يستهلك شيئًا.

ماذا لو فقدت مفتاحي؟

لا يمكن استرجاعه. يخزّن Kumpara بصمة SHA-256 والبادئة فقط، ويُعرض المفتاح مرة واحدة عند الإنشاء. إن فقدته فألغِ القديم وأنشئ مفتاحًا جديدًا؛ والإلغاء يسري فورًا.

انضم إلى برنامج البيتا

نقبل منصّات المتاجر وأنظمة ERP وبرامج المحاسبة ومكاتب المحاسبة ووسطاء المتاجر. يحصل المشاركون على الوصول وإشعار مسبق بتغيّرات العقد وقناة تواصل مباشرة.