Introducing TaxCloud.js – free and easy sales tax collection for Stripe

Visit Stripe PaymentsWe have a new library for anyone who needs to calculate sales tax and prefers to work with Javascript on the client side. We call it ‘TaxCloud.js’ and you can use it purely as a library of TaxCloud-specific API calls, or as a very simple UI shopping cart to collect items and determine sales tax due (based upon your customer’s address) before you send a total purchase amount to your purchasing platform.

In this post we describe how to use our simple UI cart option. Then we will show you how to send the total purchase amount (with sales tax) to your payment processor. In our example, we will be using Stripe, but these bits will work just as well with other payment services, such as PayPal, Google Wallet, Braintree, etc. With this scenario you can add TaxCloud.js to your order processing as a step before your payment system. Let’s take a look.

The basic process when a customer wishes to purchase from your website is:

E-Commerce Order Flow

The question is how to update this flow so that we can properly compute sales tax but not have to significantly rework proven processes or request changes of the payment processor. With TaxCloud.js this flow is virtually unaltered, except for the following minimal enhancements:

TaxCloud modified order flow

The red arrows represent TaxCloud interactions that complete sales tax requirements and are easy to implement. The executive summary is:

  1. Ask TaxCloud for the proper tax on a group of items given a merchant origin address and a customer shipping address.
  2. Notify TaxCloud that the purchase has been made.

This is the concept, now let’s take a deeper dive into exactly how to do it. For this example we will be using the following:

  • taxcloud.js – our API in javascript form
  • TaxCloud.php or TaxCloud.aspx – our minimal ‘forwarding’ script/page to handle cross-domain posting
  • checkout.js – a library provided by Stripe to handle purchases with a credit card
  • jquery.min.js – everyone knows about JQuery, right?
  • HelloTaxCloud.html – a sample page using everything described in this post

As I mentioned earlier we will be using the built-in UI cart that taxcloud.js supports. The goal of this is to make things as easy as possible for web masters to show a cart of items with their tax as a line item. Our sample page uses this option, covers everything described in this post, is a little over 100 lines in length and works. Download the HelloTaxCloud.html page and take a look at it. If you put HelloTaxCloud.html on your web server you can step through all the concepts described here at your convenience. Don’t worry, when you start with TaxCloud your account is in test mode. It doesn’t become live until you say so!

Act 1: The Setup

First thing we need to set up is the proxy page/script that will run on your web server. We have two flavors for you to choose from:

If you are using another server processing extension you can either create the same page functionality on your platform (nothing tricky going on) or let us know so that we can create it.

Open TaxCloud.php/TaxCloud.aspx in your editor and take a look at it. This file has two purposes:

  1. It holds your credentials for TaxCloud and USPS
  2. It receives posts from our taxcloud.js library running in your domain and forwards the data to our TaxCloud web service running in our TaxCloud.net domain.

While you have TaxCloud.php/TaxCloud.aspx open, lets go ahead and add your unique credentials.

websites_api_id_and_keyThe credentials you need are from your TaxCloud account, specfically your apiLoginID and apiKey. Log into TaxCloud and go to the Websites Section. Select your website, and your ‘API ID’ and ‘API KEY’ will be displayed.

The uspsUserID is an identifier that the US Post Office provides you so you may verify addresses. If you need a US Post Office user ID for shipping address verification you can get one by registering for USPS Web Tools.

Excerpt of TaxCloud.php

 // Put your TaxCloud API Login and API Key values here, along with the USPS User ID.
 $apiLoginID = "XXXXXXX"; //Use the API ID from TaxCloud
 $apiKey = "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"; //Use the API KEY from TaxCloud
 $uspsUserID = "XXXXXXXXXXXX";
Excerpt of TaxCloud.aspx
private void Page_Load(object sender, EventArgs e){
 // Put your TaxCloud API Login and API Key values here, along with the USPS User ID.
 string apiLoginID = "XXXXXXXX";// Use the API ID from TaxCloud
 string apiKey = "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"; //Use the API KEY from TaxCloud
 string uspsUserID = "XXXXXXXXXXXX";
 ...
}

