<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Square Developer</title>
    <description>The latest articles on Forem by Square Developer (@squaredev).</description>
    <link>https://forem.com/squaredev</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Forganization%2Fprofile_image%2F1096%2F55f8fe66-1cf9-49c1-9445-fd9e8159c838.png</url>
      <title>Forem: Square Developer</title>
      <link>https://forem.com/squaredev</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/squaredev"/>
    <language>en</language>
    <item>
      <title>Card on File with React Native</title>
      <dc:creator>Richard Moot</dc:creator>
      <pubDate>Mon, 12 Jul 2021 21:11:54 +0000</pubDate>
      <link>https://forem.com/squaredev/card-on-file-with-react-native-4b3e</link>
      <guid>https://forem.com/squaredev/card-on-file-with-react-native-4b3e</guid>
      <description>&lt;p&gt;In this tutorial, we’ll show you how to accept payments in a React Native application using &lt;a href="https://developer.squareup.com/in-app-payments"&gt;Square’s In-App Payments SDK&lt;/a&gt; and &lt;a href="https://github.com/square/in-app-payments-react-native-plugin"&gt;React Native plugin&lt;/a&gt;. I’ll also show you how to safely store customer card details so that they don’t have to be manually re-entered or re-swiped for future transactions.&lt;/p&gt;

&lt;p&gt;In payment industry terms, this capability is known as &lt;a href="https://squareup.com/us/en/point-of-sale/features/card-on-file"&gt;Card on File&lt;/a&gt;, or CoF for short. For frequent transactions, e.g. ordering a Lyft or a Lime, having a card stored makes for a much snappier, lower-friction in-app user experience. Entering card details every time would be very tedious.&lt;/p&gt;

&lt;p&gt;&lt;a href="//images.ctfassets.net/1wryd5vd9xez/32rUMkPO29WgXFFkziuaYO/b6ef14f1101271fa230015f71cfadca0/square-three-screen.png" class="article-body-image-wrapper"&gt;&lt;img src="//images.ctfassets.net/1wryd5vd9xez/32rUMkPO29WgXFFkziuaYO/b6ef14f1101271fa230015f71cfadca0/square-three-screen.png" alt="square-three-screen"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As a security-minded developer, I know you might be wondering: Is it safe to store a user’s credit card details? &lt;em&gt;Is this even legal?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;If you use Square, the answer is yes. Using the Square In-App Payments (IAP) SDK means that your application and database don’t actually come into contact with the real card details. Instead, your application interacts with something called a &lt;em&gt;nonce&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;A nonce is an encrypted payment token that can be exchanged with the Square API to process a payment. A card nonce represents a credit card and all the details the user typed in. The nonce is used to store cards and capture payments without compromising the user’s privacy or security. It’s just one of the key concepts of processing payments with Square that we’ll cover today.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;In this tutorial, you’ll download and run a React Native application that processes payments using Square’s In-App Payments SDK and React Native plugin, including Card on File transactions.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;p&gt;No prior knowledge of React Native or Square is required, but you will need a Square account. You will need to be familiar with NPM, git and the command line.&lt;/p&gt;

&lt;h3&gt;
  
  
  Square Account
&lt;/h3&gt;

&lt;p&gt;A Square account will allow you to take payments and get your own API keys that you’ll use in this tutorial. Thankfully, this is easy. If you already have an active Square account, you can skip this step.&lt;/p&gt;

&lt;p&gt;Use this link to sign up for a free account (pay only transaction fees):&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;a href="https://squareup.com/signup?v=developers"&gt;Sign up for Square&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;em&gt;Tip: During signup you can choose to order a magstripe reader, which you can use to take payments in person using the &lt;a href="https://developer.squareup.com/reader-sdk"&gt;Square Reader SDK&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Finally, before continuing with the rest of the tutorial, your Square account will need to be enabled for payment processing, which means that you’ll need to provide information about the account’s owner. Visit &lt;a href="http://squareup.com/activate"&gt;squareup.com/activate&lt;/a&gt; to enable it. If you’d prefer not to make actual card charges, your Square account comes with a &lt;a href="https://developer.squareup.com/docs/testing/sandbox"&gt;sandbox&lt;/a&gt; that you can use instead. If you go the sandbox route, you’ll need to use the sandbox Application ID and Location ID instead in the examples below.&lt;/p&gt;

&lt;h3&gt;
  
  
  Square Application and Location ID
&lt;/h3&gt;

&lt;p&gt;Once you have an active Square account, you’ll need to create a new developer application in order to get your IDs and credentials.&lt;/p&gt;

&lt;p&gt;Open the dashboard to create a new app:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;a href="https://developer.squareup.com/apps"&gt;Open the Square Application Dashboard&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;em&gt;Tip: You’ll need to login with your Square account if you’re not logged in already.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Click on the “New Application” button. On the next screen, enter the name "In-App Payments SDK Quick Start" or something similar.&lt;/p&gt;

&lt;p&gt;&lt;a href="//images.ctfassets.net/1wryd5vd9xez/77kRvBXYdeLwTJM6HoBwLM/92a4e9176410a4c9d616d3bbb1587c7f/square-dashboard-new-application.png" class="article-body-image-wrapper"&gt;&lt;img src="//images.ctfassets.net/1wryd5vd9xez/77kRvBXYdeLwTJM6HoBwLM/92a4e9176410a4c9d616d3bbb1587c7f/square-dashboard-new-application.png" alt="square-dashboard-new-application"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Next, click on the "In-App Payments SDK Quick Start" app to bring up your new Square Application’s settings page.&lt;/p&gt;

&lt;p&gt;Open the Credentials page and copy down your Application ID and your Personal Access Token under ACCESS_TOKEN.&lt;/p&gt;

&lt;p&gt;&lt;a href="//images.ctfassets.net/1wryd5vd9xez/RsX3P7kiC2qc6uPWb7XkU/962eb891f71d1ad313571f7cfed00177/Screen_Shot_2020-03-19_at_12.45.45_PM.png" class="article-body-image-wrapper"&gt;&lt;img src="//images.ctfassets.net/1wryd5vd9xez/RsX3P7kiC2qc6uPWb7XkU/962eb891f71d1ad313571f7cfed00177/Screen_Shot_2020-03-19_at_12.45.45_PM.png" alt="App Credentials Page"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Next, open the Locations page and copy down the ID for a location that accepts card payments.&lt;/p&gt;

&lt;p&gt;Keep your Application ID, Personal Access Token, and Location ID handy. You’ll need them later.&lt;/p&gt;

&lt;h3&gt;
  
  
  Deploy backend app to Heroku
&lt;/h3&gt;

&lt;p&gt;Using the Square In-App Payments SDK requires that you have a backend that the client device connects to and where the final payment processing step takes place. For the purposes of this tutorial, we’ve created an example backend we can use called the In-App Payments Server Quickstart.&lt;/p&gt;

&lt;p&gt;The easiest way to deploy it is with cloud hosting provider &lt;a href="https://www.heroku.com/"&gt;Heroku&lt;/a&gt;, using a Deploy to Heroku button you’ll find in the GitHub README. All of the steps you’ll need to get it up and running are here:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;a href="https://github.com/square/in-app-payments-server-quickstart"&gt;Complete the In-App Payments Server Quickstart Setup&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Once you click the Deploy to Heroku button and signup or login to Heroku, you’ll be taken to a screen that looks like this.&lt;/p&gt;

&lt;p&gt;&lt;a href="//images.ctfassets.net/1wryd5vd9xez/6u4UX88Br9cejGfwIq5Wce/2d69ec618efe9662d06658557c154eb9/heroku-square-iap-quickstart.png" class="article-body-image-wrapper"&gt;&lt;img src="//images.ctfassets.net/1wryd5vd9xez/6u4UX88Br9cejGfwIq5Wce/2d69ec618efe9662d06658557c154eb9/heroku-square-iap-quickstart.png" alt="heroku-square-iap-quickstart"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Give the app a unique name and set the &lt;code&gt;ACCESS_TOKEN&lt;/code&gt; value on the Heroku configuration page to the value from the previous step. Then click “Deploy app”. &lt;/p&gt;

&lt;p&gt;&lt;em&gt;Tip: Note down the URL of your Heroku app, you’ll need it later. The format is https://.herokuapp.com.&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Set up React Native
&lt;/h3&gt;

&lt;p&gt;Next, we need to install React Native and its dependencies, which include &lt;a href="https://developer.apple.com/xcode/"&gt;XCode&lt;/a&gt; (for iOS) and/or &lt;a href="https://developer.android.com/studio/"&gt;Android Studio&lt;/a&gt; in order to run the application on a simulator.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Tip: Only one of XCode or Android Studio is required to complete this tutorial and instructions are provided for both.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;To set up React Native, I recommend following the guide in the React Native documentation.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;a href="https://facebook.github.io/react-native/docs/getting-started.html"&gt;Follow the React Native Getting Started Guide&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Here are a few tips to help you get through it quickly:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Choose “React Native CLI Quickstart” and not “Expo CLI Quickstart”&lt;/li&gt;
&lt;li&gt;  Choose the right Development and Target OS (Android/iOS)&lt;/li&gt;
&lt;li&gt;  Complete the whole guide, including creating and running a new application - this will make sure your setup is working&lt;/li&gt;
&lt;li&gt;  See the &lt;a href="https://facebook.github.io/react-native/docs/troubleshooting"&gt;Troubleshooting page&lt;/a&gt; if you encounter any issues&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Once you’re done, you should have XCode and/or Android Simulator working, as well as the react-native NPM package installed.&lt;/p&gt;

&lt;h3&gt;
  
  
  Additional Requirements
&lt;/h3&gt;

&lt;p&gt;The Square IAP React Native plugin has &lt;a href="https://github.com/square/in-app-payments-react-native-plugin/blob/master/README.md#build-requirements"&gt;a few build requirements&lt;/a&gt; of its own, which you’ll want to verify against your installation. If you’ve just done a fresh install with the latest versions, you should be OK. But if not, this list will tell you what you need to upgrade before continuing.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Android&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Android minSdkVersion is API 21 (Lollipop, 5.0) or higher.&lt;/li&gt;
&lt;li&gt;  Android Target SDK version: API 28 (Android 9).&lt;/li&gt;
&lt;li&gt;  Android Gradle Plugin: 3.0.0 or greater.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;iOS&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Xcode version: 9.1 or greater.&lt;/li&gt;
&lt;li&gt;  iOS Base SDK: 11.0 or greater.&lt;/li&gt;
&lt;li&gt;  Deployment target: iOS 11.0 or greater.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you’re targeting Android, one more step is required to successfully simulate the app. You’ll need to create an Android virtual device based on the Android 9 version of the Android SDK.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  In the Android Studio welcome screen, click “Configure”&lt;/li&gt;
&lt;li&gt;  Click “AVD Manager”&lt;/li&gt;
&lt;li&gt;  Click “Create Virtual Device”&lt;/li&gt;
&lt;li&gt;  Choose any common hardware and click “Next”&lt;/li&gt;
&lt;li&gt;  Click “Download” next to “Oreo” on the System Image screen&lt;/li&gt;
&lt;li&gt;  Once that’s done, click “Next” and finish the wizard&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="//images.ctfassets.net/1wryd5vd9xez/5sSEgAmyXerBx3XM9wxxCL/e4c9ee035261220f5188fdd8a509e1ca/avd.gif" class="article-body-image-wrapper"&gt;&lt;img src="//images.ctfassets.net/1wryd5vd9xez/5sSEgAmyXerBx3XM9wxxCL/e4c9ee035261220f5188fdd8a509e1ca/avd.gif" alt="avd"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Pick this device to launch as the Android Simulator in the steps below.&lt;/p&gt;

&lt;h2&gt;
  
  
  Set up the quickstart app
&lt;/h2&gt;

&lt;p&gt;So far we’ve installed and configured our dependencies. Now we can move on to installing the React Native plugin and working with the example codebase.&lt;/p&gt;

&lt;p&gt;In a nutshell, the React Native plugin provides a convenient set of interfaces to the native code running inside the Square In-App Payments SDK. To learn more about the background of the React Native plugin, check out this &lt;a href="https://developer.squareup.com/blog/square-in-app-payments-sdk-for-react-native/"&gt;announcement blog post&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Clone the repository
&lt;/h3&gt;

&lt;p&gt;For the next step, we will clone the GitHub repository that the plugin lives in: &lt;a href="https://github.com/square/in-app-payments-react-native-plugin/blob/master/react-native-in-app-payments-quickstart/README.md"&gt;square/in-app-payments-react-native-plugin&lt;/a&gt;.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git clone git@github.com:square/in-app-payments-react-native-plugin
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;After the clone is complete, change directories into the app.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt; &lt;span class="nb"&gt;cd &lt;/span&gt;&lt;span class="k"&gt;in&lt;/span&gt;&lt;span class="nt"&gt;-app-payments-react-native-plugin&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Inside of this repository, there is a React Native application that lives in the &lt;code&gt;react-native-in-app-payments-quickstart&lt;/code&gt; folder. This is the quickstart application we’ll use for the rest of the tutorial.&lt;/p&gt;

&lt;p&gt;Change directories into the application directory:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd &lt;/span&gt;react-native-in-app-payments-quickstart
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, install dependencies with &lt;a href="https://yarnpkg.com/en/"&gt;Yarn&lt;/a&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;yarn
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Configure the quickstart app
&lt;/h3&gt;

&lt;p&gt;The quickstart app allows the user to purchase a "Super Cookie" for $1 that grants special powers (due to the high sugar amount, of course).&lt;/p&gt;

&lt;p&gt;Before we can fire up the app (and our blood sugar level), we need to configure it with the Square Application ID we provisioned above.&lt;/p&gt;

&lt;p&gt;Configuration variables in the quickstart app are stored in the file &lt;code&gt;app/Constants.js&lt;/code&gt; (&lt;a href="https://github.com/square/in-app-payments-react-native-plugin/blob/master/react-native-in-app-payments-quickstart/app/Constants.js"&gt;view on GitHub&lt;/a&gt;).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;SQUARE_APP_ID&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;REPLACE_ME&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="c1"&gt;// Make sure to remove trailing `/` since the CHARGE_SERVER_URL puts it&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;CHARGE_SERVER_HOST&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;REPLACE_ME&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;CHARGE_SERVER_URL&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;CHARGE_SERVER_HOST&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/chargeForCookie`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;GOOGLE_PAY_LOCATION_ID&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;REPLACE_ME&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;APPLE_PAY_MERCHANT_ID&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;REPLACE_ME&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="c1"&gt;// constants require for card on file transactions&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;CREATE_CUSTOMER_CARD_SERVER_URL&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;CHARGE_SERVER_HOST&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/createCustomerCard`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;CHARGE_CUSTOMER_CARD_SERVER_URL&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;CHARGE_SERVER_HOST&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/chargeCustomerCard`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;CUSTOMER_ID&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;REPLACE_ME&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;SQUARE_APP_ID&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;CHARGE_SERVER_HOST&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;CHARGE_SERVER_URL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;GOOGLE_PAY_LOCATION_ID&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;APPLE_PAY_MERCHANT_ID&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;CUSTOMER_ID&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;CREATE_CUSTOMER_CARD_SERVER_URL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;CHARGE_CUSTOMER_CARD_SERVER_URL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Open the file. On line 16, replace &lt;code&gt;REPLACE_ME&lt;/code&gt; with the Application ID value from above.&lt;/p&gt;

&lt;p&gt;On line 18, replace &lt;code&gt;CHANGE_SERVER_HOST&lt;/code&gt; with the URL for your Heroku backend. Include the &lt;code&gt;https://&lt;/code&gt; but &lt;span&gt;don’t&lt;/span&gt; include the trailing slash.&lt;/p&gt;

&lt;p&gt;On line 20, replace &lt;code&gt;REPLACE_ME&lt;/code&gt; with the Location ID value from above for the Google Pay Location ID.&lt;/p&gt;

&lt;h3&gt;
  
  
  Create a customer
&lt;/h3&gt;

&lt;p&gt;The last thing we need to do before we use the app is to create a customer using the &lt;a href="https://developer.squareup.com/docs/api/connect/v2#endpoint-customers-createcustomer"&gt;CreateCustomer&lt;/a&gt; endpoint of the &lt;a href="https://developer.squareup.com/docs/more-apis/customers/setup"&gt;Customers API&lt;/a&gt;. Storing cards on file requires a customer record to attach them to.&lt;/p&gt;

