# Recurring payments

> [!IMPORTANT]
> **Two surfaces, two jobs.** This Payments API can mark the *first* card payment as the start of a stored-credential relationship (the `subscription` block on `POST /initialize-payment`), but it has no call that charges a stored card by reference and no subscription object. Subscriptions, recurring invoices and off-session charging of a saved card are the **Billing API** at `/billing-api/v1` — same seller secret key, its own reference at `/billing-api/v1/docs`. Do not rely on any `/api/v1/checkout/*` endpoints; they are the dashboard's internal path, not part of either public API.

---

## Which one you need

| You want to | Use |
|-------------|-----|
| Take one card payment now and tell the processor it may be followed by merchant-initiated charges (stored-credential / COF flagging) | This API: `POST /initialize-payment` with `subscription.enabled` and `subscription.allowSubsequentMerchantInitiated` — see [Server-to-Server](https://docs.fynex.ai/payments-api/v2/docs#tag/server-to-server). |
| Bill a customer on a schedule: trials, renewals, plan changes, pauses, cancellations | Billing API: `POST /billing-api/v1/contracts/{contractId}/subscriptions` to create, then `POST /billing-api/v1/subscriptions/{subscriptionId}/cancel` · `/pause` · `/resume` · `/change-plan` · `/end-trial`. |
| Issue and collect an invoice — hosted payment link, bank transfer, or stored credit | Billing API: `POST /billing-api/v1/invoices` and `POST /invoices/{invoiceId}/send`. |
| Charge a returning customer's saved card without them present | Billing API off-session collection: a sent or overdue invoice is charged against the customer's saved card by a background loop, where the deployment has `billing.invoice.auto_charge` switched on (a platform flag operated by Fynex, not a per-account setting). There is no public "charge this card" call on either API. |
| Know that a renewal was paid, failed or went past due | Billing API webhooks: `InvoicePaid`, `InvoiceOverdue`, `BillingSubscriptionPastDue` and the rest of the lifecycle catalogue, on the same signed pipe as `PaymentCompleted`. |

---

## How the two connect

**The customer is shared.** A card payment on this API that carries a customer e-mail (hosted checkout collects it; `merchantCustomerId` is stored as your reference for the same record) resolves to the seller customer that the Billing API's `POST /billing-api/v1/customers` returns for that e-mail. That `id` is the `sellerCustomerId` every contract, subscription and invoice refers to.

**The saved card comes from hosted checkout, not from the `subscription` block.** A card is stored on Fynex only when the buyer ticks *save card* on the hosted checkout page, gives an e-mail, and the payment succeeds with a billing address. The `subscription` block by itself creates a stored-credential anchor at the card processor — enough for the processor to accept later merchant-initiated charges — but does **not** store a card that Billing's collection loop can use. If you rely on off-session collection, your customers must have saved a card on hosted checkout; a server-to-server first payment alone is not enough.

**The rail is the same.** An invoice collected off-session is finalized by the same payment engine as a hosted-checkout payment, so it fires the same `PaymentCompleted` webhook, and the invoice reads `paidVia: payment_link` either way. The payment is stamped with what it settled — its payment link's `metadata` carries `billingInvoiceId`, `invoiceNumber`, `contractId`, `agreementNumber` and `sellerCustomerId` — so you join the two from the payment side without reconstructing anything from an order reference. See the Billing **Workflows** guide.

---

## Stored-credential flagging on this API

| Field | What it does |
|-------|--------------|
| `subscription.enabled` | Marks the payment as the initial transaction of a stored-credential relationship at the processor. Card-only. |
| `subscription.allowSubsequentMerchantInitiated` | With `enabled`, tells the processor later charges may be merchant-initiated (cardholder absent). Send `false` for one-tap re-purchase where the cardholder is always present. |
| `merchantCustomerId` | Your stable customer reference; stored on the payment and on the seller customer record. |
| `skip3DS` | Only for payments that qualify for an SCA exemption (merchant-initiated, recurring with stored credentials). See [3DS](https://docs.fynex.ai/payments-api/v2/docs#tag/3ds). |

> [!NOTE]
> **PCI scope.** Raw card data stays on Fynex's infrastructure, but instructing Fynex to store credentials and relying on merchant-initiated charges moves your integration into a higher-scrutiny PCI DSS category (SAQ D / Merchant Level 2). Consult your QSA before going live with recurring billing.

---

## What is not available

- No public endpoint on either API to charge a previously stored card *by reference* on demand. Off-session charging happens only through Billing's collection loop against a sent or overdue invoice.
- No subscription object on this Payments API. Subscription state lives on the Billing API only.
- Off-session collection retries a declined charge **up to 3 attempts in total, at least 20 minutes apart**, and only when that budget is spent does the subscription go `past_due`. Do not build your own retry on top of it — you would double-charge. A `past_due` subscription recovers on its own when an invoice on the contract is paid. See the Billing **Subscriptions** and **Workflows** guides.

---

## See also

- **Billing API reference** — `/billing-api/v1/docs`: Concepts, Subscriptions, Invoices, Workflows, Webhooks.
- **[Server-to-Server](https://docs.fynex.ai/payments-api/v2/docs#tag/server-to-server)** — The `subscription` block on `POST /initialize-payment`.
- **[Hosted Checkout](https://docs.fynex.ai/payments-api/v2/docs#tag/hosted-checkout)** — Where the buyer saves the card that Billing collects against.
- **[Webhooks](https://docs.fynex.ai/payments-api/v2/docs#tag/webhooks)** — One receiver for `PaymentCompleted` and every Billing event.