You can close TaxCloud.php/TaxCloud.aspx now – you are done with it.

Act 2: “Install” The Code

Second, open your HTML file in an editor (your HTML file is the page where you sell stuff, not the TaxCloud.php/TaxCloud.aspx file) . You need to add the following javascript reference:

<!-- TaxCloud Requirements -->
<script type="text/javascript"
 src="https://taxcloud.net/taxcloud.js"></script>

Note that we are including with ‘https’ because we are doing a purchase page. Payment processors usually have this requirement. In fact, as we are demonstrating integration with Stripe, we need ensure https per their requirements:

<!-- Stripe Requirements -->
<script type="text/javascript"
 src="https://checkout.stripe.com/v2/checkout.js"></script>

And a bit of JQuery for good measure:

<script type="text/javascript"
 src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script type="text/javascript"
 src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.10.3/jquery-ui.min.js"></script>

Finally, we are going to add reference to our default JQuery UI Theme, a slightly modified version of the JQuery UI Cupertino theme:

<link
 href="https://taxcloud.net/downloads/TaxCloud.js/TaxCloud.js.css"
 rel="stylesheet" />

Of course, if your site already uses a JQuery UI Theme, you can omit this link, and the TaxCloud.js UI will look like the rest of your site automatically.

Now we will look at the actual javascript code we need to add to make all this work. This seems like a good spot to introduce the TaxCloud objects defined in taxcloud.js. They are:

  • TaxCloudConnection — this handles the actual network communication between the web page and TaxCloud (via TaxCloud.php/TaxCloud.aspx).
  • TaxCloudAddress — this class makes it easy to use a shipping address with both the US Post Office (for verification) and TaxCloud (for tax lookups)
  • TaxCloudCartItem — represents an item in your cart a customer can purchase. It has a price, quantity and Taxability Information Code (TIC). [You will need to be logged-in to review complete TIC documentation]
  • TaxCloudCart — manages a collection of TaxCloudCartItems
  • TaxCloud — manages your cart, origin and destination (shipping) addresses and communication. The TaxCloud javascript object exposes the actual methods you’ll be calling to work with our TaxCloud online services (VerifyOriginAddress, VerifyDestinationAddress, Lookup, AuthorizedWithCapture, Returned).

But what does this look like in code? In a <script></script> section, start with this:

 var myTaxCloud = new TaxCloud("TaxCloud.php", "doPurchase.php");
 var storeName = "Your Store Name";

 $().ready(function(){//be sure page is fully loaded
    myTaxCloud.OnPurchaseStep2PurchaseClicked = TaxCloudPurchaseStep2PurchaseClicked;
    myTaxCloud.Install();
    myTaxCloud.SetCustomerID(getCustomerID(), true);
  });

 function getCustomerID(){
   //go get your customer identifier from somewhere
   //if you already have their address, you could pre-populate the address form.
   return "fabulousCustomer399";
 }

When we create our new TaxCloud instance, we provide two parameters:

  1. taxCloudPostUrl — the path to the TaxCloud.php/TaxCloud.aspx page on your server
  2. purchasePostUrl — the path to your payment handler page on your server, in our case doPurchase.php which uses Stripe as our payment gateway

You can also see that we have defined a javascript variable “storeName” – you should set this to the name of your store, which will be seen by your customers in the checkout UI titlebars.

After initializing TaxCloud, we use JQuery’s ready() to register an event and finish “installing” taxcloud on your HTML page.

TaxCloud has several events you can hook into during the processing of the address and cart. We’re keeping it simple here and just wiring up the ‘OnPurchaseStep2PurchaseClicked’. This notifies you that the customer has completed the cart steps (provided their shipping address and looked up their tax information) and therefore a ‘Grand Total’ is available. You will respond to this event by grabbing that grand total and beginning your purchase process (for example, with a credit card).

