On my morning walks, I have been enjoying listening to SaaS related podcasts, and yesterday morning, I was listening to Jane Portman's "UI Breakfast" podcast in which she was talking to Rob Turlinckx about SaaS Pricing pages.
Now, we have just done a revamp of our own HR Partner pricing page, which actually meets most of the suggestions of what they talked about in the podcast, i.e. offering multiple currencies, showing the user's local currency automatically upon loading, showing monthly vs annual pricing etc.
Our page is quite complex (but thankfully I have a great UX designer on my team who made it as easy to use as possible), but I thought I would expand upon a couple of things that we did on there in order to display pricing in various currencies, and most importantly, how we detected the user's location and showed them the relevant pricing in their own local currency (or else defaulting back to USD if they were in a location outside of our usual pricing).
What I have done is to put together a simple pricing page on Github which you are welcome to explore and dissect. My aim was to be able to achieve localised pricing with (a) minimal javascript code, (b) doing it all on one page and (c) for absolutely FREE - no calling upon expensive landing page or A/B testing services to generate different pricing pages at all!
This is what it looks like (yep, I'm a coder, not a designer!):
Take a look at it running live here: https://cyberferret.github.io/LocalCurrencyPricing/
Here is a Gist of the actual web page code:
<html lang="en"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> <meta name="description" content=""> <meta name="author" content=""> <title>Demonstration of dynamic currency display</title> <!-- Bootstrap core CSS --> <link href="vendor/bootstrap/css/bootstrap.min.css" rel="stylesheet"> <!-- Custom styles for this template --> <link href="css/heroic-features.css" rel="stylesheet"> </head> <body> <!-- Navigation --> <nav class="navbar navbar-expand-lg navbar-dark bg-dark fixed-top"> <div class="container"> <a class="navbar-brand" href="#">Widgets Inc.</a> <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarResponsive" aria-controls="navbarResponsive" aria-expanded="false" aria-label="Toggle navigation"> <span class="navbar-toggler-icon"></span> </button> <div class="collapse navbar-collapse" id="navbarResponsive"> <ul class="navbar-nav ml-auto"> <li class="nav-item active"> <a class="nav-link" href="#">Home <span class="sr-only">(current)</span> </a> </li> <li class="nav-item"> <a class="nav-link" href="#">About</a> </li> <li class="nav-item"> <a class="nav-link" href="#">Services</a> </li> <li class="nav-item"> <a class="nav-link" href="#">Contact</a> </li> </ul> </div> </div> </nav> <!-- Page Content --> <div class="container"> <!-- Jumbotron Header --> <header class="jumbotron my-4"> <h1 class="display-3">Hello there!</h1> <p class="lead">The pricing shown below should correspond to your location (or default to the US) like the pricing page on our <a href="https://www.hrpartner.io" target="_blank">HR Partner</a> site.</p> <a href="https://www.hrpartner.io/pricing.html" class="btn btn-primary btn-lg">See it in action!</a> </header> <div class="row text-center"> <div class="col-lg-12 m-2"> <p>Show me pricing in: </p> <div class="btn-group mb-3" role="group" aria-label="Select Currency"> <button type="button" class="btn btn-secondary" onclick="displayPrice('USD');">USD</button> <button type="button" class="btn btn-secondary" onclick="displayPrice('GBP');">GBP</button> <button type="button" class="btn btn-secondary" onclick="displayPrice('EUR');">EUR</button> <button type="button" class="btn btn-secondary" onclick="displayPrice('AUD');">AUD</button> </div> </div> </div> <!-- Page Features --> <div class="row text-center"> <div class="col-lg-3 col-md-6 mb-4"> <div class="card"> <div class="card-header"> <h2 class="text-primary">FREE</h2> </div> <div class="card-body"> <h4 class="card-title pricing USD_pricing">USD $0</h4> <h4 class="card-title pricing GBP_pricing collapse">GBP £0</h4> <h4 class="card-title pricing EUR_pricing collapse">EUR €0</h4> <h4 class="card-title pricing AUD_pricing collapse">AUD $0</h4> <p class="card-text text-info">Our free plan will suit the Scrooge McDuck's among you.</p> </div> <div class="card-footer"> <a href="#" class="btn btn-primary">Find Out More!</a> </div> </div> </div> <div class="col-lg-3 col-md-6 mb-4"> <div class="card"> <div class="card-header"> <h2 class="text-primary">Basic</h2> </div> <div class="card-body"> <h4 class="card-title pricing USD_pricing">USD $10</h4> <h4 class="card-title pricing GBP_pricing collapse">GBP £8</h4> <h4 class="card-title pricing EUR_pricing collapse">EUR €9</h4> <h4 class="card-title pricing AUD_pricing collapse">AUD $14</h4> <p class="card-text text-info">This basic plan should get you kick started.</p> </div> <div class="card-footer"> <a href="#" class="btn btn-primary">Find Out More!</a> </div> </div> </div> <div class="col-lg-3 col-md-6 mb-4"> <div class="card"> <div class="card-header"> <h2 class="text-primary">Medium</h2> </div> <div class="card-body"> <h4 class="card-title pricing USD_pricing">USD $50</h4> <h4 class="card-title pricing GBP_pricing collapse">GBP £38</h4> <h4 class="card-title pricing EUR_pricing collapse">EUR €42</h4> <h4 class="card-title pricing AUD_pricing collapse">AUD $67</h4> <p class="card-text text-info">For businesses that really need all the bells and whistles.</p> </div> <div class="card-footer"> <a href="#" class="btn btn-primary">Find Out More!</a> </div> </div> </div> <div class="col-lg-3 col-md-6 mb-4"> <div class="card"> <div class="card-header"> <h2 class="text-primary">Enterprise</h2> </div> <div class="card-body"> <h4 class="card-title pricing USD_pricing">USD $200</h4> <h4 class="card-title pricing GBP_pricing collapse">GBP £152</h4> <h4 class="card-title pricing EUR_pricing collapse">EUR €171</h4> <h4 class="card-title pricing AUD_pricing collapse">AUD $270</h4> <p class="card-text text-info">If you have more money than Elon Musk, then this is the plan for you.</p> </div> <div class="card-footer"> <a href="#" class="btn btn-primary">Find Out More!</a> </div> </div> </div> </div> <!-- /.row --> </div> <!-- /.container --> <!-- Footer --> <footer class="py-5 bg-dark"> <div class="container"> <p class="m-0 text-center text-white">Copyright © Widgets Inc. 2018</p> </div> <!-- /.container --> </footer> <!-- Bootstrap core JavaScript --> <script src="vendor/jquery/jquery.min.js"></script> <script src="vendor/bootstrap/js/bootstrap.bundle.min.js"></script> <script> $(document).ready(function () { $.get("https://api.ipdata.co?api-key=e1173cbb1676c06b2136abfc7ca95e0c10b8ee98623bfbb0c47b0aaa", function (response) { var detectedCurrency = response.currency.code; displayPrice(detectedCurrency) }, "jsonp"); }); displayPrice = function(currency) { // First, lets hide all the current pricing $(".pricing").hide(); // Is the currency within the valid range of currencies that we wish to show? if (currency !== null || (["USD", "AUD", "GBP", "EUR"].indexOf(currency) > -1)) { // If yes, then show the currency $("." + currency + "_pricing").show(); } else { // If no, then just show USD pricing $(".USD_pricing").show(); } } </script> </body> </html>
If you want the full source code (with the Bootstrap and jQuery libraries etc. so you can test on your own server), then you can clone my code from my Github repository: https://github.com/CyberFerret/LocalCurrencyPricing
Let's break down the code here.
Firstly, I am using a simple Bootstrap 4 page layout, which has a header block, then 4 columns for the pricing. If you look at each pricing column though, I have included the 4 currencies that I want to show:
<div class="col-lg-3 col-md-6 mb-4"> <div class="card"> <div class="card-header"> <h2 class="text-primary">FREE</h2> </div> <div class="card-body"> <h4 class="card-title pricing USD_pricing">USD $0</h4> <h4 class="card-title pricing GBP_pricing collapse">GBP £0</h4> <h4 class="card-title pricing EUR_pricing collapse">EUR €0</h4> <h4 class="card-title pricing AUD_pricing collapse">AUD $0</h4> <p class="card-text text-info">Our free plan will suit the Scrooge McDuck's among you.</p> </div> <div class="card-footer"> <a href="#" class="btn btn-primary">Find Out More!</a> </div> </div> </div>
But have a look at the `collapse` class used in all but the USD pricing in the source code. What this does is 'collapses' the other currencies so that they are not visible upon page load, instead showing you the USD pricing as a default.
I have also given all the pricing <h4> tags the class of `pricing` and `XXX_pricing` (where XXX is the 3 letter currency code for each locale). You will see how I use these later to both hide and show the relevant pricing via a simple javascript function.
Now lets look at the javascript code at the bottom of the page. There are two blocks we need to look at, namely:
$(document).ready(function () { $.get("https://api.ipdata.co?api-key=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", function (response) { var detectedCurrency = response.currency.code; displayPrice(detectedCurrency) }, "jsonp"); });
This bit of code waits until the page is completely loaded, then goes off to the IPData.co free service to query the user's locale information, including the currency code associated with their locale.
This information is contained within the JSON response from the IPData service, and you can get to it via the response.currency.code variable.
Be warned that this call, even though it is done as a background asynchronous AJAX call, can take a few seconds to return a result - which is why we show the default USD pricing initially, rather than no pricing at all. This can cause a disconcerting flicker upon page load, so you may want to show NO pricing on your own page as a default, which you can do by adding the `collapse` class to ALL pricing lines initially. It is entirely up to you.
TIP: Just remember to replace the 'xxxxxxxxx' dummy API key above with your free one that you get from IPData.co!
The next bit of javascript is the one that manipulates the page DOM to show or hide the relevant currencies:
displayPrice = function(currency) { // First, lets hide all the current pricing $(".pricing").hide(); // Is the currency within the valid range of currencies that we wish to show? if (currency !== null || (["USD", "AUD", "GBP", "EUR"].indexOf(currency) > -1)) { // If yes, then show the currency $("." + currency + "_pricing").show(); } else { // If no, then just show USD pricing $(".USD_pricing").show(); } }
This function takes just one parameter, the 3 letter currency code, and then it:
- Hides ALL the pricing lines by default, then
- Checks the currency code to see if it is one of the 4 allowed codes on our page, then
- If it is allowed, shows the pricing which has the class of `[Currency Code]_pricing`, or
- Shows the default USD pricing lines.
One last thing - I realise that sometimes users may want to see the pricing in other currencies themselves, rather than in their local currency. Most often when they want to compare the USD values against other services they use etc., so we should allow them the ability to do so.
Which is why I placed the button group between the header and the pricing boxes which asks for the currency they want to see. Clicking on any of the buttons will call the `displayPrice()` function to show that locale's currency.
<div class="row text-center"> <div class="col-lg-12 m-2"> <p>Show me pricing in: </p> <div class="btn-group mb-3" role="group" aria-label="Select Currency"> <button type="button" class="btn btn-secondary" onclick="displayPrice('USD');">USD</button> <button type="button" class="btn btn-secondary" onclick="displayPrice('GBP');">GBP</button> <button type="button" class="btn btn-secondary" onclick="displayPrice('EUR');">EUR</button> <button type="button" class="btn btn-secondary" onclick="displayPrice('AUD');">AUD</button> </div> </div> </div>
That's it! Pretty easy (and cheap), isn't it? No need for a complex content management system, or PHP/Ruby scripting etc. This can all be done on a free website hosting platform like Amazon S3 (which we use) or Github Pages etc.
Have fun with it. For my next post, I might showcase how to use a free foreign currency exchange API to dynamically calculate the other pricing based on that day's exchange rates!