&lt;p&gt;In your terminal, run this command, first substituting  with the value from the ACCESS_TOKEN you noted down below.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;    curl &lt;span class="nt"&gt;--request&lt;/span&gt; POST https://connect.squareup.com/v2/customers &lt;span class="se"&gt;\&lt;/span&gt;
         &lt;span class="nt"&gt;--header&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
         &lt;span class="nt"&gt;--header&lt;/span&gt; &lt;span class="s2"&gt;"Authorization: Bearer &amp;lt;REPLACE ME&amp;gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
         &lt;span class="nt"&gt;--header&lt;/span&gt; &lt;span class="s2"&gt;"Accept: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
         &lt;span class="nt"&gt;--data&lt;/span&gt; &lt;span class="s1"&gt;'{ "idempotency_key": &amp;lt;RANDOM_STRING&amp;gt;, "given_name": "Lauren Nobel" }'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If successful, you should see details returned that represents our new customer:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;  
       &lt;/span&gt;&lt;span class="nl"&gt;"customer"&lt;/span&gt;&lt;span class="p"&gt;:{&lt;/span&gt;&lt;span class="w"&gt; 
          &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"RPRANDHZ9RV4B77TPNGF5D5WDR"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"created_at"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"2019-06-14T15:32:50.412Z"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"updated_at"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"2019-06-14T15:32:50Z"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"given_name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"Lauren Nobel"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"preferences"&lt;/span&gt;&lt;span class="p"&gt;:{&lt;/span&gt;&lt;span class="w"&gt;  
             &lt;/span&gt;&lt;span class="nl"&gt;"email_unsubscribed"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"creation_source"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"THIRD_PARTY"&lt;/span&gt;&lt;span class="w"&gt;
       &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;customer.id&lt;/code&gt; field from the JSON is what we’ll need to eventually store a card on file for this customer from the app.&lt;/p&gt;

&lt;p&gt;In &lt;code&gt;app/Constants.js&lt;/code&gt;, the file from above, set the value of the CUSTOMER_ID constant to the customer.id field above.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;CUSTOMER_ID&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="err"&gt;“&lt;/span&gt;&lt;span class="nx"&gt;REPLACE_ME&lt;/span&gt;&lt;span class="err"&gt;”&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;From the quickstart app’s perspective this will now be the Square customer who’s using it.&lt;/p&gt;

&lt;h3&gt;
  
  
  Start the app - iOS
&lt;/h3&gt;

&lt;p&gt;You’re now ready to run the app for the first time. Before we start the app, we need to launch the iOS simulator. This comes with XCode and gives us a virtual device that looks and acts like an iPhone or iPad.&lt;/p&gt;

&lt;p&gt;The simulator should live in your Applications folder and simply be called Simulator or Simulator.app. Once you open the app, a virtual device you have configured should boot up automatically.&lt;/p&gt;

&lt;p&gt;&lt;a href="//images.ctfassets.net/1wryd5vd9xez/6saTVGeCeVMk1SyJxJEaG7/0896838a68fcb732621fa7bd49c5fa02/ios-simulator.png" class="article-body-image-wrapper"&gt;&lt;img src="//images.ctfassets.net/1wryd5vd9xez/6saTVGeCeVMk1SyJxJEaG7/0896838a68fcb732621fa7bd49c5fa02/ios-simulator.png" alt="ios-simulator"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now, we’re ready to use the react-native command to run our device on the simulator. Enter this command in your terminal and hit enter:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;react-native run-ios
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If it’s your first time running, you’ll see a lot of output and the process will take a little while. Don’t worry, that’s normal. Ultimately, you should see the message &lt;code&gt;** BUILD SUCCEEDED **&lt;/code&gt; and the process will exit cleanly.&lt;/p&gt;

&lt;p&gt;Once that’s all complete, you should see our Super Cookie application loaded onto the virtual phone.&lt;/p&gt;

&lt;p&gt;&lt;a href="//images.ctfassets.net/1wryd5vd9xez/5PY1CQpWfMYKLJjCSIzPTG/1b7be5fb1fd4af79cdfdd8a5b7821e2e/super-cookie-ios-metro-bundler.png" class="article-body-image-wrapper"&gt;&lt;img src="//images.ctfassets.net/1wryd5vd9xez/5PY1CQpWfMYKLJjCSIzPTG/1b7be5fb1fd4af79cdfdd8a5b7821e2e/super-cookie-ios-metro-bundler.png" alt="super-cookie-ios-metro-bundler"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You might also have noticed that a new terminal window opened. This window is running the &lt;a href="https://facebook.github.io/metro/"&gt;Metro Bundler&lt;/a&gt;, a bundler created specifically for React Native that supports fast reloads and can handle thousands of modules at a time.&lt;/p&gt;

&lt;h3&gt;
  
  
  Start the app - Android
&lt;/h3&gt;

&lt;p&gt;The first step is to launch an AVD - Android Virtual Device - from the Android Studio. This virtual device will run our React Native application.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Open Android Studio&lt;/li&gt;
&lt;li&gt;On the welcome screen, click “Configure”&lt;/li&gt;
&lt;li&gt;Click “AVD Manager”&lt;/li&gt;
&lt;li&gt;In the modal that opens, find the device running API 27 that we created above.&lt;/li&gt;
&lt;li&gt;Click on the green Play button in the “Actions” column to launch the device.&lt;/li&gt;
&lt;li&gt;Click the power button on the top right next to the virtual device to boot it.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;In a minute or two, you should reach the Home screen of the Android device.&lt;/p&gt;

&lt;p&gt;&lt;a href="//images.ctfassets.net/1wryd5vd9xez/4YEC5bVvKBEzUp1EDZHr8V/c72631b37cb7820dd39dfd06fd5181aa/android-simulator.png" class="article-body-image-wrapper"&gt;&lt;img src="//images.ctfassets.net/1wryd5vd9xez/4YEC5bVvKBEzUp1EDZHr8V/c72631b37cb7820dd39dfd06fd5181aa/android-simulator.png" alt="android-simulator"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;With the simulator running, we can now launch our React Native application, which will attach itself to and run on the virtual device. Type this in your project directory and hit enter:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;react-native run-android
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;If it’s your first time running the app, it make take some time to install dependencies. That’s normal. Once you see &lt;code&gt;BUILD SUCCESSFUL&lt;/code&gt; and a clean process exit, the Super Cookie app should be running on the Android virtual device.&lt;/p&gt;

&lt;p&gt;&lt;a href="//images.ctfassets.net/1wryd5vd9xez/4x9majQIEqjsqAPIhY9mpp/0c54343dc7f11218007e25c96db8c820/super-cookie-android-metro-bundler.png" class="article-body-image-wrapper"&gt;&lt;img src="//images.ctfassets.net/1wryd5vd9xez/4x9majQIEqjsqAPIhY9mpp/0c54343dc7f11218007e25c96db8c820/super-cookie-android-metro-bundler.png" alt="super-cookie-android-metro-bundler"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Interacting with the app
&lt;/h2&gt;

&lt;p&gt;Now since we’ve done all of this hard work installing dependencies and configuring our environment, let’s reward ourselves with a cookie. And not just any cookie - a Super Cookie 🍪 .&lt;/p&gt;

&lt;p&gt;On either the running iOS or Android simulator app, click the green “Buy” button. This brings up a “Place your order” modal that contains example customer details, a price, and buttons that let the user choose how they want to pay: with a credit or with a digital wallet like Apple Pay or Google Pay.&lt;/p&gt;

&lt;p&gt;&lt;a href="//images.ctfassets.net/1wryd5vd9xez/2v8jVsS5WFRTKhTKgt6fxS/048e58cb38dc87954e8f99d17a7e0595/place-your-order.png" class="article-body-image-wrapper"&gt;&lt;img src="//images.ctfassets.net/1wryd5vd9xez/2v8jVsS5WFRTKhTKgt6fxS/048e58cb38dc87954e8f99d17a7e0595/place-your-order.png" alt="place-your-order"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Add a card on file
&lt;/h3&gt;

&lt;p&gt;We’re going to pay with a stored credit card, so click ‘Pay with card’. We don’t have any cards on file yet for this customer, so you’ll see a message and an ‘Add card’ button.&lt;/p&gt;

&lt;p&gt;&lt;a href="//images.ctfassets.net/1wryd5vd9xez/4zDJ6Q1tSZkIbKWgQKcELv/8533cca78ac99986e4f7422b4dd80ca0/my-saved-cards.png" class="article-body-image-wrapper"&gt;&lt;img src="//images.ctfassets.net/1wryd5vd9xez/4zDJ6Q1tSZkIbKWgQKcELv/8533cca78ac99986e4f7422b4dd80ca0/my-saved-cards.png" alt="my-saved-cards"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Next, enter the details of a valid credit card and click ‘Save 🍪’.&lt;/p&gt;

&lt;p&gt;&lt;a href="//images.ctfassets.net/1wryd5vd9xez/dGinKkZ23W5txFCZCRfZ8/da509fbab2870d0e6bb3c282b5874bb2/card-entry.gif" class="article-body-image-wrapper"&gt;&lt;img src="//images.ctfassets.net/1wryd5vd9xez/dGinKkZ23W5txFCZCRfZ8/da509fbab2870d0e6bb3c282b5874bb2/card-entry.gif" alt="card-entry"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you entered a valid card, you’ll see a confirmation alert message. Otherwise you will see an error about what was invalid. When confirmed, the card will be attached to the record of the customer you created earlier.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What happens behind the scenes?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  The Square IAP SDK generates a nonce that represents the credit card.&lt;/li&gt;
&lt;li&gt;  Our React Native application sends the nonce to our backend service running on Heroku.&lt;/li&gt;
&lt;li&gt;  The backend service calls the &lt;a href="https://developer.squareup.com/docs/api/connect/v2#endpoint-customers-createcustomercard"&gt;CreateCustomerCard&lt;/a&gt; endpoint of the Square API, passing the customer_id (from above) and the card nonce.&lt;/li&gt;
&lt;li&gt;  The information returned from the Square API is stored in our React app’s state so the card type, expiration date and last 4 digits can be shown later.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;Tip: See the &lt;a href="https://developer.squareup.com/docs/customers-api/cookbook/save-cards-on-file"&gt;Save Cards on File Cookbook&lt;/a&gt; to learn more about this flow.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Important&lt;/strong&gt;: Always ask for explicit permission before saving customer contact information or cards on file. This is required by Square.&lt;/p&gt;

&lt;h3&gt;
  
  
  Pay with a card on file
&lt;/h3&gt;

&lt;p&gt;Assuming you successfully saved a card, you should now be able to see it on the previous UI. You can identify the card by its type, expiration date and by the last 4 digits of the account number.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Note: The full card number cannot be shown because it was not returned from the CreateCustomerCard endpoint for privacy and security purposes.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="//images.ctfassets.net/1wryd5vd9xez/7wk5AP7pGenQQDbJYoScnm/168073063efe504f96dd75e928273b43/one-saved-card.png" class="article-body-image-wrapper"&gt;&lt;img src="//images.ctfassets.net/1wryd5vd9xez/7wk5AP7pGenQQDbJYoScnm/168073063efe504f96dd75e928273b43/one-saved-card.png" alt="one-saved-card"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Click the “Pay” button and then “Purchase” to confirm that you want to buy a Super Cookie for $1.&lt;/p&gt;

&lt;p&gt;&lt;a href="//images.ctfassets.net/1wryd5vd9xez/5EA9NioA9HXsCpAhReRnv/cbc0882bf1273e4a67a176bd8986be6c/square-purchase-cookie.gif" class="article-body-image-wrapper"&gt;&lt;img src="//images.ctfassets.net/1wryd5vd9xez/5EA9NioA9HXsCpAhReRnv/cbc0882bf1273e4a67a176bd8986be6c/square-purchase-cookie.gif" alt="square-purchase-cookie"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Warning: Unless you're using the sandbox, this will charge your card and incur a transaction fee of $0.33, only $0.67 will be deposited into your linked account.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What happens behind the scenes?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  The app sends the customer ID and chosen card on file ID from the previous step to the backend service.&lt;/li&gt;
&lt;li&gt;  The backend service creates a Payments API &lt;a href="https://developer.squareup.com/reference/square/payments-api/create-payment"&gt;Payment&lt;/a&gt; request with the provided fields.&lt;/li&gt;
&lt;li&gt;  The Square Payments API Charge endpoint processes the request and returns a &lt;a href="https://developer.squareup.com/reference/square/objects/Payment"&gt;Payment&lt;/a&gt; object that represents the captured payment, or an error message explaining what went wrong.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Verify transactions on the dashboard
&lt;/h3&gt;

&lt;p&gt;Now that the two payments have been processed, they will show up on your Square Dashboard. Visit the dashboard to confirm.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&amp;gt; &lt;a href="https://squareup.com/dashboard/sales/transactions"&gt;View the Transactions page on your Square Dashboard&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Dig into the code
&lt;/h2&gt;

&lt;p&gt;Now that you’ve seen how the flow works, let’s take a quick look at the code in the Super Cookie React Native application and see what’s happening.&lt;/p&gt;

&lt;p&gt;It will first help to understand all of the different layers of the stack.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;On the device:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Super Cookie React Native Application&lt;/li&gt;
&lt;li&gt;React Native Plugin for In-App Payments&lt;/li&gt;
&lt;li&gt;Square In-App Payments SDK&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Server-side:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;In-App Payments Server Quickstart (on Heroku)&lt;/li&gt;
&lt;li&gt;Square API&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All of the custom code used in this tutorial lives inside either the Super Cookie application or IAP Server Quickstart. The Square IAP SDK and React Native Plugin for IAP are officially maintained packages from Square.&lt;/p&gt;

&lt;h3&gt;
  
  
  React components
&lt;/h3&gt;

&lt;p&gt;The Super Cookie quickstart application has one main level component called &lt;code&gt;HomeScreen.js&lt;/code&gt;. This component decides what is rendered based on the state of the application.&lt;/p&gt;

&lt;p&gt;When the user first clicks ‘Buy’, a modal dialog appears from the bottom of the screen. The contents of the modal dialog change as the user walks through the flow. There are 3 views, backed by one component each:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;code&gt;OrderModal&lt;/code&gt;: Shows transaction details and buttons for payment methods&lt;/li&gt;
&lt;li&gt;  &lt;code&gt;CardsOnFileModal&lt;/code&gt;: Shows list of cards on file and a button to add a card&lt;/li&gt;
&lt;li&gt;  &lt;code&gt;PendingModal&lt;/code&gt;: Shows an activity indicator when a transaction is being processed&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The code for these components is in the &lt;code&gt;app/components&lt;/code&gt; folder of the quickstart application repository. The main job of these components is to build markup for the interface, apply CSS, and trigger events when certain areas of the screen are touched.&lt;/p&gt;

&lt;h3&gt;
  
  
  React Native IAP Plugin interfaces
&lt;/h3&gt;

&lt;p&gt;Interaction with the React Native plugin and underlying native SDKs is set up in the HomeScreen component.&lt;/p&gt;

&lt;p&gt;Up at the top of the files, we can see these interfaces being imported.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;SQIPCardEntry&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;SQIPApplePay&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;SQIPCore&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;SQIPGooglePay&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react-native-square-in-app-payments&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;SQIPCore is used to send your Square application ID down to the native layer. &lt;/p&gt;

&lt;p&gt;The &lt;code&gt;startCardEntryFlow()&lt;/code&gt; method of SQIPCardEntry is used to show the dialog for capturing credit card details. This dialog is created by the underlying native SDK so its fast and smooth. The method accepts 3 parameters - a configuration object, a success function, and a cancel function. The success function is passed a nonce that represents the card that the user entered, which can then be used to create a transaction or store a card on file.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;setIOSCardEntryTheme()&lt;/code&gt; is used to customize the look and feel of the dialog, and that’s how we added the 🍪 emoji to the “Save” button at the dialog. The &lt;code&gt;completeCardEntry()&lt;/code&gt; method closes the dialog.&lt;/p&gt;

&lt;p&gt;See the &lt;a href="https://github.com/square/in-app-payments-react-native-plugin/blob/master/docs/reference.md"&gt;React Native plugin’s technical reference&lt;/a&gt; for a full list of interfaces, features and customizations that your application can take advantage of.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;In this tutorial, we’ve shown how to take a Card on File payment within a React Native application, using the &lt;a href="https://squareup.com/us/en/developers/in-app-payments"&gt;Square In-App Payments SDK&lt;/a&gt; and the &lt;a href="https://github.com/square/in-app-payments-react-native-plugin"&gt;React Native Plugin for In-App Payments SDK.&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Even if you’re not selling super cookies, the instructions and example code here should help you integrate Square into your React Native application to create a great user experience for whatever you’re selling.&lt;/p&gt;

&lt;p&gt;Once you’re ready to do that, your next step will be to read the &lt;a href="https://github.com/square/in-app-payments-react-native-plugin/blob/master/docs/get-started.md"&gt;Getting Started with the React Native Plugin for In-App Payments SDK&lt;/a&gt; guide on GitHub, which shows you step-by-step how to add the plugin to an existing React Native app. Square Developer Evangelist &lt;a href="https://twitter.com/wootmoot"&gt;Richard Moot&lt;/a&gt; has even created a video to walk you through it step-by-step.&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/PoVuik5jqxI"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;If you want to keep up to date with the rest of our guides and tutorials, be sure to follow our &lt;a href="https://medium.com/square-corner-blog"&gt;blog&lt;/a&gt; &amp;amp; our &lt;a href="https://twitter.com/SquareDev"&gt;Twitter&lt;/a&gt; account, and sign up for our &lt;a href="https://developer.squareup.com/forums"&gt;forums&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Thanks for reading!&lt;/p&gt;

</description>
      <category>reactnative</category>
      <category>react</category>
      <category>payments</category>
      <category>mobile</category>
    </item>
    <item>
      <title>Online Payments with React + Square</title>
      <dc:creator>Richard Moot</dc:creator>
      <pubDate>Tue, 29 Oct 2019 22:40:35 +0000</pubDate>
      <link>https://forem.com/squaredev/online-payments-with-react-square-30ke</link>
      <guid>https://forem.com/squaredev/online-payments-with-react-square-30ke</guid>
      <description>&lt;p&gt;There are &lt;em&gt;a lot&lt;/em&gt; of ways to accept payments online. Wouldn’t it be nice to implement a single form that could accept as many payment methods as we want at a single time? Let’s take a look at implementing a custom payment form using &lt;a href="https://squareup.com/developers"&gt;Square&lt;/a&gt; and &lt;a href="https://reactjs.org/"&gt;React&lt;/a&gt;. This form will enable us to take credit cards online, &lt;em&gt;and&lt;/em&gt; give us support for Apple Pay, Google Pay, and Masterpass in a single payment form.&lt;/p&gt;

&lt;h3&gt;
  
  
  Things required to understand this post:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://reactjs.org/"&gt;React&lt;/a&gt; (simplified with &lt;a href="https://github.com/facebook/create-react-app"&gt;&lt;code&gt;create-react-app&lt;/code&gt;&lt;/a&gt;)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://developer.squareup.com/docs/payments/sqpaymentform/what-it-does"&gt;Square’s Payment Form&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Our final (payment) form:
&lt;/h3&gt;

&lt;p&gt;&lt;a href="//images.ctfassets.net/1wryd5vd9xez/2Gm1wvgVvahTcDXqElYvL3/d5fba6560fe9a9da935d79f966f325be/https___cdn-images-1.medium.com_max_2000_1_OX259-SlAPzFpWyuVlj6Mg.png" class="article-body-image-wrapper"&gt;&lt;img src="//images.ctfassets.net/1wryd5vd9xez/2Gm1wvgVvahTcDXqElYvL3/d5fba6560fe9a9da935d79f966f325be/https___cdn-images-1.medium.com_max_2000_1_OX259-SlAPzFpWyuVlj6Mg.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  React and Square’s Payment Form
&lt;/h2&gt;

&lt;p&gt;If you’re familiar with React, then you’re accustomed to passing along &lt;code&gt;props&lt;/code&gt; and controlling your component via its &lt;code&gt;state&lt;/code&gt;. Let’s focus on how to get a basic setup up and running with Square’s payment form controlled by a React component. We’ll also demonstrate how to dynamically load the &lt;a href="https://developer.squareup.com/docs/payment-form/payment-form-walkthrough"&gt;Square payment form script&lt;/a&gt; in case you want to simply insert the payment form component on a page. Dynamic loading the script is only relevant if you don’t want the script to only load on a checkout page (or wherever you’d like to take a payment).&lt;/p&gt;

&lt;p&gt;If you’re not acquainted with Square’s payment form, head over &lt;a href="https://developer.squareup.com/docs/payments/sqpaymentform/what-it-does"&gt;to the docs&lt;/a&gt; and get familiar. There are some templates, explanations, and guides on getting the form set up using basic HTML, CSS, and JavaScript.&lt;/p&gt;

&lt;p&gt;At a basic level, the payment form directly captures your customer’s card details directly on Square’s servers using an &lt;code&gt;&amp;lt;iframe&amp;gt;&lt;/code&gt;. The payment form facilitates the generation of these &lt;code&gt;&amp;lt;iframe&amp;gt;&lt;/code&gt; elements and provides an API for creating a &lt;a href="https://developer.squareup.com/docs/payments/sqpaymentform/how-it-works"&gt;nonce&lt;/a&gt; (a one-time-use token) to reference those details later (all without you knowing any sensitive information!).&lt;/p&gt;

&lt;p&gt;The main problem you hit with these &lt;code&gt;&amp;lt;iframe&amp;gt;&lt;/code&gt; elements replacing other elements in the &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Document_Object_Model/Introduction"&gt;DOM&lt;/a&gt; is that React usually likes to be in charge of managing all your DOM interactions. This requires doing a bit of extra setup on our components to be sure we render everything correctly, in the right order, and correctly handle different events generated by the Square payment form script.&lt;/p&gt;

&lt;h2&gt;
  
  
  Dynamically Load The Square Payment Form Script
&lt;/h2&gt;

&lt;p&gt;Our base component is where we’ll actually manage dynamically loading:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;”https://js.squareup.com/v2/paymentform”&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;into the &lt;code&gt;&amp;lt;head&amp;gt;&lt;/code&gt; of the DOM and trigger our child component to render. The child component will actually be responsible for assembling, formatting, and managing our payment form. This is done to ensure the script has loaded and we can pass the &lt;a href="https://developer.squareup.com/docs/api/paymentform#paymentform-overview"&gt;&lt;code&gt;SqPaymentForm&lt;/code&gt;&lt;/a&gt; object down to our child component.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Component&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;PaymentForm&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./components/PaymentForm&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nx"&gt;App&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;Component&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
    &lt;span class="k"&gt;super&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;loaded&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nx"&gt;componentWillMount&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;that&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;sqPaymentScript&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;createElement&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;script&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;sqPaymentScript&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;src&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://js.squareup.com/v2/paymentform&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nx"&gt;sqPaymentScript&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;type&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;text/javascript&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
    &lt;span class="nx"&gt;sqPaymentScript&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nx"&gt;sqPaymentScript&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onload&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;that&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setState&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
      &lt;span class="na"&gt;loaded&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
    &lt;span class="p"&gt;})};&lt;/span&gt;
    &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getElementsByTagName&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;head&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;appendChild&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;sqPaymentScript&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nx"&gt;render&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;loaded&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;PaymentForm&lt;/span&gt;
          &lt;span class="nx"&gt;paymentForm&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;SqPaymentForm&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;App&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;You can see we’re just using some vanilla JavaScript inside the lifecycle method &lt;code&gt;componentWillMount()&lt;/code&gt; to create a &lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt; element and set some attributes, and then making sure that we’re updating our React component’s state to &lt;code&gt;loaded&lt;/code&gt; once the script has actually loaded on the page. This will trigger React to re-render and return &lt;code&gt;true&lt;/code&gt; for &lt;code&gt;this.state.loaded&lt;/code&gt; inside our &lt;code&gt;render()&lt;/code&gt; method and allow our child component to render.&lt;/p&gt;

