Make your first Google Play purchase
Buy a subscription as a Google Play license tester and watch it unlock a perk in your app and in Studio.
A license tester purchase is the first proof that Play Billing, Google Play and Voidhash work
together: Google charges nothing, but Voidhash verifies the purchase and grants the perk exactly as
it will for a paying person. Start from an app that works in
development mode, where simulated purchases already unlock
premium.
Before you start
- Your app exists in Play Console, and a subscription such as
pro_monthlyhas an active base plan, such asmonthly. - Google Play is connected in Voidhash (Help center) with a service account key and real-time developer notifications (RTDN), for the same package name your release build uses.
- A Voidhash product grants the
premiumperk. See Products and perks. - A device or emulator with Google Play, signed in with the Google account you will test with.
Make a test purchase
Map the store product
In Studio, open Products → Products and choose Import products (the download icon). The
Google Play card lists each base plan separately. Choose Link on pro_monthly's base plan,
then pick the product that grants premium.
A new subscription can take a while to appear; choose Refresh to read the catalog again. To map it by hand instead, open the product and add its Google Play Product ID and Base plan ID under Payment providers.
Build with the production key
Test-track purchases come from the build you ship, so test with a release build and the production
publishable key (vh_pk_…). Voidhash records the purchase as sandbox, and by default lets it
unlock production apps.
Release builds ignore dev, so Google Play sells the product, not the simulated store:
val voidhash = Voidhash.configure(
context = this,
publishableKey = if (BuildConfig.DEBUG) "vh_pk_test_..." else "vh_pk_...",
options = VoidhashOptions(dev = BuildConfig.DEBUG),
)import { createVoidhashClient } from "@voidhash/react-native";
export const voidhash = createVoidhashClient(__DEV__ ? "vh_pk_test_..." : "vh_pk_...", {
dev: true,
});Upload the app and add testers
This step is Google Play behavior; Voidhash plays no part in it.
- Upload a release build signed with your upload key to the Internal testing track, or a closed track.
- Add your Google account to the track's testers, and as a license tester under Settings → License testing.
- Open the track's opt-in link with that account and install the app from Google Play.
Google Play checks the installed package, its signing key, the account and the track, so a sideloaded build isn't a reliable test.
Buy the subscription
Open your paywall or purchase screen and buy pro_monthly. A license tester sees test payment
methods in the Google Play sheet; choose one that always approves. If your app identifies users,
sign in first, so you can find the purchase under your user ID.
Check the purchase
Check three places, in this order.
In the app. The perk should be active right after the purchase returns:
val person = voidhash.getCurrentPerson(forceFetch = true)
println(person?.hasActivePerk("premium") == true)
println(voidhash.getDistinctId())const access = await voidhash.client.hasPerk("premium", { forceFetch: true });
const distinctId = await voidhash.client.getDistinctId();
console.log(access.isOk() && access.value.hasAccess, distinctId.isOk() ? distinctId.value : null);In Studio. Open the project switcher and choose Sandbox. Then open People, search for the
user ID or the distinct ID the app printed, and open the person. Under Purchases, the
subscription shows Sandbox and Active; under Perks, premium shows Active.
In your backend. If you have webhooks, the endpoint's Recent deliveries under
Settings → Webhooks lists a subscription.created delivery. A test endpoint receives every
sandbox purchase; a production endpoint receives them while they unlock production apps. With
Sandbox selected, Activity → Analytics events shows the matching $subscription.created
event.
Test subscriptions renew on an accelerated schedule, so within minutes you also see renewals arrive through RTDN. Renewals that stop arriving while the app is closed point to a broken RTDN setup; see Set up real-time developer notifications (Help center).
If it doesn't unlock
| Symptom | Cause | Fix |
|---|---|---|
| The product doesn't load | The store product or base plan isn't mapped or active, the account isn't a tester, or the app wasn't installed from the track. | See Products are empty. |
| A Test purchase sheet appears instead of Google Play's | The build runs in development mode. | Install the release build from the track. |
BILLING_CONNECTION_FAILED | Google Play services are missing or updating, or the account can't buy. | Use a device or emulator image with Google Play, signed in to the tester account. |
| Voidhash rejects the purchase | Google Play isn't connected for this package name, for example because of an applicationIdSuffix; onDiagnostic reports TRANSACTION_REJECTED. | Connect the package name under Settings → Payment providers, then relaunch. Google refunds a purchase that stays unacknowledged for 3 days. |
| The purchase is in Studio but the perk is missing | The product doesn't grant premium, or the person changed after the purchase. | See A purchase doesn't unlock the perk. |
| The purchase is under Sandbox but the app stays locked | store-sandbox-unlocks-production is off. | Test with the test publishable key, or turn the setting on. See Store sandbox in production apps. |
For other symptoms, see Troubleshooting and the React Native troubleshooting page.
Next steps
- Make your first App Store purchase
- Test purchases (Help center): renewals, expiry and simulated lifecycles.
- Go-live checklist
Something wrong or missing on this page? Tell us by email or on Discord.