wordpress - 如何根据自定义字段动态更改 WooCommerce 结帐中的运费?
问题描述
如何通过 Ajax 请求更改 Woocommerce 中的运费?我试过这个:
add_action('wp_ajax_set_shipping_price', 'set_shipping_price');
add_action('wp_ajax_nopriv_set_shipping_price', 'set_shipping_price');
function set_shipping_price(){
$packages = WC()->cart->get_shipping_packages();
foreach ($packages as $package_key => $package){
$session_key = 'shipping_for_package_'.$package_key;
$stored_rates = WC()->session->__unset( $session_key );
$WC_Shipping = new WC_Shipping();
$WC_Shipping->calculate_shipping_for_package( $package, $package_key = 0);
WC()->cart->calculate_shipping();
WC()->cart->calculate_totals();
}
wp_die();
}
和:
add_filter( 'woocommerce_package_rates', 'custom_shipping_costs', 20, 2 );
function custom_shipping_costs( $rates, $package ) {
if (isset($_POST['cost'])){
$new_cost = $_POST['cost'];
}
$new_cost = 0;
$tax_rate = 0.2;
foreach( $rates as $rate_key => $rate ){
if( $rate->method_id != 'free_shipping'){
$rates[$rate_key]->cost = $new_cost;
$taxes = array();
foreach ($rates[$rate_key]->taxes as $key => $tax){
if( $rates[$rate_key]->taxes[$key] > 0 )
$taxes[$key] = $new_cost * $tax_rate;
}
$rates[$rate_key]->taxes = $taxes;
}
}
return $rates;
}
该钩子woocommerce_package_rates
在页面加载时起作用,但通过 ajax 什么也不做。请帮忙。
解决方案
Here is the explanation on how to get post data from an Ajax call.
Additionally, you can use the WooCommerce update_checkout
event to update the checkout (and thus recalculate shipping costs) after a field in the checkout has changed or been clicked (instead of creating a custom Ajax call). Here you will find a complete list.
So, assuming you want to recalculate shipping costs when the field with id custom_shipping_price
(for example) changes, you can use this script:
// updates the checkout (and shipping charge calculation) when the value of a field changes
add_action( 'wp_footer', 'update_checkout' );
function update_checkout() {
// only in the checkout
if ( ! is_checkout() ) {
return;
}
?>
<script type="text/javascript">
jQuery( document ).ready(function( $ ) {
// when the value of the field with id "custom_shipping_price" changes it updates the checkout
jQuery('#custom_shipping_price').change(function(){
jQuery('body').trigger('update_checkout');
});
});
</script>
<?php
}
Now you will need to use the woocommerce_package_rates
hook to calculate the new shipping cost.
Make sure you initialize the value of the
$new_cost
variable in case the custom field is not set or is empty.
Here the function:
// update the shipping cost based on a custom field in the checkout
add_filter( 'woocommerce_package_rates', 'update_shipping_cost_based_on_custom_field', 10, 2 );
function update_shipping_cost_based_on_custom_field( $rates, $package ) {
if ( ! $_POST || is_admin() || ! is_ajax() ) {
return;
}
// gets the post serialized data sent with the Ajax call
if ( isset( $_POST['post_data'] ) ) {
parse_str( $_POST['post_data'], $post_data );
} else {
$post_data = $_POST;
}
// set the cost of shipping (if the custom field should be empty)
$new_cost = 0;
// if the field is set it gets the value
if ( isset( $post_data['custom_shipping_price'] ) && ! empty( $post_data['custom_shipping_price'] ) ) {
// forces conversion of value into number
$new_cost = (float) str_replace( ',', '.', $post_data['custom_shipping_price'] );
}
// set the percentage of taxes (ex. 22%)
$tax_rate = 0.22;
foreach( $rates as $rate_key => $rate ) {
if ( 'free_shipping' !== $rate->method_id ) {
// set rate cost
$rates[$rate_key]->cost = $new_cost;
// set taxes rate cost (if enabled)
$taxes = array();
foreach ( $rates[$rate_key]->taxes as $key => $tax ) {
if ( $rates[$rate_key]->taxes[$key] > 0 ) {
$taxes[$key] = $new_cost * $tax_rate;
}
}
$rates[$rate_key]->taxes = $taxes;
}
}
return $rates;
}
Both codes have been tested and work. Add them to your active theme's functions.php.
推荐阅读
- apache-spark - 如何在 Spark 中创建一个 hbase 序列文件键以加载到 Bigtable?
- linux - SSH 隧道总是尝试端口 22
- azure-devops - vsts-task-lib getvariable 返回 null
- c++ - 用于查找连续子数组的最大和的代码未通过测试用例
- r - R中嵌套列表的叶子名称
- sql - 插入和提交后行从 SQL Server 表中消失
- msbuild - 排除某些文件 ItemGroup
- javascript - 使用 OnClick 函数 JavaScript 删除 Firebase 节点
- python - Django:访问其他模型中的相关字段
- vba - 使用 vba 将数据从用户窗体传输到工作表单元格