1
0 Comments

The 5-Day Bug: What It Took to Get a Simple Restore Purchase Button Working

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

on March 4, 2026