<?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>DEV Community: Richard Moot</title>
    <description>The latest articles on DEV Community by Richard Moot (@mootrichard).</description>
    <link>https://dev.to/mootrichard</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%2Fuser%2Fprofile_image%2F65506%2Fa01d278a-b557-4b22-88c6-e3bec6ae367b.jpeg</url>
      <title>DEV Community: Richard Moot</title>
      <link>https://dev.to/mootrichard</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/mootrichard"/>
    <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://dev.to/squaredev/card-on-file-with-react-native-4b3e</link>
      <guid>https://dev.to/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://dev.to/squaredev/online-payments-with-react-square-30ke</link>
      <guid>https://dev.to/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://dev.to/squaredev/stop-using-servers-to-handle-webhooks-5f7g</link>
      <guid>https://dev.to/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://dev.to/squaredev/announcing-square-s-new-python-sdk-49pb</link>
      <guid>https://dev.to/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>The Squavenger Hunt</title>
      <dc:creator>Richard Moot</dc:creator>
      <pubDate>Fri, 31 May 2019 00:21:36 +0000</pubDate>
      <link>https://dev.to/mootrichard/the-squavenger-hunt-c72</link>
      <guid>https://dev.to/mootrichard/the-squavenger-hunt-c72</guid>
      <description>&lt;p&gt;&lt;a href="https://twitter.com/SquareDev/status/1134083181324296194"&gt;https://twitter.com/SquareDev/status/1134083181324296194&lt;/a&gt;&lt;/p&gt;

</description>
      <category>bash</category>
      <category>terminal</category>
      <category>api</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://dev.to/squaredev/square-in-app-payments-sdk-for-react-native-27o5</link>
      <guid>https://dev.to/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://dev.to/squaredev/making-the-invisible-visible-a-look-at-building-tools-for-square-developers-506</link>
      <guid>https://dev.to/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>Introducing Square In-App Payments SDK</title>
      <dc:creator>Richard Moot</dc:creator>
      <pubDate>Sun, 13 Jan 2019 00:16:57 +0000</pubDate>
      <link>https://dev.to/mootrichard/introducing-square-in-app-payments-sdk-3112</link>
      <guid>https://dev.to/mootrichard/introducing-square-in-app-payments-sdk-3112</guid>
      <description>&lt;p&gt;&lt;a href="https://medium.com/square-corner-blog/introducing-square-in-app-payments-sdk-1fc93b32814c"&gt;https://medium.com/square-corner-blog/introducing-square-in-app-payments-sdk-1fc93b32814c&lt;/a&gt;&lt;/p&gt;

</description>
      <category>payments</category>
      <category>api</category>
      <category>mobile</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://dev.to/squaredev/square-reader-sdk-for-react-native-be0</link>
      <guid>https://dev.to/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://dev.to/squaredev/square-api-versioning-for-connect-v2-4l91</link>
      <guid>https://dev.to/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>Would you appreciate an SDK being written in TypeScript?</title>
      <dc:creator>Richard Moot</dc:creator>
      <pubDate>Fri, 06 Jul 2018 00:09:16 +0000</pubDate>
      <link>https://dev.to/mootrichard/would-you-appreciate-an-sdk-being-written-in-typescript-hbl</link>
      <guid>https://dev.to/mootrichard/would-you-appreciate-an-sdk-being-written-in-typescript-hbl</guid>
      <description>&lt;p&gt;I'm curious if Node/JavaScript developers would appreciate an SDK having been written in TypeScript, even if only wanting to use the transpiled JavaScript. My inclination is the additional type checking would be appreciated and help save developers from odd mistakes of data type being passed back from the SDK. &lt;/p&gt;

&lt;p&gt;I know its a little extra overhead and adds a bit to the package size, but would you use it? (For context, this would be an SDK for interacting with a RESTful API).&lt;/p&gt;

</description>
      <category>discuss</category>
      <category>javascript</category>
      <category>typescript</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://dev.to/squaredev/serverless-instant-checkout-links-59mn</link>
      <guid>https://dev.to/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>
  </channel>
</rss>
