Braintree
Javascript
9 February 2022
Learn to implement braintree with JavaScript and NodeJs.
CDN
Braintree initilization
<!-- Braintree -->
<script src="https://js.braintreegateway.com/web/3.85.2/js/client.min.js"></script>
<script src='https://js.braintreegateway.com/web/3.85.2/js/three-d-secure.min.js'></script>
<script src="https://js.braintreegateway.com/web/3.85.2/js/hosted-fields.min.js"></script>
<script src="https://js.braintreegateway.com/web/3.85.2/js/paypal-checkout.min.js"></script>
<!-- Braintree -->
HTML
<div class="form-container pt-4">
<div class="payment-btns mt-4">
<div class="payment-card payment-btns-item active" data-type="card"><span class="iconify" data-icon="grommet-icons:mastercard"></span></div>
<div class="payment-paypal payment-btns-item" data-type="paypal"><span class="iconify" data-icon="logos:paypal"></span></div>
</div>
<div class="subs-plans"></div>
<div class="c-card payment-method active">
<form id="hosted-fields-form" method="post">
<div class="row">
<div class="col-md-12">
<div class="form-group">
<label for="card-number">Card Number</label>
<div class="form-control" id="card-number"></div>
<small class="error"></small>
</div>
</div>
<div class="col-sm-6">
<div class="form-group">
<label for="expiration-date">Expiration Date</label>
<div class="form-control" id="expiration-date"></div>
<small class="error"></small>
</div>
</div>
<div class="col-sm-6">
<div class="form-group">
<label for="cvv">CVV</label>
<div class="form-control" id="cvv"></div>
<small class="error"></small>
</div>
</div>
<div class="col-md-12">
<input type="submit" value="Pay" disabled />
</div>
</div>
</form>
</div>
<div class="paypal payment-method d-none">
<div class="mt-2" id="paypal-button"></div>
</div>
</div>
CSS
.payment-method {
width: 500px;
}
#hosted-fields-form{
padding: 10px;
background-color: rgb(233, 234, 235);
width: 100%;
height: fit-content;
}
.form-control {
height: 50px;
}
main {
display: flex;
justify-content: center;
}
.error {
display: none;
}
.error.active {
display: block;
}
.subs-plans {
display: flex;
justify-content: space-between;
align-items: center;
margin: 20px 0;
}
.subs-plans-items {
background-color: rgb(233, 234, 235);
width: 32%;
height: 70px;
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
cursor: pointer;
}
.subs-plans-items.active {
background-color: #D9000D;
color: #FFFFFF;
font-weight: bold;
}
.payment-btns {
display: flex;
justify-content: space-between;
align-items: center;
height: 60px;
}
.payment-card, .payment-paypal, .payment-subscription, .payment-sales {
width: 49%;
height: 100%;
cursor: pointer;
background-color: #ddd;
display: flex;
justify-content: center;
align-items: center;
font-size: 18px;
}
.payment-btns-item.active {
background-color: #D9000D;
color: #FFFFFF;
font-weight: bold;
}
.payment-btns-item .iconify {
width: 30px;
height: 30px;
}
.payment-option-item.active {
background-color: #D9000D;
color: #FFFFFF;
font-weight: bold;
}
.payment-option-item .iconify {
width: 30px;
height: 30px;
}
JavaScript
var form = document.querySelector('#hosted-fields-form');
var submit = document.querySelector('input[type="submit"]');
var threeDSecure;
var subsPlans = [
{
name: "3 Months",
id: "3_months",
amount: 50
},
{
name: "6 Months",
id: "6_months",
amount: 100
},
{
name: "12 Months",
id: "12_months",
amount: 150
}
];
$('.subs-plans').html(
subsPlans.map(plan => {
return `
<div class="subs-plans-items" data-id="${plan.id}" data-amount="${plan.amount}">
${plan.name}
<span>${plan.amount}</span>
</div>`
})
)
$('.subs-plans-items').first().addClass('active');
braintree.client.create({
// Insert your tokenization key here
authorization: "YOUR_TOKEN_GENERATED_WITH_BRAINTREE_ACCOUNT"
}, function (clientErr, clientInstance) {
if (clientErr) {
console.error(clientErr);
return;
}
// initialize 3d secure
braintree.threeDSecure.create({
version: 2,
client: clientInstance
}, function(threeDSecureErr, threeDSecureInstance) {
if (threeDSecureErr) {
if (threeDSecureErr) console.error(threeDSecureErr);
// Handle error in 3D Secure component creation
return;
}
threeDSecure = threeDSecureInstance;
})
// Create a hostedFields component to initialize the form
braintree.hostedFields.create({
client: clientInstance,
// Customize the Hosted Fields.
styles: {
'input': {
'font-size': '14px'
},
'input.invalid': {
'color': 'red'
},
'input.valid': {
'color': 'green'
}
},
// Configure which fields in your card form will be generated by Hosted Fields instead
fields: {
number: {
container: '#card-number',
placeholder: '4111 1111 1111 1111'
},
expirationDate: {
container: '#expiration-date',
placeholder: '10/22'
},
cvv: {
container: '#cvv',
placeholder: '123'
},
}
}, function (hostedFieldsErr, instance) {
if (hostedFieldsErr) {
console.error(hostedFieldsErr);
return;
}
// Once the fields are initialized enable the submit button
submit.removeAttribute('disabled');
instance.on('validityChange', function(event) { // calls change of input values
var field = event.fields[event.emittedBy];
var errContainer = $(field.container).siblings('.error');
var type = field.container.id;
$(field.container).siblings('.error').addClass('active');
$(field.container).siblings('.error').text('Working');
validateInput(type, field, errContainer); // check validation call
})
function validateInput(type, field, errContainer) { // check validation
if(field.isEmpty) {
errContainer.addClass('active');
switch (type) {
case "card-number":
errContainer.text("Card number is required");
break;
case "expiration-date":
errContainer.text("Expiration date is required");
break;
case "cvv":
errContainer.text("CVV is required");
break;
default:
break;
}
}
else if(!field.isValid) {
errContainer.addClass('active');
switch (type) {
case "card-number":
errContainer.text("Card number is invalid, please enter valid card number");
break;
case "expiration-date":
errContainer.text("Expiration date is invalid");
break;
case "cvv":
errContainer.text("CVV is invalid");
break;
default:
break;
}
}
else {
errContainer.removeClass('active');
}
}
// Initialize the form submit event
form.addEventListener('submit', function (event) {
event.preventDefault();
var state = instance.getState();
var formValid = Object.keys(state.fields).every(function (key) {
return state.fields[key].isValid;
});
if (formValid) {
$('.error').removeClass('active');
showLoading('Please wait', 'We are making your payment.');
// Tokenize Hosted Fields
instance.tokenize((error, payload) => {
if (error) console.error(error);
threeDSecure.verifyCard({
nonce: payload.nonce,
bill: payload.details.bin,
amount: $('.subs-plans-items.active').data('amount'),
onLookupComplete: function (data, next) {
// use `data` here, then call `next()`
next();
}
}, function(verifyError, payload) {
if (verifyError) {
console.error(verifyError);
updateLoading(false, 'Server internal error!', 'Please try again in sometime.');
hideLoading();
}
else {
porcessPayment(payload.nonce);
}
})
});
} else {
Object.keys(state.fields).map((key, i) => {
var field = state.fields[key];
var type = field.container.id;
var errContainer = $(field.container).siblings('.error');
validateInput(type, field, errContainer); // check validation call
})
}
}, false);
});
});
// Create a PayPal Checkout component
// Create a client.
braintree.client.create({
authorization: token
}, function (clientErr, clientInstance) {
// Stop if there was a problem creating the client.
// This could happen if there is a network error or if the authorization
// is invalid.
if (clientErr) {
console.error('Error creating client:', clientErr);
return;
}
// Create a PayPal Checkout component.
braintree.paypalCheckout.create({
client: clientInstance
}, function (paypalCheckoutErr, paypalCheckoutInstance) {
paypalCheckoutInstance.loadPayPalSDK({
vault: true
}, function () {
if(paypalCheckoutErr) {
console.log('paypalCheckoutErr: ', paypalCheckoutErr);
}
paypal.Buttons({
createBillingAgreement: function () {
return paypalCheckoutInstance.createPayment({
flow: 'vault', // Required
});
},
onApprove: function (data, actions) {
data.vault = false;
showLoading('Please wait', 'We are making your payment.');
return paypalCheckoutInstance.tokenizePayment(data, function (err, payload) {
// Submit `payload.nonce` to your server
porcessPayment(payload.nonce);
});
},
onCancel: function (data) {
console.log('PayPal payment canceled', JSON.stringify(data, 0, 2));
},
onError: function (err) {
console.error('PayPal error', err);
}
}).render('#paypal-button').then(function () {});
});
});
});
function porcessPayment(nonce) {
console.log('nonce: ', nonce, ' planId: ', $('.subs-plans-items.active').data('id'), ' amount: ', $('.subs-plans-items.active').data('amount'));
$.ajax({
type: "POST",
url: "/checkout",
data: {nonce: nonce, plan_id: $('.subs-plans-items.active').data('id')},
dataType: "json",
success: function(data) {
console.log('success: ', data);
updateLoading(data.status, 'Success', data.msg);
hideLoading();
},
error: function(err) {
console.log('err: ', err);
}
})
}
$('.subs-plans-items').on('click', function() {
$('.subs-plans-items').removeClass('active');
$(this).addClass('active');
})
$('.payment-btns-item').on('click', function() {
$('.payment-btns-item').removeClass('active');
$(this).addClass('active');
var type = $(this).data('type');
if(type == "card") {
$('.c-card').removeClass('d-none');
$('.paypal').addClass('d-none');
}
if(type == "paypal") {
$('.c-card').addClass('d-none');
$('.paypal').removeClass('d-none');
}
})
NodeJsBraintree initilization
const braintree = require("braintree");
const gateway = new braintree.BraintreeGateway({
environment: braintree.Environment.Sandbox,
merchantId: "YOUR_MERCHAND_ID",
publicKey: "YOUR_PUBLIC_KEY",
privateKey: "YOUR_PRIVATE_KEY"
});
Send client token to client while rendering the page
gateway.clientToken.generate({}, (err, response) => {
var token = response.clientToken;
res.render('pages/index', { title: 'Home', token: token });
});
Create customer and subscription with checkout
exports.checkout = (req, res, next) => {
var nonce = req.body.nonce;
var plan = req.body.plan_id;
gateway.customer.create({
paymentMethodNonce: nonce
}, function (err, result) {
if (result.success) {
var token = result.customer.paymentMethods[0].token;
gateway.subscription.create({
paymentMethodToken: token,
planId: plan
}, function (err, result) {
if(err){
console.log(err)
}
console.log('subscription-result', result);
res.send({
result: result,
msg: "Payment made successfully.",
status: true
});
});
}
});
};
Comments
Leave a Comment
Your email address will not be published.
Categories
You May Also Like
Javascript
Clock
30 March 2026
HTML & CSS
Responsive lightbox
4 February 2025
Javascript
Display pdf as image
10 July 2025
Javascript
Custom Calendar
10 July 2025
Javascript
Circular Progress Bar
16 August 2024
HTML & CSS
Adaptive Navbar
10 July 2025
Javascript
JavaScript Currying
9 March 2024
Javascript
Google reCAPTCHA
10 July 2025
Javascript
Braintree
10 July 2025
jQuery
Image Slider
10 July 2025