&lt;p&gt;The other notable part of our code is how we’re passing &lt;code&gt;SqPaymentForm&lt;/code&gt; via the &lt;code&gt;paymentForm&lt;/code&gt; prop. We are passing in the SqPaymentForm object that is attached to the window, so rendering the payment form and triggering submission is easier to manage.&lt;br&gt;
Full code example can also be found at &lt;a href="https://github.com/mootrichard/square-react-online-payments"&gt;https://github.com/mootrichard/square-react-online-payments&lt;/a&gt;&lt;/p&gt;


&lt;h2&gt;
  
  
  React Payment Form Component
&lt;/h2&gt;

&lt;p&gt;To keep things simple, we’re modifying existing templates found on &lt;a href="https://github.com/square/connect-api-examples/tree/master/templates/web-ui/payment-form/basic-digital-wallet"&gt;Square’s GitHub&lt;/a&gt;. For more info on customizing or setting up a Square payment form, check out our &lt;a href="https://developer.squareup.com/docs/payments/sqpaymentform/what-it-does"&gt;guides&lt;/a&gt;. We’ll focus more on the difference between those templates and wiring things into our React component.&lt;/p&gt;
&lt;h3&gt;
  
  
  Our render() Method
&lt;/h3&gt;


&lt;div class="highlight"&gt;&lt;pre class="highlight html"&gt;&lt;code&gt;  render(){
    return (
      &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;className=&lt;/span&gt;&lt;span class="s"&gt;"container"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"form-container"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"sq-walletbox"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;{{display:&lt;/span&gt; &lt;span class="err"&gt;(&lt;/span&gt;&lt;span class="na"&gt;this.state.applePay&lt;/span&gt;&lt;span class="err"&gt;)&lt;/span&gt; &lt;span class="err"&gt;?&lt;/span&gt; &lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="na"&gt;inherit&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="na"&gt;:&lt;/span&gt; &lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="na"&gt;none&lt;/span&gt;&lt;span class="err"&gt;'}}&lt;/span&gt;
                    &lt;span class="na"&gt;className=&lt;/span&gt;&lt;span class="s"&gt;"wallet-button"&lt;/span&gt;
                    &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"sq-apple-pay"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;{{display:&lt;/span&gt; &lt;span class="err"&gt;(&lt;/span&gt;&lt;span class="na"&gt;this.state.masterpass&lt;/span&gt;&lt;span class="err"&gt;)&lt;/span&gt; &lt;span class="err"&gt;?&lt;/span&gt; &lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="na"&gt;block&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="na"&gt;:&lt;/span&gt; &lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="na"&gt;none&lt;/span&gt;&lt;span class="err"&gt;'}}&lt;/span&gt;
                    &lt;span class="na"&gt;className=&lt;/span&gt;&lt;span class="s"&gt;"wallet-button"&lt;/span&gt;
                    &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"sq-masterpass"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;{{display:&lt;/span&gt; &lt;span class="err"&gt;(&lt;/span&gt;&lt;span class="na"&gt;this.state.googlePay&lt;/span&gt;&lt;span class="err"&gt;)&lt;/span&gt; &lt;span class="err"&gt;?&lt;/span&gt; &lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="na"&gt;inherit&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="na"&gt;:&lt;/span&gt; &lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="na"&gt;none&lt;/span&gt;&lt;span class="err"&gt;'}}&lt;/span&gt;
                    &lt;span class="na"&gt;className=&lt;/span&gt;&lt;span class="s"&gt;"wallet-button"&lt;/span&gt;
                    &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"sq-google-pay"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;hr&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

          &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"sq-ccbox"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;
              &lt;span class="nt"&gt;&amp;lt;span&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;{styles.leftCenter}&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Enter Card Info Below &lt;span class="nt"&gt;&amp;lt;/span&amp;gt;&lt;/span&gt;
              &lt;span class="nt"&gt;&amp;lt;span&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;{styles.blockRight}&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
                {this.state.cardBrand.toUpperCase()}
              &lt;span class="nt"&gt;&amp;lt;/span&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"cc-field-wrapper"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
              &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"sq-card-number"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
              &lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"hidden"&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"card-nonce"&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"nonce"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
              &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"sq-expiration-date"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
              &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"sq-cvv"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt;
              &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"name"&lt;/span&gt;
              &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;{styles.name}&lt;/span&gt;
              &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"text"&lt;/span&gt;
              &lt;span class="na"&gt;placeholder=&lt;/span&gt;&lt;span class="s"&gt;"Name"&lt;/span&gt;
            &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"sq-postal-code"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;className=&lt;/span&gt;&lt;span class="s"&gt;"button-credit-card"&lt;/span&gt;
                  &lt;span class="na"&gt;onClick=&lt;/span&gt;&lt;span class="s"&gt;{this.requestCardNonce}&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Pay&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;p&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;{styles.center}&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"error"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    )
  }
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;The key parts to note in the elements we have is the divs elements with the id’s: &lt;code&gt;sq-apple-pay&lt;/code&gt;, &lt;code&gt;sq-masterpass&lt;/code&gt;, &lt;code&gt;sq-google-pay&lt;/code&gt;, &lt;code&gt;sq-card-number&lt;/code&gt;, &lt;code&gt;sq-cvv&lt;/code&gt;, &lt;code&gt;sq-expiration-date&lt;/code&gt;, and &lt;code&gt;sq-postal-code&lt;/code&gt;. We transformed the examples to use divs for everything instead of form components, since these are all the fields that will be targeted by Square’s payment form script to be replaced with &lt;code&gt;&amp;lt;iframe&amp;gt;&lt;/code&gt; elements. Also, since we’re using React, we will have our own functions for controlling submission and triggering the request of a nonce from the payment form.&lt;/p&gt;
&lt;h3&gt;
  
  
  Digital Wallet Payments &amp;amp; Methods Supported
&lt;/h3&gt;

&lt;p&gt;To adjust what digital wallet options (&lt;em&gt;sometimes called mobile wallet options&lt;/em&gt;) you want to support, just provide different key-value pairs in your &lt;code&gt;SqPaymentForm&lt;/code&gt; configuration object (&lt;a href="https://developer.squareup.com/docs/payments/sqpaymentform/digitalwallet/intro"&gt;see more on that here&lt;/a&gt;). You should be able to see in the &lt;code&gt;render()&lt;/code&gt; method that we’re controlling the display of our mobile payment options using the component’s &lt;code&gt;state&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;callbacks&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;methodsSupported&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;methods&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;methods&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;googlePay&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
      &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setState&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
        &lt;span class="na"&gt;googlePay&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;methods&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;googlePay&lt;/span&gt;
      &lt;span class="p"&gt;})&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;methods&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;applePay&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
      &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setState&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
        &lt;span class="na"&gt;applePay&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;methods&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;applePay&lt;/span&gt;
      &lt;span class="p"&gt;})&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;methods&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;masterpass&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
      &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setState&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
        &lt;span class="na"&gt;masterpass&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;methods&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;masterpass&lt;/span&gt;
      &lt;span class="p"&gt;})&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;We are setting the state inside of the &lt;code&gt;methodsSupported()&lt;/code&gt; callback that the Square payment form has provided to us. Since each mobile wallet option is specific to the browser that a customer is visiting from, you need to conditionally render the buttons to match what should be available based on your customer’s browser or mobile device. We also have to make these separate conditionals since the payment form calls the &lt;code&gt;methodsSupport()&lt;/code&gt; function once for each method you’re choosing to support. Our example is trying to support Masterpass, Apple Pay, and Google Pay, so three calls will be made. It’s a little aggressive in our calls to &lt;code&gt;setState()&lt;/code&gt;, but only three calls, so no worries — just keep it in mind if you’re calling &lt;code&gt;setState()&lt;/code&gt; elsewhere, since every call will trigger a re-render of the component.&lt;/p&gt;

&lt;h3&gt;
  
  
  Linking &amp;amp; Controlling the Component
&lt;/h3&gt;

&lt;p&gt;The main takeaway is to use &lt;code&gt;state&lt;/code&gt; inside of the provided callback. Using &lt;code&gt;state&lt;/code&gt; in the component allows us to react (&lt;em&gt;so punny&lt;/em&gt;) to different events emitted by Square’s payment form script. You can learn more about all these events are &lt;a href="https://developer.squareup.com/docs/api/paymentform#_callbackfunctions_detail"&gt;in the docs&lt;/a&gt;. In our example, a key place for this tie-in would be the &lt;code&gt;inputEventReceived()&lt;/code&gt; callback since it’s called on every input event. In our example component, we update the brand of the card (in the top right corner) once it has been identified by the payment form.&lt;/p&gt;

&lt;h2&gt;
  
  
  Thoughts and Conclusions
&lt;/h2&gt;

&lt;p&gt;This is only one way of approaching implementing the Square payment form in React. Initially it seemed like a good idea to try passing in the config object as a prop, but that doesn’t work too well for configuring your callback functions, unless you’re comfortable overriding them before creating your &lt;code&gt;paymentForm&lt;/code&gt; object (this just &lt;em&gt;felt&lt;/em&gt; wrong).&lt;/p&gt;

&lt;p&gt;The main place I’ve seen developers trip up is usually on not disabling &lt;a href="https://developer.squareup.com/docs/api/paymentform#paymentform-configurationfields"&gt;&lt;code&gt;autoBuild&lt;/code&gt;&lt;/a&gt;. The &lt;code&gt;paymentform&lt;/code&gt; script is going to immediately look for elements with the provided element id’s on build, but the problem arises because React might not have rendered the elements to the DOM yet. It is better to control the build process by triggering it with a call to&lt;code&gt;.build()&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The implementation of the form in React is fairly straight forward (if you know React) and just requires understanding of the React lifecycle in relation to the &lt;code&gt;paymentform&lt;/code&gt; lifecycle.&lt;/p&gt;

&lt;p&gt;You can find a full example of this form over at: &lt;a href="https://github.com/mootrichard/square-react-online-payments"&gt;https://github.com/mootrichard/square-react-online-payments&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;If you liked this post on React + Square, but would like to see this refactored using &lt;a href="https://reactjs.org/docs/hooks-intro.html"&gt;React’s Hooks API&lt;/a&gt;, &lt;a href="https://twitter.com/@wootmoot"&gt;tweet at me&lt;/a&gt;, respond here on Medium, or bug me in &lt;a href="https://squ.re/slack"&gt;our Slack community&lt;/a&gt; and I’ll follow up with a post with how to refactor this example using the React Hooks API.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Want more? &lt;a href="https://www.workwithsquare.com/developer-newsletter.html?channel=Online%20Social&amp;amp;sqmethod=Blog"&gt;Sign up&lt;/a&gt; for our monthly developer newsletter or come hang out with us in the Square Dev &lt;a href="https://squ.re/slack"&gt;Slack channel&lt;/a&gt;! You can also follow us on Twitter at &lt;a href="https://twitter.com/@SquareDev"&gt;@SquareDev&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>react</category>
      <category>javascript</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Stop Using Servers to Handle Webhooks</title>
      <dc:creator>Richard Moot</dc:creator>
      <pubDate>Fri, 11 Oct 2019 20:24:58 +0000</pubDate>
      <link>https://forem.com/squaredev/stop-using-servers-to-handle-webhooks-5f7g</link>
      <guid>https://forem.com/squaredev/stop-using-servers-to-handle-webhooks-5f7g</guid>
      <description>&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/HkpFBZrWf-Y"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;Webhooks are increasingly becoming the main method to get real time data from different services. &lt;a href="https://developer.github.com/webhooks/"&gt;GitHub&lt;/a&gt;, &lt;a href="https://api.slack.com/custom-integrations/outgoing-webhooks"&gt;Slack&lt;/a&gt;, &lt;a href="https://sendgrid.com/docs/API_Reference/Webhooks/index.html"&gt;SendGrid&lt;/a&gt;, and even &lt;a href="https://developer.squareup.com/docs/api/connect/v1#webhooks-overview"&gt;Square &lt;/a&gt;use webhooks to let you see data or be notified of events happening on your account. Webhooks are awesome, since they are fairly easy to deal with and prevent developers from having to build some archaic polling system that ends up being fairly wasteful in terms of network requests made vs. actual useful data retrieved.&lt;/p&gt;

&lt;p&gt;When creating a service to process webhooks, you have a few choices available: you can extend our application to handle incoming data from a defined URL, you can create a microservice, or you can create a Function as a Service (FaaS) function for processing our webhooks. We’ll briefly go through each of those options and the possible tradeoffs, and then we’ll wrap up with an example implementation of a FaaS webhook handler for Square.&lt;/p&gt;

&lt;h3&gt;
  
  
  Extending your Application
&lt;/h3&gt;

&lt;p&gt;&lt;a href="//images.ctfassets.net/1wryd5vd9xez/5VcXdiIb30a0bOIQS1kF9p/7e4e18045f9ffdc104a35058db16c04b/https___cdn-images-1.medium.com_max_2000_1_zjx1zBv78bWs7GbrkTSn7g.gif" class="article-body-image-wrapper"&gt;&lt;img src="//images.ctfassets.net/1wryd5vd9xez/5VcXdiIb30a0bOIQS1kF9p/7e4e18045f9ffdc104a35058db16c04b/https___cdn-images-1.medium.com_max_2000_1_zjx1zBv78bWs7GbrkTSn7g.gif" alt="Source: [Giphy (CCTV Servers)](https://giphy.com/gifs/fj-cctv-servers-128kpIwiArqvUk)"&gt;&lt;/a&gt;&lt;em&gt;Source: &lt;a href="https://giphy.com/gifs/fj-cctv-servers-128kpIwiArqvUk"&gt;Giphy (CCTV Servers)&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Extending your application gives you the benefit of leveraging any helpers or other libraries you already have in your application. Your helpers (or other application tools) can assist with processing this incoming data and might make it easier to manage. Your application is likely continually running anyways, so there isn’t a problem with having it also handle listening for incoming data for your webhooks. However, this approach can be a drawback, since you might be extending your application to handle something that’s not a core functionality or shouldn’t really be coupled with it. How the extension works can really depend on how your own application is structured, but it might be best to separate how your webhooks are handled to something outside of your application.&lt;/p&gt;

&lt;h3&gt;
  
  
  Microservice
&lt;/h3&gt;

&lt;p&gt;&lt;a href="//images.ctfassets.net/1wryd5vd9xez/43EOEOB7R9fvWSUVMjAaOs/a5aa3e4d0c0c4528809f5ad842a9c74d/https___cdn-images-1.medium.com_max_2000_1_xGaCdZC3K2gGyivUHANzHQ.gif" class="article-body-image-wrapper"&gt;&lt;img src="//images.ctfassets.net/1wryd5vd9xez/43EOEOB7R9fvWSUVMjAaOs/a5aa3e4d0c0c4528809f5ad842a9c74d/https___cdn-images-1.medium.com_max_2000_1_xGaCdZC3K2gGyivUHANzHQ.gif" alt="Source: [Giphy (Computer Ants)](https://giphy.com/gifs/computer-ants-rthingsforants-I5xVaRw3WqYBG)"&gt;&lt;/a&gt;&lt;em&gt;Source: &lt;a href="https://giphy.com/gifs/computer-ants-rthingsforants-I5xVaRw3WqYBG"&gt;Giphy (Computer Ants)&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Meanwhile, a microservice approach might help you move a step away from your application and allow it to simply communicate or process this new data to be consumed by the application later. Unfortunately, we still have the drawback of scalability and provisioning, since we would still need to be continually listening for the new data being sent to the webhook handler. Although it’s entirely possible to estimate how much data might be coming into our webhook handler and provision accordingly, it’s still pretty likely to be a lot of downtime where it’s simply just waiting to service a request.&lt;/p&gt;

&lt;h3&gt;
  
  
  Function as a Service
&lt;/h3&gt;

