0

I am trying to programatically add a fee to the woocommerce cart from a script which is executed on a form submission. As far as I am aware, I don't think I am able to use a hook as I need to apply the custom fee when the form on the page has been submitted (Custom API integration).

I have tried doing the following within the script:

add_action( 'woocommerce_cart_calculate_fees', 'woo_add_cart_fee' );
function woo_add_cart_fee( $cart ){
    $valid = false;

    if ( ! $_POST || ( is_admin() && ! is_ajax() ) ) {
        return;
    }

    if (isset($_POST['coupon_code'])) {
        $code = $_POST['coupon_code'];
        $coupon = new WC_Coupon($code);
        if($coupon->get_amount() != null){
            $valid == true;
        }

        //if not then lets check to see if its a giftcard.
        if($valid == false){
            $api_login="xxxxxx";
            $api_password="xxxxxx";
            $url = "https://xxxxxx.com/xxxxx/xxxxx.svc";
            $client = new SoapClient( $url . "?singleWsdl",
                array(
                "location" => $url,
                "login" => $api_login,
                "password" => $api_password,
                "trace" => 1
                )
            );  

            $request = new StdClass();
            $request->bonId = $code;
            $request->bonType = 'GiftCard';

            // call the correct database
            $request->context = new StdClass();
            $request->context->DatabaseId = 'xxxxx';    

            try {
                $resu = $client->GetBonAvailableAmount($request);
                if (isset($resu->GetBonAvailableAmountResult->Amount)) {
                    $amount = $resu->GetBonAvailableAmountResult->Amount;
                    $cart->add_fee('xxxxxx Gift Card ', floatval('-'.$amount * 0.83333), false, '' );                     
                } else {
                    $response['status'] = 'error';
                    $response['message'] = 'Gift card not recognized.';
                }
            } catch (Exception $e) {

            }
        }
    }
} 

and I can see that when I echo the cart object there is a fee object which contains all the correct data.

It seems that the cart or totals are not updating, if i refresh the page, they still do not reflect the values i am expected.

I have trawled pretty much all Stack Overflow posts and cant seem to find anything which solves the issue.

Is there anything that I am missing here?

Lewis Browne
  • 904
  • 7
  • 23
  • When you say 'external php script' - what do you mean? – markmoxx Dec 10 '18 at 16:39
  • A script which is not part of the theme, its in a directory called `/scripts/`, Within the script i have loaded wordpress etc. – Lewis Browne Dec 10 '18 at 16:41
  • Are you loading this external script when the cart page loads? This is almost certainly not the preferred method. You should be using hooks, as that is the WordPress way to get pretty much anything done. – markmoxx Dec 10 '18 at 16:43
  • Im doing it like this because i am doing an ajax call which is calculating the fee, in order for me to add it to a hook i will need to try and find the relevant hook which is used to apply a coupon code. – Lewis Browne Dec 10 '18 at 16:48
  • What do coupons have to do with the question? – markmoxx Dec 10 '18 at 16:55
  • Ignore the Coupon part, The script is executed when a form is submitted on the cart page. I am unable to use a hook to achieve what i need. – Lewis Browne Dec 10 '18 at 16:58
  • Does @LoicTheAztec 's answer not work for you? – markmoxx Dec 10 '18 at 17:02
  • No because i am unable to use a hook. – Lewis Browne Dec 10 '18 at 17:02
  • The only way to enable the fee (and get the calculation) is to use the dedicated hook `woocommerce_cart_calculate_fees`… So in your case you could set a session variable to enable this fee… – LoicTheAztec Dec 10 '18 at 17:04
  • Does this help? https://stackoverflow.com/questions/32119053/woocommerce-custom-checkout-field-to-add-fee-to-order-ajax – markmoxx Dec 10 '18 at 17:05
  • @LoicTheAztec Could you give me information regarding this? – Lewis Browne Dec 10 '18 at 17:08
  • You can use a classic PHP SESSION variable, a COOKIE or some others techniques (including Woocommerce Session variable). There is many threads explaining the usage. Then in my answer hooked function you will test your session variable in an if statement, to allow the fee. You can even pass the fee amount in the session variable. – LoicTheAztec Dec 10 '18 at 17:13
  • @LoicTheAztec i have updated the question with more detail. – Lewis Browne Dec 11 '18 at 09:32
  • @LewisBrowne Where is your related code script, have you tried to set a php session variable when your script is submitted? Your question remains unclear and nobody can guess what you are doing. – LoicTheAztec Dec 11 '18 at 09:48
  • @LoicTheAztec i have now managed to get the fees to add to the cart, the only issue is when i then proceed to the payment stage, the fee disappears. – Lewis Browne Dec 11 '18 at 12:42
  • @LewisBrowne How have you manage to do that? … add your new code in your question. Remember that you need to use `woocommerce_cart_calculate_fees` hook to enable the fee calculation everywhere. Without it it will not work. – LoicTheAztec Dec 11 '18 at 12:53
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/185068/discussion-between-lewis-browne-and-loictheaztec). – Lewis Browne Dec 11 '18 at 12:56
  • New code has been added. – Lewis Browne Dec 11 '18 at 13:04
  • You are just confusing things… woocommerce_cart_calculate_fees hook has to be only use to add a fee… All your other code need to be in another function. and you need to use WC_Session or PHP $_SESSION to set the amount for the fee. Then in the fee hook you will test your session variable in an IF statement to apply your FEE. Don't use $_POST in the fee hook as you will lose it on checkout or if the customer goes to another page. – LoicTheAztec Dec 11 '18 at 13:16

1 Answers1

1

You need to use a custom function hooked in woocommerce_cart_calculate_fees action hook:

add_action( 'woocommerce_cart_calculate_fees', 'add_a_custom_fee', 10, 1 );
function add_a_custom_fee( $cart ) {
        $amount = 20;
        $cart->add_fee( __('Custom fee'), $amount );
}

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

LoicTheAztec
  • 229,944
  • 23
  • 356
  • 399