خطای درگاه پرداخت ووکامرس درست در حساس‌ترین نقطه‌ی قیف فروش رخ می‌دهد: جایی که مشتری کارت را کشیده، اعتماد کرده و فقط منتظر دیدن پیام موفقیت است. در تجربه‌ی چند ساله‌ام روی فروشگاه‌های ووکامرسی، در نُه مورد از ده مورد، پیام خطای روی صفحه مقصر واقعی نیست؛ ریشه در لایه‌ای دیگر از پشته‌ی فنی پنهان است.

این مقاله را برای عیب‌یابی نظام‌مند نوشته‌ام، نه برای وصله‌کاری سطحی. اگر پرداخت‌های فروشگاه نیمه‌کاره رها می‌شوند، اگر بعد از بازگشت از درگاه سبد خرید خالی می‌شود، یا اگر لاگ ووکامرس هر روز پر از خطاهای تکراری است، مسیری که در ادامه می‌آید همان ترتیبی است که خودم روی سایت‌های در حال فروش اجرا می‌کنم.

چرا پرداخت‌های ووکامرس نیمه‌کاره رها می‌شوند؟

درگاه پرداخت یک جزء مستقل نیست؛ یک پرداخت موفق نتیجه‌ی همکاری چهار لایه‌ی به‌هم‌پیوسته است: افزونه‌ی درگاه روی ووکامرس، هسته‌ی WooCommerce، زیرساخت سرور (PHP، curl، openssl) و در نهایت API شرکت PSP یا بانک. ناهماهنگی در هر لایه، به یک پیام خطای مشترک و مبهم ختم می‌شود که تقریباً همیشه گمراه‌کننده است. به همین دلیل اولین کار در عیب‌یابی، جدا کردن لایه‌ها است؛ و همان‌طور که در راهنمای اتصال درگاه پرداخت به ووکامرس توضیح داده‌ام، یک درگاه درست پیکربندی‌شده بیش از نیمی از این خطاها را از ابتدا حذف می‌کند.

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

دلیل دومی که پرداخت‌ها را نیمه‌کاره رها می‌کند، تفاوت رفتار درگاه‌های مختلف در برابر داده‌های ناقص است. بعضی درگاه‌ها داده‌ی شماره تلفن را اجباری می‌دانند، بعضی کد پستی، بعضی استان و شهر. اگر فرم پرداخت ووکامرس یکی از این فیلدها را نفرستد، درگاه درخواست را رد می‌کند اما پیام خطایی که به ووکامرس برمی‌گرداند عمومی و بی‌جزئیات است. همین موضوع باعث می‌شود مدت‌ها به دنبال مقصر در جای اشتباه بگردیم. راه‌حل، مطالعه‌ی مستندات دقیق درگاه و اطمینان از هم‌راستایی نگاشت فیلدهای ووکامرس و درگاه است.

سومین دلیل پنهان، همان چیزی است که در ادبیات مهندسی نرم‌افزار با نام race condition (شرایط رقابتی) شناخته می‌شود. اگر دو تراکنش همزمان از یک کاربر ارسال شود — مثلاً مشتری روی دکمه‌ی پرداخت دو بار پشت‌سرهم کلیک کند — ممکن است دو سفارش مجزا ساخته شود ولی درگاه فقط یکی را تأیید کند. نتیجه، یک سفارش پرداخت‌شده و یک سفارش معلق است. راه‌حل استاندارد، غیرفعال‌کردن دکمه بعد از اولین کلیک و استفاده از idempotency key در درخواست به درگاه است.

پیام خطایی که مشتری می‌بیند، تقریباً همیشه چند لایه دورتر از مقصر واقعی است.

چرخه‌ی حیات یک تراکنش در ووکامرس

برای عیب‌یابی حرفه‌ای، باید بدانید یک تراکنش از لحظه‌ی کلیک مشتری تا ثبت نهایی سفارش، چه مسیری را طی می‌کند. این مسیر پنج مرحله دارد و خطا می‌تواند در هر مرحله رخ بدهد:

  1. ایجاد سفارش pending: ووکامرس یک رکورد سفارش با وضعیت pending (در انتظار پرداخت) می‌سازد و شناسه‌ی آن را در سشن نگه می‌دارد.
  2. درخواست به درگاه: افزونه‌ی درگاه با استفاده از API، توکن پرداخت را می‌سازد و کاربر را به صفحه‌ی درگاه هدایت می‌کند.
  3. پرداخت در درگاه: کاربر کارت را وارد می‌کند و درگاه، تراکنش را از بانک استعلام می‌کند.
  4. بازگشت (callback): درگاه، کاربر را به URL مشخصی در سایت برمی‌گرداند و پارامترهای تراکنش را می‌فرستد.
  5. تأیید و به‌روزرسانی: افزونه‌ی درگاه، تراکنش را تأیید می‌کند و وضعیت سفارش را به processing یا completed تغییر می‌دهد.