&lt;p&gt;&lt;a href="//images.ctfassets.net/1wryd5vd9xez/5e8PvLimDWDPZORfdUqfY2/ced4b4de63afe4aeb73950a2fff03391/https___cdn-images-1.medium.com_max_2000_1_0Y0hKll2Fu0_RB6i9Uf9lw.gif" class="article-body-image-wrapper"&gt;&lt;img src="//images.ctfassets.net/1wryd5vd9xez/5e8PvLimDWDPZORfdUqfY2/ced4b4de63afe4aeb73950a2fff03391/https___cdn-images-1.medium.com_max_2000_1_0Y0hKll2Fu0_RB6i9Uf9lw.gif" alt="Source: [Giphy (Saturday Night Live GIF)](https://giphy.com/gifs/snl-ryan-gosling-3o7aD6igymCUmBOorm)"&gt;&lt;/a&gt;&lt;em&gt;Source: &lt;a href="https://giphy.com/gifs/snl-ryan-gosling-3o7aD6igymCUmBOorm"&gt;Giphy (Saturday Night Live GIF)&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;At this point I know it’s pretty obvious that I am going to advocate for all the wonderful benefits of using FaaS for processing webhooks, though I do acknowledge there are some pretty annoying tradeoffs. First the benefits. One advantage of using FaaS for processing webhook data is that it allows for nearly unlimited scalability, so you don’t have to worry about being over or under provisioned. Your function only runs when a new event occurs, so you could be saving infrastructure costs by not having to run a server continuously just for processing webhook data. On the other hand, the drawbacks around using FaaS are usually around maintainability, testing, and &lt;a href="https://hackernoon.com/im-afraid-you-re-thinking-about-aws-lambda-cold-starts-all-wrong-7d907f278a4f"&gt;cold starts&lt;/a&gt;. There are some &lt;a href="https://serverless.com/framework/"&gt;tools&lt;/a&gt; that help with maintaining versions of your functions, deploying functions, and &lt;a href="https://serverless.com/blog/keep-your-lambdas-warm/"&gt;keeping the functions warm&lt;/a&gt;. Since webhooks are not directly servicing users and most webhook providers are fairly forgiving about required response times, FaaS is really well suited for processing webhooks despite the issues around cold starts.&lt;/p&gt;

&lt;h3&gt;
  
  
  Working Example
&lt;/h3&gt;

&lt;p&gt;So this is all good in theory, but it’s better to show an example of how we could implement a webhook handler on a FaaS platform. This example will be on &lt;a href="https://cloud.google.com/"&gt;Google Cloud Platform&lt;/a&gt; using their &lt;a href="https://cloud.google.com/functions/"&gt;Google Cloud Functions&lt;/a&gt;, but the majority of what we cover would translate across platforms since we’re using JavaScript.&lt;/p&gt;

&lt;p&gt;For starters, we want to be sure to service the webhook request as quickly as possible since we don’t want it to timeout. If our webhook handler takes too long to service the request repeatedly and timeout, a lot of webhook systems will stop serving our webhook URL and assume that it is no longer working. Our goal is to minimize the amount of processing time before sending back our 200 response to be sure we can account for any &lt;a href="https://dzone.com/articles/aws-lambda-performance-and-cold-starts"&gt;cold start&lt;/a&gt; lag time our function may have.&lt;/p&gt;

&lt;p&gt;To make things easy and work a little faster, we’re just going to write the JSON response we get for our webhook into a JSON file and upload it to Google Cloud Storage. This will allow our webhook handler to quickly respond to the request and we can just periodically check this bucket for new events or even write another Google Cloud Function that processes the new JSON files.&lt;/p&gt;

&lt;p&gt;An easy way to get started if you’re completely new to FaaS is to use &lt;a href="https://serverless.com"&gt;Serverless&lt;/a&gt;. It is a tool that helps facilitate creating and deploying functions to cloud providers. You can use their &lt;a href="https://serverless.com/framework/docs/providers/google/guide/quick-start/"&gt;quick-start guide&lt;/a&gt; to get a template generated and they have guides on getting your credentials setup for each provider as well. Here, we’ll show what a slightly filled out Serverless template looks like for our webhook handler:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;fs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;fs&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Storage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@google-cloud/storage&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;BUCKET_NAME&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// This would actually have the name of our bucket&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;storage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Storage&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;projectId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// This should be your Google Cloud Project ID where you're deploying your function &amp;amp; have your bucket&lt;/span&gt;
  &lt;span class="na"&gt;keyFilename&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./keyfile.json&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nx"&gt;exports&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;webhook&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;fileName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`/tmp/&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;location_id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;_&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;entity_id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;_&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;now&lt;/span&gt;&lt;span class="p"&gt;()}&lt;/span&gt;&lt;span class="s2"&gt;.json`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="nx"&gt;fs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;writeFileSync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;fileName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="nx"&gt;storage&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;bucket&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;BUCKET_NAME&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;upload&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;fileName&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;then&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;success&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;fs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;unlink&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;fileName&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;success&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;send&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;catch&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;fs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;unlink&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;fileName&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;403&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="nx"&gt;exports&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;callback&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;callback&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Our example gives a simplified version of how our final webhook handler will be functioning. We’re stringifying our JSON, writing it to the &lt;code&gt;/tmp/&lt;/code&gt; directory using the &lt;code&gt;fs&lt;/code&gt; module. Then, we’re sending that right into Google Cloud Storage using their NodeSDK. Finally, we clean up the temporary JSON file we created locally and log our success before sending our &lt;code&gt;200&lt;/code&gt; response.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;use strict&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;dotenv&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;fs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;fs&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;crypto&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;crypto&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Storage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@google-cloud/storage&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;projectId&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;YOUR_PROJECT_ID&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;storage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Storage&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;projectId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;projectId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;keyFilename&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./keyfile.json&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;BUCKET_NAME&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;YOUR_BUCKET_NAME&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;REQUEST_URL&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://us-central1-YOUR_PROJECT_ID.cloudfunctions.net/webhook&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;isFromSquare&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;REQUEST_URL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;sigKey&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;hmac&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;crypto&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;createHmac&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;sha1&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;sigKey&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;hmac&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;update&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;REQUEST_URL&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;hash&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;hmac&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;digest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;base64&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;X-Square-Signature&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;hash&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;exports&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;webhook&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;isFromSquare&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;REQUEST_URL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;SIG_KEY&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;fileName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`/tmp/&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;location_id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;_&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;entity_id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;_&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;now&lt;/span&gt;&lt;span class="p"&gt;()}&lt;/span&gt;&lt;span class="s2"&gt;.json`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="nx"&gt;fs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;writeFileSync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;fileName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="nx"&gt;storage&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;bucket&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;BUCKET_NAME&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;upload&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;fileName&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;then&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;success&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;fs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;unlink&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;fileName&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;success&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;send&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
      &lt;span class="p"&gt;})&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;catch&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;fs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;unlink&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;fileName&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;403&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;401&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;send&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="nx"&gt;exports&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;callback&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;callback&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The above webhook handler shows how to handle events coming from our Square account. We’ve added in verification of the &lt;code&gt;X-Square-Signature&lt;/code&gt; header to validate it’s a payload coming from Square. It’s always worth being sure that a webhook service offers some way to verify the data being sent, since it’s possible for bad actors to interrupt or manipulate services by sending malicious data to your webhook handler.&lt;/p&gt;

&lt;p&gt;Verifying our headers here lets us be sure we’re not storing arbitrary payloads into our Google Cloud Storage bucket. From here, you can choose to create another function for processing the new data as it comes in with another Google Cloud Function, or you can simply just have your application periodically check this storage bucket for new events to process.&lt;/p&gt;

&lt;p&gt;For example, you could have it check if a refund is above a certain limit, monitor your inventory for an item that is getting too low, or look to see when a high value item has sold. You can find out more information about the events you can track using Square’s webhooks &lt;a href="https://docs.connect.squareup.com/api/connect/v1/#webhooks-overview"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I highly recommend giving &lt;a href="https://serverless.com/framework/docs/"&gt;Serverless&lt;/a&gt; a try and creating your own webhook handlers as a way to react to different events in your Square account. If you don’t already have a Square account, make sure to sign up at &lt;a href="https://squareup.com/developers"&gt;https://squareup.com/developers&lt;/a&gt;. Let us know how you’ve used FaaS or webhooks in the comments, we’d love to hear more!&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Want more? &lt;a href="https://www.workwithsquare.com/developer-newsletter.html?channel=Online%20Social&amp;amp;sqmethod=Blog"&gt;Signup&lt;/a&gt;&lt;/em&gt; &lt;em&gt;for our monthly developer newsletter.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>serverless</category>
      <category>webhooks</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Announcing Square’s New Python SDK</title>
      <dc:creator>Richard Moot</dc:creator>
      <pubDate>Fri, 11 Oct 2019 20:18:11 +0000</pubDate>
      <link>https://forem.com/squaredev/announcing-square-s-new-python-sdk-49pb</link>
      <guid>https://forem.com/squaredev/announcing-square-s-new-python-sdk-49pb</guid>
      <description>&lt;p&gt;We’re excited to announce the release of our new Python SDK. Run your business with Square APIs including Catalog, Customers, Employees, Inventory, Labor, Locations, Orders, and more.&lt;/p&gt;

&lt;p&gt;To install the Python SDK, just &lt;code&gt;pip install squareup&lt;/code&gt; from the command line. You can alternatively clone the SDK from GitHub and install it using &lt;code&gt;python setup.py install --user&lt;/code&gt;. Next, all you need to do is provide your access token and you’re ready to use Square APIs.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;square.client&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Client&lt;/span&gt;

&lt;span class="n"&gt;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Client&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;access_token&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;'SANDBOX_ACCESS_TOKEN'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;environment&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;'sandbox'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;api_locations&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;locations&lt;/span&gt;
&lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;api_locations&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;list_locations&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;One of the great features in the new Python SDK is that the &lt;code&gt;response&lt;/code&gt; object contains new rich information about both the request and response. These details can be used for control flow and debugging.&lt;/p&gt;

&lt;p&gt;Below are examples of checking the basic response status.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;result.is_success()
#=&amp;gt; true

result.is_error()
#=&amp;gt; false

result.errors
#=&amp;gt; []

result.reason_phrase
#=&amp;gt; OK

result.status_code
#=&amp;gt; 200
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;If you were previously using the &lt;code&gt;squareconnect&lt;/code&gt;  SDK, you might be wondering how &lt;code&gt;squareup&lt;/code&gt; compares. Let’s take a look! For example, let’s create the following customer along with their address:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;customer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s"&gt;"given_name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"Amelia"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;"family_name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"Earhart"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;"email_address"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"Amelia.Earhart@example.com"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;First, let’s look at how we used to create a customer with the legacy &lt;code&gt;squareconnect&lt;/code&gt; SDK:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;__future__&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;print_function&lt;/span&gt;

&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;squareconnect&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;squareconnect.rest&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ApiException&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;squareconnect.apis.customers_api&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;CustomersApi&lt;/span&gt;

&lt;span class="n"&gt;api_instance&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;CustomersApi&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;api_instance&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;api_client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;configuration&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;host&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"https://connect.squareupsandbox.com"&lt;/span&gt;
&lt;span class="n"&gt;api_instance&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;api_client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;configuration&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;access_token&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"SANDBOX_ACCESS_TOKEN"&lt;/span&gt;

&lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
   &lt;span class="c1"&gt;# ListLocations
&lt;/span&gt;   &lt;span class="n"&gt;api_response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;api_instance&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;create_customer&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
     &lt;span class="s"&gt;"given_name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"Amelia"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
     &lt;span class="s"&gt;"family_name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"Earhart"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
     &lt;span class="s"&gt;"email_address"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"Amelia.Earhart@example.com"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
   &lt;span class="p"&gt;})&lt;/span&gt;
   &lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;api_response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;customer&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;For comparison, let’s create the same customer with the new squareup SDK:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;square.client&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Client&lt;/span&gt;

&lt;span class="n"&gt;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Client&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;span class="n"&gt;access_token&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;'SANBOX_ACCESS_TOKEN'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="n"&gt;environment&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;'sandbox'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;api_customers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;customers&lt;/span&gt;
&lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;api_customers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;create_customer&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
 &lt;span class="s"&gt;"given_name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"Amelia"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="s"&gt;"family_name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"Earhart"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="s"&gt;"email_address"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"Amelia.Earhart@example.com"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"customer"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;That’s all there is to it!&lt;/p&gt;

&lt;p&gt;As you can see, the new &lt;code&gt;squareup&lt;/code&gt; Python SDK interface is much simpler and less verbose. The new SDK also ships with a ton of usability and debugging features.&lt;/p&gt;

&lt;p&gt;Give the &lt;code&gt;squareup&lt;/code&gt; Python SDK a try today by installing it with &lt;code&gt;pip install squareup&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;With the new &lt;code&gt;squareup&lt;/code&gt; SDK it’s easier than ever to use Square as a platform to run your business with Python. We can’t wait to see what you’ll build! If you have any questions or feedback, &lt;a href="https://squ.re/slack"&gt;drop by our developer community&lt;/a&gt;. We’d love to hear from you.&lt;/p&gt;

</description>
      <category>api</category>
      <category>python</category>
      <category>business</category>
      <category>payments</category>
    </item>
    <item>
      <title>Square In-App Payments SDK for React Native</title>
      <dc:creator>Richard Moot</dc:creator>
      <pubDate>Tue, 30 Apr 2019 22:40:07 +0000</pubDate>
      <link>https://forem.com/squaredev/square-in-app-payments-sdk-for-react-native-27o5</link>
      <guid>https://forem.com/squaredev/square-in-app-payments-sdk-for-react-native-27o5</guid>
      <description>&lt;p&gt;Since the release of our In-App Payments SDK, we’ve been getting a lot of requests for when this would be available for React Native. It is officially here! You can simply &lt;code&gt;npm install —save react-native-square-in-app-payments&lt;/code&gt; inside your React Native project and follow the setup guide over &lt;a href="https://github.com/square/in-app-payments-react-native-plugin/blob/master/docs/get-started.md"&gt;here&lt;/a&gt; to start accepting payments in your React Native app.&lt;/p&gt;

&lt;p&gt;If you’re not already familiar with the&lt;a href="https://medium.com/square-corner-blog/introducing-square-in-app-payments-sdk-1fc93b32814c"&gt; In-App Payments SDK&lt;/a&gt;, it enables developers to accept Square-powered payments from within their own mobile apps.&lt;/p&gt;

&lt;p&gt;Now, it would be too easy to say just install the SDK and move on, so we’ll dig into a React Native app that I built to show how this works.&lt;/p&gt;

&lt;p&gt;&lt;a href="//images.ctfassets.net/1wryd5vd9xez/28iYm4BTKHlHtUzHj3xk7u/c156837bef8288951c7b4576b4a2fc21/https___cdn-images-1.medium.com_max_2000_0_QrRbrkcWAMME8DWg" class="article-body-image-wrapper"&gt;&lt;img src="//images.ctfassets.net/1wryd5vd9xez/28iYm4BTKHlHtUzHj3xk7u/c156837bef8288951c7b4576b4a2fc21/https___cdn-images-1.medium.com_max_2000_0_QrRbrkcWAMME8DWg" alt="_Our Order Ahead React Native App for buying Square Legos and demoed at ShopTalk._"&gt;&lt;/a&gt;&lt;strong&gt;Our Order Ahead React Native App for buying Square Legos and demoed at ShopTalk.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Getting Your Developer Environment Setup
&lt;/h2&gt;

&lt;p&gt;Prerequisites:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://developer.android.com/studio"&gt;Android Studio&lt;/a&gt; (follow link to download and install)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://developer.apple.com/xcode/"&gt;Xcode&lt;/a&gt; (can be installed via App Store on macOS)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://squareup.com/us/en/developers"&gt;Square Account&lt;/a&gt; (sign-up here)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://facebook.github.io/react-native/docs/getting-started"&gt;React Native CLI&lt;/a&gt; (follow guide for “Building Projects with Native Code”)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To be clear, you only need either Android Studio or Xcode if you plan on having your app work on their respective platforms and want to use their simulators for development.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 1: Get React Native CLI installed and set-up
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt; react-native-cli
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Make sure to follow the&lt;a href="https://facebook.github.io/react-native/docs/getting-started"&gt; React Native&lt;/a&gt; setup guide for &lt;em&gt;“Building Projects with Native Code”&lt;/em&gt;. Using the &lt;code&gt;react-native-square-in-app-payments&lt;/code&gt; plugin requires the In-App Payments SDK, which is native code for iOS and Android. Also, part of following that guide has you install the React Native CLI (command seen above), which helps facilitate linking libraries and running the simulator while developing.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 2: Add In-App Payments React Native Plugin to your Project
&lt;/h2&gt;

&lt;p&gt;After you’ve setup React Native, you’ll want to follow the Square &lt;a href="https://github.com/square/in-app-payments-react-native-plugin/blob/master/docs/get-started.md"&gt;guide for adding In-App Payments into your React Native project&lt;/a&gt;. If you’re starting from scratch, you might want to take a look at the&lt;a href="https://github.com/square/in-app-payments-react-native-plugin/tree/master/react-native-in-app-payments-quickstart"&gt; quick-start example application&lt;/a&gt; that shows an example app for that allows a user to buy a cookie. You can also just download that example app and modify from there.&lt;/p&gt;

&lt;p&gt;&lt;a href="//images.ctfassets.net/1wryd5vd9xez/2eV6kGyfWhXWr6ahT7k2B8/c320ba23d3cb5acc36c5e7cad09ad576/https___cdn-images-1.medium.com_max_2400_0_EjKx-XdCp-zNW1dG" class="article-body-image-wrapper"&gt;&lt;img src="//images.ctfassets.net/1wryd5vd9xez/2eV6kGyfWhXWr6ahT7k2B8/c320ba23d3cb5acc36c5e7cad09ad576/https___cdn-images-1.medium.com_max_2400_0_EjKx-XdCp-zNW1dG" alt="*Quick-start App for React Native In-App Payments Plugin.*"&gt;&lt;/a&gt;&lt;strong&gt;Quick-start App for React Native In-App Payments Plugin.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Things to Understand for React Native Development with In-App Payments SDK
&lt;/h2&gt;

&lt;h3&gt;
  
  
  React Native Interfaces for the In-App Payments SDK
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;SQIPCore&lt;/strong&gt; — Used to initialize the In-App Payments SDK in your React Native application.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;SQIPCardEntry&lt;/strong&gt; — Handles the standard credit card form capture. It is worth noting that if you’re wanting to store a&lt;a href="https://docs.connect.squareup.com/payments/transactions/cookbook/save-cards-on-file"&gt; Card on File&lt;/a&gt; for your user, then you’d want to only use this interface since you cannot store card details using digital wallets.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;SQIPApplePay&lt;/strong&gt; — Although fairly straightforward in the name, this interface is used for handling Apple Pay flow.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;SQIPGooglePay&lt;/strong&gt; — Same thing as the Apply Pay interface, but for handling Google Pay.&lt;/p&gt;

