پرداخت را دوبار تأیید نکنیم؛ وبهوک و تکرار درخواست را ساده بفهمیم
هنگام انجام تراکنش موفق، درگاه پرداخت ممکن است اطلاعات وضعیت را از طریق وبهوک تکرار کند. چطور با شناسه یکتا از ثبت دوگانه سفارش جلوگیری کنیم؟

تصور کنید مشتری شما در یک فروشگاه اینترنتی هزینهٔ سفارش خود را پرداخت کرده و تراکنش با موفقیت انجام شده است. اما ناگهان سیستم شما دو سفارش مشابه ثبت میکند یا موجودی یک انبار دو بار کسر میشود. این مشکل معمولاً زمانی رخ میدهد که درگاه پرداخت یا سیستم واسطه، اطلاعات وضعیت تراکنش را از طریق وبهوک (Webhook) بیشتر از یک بار به سرور فروشگاه ارسال میکند. وبهوک در اصطلاح فنی یعنی یک پیام خودکار از طرف سرور درگاه به سرور شما که میگوید: «وضعیت این تراکنش تغییر کرد».
در این مقاله بررسی میکنیم که چرا این پیامها گاهی تکرار میشوند، خطرات ناشی از پردازش همزمان آنها چیست و چگونه میتوانیم با چند چکلیست و بررسی ساده در پایگاه داده، جلوی خطاهای حسابداری و نارضایتی مشتری را بگیریم.
وبهوک چیست و چرا درخواستها ممکن است تکرار شوند؟
برای درک بهتر موضوع، باید بدانیم ارتباط میان سرور فروشگاه ما و درگاه پرداخت چگونه برقرار میشود. هنگامی که تراکنش مالی انجام میشود، درگاه پرداخت یا سیستم واسطه باید نتیجه را به سرور ما اعلام کند تا وضعیت سفارش از «در انتظار پرداخت» به «تکمیلشده» تغییر یابد. این اطلاعرسانی معمولاً از طریق وبهوک انجام میشود.
با این حال، شبکههای کامپیوتری همیشه بینقص کار نمیکنند. اگر ارتباط اینترنتی بین سرور درگاه و سرور سایت شما با یک تأخیر کوتاه، قطعی لحظهای یا خطای تایماوت مواجه شود، درگاه پرداخت تصور میکند پیام قبلی به دست شما نرسیده است. به همین دلیل، پروتکل امنیتی درگاه ممکن است تصمیم بگیرد همان درخواست را دوباره ارسال کند. اگر سیستم فروشگاه شما مکانیزمی برای تشخیص درخواستهای تکراری نداشته باشد، هر دو پیام را به عنوان دو تراکنش مستقل پردازش خواهد کرد.
مثال کاربردی از ثبت سفارش دوگانه و اختلال حسابداری
فرض کنید در یک روز کاری، کاربری مبلغ پانصد هزار تومان برای خرید یک کالا پرداخت میکند. بانک یا درگاه پرداخت پیام موفقیت تراکنش را دو بار پیاپی (مثلاً با فاصلهٔ سه ثانیه) به سرور سایت میفرستد. اگر سیستم فروشگاه شناسهٔ یکتای تراکنش (Transaction ID) را در دیتابیس ذخیره نکرده باشد و وضعیت سفارش را قفل نکند، سناریوی زیر رخ خواهد داد:
- درخواست اول میرسد: سیستم فاکتور را پرداختشده ثبت میکند، موجودی انبار یک عدد کم میشود و پیامک موفقیت ارسال میگردد.
- درخواست دوم بلافاصله میرسد: از آنجا که سیستم بررسی نمیکند آیا این تراکنش قبلاً پردازش شده است یا خیر، فرض میکند این یک خرید جدید با همان مشخصات است؛ بنابراین ممکن است دوباره موجودی انبار کسر شود یا اختلال جدی در گزارشهای مالی روزانه ایجاد گردد.
این اتفاق علاوه بر به هم ریختن تراز حسابداری، پیگیریهای وقتگیر پشتیبانی برای استرداد وجه اضافی به مشتری را به دنبال دارد.
چکلیست و راهکار فنی ساده برای کنترل تکرار درخواست
برای جلوگیری از این مشکل، نیازی به پیادهسازیهای پیچیده نیست. رعایت چند قدم ساده در اسکریپت دریافت وبهوک امنیت جریان مالی شما را بالا میبرد:
- ثبت شناسه یکتا: همیشه هنگام ایجاد درخواست پرداخت، شناسه یکتای تراکنش یا شماره ارجاع را در جدول سفارشها ذخیره کنید.
- بررسی رکورد قبلی: پیش از اعمال هرگونه تغییر روی وضعیت سفارش یا موجودی انبار، بررسی کنید که آیا این شناسه یکتا پیش از این در دیتابیس با وضعیت «پرداختشده» ثبت شده است یا خیر.
- بازگرداندن پاسخ استاندارد: اگر رکورد با همین شناسه وجود داشت، از پردازش مجدد صرفنظر کرده و فقط یک پاسخ تأیید (مثل کد وضعیت HTTP 200) به درگاه برگردانید تا ارسال پیام متوقف شود.
مدیریت متمرکز فاکتورها و تراکنشها با ابزارهای استاندارد
مدیریت صحیح تراکنشها، صدور فاکتور و هماهنگسازی جریان دریافت وجه با پنل فروشگاهی از اهمیت بالایی برخوردار است. هنگامی که زیرساخت فروشگاه و بخش مالی با ابزارهای استانداردی مثل زیپی مدیریت میشوند، اتصال به درگاه مرکزی و هماهنگسازی جریان دریافت وجه با پنل و API به شکل ساختاریافتهتری انجام میشود تا وضعیت فاکتورها، اقلام و بازگشت نتیجهٔ پرداخت به دقت رصد شود. همچنین در کنار مدیریت مالی، نظارت بر پایداری سرویسها و زیرساخت میزبان وب در ناحیه کاربری مانند امکانات زیهاست به حفظ پایداری ارتباطات سرور کمک میکند.



گفتوگو را ادامه دهیم
تجربه و پرسش شما میتواند برای خوانندهٔ بعدی راهگشا باشد.