هر اختلال در هر یک از این پنج مرحله، به یک تجربه‌ی شکست‌خورده برای کاربر ختم می‌شود. مثال کلاسیک: کاربر پول را پرداخت کرده، ولی به‌خاطر قطع شدن callback، سفارش همچنان pending می‌ماند. این نوع خطا را در رفع خطای پرداخت در ووکامرس با جزئیات بیشتری باز کرده‌ام؛ نکته‌ی کلیدی این است که در این سناریو، مشکل در پرداخت نیست، در بازگشت و تأیید است.

مرحله‌ی سوم و چهارم معمولاً بیش از همه آسیب‌پذیرند، چون به شبکه، DNS و تنظیمات SSL وابسته‌اند. اگر سرور شما نتواند اتصال خروجی HTTPS به دامنه‌ی درگاه برقرار کند، تراکنش هرگز از سایت خارج نمی‌شود. این خطا در لاگ PHP به شکل cURL error 28: Connection timed out یا SSL certificate problem ظاهر می‌شود.

نمونه‌ی تست اتصال خروجی با PHP

برای بررسی این‌که سرور می‌تواند با درگاه ارتباط برقرار کند یا نه، می‌توانید یک فایل تستی موقت بسازید و بعد از استفاده حذفش کنید. کد زیر یک درخواست curl ساده به دامنه‌ی درگاه می‌فرستد و نتیجه را در لاگ PHP می‌نویسد:

<?php
$ch = curl_init('https://gateway.example.com/');
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
curl_exec($ch);
if (curl_errno($ch)) {
    error_log('Gateway test: ' . curl_error($ch));
}
curl_close($ch);

اگر خطای Could not resolve host گرفتید، مشکل در DNS سرور است. اگر Connection timed out گرفتید، فایروال هاست ترافیک خروجی را بسته است. اگر SSL certificate problem گرفتید، زنجیره‌ی گواهی روی سرور ناقص است.

رایج‌ترین خطاهای درگاه و ریشه‌ی آن‌ها

خطاهای درگاه پرداخت ووکامرس را می‌توان در پنج خانواده‌ی اصلی دسته‌بندی کرد. تشخیص درست این دسته، نیمی از راه‌حل است:

خطای اتصال به درگاه (Gateway Connection Error)

این خطا معمولاً با پیام‌هایی مثل خطا در برقراری ارتباط با درگاه یا عدم دریافت پاسخ از سرور پرداخت ظاهر می‌شود. ریشه‌های رایج:

  • مسدود بودن ترافیک خروجی: بعضی هاست‌ها ترافیک خروجی به پورت‌های خاص یا آی‌پی‌های خاص را محدود می‌کنند.
  • عدم دسترسی به DNS درگاه: سرور نمی‌تواند دامنه‌ی درگاه را resolve کند.
  • مسدود شدن از سمت درگاه: اگر درگاه به هر دلیل آی‌پی سرور شما را بلاک کرده باشد، تمام تراکنش‌ها به خطا می‌خورند.
  • فایروال سمت سرور: قوانین iptables یا فایروال نرم‌افزاری که ترافیک خروجی را محدود کرده‌اند.

خطای تأیید تراکنش (Verification Failed)

در این حالت، کاربر به درگاه می‌رود، پرداخت را انجام می‌دهد، ولی هنگام بازگشت، ووکامرس نمی‌تواند تراکنش را تأیید کند. دلایل شایع:

  • ناهماهنگی کلید API: کلید تأیید با کلید پرداخت یکی نیستند یا از محیط اشتباه گرفته شده‌اند (sandbox در برابر production).
  • مقدار سفارش اشتباه: اگر مبلغ سفارش بین مرحله‌ی اول و مرحله‌ی تأیید تغییر کند (مثلاً با اضافه شدن هزینه‌ی ارسال)، درگاه تراکنش را رد می‌کند.
  • شناسه‌ی تراکنش گم‌شده: اگر در سشن سفارش، شناسه‌ی درگاه ذخیره نشود، تأیید ممکن نیست.
  • عدم تطابق دامنه: بعضی درگاه‌ها فقط به دامنه‌ی ثبت‌شده در پنل خودشان اجازه‌ی callback می‌دهند.

خطای بازگشت از درگاه (Callback Error)

پس از پرداخت، درگاه کاربر را به URL مشخصی در سایت برمی‌گرداند. اگر این URL نادرست باشد، اگر توسط قالب بازنویسی شده باشد، یا اگر توسط یک فایروال یا محدودیت آی‌پی بسته شده باشد، خطای callback رخ می‌دهد. بعضی از این مشکلات با تنظیم صحیح پیوندهای یکتا از بین می‌روند.

