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

خطای نمایش قیمت در ووکامرس دقیقاً چیست؟

ووکامرس یک لایهٔ افزونه روی وردپرس است که منطق فروشگاه را از مدیریت محصول تا پرداخت و ارسال مدیریت می‌کند. در قلب این منطق، مفهوم قیمت به‌عنوان یک مقدار مالی ذخیره می‌شود که هنگام نمایش، از چند فیلتر عبور می‌کند: فیلتر واحد پول (Currency)، فیلتر مالیات، فیلتر تخفیف، و در آخر فیلتر قالب‌بندی HTML. اگر هر یک از این فیلترها درست کار نکند یا با فیلتر دیگری تعارض داشته باشد، قیمت به‌شکل اشتباه نمایش داده می‌شود — یا خالی، یا صفر، یا با واحد پول غلط، یا با فرمت عجیب.

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

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

انواع حالت‌های خطا و معنای هرکدام

در جلسه‌های پشتیبانی، خطاهای قیمت را در پنج دستهٔ کلی می‌بینم. جدول زیر را از پرونده‌های واقعی تهیه کرده‌ام:

نشانهمحتمل‌ترین علتاولویت بررسی
قیمت صفر یا خالی نمایش داده می‌شودتنظیمات قیمت محصول یا متغیرهابالا
قیمت با واحد پول اشتباه (مثلاً دلار به‌جای تومان)واحد پول یا فیلتر localeبالا
قیمت با فرمت غلط (اعشار یا جداکننده هزارگان)تنظیمات فرمت قیمت یا فیلتر قالبمتوسط
قیمت با مالیات اشتباه محاسبه می‌شودتنظیمات نرخ مالیات یا شمول قیمتبالا
قیمت فقط در بعضی صفحات غایب استکش، صفحه‌ساز یا قالبمتوسط

نکتهٔ ظریف: خطای «قیمت صفر» در محصولات متغیر (Variable Products) بسیار شایع‌تر از محصولات ساده است، چون در این نوع محصولات قیمت از ترکیب ویژگی‌ها (مثل رنگ و اندازه) محاسبه می‌شود و اگر یک ترکیب تنظیم نشده باشد، قیمتش صفر یا نامشخص می‌شود. اگر با محصولات متغیر کار می‌کنید، مرجع ساخت محصول متغیر در ووکامرس گام‌به‌گام این ساختار را توضیح داده است.

هفت علت رایج خطای نمایش قیمت

در تجربه‌ام، این هفت علت تقریباً تمام پرونده‌ها را پوشش می‌دهند:

  1. تنظیمات نامناسب واحد پول: اگر واحد پول در پیشخوان روی EUR تنظیم شده باشد و فروشگاه ایرانی باشید، تمام قیمت‌ها با علامت یورو نمایش داده می‌شوند. اصلاح این تنظیم از مسیر ووکامرس ← تنظیمات ← عمومی ← واحد پول در چند ثانیه انجام می‌شود.
  2. نبود قیمت محصول یا تنظیم نامناسب فروش فروشی: اگر محصول با گزینهٔ «فروش نداشتن» ثبت شده باشد یا گزینهٔ «قیمت صفر» فعال باشد، ووکامرس قیمت را نمایش نمی‌دهد و پیام «ناموجود» یا خالی نشان می‌دهد.
  3. تنظیمات نادرست مالیات (Tax): اگر نرخ مالیات به‌اشتباه روی درصدی تنظیم شده باشد یا گزینهٔ «قیمت‌ها شامل مالیات است» با «قیمت‌ها بدون مالیات است» اشتباه شده باشد، عدد نمایش‌داده‌شده با آنچه مدیر انتظار دارد فرق می‌کند.
  4. تعارض افزونه‌های تخفیف یا ارسال: افزونه‌هایی که برای «قیمت پویا» یا «تخفیف پلکانی» نصب می‌شوند، اگر با یکدیگر هم‌زمان فعال باشند، می‌توانند فیلترهای قیمت را چند بار اعمال کنند و نتیجه، عدد نهایی اشتباه است.
  5. تعارض قالب یا صفحه‌ساز: قالب‌هایی که برای سفارشی‌سازی صفحهٔ محصول، فایل‌های ووکامرس را override می‌کنند، در صورت آپدیت ووکامرس می‌توانند ناسازگار شوند و قیمت به‌درستی نمایش داده نشود. مسیر تشخیص در خطای قالب در ووکامرس آمده است.
  6. کش معیوب یا نسخهٔ قدیمی: اگر قیمت تغییر کرده ولی کش آن را به‌روزرسانی نکرده باشد، کاربر قیمت قدیمی را می‌بیند. این خطا در فروشگاه‌های پربازدید شایع‌تر است و راه‌حل آن یک purge ساده یا اصلاح تنظیمات کش است. راهنمای انتخاب کش در بهترین افزونه‌های کش وردپرس آمده است.
  7. تنظیمات نادرست فرمت قیمت: در پیشخوان ووکامرس، تعداد رقم اعشار، جداکنندهٔ هزارگان و موقعیت علامت واحد پول قابل تنظیم است. اگر این‌ها با نیاز بازار ایران هم‌خوان نباشد (مثلاً گذاشتن نقطه به‌جای ویرگول یا برعکس)، قیمت‌ها غیرقابل‌فهم نمایش داده می‌شوند.

