type:
snippet
category:
checkout
name:
Override Sales Tax During Checkout
versions:
0.7.2
reference:
http://forum.foxycart.com/discussion/comment/42865
tags:
checkout, snippet, tax, sso, foxy-shop
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!

Site Tools