WooCommerce adding a discount based on payment method on Checkout Screen

113 views Asked by At

I'm trying to add a discount for 'cheque' payments in my WooCommerce store but the WC()->session->get('chosen_payment_method') command isn't working as expected. I can add a discount successfully but I can't make it dependent on the selected payment method. I have this in a .php file inside a .zip file and am running it as a custom plugin on my wordpress site.

Here is my current code. The WC()->session->get('chosen_payment_method') seems to not be working as expected and is causing the if($chosen_payment_method == 'cheque') statement to not run.

add_filter( 'woocommerce_cart_calculate_fees', 'discount_based_on_payment_method', 10, 1 );

function discount_based_on_payment_method( $cart ) {
    
    $targeted_payment_method = 'cheque'; // Using the cheque payment method
    $chosen_payment_method = WC()->session->get('chosen_payment_method');
    var_dump($chosen_payment_method); //this is for debugging. it always shows NULL
    
    if($chosen_payment_method == 'cheque') {
        $discount = $cart->subtotal * 0.10; // 10% discount
        $cart->add_fee( 'Cash Discount', -$discount);
    }
    
    // jQuery code: Make dynamic text button "on change" event ?>
    <script type="text/javascript">
    (function($){
        $('form.checkout').on( 'change', 'input[name^="payment_method"]', function() {
            var t = { updateTimer: !1,  dirtyInput: !1,
                reset_update_checkout_timer: function() {
                    clearTimeout(t.updateTimer)
                },  trigger_update_checkout: function() {
                    t.reset_update_checkout_timer(), t.dirtyInput = !1,
                    $(document.body).trigger("update_checkout")
                }
            };
            t.trigger_update_checkout();
        });
    })(jQuery);
    </script><?php
    
    //$cart->add_fee( 'Test Discount', '10' );
}
1

There are 1 answers

2
LoicTheAztec On

To check something better use error_log() in a filter hook, but not echo, var_dump() or print_r()… Then don't echo/output any JavaScript in a filter hook.

Use the following instead:

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_filter( 'woocommerce_cart_calculate_fees', 'discount_based_on_payment_method', 10, 1 );
function discount_based_on_payment_method( $cart ) {
    if ( is_admin() && ! defined( 'DOING_AJAX' ) )
        return;

    if ( ! ( is_checkout() && ! is_wc_endpoint_url() ) )
        return;
    
    $targeted_payment_method = 'cheque'; // Here define the desired payment method
    
    if( WC()->session->get('chosen_payment_method') === $targeted_payment_method ) {
        $discount = $cart->subtotal * 0.10; // 10% discount
        $cart->add_fee( 'Cash Discount', -$discount);
    }
}

Code goes in functions.php file of your child theme (or in a plugin). Tested and works.

Related: How to debug in WooCommerce 3+