How to collect Stripe Payment in react native app
Tags: javascript, reactnative, stripe, tutorial
Published: 2022-04-18 19:01:19

Hi folks, today I want to share the procedure of payment integration in react native app through Stripe

* [Registration](#Registration)
* [Installation](#Installation)
* [Configuration](#Configuration)
* [Card Component](#Card Component)
* [Create a Payment Indent](#Payment Indent)
* [Submit the Payment](#Submit Payment)
* [Test Cards](#Test Cards)

### Registration <a name="Registration"></a>
First, you have to create your account on the [Stripe](https://dashboard.stripe.com/register) dashboard. 
Stripe dashboard in test mode will look like this.

![stripe dashboard](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ebzi126w1nvhta0l87ci.png)

### Installation <a name="Installation"></a>
For server-side installation, you can refer to this [link](https://stripe.com/docs/payments/accept-a-payment?platform=react-native&ui=custom#react-native-setup-server-side)
For the react-native side, run this command in terminal
```javascript
yarn add @stripe/stripe-react-native
```
And to install the required native dependencies, run this command in the `ios` folder. Android doesn’t require any additional steps.
```javascript
pod install
```

### Configuration <a name="Configuration"></a>
Now wrap your `<App/>` in `<StripeProvider>` tag and pass your account publishable key to it. You can find this key in the Home tab on the Stripe dashboard.
```javascript
import { StripeProvider } from '@stripe/stripe-react-native';

function App() {
  return (
    <StripeProvider
      publishableKey="pk_test_TYooMQauvdEDq54NiTphI7jx"
      urlScheme="your-url-scheme" // required for 3D Secure and bank redirects
      merchantIdentifier="merchant.com.{{YOUR_APP_NAME}}" // required for Apple Pay
    >
      // Your app code here
    </StripeProvider>
  );
}
```
### Card Component <a name="Card Component"></a>
Stripe has multiple [elements](https://stripe.com/docs/payments/elements) to choose from. I choose **Card Element**, it is a build-in UI component to securely collect card details.
```javascript
import { CardField, useStripe } from '@stripe/stripe-react-native';

function PaymentScreen() {
  // ...
  return (
    <View>
      <CardField
        postalCodeEnabled={false}
        placeholder={{
          number: '4242 4242 4242 4242',
        }}
        onCardChange={(cardDetails) => {
          console.log('cardDetails', cardDetails);
        }}
      />
    </View>
  );
}
```
`onCardChange` the callback returns the non-sensitive information about the card. You can use this info to enable/disable the *Checkout* button or display an error message.

![card details](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nl9klu2scoeigvhoo03m.png)

### Create a Payment Indent <a name="Payment Indent"></a>
After this, we create a payment intent to collect payment from the user.
But to create a Payment Intent we need an API because the server-side is saved as opposed to the client. Please follow these [steps](https://stripe.com/docs/payments/accept-a-payment?platform=react-native&ui=custom#react-native-create-server-side) to create a payment intent API.

Now we'll fetch the *client secret* from this API.
```javascript
function PaymentScreen() {
  const fetchPaymentIntentClientSecret = async () => {
    const response = await fetch(`${API_URL}/create-payment-intent`, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({
        currency: 'usd',
      }),
    });
    const {clientSecret} = await response.json();
    return clientSecret;
  };

  const handlePayPress = async () => {
    if (!card) {
      return;
    }

    // Fetch the intent client secret from the backend.
    const clientSecret = await fetchPaymentIntentClientSecret();
  };

  return (
    <View>
      <CardField
        onCardChange={(cardDetails) => console.log('cardDetails', cardDetails)}
      />
      <Button onPress={handlePayPress} title="Pay" disabled={loading} />
    </View>
  );
}
```

### Submit the Payment <a name="Submit Payment"></a>
Next, we'll send the *client secret* and user details to the `confirmPayment` method, which you can access with the `useConfirmPayment` hook.
```javascript
const {confirmPayment, loading} = useConfirmPayment();
const handlePayPress = async () => {
    // Gather the customer's billing information (for example, email)
    const billingDetails: BillingDetails = {
      email: 'jenny.rosen@example.com',
    };

    // Fetch the intent client secret from the backend
    const clientSecret = await fetchPaymentIntentClientSecret();

    // Confirm the payment with the card details
    const {paymentIntent, error} = await confirmPayment(clientSecret, {
      type: 'Card',
      billingDetails,
    });

    if (error) {
      console.log('Payment confirmation error', error);
    } else if (paymentIntent) {
      console.log('Success from promise', paymentIntent);
    }
  };
```
After that, you can check the statuses of payments on the Stripe dashboard.

![payment statuses](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5l4jo8i2s81zoif4co9h.png)

### Test Cards <a name="Test Cards"></a>
There is a [list](https://stripe.com/docs/testing#cards) of test cards available of different brands to test your payments.

Thank you for reading! 
Feel free to connect on [Twitter](https://twitter.com/Aneeqa_Khan25)