الانتقال إلى المحتوى الرئيسي
كل المقالات
تقني10 دقائق قراءة

الدفع المباشر: بناء نموذج البطاقة الخاص بكم عبر API في أربعة نداءات

الدفع المباشر عبر API: نموذج بطاقة خاص بكم في أربعة نداءات، موثَّقة بالجلسة ومفتاح vk، مع عودة ‎3-D Secure وما يترتب عن ذلك في امتثال PCI DSS.

الدفع المباشر هو الخيار الذي يتيح لكم بناء نموذج البطاقة الخاص بكم بدل إعادة توجيه المشتري إلى صفحة الدفع المستضافة. ويقوم على أربعة نداءات — التحقق من الجلسة، وإرسال البطاقة، وتأكيد عودة ‎3-D Secure، وقراءة حالة الأداء — تُوثَّق بالجلسة ومفتاح التحقق لمرة واحدة، لا بمفتاح API الخاص بكم أبدًا. وله ثمن ينبغي النظر إليه بوضوح: أنظمتكم تمرّ بها بيانات البطاقات، فتدخل نطاق امتثال PCI DSS. يشرح هذا الدليل متى يكون الدفع المباشر مبرَّرًا، وكيف تدمجونه خطوة بخطوة، وما الذي يغيّره بالنسبة إليكم.

الدفع المباشر في تعريف واحد

ChariPay منصة دفع مغربية، مزوّد خدمات دفع (PSP) تشغّله Chari Money، مؤسسة أداء مرخَّصة من بنك المغرب. وتعرض واجهتها البرمجية طريقتين لاستخلاص أداء بالبطاقة انطلاقًا من جلسة دفع.

يتيح لكم الدفع المباشر بناء نموذج البطاقة الخاص بكم: التحقق من الجلسة، وإرسال بيانات البطاقة، وعودة ‎3-D Secure، وحالة الأداء. ولا تُوثَّق هذه النداءات بمفتاح API الخاص بكم بل بالجلسة ومفتاح التحقق لمرة واحدة (vk) — فلا ترسلوا مفتاح API إليها أبدًا — وهي تُدخلكم في نطاق الامتثال الخاص ببيانات البطاقات.

والفرق مع صفحة الدفع المستضافة يُختصر في جملتين. مع الصفحة المستضافة، تعيدون توجيه المشتري إلى صفحة تديرها ChariPay، يُدخل فيها بطاقته ويجتاز ‎3-D Secure، فلا ترون الرقم أبدًا. ومع الدفع المباشر، نموذجكم أنتم هو الذي يستقبل البطاقة، وخادمكم هو الذي ينفّذ، من خادم إلى خادم، النداءات الأربعة الموصوفة أسفله.

نموذج بطاقة خاص بكم أم صفحة مستضافة: جدول القرار

الدفع المباشر لا معنى له إلا إذا كان لديكم سبب محدد لعدم استعمال الصفحة المستضافة. وقبل كتابة أي سطر شفرة، قارنوا نقطة بنقطة.

المعيارصفحة الدفع المستضافةالدفع المباشر
من يرى رقم البطاقةلا أحد من جهتكم: يُدخله الزبون في الصفحة المستضافةنموذجكم وكل نظام تمرّ به البيانات
نطاق الامتثالنطاق المنصة الحاصل على شهادة PCI DSS المستوى 1؛ ويُختصر استبيانكم، وهو ما يُؤكَّد مع مستشاركم أو جهة الاقتناء لديكمتدخلون نطاق الامتثال الخاص ببيانات البطاقات
عمل الدمجإنشاء الجلسة، وإعادة التوجيه، واستلام الويب هوكإنشاء الجلسة، ثم برمجة أربعة نداءات وصيانتها، مع الأخطاء وعودة ‎3-D Secure
التخصيصconfig.frontend: المظهر، والشعار، واسم المؤسسةنموذجكم، بالكامل
‎3-D Secureتتولاه الصفحةتتولونه أنتم: إعادة التوجيه ثم تأكيد العودة
تأكيد الطلبيةويب هوك موقَّعويب هوك موقَّع، كما مع الصفحة المستضافة

