انتقل إلى المقال
Aniq-UI

Food Studioالمدفوعات

المدفوعات

كيف تستقبل صفحة إتمام الطلب الدفع، وكيف تربط Stripe أو PayPal، وما يحدث للطلب في كل خطوة.

لحزمة الحزمة الكاملة

كيف تستلم صفحة إتمام الشراء الدفع

يدفع العميل على صفحة المزوّد نفسه، Stripe Checkout أو PayPal، لذلك لا يرى الموقع ولا واجهة API رقم البطاقة أبدًا. تحسب واجهة API سعر الطلب بنفسها، من قائمتها ورسومها وخصوماتها، ولا تعتمد أبدًا على الأسعار التي يرسلها المتصفح.

الطريقةيُعرض عندماما يحدث
الدفع بالبطاقة (Stripe)يكون STRIPE_SECRET_KEY مضبوطًايُحفظ الطلب غير مدفوع ويذهب المتصفح إلى صفحة Stripe. يصبح الطلب مدفوعًا بعد أن تسأل واجهة API منصة Stripe عمّا حدث ويتطابق المبلغ.
PayPalيكون PAYPAL_CLIENT_ID وPAYPAL_CLIENT_SECRET مضبوطينالأمر نفسه، على صفحة PayPal: تحصّل واجهة API الدفعة الموافق عليها قبل أن يُعدّ الطلب مدفوعًا.
الدفع التجريبيلا يوجد مزوّد مضبوطيجعل الطلب مدفوعًا من دون تحويل أي مال، حتى يمكن تجربة المسار كاملًا محليًا. لا يُعرض أبدًا بجوار مزوّد مضبوط.

يمكن للزوار إتمام الطلب باسمهم وبريدهم الإلكتروني؛ ويرى العملاء المسجّلون الطلب في حساباتهم. ينتقل الطلب المدفوع إلى قائمة انتظار المطبخ؛ ولا يستطيع الفريق تأكيد الطلب غير المدفوع.

الأسعار بالدولار الأمريكي. يكلّف التوصيل $2.99 والاستلام مجاني في الإعدادات التجريبية، مع حد أدنى للتوصيل قدره $10.00. لا يوجد سطر ضريبة منفصل: يدفع العميل أسعار القائمة مع الرسوم، ناقص أي خصم. يغيّر الفريق الرسوم في لوحة التحكم، من «الإعدادات»، ثم «المطعم»، حيث تُعرض أيضًا طرق الدفع التي يوفرها هذا البناء وما إذا كانت كل منها تعمل في الوضع التجريبي أو الحقيقي.

اربط Stripe

  1. أضف مفتاحك السري

    من صفحة مفاتيح API في لوحة تحكم Stripe، ضع المفتاح السري في ملف .env الخاص بواجهة API. استخدم مفتاحًا تجريبيًا (sk_test_…) حتى تكون مستعدًا لاستقبال أموال حقيقية: فهو لا يحوّل أي مال.

    ملف .env الخاص بواجهة API
    STRIPE_SECRET_KEY=sk_test_…
  2. اشترك في webhook

    في Stripe، أضف نقطة نهاية webhook على عنوان واجهة API الخاصة بك متبوعًا بـ /api/payments/webhooks/stripe، مشتركة في checkout.session.completed وcheckout.session.expired وcharge.refunded وcharge.dispute.created. انسخ سر التوقيع الخاص بها إلى ملف .env الخاص بواجهة API.

    ملف .env الخاص بواجهة API
    STRIPE_WEBHOOK_SECRET=whsec_…
  3. تحقق من عناوين العودة

    يعيد Stripe المتصفح إلى API_PUBLIC_URL، وترسله واجهة API بعد ذلك إلى الموقع على STOREFRONT_URL. محليًا تعمل القيمتان الافتراضيتان. على نطاقاتك الخاصة، اضبط الاثنين على العناوين الحقيقية.

  4. أعد تشغيل واجهة API

    النتيجة المتوقعة: تعرض صفحة إتمام الطلب «الدفع بالبطاقة»، ويظهر في «الإعدادات»، ثم «المطعم»، ثم «الدفع» كطريقة معروضة، في الوضع التجريبي.

لا تحتاج إلى المفتاح القابل للنشر (publishable key): يتم الدفع على صفحة Stripe نفسها. لاختبار الـ webhook على جهازك، يمكن لـ Stripe CLI تمرير الأحداث إلى http://localhost:8000/api/payments/webhooks/stripe، ويطبع سر التوقيع الذي تستخدمه أثناء عمله.

