# Finality (/concepts/finality)

A Solana transaction is **confirmed** first and **finalized** later. A confirmed block can still be
rolled back; a finalized transfer cannot be reversed. Fianto uses both steps, for different
readers: the payer is shown success at confirmed, and you are told only at finalized.

**The steps of a one-time checkout**

1. From your server, create a session with `POST /v1/checkout-sessions`. The first create returns its `url`; creating again for the same open order returns `url: null`, so reissue the link instead.
2. Send the payer to that `url`: Fianto's hosted checkout page.
3. The payer's wallet signs the transaction. The wallet only signs; it does not send.
4. The checkout page hands the signed transaction to Fianto.
5. Fianto broadcasts it to Solana, and rebroadcasts it when needed.
6. When the transaction is confirmed, Fianto tells the checkout page, which shows the payer success. The order is not `PAID` yet.
7. When it is finalized, the order becomes `PAID`, the payment `SUCCEEDED`, and Fianto sends `order.paid` and `checkout.session.completed` to your webhook endpoint — only at finalized.

## What happens at each step [#what-happens-at-each-step]

The payer's wallet only signs. Fianto broadcasts the signed transaction to Solana, rebroadcasts it
when needed, and follows it.

| Step           | Payment      | What changes                                                                                                                                                          |
| -------------- | ------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Sent to Solana | `PROCESSING` | Fianto follows the transaction.                                                                                                                                       |
| Confirmed      | `CONFIRMED`  | The checkout page, which asks Fianto for the status, shows the payer success. The order is not `PAID` yet, and no webhook is sent.                                    |
| Finalized      | `SUCCEEDED`  | The order becomes `PAID` and Fianto sends `order.paid`. When the session was still `OPEN`, it becomes `COMPLETED` and Fianto also sends `checkout.session.completed`. |

At confirmed, the payer's receipt reads "Confirmed on Solana" and says the shop is told once Solana
finalizes it. A payment can still fail after it was confirmed, so a `CONFIRMED` payment is not
yet money you can count on.

## Why webhooks wait for finalized [#why-webhooks-wait-for-finalized]

Fianto sends `order.paid` and `checkout.session.completed` only once the payment is finalized,
because a confirmed block can still be rolled back. So `order.paid` and
`checkout.session.completed` are always about a transfer that cannot be reversed. The dashboard says the same about a `SUCCEEDED` payment: "Finalized on Solana. The money is in your wallet and the transfer
cannot be reversed."

Subscriptions follow the same rule: Fianto sends `subscription.created` when the subscribe
transaction finalizes.

## The payer's success screen is not your proof [#the-payers-success-screen-is-not-your-proof]

None of what the payer's side sees waits for finalized: the success screen, the redirect
to your `success_url` about 3 seconds later, and in popup mode the message the page posts to your
`success_url` origin with `status: 'succeeded'`. None of them proves you were paid.

> **Fulfil only from finalized:**
>
> Never fulfil because the payer reached your `success_url` or because the popup reported success.
> Fulfil from the `order.paid` webhook, or read the order from your server and check that it is
> `PAID`.

A payment can also finalize after its session has closed. See
[Payment lifecycle](/concepts/payment-lifecycle) for what the order and the webhooks do then.

## See also [#see-also]

- [Payment lifecycle](/concepts/payment-lifecycle): Every session, order and payment status.

- [Checkout sessions](/developers/checkout-sessions): Create a session and send the payer to it.

- [Webhooks](/developers/webhooks/overview): How Fianto delivers events to your server.

- [How money moves](/get-started/how-money-moves): What the payer signs and where the USDC goes.