Overview
This guide walks you through the essential steps to build a fully functional Headless Checkout integration using the Purse SDK.
This guide focuses on primary payment methods (e.g. credit cards and digital wallets for example).
To handle secondary methods like gift cards, see the Features Guides.
- Load the SDK : Include the script or import the module into your application.
- Initialize the Checkout : Use your API credentials or client session data to set up the checkout instance.
- Display Available Payment Methods : Dynamically list the payment methods retrieved from the SDK.
- Handle Method Selection : Render the appropriate form UI when a user selects a method.
- Validate and Submit Payment : Monitor form validity and handle the final submission.
- Go Further : Customize UI elements, support saved payment methods or gift cards, and handle advanced workflows.
Step 1 - Load the SDK
Include the script:
<script src="https://cdn.purse-sandbox.com/headless-checkout/latest/purse.umd.js"></script>
Or use the ESM version:
<script type="module">
import * as Purse from "https://cdn.purse-sandbox.com/headless-checkout/latest/purse.esm.js";
</script>
Use the latest stable version for production.
Step 2 - Initialize the Checkout
API V1
const checkout = await Purse.createHeadlessCheckout({
apiKey: "YOUR_API_KEY",
entityId: "YOUR_ENTITY_ID",
environment: "sandbox",
paymentSession: "YOUR_SESSION"
});
API V2
const checkout = await Purse.createHeadlessCheckout(clientSession.widget.data);
Step 3 - Display Payment Methods
To allow users to choose a payment method, let's create a simple UI.
HTML Structure
<div id="root">
<div id="form"></div>
<button id="pay-button" disabled>Pay</button>
</div>
Retrieve and display the Payment Methods
Once the SDK is initialized, you can retrieve and display all available primary payment methods using the checkout.paymentMethods.subscribe()
function.
checkout.paymentMethods.subscribe((methods) => {
const ul = document.createElement("ul");
methods.forEach((pm) => {
const li = document.createElement("li");
item.textContent = pm.partner + " - " + pm.method;
li.onclick = () => selectMethod(pm);
ul.appendChild(li);
});
document.getElementById("root").appendChild(ul);
});
}
Step 4 - Select and Render a Payment Method
Once the list of available payment methods is displayed, you'll need to handle the user selection and render the corresponding payment form.
This is done by attaching an event handler to each method. When selected, the corresponding PaymentElement
will be created and mounted inside your container (e.g., a <div id="form">
).
Example
async function initCheckout() {
const checkout = await Purse.createHeadlessCheckout(clientSession.widget.data);
const paymentConfig = {};
function handlePaymentMethodSelect(paymentMethod) {
const form = document.getElementById("form");
form.innerHTML = "";
const partnerUI = paymentMethod.getPaymentElement(paymentConfig);
partnerUI.appendTo(form);
}
function displayPaymentMethods(methods) {
const ul = document.createElement("ul");
methods.forEach((pm) => {
const li = document.createElement("li");
li.textContent = `${pm.partner} ${pm.method}`;
li.addEventListener("click", () => handlePaymentMethodSelect(pm));
ul.appendChild(li);
});
document.getElementById("root").appendChild(ul);
}
checkout.paymentMethods.subscribe(displayPaymentMethods);
}
window.onload = initCheckout;
The paymentConfig
object can be used to customize UI elements (labels, placeholders, styling) depending on the payment method. This is especially useful when handling Hosted Forms or requiring specific translations.
Step 5 - Validate and Submit Payment
To ensure the payment form is complete before submission, use checkout.isPaymentFulfilled
.
This reactive variable tells you when the payment form is valid and complete.
checkout.isPaymentFulfilled.subscribe((isReady) => {
document.getElementById("pay-button").disabled = !isReady;
});
document.getElementById("pay-button").addEventListener("click", () => {
checkout.submitPayment();
});
Your basic Headless Checkout is now operational!
Full Example
Click to expand the full example code.
HTML / CSS
<html lang="en">
<head>
<meta charset="UTF-8"/>
<title>Purse Headless Checkout - Demo</title>
<script src="https://cdn.purse-sandbox.com/headless-checkout/latest/purse.umd.js"></script>
<style>
body {
font-family: sans-serif;
padding: 2rem;
max-width: 600px;
margin: auto;
}
ul {
list-style: none;
padding: 0;
}
li {
padding: 0.5rem;
border: 1px solid #ccc;
margin-bottom: 0.5rem;
cursor: pointer;
}
#pay-button {
padding: 0.75rem 1.5rem;
background: #004aff;
color: white;
border: none;
border-radius: 6px;
margin-top: 1rem;
}
#pay-button:disabled {
background: #ccc;
cursor: not-allowed;
}
#pay-button:enabled {
cursor: pointer;
}
</style>
</head>
<body>
<h1>Headless Checkout</h1>
<div id="root">
<ul id="methods"></ul>
<div id="form"></div>
<button id="pay-button" disabled>Pay</button>
</div>
</body>
</html>
JAVASCRIPT
async function initCheckout() {
const checkout = await Purse.createHeadlessCheckout(clientSession.widget.data);
const payButton = document.getElementById("pay-button");
const paymentConfig = {};
function handlePaymentMethodSelect(method) {
const form = document.getElementById("form");
form.innerHTML = "";
const element = method.getPaymentElement(paymentConfig);
element.appendTo(form);
}
function displayPaymentMethods(methods) {
const list = document.getElementById("methods");
list.innerHTML = "";
methods.forEach((pm) => {
const item = document.createElement("li");
item.textContent = pm.partner + " - " + pm.method;
item.onclick = () => handlePaymentMethodSelect(pm);
list.appendChild(item);
});
}
checkout.isPaymentFulfilled.subscribe((isReady) => {
payButton.disabled = !isReady;
});
payButton.addEventListener("click", () => {
checkout.submitPayment();
});
checkout.paymentMethods.subscribe(displayPaymentMethods);
}
window.onload = initCheckout;