Feature 检查与 Paywall
当前功能定义、访问检查、购买建议与付款后重新验证。
SDK 0.0.1更新于
当前功能定义与固定套餐合同
此页对应 2026-10-14 最新源码。功能保存即更新当前 configuration,状态只有 active/archived;恢复后可编辑,不再执行功能 publish。内部快照保留计价证据,商品仍通过发布生成固定合同。默认 Credit 费率影响后续新消费,显式套餐费率和已冻结操作保留原价格;不要把功能存档当成撤销客户已有额度。
当前 npm 组织包固定为 0.0.1;它是 2026-10-13 的独立发布快照。后续新增 checkEntitlement/showPaywall 等源码入口不因包版本号仍为 0.0.1 就自动包含在 registry 产物中。使用本页流程前须完成匹配 SDK 构建/发布、服务部署及迁移;默认安装路径继续使用已发布组织包。
检查权益、展示 Paywall、重新验证
checkEntitlement 需要 entitlements:read,requirement 明确指定稳定 entitlementId、正十进制 quantity、properties 和可选 Entity。allowed 只说明当前访问条件;reason 区分缺少权益、余额不足、容量或用量上限等。检查和预览不消费余额;执行真实任务仍需后端原子消费或预扣。
obtainRetainedPaywallController 是宿主接入点:自己的已认证后端用 createPaywallStartClient.start 保存整个原 requestId、paywallId、requirement、customerToken 及付款范围,浏览器只拿 runToken 建立控制器。操作需要 sessions:create 与 funnels:run。支付回跳恢复同一运行;完成后 showPaywall 再检查同一要求,只有实际允许才调用 onAccessGranted。回调只更新显示,不能替代业务授权。
app/paywall.ts · current-source fragmentTypeScript 1import { showPaywall } from "@tinkerlandai/indiana-sdk";2 3// grow is the identified browser client from the quickstart.4// Keep this same requirement in the verified backend start ticket.5const requirement = { entitlementId: configuredFeatureId, quantity: "1", properties: {} };6const result = await showPaywall(container, {7 check: async () => (await grow.checkEntitlement({8 requirement, paywallId: configuredPaywallId,9 commerce: { provider: "stripe", currency: "USD" },10 })).check,11 start: () => obtainRetainedPaywallController(),12 onAccessGranted: () => refreshAccessDisplay(),13 onAuthenticate: () => obtainCurrentUserCustomerToken(),14 onCheckout: ({ url }) => window.location.assign(url),15 onOpenUrl: ({ url }) => window.location.assign(url),16 onError: reportError,17});18// On route leave, destroy result.host if present and reset its controller.