文档

通过后端 API 完成购买

实现您自己的后端,监听购买事件并跟踪玩家的权利。
阅读时间11 分钟最后更新于 3 个月前

如果您的游戏使用服务器授权,请实现一个执行以下操作的后端系统:
  1. 验证 Webhook 事件 (JWT)。
  2. 解析事件。
  3. 根据事件类型更新系统中的授权或清单。
  4. 将订单标记为已完成。
  5. 返回事件响应。
这样可以确保您的系统与 Unity IAP 保持同步。
重要
即使后端授予玩家权限,也必须将每个已付款订单标记为已完成。无论哪种方式,玩家都会保留其授权,但保持
paid
状态的订单会使 Unity IAP 订单跟踪和分析不完整。在混合 SDK 和 Webhook 的混合设置中,未确认的订单也可能导致系统之间的订单状态漂移。

验证 Webhook 事件 (JWT)

为了启用验证,Unity IAP 使用 JSON Web Token (JWT) 对 Webhook 请求进行签名。在后端验证此令牌的以下信息以确保事件真实可靠:
  • Authorization 标头
  • "signature":使用私钥签名。获取并缓存 **JWKS(公钥)**以验证:
    https://services.api.unity.com/webhooks/.well-known/jwks.json
  • 发行商:
    https://services.api.unity.com/webhooks/
  • 受众声明(数组):
    upid
    (Unity Project Id)、
    envId
    (Environment Id)
  • 令牌到期:确保
    exp
    (到期)未通过。
大多数语言的库可用于验证 JWT。

Webhook 事件形状

Unity IAP 将来自所有受支持的支付提供商的事件标准化为这种一致的格式。请参阅以下示例文件:
{ "id": "018d5e5e-5e5e-7e5e-5e5e-5e5e5e5e5e5e", "version": "1.0.0", "eventType": "order.paid", "time":"2024-01-15T14:30:00Z", "projectId":"018d5e5e-1111-7e5e-5e5e-111111111111", "environmentId":"018d5e5e-2222-7e5e-5e5e-222222222222", "dataType": "order", "data": { "id": "018d5e5e-3333-7e5e-5e5e-333333333333", "playerId": "player_12345", "paymentProvider": "stripe", "paymentProviderResourceId": "cs_test_a1b2c3d4e5f6", "url": "https://checkout.stripe.com/pay/cs_test_a1b2c3d4e5f6", "lineItems": [ { "sku": "com.game.coins_100", "productType":“消耗品”, "price": { "amountMicros":"25270591" "currency":"USD" } } ], "total": { "amountMicros":"25270591" "currency":"USD", "refundedAmountMicros":0 }, "status": "paid", "customReferenceId": "order_xyz_789", "metadata": { "campaign": "summer_sale", "platform": "iOS" }, "createdAt":"2024-01-15T14:25:00Z", "updatedAt":"2024-01-15T14:30:00Z", "paidAt":"2024-01-15T14:30:00Z", "fulfilledAt": null }}
请参阅 Webhook 事件中的以下字段:

id

string
必填
Webhook 事件的唯一标识符。

version

string
必填
Webhook 事件架构的版本。

eventType

string
必填
事件的类型。请参阅事件类型以了解可能的值。

time

string
必填
生成事件的时间(ISO 8601 格式)。

projectId

string
必填
此订单所属的 Unity 项目的 ID。

environmentId

string
必填
发生此顺序的 Unity 环境的 ID。

dataType

string
必填
事件中的数据类型。

data

object
必填
包含购买详细信息的订单数据对象。

id

string
必填
订单的唯一标识符。

playerId

string
必填
Unity 身份验证玩家 ID。

paymentProvider

string
必填
处理订单的付款提供商,例如
stripe
或
coda
。

paymentProviderResourceId

string
必填
付款提供商分配给资源的唯一 ID。

url

string
必填
订单的签出 URL。

lineItems

object array
必填
订单中购买的商品列表。

sku

string
必填
商品的唯一标识符。

productType

string
必填
商品类型,例如
Consumable
。

price

object
必填
商品的价格。

amountMicros

integer
必填
以微米为单位的价格(1,000,000 micros 等于 $1.00)。这些值是向用户显示的值。

currency

string
必填
三个字母的 ISO 4217 货币代码。

total

object
必填
总订单金额。

amountMicros

integer
必填
总订单金额(以微秒为单位)。

currency

string
必填
三个字母的 ISO 4217 货币代码。

refundedAmountMicros

integer
必填
退款总额(以微克为单位)。在部分退款中,此金额可能小于
amountMicros
。

status

string
必填
订单的状态。可能的值有:
created
、
paid
、
failed
、
fulfilled
、
revoked
。

customReferenceId

string
订单的可选自定义参考 ID。

metadata

object
一个键值对象,包含购买流程期间传递的任何自定义元数据。

createdAt

string
必填
创建订单时的时间戳(ISO 8601 格式)。

updatedAt

