Stripe apple pay setup with MERN










Integration of apple pay with stripe:

Create a project directory with a name for example stripe-apple-pay.

Setup Apple Pay with a Stripe in the backend:

Create a folder named backend and move to the root directory, not the backend folder. Initialize the package.json file with the following command ...

npm init


Install some NPM packages ...

npm install stripe dotenv express 


Create a file named .env in the root directory and type the code in the .env file as same as the following...

NODE_ENV = production
PORT = 5000
STRIPE_SECRET_KEY = sk_test_51HrpB1A3RwZlQsxbaw6ocrnmKPFcAPYYd....
STRIPE_PUBLISH_KEY = pk_test_51HrpB1A3RwZlQsxbFQeHBjXsTwtX3YqO....

Create a file named server.js in the backend folder and write the code as same as the following ...

const express = require('express'); const dotenv = require('dotenv'); const stripe = require('stripe')(process.env.STRIPE_SECRET_KEY); /* if we use es module, then we have to use stripe by this way import Stripe from 'stripe'; const stripe = new Stripe(process.env.STRIPE_SECRET_KEY); */ dotenv.config(); const app = express(); // Parse form encoded data app.use(express.json()); // Parse url encoded data app.use(express.urlencoded({ extended: false })); // Setup cors app.use((_, res, next) => { res.header('Access-Control-Allow-Origin', '*'); res.header( 'Access-Control-Allow-Headers', 'Content-Type, Accept, X-Requested-With, Origin', ); next(); }); // to pass stripe publishable key from backend to frontend // with environment variable. app.get('/config', (req, res) => { res.json({ publishableKey: process.env.STRIPE_PUBLISH_KEY }); }); const PORT = process.env.PORT || 5000; app.listen(PORT, () => { console.log( `Server is running in the ${process.env.NODE_ENV} mode on port ${PORT}`, ); });


Setup Apple Pay with a Stripe in the front end:

Generate a react app with the following command in the same project directory...

npx create-react-app frontend


Go to the frontend directory and install the following NPM packages ...

// we can also use fetch api instead of using axios
@stripe/stripe-js @stripe/react-stripe-js react-router-dom axios


To setup stripe payment gateway in the MERN project, firstly we have to go to the index.js file and wrap the entire app with a self-invoking function or we can add an event listener

(async () => {
const { publishableKey } = await fetch('/config').then((response) =>
response.json(),
);

const stripePromise = loadStripe(publishableKey);

ReactDOM.render(
<Elements stripe={stripePromise}>
<App />
</Elements>,
document.getElementById('root'),
);
})();


We can also wrap the entire app with addEventListener...

document.addEventListener('DOMContentLoaded', async() => {
const publishableKey =
'pk_test_51HrpB1A3RwZlQsx.......';

const stripe_key = loadStripe(publishableKey);

ReactDOM.render(
<Elements stripe={stripe_key}>
<App />
</Elements>,
document.getElementById('root'),
);
});


Now go to the package.json file of the frontend directory, and add the following code

"proxy": "http://127.0.0.1:5000",


Now we have to create a file named ApplePay.js(any name can be taken) and create a functional component. Import useStripe and useElements hooks from react-stripe-js. 

We have to use a paymentRequest method of the stripe. This method takes an options object as a parameter to create a paymentRequest object. Options object will take some properties, from which some of the properties are mandatory and some of them are optional.

paymentRequest() method is used to make payments from customers. This method returns an instance of paymentRequest object.


const stripe = useStripe(); const elements = useElements(); const [messages, addMessages] = useMessages(); useEffect(() => { if (!stripe || !elements) { return; } const pr = stripe.paymentRequest({ currency: 'usd', // required country: 'US', // required total: { // required label: 'Demo payment', amount: 1999, }, requestPayerEmail: true, // optional requestPayerName: true, // optional }); }, [stripe, elements, addMessages]);


The instance of paymentRequest object exposes a method named canMakePaymetnRequest() method. By using this method, we can check whether or not we are able to use payment request API or apple pay API.

In safari, it uses the apple pay API and other browsers use the payment request API.
This method returns a promise which resolves an object including properties like
{applePay: true, googlePay: false}

Now load the paymentRequestButtonElement element with the options after checking the presence of the instance of paymentRequest object.


<h2>Apple Pay - Payment Form</h2>
{/* load payment request button element after checking the
        instance of payment request object */}
{paymentRequest && (
<PaymentRequestButtonElement options={{paymentRequest}} />
 )}

But the button doesn't show yet because before showing the button, we have to fulfill some prerequisites ...

  1. must have a domain registered with stripe
  1. the page needs to be hosted with https.
  1. need to have cards set up with our apple pay wallet


To test the apple pay we need to 

  1. deploy to a staging environment that has a public domain. or
  2. use tunneling software like ngrok that provides us a public domain.

Setup ngrok to get a public domain with https:

Follow the official website of ngrok for downloading and installing the ngrok. After doing that, type the following code to create a ngrok domain with https 

ngrok http 3000 --host-header=rewrite

After pressing enter, it will show a domain with https of our app which has been hosted by localhost. Take the domain URL from the terminal and paste it into the web browser. If it shows the website, then it works properly.

Now go to stripe dashboard --> settings --> Payment method --> Apple pay --> Configure --> Add new domain (button) --> paste the newly created domain with ngrok --> download the verification file.

Now create a folder named .well-known in the public directory of the project's frontend directory. Put the verification file into the .well-known directory.
Put the domain without https::// and / at the end as same as ...


3ba3-37-111-238-219.ngrok.io

Check the URL is perfectly created or not. For this, just copy the URL and paste it into the browser. If download the file started, then it is properly customized.

Then press add button and the domain will accept as expected.

Create and confirm payment intent:

Here the payment request object emits several events. One of the events is the cancel event. 
But now we will work with the payment method event. It will register a handler. 

With this handler, we will send a request to the server or backend to create a payment intent object and then will confirm payment in the client here.


Post a Comment

Previous Post Next Post