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 );
}
}
}
}
}