# Subscriptions (/merchants/subscriptions)

A subscription charges a payer's wallet every 30 days or every 365 days, at the price they
subscribed to. **Subscriptions** ("Recurring USDC billing, one row per subscription.") lists them,
and each subscription's page shows its status, its billing periods and a **Cancel this
subscription** panel. The dashboard cannot start a subscription: selling one needs your server.

**When Fianto retries a renewal**

1. Fianto's charging key tries each renewal 2 minutes after the period ends, then 1 hour after, 6 hours after and 24 hours after, measured from the period end when nothing delays them. After a delay not caused by the payer, each retry keeps its gap from the last failure.
2. Counted failures are `INSUFFICIENT_FUNDS`, `DELEGATION_REVOKED`, `ACCOUNT_FROZEN` and `ACCOUNT_CLOSED`. Each one sends `subscription.payment_failed`.
3. The first counted failure moves the subscription to `PAST_DUE` and sends `subscription.past_due` once.
4. Any other failure is not counted: Fianto retries it every 5 minutes.
5. A successful charge moves the subscription back to `ACTIVE`.
6. The 4th counted failure ends it: `ENDED` with reason `PAYMENT_FAILED`.
7. No back-billing: missed periods are never billed.

## Before you start [#before-you-start]

* Your account is approved.
* You have a recurring price. See [Products and prices](/merchants/products-and-prices).
* Your server can create checkout sessions. Selling a subscription needs the API: see
  [Do I need a developer?](/get-started/do-i-need-a-developer).

## Steps [#steps]

**Step 1.**

### Sell the recurring price from your server [#sell-the-recurring-price-from-your-server]

Your server creates a checkout session with `mode: subscription` and the recurring price's
`fian_price_…` id, and sends the payer to it. There is no other way to sell a subscription: no page
in the dashboard creates one. The developer guide is
[Subscriptions](/developers/subscriptions).

The first such session for a price also creates its plan on Solana. The price's **On-chain plan**
column on the product page says "Being created" and then "Live"; payers can pay once it is live.
Fianto signs and pays for the plan.

**Step 2.**

### Follow the subscription [#follow-the-subscription]

When the payer's subscribe transaction finalizes, the subscription appears with the status
"Active". The first period is paid inside that transaction; **Billing periods** lists the 24 most
recent periods, newest first.

Fianto charges each renewal itself: the payer does not sign again, and Fianto pays the network fee
for renewals.

**Step 3.**

### Watch for past-due subscriptions [#watch-for-past-due-subscriptions]

A renewal can fail for a reason the payer can fix: not enough USDC, the approval removed, or the
USDC account frozen or closed. Those failures are counted. The first one makes the subscription
"Past due", and it appears under **Needs attention**. A later successful charge makes it "Active"
again. The 4th counted failure ends it, with the reason "Payment failed". Other failures are retried
every 5 minutes and never count, except a renewal refused because the payer already cancelled on
Solana: Fianto records that as the payer's cancel instead. Missed periods are never billed later.

**Step 4.**

### Cancel a subscription, if you need to [#cancel-a-subscription-if-you-need-to]

Open the subscription and go to **Cancel this subscription**:

* **Cancel at period end** asks "Stop this subscription at the end of the current period? Fianto
  will not start another charge for it." The subscription keeps its status, "Active" or "Past
  due", with the cancellation shown as scheduled, and Fianto sends `subscription.cancel_scheduled`.
  A past-due subscription then reads "Past due, but a cancellation is scheduled": Fianto will not
  retry the failed charge.
* **Cancel now** asks "End this subscription now? It ends immediately and cannot be restarted."
  It then reads "Canceled. The subscription has ended." and Fianto sends `subscription.ended`.

Cancelling needs no password or code. Your server can do the same with
`POST /v1/subscriptions/{id}/cancel`; the rules below are the same either way.

> **A cancel changes nothing on Solana and cannot be undone:**
>
> Cancelling only stops Fianto from starting new charges. Nothing is signed on Solana, so the
> payer's subscription there stays live. A cancel cannot be reversed. With **Cancel now**, a renewal
> charge already on its way to Solana can still land: the period then shows as paid.

> **Refunds are yours to send:**
>
> A cancel refunds nothing, and there is no refund API. To refund a payer, send the USDC back from
> your own wallet. Each charge is the price plus, when it is above zero, the service fee, which the
> payer pays on top.

## What your cancel means for the payer [#what-your-cancel-means-for-the-payer]

Because the payer's subscription stays live on Solana, the same wallet cannot subscribe to the same
plan again until the payer uses **Cancel on Solana** in the Fianto payer portal, waits for the
on-chain end and reclaims the rent. While your cancel at period end is pending, the portal offers
the payer no cancel of its own.

When the payer cancels first, the subscription page shows the cancel as "Requested by the payer",
and notes that the payer can change their mind before then. To make sure it ends, cancel at period
end too: it then ends even if the payer changes their mind.

## When your wallet or the fee changes [#when-your-wallet-or-the-fee-changes]

A subscription is set up on Solana to pay one wallet, with one fee. After your receiving wallet
changes, or the fee changes, Fianto creates a new plan the next time your server creates a
subscription session for the price. New subscribers get the new wallet and fee; existing
subscribers keep paying the old wallet, with the old fee. Keep the old wallet safe until those
subscriptions have ended.

## Check it worked [#check-it-worked]

> A new subscription is listed as "Active". After **Cancel at period end**, it stays "Active" and its
> status reads "Active, but a cancellation is scheduled"; it becomes "Ended" with the reason "Canceled by you" after
> the period ends. After **Cancel now**, it is "Ended" at once.

## Troubleshooting [#troubleshooting]

| You see | Why | Fix |
|---|---|---|
| "Another update to this subscription was in progress, so nothing was changed. Try again in a moment." | Something else was changing the subscription at the same time. | Try again in a moment. |
| "Too many changes in a short time. Wait a minute and try again." | Too many requests in a short time. | Wait a minute. |
| "Something went wrong, and we can't tell whether the cancellation went through." | The dashboard did not get an answer. | Refresh the page to see the subscription's current state before trying again. |
| A payer cannot subscribe again after your cancel | Their subscription is still live on Solana. | Ask them to use Cancel on Solana in the payer portal, wait for the on-chain end and reclaim the rent. |
| The On-chain plan column says "Being created" | Fianto is creating the plan on Solana after the first subscription session. | Wait. Payers can pay once it is live. |
| The checkout page cannot start the subscription, and the On-chain plan column is back to "Not created yet" | Creating the plan on Solana failed after every retry. | Have your server create a new subscription checkout session for the price: it starts a new attempt. If that fails too, write to support@fianto.xyz. |

## See also [#see-also]

- [Subscriptions for developers](/developers/subscriptions): Create subscription sessions and cancel from your server.

- [Needs attention](/merchants/needs-attention): Where past-due subscriptions are counted.

- [Security](/merchants/security): Changing your receiving wallet.