> ## Documentation Index
> Fetch the complete documentation index at: https://docs.puffinmoney.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Embedded checkout (iframe SDK)

> puffin.js — a dependency-free modal checkout for your site

Keep customers on your page. `puffin.js` opens the hosted checkout in a
sandboxed iframe modal and reports status back via callbacks.

## Install

```html theme={null}
<script src="https://pay.puffinmoney.com/puffin.js"></script>
```

No npm, no build step, \~2 KB, zero dependencies.

## Open a payment intent

Create the intent server-side ([hosted checkout](/hosted-checkout)), pass
the id to the browser:

```html theme={null}
<button id="pay">Pay 25 USDC</button>
<script>
  document.getElementById('pay').onclick = () =>
    PuffinPay.open({
      intentId: 'INTENT_ID_FROM_YOUR_SERVER',
      onSuccess: (checkout) => (window.location = '/thanks'),
      onExpired: () => alert('Payment window expired — try again'),
      onClose:   () => console.log('Customer closed checkout'),
    });
</script>
```

## Open a payment link

No backend at all:

```js theme={null}
PuffinPay.openLink({
  slug: 'consulting-invoice-x7k2m9',
  amount: '150.00',            // omit if the link has a fixed amount
  customerEmail: 'buyer@example.com',
  onSuccess: () => (window.location = '/thanks'),
});
```

## API

| Method                     | Arguments                                                             |
| -------------------------- | --------------------------------------------------------------------- |
| `PuffinPay.open(opts)`     | `intentId` (required), `onSuccess`, `onExpired`, `onClose`            |
| `PuffinPay.openLink(opts)` | `slug` (required), `amount?`, `customerEmail?`, callbacks + `onError` |
| `PuffinPay.close()`        | Programmatically dismiss the modal                                    |

<Warning>
  Client callbacks are for UX only. Fulfil orders from the
  `payment.confirmed` [webhook](/webhooks) or a server-side GET of the intent.
</Warning>
