Skip to content

Collects as they arrive, acts daily

Track failed payments until they're recovered

Every failed payment is followed until it's paid, and each Friday you see what's recovered and what's still unpaid.

Runs
Collects as they arrive, acts daily
Apps
Stripe
AI
Not needed
Access
read

Send this to your assistant

Create a ClickRuntime automation: keep track of every failed Stripe invoice payment, mark it recovered when it's later paid, and every Friday email me what's still unpaid and the total recovered.

Paste it into your assistant. It tells you what it will send or change before it runs live.

First time? Adding ClickRuntime to your assistant takes about two minutes.

Why use it

Why teams use this automation

A subscription company knows failed payments happen, but not how many are recovered. A card fails on the 3rd, Stripe retries three times, and the customer either updates their card or quietly disappears. Finance sees only the end result in monthly revenue, with no visibility on which failures are still open, how much money is at stake or whether recovery efforts are working. Without a tracker, recovery stays a guess.

ClickRuntime records each failed payment as it arrives and clears it when the matching invoice is paid. Every Friday it emails a summary: how much remains outstanding, how much was recovered this week and how many accounts are still at risk, so you know where to focus before the weekend.

It suits teams that run dunning through Stripe and want a clear weekly picture.

What you get out of it

  • You see the money still at risk

    An outstanding total makes the stakes concrete. Knowing 6,200 dollars of renewals remain unpaid focuses attention more than a general sense that some payments failed. The number gives the team a goal to chase during the week.

  • Recovery performance becomes measurable

    Comparing recovered amounts week to week shows whether dunning emails, retry timing or card update prompts are working. You can test a change and see its effect in the next summary.

  • Follow-up is aimed at the right accounts

    The list of unrecovered failures tells your team exactly who to contact before access is cut off. Effort goes to unpaid accounts, not to customers who already fixed the problem.

  • Closed failures drop off automatically

    When an invoice is paid, its failure entry is cleared, so the Friday email never nags you about resolved cases. The list stays short and trustworthy. Resolved cases never clutter the report, so the list stays short.

  • Forecasts reflect reality

    Finance can separate expected recoveries from likely losses when planning cash. That makes revenue projections more accurate and avoids a nasty surprise at month end. A clearer recovery picture also helps when setting growth targets and budgets.

How it works

What happens, step by step

  1. Every time a Stripe payment fails, ClickRuntime adds it to its list of unpaid payments.

  2. When that invoice is later paid, it is moved from unpaid to recovered.

  3. Every Friday you get an email with the payments still unpaid and the total recovered so far.

Before it runs live

  • Connect Stripe
  • Paste your automation's link into the other app's webhook settings

What you get

RunsCollects as they arrive, acts daily
Track failed payments until they're recoveredtoday, 9:00Succeeded
Email · Failed payments: 3 unpaid, $1,180.00 recoveredStill unpaid: • billing@acme.example: $299.00 • ops@northwind.example: $79.00

Build your own

Need it to work differently?

This template is a starting point. Copy the prompt and change it, or describe a different automation from scratch, with your own conditions, more apps or an AI step. Your assistant writes it, tests it and runs it on ClickRuntime.
  • Your own rules

    Conditions, thresholds, filters and exceptions, written the way you'd explain them to a colleague.

  • Any number of apps

    One automation can read from one app and update several others. Over 248 apps are ready, and anything with an API works too.

  • AI where it helps

    Summaries, classification, extraction and drafts use ClickRuntime's built-in AI, with no extra key.

  • On a schedule or on each event

    Runs as often as every 5 minutes, or the moment an app sends an event, and keeps track of what it already handled.

Changes you can ask for

  • Act only on the items that match your own rules, and skip the rest
  • Add an AI step, for example to summarize, sort or draft a reply
  • Add another app, for example also send it to Slack
  • Combine it with other Stripe steps into one automation

Under the hood

The code that runs this automation

This is the Python script that runs each time the automation starts. Your AI assistant writes it for you when you send the prompt, and you allow each step in your assistant. To change how the automation works, describe the change to your assistant and it updates the script for you. For every function it can use, see the script reference.
failed_payment_recovery_tracker.pyexample
from clickruntime import on_event, on_trigger, state, notify, verify, credentials

@on_event
def handle(event):
    if not verify.stripe(event.body, event.header("Stripe-Signature"), credentials.secret("STRIPE_WEBHOOK_SECRET")):
        return {"ignored": "bad signature"}
    inv = event.json["data"]["object"]
    failed = state.get("failed") or {}
    if event.json["type"] == "invoice.payment_failed":
        failed[inv["id"]] = {"customer": inv.get("customer_email"), "amount": inv["amount_due"]}
    elif event.json["type"] == "invoice.paid" and inv["id"] in failed:
        state.set("recovered", (state.get("recovered") or 0) + failed.pop(inv["id"])["amount"])
    state.set("failed", failed)
    return {"outstanding": len(failed)}

@on_trigger
def friday_report(event):
    failed = state.get("failed") or {}
    recovered = state.get("recovered") or 0
    lines = [f"• {f['customer']}: ${f['amount'] / 100:,.2f}" for f in failed.values()]
    notify.email_me(f"Failed payments: {len(failed)} unpaid, ${recovered / 100:,.2f} recovered",
                    "Still unpaid:\n" + ("\n".join(lines) or "none"))
    return {"unpaid": len(failed), "recovered": recovered}

FAQ

Common questions

How does it know a payment has been recovered?
When Stripe sends an event showing the invoice was paid, the stored failure for that invoice is removed and its amount is counted as recovered. A paid event is the only thing that clears a failure.
What if a customer cancels instead of paying?
A failure stays on the list until the invoice is paid or you tell it otherwise. You can add a rule that moves failures into a lost bucket when the subscription is canceled, so the totals show lost revenue separately.
Can the summary go to a Slack channel instead of email?
Yes. The Friday message can be posted to Slack or sent to several recipients at once. Name the destination to your assistant, check the preview of the change and approve it before the next Friday run.
What permissions does it need?
read. Nothing else in your accounts is used.
Does it need AI?
No. It runs without AI, so it doesn't use your plan's AI allowance.
How many runs does it use?
One run each time it checks. Checks that find nothing new and stop right away aren't counted.
Can I change how it works?
Yes. Describe the change to your AI assistant, for example a different schedule, channel or filter. It updates the automation, tests it and tells you what changed.

Set up “Track failed payments until they're recovered” from your assistant

Copy the prompt above, or connect your assistant first. Free plan, no credit card.