DEV Community

Nwanze franklin
Nwanze franklin

Posted on • Updated on

Paypal in React Native WebView

React native is one of the most popular and widely used Javascript cross platform mobile development framework. It is based on ReactJS thus making it easy for developers who are already good with ReactJS to delve into it. For more on React Native check here.

The Process
I was working on a project that needed Paypal integration recently and couldn’t find a stable open source React Native module for it so I came up with an implementation based on WebView.

Steps to complete before implementation

  • Create a Paypal account if you don’t have one already
  • Login to developer and create a sandbox account
  • Create an app with an already existing sandbox account and get a Client ID

Creating a new app with an existing sandbox account

Set up the React Native part

At this point it is assumed that most part of you app is working and perhaps you need the payment part to complete the flow process.
Since we are using WebView there will be a HTML file which we will design to suit our app user interface and a component to communicate with the WebView back and forth.

PayPal.js

Brief explanation of some functions and variables

const patchPostMessageFunction fixes the issue described here.

handleMessage function receives the data emitted from Javascript within paypal.html.

passValues function sends data from react native to paypal.html.

sent key in the state is used to mark when data has been passed from react native to WebView.

paypal.html

<!DOCTYPE html>
<html lang="">
  <head>
    <meta charset="utf-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <title>Paypal</title>
    <script src="https://www.paypal.com/sdk/js?client-id={clientID}"></script>

    <style>
        html, body{
            width: 100%;
            height: 100%;
            margin: 0;
            padding: 0;
            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
            background: linear-gradient(180deg, #3D40AD 0%, #6B6ED7 100%);
        }
        .container{
            height: 100%;
            display: flex;
            margin-left: 20px;
            margin-right: 20px;
            overflow-y: scroll;
            justify-content: center;
            align-items: center;
        }
        p{
            color: white;
            font-size: 16px;
            text-align: justify;
            margin-bottom: 50px;
        }
        #preloaderSpinner{
          display: none;
        }
    </style>
  </head>
  <body>
      <div class="container">
            <div style="justify-content: center; text-align: center">
                <img width="80px" height="80px" src="logo.png"/>
                <p>
                </p>
                <div id="paypal-button-container"></div>
            </div>
      </div>


    <script>
      function payWithPayPal(amount, orderID) {
        paypal
          .Buttons({

            createOrder: function(data, actions) {
                return new Promise(function(resolve, reject){
                  resolve(orderID);
              });
            },
            onApprove: function(data, actions) {
              window.postMessage(JSON.stringify({
                    reference: data.orderID, 
                    message: 'Transaction Successful',
                    status: 'success'
                }));
            }
          })
          .render("#paypal-button-container");
      }
      document.addEventListener("message", function(data) {
        var details = JSON.parse(data.data);
        document.querySelector('p').innerText = "You are about to fund your wallet with USD "+details.amount+" on XYZ. Click on any of the payment options to proceed. Your account will be credited instantly after payment."
        payWithPayPal(details.amount, details.orderID);
      })

    </script>
  </body>
</html>

document.addEventListener("message", function(data)) part listens for message emitted from react native and receives the data sent. This data is then parsed back to JSON, used to prepare a display message and setup PayPal SDK as well.

Transactions are initiated from the server end via an API call and a payload containing the orderID from PayPal is returned.

To initiate a transaction from the backend, PayPal SDKs are very helpful and they can be found here for different languages.

Conclusion

React Native WebView Comes in handy for situations like this as well as plotting some complex animated graphs. I would like to hear from you and learn more too.

Top comments (7)

Collapse
 
wkoutre profile image
Nick

Nwanze,

1) Great write-up! Might want to add “with WebView” to the title. I came here because I use PayPal SDK bridged to RN, and wanted to see if someone out there (you) had a different/better way of doing it.
2) WebView is no longer part of the react-native library. Instead, it’s being maintained by the react-native-community:

github.com/react-native-community/...

Collapse
 
franko4don profile image
Nwanze franklin

Thanks, I should have mentioned the React Native version I used for the Demo. I will update the title accordingly and would also like to see your implementation.

Collapse
 
wkoutre profile image
Nick

I actually use a native module, react-native-braintree-xplat, which I forked and can be found here.

Collapse
 
ali67744 profile image
Mohammad Ali Raza Khan

hey i follow your code i got this error any one up here help me please
could not find "store" in the context of "connect(paypal)". either wrap the root component in a , or pass a custom react contextprovider to and the corresponding react context consumer to connect(paypal) in connect options.

Collapse
 
zchenzy profile image
ZChenzy

Did you run into issues with 2FA on ios? I keep getting 403 when I try to get the code

Collapse
 
bikamdhakal profile image
bikamdhakal

I need a little help from you on my code
cause I have used different payment gateway

Collapse
 
shabax profile image
Muhammad Shahbaz Mancho

if we select Debit or Credit Card option it stuck with message "Something Went Wrong. We'll take you back to the checkout so you can try again."
And try again button not working in webview