خطای Timeout و اجرای طولانی

اگر درخواست به درگاه بیش از max_execution_time PHP طول بکشد، تراکنش نیمه‌کاره قطع می‌شود. این خطا در فروشگاه‌هایی که هاست ضعیف دارند یا در ساعت‌های پیک ترافیک، بسیار شایع است. راه‌حل ریشه‌ای، ارتقای منابع هاست یا پیکربندی درست کش است؛ اما به‌عنوان یک راه‌حل موقت می‌توان مقدار max_execution_time را در php.ini افزایش داد. راهنمای کامل این موضوع در رفع خطاهای رایج ووکامرس آمده است.

خطای پورت، فایروال و محدودیت شبکه

بعضی هاست‌های اشتراکی، ترافیک خروجی به پورت ۴۴۳ را محدود می‌کنند یا فقط به آی‌پی‌های لیست سفید اجازه می‌دهند. این نوع محدودیت‌ها گاهی به‌صورت بی‌سروصدا اعمال می‌شوند و فقط در زمان پرداخت خودشان را نشان می‌دهند.

نشانهاحتمال ریشهراه‌حل اولیه
کاربر به درگاه نمی‌رودمسدودی ترافیک خروجی یا خطای افزونهتست curl خروجی از سرور
پرداخت انجام می‌شود ولی سفارش pending می‌ماندخطای callback یا سشنبررسی URL بازگشت و session handler
خطای Verification Failedکلید API یا مقدار سفارشتطبیق کلیدها و محاسبه‌ی مجدد مبلغ
خطای Timeoutمنابع هاست یا API کندارتقای هاست یا کش مؤثر
خطای SSLگواهی منقضی یا زنجیره‌ی ناقصنصب مجدد گواهی و ریدایرکت HTTPS

عیب‌یابی گام‌به‌گام خطای پرداخت

حالا به بخش عملی می‌رسیم. ترتیبی که در ادامه می‌آید، همان مسیری است که در پروژه‌های واقعی روی سایت‌های در حال فروش اجرا می‌کنم. هدف این است که در کمترین زمان، مقصر واقعی را جدا کنیم.

گام اول: فعال‌سازی لاگ ووکامرس

ووکامرس به‌صورت پیش‌فرض لاگ نمی‌گیرد، ولی یک سیستم لاگ داخلی دارد که به‌سادگی فعال می‌شود. از مسیر ووکامرس ← وضعیت ← لاگ‌ها می‌توانید خطاهای اخیر را ببینید. اگر هیچ لاگی وجود ندارد، از تنظیمات ووکامرس یا از طریق wp-config.php مقدار WP_DEBUG_LOG را روی true بگذارید تا خطاهای PHP هم ثبت شوند. روش کامل خواندن این لاگ‌ها در پیدا کردن خطاهای ووکامرس در لاگ‌ها آمده است.

در ۸۰ درصد مواردی که با آن‌ها مواجه شده‌ام، لاگ ووکامرس یا لاگ PHP، مستقیماً به یک افزونه‌ی مشخص یا یک درخواست خروجی اشاره می‌کند. حتی وقتی پیام خطای روی صفحه مبهم است، لاگ معمولاً دقیق است.

گام دوم: بررسی تنظیمات درگاه

بعد از بررسی لاگ، نوبت به تنظیمات درگاه می‌رسد. چهار چیز را چک کنید:

  • کلید API و Secret API درست وارد شده و از محیط production است، نه sandbox.
  • حالت تست (Test Mode) خاموش است.
  • URL بازگشت (Return URL) در پنل درگاه با URL سایت شما مطابقت دارد.
  • دامنه‌ی ثبت‌شده در پنل درگاه، با دامنه‌ی فعلی سایت یکی است.

درگاه‌های ایرانی معمولاً به‌جای کلید از ترمینال (Terminal ID) و شناسه‌ی پذیرنده استفاده می‌کنند. تنظیمات دقیق این درگاه‌ها در تنظیم روش‌های پرداخت در ووکامرس توضیح داده شده است.

گام سوم: تست با Sandbox یا مقدار حداقلی

قبل از هر تغییر دیگری، درگاه را در حالت sandbox یا با مبلغ حداقلی تست کنید. اگر در sandbox پرداخت موفق است ولی در production خطا می‌دهد، مشکل در تنظیمات یا محدودیت‌های سمت درگاه است، نه در سایت. اگر در sandbox هم خطا می‌دهد، ریشه سمت سایت است و باید ادامه‌ی عیب‌یابی را روی لایه‌های پایین‌تر انجام دهید.

گام چهارم: تعویض قالب به پیش‌فرض

