Stripe in-app payments in React Native
Tags: reactnative, stripe, payment, checkout
Published: 2020-12-08 11:05:29

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.

🚨 Important 🚨

> Since May 2021 Stripe has an official package to support React Native platform called [stripe-react-native](https://github.com/stripe/stripe-react-native) . It's recommended to use the official package for long term support and stability. 



Stripe does not have an official package for React Native, but the community has some libraries to offer. One of them is [tipsi-stripe](https://github.com/tipsi/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](https://github.com/tipsi/tipsi-stripe/tree/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](https://lloyds-design.com/) 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](https://dashboard.stripe.com/register). 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](https://stripe.com/global) 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](https://lloyds-design.com/) we are using Laravel, a PHP framework.

# How it works?

Everything is revolving around [Payment intents](https://stripe.com/docs/payments/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](https://stripe.com/docs/payments/payment-intents#passing-to-client)* 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](https://stripe.com/docs/api) 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](https://dashboard.stripe.com/webhooks). 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](https://github.com/Fitpassu/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](https://stripe.com/docs/keys):

```javascript
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](https://github.com/sbycrosz/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](https://github.com/Fitpassu/react-native-stripe-payments#validate-the-given-card-details). For testing you can find the test credit cards [here](https://stripe.com/docs/testing).

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

```javascript
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](https://dashboard.stripe.com/test/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 🙂

Thank you for reading this! If you've found this interesting, consider leaving a ❤️, 🦄, and of course, share and comment your thoughts!

Lloyds is available for partnerships and open for new projects. If you want to know more about us, click [here](https://lloyds-design.com/).

Also, don’t forget to follow us on [Instagram](https://www.instagram.com/lloyds.design/) and [Facebook](https://www.facebook.com/lloydsgn/)!