وإن كان كل ما تحتاجونه ألوانكم وشعاركم، فالصفحة المستضافة تلبّي ذلك أصلًا: جلسة الدفع تأخذ ألوانكم وشعاركم. أما الأسباب التي تبرّر الدفع المباشر فأندر: مسار دفع مدمج كليًا في منتجكم مثلًا، مع فريق مستعد لتحمّل الامتثال المرافق له. وإن كنتم ما زلتم تقارنون بين رابط الدفع والجلسة، فالمقارنة في رابط دفع أم صفحة دفع؛ ولتطبيق iOS أو Android، فالبنية الموصى بها مشروحة في الدفع داخل تطبيق الهاتف.

هل ما زال لديكم سبب محدد؟ جرّبوا النداءات الأربعة في السندبوكس قبل أن تقرّروا، وقارنوها بالصفحة المستضافة في الحساب نفسه: ابدؤوا في وضع الاختبار. ثلاثة حقول (الاسم، والبريد الإلكتروني المهني، والمؤسسة)، ورابط تفعيل يصلكم بالبريد لاختيار كلمة المرور، ثم بوابة التاجر حيث تنشئون بأنفسكم مفتاح الاختبار بعد إعادة مصادقة؛ ولا يُعرض المفتاح كاملًا إلا مرة واحدة. ادفعوا ببطاقة الاختبار ‎4918 9141 0719 5005، CVV 123، وأي تاريخ انتهاء مستقبلي، ورمز ‎3-D Secure 555: هذه البطاقة هي الوحيدة المقبولة، ولا يتحرك أي مال حقيقي. الأمر مجاني، بلا حد زمني ودون موافقة تنتظرونها.

قبل كل شيء: جلسة ينشئها خادمكم

الدفع المباشر لا يعوّض جلسة الدفع، بل يستهلكها. تتحول الطلبية إلى جلسة: تنشئون الجلسة من جهة الخادم، بمفتاح API الخاص بكم، عبر POST /v1/payment-sessions — المبلغ، وorderId، وبيانات الزبون، وعناوين العودة والإشعار، وmetadata. ويحمل الرد (201، أو 200 عند إعادة الإرسال بالـexternalId نفسه) خمسة حقول لا غير:

json
{
  "sessionId": "ps_5Kd0Rn",
  "sessionToken": "st_…",
  "verifyKey": "vk_5Kd0Rn",
  "expiresAt": "2026-10-05T10:15:00Z",
  "checkoutUrl": "https://…/checkout/ps_5Kd0Rn"
}

