AppPaywall
Access gate for monetized built apps: renders children when the end-user has access, otherwise shows a paywall overlay with the unlock CTA. The default way to charge users of an app.
import { AppPaywall } from 'flowstack-sdk/paywall'Wraps app content and surfaces the platform paywall when useAppAccess reports the user is blocked, or immediately when the backend emits an app_paywall SSE event mid-conversation (metered credits running out). It does NOT replace backend enforcement — the backend's AppAccessGate always has the final say (402 / SSE event).
This is the monetization entry point for built apps: the owner sets pricing with setMonetization (platform-level config), the app wraps its content in AppPaywall, done. Do not wire raw Stripe calls to charge app users — the owner-registered Stripe integration is for operating the OWNER'S Stripe account, not for app monetization. 0.3.0 (P0-162): when the builder configures a monthly subscription plan, the paywall renders the plan CTA above the one-time unlock. Since 0.3.3 (P0-167) subscriptions are status-only: a subscriber with an open paid period has full access and never reaches this paywall, so the subscribe CTA shows only for lapsed or never-subscribed users.
Signature
<AppPaywall siteId={config.appScope} builderTenantId?={...} onBlocked?={(reason) => ...}>{children}</AppPaywall>Parameters
| Param | Type | Notes | Description |
|---|---|---|---|
siteId | string | required | Site ID of the built app (typically config.appScope). |
builderTenantId | string | — | Builder's tenant ID — needed to load app config. |
children | React.ReactNode | required | Content to show when the user has access. |
onBlocked | (reason: string) => void | — | Called when the backend returns an app_paywall SSE event. |
Examples
import { AppPaywall } from 'flowstack-sdk/paywall';
export default function App() {
return (
<AppPaywall siteId={config.appScope}>
<YourAppContent />
</AppPaywall>
);
}app_unfunded (the app owner is out of compute credits), the paywall renders a "Temporarily unavailable" state with NO purchase CTAs — the end user can't fix owner funding, so don't offer them a buy button.flowstack-sdk/paywall (0.3.2+). The flowstack-sdk/wallet entry statically imports the wagmi optional peer dependency (via useWalletAuth/useDeposit/WalletProvider) and fails to resolve in built apps that don't carry the wallet stack. /wallet still re-exports AppPaywall for consumers that do.setMonetization + this component). Do NOT use raw Stripe API calls to charge app users.app_paywall SSE event dispatched by useAgent, so metered apps gate mid-conversation without a page reload.payment_mode is 'agent' (token-only apps). In 'both' mode the Stripe CTA is the single visible path — the AGENT rail still charges server-side; the paywall just no longer advertises it.See also
useAppAccess · setMonetization · getMonetization · PaymentRequired · AppSubscriptionStatus
Source: wallet/AppPaywall.tsx · Also available in llms-full.txt and registry.json.