چطور علت واقعی را تشخیص دهیم؟

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

ابزار اول: WP_DEBUG و لاگ خطا

در فایل wp-config.php، سه خط زیر را قبل از خط /* That's all, stop editing! */ اضافه کنید:

define( 'WP_DEBUG', true );
define( 'WP_DEBUG_LOG', true );
define( 'WP_DEBUG_DISPLAY', false );

سپس یک محصول با قیمت مشکل‌دار را در پیشخوان باز کنید و فایل wp-content/debug.log را ببینید. اگر خطای PHP مثل Undefined index یا Call to undefined function در ارتباط با فایل‌های ووکامرس یا افزونهٔ جانبی دیده شود، همان‌جا مقصر لو می‌رود. بعد از پایان تشخیص، WP_DEBUG_DISPLAY را حتماً به false برگردانید — روشن گذاشتن آن روی سایت زنده، خطاها را به چشم کاربر می‌آورد و ممکن است اطلاعات حساس سرور را افشا کند.

ابزار دوم: غیرفعال‌سازی افزونه‌ها با روش دوبه‌دو

اگر در لاگ خطای PHP ندیدید ولی قیمت‌ها هنوز غلط نمایش داده می‌شوند، سراغ افزونه‌ها بروید. همان روش تقسیم دوتایی — که در چگونه افزونه مشکل‌ساز وردپرس را پیدا کنیم گام‌به‌گام توضیح داده‌ام — سریع‌ترین مسیر است. توجه ویژه به افزونه‌های «تخفیف، ارسال، مالیات، چندارزی» داشته باشید؛ این‌ها پرخطرترین دسته‌اند و معمولاً مقصر واقعی در میانشان است.

ابزار سوم: تست با قالب پیش‌فرض

اگر با غیرفعال‌سازی افزونه‌های جانبی مشکل حل نشد، قالب را به Twenty Twenty-Four تغییر دهید و یک محصول را تست کنید. اگر قیمت درست شد، مقصر قالب فعلی یا صفحه‌ساز است. سفارشی‌سازی‌های صفحهٔ محصول را در قالب فعلی خود بازبینی کنید؛ اگر از المنتور یا Divi استفاده می‌کنید، احتمال تعارض بین ابزار سازندهٔ صفحه و template ووکامرس جدی است. مسیر سفارشی‌سازی امن در سفارشی‌سازی صفحه محصول در ووکامرس آمده است.

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

راه‌حل‌های گام‌به‌گام رفع خطا

بسته به علت، یکی از مسیرهای زیر را انتخاب کنید. ترتیب را رعایت کنید؛ در بیشتر موارد، مسیر اول یا دوم مسئله را حل می‌کند.

مسیر اول: اصلاح تنظیمات واحد پول و فرمت قیمت

به پیشخوان بروید و مسیر ووکامرس ← تنظیمات ← عمومی را دنبال کنید. سه مقدار کلیدی را بررسی کنید:

  • واحد پول (Currency): برای ایران روی IRR (ریال) یا IRT (تومان) قرار دهید.
  • موقعیت نماد واحد پول: برای فارسی، «سمت چپ با فاصله» یا «سمت راست با فاصله» بهتر است.
  • جداکنندهٔ هزارگان و اعشار: استاندارد فارسی، ویرگول برای هزارگان و نقطه برای اعشار است.

