Я создаю магазин WooCommerce, который продает товары местным муниципалитетам, поэтому к некоторым заказам нужно применять налог с продаж, а другие освобождены от налога. Я установил налоговые ставки в настройках WooCommerce: стандартные ставки для обычных продаж и нулевую ставку для исключений.
Я создал собственный код, чтобы добавить флажок при оформлении заказа для заявления об освобождении от налога. Он сохраняет значение в мета-данных клиента, а сеанс применяет set_is_vat_exempt() во время расчета корзины, сохраняет его в заказе и очищает после покупки. Первоначально он работает, но когда пользователи добавляют примечания к заказу или переключают способы оплаты (запуская запросы AJAX), состояние флажка визуально сохраняется, но налоги сбрасываются до ставок по умолчанию (не освобожденных от уплаты налогов). Я использую блокировку оформления заказа.
add_action('woocommerce_init', 'register_tax_exempt_field');
function register_tax_exempt_field() {
woocommerce_register_additional_checkout_field(
array(
'id' => 'tax-exemption/claim-exemption',
'label' => __('I am tax-exempt (municipal/government purchase)', 'woocommerce'),
'location' => 'contact',
'type' => 'checkbox',
'required' => false,
)
);
}
// Store the checkbox value in customer session meta
add_action('woocommerce_store_api_checkout_update_order_from_request', 'save_tax_exempt_to_session', 5, 2);
function save_tax_exempt_to_session($order, $request) {
$is_exempt = isset($request['additional_fields']['tax-exemption/claim-exemption'])
&& $request['additional_fields']['tax-exemption/claim-exemption'];
// Store in customer meta (not just session)
if (WC()->customer) {
WC()->customer->update_meta_data('_tax_exempt_checkout', $is_exempt ? 'yes' : 'no');
WC()->customer->save();
WC()->customer->set_is_vat_exempt($is_exempt);
}
// Also store in session as backup
if (WC()->session) {
WC()->session->set('tax_exempt_checkout', $is_exempt ? 'yes' : 'no');
}
}
// Apply tax exemption on EVERY cart calculation
add_action('woocommerce_cart_loaded_from_session', 'apply_tax_exempt_from_customer', 1);
function apply_tax_exempt_from_customer($cart) {
if (!WC()->customer) {
return;
}
// Check customer meta first, then session
$is_exempt = WC()->customer->get_meta('_tax_exempt_checkout') === 'yes';
if (!$is_exempt && WC()->session) {
$is_exempt = WC()->session->get('tax_exempt_checkout') === 'yes';
}
// Apply VAT exemption
WC()->customer->set_is_vat_exempt($is_exempt);
}
// Also apply before calculate totals
add_action('woocommerce_before_calculate_totals', 'reapply_vat_exempt', 1);
function reapply_vat_exempt($cart) {
if (is_admin() && !defined('DOING_AJAX')) {
return;
}
if (!WC()->customer) {
return;
}
$is_exempt = WC()->customer->get_meta('_tax_exempt_checkout') === 'yes';
if (!$is_exempt && WC()->session) {
$is_exempt = WC()->session->get('tax_exempt_checkout') === 'yes';
}
WC()->customer->set_is_vat_exempt($is_exempt);
}
// Save to order
add_action('woocommerce_checkout_create_order', 'save_tax_exemption_to_order', 10, 2);
function save_tax_exemption_to_order($order, $data) {
if (WC()->customer && WC()->customer->is_vat_exempt()) {
$order->update_meta_data('_is_tax_exempt', 'yes');
$order->update_meta_data('_tax_exemption_claimed', current_time('mysql'));
}
}
// Clear after order
add_action('woocommerce_thankyou', 'clear_tax_exemption_after_order');
function clear_tax_exemption_after_order($order_id) {
if (WC()->customer) {
WC()->customer->delete_meta_data('_tax_exempt_checkout');
WC()->customer->save();
WC()->customer->set_is_vat_exempt(false);
}
if (WC()->session) {
WC()->session->set('tax_exempt_checkout', 'no');
}
}
// Display in admin
add_action('woocommerce_admin_order_data_after_billing_address', 'display_tax_exempt_admin');
function display_tax_exempt_admin($order) {
$is_exempt = $order->get_meta('_is_tax_exempt');
if ($is_exempt === 'yes') {
echo '
[b]Tax Status:[/b] ✓ Tax Exempt (Municipal)
';
$claimed_date = $order->get_meta('_tax_exemption_claimed');
if ($claimed_date) {
echo '
Claimed: ' . esc_html(date('M j, Y g:i A', strtotime($claimed_date))) . '
';
}
}
}
Я использовал инструменты искусственного интеллекта, такие как Claude и GitHub Copilot, для устранения неполадок, но мне не повезло, они предложили аналогичные приемы, которые не решают проблему AJAX.
Я создаю магазин WooCommerce, который продает товары местным муниципалитетам, поэтому к некоторым заказам нужно применять налог с продаж, а другие освобождены от налога. Я установил налоговые ставки в настройках WooCommerce: стандартные ставки для обычных продаж и нулевую ставку для исключений. Я создал собственный код, чтобы добавить флажок при оформлении заказа для заявления об освобождении от налога. Он сохраняет значение в мета-данных клиента, а сеанс применяет set_is_vat_exempt() во время расчета корзины, сохраняет его в заказе и очищает после покупки. Первоначально он работает, но когда пользователи добавляют примечания к заказу или переключают способы оплаты (запуская запросы AJAX), состояние флажка визуально сохраняется, но налоги сбрасываются до ставок по умолчанию (не освобожденных от уплаты налогов). Я использую блокировку оформления заказа. [code]add_action('woocommerce_init', 'register_tax_exempt_field');
// Store the checkbox value in customer session meta add_action('woocommerce_store_api_checkout_update_order_from_request', 'save_tax_exempt_to_session', 5, 2);
function save_tax_exempt_to_session($order, $request) { $is_exempt = isset($request['additional_fields']['tax-exemption/claim-exemption']) && $request['additional_fields']['tax-exemption/claim-exemption'];
// Store in customer meta (not just session) if (WC()->customer) { WC()->customer->update_meta_data('_tax_exempt_checkout', $is_exempt ? 'yes' : 'no'); WC()->customer->save(); WC()->customer->set_is_vat_exempt($is_exempt); }
// Also store in session as backup if (WC()->session) { WC()->session->set('tax_exempt_checkout', $is_exempt ? 'yes' : 'no'); } }
// Apply tax exemption on EVERY cart calculation add_action('woocommerce_cart_loaded_from_session', 'apply_tax_exempt_from_customer', 1);
function apply_tax_exempt_from_customer($cart) { if (!WC()->customer) { return; }
// Check customer meta first, then session $is_exempt = WC()->customer->get_meta('_tax_exempt_checkout') === 'yes';
// Save to order add_action('woocommerce_checkout_create_order', 'save_tax_exemption_to_order', 10, 2);
function save_tax_exemption_to_order($order, $data) { if (WC()->customer && WC()->customer->is_vat_exempt()) { $order->update_meta_data('_is_tax_exempt', 'yes'); $order->update_meta_data('_tax_exemption_claimed', current_time('mysql')); } }
// Clear after order add_action('woocommerce_thankyou', 'clear_tax_exemption_after_order');
function clear_tax_exemption_after_order($order_id) { if (WC()->customer) { WC()->customer->delete_meta_data('_tax_exempt_checkout'); WC()->customer->save(); WC()->customer->set_is_vat_exempt(false); }
if (WC()->session) { WC()->session->set('tax_exempt_checkout', 'no'); } }
// Display in admin add_action('woocommerce_admin_order_data_after_billing_address', 'display_tax_exempt_admin');
function display_tax_exempt_admin($order) { $is_exempt = $order->get_meta('_is_tax_exempt');
if ($is_exempt === 'yes') { echo ' [b]Tax Status:[/b] ✓ Tax Exempt (Municipal) '; $claimed_date = $order->get_meta('_tax_exemption_claimed'); if ($claimed_date) { echo ' Claimed: ' . esc_html(date('M j, Y g:i A', strtotime($claimed_date))) . ' '; } } } [/code] Я использовал инструменты искусственного интеллекта, такие как Claude и GitHub Copilot, для устранения неполадок, но мне не повезло, они предложили аналогичные приемы, которые не решают проблему AJAX.