قالب‌های پیچیده یا قالب‌هایی که توابع ووکامرس را بازنویسی می‌کنند، گاهی در ساختار HTML صفحه‌ی تسویه‌حساب تغییر ایجاد می‌کنند و باعث می‌شوند پارامترهای لازم به درگاه نرسند. برای تست سریع، قالب را موقتاً به یک قالب پیش‌فرض مثل Twenty Twenty-Four تغییر دهید. اگر خطا رفع شد، مقصر قالب است و باید مسیر تست آن را دقیق‌تر کنید.

گام پنجم: غیرفعال‌سازی افزونه‌ها

روش سنتی ولی مؤثر: تمام افزونه‌ها را غیرفعال کنید، فقط ووکامرس و افزونه‌ی درگاه را نگه دارید، و یکی‌یکی افزونه‌ها را فعال کنید. اگر بعد از فعال کردن یک افزونه‌ی خاص خطا برگشت، مقصر پیدا شده است. برای انجام این کار روی سایت زنده، حتماً از یک محیط استیجینگ یا نسخه‌ی کلون استفاده کنید. روش کامل شناسایی افزونه‌ی مشکل‌ساز در پیدا کردن افزونه‌ی مشکل‌ساز وردپرس نوشته شده است.

نکته‌ی تجربی: در بیشتر فروشگاه‌هایی که با آن‌ها مواجه شده‌ام، افزونه‌های کش و امنیتی بیش از هر چیز دیگری با درگاه پرداخت تضاد پیدا می‌کنند. افزونه‌ی کش ممکن است صفحه‌ی تسویه‌حساب را کش کند و سشن کاربر را از بین ببرد. افزونه‌ی امنیتی ممکن است درخواست‌های خروجی به درگاه را به‌عنوان حمله‌ی مشکوک تلقی کند.

گام ششم: بررسی سرور، PHP و curl

اگر تا اینجا مقصر پیدا نشد، ریشه در سرور است. سه چیز را بررسی کنید:

  1. نسخه‌ی PHP حداقل ۸.۰ باشد؛ نسخه‌های قدیمی‌تر با درگاه‌های جدید مشکل دارند.
  2. افزونه‌های curl، openssl و mbstring فعال باشند.
  3. محدودیت خروجی (outbound) در فایروال هاست به درگاه پرداخت اجازه بدهد.

برای بررسی اتصال خروجی، می‌توانید از فایل تستی PHP که قبلاً آوردیم استفاده کنید. اگر پاسخ برنگشت، مقصر سمت هاست است. مباحث کلی این لایه در بررسی خطاهای سرور در لاگ‌ها بررسی شده است.

وقتی خطای درگاه به سرور می‌رسد، دیگر تغییر افزونه‌ها هیچ کمکی نمی‌کند؛ فقط تغییر زیرساخت یا تنظیمات PHP مسئله را حل می‌کند.

گام هفتم: بررسی سشن‌ها و کوکی‌ها

سشن ووکامرس، به‌صورت پیش‌فرض از طریق کوکی‌های wp_woocommerce_session_* مدیریت می‌شود. اگر این کوکی‌ها به هر دلیل حذف یا مسدود شوند، درگاه نمی‌تواند سفارش را به تراکنش متصل کند. دلایل رایج:

  • تنظیم SameSite کوکی روی Strict که در بازگشت از درگاه مسدود می‌شود.
  • عدم فعال بودن کوکی‌های third-party در مرورگر کاربر.
  • تنظیم نادرست دامنه‌ی کوکی در حالت چند‌دامنه‌ای.

راه‌حل: در کد، مقدار SameSite را روی Lax تنظیم کنید و مطمئن شوید دامنه‌ی کوکی روی دامنه‌ی اصلی ست می‌شود، نه زیر‌دامنه.

خطاهای اختصاصی درگاه‌های ایرانی

درگاه‌های ایرانی، به‌خاطر مقررات بانک مرکزی و تفاوت‌های API، خطاهای مخصوص خودشان را دارند. در این بخش، به تفکیک درگاه، خطاهای شایع و راه‌حل‌ها را مرور می‌کنم.

زرین‌پال

خطاهای رایج زرین‌پال بیشتر از جنس تنظیمات هستند: مرچنت کد اشتباه، عدم تطابق دامنه با دامنه‌ی ثبت‌شده در پنل، یا استفاده از کلید sandbox در production. خطای تأیید تراکنش در زرین‌پال معمولاً به معنی نرسیدن callback است. برای رفع، ابتدا در پنل زرین‌پال لاگ تراکنش را بررسی کنید و ببینید آیا درخواست پرداخت در سمت درگاه ثبت شده یا نه.

نکته‌ی مهم درباره‌ی زرین‌پال: این درگاه در حالت پیش‌فرض، به callback فقط از دامنه‌ی ثبت‌شده اجازه می‌دهد. اگر سایت شما روی چند دامنه (مثلاً www و بدون www) پاسخ می‌دهد، هر دو نسخه را در پنل ثبت کنید تا callback گم نشود.