پس از ذخیره، اگر قیمت‌ها هنوز با فرمت قدیمی نمایش داده می‌شوند، کش سایت را پاک کنید. شایع‌ترین دلیل «قیمت‌ها تغییر نکرده»، همان کش است.

مسیر دوم: بازبینی قیمت محصول و فروش فروشی

هر محصول را باز کنید و در باکس «داده‌های محصول» تب «عمومی» را ببینید. سه گزینهٔ مهم:

  • قیمت عادی و قیمت فروش ویژه: اگر هر دو خالی باشند، محصول «قیمت ندارد» و ووکامرس ممکن است آن را ناموجود یا بدون قیمت نمایش دهد.
  • فروش فروشی (Sale Price): اگر قیمت فروش از قیمت عادی بزرگ‌تر باشد، ووکامرس آن را نادیده می‌گیرد و ممکن است قیمت اشتباه نمایش دهد.
  • وضعیت موجودی: اگر روی «ناموجود» تنظیم شده باشد، قیمت ممکن است پنهان شود. مسیر مدیریت دقیق موجودی در مدیریت موجودی محصولات در ووکامرس آمده است.

مسیر سوم: بازبینی تنظیمات مالیات

در ووکامرس ← تنظیمات ← مالیات، سه چیز را چک کنید:

  • گزینهٔ «قیمت‌ها شامل مالیات است» یا «قیمت‌ها بدون مالیات است» — این گزینه باید با سیاست کسب‌وکار شما هم‌خوان باشد.
  • نرخ مالیات برای استان‌ها یا کشورهای مقصد — نرخ اشتباه، قیمت نهایی اشتباه می‌سازد.
  • گزینهٔ «نمایش قیمت با مالیات» در صفحهٔ فروشگاه — اگر خاموش باشد، قیمت خام نمایش داده می‌شود و ممکن است کاربر آن را با قیمت نهایی اشتباه بگیرد.

توضیح کامل این بخش در مدیریت مالیات در ووکامرس آمده است.

مسیر چهارم: رفع تعارض افزونه

اگر مطمئنید تنظیمات ووکامرس و محصولات درست است، سراغ افزونه‌های جانبی بروید. به‌ویژه اگر آخرین بار پس از نصب یک افزونهٔ تخفیف یا ارسال، این خطا ظاهر شد. پیش از هر حذف، بکاپ بگیرید؛ مسیر امن در بکاپ‌گیری از فروشگاه ووکامرس آمده است. اگر افزونهٔ مشکل‌ساز حیاتی است و جایگزین ندارد، به سازنده تیکت بدهید یا با override کردن در چایلد تم، فقط بخش مشکل‌دار را اصلاح کنید — به‌جای ویرایش فایل خودِ افزونه.

مسیر پنجم: پاک‌سازی و تنظیم کش

اگر قیمت درست در پیشخوان ولی اشتباه در سایت نمایش داده می‌شود، مشکل کش است. سه گام:

  • کش افزونهٔ کش را purge کنید (نه فقط refresh).
  • کش سروری (مثل LiteSpeed یا Varnish) را هم پاک کنید.
  • اگر CDN دارید، کش لبه (Edge Cache) را هم invalidation کنید.

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

مسیر ششم: بازبینی قالب و صفحه‌ساز

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

مسیر هفتم: بازبینی ناسازگاری PHP

اگر خطای قیمت بعد از ارتقای نسخهٔ PHP توسط هاست ظاهر شده، مسئله احتمالاً ناسازگاری است. یک افزونهٔ قدیمی که روی PHP 7.4 کار می‌کرد، ممکن است در PHP 8.2 خطای deprecated یا warning بدهد و قیمت را به‌درستی محاسبه نکند. راه‌حل: آپدیت افزونه‌ها، یا در صورت نبود آپدیت، جایگزینی با افزونهٔ فعال. این پرونده از جنس همان تصمیم‌هایی است که در رفع خطاهای رایج ووکامرس به آن پرداخته‌ام.

