This translation is community contributed and may not be up to date. We only maintain the English version of the documentation. Read this manual in English
Defold 提供了方便的 iOS Appstore “in-app purchases” 和 Google Play 及 Amazon “in-app billing” 系统接口. Facebook Canvas 的 “game payments” 用于 Facebook Canvas 游戏. 这些服务能让你销售:
目前 Defold 接口可以与 Apple 的 Storekit 完整交互. 对于 Google Play 和 Facebook Canvas, 接口是一致的, 这有助于代码跨平台. 但是不同平台需要的流程有所不同. 而且注意目前没有针对 macOS 系统上 Mac Appstore 的支付接口.
关于 Apple, Google, Amazon 和 Facebook 的详细文档参考:
首先要在 game.project 文件中加入内支付扩展依赖. 最新稳定版本地址如下:
https://github.com/defold/extension-iap/archive/master.zip
推荐使用 正式发布版 的zip连接作为依赖引用.
其 API 文档详见 扩展项目首页.
Android 建议使用 Google Play 的静态报告来实现 IAP. 这样在正式发布之前就可以确保内支付工作正常. 测试用静态报告包括4个ID:
android.test.purchased
android.test.canceled
android.test.refunded
android.test.item_unavailable
iOS 和 Android 内支付的准备流程差不多:
为应用商店进行测试配置:
对于 Google Play, 你需要 上传并发布 测试版 .apk 文件. 对于 iTunes Connect, 直到应用审批之前你 不用上传 应用文件给 iTunes Connect. 加入上传了未完成的应用文件给 iTunes Connect, Apple 会拒绝该应用.
设置应用内消费品.
Facebook 内支付准备流程:
内支付 API 是异步的, 也就是说应用发送信息给服务器, 然后能继续运行. 等到从服务器传回的信息时, 一个 回调 函数会被调用, 从中可以根据回调数据进行各种处理工作.
获得消费品列表:
local COINS_ID = "com.defold.examples.coins"
local LOGO_ID = "com.defold.examples.logo"
local function product_list(self, products, error)
if error == nil then
for i,p in pairs(products) do
print(p.ident)
print(p.title)
print(p.description)
print(p.currency_code)
print(p.price_string)
end
else
print(error.error)
end
end
function init(self)
-- 初始化消费品列表 (对于 Google Play 来说一次能获取 20 个)
iap.list({ COINS_ID, LOGO_ID }, product_list)
end
对于正式交易, 首先要注册交易结果监听器, 然后在玩家购买时调用内支付函数:
local function iap_listener(self, transaction, error)
if error == nil then
if transaction.state == iap.TRANS_STATE_PURCHASING then
print("Purchasing...")
elseif transaction.state == iap.TRANS_STATE_PURCHASED then
print("Purchased!")
elseif transaction.state == iap.TRANS_STATE_UNVERIFIED then
print("Unverified!")
elseif transaction.state == iap.TRANS_STATE_FAILED then
print("Failed!")
elseif transaction.state == iap.TRANS_STATE_RESTORED then
print("Restored")
end
else
print(error.error)
end
end
function on_message(self, message_id, message, sender)
...
-- 注册内支付结果监听器.
iap.set_listener(iap_listener)
-- 买一个金币...
iap.buy(COINS_ID)
...
end
操作系统会自动弹出支付界面. 要是处于测试/沙盒环境下, 界面中会明确标明.
大多数付款系统都是实时的. 支付完成时应用会收到一个消息, TRANS_STATE_PURCHASED. 这是交易的最终状态, 表明对于这笔交易不会再有其他消息了.
有的付款系统需要非实时的支持. 也就是说你的应用只在付款开始时收到一个消息. 为了验证付款完成与否, 需要你的服务器 (或者客户端) 与付款系统进行更多的交流. 这种情况下支付完成时应用会收到一个 TRANS_STATE_UNVERIFIED 消息 (而不是 TRANS_STATE_PURCHASED). 这也是交易的最终状态, 表明对于这笔交易不会再有其他消息了.
玩家购买消费品之后, 应用有义务告知玩家支付已完成 (比如服务器验证支付成功之后).
内支付支持 auto-completion, 也就是自动产生支付完成的消息 (默认设置). 也可以在项目配置里关闭 auto-completion. 支付完成时手动调用 iap.finish()
, 来产生完成消息.
Google Play 应用商店只支持消耗品. 必须使用非消耗品的话就关闭 auto-completion 并且不要调用完成函数. 这样在 iap.set_listener()
被调用时, 消费品购买总是保持着购买中的状态.
Apple App Store 支持非消耗品, 也就是说购买完成时才向玩家提供消费品交付. 这种情况下 auto-completion 可以开启也可以关闭 (比如你需要自己验证支付成功) 之后调用 iap.finish()
.
收据是一堆加密数据, 可以把它发送给 App Store 来验证付款是否真正完成. 这是用开发者服务器验证付款必须使用的东西.
iap.list()
返回 “failed to fetch product”iap.list()
只返回 20 个消费品iap.list()
然后合并返回结果以实现20个以上的消费品列表.iap.list()
返回空值检查 “Member Center” 上的应用ID是否开启了 in-app purchases (检查 “Member Center” 里 “Certificates, Identifiers & Profiles” 的 “Enabled Services:” 项) 并且该应用 (或者调试版应用) 已用供应商档案进行了签名而且签名没过期.
内支付消费品信息传到沙盒环境需要几小时时间, 请耐心等待.
iap.list()
产生错误日志 “Unexpected callback set”iap.list()
调用不可以嵌套. 从 iap.list()
调用 iap.list()
就会产生这个错误日志.iap.list()
返回的数据使用 不间断空白 (\u00a0
) 分割价格和货币符号并填充 “price_string” 变量. 使用 GUI 组件渲染的话, 需要在字体 extra_characters 属性里设置所需字符. 在 macOS 上按 Option + SPACE 就是不间断空白. 详情请见 http://en.wikipedia.org/wiki/Non-breaking_space.Did you spot an error or do you have a suggestion? Please let us know on GitHub!
GITHUB