The last line in this code snippet sets the unique customer id for the end user. The customerID is a field you supply that uniquely represents the customer. The function also takes a flag that tells TaxCloud whether or not to retrieve previous address and cart information, if found. This handles the case where people start a purchase, cancel it and then return later to pick up where they left off. Right now we only store this information for 24 hours. You can use this customerID later to view customer specific transactions in our activity log. The customerID field is required.

Fabulous, TaxCloud.js is now installed and ready to go to work.

Act 3: Where are you?

We have one more step before you can get onto the business of selling things. You need to tell TaxCloud.js what your address is (your store or office location). Note: This location must also be added to the TaxCloud website, in the Locations section.

SetMyAddress();//this should be done within the $(document).ready function

function SetMyAddress() {
  myTaxCloud.addressOrigin.address1 = "Your Address";
  myTaxCloud.addressOrigin.city = "Your City";
  myTaxCloud.addressOrigin.state = "Your State as Two Letters";
  myTaxCloud.addressOrigin.zip5 = "Your 5-Digit zip code";
}

Act 4: The Products

Next we need to let TaxCloud know what the items are that we will be checking tax information for. This means we need to create a TaxCloudCart with a list of TaxCloudCartItem objects. Each TaxCloudCartItem object has five properties:

  1. an item identifier (a SKU works great) but we do not recommend using a title or product name – this identifier is for machine use, not human use
  2. the item display name or brief description – this one is for human use
  3. the unit price
  4. a quantity
  5. a TIC (remember that Taxability Information Code?)

You can add TaxCloudCartItems to the TaxCloudCart one at a time or in bulk. For example, to add a single item at a time you could create a button as follows:

<button id="001" onclick="
    myTaxCloud.cart.AddItem(
      new TaxCloudCartItem(
       'TST001',
       'Awesome product',
       24.99,
       1,
       00000)
      )"
 type="button">Add to cart</button>

The ‘onclick’ handler adds the new TaxCloudCartItem to the TaxCloudCart, which triggers an internal event so that it immediately appears in the UI. Then the ‘onclick’ handlers does a Lookup to update all the line items in the cart, including the new one we just added.

We could also fill a cart with items like this:

FillTaxCloudCart();

function FillTaxCloudCart() {
 if (myTaxCloud.cart.items.length == 0) {
  myTaxCloud.cart.AddItem(new TaxCloudCartItem("MTS102", "Blue T-shirt", 1.5, 1, 20010));
  myTaxCloud.cart.AddItem(new TaxCloudCartItem("MTS103", "Pencil", .99, 1, 20070));
  myTaxCloud.cart.AddItem(new TaxCloudCartItem("PRD711", "Potato Chips", 1.9, 1, 40030));
  myTaxCloud.cart.AddItem(new TaxCloudCartItem("PRD712", "8 oz. bottle of water", .49, 12, 40060));
  myTaxCloud.cart.AddItem(new TaxCloudCartItem("FLG001", "Connecticut flag", 19.99, 1, 90104));
  myTaxCloud.cart.AddItem(new TaxCloudCartItem("GRP001", "Graphic design", 99, 1, 91040));
  myTaxCloud.cart.AddItem(new TaxCloudCartItem("SVC003", "Running shoes", 149, 1, 92005));
  myTaxCloud.deliveredBySeller = false;//True only if delivered in a seller vehicle
 }
}

Act 5: The Customer

Once we have the origin address and the cart in place we need to get the shipping address, verify it and do the tax lookup. Here we will make use of the taxcloud.js built-in UI to display an address form the customer can fill out. We respond to a click event on the page to start the purchase flow. In this case I created a standard button that a JQuery handler will catch the ‘click’ event for. I named it with id=’TaxCloudPurchaseButton’, but you can call it anything you like.

So, let’s create our purchase button:

<button id="TaxCloudPurchaseButton" type="button">Purchase</button>

Now, let’s wire-it up to the taxcloud.js:

//this should be put within the $(document).ready function
$('#TaxCloudPurchaseButton').click(function () {
 myTaxCloud.OpenPurchaseStep1();
 return false;
});

When a user clicks the button identified by ‘TaxCloudPurchaseButton’, it fires the javascript code above and TaxCloud.js initiates the UI.