نگاه مهندسی عمیق به خط قیمت در ووکامرس

برای مهندسانی که می‌خواهند بدانند زیر پوست ووکامرس چه می‌گذرد: قیمت محصول در ووکامرس به‌صورت یک متای محصول (_regular_price و _sale_price) در جدول wp_postmeta ذخیره می‌شود. کلاس WC_Product که در فایل includes/class-wc-product.php تعریف شده، مسئول خواندن و ارائهٔ این مقادیر است. تابع get_price_html() در همین کلاس، مسئول تولید HTML قیمت است و از چند فیلتر کلیدی عبور می‌کند: woocommerce_get_price_html، wc_price، woocommerce_currency_symbol، و woocommerce_price_format. هر افزونهٔ جانبی یا قالب که یکی از این فیلترها را override کند، می‌تواند قیمت نهایی را تغییر دهد.

سه نکتهٔ فنی که در پروژه‌های بزرگ به کارم آمده:

  • ترتیب اجرای فیلترها حیاتی است: اگر دو افزونه به woocommerce_get_price_html متصل شوند، ترتیب اجرایشان بر اساس priority تعیین می‌شود. اگر هر دو priority یکسان بدهند، ترتیب ثبت، ترتیب اجرا را مشخص می‌کند — که می‌تواند بین نصب‌های مختلف متفاوت باشد. این پدیده توضیح می‌دهد چرا گاهی روی استجینگ مشکل دیده نمی‌شود ولی روی سایت زنده بله.
  • cache invalidation در ووکامرس: ووکامرس برای بهینه‌سازی از چند لایهٔ کش داخلی استفاده می‌کند. یکی از این لایه‌ها، wc_get_product_transient است. اگر قیمت محصولی تغییر کند ولی این transient پاک نشود، ممکن است برای ساعت‌ها قیمت قدیمی نمایش داده شود. این مسئله در فروشگاه‌های پربازدید به سادگی دیده می‌شود و راه‌حلش، پاک‌سازی کش داخلی از مسیر ووکامرس ← وضعیت ← ابزارها است.
  • مسئلهٔ گرد کردن (Rounding): در پروژه‌های چندارزی یا با تخفیف پلکانی، مسئلهٔ گرد کردن اعشار می‌تواند به اختلاف چند صد تومانی بین قیمت نمایشی و قیمت نهایی سبد منجر شود. ووکامرس چند فیلتر برای کنترل این رفتار دارد: wc_get_rounding_precision و wc_get_price_decimals. در فروشگاه‌هایی که سبد خرید بزرگ دارند، تنظیم دقیق این دو، تفاوت بین تجربهٔ روان و شکایت مکرر کاربران است.

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

پیشگیری از تکرار خطای قیمت

سه عادت ساده که در پروژه‌های فروشگاهی همیشه اجرا می‌کنم:

  1. محیط استجینگ اجباری برای هر تغییر قیمتی: پیش از هر تغییر در تنظیمات مالیات، افزونه‌های تخفیف، یا قالب، این تغییرات را در یک نسخهٔ موازی فروشگاه تست کنید. اگر افزونهٔ جدید قیمت‌ها را خراب کرد، بهتر است این خرابی در نسخهٔ استجینگ رخ دهد تا در سایت زنده.
  2. پایش خودکار قیمت‌ها: یک اسکریپت کوچک یا افزونهٔ ساده که هر شب چند محصول نمونه را بازرسی کند و اگر قیمت‌شان صفر یا خالی بود، به مدیر ایمیل بزند. این کار در فروشگاه‌هایی که روزانه ده‌ها محصول اضافه می‌کنند، از فاجعهٔ شبانه جلوگیری می‌کند.
  3. مستندسازی افزونه‌های جانبی: فهرست همهٔ افزونه‌هایی که روی محاسبهٔ قیمت اثر می‌گذارند را در یک فایل نگه دارید. روزی که مسئله پیش بیاید، این فهرست، شبیه نقشهٔ گنج می‌شود. این رویکرد از جنس همان انضباطی است که در سئو فروشگاه ووکامرس هم به آن اشاره کرده‌ام: پایداری داده و تنظیمات، پیش‌نیاز مقیاس است.

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

خط بسته‌شدن پرونده

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