&lt;p&gt;Each interface has some methods for initiating the flow, handling errors or the user closing the form, and completing authorization to get a nonce (a one-time use token). You are still required to have a backend implementation to use the nonce for either &lt;a href="https://docs.connect.squareup.com/more-apis/customers/cookbook/save-cards-on-file"&gt;storing a card on a customer profile&lt;/a&gt;, or&lt;a href="https://docs.connect.squareup.com/payments/transactions/overview"&gt; processing a transaction&lt;/a&gt;. You can find more on how this flow works in the &lt;a href="https://docs.connect.squareup.com/payments/in-app-payments-sdk/how-it-works"&gt;Square documentation&lt;/a&gt; on.&lt;/p&gt;

&lt;h2&gt;
  
  
  Routing / Navigation
&lt;/h2&gt;

&lt;p&gt;Although this can vary depending on which library you’re using, its worth explaining the one we use in our example. &lt;a href="https://reactnavigation.org/"&gt;React Navigation&lt;/a&gt; is a commonly used library for routing and navigation in React Native apps.&lt;/p&gt;

&lt;p&gt;You can add it by running:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; — save react-navigation react-native-gesture-handler
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;react-native &lt;span class="nb"&gt;link &lt;/span&gt;react-native-gesture-handler
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The basic premise of the navigation library is to create a central hub at the root of your React Native app that can control which “screen” should be displayed at any given time. There are a few different types of navigation you can have with this library, but we’re just sticking with the &lt;a href="https://reactnavigation.org/docs/en/hello-react-navigation.html"&gt;stack navigator&lt;/a&gt;. It works exactly like a stack data structure that has each screen go “on” to the stack and when a user goes back it just pops them off the stack.&lt;/p&gt;

&lt;h2&gt;
  
  
  An Order Ahead Example Application
&lt;/h2&gt;

&lt;p&gt;In order &lt;em&gt;(so punny)&lt;/em&gt; to show what can be done with the React Native In-App Payments Plugin, we created an app to let people pick their own Square Lego person at conferences and also demonstrate how the new &lt;a href="https://medium.com/p/orders-push-public-beta-25bda7c31521"&gt;Orders Push Beta&lt;/a&gt; can push that into a Square Point of Sale (POS).&lt;/p&gt;

&lt;p&gt;At the root of our app, we use the &lt;code&gt;createAppContainer&lt;/code&gt; and &lt;code&gt;createStackNavigator&lt;/code&gt; from &lt;a href="https://reactnavigation.org/"&gt;React Navigation&lt;/a&gt; for wrapping our React app and handling all of our routing and navigation. This is also where we will initialize the In-App Payments SDK using &lt;code&gt;SQIPCore&lt;/code&gt; in the &lt;code&gt;componentDidMount()&lt;/code&gt; lifecycle method.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;Component&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
 &lt;span class="nx"&gt;createStackNavigator&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="nx"&gt;createAppContainer&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react-navigation&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;HomeScreen&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./screens/Home&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;CheckoutScreen&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./screens/Checkout&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
 &lt;span class="nx"&gt;SQIPCore&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react-native-square-in-app-payments&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;AppNavigator&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;createStackNavigator&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
 &lt;span class="na"&gt;Home&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;HomeScreen&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="na"&gt;Checkout&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;CheckoutScreen&lt;/span&gt;
&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
 &lt;span class="na"&gt;initialRouteName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Home&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;AppContainer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;createAppContainer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;AppNavigator&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nx"&gt;App&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;Component&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
 &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nx"&gt;componentDidMount&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;SQIPCore&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setSquareApplicationId&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;YOUR_APP_ID&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
 &lt;span class="p"&gt;}&lt;/span&gt;
 &lt;span class="nx"&gt;render&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;AppContainer&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
 &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We kept this really simple by having only two screens. The main screen displays all of our products (in this case, lego people) and the other screen is our checkout.&lt;/p&gt;

&lt;p&gt;A lot of the code in the application is dedicated to styling the components, which could be its own blog post. The key part to take away from this is how to interact with the In-App Payments SDK.&lt;/p&gt;

&lt;p&gt;Next, we’ll dig into our Checkout screen and look inside our &lt;code&gt;componentWillMount()&lt;/code&gt; method of our CheckoutScreen component. This is where we set our &lt;a href="https://github.com/square/in-app-payments-react-native-plugin/blob/master/docs/get-started.md#ios"&gt;iOS card entry theme&lt;/a&gt; (&lt;a href="https://docs.connect.squareup.com/payments/in-app-payments-sdk/cookbook/customize-payment-form"&gt;you need to set these in a styles.xml in Android&lt;/a&gt;).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nx"&gt;componentWillMount&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
   &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Platform&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;OS&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ios&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
     &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;SQIPCardEntry&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setIOSCardEntryTheme&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
       &lt;span class="na"&gt;saveButtonFont&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
         &lt;span class="na"&gt;size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;25&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
       &lt;span class="p"&gt;},&lt;/span&gt;
       &lt;span class="na"&gt;saveButtonTitle&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Order 💳 &lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
       &lt;span class="na"&gt;keyboardAppearance&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Light&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
       &lt;span class="na"&gt;saveButtonTextColor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
         &lt;span class="na"&gt;r&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;255&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
         &lt;span class="na"&gt;g&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
         &lt;span class="na"&gt;b&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;125&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
         &lt;span class="na"&gt;a&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;0.5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
       &lt;span class="p"&gt;},&lt;/span&gt;
     &lt;span class="p"&gt;});&lt;/span&gt;
   &lt;span class="p"&gt;}&lt;/span&gt;
 &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then, we have to create a few lifecycle methods for handling events after starting the credit card form flow and handle getting our nonce for processing the card details.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;onCardEntryComplete&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="c1"&gt;// Update UI to notify user that the payment flow is completed&lt;/span&gt;
 &lt;span class="p"&gt;}&lt;/span&gt;

 &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nx"&gt;onCardNonceRequestSuccess&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;cardDetails&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
     &lt;span class="c1"&gt;// take payment with the card details&lt;/span&gt;
     &lt;span class="c1"&gt;// await chargeCard(cardDetails);&lt;/span&gt;
     &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;YOUR_BACKEND_URL&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
       &lt;span class="na"&gt;method&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;POST&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
       &lt;span class="na"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
         &lt;span class="na"&gt;Accept&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;application/json&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
         &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Content-Type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;application/json&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
       &lt;span class="p"&gt;},&lt;/span&gt;
       &lt;span class="na"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
         &lt;span class="na"&gt;nonce&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;cardDetails&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;nonce&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
         &lt;span class="na"&gt;item&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;cartItem&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;item_data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
         &lt;span class="na"&gt;customer&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;customer&lt;/span&gt;
       &lt;span class="p"&gt;})&lt;/span&gt;
     &lt;span class="p"&gt;}).&lt;/span&gt;&lt;span class="nx"&gt;then&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;resp&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
       &lt;span class="c1"&gt;// Handle resp&lt;/span&gt;
     &lt;span class="p"&gt;})&lt;/span&gt;

     &lt;span class="c1"&gt;// payment finished successfully&lt;/span&gt;
     &lt;span class="c1"&gt;// you must call this method to close card entry&lt;/span&gt;
     &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;cardDetails&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
     &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;SQIPCardEntry&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;completeCardEntry&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
       &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onCardEntryComplete&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
     &lt;span class="p"&gt;);&lt;/span&gt;
   &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ex&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
     &lt;span class="c1"&gt;// payment failed to complete due to error&lt;/span&gt;
     &lt;span class="c1"&gt;// notify card entry to show processing error&lt;/span&gt;
     &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;SQIPCardEntry&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;showCardNonceProcessingError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ex&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
   &lt;span class="p"&gt;}&lt;/span&gt;
 &lt;span class="p"&gt;}&lt;/span&gt;

 &lt;span class="nx"&gt;onCardEntryCancel&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="c1"&gt;// Handle the cancel callback&lt;/span&gt;
 &lt;span class="p"&gt;}&lt;/span&gt;
 &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nx"&gt;onStartCardEntry&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;cardEntryConfig&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
     &lt;span class="na"&gt;collectPostalCode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
   &lt;span class="p"&gt;};&lt;/span&gt;
   &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;SQIPCardEntry&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;startCardEntryFlow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
     &lt;span class="nx"&gt;cardEntryConfig&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
     &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onCardNonceRequestSuccess&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
     &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onCardEntryCancel&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
   &lt;span class="p"&gt;);&lt;/span&gt;
 &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To break this down, at our base method for starting the card flow is the &lt;code&gt;onStartCardEntry()&lt;/code&gt; method. We then have our &lt;code&gt;onCardNonceRequestSuccess&lt;/code&gt;, &lt;code&gt;onCardEntryCancel&lt;/code&gt;, and &lt;code&gt;onCardEntryComplete&lt;/code&gt; for handling the different events in our flow.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;onCardNonceRequestSuccess&lt;/code&gt; — handles when we’ve successfully requested a nonce using the In-App Payments SDK, so we can send it to our backend for additional processing.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;onCardEntryCancel&lt;/code&gt; — should be used to handle if a user closes out the card entry form before filling it out and triggering a card nonce response.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;onCardEntryComplete&lt;/code&gt; — is used to close out the form, but can also be used for handling any state updates to your application.&lt;/p&gt;

&lt;p&gt;&lt;a href="//images.ctfassets.net/1wryd5vd9xez/2owUvWGUichot39kd9a7ge/6e828cb619df6bbf19e2cd8798a144dd/https___cdn-images-1.medium.com_max_2000_1_prFcvMdGncCv4nS7QP8Yyg.gif" class="article-body-image-wrapper"&gt;&lt;img src="//images.ctfassets.net/1wryd5vd9xez/2owUvWGUichot39kd9a7ge/6e828cb619df6bbf19e2cd8798a144dd/https___cdn-images-1.medium.com_max_2000_1_prFcvMdGncCv4nS7QP8Yyg.gif" alt="The React Native Order Ahead App in action."&gt;&lt;/a&gt;&lt;em&gt;The React Native Order Ahead App in action.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Now, as far as our front-end is concerned(in the case our React Native App), that is all we really need for processing a payment. The app should only be concerned with using the In-App Payments SDK for securely capturing those card details, getting the nonce, passing it to the backend for further processing, then &lt;em&gt;react&lt;/em&gt;-ing &lt;em&gt;(again, so punny)&lt;/em&gt; to the results of what was processed.&lt;/p&gt;

&lt;p&gt;Also, to be clear, this is only &lt;em&gt;one&lt;/em&gt; way to implement the &lt;a href="https://github.com/square/in-app-payments-react-native-plugin"&gt;In-App Payments SDK Plugin&lt;/a&gt; in your React Native application. You could certainly also add in digital wallet support for Google Pay and/or Apple Pay, this was just focused on demonstrating the card flow.&lt;/p&gt;

&lt;p&gt;The rest of our capabilities for creating and pushing orders into a Square POS, &lt;a href="https://docs.connect.squareup.com/payments/transactions/overview"&gt;charging a transaction&lt;/a&gt; (taking a payment), and/or &lt;a href="https://docs.connect.squareup.com/payments/transactions/cookbook/save-cards-on-file"&gt;storing customer card details&lt;/a&gt; will happen in your backend. You can read more about our &lt;a href="https://medium.com/p/orders-push-public-beta-25bda7c31521"&gt;Orders Push Beta&lt;/a&gt; and our &lt;a href="https://docs.connect.squareup.com/payments/transactions/cookbook"&gt;Card on File transactions&lt;/a&gt; by following the links if you’re interested in building your own app for that, or &lt;a href="http://squ.re/slack"&gt;join our Slack community&lt;/a&gt; and ask for help.&lt;/p&gt;

&lt;p&gt;If you’re plan on building something on Square using our React Native In-App Payments Plugin and want to write about it &lt;em&gt;(or anything else Square related)&lt;/em&gt;, please hop into our &lt;a href="http://squ.re/slack"&gt;Slack community&lt;/a&gt; and let us know &lt;em&gt;(you can join just to say hi too)&lt;/em&gt;, we’re always happy to chat about whatever you’re working on.&lt;/p&gt;

&lt;p&gt;If you want to keep up to date with the rest of our content, be sure to follow this &lt;a href="https://medium.com/square-corner-blog"&gt;blog&lt;/a&gt; &amp;amp; our &lt;a href="https://twitter.com/SquareDev"&gt;Twitter&lt;/a&gt; account, and sign up for our &lt;a href="https://www.workwithsquare.com/developer-newsletter.html?channel=Online%20Social&amp;amp;sqmethod=Blog"&gt;developer newsletter&lt;/a&gt;! We also have a &lt;a href="https://squ.re/slack"&gt;Slack&lt;/a&gt; community for connecting with and talking to other developers implementing Square APIs.&lt;/p&gt;

</description>
      <category>reactnative</category>
      <category>mobile</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Making the Invisible Visible: A Look at Building Tools for Square Developers</title>
      <dc:creator>Richard Moot</dc:creator>
      <pubDate>Tue, 15 Jan 2019 17:47:18 +0000</pubDate>
      <link>https://forem.com/squaredev/making-the-invisible-visible-a-look-at-building-tools-for-square-developers-506</link>
      <guid>https://forem.com/squaredev/making-the-invisible-visible-a-look-at-building-tools-for-square-developers-506</guid>
      <description>&lt;p&gt;&lt;em&gt;Written by &lt;strong&gt;Lindy Zeng&lt;/strong&gt; on **&lt;a href="https://medium.com/square-corner-blog/making-the-invisible-visible-a-look-at-building-tools-for-square-developers-bae30a212950"&gt;Square Corner Blog&lt;/a&gt;&lt;/em&gt;**&lt;/p&gt;

&lt;p&gt;At Square, the Developers team exposes APIs that allow third-party developers to build custom business-processing solutions. On October 18, we announced to developers using our APIs that webhooks would now support retries. If a webhook cannot be delivered, our system will now be able to retry multiple times until a successful delivery.&lt;/p&gt;

&lt;p&gt;Square’s webhook delivery system is a service I’ll refer to as Webhooks. Improving Webhooks’ reliability was a project I had the opportunity to dive into the first week I started at Square as a new college graduate. From the beginning, we wanted our Webhooks upgrades to require no change on the part of our external developers, in stark contrast to the amount of research, planning and work that went into the project. In fact, the announcement we sent out assured developers that they “should not need to make any changes to support webhooks with retries.” My manager remarked that it was “the most invisible change ever” — and that is how it should be. The focus of our team is to enable developers to easily integrate with Square’s APIs and provide them with a reliable and simple-to-use experience. Perhaps it was my manager’s remark about our “invisible” project that inspired me to share some insight into not only our webhooks reliability project, but also some of our “visibility” practices here at Square.&lt;/p&gt;

&lt;p&gt;Read more on the &lt;a href="https://medium.com/square-corner-blog/making-the-invisible-visible-a-look-at-building-tools-for-square-developers-bae30a212950"&gt;Square Corner Blog&lt;/a&gt;&lt;/p&gt;

</description>
      <category>api</category>
      <category>serverless</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Square Reader SDK for React Native</title>
      <dc:creator>Richard Moot</dc:creator>
      <pubDate>Mon, 01 Oct 2018 18:43:31 +0000</pubDate>
      <link>https://forem.com/squaredev/square-reader-sdk-for-react-native-be0</link>
      <guid>https://forem.com/squaredev/square-reader-sdk-for-react-native-be0</guid>
      <description>&lt;p&gt;In the beginning of August, we announced the release of our &lt;a href="https://squareup.com/developers/reader-sdk"&gt;Reader SDK&lt;/a&gt; for iOS and Android to allow developers to build their own custom in-person payment experiences.&lt;/p&gt;

&lt;p&gt;Now, we’ve taken that ground-breaking SDK and wrapped it up in a React Native plugin that you can use in your own React Native project. So whether you’re a cross-platform guru looking to creating the ultimate in-person payment experience or just a React hacker looking to try out something new, you can now &lt;code&gt;npm install react-native-square-reader-sdk&lt;/code&gt; in your project &lt;em&gt;(just be sure to read our &lt;a href="https://github.com/square/react-native-square-reader-sdk/tree/master/reader-sdk-react-native-quickstart"&gt;quick start guide&lt;/a&gt; on getting the native dependencies installed)&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;We released a React Native plugin for our Reader SDK to allow developers to more easily and rapidly create new in-person payment applications. We know that iOS and Android developers can just as easily use the native SDK, but here we can reach &lt;em&gt;any&lt;/em&gt; JavaScript developer. We even have a &lt;a href="https://github.com/square/react-native-square-reader-sdk/tree/master/reader-sdk-react-native-quickstart"&gt;quick-start&lt;/a&gt; application that can give you a starting place for creating your very own point of sale, kiosk, or custom in-person payment experience. It’s as easy as tweaking some JSX, or creating your own components, and then connecting them to the interfaces we’ve provided.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;It’s possible to get an app up and running locally within five minutes.&lt;/strong&gt; I was even able to get a custom keypad, entering arbitrary values, in an hour (granted, I was a little rusty on my React Native when I was trying it). I’m also very much not a mobile developer, and having the application running on an iPhone and Android simulator simultaneously was so powerful for having a responsive feedback loop when developing. You can enable live reloading on each device and have all your changes reflected immediately upon saving.&lt;/p&gt;

&lt;p&gt;&lt;a href="//downloads.ctfassets.net/1wryd5vd9xez/5PxRRCwiNi6j1MCgJxHgKz/3fa7de2d3a44061d8b14b0850f260c62/https___cdn-images-1.medium.com_max_3840_1_Mw1dOzMhFLZn-FMsMQdLKg.gif" class="article-body-image-wrapper"&gt;&lt;img src="//downloads.ctfassets.net/1wryd5vd9xez/5PxRRCwiNi6j1MCgJxHgKz/3fa7de2d3a44061d8b14b0850f260c62/https___cdn-images-1.medium.com_max_3840_1_Mw1dOzMhFLZn-FMsMQdLKg.gif" alt="Live reloading a React Native Square Reader app in iOS and Android simultaneously!"&gt;&lt;/a&gt;&lt;em&gt;Live reloading a React Native Square Reader app in iOS and Android simultaneously!&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Let’s say you take our quick-start app out for a spin and are looking to just get your feet wet in making your own point of sale app.&lt;/p&gt;

