Square In-App Payments SDK for React Native

Square In-App Payments SDK for React Native

A React Native Plugin for the Square In-App Payments SDK

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 npm install — save react-native-square-in-app-payments inside your React Native project and follow the setup guide over here to start accepting payments in your React Native app.

If you’re not already familiar with the In-App Payments SDK, it enables developers to accept Square-powered payments from within their own mobile apps.

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.

Our Order Ahead React Native App for buying Square Legos and demoed at ShopTalk.Our Order Ahead React Native App for buying Square Legos and demoed at ShopTalk.

Getting Your Developer Environment Setup

Prerequisites:

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.

Step 1: Get React Native CLI installed and set-up

npm install -g react-native-cli

Make sure to follow the React Native setup guide for “Building Projects with Native Code”. Using the react-native-square-in-app-payments 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.

Step 2: Add In-App Payments React Native Plugin to your Project

After you’ve setup React Native, you’ll want to follow the Square guide for adding In-App Payments into your React Native project. If you’re starting from scratch, you might want to take a look at the quick-start example application 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.

Quick-start App for React Native In-App Payments Plugin.Quick-start App for React Native In-App Payments Plugin.

Things to Understand for React Native Development with In-App Payments SDK

React Native Interfaces for the In-App Payments SDK

SQIPCore — Used to initialize the In-App Payments SDK in your React Native application.

SQIPCardEntry — Handles the standard credit card form capture. It is worth noting that if you’re wanting to store a Card on File for your user, then you’d want to only use this interface since you cannot store card details using digital wallets.

SQIPApplePay — Although fairly straightforward in the name, this interface is used for handling Apple Pay flow.

SQIPGooglePay — Same thing as the Apply Pay interface, but for handling Google Pay.

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 storing a card on a customer profile, or processing a transaction. You can find more on how this flow works in the Square documentation on.

Routing / Navigation

Although this can vary depending on which library you’re using, its worth explaining the one we use in our example. React Navigation is a commonly used library for routing and navigation in React Native apps.

You can add it by running:

npm install — save react-navigation react-native-gesture-handler
react-native link react-native-gesture-handler

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 stack navigator. 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.

An Order Ahead Example Application

In order (so punny) 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 Orders Push Beta can push that into a Square Point of Sale (POS).

At the root of our app, we use the createAppContainer and createStackNavigator from React Navigation 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 SQIPCore in the componentDidMount() lifecycle method.

import React, {Component} from 'react';
import {
 createStackNavigator,
 createAppContainer
} from 'react-navigation';
import HomeScreen from './screens/Home';
import CheckoutScreen from './screens/Checkout';
import {
 SQIPCore,
} from 'react-native-square-in-app-payments';

const AppNavigator = createStackNavigator({
 Home: HomeScreen,
 Checkout: CheckoutScreen
}, {
 initialRouteName: "Home"
});

const AppContainer = createAppContainer(AppNavigator);

export default class App extends Component {
 async componentDidMount() {
   await SQIPCore.setSquareApplicationId('YOUR_APP_ID');
 }
 render() {
   return <AppContainer />;
 }
}

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.

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.

Next, we’ll dig into our Checkout screen and look inside our componentWillMount() method of our CheckoutScreen component. This is where we set our iOS card entry theme (you need to set these in a styles.xml in Android).

 async componentWillMount(){
   if (Platform.OS === 'ios') {
     await SQIPCardEntry.setIOSCardEntryTheme({
       saveButtonFont: {
         size: 25,
       },
       saveButtonTitle: 'Order 💳 ',
       keyboardAppearance: 'Light',
       saveButtonTextColor: {
         r: 255,
         g: 0,
         b: 125,
         a: 0.5,
       },
     });
   }
 }

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.

onCardEntryComplete() {
   // Update UI to notify user that the payment flow is completed
 }

 async onCardNonceRequestSuccess(cardDetails) {
   try {
     // take payment with the card details
     // await chargeCard(cardDetails);
     await fetch('YOUR_BACKEND_URL', {
       method: 'POST',
       headers: {
         Accept: 'application/json',
         "Content-Type": "application/json"
       },
       body: JSON.stringify({
         nonce: cardDetails.nonce,
         item: this.state.cartItem.item_data,
         customer: this.state.customer
       })
     }).then((resp)=>{
       // Handle resp
     })

     // payment finished successfully
     // you must call this method to close card entry
     console.log(cardDetails);
     await SQIPCardEntry.completeCardEntry(
       this.onCardEntryComplete(),
     );
   } catch (ex) {
     // payment failed to complete due to error
     // notify card entry to show processing error
     await SQIPCardEntry.showCardNonceProcessingError(ex.message);
   }
 }

 onCardEntryCancel() {
   // Handle the cancel callback
 }
 async onStartCardEntry() {
   const cardEntryConfig = {
     collectPostalCode: true,
   };
   await SQIPCardEntry.startCardEntryFlow(
     cardEntryConfig,
     this.onCardNonceRequestSuccess,
     this.onCardEntryCancel,
   );
 }

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

onCardNonceRequestSuccess — 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.

onCardEntryCancel — should be used to handle if a user closes out the card entry form before filling it out and triggering a card nonce response.

onCardEntryComplete — is used to close out the form, but can also be used for handling any state updates to your application.

The React Native Order Ahead App in action.The React Native Order Ahead App in action.

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 react-ing (again, so punny) to the results of what was processed.

Also, to be clear, this is only one way to implement the In-App Payments SDK Plugin 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.

The rest of our capabilities for creating and pushing orders into a Square POS, charging a transaction (taking a payment), and/or storing customer card details will happen in your backend. You can read more about our Orders Push Beta and our Card on File transactions by following the links if you’re interested in building your own app for that, or join our Slack community and ask for help.

If you’re plan on building something on Square using our React Native In-App Payments Plugin and want to write about it (or anything else Square related), please hop into our Slack community and let us know (you can join just to say hi too), we’re always happy to chat about whatever you’re working on.

If you want to keep up to date with the rest of our content, be sure to follow this blog & our Twitter account, and sign up for our developer newsletter! We also have a Slack community for connecting with and talking to other developers implementing Square APIs.

Table Of Contents
View More Articles ›