# Add checkout to a button

Publish an offer with the slug `upgrade`, then connect a button on your page. HTML attributes need only the browser bundle. JavaScript and React let the page await the checkout result and refresh access from your server.

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

The SDK scans the page and binds the button automatically. Use your organization's SDK URL.

```html title="upgrade.html" lineNumbers lineNumberStart=1 highlight="2"
<script defer src="https://your-org.plandalf.dev/js/plandalf-sdk.js"></script>
<button data-plandalf-present="upgrade">Upgrade</button>
```

This opens checkout without application JavaScript. If the upgrade grants access to a paid feature, your server must confirm the purchase before granting it.

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

Import the SDK class when your site already has JavaScript and you want the checkout result in the page.

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

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

button.addEventListener('click', async () => {
  const result = await sdk.present('upgrade')
  if (result.status === 'complete') {
    // Refresh the customer's access from your server.
  }
})
```

```html title="upgrade.html"
<button id="upgrade">Upgrade</button>
```

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

Put [`PlandalfProvider`](https://plandalf.com/docs/packages/react/functions/PlandalfProvider) above the component, then use [`usePresent()`](https://plandalf.com/docs/packages/react/functions/usePresent) inside it.

```tsx title="Upgrade.tsx" lineNumbers lineNumberStart=1 highlight="5,8,21"
import { PlandalfProvider, usePresent } from '@plandalf/react'

function UpgradeButton() {
  const { present, presenting } = usePresent()
  async function upgrade() {
    const result = await present('upgrade')
    if (result.status === 'complete') {
      // Refresh the customer's access from your server.
    }
  }

  return (
    <button disabled={presenting} onClick={upgrade}>
      {presenting ? 'Opening…' : 'Upgrade'}
    </button>
  )
}

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

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

`usePresent()` returns the core `FlowHandle<FlowResult>`, so the same [awaitable result](https://plandalf.com/docs/guides/await-a-checkout) and type definitions apply. The HTML trigger opens the same offer but has no Promise in the markup. The checked-out Numi React package currently has typecheck errors; verify a matching package build before using it in production.

Source: https://plandalf.com/docs/guides/react-checkout
