Accepting Payments in a React Native App (Part 2)
Building A Server Using Amazon Web Services
Background
This article is part two of a four part series on integrating a payment system into a React Native mobile application.
The other articles can be found here:
1. Project Introduction. This section may not sound like much, but it’s a good explanation on how everything will fit together.
2. Application Server using Amazon Web Services. This portion explains how to interact with Braintree’s server in a secure manner.
3. Initial Version Using Vanilla-JavaScript discusses building an application that can receive payments.
4. React Component Based Version is about putting React inside a React Native application.
This article describes the Braintree’s data flow involving a client, an application server, and Braintree’s server. I’ll then present a way to implement that server using an API created using Amazon Web Services (AWS) API Gateway and Lambda.
Introduction
Braintree provides excellent documentation describing the data exchange that happens in order to make secure purchases. I will do my best to describe it here (as I understand and implemented it), but I encourage you to read their get started documentation. Additionally, my description is specific to how the flow relates to using the Drop-in UI element. The Drop-in UI element is described as “…a pre-formatted payment form with a sleek UI in just a few simple lines of code.” It provides a secure easy to set up payment form by sacrificing some flexibility.
- Application gets client token from our server
- Server gets token from Braintree and sends it back to our mobile application
- Client uses that token in order to request a payment form UI element from Braintree
- Braintree provides a secure UI component for the mobile application to display
- Mobile application displays that UI component to the user so that user can input payment information and commit the actual purchase at which point the payment information is sent to Braintree
- Braintree then provides a nonce (think of it as an authorization ticket) to the app that basically says “Okay, that user is good to make this purchase. Give this nonce to your server along with the purchase amount.”
- The app then does just that. It sends the nonce to your server along with purchase information such as price, user name, etc.
- Your server’s primary step here is to send the nonce and sales information to Braintree which will in turn transfer money if the nonce is legitimate. It’s at this point that your serve will also record transaction data to a database, but that really has nothing to do with Braintree. The server also sends a message back to the client notifying it if the nonce was accepted.
Note that there are portions where the client interfaces directly with Braintree’s servers. That interaction will be discussed in future articles. This article focuses on the interations between the client, through the application server, to Braintree, as well as the reverse.
Now let’s talk about the pieces that will do all those.
Design
Based on Braintree’s overview its pretty obvious that a server is requirement in order to accept payments. I’m not talking about Braintree’s servers, I’m talking about one for use by the client application.
Braintree provides you with a couple of keys as part of setting up a developer account, and we don’t want any identity or signature keys falling in the wrong hands. That means, we can’t ever let them touch the client whether its a mobile application or web.
Now you could do that server stuff from the client, but that’s a really bad idea.
So we need a server that will provide a client token upon request and also receive a nonce and send that to Braintree upon request. Logically, the server will have two endpoints: one to process “get token” requests and the other to process “post purchase” requests. The endpoints can be created in AWS API Gateway which will connect to the Lambda function that contains the server logic.
This overall design is summarized in the graphic below
Implementation
Let’s start with building the Lambda function that will perform the logic portion of the application server. The “how-to” of creating a Lambda is beyond the scope of this article. I recommend this series by YouTube user Savjee to get up to speed on not just creating Lambdas, but also connecting them to API Gateway. Those two skills are foundational to creating the application server described in this article.
The first step is to create an AWS Lambda function with the following code:
BTW, This Lambda was built on my Lambda API boilerplate located here. As you can see it includes comments on how to perform several actions typical of Lambda API functions.
The code basically converts the Braintree Server example snippets from here https://developers.braintreepayments.com/start/hello-server/node from a node.js Express server to acceptable Lambda code. Also, Since this Lambda will be generating client tokens and submitting purchase transactions, any client using it must pass a query string value that lets the server know what it is doing. An equally valid alternative would be to create separate Lambdas for each piece of functionality.
The other piece of the application server is the API endpoint provided by AWS API Gateway. The important point to note is that API Gateway enables integration with existing Lambda functions on the same account:
Once integrated, the resource and POST
method attached to the Lambda function looks like this:
The connection between API Gateway and the Lambda function can be tested to ensure connectivity and correctness by clicking on “TEST” in the overview page shown above. Passing a query string of “action=get-client-token”
to the test results in the following output:
Conclusion
I hope this article did an adequate job providing an overview on how to replicate an node.js server with Express using AWS API Gateway and Lambda in order to act as an application server to accept Braintree payments.
I will discuss the creating the React Native client in the next article.
Reginald Johnson has maintained his passion for coding throughout his 20+ year career as an Officer in the United States Navy. He enjoys applying his training and experience in programming, Systems Engineering, and Operational Planning towards programming. Follow him Twitter @reginald3.