Braintree failed-payment recovery queue for billing teams
One screen where your billing team works every declined Braintree charge: retry the card on file, email the customer, or write it off with a reason.
Build me a failed-payment recovery console for my billing team. This is a working queue, not a report: every row is a declined payment that somebody has to chase, and this app is where they actually do the chasing.
The main screen lists every declined, failed and gateway-rejected Braintree transaction from the last 30 days, loaded with Braintree Search Transactions filtered by those statuses. Across the top, show two running totals: revenue at risk, which is the summed amount of every failed payment in the window that has not been recovered or written off, and revenue recovered this month, which is the summed amount of retries that succeeded in the current calendar month.
Group the queue into two buckets based on the decline code on each transaction. The 'retry worth it' bucket holds the soft declines: insufficient funds, limit exceeded, cardholder activity limit exceeded, issuer or processor temporarily unavailable, and the generic try-again processor declines. The 'do not retry' bucket holds the hard declines: lost card, stolen card, suspected fraud, pick up card, card reported lost or stolen, invalid card number and no account. Hard-decline rows must be visually locked, with the retry action disabled and a short plain-English reason shown for why, and they must never be retried automatically under any circumstances.
Two refinements on that split. Treat expired card and invalid expiration date as do-not-retry rows, but steer the rep toward the email action on those instead of just locking them, since a fresh card is the only thing that will ever fix them. For gateway rejections, use the rejection reason the same way: duplicate, fraud and risk-threshold rejections are locked, while AVS and CVV rejections belong with the email-them rows because the customer needs to re-enter their details.
Clicking a row opens a detail panel for that payment. Show the customer record from Braintree Search Customers, their charge history split into past successful and past failed payments from Search Transactions scoped to that customer, and any recent card verification results from Braintree Search Verifications. The whole purpose of this panel is to let the rep tell a one-off blip apart from a dying card, so make that pattern jump out visually: a customer who has paid ten times and failed once should look obviously different from one whose last four charges and two verifications have all failed.
From that panel the rep can take three actions. Retry charges the customer's vaulted payment method for the original amount using Braintree Charge Payment Method, with the result appearing inline on the row straight away, either success or a fresh decline code, without a page reload. Send email uses Gmail Send a Message to send a 'please update your card' note built from an editable template with the customer name, the amount and the invoice or order reference already filled in. Write off dismisses the row from the queue and requires the rep to pick or type a reason first.
Every retry and every write-off posts to a billing channel in Slack using Send a Message, so the audit trail maintains itself. Include the customer, the amount, the transaction reference, which rep acted and the outcome, including the new decline code when a retry fails. Use the user-token Slack integration rather than a bot here on purpose: these entries should read as authored by the rep who took the action, which is exactly what makes them useful as an audit trail.
Bake in the guardrails that matter. Cap retries at three attempts per transaction and lock the row once that is exhausted, so the only moves left are email or write off. Let each rep claim a row before working it, show who holds it and since when, and disable rather than hide the actions for everyone else so it is clear a row is taken rather than missing. Let a rep release a claim, and expire stale claims automatically after a day so nothing gets stranded when someone goes on holiday.
Braintree does not store any of this queue state, so persist it in the app itself: retry count and the full retry history per transaction, who claimed each row and when, write-off status and reason, and which customers have already been emailed and when. Revenue recovered should come from the app's own record of successful retries rather than being re-derived from Braintree on every load.
Give the queue the basics that make it fast to work: search by customer name or email, filter by bucket, by claim status and by whether a row has already been emailed, and sort by amount so the biggest recoveries float to the top.
One constraint to design around: there is no subscription or dunning-schedule operation available in Braintree, so recovery here is deliberately manual retries against vaulted payment methods rather than an automated dunning ladder. The value of this app is the queue itself and the guardrails around the rep's judgement, not a scheduler.
What does this prompt do?
- Pulls every declined, failed and gateway-rejected Braintree payment from the last 30 days into a single working queue, with the revenue at risk and the revenue you have already recovered this month sitting at the top.
- Sorts each payment into 'worth retrying' or 'do not retry' based on why the card was declined, so nobody burns a retry on a stolen, closed or fraudulent card.
- Opens the full picture of a customer on click: who they are, what they have paid before, what has failed, and whether their card has been failing checks lately, so a one-off blip is easy to tell apart from a dying card.
- Lets a rep retry the saved card, send a 'please update your card' email, or write the payment off with a reason, and posts every retry and write-off to Slack so the audit trail keeps itself.
What do I need to use this?
- A Braintree account containing the payments you want to recover, with saved cards on file for the customers you plan to retry.
- A Gmail account to send the 'please update your card' emails from.
- A Slack workspace with a billing channel where retries and write-offs get logged.
- Your team's own view on which decline reasons are worth a second attempt, if it differs from the standard soft and hard decline split.
How can I customize it?
- Change the 30 day lookback window, or move specific decline reasons between the 'worth retrying' and 'do not retry' buckets to match how your team works.
- Adjust the retry cap, which starts at three attempts per payment, and how long a claimed row stays locked to one rep before it frees up again.
- Rewrite the customer email template and point the audit log at whichever Slack channel your billing team actually reads.
FAQs
Does this retry failed payments automatically?
What is the difference between a soft and a hard decline?
Could two people end up chasing the same customer?
Will a customer get charged twice by mistake?
Does this work with Braintree subscriptions and recurring billing?
Related templates
Search creators for free, shortlist the best with your team, and spend an audit credit only when you decide someone is worth a closer look.
One screen showing invited, completed, and shortlisted counts for every open role, plus the stalled invites that have quietly gone nowhere.
A calibration board that lines up every candidate's answer to the same question, hides names until your panel has scored, and writes the agreed rating back.
Search three months of global coverage on your topic, rank the outlets actually writing about it, and draft a tailored pitch for each one.
Open one board every morning to see every outstanding quote by age and value, decide on each one, and send follow-ups only after you approve them.
Open one board each morning to see which of your facilities, suppliers and shipping lanes are sitting near trouble in the news right now.
Stop working declined payments out of a spreadsheet.
Give your billing team one screen to retry, email and write off failed Braintree charges, with every action logged in Slack automatically.