اربط PayPal

  1. أضف بيانات اعتماد تطبيقك

    من لوحة مطوّري PayPal، انسخ معرّف العميل (client id) والسر الخاصين بتطبيقك إلى ملف .env الخاص بواجهة API. قيمة PAYPAL_ENV الافتراضية هي sandbox، التي لا تحوّل أي مال؛ أما live فتستقبل مدفوعات حقيقية.

    ملف .env الخاص بواجهة API
    PAYPAL_CLIENT_ID=your-paypal-sandbox-client-id
    PAYPAL_CLIENT_SECRET=your-paypal-sandbox-client-secret
    PAYPAL_ENV=sandbox
  2. اشترك في webhook

    أضف webhook على عنوان واجهة API الخاصة بك متبوعًا بـ /api/payments/webhooks/paypal، مع أحداث تحصيل الدفع: مكتمل، ومرفوض، ومسترد، ومعكوس. انسخ معرّف الـ webhook إلى ملف .env الخاص بواجهة API: تتحقق واجهة API من كل استدعاء بمقارنته به.

    ملف .env الخاص بواجهة API
    PAYPAL_WEBHOOK_ID=your-paypal-webhook-id
  3. أعد تشغيل واجهة API

    النتيجة المتوقعة: تعرض صفحة إتمام الطلب PayPal.

ما يحدث للطلب

الحدثالطلب
يرسله العميليُحفظ قيد الانتظار وغير مدفوع. يحجز مخزونه وأي نقاط مكافآت استبدلها العميل.
يؤكد المزوّد الدفعمدفوع، بعودة العميل أو بالـ webhook، أيهما يصل أولًا. عودة المتصفح وحدها لا تجعل الطلب مدفوعًا أبدًا: تسأل واجهة API المزوّد أولًا.
يغادر العميل صفحة الدفعيُتحقق منه لدى المزوّد بعد 35 دقيقة لـ Stripe و3 ساعات لـ PayPal، ثم يُلغى كدفع فاشل، ويُعاد مخزونه ونقاطه.
يُبلغ المزوّد عن استرداد كاملمُسترد، وتُسحب النقاط التي اكتسبها. الاسترداد الجزئي في Stripe يُسجَّل ويبقى الطلب كما هو.

الدفعة التي تصل لطلب أُلغي من قبل تُسجَّل على أنها تحتاج إلى استرداد ولا تعيد الطلب أبدًا. لا يستطيع الفريق جعل الطلب مُستردًا يدويًا: يتم الاسترداد في Stripe أو PayPal، ويحدّث الـ webhook الطلب.

الدفع التجريبي

  • من دون أي مزوّد مضبوط، تعرض صفحة إتمام الطلب «دفع تجريبي» و«أرسل الطلب التجريبي». يصبح الطلب مدفوعًا فورًا، من دون تحويل أي مال، حتى يمكن تجربة قائمة انتظار المطبخ وصفحة التتبّع من البداية إلى النهاية.
  • بمجرد ضبط Stripe أو PayPal، يختفي الدفع التجريبي، ويُرفض أي طلب يطلبه.
  • الـ webhook الخاص بالدفع التجريبي، POST /api/payments/webhooks/demo، يرفض كل استدعاء ما لم يكن PAYMENT_WEBHOOK_SECRET مضبوطًا ومرسلًا في الترويسة x-webhook-secret.

استلام مدفوعات حقيقية

  • ضع المفاتيح الحقيقية (sk_live_…، أو تطبيق PayPal الحقيقي مع PAYPAL_ENV=live) و webhook منشأً في الوضع الحقيقي، وله سر توقيع أو معرّف خاص به.
  • اضبط API_PUBLIC_URL وSTOREFRONT_URL على عناوينك الحقيقية، وأضف الموقع إلى CORS_ORIGIN: عنوان العودة الذي ليس فيه يُرفض.
  • تعرض «الإعدادات»، ثم «المطعم»، ثم «الدفع» كل طريقة على أنها «مباشر، أموال حقيقية» بمجرد أن تعمل ببيانات اعتماد حقيقية.
  • المبالغ بالدولار الأمريكي في كل مكان: تحصّل واجهة API بالعملة CURRENCY من back-end/src/common/constants/ordering.constants.ts، وتعرض الواجهتان الأماميتان الأسعار بالدولار. استخدام عملة أخرى يتطلب تعديل الكود في واجهة API والواجهات الأمامية، مع ضبط NEXT_PUBLIC_ANALYTICS_CURRENCY بما يطابقها.

توقفت عند خطوة؟

ابحث عن الحل قبل أن تبدأ من جديد.

حل المشكلات

تفضيلات ملفات تعريف الارتباط

نستخدم ملفات تعريف الارتباط لتعزيز تجربة التصفح الخاصة بك وتحليل حركة المرور على الموقع وتخصيص المحتوى. بالنقر على "قبول الكل"، فإنك توافق على استخدامنا لملفات تعريف الارتباط للتحليلات والإعلانات المخصصة.