آیدی‌پی (IDPay)

آیدی‌پی از API نسبتاً ساده‌ای استفاده می‌کند، اما محدودیت‌های جدی روی آی‌پی سرور اعمال می‌کند. اگر خطای اتصال یا خطای عدم احراز هویت می‌بینید، اول از پنل خود آیدی‌پی آی‌پی سرور را چک و در صورت نیاز whitelist کنید. همچنین آیدی‌پی نسبت به تعداد درخواست‌ها حساس است؛ درخواست‌های مکرر می‌توانند به بلاک موقت آی‌پی منجر شوند.

پی‌پینگ و سایر درگاه‌ها

پی‌پینگ معمولاً از خطای ساختار callback شکایت می‌کند. بعضی قالب‌های فارسی، پارامترهای callback را دستکاری می‌کنند و باعث می‌شوند امضای تراکنش درست تشخیص داده نشود. تست با قالب پیش‌فرض وردپرس، سریع‌ترین راه تشخیص این نوع مشکل است.

نکات مشترک درگاه‌های ایرانی

  • اکثر درگاه‌ها به آی‌پی سرور حساس هستند؛ تغییر هاست باید با اطلاع به درگاه انجام شود.
  • بعضی درگاه‌ها دامنه‌ی callback را در پنل خودشان ذخیره می‌کنند؛ اگر دامنه را عوض کردید، باید پنل درگاه را هم به‌روز کنید.
  • درگاه‌ها معمولاً در زمان بلاک شدن یا downtime موقت، خطای عمومی برمی‌گردانند؛ در این موارد فقط انتظار و پیگیری با پشتیبانی درگاه کمک می‌کند.
  • بعضی درگاه‌ها فقط به پروتکل TLS ۱.۲ به بالا اجازه می‌دهند؛ اگر سرور شما قدیمی است، باید این را به‌روز کنید.

SSL و HTTPS؛ پیش‌نیاز امن پرداخت

بدون HTTPS معتبر، هیچ درگاه پرداخت معتبری تراکنش را قبول نمی‌کند. SSL (Secure Sockets Layer) لایه‌ای است که داده‌های کاربر را بین مرورگر و سرور رمزنگاری می‌کند و برای پرداخت آنلاین ضروری است. اطلاعات بیشتر درباره‌ی SSL را می‌توانید در ویکی‌پدیا ببینید.

اما صرف داشتن SSL کافی نیست. خطاهای زیر باعث می‌شوند درگاه پرداخت را رد کند:

  • گواهی منقضی: اگر تاریخ انقضای گواهی گذشته باشد، مرورگر و درگاه اتصال را رد می‌کنند.
  • زنجیره‌ی گواهی ناقص: بعضی گواهی‌ها بدون زنجیره‌ی کامل نصب می‌شوند و فقط در بعضی مرورگرها کار می‌کنند.
  • مخلوط HTTP و HTTPS: اگر بعضی از منابع صفحه با HTTP لود شوند، مرورگر صفحه را ناامن علامت می‌زند و بعضی درگاه‌ها تراکنش را متوقف می‌کنند.
  • عدم ریدایرکت صحیح: اگر سایت روی HTTP هم پاسخ بدهد، درگاه ممکن است callback را روی نسخه‌ی HTTP بفرستد و تراکنش ناتمام بماند.

برای رفع این خطاها، ابتدا گواهی SSL را بررسی و در صورت نیاز تمدید کنید. روش گام‌به‌گام این کار در رفع خطای SSL در وردپرس آمده است. سپس مطمئن شوید تمام منابع صفحه با HTTPS لود می‌شوند و ریدایرکت ۳۰۱ از HTTP به HTTPS در سرور فعال است.

نکات فنی درباره‌ی ریدایرکت HTTPS

برای اطمینان از ریدایرکت صحیح، می‌توانید این قواعد را در فایل .htaccess اضافه کنید:

RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

ترتیب این قواعد مهم است؛ اگر قبل از قواعد وردپرس قرار بگیرند، می‌توانند با برخی تنظیمات دیگر تضاد پیدا کنند. توصیه‌ی من این است که ابتدا از پنل هاست ریدایرکت را تنظیم کنید و فقط در صورت نبود گزینه، به .htaccess دست بزنید.

تضاد افزونه‌ها و قالب

