Getting started

# Recurring billing

Automate monthly invoices and collect recurring payments from your application.

## How recurring billing works

Manza does not auto-charge stored cards. Your application owns the subscription, billing dates and reminders; the customer authorizes a new payment each period. This guide covers collecting subscription payments, not scheduling outgoing transfers.

1. Run a scheduled job in your application on each billing date.
2. Create a fresh single-use link with `POST /api/payment_links`. Use an open account belonging to your entity, and supply the amount and a `payment_reference` for the billing period.
3. Store the returned link ID against that subscription and period before delivering it.
4. Email or message the returned `url` to the customer from your application.
5. Confirm payment through `payment_link.paid`, then renew access once for that period.

Use a key with `payment_links:write` to create links and `payment_links:read` to reconcile them. See [Payment links](https://ma.manza.dev/docs/api/payment-links#create-payment-link) for request examples, required fields and the deployment's minimum amount. Reusable links accept multiple payments; they do not schedule payments or charge cards automatically.

## Fixed monthly subscriptions

Your application owns the subscription schedule. The API creates individual invoices; it does not create a recurring invoice schedule or a subscription you can cancel. For a customer paying the same amount each month:

1. Create the customer once with `POST /api/customers` and store its ID.
2. Store the agreed line items, amount and billing day in your application.
3. Each month, call `POST /api/invoices` with the same `customer_id` and line items, updated `issue_date` and `due_date`, and a `reference` identifying the billing period.
4. Use `invoices:write` and `invoices:auto_approve` to issue each invoice without monthly manual approval. Include `send_to_email` to queue the invoice email.
5. Store the returned invoice ID against the subscription and billing period. When the subscription ends, stop future creation jobs in your application.

For example, Ruby can build the period reference as `"club-#{club_id}-#{billing_month}"`.

Auto-approval is an API-key permission, not an `approved=true` request parameter. It is not restricted to a fixed amount or a particular agreement: your integration must enforce those rules. A `sent` status does not mean the email was delivered or that the customer has paid. Omitting `send_to_email` still returns `sent`, but does not queue an email.

For issuer logo setup and safe retries, see [Recurring invoices and branding](https://ma.manza.dev/docs/api/invoices#recurring-invoices-and-branding).

## Automate invoice approval

For an invoice each period, use `POST /api/invoices` with `invoices:write` and `invoices:auto_approve`. Supply the customer, issue and due dates, and line items described in [Create invoice](https://ma.manza.dev/docs/api/invoices#create-invoice). Create customers first with `customers:write` if needed.

The response is already `sent`: Manza approves and sends the invoice in the create request. When `send_to_email` is set, it also queues the invoice email. Do not call `POST /api/invoices/:id/send` again for this path.

**This scope bypasses the entity's approval rules, including multi-approval requirements.** Grant it only to an integration trusted to issue invoices without a human decision.

**An invoice is not automatically given a payment link.** To deliver a card-payment request reliably with this path:

1. Create the invoice without `send_to_email` so no invoice email is queued yet.
2. Call `POST /api/invoices/:id/payment_link` with `account_id` and a key carrying `payment_links:write`. The link uses the invoice's amount and currency.
3. Store the returned link ID and send its `url` from your own application.

Setting `send_to_email` on creation queues email before you can attach the link; do not rely on a later attachment appearing in that email. See [Create payment link from invoice](https://ma.manza.dev/docs/api/payment-links#create-payment-link-from-invoice).

## Keep dashboard approval

If invoices need human review, use a key **without** `invoices:auto_approve`:

1. Create the invoice with `POST /api/invoices` and `invoices:write`. It starts in `pending_approval`. Set `send_to_email` to the customer's email.
2. Attach its card-payment link using `POST /api/invoices/:id/payment_link` with `account_id` and `payment_links:write`, before sending the invoice.
3. A member completes **Approve & Send** in the dashboard (Invoicing → Invoices). Once the approval requirements are met, this also sends the invoice and queues its email, including the attached payment link. Do not send it again through the API.
4. Only if an invoice is still `approved`, use `POST /api/invoices/:id/send` with `invoices:send`. Check its current status first.

There is no public invoice-approve API endpoint. See [Approval before send](https://ma.manza.dev/docs/api/invoices#approval-before-send) for both paths.

## Confirm each renewal

Verify the webhook signature and deduplicate deliveries using `X-Manza-Event-Id`. Match the payment link ID to the subscription and billing period you stored. Mark that period paid and extend access only once.

`payment_link.paid` confirms the customer's payment; the link can still be `clearing` while funds settle. If your service must wait for money to land, use `payment_link.payment_settled` instead. A browser redirect alone is not proof of payment. See [Webhooks](https://ma.manza.dev/docs/webhooks) for verification and retry behavior.

Reconcile with `GET /api/payment_links/:id`, including its status and `settled_at`, if delivery is delayed or your integration needs to recover after an outage.

## Retries, reminders and cancellation

Keep one billing record per subscription and period in your own database and prevent concurrent jobs from creating duplicate requests. `payment_reference` is a reconciliation label, not an idempotency guarantee; the same applies to an invoice's `reference`. If creation times out, reconcile the result before creating another invoice or link.

Send reminders for the existing unpaid link rather than creating a new charge each time. If a link expires, reconcile its payment state before issuing a replacement. Stop future billing jobs when a subscription is cancelled; cancel an outstanding active link with `POST /api/payment_links/:id/cancel` when appropriate. Cancelling a link does not cancel an associated invoice or reverse an earlier payment.