Make your first App Store purchase
Buy a subscription in the App Store sandbox and watch it unlock a perk in your app and in Studio.
A sandbox purchase is the first proof that StoreKit, the App Store and Voidhash work together:
Apple charges nothing, but Voidhash verifies the transaction 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
- In App Store Connect, the Paid Apps Agreement is active, with banking and tax details complete.
- A subscription such as
pro_monthlyexists in App Store Connect with a price and, ideally, the status Ready to Submit. - The App Store is connected in Voidhash (Help center), with the Apple Server Notification URL set as both the Production Server URL and the Sandbox Server URL.
- A Voidhash product grants the
premiumperk. See Products and perks. - A real iPhone or iPad. The Simulator can't buy from the App Store sandbox.
Make a sandbox purchase
Map the store product
In Studio, open Products → Products and choose Import products (the download icon). The
Apple App Store card lists the subscriptions Voidhash read from App Store Connect. Choose
Link on pro_monthly, 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 App Store Product ID under Payment providers.
Build with the production key
Sandbox purchases come from the build you ship: TestFlight runs your release build, and App Review
buys with a sandbox account. 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 StoreKit sells the product, not the simulated store:
import Voidhash
func configureVoidhash() {
var options = VoidhashOptions()
#if DEBUG
options.dev = true
let publishableKey = "vh_pk_test_..."
#else
let publishableKey = "vh_pk_..."
#endif
Voidhash.configure(publishableKey: publishableKey, options: options)
}import { createVoidhashClient } from "@voidhash/react-native";
export const voidhash = createVoidhashClient(__DEV__ ? "vh_pk_test_..." : "vh_pk_...", {
dev: true,
});Upload the build to TestFlight, or run it from Xcode with the scheme's Run configuration set to Release. Remove any StoreKit configuration file from the scheme: purchases made against one never reach Voidhash.
Sign in with a sandbox account
This step is App Store behavior; Voidhash plays no part in it.
- From Xcode: create a Sandbox Apple Account in App Store Connect under Users and Access → Sandbox, with an email address that isn't an existing Apple Account. On the device, sign in to it under Settings → Developer → Sandbox Apple Account.
- From TestFlight: skip the sandbox account. TestFlight buys in the sandbox with the tester's own Apple Account and charges nothing.
Buy the subscription
Open your paywall or purchase screen, buy pro_monthly, and confirm the App Store sheet. 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:
let person = try await voidhash.getCurrentPerson(forceFetch: true)
print(person?.hasActivePerk("premium") ?? false)
print(await 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.
Sandbox subscriptions renew on an accelerated schedule, so within minutes you also see renewals arrive, and the subscription expire after the sandbox's last renewal.
If it doesn't unlock
| Symptom | Cause | Fix |
|---|---|---|
| The product doesn't load | The store product isn't mapped, the Paid Apps Agreement isn't active, or the bundle ID differs from the one in Voidhash. | Check each; see Products are empty. |
| A confirmation sheet appears instead of the App Store's | The build runs in development mode. | Build the Release configuration. |
| The purchase succeeds but nothing reaches Voidhash | A StoreKit configuration file is in the scheme; the SDK reports STOREKIT_TESTING_TRANSACTION_SKIPPED. | Remove it from the scheme. |
| Voidhash rejects the purchase | The App Store provider is disabled or set up for another bundle ID; onDiagnostic reports TRANSACTION_REJECTED. | Fix it under Settings → Payment providers. |
| 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 Google Play 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.