المستندات / إعداد المدفوعات — والخطوة الواحدة التي تُضيّع المال بصمت

إعداد المدفوعات — والخطوة الواحدة التي تُضيّع المال بصمت

بيانات اعتماد الدفع من جهة الخادم فقط: تعيش في .env على جهازك ولا في قاعدة البيانات أبدًا، ولا في نموذج، ولا في هذه اللوحة. هذا عمدي. ما يلي هو أين تذهب كل قيمة — والخطوة الواحدة التي يسهل تفويتها وتفويتها مكلف.

الخطوة التي تكلّف المال إن تخطّيتها

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

لذا تكتمل عملية الشراء باتّصال المزوّد بخادمك — webhook — ولا شيء غيره.

إن لم يصل ذلك الاتصال أبدًا:

  • يصلك مال المشتري،
  • ولا يُصدَر ترخيصهم أبدًا،
  • ويجلس الطلب عند "معلّق"،
  • ولا شيء في أي مكان يقول لماذا.

هذه ليست حالة حافّة نادرة. على الطرق الإندونيسية إنها المسار الطبيعي.

أين تحصل كل بوّابة على عنوان URL الخاص بها

المزوّد عنوان URL للـ webhook من يضبطه
Xendit https://yourdomain/webhooks/xendit أنت، يدويًا، مرة واحدة
PayPal (لا شيء) غير مطلوب — يكتمل عند العودة

يكتمل PayPal حين يعود المشتري، فلا يحتاج webhook إطلاقًا. Xendit هي التي تحتاجك — انظر أدناه.

Xendit هي التي تحتاجك. رد اتصال "invoice paid" الخاص بها على مستوى الحساب كله، لا لكل فاتورة، فيُضبَط مرة واحدة في لوحة Xendit نفسها.

Xendit، نقرة بنقرة

  1. سجّل الدخول في dashboard.xendit.co.
  2. Settings → Developers → Webhooks.
  3. تحت Invoices paid، الصق عنوان URL الذي تُظهره صفحة المسؤول لديك لـ Xendit (https://yourdomain/webhooks/xendit).
  4. احفظ، وانسخ رمز التحقق من webhook المعروض على الصفحة نفسها.
  5. ضع ذلك الرمز في .env لخادمك كـ XENDIT_CALLBACK_TOKEN، إلى جانب XENDIT_SECRET_KEY.
  6. أعِد تشغيل الموقع كي تُقرأ القيم الجديدة.

كلا النصفين مطلوب. عنوان URL دون الرمز يعني أن التسليمات تصل وتُرفَض؛ والرمز دون عنوان URL يعني ألّا يصل شيء إطلاقًا.

إثبات أنها تعمل فعلًا

لا تثق بـ"لصقته". افتح المسؤول ← الإعدادات ← webhooks الدفع. يُبلِّغ عمّا وصل خادمك فعلًا:

ما يقوله ماذا يعني ماذا تفعل
لم يُستقبَل قط لم يصل شيء قط من هذا المزوّد عنوان URL مفقود أو خاطئ في لوحة المزوّد
غير مطابق تصل التسليمات لكنها لا تسمّي أي طلب من طلباتك يشير عنوان URL إليك من حساب مزوّد مختلف عن الذي يستخدمه المتجر
يعمل تسليم واحد على الأقل طابق طلبًا حقيقيًا لا شيء — إنه موصول

تتحرّك العدّادات فقط للاتصالات التي تحمل بيانات اعتماد المزوّد نفسه، فلا يمكن لفحص عشوائي من الإنترنت أن يجعل بوّابة غير مُعدّة تبدو سليمة أبدًا.

اختبرها من طرف إلى طرف قبل أن تأخذ مالًا حقيقيًا. لوحة Xendit فيها زر "test webhook" على الصفحة نفسها؛ استخدمه، ثم أعِد تحميل بطاقة المسؤول. إن ظلّت تقول لم يُستقبَل قط، فعنوان URL خاطئ — تحقّق من مطبعة، أو https:// مفقود، أو شرطة مائلة زائدة في النهاية.

بيانات الاعتماد نفسها

هناك طريقتان لضبطها. كلتاهما تُبقيان السرّ بعيدًا عن الأنظار — ولا تُظهر أيٌّ منهما قيمة محفوظة قط.

من صفحة المسؤول (موصى بها)

المسؤول ← الإعدادات ← بيانات اعتماد بوّابة الدفع. أدخِل PayPal Client ID + Secret (ومفتاح التبديل sandbox/live) وXendit Secret Key + Callback token. تُخزَّن مشفّرة على الخادم؛ الحقول للكتابة فقط، فبمجرّد حفظها لا تُعرَض ثانيةً أبدًا — تُظهر الصفحة فقط Configured / Not set. اترك حقلًا فارغًا لإبقائه دون تغيير؛ استخدم إزالة بيانات الاعتماد المخزّنة لمسح واحد منها.

إعداد لمرة واحدة: ولّد المفتاح الذي يشفّرها، مُبقىً منفصلًا عن مفتاح التطبيق كي تكون مُفرَغة قاعدة البيانات وتسريب .env كلٌّ منهما عديم الجدوى بمفرده:

php artisan store:secrets-key      # writes STORE_SECRETS_KEY to .env — then BACK IT UP off the server
php artisan config:clear

فقدان STORE_SECRETS_KEY يجعل بيانات الاعتماد المخزّنة غير قابلة للقراءة (وسيلزمك فقط إعادة إدخالها).

أو من .env (بديل)

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

# Xendit
XENDIT_SECRET_KEY=...
XENDIT_CALLBACK_TOKEN=...     # from Settings → Developers → Webhooks

# PayPal
PAYPAL_CLIENT_ID=...
PAYPAL_SECRET=...
PAYPAL_ENV=sandbox           # or: live

البوّابة التي لا بيانات اعتماد لها تُطفأ ببساطة — لا شيء آخر لتفعيله.

إن كان خادمك خلف وكيل أو جدار حماية

مسار webhook هو عنوان URL عام، من خادم إلى خادم. لا تسجيل دخول له، بالضرورة — المزوّد لا يستطيع تسجيل الدخول باسمك. يُحمى بدلًا من ذلك بتوقيع المزوّد أو رمزه، وإعادة قراءة موثوقة لحالة الدفع مباشرة من المزوّد، وحدّ للمعدّل.

هذا يعني أن POST /webhooks/* يجب أن يكون قابلًا للوصول من الإنترنت العام. إن حجبته، أو وضعت الموقع كله خلف قائمة سماح IP، تتوقّف المدفوعات غير المتزامنة عن التنفيذ — بالعرض الصامت نفسه تمامًا كأنك لم تُعدّ عنوان URL قط.