Building web-based points of sale for Android & iOS

With Square, you can build a web app that switches to the Square Point of Sale app to accept in-person payments. The best part is that you can do this with both Android and iOS, so it is possible to build a web-based point of sale that can utilize Square’s hardware to accept in person payments on both iOS and Android. In this post we’ll walk through the necessary steps to build your own apps.

In order to make a cross platform web app, we need logic to detect what platform the target device is running. Doing this accurately can be really hard, and there are whole libraries dedicated to parsing out user agents. To keep this example simple we’ll use a javascript solution roughly outlined in this Stack Overflow answer that uses a regular expression on the user agent.

var userAgent = navigator.userAgent || navigator.vendor;
if (/android/i.test(userAgent)) {
return "Android";
if (/iPad|iPhone|iPod/.test(userAgent) && !window.MSStream) {
return "iOS";
return "unknown OS"

If the user is on an Android or iOS device, then we will display a button that will switch over to the native Square Point of Sale app when clicked. For desktop and other platforms we’ll show a dummy e-commerce form for users to input their card information.

Before you begin

If you haven’t created a Square account or registered an application to get API credentials, follow steps 1 & 2 in this Getting Started guide for the Square APIs. You’ll need your application id and to fill out your callback urls.

Building the URLs

You initiate the switch to the native Square app with a link, just like navigating to any other page on the web. Keep in mind the link is going to look a little different than what you normally put in an href.

The basic structure is to have a link like this <a href="square-commerce-v1://payment/create?data=PARAMETERS"> where the PARAMETERS is an encoded JSON object with information about how much the sale is for, what tenders the Square app should allow for payment, etc. Your PARAMETERS might look something like this:

"amount_money": {
"amount": 500,
"currency_code": "USD"
"callback_url": "myapp-url-scheme://payment-complete",
"client_id": "MY_APPLICATION_ID",
"version": "1.2",
"notes": "Rental fee",
"options": {
"supported_tender_types": [

Be sure to remember to encode them with a function like encodeURIComponent() so that your final URL looks something like this:

<a href="square-commerce-v1://payment/create?data=%7B%22amount_money%22%3A%7B%22amount%22%3A500%2C%22currency_code%22%3A%22USD%22%7D%2C%22callback_url%22%3A%22myapp-url-scheme%3A%2F%2Fpayment-complete%22%2C%22client_id%22%3A%22MY_APPLICATION_ID%22%2C%22version%22%3A%221.2%22%2C%22notes%22%3A%22Rental%20fee%22%2C%22options%22%3A%7B%22supported_tender_types%22%3A%5B%22CREDIT_CARD%22%2C%22CASH%22%2C%22SQUARE_GIFT_CARD%22%5D%7D%7D">Click on me to Check out!</a>

You can learn more about the the options at the Using the Point of Sale API for iOS guide.

Android links look very different, but should be somewhat familiar if you used Android before. All you have to do is put your intent directly in the link:

<a href="intent:#Intent;action=com.squareup.register.action.CHARGE;package=com.squareup;S.browser_fallback_url=;;;;;;,com.squareup.register.TENDER_CARD_ON_FILE,com.squareup.register.TENDER_CASH,com.squareup.register.TENDER_OTHER;end">Buy Now!</a>

All the information for the transaction is added into different parameters. See the reference at Using the Web API for Android.

Putting it all together

Now we have the logic for roughly detecting the operating system, as well as handling payments for iOS, Android, and the web. The rest of our code is made up of HTML and javascript gluing everything together. Don’t forget, an easy way to test out the code is to use ngrok to expose your development environment to a URL.

If you have any questions about this code, or using the web API for Point of Sale, please read more in the documentation, or leave a comment, or reach out to us on Twitter (@SquareDev). And check out the final code in the example we created below!

Source link