&lt;p&gt;You can open up &lt;code&gt;[reader-sdk-react-native-quickstart/app/screens/CheckoutScreen.js&lt;/code&gt;](&lt;a href="https://github.com/square/react-native-square-reader-sdk/blob/master/reader-sdk-react-native-quickstart/app/screens/CheckoutScreen.js"&gt;https://github.com/square/react-native-square-reader-sdk/blob/master/reader-sdk-react-native-quickstart/app/screens/CheckoutScreen.js&lt;/a&gt;) and start modifying some of the buttons to adjust the amounts that you’re charging.&lt;/p&gt;

&lt;p&gt;Then add some additional buttons that look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;KeyPadButton&lt;/span&gt;
  &lt;span class="na"&gt;title=&lt;/span&gt;&lt;span class="s"&gt;"1"&lt;/span&gt;
  &lt;span class="na"&gt;onPress=&lt;/span&gt;&lt;span class="s"&gt;{()&lt;/span&gt; &lt;span class="err"&gt;=&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt; this.addValue(1)}
  primary
/&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The above is just a modified version of the provided &lt;a href="https://github.com/square/react-native-square-reader-sdk/blob/master/reader-sdk-react-native-quickstart/app/components/CustomButton.js"&gt;&lt;code&gt;CustomButton&lt;/code&gt;&lt;/a&gt; component to look a little different. We then add in our own function for adding a value:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;addValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setState&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;prevState&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;currentValue&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[...&lt;/span&gt;&lt;span class="nx"&gt;prevState&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;currentValue&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;and add a &lt;code&gt;currentValue&lt;/code&gt; array to the state of our &lt;code&gt;CheckoutScreen&lt;/code&gt; component:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nx"&gt;CheckoutScreen&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;Component&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;super&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;currentValue&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;You now have your own keypad to enter amounts to charge.&lt;/p&gt;

&lt;p&gt;&lt;a href="//images.ctfassets.net/1wryd5vd9xez/7aYw4nYAU3eJoFfI9IEa8w/41f85e0e5b181a0066c736c8db7bd2f2/https___cdn-images-1.medium.com_max_2000_1_CfyhDYh7qfcoE0K2KoHJnA.gif" class="article-body-image-wrapper"&gt;&lt;img src="//images.ctfassets.net/1wryd5vd9xez/7aYw4nYAU3eJoFfI9IEa8w/41f85e0e5b181a0066c736c8db7bd2f2/https___cdn-images-1.medium.com_max_2000_1_CfyhDYh7qfcoE0K2KoHJnA.gif" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here you can see what a final custom keypad looks like. We have buttons for every number, we can clear values, and we’re just storing the current value we want to charge in the main &lt;code&gt;CheckoutScreen&lt;/code&gt; component. The state even persists if we back out of the charge.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;It’s so easy to modify these interfaces!&lt;/strong&gt; You can change the text, add in some additional state, or create custom functions to tailor the application to do whatever you need. The key benefit here is that you can then deploy this to iOS and Android using the same core components.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;This is really just scratching the surface&lt;/strong&gt;, since these are only simple modifications to the &lt;a href="https://github.com/square/react-native-square-reader-sdk/tree/master/reader-sdk-react-native-quickstart"&gt;quick-start application&lt;/a&gt;. We are looking forward to seeing what the React Native community creates with this new plugin. Whether you want to make the next self-ordering kiosk, create a whole new point of sale for your favorite industry, or just be the first to build a React Native application with it — we want to hear about it!&lt;/p&gt;

&lt;p&gt;Tweet us at &lt;a href="https://twitter.com/@SquareDev"&gt;@SquareDev&lt;/a&gt; or join us in our slack community over at &lt;a href="https://squ.re/slack"&gt;https://squ.re/slack&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Also, if you just want to contribute to the &lt;a href="https://github.com/square/react-native-square-reader-sdk/"&gt;open-source project on GitHub&lt;/a&gt;, feel free to give it a fork and submit a PR to us!&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>react</category>
      <category>reactnative</category>
      <category>payments</category>
    </item>
    <item>
      <title>Square API Versioning for Connect v2</title>
      <dc:creator>Richard Moot</dc:creator>
      <pubDate>Fri, 13 Jul 2018 20:04:32 +0000</pubDate>
      <link>https://forem.com/squaredev/square-api-versioning-for-connect-v2-4l91</link>
      <guid>https://forem.com/squaredev/square-api-versioning-for-connect-v2-4l91</guid>
      <description>&lt;p&gt;We’ve got an exciting update coming for our Connect v2 developers! We have released &lt;a href="https://developer.squareup.com/docs/changelog/overview"&gt;versioning for all Connect v2 endpoints&lt;/a&gt; for Square’s APIs. This will allow us to deliver more functionality and features faster than ever before. No need to worry though, our APIs will remain backwards-compatible and will allow you to upgrade when you’re most comfortable. This means you can safely continue using the Square APIs you already love, but allows us to bring you new or improved features without breaking your code.&lt;/p&gt;

&lt;p&gt;&lt;a href="//images.ctfassets.net/1wryd5vd9xez/26WYajTAeTr98rly97fON0/6cb93860b98b12021b930c007dd7dcf0/https___cdn-images-1.medium.com_max_3840_1_BkvbW9_QdvWTI6s-Elvx9Q.png" class="article-body-image-wrapper"&gt;&lt;img src="//images.ctfassets.net/1wryd5vd9xez/26WYajTAeTr98rly97fON0/6cb93860b98b12021b930c007dd7dcf0/https___cdn-images-1.medium.com_max_3840_1_BkvbW9_QdvWTI6s-Elvx9Q.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  What does this mean for me?
&lt;/h3&gt;

&lt;p&gt;If you don’t want to upgrade your integration or use the latest and greatest, then it means you can stick with the version of the API that you’re currently using. If you &lt;em&gt;do&lt;/em&gt; want to upgrade, you can easily test things out by setting your &lt;code&gt;Square-Version&lt;/code&gt; header to your desired version.&lt;/p&gt;

&lt;h3&gt;
  
  
  How do I know what version I am on?
&lt;/h3&gt;

&lt;p&gt;You can always check your &lt;a href="https://connect.squareup.com/apps"&gt;developer dashboard&lt;/a&gt;. You can also check the response from calling an endpoint and see what your &lt;code&gt;Square-Version&lt;/code&gt; header is set to. When you create your app, your default version (the version currently set for your application) is set to the most recent version of the API. This means that if you don’t explicitly specify the version of the API to use when making requests to Connect v2 endpoints, your default version will be used. So if the most recent version of the API is &lt;code&gt;2018-07–12&lt;/code&gt; and you created your app on &lt;code&gt;2018-07–15&lt;/code&gt;, then you’ll be set to version &lt;code&gt;2018-07–12&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why are you doing this?
&lt;/h3&gt;

&lt;p&gt;This lets us deliver more functionality to developers while preventing negative impacts that upgrading APIs can have on developers who have already implementations.&lt;/p&gt;

&lt;h3&gt;
  
  
  Do I need to upgrade my SDK?
&lt;/h3&gt;

&lt;p&gt;If you are upgrading your API version, you may upgrade the SDK version when you are ready. Each version of the SDK is “pinned” to a version of the API, so you never need to worry about the SDK accessing the “wrong” version, even if you change your default. As new versions of the API are released, so are new versions of our SDKs. The SDK version will follow the format &lt;code&gt;2.20180712.0&lt;/code&gt; to correspond to version &lt;code&gt;2018-07–12&lt;/code&gt; of the API. You’ll always know what version of the API the SDK is using by just looking at the SDK version.&lt;/p&gt;

&lt;p&gt;The great benefit here is also that even if you don’t remember to go into your dashboard and upgrade your app’s default API version, the SDK will handle explicitly setting the &lt;code&gt;Square-Version&lt;/code&gt; header to the API version that matches to the SDK. No more thinking about which version to be on, let the SDK do the work for you!&lt;/p&gt;

&lt;h3&gt;
  
  
  What does this look like?
&lt;/h3&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;curl https://connect.squareup.com/v2/locations/&lt;span class="o"&gt;{{&lt;/span&gt;location_id&lt;span class="o"&gt;}}&lt;/span&gt;/transactions &lt;span class="se"&gt;\&lt;/span&gt;
   &lt;span class="nt"&gt;-X&lt;/span&gt; POST &lt;span class="se"&gt;\&lt;/span&gt;
   &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt;  &lt;span class="se"&gt;\&lt;/span&gt;
   &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Authorization: Bearer ACCESS_TOKEN"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
   &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Square-Version: 2018-07-12"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
   &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{
    "idempotency_key": "74ae1696-b1e3-4328-af6d-f1e04d947a13",
    "amount_money": {
      "amount": 200,
      "currency": "USD"
    },
    "card_nonce": "card_nonce_from_square_123",
   }'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;We are really looking forward to delivering new and improved functionality to developers. Having API versioning is a key step to getting this into the hands of developers. We can now give developers the features they want more rapidly while also not breaking things for existing implementations. If there are new features that you really want or things that you want improved, come join us in our &lt;a href="https://squ.re/slack"&gt;Slack community&lt;/a&gt; or post on &lt;a href="https://stackoverflow.com/"&gt;StackOverflow&lt;/a&gt; with the tag &lt;code&gt;square-connect&lt;/code&gt; so that we can hear from you.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Want more? &lt;a href="https://www.workwithsquare.com/developer-newsletter.html?channel=Online%20Social&amp;amp;sqmethod=Blog"&gt;Sign up&lt;/a&gt; for our monthly developer newsletter or come say hi in the Square dev &lt;a href="https://squ.re/slack"&gt;Slack channel&lt;/a&gt;!&lt;/em&gt;&lt;/p&gt;

</description>
      <category>api</category>
      <category>webdev</category>
      <category>sdks</category>
    </item>
    <item>
      <title>Serverless Instant Checkout Links</title>
      <dc:creator>Richard Moot</dc:creator>
      <pubDate>Wed, 27 Jun 2018 21:27:57 +0000</pubDate>
      <link>https://forem.com/squaredev/serverless-instant-checkout-links-59mn</link>
      <guid>https://forem.com/squaredev/serverless-instant-checkout-links-59mn</guid>
      <description>&lt;p&gt;Servers beware! Watch out containers! Our serverless overlords are here! There is a lot of hype around serverless and talk about it being the end of containers, but we’re still not seeing a whole lot of major adoption of the technology (at least not seeing many companies vocal about it). My hope is to spark a little interest on what is possible in this space by showing different ways to use serverless beyond image processing, ETL, or general async tasks (but its really great for those things!). We’re still sticking with eCommerce though.&lt;/p&gt;

&lt;p&gt;In a previous post, I talked a bit about how to create a &lt;a href="https://developer.squareup.com/blog/super-simple-serverless-ecommerce"&gt;Super Simple Serverless eCommerce&lt;/a&gt; site that used AWS Lambda and S3 to do serverless checkout payments. This got me thinking about creating something a little more advanced—something almost any Square seller could use to allow customers to immediately purchase products using just a link. We’ll go over a simple version of the application I built using only four Google Cloud functions via Firebase. The idea behind switching from AWS Lambda to Firebase here is to demonstrate different platform offerings in the serverless space, but also because there were a lot more tools available on Firebase to support this kind of service. It’s also worth having some examples out there that aren’t needing to use the Serverless Framework.&lt;/p&gt;

&lt;p&gt;The application consists of:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://developer.squareup.com/docs/basics/oauth/overview"&gt;OAuth to Square&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://firebase.google.com/products/auth/"&gt;User management via Firebase&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://firebase.google.com/products/hosting/"&gt;Static hosting on Firebase&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://firebase.google.com/products/functions/"&gt;Cloud Functions&lt;/a&gt; (duh)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Shortlinks via &lt;a href="https://firebase.google.com/docs/dynamic-links/"&gt;Firebase Dynamic Links&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://developer.squareup.com/docs/products/catalog/overview"&gt;Square Catalog API&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://developer.squareup.com/docs/payments/checkout/overview"&gt;Square Checkout API&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="//images.ctfassets.net/1wryd5vd9xez/4nzU7BHOVNBhzx4moUdQzf/3be5b70b7901dadb6d7f91b14c11f1c7/https___cdn-images-1.medium.com_max_2968_1_L8gYudVwq0gRP3SJFkgSwA.png" class="article-body-image-wrapper"&gt;&lt;img src="//images.ctfassets.net/1wryd5vd9xez/4nzU7BHOVNBhzx4moUdQzf/3be5b70b7901dadb6d7f91b14c11f1c7/https___cdn-images-1.medium.com_max_2968_1_L8gYudVwq0gRP3SJFkgSwA.png" alt="Warning! Clicking on this image will not actually connect your Square account."&gt;&lt;/a&gt;&lt;em&gt;Warning! Clicking on this image will not actually connect your Square account.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The front-end of the application originally was just static pages, but has since been refactored into a fairly simple React application. The main focus here will be on using serverless functions for doing our processing though. The first step in getting our instant checkout links created requires setting up OAuth in order to get our user’s access token. For this, we will create our first two functions, named “authorize” and “code”. Google does a great job of explaining how to use Firebase CLI &lt;a href="https://firebase.google.com/docs/functions/get-started"&gt;on their site&lt;/a&gt; so we’ll skip that.&lt;/p&gt;

&lt;p&gt;If you’re not familiar with OAuth or want to know more about OAuth with Square, checkout (pun intended) my previous blog post “&lt;a href="https://developer.squareup.com/blog/oauth-wherefore-art-thou"&gt;OAuth, wherefor art thou?&lt;/a&gt;”.&lt;/p&gt;

&lt;p&gt;Now let’s dig into some sweet, sweet code examples.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;functions&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;firebase-functions&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;crypto&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;crypto&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;exports&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;authorize&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;functions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;https&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onRequest&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;squareAuthURL&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://connect.squareup.com/oauth2/authorize?&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;crypto&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;randomBytes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;32&lt;/span&gt;&lt;span class="p"&gt;)).&lt;/span&gt;&lt;span class="nx"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;hex&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Set-Cookie&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;`__session=&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;; Secure`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nx"&gt;squareAuthURL&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;
    &lt;span class="s2"&gt;`client_id=&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;functions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nx"&gt;square&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;prod&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;app_id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;amp;`&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;
    &lt;span class="s2"&gt;`response_type=code&amp;amp;`&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;
    &lt;span class="s2"&gt;`scope=MERCHANT_PROFILE_READ PAYMENTS_WRITE ORDERS_WRITE ITEMS_READ&amp;amp;`&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;
    &lt;span class="s2"&gt;`session=false&amp;amp;`&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;
    &lt;span class="s2"&gt;`locale=en-US&amp;amp;`&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;
    &lt;span class="s2"&gt;`state=&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Here we are just creating a string to send to the client-side for redirecting our user. The main purpose here is more about generating our state, creating the cookie, and passing it along for us to verify later when we get the callback from Square redirecting our user back to us.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;exports&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;code&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;functions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;https&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onRequest&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;tokenURL&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://connect.squareup.com/oauth2/token&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;redirectURI&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://checkout-now.firebaseapp.com/callback&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;cookieState&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;getSessionCookie&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;cookie&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;code&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;cookieState&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;app_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;secret&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;functions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nx"&gt;square&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;prod&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;access_token&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;email&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;axios&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;tokenURL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;client_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;app_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;client_secret&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;secret&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;code&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;decodeURIComponent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;code&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="na"&gt;redirect_uri&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;redirectURI&lt;/span&gt;
      &lt;span class="p"&gt;})&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;token&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;access_token&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;token&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;axios&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://connect.squareup.com/v1/me&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;headers&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
              &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Authorization&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`Bearer &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;access_token&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;}).&lt;/span&gt;&lt;span class="nx"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;email&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;createFirebaseAccount&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;email&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;access_token&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;}).&lt;/span&gt;&lt;span class="nx"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;firebaseToken&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;json&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
          &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;email&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;email&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;token&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;firebaseToken&lt;/span&gt;
        &lt;span class="p"&gt;});&lt;/span&gt;
      &lt;span class="p"&gt;}).&lt;/span&gt;&lt;span class="k"&gt;catch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`INVALID STATE: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;cookieState&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; === &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`INVALID STATE: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;cookieState&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; === &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;We’re definitely doing a bit more here than just getting our access token from the callback. We are looking up the user’s info using their access token and then creating an account in Firebase for that user’s email. The intention here was to disallow a user to create an account using any email they wanted, and strictly having it tied to the email that is set for their Square account. We’ve omitted the &lt;code&gt;createFirebaseAccount()&lt;/code&gt; function definition, since it’s just another detail peculiar to Firebase for creating accounts.&lt;/p&gt;

&lt;p&gt;We’re in a pretty good place! We have authorized our user, received an access token, set the user up in Firebase, stored their token, and now we can start using Square’s API’s for generating our instant checkout links.&lt;/p&gt;

&lt;p&gt;After our user gets their sign-in link in their email and is redirected back to our app to sign in, we need to generate our links to send to the user. This is where we’ll need the &lt;code&gt;catalog&lt;/code&gt; function.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;exports&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;catalog&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;functions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;https&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onRequest&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;uid&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nx"&gt;admin&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;auth&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nx"&gt;verifyIdToken&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;idToken&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;decodedToken&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="p"&gt;({&lt;/span&gt;
        &lt;span class="nx"&gt;uid&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;decodedToken&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;admin&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;database&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ref&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`/squareAccessToken/&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;uid&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;once&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;value&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}).&lt;/span&gt;&lt;span class="nx"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;userToken&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;SquareConnect&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ApiClient&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;instance&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;authentications&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;oauth2&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;accessToken&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;userToken&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;val&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;catalogApi&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;SquareConnect&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;CatalogApi&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;catalogApi&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;listCatalog&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;}).&lt;/span&gt;&lt;span class="nx"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;catalog&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;formattedResponse&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;catalog&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;objects&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;elem&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;axios&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`https://firebasedynamiclinks.googleapis.com/v1/shortLinks?`&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;
          &lt;span class="s2"&gt;`key=&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;functions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nx"&gt;web&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;longDynamicLink&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`https://checkout.page.link/?`&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;
              &lt;span class="s2"&gt;`link=https://checkout-now.firebaseapp.com/checkout/`&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;
              &lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${(&lt;/span&gt;&lt;span class="nx"&gt;uid&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;))[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]}&lt;/span&gt;&lt;span class="s2"&gt;/&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;elem&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;item_data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;variations&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;suffix&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
              &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;option&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;SHORT&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
          &lt;span class="p"&gt;}).&lt;/span&gt;&lt;span class="nx"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;resp&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;elem&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;item_data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;catalogId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;elem&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;varId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;elem&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;item_data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;variations&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;price&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;elem&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;item_data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;variations&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;item_variation_data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;price_money&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;checkoutUrl&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;resp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;shortLink&lt;/span&gt;
          &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}).&lt;/span&gt;&lt;span class="k"&gt;catch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
      &lt;span class="p"&gt;});&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;all&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;formattedResponse&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}).&lt;/span&gt;&lt;span class="nx"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;values&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;json&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;values&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}).&lt;/span&gt;&lt;span class="k"&gt;catch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;This function is a little bit dense. We’re taking the token send to us, decoding the Firebase token, looking up our user, getting their Square access token, querying the catalog API, iterating over the catalog items, creating a list of item objects, and creating short url links for checking out with.&lt;/p&gt;