تضاد افزونه، شایع‌ترین دلیل خطاهای درگاه پرداخت است، حتی وقتی افزونه‌ها به‌ظاهر بی‌ارتباط به نظر می‌رسند. سه دسته افزونه بیشتر از بقیه مشکوک هستند:

  1. افزونه‌های کش: اگر صفحه‌ی تسویه‌حساب کش شود، سشن کاربر از بین می‌رود و درگاه نمی‌تواند تراکنش را به سفارش متصل کند.
  2. افزونه‌های امنیتی: بعضی از این افزونه‌ها درخواست‌های خروجی به درگاه را به‌عنوان ترافیک مشکوک علامت‌گذاری و مسدود می‌کنند.
  3. افزونه‌های تغییردهنده‌ی تسویه‌حساب: افزونه‌هایی که فرم سفارش را بازنویسی می‌کنند، ممکن است بعضی فیلدهای اجباری درگاه را حذف کنند.

در یکی از پروژه‌های فروشگاهی که با آن مواجه شدم، یک افزونه‌ی ظاهراً بی‌خطر مدیریت فایل‌های CSS، با تزریق کد اضافی به صفحه‌ی تسویه‌حساب، فرم درگاه را از ارسال پارامترهای اجباری محروم می‌کرد. پیدا کردن این افزونه چند ساعت طول کشید و فقط با روش حذف تدریجی ممکن شد.

روش حذف تدریجی را در محیط استیجینگ انجام دهید، نه روی سایت زنده. ترتیب پیشنهادی من:

  1. قالب را به پیش‌فرض تغییر دهید.
  2. تمام افزونه‌ها را غیرفعال کنید، به‌جز ووکامرس و افزونه‌ی درگاه.
  3. تراکنش تستی بزنید.
  4. افزونه‌ها را یکی‌یکی فعال کنید و بعد از هر فعال‌سازی، تست کنید.

اگر بعد از فعال‌سازی یک افزونه‌ی خاص، خطا برگشت، مقصر پیدا شده است. در این حالت یا آن افزونه را حذف کنید، یا در چایلد‌تم یک راه دور زدن تعریف کنید.

مشکلات سرور، PHP و هاست

وقتی لایه‌ی نرم‌افزار سالم است، ریشه در زیرساخت است. فروشگاه‌های اینترنتی، به‌دلیل ماهیت تراکنشی، به منابع بیشتری از یک وبلاگ نیاز دارند. اگر در ساعت‌های پیک، پرداخت‌ها زیاد خطا می‌دهند ولی در ساعت‌های خلوت موفق‌اند، مشکل از بار سرور است. انتخاب هاست مناسب برای فروشگاه یکی از مهم‌ترین تصمیم‌های زیرساختی است و در انتخاب هاست برای فروشگاه اینترنتی معیارهای دقیق آن را آورده‌ام.

سه مقدار PHP که مستقیماً روی پرداخت تأثیر می‌گذارند:

  • max_execution_time: حداکثر زمان اجرای یک اسکریپت. مقدار پایین، تراکنش‌های کند را قطع می‌کند.
  • memory_limit: مقدار حافظه‌ی در دسترس. مقدار پایین باعث خطای fatal در حین ساخت سفارش می‌شود.
  • max_input_vars: تعداد متغیرهای ورودی. اگر فرم تسویه‌حساب بیش از این مقدار فیلد داشته باشد، بعضی داده‌ها ارسال نمی‌شوند.

مقدار توصیه‌شده برای فروشگاه‌های معمولی: max_execution_time حداقل ۱۲۰ ثانیه، memory_limit حداقل ۲۵۶ مگابایت، max_input_vars حداقل ۳۰۰۰. این مقادیر را می‌توانید از پنل هاست یا فایل php.ini تنظیم کنید.

مشکل DNS و resolve شدن دامنه‌ی درگاه

در موارد نادری، سرور قادر به resolve کردن دامنه‌ی درگاه نیست. این مشکل با تست dig یا nslookup از داخل سرور مشخص می‌شود. راه‌حل، تنظیم DNS resolver معتبر در سرور یا استفاده از آی‌پی به‌جای دامنه در پیکربندی است (که به‌خاطر تغییرات آی‌پی درگاه، توصیه نمی‌شود).

محدودیت ترافیک خروجی

بعضی هاست‌های اشتراکی ترافیک خروجی به پورت ۴۴۳ را محدود می‌کنند. راه‌حل ریشه‌ای این است که با پشتیبانی هاست صحبت کنید و درخواست کنید پورت‌های خروجی به آی‌پی درگاه باز شوند. اگر اجازه ندادند، ارتقا به VPS یا هاست اختصاصی اجتناب‌ناپذیر است.

مشکل CPU و منابع اشتراکی

در هاست‌های اشتراکی، وقتی یکی از سایت‌های همسایه بار زیادی روی سرور می‌گذارد، تراکنش‌های شما هم کند می‌شوند. نشانه‌ی این وضعیت: خطاهای تصادفی در ساعت‌های خاص، بدون تغییر در کد یا تنظیمات. راه‌حل، پیگیری با پشتیبانی هاست و در صورت لزوم ارتقا به پلن بالاتر یا VPS است.

