Notes · October 2026
The app says the plan ended, and Stripe keeps charging the card.
Folioport is a sample portal built for a case: the studios are made up, the data is test data, and Stripe ran in test mode. Design studios share work with their clients in it, and it has three plans: Free, Studio at €29 a month and Agency at €79. Paying for them through Stripe was added with Claude Code, from requests in plain words. On the normal path it worked. A studio could buy a plan, renew it, have a failed payment retried, and cancel to the end of the month.
The problems that cost the most were on the paths a founder uses less often. In each of them the app said one thing about the plan, and Stripe went on doing another.
One plan, two records
An app with subscriptions keeps every plan twice. The app has its own record that says this studio is on Agency. Stripe has the subscription that says this card pays €29 every month. Both start together when someone buys, and after that nothing ties them. Stripe charges until it is told to stop: by your code, by someone in the Stripe dashboard, or by its own settings after payments keep failing. Nothing the app shows on its own pages counts.
So every place in the app that changes a paying customer's plan has to say what happens to the Stripe subscription and to the next charge. Where it says nothing, the card goes on paying.
Five ways the card kept paying
- A plan given free of charge. The founder gave Agency for free to a studio that paid €29 for Studio. The app showed Agency at no cost, and a month later Stripe charged €29 again. The owner's page said "Contact us to change it" and offered no way to cancel. The founder's revenue showed €0 while the money kept coming in.
- A suspended studio. The founder suspended a paying studio, and Stripe went on charging €29 a month. The owner tried to cancel and to open the payment page, and the app refused both with "This studio is suspended". They paid for a studio they could not use.
- A handover. An owner handed the studio over to a team member, and the subscription stayed on the previous owner's card. The new owner moved up to Agency, and the previous owner's card paid for it. The previous owner was now only a member and could no longer cancel.
- A deletion that stopped halfway. Deleting a studio cancelled its subscription only at the very last step. When a deletion stopped after its first step, the studio showed "Being deleted", and a month later the card was charged again.
- A cancel that the app refused. An owner whose studio had more people than Free allows could not stop paying. "Cancel and move to Free" was greyed out, and Stripe's own page had no cancel either. The only way out was to remove people first.
In all five the customer is charged for something they no longer have or no longer want, and the app gives them no way to stop it. A customer in that spot writes to their bank and disputes the charge. Each dispute costs the business a fee, and too many of them put the Stripe account itself at risk.
The same gap, the other way
The two records can also disagree the other way, and then the business loses. Studios that were on Studio or Agency before payments existed had the plan in the app and no subscription in Stripe. Nothing ever asked them to pay, and the founder's revenue counted them at full price.
The fix
The rule became simple: a change of plan in the app goes through Stripe first, and a customer can always leave.
- Giving a paying studio a plan free of charge cancels its subscription at once and refunds the unused part of the month. The founder can no longer change a paying studio's plan any other way.
- Nothing is collected while a studio is suspended, and its owner can still cancel and open the payment page. Lifting the suspension asks for the current month, with the usual notice.
- Each owner pays as their own Stripe customer. After a handover, the previous owner's subscription runs to the end of the month they paid for and is never charged again. From then on the new owner pays with their own card.
- The first step of a deletion stops the subscription, and a regular clean-up stops any that were left behind.
- Cancelling and moving down are always allowed, whatever the size of the studio. They take effect at the end of the paid month, and nothing is deleted.
- Paid plans nobody pays for get 14 days' notice, like a trial that ends. The owner can keep the plan by paying, and after the date the studio moves to Free.
After the fix, every one of these cases ran again against Stripe in test mode, with time moved on through the next renewal. Cards were charged only where the founder's rules say they should be.
Check your own app
- Write down every way a plan can change in your app apart from buying and cancelling. Think of an admin page, a plan given for free, a coupon, a suspension or a ban, moving the account to someone else, deleting it, and anything your support team can do.
- In test mode, do each of them to an account that pays. Then open that customer in the Stripe dashboard. If your app says Free, suspended or deleted and Stripe still shows a next payment date, that card will be charged.
- To see the renewal itself without waiting a month, Stripe's test clocks move a test subscription forward in time.
- Try to leave as the customer in every state: suspended, just after a handover, and on an account bigger than your free plan. Can they cancel from the app? Does Stripe's billing page let them?
- If someone else wrote the code, ask them one question: "List every place that changes the plan, and for each, what happens to the Stripe subscription." An answer like "nothing" for any of them is the hole.