&lt;p&gt;Take a breath, there was a lot in that list.&lt;/p&gt;

&lt;p&gt;&lt;a href="//images.ctfassets.net/1wryd5vd9xez/2VfbSezW8iDOvHk7iBZEjo/51b86c4139f2a5bc7ab8e26b495fcec8/https___cdn-images-1.medium.com_max_2000_1_FAlgA0IPTybwJKnrSEXkcw.png" class="article-body-image-wrapper"&gt;&lt;img src="//images.ctfassets.net/1wryd5vd9xez/2VfbSezW8iDOvHk7iBZEjo/51b86c4139f2a5bc7ab8e26b495fcec8/https___cdn-images-1.medium.com_max_2000_1_FAlgA0IPTybwJKnrSEXkcw.png" alt="This is a not so pretty example of our checkout link."&gt;&lt;/a&gt;&lt;em&gt;This is a not so pretty example of our checkout link.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Okay, break’s over. Back to work.&lt;/p&gt;

&lt;p&gt;In the catalog links, we’re constructing a URL the follows the format&lt;code&gt;/merchantId/catalogVariantId/&lt;/code&gt; which allows us to look up our Square merchant and then what item is being purchased. This might be a little confusing, since we haven’t looked at the final function yet. We have one more function to go over: the &lt;code&gt;checkout&lt;/code&gt; function. Our &lt;code&gt;checkout&lt;/code&gt; function will handle the process of looking up a merchant, looking up the catalog item, creating a Square checkout URL, and then redirecting the user to that checkout url. Let’s take a look at what this function looks like.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;express&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/checkout/:userId/:variantId&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;admin&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;database&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
       &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ref&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`/squareAccessToken/square:&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
       &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;once&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;value&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nx"&gt;userToken&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;SquareConnect&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ApiClient&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;instance&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;authentications&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;oauth2&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;accessToken&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;userToken&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;val&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;catalogApi&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;SquareConnect&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;CatalogApi&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;catalogApi&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;retrieveCatalogObject&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;variantId&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}).&lt;/span&gt;&lt;span class="nx"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nx"&gt;item&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;checkoutApi&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;SquareConnect&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;CheckoutApi&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;idempotencyKey&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;crypto&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;randomBytes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;48&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;base64&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;locationId&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;present_at_location_ids&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;checkoutReq&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;idempotency_key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;idempotencyKey&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;order&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="na"&gt;idempotency_key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;idempotencyKey&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;reference_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;now&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nx"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
          &lt;span class="na"&gt;line_items&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt;
              &lt;span class="na"&gt;catalog_object_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;variantId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
              &lt;span class="na"&gt;quantity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;1&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
          &lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;checkoutApi&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;createCheckout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;locationId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;checkoutReq&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}).&lt;/span&gt;&lt;span class="nx"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nx"&gt;returnedCheckout&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;redirect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;returnedCheckout&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;checkout&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;checkout_page_url&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}).&lt;/span&gt;&lt;span class="k"&gt;catch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="nx"&gt;exports&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;checkout&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;functions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;https&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onRequest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;We switched things up here by wrapping our function up as an Express application. This allows an easier time in parsing route variables so we could look up our merchant and catalog IDs. Since our prices are already set in Square, all we need to do is place the item as a line item in our order, generate our checkout link, and then redirect!&lt;/p&gt;

&lt;p&gt;Candidly: this example is missing a lot. It is meant as a proof of concept (which is why I omitted the actual URLs for the application) since there are a few scenarios we’re not really handling here that actual merchants would likely want. For starters, the &lt;code&gt;catalog&lt;/code&gt; function for generating links entirely disregards other &lt;a href="https://developer.squareup.com/docs/products/catalog/overview#catalog-items-versus-variations"&gt;item variants&lt;/a&gt; (i.e. large, medium, small, for t-shirt sizes). The function just grabs the first variant. Clearly more could be done here to accommodate that, but the focus was to show how easily we could get instant checkout links.&lt;/p&gt;

&lt;p&gt;To add to this, we’re best supporting a digital good or an item that had flat-rate shipping (we’d need to capture a shipping address and add a line item for the shipping charges, but the checkout API supports that). That’s all easy enough, but if we wanted dynamic shipping rates, we might need to capture their address earlier in the process to create a line item that included the shipping rate.&lt;/p&gt;

&lt;p&gt;In my previous post on &lt;a href="https://developer.squareup.com/blog/super-simple-serverless-ecommerce"&gt;Super Simple Serverless eCommerce&lt;/a&gt;, I touched on the fact that cold starts can really harm something like a checkout experience since the functions not having run for a while could mean a slow startup. We would have to monitor the impact on that &lt;code&gt;checkout&lt;/code&gt; function, since a single social media post could spike traffic drastically and cause a lot of instances of our function to be spun up to handle it all. The hope is that so many people would use this particular function that it could reasonably handle all of the traffic. The more concerning issue might be the cost of having so many calls against this function. You’d have to weigh the cost of having a lot of invocations of your function against just having your own server handling these requests. All things to consider before trying to go fully serverless!&lt;/p&gt;

&lt;p&gt;We hope this helped spark some ideas on what you can do with serverless, but even more so, we hope it makes you want to try out Square’s APIs! If you have a project you’re working on that you want to talk about, pains with payments, or just want to chat with some devs, check out the links below to get in touch with us!&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Want more? &lt;a href="https://www.workwithsquare.com/developer-newsletter.html?channel=Online%20Social&amp;amp;sqmethod=Blog"&gt;Sign up&lt;/a&gt; for our monthly developer newsletter or come say hi in the Square dev &lt;a href="https://squ.re/slack"&gt;Slack channel&lt;/a&gt;!&lt;/em&gt;&lt;/p&gt;

</description>
      <category>serverless</category>
      <category>javascript</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Super Simple Serverless eCommerce</title>
      <dc:creator>Richard Moot</dc:creator>
      <pubDate>Fri, 20 Apr 2018 16:43:06 +0000</pubDate>
      <link>https://forem.com/squaredev/super-simple-serverless-ecommerce-41p4</link>
      <guid>https://forem.com/squaredev/super-simple-serverless-ecommerce-41p4</guid>
      <description>&lt;p&gt;A lot of companies have been taking the plunge into utilizing &lt;a href="https://en.wikipedia.org/wiki/Serverless_computing"&gt;serverless&lt;/a&gt; in order to enhance their tech stacks (e.g., &lt;a href="https://read.acloud.guru/serverless-event-sourcing-at-nordstrom-ea69bd8fb7cc"&gt;Nordstrom&lt;/a&gt;, &lt;a href="https://medium.com/netflix-techblog/developer-experience-lessons-operating-a-serverless-like-platform-at-netflix-a8bbd5b899a0"&gt;Netflix&lt;/a&gt;, and &lt;a href="https://aws.amazon.com/serverless/videos/video-lambda-coca-cola/"&gt;Coca-Cola&lt;/a&gt;). It may seem like serverless is just a growing fad, but that was the same line of thought many people had about &lt;a href="https://nodejs.org/"&gt;Node&lt;/a&gt; until &lt;a href="https://changelog.com/podcast/116"&gt;Walmart launched a new site before Black Friday&lt;/a&gt;. We might be approaching a similar inflection point for serverless to rapidly improve the speed of development and scale that Node has been able to accomplish.&lt;/p&gt;

&lt;p&gt;If you haven’t jumped on the serverless bandwagon yet, now is the time. We’re going to walk though a simple way to create serverless functions to allow customers to instantly checkout and buy an item from a Square store. We’ll go through creating a static site on S3, creating AWS Lambda functions, and creating AWS API Gateway endpoints to allow customers to instantly checkout using the Square Checkout API.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;It’s worth clarifying that there’s a difference between &lt;a href="https://serverless.com/"&gt;The Serverless Framework&lt;/a&gt; and &lt;a href="https://en.wikipedia.org/wiki/Serverless_computing"&gt;serverless computing&lt;/a&gt;. The Serverless Framework is just a tool that can be used to facilitate creating, deploying, and managing your serverless functions that you create with your desired cloud provider. Serverless computing is a reference to a cloud provider dynamically managing the allocation of machine resources.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;We’ll be using the The Serverless Framework in this post to facilitate creating and deploying our functions more easily, but we don’t want it confused with serverless computing as a whole. We’ll explore different platforms and different tools in future posts as we build on the concepts covered here.&lt;/p&gt;

&lt;p&gt;Things you need to build this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://squareup.com/developers"&gt;Square Developer Account&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://aws.amazon.com/"&gt;AWS Account&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://serverless.com/"&gt;The Serverless Framework&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Static Site Using S3
&lt;/h3&gt;

&lt;p&gt;The basic structure of our little store will be a static HTML page hosted on S3 and spiffed up with CSS and JavaScript. We’ll then process our checkout through Lambda functions that allow you to just purchase the one item you clicked on. This is intended to be super basic to illustrate how to get things up and running on AWS — we can explore more advanced ways of doing this all in future posts. We’ll start with the HTML and getting that into S3 to create our static website.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="c"&gt;&amp;lt;!-- start product --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;'product'&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;'imageContainer'&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;img&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;'productImage'&lt;/span&gt; &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"/0.jpeg"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="c"&gt;&amp;lt;!-- insert product image url here --&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;'imageOverlay'&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;button&amp;gt;&lt;/span&gt;View Details&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;'modal clearfix'&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;'close'&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Close&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;img&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;'modalImage'&lt;/span&gt; &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"/0.jpeg"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="c"&gt;&amp;lt;!-- insert product image url here --&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;'productInfo'&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;h2&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;'productTitle'&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Back to Square 1 Sticker&lt;span class="nt"&gt;&amp;lt;/h2&amp;gt;&lt;/span&gt;
            &lt;span class="c"&gt;&amp;lt;!-- insert product title here --&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;p&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;'productDescription'&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;"If only 88 was a perfect Square..."&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;'productMeta'&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;h2&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;'productCost'&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
                    &lt;span class="nt"&gt;&amp;lt;span&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;'green'&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;$1.00&lt;span class="nt"&gt;&amp;lt;/span&amp;gt;&lt;/span&gt;*
                &lt;span class="nt"&gt;&amp;lt;/h2&amp;gt;&lt;/span&gt;

                &lt;span class="c"&gt;&amp;lt;!-- insert product cost here --&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;span&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;'helperText'&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;*We're not actually going to charge you.&lt;span class="nt"&gt;&amp;lt;/span&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;form&lt;/span&gt; &lt;span class="na"&gt;action=&lt;/span&gt;&lt;span class="s"&gt;'https://UNIQUE_ID.execute-api.us-east-1.amazonaws.com/prod/checkout'&lt;/span&gt; &lt;span class="na"&gt;method=&lt;/span&gt;&lt;span class="s"&gt;'post'&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
                    &lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;'itemVarID'&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;'hidden'&lt;/span&gt; &lt;span class="na"&gt;value=&lt;/span&gt;&lt;span class="s"&gt;"IBXSHR4PIMEAHHSOAKNBC5PQ"&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;'display: none'&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
                    &lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;'price'&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;'hidden'&lt;/span&gt; &lt;span class="na"&gt;value=&lt;/span&gt;&lt;span class="s"&gt;"100"&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;'display: none'&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
                    &lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;'name'&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;'hidden'&lt;/span&gt; &lt;span class="na"&gt;value=&lt;/span&gt;&lt;span class="s"&gt;"Back to Square 1 Sticker"&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;'display: none'&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
                    &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;'submit'&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;'productPurchase'&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Buy This&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;/form&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="c"&gt;&amp;lt;!-- end product --&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Take a look at the meat of our &lt;code&gt;index.html&lt;/code&gt; by just looking at the product div elements. We’re hard coding our item’s &lt;a href="https://developer.squareup.com/docs/api/connect/v2#endpoint-retrievecatalogobject"&gt;variant id&lt;/a&gt; to each div and stuffing that into a hidden input field as well. This will let us easily pass this to our Lambda function with a POST request. My main reason for this approach is entirely the simplicity of it. We don’t need to write any JavaScript to handle passing the information — we can just use the native behavior of a form element to POST our item info to our function.&lt;/p&gt;

&lt;p&gt;If we put in our 12 products, we get something similar to what we have below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;!DOCTYPE html&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;html&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;head&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;title&amp;gt;&lt;/span&gt;Square Swag Shop&lt;span class="nt"&gt;&amp;lt;/title&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"description"&lt;/span&gt; &lt;span class="na"&gt;content=&lt;/span&gt;&lt;span class="s"&gt;"A Simple eCommerce Store"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;link&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"favicon"&lt;/span&gt; &lt;span class="na"&gt;rel=&lt;/span&gt;&lt;span class="s"&gt;"icon"&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"/favicon.ico"&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"image/x-icon"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;charset=&lt;/span&gt;&lt;span class="s"&gt;"utf-8"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;http-equiv=&lt;/span&gt;&lt;span class="s"&gt;"X-UA-Compatible"&lt;/span&gt; &lt;span class="na"&gt;content=&lt;/span&gt;&lt;span class="s"&gt;"IE=edge"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;'viewport'&lt;/span&gt; &lt;span class="na"&gt;content=&lt;/span&gt;&lt;span class="s"&gt;'width=device-width, initial-scale=1'&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;link&lt;/span&gt; &lt;span class="na"&gt;rel=&lt;/span&gt;&lt;span class="s"&gt;'stylesheet'&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;'/normalize.css'&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;link&lt;/span&gt; &lt;span class="na"&gt;rel=&lt;/span&gt;&lt;span class="s"&gt;'stylesheet'&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;'/main.css'&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;body&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"cocoon"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;header&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"container"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"square-logo"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/header&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"products"&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"container clearfix"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;'product'&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
                &lt;span class="c"&gt;&amp;lt;!-- Our other product html tags here --&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;'product'&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
                &lt;span class="c"&gt;&amp;lt;!-- Our other product html tags here --&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;'product'&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
                &lt;span class="c"&gt;&amp;lt;!-- Our other product html tags here --&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;'product'&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
                &lt;span class="c"&gt;&amp;lt;!-- Our other product html tags here --&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"veil"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;'/modernizr-3.5.0.min.js'&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;'https://code.jquery.com/jquery-3.2.1.min.js'&lt;/span&gt; &lt;span class="na"&gt;integrity=&lt;/span&gt;&lt;span class="s"&gt;'sha256-hwg4gsxgFZhOsEEamdOYGBf13FyQuiTwlAQgxVSNgt4='&lt;/span&gt; &lt;span class="na"&gt;crossorigin=&lt;/span&gt;&lt;span class="s"&gt;'anonymous'&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;'/plugin.js'&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;'/main.js'&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;/html&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;We’ll skip over the stylings and the jQuery used to make modals, since that’s not really the focus here. All we have to do is upload all of our files to S3 and enable “Static website hosting” in Properties to have a publicly accessible site.&lt;/p&gt;

&lt;p&gt;Now we should have a nice page for everyone to see our products, but we need to have a way to allow everyone to buy those products. Now we finally start digging into creating our AWS Lambda functions (serverless functions). This is what we’ll create to place in the form “action” attribute so that our form POSTs to our function.&lt;/p&gt;

&lt;p&gt;&lt;a href="//images.ctfassets.net/1wryd5vd9xez/2BaS7Axhh4MP1WE6VI2Nto/789847564faa6f3f6cfe45b8aae3cf56/https___cdn-images-1.medium.com_max_2102_1_RiQhDFnejiTQYb3B1tNASg.png" class="article-body-image-wrapper"&gt;&lt;img src="//images.ctfassets.net/1wryd5vd9xez/2BaS7Axhh4MP1WE6VI2Nto/789847564faa6f3f6cfe45b8aae3cf56/https___cdn-images-1.medium.com_max_2102_1_RiQhDFnejiTQYb3B1tNASg.png" alt="I should hope its clear you have your own bucket name for the URL."&gt;&lt;/a&gt;&lt;em&gt;I should hope its clear you have your own bucket name for the URL.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;You should be able to access your static site by visiting the URL provided by AWS and you can see all your wonderful items on display.&lt;/p&gt;

&lt;h3&gt;
  
  
  Serverless Functions using AWS Lambda
&lt;/h3&gt;

&lt;p&gt;For our serverless function, we’ll process the Square &lt;a href="https://developer.squareup.com/docs/api/connect/v2#endpoint-retrievecatalogobject"&gt;catalog variant ID&lt;/a&gt; that is being sent from our form in our static site, and then create a checkout URL to redirect our user to. To do this, we’ll use Square’s &lt;a href="https://github.com/square/connect-javascript-sdk"&gt;JavaScript SDK&lt;/a&gt; inside our function to more easily generate the URL we need. You’re more than welcome to attempt using &lt;em&gt;just&lt;/em&gt; AWS tools for creating and deploying the function, but we’re going to just use &lt;a href="https://serverless.com/"&gt;Serverless&lt;/a&gt; for managing deploying the function and linking it to AWS API Gateway.&lt;/p&gt;

&lt;p&gt;If you, too, want to use serverless to create your own functions, they have great tutorials &lt;a href="https://serverless.com/framework/docs/providers/aws/guide/quick-start/"&gt;over here&lt;/a&gt;. You need to have Node on your machine and install serverless with &lt;code&gt;npm install -g serverless&lt;/code&gt; (or if you don’t want it installed globally, just use &lt;code&gt;[npx&lt;/code&gt;](&lt;a href="https://medium.com/@maybekatz/introducing-npx-an-npm-package-runner-55f7d4bd282b)"&gt;https://medium.com/@maybekatz/introducing-npx-an-npm-package-runner-55f7d4bd282b)&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;You can run &lt;code&gt;serverless create --template aws-nodejs&lt;/code&gt; to get a template going, but it creates a lot more than what’s needed. Feel free to just copy the &lt;code&gt;handler.js&lt;/code&gt; and &lt;code&gt;serverless.yml&lt;/code&gt; to modify into your own templates. We’ll start out with a basic function to test that our deployment is working as intended, then add in functionality for our checkout.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;use strict&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;SquareConnect&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;square-connect&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;checkout&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;callback&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Success! Our function is running!&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nx"&gt;callback&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;This is just our example to test. Next, we want to create our &lt;code&gt;serverless.yml&lt;/code&gt; file for deploying our function and creating the AWS API Gateway endpoint.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;service&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;serverless-checkout&lt;/span&gt; &lt;span class="c1"&gt;# NOTE: update this with your service name&lt;/span&gt;

&lt;span class="na"&gt;provider&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;aws&lt;/span&gt;
  &lt;span class="na"&gt;runtime&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;nodejs8.10&lt;/span&gt;
  &lt;span class="na"&gt;stage&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;prod&lt;/span&gt;
  &lt;span class="na"&gt;memorySize&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;256&lt;/span&gt;

&lt;span class="na"&gt;package&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;include&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;node_modules/square-connect/**&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;node_modules/superagent/**&lt;/span&gt;
  &lt;span class="na"&gt;excludeDevDependencies&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="no"&gt;true&lt;/span&gt;

&lt;span class="na"&gt;functions&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;checkout&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;environment&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;ACCESS_TOKEN&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;YOUR_ACCESS_TOKEN&lt;/span&gt;
      &lt;span class="na"&gt;LOCATION_ID&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;YOUR_LOCATION_ID&lt;/span&gt;
    &lt;span class="na"&gt;handler&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;handler.checkout&lt;/span&gt;
    &lt;span class="na"&gt;events&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;http&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;/checkout&lt;/span&gt;
          &lt;span class="na"&gt;method&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;any&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Now, it’s as simple as running &lt;code&gt;serverless deploy&lt;/code&gt; to launch our functions into the cloud. You should see something similar to the below when you deploy:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Serverless: Packaging service...
Serverless: Excluding development dependencies...
Serverless: Uploading CloudFormation file to S3...
Serverless: Uploading artifacts...
Serverless: Uploading service .zip file to S3 (742.81 KB)...
Serverless: Validating template...
Serverless: Updating Stack...
Serverless: Checking Stack update progress...
..............
Serverless: Stack update finished...
Service Information
service: serverless-checkout
stage: prod
region: us-east-1
stack: serverless-checkout-prod
api keys:
  None
endpoints:
  ANY - https://UNIQUE_ID.execute-api.us-east-1.amazonaws.com/prod/checkout
functions:
  checkout: serverless-checkout-prod-checkout
Serverless: Removing old service versions...
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;You should be able to visit the URL that Serverless logged out to the console in your browser and find our message, &lt;code&gt;“Success! Our function is running!”&lt;/code&gt; showing up in the browser. We just need to refactor our Lambda function to handle the catalog variant ID in order to request our checkout URL and redirect the user.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;SquareConnect&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;square-connect&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;crypto&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;crypto&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;querystring&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;querystring&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;checkout&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;callback&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;SquareConnect&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ApiClient&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;instance&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;authentications&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;oauth2&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;accessToken&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ACCESS_TOKEN&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;formData&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;querystring&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;locationId&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;LOCATION_ID&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;checkoutRequest&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;idempotency_key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;crypto&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;randomBytes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;48&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;base64&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="na"&gt;order&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;idempotency_key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;crypto&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;randomBytes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;48&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;base64&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
      &lt;span class="na"&gt;reference_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;now&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nx"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
      &lt;span class="na"&gt;line_items&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
          &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="na"&gt;catalog_object_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;formData&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;itemVarID&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;quantity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;1&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
          &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;merchant_support_email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;support@squareup.com&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;checkoutApi&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;SquareConnect&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;CheckoutApi&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

  &lt;span class="nx"&gt;checkoutApi&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;createCheckout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;locationId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;checkoutRequest&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;then&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;checkoutResponse&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;statusCode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;302&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;Location&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;checkoutResponse&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;checkout&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;checkout_page_url&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;
    &lt;span class="nx"&gt;callback&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}).&lt;/span&gt;&lt;span class="k"&gt;catch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
      &lt;span class="nx"&gt;callback&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Here we have our fully functioning (pun intended) Lambda function that can create checkout URLs to allow users to buy our products.&lt;/p&gt;

&lt;p&gt;Again, it’s worth reminding that this is intentionally a minimal implementation that would only work for something like a digital good (that requires no tax), but demonstrates how easy it is to create your checkout and redirect a customer without having to spin up our own servers. In fact, if you were to append your catalog variant ID as query string parameters to your function URL, you could just parse those out in your function to essentially have your own serverless “buy it now” link. Additionally, you could add a line item for shipping costs to easily handle flat rate shipping and even capture the customer’s shipping details in the checkout (see &lt;a href="https://developer.squareup.com/docs/payments/checkout/overview#create-the-post-request"&gt;here&lt;/a&gt; for more details on that).&lt;/p&gt;

&lt;p&gt;&lt;a href="//images.ctfassets.net/1wryd5vd9xez/4IyeEguXo7RZQw9l32K7n4/d2861fa5fcacc72a0550add41f1033b4/https___cdn-images-1.medium.com_max_3004_1_VC8FjM4vSbPwtsTdDDDKNw.png" class="article-body-image-wrapper"&gt;&lt;img src="//images.ctfassets.net/1wryd5vd9xez/4IyeEguXo7RZQw9l32K7n4/d2861fa5fcacc72a0550add41f1033b4/https___cdn-images-1.medium.com_max_3004_1_VC8FjM4vSbPwtsTdDDDKNw.png" alt="A preview of our eCommerce store. Those are our stickers we give away at developer conferences."&gt;&lt;/a&gt;&lt;em&gt;A preview of our eCommerce store. Those are our stickers we give away at developer conferences.&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Serverless Misunderstandings
&lt;/h3&gt;

&lt;p&gt;There seems to be widespread misunderstanding around serverless computing and what it is comprised of. Is it pay per invocation? Pay per Mb/s of memory? Just like Node, serverless is suffering a bit from the same desire to “do all the things.” True, it’s a new technology that needs to be explored, but a lot of weird uses are cropping up that come across as anti-patterns (in my opinion). Node was and is known for being really bad at handling CPU-intensive tasks due to its single-threaded nature, and the same goes for using serverless for user facing interactions or APIs. Users expect things to be responsive, and cold starts kill the expected responsiveness. You can certainly try circumvent this by keeping your functions warm as a solution to this, but smells like an anti-pattern. The whole benefit of serverless is to not have to be as concerned with your infrastructure, yet people are writing more code to modify their infrastructure’s behavior that they don’t really have control over.&lt;/p&gt;

&lt;p&gt;If you plan to use serverless for user-facing applications, look carefully at your user traffic patterns to your endpoints, since that would play heavily into overall user experience. A constant amount of traffic would be relatively fine — functions would stay warm and a very small percentage of users would be impacted by a slow response — but if you have particularly spiky traffic, the user experience will suffer as your platform provider is &lt;a href="https://theburningmonk.com/2018/01/im-afraid-youre-thinking-about-aws-lambda-cold-starts-all-wrong/"&gt;spinning up additional instances&lt;/a&gt; of your function to service your traffic.&lt;/p&gt;

&lt;p&gt;There are many possibilities to explore with serverless computing as the technology continues to mature, and today’s problems will diminish with time. The real reason to start now is so you can be really condescending to all the new serverless adopters of the future and tell them how much harder serverless programming was back in your day. So get started now and build something serverless!&lt;/p&gt;

&lt;p&gt;To follow along with this post, you’ll need to &lt;a href="https://squareup.com/developers"&gt;sign up for a Square Developer account&lt;/a&gt;. Even if you don’t want to follow along, sign up anyways, its free!&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Want more? &lt;a href="https://www.workwithsquare.com/developer-newsletter.html?channel=Online%20Social&amp;amp;sqmethod=Blog"&gt;Sign up&lt;/a&gt;&lt;/em&gt; &lt;em&gt;for our monthly developer newsletter.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>serverless</category>
      <category>javascript</category>
      <category>webdev</category>
    </item>
    <item>
      <title>OAuth, wherefore art thou?</title>
      <dc:creator>Richard Moot</dc:creator>
      <pubDate>Mon, 02 Apr 2018 21:41:50 +0000</pubDate>
      <link>https://forem.com/squaredev/oauth-wherefore-art-thou-29ka</link>
      <guid>https://forem.com/squaredev/oauth-wherefore-art-thou-29ka</guid>
      <description>&lt;p&gt;Shakespeare’s plays are wonderful expressions of beauty and romance. His plays are also complicated, tragic, and hard to understand. Working with OAuth can feel a lot like Shakespeare. It sounds overly complicated, but the more time you spend with it, the more you see the underlying beauty and begin to truly understand it.&lt;/p&gt;

&lt;p&gt;Let’s demystify some aspects of OAuth so you, too, can see the beauty and benefits to using it. If you’re already familiar with OAuth, skip ahead to take a look at the basic OAuth setup with Square.&lt;/p&gt;

&lt;p&gt;Before we go into explaining OAuth , it’s worth talking about when you should be implementing it. A lot of API’s require &lt;em&gt;utilizing&lt;/em&gt; OAuth, but sometimes you might not really need to use it. If you’re building an integration solely for your own use or your own application, you’re probably fine using your personal access token. If you’re wanting to build an application that needs access to multiple accounts or needs granular access, you’ll want to build out an OAuth integration. Even for your own infrastructure, if you have an &lt;a href="https://en.wikipedia.org/wiki/Extract,_transform,_load"&gt;ETL&lt;/a&gt; service, you might want to create an access token specifically for just that service that has read-only access.&lt;/p&gt;

&lt;h3&gt;
  
  
  Behind the Scenes of OAuth
&lt;/h3&gt;

&lt;p&gt;To explain OAuth, we’ll walk through it like acts in a play. The first act is the authorization, the second act is the redirect, and the third act is acquisition. There’s also a prologue — getting things set up with your authorizer (in this case, Square) to register your application and get all your special credentials to use in the process.&lt;/p&gt;

&lt;p&gt;In the first act, we’re sending the user off to the authorization server to ask for some permissions — like a kid who wants to go on a field trip. In order to attend, they’re sent to their parent with a list of what the field trip entails, and the parent has to sign off on it. For OAuth, you’re sending a user to the authorizer with your scope (permissions) that you would like to have. Then the user can see everything being requested and confirm that they would like to grant your application access for those permissions.&lt;/p&gt;

&lt;p&gt;The second act is the redirect, which is where Square sends back a code to your application that can be used to acquire an access token. This should seem familiar if you’ve ever used SMS to log in to something. You need to provide &lt;em&gt;both&lt;/em&gt; your password and the code that was sent via SMS in order to log in. The code sent back to your application from Square is your authorization code and is used by your application in the final act of getting the access token.&lt;/p&gt;

&lt;p&gt;The third act is where we finally receive our access token from Square so we can process API requests for our user. Here, we need to provide the authorization code we received in the redirect to our callback url &lt;em&gt;and&lt;/em&gt; our own application secret (which is acquired when registering with Square) in order to get our user’s access token. The access token can then be used to make API calls on behalf of our user.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Benefits
&lt;/h3&gt;

&lt;p&gt;We’ve gone through a few analogies and it’s clear that this process is a lot more complicated than simply asking a user for their password or making your user go get a special access token for you. The complexity ensures the process is secure — but it also gifts us more flexibility.&lt;/p&gt;

&lt;p&gt;If we simply ask a user for their password, and they forget their Square password, then we’ll have to update our system with this new password and our integration would likely break in the interim &lt;strong&gt;&lt;em&gt;(also, don’t ever ask for someone’s password)&lt;/em&gt;&lt;/strong&gt;. We also give the end users the ability to gracefully revoke access without having to change their password.&lt;/p&gt;

&lt;p&gt;In addition, since we specified the scope up front, we only have to give access to whatever was specified. This means the end user can make an informed decision on what’s being granted. When providing a password, you can’t really control what’s being accessed. It’s all or nothing.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Implementation
&lt;/h3&gt;

&lt;p&gt;In order to solidify our understanding of OAuth, we’ll actually walk through an implementation of Square’s OAuth. There is a fully functional example over at &lt;a href="https://glitch.com/~square-oauth-example"&gt;https://glitch.com/~square-oauth-example&lt;/a&gt;. You can take a look at the source code and even remix it to have it work with your own account; just be sure to add in your own variables in the &lt;code&gt;.env&lt;/code&gt; file. We’ll cover the core parts of the process, but we won’t be going into detail on things like storing user credentials or how best to handle session persistence.&lt;/p&gt;

&lt;p&gt;The example is built using Express and SQLite. Express allows us to direct our users to the correct authorization URL and handle callbacks while SQLite allows us to store the token, and eventually renew or revoke the token. The last step there is important for a full implementation, since we don’t really want our users having to re-authorize our application every 30 days (the length an access token is valid for).&lt;/p&gt;

&lt;p&gt;Before getting into writing code for our implementation we need to sign up for a Square Developer Account. We need to create an application and acquire our Application Secret and set our redirect URL. The redirect URL is where the user will be sent &lt;em&gt;after&lt;/em&gt; they have signed-in and granted our application permission to access their account.&lt;/p&gt;

&lt;p&gt;We’ll start off creating our route for handling sending the user to the authorization URL where we as for our permissions. Here’s what our route will look like:&lt;/p&gt;


&lt;div class="glitch-embed-wrap"&gt;
  &lt;iframe src="https://glitch.com/embed/#!/embed/square-oauth-example?path=routes%2Fauth.js%3A14%3A0" alt="square-oauth-example on glitch"&gt;&lt;/iframe&gt;
&lt;/div&gt;
&lt;br&gt;
Our authorize route start on line 14.

&lt;p&gt;For those unfamiliar with Express, the &lt;code&gt;req&lt;/code&gt; parameter is just our request object and the &lt;code&gt;res&lt;/code&gt; parameter is our response object. We are also using Mozilla’s &lt;code&gt;client-sessions&lt;/code&gt; middleware for creating encrypted cookies, which are accessible via &lt;code&gt;req.auth&lt;/code&gt;. We start our method with checking if the user has already been authenticated, so we could skip needing to run through our whole authorization process. If the user hasn’t previously authorized with us, we initialize their &lt;code&gt;state&lt;/code&gt; and store it in their cookie using &lt;code&gt;req.auth&lt;/code&gt; so that we could later verify it to mitigate &lt;a href="https://www.owasp.org/index.php/Cross-Site_Request_Forgery_(CSRF)"&gt;CSRF&lt;/a&gt;. After that, we’re simply constructing our authorization URL for redirecting the user. The &lt;code&gt;CLIENT_ID&lt;/code&gt; is our application ID found at &lt;a href="https://developer.squareup.com/apps"&gt;https://developer.squareup.com/apps&lt;/a&gt; for our specific application. Take a note of the &lt;code&gt;scope&lt;/code&gt; and how we’re limiting this application to only read the &lt;code&gt;MERCHANT_PROFILE&lt;/code&gt; to limit our access to read-only access on our user’s profile. If we needed more access, we could request more by adding additional values to the &lt;code&gt;scope&lt;/code&gt; URL parameter.&lt;/p&gt;

&lt;p&gt;Next, we want to show how to construct our redirect URL for handling the callback. Here is our example (I’ll forewarn, this part looks a little bit dense):&lt;/p&gt;


&lt;div class="glitch-embed-wrap"&gt;
  &lt;iframe src="https://glitch.com/embed/#!/embed/square-oauth-example?path=routes%2Fauth.js%3A33%3A0" alt="square-oauth-example on glitch"&gt;&lt;/iframe&gt;
&lt;/div&gt;
&lt;br&gt;
Our callback route starts on line 33.

&lt;p&gt;We immediately start off by checking that the &lt;code&gt;state&lt;/code&gt; in the query string matches what was stored in the user’s encrypted cookie, since we don’t want to process unauthorized requests. Then we’re simply POSTing our payload to &lt;code&gt;https://connect.squareup.com/oauth2/token&lt;/code&gt; in order to get our access token for our user. Everything after that is simply querying Square’s API for some user information and creating our user in the database (we’re using &lt;a href="http://docs.sequelizejs.com/"&gt;Sequelize&lt;/a&gt; as an ORM to simplify things). I would like to point out as well that we’re only storing the user’s &lt;code&gt;id&lt;/code&gt; in the cookie and no other personal information, because even though the cookie is encrypted, we don’t want to store sensitive information there. You need to treat access tokens like passwords, and you wouldn’t store passwords in unsafe places, so do the same for access tokens. In this example application, we’re going the extra step to encrypt the tokens before storing them and decrypting them when we need to use them.&lt;/p&gt;

&lt;p&gt;Finally, we’ll cover renewal and revocation. Although these steps are optional, they’re extremely useful to implement to create a better user experience. Square allows access tokens to remain valid for 30 days, after which, you would need to renew them. You have a 15-day window to renew an access token.&lt;/p&gt;


&lt;div class="glitch-embed-wrap"&gt;
  &lt;iframe src="https://glitch.com/embed/#!/embed/square-oauth-example?path=routes%2Fauth.js%3A80%3A0" alt="square-oauth-example on glitch"&gt;&lt;/iframe&gt;
&lt;/div&gt;
&lt;br&gt;
Our renew route begins on line 80.

&lt;p&gt;The renewal step is fairly straightforward: we just post the access token to &lt;code&gt;https://developer.squareup.com/oauth2/clients/${CLIENT_ID}/access-token/renew&lt;/code&gt; with our application secret used in the authorization header.&lt;/p&gt;

&lt;p&gt;You can find the detail of revoking a token starting on line 105 in our example below:&lt;/p&gt;


&lt;div class="glitch-embed-wrap"&gt;
  &lt;iframe src="https://glitch.com/embed/#!/embed/square-oauth-example?path=routes%2Fauth.js%3A105%3A0" alt="square-oauth-example on glitch"&gt;&lt;/iframe&gt;
&lt;/div&gt;
&lt;br&gt;
Our revoke route begins on line 105.

&lt;p&gt;Revoking a token is even easier, since we just post our client id and access token to &lt;code&gt;https://developer.squareup.com/oauth2/revoke&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;We’ve covered each step in the process of creating an OAuth integration with Square to show how each method works, but there are a lot of libraries out there that simplify this process for you (&lt;a href="http://www.passportjs.org/"&gt;PassportJS&lt;/a&gt;, &lt;a href="https://github.com/simov/grant"&gt;Grant&lt;/a&gt;, and many others). If you’ve never implemented OAuth before, it’s useful to see a full integration like this in order to understand each step of the process better (which always helps with debugging down the road).&lt;/p&gt;

&lt;p&gt;I highly encourage you to sign up for a &lt;a href="https://squareup.com/developers"&gt;Square developer account&lt;/a&gt; and try out this integration. You can just visit &lt;a href="https://square-oauth-example.glitch.me/"&gt;https://square-oauth-example.glitch.me/&lt;/a&gt; and authorize your Square account there. Feel free to remix the example on Glitch to try getting your &lt;em&gt;own&lt;/em&gt; OAuth integration working. You can also check out our OAuth &lt;a href="https://developer.squareup.com/docs/authz/oauth/build-with-the-api"&gt;guide&lt;/a&gt; and &lt;a href="https://developer.squareup.com/docs/authz/oauth/how-it-works"&gt;overview&lt;/a&gt; for more instruction on getting setup.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Want more? &lt;a href="https://www.workwithsquare.com/developer-newsletter.html?channel=Online%20Social&amp;amp;sqmethod=Blog"&gt;Sign up&lt;/a&gt;&lt;/em&gt; &lt;em&gt;for our monthly developer newsletter.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>beginners</category>
      <category>square</category>
    </item>
  </channel>
</rss>
