Alan Hou的个人博客

Odoo 13开发者文档:应用内购买

本文来自Odoo 13官方文档之开发者文档系列文章
应用内购买(IAP)允许持续通过 Odoo 提供服务的供应商进行持续的服务收费,而不是单独的一次性购买。在这一背景下, Odoo扮演客户和Odoo应用开发者之间的经纪人的角色:
  • 用户通过Odoo购买服务令牌。
  • 服务提供者在用户请求服务时从其Odoo账户中提取令牌。

玩家

  • 服务提供者 (可能是)读者你自己,你可以按使用收费服务的形式为客户提供价值。
  • 客户安装了你的 Odoo应用,并藉此请求服务。
  • Odoo从间进行余额控制,客户向账户中充值,然后你在提供服务时从该账户提供金额。
  • 外部服务也可以加入:你可以直接提供服务,或者代理实际的服务,在其中作为 Odoo 系统和实际服务之间的桥梁或转换者。

积分余额

“正常”服务流

如果一切顺利,正常的流程如下:

  1. 客户请求某种服务。
  2. 服务提供者询问Odoo在该客户账户中是否有足够用于服务的积分,并通过该金额创建交易。
  3. 服务提供者提供服务 (通过他们自己或外部服务)。
  4. 服务提供者回到Odoo来捕获(若已提供服务)或取消(若无法提供服务) 第2步中所创建的交易。
  5. 最后,服务方提供客户服务已提供,(根据服务)可能会在客户的系统中显示或存储该结果。

余额不足

但在客户账户里的余额不足支付服务时,流程如下:

  1. 客户像之前一样请求服务。
  2. 服务提供者向Odoo询问客户账户中是否有足够余额并获得一个否定的回复。
  3. 将这一信号返回给客户。
  4. 客户被重定向到Odoo账户中进行充值并再次尝试。

本例中,我们将提供的服务- 狗币(dogecoin)挖矿 – 每个积分运行10秒钟CPU。对于你自己的服务,你可以:

  • 自己提供在线服务 (如将报价转换为日本的商务传真);
  • 自己提供离线服务 (如提供会计服务); 或
  • 作为其他服务提供者的中介 (如彩信网关的中介)。

