# Sell tickets to an event

Imagine your event page announces a one-day workshop. It has the date, venue, and a **Get a ticket** button. Publish a ticket offer in Plandalf, then let the button open its checkout.

## Set it up

1. Publish an offer for the ticket. This example calls it `spring-workshop-ticket`.
2. Put the button on your event page, using your real organization host in the script URL or `apiBase`.
3. Have your server confirm the purchase before it issues a ticket or reserves a place. The browser result alone is not a ticket record.

<scalar-tabs default="HTML">
<scalar-tab title="HTML">

The browser bundle automatically binds the ticket button. No application JavaScript is needed to open checkout.

```html title="event.html" lineNumbers lineNumberStart=1 highlight="2"
<script defer src="https://your-org.plandalf.dev/js/plandalf-sdk.js"></script>
<button data-plandalf-present="spring-workshop-ticket">Get a ticket</button>
```

Issue the ticket only after your server confirms the purchase. For an immediate page message based on the checkout result, use the JavaScript or React tab.

</scalar-tab>
<scalar-tab title="JavaScript">

```javascript title="tickets.js" lineNumbers lineNumberStart=1 highlight="7-8"
import { Plandalf } from '@plandalf/sdk'

const sdk = new Plandalf({ apiBase: 'https://your-org.plandalf.dev' })
const button = document.querySelector('#get-ticket')
const message = document.querySelector('#ticket-message')

button.addEventListener('click', async () => {
  const result = await sdk.present('spring-workshop-ticket')
  message.textContent = result.status === 'complete'
    ? 'Checkout finished. We are confirming your ticket.'
    : 'You can come back for a ticket later.'
})
```

```html title="event.html"
<button id="get-ticket">Get a ticket</button>
<p id="ticket-message" role="status"></p>
```

</scalar-tab>
<scalar-tab title="React">

```tsx title="TicketButton.tsx" lineNumbers lineNumberStart=1 highlight="7-8"
import { useState } from 'react'
import { PlandalfProvider, usePresent } from '@plandalf/react'

function TicketButton() {
  const { present, presenting } = usePresent()
  const [message, setMessage] = useState('')

  async function getTicket() {
    const result = await present('spring-workshop-ticket')
    setMessage(result.status === 'complete'
      ? 'Checkout finished. We are confirming your ticket.'
      : 'You can come back for a ticket later.')
  }

  return <>
    <button disabled={presenting} onClick={getTicket}>Get a ticket</button>
    <p role="status">{message}</p>
  </>
}

export function EventPage() {
  return <PlandalfProvider apiBase="https://your-org.plandalf.dev">
    <TicketButton />
  </PlandalfProvider>
}
```

</scalar-tab>
</scalar-tabs>

The page can respond immediately to a completed or dismissed checkout. Your ticketing system still needs a confirmed purchase from your server before sending a ticket, QR code, or admission confirmation. Add your site's usual error handling for failed checkout requests.

For exact inputs and outputs, inspect [`present()`](https://plandalf.com/docs/sdk/present), [`FlowOpenOptions`](https://plandalf.com/docs/packages/sdk/interfaces/FlowOpenOptions), and [`FlowResult`](https://plandalf.com/docs/packages/sdk/interfaces/FlowResult). To add an early-bird price to one ticket offer, [configure promo tiers](https://plandalf.com/docs/product-guides/promos/tiers) and pass the promo slug to `present()`.

Source: https://plandalf.com/docs/guides/sell-event-tickets
