Display a paywall

Resolve the paywall assigned to a location and present it from your app.

Use this page to show a hosted paywall from the React Native SDK. A paywall is the screen a customer sees. A location is the stable slug your app asks for, such as onboarding or settings-upsell. You publish paywalls and assign them to locations in Studio, as described in Paywall locations.

Present it

Ask for a location with the usePaywallByLocation hook. It preloads the paywall assigned to that location and returns a show() function you call when you want to present it.

const paywall = voidhash.usePaywallByLocation("settings-upsell", {
  onPurchase: ({ productId }) => {
    console.log("Purchased", productId);
  },
  onRestore: () => {
    console.log("Purchases restored");
  },
  onError: (error, { action }) => {
    console.warn(`Paywall ${action} failed`, error);
  },
});

const result = await paywall.show();

show() never rejects. It resolves to a ShowPaywallResult whose status tells you what happened:

statusMeaning
shownThe native presenter opened the paywall.
not_assignedNo published paywall is assigned to the location.
not_initializedStill initializing, or used outside <voidhash.Provider>.
initialization_failedThe provider's init() failed. The result carries error.
native_unavailableThe platform has no native paywall presenter.
disabledThe client was created with enabled: false.
failedResolve, preload, or presentation failed. Carries error.

Purchase and restore failures do not come back from show(), because by then the paywall is already on screen. They are reported through the hook's onError callback instead.

Purchases and restores started from a hosted paywall go through the SDK like any other purchase. After a successful transaction, Voidhash refreshes the person snapshot and dismisses the paywall.

Fall back when nothing was shown

When you clear or archive a location in Studio, later presentations return not_assigned. Keep a fallback for important entry points so the customer still has a way to upgrade.

const result = await paywall.show();

if (result.status !== "shown") {
  navigation.navigate("Plans");
}

Preloading

The hook preloads this location's paywall in the background, so show() presents without waiting on the network. The hook's options let you react to what happens on the hosted paywall and to preloading itself:

OptionFires when
onPurchaseA purchase started from the hosted paywall succeeded.
onRestoreA restore started from the hosted paywall succeeded.
onErrorA hosted paywall purchase or restore action failed.
onPreloadErrorBackground preloading of this location's paywall failed.

Treat onPreloadError as a place to report, not a place to recover. The SDK retries preloading on the next app foreground and again when you call show(). If show() hits the same failure, it returns a failed result instead of calling the callback.

Next steps