WooCommerce的Fees API包含三个函数,add_fee(), get_fees()和calculate_fees()。我们可以用add_fee()向订单中添加固定费用或者百分比费用,需要注意的是使用哪个action添加。
回顾代码,发现问题
在之前写的WooCommerce实用代码集合一文中,写过一段添加手续费的代码,用的action是woocommerce_calculate_totals,最近需要加一个可以应用税率的手续费,进而发现代码中有个逻辑错误。
$woocommerce->cart->add_fee( 'Surcharge', $surcharge, false, '' ); $woocommerce->cart->fee_total += $surcharge;
第一句话用Fee API增加了费用,第二句话把这个费用和总费用相加,add_fee第三个参数含义为是否应用税率。
既然add_fee可以给费用增加一个税钱,第二句话中却没有税的踪影,岂不是要出错了!
细看woocommerce的fee api后发现,正确的action是woocommerce_cart_calculate_fees,第二句话并不需要。
下面是正确的代码,这里允许给费用加税。
add_action( 'woocommerce_cart_calculate_fees','woocommerce_custom_surcharge' ); function woocommerce_custom_surcharge() { global $woocommerce; if ( is_admin() && ! defined( 'DOING_AJAX' ) ) return; $percentage = 0.01; $surcharge = ( $woocommerce->cart->cart_contents_total + $woocommerce->cart->shipping_total ) * $percentage; $woocommerce->cart->add_fee( 'Surcharge', $surcharge,true ); }
WooCommerce Fees API
Fees API位于class-wc-cart.php中
三个函数代码如下,供参考
/*-----------------------------------------------------------------------------------*/ /* Fees API to add additonal costs to orders */ /*-----------------------------------------------------------------------------------*/ /** * add_fee function. * * @param mixed $name * @param mixed $amount * @param bool $taxable (default: false) * @param string $tax_class (default: '') */ public function add_fee( $name, $amount, $taxable = false, $tax_class = '' ) { if ( empty( $this->fees ) ) $this->fees = array(); $new_fee = new stdClass(); $new_fee->id = sanitize_title( $name ); $new_fee->name = esc_attr( $name ); $new_fee->amount = (float) esc_attr( $amount ); $new_fee->tax_class = $tax_class; $new_fee->taxable = $taxable ? true : false; $new_fee->tax = 0; $this->fees[] = $new_fee; } /** * get_fees function. * * @access public * @return void */ public function get_fees() { return array_filter( (array) $this->fees ); } /** * Calculate fees */ public function calculate_fees() { // Fire an action where developers can add their fees do_action( 'woocommerce_cart_calculate_fees', $this ); // If fees were added, total them and calculate tax if ( $fees = $this->get_fees() ) { foreach ( $fees as $fee ) { $this->fee_total += $fee->amount; if ( $fee->taxable ) { // Get tax rates $tax_rates = $this->tax->get_rates( $fee->tax_class ); $fee_taxes = $this->tax->calc_tax( $fee->amount, $tax_rates, false ); // Store $fee->tax = array_sum( $fee_taxes ); // Tax rows - merge the totals we just got foreach ( array_keys( $this->taxes + $fee_taxes ) as $key ) { $this->taxes[ $key ] = ( isset( $fee_taxes[ $key ] ) ? $fee_taxes[ $key ] : 0 ) + ( isset( $this->taxes[ $key ] ) ? $this->taxes[ $key ] : 0 ); } } } } }