The payment screen said thank you. The credits screen said zero. Between those two screens there was a pipe I had never drawn.
A tap with no echo
Someone paid. The Google screen thanked them, the receipt exists, the money is real. On my side nothing moved — credits still zero, the account still on the free tier, no error anywhere.
That shape of bug is the worst kind, because every single piece you can see is working. There is no stack trace for a message that was never sent.
The pipe I never drew
The flow I had in my head was two boxes: user pays and user gets credits. In reality there are four, and the middle two are invisible. Google does not tell your app directly that a purchase happened. It publishes a message, and a relay service picks it up and forwards it to the billing platform, which finally calls your server.
The payment can succeed on step one and die on step two, and step one is the only one your user sees. That is why the tap had no echo — the purchase was fine, the announcement was missing.
Enabled is not permitted
So I went and switched the relay on, which felt like the fix. It wasn't. The next attempt failed with a permissions message, and that was the actually useful part of the day.
Switching a service on is not the same as letting your identity use it. The relay was running the whole time; the credential I handed over had no standing to touch it. Two separate switches, on two separate screens, and I had only found the first one. Nobody had denied the request out loud — it was simply never allowed to be made.
What the bottle does differently
FocusBottle is a jar of light particles that change with your attention, and it only works because the loop is short: you stay, the light brightens; you reach for your phone, it dims. There is no gap between the action and the feedback, so there is nothing to interpret.
A payment pipeline is the opposite. The action and the feedback are separated by three hops and several minutes, which is exactly where a silent failure can live for a week without anyone noticing.
I fixed the permission, tested with a real purchase, and watched the credits land. The lesson I kept wasn't about billing. It was that any time I have to guess whether something worked, I have built a system that will eventually lie to me — and the honest version is always the one that tells you, at the moment it happens, that the light is still off.