Integrating the Braintree Payment solution in React Native/Expo and Node.js


Recently got on a project to integrate Braintree as a payment system on an Expo project, and couldn't find any resources on doing that, so this is my attempt at one.

In this article, we will integrate the Braintree API Gateway SDK along with Node.js and Express, and then we will create a front-end application using Expo/React Native.

At the end of this, you should have a functioning integration that accepts credit/debit card payments in sandbox using Braintree Direct's drop-in user interface.

Getting Started

So, to get started, the first step would be installing the braintree server npm module on your expressjs project.

npm install braintree --save

When we have that installed, we want to setup a payment controller & route to resolve transactions through the Braintree payment gateway.

const braintree = require("braintree");

// Set your secret key. Remember to switch to your live secret key in production.
const gateway = new braintree.BraintreeGateway({
  environment: braintree.Environment.Sandbox,
  merchantId: process.env.BRAINTREE_MERCHANT_ID,
  publicKey: process.env.BRAINTREE_PUBLIC_KEY,
  privateKey: process.env.BRAINTREE_PRIVATE_KEY,
});'/createPaymentTransaction', async (req, res) => {
  const { body } = req;

  try {

    //create a transaction 
    const result = await{
      amount: body.amount,
      paymentMethodNonce: body.nonce,
      options: {
        submitForSettlement: true

      isPaymentSuccessful: result.success,
      errorText: result.transaction?.processorResponseText || "",

  } catch (error) {
    console.log("Error in creating transaction ", error);
      isPaymentSuccessful: false, errorText: "Error in creating the payment transaction" + error


To test if the above is working properly, you can pass 'fake-valid-nonce' to the nonce key using Postman or other API clients.


Next, Setup HTML client

We want to collect the customer payment information. The easiest way to get up and running is via the Drop-in UI. We'd be serving the HTML file via express.


  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width,initial-scale=1">
  <script src=""></script>

<body style="display:flex;flex-direction: column;">
  <div id="dropin-container"></div>
  <button id="submit-button" class="paymentButton">COMPLETE PAYMENT</button>
    var button = document.querySelector('#submit-button');
      authorization: '', //the tokenization key from Braintree
      container: '#dropin-container'
    }, function (createErr, instance) {
      button.addEventListener('click', function () {
        button.textContent="PROCESSING PAYMENT";
        instance.requestPaymentMethod((requestPaymentMethodErr, payload) => {
          // Send payload to React Native to send to the server


Key things from the HTML file above

The authorization property when setting up the braintree dropin ui. We'd be using the Braintree tokenization key, here's Braintree's guide on getting the key.

When the drop-in client SDK communicates the customer's card information to Braintree, Braintree returns a payment method nonce, and we want to send that to React Native. We do that by using the window.ReactNativeWebView.postMessage method

The express routing to serve the HTML file:

const path = require('path');

app.get('/braintree', function (req, res) {
  res.sendFile(path.join(__dirname, 'braintree.html'));

Lastly, Setup React Native Client

We want to embed the HTML served by express in a webview on react native. First, install the react-native-webview package.

npm install --save react-native-webview

Or if you're using Expo,

expo install react-native-webview

After installing the webview package, we'd be creating the component to embed the /braintree route in the Webview.

const HOST = "";

const BrainTreePaymentWebView = ({
}) => {

  return (
    <View style={{ height: 450 }}>
      <Text style={{fontSize: 30, fontWeight: '500'}}>BrainTree Payment Integration</Text>
        source={{ uri: `${HOST}/braintree` }}
        onMessage={(event) => {

After creating the Braintree component, we'd want to get the payment nonce to the Braintree payment transaction resolver route, createPaymentTransaction.

        onNonceRetrieved={async (nonce) => {
          const response = await`${HOST}/createPaymentTransaction`, {
            amount: 10, //change to price gotten from your user
            nonce: nonce,
          const { isPaymentSuccessful, errorText } = await;
          Alert.alert(isPaymentSuccessful ? "Payment successful" : `Payment error - ${errorText}`);

And, we are done!!!!

To test the Braintree payment integration, use the following test cards provided by Braintree.

When you click on Complete Payment, the app should show an alert informing you that the Payment is successful.


The Working version of this article is available on GitHub —

Here are some resources/documentation that could be helpful during your integration:


Edwards Moses - Web & Mobile — React & React Native Consultant

Edwards Moses
Web & Mobile — React & React Native Consultant

I'm Edwards, based in Lagos, Nigeria.
Freelancer Software Developer — collaborating with teams to craft extraordinary products.
From conception through to completion, I find immense joy in witnessing the evolution of an idea into a fully realized product in the hands of users.

Ready to bring your ideas to life? Let's connect