VoidhashDocs
DevelopersHelp centerGuidesAPI reference
Dashboard
Guides
Launch
Go-live checklist
Make your first App Store purchase
Make your first Google Play purchase
Troubleshoot
Troubleshooting
Recover from incidents
SDK error codes
Purchase error codes
API error codes
FAQ
Recipes
Win back subscribers
Handle plan changes
Unlock the app after a web purchase
Link accounts across platforms
Handle refunds
Register devices for push
Migrate
Migrate to Voidhash
Migrate from RevenueCat
Migrate from Adapty
Migrate from Superwall
Run in observer mode
Privacy and hosting
Delete personal data
Self-hosting
Operate a self-hosted server

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_monthly exists 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 premium perk. 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:

MyApp.swift
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)
}
src/lib/voidhash.ts
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

SymptomCauseFix
The product doesn't loadThe 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'sThe build runs in development mode.Build the Release configuration.
The purchase succeeds but nothing reaches VoidhashA StoreKit configuration file is in the scheme; the SDK reports STOREKIT_TESTING_TRANSACTION_SKIPPED.Remove it from the scheme.
Voidhash rejects the purchaseThe 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 missingThe 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 lockedstore-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.

PreviousGo-live checklistNextMake your first Google Play purchase

On this page

Before you startMake a sandbox purchaseMap the store productBuild with the production keySign in with a sandbox accountBuy the subscriptionCheck the purchaseIf it doesn't unlockNext steps