وب هوک پرداخت چیست؟ راهنمای کامل پیادهسازی و امنسازی Webhook درگاه پرداخت

مشتری پول را پرداخته و پیامک کسر وجه از بانک برای او ارسال شده است. با این حال، سفارش در پنل فروشگاه شما همچنان در وضعیت «در انتظار پرداخت» قرار دارد. دلیل آن ساده است؛ کاربر پس از پرداخت، صفحه مرورگر را بسته و هرگز به سایت شما بازنگشته است. وبهوک دقیقاً برای جلوگیری از همین مشکل طراحی شده است.
پاسخ سریع: وب هوک پرداخت (Webhook) یک درخواست HTTP است که درگاه پرداخت بهصورت خودکار به آدرس مشخصشده در سرور فروشنده میفرستد. این مکانیزم نتیجه تراکنش را در لحظه اطلاعرسانی میکند؛ مستقل از اینکه کاربر به سایت بازگشته باشد یا خیر.
وب هوک پرداخت چیست؟
وب هوک یک درخواست HTTP POST حاوی بدنه JSON است که از سمت درگاه به سرور شما ارسال میشود. بهجای اینکه سیستم شما هر دقیقه از درگاه پرداخت اینترنتی (در تب جدید) بپرسد «آیا پرداخت انجام شد؟»، درگاه در لحظه وقوع تراکنش، زنگ سرور شما را به صدا درمیآورد. این وارونگی جهت درخواست، هسته اصلی این مفهوم است.
به همین دلیل، گاهی به آن API معکوس (Reverse API) یا کالبک سرور (HTTP Callback) نیز میگویند. البته باید دقت کنید که این اعلان صرفاً یک اطلاعرسانی است، نه منبع قطعی حقیقت. مرحله تأیید نهایی (Verify) تراکنش همچنان الزامی است.
چرا به وب هوک نیاز داریم؟
آدرس بازگشت (Redirect URL) بهشدت وابسته به مرورگر کاربر است و این وابستگی یک نقطه ضعف بزرگ محسوب میشود. سناریوهای زیر شکست ریدایرکت را نشان میدهند:
- کاربر پس از وارد کردن رمز، مرورگر را میبندد یا اینترنت او قطع میشود.
- تب پرداخت روی مرورگر موبایل در پسزمینه سیستمعامل بسته میشود.
- تراکنش در وضعیت «در انتظار» میماند و چند دقیقه بعد توسط شبکه بانکی نهایی میشود.
- تراکنش بعداً مسترد (Refund) میشود و ریدایرکتی برای اعلام آن وجود ندارد.
ریدایرکت یک روش شکننده است. در مقابل، وبهوک یک ارتباط پایدارِ سرور به سرور (Server-to-Server) ایجاد میکند که کاملاً قابل اتکا است.
نحوه کار وب هوک
فرآیند ارسال و دریافت این رویداد (Payment Event) شامل مراحل زیر است:
۱. ثبت آدرس اندپوینت (Webhook URL) در پنل مدیریت درگاه.
۲. کاربر پرداخت را انجام میدهد و رویدادی در سمت درگاه رخ میدهد.
۳. درگاه یک درخواست POST حاوی بدنه JSON و هدر امضا به آدرس شما میفرستد.
۴. سرور شما امضا را بررسی کرده و در صورت تأیید، سریعاً کد ۲۰۰ برمیگرداند.
۵. پردازشهای سنگین نظیر بهروزرسانی دیتابیس به صف پسزمینه (Queue) منتقل میشود.
۶. اگر درگاه پاسخ ۲۰۰ نگیرد، درخواست را با فاصلههای زمانی فزاینده دوباره ارسال میکند.
ساختار یک Payload نمونه
درگاه معمولاً یک شیء JSON مشابه زیر ارسال میکند:
{
"event_id": "evt_123456",
"event_type": "payment.succeeded",
"transaction_id": "txn_987654",
"amount": 500000,
"status": "success",
"created_at": "2026-09-19T14:01:05Z"
}
شناسه رویداد برای جلوگیری از پردازش تکراری و شناسه تراکنش (در تب جدید) برای پیگیری وضعیت نهایی در API استفاده میشود.
انواع رویدادهای پرداخت
توسعهدهندگان نباید فقط رویداد «موفق» را مدیریت کنند. رویدادهای ناموفق، در انتظار، مستردشده و حتی لغوشده نیز باید در سیستم شما ثبت شوند تا وضعیت حساب مشتری همیشه دقیق باشد.
تفاوت وب هوک و کال بک و API معمولی
این سه مکانیزم جایگزین یکدیگر نیستند، بلکه در یک معماری درست مکمل هم عمل میکنند:
| روش دریافت | جهت درخواست | وابسته به مرورگر؟ | مصرف منابع | کاربرد صحیح |
|---|---|---|---|---|
| ریدایرکت (کالبک) | از مرورگر به سرور | بله (شکننده) | بسیار کم | فقط برای نمایش نتیجه به کاربر و تجربه کاربری (UX) |
| وبهوک | از درگاه به سرور | خیر (پایدار) | کم | منبع اصلی اتکا برای ثبت رویداد و تغییر وضعیت سفارش |
| Polling | از سرور به درگاه | خیر | بالا (پرهزینه) | صرفاً بهعنوان مکانیزم پشتیبان برای مغایرتگیری |
امنیت وب هوک، چطور از جعل تراکنش جلوگیری کنیم؟
آدرس وبهوک شما یک اندپوینت عمومی روی اینترنت است. اگر امضا را بررسی نکنید، هر شخصی با ارسال یک درخواست POST جعلی میتواند سفارش ۵۰ میلیون تومانی خود را «پرداختشده» ثبت کند.
اعتبارسنجی امضای HMAC
درگاه بدنه خام درخواست را با کلید مخفی (Secret Key) شما هش میکند و نتیجه را در هدر میگذارد. سرور شما باید همین کار را تکرار کرده و دو مقدار را مقایسه کند. محاسبه هش حتماً باید روی بدنه خام (Raw Body) انجام شود. مقایسه نیز باید با تابع زمانثابت صورت گیرد تا از حملات زمانبندی جلوگیری شود.
نمونه کد امن در PHP:
$secret = getenv('WEBHOOK_SECRET');
$signature = $_SERVER['HTTP_X_SIGNATURE'] ?? '';
$payload = file_get_contents('php://input'); // خواندن بدنه خام
$hash = hash_hmac('sha256', $payload, $secret);
// استفاده از تابع زمانثابت برای مقایسه
if (!hash_equals($hash, $signature)) {
http_response_code(401);
exit('Invalid signature');
}
نمونه کد امن در Node.js:
const crypto = require('crypto');
function verifySignature(req, secret) {
const signature = req.headers['x-signature'];
const payload = req.rawBody; // حتماً از بافر یا استرینگ خام استفاده کنید
const hash = crypto.createHmac('sha256', secret)
.update(payload)
.digest('hex');
// مقایسه امن در برابر حملات زمانبندی
return crypto.timingSafeEqual(Buffer.from(hash), Buffer.from(signature));
}
جلوگیری از حمله بازپخش (Replay Attack)
مهاجم ممکن است یک درخواست معتبر و قدیمی را دوباره به سرور شما بفرستد. برای جلوگیری از این مشکل، timestamp موجود در هدر را بررسی کنید و درخواستهای قدیمیتر از چند دقیقه را رد نمایید. ذخیره شناسه رویدادهای پردازششده نیز راهکار مکملی است.
لایههای دفاعی مکمل
همیشه از پروتکل HTTPS برای دریافت دادهها استفاده کنید. کلید مخفی را حتماً در متغیرهای محیطی (.env) سرور نگه دارید. در صورت امکان، دریافت درخواست را به IPهای اعلامشده از سمت درگاه محدود کنید.
چرا با وجود وبهوک باز هم باید Verify کنید؟
قاعده طلایی امنیت پرداخت: مبلغ و وضعیت تراکنش را همیشه از طریق فراخوانی متد Verify در API درگاه تأیید کنید. دادههای بدنه وبهوک تنها یک اعلان اولیه هستند.
پیادهسازی وب هوک پرداخت
برای پیادهسازی صحیح این اندپوینت، مسیر زیر را طی کنید:
۱. یک مسیر POST عمومی بسازید و آن را از محافظت CSRF مستثنی کنید (این یک خطای رایج در لاراول و جنگو است).
۲. بدنه خام درخواست را پیش از هرگونه پردازش یا پارس کردن (Parsing) بخوانید.
۳. امضا را اعتبارسنجی کنید و درخواستهای نامعتبر را با کد ۴۰۱ رد نمایید.
۴. رویداد خام را جهت رهگیری در دیتابیس ذخیره (لاگ) کنید.
۵. کد وضعیت ۲۰۰ را در کمتر از ۱ تا ۲ ثانیه برای درگاه ارسال کنید.
۶. پردازش نهایی (بهروزرسانی سفارش) را به صف پردازش پسزمینه بسپارید.
کد وضعیت درستی که باید برگردانید
| کد HTTP | معنای آن برای درگاه پرداخت |
|---|---|
| ۲۰۰ | دریافت شد؛ ارسال مجدد متوقف شود. |
| ۴۰۱ / ۴۰۳ | امضا نامعتبر است یا دسترسی مسدود شده. |
| ۵۰۰ / ۵۰۲ | سرور دچار خطا شده؛ مجدداً ارسال شود. |
نکته حیاتی: هرگز پردازشهای سنگین نظیر ارسال ایمیل یا تولید فاکتور PDF را داخل هندلر وبهوک انجام ندهید. این کار باعث بروز تایماوت شده و سیلی از درخواستهای تکراری را روانه سرور شما میکند.
چرا وب هوک دریافت نمیشود؟
اگر اعلانی دریافت نمیکنید، جدول زیر را برای عیبیابی بررسی نمایید:
| علامت و خطا | علت محتمل | راهحل قطعی |
|---|---|---|
| درخواست اصلاً نمیرسد | آدرس در شبکه داخلی است یا پشت فایروال قرار دارد | آدرس باید روی اینترنت عمومی قابل دسترسی باشد. |
| خطای SSL در پنل درگاه | گواهی SSL نامعتبر یا منقضی شده است | گواهی HTTPS سرور خود را تمدید و پیکربندی کنید. |
| درگاه خطای ۳۰۱ میدهد | ریدایرکت روی مسیر وبهوک فعال است | درگاهها معمولاً ریدایرکت را دنبال نمیکنند؛ مسیر را اصلاح کنید. |
| خطای ۴۱۹ یا ۴۰۳ | محافظت CSRF روشن است | مسیر وبهوک را از لیست بررسی CSRF فریمورک خارج کنید. |
| درگاه مدام رویداد تکراری میفرستد | پاسخ سرور کند است (تایماوت رخ میدهد) | کد ۲۰۰ را فوراً برگردانید و بقیه کار را به صف (Queue) بسپارید. |
تست وبهوک روی لوکالهاست
برای تست مسیر پرداخت در سیستم شخصی، از یک تونل محلی نظیر ngrok استفاده کنید تا یک آدرس عمومی موقت بسازید. دقت کنید که هرگز کلید مخفی محیط Production را روی ابزارهای عمومی تست قرار ندهید.