# Examples (/developers/examples)

The SDK repository (`github.com/fianto-xyz/sdk`) has two small apps under `examples/`. Each wires a
checkout route, a pay button and a webhook route with the SDK, so you can read a whole integration
in a few files. There is no Hono example; the [Hono page](/developers/sdks/hono) has the code.

## `examples/nextjs-app` [#examplesnextjs-app]

A Next.js App Router app that sells a **subscription**, built on `@fianto/nextjs` and
`@fianto/react`.

| File                               | What it shows                                                                                                                                |
| ---------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------- |
| `app/api/checkout/route.ts`        | `Checkout()` creating a `mode: 'subscription'` session from a recurring price id (`FIANTO_PRICE_PRO`), chosen on the server from a plan name |
| `app/pay-button.tsx`               | A client component around `FiantoButton`, with a message for each of the four statuses                                                       |
| `app/api/webhooks/fianto/route.ts` | `Webhooks()` logging `onOrderPaid`, `onSubscriptionRenewed` and every event through `onEvent`                                                |

It reads `FIANTO_APP_ID`, `FIANTO_APP_SECRET`, `FIANTO_WEBHOOK_SECRET` and `FIANTO_PRICE_PRO` from
`.env.local`, and `SITE_URL` (see [Running them](#running-them)) when it is set. Create the recurring price in the dashboard first: subscriptions are sold through the
API with a recurring `price_id`.

## `examples/express-server` [#examplesexpress-server]

An Express server that takes a **one-time payment**, built on `@fianto/express` and a plain HTML
page with `<fianto-button>`, no bundler.

| File                | What it shows                                                                                                                                                                                                       |
| ------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `src/app.ts`        | `checkout()` creating a `mode: 'payment'` session for `10.00` USDC, and `webhooks()`, both mounted before `express.json()`; it also serves the button script from the installed `@fianto/js` at `/fianto-button.js` |
| `public/index.html` | `<fianto-button session-endpoint="/api/checkout" data-plan="pro">` with `fianto:result` and `fianto:error` listeners                                                                                                |
| `src/server.ts`     | Starts the server on `PORT`, default 3100                                                                                                                                                                           |

Its `dev` script does not load `.env`: export `FIANTO_APP_ID`, `FIANTO_APP_SECRET` and
`FIANTO_WEBHOOK_SECRET` in your shell before you start it, and `SITE_URL` when you need it.

## Running them [#running-them]

From the root of the SDK repository, run `pnpm --filter nextjs-app dev` or
`pnpm --filter express-server dev`.

Both build `success_url` and `cancel_url` from `SITE_URL`, your app's public origin, and fall back
to the request's own origin in development only; in production `SITE_URL` must be set and `https`.
The production API refuses an `http` `success_url` or `cancel_url` with 400 `url_insecure`, so a
local run against `https://api.fianto.xyz` needs an `https` `SITE_URL`, such as a tunnel to your
machine.

Neither example has a page at its `success_url` yet: add one
that says the payment is being confirmed, since reaching it does not prove the payer paid.

> **Fulfilment happens in the webhook route:**
>
> The examples only log inside their webhook callbacks. A real app marks the order paid there, and
> records `event.id` in the same database transaction so a repeated delivery changes nothing.

## See also [#see-also]

- [Next.js](/developers/sdks/nextjs): Checkout() and Webhooks() in depth.

- [Express](/developers/sdks/express): Mount order, body size and proxies.

- [Subscriptions](/developers/subscriptions): Sell a recurring price through the API.

- [Quickstart](/get-started/quickstart): Build the same flow in your own app.