دیتابیس، کش و سشن‌ها

دیتابیس و مدیریت سشن، دو لایه‌ی پنهان در پرداخت هستند که گاهی نادیده گرفته می‌شوند. اگر دیتابیس کند باشد یا قفل (lock) داشته باشد، درج رکورد سفارش کند می‌شود و ممکن است پیش از تکمیل، تراکنش timeout بخورد. رفع خطاهای دیتابیس در وردپرس، پیش‌نیاز پایداری پرداخت است.

روی هاست‌های اشتراکی، گاهی تنظیمات سشن PHP برای همه‌ی سایت‌ها مشترک است و می‌تواند با سشن ووکامرس تضاد داشته باشد. راه‌حل: استفاده از دیتابیس به‌جای فایل برای ذخیره‌ی سشن‌ها، یا استفاده از Redis Object Cache برای سشن‌ها.

در یکی از پروژه‌ها، مشکل پرداخت با پاک کردن کش دیتابیس حل شد. جدول wp_options به‌دلیل حجم زیاد ترنزینت‌ها کند شده بود و کوئری‌های ووکامرس در حین ساخت سفارش با تأخیر پاسخ می‌گرفتند. پاک‌سازی ترنزینت‌های منقضی‌شده، زمان پرداخت را محسوس کاهش داد.

کوئری مفید برای پیدا کردن سفارش‌های معلق

برای بررسی سفارش‌های pending که ممکن است به‌دلیل خطای callback معلق مانده باشند، می‌توانید این کوئری را در phpMyAdmin اجرا کنید:

SELECT ID, post_date, post_status
FROM wp_posts
WHERE post_type = 'shop_order'
  AND post_status = 'wc-pending'
  AND post_date >= DATE_SUB(NOW(), INTERVAL 7 DAY)
ORDER BY post_date DESC;

اگر تعداد این رکوردها زیاد باشد، یعنی سیستم callback شما سالم نیست. هر رکورد اضافه، یک مشتری است که پول داده و سفارشش ثبت نشده؛ این وضعیت نیاز به مداخله‌ی فوری دارد.

پایش، تست و پیشگیری

بعد از رفع خطا، مهم‌تر از رفع، پیشگیری از تکرار آن است. سه سطح پایش توصیه می‌کنم:

سطح اول: پایش لاگ روزانه

یک بازه‌ی پنج‌دقیقه‌ای روزانه برای بررسی لاگ ووکامرس و لاگ PHP اختصاص دهید. اکثر خطاها قبل از آن‌که به یک بحران تبدیل شوند، در لاگ ظاهر می‌شوند. ابزارهای اتوماسیون مثل WP-CLI یا سیستم‌های هشدار ایمیل هم می‌توانند کمک کنند.

سطح دوم: تراکنش تستی دوره‌ای

هفته‌ای یک‌بار، یک سفارش تستی با کمترین مقدار ممکن ثبت کنید. این کار به‌سرعت نشان می‌دهد که آیا درگاه هنوز سالم است یا خیر. اگر خطا رخ داد، می‌توانید قبل از شکایت مشتری، خودتان رفع کنید.

سطح سوم: هشدار در لحظه

سیستم‌های هشدار مثل Uptime Robot یا Pingdom می‌توانند صفحه‌ی تسویه‌حساب را به‌صورت دوره‌ای بررسی کنند و در صورت خطا، ایمیل یا پیام فوری بفرستند. علاوه‌براین، در خود ووکامرس می‌توانید قواعد سفارشی برای ارسال ایمیل در صورت خطای پرداخت تنظیم کنید.

پرسش‌های پرتکرار درباره خطای درگاه پرداخت ووکامرس

چرا پرداخت در ووکامرس گاهی موفق است و گاهی ناموفق؟

این الگوی ناپایدار، تقریباً همیشه نشانه‌ی مشکل زیرساختی است، نه باگ افزونه. اگر پرداخت‌ها در ساعت‌های پیک خطا می‌دهند، احتمالاً منابع سرور محدود است. اگر خطا با تغییر شبکه‌ی کاربر عوض می‌شود، احتمالاً مسئله در SSL یا DNS است.

آیا افزونه‌های کش با درگاه پرداخت تضاد دارند؟

بله. اگر افزونه‌ی کش، صفحه‌ی تسویه‌حساب را هم کش کند، سشن کاربر از بین می‌رود و درگاه نمی‌تواند تراکنش را به سفارش متصل کند. راه‌حل: صفحه‌های تسویه‌حساب، سبد خرید و حساب کاربری را در تنظیمات افزونه‌ی کش، از کش مستثنی کنید.

چرا بعضی پرداخت‌ها به سفارش pending وصل نمی‌شوند؟

