Table of Contents
- type:
- snippet
- category:
- checkout
- name:
- Override Sales Tax During Checkout
- versions:
- 0.7.2
- reference:
- http://forum.foxycart.com/discussion/comment/42865
- date:
- 2012-10-05
Overriding product category during checkout via SSO Endpoint in Foxy-Shop
This code will help you change product categories on the fly for specific users during checkout. I had a use-case where a specific class of user wasn't supposed to be charged state sales tax. To accomplish this, I had to remove all of the products from the cart, changed the category of each product, then re-add the product to the cart. This is done at the SSO endpoint. I was using WordPress and Foxy-Shop, so had a nice and neat hook to which I could attach my function. If you're in a similar environment, add the following code to your functions.php (or a functionality plugin).
Step 1: Adding the PHP
Paste the following code in your theme's functions.php file, or functionality plugin, or customize it to match your environment.
// attach our action to the foxyshop hook add_action('foxyshop_sso_endpoint', 'my_sso_endpoint'); function my_sso_endpoint() { global $foxyshop_settings, $current_user; if ( is_user_logged_in() ) { $user = new WP_User( get_current_user_id() ); // we only want this code to run for specific users, so figure out the current user's role. foreach ( $user->roles as $role ) { // if the user has the custom role of retailer or distributor do a bunch of crazy stuff. if ( $role == 'retailer' || $role == 'distributor' ) { // hijack cart contents and change category if (isset($_GET['fcsid']) && isset($_GET['timestamp'])) { // get the contents of the cart $ch = curl_init(); if ( !defined('FOXYSHOP_CURL_CONNECTTIMEOUT') ) define('FOXYSHOP_CURL_CONNECTTIMEOUT', 10); if ( !defined('FOXYSHOP_CURL_TIMEOUT') ) define('FOXYSHOP_CURL_TIMEOUT', 15); curl_setopt( $ch, CURLOPT_URL, "https://"; . esc_attr($foxyshop_settings['domain']) . "/cart?fcsid=" . $_GET['fcsid'] . "&output=json" ); curl_setopt( $ch, CURLOPT_RETURNTRANSFER, 1 ); curl_setopt( $ch, CURLOPT_CONNECTTIMEOUT, FOXYSHOP_CURL_CONNECTTIMEOUT ); curl_setopt( $ch, CURLOPT_TIMEOUT, FOXYSHOP_CURL_TIMEOUT ); if ( defined('FOXYSHOP_CURL_SSL_VERIFYPEER') ) curl_setopt( $ch, CURLOPT_SSL_VERIFYPEER, FOXYSHOP_CURL_SSL_VERIFYPEER ); $curlout = trim(curl_exec($ch)); if ($curlout) { /* added for troubleshooting. need to see what's being passed around. $file = STYLESHEETPATH.'/datafeed.xml'; $fh = fopen($file, 'a') or die("Couldn't open $file for writing!"); fwrite($fh, $url); fwrite($fh, $curlout); fclose($fh); /**/ $response = json_decode($curlout, true); // we have to create the new query string by which we re-add the products to the cart $product_vars = array("name", "id", "width", "height", "length", "code", "image", "url", "quantity", "quantity_max", "price_each", "price", "weight_each", "weight", "shipto", "category"); //"sub_frequency" $product_subs = array("sub_startdate", "sub_nextdate", "sub_enddate"); foreach( $response['products'] as $product ) { $url = "https://"; . esc_attr($foxyshop_settings['domain']) . "/cart?fcsid=" . $_GET['fcsid'] . "&output=json"; $code = $product['code']; $name = $product['name']; $pid = $product['id']; //Remove Product From Cart /**/ $ch = curl_init(); if (!defined('FOXYSHOP_CURL_CONNECTTIMEOUT')) define('FOXYSHOP_CURL_CONNECTTIMEOUT', 10); if (!defined('FOXYSHOP_CURL_TIMEOUT')) define('FOXYSHOP_CURL_TIMEOUT', 15); curl_setopt($ch, CURLOPT_URL, "https://"; . esc_attr($foxyshop_settings['domain']) . "/cart?fcsid=" . $_GET['fcsid'] . "&cart=update&quantity=0&id=".$pid); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, FOXYSHOP_CURL_CONNECTTIMEOUT); curl_setopt($ch, CURLOPT_TIMEOUT, FOXYSHOP_CURL_TIMEOUT); if (defined('FOXYSHOP_CURL_SSL_VERIFYPEER')) curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FOXYSHOP_CURL_SSL_VERIFYPEER); $curlout = trim(curl_exec($ch)); /**/ foreach ($product as $key => $val) { //Base Names if (in_array($key, $product_vars)) { // this has to be in here or your pricing will be all kinds of screwy if ($key == "price") $val = $product["price_each"]; if ($key == "weight") $val = $product["weight_each"]; // this is where we change the category. I created a category that applies no tax if ($key == "category") $val = "no_tax"; $url .= "&" . urlencode(htmlspecialchars($key)) . "=" . urlencode(htmlspecialchars($val)) . get_verification($key, $val, $code); //Sub - had to comment this out, but with a little work, it will do the job // } elseif (in_array($key, $product_subs) && $val != "0000-00-00") { // $url .= "&" . $key . "=" . urlencode(htmlspecialchars($val)) . get_verification($key, $val, $code); //Options } elseif ($key == "options") { foreach ($val as $option_key => $option_val) { $url .= "&" . urlencode(htmlspecialchars($option_key)) . "=" . urlencode(htmlspecialchars($option_val)) . get_verification($option_key, $option_val, $code); } } } // as key => val //Add Item back to the cart $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); $curloutAdd = trim(curl_exec($ch)); /* added for troubleshooting. need to see what's being passed around. $file = STYLESHEETPATH.'/datafeed.xml'; $fh = fopen($file, 'a') or die("Couldn't open $file for writing!"); fwrite($fh, $url); fwrite($fh, $curloutAdd); fclose($fh); /**/ } // end foreach } // end curlout } // if fcsid and timestamp } else { return; } } // end foreach role } // if is logged in } //Function function get_verification($var_name, $var_value, $var_code) { global $foxyshop_settings; $api_key = $foxyshop_settings['api_key']; $encodingval = htmlspecialchars($var_code) . htmlspecialchars($var_name) . htmlspecialchars($var_value); return '||'.hash_hmac('sha256', $encodingval, $api_key).($var_value == "--OPEN--" ? "||open" : ""); }
Step 2: Test, Test, Test
Test this thing as much as possible. You'll thank yourself later!