→ كل الشروحات

الشرح 4 / 12

أنشئ صفحة دفع وتحقق من الدفعة.

أنشئ الفواتير من الخادم الخلفي وعالج إشعارات الدفع بعد التحقق منها.

ما الذي ستحصل عليه

مسار دفع يعمل على الخادم مع حماية من التكرار وإعادة المحاولة.

1. جهّز المعرّفات وصلاحيات الوصول

ابدأ بمتجر مفعّل ووسائل دفع مختبرة. في الإعدادات ← الوصول إلى API، أنشئ بيانات اعتماد للقراءة والكتابة محصورة بالمشروع المطلوب. احتفظ بالرمز في خادمك الخلفي، لا في كود المتصفح أو مستودع عام.

انسخ معرّف API للمشروع و معرّف API للمتجر من قسم المتجر الأساسيات ← معرّفات API . هذه UUIDs، وليست معرّف المشروع المقروء أو رقم طلبك. استخدم اسم مضيف API الخاص بك.

في المتجر ← IPN، أنشئ سر توقيع قبل تحديد ipn_url. يجب أن يكون مستقبل HTTPS لديك قابلًا للوصول من خادم التاجر.

2. أنشئ فاتورة

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

curl --fail-with-body --request POST \
  'https://api.example.com/v1/projects/YOUR_PROJECT_ID/stores/YOUR_STORE_ID/invoices' \
  --header 'Authorization: Bearer YOUR_MERCHANT_API_TOKEN' \
  --header 'Content-Type: application/json' \
  --header 'Idempotency-Key: order-1042-attempt-1' \
  --data '{
  "amount": "10.00",
  "currency": "EUR",
  "order_id": "order-1042",
  "description": "Example order",
  "ipn_url": "https://shop.example.com/payments/wholly-ipn",
  "metadata": {
    "cart_id": "cart-1042"
  }
}'

احفظ data.invoice_id مع طلبك، ثم وجّه العميل إلى links.checkout. استخدم مفتاح عدم تكرار فريدًا لمحاولة دفع جديدة. عند انتهاء مهلة الطلب، أعد المحاولة باستخدام بيانات الاعتماد والمفتاح وبايتات محتوى الطلب نفسها تمامًا.

عدم تضمين payment_methods يستخدم الوسائل المقبولة في المتجر. يمكنك تقليصها لكل فاتورة باستخدام معرّفات الشبكات والرموز المختصرة، لكن ذلك لا يفعّل أصلًا غير مقبول أبدًا. كل حقول الطلب وأمثلة الاستجابة ←

3. اختر IPN أوwebhooks أوكليهما

IPN يتابع دورة حياة الفاتورة. حدد عنوان IPN الافتراضي للمتجر أو تجاوزه باستخدام ipn_url لفاتورة معينة. Webhooks تُشرك نقطة نهاية في أحداث مختارة، مثل invoice.settled.

يستخدمان صيغة التوقيع نفسها، لكن أسرارًا مختلفة: يستخدم IPN سر IPN الخاص بالمتجر، ولكل نقطة webhook سرها الخاص. لا يستخدم أيهما رمز API من نوع Bearer للتوقيع.

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

4. تحقق من الإشعار واحفظه

  1. اقرأ بايتات محتوى الطلب الخام كما هي قبل تحليل JSON. تحقق من Wholly-Signature بالسر المطابق مع فحوص الطابع الزمني ومنع إعادة التشغيل. توفر حزم SDK الرسمية أدوات تحقق.
  2. تحقق من هوية المشروع والمتجر والفاتورة والحدث في المحتوى الموقّع. ترويسات التسليم غير الموقّعة ليست مصدر مصادقة.
  3. احفظ الحدث بشكل دائم مع قيد فريد على event_id، ثم أرجع HTTP 2xx سريعًا. عالج الطلبات في عامل خلفي.
  4. اجلب الفاتورة الحالية من مضيف API الذي أعددته، لا من مضيف عشوائي يرد في طلب. قارن المشروع والمتجر والمبلغ والعملة ومرجع الطلب التي حفظتها.

PHP · Python · JavaScript / TypeScript · مواصفات التوقيع وأمثلة المستقبل

5. نفّذ الطلب مرة واحدة عند التسوية

في مستقبل يعتمد على الأحداث ، عالج event_type = invoice.settled، ثم تحقق من الحالة الحالية status = settled وسياسة الحالات الاستثنائية لديك. نفّذ الطلب مرة واحدة ضمن معاملة قاعدة بيانات أو قيد فريد للطلب.

نوع الحدث والحالة شيئان مختلفان

قد ترسل شبكة سريعة الإنهاء كلا الحدثين payment.received و invoice.settled مع status = settled. على شبكة أخرى، قد يظل payment.received بحالة processing. كلا المسارين صحيح.

امنع تكرار الأحداث باستخدام event_id، لا التسلسل وحده: قد تشترك أنواع أحداث مختلفة في تسلسل واحد. أما معالجات SDK القائمة على الحالة فتدمج مراجعات الفاتورة وتتحقق من الحالة بغض النظر عن نوع الحدث. لا تجمع هذا الدمج مع مرشح لنوع الحدث. كلا النهجين يحتاج أيضًا إلى حماية من التكرار على مستوى الطلب.

افحص requires_review والحلول اليدوية قبل تنفيذ الطلب. amount_status = paid وحدها لا تثبت التأكيد. تلخص حقول الأصل المدفوع في المستوى الأعلى التسوية، بينما payment_info يحتوي تفاصيل الاستلام وبيانات عرض السعر. كل الحالات والأحداث وقواعد الحالات الاستثنائية ←

6. اختبر إعادة المحاولة والاستعادة

اختبر دفعة صغيرة وتسليمًا مكررًا وفاتورة منتهية ومستقبلًا غير متاح مؤقتًا. يجب ألا تضيف إعادة تشغيل حدث رصيدًا ثانيًا للطلب. عالج الأحداث التي تصل بغير ترتيبها دون الكتابة فوق حالة أحدث.

افحص المتجر ← IPN / Webhooks ← السجل ← التفاصيل، أو أقسام التسليم في تفاصيل الفاتورة. تعيد إعادة الإرسال استخدام الحدث المسجل، ولا تنشئ تسوية جديدة.

يوقف انخفاض رصيد المعالجة IPN/webhooks مؤقتًا بينما تستمر المدفوعات. طابق الطلبات المعلّقة عبر API وعالج التسليمات المحتفظ بها بعد التعافي. لا تنفّذ طلبًا اعتمادًا على إعادة توجيه المتصفح أو لقطة شاشة من العميل.