TaxCloud.js Address Entry UISpecifically, it calls ‘OpenPurchaseStep1()’. This tells the TaxCloud library to use its built-in UI components. Once this call is made the following UI pops up to obtain the customer’s shipping address.

This form will be filled out by the customer and represents their shipping address for all the items in the cart. The button at the lower-left lets them know the ‘state’ of their address. That is, if its verified or unverified. At this point, you can click on the USPS verify address button if your want to check what you have entered, but it is not necessary because TaxCloud.js does this automatically when you press ‘Next’. So, let’s enter an example shipping address to work with and click ‘Next’ to go to our second page.

TaxCloud.js Cart UINow we see all the items in our cart. Lets talk for a moment about what else is going on here. You can see now that the address has been verified (or verification failed). You don’t need to have a verified address in order to complete a purchase, but a verified address will ensure the most accurate sales tax rates.

After attempting to verify the address, TaxCloud.js proceeded to lookup the correct sales tax amount due for each item in the cart. These calls happen asynchronously, which means the customer may see the sales tax amounts appear/update in the cart.

We also see each item listed with a unit price, the current quantity, the line item price, the line item tax amount and the line item total (price + tax). Finally, just above the ‘Update’ and ‘Purchase’ buttons we have the total, which is the sum of price and tax for all line items.

This form is interactive as well in that the customer can change quantity amounts and everything will be looked-up and computed again. Simply adjust a quantity and either click in another field to trigger the update, or click the ‘Update’ button. The new prices and tax amounts will be changed in the screen when the asynchronous calls receive their response.

At this point you may be curious what code you need to add in order to handle the transition from the first purchase page to the second. The answer is, there is none. The TaxCloud library, being UI aware, handles this transition for you. We do make callback hooks available if you require additional processing before proceeding, but we’re keeping things simple for the time being. In a future post we will look at all the TaxCloud UI events available. One event we do need to hookup is when the customer clicks the ‘Purchase’ button. For that action we have the following event hook and callback example:

myTaxCloud.OnPurchaseStep2PurchaseClicked = TaxCloudPurchaseStep2PurchaseClicked;

//...

function TaxCloudPurchaseStep2PurchaseClicked(myTaxCloud) {
 purchaseWithStripe(myTaxCloud, Math.floor(myTaxCloud.cart.GrandTotal() * 100.0));
}

Act 6: The Purchase

We told the TaxCloud library what call to make when the purchase button on the second page is clicked. TaxCloud will call this method and pass in an instance of itself as the parameter. This is where you, the merchant, can do extra processing if needed before making the actual purchase. In this test case we have a small but important processing step to do. Stripe requires purchase amounts to be in cents, so we multiply the ‘myTaxCloud.cart.GrandTotal()’ by 100.0 and send that that amount to our Stripe purchase handler. Additional processing steps don’t have to be complicated to be important!

So what does the Stripe purchasing code look like? Our implementation looks like this:

function purchaseWithStripe(myTaxCloud, grandTotal) {
 var token = function (res) {
  var formData = "stripeToken=" + res.id + "&amp;";
  formData += "amount=" + grandTotal.toString() + "&amp;";
  formData += "userid=" + getUserID();
  myTaxCloud.Purchase("./doPurchase.php", formData, purchaseWithStripeCallback);
 };
 StripeCheckout.open({
 key: '<YOUR STRIPE PUBLISHABLE KEY>',
 address: false,
 amount: grandTotal,
 currency: 'usd',
 name: 'Test Purchase',
 description: 'This is a test purchase',
 panelLabel: 'Checkout',
 token: token
 });
}
function purchaseWithStripeCallback(myTaxCloud, responseText) {
 if (responseText) {
 // handle stripe specific response text
 var stripeObject = JSON.parse(responseText);
 var created = new Date(stripeObject.created * 1000);
 myTaxCloud.AuthorizedWithCapture(
 stripeObject.id,
 created,
 created,
 authorizedWithCaptureCallback);
 }
}

