DEV Community

Cover image for CardChase recovers failed subscription charges before churn
Isaiah Kim
Isaiah Kim

Posted on Originally published at thecompound.tech

CardChase recovers failed subscription charges before churn

cardchase.thecompound.tech

CardChase had a real failure mode in commit 04e6130: an admin lookup error could look like "no demo account," allowing a fabricated retry to continue toward payment or email. The fix touched three paths and made the lookup fail closed.


CardChase

The queue

The queue shows seven open charges, their monthly risk, the retry cap, the kill window, and three actions waiting for approval. Each row carries the customer, amount, decline reason, and current rung.

The queue lets me approve, edit, or stop the next retry. Approval stages both the card retry and the customer note behind a 30-second window.

CardChase, The main console: WAITING ON YOU Harborview Group Insufficient funds $899/mo 12d $899.00 on Visa 4242 / rung 2 of 4 / 1 of 4 attempts spen

The record

The record shows receipts for failed charges, drafted notes, staged retries, blocked attempts, capped retries, and recovered charges. Each receipt includes evidence such as the invoice, decline code, rung, or stop authority.

The record preserves why CardChase acted or stopped. A permanent decline writes its own receipt instead of appearing as an ordinary retry.

CardChase, The record: Stopped retrying Meridian Labs The issuer returned do_not_try_again. The card must not be used again for this charge.

The ladder

The ladder shows four rungs across seven days: a silent retry after one day, then notices after three, five, and seven days. The schedule counts from the first failure, not from the previous attempt.

The ladder decides when a charge becomes due. Before staging anything, CardChase checks the issuer advice, hard-decline codes, and raw network response.

CardChase, The ladder: The window covers both halves of a rung, the retry against the card and the note to the customer. A retry that has left

The kill window

The kill-window view shows the 30-second release period shared by the retry and the customer note. An approved action is staged, not sent immediately.

The window lets me undo the action before either side reaches the payment or mail rail. The dispatcher cannot claim the row until the release instant.

CardChase, About: The figures in that record are counted from this product's own claim register rather than written beside it, and the dat

How it works

The workflow moves through five named states: failed charge, ladder, gate, approval window, and receipt. The gate can stop the charge before the ladder produces a retry.

flowchart LR
  A[Failed charge] --> B[Ladder]
  B --> C[Stop gate]
  C --> D[Approval window]
  D --> E[Receipt]

The page explains the same path in the console's own terms. CardChase reads the failed charge, checks whether the next rung is due, stages the action, and records the evidence.

CardChase, How it works: How it works A COPY OF /HOW-IT-WORKS, TAKEN 2026-09-13

The changelog

The changelog shows four shipped changes, including the hard-decline stop, the retry cap, the shared kill window, and direct billing reads. The kill-window entry says approval stages both halves of the action.

Commit 04e6130cf4ba2666c4b8ae559f40c8c99ababd0e fixed the lookup defect in src/app/_lib/dispatch-run.ts, src/app/_lib/pass-run.ts, and src/app/auth/callback/route.ts.

diff --git a/src/app/_lib/dispatch-run.ts b/src/app/_lib/dispatch-run.ts
@@
-  const { data } = adminSupabase().auth.admin.listUsers({ page: 1, perPage: 200 });
+  const { data, error } = adminSupabase().auth.admin.listUsers({ page: 1, perPage: 200 });
+  // A broken admin lookup is not evidence that the demo user is absent.
+  if (error) throw new Error(`Unable to resolve the demo account: ${error.message}`);
Enter fullscreen mode Exit fullscreen mode

I changed the lookup so an error stops the pass before it can reach a real payment or mail rail.

Top comments (0)