اگر فروشگاه اینترنتی شما با ووکامرس ساخته شده و میخواهید مشتریان را به افزایش مبلغ سبد خرید تشویق کنید، تعیین حداقل مبلغ سفارش ووکامرس یکی از روشهایی است که میتواند در این زمینه کاربرد داشته باشد.
با استفاده از کدی که در این صفحه قرار دادهایم، میتوانید برای فروشگاه ووکامرسی خود یک حداقل مبلغ سفارش تعیین کنید و زمانی که مبلغ سبد مشتری به حد تعیین شده نرسیده است، مقدار باقیمانده را به او نمایش دهید.
برای جذاب تر شدن این قابلیت، این کد از نوار پیشرفت حداقل مبلغ سفارش نیز پشتیبانی میکند. بنابراین مشتری میتواند به صورت بصری مشاهده کند چه مقدار از حداقل مبلغ سفارش را تکمیل کرده و چقدر دیگر باید خرید کند.
این قابلیت به صورت یک Snippet آماده ارائه شده و میتوانید آن را با افزونه Code Snippets در سایت وردپرسی خود فعال کنید.
کد حداقل مبلغ سفارش ووکامرس چه کاری انجام می دهد؟
این کد برای فروشگاه هایی طراحی شده که میخواهند برای ثبت سفارش، حداقل مبلغ مشخصی تعیین کنند.
برای مثال، اگر حداقل مبلغ سفارش را روی ۳۰۰٬۰۰۰ تومان تنظیم کنید و مشتری محصولاتی به ارزش ۲۲۰٬۰۰۰ تومان در سبد خرید داشته باشد، سیستم میتواند به او اعلام کند:
۸۰٬۰۰۰ تومان دیگر خرید کنید تا بتوانید سفارش خود را ثبت کنید.
در همین شرایط، نوار پیشرفت نیز میتواند میزان تکمیل مبلغ سفارش را نمایش دهد؛ برای مثال:
۲۲۰٬۰۰۰ از ۳۰۰٬۰۰۰ تومان — ۷۳٪
با رسیدن مبلغ سبد به حداقل تعیین شده، وضعیت نوار پیشرفت به ۱۰۰ درصد تغییر کرده و پیام تکمیل سفارش نمایش داده میشود.
چرا از حداقل مبلغ سفارش استفاده کنیم؟
یکی از کاربردهای این قابلیت، تشویق مشتری به افزایش ارزش سبد خرید است.
فرض کنید مشتری محصولی به ارزش ۲۷۰ هزار تومان در سبد خود دارد و حداقل مبلغ سفارش فروشگاه ۳۰۰ هزار تومان است. در این حالت مشتری تنها ۳۰ هزار تومان با حداقل مبلغ فاصله دارد.
نمایش پیامی مانند:
فقط ۳۰٬۰۰۰ تومان دیگر به سبد خرید اضافه کنید.
میتواند مشتری را به بررسی سایر محصولات فروشگاه و اضافه کردن یک محصول دیگر به سبد ترغیب کند.
البته میزان تأثیر این روش به مدل فروشگاه، قیمت محصولات، هزینه ارسال و رفتار مشتریان بستگی دارد و نمیتوان افزایش فروش را در همه فروشگاهها تضمین کرد.
امکانات کد
این کد فقط یک شرط ساده برای حداقل مبلغ سفارش نیست و مجموعهای از تنظیمات کاربردی را در اختیار مدیر فروشگاه قرار میدهد.
مهم ترین امکانات عبارتاند از:
- تعیین حداقل مبلغ سفارش
- فعال یا غیرفعال کردن قابلیت
- جلوگیری از ثبت سفارش زیر حداقل مبلغ
- نمایش مبلغ باقی مانده
- نمایش درصد پیشرفت
- نوار پیشرفت سبد خرید
- پیام اختصاصی برای مبلغ کمتر از حداقل سفارش
- پیام موفقیت پس از رسیدن به حداقل مبلغ
- امکان تعیین نحوه محاسبه مبلغ سفارش
- پشتیبانی از تخفیف و کوپن
- امکان احتساب یا عدم احتساب هزینه حمل ونقل
- استثنا کردن محصولات
- استثنا کردن دسته بندیها
- استثنا کردن نقشهای کاربری
- تنظیمات مربوط به کاربران مهمان و واردشده
- تنظیمات پیشرفته نمایش پیام
- طراحی واکنش گرا برای موبایل
- پشتیبانی از حالت روشن و دارک مود
بخش دریافت و استفاده از کد
کد زیر آماده استفاده است و نیازی به تغییر در ساختار آن ندارید.
برای استفاده از این قابلیت، افزونه Code Snippets را در وردپرس نصب کنید و یک Snippet جدید ایجاد کنید.
سپس کد زیر را در قسمت PHP قرار دهید و Snippet را فعال کنید.
کد
<?php
/**
* WooCommerce Minimum Order Amount
* سیستم حرفهای حداقل مبلغ سفارش + نوار پیشرفت شناور مینیمال
*
* نویسنده: آی کدیتو
* وبسایت: https://icodito.ir
* سازگار با: WordPress 6+, WooCommerce 8+, PHP 8.1+, HPOS
*/
if (!class_exists('Icodito_Min_Order')):
class Icodito_Min_Order
{
const OPTION_KEY = 'icodito_min_order_settings';
const AJAX_NONCE = 'icodito_min_order_ajax';
const CAPABILITY = 'manage_woocommerce';
const MENU_SLUG = 'icodito-min-order';
private static $instance = null;
private $notice_rendered = false;
public static function instance()
{
if (null === self::$instance) {
self::$instance = new self();
}
return self::$instance;
}
private function __construct()
{
add_action('plugins_loaded', array($this, 'init'), 20);
}
/* =========================================================
* INIT
* ========================================================= */
public function init()
{
if (!class_exists('WooCommerce')) {
if (is_admin()) {
add_action('admin_notices', array($this, 'notice_woocommerce_missing'));
}
return;
}
// مدیریت
add_action('admin_menu', array($this, 'add_menu'));
add_action('admin_init', array($this, 'register_settings'));
add_action('admin_enqueue_scripts', array($this, 'admin_assets'));
add_action('admin_post_icodito_min_order_reset', array($this, 'handle_reset'));
// فرانت
add_action('wp_enqueue_scripts', array($this, 'frontend_assets'));
add_action('wp_footer', array($this, 'render_floating_bar'), 100);
$settings = self::get_settings();
$priority = max(1, (int) $settings['hook_priority']);
// اعتبارسنجی
add_action('woocommerce_check_cart_items', array($this, 'validate_cart'), $priority);
add_action('woocommerce_checkout_process', array($this, 'validate_checkout'), $priority);
// Store API / Blocks
add_filter('woocommerce_store_api_cart_errors', array($this, 'store_api_errors'), $priority, 2);
// AJAX Refresh
add_action('wp_ajax_icodito_min_order_refresh', array($this, 'ajax_refresh'));
add_action('wp_ajax_nopriv_icodito_min_order_refresh', array($this, 'ajax_refresh'));
}
public function notice_woocommerce_missing()
{
if (!current_user_can('activate_plugins'))
return;
echo '<div class="notice notice-warning"><p><strong>حداقل مبلغ سفارش:</strong> افزونه WooCommerce فعال نیست.</p></div>';
}
/* =========================================================
* تنظیمات پیشفرض
* ========================================================= */
public static function defaults()
{
return array(
'enabled' => 'yes',
'minimum_amount' => 0,
'apply_on' => 'both',
'prevent_checkout' => 'yes',
'base_amount' => 'subtotal_after_discount',
'include_shipping' => 'no',
'include_discounts' => 'yes',
'message' => 'حداقل مبلغ سفارش {minimum} است. لطفاً {remaining} دیگر به سبد خرید اضافه کنید.',
'success_message' => '🎉 حداقل مبلغ سفارش تکمیل شد.',
'show_success_message' => 'yes',
'progress_enabled' => 'yes',
'progress_show_percent' => 'yes',
'progress_show_remaining' => 'yes',
'progress_show_current' => 'no',
'progress_show_minimum' => 'no',
'progress_text_top' => '',
'progress_text_bottom' => '',
'excluded_products' => '',
'excluded_categories' => array(),
'exempt_roles' => array(),
'exempt_logged_in' => 'no',
'exempt_guests' => 'no',
'exempt_payment_methods' => array(),
'notice_type' => 'error',
'hook_priority' => 20,
'disable_css' => 'no',
'debug' => 'no',
);
}
public static function get_settings()
{
$stored = get_option(self::OPTION_KEY, array());
if (!is_array($stored))
$stored = array();
return wp_parse_args($stored, self::defaults());
}
/* =========================================================
* نگاشت تب ↔ فیلد
* ========================================================= */
private static function tab_fields()
{
return array(
'general' => array('enabled', 'minimum_amount', 'apply_on', 'prevent_checkout', 'base_amount', 'include_shipping', 'include_discounts'),
'messages' => array('message', 'success_message', 'show_success_message'),
'progress' => array('progress_enabled', 'progress_show_percent', 'progress_show_remaining', 'progress_show_current', 'progress_show_minimum', 'progress_text_top', 'progress_text_bottom'),
'excludes' => array('excluded_products', 'excluded_categories', 'exempt_roles', 'exempt_logged_in', 'exempt_guests', 'exempt_payment_methods'),
'advanced' => array('notice_type', 'hook_priority', 'disable_css', 'debug'),
);
}
public function register_settings()
{
register_setting('icodito_min_order_group', self::OPTION_KEY, array(
'type' => 'array',
'sanitize_callback' => array($this, 'sanitize_settings'),
'default' => self::defaults(),
));
}
/** Sanitize – حفظ تنظیمات سایر تبها */
public function sanitize_settings($input)
{
$defaults = self::defaults();
$existing = self::get_settings();
if (!is_array($input))
return $existing;
$active_tab = isset($input['icodito_active_tab']) ? sanitize_key(wp_unslash($input['icodito_active_tab'])) : '';
$tab_map = self::tab_fields();
if (!isset($tab_map[$active_tab])) {
$fields_in_scope = array();
foreach ($tab_map as $fields)
$fields_in_scope = array_merge($fields_in_scope, $fields);
} else {
$fields_in_scope = $tab_map[$active_tab];
}
$out = $existing;
$checkboxes = array('enabled', 'prevent_checkout', 'include_shipping', 'include_discounts', 'show_success_message', 'progress_enabled', 'progress_show_percent', 'progress_show_remaining', 'progress_show_current', 'progress_show_minimum', 'exempt_logged_in', 'exempt_guests', 'disable_css', 'debug');
$arrays = array('excluded_categories', 'exempt_roles', 'exempt_payment_methods');
foreach ($fields_in_scope as $field) {
if (in_array($field, $checkboxes, true)) {
$out[$field] = (isset($input[$field]) && 'yes' === $input[$field]) ? 'yes' : 'no';
continue;
}
if (in_array($field, $arrays, true)) {
$out[$field] = array();
if (!empty($input[$field]) && is_array($input[$field])) {
$out[$field] = array_values(array_filter(array_map('sanitize_text_field', $input[$field])));
}
continue;
}
if ('minimum_amount' === $field) {
$out[$field] = isset($input[$field]) ? (float) wc_format_decimal($input[$field]) : 0;
continue;
}
if ('hook_priority' === $field) {
$out[$field] = isset($input[$field]) ? max(1, min(999, absint($input[$field]))) : 20;
continue;
}
if ('apply_on' === $field) {
$allowed = array('cart', 'checkout', 'both');
$out[$field] = isset($input[$field]) && in_array($input[$field], $allowed, true) ? $input[$field] : 'both';
continue;
}
if ('base_amount' === $field) {
$allowed = array('subtotal_before_discount', 'subtotal_after_discount', 'cart_total_no_shipping', 'final_total');
$out[$field] = isset($input[$field]) && in_array($input[$field], $allowed, true) ? $input[$field] : 'subtotal_after_discount';
continue;
}
if ('notice_type' === $field) {
$allowed = array('error', 'notice', 'success');
$out[$field] = isset($input[$field]) && in_array($input[$field], $allowed, true) ? $input[$field] : 'error';
continue;
}
if ('excluded_products' === $field) {
$out[$field] = '';
if (isset($input[$field]) && '' !== trim((string) $input[$field])) {
$ids = array_filter(array_map('absint', preg_split('/[\s,]+/', (string) $input[$field])));
$out[$field] = implode(',', array_unique($ids));
}
continue;
}
if ('progress_text_top' === $field) {
$out[$field] = isset($input[$field]) ? sanitize_text_field($input[$field]) : $defaults[$field];
continue;
}
if (in_array($field, array('message', 'success_message', 'progress_text_bottom'), true)) {
$out[$field] = isset($input[$field]) ? wp_kses_post($input[$field]) : $defaults[$field];
continue;
}
}
if ('yes' === $out['debug']) {
error_log('[Icodito Min Order] Settings saved (tab=' . $active_tab . '): ' . wp_json_encode($out));
}
return $out;
}
public function handle_reset()
{
if (!current_user_can(self::CAPABILITY))
wp_die(esc_html__('دسترسی مجاز نیست.', 'icodito'));
check_admin_referer('icodito_min_order_reset');
update_option(self::OPTION_KEY, self::defaults());
wp_safe_redirect(add_query_arg(array('page' => self::MENU_SLUG, 'reset' => '1'), admin_url('admin.php')));
exit;
}
public function add_menu()
{
add_submenu_page(
'woocommerce',
__('حداقل مبلغ سفارش', 'icodito'),
__('حداقل مبلغ سفارش', 'icodito'),
self::CAPABILITY,
self::MENU_SLUG,
array($this, 'render_settings_page')
);
}
/* =========================================================
* Assets
* ========================================================= */
public function admin_assets($hook)
{
if ('woocommerce_page_' . self::MENU_SLUG !== $hook)
return;
wp_register_style('icodito-min-order-admin', false, array(), '1.0.0');
wp_enqueue_style('icodito-min-order-admin');
wp_add_inline_style('icodito-min-order-admin', $this->admin_css());
}
/** Assets فرانت – روی همه صفحات فرانت لود میشود تا با AJAX Cart هم کار کند */
/** Assets فرانت – روی همه صفحات فرانت لود میشود تا با AJAX Cart هم کار کند */
public function frontend_assets()
{
$settings = self::get_settings();
if ('yes' !== $settings['enabled'])
return;
if (is_admin())
return;
// ===== CSS =====
if ('yes' !== $settings['disable_css']) {
wp_register_style('icodito-min-order-front', false, array(), '1.3.0');
wp_enqueue_style('icodito-min-order-front');
wp_add_inline_style('icodito-min-order-front', $this->frontend_css());
}
// ===== JS (Inline) =====
wp_register_script('icodito-min-order-front', '', array('jquery'), '1.3.0', true);
wp_enqueue_script('icodito-min-order-front');
wp_localize_script('icodito-min-order-front', 'icoditoMinOrder', array(
'ajaxUrl' => admin_url('admin-ajax.php'),
'nonce' => wp_create_nonce(self::AJAX_NONCE),
'action' => 'icodito_min_order_refresh',
'closeLabel' => __('جمع کردن', 'icodito'),
'expandLabel' => __('نمایش وضعیت حداقل مبلغ سفارش', 'icodito'),
'collapsedText' => __('حداقل مبلغ سفارش', 'icodito'),
));
// 🔴 این خط حیاتی بود که وجود نداشت:
wp_add_inline_script('icodito-min-order-front', $this->frontend_js());
}
/* =========================================================
* محاسبه مبلغ مبنا
* ========================================================= */
public function get_cart_base_amount()
{
if (!function_exists('WC') || !WC()->cart instanceof WC_Cart)
return 0.0;
$cart = WC()->cart;
$settings = self::get_settings();
$subtotal_with_tax = (float) $cart->get_subtotal() + (float) $cart->get_subtotal_tax();
$contents_with_tax = (float) $cart->get_cart_contents_total() + (float) $cart->get_cart_contents_tax();
$shipping_with_tax = (float) $cart->get_shipping_total() + (float) $cart->get_shipping_tax();
$fees_with_tax = (float) $cart->get_fee_total() + (float) $cart->get_fee_tax();
switch ($settings['base_amount']) {
case 'subtotal_before_discount':
$base = $subtotal_with_tax;
break;
case 'subtotal_after_discount':
$base = $contents_with_tax;
break;
case 'cart_total_no_shipping':
$base = $contents_with_tax + $fees_with_tax;
break;
case 'final_total':
default:
$base = (float) $cart->get_total('edit');
break;
}
if ('yes' === $settings['include_shipping'] && 'final_total' !== $settings['base_amount']) {
$base += $shipping_with_tax;
}
$base = max(0, (float) $base);
if ('yes' === $settings['debug']) {
error_log(sprintf('[Icodito Min Order] base=%.2f mode=%s', $base, $settings['base_amount']));
}
return $base;
}
/* =========================================================
* استثناها
* ========================================================= */
public function is_exempt()
{
$settings = self::get_settings();
if (is_user_logged_in()) {
if ('yes' === $settings['exempt_logged_in'])
return true;
$user = wp_get_current_user();
$exempt_roles = (array) $settings['exempt_roles'];
if ($exempt_roles && !empty($user->roles) && array_intersect($exempt_roles, (array) $user->roles))
return true;
} else {
if ('yes' === $settings['exempt_guests'])
return true;
}
if (function_exists('WC') && WC()->cart instanceof WC_Cart) {
$exempt_products = array_filter(array_map('absint', explode(',', (string) $settings['excluded_products'])));
$exempt_cats = array_filter(array_map('absint', (array) $settings['excluded_categories']));
if ($exempt_products || $exempt_cats) {
foreach (WC()->cart->get_cart() as $item) {
$product_id = !empty($item['product_id']) ? (int) $item['product_id'] : 0;
$variation_id = !empty($item['variation_id']) ? (int) $item['variation_id'] : 0;
if ($exempt_products) {
if (
($product_id && in_array($product_id, $exempt_products, true))
|| ($variation_id && in_array($variation_id, $exempt_products, true))
)
return true;
}
if ($exempt_cats && $product_id) {
$terms = wp_get_post_terms($product_id, 'product_cat', array('fields' => 'ids'));
if (!is_wp_error($terms) && $terms && array_intersect($terms, $exempt_cats))
return true;
}
}
}
}
$exempt_pms = (array) $settings['exempt_payment_methods'];
if ($exempt_pms && function_exists('WC') && WC()->session) {
$chosen = (string) WC()->session->get('chosen_payment_method');
if ($chosen && in_array($chosen, $exempt_pms, true))
return true;
}
return (bool) apply_filters('icodito_min_order_is_exempt', false);
}
/* =========================================================
* محاسبه
* ========================================================= */
public function get_calculation()
{
$settings = self::get_settings();
$minimum = (float) $settings['minimum_amount'];
$current = $this->get_cart_base_amount();
$remaining = max(0, $minimum - $current);
$progress = ($minimum > 0) ? min(100, ($current / $minimum) * 100) : 100;
return array(
'minimum' => $minimum,
'current' => $current,
'remaining' => $remaining,
'progress' => $progress,
'reached' => ($current >= $minimum),
'currency' => get_woocommerce_currency_symbol(),
);
}
public function format_message($template, $data)
{
$replace = array(
'{minimum}' => wc_price($data['minimum']),
'{cart_total}' => wc_price($data['current']),
'{remaining}' => wc_price($data['remaining']),
'{progress}' => number_format_i18n(round($data['progress'], 2), 2) . '%',
'{currency}' => esc_html($data['currency']),
);
return str_replace(array_keys($replace), array_values($replace), $template);
}
/* =========================================================
* تولید HTML نوار مینیمال تکردیفی
* ========================================================= */
public function get_notice_html()
{
$settings = self::get_settings();
if ('yes' !== $settings['enabled'])
return '';
if (!function_exists('WC') || !WC()->cart instanceof WC_Cart)
return '';
if (WC()->cart->is_empty())
return '';
if ($this->is_exempt())
return '';
if ((float) $settings['minimum_amount'] <= 0)
return '';
$data = $this->get_calculation();
if ($data['reached'] && 'yes' !== $settings['show_success_message']) {
return '';
}
$is_success = $data['reached'];
$percent = max(0, min(100, (float) $data['progress']));
$percent_display = (int) round($percent);
// ===== عنوان بالای متن (progress_text_top) =====
$title = trim((string) $settings['progress_text_top']);
if ('' === $title) {
$title = $is_success ? 'حداقل مبلغ سفارش تکمیل شد' : 'تا تکمیل حداقل مبلغ سفارش';
}
// ===== متن باقیمانده (progress_text_bottom) =====
$bottom_tpl = trim((string) $settings['progress_text_bottom']);
if ('' === $bottom_tpl) {
$bottom_tpl = $is_success ? 'میتوانید سفارش خود را ثبت کنید' : '{remaining} دیگر خرید کنید';
}
$bottom = $this->format_message($bottom_tpl, $data);
// ===== پیام اصلی داخل باکس سبز =====
if ($is_success) {
$badge_text = $this->format_message($settings['success_message'], $data);
$badge_icon = '✓';
} else {
$badge_text = $this->format_message($settings['message'], $data);
$badge_icon = '🎁';
}
$show_current = ('yes' === $settings['progress_show_current']);
$show_minimum = ('yes' === $settings['progress_show_minimum']);
$show_percent = ('yes' === $settings['progress_show_percent']);
$show_progress = ('yes' === $settings['progress_enabled']);
ob_start();
?>
<!-- ===== بخش راست: متن عنوان و باقیمانده ===== -->
<div class="icodito-min-order-bar-text">
<div class="icodito-min-order-bar-title"><?php echo wp_kses_post($title); ?></div>
<div class="icodito-min-order-bar-remaining"><?php echo wp_kses_post($bottom); ?></div>
</div>
<!-- ===== بخش میانی: نوار پیشرفت ===== -->
<?php if ($show_progress): ?>
<div class="icodito-min-order-bar-progress">
<?php if ($show_percent): ?>
<div class="icodito-min-order-bar-percent"><?php echo esc_html(number_format_i18n($percent_display) . '%'); ?>
</div>
<?php endif; ?>
<div class="icodito-min-order-bar-track" role="progressbar" aria-valuemin="0" aria-valuemax="100"
aria-valuenow="<?php echo esc_attr($percent_display); ?>">
<div class="icodito-min-order-bar-fill" style="width:<?php echo esc_attr($percent); ?>%;"></div>
</div>
<?php if ($show_current || $show_minimum): ?>
<div class="icodito-min-order-bar-meta">
<?php if ($show_minimum): ?>
<div class="icodito-min-order-bar-meta-item is-minimum">
<span class="value"><?php echo wp_kses_post(wc_price($data['minimum'])); ?></span>
<span class="label"><?php esc_html_e('حداقل مبلغ سفارش', 'icodito'); ?></span>
</div>
<?php endif; ?>
<?php if ($show_current): ?>
<div class="icodito-min-order-bar-meta-item is-current">
<span class="value"><?php echo wp_kses_post(wc_price($data['current'])); ?></span>
<span class="label"><?php esc_html_e('مبلغ فعلی سبد', 'icodito'); ?></span>
</div>
<?php endif; ?>
</div>
<?php endif; ?>
</div>
<?php endif; ?>
<!-- ===== بخش چپ: باکس پیام سبز ===== -->
<div class="icodito-min-order-bar-hint">
<span class="icodito-min-order-bar-hint-icon" aria-hidden="true"><?php echo esc_html($badge_icon); ?></span>
<span class="icodito-min-order-bar-hint-text"><?php echo wp_kses_post($badge_text); ?></span>
</div>
<!-- ===== بخش انتهایی: آیکون سبد خرید ===== -->
<div class="icodito-min-order-bar-cart" aria-hidden="true">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"
stroke-linejoin="round">
<circle cx="9" cy="21" r="1"></circle>
<circle cx="20" cy="21" r="1"></circle>
<path d="M1 1h4l2.68 13.39a2 2 0 0 0 2 1.61h9.72a2 2 0 0 0 2-1.61L23 6H6"></path>
</svg>
<span class="icodito-min-order-bar-cart-plus">+</span>
</div>
<?php
return ob_get_clean();
}
/* =========================================================
* رندر نوار شناور در فوتر
* ========================================================= */
public function render_floating_bar() {
$settings = self::get_settings();
if ( 'yes' !== $settings['enabled'] ) return;
if ( 'yes' !== $settings['progress_enabled'] ) return;
if ( is_admin() ) return;
$has_items = function_exists( 'WC' ) && WC()->cart && ! WC()->cart->is_empty();
if ( ! $has_items ) return;
if ( $this->is_exempt() ) return;
if ( (float) $settings['minimum_amount'] <= 0 ) return;
$html = $this->get_notice_html();
if ( '' === $html ) return;
$state = 'error';
$data = $this->get_calculation();
if ( $data['reached'] ) $state = 'success';
// متن کوتاه برای حالت جمعشده
$collapsed_text = trim( (string) $settings['progress_text_top'] );
if ( '' === $collapsed_text ) {
$collapsed_text = __( 'حداقل مبلغ سفارش', 'icodito' );
}
?>
<div id="icodito-min-order-floating"
class="icodito-min-order-floating icodito-min-order-bar--<?php echo esc_attr( $state ); ?> is-visible"
role="region"
aria-live="polite"
aria-label="<?php esc_attr_e( 'وضعیت حداقل مبلغ سفارش', 'icodito' ); ?>">
<div class="icodito-min-order-floating-inner">
<?php echo $html; // escaped internally ?>
</div>
<button type="button"
class="icodito-min-order-floating-close"
aria-label="<?php esc_attr_e( 'جمع کردن', 'icodito' ); ?>"
title="<?php esc_attr_e( 'جمع کردن', 'icodito' ); ?>">
<span aria-hidden="true">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><g fill="none" stroke="currentColor" stroke-width="1.5"><path d="M2 12c0-4.714 0-7.071 1.464-8.536C4.93 2 7.286 2 12 2s7.071 0 8.535 1.464C22 4.93 22 7.286 22 12s0 7.071-1.465 8.535C19.072 22 16.714 22 12 22s-7.071 0-8.536-1.465C2 19.072 2 16.714 2 12Z" opacity=".5"/><path stroke-linecap="round" d="m14.5 9.5l-5 5m0-5l5 5"/></g></svg>
</span>
</button>
<button type="button"
class="icodito-min-order-collapsed-trigger"
aria-label="<?php esc_attr_e( 'نمایش وضعیت حداقل مبلغ سفارش', 'icodito' ); ?>"
title="<?php esc_attr_e( 'نمایش', 'icodito' ); ?>">
<span class="icodito-min-order-collapsed-text"><?php echo esc_html( $collapsed_text ); ?></span>
<span class="icodito-min-order-collapsed-arrow" aria-hidden="true">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor"
stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round">
<polyline points="18 15 12 9 6 15"></polyline>
</svg>
</span>
</button>
</div>
<?php
}
/* =========================================================
* اعتبارسنجی
* ========================================================= */
public function validate_cart()
{
$settings = self::get_settings();
if ('yes' !== $settings['enabled'])
return;
if ('yes' !== $settings['prevent_checkout'])
return;
if (!function_exists('WC') || !WC()->cart instanceof WC_Cart)
return;
if (WC()->cart->is_empty())
return;
if ($this->is_exempt())
return;
if ((float) $settings['minimum_amount'] <= 0)
return;
if (!in_array($settings['apply_on'], array('cart', 'both'), true))
return;
$data = $this->get_calculation();
if (!$data['reached']) {
wc_add_notice(wp_kses_post($this->format_message($settings['message'], $data)), 'error');
}
}
public function validate_checkout()
{
$settings = self::get_settings();
if ('yes' !== $settings['enabled'])
return;
if ('yes' !== $settings['prevent_checkout'])
return;
if (!function_exists('WC') || !WC()->cart instanceof WC_Cart)
return;
if (WC()->cart->is_empty())
return;
if ($this->is_exempt())
return;
if ((float) $settings['minimum_amount'] <= 0)
return;
if (!in_array($settings['apply_on'], array('checkout', 'both'), true))
return;
$data = $this->get_calculation();
if (!$data['reached']) {
wc_add_notice(wp_kses_post($this->format_message($settings['message'], $data)), 'error');
}
}
public function store_api_errors($errors, $cart)
{
$settings = self::get_settings();
if ('yes' !== $settings['enabled'])
return $errors;
if ('yes' !== $settings['prevent_checkout'])
return $errors;
if ($this->is_exempt())
return $errors;
if ((float) $settings['minimum_amount'] <= 0)
return $errors;
if (!$errors instanceof WP_Error)
$errors = new WP_Error();
$data = $this->get_calculation();
if (!$data['reached']) {
$message = wp_strip_all_tags($this->format_message($settings['message'], $data));
$errors->add('icodito_min_order', $message);
}
return $errors;
}
/* =========================================================
* AJAX Refresh
* ========================================================= */
public function ajax_refresh()
{
check_ajax_referer(self::AJAX_NONCE, 'nonce');
if (function_exists('wc_load_cart') && (!WC()->cart)) {
wc_load_cart();
}
$html = $this->get_notice_html();
$cart_count = (function_exists('WC') && WC()->cart) ? WC()->cart->get_cart_contents_count() : 0;
$state = 'error';
if (function_exists('WC') && WC()->cart && !WC()->cart->is_empty()) {
$data = $this->get_calculation();
if ($data['reached'])
$state = 'success';
}
wp_send_json_success(array(
'html' => $html,
'cart_count' => (int) $cart_count,
'state' => $state,
));
}
/* =========================================================
* صفحه تنظیمات
* ========================================================= */
public function render_settings_page()
{
if (!current_user_can(self::CAPABILITY))
wp_die(esc_html__('شما اجازه دسترسی به این صفحه را ندارید.', 'icodito'));
$settings = self::get_settings();
$active = isset($_GET['tab']) ? sanitize_key(wp_unslash($_GET['tab'])) : 'general';
$tabs = array(
'general' => __('تنظیمات عمومی', 'icodito'),
'messages' => __('پیامها', 'icodito'),
'progress' => __('نوار پیشرفت', 'icodito'),
'excludes' => __('استثناها', 'icodito'),
'advanced' => __('پیشرفته', 'icodito'),
);
if (!isset($tabs[$active]))
$active = 'general';
$roles = wp_roles()->get_names();
$pms = array();
if (function_exists('WC') && WC()->payment_gateways()) {
foreach (WC()->payment_gateways()->payment_gateways() as $gateway) {
if ('yes' === $gateway->enabled)
$pms[$gateway->id] = $gateway->get_title();
}
}
$categories = get_terms(array('taxonomy' => 'product_cat', 'hide_empty' => false, 'number' => 300));
?>
<div class="wrap icodito-min-order-wrap">
<h1 class="icodito-min-order-title">
<span class="dashicons dashicons-cart"></span>
<?php esc_html_e('حداقل مبلغ سفارش', 'icodito'); ?>
</h1>
<?php $this->render_author_support_box(); ?>
<?php if (isset($_GET['settings-updated'])): ?>
<div class="notice notice-success is-dismissible">
<p><?php esc_html_e('تنظیمات با موفقیت ذخیره شد.', 'icodito'); ?></p>
</div>
<?php endif; ?>
<?php if (isset($_GET['reset'])): ?>
<div class="notice notice-success is-dismissible">
<p><?php esc_html_e('تنظیمات به حالت پیشفرض بازگشت.', 'icodito'); ?></p>
</div>
<?php endif; ?>
<nav class="nav-tab-wrapper icodito-min-order-tabs">
<?php foreach ($tabs as $key => $label):
$url = add_query_arg(array('page' => self::MENU_SLUG, 'tab' => $key), admin_url('admin.php'));
?>
<a class="nav-tab <?php echo $active === $key ? 'nav-tab-active' : ''; ?>"
href="<?php echo esc_url($url); ?>">
<?php echo esc_html($label); ?>
</a>
<?php endforeach; ?>
</nav>
<form method="post" action="options.php" class="icodito-min-order-form">
<?php settings_fields('icodito_min_order_group'); ?>
<input type="hidden" name="<?php echo esc_attr(self::OPTION_KEY); ?>[icodito_active_tab]"
value="<?php echo esc_attr($active); ?>">
<?php if ('general' === $active): ?>
<table class="form-table" role="presentation">
<tr>
<th scope="row"><?php esc_html_e('فعالسازی حداقل مبلغ سفارش', 'icodito'); ?></th>
<td>
<label class="icodito-switch">
<input type="checkbox" name="<?php echo esc_attr(self::OPTION_KEY); ?>[enabled]" value="yes"
<?php checked($settings['enabled'], 'yes'); ?>>
<span class="icodito-switch-slider"></span>
</label>
</td>
</tr>
<tr>
<th scope="row"><label
for="icodito-min-amount"><?php esc_html_e('حداقل مبلغ سفارش', 'icodito'); ?></label></th>
<td>
<input type="number" min="0" step="any" id="icodito-min-amount"
name="<?php echo esc_attr(self::OPTION_KEY); ?>[minimum_amount]"
value="<?php echo esc_attr($settings['minimum_amount']); ?>" class="regular-text">
<p class="description">
<?php printf(esc_html__('کمترین مبلغ برای ثبت سفارش. پیشنمایش: %s', 'icodito'), wp_kses_post(wc_price((float) $settings['minimum_amount']))); ?>
</p>
</td>
</tr>
<tr>
<th scope="row"><?php esc_html_e('محل اعمال محدودیت', 'icodito'); ?></th>
<td>
<fieldset>
<label><input type="radio" name="<?php echo esc_attr(self::OPTION_KEY); ?>[apply_on]"
value="cart" <?php checked($settings['apply_on'], 'cart'); ?>>
<?php esc_html_e('فقط سبد خرید', 'icodito'); ?></label><br>
<label><input type="radio" name="<?php echo esc_attr(self::OPTION_KEY); ?>[apply_on]"
value="checkout" <?php checked($settings['apply_on'], 'checkout'); ?>>
<?php esc_html_e('فقط تسویهحساب', 'icodito'); ?></label><br>
<label><input type="radio" name="<?php echo esc_attr(self::OPTION_KEY); ?>[apply_on]"
value="both" <?php checked($settings['apply_on'], 'both'); ?>>
<?php esc_html_e('سبد خرید و تسویهحساب', 'icodito'); ?></label>
</fieldset>
</td>
</tr>
<tr>
<th scope="row"><?php esc_html_e('جلوگیری از ثبت سفارش', 'icodito'); ?></th>
<td>
<label class="icodito-switch">
<input type="checkbox" name="<?php echo esc_attr(self::OPTION_KEY); ?>[prevent_checkout]"
value="yes" <?php checked($settings['prevent_checkout'], 'yes'); ?>>
<span class="icodito-switch-slider"></span>
</label>
</td>
</tr>
<tr>
<th scope="row"><label
for="icodito-base-amount"><?php esc_html_e('مبلغ مبنا برای حداقل سفارش', 'icodito'); ?></label>
</th>
<td>
<select id="icodito-base-amount" name="<?php echo esc_attr(self::OPTION_KEY); ?>[base_amount]"
class="regular-text">
<option value="subtotal_before_discount" <?php selected($settings['base_amount'], 'subtotal_before_discount'); ?>>
<?php esc_html_e('مجموع قیمت محصولات قبل از تخفیف', 'icodito'); ?></option>
<option value="subtotal_after_discount" <?php selected($settings['base_amount'], 'subtotal_after_discount'); ?>>
<?php esc_html_e('مجموع قیمت محصولات بعد از تخفیف (بدون حمل)', 'icodito'); ?></option>
<option value="cart_total_no_shipping" <?php selected($settings['base_amount'], 'cart_total_no_shipping'); ?>>
<?php esc_html_e('مجموع سبد پس از تخفیف و بدون هزینه حملونقل', 'icodito'); ?></option>
<option value="final_total" <?php selected($settings['base_amount'], 'final_total'); ?>>
<?php esc_html_e('مجموع نهایی قابل پرداخت (شامل حملونقل)', 'icodito'); ?></option>
</select>
</td>
</tr>
<tr>
<th scope="row"><?php esc_html_e('هزینه حملونقل', 'icodito'); ?></th>
<td>
<label class="icodito-switch">
<input type="checkbox" name="<?php echo esc_attr(self::OPTION_KEY); ?>[include_shipping]"
value="yes" <?php checked($settings['include_shipping'], 'yes'); ?>>
<span class="icodito-switch-slider"></span>
</label>
<span
class="icodito-inline-label"><?php esc_html_e('هزینه حملونقل در حداقل مبلغ محاسبه شود؟', 'icodito'); ?></span>
</td>
</tr>
<tr>
<th scope="row"><?php esc_html_e('تخفیف و کوپن', 'icodito'); ?></th>
<td>
<label class="icodito-switch">
<input type="checkbox" name="<?php echo esc_attr(self::OPTION_KEY); ?>[include_discounts]"
value="yes" <?php checked($settings['include_discounts'], 'yes'); ?>>
<span class="icodito-switch-slider"></span>
</label>
<span
class="icodito-inline-label"><?php esc_html_e('تخفیف و کوپن در محاسبه لحاظ شود؟', 'icodito'); ?></span>
</td>
</tr>
</table>
<?php elseif ('messages' === $active): ?>
<table class="form-table" role="presentation">
<tr>
<th scope="row"><label
for="icodito-message"><?php esc_html_e('پیام حداقل مبلغ', 'icodito'); ?></label></th>
<td>
<textarea id="icodito-message" rows="3" class="large-text"
name="<?php echo esc_attr(self::OPTION_KEY); ?>[message]"><?php echo esc_textarea($settings['message']); ?></textarea>
<p class="description">
<code>{minimum}</code> <?php esc_html_e('حداقل مبلغ', 'icodito'); ?> |
<code>{cart_total}</code> <?php esc_html_e('مبلغ فعلی سبد', 'icodito'); ?> |
<code>{remaining}</code> <?php esc_html_e('مبلغ باقیمانده', 'icodito'); ?> |
<code>{progress}</code> <?php esc_html_e('درصد', 'icodito'); ?> |
<code>{currency}</code> <?php esc_html_e('واحد پول', 'icodito'); ?>
</p>
</td>
</tr>
<tr>
<th scope="row"><label
for="icodito-success-message"><?php esc_html_e('پیام تکمیل حداقل مبلغ', 'icodito'); ?></label>
</th>
<td>
<textarea id="icodito-success-message" rows="2" class="large-text"
name="<?php echo esc_attr(self::OPTION_KEY); ?>[success_message]"><?php echo esc_textarea($settings['success_message']); ?></textarea>
</td>
</tr>
<tr>
<th scope="row"><?php esc_html_e('نمایش پیام موفقیت', 'icodito'); ?></th>
<td>
<label class="icodito-switch">
<input type="checkbox" name="<?php echo esc_attr(self::OPTION_KEY); ?>[show_success_message]"
value="yes" <?php checked($settings['show_success_message'], 'yes'); ?>>
<span class="icodito-switch-slider"></span>
</label>
</td>
</tr>
</table>
<?php elseif ('progress' === $active): ?>
<table class="form-table" role="presentation">
<tr>
<th scope="row"><?php esc_html_e('فعالسازی نوار پیشرفت شناور', 'icodito'); ?></th>
<td>
<label class="icodito-switch">
<input type="checkbox" name="<?php echo esc_attr(self::OPTION_KEY); ?>[progress_enabled]"
value="yes" <?php checked($settings['progress_enabled'], 'yes'); ?>>
<span class="icodito-switch-slider"></span>
</label>
<p class="description">
<?php esc_html_e('نوار باریک در پایین همه صفحات فرانت هنگام وجود کالا در سبد نمایش داده میشود.', 'icodito'); ?>
</p>
</td>
</tr>
<tr>
<th scope="row"><?php esc_html_e('نمایش درصد', 'icodito'); ?></th>
<td><label class="icodito-switch"><input type="checkbox"
name="<?php echo esc_attr(self::OPTION_KEY); ?>[progress_show_percent]" value="yes" <?php checked($settings['progress_show_percent'], 'yes'); ?>><span
class="icodito-switch-slider"></span></label></td>
</tr>
<tr>
<th scope="row"><?php esc_html_e('نمایش مبلغ باقیمانده', 'icodito'); ?></th>
<td><label class="icodito-switch"><input type="checkbox"
name="<?php echo esc_attr(self::OPTION_KEY); ?>[progress_show_remaining]" value="yes"
<?php checked($settings['progress_show_remaining'], 'yes'); ?>><span
class="icodito-switch-slider"></span></label></td>
</tr>
<tr>
<th scope="row"><?php esc_html_e('نمایش مبلغ فعلی', 'icodito'); ?></th>
<td><label class="icodito-switch"><input type="checkbox"
name="<?php echo esc_attr(self::OPTION_KEY); ?>[progress_show_current]" value="yes" <?php checked($settings['progress_show_current'], 'yes'); ?>><span
class="icodito-switch-slider"></span></label></td>
</tr>
<tr>
<th scope="row"><?php esc_html_e('نمایش حداقل مبلغ', 'icodito'); ?></th>
<td><label class="icodito-switch"><input type="checkbox"
name="<?php echo esc_attr(self::OPTION_KEY); ?>[progress_show_minimum]" value="yes" <?php checked($settings['progress_show_minimum'], 'yes'); ?>><span
class="icodito-switch-slider"></span></label></td>
</tr>
<tr>
<th scope="row"><label
for="icodito-progress-top"><?php esc_html_e('متن بالای نوار (اختیاری)', 'icodito'); ?></label>
</th>
<td>
<input type="text" class="large-text" id="icodito-progress-top"
name="<?php echo esc_attr(self::OPTION_KEY); ?>[progress_text_top]"
value="<?php echo esc_attr($settings['progress_text_top']); ?>"
placeholder="<?php esc_attr_e('خالی بگذارید تا نمایش داده نشود', 'icodito'); ?>">
</td>
</tr>
<tr>
<th scope="row"><label
for="icodito-progress-bottom"><?php esc_html_e('متن زیر نوار (اختیاری)', 'icodito'); ?></label>
</th>
<td>
<input type="text" class="large-text" id="icodito-progress-bottom"
name="<?php echo esc_attr(self::OPTION_KEY); ?>[progress_text_bottom]"
value="<?php echo esc_attr($settings['progress_text_bottom']); ?>"
placeholder="<?php esc_attr_e('خالی بگذارید تا نمایش داده نشود', 'icodito'); ?>">
<p class="description">
<?php esc_html_e('در نسخه مینیمال فعلی، این متون داخل نوار نمایش داده نمیشوند.', 'icodito'); ?>
</p>
</td>
</tr>
</table>
<?php elseif ('excludes' === $active): ?>
<table class="form-table" role="presentation">
<tr>
<th scope="row"><label
for="icodito-excluded-products"><?php esc_html_e('استثنای محصولات (ID)', 'icodito'); ?></label>
</th>
<td>
<input type="text" class="large-text" id="icodito-excluded-products"
name="<?php echo esc_attr(self::OPTION_KEY); ?>[excluded_products]"
value="<?php echo esc_attr($settings['excluded_products']); ?>" placeholder="100, 125, 350">
</td>
</tr>
<tr>
<th scope="row"><?php esc_html_e('استثنای دستهبندیها', 'icodito'); ?></th>
<td>
<?php if (!is_wp_error($categories) && $categories): ?>
<div class="icodito-checkbox-list">
<?php foreach ($categories as $cat): ?>
<label class="icodito-checkbox-item">
<input type="checkbox"
name="<?php echo esc_attr(self::OPTION_KEY); ?>[excluded_categories][]"
value="<?php echo esc_attr($cat->term_id); ?>" <?php checked(in_array((int) $cat->term_id, (array) $settings['excluded_categories'], true)); ?>>
<?php echo esc_html($cat->name); ?>
</label>
<?php endforeach; ?>
</div>
<?php endif; ?>
</td>
</tr>
<tr>
<th scope="row"><?php esc_html_e('نقشهای معاف', 'icodito'); ?></th>
<td>
<div class="icodito-checkbox-list">
<?php foreach ($roles as $role_key => $role_name): ?>
<label class="icodito-checkbox-item">
<input type="checkbox" name="<?php echo esc_attr(self::OPTION_KEY); ?>[exempt_roles][]"
value="<?php echo esc_attr($role_key); ?>" <?php checked(in_array($role_key, (array) $settings['exempt_roles'], true)); ?>>
<?php echo esc_html(translate_user_role($role_name)); ?>
</label>
<?php endforeach; ?>
</div>
</td>
</tr>
<tr>
<th scope="row"><?php esc_html_e('کاربران واردشده', 'icodito'); ?></th>
<td>
<label class="icodito-switch"><input type="checkbox"
name="<?php echo esc_attr(self::OPTION_KEY); ?>[exempt_logged_in]" value="yes" <?php checked($settings['exempt_logged_in'], 'yes'); ?>><span
class="icodito-switch-slider"></span></label>
<span class="icodito-inline-label"><?php esc_html_e('معاف باشند.', 'icodito'); ?></span>
</td>
</tr>
<tr>
<th scope="row"><?php esc_html_e('کاربران مهمان', 'icodito'); ?></th>
<td>
<label class="icodito-switch"><input type="checkbox"
name="<?php echo esc_attr(self::OPTION_KEY); ?>[exempt_guests]" value="yes" <?php checked($settings['exempt_guests'], 'yes'); ?>><span class="icodito-switch-slider"></span></label>
<span class="icodito-inline-label"><?php esc_html_e('معاف باشند.', 'icodito'); ?></span>
</td>
</tr>
<tr>
<th scope="row"><?php esc_html_e('روشهای پرداخت معاف', 'icodito'); ?></th>
<td>
<?php if ($pms): ?>
<div class="icodito-checkbox-list">
<?php foreach ($pms as $pm_id => $pm_title): ?>
<label class="icodito-checkbox-item">
<input type="checkbox"
name="<?php echo esc_attr(self::OPTION_KEY); ?>[exempt_payment_methods][]"
value="<?php echo esc_attr($pm_id); ?>" <?php checked(in_array($pm_id, (array) $settings['exempt_payment_methods'], true)); ?>>
<?php echo esc_html($pm_title); ?>
</label>
<?php endforeach; ?>
</div>
<?php endif; ?>
</td>
</tr>
</table>
<?php else: ?>
<table class="form-table" role="presentation">
<tr>
<th scope="row"><label for="icodito-notice-type"><?php esc_html_e('نوع Notice', 'icodito'); ?></label>
</th>
<td>
<select id="icodito-notice-type" name="<?php echo esc_attr(self::OPTION_KEY); ?>[notice_type]">
<option value="error" <?php selected($settings['notice_type'], 'error'); ?>>
<?php esc_html_e('Error', 'icodito'); ?></option>
<option value="notice" <?php selected($settings['notice_type'], 'notice'); ?>>
<?php esc_html_e('Notice', 'icodito'); ?></option>
<option value="success" <?php selected($settings['notice_type'], 'success'); ?>>
<?php esc_html_e('Success', 'icodito'); ?></option>
</select>
</td>
</tr>
<tr>
<th scope="row"><label
for="icodito-hook-priority"><?php esc_html_e('اولویت Hook', 'icodito'); ?></label></th>
<td><input type="number" min="1" max="999" id="icodito-hook-priority"
name="<?php echo esc_attr(self::OPTION_KEY); ?>[hook_priority]"
value="<?php echo esc_attr($settings['hook_priority']); ?>" class="small-text"></td>
</tr>
<tr>
<th scope="row"><?php esc_html_e('حذف CSS پیشفرض', 'icodito'); ?></th>
<td>
<label class="icodito-switch"><input type="checkbox"
name="<?php echo esc_attr(self::OPTION_KEY); ?>[disable_css]" value="yes" <?php checked($settings['disable_css'], 'yes'); ?>><span class="icodito-switch-slider"></span></label>
</td>
</tr>
<tr>
<th scope="row"><?php esc_html_e('حالت Debug', 'icodito'); ?></th>
<td>
<label class="icodito-switch"><input type="checkbox"
name="<?php echo esc_attr(self::OPTION_KEY); ?>[debug]" value="yes" <?php checked($settings['debug'], 'yes'); ?>><span class="icodito-switch-slider"></span></label>
</td>
</tr>
</table>
<?php endif; ?>
<?php submit_button(__('ذخیره تنظیمات', 'icodito')); ?>
</form>
<hr class="icodito-sep">
<form method="post" action="<?php echo esc_url(admin_url('admin-post.php')); ?>"
onsubmit="return confirm('<?php echo esc_js(__('آیا مطمئن هستید؟', 'icodito')); ?>');">
<input type="hidden" name="action" value="icodito_min_order_reset">
<?php wp_nonce_field('icodito_min_order_reset'); ?>
<button type="submit" class="button button-secondary icodito-reset-btn">
<span class="dashicons dashicons-update"></span>
<?php esc_html_e('بازگردانی تنظیمات پیشفرض', 'icodito'); ?>
</button>
</form>
</div>
<?php
}
/* =========================================================
* باکس حمایت از آی کدیتو
* ========================================================= */
public function render_author_support_box()
{
?>
<div class="icodito-author-support">
<div class="icodito-author-support-icon">❤️</div>
<div class="icodito-author-support-content">
<h3>این کد توسط آی کدیتو نوشته و بهینه شده است</h3>
<p>
این کد با هدف ارائه یک راهکار کاربردی و رایگان توسط
<strong>آی کدیتو</strong> تهیه و بهینه شده است.
در صورت مفید بودن این کد و استفاده از آن در سایت خود،
میتوانید با حمایت از آی کدیتو به ادامه توسعه و انتشار
کدها و منابع رایگان کمک کنید.
</p>
<div class="icodito-author-support-links">
<a href="https://icodito.ir/" target="_blank" rel="noopener noreferrer">وبسایت آی کدیتو</a>
<a href="https://donito.me/icodito" target="_blank" rel="noopener noreferrer">حمایت مالی از آی کدیتو</a>
</div>
</div>
</div>
<?php
}
/* =========================================================
* CSS مدیریت
* ========================================================= */
private function admin_css()
{
return '
.icodito-min-order-wrap{max-width:1080px}
.icodito-min-order-title{display:flex;align-items:center;gap:10px;margin:12px 0 18px;font-size:22px;font-weight:700;color:#1e293b}
.icodito-min-order-title .dashicons{font-size:26px;width:26px;height:26px;color:#00bcd4}
.icodito-author-support{display:flex;align-items:flex-start;gap:16px;margin:0 0 22px;padding:20px 22px;background:#f8fafc;border:1px solid #e2e8f0;border-right:4px solid #00bcd4;border-radius:10px 0 0 10px;direction:rtl;text-align:right;box-sizing:border-box}
.icodito-author-support-icon{display:flex;align-items:center;justify-content:center;flex:0 0 44px;width:44px;height:44px;background:#fff;border:1px solid #e2e8f0;border-radius:50%;font-size:20px;line-height:1}
.icodito-author-support-content{flex:1;min-width:0}
.icodito-author-support-content h3{margin:0 0 8px;color:#1e293b;font-size:15px;font-weight:700;line-height:1.8}
.icodito-author-support-content p{margin:0;color:#64748b;font-size:13px;line-height:2}
.icodito-author-support-links{display:flex;flex-wrap:wrap;align-items:center;gap:8px;margin-top:14px}
.icodito-author-support-links a{display:inline-flex;align-items:center;justify-content:center;padding:7px 13px;background:#fff;color:#00a5bb;border:1px solid #cbd5e1;border-radius:7px;font-size:12px;font-weight:600;text-decoration:none;transition:all .2s}
.icodito-author-support-links a:hover{background:#00bcd4;color:#fff;border-color:#00bcd4}
@media (max-width:600px){.icodito-author-support{gap:12px;padding:16px}.icodito-author-support-icon{flex-basis:38px;width:38px;height:38px;font-size:17px}.icodito-author-support-links{flex-direction:column;align-items:stretch}.icodito-author-support-links a{width:100%}}
.icodito-min-order-form{background:#fff;border:1px solid #e2e8f0;border-radius:10px;padding:6px 22px 18px;margin-top:18px}
.icodito-switch{position:relative;display:inline-block;width:44px;height:24px;vertical-align:middle}
.icodito-switch input{opacity:0;width:0;height:0}
.icodito-switch-slider{position:absolute;cursor:pointer;top:0;left:0;right:0;bottom:0;background-color:#cbd5e1;transition:.25s;border-radius:24px}
.icodito-switch-slider::before{position:absolute;content:"";height:18px;width:18px;left:3px;bottom:3px;background-color:#fff;transition:.25s;border-radius:50%;box-shadow:0 1px 3px rgba(0,0,0,.15)}
.icodito-switch input:checked + .icodito-switch-slider{background-color:#00bcd4}
.icodito-switch input:checked + .icodito-switch-slider::before{transform:translateX(20px)}
body.rtl .icodito-switch input:checked + .icodito-switch-slider::before{transform:translateX(20px)}
.icodito-inline-label{margin-inline-start:8px;vertical-align:middle}
.icodito-checkbox-list{display:grid;grid-template-columns:repeat(auto-fill,minmax(200px,1fr));gap:8px;max-height:260px;overflow:auto;padding:10px;background:#f8fafc;border:1px solid #e2e8f0;border-radius:8px}
.icodito-checkbox-item{display:flex;align-items:center;gap:6px;font-size:13px;color:#334155}
.icodito-sep{margin:22px 0 16px;border:0;border-top:1px solid #e2e8f0}
.icodito-reset-btn .dashicons{font-size:16px;width:16px;height:16px;vertical-align:middle;margin-inline-end:4px}
';
}
private function frontend_css()
{
return '
/* ============================================================
* نوار شناور مینیمال سفید – آی کدیتو (طرح کارتی)
* ============================================================ */
.icodito-min-order-floating{
position:fixed;
left:16px;
right:16px;
bottom:16px;
z-index:999990;
max-width:1200px;
margin:0 auto;
background:#ffffff;
border-radius:24px;
box-shadow:0 20px 50px rgba(15,23,42,.12),0 6px 18px rgba(15,23,42,.06);
transform:translateY(140%);
opacity:0;
visibility:hidden;
transition:transform .5s cubic-bezier(.4,0,.2,1),opacity .35s ease,visibility 0s linear .5s;
will-change:transform;
font-family:inherit;
box-sizing:border-box;
direction:inherit;
padding:16px 22px;
}
.icodito-min-order-floating.is-visible{
transform:translateY(0);
opacity:1;
visibility:visible;
transition:transform .5s cubic-bezier(.4,0,.2,1),opacity .35s ease,visibility 0s;
}
.icodito-min-order-floating-inner{
display:flex;
align-items:center;
justify-content:space-between;
gap:22px;
width:100%;
box-sizing:border-box;
}
/* ============================================================
* بخش متن (راست در RTL)
* ============================================================ */
.icodito-min-order-bar-text{
flex:0 0 auto;
min-width:170px;
max-width:230px;
text-align:start;
line-height:1.6;
}
.icodito-min-order-bar-title{
font-size:14.5px;
font-weight:700;
color:#0f172a;
margin-bottom:5px;
}
.icodito-min-order-bar-remaining{
font-size:12.5px;
font-weight:500;
color:#64748b;
line-height:1.7;
}
.icodito-min-order-bar-remaining .woocommerce-Price-amount,
.icodito-min-order-bar-remaining bdi{
color:#10b981;
font-weight:800;
white-space:nowrap;
}
/* ============================================================
* نوار پیشرفت (وسط)
* ============================================================ */
.icodito-min-order-bar-progress{
flex:1 1 auto;
min-width:180px;
display:flex;
flex-direction:column;
gap:5px;
}
.icodito-min-order-bar-percent{
font-size:13px;
font-weight:700;
color:#10b981;
text-align:end;
letter-spacing:.3px;
line-height:1;
padding-inline-end:2px;
}
.icodito-min-order-bar-track{
display:block;
width:100%;
height:9px;
background:#e5e7eb;
border-radius:999px;
overflow:hidden;
position:relative;
}
.icodito-min-order-bar-fill{
display:block;
height:100%;
background:linear-gradient(90deg,#10b981 0%,#059669 100%);
border-radius:999px;
transition:width .6s cubic-bezier(.4,0,.2,1);
box-shadow:0 0 8px rgba(16,185,129,.4);
}
.icodito-min-order-bar-meta{
display:flex;
justify-content:space-between;
align-items:flex-start;
gap:12px;
margin-top:2px;
}
.icodito-min-order-bar-meta-item{
display:flex;
flex-direction:column;
gap:1px;
}
.icodito-min-order-bar-meta-item.is-minimum{
text-align:end;
align-items:flex-end;
}
.icodito-min-order-bar-meta-item.is-current{
text-align:start;
align-items:flex-start;
}
.icodito-min-order-bar-meta-item .value{
font-size:12px;
font-weight:800;
color:#0f172a;
white-space:nowrap;
line-height:1.4;
}
.icodito-min-order-bar-meta-item .label{
font-size:10.5px;
font-weight:500;
color:#94a3b8;
line-height:1.4;
}
/* ============================================================
* باکس پیام سبز (چپ)
* ============================================================ */
.icodito-min-order-bar-hint{
flex:0 1 auto;
display:inline-flex;
align-items:center;
gap:10px;
padding:12px 16px;
background:#ecfdf5;
border-radius:16px;
min-width:0;
max-width:270px;
line-height:1.6;
}
.icodito-min-order-bar-hint-icon{
flex:0 0 auto;
font-size:19px;
line-height:1;
color:#047857;
}
.icodito-min-order-bar-hint-text{
font-size:12.5px;
font-weight:700;
color:#047857;
line-height:1.65;
}
.icodito-min-order-bar-hint-text .woocommerce-Price-amount,
.icodito-min-order-bar-hint-text bdi{
color:#047857;
font-weight:800;
}
/* ============================================================
* آیکون سبد خرید (انتهای چپ در RTL)
* ============================================================ */
.icodito-min-order-bar-cart{
flex:0 0 auto;
width:52px;
height:52px;
display:inline-flex;
align-items:center;
justify-content:center;
background:#ecfdf5;
border-radius:50%;
color:#10b981;
position:relative;
}
.icodito-min-order-bar-cart svg{
width:24px;
height:24px;
display:block;
stroke:#10b981;
}
.icodito-min-order-bar-cart-plus{
position:absolute;
bottom:2px;
inset-inline-end:2px;
width:18px;
height:18px;
background:#10b981;
color:#fff;
border-radius:50%;
display:inline-flex;
align-items:center;
justify-content:center;
font-size:13px;
font-weight:800;
line-height:1;
border:2px solid #ffffff;
box-shadow:0 2px 4px rgba(16,185,129,.3);
}
/* ============================================================
* دکمه بستن
* ============================================================ */
.icodito-min-order-floating-close{
position:absolute;
top:8px;
inset-inline-end:10px;
width:24px;
height:24px;
border:0;
background:transparent;
font-size:18px;
line-height:1;
cursor:pointer;
display:inline-flex;
align-items:center;
justify-content:center;
border-radius:50%;
padding:0;
transition:background .2s ease,color .2s ease,transform .2s ease;
font-family:inherit;
opacity:.65;
}
.icodito-min-order-floating-close:hover{
transform:rotate(90deg);
opacity:1;
}
.icodito-min-order-floating-close:focus{
outline:2px solid #10b981;
outline-offset:2px;
}
.icodito-min-order-floating-close span svg{
color: #F44336;
width: 35px;
height: 30px;
}
/* ============================================================
* حالت موفقیت (RTL)
* ============================================================ */
.icodito-min-order-floating.icodito-min-order-bar--success .icodito-min-order-bar-hint{
background:#d1fae5;
}
.icodito-min-order-floating.icodito-min-order-bar--success .icodito-min-order-bar-hint-text,
.icodito-min-order-floating.icodito-min-order-bar--success .icodito-min-order-bar-hint-icon{
color:#065f46;
}
.icodito-min-order-floating.icodito-min-order-bar--success .icodito-min-order-bar-cart{
background:#d1fae5;
}
/* ============================================================
* ریسپانسیو
* ============================================================ */
@media (max-width:960px){
.icodito-min-order-floating{
padding:14px 18px;
border-radius:20px;
}
.icodito-min-order-floating-inner{
gap:16px;
}
.icodito-min-order-bar-hint{
padding:10px 14px;
max-width:220px;
}
.icodito-min-order-bar-hint-text{
font-size:12px;
}
.icodito-min-order-bar-cart{
width:46px;
height:46px;
}
.icodito-min-order-bar-cart svg{
width:21px;
height:21px;
}
}
@media (max-width:782px){
.icodito-min-order-floating{
left:10px;
right:10px;
bottom:10px;
padding:13px 15px;
border-radius:18px;
}
.icodito-min-order-floating-inner{
flex-wrap:wrap;
gap:12px;
}
.icodito-min-order-bar-text{
flex:1 1 100%;
min-width:0;
max-width:none;
order:1;
}
.icodito-min-order-bar-title{
font-size:13.5px;
margin-bottom:2px;
}
.icodito-min-order-bar-remaining{
font-size:12px;
}
.icodito-min-order-bar-progress{
flex:1 1 auto;
min-width:0;
order:2;
}
.icodito-min-order-bar-cart{
order:3;
width:42px;
height:42px;
}
.icodito-min-order-bar-cart svg{
width:20px;
height:20px;
}
.icodito-min-order-bar-cart-plus{
width:16px;
height:16px;
font-size:12px;
}
.icodito-min-order-bar-hint{
flex:1 1 100%;
order:4;
max-width:none;
padding:10px 14px;
}
}
@media (max-width:480px){
.icodito-min-order-floating{
padding:12px 14px;
border-radius:16px;
}
.icodito-min-order-bar-title{
font-size:13px;
}
.icodito-min-order-bar-track{
height:8px;
}
.icodito-min-order-bar-meta-item .value{
font-size:11px;
}
.icodito-min-order-bar-meta-item .label{
font-size:10px;
}
}
/* ============================================================
* حالت جمعشده (Collapsed)
* ============================================================ */
.icodito-min-order-collapsed-trigger{
display:none;
}
.icodito-min-order-floating.is-collapsed{
inset-inline-start:auto;
inset-inline-end:20px;
left:50%;
right:auto;
transform:translate(-50%, 0);
max-width:320px;
width:auto;
margin:0;
padding:0;
border-radius:999px;
background:linear-gradient(135deg,#10b981 0%,#059669 100%);
box-shadow:0 14px 32px rgba(16,185,129,.35),0 4px 12px rgba(16,185,129,.25);
cursor:pointer;
overflow:hidden;
}
.icodito-min-order-floating.is-collapsed:hover{
box-shadow:0 18px 38px rgba(16,185,129,.45),0 6px 16px rgba(16,185,129,.35);
transform:translate(-50%, -2px);
}
/* وقتی جمع شده: محتوا و دکمه × مخفی شوند */
.icodito-min-order-floating.is-collapsed .icodito-min-order-floating-inner,
.icodito-min-order-floating.is-collapsed .icodito-min-order-floating-close{
display:none !important;
}
/* نمایش دکمه قرصی شکل در حالت جمعشده */
.icodito-min-order-floating.is-collapsed .icodito-min-order-collapsed-trigger{
display:inline-flex;
align-items:center;
gap:8px;
padding:10px 14px 10px 16px;
width:100%;
border:0;
background:transparent;
color:#ffffff;
font-family:inherit;
font-size:13px;
font-weight:700;
cursor:pointer;
line-height:1.4;
box-sizing:border-box;
}
body.rtl .icodito-min-order-floating.is-collapsed{
left:50%;
right:auto;
transform:translate(-50%, 0);
}
body.rtl .icodito-min-order-floating.is-collapsed:hover{
transform:translate(-50%, -2px);
}
body.rtl .icodito-min-order-floating.is-collapsed .icodito-min-order-collapsed-trigger{
padding:10px 16px 10px 14px;
}
.icodito-min-order-collapsed-trigger .icodito-min-order-collapsed-text{
flex:1 1 auto;
text-align:start;
white-space:nowrap;
overflow:hidden;
text-overflow:ellipsis;
}
.icodito-min-order-collapsed-trigger .icodito-min-order-collapsed-arrow{
flex:0 0 auto;
display:inline-flex;
align-items:center;
justify-content:center;
width:22px;
height:22px;
background:rgba(255,255,255,.18);
border-radius:50%;
transition:transform .3s cubic-bezier(.4,0,.2,1);
}
.icodito-min-order-collapsed-trigger .icodito-min-order-collapsed-arrow svg{
width:14px;
height:14px;
display:block;
stroke:#ffffff;
}
.icodito-min-order-floating.is-collapsed:hover .icodito-min-order-collapsed-arrow{
transform:translateY(-2px);
background:rgba(255,255,255,.28);
}
/* انیمیشن پالس ملایم روی قرص جمعشده */
.icodito-min-order-floating.is-collapsed::after{
content:"";
position:absolute;
inset:0;
border-radius:999px;
box-shadow:0 0 0 0 rgba(16,185,129,.6);
animation:icoditoPulse 2.4s cubic-bezier(.4,0,.6,1) infinite;
pointer-events:none;
}
@keyframes icoditoPulse{
0%{box-shadow:0 0 0 0 rgba(16,185,129,.55)}
70%{box-shadow:0 0 0 14px rgba(16,185,129,0)}
100%{box-shadow:0 0 0 0 rgba(16,185,129,0)}
}
/* دارک مود – قرص جمعشده */
@media (prefers-color-scheme: dark){
.icodito-min-order-floating.is-collapsed{
background:linear-gradient(135deg,#059669 0%,#047857 100%);
box-shadow:0 14px 32px rgba(0,0,0,.5),0 4px 12px rgba(0,0,0,.35);
}
.icodito-min-order-floating.is-collapsed:hover{
box-shadow:0 18px 38px rgba(0,0,0,.6),0 6px 16px rgba(0,0,0,.4);
}
}
/* موبایل */
@media (max-width:782px){
.icodito-min-order-floating.is-collapsed{
left:50%;
right:auto;
inset-inline-end:auto;
max-width:calc(100vw - 24px);
transform:translate(-50%, 0);
}
.icodito-min-order-floating.is-collapsed:hover{
transform:translate(-50%, 0);
}
.icodito-min-order-floating.is-collapsed .icodito-min-order-collapsed-trigger{
font-size:12.5px;
padding:9px 12px 9px 14px;
}
.icodito-min-order-collapsed-trigger .icodito-min-order-collapsed-arrow{
width:20px;
height:20px;
}
.icodito-min-order-collapsed-trigger .icodito-min-order-collapsed-arrow svg{
width:12px;
height:12px;
}
}
/* ============================================================
* نوار شناور حداقل مبلغ سفارش – حالت دارک مود
* آی کدیتو
* ============================================================ */
/* ---------- ۱) دارک مود خودکار (بر اساس تنظیمات سیستم) ---------- */
@media (prefers-color-scheme: dark) {
.icodito-min-order-floating {
background: #1e293b;
box-shadow:
0 20px 50px rgba(0, 0, 0, .55),
0 6px 18px rgba(0, 0, 0, .35);
}
/* عنوان */
.icodito-min-order-bar-title {
color: #f1f5f9;
}
/* متن باقیمانده */
.icodito-min-order-bar-remaining {
color: #94a3b8;
}
.icodito-min-order-bar-remaining .woocommerce-Price-amount,
.icodito-min-order-bar-remaining bdi {
color: #34d399;
}
/* نوار پیشرفت */
.icodito-min-order-bar-percent {
color: #34d399;
}
.icodito-min-order-bar-track {
background: #334155;
}
.icodito-min-order-bar-fill {
background: linear-gradient(90deg, #34d399 0%, #10b981 100%);
box-shadow: 0 0 10px rgba(52, 211, 153, .55);
}
/* برچسبهای مبلغ فعلی / حداقل */
.icodito-min-order-bar-meta-item .value {
color: #f1f5f9;
}
.icodito-min-order-bar-meta-item .label {
color: #64748b;
}
/* باکس پیام سبز */
.icodito-min-order-bar-hint {
background: rgba(16, 185, 129, .14);
}
.icodito-min-order-bar-hint-text {
color: #6ee7b7;
}
.icodito-min-order-bar-hint-text .woocommerce-Price-amount,
.icodito-min-order-bar-hint-text bdi {
color: #6ee7b7;
}
.icodito-min-order-bar-hint-icon {
color: #34d399;
}
/* آیکون سبد خرید */
.icodito-min-order-bar-cart {
background: rgba(16, 185, 129, .14);
}
.icodito-min-order-bar-cart svg {
stroke: #34d399;
}
.icodito-min-order-bar-cart-plus {
background: #10b981;
border-color: #1e293b;
color: #ffffff;
}
/* دکمه بستن */
.icodito-min-order-floating-close {
color: #64748b;
}
.icodito-min-order-floating-close:hover {
background: rgba(255, 255, 255, .06);
color: #f1f5f9;
}
/* حالت موفقیت */
.icodito-min-order-floating.icodito-min-order-bar--success .icodito-min-order-bar-hint {
background: rgba(16, 185, 129, .22);
}
.icodito-min-order-floating.icodito-min-order-bar--success .icodito-min-order-bar-hint-text,
.icodito-min-order-floating.icodito-min-order-bar--success .icodito-min-order-bar-hint-icon {
color: #6ee7b7;
}
.icodito-min-order-floating.icodito-min-order-bar--success .icodito-min-order-bar-cart {
background: rgba(16, 185, 129, .22);
}
}
/* ---------- ۲) دارک مود دستی (کلاس روی html یا body) ---------- */
/* این کلاسها معمولاً توسط قالبهای وودمارت، آسترا، Blocksy و ... گذاشته میشوند */
html.dark .icodito-min-order-floating,
body.dark .icodito-min-order-floating,
html.icodito-dark .icodito-min-order-floating,
body.icodito-dark .icodito-min-order-floating,
html[data-theme="dark"] .icodito-min-order-floating,
body[data-theme="dark"] .icodito-min-order-floating,
.icodito-dark-mode .icodito-min-order-floating {
background: #1e293b;
box-shadow:
0 20px 50px rgba(0, 0, 0, .55),
0 6px 18px rgba(0, 0, 0, .35);
}
html.dark .icodito-min-order-bar-title,
body.dark .icodito-min-order-bar-title,
html.icodito-dark .icodito-min-order-bar-title,
body.icodito-dark .icodito-min-order-bar-title,
html[data-theme="dark"] .icodito-min-order-bar-title,
body[data-theme="dark"] .icodito-min-order-bar-title,
.icodito-dark-mode .icodito-min-order-bar-title {
color: #f1f5f9;
}
html.dark .icodito-min-order-bar-remaining,
body.dark .icodito-min-order-bar-remaining,
html.icodito-dark .icodito-min-order-bar-remaining,
body.icodito-dark .icodito-min-order-bar-remaining,
html[data-theme="dark"] .icodito-min-order-bar-remaining,
body[data-theme="dark"] .icodito-min-order-bar-remaining,
.icodito-dark-mode .icodito-min-order-bar-remaining {
color: #94a3b8;
}
html.dark .icodito-min-order-bar-remaining .woocommerce-Price-amount,
body.dark .icodito-min-order-bar-remaining .woocommerce-Price-amount,
html.icodito-dark .icodito-min-order-bar-remaining .woocommerce-Price-amount,
body.icodito-dark .icodito-min-order-bar-remaining .woocommerce-Price-amount,
html[data-theme="dark"] .icodito-min-order-bar-remaining .woocommerce-Price-amount,
body[data-theme="dark"] .icodito-min-order-bar-remaining .woocommerce-Price-amount,
.icodito-dark-mode .icodito-min-order-bar-remaining .woocommerce-Price-amount {
color: #34d399;
}
html.dark .icodito-min-order-bar-percent,
body.dark .icodito-min-order-bar-percent,
html.icodito-dark .icodito-min-order-bar-percent,
body.icodito-dark .icodito-min-order-bar-percent,
html[data-theme="dark"] .icodito-min-order-bar-percent,
body[data-theme="dark"] .icodito-min-order-bar-percent,
.icodito-dark-mode .icodito-min-order-bar-percent {
color: #34d399;
}
html.dark .icodito-min-order-bar-track,
body.dark .icodito-min-order-bar-track,
html.icodito-dark .icodito-min-order-bar-track,
body.icodito-dark .icodito-min-order-bar-track,
html[data-theme="dark"] .icodito-min-order-bar-track,
body[data-theme="dark"] .icodito-min-order-bar-track,
.icodito-dark-mode .icodito-min-order-bar-track {
background: #334155;
}
html.dark .icodito-min-order-bar-fill,
body.dark .icodito-min-order-bar-fill,
html.icodito-dark .icodito-min-order-bar-fill,
body.icodito-dark .icodito-min-order-bar-fill,
html[data-theme="dark"] .icodito-min-order-bar-fill,
body[data-theme="dark"] .icodito-min-order-bar-fill,
.icodito-dark-mode .icodito-min-order-bar-fill {
background: linear-gradient(90deg, #34d399 0%, #10b981 100%);
box-shadow: 0 0 10px rgba(52, 211, 153, .55);
}
html.dark .icodito-min-order-bar-meta-item .value,
body.dark .icodito-min-order-bar-meta-item .value,
html.icodito-dark .icodito-min-order-bar-meta-item .value,
body.icodito-dark .icodito-min-order-bar-meta-item .value,
html[data-theme="dark"] .icodito-min-order-bar-meta-item .value,
body[data-theme="dark"] .icodito-min-order-bar-meta-item .value,
.icodito-dark-mode .icodito-min-order-bar-meta-item .value {
color: #f1f5f9;
}
html.dark .icodito-min-order-bar-meta-item .label,
body.dark .icodito-min-order-bar-meta-item .label,
html.icodito-dark .icodito-min-order-bar-meta-item .label,
body.icodito-dark .icodito-min-order-bar-meta-item .label,
html[data-theme="dark"] .icodito-min-order-bar-meta-item .label,
body[data-theme="dark"] .icodito-min-order-bar-meta-item .label,
.icodito-dark-mode .icodito-min-order-bar-meta-item .label {
color: #64748b;
}
html.dark .icodito-min-order-bar-hint,
body.dark .icodito-min-order-bar-hint,
html.icodito-dark .icodito-min-order-bar-hint,
body.icodito-dark .icodito-min-order-bar-hint,
html[data-theme="dark"] .icodito-min-order-bar-hint,
body[data-theme="dark"] .icodito-min-order-bar-hint,
.icodito-dark-mode .icodito-min-order-bar-hint {
background: rgba(16, 185, 129, .14);
}
html.dark .icodito-min-order-bar-hint-text,
body.dark .icodito-min-order-bar-hint-text,
html.icodito-dark .icodito-min-order-bar-hint-text,
body.icodito-dark .icodito-min-order-bar-hint-text,
html[data-theme="dark"] .icodito-min-order-bar-hint-text,
body[data-theme="dark"] .icodito-min-order-bar-hint-text,
.icodito-dark-mode .icodito-min-order-bar-hint-text {
color: #6ee7b7;
}
html.dark .icodito-min-order-bar-hint-text .woocommerce-Price-amount,
body.dark .icodito-min-order-bar-hint-text .woocommerce-Price-amount,
html.icodito-dark .icodito-min-order-bar-hint-text .woocommerce-Price-amount,
body.icodito-dark .icodito-min-order-bar-hint-text .woocommerce-Price-amount,
html[data-theme="dark"] .icodito-min-order-bar-hint-text .woocommerce-Price-amount,
body[data-theme="dark"] .icodito-min-order-bar-hint-text .woocommerce-Price-amount,
.icodito-dark-mode .icodito-min-order-bar-hint-text .woocommerce-Price-amount {
color: #6ee7b7;
}
html.dark .icodito-min-order-bar-hint-icon,
body.dark .icodito-min-order-bar-hint-icon,
html.icodito-dark .icodito-min-order-bar-hint-icon,
body.icodito-dark .icodito-min-order-bar-hint-icon,
html[data-theme="dark"] .icodito-min-order-bar-hint-icon,
body[data-theme="dark"] .icodito-min-order-bar-hint-icon,
.icodito-dark-mode .icodito-min-order-bar-hint-icon {
color: #34d399;
}
html.dark .icodito-min-order-bar-cart,
body.dark .icodito-min-order-bar-cart,
html.icodito-dark .icodito-min-order-bar-cart,
body.icodito-dark .icodito-min-order-bar-cart,
html[data-theme="dark"] .icodito-min-order-bar-cart,
body[data-theme="dark"] .icodito-min-order-bar-cart,
.icodito-dark-mode .icodito-min-order-bar-cart {
background: rgba(16, 185, 129, .14);
}
html.dark .icodito-min-order-bar-cart svg,
body.dark .icodito-min-order-bar-cart svg,
html.icodito-dark .icodito-min-order-bar-cart svg,
body.icodito-dark .icodito-min-order-bar-cart svg,
html[data-theme="dark"] .icodito-min-order-bar-cart svg,
body[data-theme="dark"] .icodito-min-order-bar-cart svg,
.icodito-dark-mode .icodito-min-order-bar-cart svg {
stroke: #34d399;
}
html.dark .icodito-min-order-bar-cart-plus,
body.dark .icodito-min-order-bar-cart-plus,
html.icodito-dark .icodito-min-order-bar-cart-plus,
body.icodito-dark .icodito-min-order-bar-cart-plus,
html[data-theme="dark"] .icodito-min-order-bar-cart-plus,
body[data-theme="dark"] .icodito-min-order-bar-cart-plus,
.icodito-dark-mode .icodito-min-order-bar-cart-plus {
background: #10b981;
border-color: #1e293b;
color: #ffffff;
}
html.dark .icodito-min-order-floating-close,
body.dark .icodito-min-order-floating-close,
html.icodito-dark .icodito-min-order-floating-close,
body.icodito-dark .icodito-min-order-floating-close,
html[data-theme="dark"] .icodito-min-order-floating-close,
body[data-theme="dark"] .icodito-min-order-floating-close,
.icodito-dark-mode .icodito-min-order-floating-close {
color: #64748b;
}
html.dark .icodito-min-order-floating-close:hover,
body.dark .icodito-min-order-floating-close:hover,
html.icodito-dark .icodito-min-order-floating-close:hover,
body.icodito-dark .icodito-min-order-floating-close:hover,
html[data-theme="dark"] .icodito-min-order-floating-close:hover,
body[data-theme="dark"] .icodito-min-order-floating-close:hover,
.icodito-dark-mode .icodito-min-order-floating-close:hover {
background: rgba(255, 255, 255, .06);
color: #f1f5f9;
}
/* حالت موفقیت در دارک مود دستی */
html.dark .icodito-min-order-floating.icodito-min-order-bar--success .icodito-min-order-bar-hint,
body.dark .icodito-min-order-floating.icodito-min-order-bar--success .icodito-min-order-bar-hint,
html.icodito-dark .icodito-min-order-floating.icodito-min-order-bar--success .icodito-min-order-bar-hint,
body.icodito-dark .icodito-min-order-floating.icodito-min-order-bar--success .icodito-min-order-bar-hint,
html[data-theme="dark"] .icodito-min-order-floating.icodito-min-order-bar--success .icodito-min-order-bar-hint,
body[data-theme="dark"] .icodito-min-order-floating.icodito-min-order-bar--success .icodito-min-order-bar-hint,
.icodito-dark-mode .icodito-min-order-floating.icodito-min-order-bar--success .icodito-min-order-bar-hint {
background: rgba(16, 185, 129, .22);
}
html.dark .icodito-min-order-floating.icodito-min-order-bar--success .icodito-min-order-bar-hint-text,
body.dark .icodito-min-order-floating.icodito-min-order-bar--success .icodito-min-order-bar-hint-text,
html.icodito-dark .icodito-min-order-floating.icodito-min-order-bar--success .icodito-min-order-bar-hint-text,
body.icodito-dark .icodito-min-order-floating.icodito-min-order-bar--success .icodito-min-order-bar-hint-text,
html[data-theme="dark"] .icodito-min-order-floating.icodito-min-order-bar--success .icodito-min-order-bar-hint-text,
body[data-theme="dark"] .icodito-min-order-floating.icodito-min-order-bar--success .icodito-min-order-bar-hint-text,
.icodito-dark-mode .icodito-min-order-floating.icodito-min-order-bar--success .icodito-min-order-bar-hint-text {
color: #6ee7b7;
}
html.dark .icodito-min-order-floating.icodito-min-order-bar--success .icodito-min-order-bar-cart,
body.dark .icodito-min-order-floating.icodito-min-order-bar--success .icodito-min-order-bar-cart,
html.icodito-dark .icodito-min-order-floating.icodito-min-order-bar--success .icodito-min-order-bar-cart,
body.icodito-dark .icodito-min-order-floating.icodito-min-order-bar--success .icodito-min-order-bar-cart,
html[data-theme="dark"] .icodito-min-order-floating.icodito-min-order-bar--success .icodito-min-order-bar-cart,
body[data-theme="dark"] .icodito-min-order-floating.icodito-min-order-bar--success .icodito-min-order-bar-cart,
.icodito-dark-mode .icodito-min-order-floating.icodito-min-order-bar--success .icodito-min-order-bar-cart {
background: rgba(16, 185, 129, .22);
}
/* حفظ پسزمینه سبز قرص جمعشده در دارک مود دستی */
html.dark .icodito-min-order-floating.is-collapsed,
body.dark .icodito-min-order-floating.is-collapsed,
html.icodito-dark .icodito-min-order-floating.is-collapsed,
body.icodito-dark .icodito-min-order-floating.is-collapsed,
html[data-theme="dark"] .icodito-min-order-floating.is-collapsed,
body[data-theme="dark"] .icodito-min-order-floating.is-collapsed,
.icodito-dark-mode .icodito-min-order-floating.is-collapsed {
background: linear-gradient(135deg, #059669 0%, #047857 100%);
}
';
}
/* =========================================================
* JS فرانت
* ========================================================= */
private function frontend_js() {
return '
(function($){
if (typeof icoditoMinOrder === "undefined") return;
var FLOAT_ID = "icodito-min-order-floating";
var refreshTimer = null;
function ensureFloating(){
var $f = $("#" + FLOAT_ID);
if (!$f.length){
$f = $(
"<div id=\"" + FLOAT_ID + "\" class=\"icodito-min-order-floating\" role=\"region\" aria-live=\"polite\">" +
"<div class=\"icodito-min-order-floating-inner\"></div>" +
"<button type=\"button\" class=\"icodito-min-order-floating-close\" aria-label=\"" + (icoditoMinOrder.closeLabel || "جمع کردن") + "\"><span aria-hidden=\"true\">×</span></button>" +
"<button type=\"button\" class=\"icodito-min-order-collapsed-trigger\" aria-label=\"" + (icoditoMinOrder.expandLabel || "نمایش وضعیت") + "\">" +
"<span class=\"icodito-min-order-collapsed-text\">" + (icoditoMinOrder.collapsedText || "حداقل مبلغ سفارش") + "</span>" +
"<span class=\"icodito-min-order-collapsed-arrow\" aria-hidden=\"true\">" +
"<svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"18 15 12 9 6 15\"></polyline></svg>" +
"</span>" +
"</button>" +
"</div>"
);
$("body").append($f);
}
return $f;
}
function showFloating(html, state){
var $f = ensureFloating();
$f.removeClass("icodito-min-order-bar--error icodito-min-order-bar--success");
$f.addClass("icodito-min-order-bar--" + (state || "error"));
$f.find(".icodito-min-order-floating-inner").html(html);
$f.addClass("is-visible");
}
function hideFloating(){
var $f = $("#" + FLOAT_ID);
if ($f.length){
$f.removeClass("is-visible is-collapsed");
}
}
function collapse(){
var $f = $("#" + FLOAT_ID);
if (!$f.length) return;
$f.addClass("is-collapsed");
}
function expand(){
var $f = $("#" + FLOAT_ID);
if (!$f.length) return;
$f.removeClass("is-collapsed");
$f.addClass("is-visible");
}
function refresh(){
$.ajax({
url: icoditoMinOrder.ajaxUrl,
type: "POST",
dataType: "json",
data: {
action: icoditoMinOrder.action,
nonce: icoditoMinOrder.nonce
}
}).done(function(res){
if (!res || !res.success) return;
var html = (res.data && typeof res.data.html === "string") ? res.data.html : "";
var count = (res.data && res.data.cart_count) ? parseInt(res.data.cart_count, 10) : 0;
var state = (res.data && res.data.state) ? res.data.state : "error";
if (count === 0 || html.trim() === ""){
hideFloating();
return;
}
var $f = $("#" + FLOAT_ID);
var wasCollapsed = $f.hasClass("is-collapsed");
showFloating(html, state);
if (wasCollapsed){
$f.addClass("is-collapsed");
}
if (state === "success"){
expand();
}
});
}
function scheduleRefresh(){
if (refreshTimer) clearTimeout(refreshTimer);
refreshTimer = setTimeout(refresh, 120);
}
$(document.body).on("added_to_cart", function(){
expand();
scheduleRefresh();
});
$(document.body).on(
"updated_wc_div updated_cart_totals removed_from_cart wc_fragments_refreshed wc_fragments_loaded",
scheduleRefresh
);
$(document.body).on("change", "input[name=payment_method]", scheduleRefresh);
$(document).on("click", ".icodito-min-order-floating-close", function(e){
e.preventDefault();
e.stopPropagation();
collapse();
});
$(document).on("click", ".icodito-min-order-collapsed-trigger", function(e){
e.preventDefault();
e.stopPropagation();
expand();
});
$(function(){
var $f = $("#" + FLOAT_ID);
if ($f.length){
$f.removeClass("is-collapsed");
$f.addClass("is-visible");
}
});
})(jQuery);
';
}
}
Icodito_Min_Order::instance();
endif;
نکته: کد نهایی این بخش باید بدون تگ <?php قرار داده شود تا مستقیماً در Code Snippets قابل استفاده باشد.
پس از فعال کردن Snippet، بخش تنظیمات مربوط به حداقل مبلغ سفارش در پنل مدیریت ووکامرس در دسترس قرار میگیرد.
تنظیمات حداقل مبلغ سفارش

پس از فعال سازی کد، مدیر سایت میتواند تنظیمات قابلیت را از بخش اختصاصی ایجاد شده در پنل ووکامرس مدیریت کند.
در این بخش امکان تعیین حداقل مبلغ سفارش و تنظیم رفتار سیستم وجود دارد.
برای مثال میتوانید حداقل مبلغ سفارش را روی ۳۰۰٬۰۰۰ تومان قرار دهید.
از این پس اگر مبلغ سفارش مشتری کمتر از این مقدار باشد، سیستم مقدار باقیمانده را محاسبه و به کاربر نمایش میدهد.
نوار پیشرفت حداقل مبلغ سفارش

یکی از بخشهای مهم این کد، Progress Bar یا نوار پیشرفت است.
این نوار به مشتری نشان میدهد چه مقدار از حداقل مبلغ سفارش را تکمیل کرده است.
برای مثال:
مبلغ فعلی سبد: ۲۲۰٬۰۰۰ تومان
حداقل مبلغ سفارش: ۳۰۰٬۰۰۰ تومان
مبلغ باقیمانده: ۸۰٬۰۰۰ تومان
پیشرفت: ۷۳٪
به این ترتیب کاربر مجبور نیست صرفاً یک پیام متنی را بخواند و میتواند وضعیت سبد خرید خود را بهصورت تصویری مشاهده کند.
با رسیدن مبلغ سبد به حداقل تعیینشده، نوار به ۱۰۰ درصد میرسد.
در این حالت میتوان پیام موفقیت نمایش داد:
🎉 حداقل مبلغ سفارش تکمیل شد. میتوانید سفارش خود را ثبت کنید.
نمایش نوار وضعیت در پایین صفحه
در طراحی این قابلیت میتوان نوار وضعیت را در قسمت پایین صفحه نمایش داد تا در زمان مرور محصولات نیز برای کاربر قابل مشاهده باشد.
یک طراحی مناسب برای این بخش باید:
- ظاهر ساده و مینیمال داشته باشد.
- فضای کمی از صفحه را اشغال کند.
- روی محتوای سایت مزاحمت ایجاد نکند.
- روی موبایل بهدرستی نمایش داده شود.
- مبلغ باقیمانده را بهصورت واضح نمایش دهد.
- درصد پیشرفت را مشخص کند.
- پس از تکمیل مبلغ، وضعیت موفقیت را نمایش دهد.
این مدل نمایش میتواند تجربه کاربری بهتری نسبت به نمایش یک پیام خطای ساده ایجاد کند.
تنظیم نحوه محاسبه مبلغ سفارش
در فروشگاههای مختلف ممکن است مدیر سایت بخواهد حداقل مبلغ سفارش را با روش متفاوتی محاسبه کند.
به همین دلیل این کد امکان تنظیم مبلغ مبنا را در اختیار مدیر قرار میدهد.
برای مثال میتوان مشخص کرد که حداقل مبلغ بر اساس:
- مبلغ محصولات قبل از تخفیف
- مبلغ محصولات بعد از تخفیف
- مبلغ سبد بدون هزینه ارسال
- مبلغ نهایی سفارش
محاسبه شود.
این موضوع مخصوصاً برای فروشگاههایی که از تخفیف و کوپنهای ووکامرس استفاده میکنند اهمیت دارد.
پشتیبانی از تخفیف و کوپن
فرض کنید مشتری محصولاتی به ارزش ۳۵۰٬۰۰۰ تومان در سبد دارد و ۷۰٬۰۰۰ تومان تخفیف دریافت کرده است.
در این شرایط مبلغ قبل از تخفیف:
۳۵۰٬۰۰۰ تومان
و مبلغ پس از تخفیف:
۲۸۰٬۰۰۰ تومان
است.
در تنظیمات کد میتوان مشخص کرد که کدام مبلغ برای بررسی حداقل سفارش ملاک قرار بگیرد.
بنابراین میتوانید رفتار سیستم را با مدل فروشگاه و سیاست قیمت گذاری خود هماهنگ کنید.
احتساب هزینه حمل ونقل
هزینه ارسال نیز میتواند در محاسبه حداقل مبلغ سفارش اهمیت داشته باشد.
برای مثال:
- مبلغ محصولات: ۲۸۰٬۰۰۰ تومان
- هزینه ارسال: ۳۰٬۰۰۰ تومان
- مبلغ نهایی: ۳۱۰٬۰۰۰ تومان
در صورتی که هزینه حملونقل در محاسبه حداقل سفارش فعال شده باشد، سیستم میتواند هزینه ارسال را نیز در مبلغ مورد بررسی قرار دهد.
در غیر این صورت، فقط مبلغ محصولات برای تعیین وضعیت حداقل سفارش استفاده خواهد شد.
استثنا کردن محصولات و دستهبندیها

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

یکی از مزیتهای این سیستم، نمایش مقدار دقیق مبلغ باقیمانده است.
برای مثال بهجای نمایش:
حداقل مبلغ سفارش ۳۰۰٬۰۰۰ تومان است.
میتوان به مشتری گفت:
فقط ۸۰٬۰۰۰ تومان دیگر خرید کنید تا سفارش شما تکمیل شود.
در این حالت مشتری دقیقاً میداند چه مقدار دیگر باید به سبد خود اضافه کند.
متن پیام نیز میتواند از طریق تنظیمات قابلیت شخصی سازی شود.
سازگاری با دارک مود
این کد و استایل نوار وضعیت از دارک مود پشتیبانی می کند، سایت هایی که از قابلیت دارک مود استفاده میکنند بدون مشکل میتوانند از این کد استفاده کنند.
در حالت روشن، پسزمینه، متن، Progress Bar و پیامها باید کنتراست مناسبی دارند.
در حالت تاریک نیز رنگ ها متناسب با پس زمینه تغییر میکند تا:
- متن خوانا باقی بماند.
- نوار پیشرفت بهخوبی دیده شود.
- پیام موفقیت و خطا قابل تشخیص باشد.
- نوار پایین صفحه ظاهر متفاوت و ناهماهنگ با قالب نداشته باشد.
طراحی واکنش گرا برای موبایل
بخش قابل توجهی از کاربران فروشگاههای اینترنتی از تلفن همراه استفاده میکنند؛ بنابراین نوار وضعیت باید کاملاً Responsive باشد.
در نمایشگرهای کوچک، اطلاعات اضافی میتواند جمعوجور شود و عناصر اصلی مانند:
مبلغ باقیمانده + درصد پیشرفت + نوار وضعیت
در اولویت قرار بگیرند.
همچنین باید دقت شود که نوار ثابت پایین صفحه روی دکمههای مهم، منوی موبایل یا عناصر Checkout قرار نگیرد.
بله، در صورتی که گزینه جلوگیری از ثبت سفارش فعال باشد، سیستم میتواند تا زمانی که مبلغ سبد به حداقل تعیینشده نرسیده است، اجازه تکمیل سفارش را ندهد.
این موضوع باعث میشود نمایش نوار پیشرفت تنها جنبه اطلاعرسانی نداشته باشد و حداقل مبلغ واقعاً بهعنوان یک شرط ثبت سفارش عمل کند.
استفاده از این قابلیت به مدل کسب وکار فروشگاه بستگی دارد.
برای مثال ممکن است برای فروشگاهی که پردازش سفارشهای بسیار کوچک هزینه زیادی دارد، حداقل مبلغ سفارش منطقی باشد.
از طرف دیگر، اگر مبلغ تعیینشده بیش از حد بالا باشد، ممکن است مشتری بهجای اضافه کردن محصول بیشتر، از خرید منصرف شود.
بنابراین بهتر است حداقل مبلغ با توجه به:
- میانگین قیمت محصولات
- هزینه ارسال
- حاشیه سود
- هزینه پردازش سفارش
- رفتار مشتریان
- میانگین ارزش سبد خرید
تعیین شود.
نکات مهم قبل از استفاده
قبل از فعال کردن کد در سایت اصلی، بهتر است عملکرد آن را با شرایط مختلف بررسی کنید.
سبد کمتر از حداقل مبلغ
مثلاً:
۲۲۰٬۰۰۰ از ۳۰۰٬۰۰۰ تومان
باید پیام کمبود مبلغ و نوار پیشرفت نمایش داده شود.
سبد برابر با حداقل مبلغ
مثلاً:
۳۰۰٬۰۰۰ از ۳۰۰٬۰۰۰ تومان
باید وضعیت ۱۰۰ درصد و پیام موفقیت نمایش داده شود.
سبد بیشتر از حداقل مبلغ
اگر مشتری ۴۰۰٬۰۰۰ تومان خرید کرده باشد، درصد پیشرفت نباید از ۱۰۰ درصد بیشتر نمایش داده شود.
استفاده از تخفیف
محاسبه مبلغ را با کوپن و تخفیفهای فروشگاه بررسی کنید.
هزینه ارسال
اگر هزینه حملونقل در محاسبه فعال شده است، وضعیت را با روشهای مختلف ارسال بررسی کنید.
موبایل و دارک مود
نوار وضعیت را در موبایل و هر دو حالت روشن و تاریک قالب بررسی کنید.
تنظیمات پیشرفته کد حداقل مبلغ سفارش

در تنظیمات این کد تو تب پیشرفته میتوانید نوع پیام که به چه صورت نمایش داده بشه مشخص کنید و اولویت هوک را تعیین کنید .
حتی میتوانید استایل پیشفرض از تنظیمات غیرفعال کنید و همچنین اگر با خطا رو به رو شدید حالت دیباگ فعال کنید و خطا رو بررسی کنید .
جمع بندی
کد حداقل مبلغ سفارش ووکامرس یک Snippet آماده برای فروشگاههایی است که میخواهند حداقل مبلغ مشخصی برای ثبت سفارش تعیین کنند و در عین حال مشتری را به افزایش ارزش سبد خرید تشویق کنند.
وجود نوار پیشرفت، نمایش مبلغ باقیمانده، پیام هوشمند، پشتیبانی از تخفیف و حملونقل و امکان تعریف استثناها باعث میشود این قابلیت انعطاف بیشتری نسبت به یک کد ساده حداقل مبلغ سفارش داشته باشد.
از طرف دیگر، طراحی مناسب نوار وضعیت برای موبایل، حالت روشن و دارک مود کمک میکند این قابلیت بدون ایجاد اختلال جدی در تجربه کاربری فروشگاه نمایش داده شود.
اگر از ووکامرس استفاده میکنید و میخواهید مشتریانی که فاصله کمی با حداقل مبلغ سفارش دارند را به اضافه کردن محصولات بیشتر تشویق کنید، میتوانید این Snippet آماده را در سایت خود فعال و تنظیم کنید.
سوالات متداول
حداقل مبلغ سفارش مقداری است که مشتری باید ارزش سبد خرید خود را به آن برساند تا بتواند سفارش خود را ثبت کند.
بله. پس از فعال کردن Snippet، حداقل مبلغ از بخش تنظیمات مربوط به آن در پنل مدیریت ووکامرس قابل تغییر است.
بله. زمانی که مبلغ سبد کمتر از حداقل تعیینشده باشد، میتوان مقدار باقیمانده تا تکمیل سفارش را به مشتری نمایش داد.
بله. نوار پیشرفت میزان تکمیل حداقل مبلغ سفارش را بهصورت بصری نمایش میدهد و پس از رسیدن به حداقل مبلغ روی ۱۰۰ درصد قرار میگیرد.
نحوه محاسبه قابل تنظیم است و میتوان مشخص کرد مبلغ قبل یا بعد از تخفیف مبنای بررسی حداقل سفارش باشد.
بله، در صورت فعال بودن گزینه مربوط به حملونقل، هزینه ارسال نیز میتواند در محاسبه مبلغ سفارش لحاظ شود.
بله. امکان تعریف استثنا برای محصولات و دستهبندیهای مشخص وجود دارد.
بله. میتوان بر اساس نقش کاربری و شرایط کاربران واردشده یا مهمان، استثناهای موردنظر را تنظیم کرد.
بله. استایل این بخش میتواند برای حالت روشن و تاریک طراحی شود تا متن، Progress Bar و پیامها در هر دو حالت خوانایی مناسبی داشته باشند.
بله. کد بهصورت یک Snippet آماده ارائه شده و میتوان آن را در افزونه Code Snippets قرار داد و فعال کرد.
