API 规格书
📝 本页为参考译文(简体中文)。如与日文原版有出入,以日文版为准。
本文档说明用于与Game8 Store对接的API规范。
API列表
需发行商实现的API
请求由Game8 Store发送。
| 道具购买资格检查 / Purchase Eligibility Check | /check | GET | 必填 | 确认用户是否可以购买指定道具 |
| 道具购买登记 / Register Purchase | /register | POST | 必填 | 购买完成后,发放游戏内道具 |
| 玩家信息获取 / Retrieve Player Information | /user_info | GET | 必填 | 基于游戏内ID,获取玩家名称和等级信息。 |
| 库存检查 / Inventory Check | /stock | GET | 推荐 | 确认指定道具的库存状况 |
Game8 Store提供的API
由发行商向Game8 Store发送请求。
| 订单查询 / Order Verify | /orders/verify | GET | 可选 | paid_transaction_id 指定后查询订单的状态 |
1. 通用规范
| 主机 | Game8提供的API: <由Game8指定> 发行商提供的API: <由发行商指定> |
| 协议 | HTTPS |
| 字符编码 | UTF-8 |
1.1. 请求规范
请求头
| Authorization | Bearer <ACCESS_TOKEN> | 认证信息 |
| Content-Type | application/json | 内容类型 |
| X-Signature | <SIGNED_DATA> | 用于签名验证的签名 |
1.2. 响应规范
通用响应头
| Content-Type | application/json |
通用响应体
| request_id | string | 唯一的请求ID。用于故障排查等场景下追踪请求。 |
| timestamp | string (ISO8601) | 响应的时间戳 |
| result_code | string | 结果代码 |
| message | string | 消息 |
1.3. X-Signature的设置
为了判定请求是否合法,需使用为每款游戏签发的密钥进行签名,并设置到请求头中。
签名的设置方法
- GET时根据查询字符串、POST时根据请求体的内容计算摘要。摘要使用密钥的secret通过HMAC-SHA256算出。
- 将算出的摘要进行Base64编码,并设置到请求头的X-Signature中。
签名的验证方法
- GET时根据查询字符串、POST时根据请求体的内容计算摘要。摘要使用密钥的secret通过HMAC-SHA256算出。
- 将算出的摘要进行Base64编码,并验证其是否与请求头X-Signature的内容一致。
- 一致时,作为合法请求进行处理。
- 不一致时,作为非法请求返回错误。
密钥的获取方法
密钥由Game8, Inc.创建并共享给您。
2. 需发行商实现的API详情
2.1. 道具购买资格检查(GET /check)必填
概述
确认游戏内道具是否可购买,并返回考虑了年龄限制和购买上限后的结果。
此外,为了避免在购买限量道具等时因支付前的时间差导致购买中止,可通过设置 transaction id 来预留目标道具。
请求规范
| 方法 | GET |
| 端点 | /check |
| 协议 | HTTPS |
| 内容类型 | application/json |
请求头
| Authorization | Bearer <ACCESS_TOKEN> | 认证信息 |
| Content-Type | application/json | 内容类型 |
| X-Signature | <SIGNED_DATA> | 用于签名验证的签名 |
查询参数
| game | string | ✅ | 由Game8 Store发放的游戏唯一ID |
| user | string | ✅ | 在游戏内签发的游戏内用户唯一ID |
| transaction_id | string | ✅ | 唯一标识交易的标识符 |
| item | string | ✅ | 在游戏内签发的购买目标道具ID(?) |
| item_category | string | ✅ | 购买目标道具的类别
paid : 付费商品(常规的付费道具)
free : 免费商品(赠品、活动配发品等价格为0日元的商品) |
| price | integer | ✅ | 购买目标道具的商品金额(含税,日元)。为折扣适用前的定价。 |
| selling_price | integer | ✅ | 适用由发行商承担的折扣后的购买价款(含税,日元)。无折扣时与 price 金额相同。 |
| billing_amount | integer | ✅ | 从购买价款中扣除积分、优惠券使用等之后的最终支付金额(含税,日元)。无适用项时与 selling_price 金额相同。 |
请求示例
GET /check HTTP/1.1
Host: <由发行商自行指定>
Authorization: Bearer <ACCESS_TOKEN>
Content-Type: application/json
X-Signature: <SIGNED_DATA>
Query Parameter:
?game=game123&user=user456&transaction_id=txn_123456&item=item789&item_category=paid&price=500
响应规范
响应体
| request_id | string | 唯一的请求ID |
| timestamp | string (ISO8601) | 响应的时间戳 |
| result_code | string | 结果代码 |
| message | string | 消息 |
| purchasable | string | 可购买:available 不可购买:unavailable 维护中:maintenance |
| age_category | string | 用户的年龄区分。例如有 under_15 / under_18 / adult / under_17 / over_17 等值,也可以根据需要设置其他值。 |
| account_limit | Object | null | 账户的消费限额。若无消费限额则为null |
| stock | Object | null | 库存信息。库存无限时为null |
| requested_price | integer | 所请求道具的价格(日元) |
account_limit的结构
| total | integer | 消费限额(日元) |
| remaining | integer | 剩余可购买金额(日元) |
| reset_at | string (ISO8601) | null | 消费限额的预定解除日期时间。未定时为 null |
stock的结构
| total | integer | 总库存数 |
| remaining | integer | 剩余库存数 |
| restock_interval | string | 每日:daily 每周:weekly 每月: monthly 补货计划未定时为null |
| restock_at | string (ISO8601) | null | 下次补货预定日期时间(有计划时)。未定或无限时为 null |
响应示例(可购买)
{
"request_id": "abc123",
"timestamp": "2025-02-04T12:34:56Z",
"result_code": "PUB0000",
"message": "可以购买",
"purchasable": "available",
"age_category": "under_15",
"account_limit": {
"total": 10000,
"remaining": 9000,
"reset_at": "2025-03-01T00:00:00Z"
},
"stock": {
"total": 10,
"remaining": 9,
"restock_interval": "daily",
"restock_at": "2025-02-05T00:00:00Z"
},
"requested_price": 500
}
响应示例(不可购买 - 未提交年龄验证)
{
"request_id": "abc124",
"timestamp": "2025-02-04T12:35:00Z",
"result_code": "PUB2006",
"message": "由于未进行年龄验证,无法购买。",
"purchasable": "unavailable",
"age_category": "unset",
"account_limit": null,
"stock": null,
"requested_price": 500
}
响应示例(不可购买 - 超出消费限额)
{
"request_id": "abc125",
"timestamp": "2025-02-04T12:36:00Z",
"result_code": "PUB2005",
"message": "已达到消费限额的上限。",
"purchasable": "unavailable",
"age_category": "under_18",
"account_limit": {
"total": 10000,
"remaining": 0,
"reset_at": "2025-03-01T00:00:00Z"
},
"stock": {
"total": 10,
"remaining": 9,
"restock_interval": "daily",
"restock_at": "2025-02-05T00:00:00Z"
},
"requested_price": 500
}
响应示例(不可购买 - 道具未销售)
{
"request_id": "abc125",
"timestamp": "2025-02-04T12:36:00Z",
"result_code": "PUB2007",
"message": "目标道具当前处于不可销售状态。",
"purchasable": "unavailable",
"age_category": "under_18",
"account_limit": {
"total": 10000,
"remaining": 9000,
"reset_at": "2025-03-01T00:00:00Z"
},
"stock": {
"total": 10,
"remaining": 9,
"restock_interval": "daily",
"restock_at": "2025-02-05T00:00:00Z"
},
"requested_price": 500
}
响应示例(不可购买 - 维护中)
{
"request_id": "abc125",
"timestamp": "2025-02-04T12:36:00Z",
"result_code": "PUB6000",
"message": "服务正在维护中。",
"purchasable": "maintenance",
"age_category": "under_18",
"account_limit": {
"total": 10000,
"remaining": 9000,
"reset_at": "2025-03-01T00:00:00Z"
},
"stock": {
"total": 10,
"remaining": 9,
"restock_interval": "daily",
"restock_at": "2025-02-05T00:00:00Z"
},
"requested_price": 500
}
2.2. 道具购买记录登记(POST /register)必填
概述
购买完成后,用于增加游戏内道具的处理。
请求规范
| 方法 | POST |
| 端点 | /register |
| 协议 | HTTPS |
| 内容类型 | application/json |
请求头
| Authorization | Bearer <ACCESS_TOKEN> | 认证信息 |
| Content-Type | application/json | 内容类型 |
| X-Signature | <SIGNED_DATA> | 用于签名验证的签名 |
请求体
| game | string | ✅ | 由Game8 Store发放的游戏唯一ID |
| user | string | ✅ | 在游戏内签发的游戏内用户唯一ID |
| item | string | ✅ | 在游戏内签发的购买目标道具ID(?) |
| transaction_id | string | ✅ | 唯一标识交易的标识符 |
| item_category | string | ✅ | 购买目标道具的类别
paid : 付费商品(常规的付费道具)
free : 免费商品(赠品、活动配发品等价格为0日元的商品) |
| item_name | string | ✅ | 购买目标道具的名称(例:宝石100个礼包) |
| price | integer | ✅ | 购买目标道具的商品金额(含税,日元)。为折扣适用前的定价。 |
| selling_price | integer | ✅ | 适用由发行商承担的折扣后的购买价款(含税,日元)。无折扣时与 price 金额相同。 |
| billing_amount | integer | ✅ | 从购买价款中扣除积分、优惠券使用等之后的最终支付金额(含税,日元)。无适用项时与 selling_price 金额相同。 |
| purchased_at | string (ISO8601) | ✅ | 购买日期时间 |
| ref | string | null | ✅ | 流量来源的域名(例:game8.jp)。来源不明时为 null。 |
| payment_method | string | null | ✅ | 支付方式。信用卡为Card,其他为支付服务名称(メルペイ、PayPal等)。全额积分支付等不经由支付服务的情况为null。 |
| contents | array | ✅ | 道具中所含内容物的列表 |
contents 数组的结构
| content_id | string | ✅ | item 加上后缀后自动赋予的道具内内容物ID(例:pack001-1) |
| content_name | string | ✅ | 道具内内容物的名称(例:宝石) |
| quantity | integer | ✅ | 道具内内容物的数量(例:1000) |
请求示例
POST /register HTTP/1.1
Host: <由发行商自行指定>
Authorization: Bearer <ACCESS_TOKEN>
Content-Type: application/json
X-Signature: <SIGNED_DATA>
{
"game": "game123",
"user": "user456",
"transaction_id": "txn789",
"item": "pack001",
"item_category": "paid",
"item_name": "宝石1000个",
"price": 5000,
"selling_price": 5000,
"billing_amount": 5000,
"purchased_at": "2025-02-04T12:36:00Z",
"ref": "game8.jp",
"payment_method": "Card",
"contents": [
{
"content_id": "pack001-1",
"content_name": "宝石",
"quantity": 1000
},
{
"content_id": "pack001-2",
"content_name": "赠送金币",
"quantity": 100
}
]
}
响应规范
响应体
| request_id | string | 唯一的请求ID |
| timestamp | string (ISO8601) | 响应的时间戳 |
| result_code | string | 结果代码 |
| message | string | 消息 |
| item_granted | boolean | 游戏内道具是否已发放 (true / false) |
响应示例(成功)
{
"request_id": "def456",
"timestamp": "2025-02-04T12:36:00Z",
"result_code": "PUB0000",
"message": "已登记购买记录。",
"item_granted": true
}
响应示例(失败 - 用户不明)
{
"request_id": "def458",
"timestamp": "2025-02-04T12:38:00Z",
"result_code": "PUB3002",
"message": "指定的用户不存在。",
"item_granted": false
}
响应示例(失败 - 已登记)
{
"request_id": "def458",
"timestamp": "2025-02-04T12:38:00Z",
"result_code": "PUB3004",
"message": "指定的TransactionID已被登记。",
"item_granted": false
}
2.3. 玩家信息获取(GET /user_info)必填
概述
根据用户输入的游戏内ID,获取玩家名称和等级信息。通过在购买确认页面显示获取到的信息,用户可以确认输入的ID是否正确,以及与游戏的连接是否正常。
请求规范
| 方法 | GET |
| 端点 | /user_info |
| 协议 | HTTPS |
| 内容类型 | application/json |
请求头
| Authorization | Bearer <ACCESS_TOKEN> | 认证信息 |
| Content-Type | application/json | 内容类型 |
| X-Signature | <SIGNED_DATA> | 用于签名验证的签名 |
查询参数
| game | string | ✅ | 由Game8 Store发放的游戏唯一ID |
| user | string | ✅ | 在游戏内签发的游戏内用户唯一ID |
请求示例
GET /user_info HTTP/1.1
Host: <由发行商自行指定>
Authorization: Bearer <ACCESS_TOKEN>
Content-Type: application/json
X-Signature: <SIGNED_DATA>
Query Parameter:
?game=game123&user=Player5678
响应规范
响应体
| request_id | string | ✅ | 唯一的请求ID |
| timestamp | string (ISO8601) | ✅ | 响应的时间戳 |
| result_code | string | ✅ | 结果代码 |
| message | string | ✅ | 消息 |
| user_name | string | ✅ | 玩家名称(可掩码) |
| user_level | integer | ✅ | 玩家等级或段位。若游戏内不存在相应信息,则返回-1。 |
user_name 的掩码示例
| aa | *a |
| aaa | *aa |
| aaaa | **aa |
| aaaaa | ***aa |
响应示例(成功)
{
"request_id": "abc123",
"timestamp": "2025-03-12T14:30:00Z",
"result_code": "PUB0000",
"message": "获取成功",
"user_name": "****rX",
"user_level": 45
}
响应示例(失败 - 未找到玩家ID)
{
"request_id": "abc124",
"timestamp": "2025-03-12T14:31:00Z",
"result_code": "PUB2004",
"message": "未找到玩家ID。"
}
响应示例(失败 - 账号因封禁等原因处于非活跃状态)
{
"request_id": "abc124",
"timestamp": "2025-03-12T14:31:00Z",
"result_code": "PUB2008",
"message": "因账号停用而无法购买。"
}
响应示例(失败 - 服务器维护中)
{
"request_id": "abc125",
"timestamp": "2025-03-12T14:32:00Z",
"result_code": "PUB6000",
"message": "服务正在维护中。"
}
2.4. 库存检查(GET /stock)推荐
概述
确认指定道具的库存状况,并返回可购买的剩余数量。
对于限量商品或活动商品等需要库存管理的道具,用于向用户显示库存状况,以及在购买流程开始前进行预先检查。
请求规范
| 方法 | GET |
| 端点 | /stock |
| 协议 | HTTPS |
| 内容类型 | application/json |
请求头
| Authorization | Bearer <ACCESS_TOKEN> | 认证信息 |
| Content-Type | application/json | 内容类型 |
| X-Signature | <SIGNED_DATA> | 用于签名验证的签名 |
查询参数
| game | string | ✅ | 由Game8 Store发放的游戏唯一ID |
| user | string | ✅ | 在游戏内签发的游戏内用户唯一ID |
| transaction_id | string | ✅ | 唯一标识交易的标识符 |
| items | string | ✅ | 在游戏内签发的购买目标道具ID(?) 可用逗号分隔指定多个 |
请求示例
GET /stock HTTP/1.1
Host: <由发行商自行指定>
Authorization: Bearer <ACCESS_TOKEN>
Content-Type: application/json
X-Signature: <SIGNED_DATA>
Query Parameter:
?game=game123&user=user456&transaction_id=txn_123456&items=item789,item012
响应规范
响应体
| request_id | string | 唯一的请求ID |
| timestamp | string (ISO8601) | 响应的时间戳 |
| result_code | string | 结果代码 |
| message | string | 消息 |
| stock | Object[] | 库存信息 |
stock的结构
| item | string | 在游戏内签发的购买目标道具ID(?) |
| total | integer | 总库存数。无限制时返回 -1 |
| remaining | integer | 剩余库存数。无限制时返回 -1 |
| restock_at | string (ISO8601) | null | 下次补货预定日期时间(有计划时)。未定或无限时为 null |
响应示例(有库存)
{
"request_id": "abc123",
"timestamp": "2025-02-04T12:34:56Z",
"result_code": "PUB0000",
"message": "成功",
"stock": [
{
"item": "item789",
"total": 10,
"remaining": 8,
"restock_at": null
}
]
}
响应示例(无库存)
{
"request_id": "abc124",
"timestamp": "2025-02-04T12:35:00Z",
"result_code": "PUB2009",
"message": "已达到道具购买数量限制的上限",
"stock": [
{
"item": "item789",
"total": 10,
"remaining": 0,
"restock_at": null
}
]
}
响应示例(无限库存)
{
"request_id": "abc124",
"timestamp": "2025-02-04T12:36:00Z",
"result_code": "PUB0000",
"message": "成功",
"stock": [
{
"item": "item789",
"total": -1,
"remaining": -1,
"restock_at": null
}
]
}
3. Game8 Store提供的API详情
3.1. 订单查询(GET /orders/verify)使用可选
概述
/register API通知的订单状态可通过本API进行查询,查询时使用paid_transaction_id 。
/register API中使用的 transaction_id ,请将相同的值指定为 paid_transaction_id 。
预想的使用场景如下:
/register 接收后确认订单状态- API调用失败时的再次查询
由此,通知(/register)+ 查询(/orders/verify)的双重确认成为可能。
本API由Game8 Store侧持续运行,无需事先申请。发行商侧无需准备端点,使用时只需实现对本API的调用。即使未将其纳入支付流程,也可通过发送请求确认订单的支付状态(是否使用为可选)。
请求规范
| 方法 | GET |
| 端点 | /api/public/marketplace/publishers/{publisher_slug}/games/{game_slug}/orders/verify |
| 协议 | HTTPS |
| 内容类型 | application/json |
请求头
| Authorization | Bearer <ACCESS_TOKEN> | 认证信息 |
| X-Signature | <SIGNED_DATA> | 用于签名验证的签名 |
查询参数
| paid_transaction_id | string | ✅ | /register API中使用的 transaction_id 的相同值。仅可使用字母数字、连字符和下划线。 |
请求示例
GET /api/public/marketplace/publishers/example-publisher/games/example-game/orders/verify HTTP/1.1
Host: <Game8指定>
Authorization: Bearer <ACCESS_TOKEN>
X-Signature: <SIGNED_DATA>
Query Parameter:
?paid_transaction_id=txn_123456
响应规范
响应体(成功时)
| request_id | string | 唯一的请求ID |
| timestamp | string (ISO8601) | 响应的时间戳 |
| result_code | string | 结果代码 |
| message | string | 消息 |
| paid_transaction_id | string | 订单的交易ID |
| status | string | 订单状态(参见下文) |
| item_id | string | 发行商侧的道具ID |
| price | integer | 购买目标道具的商品金额(含税,日元)。为折扣适用前的定价。 |
| selling_price | integer | 适用由发行商承担的折扣后的购买价款(含税,日元)。无折扣时与 price 金额相同。 |
| billing_amount | integer | 从购买价款中扣除积分、优惠券使用等之后的最终支付金额(含税,日元)。无适用项时与 selling_price 金额相同。 |
| purchased_at | string (ISO8601) | null | 购买日期时间。支付处理中(pending)时为 null |
status的值
pending | 支付处理中 |
payment_confirmed | 支付已确认(支付已完成但道具发放处理尚未完成的状态) |
completed | 已完成(道具已发放) |
cancelled | 已取消 |
响应示例(成功 - 已完成的订单)
{
"request_id": "abc123",
"timestamp": "2025-04-01T12:00:00+09:00",
"result_code": "PUB0000",
"message": "成功",
"paid_transaction_id": "txn_123456",
"status": "completed",
"item_id": "item789",
"price": 1000,
"selling_price": 900,
"billing_amount": 800,
"purchased_at": "2025-04-01T12:00:00+09:00"
}
响应示例(成功 - 支付处理中)
{
"request_id": "abc124",
"timestamp": "2025-04-01T12:00:01+09:00",
"result_code": "PUB0000",
"message": "成功",
"paid_transaction_id": "txn_123456",
"status": "pending",
"item_id": "item789",
"price": 1000,
"selling_price": 1000,
"billing_amount": 1000,
"purchased_at": null
}
错误响应
发生错误时仅返回通用响应体:
{
"request_id": "<请求ID>",
"timestamp": "<时间戳>",
"result_code": "<错误代码>",
"message": "<错误消息>"
}
| 400 | PUB2001 | 缺少必需参数 / 参数不正确 | paid_transaction_id 未指定、格式不正确,或路径标识符不正确 |
| 401 | PUB1002 | 认证或签名验证失败 | 访问令牌或签名不正确 |
| 403 | PUB1003 | 无法访问其他发行商或其他游戏的订单 | 查询非本公司的订单 |
| 404 | PUB3001 | 未找到指定的订单 | 相应的订单不存在 |
| 429 | - | Rate limit exceeded. Please try again later. | 超过速率限制(60次请求/分钟)。响应体为 {"error": "..."} 格式 |
| 500 | PUB4000 | 发生了意外错误 | 服务器内部错误 |
| 503 | PUB4001 | 无法连接到服务 | 临时网络故障。请稍后重试 |
响应示例(错误 - 认证失败)
{
"request_id": "abc125",
"timestamp": "2025-04-01T12:00:02+09:00",
"result_code": "PUB1002",
"message": "认证或签名验证失败"
}
响应示例(错误 - 未找到订单)
{
"request_id": "abc126",
"timestamp": "2025-04-01T12:00:03+09:00",
"result_code": "PUB3001",
"message": "未找到指定的订单"
}
4. 错误处理
4.1. 错误代码列表
PUB0000 | 成功 | - |
PUB1000 | 请求格式不正确 | 确认请求的结构和必需参数,以正确的格式发送 |
PUB1001 | 缺少认证信息 | Authorization 在请求头中将 Bearer <ACCESS_TOKEN> 设置为正确的值 |
PUB1002 | 无效的访问令牌 | 确认访问令牌的有效期,必要时重新签发 |
PUB1003 | 访问权限不足 | 确认是否拥有对API端点的适当权限 |
PUB1004 | 签名内容不一致 | 确认用于签名的密钥的secret是否正确 |
PUB1005 | 已处理的请求 | 请勿将同一request_id 重复发送 |
PUB2001 | 缺少必需参数 | 确认必需参数并修正请求 |
PUB2002 | 参数类型无效 | 例: price 中传入了 string 时,请修正为整数值 |
PUB2003 | 参数值不正确 | 确认是否发送了不被允许的值或超出范围的值 |
PUB2004 | 相应的数据不存在 | 请确认所指定的 game 或 user 确实存在 |
PUB2005 | 已达到基于年龄的购买金额限制的上限 | account_limit.remaining 的值,请确认是否超过了限制 |
PUB2006 | 尚未进行年龄验证 | 提示用户在游戏内进行年龄验证 |
PUB2007 | 道具停止销售 | 就商店侧销售道具的调整,咨询销售与开发团队 |
PUB2008 | 因账号停用而无法购买 | - |
PUB2009 | 已达到道具购买数量限制的上限 | 确认购买历史,并确认是否超过限制 |
PUB3001 | 无效的交易ID | transaction_id 是否正确,请进行确认 |
PUB3002 | 指定的用户不存在 | user 是否正确,请进行确认 |
PUB3003 | 指定的道具不存在 | item 需要确认,并指定正确的值 |
PUB3004 | 已登记的交易ID | transaction_id 是否正确,请进行确认 |
PUB4000 | 服务器内部错误 | 可能是服务器侧的问题,请在一定时间后重试 |
PUB4001 | 临时系统故障 | 进行重试(推荐: 5秒后重试) |
PUB5000 | 未知错误 | 确认详细的错误消息,并咨询开发团队 |
PUB6000 | 维护中 | 视为服务暂停,在一定时间后重试 |
4.2. 错误处理的推荐流程
result_code 进行确认PUB0000(成功)时为正常处理。- 否则,判定错误的种类。
- 确认是否为客户端侧可修正的错误
PUB1000 类, PUB2000 类错误可通过修正请求内容来应对。PUB3000 类错误需确认数据的一致性。
- 确认是否为可重试的错误
PUB4000, PUB4001 可能是临时性错误,请在数秒后重试。
- 记录并通知错误消息
- 未知错误(
PUB5000)应保留日志,并向开发团队报告。
4.3. 重试策略
PUB4000 | 5秒后 | 3次 | 由于是服务器内部错误,可能会在短时间内解决 |
PUB4001 | 10秒后 | 5次 | 由于是临时系统故障,请留出较长的间隔 |
PUB5000 | 无 | 0次 | 未知错误应立即报告 |
请参考此错误处理列表,实现适当的错误处理。