Dealing with taxes is a constant headache in e-commerce. Take a look at how you can take complete control over the taxes charged on any order in Shopp.

Overriding Tax Rates

Overriding Tax Rates

No matter how good the tools, there are always situations that break the mold and require a custom solution. This guide will show you how you can override the taxes charged on an order so you can do your own thing when the situation requires it.

Tax Exempt Orders

One case in particular that Shopp does not handle out-of-the-box is tax exempt purchases. A customer provides you with a valid tax exempt ID and you need a way to allow them to order without paying taxes.

Before dropping the taxes, you’ll need a system for identifying tax exempt customers. The business policies and procedures for identifying and verifying tax exempt customers aren’t something we’re going to cover in this guide. There are several strategies for this including adding a tax exempt ID field to customer profiles, and maybe even tying it to an automated verification service. For this tutorial though, we’re going to assume you already have a way to verify their exempt status. Once you have a customer verified, you can easily use Shopp’s customer profile manager to set their customer type to Tax Exempt. This provides an means to identify customers that are tax exempt versus those that aren’t. Using this strategy, however, does require the use of accounts in Shopp (either Shopp customer accounts or accounts integrated with WordPress users).

While Shopp does have a customer type, it has no built-in functionality to act on the customer type. The Tax Exempt customer type is nothing more than a label. The meaning of that type label gets assigned by how it is decided to handle it. At this point we need to step into the middle of Shopp’s process for determining the applicable tax rate. There is a handy filter hook for this in Shopp’s tax system called shopp_cart_taxrate.

So the basic approach is to take current rate given by the filter hook, and check if the current customer type is set to Tax Exempt or not. If it is, we return a tax rate of 0% (0.0). If not, let the current rate pass through:

// Add our custom tax exemption function to the tax rate process
add_filter('shopp_cart_taxrate', 'tax_exempt');

// Capture the current tax rate from the filter into the $rate variable
function tax_exempt ( $rate ) {

    // Access the current shopping customer (logged in or not)
    $Customer = shopp_customer();

    // Check if the customer type is tax exempt, set the rate to 0
    if ( 'Tax Exempt' == $Customer->type ) return (float)0.0;

    // Return the current rate, unchanged
    return $rate;

it is literally as simple as that.

Real-time Tax Rate Lookups

Another where it can be handy to take manual control of the tax rates is when you want to wire a Shopp store up to a tax rate service. Let’s say your store is based out of Washington state. The state government of Washington has an API that allows you to send requests and get the rate based on an address. All you need to do is funnel the information the customer has filled out from the cart, to the WA Sales Tax Rate Lookup Interface and get a rate back to Shopp.

The example below is based on the published documentation for the WA Sales Tax Rate Lookup Interface

The basic approach is to build a query, send it to the interface, parse the results and determine which rate give back, the current rate (from Shopp tax settings) or our lookup rate.

// Setup our tax rate handler
add_filter('shopp_cart_taxrate', 'wa_state_taxes');

function wa_state_taxes ( $rate ) {
    // Access the current shipping address information
    $Shipping = ShoppOrder()->Shipping;

    // Setup the query to the tax rate interface
    $query = array(
        'output' => 'text',                 // Use plain text (for simple processing)
        'addr' => $Shipping->address,       // The street address
        'city' => $Shipping->city,          // The city
        'zip' => $Shipping->postcode        // The zip code

    // Package the query for transport over the web (stringify, encode, etc)
    $options = array('body' => http_build_query($query));

    // Establish a connection to the tax rate interface and send the query
    $connection = new WP_Http();
    $result = $connection->request('',$options);

    // Normalize the results for easier parsing
    $result = str_replace('  ',' ',$result);

    // Split the space delimmited values
    $result = explode(' ',$result);

    // Convert the results to an associative array
    $_ = array(); // Setup a placeholder array for the data
    foreach ($result as $data) {
        // Parse each key value pair
        list($name,$value) = explode('=',$data);
        $_[$name] = $value;

    // Extract the fields to variables

    // Return the lookup rate if the result code is a success (ResultCode 0 or 1 or 2)
    if ( (int)$ResultCode < 3 ) return (float)$Rate;
    else return $rate;



The developers of Shopp aren’t really tax experts. While they’ve built a pretty flexible system for setting up tax rates, it has its limits and can’t possibly model every tax scenario. With filter hooks like this, it’s obvious they wanted to give developers “a way out” so that they can fill in the gaps that Shopp doesn’t cover. This strikes as the right balance between doing as much as you can for people without getting in the way of the developer and is another reason why Shopp is such a powerful e-commerce toolbox.


Jonathan was born at an early age and began designing and developing shortly after. He is the founder of Ingenesis Limited and Project Lead on the Shopp e-commerce plugin for WordPress. He lives and works in the heart of the midwest US with his family. He fancies himself a designer of code, and is only slightly addicted to coffee.

You must be logged in to post a comment.

© Ingenesis Limited. Shopp™ is a registered trademark of Ingenesis Limited.