On a Woocommerce store, I am trying to create a checkbox during the checout for a "hand written card" (or whatever anyone calls it). I create the field save it during checkout and showing it appropriately on the admin page. No problems here.
However, I want to add a fee for that. I implement a check for the field but I cant figure it out how to pass the data to save the fee. I tried the following but the fee appears in the final cart table but is not calculated or shown on the thank you page or admin > order.
What I tried:
<?php
//add card fee if checkbox field is checked
add_action( 'woocommerce_cart_calculate_fees', 'add_custom_fee' );
function add_custom_fee( $cart ) {
if ( is_admin() && ! defined( 'DOING_AJAX' ) ){return;}
//if on post data there is gift_card_checkbox that is 'checked' then add fee
parse_str($_POST['post_data'], $post_data);
if ( isset( $post_data['gift_card_checkbox'] ) && $post_data['gift_card_checkbox'] == 1 ) {
$fee = 1;
WC()->cart->add_fee('Gift card', $fee, true, '');
}
}
add_action( 'woocommerce_checkout_create_order', 'add_custom_fee_checkout', 20, 2 );
function add_custom_fee_checkout( $order, $data ) {
$gift_card = get_post_meta($order->get_id(), 'gift_card_checkbox', true);
if ($gift_card && $gift_card == 1) {
//if (isset($_POST['gift_card_checkbox']) && $_POST['gift_card_checkbox'] == 1) {
//test1
$order->add_fee('Gift card 1', 1);
//test2
$order->add_item(
new WC_Order_Item_Fee(
array(
'name' => "Gift card 2",
'amount' => 2,
'tax_status' => 'taxable',
'total' => 2
)
)
);
//test3
WC()->cart->add_fee('Gift card 3', 3, true, '');
}
}
?>
2
Answers
add a custom checkbox field to the WooCommerce checkout page after the order notes section. It uses the
woocommerce_after_order_notes
action hook to add the field. Theadd_custom_checkbox_to_checkout
function is responsible for rendering the checkbox field. It uses thewoocommerce_form_field
function to generate the checkbox field HTML. The value of the checkbox is retrieved from the WooCommerce session usingWC()->session->get('handwritten_card')
.add a JavaScript script to the footer of the page using the
wp_footer
action hook. The script uses jQuery to detect the change event of the checkbox and triggers theupdate_checkout
event when the checkbox is changed. This event is used to update the checkout page and recalculate the totals.Below code defines the
woo_add_cart_fee
function, which is hooked to thewoocommerce_cart_calculate_fees
action. This function is responsible for adding a fee to the cart when the checkbox is checked and removing the fee when the checkbox is unchecked. It first checks if the request is a valid submission and then parses the POST data to retrieve the checkbox value. The checkbox value in the session is reset to null. If the checkbox is checked, it adds a fee named "Gift card" with a value of 2 to the cart using$woocommerce->cart->add_fee()
. It also sets the checkbox value in the WooCommerce session usingWC()->session->set('handwritten_card', sanitize_text_field($data['handwritten_card']))
. If the checkbox is unchecked, it removes the "Gift card" fee from the cart using$woocommerce->cart->remove_fee()
.OUTPUT
If anyone is coming across this wondering why the fee is showing on the checkout page but not on the thank you page or in the order…the reason it was happening to me was that I was making use of
$_POST['post_data']
on the checkout page to get the form fields.I posted my solution on another stackoverflow question here: https://stackoverflow.com/a/77656386/4484799