Display a paywall

Resolve a paywall by location and present it from your app.

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 and assign paywalls to locations in Studio — see Paywall locations. This page covers presenting them with the Swift SDK.

Present it

let result = try await voidhash.presentPaywall(
    location: "settings-upsell",
    delegate: paywallsDelegate
)

presentPaywall resolves the paywall configured for the location, presents it fullscreen, and speaks the paywall bridge protocol natively: purchases, restores, close, and external links are handled for you.

The result names the outcome:

ResultMeaning
.shownThe presenter opened the paywall.
.notAssignedNo published paywall is assigned to the location.
.failedResolve or presentation failed.

The delegate receives purchase completions and dismissal:

final class Paywalls: VoidhashPaywallDelegate {
    func paywall(_ location: String, didPurchaseProductId productId: String, requestId: String?) {}
    func paywallDidDismiss(_ location: String) {}
}

Every delegate method has a default no-op implementation. The delegate is held weakly, so keep your own strong reference for as long as the paywall is presented — a released delegate silently stops receiving callbacks.

Dismiss the paywall yourself with:

try await voidhash.dismissPaywall()

Hosted paywalls send purchase and restore actions through the same purchase pipeline. After a successful transaction, Voidhash refreshes the person snapshot and dismisses the paywall.

Fall back when nothing was shown

Clearing or archiving a location in Studio makes future presentations return .notAssigned. Keep a fallback for important entry points:

let result = try await voidhash.presentPaywall(location: "settings-upsell")

if result != .shown {
    showOwnUpgradeScreen()
}

Next steps