Quickstart
Install the Plandalf SDK, open an offer from a button, and handle the completed checkout result.
This guide adds Plandalf checkout to any page with a script tag and one button.
Prerequisites
- A Plandalf account with an organization subdomain.
- An offer slug from the Offers editor.
- A live or test payment integration connected before you accept real payments.
Install the SDK
Add the stub before the SDK script. The stub lets you queue calls before the async SDK file finishes loading.
<script>
// Queue SDK calls until the async Plandalf bundle is ready.
window.plandalf = window.plandalf || function () {
(window.plandalf.q = window.plandalf.q || []).push(arguments);
};
</script>
<!-- Replace acme with your Plandalf organization subdomain. -->
<script src="https://acme.plandalf.com/js/plandalf-sdk.js" async></script>
Install snippet explained
This script is intentionally small so it can live in page builders, CMS templates, and app layouts.
window.plandalf = window.plandalf || function () { ... } window.plandalf.q.push(arguments) https://acme.plandalf.com/js/plandalf-sdk.js Open an offer
Replace pro-plan with your offer slug.
<button id="buy-pro">Buy Pro</button>
<script>
document.getElementById("buy-pro").addEventListener("click", async () => {
// Open the published offer by slug and wait for the final checkout result.
const result = await plandalf.present("pro-plan");
// Redirect only after checkout completes successfully.
if (result.status === "complete") {
window.location.href = result.redirectUrl ?? "/thank-you";
}
});
</script>
plandalf.present() returns a FlowHandle. It behaves like a Promise, so await gives you the final checkout result. It also exposes .events for live purchase events and .close() for dismissing the frame programmatically.
Checkout snippet explained
plandalf.present("pro-plan") await plandalf.present(...) result.status === "complete" result.redirectUrl ?? "/thank-you" What happens when the customer clicks
Button click
Your page calls `plandalf.present()` with the offer slug.
Checkout opens
Plandalf creates or resumes a checkout session and renders the published offer.
Result resolves
Your code receives a completed or dismissed result and can decide what to do next.
Use declarative HTML
For simple buttons, you can skip custom JavaScript.
<button data-plandalf-present="pro-plan">
Buy Pro
</button>
Add frame and mode options as attributes.
<button
data-plandalf-present="pro-plan"
data-plandalf-frame="slideout"
data-plandalf-mode="test"
data-plandalf-size="wide"
>
Test checkout
</button>
The same checkout trigger in different stacks
Use the HTML version in no-code builders, the JavaScript version in static pages, and the React version inside app components.
The SDK listens for data attributes and opens the offer when the customer clicks the button.
<button
data-plandalf-present="pro-plan"
data-plandalf-frame="slideout"
data-plandalf-mode="test"
>
Buy Pro
</button> Use direct JavaScript when your page needs to handle completion, analytics, or redirects.
const button = document.querySelector("[data-buy-pro]");
button.addEventListener("click", async () => {
// Open the offer and wait for either completion or dismissal.
const result = await plandalf.present("pro-plan", {
frame: "slideout",
mode: "test"
});
// Only treat completed checkout as a successful purchase.
if (result.status === "complete") {
window.location.href = result.redirectUrl ?? "/thank-you";
}
}); Use the same browser SDK from React when checkout starts from component state or app routing.
export function BuyButton() {
async function openCheckout() {
// present() resolves when the Plandalf frame finishes.
const result = await window.plandalf.present("pro-plan", {
frame: "modal",
mode: "test"
});
// Keep fulfillment behind a completed checkout result.
if (result.status === "complete") {
window.location.assign(result.redirectUrl ?? "/thank-you");
}
}
return <button onClick={openCheckout}>Buy Pro</button>;
} Expected result
Clicking the button opens the offer in a Plandalf checkout frame. A completed checkout resolves with:
{
status: "complete",
session: {
uuid: "ck_...",
total: 2900,
currency: "usd",
customer: { email: "jane@example.com" }
},
customer: { email: "jane@example.com" },
redirectUrl: "https://example.com/thanks"
}
Customer dismissal is not an exception:
{ status: "dismissed", reason: "cancel" }
Only real errors, such as network failures or an invalid offer slug, reject the Promise.
Next steps
Configure SDK options
Choose frame, test mode, size, metadata, continuity, and close behavior.
Identify customers
Attach purchases to logged-in users with email or signed JWT identity.
Create an offer
Build the checkout surface customers will see.
Go live
Check payments, test mode, URLs, invoices, and post-purchase automations.
Builder context
Keep building from here.
Use the related Plandalf pages to connect this doc to offers, checkout, timers, integrations, automation, and implementation recipes.