VoidhashDocs
DocumentationAPI reference
Dashboard
Get started
Introduction
Quickstart
Setup
Setup overview
Create a project
Environments
Products and perks
Paywall locations
CLI
Paywall components
Components
Develop a component
Editor panels
Component definition
Publishing
Installing and capabilities
SDKs
Swift
Kotlin
React Native
Web
Store setup
Connect the App Store
Connect Google Play
Connect Stripe
Record payments from other sources
API libraries
Node.js
PHP
Rust
Go
Resources
MCP server
Ad measurement
Meta ads
Migrate in observer mode
Delete a person's data

Environments

Keep test purchases, keys and webhooks apart from production.

Every purchase Voidhash records belongs to an environment. The environment decides which API keys can read the purchase, which webhooks receive its events, and where it appears in Studio. Test purchases never unlock access in production, so a staging server or a test checkout cannot give anyone paid access in your live app.

Purchase environments

EnvironmentWhat it holds
ProductionReal purchases from the App Store, Google Play, Stripe live mode and payment sources.
SandboxFree purchases in a store's own sandbox: App Store sandbox accounts, TestFlight, Apple's App Review and Google Play test purchases.
TestFree purchases your own build or deployment makes: simulated purchases of debug builds in development mode, Stripe test mode, and payment sources reporting with a test key.

Store sandbox purchases are separate from test purchases because the store decides when a purchase is a sandbox one, and your published app cannot tell them apart: TestFlight runs the same build you ship, and App Review buys with a sandbox account in the build you submit. So by default, store sandbox purchases also unlock access in production apps. You can turn that off, at the cost of App Review no longer unlocking what it buys.

Test purchases never unlock production: anyone can make them without paying. Development mode (React Native, Swift, Kotlin) stands in for the App Store and Google Play, which emulators lack, so its simulated purchases are test purchases too.

API keys

Every API key belongs to production or test, fixed for the life of the key.

KeyPrefixReads
Productionvh_pk_, vh_sk_Production purchases, plus store sandbox purchases while they unlock production apps (the default).
Testvh_pk_test_, vh_sk_test_Store sandbox and test purchases.

Every project has a production publishable key and a test publishable key. Secret keys are created as production or test under Settings → API keys in Studio. What a test secret key reports, such as a payment source's payments, is recorded as test.

Use test keys in staging servers, staging websites and debug builds, and production keys in production. A mobile app you publish to the App Store or Google Play, including TestFlight and Play testing tracks, uses the production publishable key in its release build: TestFlight, App Review and Play test purchases are store sandbox purchases, and they unlock access there by default.

Debug builds in development mode must use the test publishable key. Voidhash refuses simulated purchases made with a production key, since a production key could never read them.

No request header changes what a key reads, so a production key never sees test purchases.

Analytics events

Every analytics event is recorded in the environment of the key that sent it, like a purchase. Voidhash sets each event's $environment property when the event arrives: test for a test key, production for a production key. The SDKs send no environment of their own, so a staging website or a debug build that uses the test publishable key records test page views and events, and a production key never records test events.

Analytics, ad reports, the event list and experiment results show the events of one environment:

  • Production and Sandbox show production events. Store sandbox purchases come from the app you publish, which uses the production key.
  • Test shows test events.

So a staging website on the test key stays out of your production visitors, page views, events and experiment results. Events recorded before keys had environments count as production. Through the API, a test key reads test events and a production key production events.

People are not split by environment. Signups and people in ad reports count the people both environments identified, and tracking health lists every website and app that sends events, staging included. A staging site that identifies its users with the same IDs as production identifies the same people, so give staging users IDs of their own, such as with a staging: prefix.

Webhooks

Every webhook endpoint belongs to production or test. Choose its environment when you create it under Settings → Webhooks, or set environment through the API; the default is production.

  • A production webhook receives the purchase events a production key reads: production purchases, and store sandbox purchases while they unlock production apps.
  • A test webhook receives store sandbox and test purchase events.
  • Events that belong to no purchase, such as person.deleted, go to every webhook.

Each purchase event's payload says where it came from in its environment field: production, sandbox or test. See Receive webhooks.

Studio

The environment switcher next to the project name shows one environment at a time:

  • Production shows production purchases.
  • Sandbox shows store sandbox purchases.
  • Test shows test purchases, simulated ones included.

Simulated purchases are turned on or off, and deleted, under Settings → General → Simulated purchases. Deleting removes simulated purchases only, not Stripe test mode or payment-source test purchases.

Analytics and ad reports take the same three environments, production, sandbox and test, and report production unless you choose another: the revenue of that environment's purchases, and the events of its keys. See Analytics events.

A typical setup

DeploymentKeyWebhook
App Store and Google Play release builds, including TestFlightProduction publishable key—
Production website and backendProduction publishable and secret keysProduction
Staging website and backend, Stripe test modeTest publishable and secret keysTest
Debug builds in development modeTest publishable keyTest

Next steps

  • Create a project and copy its keys
  • Connect Stripe in live and test mode
  • Stage a payment source on the same project
PreviousCreate a projectNextProducts and perks

On this page

Purchase environmentsAPI keysAnalytics eventsWebhooksStudioA typical setupNext steps