ThriveCart, 2013 to 2026
Ten years on one checkout platform, working through several roles into product.
ThriveCart is a conversion-focused, funnel-based checkout platform for SMEs and course creators. I was one of the four people who helped build it, under the founder’s direction, covering support, documentation, video and community before moving into product. It was acquired by LTV SaaS Growth Fund in late 2022 and reached around 200 people, partly through further acquisitions of its own. I stayed three and a half years past that point.
Annual GMV on the platform in the year before it was acquired.
People building and running it through the years that got it there.
Staff by the time I left, after further acquisitions.
Knowing the product end to end was the job I gave myself.
Nobody asked me to become the person who knew how all of it fitted together. It is the part of the work I enjoy most, and it is the part that compounds.
Width, not just depth
Over ten years I worked on or alongside most of the platform: checkout and payments, affiliates and commissions, reporting, courses, tax, ConvertBox, and the support processes wrapped around all of it. Knowing one area well makes you useful. Knowing how the areas behave when they meet is what lets you answer the question somebody has not quite worked out how to ask yet.
- Checkout and payments
- Affiliates and commissions
- Reporting, courses and tax
The first two hours of the day
For long stretches my morning started with an hour or two answering colleagues: a question about how something behaved, access to set up, a configuration nobody could get to work. The customer success managers who looked after our higher profile accounts would bring me the technical problems those accounts had hit, and I could usually either answer on the spot or get to the bottom of it inside half an hour. None of that was in my job description. Asking me was simply the quickest route to a correct answer, so the questions came.
Why I would do it again
I have watched people join a product company and never really learn the product. You can get away with that for a while, and it shows up eventually in the quality of the decisions. Going deep early is exactly what I would want to do in a new role: what it does, who it is for, where it bends, and what everybody has quietly agreed to stop asking about.
I ran the support desk, then started building for it.
The move into product was official in December 2024. In practice the direction had been set well before that, and the first things I shipped were for the team I had just come from.
Ten years on the desk
Support for tens of thousands of customers at above 95% CSAT with a team of two, and the knowledge base built from nothing in both written and video form. I came off the queue around the middle of 2024 and stopped writing customer-facing documentation that year, after a decade of reading what people were actually confused by.
Building for the job I had just left
Some of the earliest product work I did was internal: features that made the support team faster. Surfacing the key details about an account in the backend, for instance, so an agent could see what they needed without assuming the user first. Unglamorous, invisible to customers, and it took minutes off every ticket of a particular shape. I knew precisely which shapes, because I had spent years working them.
A handover template, January 2025
I wrote a template for handing a finished feature over to other departments: how it behaves, every scenario worked through with real figures, the UI changes, the known issues and where to escalate. Not a release note. Ten years of reading tickets tells you which five questions are coming, so the document answers them before they are asked. It became the standard across the product managers who joined after me, and support used it as the source for the customer-facing articles.
Then I automated the first draft
Writing one properly took real time, which is the usual reason this sort of document quietly stops happening. So I built an AI workflow to draft it: pulling the PDR and PRD from Confluence and the matching epic from Jira, user stories and bugs included, and writing the first pass from the actual record rather than from somebody’s memory of it. I reviewed and corrected every one. It turned a slow job into a quick one: a thorough, well-sourced starting point in minutes rather than hours, which is the difference between a practice that holds and one that quietly lapses.
- Sources from Confluence and Jira
- Drafted from the record, not recall
- Reviewed and corrected by me
The clearest signals never arrive as feature requests.
They arrive as a run of tickets that each look like something else, and the shape only appears if you have read enough of them.
The pattern underneath
Power users were running several paid campaigns at once into their landing and checkout pages, and could not reliably tell which campaign a sale had come from. Not in the reporting screens, not through the webhooks, not through the API. Nobody wrote in asking for better attribution. They wrote in about individual confusions, and only the volume made the real problem visible: people spending serious money on acquisition with no dependable way to see what came back.
Making the case, then phasing it
I built the argument from that pattern and scoped the work in stages rather than as one large release. A straightforward implementation first, so the data existed and was visible where people were already looking, then the more detailed breakdowns layered on top of it once the foundation was real.
- Make the data exist and be visible
- Then deepen the breakdowns
Delivering through moving priorities
Senior priorities changed often, and pod and developer resourcing moved with them, so work I owned was re-sequenced more than once. The phasing was partly a response to that. Something that ships in stages survives a reshuffle; something that needs eight uninterrupted weeks does not. Keeping it alive through the gaps was the rest of the job: updating the helpdesk articles as feature gating changed, walking support through how the values flowed, and answering questions on it from support, reporting, marketing and affiliates, each one more evidence for the case.
The proper fix was a much bigger piece of work. People needed something sooner.
Pro-rata subscription upgrade support shipped on 28 May 2025. Getting there meant working inside a decision made a decade earlier that I would still defend, and inside the limits of two payment processors.
Sellers own their own subscriptions
From the beginning ThriveCart created each subscription directly in the seller’s own Stripe or PayPal account, between them and their customer. Recurring revenue never depended on ThriveCart sitting in the middle, at a time when other platforms were effectively holding it hostage. We were doing this before Stripe supported pausing and resuming subscriptions natively, which gives some idea of how early it was. It is the right call for sellers, and it narrows what the platform can then do on their behalf: you are managing somebody else’s subscription, inside somebody else’s processor, through whatever that processor’s API happens to allow this year.
- Revenue independent of the platform
- Limits inherited from each processor
Rebuilding what an upgrade had taken away
Updating the processor integrations in 2023 gave sellers and their customers more payment options, and quietly removed something: a funnel could no longer cancel and replace a product the customer had already agreed to buy, because the new integrations capture at the point of purchase rather than authorising first and capturing later. I rebuilt that capability in steps rather than in one go. Automatic cancellation of one subscription when another was bought came first. Pro-rata credit came next, on top of it.
Choosing the smaller thing on purpose
The proper answer is a full subscription management layer, and that is a substantial piece of work. It was not going to arrive in time for the people hitting this every week, so the job was to find something genuinely useful inside the constraints that already existed, and make it behave the same way on Stripe and on PayPal. Nearly all the design effort went into the gap between what each processor would permit and what a customer would consider fair.
Sometimes the checkout can show the credit, sometimes it cannot
It depends on the flow. Inside a funnel, where someone is buying several products in one pass, we could show the discounted amount on the upsell itself. Where the new purchase came later and cancelled an existing subscription, the checkout had no way to work the calculation out in advance, so the customer could be charged less than the page said and only see the true breakdown on their receipt. Being charged less than you expected is the safe direction for that to fail in, so we shipped it with a notice under the buy button. Both cases went into the handover document with the reasoning, because the difference between those two flows is precisely the sort of thing support gets asked to explain. A limitation you have written down is a decision. One you have not is a surprise waiting for your support team.
Why credit moves the date instead of carrying forward
Because we did not own the subscription, we could not charge a reduced amount on one rebill and the usual amount on the next, and whatever we did had to hold on both Stripe and PayPal. Stripe can carry a credit balance against a customer profile. PayPal cannot. Building on the Stripe behaviour would have worked for some sellers and silently not for others, which is worse than not building it at all. So where someone is owed more than the new plan costs, the new billing simply starts when the old period ends instead. Less precise than a true credit balance, and identical on both processors, which was the harder requirement to meet.
- Same behaviour on both processors
- Deferred date, not a credit ledger
A known issue, written down
Reporting still counts the change as a cancellation plus a new subscription, so churn looks worse than it is for anyone using the feature. That was not something to fix in the same release, so it went into the handover as a known issue with the reasoning attached, rather than waiting to be discovered in a quarterly review.
Changing a platform fee should not need a deployment.
The one piece where I was specifying a system rather than a feature. Phase one shipped before I left. Phase two was written, prototyped and ticketed, ready to build.
The problem was where the logic lived
The surcharge sat on top of the base processing rates, and varied by plan and by which features a given transaction had used. That logic lived inside each payment processor integration, so adding a case, or changing the conditions attached to one, meant touching code in several places, a review and a release. The number of chargeable situations only grows as a platform grows, so the cost of every future change was heading in the wrong direction.
A service that answers one question
I specified an independent service sitting between order processing and the processors. It takes the transaction, evaluates an ordered hierarchy of conditional rules, and returns the payload enriched with whatever that particular processor needs in order to apply the result. The conditions live in configuration, so changing one is a configuration change rather than a release. That was the entire point of the exercise.
- Conditions in configuration, not code
- One place to look, not several
- Processor differences handled at the edge
It fails open, and it logs everything
If the service is slow, erroring or unreachable, the transaction still completes and the base processing rate still applies. Only the additional surcharge is skipped, and the failure is logged. That asymmetry is what makes failing open the right default: the worst case costs a little margin on a single transaction, where blocking would cost the sale outright and some of the customer’s confidence in the checkout. Every request writes an entry recording what matched, at which level, what was returned and why, because that log is the answer to every dispute and reconciliation question that turns up six months later. Personal data stays out of it, or is hashed, unless the logging meets the same handling standard as the main customer store.
Phase two: nobody approves their own rule
The administration interface was specified, prototyped and ticketed, ready for development when I left. The part I cared about was not the screens. It was role-based access and a two-step approval, so a rule created or changed by one person has to be approved by another. A system that lets one person quietly change what customers are charged is a system waiting for an incident.
That is ThriveCart. TradeSoft is the other half.
ThriveCart is what I learned inside someone else’s product, at four people and at two hundred. TradeSoft is the marketplace I built, sold, bought back and rebuilt on my own, and it is where the same thinking has nowhere to hide.
There is more detail behind all of this than belongs on a page. Ask me about any of it.