# Retry the payments that failed

URL: /systems/finance/retry-failed-payments · Id: `guide:retry-failed-payments`

> Say "retry the payments that failed" and each unpaid Invoice is tried again over the following days, with access paused only after the last try.

Retry each unpaid [Invoice](/business/nouns/invoice) over the following days, so a declined renewal becomes a paid one before the [Customer](/business/nouns/customer) loses access.

Needs: [Open a bank account](/systems/finance/open-a-bank-account) · [Charge monthly](/systems/finance/charge-monthly)

**Before real money moves**

- Who says yes: Your agent, within a standing [Mandate](/business/nouns/mandate) and its [Limit](/business/nouns/limit). Past the Limit, it waits for your [Approval](/business/nouns/approval).
- You leave the chat: Never: it all happens in the chat.

## What you get
- 4 retries of each unpaid Invoice, spaced out over the following days (Invoice)
- 1 email to the Customer after each failed retry, with a link to update the card (Message)
- 1 standing permission for the Billing Specialist to retry without asking you each time (Mandate)
- 1 pause of the customer’s access only after the last retry fails (Subscription)
- 2 lines in your books when a retry succeeds: cash in and revenue earned (Entry)

## Your agent does
**For agents**

- Guide: `guide:retry-failed-payments`, status `live`. Page: [/systems/finance/retry-failed-payments.md](/systems/finance/retry-failed-payments.md).
- Approval: none inside the standing Mandate and its Limit. Past the Limit, the call waits `pending` for the founder’s Approval.
- Leaves the chat: never.
- Needs first: [Open a bank account](/systems/finance/open-a-bank-account), [Charge monthly](/systems/finance/charge-monthly).
- Run: call the steps in order, each through the API, SDK, CLI or MCP tab below; a later step passes the `$id` an earlier one returns. Each value marked example is the sample business’s: pass the founder’s own.

| Step | Verb | Inputs (type, required, this guide’s value) | Returns |
| --- | --- | --- | --- |
| 1 | [`Invoice.collect`](/business/nouns/invoice/collect) (`verb:Invoice.collect`) | `invoice` Invoice (an id), required: example `"invoice_harbor_0002"` | `invoice` Invoice |

Returns: the last call answers with `invoice` and its `action`, whose `status` is `done`, `pending` (waiting on an Approval or a Worker), `failed`, `canceled` or `refused`:

```json
{
  "api": "https://api.sb/leaseline.app",
  "invoice": {
    "$id": "https://api.sb/leaseline.app/invoices/invoice_harbor_0002",
    "$type": "Invoice",
    "status": "paid"
  },
  "action": {
    "$id": "https://api.sb/leaseline.app/actions/action_1",
    "operation": "Invoice.collect",
    "status": "done"
  },
  "links": {
    "self": "https://api.sb/leaseline.app/actions/action_1"
  }
}
```

Next: offer “Retry six times instead of four”, or “Keep service on until the last retry fails”.

Calls: `Invoice.collect`

Ask:

```text
Retry the payments that failed.
A customer’s card was declined, charge it again.
Chase the renewals that did not go through.
```

API:

```bash
# Invoice.collect
curl -X POST https://api.sb/leaseline.app/invoices/invoice_harbor_0002/collect \
  -H "Authorization: Bearer $STARTUP_BUILDER_API_KEY"
```

SDK:

```ts
import { $ } from 'startup-builder'

await $.Invoice.collect({ invoice: 'invoice_harbor_0002' })
```

CLI:

```bash
npx startup-builder do Invoice.collect --json '{"invoice":"invoice_harbor_0002"}'
```

MCP:

```json
{
  "name": "do",
  "arguments": {
    "code": "return await $.Invoice.collect({ invoice: 'invoice_harbor_0002' })"
  }
}
```

## Change it
- Retry six times instead of four.
- Keep service on until the last retry fails.
- Email me the list of past-due customers every Monday.

## Under the hood
- Systems: [Billing](/systems/billing), [Ledger](/systems/ledger)
- Nouns: [Invoice](/business/nouns/invoice), [Subscription](/business/nouns/subscription), [Mandate](/business/nouns/mandate), [Entry](/business/nouns/entry)
- Events: `Invoice.overdue`, [`Invoice.collected`](/business/events/Invoice.collected), [`Subscription.paused`](/business/events/Subscription.paused)
- Stripe objects: `Invoice`, `PaymentIntent`, `Subscription`

The guide wakes the first time a renewal fails, when `Invoice.overdue` appears in your records. Each retry runs [`Invoice.collect`](/business/nouns/invoice/collect) under the [Billing Specialist](/agents/finance/billing-specialist)'s dunning [Mandate](/business/nouns/mandate), so no retry waits for your yes. The [Billing](/workflows/processes/billing) [Process](/business/nouns/process) holds the schedule: four retries by default, set with `dunning.retries`.