function authorizedWithCaptureCallback(myTaxCloud) {
 if (myTaxCloud.authorizedWithCaptureResponseType == "OK")
 alert("Thank you for purchasing!");
 else
 alert(myTaxCloud.authorizedWithCaptureResponseMessage);
}

Stripe API Keys

Note: You will need to log into Stripe to find your API Keys, as pictured.

There are three global functions and one embedded function in the code snippet above. Let’s talk about what each one is doing.

purchaseWithStripe(myTaxCloud, grandTotal)

This function is responsible for building form data, creating a Stripe token and showing the Stripe ‘Checkout’ dialog. Similar to how TaxCloud manages the two purchase step pages, Stripe provides a javascript library that pops up a nice credit card entry form.

Stripe credit card entry formOnce this form has been filled out we use the Stripe library to create a special, proprietary Stripe token.

Next we use the TaxCloud.Purchase method to send this data to Stripe via another proxy page (in this case another page we created using Stripe’s PHP library). This method simply takes a page to post form data to, the actual form data to post and a callback function. Once the data is posted and the response is received, the callback function is invoked. In this case it was:

purchaseWithStripeCallback(myTaxCloud, responseText)

The responseText is the actual data returned from Stripe. TaxCloud will treat this as opaque and hand it to you as a parameter in the callback. With Stripe this happens to be JSON data we can turn into a javascript object. Now we have TaxCloud data and Stripe data available to issue, if the purchase was successful, the final call in our flow:

myTaxCloud.authorizedWithCapture

This function lets TaxCloud know that the transaction is finished and approved. As a result, TaxCloud will add it to your monthly sales tax report. IMPORTANT: This is a mandatory API call for TaxCloud.

The method itself takes an orderID that you supply (in this case I’m using the Stripe purchase ID so that I can cross reference easily), an authorized date, a captured date (which can be the same) and the callback to invoke when the authorizedWithCapture web service call to TaxCloud returns.

Finally, upon that last callback we tell the customer the good news. You may want to add a bit more to this step.

This is our first iteration with TaxCloud.js and we are excited to hear your feedback as to how to improve it. Our goal is to make calculating sales tax as easy as possible for everyone – at no cost.

One last thing

Congratulations are in order! You have successfully integrated real-time sales tax for your customers – and you probably did it in less than an hour. Now that you have completed a transaction with your account in test-mode, you should return to TaxCloud, go to the Websites section, and click Go Live. This is important so that TaxCloud can begin preparing your monthly sales tax reports – and in 24 states, TaxCloud can even file your returns and remit your sales tax proceeds for you (with more states coming soon).

And best of all, it’s free!

7 Responses to Introducing TaxCloud.js – free and easy sales tax collection for Stripe

  1. […] sales tax service, now integrates with Stripe. Stripe will be TaxCloud’s initial partner for TaxCloud.js, TaxCloud’s new sales tax management API. Stripe merchants can now easily comply with any […]

  2. FedTax says:

    Note: based upon initial implementing feedback, TaxCloud.js was updated this evening for two purpose:

    1. Take advantage of HTML5 storage to persist a customer’s shopping cart items across an entire domain, and

    2. Updated to ensure that if a sellers’ platform does not have the ability to generate or persist a unique Customer ID, then TaxCloud.js will generate one automatically, which can then be used later to cross-reference the order.

    Thanks again for helping us make sales tax compliance easy!

  3. […] by our team of writers. In this post, we’ll shine a spotlight on those seven, which included the TaxCloud.js API.  Put simply, TaxCloud automates sales tax returns for small businesses. Through the use of the […]

  4. xxswingxx says:

    Hi!This is a very interesting application. but as it executes on the client side I’m wondering, how do you prevent users from faking the taxes amounts using the browser javascript console or it is something you must live with?

    • FedTax says:

      Hi XXSWINGXX,

      Thanks for your question. This has not been a problem because if the tax amount changes between the lookup and the authorize/capture event the transaction will fail.

      Please let us know if you have any other questions.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

Join 548 other followers

%d bloggers like this: