Back to Community Blog

Accept E-Commerce Payments Easily with PayPal’s Buttons Component

authorImage

Arit Amana

Oct 24, 2023

51 min read

featuredImage

Accepting online payments is now a universal must-have, catering to everyone from solo entrepreneurs to massive global corporations.

PayPal’s Standard Checkout allows for seamless integration of PayPal’s Payment Buttons component into your e-commerce app, granting you the power to accept online payments. In this guide, I am going to show how to add Standard Checkout to a simple shopping app, built with HTML and NodeJS.

Guide Overview

Part 1. Prerequisites

Part 2a. Basic Integration — Code Setup

Part 2b. Basic Integration — Checkout Flow

Part 3a. Custom Integration — Code Setup

Part 3b. Custom Integration — Checkout Flow

Part 4. Conclusion

Part 5. Additional PayPal Payment Integrations

Part 1. Prerequisites

To complete this integration, you will need the following information:

  • API Credentials (Client ID and Secret) for a PayPal REST app: paste these from your Developer Dashboard. Since we are working in a development environment in this demo, ensure that the Sandbox Toggle is on.

image

Obtain Test API Credentials

  • The username and password for a Personal Sandbox account: you will need this to complete the checkout process.

image

Navigate to Sandbox Accounts under Testing Tools

image

Obtain Personal Sandbox Account login details

You can grab the code for our completed Checkout Integration demo from the PayPal Developer GitHub repository.

Part 2a. Basic Integration — Code Setup

Navigate to PayPal’s Integrate Checkout documentation. The documentation shows you how to set your development environment up: installing npm, verifying your package.json file, and setting up your .env file.

Next, you will set up your back-end server and front-end code. The documentation presents the contents of three files: server.js (for the back-end server), app.js (for the client-side logic) and checkout.html (for the user interface).image

Copy the Code Snippets

Grab these code snippets and paste them into your IDE (Integrated Development Environment). I strongly recommend that you implement the basic integration first, and ensure that you are able to complete the Standard Checkout Flow successfully, before adding your custom e-commerce code. I find that this approach reduces potential errors and associated frustrations. 😅

In the checkout.html file, replace the word “test” within the Software Development Kit (SDK) script tag with your Client ID.

<script src="https://www.paypal.com/sdk/js?client-id=CLIENT_ID"></script>

In the app.js file, note that the “cart” object in the response body is hard-coded with one product’s SKU and quantity information. For important security reasons, we do not pass any transaction or price amounts from the front- end. Instead, we use the SKU/ID and quantity information to look up the product(s) in a datastore and use these product details to calculate the total cart price in our back-end.

body: JSON.stringify({

cart: [

{

id: "YOUR_PRODUCT_ID",

quantity: "YOUR_PRODUCT_QUANTITY",

},

],

})

In the server.js file, note that the transaction quantity (“100.00”) is hardcoded into the createOrder call.

const createOrder = async (cart) => {

console.log(

"shopping cart information passed from the frontend createOrder() callback:",

cart,

);



const accessToken = await generateAccessToken();

const url = `${base}/v2/checkout/orders`;

const payload = {

intent: "CAPTURE",

purchase_units: [

{

amount: {

currency_code: "USD",

value: "100.00",

},

},

],

};



... more code ...

}

Part 2b. Basic Integration — Checkout Flow

Start your server; on the command line, run “node server/server.js” or whichever shortcut is defined in your package.json file. You should see the PayPal Buttons component displayed on the front- end.

image

PayPal Button Component — Basic Integration

Click the first PayPal button, which displays the Checkout modal. Note that the URL in the modal shows that we are in a sandbox environment. Sign in using your Personal Sandbox account (if you haven’t already).image

The Checkout Modal starts the checkout process

You are then presented with the transaction amount (at this point, this should be $100.00) and several payment options.

image

The transaction amount is hardcoded to $100

Complete the transaction with the PayPal Balance option. A confirmation message should appear in your browser; its location depends on where you place the element with the id “result-message” in your application.

<p id="result-message"></p>
image
Status message after completed checkout process

Part 3a. Custom Integration — Code Setup

Now, let’s add our custom e-commerce code!

In the checkout.html file, I added the code for three products being sold at the LiftOff Shop. I styled the code with TailwindCSS:

<!DOCTYPE html>

<html lang="en">

<head>

<meta charset="UTF-8" />

<meta name="viewport" content="width=device-width, initial-scale=1.0" />

<title>PayPal JS SDK Standard Integration Demo</title>

<script src="https://cdn.tailwindcss.com"></script>

</head>

<body class="p-6">

<h1 class="text-center text-4xl font-medium">LiftOff Shop</h1>

<main class="products flex flex-wrap justify-center">

<div

class="product text-center m-3 p-3 border border-slate-400 rounded-md"

>


<img src="https://picsum.photos/id/21/200" class="rounded-md" />

<h2 class="text-xl my-2">Galaxy Shoes</h2>

<p class="text-green-600 font-medium text-lg mb-2">$100</p>

<div class="mb-3">

<label class="text-lg" for="quantity1">Quantity:</label>

<select class="text-lg" id="quantity1">

<option value="0">0</option>

<option value="1">1</option>

<option value="2">2</option>

<option value="3">3</option>

</select>

</div>

<button

class="product-btn py-1 px-3 rounded-md bg-indigo-200 hover:bg-indigo-300"

data-product-id="hdqgapq9"

data-quantity-id="quantity1"

>


Add to Cart

</button>

</div>



<div

class="product text-center m-3 p-3 border border-slate-400 rounded-md"

>


<img src="https://picsum.photos/id/104/200" class="rounded-md" />

<h2 class="text-xl my-2">Spaceship Earrings</h2>

<p class="text-green-600 font-medium text-lg mb-2">$40</p>

<div class="mb-3">

<label class="text-lg" for="quantity2">Quantity:</label>

<select class="text-lg" id="quantity2">

<option value="0">0</option>

<option value="1">1</option>

<option value="2">2</option>

<option value="3">3</option>

</select>

</div>

<button

class="product-btn py-1 px-3 rounded-md bg-indigo-200 hover:bg-indigo-300"

data-product-id="rnfjwsy0"

data-quantity-id="quantity2"

>


Add to Cart

</button>

</div>



<div

class="product text-center m-3 p-3 border border-slate-400 rounded-md"

>


<img src="https://picsum.photos/id/342/200" class="rounded-md" />

<h2 class="text-xl my-2">Martian Tote</h2>

<p class="text-green-600 font-medium text-lg mb-2">$75</p>

<div class="mb-3">

<label class="text-lg" for="quantity3">Quantity:</label>

<select class="text-lg" id="quantity3">

<option value="0">0</option>

<option value="1">1</option>

<option value="2">2</option>

<option value="3">3</option>

</select>

</div>

<button

class="product-btn py-1 px-3 rounded-md bg-indigo-200 hover:bg-indigo-300"

data-product-id="zytkddw5"

data-quantity-id="quantity3"

>


Add to Cart

</button>

</div>

</main>



<p id="result-message" class="mx-auto text-center text-red-600 w-1/2"></p>



<section class="mt-8 mx-auto flex flex-wrap w-1/2">

<div class="mb-3 w-1/2 text-center" id="cart">

<h2 class="text-xl font-medium">Cart</h2>

<ul id="cart-items"></ul>

<p>TOTAL $<span id="cart-total">0</span></p>

<button

id="clear-cart"

class="py-1 px-3 mt-3 rounded-md bg-gray-200 hover:bg-gray-300"

>


Clear Cart

</button>

</div>

<div class="text-center" id="paypal-button-container"></div>

</section>



<script src="https://www.paypal.com/sdk/js?client-id=AYCd0wKOWs9itZ23_2XEZUhZpbZdHT_c1qcMCjqTnb6fxFE7tQBnUQGSPh3_PVQkgoBamFV1KgPUI9B4¤cy=USD"></script>

<script type="module" src="app.js"></script>

</body>

</html>
image
E-Commerce App with PayPal Buttons Component

In the app.js file, I added code that brings the Add-To-Cart, Calculate-Cart-Total and Clear-Cart functionalities. To calculate my cart total, I imported my product information from the products.js file, which serves as my makeshift datastore. I also updated the cart object in the response body to the cartItems array (instead of the hard-coded product from earlier).

import { PRODUCTS } from "./products.js";



const cartItems = [];

let cartTotal = 0;



function addToCart(productId, quantityId) {

const quantitySelect = document.getElementById(quantityId);

const selectedQuantity = parseInt(quantitySelect.value, 10);



if (selectedQuantity > 0) {

cartItems.push({

id: productId,

quantity: selectedQuantity,

});

cartTotal = calculateCartTotal(cartItems);

updateCart(cartItems);

}

}



function calculateCartTotal(cartItems) {

let total = 0;

cartItems.forEach((item) => {

total += item.quantity * PRODUCTS[item.id].price;

});



return total;

}



function updateCart(cartItems) {

const cartItemsList = document.getElementById("cart-items");

const cartTotalElement = document.getElementById("cart-total");



cartItemsList.innerHTML = "";

cartTotalElement.textContent = cartTotal;



cartItems.forEach((item) => {

const li = document.createElement("li");

li.textContent = `${PRODUCTS[item.id].name}: ${item.quantity}`;

cartItemsList.appendChild(li);

});

}



window.paypal

.Buttons({

async createOrder() {

try {

const response = await fetch("/api/orders", {

method: "POST",

headers: {

"Content-Type": "application/json",

},

// use the "body" param to optionally pass additional order information

// like product ids and quantities

body: JSON.stringify({

cart: cartItems,

}),

});



... more code ...



... more code ...

})

.render("#paypal-button-container");



// Example function to show a result to the user. Your site's UI library can be used instead.

function resultMessage(message) {

const container = document.querySelector("#result-message");

container.innerHTML = message;

}



// Event Listeners

const productBtns = document.querySelectorAll(".product-btn");

productBtns.forEach((btn) => {

btn.addEventListener("click", (e) => {

const productId = e.target.dataset.productId;

const quantityId = e.target.dataset.quantityId;

addToCart(productId, quantityId);

});

});



// clear cart

document.getElementById("clear-cart").addEventListener("click", () => {

// clear cart items, without reassigning the array

cartItems.length = 0;

cartTotal = 0;

updateCart(cartItems);

});

In the server.js file, I imported my products from products.js and added a function that calculates the transaction amount using the cart contents. In the createOrder call, I replaced the hardcoded transaction value with the calculated cart value.

import express from "express";

import fetch from "node-fetch";

import "dotenv/config";

import path from "path";

import { PRODUCTS } from "../client/products.js";



... more code ...

... more code ...



function calculateTotalPrice(cart) {

let totalPrice = 0;

for (let i = 0; i < cart.length; i++) {

totalPrice += PRODUCTS[cart[i].id].price * cart[i].quantity;

}

return totalPrice.toString();

}



/**

* Create an order to start the transaction.

* @see https://developer.paypal.com/docs/api/orders/v2/#orders_create

*/


const createOrder = async (cart) => {

// use the cart information passed from the front-end to calculate the purchase unit details

console.log(

"shopping cart information passed from the frontend createOrder() callback:",

cart

);



const accessToken = await generateAccessToken();

const url = `${base}/v2/checkout/orders`;

const payload = {

intent: "CAPTURE",

purchase_units: [

{

amount: {

currency_code: "USD",

value: calculateTotalPrice(cart),

},

},

],

};



... more code ...

};



... more code ...

Part 3b. Custom Integration — Checkout Flow

Restart the server and add some products to the cart; I chose one of each item, totaling $215.

image
Cart total showing total amount of cart items

Click the gold PayPal button to activate Checkout (signing in with your Personal Sandbox account, if necessary). You should see that the transaction amount is the value of your cart.

image
Transaction value in the Checkout modal is equal to the cart amount

Go ahead and complete the purchase. You should see a confirmation message in the browser.

image
Confirmation of successful checkout in browser

Part 4. Conclusion

This demo introduced a straightforward integration of PayPal’s Standard Checkout, using the PayPal Buttons component. You may customize your further, to meet your use cases. Read our Checkout Documentation for examples of these customizations. The PayPal Developer GitHub repository also has several examples of integrations within various code environments, such as React and Angular.

Part 5. Additional PayPal Payment Integrations

Join the PayPal Developer Community!Our Developer Community members support each other in integrating PayPal technologies, contributing to open source, expanding knowledge and networks, and improving PayPal’s products and documentation.

We’d love to have you join us! 💙

- 
Website

- 
Twitter

- 
GitHub

Recommended