When people imagine building an app, they picture the exciting parts: designing features, launching products, getting your first users.
What they don’t picture is spending five full days fixing a single button.
But that’s exactly what happened while I was building ClearAhead, a calm forward-planning budgeting app.
And the button?
Just “Restore Purchase.”
Something that should have taken an afternoon ended up becoming a deep dive into Android signing keys, Play Billing, Trusted Web Activities, Digital Asset Links, and debugging tools I had never even heard of before.
Here’s the story.
The App
ClearAhead is designed to help people answer a simple question:
“What money is actually safe to spend?”
Most budgeting apps show what already happened. ClearAhead focuses on what’s coming next.
Instead of looking backwards, it projects forward across the next five weeks so you can see upcoming bills and understand what’s truly available.
It’s built as a Progressive Web App, then packaged for Android using Trusted Web Activities (TWA).
This keeps the experience identical across platforms while still allowing distribution through the Play Store.
The monetization model is simple:
Basic version: small one-time unlock
Pro version: additional features
No subscriptions. No ads.
Just one purchase.
Which is where the problems started.
The Button That Broke Everything
Inside the app there are two important buttons:
Unlock
Restore Purchase
Unlock worked perfectly.
Restore did not.
Every time I pressed it, I got:
“No purchase found on this Google account.”
But I had definitely bought it.
And that’s when the five-day debugging marathon started.
Day 1 – The Obvious Things
The first assumption was that the billing code was wrong.
So I started checking:
product IDs
purchase tokens
restore logic
purchase acknowledgement
Everything looked correct.
The code was properly calling the Google Play Digital Goods API and asking for purchases.
But it always returned an empty list.
So the app believed no purchase existed.
Day 2 – The Signing Key Problem
Then I discovered something I hadn’t fully understood before:
Android app signing matters for billing.
If an app is built unsigned or signed with the wrong key, Google Play can’t associate the purchase with the installed app.
So I rebuilt the project, created a keystore, added signing configs to Gradle, and generated a new release bundle.
That fixed one problem.
But restore still didn’t work.
Day 3 – Digital Asset Links
Because the app is a Trusted Web Activity, Android has to verify that the website and the Android app belong to the same developer.
That verification happens through a file called:
assetlinks.json
which must live at:
/.well-known/assetlinks.json
If that file isn’t correct, Android launches the website inside Chrome instead of inside the app container.
I spent hours:
adjusting Netlify headers
fixing caching
verifying JSON responses
confirming SHA-256 certificates
Eventually I ran an ADB command to check the status:
adb shell pm get-app-links app.clearahead.basic
The result finally showed:
Domain verification state: verified
Progress.
But the restore button still failed.
Day 4 – The Billing API Edge Cases
Google Play can return purchases under multiple possible fields:
sku
productId
itemId
product
My restore logic was only checking one of them.
So I updated the entitlement logic to safely check all possibilities.
Still nothing.
At this point I started questioning everything.
Day 5 – The Missing Purchase
Then I opened Google Play and checked:
Play Store → Payments → Budget & History
And the purchase wasn’t there anymore.
It had disappeared.
During testing, Google sometimes automatically refunds or cancels test purchases, which means the billing API returns nothing.
So the restore button wasn’t broken.
There was simply no purchase to restore anymore.
Five days of debugging had actually fixed multiple unrelated issues along the way:
app signing
billing configuration
Digital Asset Links
restore logic
But the final problem was simply a missing purchase record.
What I Learned
Building apps is rarely about writing code.
It’s about navigating ecosystems.
In this case the stack looked like this:
Website → PWA → Trusted Web Activity → Android → Google Play → Play Billing → Digital Goods API.
If any link in that chain breaks, the whole feature fails.
But fixing it means you understand the system much more deeply.
Why I’m Still Glad I Built It
Despite the debugging marathon, ClearAhead is now working exactly as intended.
Users can:
unlock the app with a one-time purchase
restore purchases when reinstalling
run the same experience across web and Android
And the infrastructure behind it is now solid.
The bug that took five days to fix ended up teaching me more about Android deployment than anything else in the project.
The Builder Reality
From the outside, building apps can look smooth.
But the reality is usually:
five minutes of success
five days of debugging
and one tiny fix that suddenly makes everything work.
And honestly?
That’s part of the fun.
If you want to follow the project or try the app, you can check it out here:
clearahead.app