واجهة API لإنشاء الفواتير
أنشئ فواتير PDF احترافية برمجياً من خادمك، مناسبة للأنظمة الداخلية أو الأسواق أو منتجات SaaS.
1. المصادقة#
أنشئ API key من app.invosend.com/settings/api-keys. يلزم وجود خطة مدفوعة ودور owner.
أرسل المفتاح كـ Bearer token في header Authorization مع كل طلب:
Authorization: Bearer isk_live_xxxxxxxxxxxxxxxxxxxxxxxx403. يتم رفض المفاتيح أيضاً إذا كانت مساحة العمل مجانية أو موقوفة أو منتهية.2. Endpoint#
Base URL: https://app.invosend.com
وصف API قابل للقراءة آليًا: OpenAPI 3.1 وPostman collection. استورد أيًا منهما في Postman أو Insomnia أو مولّد SDK.
3. Request Body#
مثال طلب كامل:
curl -X POST https://app.invosend.com/api/invoices/generate-external \
-H "Authorization: Bearer isk_live_xxxxxxxxxxxxxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{
"customer_name": "Acme Corp",
"customer_email": "billing@acme.com",
"items": [
{ "description": "Consulting Services", "quantity": 2, "price": 2000, "tax_rate": 11 }
],
"discount_total": 200,
"currency": "SAR",
"notes": "Thank you for your business."
}'مثال على فاتورة متكررة (الأولى الآن ثم واحدة كل شهر، بإجمالي 6):
curl -X POST https://app.invosend.com/api/invoices/generate-external \
-H "Authorization: Bearer isk_live_xxxxxxxxxxxxxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{
"customer_name": "Acme Corp",
"customer_email": "billing@acme.com",
"items": [
{ "description": "Monthly retainer", "quantity": 1, "price": 10000 }
],
"currency": "SAR",
"recurring_interval": "monthly",
"recurring_count": 6
}'Idempotency-Key (من 1 إلى 255 حرفًا، مثل UUID تنشئه لكل فاتورة). إذا نجح الطلب الأول، تعيد المحاولة الاستجابة نفسها مع الترويسة Idempotent-Replayed: true دون إنشاء فاتورة أخرى أو استهلاك رصيد آخر (قيمة credits_remaining هي قيمة الطلب الأول). تُحفظ المفاتيح 24 ساعة لكل مساحة عمل. تُحفظ الاستجابات الناجحة فقط، لذا يمكن إعادة محاولة طلب فاشل بالمفتاح نفسه.4. الاستجابة#
200 OK يعني أن الفاتورة أُنشئت وتم إنشاء ملف PDF:
{
"data": {
"id": "cjld2cjxh0000qzrmn831i7rn",
"invoice_number": "INV-1-202609-0016",
"pdf_url": "https://cdn.invosend.com/company/1/pdf/Invoice_INV_1_202609_0016_UNPAID_0da2beeabb.pdf",
"credits_remaining": 24,
"is_recurring": false,
"template": {
"id": "k3p9x2m7c0000abcd1234efgh",
"name": "Classic",
"source": "system_default"
}
}
}credits_remaining هي null عندما تكون الحصة غير محدودة. يُستخدم id لاستدعاء الواجهات الإضافية أدناه. الفواتير المنشأة عبر API تظهر أيضاً في قائمة فواتير مساحة العمل وتستخدم نفس تسلسل الأرقام. تأخذ أرقام الفواتير الشكل INV-{معرّف مساحة العمل}-{YYYYMM}-{التسلسل}. في الفاتورة المتكررة تتضمن الاستجابة أيضًا كائن recurring: schedule_id وinterval وoccurrences وnext_issue_date وend_date. recurring.schedule_id هو المعرّف المستخدم مع نقاط النهاية المتكررة أدناه.5. أكواد الأخطاء#
6. حد الطلبات#
X-RateLimit-Limit وX-RateLimit-Remaining. تُضبط حصص API لمساحة العمل حسب باقة العضوية في Invosend. هل تحتاج إلى حجم إنتاج أكبر؟ تواصل معنا من حساب مساحة العمل. المفاتيح الملغاة لا تُحتسب ضمن حد عدد المفاتيح.7. واجهات إضافية#
يمكن استخدام نفس مفتاح API لقراءة وإدارة الفواتير التي أُنشئت عبر generate-external:
payment_gateway (وpayment_account اختياريًا) في generate-external، ثم أرسل إلى عميلك صفحة الدفع العامة للفاتورة: https://app.invosend.com/p/invoice/{id}، مستخدمًا id الذي تعيده الواجهة. يدفع العميل هناك عبر البوابة المتصلة وتُوسَم الفاتورة تلقائيًا بأنها مدفوعة. تتولى تلك الصفحة إتمام الدفع؛ ولا توجد نقطة دفع عامة منفصلة عليك استدعاؤها.8. Webhooks#
بدلًا من الاستعلام المتكرر، سجّل عنوان HTTPS وسيرسل Invosend إليه طلب POST بمحتوى JSON كلما تغيّرت فاتورة. أضف نقاط النهاية من الإعدادات > Webhooks (مالك مساحة العمل، وخطة تتضمن الوصول إلى API، وحتى 5 نقاط نهاية). لكل نقطة نهاية سرّ توقيع خاص بها يظهر مرة واحدة فقط.
تُرسل الأحداث للفواتير المنشأة من لوحة التحكم ومن خلال هذه الواجهة على حد سواء. لا تُرسل أبدًا قوالب الفواتير المتكررة.
لكل حدث الغلاف نفسه. data.object هو الفاتورة بالشكل نفسه الذي يعيده GET /api/invoices/external/:id؛ وتتضمن أحداث الحالة أيضًا data.previous_status:
{
"id": "evt_9f2c1b7a4e3d5c6b8a1f0e2d",
"object": "event",
"type": "invoice.paid",
"created": "2026-10-01T09:30:12.000Z",
"data": {
"object": {
"id": "cjld2cjxh0000qzrmn831i7rn",
"invoice_number": "INV-1-202610-0007",
"customer_name": "Acme Corp",
"customer_email": "billing@acme.com",
"currency": "USD",
"subtotal": 500,
"discount_total": 0,
"tax_rate": 0,
"tax_amount": 0,
"amount": 500,
"amount_paid": 500,
"amount_credited": 0,
"amount_received": 500,
"invoice_status": "paid",
"is_archived": false,
"is_recurring": false,
"recurring_interval": "none",
"issue_date": "2026-10-01T02:15:40.000Z",
"due_date": "2026-10-15",
"paid_at": "2026-10-01T09:30:11.000Z",
"pdf_url": "https://cdn.invosend.com/company/1/pdf/Invoice_INV_1_202610_0007_PAID.pdf",
"pdf_status": "ready"
},
"previous_status": "unpaid"
}
}يحمل كل طلب الترويسات التالية. للتحقق منه، احسب HMAC-SHA256 للقيمة {t}.{النص الخام} بسرّ نقطة النهاية وقارنه بـ v1؛ وارفض الطلب إذا كان t أقدم من 5 دقائق:
POST /your/webhook/url
Content-Type: application/json
Invosend-Event: invoice.paid
Invosend-Delivery: evt_9f2c1b7a4e3d5c6b8a1f0e2d
Invosend-Signature: t=1790847012,v1=5b1d...e9a2
// Node.js
import crypto from "crypto";
function verify(rawBody, header, secret) {
const parts = Object.fromEntries(header.split(",").map((p) => p.split("=")));
if (Math.abs(Date.now() / 1000 - Number(parts.t)) > 300) return false;
const expected = crypto
.createHmac("sha256", secret)
.update(parts.t + "." + rawBody)
.digest("hex");
return crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(parts.v1));
}2xx خلال 10 ثوانٍ. وإلا ستُعاد المحاولة حتى 7 مرات إضافية (بعد دقيقة و5 دقائق و30 دقيقة وساعتين و6 ساعات و12 ساعة و24 ساعة). تُوقف نقطة النهاية التي تفشل باستمرار ويصلك إشعار. قد يصل الحدث أكثر من مرة أو بترتيب مختلف: استخدم id الحدث لتجاهل التكرار واعتبر invoice_status المصدر الموثوق. تُحفظ سجلات التسليم 30 يومًا، ويمكن إعادة إرسال أي حدث من الإعدادات > Webhooks.9. القيود#
هذه الواجهة مخصصة عمداً لإنشاء الفواتير وإدارتها بشكل بسيط. الميزات التالية غير متاحة بعد:
- تغطي Webhooks فقط إنشاء الفاتورة ودفعها وتأخرها وإلغاءها. أما التغييرات الأخرى مثل التعديل أو الأرشفة فلا تُرسل: اقرأ الحالة الحالية عبر
GET /invoices/external/:id. - لا تُرسل الفاتورة التي ينشئها كل طلب عبر البريد: هذه الواجهة تُنشئ ملف PDF فقط، وتسليمه إلى عميلك مسؤوليتك (أو استخدم لوحة التحكم). الاستثناء هو السلاسل المتكررة: تُرسل كل فاتورة لاحقة ينشئها المجدوِل تلقائيًا إلى
customer_email. - لا يمكن تعديل الفاتورة بعد إنشائها — يمكن عبر هذه الواجهة تغيير الحالة وحالة الأرشفة فقط.
- يتطلب دعم بوابة الدفع أن تكون متصلة مسبقاً من لوحة التحكم؛ هذه الواجهة تُرفقها بالفاتورة فقط ولا تقوم بربط البوابة بنفسها.
- يمكن إيقاف السلسلة المتكررة مؤقتًا واستئنافها وتمديدها وتغيير جدولها وتخطي دوراتها القادمة عبر API، لكن لا يمكن تعديل محتواها (البنود والعميل والمبالغ) ولا حذفها عبر API؛ نفّذ ذلك من لوحة التحكم.
الأسئلة الشائعة#
كيف أحصل على API key من Invosend؟
أنشئ حساباً في app.invosend.com، ارفع مساحة العمل إلى خطة مدفوعة، ثم افتح Settings > API Keys واضغط Generate key. يظهر المفتاح الأصلي مرة واحدة فقط عند إنشائه.
كم تكلف كل عملية إنشاء فاتورة عبر API؟
كل طلب ناجح يخصم 1 رصيد فاتورة من مساحة العمل، من نفس رصيد الفواتير المستخدمة عبر لوحة التحكم.
ما هو rate limit لهذه الواجهة؟
يتبع حد المعدل لمساحة العمل إعدادات باقتك المدفوعة. يسرد قسم Rate Limit أعلاه الحد الحالي لكل باقة.