string
必填
上次更新订单的时间戳(ISO 8601 格式)。

paidAt

string
支付订单的时间戳(ISO 8601 格式)。

fulfilledAt

string
完成订单的时间戳,如果尚未完成,则
null
。

revokedAt

string
撤销订单时的时间戳,如果未撤销,则
null
。

事件类型

Unity IAP 发送以下 Webhook 事件类型:

order.paid

当玩家成功完成购买时,Unity IAP 会发送
order.paid
事件。收到此事件后,请向玩家授予他们购买的权利或货币,并将订单标记为已执行。

order.updated

Unity IAP 会在每次更新订单时发送
order.updated
事件。这包括以下更改:
  • 标记为已完成的顺序。
  • 正在处理的退款。
  • 其他顺序修改。
data.total
中的
refundedAmountMicros
字段反映了当前退款总额。
退款由开发者发起。例如,您可以通过付款提供商的后台向玩家发放退款。
Unity IAP 在发生退款时不会自动撤销授权。如果要在退款时撤销授权,可以监听此事件并在您自己的授权系统中进行处理。

order.revoked

当订单状态更改为
revoked
时,Unity IAP 会发送
order.revoked
事件。收到此事件后,撤销玩家在最初购买时获得的权利或货币。
按存储容量使用计费由玩家发起。例如,玩家可能会通过信用卡公司或银行对收费提出异议。
当按存储容量使用计费争议结束并且玩家赢得争议时,Unity IAP 会自动撤销订单并发送此事件。与退款不同,Unity IAP 会撤销退款授权。

通过 API 将订单标记为已完成

在后端授予授权后,使用 Orders API 将订单标记为已完成。这会更新
fulfilledAt
时间戳并确保正确跟踪订单状态。

身份验证

要调用这些终端,需要使用以下方法之一进行身份验证:
  • 服务帐户在 Unity Dashboard(Unity 后台)中创建一个服务帐户,并用它来验证后端服务器。有关更多信息,请参阅服务帐户身份验证。
  • Cloud Code从 Cloud Code 脚本或模块调用终端,该脚本或模块可以代表项目进行身份验证。有关更多信息,请参阅使用 Cloud Code 模块实现购买。

获取顺序

调用
GET
终端
以检索订单。
GET https://iap.services.api.unity.com/v1/projects/{projectId}/environments/{environmentId}/orders/{orderId}

订单状态

状态

描述

created
订单已创建,但尚未完成付款。可以转换到
paid
、
failed
或
cancelled
。
paid
付款已收到并由付款提供商确认。可以转换到
fulfilled
或
revoked
。
fulfilled
订单已完成,玩家已获得奖励。
可以转换到
revoked`
failed
订单失败。这是终端状态。
revoked
订单已撤销。这是终端状态。
cancelled
订单在付款前已取消。这是终端状态。

响应正文示例

GET
和
PATCH
终端都返回完整顺序对象:
{ "id": "018d5e5e-3333-7e5e-5e5e-333333333333", "projectId":"018d5e5e-1111-7e5e-5e5e-111111111111", "environmentId":"018d5e5e-2222-7e5e-5e5e-222222222222", "playerId": "player_12345", "paymentProvider": "stripe", "paymentProviderResourceId": "cs_test_12345", "url": "https://checkout.stripe.com/pay/cs_test_12345", "lineItems": [ { "sku": "com.game.coins_100", "productType":“消耗品” } ], "status": "paid", "fulfilledAt": null, "revokedAt": null, "customReferenceId": "order_xyz_789", "metadata": { "campaign": "summer_sale" }, "createdAt":"2024-01-15T14:25:00Z", "updatedAt":"2024-01-15T14:30:00Z"}

更新订单

调用
PATCH
终端
以更新订单的状态:
PATCH https://iap.services.api.unity.com/v1/projects/{projectId}/environments/{environmentId}/orders/{orderId}

请求正文

{ "status": "fulfilled"}

status

string
必填
要为订单设置的新状态。允许的值:。
fulfilled
在授予玩家权利后设置。只能根据
paid
订单进行设置。 设置为撤销玩家的权利(例如,退款后)。只能根据
paid
或
fulfilled
订单进行设置。 设置为取消订单。只能在
created
订单上设置(付款前)。
一旦订单为
revoked
或
cancelled
,就无法更改其状态。
请参阅 IAP Client API 文档以了解 HTTP 响应状态代码。

返回事件响应

您需要返回事件响应来指示处理事件的成功或失败。
  • "response": 指示事件处理成功。
  • 非
    2xx
    响应
    :指示失败。Unity IAP 将根据重播策略重播事件。

事件重放行为

当您的 Webhook 终端返回非
2xx
响应时,Unity IAP 会自动重试事件的传递。确保 Webhook 处理程序幂等,以免重放的事件导致重复授权。

后续步骤

本页面是使用 IAP 设置直接到消费者 (D2C) 付款提供商的工作流程的一部分。要继续此工作流程,请选择以下选项之一: