الدفعات
إنشاء الدفعات وجلبها وإلغاؤها؛ كل الحقول، ومنع التكرار، وقاعدة مرجع الطلب.
| الطريقة | المسار | الوظيفة |
|---|---|---|
POST |
/api/v1/payments |
إنشاء دفعة والحصول على رابط الدفع |
GET |
/api/v1/payments/{id} |
جلب دفعة |
POST |
/api/v1/payments/{id}/cancel |
إلغاء دفعة معلّقة |
POST |
/api/v1/payments/{id}/refunds |
استرداد دفعة (في الوضع التجريبي)، راجع الاسترداد |
{id} هو قيمة id للدفعة من رد الإنشاء. كل طلب يحتاج إلى مفتاح API، راجع المصادقة.
إنشاء دفعة
POST /api/v1/payments
curl -s -X POST "$BRIDGE_URL/api/v1/payments" \
-H "Authorization: Bearer $BRIDGE_KEY" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-H "Idempotency-Key: 7f9c2b1e-order-1001" \
-d @payment.json
ومحتوى payment.json:
{
"amount": 25000,
"currency": "IQD",
"method": "aps_card",
"order_reference": "ORD-1001",
"description": "Two coffees",
"customer": {"name": "Ali", "phone": "+9647700000000", "email": "ali@example.com"},
"payer_name": "Ali Hassan",
"payer_phone": "+9647701234567",
"payer_email": "ali.hassan@example.com",
"locale": "en",
"return_url": "https://shop.example/return",
"metadata": {"cart_id": "c-42"}
}
حقول الطلب
| الحقل | النوع | إلزامي | القواعد |
|---|---|---|---|
amount |
عدد صحيح | نعم | بالدينار، 250 على الأقل. وقد يكون لتطبيقك حد أدنى وأقصى خاص به. |
currency |
نص | لا | IQD، العملة الوحيدة حالياً. القيمة الافتراضية IQD. |
method |
نص | لا | aps_card. إلزامي فقط إن كان تطبيقك يقدّم أكثر من طريقة دفع. |
order_reference |
نص | نعم | رقم طلبك، حتى 64 حرفاً. راجع القاعدة أدناه. |
description |
نص | لا | حتى 512 حرفاً، ويظهر للعميل في صفحة الدفع. |
customer |
كائن | لا | فقط name (حتى 255) وphone (حتى 32) وemail. |
payer_name |
نص | لا | اسم الدافع، حتى 255 حرفاً، ويظهر في لوحات التحكم. |
payer_phone |
نص | لا | حتى 20 حرفاً. |
payer_email |
نص | لا | بريد إلكتروني صالح. |
locale |
نص | لا | ar أو en: لغة صفحة الدفع وصفحة البطاقة. الافتراضي لغة تطبيقك. |
return_url |
نص | لا | إلى أين يُعاد العميل بعد الدفع، حتى 2048 حرفاً. الافتراضي عنوان العودة لتطبيقك. يجب أن يبدأ بـ https:// مع المفتاح الفعلي، وأن يكون مضيفه مطابقاً لمضيف عنوان العودة المسجَّل لتطبيقك. راجع القاعدة أدناه. |
metadata |
كائن | لا | أي كائن JSON حتى 4 كيلوبايت، ويُعاد كما أُرسل. |
الرد
201 Created:
{
"id": "01a13c8c-8592-70f4-9ef9-d3767e74d54c",
"status": "pending",
"mode": "test",
"amount": 25000,
"refunded_amount": 0,
"currency": "IQD",
"method": "aps_card",
"order_reference": "ORD-1001",
"description": "Two coffees",
"customer": {"name": "Ali", "phone": "+9647700000000", "email": "ali@example.com"},
"payer": {"name": "Ali Hassan", "phone": "+9647701234567", "email": "ali.hassan@example.com", "ip": "203.0.113.10", "user_agent": "GuzzleHttp/7"},
"locale": "en",
"return_url": "https://shop.example/return",
"metadata": {"cart_id": "c-42"},
"checkout_url": "https://<your-bridge-domain>/checkout/01a13c8c-8592-70f4-9ef9-d3767e74d54c",
"expires_at": "2026-10-14T23:03:24+00:00",
"paid_at": null,
"created_at": "2026-10-14T22:33:24+00:00",
"refunds": []
}
حقول الدفعة
| الحقل | النوع | المعنى |
|---|---|---|
id |
نص (UUID) | معرّف الدفعة، تستخدمه في كل الطلبات الأخرى. |
status |
نص | pending أو paid أو failed أو cancelled أو expired أو partially_refunded أو refunded. راجع الحالات. |
mode |
نص | test أو live، حسب المفتاح الذي أنشأها. |
amount |
عدد صحيح | بالدينار. |
refunded_amount |
عدد صحيح | ما استُرد حتى الآن بالدينار. |
currency |
نص | IQD. |
method |
نص | aps_card. |
order_reference |
نص | رقم طلبك. |
description |
نص أو null | كما أُرسل. |
customer |
كائن | name وphone وemail، وكل منها null إن لم يُرسل. |
payer |
كائن | name وphone وemail كما أُرسلت، ومعها ip وuser_agent للخادم الذي أنشأ الدفعة. |
locale |
نص | ar أو en. |
return_url |
نص أو null | إلى أين يُعاد العميل بعد الدفع. |
metadata |
كائن أو null | كما أُرسل. |
checkout_url |
نص | حوّل العميل إلى هذا الرابط ليدفع. |
expires_at |
نص | بصيغة ISO 8601. إن لم تُدفع حتى هذا الوقت تنتهي الدفعة، وهو افتراضياً بعد 30 دقيقة من الإنشاء. |
paid_at |
نص أو null | بصيغة ISO 8601، ويُضبط عندما تصبح الدفعة paid. |
created_at |
نص | بصيغة ISO 8601. |
refunds |
مصفوفة | كل استرداد مؤكَّد: id وamount وsource وprovider_reference وnote وcreated_at. |
قيمة refunds[].source هي api (استرداد تجريبي عبر الواجهة البرمجية)، أو manual (استرداد فعلي
أُكّد من لوحة التحكم)، أو provider_detected (أبلغ المزوّد عن استرداد لم يكن مسجلاً في الجسر).
قاعدة مرجع الطلب
لا يمكن دفع order_reference نفسه مرتين. ما دامت هناك دفعة بهذا المرجع بحالة pending أو
paid أو partially_refunded أو refunded، فإن إنشاء دفعة أخرى بالمرجع نفسه يرد بـ
409 order_reference_already_paid ومعه معرّف الدفعة الموجودة:
{
"error": {
"code": "order_reference_already_paid",
"message": "A payment for this order_reference is still pending. Reuse it or wait until it fails, is cancelled or expires.",
"payment_id": "01a13c8c-8592-70f4-9ef9-d3767e74d54c"
}
}
حوّل العميل إلى checkout_url لتلك الدفعة إن كانت ما زالت معلّقة، أو اعتبر الطلب مدفوعاً. وبعد أن
تصبح الدفعة failed أو cancelled أو expired يمكنك إنشاء دفعة جديدة بالمرجع نفسه. المراجع
التجريبية منفصلة عن الفعلية.
قاعدة return_url
يجب أن يكون مضيف return_url الذي ترسله مطابقاً لمضيف عنوان العودة المسجَّل لتطبيقك (أي مسار أو
استعلام مختلف لا يهم)، وإلا يرد الجسر بـ 422 return_url_not_allowed:
{
"error": {
"code": "return_url_not_allowed",
"message": "The return_url host must match this application's own return-URL host."
}
}
اترك return_url فارغاً لاستخدام العنوان المسجَّل. تسري هذه القاعدة في الوضعين التجريبي والفعلي.
إن احتجت نطاقاً ثانياً، اطلب من ألفابيت تغيير عنوان العودة المسجَّل لتطبيقك.
منع التكرار
أخطاء الشبكة واردة. لإعادة محاولة POST /api/v1/payments بأمان، أرسل ترويسة Idempotency-Key
(أي نص حتى 255 حرفاً، فريد لكل محاولة طلب، مثل UUID).
| ما ترسله | ما تحصل عليه |
|---|---|
| مفتاح جديد | تُنشأ الدفعة كالمعتاد ويُحفظ الرد مع المفتاح. |
| المفتاح نفسه والجسم نفسه | الرد المحفوظ مرة أخرى مع الترويسة Idempotent-Replayed: true، ولا تُنشأ دفعة ثانية. |
| المفتاح نفسه بجسم مختلف | 409 idempotency_key_reused. |
| المفتاح نفسه والطلب الأول ما زال قيد التنفيذ | 409 idempotency_request_in_progress. أعد المحاولة بعد قليل. |
رد 422 validation_failed لا يُحفظ، فيمكنك تصحيح الجسم وإعادة المحاولة بالمفتاح نفسه. المفاتيح
خاصة بكل تطبيق وبكل وضع.
جلب دفعة
GET /api/v1/payments/{id}
curl -s "$BRIDGE_URL/api/v1/payments/01a13c8c-8592-70f4-9ef9-d3767e74d54c" \
-H "Authorization: Bearer $BRIDGE_KEY" \
-H "Accept: application/json"
يأتي الرد 200 OK بالدفعة وبالشكل نفسه. وهنا دُفعت واستُرد جزء منها:
{
"id": "01a13c8c-8592-70f4-9ef9-d3767e74d54c",
"status": "partially_refunded",
"mode": "test",
"amount": 25000,
"refunded_amount": 10000,
"currency": "IQD",
"method": "aps_card",
"order_reference": "ORD-1001",
"description": "Two coffees",
"customer": {"name": "Ali", "phone": "+9647700000000", "email": "ali@example.com"},
"payer": {"name": "Ali Hassan", "phone": "+9647701234567", "email": "ali.hassan@example.com", "ip": "203.0.113.10", "user_agent": "GuzzleHttp/7"},
"locale": "en",
"return_url": "https://shop.example/return",
"metadata": {"cart_id": "c-42"},
"checkout_url": "https://<your-bridge-domain>/checkout/01a13c8c-8592-70f4-9ef9-d3767e74d54c",
"expires_at": "2026-10-14T23:03:24+00:00",
"paid_at": "2026-10-14T22:35:02+00:00",
"created_at": "2026-10-14T22:33:24+00:00",
"refunds": [
{"id": 1, "amount": 10000, "source": "api", "provider_reference": "01a13c8c-8595-723d-90e3-978995c21827", "note": "One item out of stock", "created_at": "2026-10-14T22:40:11+00:00"}
]
}
إن كانت الدفعة لتطبيق آخر، أو من الوضع الآخر، أو كان المعرّف غير موجود، فالرد 404 not_found.
إلغاء دفعة
POST /api/v1/payments/{id}/cancel بلا جسم.
curl -s -X POST "$BRIDGE_URL/api/v1/payments/01a13c8c-85e7-718d-ad61-4dc03208c5f0/cancel" \
-H "Authorization: Bearer $BRIDGE_KEY" \
-H "Accept: application/json"
لا تُلغى إلا الدفعة pending. يسأل الجسر المزوّد أولاً عن آخر نتيجة، فلا تُلغى دفعة دفعها العميل
للتو. عند النجاح يكون الرد 200 OK بالدفعة و"status": "cancelled"، ويُرسل إشعار
payment.cancelled.
إن لم تعد الدفعة معلّقة، فالرد 409 مع حالتها الحالية:
{
"error": {
"code": "payment_not_cancellable",
"message": "Only a pending payment can be cancelled; this one is paid.",
"status": "paid"
}
}
الدفعة الملغاة قد تصبح paid حتى موعد expires_at الأصلي إن أكمل العميل صفحة البطاقة التي كانت
مفتوحة أمامه. عندها يصلك payment.paid وعليك أن تسلّم الطلب أو تسترد المبلغ. راجع
مسار الدفع.