Update total Woocommerce Checkout based on payment method
Update total Woocommerce Checkout based on payment method
I have a problem when I try to update woocommerce total based on payment method on checkout page. In my case I need to apply a discount if customer select paypal or credit card. The strange thing is that the most of times the code works corrrectly but for about 20-25% of order it doesn't work.
This is my code to trigger the update:
add_action( 'wp_footer', 'refresh_payment_methods', 20, 1 );
function refresh_payment_methods() {
?>
<script type="text/javascript">
(function($){
$( 'form.checkout' ).on( 'change', 'input[name^="payment_method"]', function() {
$('body').trigger('update_checkout');
});
});
</script>
<?php } ?>
This is the code that manage the discount:
/* APPLY DISCOUNT BASED ON PAYMENT METHOD */
add_action('woocommerce_checkout_update_order_review', 'payment_method_discount', 10, 2);
add_action( 'woocommerce_cart_calculate_fees', 'payment_method_discount', 20, 1 );
function payment_method_discount( $cart_object ) {
if ( is_admin() && !defined( 'DOING_AJAX' ) ) return;
foreach($cart_object->cart_contents as $cart_item_id => $cart_item) {
$riepilogo = json_decode(stripslashes($cart_item['_dettagli_noleggio']));
$payment_method_arr = array('ppcp-gateway' ,'axepta');
$chosen_payment_method = WC()->session->get('chosen_payment_method');
if(in_array($chosen_payment_method, $payment_method_arr)) {
$discount = number_format( ($riepilogo->noleggio->prezzo_noleggio / 100) * $percent , 2);
WC()->cart->add_fee( 'Sconto pagamento online', 0 - $discount );
$riepilogo->noleggio->prezzo_noleggio_scontato = number_format( $riepilogo->noleggio->prezzo_noleggio - $discount , 2, '.','');
$riepilogo->noleggio->prezzo_totale_scontato = number_format( $riepilogo->noleggio->prezzo_noleggio_scontato + $riepilogo->noleggio->prezzo_accessori + $riepilogo->noleggio->prezzo_assicurazione, 2, '.','');
$cart_object->cart_contents[$cart_item_id]['_dettagli_noleggio'] = json_encode($riepilogo);
}else{
$fees = WC()->cart->get_fees();
foreach ($fees as $key => $fee) {
unset($fees[$key]);
}
WC()->cart->fees_api()->set_fees($fees);
$riepilogo->noleggio->prezzo_noleggio_scontato = "";
$riepilogo->noleggio->prezzo_totale = number_format( $riepilogo->noleggio->prezzo_noleggio + $riepilogo->noleggio->prezzo_accessori + $riepilogo->noleggio->prezzo_assicurazione, 2,'.','');
$riepilogo->noleggio->prezzo_totale_scontato = '';
$cart_object->cart_contents[$cart_item_id]['_dettagli_noleggio'] = json_encode($riepilogo);
}
}
}
I think the cause of the problem is related to the saving times in the database. When I go on paypal or credit card page I get the full price instead of the discounted value.
Any suggest or best approach to do it?
First, in your code, the $percent variable is not defined. Your question is not really clear (missing context) and your code is not testable.
What is behind $cart_item['_dettagli_noleggio'] and how do you set it?
Based on this answer code, try the following revised and simplified code:
add_action( 'woocommerce_checkout_init', 'payment_method_change_trigger_update_checkout_js' );
function payment_method_change_trigger_update_checkout_js() {
wc_enqueue_js("$('form.checkout').on( 'change', 'input[name=payment_method]', function(){
$(document.body).trigger('update_checkout');
});");
}
add_action( 'woocommerce_cart_calculate_fees', 'payment_method_discount', 20, 1 );
function payment_method_discount( $cart ) {
if ( is_admin() && !defined( 'DOING_AJAX' ) )
return;
$percent = 10; // HERE define the percentage
$payment_methods = array('ppcp-gateway' ,'axepta'); // HERE define the allowed payment IDs
$chosen_payment = WC()->session->get('chosen_payment_method');
$discount = 0; // Initializing
foreach( $cart->get_cart() as $item_key => $item ) {
if ( isset($item['_dettagli_noleggio']) && in_array($chosen_payment, $payment_methods) ) {
$rent_data = json_decode(stripslashes($item['_dettagli_noleggio']));
$discount -= number_format( ($rent_data->noleggio->prezzo_noleggio / 100) * $percent , 2);
}
}
if ( $discount < 0 ) {
$cart->add_fee( 'Sconto pagamento online', $discount );
}
}
Or for multiple separated discounts, replace the 2nd function with:
add_action( 'woocommerce_cart_calculate_fees', 'payment_method_discount', 20, 1 );
function payment_method_discount( $cart ) {
if ( is_admin() && !defined( 'DOING_AJAX' ) )
return;
$percent = 10; // HERE define the percentage
$payment_methods = array('ppcp-gateway' ,'axepta'); // HERE define the allowed payment IDs
$chosen_payment = WC()->session->get('chosen_payment_method');
foreach( $cart->get_cart() as $item_key => $item ) {
if ( isset($item['_dettagli_noleggio']) && in_array($chosen_payment, $payment_methods) ) {
$rent_data = json_decode(stripslashes($item['_dettagli_noleggio']));
$discount = number_format( ($rent_data->noleggio->prezzo_noleggio / 100) * $percent , 2);
$cart->add_fee( 'Sconto pagamento online', -$discount );
}
}
}
Code goes in functions.php file of your child theme (or in a plugin). It could work.
December 29, 2023
Turbo Multi-language Translator
Make the better internet purchasing globaly
Turbosify SEO Speed Booster
5.0 (7)•Free plan available
Get better conversions by improving store loading speed
Installed
Turbo Multi-language Chat - AI Customer service in one hand
December 29, 2023