The Client from Brazil Was Right
Shipped a version with automated emails and a new listing, then dug in over the weekend and found it: since March, Stripe had been sending the renewal webhook differently, and people's credits weren't being credited. Sat up until three in the morning fixing it.

By Georg Malahov
On Friday I finally shipped a new version of Call Copilot — with automated sending of emails from generated templates and a rewritten text on the extension's Chrome Store listing. The emails started going out, and I sat there feeling pleased with myself, as if I'd done something big. That lasted exactly until Saturday.
The weekend went into testing email sending and receiving, and I found a pile of bugs: in user segmentation, in counting registrations, in counting statistics. Separately, earlier in the week, before the release, a logic bug from the previous version surfaced: every single user, without exception, hit the registration requirement right away instead of seeing the demo first. In other words, the first encounter with the product was built exactly backwards, and some people simply dropped off at that step. Today I rolled out 1.9.4: the demo comes first again, and registration is only needed before the second, real call.
The statistics paint a mixed picture — and these are still numbers for the July versions, taken before Friday's release. Registrations jumped sharply — about 30% of all installs now register. Uninstalls are unchanged. Installs slipped from ten a day to nine, but that looks like noise. Activation, though — the first real call — dropped noticeably, and I'm almost certain it's precisely because of that demo bug. The emails, meanwhile, are working: people click through them, visible both in the extension's internal stats and via UTM tags. I see no influx of impressions or SEO payoff from the new listing at all, but the Chrome Store updates its numbers with a three-day delay, so it's too early to judge.
And then I dug my way down to the biggest bug of all, and it explains everything at once — the low retention and the fact that I'd never had a single renewal. In March, Stripe changed the response signature of the webhook fired after a subscription renews. I kept reading the data the old way, the webhook failed to process, and people's credits weren't credited on renewal. Since March. Almost five months.
The client from Brazil, who opened a dispute through his bank over the charge, was right about the substance of his claim. He paid, the credits never arrived, and he wrote down exactly what he saw. And in that story, the one who considered himself in the right was me. I had nothing that could have told me otherwise: no alert, no report, not a single line in the logs that would have hinted in advance that something was wrong with the crediting. That's an explanation, of course, not an excuse. The money he paid was real, and I took it.
I was fixing it yesterday until three in the morning. Not out of heroism — I simply have one live client with a €12.99 subscription, and it renews in early August. If I hadn't found this now, I would have charged the man a second time and delivered nothing a second time. That's what kept me working late into the night.
The big-picture work is done; from here on it's only bugfixes and gathering statistics. Whether the weekend was worth it, the renewal will show: the renewal has to go through on its own, without me, and the credits have to appear in the account. And the second sign — activation, after the demo fix, should return to where it was before the last version. If the renewal fails to credit again, or activation stays on the floor, then I've been fixing the wrong thing all along and have to start digging again.
For now I'm switching into watch mode: keeping an eye on the emails, the demo, user behavior. I'm worse at waiting than at fixing, but there isn't much of a choice.