سناریوی کلاسیک: کاربر پول را پرداخت کرده، ولی callback از درگاه به سایت نرسیده یا به‌درستی پردازش نشده. نتیجه: سفارش در وضعیت pending می‌ماند و مشتری فکر می‌کند پرداخت ناموفق بوده. راه‌حل: بررسی لاگ درگاه، بررسی URL بازگشت و در صورت لزوم، تأیید دستی سفارش. مباحث مرتبط با این سناریو در افزایش امنیت فروشگاه ووکامرس هم پوشش داده شده است.

آیا استفاده از درگاه تست (Sandbox) کافی است؟

خیر. sandbox فقط برای بررسی صحت کد و منطق پرداخت کافی است. بعضی خطاها فقط در محیط production رخ می‌دهند؛ مثل محدودیت آی‌پی، رفتار واقعی بانک یا حجم ترافیک. توصیه‌ی من این است که بعد از تست sandbox، یک تراکنش واقعی کوچک هم بزنید و روند کامل را ببینید.

چرا خطای درگاه فقط در موبایل رخ می‌دهد؟

این الگو معمولاً به دو دلیل است: یا صفحه‌ی تسویه‌حساب در موبایل با ساختار متفاوتی رندر می‌شود که پارامترهای لازم را ارسال نمی‌کند، یا مرورگر موبایل از کوکی‌های third-party استفاده نمی‌کند و سشن کاربر در زمان بازگشت از درگاه گم می‌شود. تست با قالب پیش‌فرض و بررسی لاگ، سریع‌ترین راه تشخیص است.

آیا SSL رایگان برای درگاه پرداخت کافی است؟

SSL رایگان مثل Let"s Encrypt از نظر فنی معتبر است و درگاه‌ها آن را قبول می‌کنند. فقط باید مطمئن باشید که گواهی به‌درستی نصب شده، به‌موقع تمدید می‌شود و زنجیره‌ی گواهی کامل است.

چرا پس از تغییر هاست، پرداخت‌ها از کار می‌افتند؟

سه دلیل عمده: اول، آی‌پی سرور جدید ممکن است در فایروال درگاه whitelist نباشد. دوم، سرور جدید ممکن است محدودیت خروجی داشته باشد. سوم، تنظیمات SSL و گواهی ممکن است به‌درستی منتقل نشده باشد. بعد از هر مهاجرت، حتماً یک تراکنش تستی بزنید.

چگونه می‌توانم خطای درگاه را به‌صورت دقیق ثبت کنم؟

لاگ‌های ووکامرس معمولاً پیام خطا را با جزئیات ثبت می‌کنند، ولی گاهی این لاگ‌ها کافی نیستند. توصیه‌ی من اضافه‌کردن یک لاگ سفارشی به افزونه‌ی درگاه است که پارامترهای ارسال‌شده و پاسخ دریافتی را ثبت کند. این کار در مرحله‌ی عیب‌یابی بسیار مؤثر است.

آنچه تجربه‌ی میدانی به من آموخته

خطای درگاه پرداخت، به‌ظاهر یک مشکل فنی است، ولی در واقع یک مشکل کسب‌وکاری است. هر تراکنش ناموفق، یک مشتری است که رفته؛ و بعضی از آن‌ها هرگز برنمی‌گردند. به همین دلیل، عیب‌یابی پرداخت باید سریع‌تر از عیب‌یابی هر بخش دیگری از سایت انجام شود و پیشگیری از آن، بخشی از فرآیند روزمره‌ی نگهداری باشد.

سه درس کلیدی که در سال‌ها کار به من ثابت شده:

  1. هیچ‌وقت روی سایت زنده عیب‌یابی نکنید. یک محیط استیجینگ با داده‌ی مشابه، سریع‌تر از بکاپ‌های اضطراری جواب می‌دهد.
  2. لاگ را قبل از هر تغییری فعال کنید. بدون لاگ، عیب‌یابی فقط حدس است.
  3. پایه‌های زیرساخت را جدی بگیرید. هاست خوب، SSL به‌روز، نسخه‌ی PHP مدرن و کش درست، از ۹۰ درصد خطاها جلوگیری می‌کنند.

اگر در فروشگاه‌تان با نوعی از خطای درگاه مواجه شده‌اید که در این مقاله پوشش داده نشده، یا اگر راه‌حل متفاوتی پیدا کرده‌اید که به کارتان آمده، برای من جالب است آن را بشنوم. تجربه‌تان را در دیدگاه‌ها بنویسید — به‌خصوص اگر پیام خطا و ریشه‌ی واقعی آن را با جزئیات یادداشت کرده‌اید؛ این یادداشت‌ها برای صاحب فروشگاه بعدی، ساعت‌ها زمان صرفه‌جویی می‌کنند. 🔧