Skip to main content

How to build

Overview

This guide walks you through the essential steps to build a fully functional Headless Checkout integration using the Purse SDK.

Scope of This Guide

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>
info
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 = {}; // Optional configuration for appearance and translation

function handlePaymentMethodSelect(paymentMethod) {
const form = document.getElementById("form");
form.innerHTML = ""; // Clear previously mounted forms
const partnerUI = paymentMethod.getPaymentElement(paymentConfig);
partnerUI.appendTo(form); // Mount the form to the container
}

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;
Optional configuration
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();
});
success
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 = {}; // Optional: customize UI

function handlePaymentMethodSelect(method) {
const form = document.getElementById("form");
form.innerHTML = ""; // Reset
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);
});
}

// Update Pay button state based on validation
checkout.isPaymentFulfilled.subscribe((isReady) => {
payButton.disabled = !isReady;
});

// Submit the payment
payButton.addEventListener("click", () => {
checkout.submitPayment();
});

// Init methods
checkout.paymentMethods.subscribe(displayPaymentMethods);
}

window.onload = initCheckout;