Вопрос или проблема
Мне нужно вызвать AJAX-запрос на основе изменений пользовательского поля в форме оформления заказа, чтобы добавить скидку. Но если я вызываю хуки для добавления скидки в подсчет итоговой суммы корзины, то это ничего не делает. Обратите внимание, что AJAX-запрос работает нормально. Даже если я использую хук woocommerce_cart_calculate_fees
вне функции обратного вызова AJAX, это сработает.
add_action('wp_ajax_test', 'test');
add_action('wp_ajax_nopriv_test', 'test');
function test(){
add_action('woocommerce_cart_calculate_fees' , 'add_custom_fees');
}
function add_custom_fees( WC_Cart $cart ){
// Рассчитаем сумму скидки
$discount = $cart->subtotal * 0.2;
$cart->add_fee( 'У вас более 3-х предметов в корзине, скидка 10% добавлена.', -$discount);
}
Проблема, с которой вы столкнулись, заключается в том, что функция add_action
будет влиять только на текущий запрос, который в данном случае является вашим AJAX-запросом. После этого, когда вы отправляете форму, это уже другой запрос, и действие больше не присутствует.
Чтобы достичь желаемого, вам нужно каким-то образом изменить форму, чтобы скидка была учтена при ее отправке.
Вы можете использовать AJAX, возможно, чтобы проверить, разрешена ли скидка, и вернуть текст для пользователя и/или правильный элемент для добавления в форму, чтобы сделать ее с учетом скидки позднее.
Вот примерно что я имею в виду:
add_action('wp_ajax_discount', 'maybe_discount');
function maybe_discount() {
/* определите, уместна ли скидка, затем */
if ($discount) {
echo json_encode('status'=>'discount', 'text'=>'....');
} else {
echo json_encode('status'=>'nodiscount');
die();
}
/* На стороне клиента вы будете использовать возвращенную информацию для
* отображения чего-то пользователю или, возможно, изменения самой формы
* (я не знаю, что поддерживает WooCommerce).
* Затем, когда вы *отправите* форму, вам может понадобиться хук вроде этого:
*/
add_action('some_woocomerce_hook_here','add_my_discount');
function add_my_discount( WC_Cart $cart ) {
$discount = $cart->subtotal * 0.2;
$cart->add_fee( 'У вас есть скидка...', -$discount);
}
Ответ или решение
Чтобы правильно вызвать действие в callback-функции wp_ajax
для добавления скидки в WooCommerce, нужно учитывать несколько ключевых аспектов работы с AJAX и хуками в WordPress. Ниже приведен подробный ответ на поставленный вопрос, который поможет решить вашу задачу.
Введение в проблему
Вы столкнулись с задачей, которая требует выполнения AJAX-вызова на основе изменений пользовательского поля в форме оформления заказа для добавления скидки. Ваша текущая реализация не дает ожидаемого результата, потому что вызов хука add_action
в вашем AJAX callback не сохраняется для других запросов, которые проходит форма после AJAX-вызова.
Почему ваш код не работает?
Ваша функция test()
добавляет хук woocommerce_cart_calculate_fees
, но этот хук срабатывает только в текущем запросе AJAX. При последующей обработке формы (например, при отправке ее финансами) хук больше не активен, так как был добавлен только в рамках AJAX-реквеста.
Решение проблемы
Для того чтобы скидка применялась при каждом запросе, вам нужно применить логику определения скидки глобально, а не только внутри вашей AJAX-функции. Вот предложенная структура кода, которая сделает это:
// Хуки для AJAX запросов
add_action('wp_ajax_discount', 'maybe_discount');
add_action('wp_ajax_nopriv_discount', 'maybe_discount');
function maybe_discount() {
// Определяем, требуется ли скидка
// В вашем коде это будет зависеть от логики
$should_discount = true; // Это условие должно зависеть от ваших требований
if ($should_discount) {
// Пример того, как вернуть ответ на AJAX-запрос
echo json_encode(array('status' => 'discount', 'message' => 'Скидка применена.'));
} else {
echo json_encode(array('status' => 'nodiscount'));
}
wp_die(); // Завершение AJAX вызова
}
// Выполнение скидки при расчете стоимости корзины
add_action('woocommerce_cart_calculate_fees', 'add_my_discount');
function add_my_discount(WC_Cart $cart) {
// Проверяем, предопределена ли скидка (можно создать глобальную переменную или опцию для этого)
$discount_allowed = true; // Это нужно поменять на ваше условие
if ($discount_allowed) {
// Рассчитываем и добавляем скидку
$discount = $cart->subtotal * 0.2; // Пример: 20% скидка
$cart->add_fee('Скидка за более чем 3 товара: -' . wc_price($discount), -$discount);
}
}
Объяснение решения
-
AJAX Вызов: Функция
maybe_discount()
обрабатывает AJAX-запросы и возвращает информацию о том, применяется ли скидка. Не забудьте проверить условия для применения скидки в соответствии с вашими нуждами. -
Добавление скидки: Использование хука
woocommerce_cart_calculate_fees
, который обрабатывается при каждом расчете корзины, позволяет применять скидку, даже если она была инициирована через AJAX. -
Глобальные параметры скидки: Убедитесь, что вы определили условие для применения скидки в вашем приложении (например, проверка количества товаров в корзине). Это можно сделать через глобальные переменные, опции или с помощью сессий.
Заключение
Следуя данной инструкции, вы сможете успешно интегрировать логику применения скидок в WooCommerce и учесть изменения пользовательских форм в реальном времени через AJAX. При этом убедитесь, что вся логика правильно обрабатывает условия для скидки и корректно реагирует на запросы клиента, тем самым обеспечивая безупречный пользовательский опыт.