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

# Recurring Payments

> Create subscriptions that debit your customer's Flouci wallet on a schedule, with a status model modeled on the industry standard.

<Info>
  Recurring payments are being rolled out to selected merchants. The endpoints on these pages are not yet available on the public production API — your Flouci contact will tell you when your app is enabled.
</Info>

A **subscription** lets you charge a customer the same amount on a fixed cadence — every week, every month, every year — after they approve it once. You create the subscription, your customer pays the first charge on the hosted checkout with their Flouci wallet and accepts the recurring debit, and Flouci then debits the wallet at each renewal without the customer present. Every state change is pushed to your `webhook` as a signed event, and every charge is an ordinary payment you can verify with [Verify Payment](/api-reference/verify-transaction).

## How it works

<Steps>
  <Step title="Create the subscription">
    Call [Create Subscription](/api-reference/recurring-payments/create-subscription) with the amount, the cadence and your links. You get a `subscription_id`, the `payment_id` of the first charge and a checkout `link`. The subscription is `incomplete` until that first charge is paid.
  </Step>

  <Step title="The customer approves it on the checkout">
    Redirect your customer to the `link`. The checkout shows the payment as recurring — amount, cadence and the consent text — and the customer pays with their Flouci wallet. In the Flouci app they explicitly accept the mandate before the debit. See [Checkout experience](/api-reference/recurring-payments/checkout-experience).
  </Step>

  <Step title="The subscription activates">
    When the first charge succeeds the subscription becomes `active`, its billing cycle is anchored on the payment time, and you receive `subscription.activated` and `subscription.charge.succeeded`. Provision access now.
  </Step>

  <Step title="Renewals run on their own">
    At the start of each new period Flouci debits the wallet at 09:00 (Africa/Tunis). Each renewal is a new `payment_id` you receive in `subscription.charge.succeeded` — or `subscription.charge.failed`, in which case the subscription becomes `past_due` and is retried. See [Failed renewals](#failed-renewals).
  </Step>

  <Step title="Cancel when it ends">
    You cancel through the API or the business dashboard; the customer can cancel at any time from « Paiements récurrents » in the Flouci app. You receive `subscription.canceled` either way.
  </Step>
</Steps>

## Lifecycle

```mermaid theme={null}
stateDiagram-v2
    [*] --> incomplete: POST /subscriptions
    incomplete --> active: first charge paid
    incomplete --> incomplete_expired: session_timeout elapsed / first charge failed
    active --> active: renewal paid (new period)
    active --> past_due: renewal failed
    past_due --> active: a retry succeeds
    past_due --> canceled: 3 retries failed (default)
    past_due --> unpaid: 3 retries failed (kept unpaid)
    active --> canceled: cancel (merchant, customer or max_cycles reached)
    past_due --> canceled: cancel
    incomplete --> canceled: cancel before payment
```

### Statuses

| Status | Meaning | What to do |
| - | - | - |
| `incomplete` | Created; waiting for the customer to pay the first charge on the checkout. `checkout_url` and `payment_id` are returned so you can send the customer back to it. | Nothing yet. Do not provision. |
| `incomplete_expired` | The first charge was not paid within `session_timeout` (or failed). Terminal. | Create a new subscription if the customer still wants it. |
| `active` | In good standing. `next_charge_at` says when the next renewal is debited. | Provision access. |
| `past_due` | The latest renewal failed. Retries are scheduled — see [Failed renewals](#failed-renewals). | Keep or suspend access according to your policy; the customer is notified in the app. |
| `unpaid` | Retries exhausted and the subscription was kept rather than canceled. No further charges. | Revoke access. |
| `canceled` | Ended — by you, by the customer, by the system after failed retries, or because `max_cycles` was reached (`cancellation_reason: completed`). Terminal. | Revoke access at the end of the paid period. |

Terminal statuses (`canceled`, `incomplete_expired`) never change again. A customer who wants to come back needs a new subscription.

## Billing periods

* The **anchor** is the moment the first charge is paid. Period 0 runs from the anchor to the same calendar day one cadence later; every following period boundary falls on local midnight (Africa/Tunis) of the anchor's calendar day shifted by whole cadences.
* Boundaries are always computed from the anchor, never from the previous period, so nothing drifts across months of different lengths. A subscription taken on **31 January** renews on **28 February**, then again on **31 March**.
* The renewal debit runs at **09:00 Africa/Tunis on the first day of the new period**. `next_charge_at` on the subscription tells you the exact instant; it is `null` while a charge is in flight.
* `current_period_start` / `current_period_end` describe the period the customer has paid for.

<Tip>
  Provision access for `[current_period_start, current_period_end)`. When a renewal succeeds the period rolls forward; when it fails you still have the paid period to fall back on.
</Tip>

## Failed renewals

A renewal fails when the customer's wallet balance is insufficient or the ledger refuses the debit. The subscription becomes `past_due` and Flouci retries automatically:

| Attempt | When |
| - | - |
| Retry 1 | 1 day after the failure |
| Retry 2 | 3 days after retry 1 fails |
| Retry 3 | 7 days after retry 2 fails |

If a retry succeeds, the subscription returns to `active` (you receive `subscription.reactivated`) and the paid period keeps its original boundaries — the next renewal is still due at the end of that period. If the third retry fails, the subscription is **canceled** (`subscription.canceled`, `cancellation_reason: dunning_exhausted`). Keeping an exhausted subscription as `unpaid` instead is a per-subscription setting that is not yet exposed in the API.

The customer receives a push notification at each failure with the next retry date, and a reminder 24 hours before every scheduled renewal.

## Cancelling

* **You** call [Cancel Subscription](/api-reference/recurring-payments/cancel-subscription), immediately or `at_period_end`, or cancel from the business dashboard.
* **Your customer** cancels from « Paiements récurrents » in the Flouci app (PIN or biometric confirmation). You receive `subscription.canceled` with `cancellation_initiator: customer`.
* **Flouci** cancels when the retries are exhausted, when `max_cycles` payments have been collected (`cancellation_reason: completed`), or when the customer's wallet is closed (`customer_wallet_closed`).

## Payment methods

| Method | Status |
| - | - |
| Flouci wallet (`flouci`) | Available. The customer pays the first charge on the checkout with their wallet and accepts the mandate in the app; renewals debit the same wallet. Wallets held at another bank (mobile switch) cannot be used for a subscription. |
| Card (`card`) | Coming soon. `accept_card: true` is refused until card recurring is enabled on your affiliation. Note that [Pay with Binding](/api-reference/advanced-payment-flow/confirm-binding) requires the CVC on every charge and is therefore not a mechanism for unattended recurring debits. |

## Idempotency and limits

* `developer_tracking_id` is unique per merchant. Repeating one returns **HTTP 409** with the existing `subscription_id`, `payment_id` and `link`, so a retried create never opens a second subscription.
* Creation is limited to **60 requests per minute per app** (HTTP 429 beyond).
* Amounts are integers in **millimes**, `TND` only, minimum 100 millimes.
* A billing cycle may not exceed one year: `interval_count` is at most 366 for `day`, 52 for `week`, 12 for `month` and 1 for `year`.
* Split payments (`destination`) are not supported on subscriptions.

## Endpoints

<CardGroup cols={2}>
  <Card title="Create Subscription" icon="plus" href="/api-reference/recurring-payments/create-subscription">
    Create a subscription and get the checkout link for its first charge.
  </Card>

  <Card title="Get Subscription" icon="magnifying-glass" href="/api-reference/recurring-payments/get-subscription">
    Read the current state, billing period and latest charge.
  </Card>

  <Card title="List Subscriptions" icon="list" href="/api-reference/recurring-payments/list-subscriptions">
    Paginate your subscriptions, filtered by status or customer.
  </Card>

  <Card title="List Charges" icon="receipt" href="/api-reference/recurring-payments/list-charges">
    Every charge of a subscription, newest first.
  </Card>

  <Card title="Cancel Subscription" icon="ban" href="/api-reference/recurring-payments/cancel-subscription">
    Stop now or at the end of the current period.
  </Card>

  <Card title="Webhooks" icon="bell" href="/api-reference/recurring-payments/webhooks">
    Signed events for every state change.
  </Card>
</CardGroup>

Every charge — the first one and each renewal — is a regular payment: [Verify Payment](/api-reference/verify-transaction) and [Transaction History](/api-reference/transaction-history) return it with a `subscription_id` and a `billing_reason` (`subscription_create`, `subscription_cycle` or `subscription_retry`).


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.