Card-on-file console for subscription billing teams
A worklist of customers whose saved cards are expiring, duplicated, or missing, so your team can fix them before the next rebill fails.
I want an internal app for our subscription operations team to keep customer cards on file healthy and to rescue rebills that are about to fail. The people using it are billing and retention ops, and the point is to work a queue of at-risk customers before the next rebill breaks, not to react after a decline.
Design around this constraint. Adyen can only list stored payment methods for one shopper at a time, keyed by shopperReference, and there is no operation that enumerates every shopper. So HubSpot is the customer index, not Adyen. During setup the app should ask which HubSpot property holds the Adyen shopper reference on a contact or a company (for example a custom property called adyen_shopper_reference), and which Adyen merchant account and default currency to bill in, and save that configuration. The app always reads the shopper reference off the HubSpot record and never tries to list customers from Adyen.
The landing page is a worklist, not a search box. It lists customers who need attention with a reason on each row: card expiring in the next sixty days, duplicate tokens on the same shopper (same brand and same last four), or no usable card on file at all. Build the worklist by iterating the HubSpot records that carry a shopper reference using Search Contacts and Search Companies, then fetching tokens per shopper with Adyen List Stored Payment Methods. Persist the last seen token state per shopper (token id, brand, last four, expiry month and year, and when it was fetched) so the worklist renders from stored state instead of calling Adyen for every customer on every page load. Give the team a Refresh action for a single customer and for the whole queue, and show the last refreshed time on each row. Let them filter by reason and sort so the queue can actually be worked down.
There is also a search view where the team can find any customer by name, email or company domain using HubSpot Search Contacts and Search Companies. Opening a customer from either the worklist or search shows the detail view: the HubSpot record summary plus every card Adyen holds for that shopper from List Stored Payment Methods, each showing brand, last four digits and expiry, with badges for expiring soon, duplicate, and no usable card.
Per card the team can do three things. First, delete a dead or duplicated token with Adyen Delete Stored Payment Method, always behind a confirmation dialog that names the exact card being removed, because deletion is irreversible. Second, retry an outstanding amount against a chosen card with Adyen Make a Payment: the team enters an amount and currency, and the app sends the amount as an object in minor units (value 1000 with currency EUR means 10.00), passes the shopper reference together with the stored payment method id because a retry against a stored token is a merchant initiated transaction, generates a fresh reference for every attempt, and sets an Idempotency-Key header so a double click cannot charge the customer twice. Disable the retry button while a request is in flight and surface the result plainly, including the refusal reason when the payment is refused. Third, when no card works, fall back to Adyen Create Payment Link for the outstanding amount so the customer can pay themselves, and display the link so the team can copy and send it. Use Adyen List Payment Methods to show which methods are actually available for the customer's country and currency when building a link or picking how to retry.
Every action writes a HubSpot note with Create Note, associated to that contact or company, so the account owner sees the history in the CRM. The note should say which token was deleted, which retry was attempted against which card and what the result was, or which payment link was generated with its amount and URL, plus who on the team did it and when. Keep an in-app log of the same actions.
At the end of a working session the team can send a recap to the retention channel with Slack Bot Send a Message, built from that action log: retries attempted and how many recovered, total value recovered, dead or duplicate tokens deleted, payment links sent, and how many customers still have no usable card. Let the user choose the channel.
Also support one off requests to remove a customer's card on file, since people ask for that under privacy rules, using the same confirmation step and the same note trail.
What does this prompt do?
- Opens on a worklist of customers whose saved card is about to expire, is duplicated, or is missing entirely, so your team has a queue to work through instead of a blank search box
- Shows every card a customer has on file with the brand, last four digits and expiry date, and flags the ones that need attention
- Lets the team remove a dead or duplicate card behind a confirmation, retry an outstanding amount against a card that should work, or send the customer a payment link when nothing works
- Writes every action back to the customer record in your CRM and posts a recap of the day's recoveries and clean ups to your retention channel
What do I need to use this?
- An Adyen account that stores cards on file for your customers
- A HubSpot account where your customers live, plus a field on the contact or company that holds each customer's Adyen shopper id
- A Slack workspace and a channel for your retention or billing team
- Confirmation of which Adyen merchant account and currencies you bill in
How can I customize it?
- Change the expiring soon window from sixty days to whatever matches your billing cycle
- Choose which customers land in the worklist, for example only active subscribers or only accounts above a certain value
- Pick the Slack channel and decide whether the recap goes out daily or at the end of each working session
FAQs
Will this work with a free HubSpot account?
Can someone accidentally charge a customer twice by clicking retry twice?
Can we undo deleting a card?
Does the app store our customers' card numbers?
Why do we need to put the Adyen shopper id on the HubSpot record?
Related templates
Stop buying stale lists. Reps run a saved search, work the results like an inbox, and only the accounts they approve ever reach your CRM.
Pick a date, a starting point and a radius, then build a sequenced day of customer visits that lands straight on your calendar.
See how your brand's news coverage and sentiment stack up against four competitors, then let an assistant write the weekly report for you.
One screen where reps filter for companies that fit, see who is actually reachable at each account, and save only the addresses that verify.
One screen showing every social post waiting on approval, sorted by deadline, so reviewers can approve or reject without leaving the page.
Every Monday, find the past champions and closed-won contacts who changed jobs, update Attio, and get the moves worth chasing in Slack.
Stop finding out a card was dead when the rebill fails.
Give your billing team one screen to spot expiring cards, clear out dead tokens, and recover the payments worth saving.