التوثيق
واجهات بوابة الدفع
مقدمة وتعريف بالخدمة
#
بوابة الساقي للدفع الإلكتروني
ابدأ تكامل الدفع عبر رابط: صادِق من خادمك، وأنشئ رابط دفع مستضافاً، ثم تحقّق من حالة الدفع قبل إتمام طلب العميل.
توفّر واجهة بوابة الساقي للدفع RESTful طلبات واستجابات بصيغة JSON. يشرح هذا الدليل نموذج الدفع عبر رابط: يوجّه تطبيقك العميل إلى صفحة الساقي المستضافة لإدخال بيانات البطاقة، ويتولى خادمك إنشاء الرابط والتحقق من النتيجة. احتفظ ببيانات الاعتماد ورمز الوصول على الخادم، ولا تعتمد على إعادة التوجيه في المتصفح وحدها لإثبات الدفع.
عنوان بيئة الاختبار (Sandbox)
استخدم https://pg-t2.alsaqi.net للتطوير والاختبار، وأرسل جميع الطلبات عبر HTTPS . راجع قسم بيئات التشغيل قبل الانتقال إلى الإنتاج.
آلية الربط والتكامل
#
يتبع التكامل عبر رابط الدفع أربع خطوات.
الخطوة
الإجراء
نقطة النهاية
1
صادِق واحصل على رمز وصول JWT و clientId.
/api/Auth/CreateAccessToken
2
أنشئ رابط دفع لمبلغ وفاتورة محدّدين.
/api/Payment/generate-payment-link/{client_id}
3
وجّه العميل إلى paymentLink للدفع على الصفحة المستضافة.
صفحة مستضافة
4
تحقّق من النتيجة النهائية من جهة الخادم قبل إتمام الطلب.
/api/Payment/CheckPaymentStatus
المسار بنظرة سريعة
#
Create Token ──▶ Generate Payment Link ──▶ Cardholder pays (hosted page) ──▶ Check Payment Status
(auth) (returns paymentLink) (success / fail URL) (final result)
تأكّد دائمًا من جهة الخادم
لا تعتمد على إعادة التوجيه في المتصفح وحدها. اعتبر الطلب مدفوعًا فقط بعد أن تُعيد عملية التحقق linkStatus = 2 (مقبول).
بيئات التشغيل
#
يجري التطوير والاختبار على بيئة الاختبار. وعند الانتقال إلى الإنتاج يتغيّر العنوان الأساسي وبيانات الاعتماد فقط، أمّا المسارات وصيغ الطلبات فمتطابقة في البيئتين.
البيئة
العنوان الأساسي
الاستخدام
الاختبار
https://pg-t2.alsaqi.net
التطوير والاختبار ببطاقات تجريبية.
الإنتاج
يُمنح بعد التفعيل
معاملات حقيقية ببطاقات فعلية.
بطاقة الاختبار
Card number
4032080000002567
Expiry
12/25
CVV
200
Currency
IQD
تعمل بيانات الاختبار والبطاقة التجريبية في بيئة الاختبار فقط. وللحصول على بيانات الاعتماد يتواصل التاجر مع دعم الساقي: support@alsaqi.net أو +964 781 054 7229 .
المصادقة والأمان
#
تتطلّب نقاط النهاية المحميّة رمز وصول من نوع Bearer يُؤخذ من نقطة إنشاء رمز الوصول. أرسله في ترويسة Authorization مع كل طلب محمي:
Authorization: Bearer ACCESS_TOKEN_STRING
أفضل ممارسات الأمان
#
يجب إرسال جميع الطلبات عبر HTTPS.
يجب حفظ اسم المستخدم وكلمة المرور ورمز الوصول في خادم التاجر فقط.
رمز الوصول صالح لمدّة 24 ساعة افتراضيًا، ويجب طلب رمز جديد قبل انتهائه.
يجب استخدام RequestId جديد لكل عملية دفع.
نظرة عامة على الـ API
#
ينشئ نموذج «الدفع عبر رابط» رابط دفع مستضافًا آمنًا. يُدخل حامل البطاقة بياناته على صفحة الساقي المستضافة، مما يُبقيك خارج نطاق امتثال PCI.
المورد
الطريقة
المسار
إنشاء رمز
POST
/api/Auth/CreateAccessToken
إنشاء رابط
POST
/api/Payment/generate-payment-link/{client_id}
التحقق من الحالة
POST
/api/Payment/CheckPaymentStatus
التحقق عبر RequestId
POST
/api/Payment/CheckPaymentStatusByRequestId
إنشاء رمز الوصول
#
POST
https://pg-t2.alsaqi.net/api/Auth/CreateAccessToken
نسخ
ينشئ رمز وصول JWT للعميل، ويُعيد معه clientId. يجب إرسال الرمز كترويسة Bearer على نقاط النهاية المحميّة.
جسم الطلب
الحقل
الإلزام
النوع
الوصف
UserName
إلزامي
string
اسم مستخدم العميل.
Password
إلزامي
string
كلمة مرور العميل.
ExpireDuration
اختياري
number
مدّة صلاحية الرمز بالدقائق. الافتراضي 1440 (24 ساعة).
الطلب
cURL
JavaScript
Python
نسخ
curl -X POST https://pg-t2.alsaqi.net/api/Auth/CreateAccessToken \
-H "Content-Type: application/json" \
-d '{
"UserName": "client_username",
"Password": "client_password",
"ExpireDuration": 1440
}'
const res = await fetch("https://pg-t2.alsaqi.net/api/Auth/CreateAccessToken", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
UserName: "client_username",
Password: "client_password",
ExpireDuration: 1440
})
});
const data = await res.json();
// store data.access_token and data.clientId
console.log(data.access_token, data.clientId);
import requests
res = requests.post(
"https://pg-t2.alsaqi.net/api/Auth/CreateAccessToken",
json={
"UserName": "client_username",
"Password": "client_password",
"ExpireDuration": 1440,
},
)
data = res.json()
print(data["access_token"], data["clientId"])
200 — نجاح
{
"access_token": "ACCESS_TOKEN_STRING",
"clientId": 29
}
الأخطاء
الحالة
الاستجابة
Client inactive
{ "status": false, "message": "Client is not active. Please contact support." }
Invalid credentials
{ "status": false, "message": "Please provide valid credentials" }
إنشاء رابط الدفع
#
POST
https://pg-t2.alsaqi.net/api/Payment/generate-payment-link/{client_id}
نسخ
ينشئ رابط دفع مستضافًا للعميل. يتطلّب رمز Bearer؛ ويجب أن يطابق {client_id} قيمة clientId المضمّنة في الرمز.
معاملات الرابط
الحقل
الإلزام
النوع
الوصف
client_id
إلزامي
number
معرّف العميل المُعاد من واجهة إنشاء رمز الوصول.
جسم الطلب
الحقل
الإلزام
النوع
الوصف
RequestId
إلزامي
string
معرّف الطلب الفريد.
InvoiceId
اختياري
string
قابل لإعادة الاستخدام بين المحاولات، إلا إذا بلغت العملية حالة Approved أو Unknown — فعندها يُمنع إعادة استخدامه.
amount
إلزامي
decimal
المبلغ المطلوب دفعه.
Currency
إلزامي
string
رمز العملة (مثل IQD).
successUrl
إلزامي
string
يُوجَّه العميل إلى هذا الرابط بعد نجاح الدفع، كما هو دون إضافة أي معاملات. يمكن للتاجر إضافة رقم الطلب إلى الرابط.
failUrl
إلزامي
string
يُوجَّه العميل إلى هذا الرابط بعد فشل الدفع، كما هو دون إضافة أي معاملات.
linkExpireMinutes
اختياري
integer
مدّة انتهاء الرابط بالدقائق. الافتراضي 30.
الطلب
cURL
JavaScript
Python
نسخ
curl -X POST https://pg-t2.alsaqi.net/api/Payment/generate-payment-link/1024 \
-H "Authorization: Bearer ACCESS_TOKEN_STRING" \
-H "Content-Type: application/json" \
-d '{
"RequestId": "REQ-987654321",
"InvoiceId": "INV-00021",
"amount": 25000,
"Currency": "IQD",
"successUrl": "https://example.com/success",
"failUrl": "https://example.com/fail",
"linkExpireMinutes": 60
}'
const res = await fetch(
`https://pg-t2.alsaqi.net/api/Payment/generate-payment-link/${clientId}`,
{
method: "POST",
headers: {
"Authorization": `Bearer ${accessToken}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
RequestId: "REQ-987654321",
InvoiceId: "INV-00021",
amount: 25000,
Currency: "IQD",
successUrl: "https://example.com/success",
failUrl: "https://example.com/fail",
linkExpireMinutes: 60
})
}
);
const { paymentLink } = await res.json();
// redirect the customer to paymentLink
import requests
res = requests.post(
f"https://pg-t2.alsaqi.net/api/Payment/generate-payment-link/{client_id}",
headers={"Authorization": f"Bearer {access_token}"},
json={
"RequestId": "REQ-987654321",
"InvoiceId": "INV-00021",
"amount": 25000,
"Currency": "IQD",
"successUrl": "https://example.com/success",
"failUrl": "https://example.com/fail",
"linkExpireMinutes": 60,
},
)
print(res.json()["paymentLink"])
200 — نجاح
{
"status": true,
"paymentId": "e6e6fdd0-15a3-4782-9d0d-d1996cda99fe",
"requestId": "REQ-987654321",
"invoiceId": "INV-00021",
"expiry": "2026-06-05T12:51:52.77+03:00",
"amount": 25000,
"stanID": "672691",
"paymentLink": "https://pg-t.alsaqi.net/e6e6fdd0-15a3-4782-9d0d-d1996cda99fe"
}
الأخطاء
الحالة
الرسالة
RequestId already taken
RequestId REQ-987654321 is already taken
InvoiceId already taken
بلغ InvoiceId حالة نهائية (Approved/Unknown) ولا يمكن إعادة استخدامه أبدًا.
InvoiceId under process
يوجد رابط فعّال لهذا InvoiceId. انتظر حتى يكتمل أو ينتهي.
التحقق من حالة الدفع
#
POST
https://pg-t2.alsaqi.net/api/Payment/CheckPaymentStatus
نسخ
POST
https://pg-t2.alsaqi.net/api/Payment/CheckPaymentStatusByRequestId
نسخ
يُعيد الحالة الحالية للدفع. يتطلّب رمز Bearer. يمكنك الاستعلام عبر paymentId أو RequestId أو InvoiceId.
أمّا نقطة النهاية الثانية CheckPaymentStatusByRequestId فمخصّصة للاستعلام عبر RequestId، وتُعيد الاستجابة نفسها.
الطلب — أي معرّف واحد
PaymentId
RequestId
InvoiceId
نسخ
{ "PaymentId": "4e8185b2-8134-4bc7-aca4-59ee87a45910" }
{ "RequestId": "REQ-987654321" }
{ "InvoiceId": "INV-00021" }
حقول الاستجابة
الحقل
النوع
الوصف
status
boolean
نجحت العملية (true) أو فشلت (false).
linkStatus
integer
رمز الحالة الحالي — راجع مرجع حالات الرابط.
message
string
وصف نصّي مقروء للحالة.
paymentId
string
معرّف رابط الدفع الفريد الذي تنشئه البوابة.
requestId
string
معرّف الطلب الفريد الذي أرسله العميل.
invoiceId
string
معرّف الفاتورة. قابل لإعادة الاستخدام إلا إذا كانت العملية Approved/Unknown.
rrn
string
الرقم المرجعي للاسترجاع من المعالج.
cardMasked
string
رقم البطاقة المُقنّع المستخدم في العملية.
cardHolderName
string
اسم حامل البطاقة المُعاد من العملية.
expiry
datetime
تاريخ/وقت انتهاء رابط الدفع.
paidDate
datetime
وقت اكتمال الدفع. فارغ إذا لم يُدفع.
createDate
datetime
وقت إنشاء رابط الدفع.
totalAmount
decimal
إجمالي مبلغ الدفع.
respCode
string
رمز استجابة المعالج (00 = مقبول؛ Z1/Z4 = انتهاء المهلة).
errorMessage
string
رسالة الرفض/الخطأ من المعالج، إن وجدت.
isReversal
boolean
يظهر عند وجود محاولة دفع: true إذا عُكست العملية تلقائيًا، وعندها تصبح الحالة Unknown (8).
أمثلة الاستجابة
#
linkStatus 2 · Approved
{
"status": true,
"linkStatus": 2,
"message": "Approved",
"paymentId": "170acac1-3eb9-498c-8623-845139eb204a",
"requestId": "ZO-1780503160412-1020",
"rrn": "000030614276",
"cardMasked": "403208******2567",
"cardHolderName": "GDGBDHFHFN",
"expiry": "2026-06-17T16:32:40.49",
"paidDate": "2026-06-03T19:12:52.863",
"createDate": "2026-06-03T19:12:40.49",
"totalAmount": 1,
"respCode": null,
"errorMessage": null
}
linkStatus 4 · Declined
{
"status": false,
"linkStatus": 4,
"message": "Declined",
"paymentId": "fee05441-0c8c-414a-a756-b532629cb9d3",
"requestId": "ZO-1779611550221-821",
"invoiceId": "test-0000350",
"rrn": "000030617015",
"cardMasked": "403208******2567",
"cardHolderName": "AHMED ALI",
"expiry": "2026-06-07T08:52:30.257",
"paidDate": "2026-05-24T11:35:11.933",
"createDate": "2026-05-24T11:32:30.257",
"totalAmount": 1,
"respCode": "AB",
"errorMessage": "رمز CVV2 غير صالح",
"isReversal": false
}
الاسترجاع والعكس
#
الاسترجاع اليدوي
#
لا يمكن استرجاع المبلغ عبر الـ API. لاسترجاع مبلغ عملية مكتملة، يتواصل التاجر مع دعم الساقي ويرسل paymentId و rrn.
السيناريو
السلوك
عملية دفع مكتملة
عبر دعم الساقي
رموز الأخطاء والحالات
#
مرجع حالات الرابط
#
يُطابِق حقل linkStatus في كل استجابة حالة إحدى القيم التالية.
القيمة
الحالة
الوصف
0
Invalid
لا يوجد دفع لهذا المعرّف، أو الرابط غير صالح.
1
Pending
الدفع قيد التنفيذ؛ لم يكمله العميل بعد.
2
Approved
اكتمل الدفع وقُبِل بنجاح.
3
Expired
انتهى الرابط قبل أن يدفع العميل.
4
Declined
رُفِض الدفع.
5
Error
حدث خطأ في البوابة أو المعالجة.
6
NotPaid
لم يكتمل الدفع.
7
Timeout
انتهت مهلة الاتصال قبل النتيجة النهائية.
8
Unknown
الحالة غير معروفة أو ما تزال قيد التحقق.
رموز استجابة المعالج الشائعة
#
respCode
المعنى
00
مقبول.
31
الجهة المصدرة غير متاحة.
AB
رمز CVV2 غير صالح.
68
انتهت مهلة العملية.
Z1 / Z4
انتهاء مهلة المضيف/الاتصال.
تعامل مع Timeout (7) و Unknown (8) كحالات غير نهائية. أعد الاستعلام عن الحالة قبل إعادة المحاولة لتجنّب تحصيل العميل مرّتين.
مجموعة Postman
#
يُحمِّل التاجر المجموعة من الزر أسفل هذا القسم ويستوردها إلى Postman، ثم يُدخل userName و password في تبويب «Variables». باقي القيم تُنسخ من الاستجابات كما في الجدول التالي.
متغيّرات المجموعة
المتغيّر
القيمة
baseUrl
https://pg-t2.alsaqi.net
userName
يُدخَل يدويًا: اسم المستخدم الخاص بك
password
تُدخَل يدويًا: كلمة المرور الخاصة بك
accessToken
انسخه من access_token في استجابة Generate Access Token
clientId
انسخه من clientId في استجابة Generate Access Token
paymentId
انسخه من paymentId في استجابة Generate Link
requestId
انسخه من requestId في استجابة Generate Link (لطلب Check Payment Status By RequestId)
المصادقة مضبوطة مسبقًا في المجموعة؛ يكفي وضع رمز الوصول في المتغيّر accessToken. ويُنشأ RequestId جديد تلقائيًا مع كل طلب Generate Link.
تحميل مجموعة Postman
سجل التغييرات والتحديثات
#
الإصدار
التاريخ
التغييرات
v1.0
2025
الإصدار الأول: الدفع عبر رابط مستضاف، ومصادقة JWT، والتحقق من حالة الدفع.