# Handling a failed card

URL: /code/learn/handling-a-failed-card · Id: `page:code/learn/handling-a-failed-card`

> Tutorial 10 of 12 follows Birchwood Lettings' failed renewal on 2026-10-13 through Stripe, the Events it raised and the follow-up Workflow.

On 2026-10-13, Birchwood Lettings' card failed on its $29 `pro` renewal. Stripe leads every money record, so the [Invoice](/business/nouns/invoice), the retry and the [Events](/business/nouns/event) all start there.

## What you build
You trace the failure from [invoice](/business/nouns/invoice) `LEAS-0018` to the [Events](/business/nouns/event) it raised, then write the [Workflow](/business/nouns/workflow) that tries the card again. Nothing in this tutorial moves money by hand.

## Steps
1. To read the Invoice, get it by id. It is an `upstream` [Resource](/business/nouns/resource): [api.sb](/code/platform/api-sb) reads it through from Stripe and keeps a mirror:

   ```bash
   npx startup-builder do Invoice.get --json '{"id":"inv_FXANyzQojc"}'
   ```

   It is `open`, due 2026-10-13, for $29.

2. To see what the failure set off, list the Events of 2026-10-14:

   ```bash
   npx startup-builder show /events --fields 'seq,name,at'
   ```

   `Invoice.overdue` fired at 08:00 and `Subscription.pastDue` at 08:05.

3. To try the card again, write the Workflow that wakes on the first of those Events:

   ```ts title="workflows/billing/past-due-follow-up.ts"
   on.Invoice.overdue(async (invoice, $) => {
     await $.step('retry', () => $.Invoice.collect({ invoice: invoice.$id }))
   })
   ```

4. To rehearse it in test, fire the Event and read the delivery:

   ```bash
   npx startup-builder trigger Invoice.overdue
   ```

## Result
The morning after an Invoice goes overdue, Leaseline asks Stripe to collect it again, once. Leaseline's own follow-up also emails the pay link and opens a [Task](/business/nouns/task) for the founder after 7 unpaid days. Checkpoint `leaseline@ch10` (status `planned`) adds `workflows/billing/`.

## Next steps
- [Tutorial 11](/code/learn/reviewing-a-change) ships the Workflow through review as one [Change](/business/nouns/change).
- [Stripe](/code/platform/stripe): which side leads for each money record.