# راه‌اندازی وب‌هوک bluauto وب‌هوک، درخواست POST سرور bluauto به سرور فروشگاه است. صفحه برگشت مشتری جای وب‌هوک را نمی‌گیرد. یک گیرنده مناسب زبان سرورتان انتخاب کنید: | زبان | فایل | نیازمندی | |---|---|---| | PHP | receiver.php | PHP 8.1+ و PDO SQLite، وب‌سرور HTTPS | | Python | receiver.py | Python 3.10+، بدون بسته اضافی | | Node.js | receiver.mjs | Node.js 24.12+، بدون بسته اضافی | ۱. فایل گیرنده را روی سرور فروشگاه قرار دهید. فایل SQLite را بیرون پوشه عمومی وب نگهداری کنید و به فرایند گیرنده اجازه نوشتن بدهید. در پروژه واقعی جداول نمونه را با پایگاه سفارش‌های خود ادغام کنید. ۲. آدرس HTTPS عمومی گیرنده را از تنظیمات وب‌هوک پنل ثبت کنید یا API زیر را فراخوانی کنید: ```sh curl "$BLUAUTO_URL/api/v1/webhook" \ -H "Authorization: Bearer $BLUAUTO_API_KEY" \ -H 'Content-Type: application/json' \ --data '{"url":"https://shop.example/webhook","enabled":true}' ``` کلید `secret` را از پاسخ اولین ثبت بردارید و فقط در محیط سرور گیرنده با نام `BLUAUTO_WEBHOOK_SECRET` تنظیم کنید. این کلید با کلید API فروشگاه متفاوت است. هنگام تغییر کلید از `/api/v1/webhook/rotate` استفاده کنید؛ رویدادهای قدیمی صف با کلید قبلی ارسال می‌شوند. پیش از چرخش، صف قبلی را تعیین تکلیف کنید. ۳. `BLUAUTO_WEBHOOK_DB` را مسیر مطلق یک فایل خارج از web root بگذارید. برای اجرای Python یا Node: ```sh python receiver.py node receiver.mjs ``` هر دو فقط روی 127.0.0.1:8088 گوش می‌دهند. reverse proxy با گواهی معتبر HTTPS باید درخواست `/webhook` را به همین مسیر محلی هدایت کند. PHP را با وب‌سرور موجود روی مسیر دلخواه منتشر کنید. برای آزمایش محلی می‌توان گیرنده را بدون HTTPS صدا زد؛ bluauto برای ارسال واقعی فقط مقصد عمومی HTTPS پورت ۴۴۳ را می‌پذیرد. ۴. هنگام ساخت فاکتور، پیش از نمایش اطلاعات پرداخت به مشتری، `order_id`، `id` فاکتور و **مبلغ نهایی** `amount_rial` پاسخ را در جدول سفارش خود ذخیره کنید. مبلغ پایه درخواست جای مبلغ نهایی پاسخ نیست. ابزار `save-order.py` برای ثبت یک سفارش نمونه در SQLite همین گیرنده موجود است: ```sh python save-order.py ORDER-1001 INVOICE_UUID FINAL_AMOUNT_RIAL ``` این ابزار از همان `BLUAUTO_WEBHOOK_DB` استفاده می‌کند و سفارش موجود را بازنویسی نمی‌کند. در پروژه اصلی این ثبت باید داخل مسیر ساخت سفارش خودتان انجام شود. ۵. گیرنده روی بایت‌های خام بدنه، `HMAC-SHA256(secret, timestamp + "." + raw_body)` را بررسی می‌کند. هدرهای فعلی `X-Didban-Timestamp`، `X-Didban-Signature` و `X-Didban-Event-Id` هستند؛ نام قدیمی هدرها عمداً برای سازگاری ثابت مانده است. اختلاف زمان مجاز ۳۰۰ ثانیه است؛ ساعت سرور باید هماهنگ باشد. بدنه را پیش از بررسی امضا دوباره JSON نکنید. ۶. تنها `invoice.paid` با `mode=live`، `paid=true` و `status=PAID` پذیرفته می‌شود. شناسه فاکتور، شناسه سفارش و مبلغ باید دقیقاً با اطلاعات ذخیره‌شده فروشگاه یکسان باشند. دریافت دوباره همان رویداد یا رویداد دیگری برای سفارش پرداخت‌شده، سفارش و کار تحویل تازه ایجاد نمی‌کند. ثبت دریافت، پرداخت سفارش و صف تحویل در یک تراکنش پایگاه داده انجام می‌شوند. کارهای `fulfillment_jobs` را با worker خودتان انجام دهید و شناسه سفارش را کلید یکتای تحویل قرار دهید؛ نمونه‌ها خودشان کالا یا پیام ارسال نمی‌کنند. ۷. پاسخ 200 یعنی ثبت پایدار موفق شده است. 401 برای امضای اشتباه یا قدیمی، 409 برای سفارش ناشناخته یا مغایرت و 503 برای خرابی موقت پایگاه داده است. خطای موقت را با 200 مخفی نکنید. bluauto تا ۸ تلاش با فاصله افزایشی دارد؛ سپس رویداد failed می‌ماند و از پنل قابل ارسال مجدد است. صف ارسال و وضعیت را از `GET /api/v1/webhook/events` ببینید. برای آزمون: یک رویداد معتبر را دوبار ارسال کنید؛ باید فقط یک ردیف دریافت و یک کار تحویل ثبت شود. مبلغ را تغییر دهید، امضا را خراب کنید و timestamp قدیمی بفرستید؛ هیچ‌کدام نباید سفارش را پرداخت‌شده کنند. نسخه آزمایشی فاکتور (`test`) رویداد پرداخت واقعی ایجاد نمی‌کند.