وقتی مشتری رسید پرداخت موفق دارد یا مبلغ از حسابش کسر شده، اما سفارش ووکامرس Failed، Pending payment یا On hold مانده است، نباید فوراً سفارش تازه بسازید یا وضعیت را بدون بررسی روی Processing بگذارید. مسئله معمولاً در بازگشت مرورگر، webhook، مرحله verify، تطبیق مبلغ یا اجرای hook پس از پرداخت رخ داده است. ابتدا باید واقعیت مالی در پنل درگاه با رکورد فروشگاه تطبیق داده شود.
اقدام فوری: از مشتری نخواهید دوباره پرداخت کند. شماره سفارش، مبلغ، زمان، شناسه مرجع غیرحساس و وضعیت تراکنش در پنل درگاه را ثبت کنید. موجودی و ارسال را موقتاً با فرایند داخلی کنترل کنید، اما داده سفارش را حذف نکنید. سپس callback و verification را در لاگ همان timestamp دنبال کنید.
«موفق» از نگاه کدام سیستم؟
رسید مرورگر، پیامک بانکی، وضعیت پنل درگاه و وضعیت verify در API یک معنا ندارند. کسر اولیه ممکن است بعداً برگشت بخورد؛ از طرف دیگر ممکن است پرداخت در پنل قطعی باشد ولی پاسخ verification به فروشگاه نرسیده باشد. مرجع تصمیم باید مستندات و API رسمی درگاه و نتیجه قابل رهگیری آن باشد، نه فقط screenshot مشتری.
زنجیره پرداخت را مرحلهبهمرحله ببینید
- ووکامرس سفارش و تلاش پرداخت را ایجاد میکند.
- فروشگاه از API درگاه token یا authority میگیرد.
- مرورگر مشتری به درگاه منتقل میشود.
- درگاه نتیجه را به callback مرورگر یا webhook سرور میفرستد.
- افزونه مبلغ و شناسه را با API verify میکند.
- در صورت موفقیت معتبر، سفارش پرداختشده علامت میخورد.
- موجودی، ایمیل، webhook و عملیات بعدی اجرا میشوند.
شکست هر مرحله نشانه متفاوت دارد. برای نمونه بسته شدن مرورگر نباید در معماری دارای webhook سالم، تأیید نهایی را برای همیشه متوقف کند؛ اما رفتار دقیق به قابلیت درگاه و پیادهسازی افزونه وابسته است.
پیش از هر تغییر، Reconciliation انجام دهید
| داده | فروشگاه | درگاه |
|---|---|---|
| شناسه | شماره سفارش و transaction ID | authority/reference رسمی |
| مبلغ | total و currency | مبلغ و واحد ثبتشده |
| زمان | ایجاد و آخرین تغییر سفارش | ایجاد، پرداخت و settlement |
| وضعیت | Pending/Failed/On hold | ناموفق، موفق، verify یا refund |
شناسه کامل حساس یا داده کارت را در ticket عمومی نگذارید. اگر چند سفارش مبلغ یکسان دارند، فقط مبلغ و زمان برای تطبیق کافی نیست؛ شناسه یکتا لازم است.
Callback مرورگر نرسیده است
کاربر ممکن است تب را ببندد، اینترنتش قطع شود یا redirect توسط مرورگر، افزونه حریم خصوصی یا مسیر زبان مختل شود. access log را برای URL callback، status و redirect chain بررسی کنید. 404، 403، loop یا هدایت به login شواهد مهمیاند. اگر درگاه webhook مستقل دارد، رسیدن و امضای آن را جدا از مرورگر بررسی کنید.
Verification شکست خورده است
افزونه بعد از callback معمولاً شناسه، مبلغ و داده درخواست را به API درگاه میفرستد. timeout، DNS/TLS، credential اشتباه، اختلاف مبلغ یا کد «قبلاً verify شده» باید طبق مستندات همان درگاه تفسیر شود. پیام «قبلاً verify شده» را خودکار ناموفق یا موفق تلقی نکنید؛ ابتدا مشخص کنید verify قبلی متعلق به همین سفارش و مبلغ بوده است.
اختلاف ریال و تومان یا Total سفارش
اگر فروشگاه مبلغ را با یک واحد و درگاه با واحد دیگری دریافت کند، ساخت تراکنش یا verify ممکن است ناسازگار شود. تخفیف، مالیات، shipping، rounding و تغییر سفارش بعد از هدایت نیز total را متفاوت میکنند. مبلغ ارسالی اولیه، مبلغ callback/verify و total ذخیرهشده را بدون دستکاری دستی مقایسه کنید.
Webhook به WAF یا Cache برخورد کرده است
WAF، Geo-block، rate limit، maintenance mode یا اجبار authentication میتواند درخواست سرور درگاه را با 401/403 رد کند. cache نیز نباید پاسخ callback شخصی را جایگزین کند. rule ID و request مشخص را پیدا و استثنای حداقلی بسازید؛ IPهای حدسی را whitelist و کل WAF را خاموش نکنید.
Fatal Error بعد از تأیید پرداخت
گاهی verify موفق است اما یک hook مربوط به کاهش موجودی، ایمیل، فاکتور، CRM یا پیامک exception میدهد. باید دید افزونه درگاه قبل از hook وضعیت پرداخت را commit کرده یا نه. PHP error log و WooCommerce log همان لحظه را بررسی کنید. اجرای دوباره hook بدون شناخت idempotency ممکن است موجودی یا پیام را دوبار اعمال کند.
HPOS و سازگاری افزونه درگاه
در فروشگاهی که High-Performance Order Storage فعال است، افزونه باید سفارش را از APIهای پشتیبانیشده ووکامرس بخواند و بنویسد. افزونه قدیمی که مستقیماً به ساختار ذخیرهسازی قبلی وابسته است ممکن است transaction ID یا وضعیت را در محل نادرست ثبت کند. وضعیت سازگاری اعلامشده افزونه، feature settings و log را بررسی کنید؛ جدولها را دستی همگام یا یکسانسازی نکنید.
برای آزمون، یک clone با همان حالت HPOS و نسخهها بسازید. ایجاد، پرداخت، lookup سفارش با شناسه، refund و گزارش مدیریتی را بررسی کنید. خاموشکردن HPOS روی production بدون ارزیابی migration و سفارشهای جاری، راهحل کمریسکی نیست.
Cron و Action Scheduler
برخی افزونهها reconcile، webhook retry یا عملیات بعد از پرداخت را در صف انجام میدهند. failed/pending actionها را بر اساس hook، سن و exception بررسی کنید. حذف همه jobها راهحل نیست و میتواند تأیید، ایمیل یا sync سفارش را از بین ببرد. consumer، cron و قفلهای قدیمی را قبل از retry اصلاح کنید.
چرا تغییر دستی وضعیت خطرناک است؟
قرار دادن سفارش روی Processing ممکن است ایمیل، کاهش موجودی، webhook حسابداری و fulfillment را اجرا کند؛ درحالیکه پول شاید قطعی نشده یا همین عملیات قبلاً بخشی اجرا شده باشد. ابتدا نتیجه مالی را قطعی و تاریخچه noteها را حفظ کنید. سپس بر اساس runbook فروشگاه، اقدام جبرانی قابل حسابرسی انجام دهید.
Refund خودکار یا دستی را عجولانه شروع نکنید
اگر سفارش ناموفق است ولی تراکنش قطعی شده، ابتدا مشخص کنید کالا قابل تحویل است یا باید وجه برگردد. refund از پنل درگاه و refund از ووکامرس ممکن است دو مسیر متفاوت با webhookهای جدا باشند. اجرای هر دو میتواند درخواست تکراری بسازد. سیاست فروشگاه، وضعیت settlement و قابلیت idempotency API را بررسی و شناسه refund را در note داخلی سفارش ثبت کنید.
تا زمانی که نتیجه refund رسمی نشده، پیام قطعی به مشتری ندهید. در رخداد گروهی، فهرست سفارشها را با شناسه یکتا نگه دارید و هر مورد را به یکی از حالتهای «تحویل»، «بازپرداختشده» یا «نیازمند پیگیری» برسانید؛ جمع مبلغها بهتنهایی جای تطبیق تراکنشبهتراکنش را نمیگیرد.
رویه امن برای یک سفارش واقعی
- به مشتری اطلاع دهید پرداخت دوباره انجام ندهد.
- از سفارش، noteها و logهای مرتبط snapshot یا backup بگیرید.
- تراکنش را در پنل/API رسمی درگاه با شناسه یکتا پیدا کنید.
- مبلغ، واحد، زمان و وضعیت settlement/verify را تطبیق دهید.
- callback، webhook و log verification را در همان زمان پیدا کنید.
- علت فنی را روی staging یا با داده غیرحساس بازتولید کنید.
- اقدام جبرانی سفارش را با ثبت note و بدون اجرای دوباره عملیات غیر idempotent انجام دهید.
- پس از اصلاح، پرداخت موفق، لغو، timeout و callback تکراری را تست کنید.
کنترل Callback تکراری
درگاه ممکن است webhook را retry کند یا کاربر صفحه بازگشت را refresh کند. handler باید با transaction ID و وضعیت فعلی، اجرای دوباره عملیات تجاری را مهار کند. تست کنید callback یکسان دوبار، سفارش یا کاهش موجودی دوم نسازد و پاسخ مناسب به درگاه بدهد. قفل سراسری یا حذف درخواست تکراری بدون ثبت نیز عیبیابی را دشوار میکند.
پیشگیری و مانیتورینگ
- نسبت تراکنش موفق درگاه به سفارش پرداختشده را پایش کنید.
- برای Pending/Failed قدیمی و webhook 4xx/5xx هشدار داشته باشید.
- request ID و transaction ID غیرحساس را در log ساختاریافته ثبت کنید.
- پس از هر update یک پرداخت end-to-end کنترلشده اجرا کنید.
- زمان سیستم، DNS، TLS و دسترسی callback را مانیتور کنید.
- runbook تطبیق مالی و دسترسی مسئول پاسخگو را مشخص کنید.
اشتباههای رایج
- درخواست پرداخت مجدد پیش از inquiry
- حذف سفارش یا log برای شروع دوباره
- تغییر دستی وضعیت بدون تأیید مالی
- اعتماد صرف به screenshot یا پیامک
- اجرای دوباره callback با URL دستساز روی production
- ثبت secret و token در لاگ
- خاموش کردن TLS verification یا WAF
- restore دیتابیس قدیمی و از دست دادن سفارشهای جدید
تفکیک این خطا از خرابی عمومی درگاه
اگر هیچ کاربری وارد درگاه نمیشود، ابتدا خرابی درگاه ووکامرس را بررسی کنید. اگر سفارش پیش از redirect ساخته میشود اما رابط منتظر میماند، گیرکردن Checkout مناسبتر است. این راهنما زمانی است که شاهد مالی موفق وجود دارد ولی وضعیت سفارش همگام نشده است.
چه زمانی کمک تخصصی لازم است؟
اگر چند پرداخت موفق با سفارش Failed دارید یا نمیدانید کدام callback عملیات موجودی و fulfillment را اجرا کرده، تغییر مستقیم وضعیت میتواند مشکل مالی را بزرگتر کند. پشتیبانی فروشگاه ووکامرس میتواند سفارش، تراکنش، verify، webhook و log سرور را در یک timeline تطبیق دهد و مسیر اصلاح قابل حسابرسی پیشنهاد کند.
پرسشهای متداول
اگر پول کسر شده، حتماً پرداخت موفق است؟
نه همیشه؛ برخی کسرها ناموفق و برگشتپذیرند. وضعیت رسمی درگاه و inquiry معیار دقیقتری است.
میتوانم سفارش را دستی Processing کنم؟
فقط پس از تطبیق مالی و شناخت اثر hookها؛ این اقدام باید ثبتشده و مطابق runbook فروشگاه باشد.
چرا سفارش روی On hold مانده است؟
ممکن است رفتار مورد انتظار یک روش پرداخت یا نتیجه بررسی باشد. note سفارش و مستندات gateway را قبل از تغییر ببینید.
اگر callback دوبار برسد چه میشود؟
پیادهسازی درست باید تکرار را idempotent مدیریت کند؛ آن را با تراکنش آزمایشی و بررسی موجودی/ایمیل تست کنید.
آیا پاک کردن Action Scheduler کمک میکند؟
خیر؛ ممکن است job لازم برای reconcile یا عملیات سفارش را حذف کند. ابتدا hook شکستخورده را شناسایی کنید.