Back to blogs

Tech & Trends

08. 12. 2020

Stripe in-app payments in React Native

by Masimo Orbanić

Stripe is currently one of the best payment services that you can use in your web and mobile applications. It offers many features like subscriptions, the option to collect payments from customers and pay them out to sellers or service providers, invoicing, and many other good things. It is also very developer-friendly, it has support for popular programming languages, Webhooks for all types of events and the developer documentation is well written.

Stripe does not have an official package for React Native, but the community has some libraries to offer. One of them is tipsi-stripe. The stable release of tipsi-stripe is not currently supported (December 2020) because the last stable release is from August 2019, and since then the EU Strong Customer Authentication (SCA) came into power. It requires a major update of the package because the native part of the package has been updated. The version of tipsi-stripe that supports SCA 8.0.0-beta.11 is still being developed.

Another package is react-native-stripe-payments, it has a stable release that supports SCA, but accepts only payments with credit cards. Other methods are not supported. We in Lloyds are using react-native-stripe-payments and so far it is working well.

What do you need in order to implement Stripe?

The first thing you will need is, of course, a Stripe account. After you create one, you are free to jump into testing mode by turning on the test mode (“View test data” switch in the sidebar). To switch Stripe to production environment, you must enter a bunch of company data and bank account information to receive payments. Also, you must be sure that Stripe is available in the country where the company is registered.

In order to have Stripe in your React Native app, you must have a backend where the majority of the checkout process is defined. The official Stripe package is available for Node, Ruby, Python, PHP, .NET, Java and Go. In Lloyds we are using Laravel, a PHP framework.

How it works?

Everything is revolving around Payment intents. Payment intents track a payment, from initial creation through the entire checkout process, and triggers additional authentication steps when required. In order for react-native-stripe-payments to work, you must have client_secret which is retrieved from the backend where the payment intent is created.

The flow is:

  1. user presses the BUY button,
  2. a request containing items to buy is sent to the backend,
  3. payment intent is created on the backend and client_secret is returned in the response,
  4. user is prompted to enter credit card details,
  5. payment is confirmed on the client-side using client_secret and credit card details,
  6. payment confirmation is recorded in the backend using Stripe Webhooks

Since the items to buy and client_secret are the only two thing shared between client and server, this process is very secure, there is very little room for the corruption of the payment process.

Backend

Backend is used to create Payment intent and to store information about the transactions that occurred.

First, we add the Stripe package to our framework so our backend can communicate with Stripe.

In total, the basic implementation of Stripe requires two API endpoints to be created:

  • to create payment intent and return client_secret to client
  • Webhook URL to receive information from Stripe about a successful payment

The endpoint to create payment intent is used to create payment intent and to bind created payment intent to order in the database. The order in the database must have stored information about payment intent because the payment is not confirmed yet, the confirmation of the payment is done through the Webhook endpoint. The response must contain client_secret, which can be found in the created Payment intent object.

The request from Stripe to our backend (Webhook) contains data about the payment intent, so we can find an order which is bound to payment intent in the database and mark that order as completed. Webhook can be configured on Stripe dashboard. The event that you want to trigger is payment_intent.succeeded. That is just the basic setup, but with Stripe Webhooks you can configure Webhook for many types of events, in other words, notify your backend about the change that occurred.

React Native

As mentioned earlier, we will use the react-native-stripe-payments package. Installation of the package does not require any linking process, everything is handled with autolinking.

The package is very simple and does not require a lot of configuration. The first thing we must do is to call setOptions method and pass the Stripe publishing key:

import stripe from 'react-native-stripe-payments';

stripe.setOptions({ publishingKey: 'STRIPE_PUBLISHING_KEY' });

Next thing, as we described in the “How it works” section, we’ll send a request to your backend on route to create payment intent. In the request, you can pass the cart_id, or array of cart items that are being bought, as long as you can calculate the total price, you are good.
If the request was successful, the backend should return you the client_secret, and you can prompt the user to enter his credit card details. You can create your own design of the credit card input, or you can use react-native-credit-card-input or some other credit card input package. You can check if the credit card is valid using the stripes isCardValid method. For testing you can find the test credit cards here.

When you have client_secret and valid credit card, you can run the confirmPayment method:

stripe.confirmPayment('client_secret_from_backend', cardDetails)
  .then(result => {
    // payment was successful
  })
  .catch(err =>
    // error occurred
  )

If the payment was successful, Stripe will fire a Webhook request to the backend, and the backend will make a record that the transaction occurred and store data relevant to the transaction so the transaction can be back-traced if needed. You can also check the received payments on the Stripe dashboard and make sure that the transaction was successful.

Conclusion

The process of payment on the web and in mobile apps is evolving and is being made secure every day. It is on the developer to create flexible solutions and quickly respond to the changes that need to be made. Also, don’t forget to check if you are viewing the test data or live data on the Stripe dashboard