كيف تعمل
الهيئة تُصدر الشهاداتلكل مكلَّف على حدة— لا وجود لشهادة مشتركة يُوقَّع بها عن الجميع. لذلك كل تاجر تنشئه عبر هذه الواجهة هو منشأة مستقلة كاملة: رقمه الضريبي، شهادته، سلسلة فواتيره (ICV/PIH)، وأرشيفه. ما توفره الواجهة هو أنك تنشئ هذه المنشآت وتديرها من نظامك بدل أن يسجّل كل تاجر بنفسه.
| الخطوة | من يقوم بها | كيف |
|---|---|---|
| 1 · إنشاء منشأة التاجر | نظامك | POST /merchants |
| 2 · الربط مع بوابة فاتورة | نظامك — والتاجر يجلب الرمز | POST /merchants/{id}/connect |
| 3 · إصدار الفواتير | نظامك | POST /api/v1/invoices + X-Merchant-Id |
الاشتراكات:اتفاقك معنا يحدد عدد اشتراكات التجار المدفوعة. كل تاجر نشط يستهلك اشتراكًا، وإيقاف اشتراك تاجرٍ غادَرَ يُعيده لرصيدك. حين يُستهلك الرصيد ترجع الواجهة402 seat_limit_reached— تواصل معنا لزيادتها.
حقيقة رمز فاتورة — اقرأها قبل أن تكتب سطرًا
القيد علىمصدر الرمزفقط — أما إدخاله فيحدثداخل شاشتك أنت: اعرض لتاجرك «أدخل رمز التحقق من بوابة فاتورة»، ومرّر ما يكتبه إلىPOST /merchants/{id}/connectوتابع التقدم منGET /merchants/{id}/status— الشهادة وفحوص التوافق الستة خلال دقيقتين تقريبًا، وتاجرك لم يغادر نظامك. والقاعدة نفسها تنطبق على كل جهاز فرع لاحقًا:رمز جديد لكل جهاز(إلحاق حل فوترة جديد ← عدد الأجهزة) — تفاصيلها فيفروع التاجر وأجهزته.
لا تريد بناء الشاشة؟onboarding_urlيبقى بديلًا جاهزًا: رابط موقَّع يفتح صفحتنا على الخطوة نفسها.
الاستيثاق
مفتاح الشريك يبدأ بـztkp_live_وتستلمه منا عند توقيع الاتفاق — يظهر مرة واحدة، فخزّنه في متغير بيئة. وهو للأنظمة فقط:بوابة الشركاء تفتح ببريدك المسجّل ورمز تحقق، فلا يحتاج مفتاحك أن يمر بحافظة أحد. وهو مفتاحكالوحيد: يدير حساباتك هنا،ويُصدر فواتير كل تجّاركعلى واجهة الفواتير — التاجر المقصود تسمّيه في كل نداء بترويسةX-Merchant-Id. سرّ واحد في خزنتك، وتدوير واحد تديره.
curl https://zatcatools.com/api/partner/account \
-H "Authorization: Bearer ztkp_live_..."
الأخطاء
| HTTP | code | المعنى |
|---|---|---|
| 401 | unauthenticated | مفتاح الشريك مفقود أو غير صحيح — أو أرسلت مفتاح تاجر بالخطأ |
| 402 | seat_limit_reached | كل اشتراكاتك المدفوعة مشغولة — حرّر اشتراكًا أو تواصل لزيادتها |
| 403 | partner_suspended | حساب الشراكة موقوف — تواصل معنا |
| 404 | not_found | لا تاجر بهذا المعرّف ضمن شراكتك |
| 409 | email_taken / vat_taken | البريد له حساب قائم، أو الرقم الضريبي مسجّل لمنشأة أخرى |
| 422 | validation_failed | بيانات ناقصة أو غير صالحة — الرسالة توضح السبب |
| 429 | too_many_requests | تجاوزت حد الطلبات (120/دقيقة) |
حسابك واشتراكاتك
GET /api/partner/account
{
"partner": {
"name": "Smart POS Co.",
"status": "active",
"seats": { "limit": 50, "used": 34, "remaining": 16 }
}
}
إنشاء تاجر
POST /api/partner/merchants
يستهلك اشتراكًا وينشئ منشأة كاملة بفوترةبلا حدّ.
nameوemailإلزاميان؛vat_numberإلزامي أيضًا — هو هوية المنشأة لدى الهيئة، ونظامك يعرفه عن عميله دائمًا. السجل التجاري اختياري. وللعنوان أرسلshort_address— العنوان الوطني المختصر (4 أحرف و4 أرقام، مثلRRRD2929): نحلّ منه العنوان التفصيلي كاملًا تلقائيًا كما في التسجيل العادي، وإن تعذّر الحلّ يكمل التاجر بياناته في خطوة الـOnboarding — لا شيء يتعطل. البريد يجب أن يكونجديدًا عندنا: بريد له حساب قائم يُرفض بـ409 ولا يُتبنّى — معرفتك ببريد تاجر ليست بابًا إلى حساب يملكه.
ومع رقم التسجيل أرسلcr_scheme— أي وثيقة هو. الافتراضيCRNأي سجل تجاري من عشرة أرقام؛ ومن يعمل بترخيص أو برقم موحّد يرسلMOMلترخيص وزارة الشؤون البلدية، أوMLSلترخيص وزارة الموارد البشرية، أوSAGلترخيص وزارة الاستثمار، أو700للرقم الموحد، أوOTH. رمز خارج هذه القائمة يُرفض ولا يُقرأ سجلًا تجاريًا: كل مستند نوقّعه بعدها سيسمّي الوثيقة الخطأ. وهذا هو الحقل نفسه الذي يختاره التاجر منالإعدادات ← ملف المنشأة.
curl -X POST https://zatcatools.com/api/partner/merchants \
-H "Authorization: Bearer ztkp_live_..." \
-H "Content-Type: application/json" \
-d '{
"name": "مطعم الذواقة — فرع المروج",
"email": "[email protected]",
"vat_number": "310000000000003",
"cr_number": "1010203040",
"cr_scheme": "CRN",
"short_address": "RRRD2929"
}'
HTTP/1.1 201 Created
{
"merchant": { "id": 34, "name": "…", "status": "awaiting_onboarding", "seat": "active" },
"onboarding_url": "https://…", // موقَّع، صالح 72 ساعة
"seats": { "limit": 50, "used": 35, "remaining": 15 }
}
لا مفتاح لكل تاجر — خزّنmerchant.idمقابل عميلك في نظامك: هو ما يذهب في ترويسةX-Merchant-Idمع مفتاح شراكتك في كل نداء فوترة.
ربط التاجر — من داخل شاشتك
POST /api/partner/merchants/{id}/connect · GET /api/partner/merchants/{id}/status
قبل النداء تأكد أن بيانات المنشأة مكتملة —nameوvat_numberوcr_numberوshort_address— أكملها بـPATCH /merchants/{id}إن نقصت. النقص يُرفضقبلصرف الرمز: رمز فاتورة يُستخدم مرة واحدة، وحرقه على نقص حقل هو أسوأ نسخ هذا الخطأ.
ويُقرأcr_numberبحسبcr_schemeالخاص بالتاجر نفسه — فالترخيص لا يُطالب بأن يبدو سجلًا تجاريًا من عشرة أرقام.
# The merchant typed the six digits into YOUR screen:
curl -X POST https://zatcatools.com/api/partner/merchants/34/connect \
-H "Authorization: Bearer ztkp_live_…" \
-H "Content-Type: application/json" \
-d '{ "otp": "123456" }'
HTTP/1.1 202 Accepted
{ "status": "connecting", "poll": "…/merchants/34/status" }
# Poll every couple of seconds while your checklist spins:
GET /api/partner/merchants/34/status
{
"connected": false, "connecting": true, "stalled": false,
"compliance_passed": 4, // of the 6 checks
"error": null
}
# …until:
{ "connected": true, "compliance_passed": 6, "certificate_expires_at": "2029-08-31" }
errorيهمك منه اثنان:otp_invalid— الرمز خاطئ أو منتهٍ، اطلب من تاجرك رمزًا جديدًا؛ وstalled: true— توقف العدّ، أعد المحاولة برمز جديد. وبعد الربط تُقفل حقول الهوية (الاسم والرقم الضريبي والسجل): الشهادة الصادرة تحملها، وتغييرها يجعل الوثائق تخالف شهادتها.
قائمة التجار وتفاصيلهم
GET /api/partner/merchants · GET /api/partner/merchants/{id}
الحقل الذي تبني عليه شاشتك هوstatus:
| awaiting_onboarding | أُنشئ ولم يُكمل الربط — اعرض له رابط الإكمال |
| connected | مرتبط بالهيئة — فواتيره تصدر الآن |
| failed | آخر محاولة ربط فشلت — اطلب رابطًا جديدًا وأعد توجيهه |
| trial | يجرّب على بيئة الهيئة التجريبية |
| released | حرّرتَ اشتراكه — بياناته محفوظة ولا فوترة جديدة |
Onboarding Link
POST /api/partner/merchants/{id}/onboarding-link
يسكّ رابطًا موقَّعًا جديدًا صالحًا 72 ساعة — الرابطيوقّع التاجر داخل حسابهفعامله كسرّ: اعرضه داخل شاشة التاجر نفسه فقط، ولا تضعه في بريد جماعي أو رسالة قابلة لإعادة التوجيه. انتهت صلاحيته؟ اطلب غيره — بلا حدّ.
إصدار الفواتير
المشتري الذي لا يحمل رقمًا ضريبيًا — جهة حكومية أو منشأة صغيرة أو فرد — يُعرَّف بـcr_numberمصحوبًا بـid_schemeداخل كائنcustomer؛ فالرقم الموحد700للجهات الحكومية، وNATللهوية الوطنية، وIQAللإقامة. والسطر المعفى تعليمًا أو صحة يلزمهNATتحديدًا (BR-KSA-49). التفاصيل كاملة فيمرجع الواجهة.
من هنا وصاعدًا تستخدمواجهة الفواتير v1 بمفتاح شراكتك نفسه+ ترويسة تسمّي التاجر — إصدار، إشعارات دائن ومدين، XML وPDF وQR. مثال بيع من نقطة بيعك:
curl -X POST https://zatcatools.com/api/v1/invoices \
-H "Authorization: Bearer ztkp_live_…" \
-H "X-Merchant-Id: 34" # التاجر صاحب هذا البيع \
-H "Content-Type: application/json" \
-d '{
"type": "simplified",
"branch_id": 3, // البيع من فرع؟ سمِّ الفرع وجهازه معًا —
"device_id": 7, // القاعدة نفسها للضريبية والمبسطة سواء
"lines": [
{ "name": "وجبة غداء", "quantity": 2, "unit_price": 45.00 },
{ "name": "دواء", "quantity": 1, "unit_price": 120.00,
"tax_category": "Z", "tax_reason_code": "VATEX-SA-35" }
]
}'
البنود تقبلtax_category
(Sافتراضيًا ·Zصفرية ·Eمعفاة ·Oخارج النطاق) — والفئات غير الخاضعة تتطلبtax_reason_codeمن قائمة الهيئة، والفاتورة الواحدة تجمع فئات مختلفة بلا مشكلة. والبيع من فرع يسمّيbranch_idوdevice_idمعًا — للضريبية والمبسطة سواء؛ التفاصيل فيفروع التاجر وأجهزتهأدناه.
فروع التاجر وأجهزته
تاجرك له أكثر من نقطة بيع؟ كل الفروع تحت رقمه الضريبي، لكن كل فرع يُصدر عبرجهازه الخاص (EGS unit) — نموذج الهيئة نفسه: التاجر يولّد من بوابة فاتورة رمز OTPلكل جهاز(إلحاق حل فوترة جديد ← عدد الأجهزة)، أنت تجمعه في شاشتك وتمرره لنا، وكل جهاز يخرج بشهادته وسلسلة فواتيره المستقلة. ربط المنشأة الأساسي (أعلاه) هو جهاز المقر الرئيسي؛ ما يلي للفروع. نفس مفتاحك + ترويسة التاجر:
# 1. الفرع
curl -X POST https://zatcatools.com/api/v1/branches \
-H "Authorization: Bearer ztkp_live_…" -H "X-Merchant-Id: 34" \
-d '{ "name": "فرع النخيل مول", "cr_number": "1010999888", "short_address": "RESB3139" }'
# → 201 { "branch": { "id": 3, … } }
# 2. جهاز الفرع — otp جمعته من شاشة تاجرك
curl -X POST https://zatcatools.com/api/v1/branches/3/devices \
-H "Authorization: Bearer ztkp_live_…" -H "X-Merchant-Id: 34" \
-d '{ "otp": "482913", "name": "كاشير 1" }'
# → 202 { "device": { "id": 7, "status": "pending", … } }
# 3. تتبّع حتى connected (عادة أقل من دقيقة)
curl https://zatcatools.com/api/v1/devices/7 \
-H "Authorization: Bearer ztkp_live_…" -H "X-Merchant-Id: 34"
# → { "device": { "status": "connected", "usable": true, … } }
# 4. بيع من الفرع — الفاتورة تسمّي فرعها وجهازها معًا
curl -X POST https://zatcatools.com/api/v1/invoices \
-H "Authorization: Bearer ztkp_live_…" -H "X-Merchant-Id: 34" \
-d '{ "type": "simplified", "branch_id": 3, "device_id": 7,
"lines": [{ "name": "وجبة", "quantity": 1, "unit_price": 45 }] }'
الفرع الواحد يتحمّل عدة أجهزة — كرر الخطوة 2 برمز OTP جديد لكل جهاز، وكلٌّ بسلسلته المستقلة فتُصدر نقاط البيع بالتوازي.فاتورة الفرع تسمّي جهازها: خزّنdevice_idعند كل نقطة بيع ومرّره معbranch_idعلى كل فاتورة — أحدهما بلا الآخر يُرفض (device_required /
branch_required)، وجهاز غير متصل يُرفض بـdevice_not_usable. الإشعارات تتبع فرع فاتورتها الأصل تلقائيًا وجهازها عليها اختياري. فشل التفعيل بـotp_invalid؟ الرمز خُطئ أو انتهت ساعته أو استُهلك — اطلب من تاجرك رمزًا جديدًا وأعد التفعيل على نفس الجهاز:POST /v1/devices/{id}/connect. القائمة الكاملة للفروع وأجهزتها دائمًا علىGET /v1/account.
إيقاف اشتراك وإعادته
POST /api/partner/merchants/{id}/release · POST /api/partner/merchants/{id}/reinstate
تاجر غادر نظامك؟ أوقف اشتراكه ليخدم غيره. الإيقافلا يحذف شيئًا أبدًا— الهيئة تُلزم بأرشيف ست سنوات، وسلسلة الفواتير لا تنقطع: المنشأة ووثائقها ودخول صاحبها كلها تبقى،وقراءة أرشيفه عبر الـ API تبقى أيضًا(كل نداءاتGETتعمل للموقوف — تصدير وتدقيق بلا انقطاع)؛ الذي يتوقف هو الفوترة الجديدة وكل فعل يُنشئ شيئًا. عاد التاجر؟reinstateيعيد تفعيله على اشتراك شاغر ويستأنف سلسلته من حيث توقفت.
حدود الاستخدام
واجهة الشركاء:120 طلبًا في الدقيقة. واجهة الفواتير:60 طلبًا في الدقيقةعلى مفتاحك — يكفي مئات نقاط البيع في الاستخدام الواقعي؛ ولو بلغت حجمًا يتجاوزه فراسلنا ونرفعه لك.