مع الصفحة المستضافة كنتم ستعيدون توجيه المشتري إلى checkoutUrl. أما مع الدفع المباشر فتحتفظون بقيمتين: sessionId وverifyKey، الذي ينتظره POST /checkout/verify باسم vk. ويبقى مفتاح API في خادمكم، وخادمكم أيضًا هو الذي ينفّذ نداءات /checkout/*، من خادم إلى خادم: يستقبل نموذجكم البطاقة وينقلها إلى خادمكم. ولكل جلسة مدة حياة محدودة — 72 ساعة افتراضيًا، وexpiresAt لتقصيرها — ولا تُستهلك إلا مرة واحدة، ما لم تنشئوها قابلة لإعادة الاستعمال (singleUse: false).

النداءات الأربعة بالترتيب

تفصّل وحدة «الدفع المباشر» في توثيق API كل نداء. وهذا تسلسلها، على العنوان الأساسي الوحيد https://api-psp.charipay.ma.

  1. 1التحقق من الجلسة — POST /checkout/verify، مع sessionId وvk في متن الطلب. يعطيكم الرد سياق العرض: المبلغ، والعملة، وعناصر الهوية البصرية، وتاريخ الانتهاء. وهذا النداء إلزامي قبل أي إرسال للبطاقة؛ وفي جلسة لاستعمال واحد، يُستهلك vk بهذا التحقق الأول.
  2. 2إرسال البطاقة — POST /checkout/submit، مع sessionId وبيانات البطاقة. ويحمل الرد operationId وreference وstatus: إما حالة نهائية، وإما PENDING_3DS مرفوقة بـredirectionUrl.
  3. 3تأكيد عودة ‎3-D Secure — POST /checkout/return، مع sessionId وoperationId المتلقى في الخطوة 2، بعد أن ينهي المشتري المصادقة. ويعطيكم الرد الحالة النهائية وredirectUrl الخاص بالقبول أو الرفض في جلستكم.
  4. 4قراءة حالة الأداء — GET /checkout/payments/{reference}، للعرض. ويعطي الرد status وpaid والمبلغ والعملة، دون أي معطيات شخصية.
النداءالدورالتوثيقما تحتفظون به
POST /checkout/verifyفتح الجلسة للأداءsessionId وvkالمبلغ، العملة، الهوية البصرية، الانتهاء
POST /checkout/submitإرسال بيانات البطاقةجلسة سبق التحقق منها؛ وIdempotency-Key إن كانت الجلسة قابلة لإعادة الاستعمالoperationId، reference، status، redirectionUrl
POST /checkout/returnربط عودة ‎3-D SecuresessionId وoperationIdالحالة النهائية، redirectUrl
GET /checkout/payments/{reference}عرض الحالةبلا مفتاح ولا معطيات شخصيةstatus، paid

التحقق بـcurl:

bash
# No X-CHARI-PAY-API-KEY header: the session and its vk authenticate this call.
curl -X POST 'https://api-psp.charipay.ma/checkout/verify' \
  -H 'Content-Type: application/json' \
  -d '{
    "sessionId": "ps_5Kd0Rn",
    "vk": "vk_5Kd0Rn"
  }'

ولا ننشر عمدًا أي مثال لنداء submit: فهو الذي يحمل رقم البطاقة، ولا مكان له إلا في شفرة تتحكمون في امتثالها.

التوثيق: الجلسة ومفتاح vk، لا مفتاح API أبدًا

في الدفع المباشر، خادمكم هو الذي ينفّذ نداءات /checkout/*، من خادم إلى خادم؛ وفي صفحة الدفع المستضافة، تنفّذها صفحة الدفع الخاصة بـChariPay نفسها. وفي الحالتين تُوثَّق بالجلسة ومفتاحها vk، لا بمفتاح API الخاص بكم أبدًا: فهي الاستثناء من قاعدة الترويسة X-CHARI-PAY-API-KEY. والمفتاح سرّ: لا يوضع أبدًا في المتصفح، ولا في تطبيق محمول، ولا في مستودع git، ولا في لقطة شاشة.

وحين يفشل توثيق الجلسة، تجيب API بـ401 INVALID_TOKEN: vk غير صالح أو سبق استهلاكه في verify، أو إرسال بطاقة على جلسة لم يُتحقق منها أولًا. وثلاثة أجوبة أخرى تتعلق بدورة حياة الجلسة:

  • 410 SESSION_EXPIRED: تجاوزت الجلسة expiresAt الخاص بها؛ أنشئوا جلسة جديدة من جهة الخادم.
  • 409 SESSION_ALREADY_CONSUMED: الجلسة أُدّيت من قبل — لا ترسلوها مجددًا؛ ولأداء جديد أنشئوا جلسة جديدة، ولإرجاع المال استعملوا الاسترداد.
  • 409 SESSION_NOT_ACTIVE: الجلسة أُلغيت — أنشئوا جلسة جديدة إذا كانت الطلبية ما تزال واجبة الأداء.

وما ينتج هذه الحالات — مدة الحياة، وعودة المشتري، والإلغاء — مشروح في انتهاء جلسة الدفع والعودة منها.

عودة ‎3-D Secure والتأكيد عبر الويب هوك

تمرّ الأداءات بالبطاقة عبر مصادقة ‎3-D Secure: يؤكّد حامل البطاقة العملية لدى بنكه، وهو ما يحمي التاجر من معظم حالات عدم الأداء والنزاعات. ومع الدفع المباشر، تنظيم هذه اللحظة مسؤوليتكم.

  1. 1يجيب submit بـPENDING_3DS مع redirectionUrl: على المشتري فتحه ليصادق لدى بنكه.
  2. 2عند عودة المشتري، ينادي خادمكم POST /checkout/return بـsessionId وoperationId: فيحصل على الحالة النهائية وredirectUrl الواجب اتباعه.
  3. 3ولعرض النتيجة، اقرؤوا GET /checkout/payments/{reference}.

وما يعرضه المتصفح لا يكفي لتأكيد طلبية. أكّدوا الطلبية عند استلام الويب هوك، لا عند إعادة التوجيه وحدها: فإعادة التوجيه تعني أن المشتري عاد، لا أن الأداء قد تمّ. ويصل الويب هوك الموقَّع إلى نقطة استقبال الويب هوكس لديكم — وإلى عنوان الإشعار الخاص بالجلسة إن صرّحتم به —، تمامًا كما مع الصفحة المستضافة. واعثروا على طلبيتكم عبر metadata الخاص بكم، الذي يعود كما هو في الحدث؛ وبالنسبة إلى الجلسة، يحمل الحدث أيضًا orderId الخاص بكم.

Idempotency: لا إرسال مرتين أبدًا

نقرة مزدوجة على «ادفع»، أو انقطاع الاتصال في اللحظة الخطأ، أو مستخدم يعيد تحميل الصفحة: على الدفع المباشر أن يستخلص مرة واحدة مهما حدث. وترويسة Idempotency-Key مطلوبة في POST /checkout/submit لجلسة قابلة لإعادة الاستعمال (singleUse: false)، وموصى بها لجلسة لاستعمال واحد. وإعادة إرسال القيمة نفسها تعيد النتيجة الأولى؛ أما المفتاح نفسه مع متن مختلف فيجيب بـ409 IDEMPOTENCY_CONFLICT. وفي جلسة قابلة لإعادة الاستعمال، يجيب المفتاح الغائب أو المفرط الطول بـ400 INVALID_IDEMPOTENCY_KEY.

ثلاث قواعد عملية:

  • مفتاح لكل محاولة أداء، يُولَّد حين يرسل المشتري النموذج ويُحفظ إلى حين وصول الرد، لتُعاد به المحاولة كما هي بعد انقطاع الشبكة.
  • زر معطَّل منذ النقرة الأولى إلى حين رد submit.
  • إعادة إرسال لا إرسال جديد: بعد خطأ 5xx، أعيدوا الإرسال بالمفتاح نفسه؛ فأخطاء 5xx من جهتنا.

وكل الأخطاء تتبع الغلاف نفسه:

json
{
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "amount: must be greater than 0"
  },
  "correlationId": "b0c1e2d3-4f56-7890-abcd-ef0123456789"
}

اختبروا code لا message أبدًا: فالأول ثابت، والثاني قد يتغير. واحتفظوا بـcorrelationId في سجلاتكم، فهو يتيح للفريق العثور على طلب بعينه.

ما يغيّره الدفع المباشر في PCI DSS

PCI DSS هو معيار أمن بيانات البطاقات الذي ينشره PCI Security Standards Council، وقد وُضع، كما يصفه المجلس، لتعزيز أمن بيانات حسابات بطاقات الدفع وتشجيع الاعتماد الواسع لتدابير متّسقة لأمن البيانات في العالم كله. والمستوى الأول هو الأكثر تطلبًا.

المنصة حاصلة على شهادة PCI DSS المستوى 1 تُجدَّد كل سنة؛ وهي صفة للمنصة، لا لموقعكم. فمع الصفحة المستضافة، يُدخل زبونكم بطاقته في صفحة الدفع المستضافة، داخل نطاق حاصل على شهادة PCI DSS المستوى 1: لا ترون أبدًا رقم بطاقة، ويُختصر استبيان التقييم الذاتي الخاص بكم تبعًا لذلك — وهو ما يُؤكَّد مع مستشاركم أو جهة الاقتناء لديكم. أما مع الدفع المباشر فينقلب الوضع: نموذجكم يستقبل البطاقة، وأنظمتكم تنقلها، فتدخلون نطاق الامتثال الخاص ببيانات البطاقات. والالتزامات المترتبة على ذلك التزاماتكم، تُقيَّم مع مستشاركم قبل الانتقال إلى الإنتاج.

وتفاصيل هذا النطاق من جهة التاجر في معيار PCI DSS للتجار.

أسئلة شائعة

ما هو الدفع المباشر؟

هو طريقة استخلاص أداء بالبطاقة عبر نموذجكم الخاص، بدل إعادة توجيه المشتري إلى الصفحة المستضافة. وتتعاقب فيه أربعة نداءات: التحقق من الجلسة، وإرسال بيانات البطاقة، وعودة ‎3-D Secure، وحالة الأداء. وتُوثَّق هذه النداءات بالجلسة ومفتاح التحقق لمرة واحدة، وهي تُدخلكم في نطاق الامتثال الخاص ببيانات البطاقات.

ما الفرق بين الدفع المباشر وصفحة الدفع المستضافة؟

مع الصفحة المستضافة، يُدخل المشتري بطاقته في صفحة تديرها ChariPay، بألوانكم، ولا ترون الرقم أبدًا. ومع الدفع المباشر، نموذجكم هو الذي يستقبل البطاقة، وخادمكم هو الذي ينفّذ النداءات الأربعة، من خادم إلى خادم، مع عودة ‎3-D Secure والأخطاء. وفي الحالتين، تُؤكَّد الطلبية عند استلام الويب هوك الموقَّع.

هل يجب إرسال مفتاح API إلى نداءات الدفع المباشر؟

لا، أبدًا. نقاط النهاية /checkout/* تُوثَّق بالجلسة ومفتاح التحقق لمرة واحدة، أي vk، الذي يُعاد باسم verifyKey عند إنشاء الجلسة. وفي هذا المسار، لا يُستعمل مفتاح API إلا لإنشاء الجلسة من جهة الخادم. ولا ينبغي أن يظهر أبدًا في متصفح أو تطبيق محمول أو مستودع git أو لقطة شاشة.

هل يُلغي الدفع المباشر خطوة ‎3-D Secure؟

لا. تمرّ الأداءات بالبطاقة عبر مصادقة ‎3-D Secure، سواء كان النموذج نموذجكم أو الصفحة المستضافة. وحين يطلبها البنك، يجيب submit بـPENDING_3DS مع redirectionUrl على المشتري فتحه؛ وعند عودته ينادي خادمكم POST /checkout/return للحصول على الحالة النهائية. فعلى واجهتكم أن تحسب حساب هذا المرور عبر البنك.

هل يغيّر الدفع المباشر التزاماتي في PCI DSS؟

نعم. نموذجكم يستقبل بيانات البطاقة وأنظمتكم تنقلها: فتدخلون نطاق الامتثال الخاص ببيانات البطاقات. وشهادة PCI DSS المستوى 1 صفة للمنصة، لا لموقعكم. ومع الصفحة المستضافة يُختصر استبيان التقييم الذاتي الخاص بكم؛ أما مع الدفع المباشر فاطلبوا من مستشاركم تقييم التزاماتكم قبل الانتقال إلى الإنتاج.

ماذا يحدث إذا نقر الزبون مرتين على «ادفع»؟

مع Idempotency-Key في POST /checkout/submit، يعيد الإرسال الثاني النتيجة الأولى بدل الاستخلاص مرتين؛ والمفتاح نفسه مع متن مختلف يجيب بـ409 IDEMPOTENCY_CONFLICT. والترويسة مطلوبة في الجلسة القابلة لإعادة الاستعمال وموصى بها في غيرها. والجلسة التي أُدّيت من قبل تجيب بـ409 SESSION_ALREADY_CONSUMED. وعطّلوا الزر منذ النقرة الأولى.

ماذا يعني الخطأ 401 INVALID_TOKEN في الدفع المباشر؟

يعني أن الجلسة لم يمكن توثيقها. ففي POST /checkout/verify، يكون vk غير صالح أو سبق استهلاكه — وفي جلسة لاستعمال واحد لا يصلح إلا مرة. وفي POST /checkout/submit، لم يُتحقق من الجلسة مسبقًا. راجعوا ترتيب النداءات والقيمة المرسلة، أو أنشئوا جلسة جديدة من جهة الخادم.

الخطوة التالية

جرّبوا أولًا الصفحة المستضافة، التي تأخذ أصلًا ألوانكم وشعاركم، ثم الدفع المباشر في السندبوكس ببطاقة الاختبار: ابدؤوا في وضع الاختبار. وإن اعتمدتم الدفع المباشر، فاطلبوا من مستشاركم التحقق من نطاق PCI DSS الخاص بكم قبل الانتقال إلى الإنتاج. وسترافقكم وحدة «الدفع المباشر» في توثيق API ومعيار PCI DSS للتجار في ما بعد.

Sources

بقلم فريق ChariPay.

اقرؤوا بعده

دليل4 دقائق قراءة

رابط دفع أم صفحة دفع مدمجة — أيّهما تختارون

رابط الدفع أم صفحة الدفع المستضافة: طريقتان للتحصيل عبر الإنترنت وعبئا عمل مختلفان. المعايير التي تحسم فعلًا — الحجم، والمبلغ، والفريق، والتخصيص.

مستعدون للتجربة بأنفسكم؟

أنشئوا حسابكم واستخلصوا في وضع الاختبار اليوم: مجانًا، ودون موافقة تنتظرونها. سؤال؟ يجيب فريقنا التجّار والمطوّرين على حد سواء.

  • مجاني ودون التزام
  • وضع الاختبار منذ التسجيل
  • لا موافقة تنتظرونها