How to Integrate Stripe Payment Gateway In Node.js 2022
Stripe is the most popular and secure payment gateway. In this article, we will integrate stripe(server-side) with our node.js(express) project step by step.
1. Let's create a new express project using express generator.
npm install -g express-generator
express node-stripe --view=hbs //node-stripe is project name
2. Install stripe npm package.
npm install --save stripe
3. Create a new folder config. inside this folder create a file stripe.js
config/stripe.js
module.exports = {
secretKey: process.env.STRIPE_SECRET_KEY, // Secret KEY: https://dashboard.stripe.com/account/apikeys
}
4. Create a .env file and add the stripe secret key environment variable.
STRIPE_SECRET_KEY= // your secret key
5. Install dotenv npm package.
npm i dotenv
After Installation import dotenv in app.js
require('dotenv').config();
Stripe API Keys - https://dashboard.stripe.com/account/apikeys
Note:- For sandbox keys click on test mode option on the stripe dashboard.
Stripe API
Stripe API provides a bunch of methods to simplify the integration process. stripe payment is divided into two steps.
(a). Tokenization:- In this step stripe collects sensitive card or bank account details and returns a token.
const stripe = require('stripe')('sk_test_0CaAJrFqtvoLO3pfWUayDGgK');
const token = await stripe.tokens.create({
card: {
number: '4242424242424242',
exp_month: 2,
exp_year: 2023,
cvc: '314',
}
});
Ref:- Stripe API Reference - Create a card token
(b). Charge:- In this step stripe will charge the amount using the token created during tokenization
const stripe = require('stripe')('sk_test_0CaAJrFqtvoLO3pfWUayDGgK');
const charge = await stripe.charges.create({
amount: 2000,
currency: 'usd',
source: 'tok_amex',
description: 'My First Test Charge'
});
Note:- amount should be passed in the smallest currency unit. In the above example, 2000 is 20USD. description is optional.
you can also pass extra data in form of key-value pair in metadata field.
Ref:-Stripe API Reference - Create a charge
So let's continue with the integration...
6. We need to create a payment form.
views/index.hbs
<main>
<div class="row">
<aside class="col-sm-6 offset-3">
<article class="card">
<div class="card-body p-5">
<ul class="nav bg-light nav-pills rounded nav-fill mb-3" role="tablist">
<li class="nav-item">
<a class="nav-link active" data-toggle="pill" href="#nav-tab-card">
<i class="fa fa-credit-card"></i> Credit Card</a>
</li>
</ul>
<div class="tab-content">
<div class="tab-pane fade show active" id="nav-tab-card">
{{#each message}}
<p class="alert alert-{{@key}}">{{ this.[0] }}</p>
{{/each}}
<form role="form" method="POST" id="paymentForm" action="/payment">
<div class="form-group">
<label for="username">Full name (on the card)</label>
<input type="text" class="form-control" name="fullName" placeholder="Full Name">
</div>
<div class="form-group">
<label for="cardNumber">Card number</label>
<div class="input-group">
<input type="text" class="form-control" name="cardNumber" placeholder="Card Number">
<div class="input-group-append">
<span class="input-group-text text-muted">
<i class="fab fa-cc-visa fa-lg pr-1"></i>
<i class="fab fa-cc-amex fa-lg pr-1"></i>
<i class="fab fa-cc-mastercard fa-lg"></i>
</span>
</div>
</div>
</div>
<div class="row">
<div class="col-sm-8">
<div class="form-group">
<label><span class="hidden-xs">Expiration</span> </label>
<div class="input-group">
<select class="form-control" name="month">
<option value="">MM</option>
{{#each months}}
<option value="{{inc @index}}">{{this}}</option>
{{/each}}
</select>
<select class="form-control" name="year">
<option value="">YYYY</option>
{{#each years}}
<option value="{{this}}">{{this}}</option>
{{/each}}
</select>
</div>
</div>
</div>
<div class="col-sm-4">
<div class="form-group">
<label data-toggle="tooltip" title=""
data-original-title="3 digits code on back side of the card">CVV <i
class="fa fa-question-circle"></i></label>
<input type="number" class="form-control" placeholder="CVV" name="cvv">
</div>
</div>
</div>
<button class="subscribe btn btn-primary btn-block" type="submit"> Confirm </button>
</form>
</div>
</div>
</div>
</article>
</aside>
</div>
</main>
Note:- please checkout github repo - https://github.com/ultimateakash/node-stripe
7. Create a new folder controllers. inside this folder create a file payment.controller.js
controllers/payment.controller.js
const Moment = require('moment');
const MomentRange = require('moment-range');
const moment = MomentRange.extendMoment(Moment);
const config = require('../config/stripe');
const stripe = require('stripe')(config.secretKey);
exports.index = (req, res) => {
const fromDate = moment();
const toDate = moment().add(10, 'years');
const range = moment().range(fromDate, toDate);
const years = Array.from(range.by('year')).map(m => m.year());
const months = moment.monthsShort();
return res.render('index', { months, years, message: req.flash() });
}
exports.payment = async (req, res) => {
const token = await createToken(req.body);
if (token.error) {
req.flash('danger', token.error)
return res.redirect('/');
}
if (!token.id) {
req.flash('danger', 'Payment failed.');
return res.redirect('/');
}
const charge = await createCharge(token.id, 2000);
if (charge && charge.status == 'succeeded') {
req.flash('success', 'Payment completed.');
} else {
req.flash('danger', 'Payment failed.');
}
return res.redirect('/');
}
const createToken = async (cardData) => {
let token = {};
try {
token = await stripe.tokens.create({
card: {
number: cardData.cardNumber,
exp_month: cardData.month,
exp_year: cardData.year,
cvc: cardData.cvv
}
});
} catch (error) {
switch (error.type) {
case 'StripeCardError':
token.error = error.message;
break;
default:
token.error = error.message;
break;
}
}
return token;
}
const createCharge = async (tokenId, amount) => {
let charge = {};
try {
charge = await stripe.charges.create({
amount: amount,
currency: 'usd',
source: tokenId,
description: 'My first payment'
});
} catch (error) {
charge.error = error.message;
}
return charge;
}
Note:- You can store charge.id as a transaction id and later you can fetch the charge data using this id.
Ref:- Stripe API Reference - Retrieve a charge
8. Create routes.
routes/index.js
const express = require('express');
const router = express.Router();
const { validate } = require('../middleware/validator');
const paymentController = require('../controllers/payment.controller');
router.get('/', paymentController.index);
router.post('/payment', validate('payment'), paymentController.payment);
module.exports = router;
9. Finally start the project.
npm start
10. Open http://localhost:3000 and test the integration.
For Testing:-
Card Number: 4242424242424242
Month/Year: Any future date
CVV: Any 3 digits
Ref:- Testing Cards | Stripe
If you facing any issues. please post a comment. I will be happy to help you,
Thanks
Leave Your Comment