开始实际查询用户账户前的第一步是在 IAP端点中注册服务(生产和/或测试)。要创建服务,进入你在IAP(生产环境为https://iap.odoo.com 测试环境为https://iap-sandbox.odoo.com,端点是独立非同步的)的 Portal 账户。或者可以进入在Odoo的门户 (https://iap.odoo.com/my/home) 并选择 In-App Services

登录,然后进入My Account ‣ Your In-App Services, 占Create并提供你的服务的相关信息。

服务有7个重要字段:

  • name – ServiceName: 这是在通过 Odoo 请求交易时需要在客户的 app 中进行提供的。(如 self.env['iap.account].get(name))。作为一个良好实践,它应当与你的应用名称相匹配。
  • label – Label: 这个名称在客户端的购买门户上显示。
  • icon – Icon: 在你的服务包中作为默认的图标。
  • key – ServiceKey: 在IAP中标识你的开发者密钥 (参见 你的服务) 并允许从客户端中提取积分。它仅好在创建服务时显示一次,并且可随意进行重新生成。
  • 试用积分 – Float: 对应你准备为第一次使用应用的用户所提供的积分。注意这类服务仅对有企业合同在身的用户可用。
  • 隐私政策 – PrivacyPolicy: 这是一个可访问你的服务隐私政策的链接。应明确表明所收集的信息,如何使用信息,与你的服务的关联性,并告知客户他们如何访问、更新或删除他们的个人信息。

然后你可以创建客户使用你的服务可购买的 积分包

然后你可以创建客户使用你的服务可购买的 积分包

积分包是一个具有五大特性的产品:

  • 名称:包的名称,
  • 图标:服务包的具体图标 (如未提供,则回到使用服务图标),
  • 描述:出现在购买页面及发票上的服务包详情,
  • 额度:在购买包时客户可获取的积分额度,
  • 价格:价格为欧元 (截至目前,有规划对美元的支持)。

第二步是开发一个客户可在 Odoo实例中安装的 Odoo应用 并且通过它他们可以请求你所提供的服务。我们的应用将仅向Partner表单提供一个按钮来让用户请求使用 一段时间服务器上的CPU。

首先,我们将根据iap创建一个 odoo 模块 。IAP是一个标准的 V11 模块并且其依赖确保本地账户进行了相应的配置,我们将可以访问一些必要的视图和有用的帮助信息。

coalroller/__manifest__.py

coalroller/__init__.py

然后, 集成的 “本地” 方面。这里我们将仅向伙伴视图添加一个动作按钮,但你完全可以通过你的应用提供本地值及通过远程服务提供额外的部分。

coalroller/__manifest__.py

coalroller/views/views.xml

现在我们可以实现动作方法/回调。这将调用我们自己的服务端。

现在我们可以实现动作方法/回调。这将调用我们自己的服务端。

对服务应用和服务端的通讯协议和服务器并没有什么要求,但 iap 提供了一个 jsonrpc() 帮助方法来调用其它 Odoo 实例上的JSON-RPC2 端点并透明地重新抛出相关Odoo异常 (InsufficientCreditErrorodoo.exceptions.AccessError 和 odoo.exceptions.UserError).

在这个调用中,我们需要提供:

  • 任意相关的客户端参数(此处没有),
  • iap.account 模型的 account_token 字段提供的当前客户端token。你可以通过调用env['iap.account'].get(service_name) 来获取服务的账户,其中service_name 是注册在IAP端点的服务名称。

coalroller/__init__.py

coalroller/models/__init__.py

coalroller/models/res_partner.py

虽然并非必须,因为 iap 为 JSON-RPC2调用(jsonrpc()) 提供了客户端帮助方法并为事务 (charge) 提供了服务帮助方法,但我们还可以用 Odoo模块实现服务层面:

coalroller_service/__init__.py

coalroller_service/__manifest__.py

因为来自客户端的查询以 JSON-RPC2 的形式出现,我们需要对应的控制器,它可以调用charge并执行其中的服务:

coalroller_service/controllers/main.py

coalroller_service/controllers/__init__.py

coalroller_service/__init__.py

charge 帮助方法将:

  1. 通过具体积分额授权(创建)事务,如果账户没有足够积分,将会报出相关错误
  2. 执行 with语句体
  3. 如果 with 体执行成功,在需要时更新交易的价格
  4. 捕获(确认)交易
  5. 否则,如果从 with体中抛出错误,取消交易 (并释放所保留的积分)

charge 帮助方法有两个额外的可选参数,我们可用于让内容对终端用户更为清晰。

description
是一条消息,它与交易相关联并将在用户的仪表盘中显示,有助于提醒用户为什么存在这笔费用。
credit_template
QWeb 模板的名称,它将在用户积分不足以支付服务商所请求的金额时进行渲染并显示给用户,其目的是告诉用户为什么他们会对IAP内容感兴趣。

coalroller_service/controllers/main.py

coalroller_service/views/no-credit.xml

coalroller_service/__manifest__.py

  • IAP 交易 API 不要求在实现服务端网关时使用Odoo,调用是标准的 JSON-RPC2
  • 调用使用不同的端点 但对所有端点是相同的方法  (call)。
  • 异常以 JSON-RPC2 错误的形式返回,正式的异常名可在程序操作中通过 data.name 获取。
/iap/1/authorize

验证用户的账户中至少有可用 积分 并对该金额创建一个 预授权(等待交易) 。

任意当前由进行中交易所预授权的金额都进一步的授权调用都是不可用的。

返回 TransactionToken 标识进行中的交易为可用于捕获 (确认) 或取消所涉及的交易。

参数
  • key (ServiceKey) –
  • account_token (UserToken) –
  • credit (float) –
  • description (str) – 可选,帮助用户知晓账户中扣费的原因
  • dbuuid (str) – 可选,让用户在其数据库有效时利用试用积分 (参见 注册服务)
若授权成功,返回
若服务令牌无效,抛出
AccessError
若账户无足够余额,抛出
credit值不为整型或浮点型,抛出
TypeError
/iap/1/capture

确定具体的交易,将保留的积分从用户账户转账到服务提供方账户。

捕获调用是幂等的:对已捕获交易执行捕获调用不会有任何效果。

参数
异常后抛出
AccessError
/iap/1/cancel

取消具体的交易,释放所保留的用户积分。

取消调用是幂等的:对已取消调用执行捕获调用不会产生任何效果。

参数
异常抛出
AccessError

异常放到一边,这些用于清晰化的抽象类型, 无需关心其底层实现。

class ServiceName

字符串标识你在 https://iap.odoo.com (生产环境)上的服务以及在客户端数据库中与服务相关联的账户。

class ServiceKey

为提供者的服务所生成的标识符。 每个键(及服务)与一个由服务提供者生成的固定值令牌相匹配。

多种类型的令牌对应多个服务。举个例子,SMS 和 MMS 可以是相同的服务 (一条 MMS 等价于多条SMS) or 或不同价格的不同服务。

class UserToken

用于用户账户的标识符。

class TransactionToken

事务标识符,由授权过程返回并由捕获或取消交易进行消费。

exception odoo.addons.iap.models.iap.InsufficientCreditError

如果在账户中当前没有所请求的积分时在交易授权过程中抛出(没有足够积分或过多待完成交易/已有保留授权)。

exception odoo.exceptions.AccessError

由以下抛出:

  • 如果服务令牌无效,对于要求有服务令牌的任意操作;
  • 跨服务端调用的任意错误。(经常是在 jsonrpc()中)。
exception odoo.exceptions.UserError

在对应用开发者(也就是你)的审查时由任意预期外行为抛出。

为测试已开发应用, 我们推荐使用沙盒平台,这样你可以:

  1. 从客户视角测试整个流程 – 可能产生的实际服务和交易。 (当然这要求修改端点,参见服务中的危险事项).
  2. 测试API。

后者在具体的仅在IAP沙盒中生效的令牌中存在。

  • 令牌 000000: 表示一个不存在的账户。在尝试授权时返回InsufficientCreditError
  • 令牌 000111: 表示执行任意服务积分不足的账户。在尝试授权时返回 InsufficientCreditError
  • 令牌 111111: 表示执行任意服务时具有足够积分的账户。尝试授权时会返回一个由捕获和取消路由所处理的交易令牌。

为方便起见,如果使用Odoo实现服务, iap 模块提供一些让 IAP 流程更为简单的帮助类。

class odoo.addons.iap.models.iap.charge(envkeyaccount_tokencredit[, dbuuiddescriptioncredit_template])

用于授权及自动捕获或取消后台/代理使用的交易的上下文管理器

运行方式类似于游标(cursor)上下文管理器:

  • 立即通过具体的参数授权交易;
  • 执行 with 体;
  • 如果内容体完整执行且未报错,则捕获交易;
  • 否则取消交易。
参数
  • env (odoo.api.Environment) – 用于获取 iap.endpoint 配置密钥
  • key (ServiceKey) –
  • token (UserToken) –
  • credit (float) –
  • description (str) –
  • 模板 credit_template (Qweb) –
class odoo.addons.iap.models.iap.authorize(envkeyaccount_tokencredit[, dbuuiddescriptioncredit_template])

将授权所有操作。

参数
  • env (odoo.api.Environment) – 用于获取 iap.endpoint 配置密钥
  • key (ServiceKey) –
  • token (UserToken) –
  • credit (float) –
  • description (str) –
  • template credit_template (Qweb) –
class odoo.addons.iap.models.iap.cancel(envtransaction_tokenkey)

将取消已授权交易。

参数
  • env (odoo.api.Environment) – 用于获取 iap.endpoint 配置密钥
  • transaction_token (str) –
  • key (ServiceKey) –
class odoo.addons.iap.models.iap.capture(envtransaction_tokenkeycredit)

将对给定交易捕获取 credit 金额。

参数
  • env (odoo.api.Environment) – 用于获取 iap.endpoint 配置密钥
  • transaction_token (str) –
  • key (ServiceKey) –
  • credit –
退出移动版