Search code examples
phpjquerywordpresswoocommercepayment-method

Custom checkout field enable or disable payment methods in Woocommerce 3


So i'm working on http://www.lichtunie.nl We have a functioning checkout page with the needed fields. The problem is this: In the Netherlands (where we're based) We have something called KvK, if you start a company you need to register it there and you get a KvK number. We can check those numbers through a website to see if they're legit and how their payment history is.

Now we have the option of "paying with cheque" Which let's you order and pay within a 30 day time period after receiving the invoice. What we want now is that when someone doesn't fill in their KvK number field on checkout they can't use this method of payment.

As soon as they've filled in the "KvK number" field they should be able to though.

I've been looking for a while and just can't figure out how to do this. Anyone got any tips?

Thanks in advance,

Lex


Solution

  • The following code will keep only "cheque" payment method if the billing KVK number checkout field is filled or exist:

    add_filter( 'woocommerce_available_payment_gateways', 'kvk_field_cheque_payment_method', 20, 1);
    function kvk_field_cheque_payment_method( $gateways ){
        foreach( $gateways as $gateway_id => $gateway ) {
        // Not in backend (admin)
        if( is_admin() ) 
            return $gateways;
    
            if( WC()->session->get( 'is_kvk_nummer' ) && $gateway_id != 'cheque' ){
                unset( $gateways[$gateway_id] );
            }
        }
        return $gateways;
    }
    
    // The Wordpress Ajax PHP receiver
    add_action( 'wp_ajax_kvk_nummer', 'get_ajax_kvk_nummer' );
    add_action( 'wp_ajax_nopriv_kvk_nummer', 'get_ajax_kvk_nummer' );
    function get_ajax_kvk_nummer() {
        if ( $_POST['bkvkn'] == '1' ){
            WC()->session->set('is_kvk_nummer', '1');
        } else {
            WC()->session->set('is_kvk_nummer', '0');
        }
        die();
    }
    
    // The jQuery Ajax request
    add_action( 'wp_footer', 'checkout_kvk_fields_script' );
    function checkout_kvk_fields_script() {
        // Only checkout page
        if( is_checkout() && ! is_wc_endpoint_url() ):
    
        // Remove "is_kvk_nummer" custom WC session on load
        if( WC()->session->get('is_kvk_nummer') ){
            WC()->session->__unset('is_kvk_nummer');
        }
        ?>
        <script type="text/javascript">
            jQuery( function($){
                var a = 'input#billing_kvk_nummer';
    
                // Ajax function
                function checkKvkNummer( value ){
                     $.ajax({
                        type: 'POST',
                        url: wc_checkout_params.ajax_url,
                        data: {
                            'action': 'kvk_nummer',
                            'bkvkn': value != '' ? 1 : 0,
                        },
                        success: function (result) {
                            $('body').trigger('update_checkout');
                        }
                    });
                }
    
                // On start
                checkKvkNummer($(a).val());
    
                // On change event
                $(a).change( function () {
                    checkKvkNummer($(this).val());
                });
            });
        </script>
        <?php
        endif;
    };
    

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

    Addition
    Also to hide "cheque" payment method if billing KVK number checkout field is not filled, replace the first function with this one:

    add_filter( 'woocommerce_available_payment_gateways', 'kvk_field_cheque_payment_method', 20, 1);
    function kvk_field_cheque_payment_method( $gateways ){
        // Not in backend (admin)
        if( is_admin() ) 
            return $gateways;
    
        foreach( $gateways as $gateway_id => $gateway ) {
    
            if( $gateway_id != 'cheque' && WC()->session->get( 'is_kvk_nummer' ) ){
                unset( $gateways[$gateway_id] );
            } elseif( $gateway_id == 'cheque' && ! WC()->session->get( 'is_kvk_nummer' ) ){
                unset( $gateways[$gateway_id] );
            }
        }
        return $gateways;
    }
    

    It should work (untested).