The problem

When a subscription payment fails, PayPal's native handling is short and silent: retry the payment every 5 days, twice, and if both retries fail, suspend the subscription. That is the whole system. The member is never told why their membership stopped or how to fix it. The business loses the payment and usually loses the customer, and most never learn it happened.

Failed payments are involuntary churn, and they hit exactly the businesses least able to absorb them: membership programs, subscription boxes, coaching plans, community tiers — small operations where every member is real revenue and there is no billing department watching for silent suspensions.

The solution

Resurrection treats a suspended subscription as a patient, not a write-off.

  1. Detect. Resurrection reads the suspended subscription and its billing record through the PayPal Subscriptions API — failed payment count, suspension note, outstanding balance.
  2. Diagnose. An AI diagnosis step turns that raw failure data into a plain-language diagnosis of what went wrong, and writes a concrete recovery message for the member: what happened, the exact amount owed, and what paying it restores. The diagnosis runs on deterministic logic over the real subscription data; an optional LLM polish pass (DeepSeek or Kimi) can rewrite the member message with every fact and amount locked, and any failure falls back to the template.
  3. Invoice. Resurrection creates and sends a PayPal recovery invoice for exactly the missed amount through Invoicing v2. The recovery message rides on the invoice, so the member gets one clear document — not a dunning chain.
  4. Recover. The moment the invoice is paid, Resurrection reads the outstanding balance PayPal itself reports on the subscription. If PayPal reports a balance, Resurrection captures it (OUTSTANDING_BALANCE); if PayPal reports none, there is nothing to capture and the recovery rides on the invoice the member just paid. Either way it then reactivates the subscription. No rejoining, no new plan, no fees for the member. One sandbox limitation, stated plainly: a genuinely failed payment cannot be produced on demand in the PayPal sandbox, so the live-tested patient carries an API-reported balance of $0.00 (its first cycle was collected when the buyer approved it) and its recovery rides on the paid invoice; the capture against a positive reported balance is exercised in the app's SIM mode, where the patient carries one.
  5. Verify. The dashboard's $ RECOVERED counter is tallied from Resurrection's own recovery invoices — each invoice read back from PayPal, summing the payments recorded on the paid ones — not from local bookkeeping. A Transaction Search call runs alongside each recovery as independent verification (in the final live verification run on 2026-11-10 it returned 200, and its success was logged alongside the recovery). The counter stands on the invoice records either way — and if the verification call is ever refused, the refusal is shown in the event log, not hidden.

The whole flow runs on a live dashboard built to be watched: the subscription as a patient card, an EKG heartbeat that flatlines on suspension and comes back on reactivation, and a complete event log of every PayPal API call as it happens — method, endpoint, HTTP status. Nothing is hidden behind a spinner.

PayPal APIs used

  • Subscriptions API — read the patient subscription, capture the outstanding balance (OUTSTANDING_BALANCE) when PayPal reports one, reactivate
  • Invoicing v2 — create, send, and poll the recovery invoice; the $ RECOVERED counter is tallied from these invoices' payment records
  • Transaction Search (Reporting API) — independent verification call alongside each recovery (verified live, 2026-11-10)

How it was built

Resurrection is a zero-dependency Python application (standard library only — no framework, no build step): a small HTTP server, a raw-REST PayPal client using OAuth client-credentials, a recovery state machine, and a single-page dashboard. It was designed, built, and verified during the hackathon submission window.

One honest design note: the PayPal sandbox cannot force a real payment to fail on a schedule, so the failed state is seeded — a sandbox subscription is suspended with the same end state PayPal's retry-twice-then-suspend policy produces. Every step of the recovery itself is a real PayPal API call. Two more disclosures in the same spirit: in the live sandbox runs, the member's payment on the recovery invoice was recorded through PayPal's Invoicing record-payment API (an external-payment record — a real API call, but not a payer checkout click), and the sandbox patient's API-reported outstanding balance is $0.00 because its first cycle was collected at buyer approval, so no capture was called on it — the flow detects that, says so in the event log, and completes on the strength of the paid invoice.

The app also ships with a SIM mode used for development and testing before credentials were in place: with no PayPal credentials configured, the full flow runs against a simulated state machine, and every simulated call is permanently labeled SIM in the UI and the event log. Simulated traffic is never presented as real.

Live verification (2026-11-10): the full flow was verified live end-to-end in the PayPal sandbox on a clean, buyer-approved subscription: seed (real suspend of I-X1U9CRW8XLE8), diagnosis generated from the real subscription record, recovery invoice INV2-D455-Z4A2-YKGK-PJTD created and sent, the member's payment recorded through the Invoicing record-payment API (payment EXTR-9A071574XW8456717; invoice MARKED_AS_PAID), the settle step reading the outstanding balance PayPal itself reports ($0.00 — so no capture was called and the recovery rode on the paid invoice, exactly as the copy above describes), reactivation to ACTIVE on the original $9.99 plan, and the $ RECOVERED counter tallying $9.99 from the invoice's own payment record with the Transaction Search verification call returning 200 in the same run. The disclosures in the copy above stand as written: the invoice payment was recorded through the record-payment API (a real API call recording an external payment — not a payer checkout), and a genuinely failed payment cannot be produced on demand in the PayPal sandbox, so the live patient's API-reported balance is $0.00; capture against a positive reported balance is exercised in the app's SIM mode, where the patient carries one.

What a judge can do with it

Try the live demo: https://nuviratech-resurrection-demo.static.hf.space — the project's dashboard running its simulation entirely in the browser (permanently badged as a simulation demo; no server, no real PayPal calls), so the full flatline-to-revival flow can be clicked through with nothing to install.

Or run the real app: clone the repo, run python3 app.py, open the dashboard. With sandbox credentials set, admit a patient, run the diagnosis, send the invoice, record the member's payment through the Invoicing record-payment API (or pay it as a sandbox buyer through the invoice's payer-view link), then settle and reactivate — and watch the counter tally the recovery from the invoice's own payment record, with a Transaction Search verification call alongside it. A render.yaml Blueprint for a free hosted deployment is included.

Built With

Share this project:

Updates

Submission history