Introduction

Today we will see how to make payments in our React Native application. To do this, we will use braintree. Braintree is a service that helps accept, process and split payments. It is a Paypal service.

Set up braintree

To use braintree, you need to create an account. After that, we can use their sandbox to test our application.

In the sandbox, we can see the total of transactions, the total sales volume, and a bunch of other options. Also, we can list our transactions.

Using the sandbox, we can use fake cards, as you can see in the page Testing and Go Live. There are some cards that can return errors and we can test our application with these errors.

Currently, braintree has some SDK. For ruby, python, php, JavaScript and other languages. I have set up the Ruby one, using the braintree example app.

In our Ruby side, we receive the following request:

result = Braintree::Transaction.sale(
  :amount => amount,
  :payment_method_nonce => 'fake-valid-nonce',
  :options => {
    :submit_for_settlement => true
  }
)

You can check it in the documentation in the part from Payment method nonces.

So, our react native application should send these parameters.

Let's create our React Native app.

Project

We will use our DailyDrip Starter App from the last episode.

Let's clone this to a folder called RNPayments.

git clone git@github.com:dailydrip/react-native-starter-app.git RNPayments

Let's install the dependencies, and run our app.

yarn
react-native run-ios

Ok. Everything works. Let's start our implementation.

Implementation

API

Let's create our API call.

vim src/api.js
const BASE_URL = "http://localhost:3000";

const api = {
  pay: function(amount) {
    const nonce = {
      amount: amount,
      payment_method_nonce: "fake-valid-nonce",
      options: {
        submit_for_settlement: true
      }
    };
    return fetch(`${BASE_URL}/pay`, {
      method: "POST",
      headers: {
        "Content-Type": "application/json"
      },
      body: JSON.stringify({ nonce })
    });
  }
};

export default api;

In our back-end we have a route /pay that receives our amount and in our case, we are using the payment_method_nonce. Using this, we don't need to associate a credit card. We just need to pass the amount.

In our app, as we are just passing the amount, we will have some buttons and we will say the amount is a donation.

Redux actions

We will use redux-thunk to handle the side effects of our application. We don't have an action file yet. Let's create it.

vim src/reducers/actions.js
import API from "../api";

function pay(amount) {
  return dispatch => {
    API.pay(amount)
      .then(response => {
        console.log(response);
        if (response.status === 200) {
          dispatch(gotSuccessfulResponse());
        } else {
          dispatch(gotErrorResponse());
        }
      })
      .catch(err => console.log(err));
  };
}

function gotSuccessfulResponse() {
  return {
    type: "SUCCESS_RESPONSE"
  };
}

function gotErrorResponse() {
  return {
    type: "ERROR_RESPONSE"
  };
}

export default {
  pay,
  gotSuccessfulResponse,
  gotErrorResponse
};

We will have an action pay. We will receive the amount. If the response is successful, we will dispatch the action gotSuccessfulResponse. If not, we will dispatch gotErrorResponse.

These two last actions are used to show a message as feedback to the user. Let's implement our reducer.

Reducer

We will change our current reducer, and we will pass the two actions we have from the response.

import { combineReducers } from "redux";
import navReducer from "./navReducer";

const initialGenericState = { message: "" };

function genericReducer(state = initialGenericState, action) {
  switch (action.type) {
    case "SUCCESS_RESPONSE":
      let newMessage = "Thanks!";
      return { ...state, message: newMessage };
    case "ERROR_RESPONSE":
      newValue = "There was an error in your transaction";
      return { ...state, message: newMessage };
    default:
      return state;
  }
}

export default function getRootReducer(navReducer) {
  return combineReducers({
    nav: navReducer,
    generic: genericReducer
  });
}

Here we will handle our two cases, one case for SUCCESS_RESPONSE and another for ERROR_RESPONSE. Related to each response, we will have a specific message.

Changing our app

// @flow

import React, { Component } from "react";
import { AppRegistry, StyleSheet, Text, View, Button } from "react-native";
import Styles from "./Styles/AppStyles";
import Routes from "../routes";
import { DrawerNavigator } from "react-navigation";
import { connect } from "react-redux";
import Actions from "./reducers/actions";

const App = props => {
  return (
    <View style={Styles.container}>
      <Text style={Styles.welcome}>
        Donate some money!
      </Text>
      <Button onPress={() => props.pay(1)} title="Donate $1" />
      <Button onPress={() => props.pay(10)} title="Donate $10" />
      <Button onPress={() => props.pay(20)} title="Donate $20" />
      <Button onPress={() => props.pay(100)} title="Donate $100" />
      <Button onPress={() => props.pay(120)} title="Donate $120" />
      <Text> {props.message} </Text>
    </View>
  );
};

const mapStateToProps = state => {
  return { message: state.generic.message, nav: state.nav };
};

const mapDispatchToProps = dispatch => ({
  pay: amount => dispatch(Actions.pay(amount))
});

export default connect(mapStateToProps, mapDispatchToProps)(App);

Let's change our view. In our connection with redux, we will get the message from the state. We will also use the Actions.pay and pass the desired amount. Now we have message and the method pay in our props.

Let's implement some buttons with some amounts. Once the person presses the button, we will make the API request. As we implemented in our action, we will change the message and the message will be shown. So, we will also show the message in a <Text> tag.

This is our entire implementation.

To test that, we will have the logs of our rails application and we will also see the transactions in the sandbox.

Let's run our app. Now, let's donate $1. We can see this in the rails logs. And now, we can check in the braintree transactions. Now, let's donate $120. Checking the rails log, it's here... and we can see the $120 in the braintree transactions.

Summary

We have implemented a simple method of payment using braintree. We saw how easy It was. Braintree is really good and it has a sandbox we can use for testing.

Resources

Franzé Jr

Software Engineer with experience working in multi-cultural teams, Franze wants to help people when he can, and he is passionate about programming and Computer Science. Founder of RemoteMeetup.com where he can meet people all over the World. When Franze is not coding, he is studying something about programming.

  1. Comments for Payments in React Native: Using braintree

You must login to comment

You May Also Like