内购(Construct 3)
插件把内购暴露成事件表 动作、触发器 和 表达式 —— 不写 JavaScript。底层的商店(Facebook IAP、Apple IAP、Google Play Billing……)由当前渠道决定;你不需要选。商品目录的概念见 Web SDK 内购。
插件给你提供了什么
Section titled “插件给你提供了什么”动作
| 动作 | 作用 |
|---|---|
| Check if IAP is ready | 商店是否已初始化?结果在 IAPReadyStatus 表达式上(1/0)。 |
| Get IAP catalog | 拉取商品目录。结果在 LastCatalog 上(JSON)。 |
| Get product by ID | 拉取单个商品。结果在 LastProduct 上(JSON)。 |
| Purchase product | 发起购买 —— Product ID(+ 可选的 metadata JSON)。 |
| Consume purchase | 把消耗品标记为已发放,让它能再次购买 —— 传入那笔购买。 |
| Get unconsumed purchases | 拉取尚未消耗的消耗品(启动时恢复用)。 |
| Configure IAP | 应用 IAP 配置 JSON。 |
触发器
| 触发器 | 何时触发 |
|---|---|
| On purchase success | 购买完成 —— 发放内容。读 LastPurchase。 |
| On purchase cancelled | 用户关掉了商店弹窗 —— 不是错误。 |
| On purchase unknown product | 商品 ID 不在目录里。 |
| On purchase error | 购买 / 消耗 / 恢复失败。读 LastIAPError。 |
| On purchase consumed | 一次消耗完成。读 LastConsumedPurchaseId。 |
| On unconsumed purchases retrieved | 未消耗列表已就绪。读 LastUnconsumedPurchases。 |
| On IAP configured | Configure IAP 完成。 |
表达式
| 表达式 | 返回 |
|---|---|
FRVR SDK.LastPurchase | 最近一次成功购买(JSON)。 |
FRVR SDK.LastUnconsumedPurchases | 未消耗购买的数组(JSON)。 |
FRVR SDK.LastConsumedPurchaseId | 最近一次消耗的购买 ID。 |
FRVR SDK.LastCatalog | 商品目录(JSON)。 |
FRVR SDK.LastProduct | 最近按 ID 拉取的商品(JSON)。 |
FRVR SDK.LastIAPError | 最近一次内购错误信息。 |
FRVR SDK.IAPReadyStatus | 内购就绪为 1,否则 0。 |
- 用 Purchase product 发起购买 —— Product ID,外加一个可选的 metadata JSON 串。
- 在 On purchase success 里,发放内容。票据在
FRVR SDK.LastPurchase上(一个 JSON 对象)。如果是消耗品,把它传给 Consume purchase,让商店允许再次购买。 - 在 On purchase error 里,显示
FRVR SDK.LastIAPError的信息。
想要更精细的控制,可以把 On purchase cancelled(用户退出 —— 什么都不说)和 On purchase unknown product(商品 ID 错误)各自单独处理。
消耗品 vs. 持久商品
Section titled “消耗品 vs. 持久商品”- 消耗品(金币、宝石、生命) —— 发放后必须调 Consume purchase。完成后会触发 On purchase consumed,并且
FRVR SDK.LastConsumedPurchaseId里是那笔 ID。 - 持久商品(去广告、皮肤、季票) —— 绝对不要消耗,否则会变成可重复购买。把发放逻辑写成 幂等 的,重复执行也不会多发。
恢复未完成的购买
Section titled “恢复未完成的购买”如果 app 在购买和发放之间崩溃了 —— 或者某个消耗品一直没被消耗 —— Get unconsumed purchases 会一次性把所有待处理的购买给你。(它 不会 重放 On purchase success。)
这正是 FRVR.iap.getUnconsumedPurchases() → 循环 → consumePurchase(...),并把 .catch 映射到 On purchase error。有两点要注意:
- 列表 通过触发器 到达(以及
FRVR SDK.LastUnconsumedPurchases),而不是作为返回值 —— 在触发器里读它,而不是在动作的下一行。 - 插件把整个列表作为一个 JSON 数组给你;把它读进 Construct 的 JSON 对象里,自己遍历每一项。
读取商品目录
Section titled “读取商品目录”没有 “catalog ready” 触发器 —— 结果存在 FRVR SDK.LastCatalog 上(Get product by ID 则是 FRVR SDK.LastProduct)。在调用动作后过一两帧再读它,然后解析 JSON 来搭建你的商店 UI。价格已经按玩家所在货币本地化过 —— 不要在 UI 里硬编码价格。