Sell a course from your own site
Imagine you run a ceramics course. Your website explains the lessons and has a Join the course button. Plandalf handles the checkout when someone clicks it; your site stays responsible for giving them access to the lessons.
Set it up
- Publish a Plandalf offer for the course. In this example its slug is
ceramics-course. - Replace
https://your-org.plandalf.devwith your organization's host. - Put the button on your course page. Choose HTML attributes, JavaScript, or React below.
The offer slug is just a name you choose in Plandalf. The same slug appears in the code below.
Load the browser bundle from your organization's host. The SDK finds the button and opens the offer when it is clicked.
<script defer src="https://your-org.plandalf.dev/js/plandalf-sdk.js"></script>
<button data-plandalf-present="ceramics-course">Join the course</button>The HTML button opens checkout. Use a server purchase confirmation to unlock lessons; this markup does not receive an awaited result.
import { Plandalf } from '@plandalf/sdk'
const sdk = new Plandalf({ apiBase: 'https://your-org.plandalf.dev' })
const button = document.querySelector('#join-course')
button.addEventListener('click', async () => {
const handle = sdk.present('ceramics-course')
const result = await handle
if (result.status === 'complete') {
// Ask your server to confirm this purchase, then unlock lessons.
}
})<button id="join-course">Join the course</button>import { PlandalfProvider, usePresent } from '@plandalf/react'
function CourseButton() {
const { present, presenting } = usePresent()
async function join() {
const handle = present('ceramics-course')
const result = await handle
if (result.status === 'complete') {
// Ask your server to confirm this purchase, then unlock lessons.
}
}
return <button disabled={presenting} onClick={join}>Join the course</button>
}
export function CoursePage() {
return (
<PlandalfProvider apiBase="https://your-org.plandalf.dev">
<CourseButton />
</PlandalfProvider>
)
}What happens for the buyer
They click Join the course, complete or dismiss the checkout, and return to your page. In JavaScript and React, the awaited result.status tells your page which happened. The browser result is useful for the page message; your server must confirm the purchase before it grants course access. A failed checkout request rejects the handle, so add your site's normal error message around the call.
Want the buy button to open ticket checkout instead? See Sell event tickets. Want a deadline that changes the next offer? See Event merch deadline.
Follow the types
Plandalf.present()lists the JavaScript call signature.usePresent()lists the React hook signature.FlowOpenOptionslists frame, continuity, identity, and metadata inputs.FlowResultlists the awaited outcome.FlowHandleEventlists live events if you later want a progress indicator.