---
title: "API 规格书"
site: "Game8 Store – Developer Center"
lang: "zh"
category: "技术规格与 API"
canonical: "https://developers.store.game8.jp/zh/api-v5/"
---

# API 规格书

📝 本页为参考译文（简体中文）。如与日文原版有出入，以日文版为准。

本文档说明用于与Game8 Store对接的API规范。

## API列表

### 需发行商实现的API

请求由Game8 Store发送。

| API名称 / API Name | 端点 / Endpoint | 方法 / Method | 必填 / Required | 说明 / Description |
| --- | --- | --- | --- | --- |
| **道具购买资格检查** / 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发送请求。

| API名称 / API Name | 端点 / Endpoint | 方法 / Method | 必填 / Required | 说明 / Description |
| --- | --- | --- | --- | --- |
| **订单查询** / Order Verify | `/orders/verify` | `GET` | 可选 | `paid_transaction_id` 指定后查询订单的状态 |

## 1. 通用规范

| 项目 | 内容 |
| --- | --- |
| 主机 | Game8提供的API： `<由Game8指定>`<br>发行商提供的API：`<由发行商指定>` |
| 协议 | HTTPS |
| 字符编码 | UTF-8 |

### 1.1. 请求规范

#### 请求头

| 键 | 值 | 内容 |
| --- | --- | --- |
| Authorization | Bearer `<ACCESS_TOKEN>` | 认证信息 |
| Content-Type | application/json | 内容类型 |
| X-Signature | `<SIGNED_DATA>` | 用于签名验证的签名 |

> 访问令牌必须是为每款游戏签发的16～36个字符的随机字符串，由字母（包含大写和小写）和数字组成。
>
> 由Game8, Inc.创建并提供给您。您也可以自行创建，如有需要请咨询。

### 1.2. 响应规范

#### 通用响应头

| 键 | 值 |
| --- | --- |
| Content-Type | application/json |

#### 通用响应体

| 键 | 值 | 内容 |
| --- | --- | --- |
| request_id | `string` | 唯一的请求ID。用于故障排查等场景下追踪请求。 |
| timestamp | `string (ISO8601)` | 响应的时间戳 |
| result_code | `string` | 结果代码 |
| message | `string` | 消息 |

> [错误代码列表](https://developers.store.game8.jp/zh/api-v5/#337bef2a-13a2-8102-b2d0-c0c36f98ad7e) 中记载的错误发生时，仅返回通用响应体的字段。

### X-Signature的设置

为了判定请求是否合法，需使用为每款游戏签发的密钥进行签名，并设置到请求头中。

#### 签名的设置方法

1. GET时根据查询字符串、POST时根据请求体的内容计算摘要。摘要使用密钥的secret通过HMAC-SHA256算出。

> 用于计算摘要的消息示例
>
> GET时：game=game123&user=user456&…
>
> POST时：{\”game\”:\”game123\”,\”user\”:\”user456\”,…}

1. 将算出的摘要进行Base64编码，并设置到请求头的X-Signature中。

#### 签名的验证方法

1. GET时根据查询字符串、POST时根据请求体的内容计算摘要。摘要使用密钥的secret通过HMAC-SHA256算出。

> 用于计算摘要的消息示例
>
> GET时：game=game123&user=user456&…
>
> POST时：{\”game\”:\”game123\”,\”user\”:\”user456\”,…}

1. 将算出的摘要进行Base64编码，并验证其是否与请求头X-Signature的内容一致。
  1. 一致时，作为合法请求进行处理。
  2. 不一致时，作为非法请求返回错误。

#### 密钥的获取方法

密钥由Game8, Inc.创建并共享给您。

## 2. 需发行商实现的API详情

### 2.1. 道具购买资格检查（GET /check）`必填`

#### 概述

确认游戏内道具是否可购买，并返回考虑了年龄限制和购买上限后的结果。
此外，为了避免在购买限量道具等时因支付前的时间差导致购买中止，可通过设置 transaction id 来预留目标道具。

> 在开展赠品活动时，对于0日元的商品，我们可能会请您将其判定为无需年龄验证也可购买道具。

#### 请求规范

| 项目 | 内容 |
| --- | --- |
| 方法 | 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（[？](https://developers.store.game8.jp/zh/faq/#acc-faq-523efe3d)） |
| item_category | string | ✅ | 购买目标道具的类别<br>`paid` : 付费商品（常规的付费道具）<br>`free` : 免费商品（赠品、活动配发品等价格为0日元的商品） |
| price | integer | ✅ | 购买目标道具的商品金额（含税，日元）。为折扣适用前的定价。 |
| selling_price | integer | ✅ | 适用由发行商承担的折扣后的购买价款（含税，日元）。无折扣时与 price 金额相同。 |
| billing_amount | integer | ✅ | 从购买价款中扣除积分、优惠券使用等之后的最终支付金额（含税，日元）。无适用项时与 selling_price 金额相同。 |

#### 请求示例

```json
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`<br>不可购买：`unavailable`<br>维护中：`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`<br>每周：`weekly`<br>每月： `monthly`<br>补货计划未定时为null |
| restock_at | string (ISO8601) \| null | 下次补货预定日期时间（有计划时）。未定或无限时为 null |

#### 响应示例（可购买）

```json
{
  "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
}
```

#### 响应示例（不可购买 - 未提交年龄验证）

```json
{
  "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
}
```

#### 响应示例（不可购买 - 超出消费限额）

```json
{
  "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
}
```

#### 响应示例（不可购买 - 道具未销售）

```json
{
  "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
}
```

#### 响应示例（不可购买 - 维护中）

```json
{
  "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）`必填`

#### 概述

购买完成后，用于增加游戏内道具的处理。

> 在登记购买记录之前，建议加入以下处理。
>
> - 仅接受包含已通过道具购买资格检查API的transaction_id的请求
> - 验证未触及消费限额

> 在开展赠品活动时，对于0日元的商品，我们可能会请您将其判定为无需年龄验证也可购买道具。

#### 请求规范

| 项目 | 内容 |
| --- | --- |
| 方法 | 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（[？](https://developers.store.game8.jp/zh/faq/#acc-faq-523efe3d)） |
| transaction_id | string | ✅ | 唯一标识交易的标识符 |
| item_category | string | ✅ | 购买目标道具的类别<br>`paid` : 付费商品（常规的付费道具）<br>`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） |

#### 请求示例

```json
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`) |

#### 响应示例（成功）

```json
{
  "request_id": "def456",
  "timestamp": "2025-02-04T12:36:00Z",
  "result_code": "PUB0000",
  "message": "已登记购买记录。",
  "item_granted": true
}
```

#### 响应示例（失败 - 用户不明）

```json
{
  "request_id": "def458",
  "timestamp": "2025-02-04T12:38:00Z",
  "result_code": "PUB3002",
  "message": "指定的用户不存在。",
  "item_granted": false
}
```

#### 响应示例（失败 - 已登记）

```json
{
  "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 |

#### 请求示例

```json
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。 |

> 由于根据输入的游戏内ID也可以获取其他玩家的名称，请根据需要对玩家名称进行掩码处理。

#### user_name的掩码示例

| 玩家名称 | 掩码后的user_name |
| --- | --- |
| aa | *a |
| aaa | *aa |
| aaaa | **aa |
| aaaaa | ***aa |

#### 响应示例（成功）

```json
{
  "request_id": "abc123",
  "timestamp": "2025-03-12T14:30:00Z",
  "result_code": "PUB0000",
  "message": "获取成功",
  "user_name": "****rX",
  "user_level": 45
}
```

#### 响应示例（失败 - 未找到玩家ID）

```json
{
  "request_id": "abc124",
  "timestamp": "2025-03-12T14:31:00Z",
  "result_code": "PUB2004",
  "message": "未找到玩家ID。"
}
```

#### 响应示例（失败 - 账号因封禁等原因处于非活跃状态）

```json
{
  "request_id": "abc124",
  "timestamp": "2025-03-12T14:31:00Z",
  "result_code": "PUB2008",
  "message": "因账号停用而无法购买。"
}
```

#### 响应示例（失败 - 服务器维护中）

```json
{
  "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（[？](https://developers.store.game8.jp/zh/faq/#acc-faq-523efe3d)）<br>可用逗号分隔指定多个 |

#### 请求示例

```json
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（[？](https://developers.store.game8.jp/zh/faq/#acc-faq-523efe3d)） |
| total | integer | 总库存数。无限制时返回 -1 |
| remaining | integer | 剩余库存数。无限制时返回 -1 |
| restock_at | string (ISO8601) \| null | 下次补货预定日期时间（有计划时）。未定或无限时为 null |

#### 响应示例（有库存）

```json
{
	"request_id": "abc123",
	"timestamp": "2025-02-04T12:34:56Z",
	"result_code": "PUB0000",
	"message": "成功",
	"stock": [
	  {
		  "item": "item789",
		  "total": 10,
		  "remaining": 8,
		  "restock_at": null
	  }
	]
}
```

#### 响应示例（无库存）

```json
{
	"request_id": "abc124",
	"timestamp": "2025-02-04T12:35:00Z",
	"result_code": "PUB2009",
	"message": "已达到道具购买数量限制的上限",
	"stock": [
	  {
		  "item": "item789",
		  "total": 10,
		  "remaining": 0,
		  "restock_at": null
	  }
	]
}
```

#### 响应示例（无限库存）

```json
{
	"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详情

### 订单查询（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 |

> `{publisher_slug}` 是发行商的标识符，`{game_slug}` 是游戏的标识符。将由Game8, Inc.告知。

#### 请求头

| 键 | 值 | 内容 |
| --- | --- | --- |
| Authorization | Bearer `<ACCESS_TOKEN>` | 认证信息 |
| X-Signature | `<SIGNED_DATA>` | 用于签名验证的签名 |

> 签名的生成方法与「1.3. X-Signature的设置」相同。由于是GET请求，签名对象为查询字符串。

#### 查询参数

| 键 | 类型 | 必填 | 说明 |
| --- | --- | --- | --- |
| 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` | 已取消 |

#### 响应示例（成功 - 已完成的订单）

```json
{
  "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"
}
```

#### 响应示例（成功 - 支付处理中）

```json
{
  "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
}
```

#### 错误响应

发生错误时仅返回通用响应体：

```json
{
  "request_id": "<请求ID>",
  "timestamp": "<时间戳>",
  "result_code": "<错误代码>",
  "message": "<错误消息>"
}
```

| HTTP状态 | result_code | 消息 | 说明 |
| --- | --- | --- | --- |
| 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` | 无法连接到服务 | 临时网络故障。请稍后重试 |

#### 响应示例（错误 - 认证失败）

```json
{
  "request_id": "abc125",
  "timestamp": "2025-04-01T12:00:02+09:00",
  "result_code": "PUB1002",
  "message": "认证或签名验证失败"
}
```

#### 响应示例（错误 - 未找到订单）

```json
{
  "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` | 已达到道具购买数量限制的上限 | 确认购买历史，并确认是否超过限制 |
| `PUB2010` | 因上一笔交易尚未完成，暂时无法购买 | 未完成的交易将由Game8 Store侧在一定时间后自动取消，恢复为可购买状态。请提示用户稍后再次购买 |
| `PUB3001` | 无效的交易ID | `transaction_id` 是否正确，请进行确认 |
| `PUB3002` | 指定的用户不存在 | `user` 是否正确，请进行确认 |
| `PUB3003` | 指定的道具不存在 | `item` 需要确认，并指定正确的值 |
| `PUB3004` | 已登记的交易ID | `transaction_id` 是否正确，请进行确认 |
| `PUB4000` | 服务器内部错误 | 可能是服务器侧的问题，请在一定时间后重试 |
| `PUB4001` | 临时系统故障 | 进行重试（推荐: 5秒后重试） |
| `PUB5000` | 未知错误 | 确认详细的错误消息，并咨询开发团队 |
| `PUB6000` | 维护中 | 视为服务暂停，在一定时间后重试 |

### 4.2. 错误处理的推荐流程

1. **`result_code`****进行确认**
  - `PUB0000`（成功）时为正常处理。
  - 否则，判定错误的种类。
2. **确认是否为客户端侧可修正的错误**
  - `PUB1000` 类， `PUB2000` 类错误可通过修正请求内容来应对。
  - `PUB3000` 类错误需确认数据的一致性。
3. **确认是否为可重试的错误**
  - `PUB4000`, `PUB4001` 可能是临时性错误，请在数秒后重试。
4. **记录并通知错误消息**
  - 未知错误（`PUB5000`）应保留日志，并向开发团队报告。

### 4.3. 重试策略

| 错误代码 | 重试间隔 | 最大重试次数 | 备注 |
| --- | --- | --- | --- |
| `PUB4000` | 5秒后 | 3次 | 由于是服务器内部错误，可能会在短时间内解决 |
| `PUB4001` | 10秒后 | 5次 | 由于是临时系统故障，请留出较长的间隔 |
| `PUB5000` | 无 | 0次 | 未知错误应立即报告 |

请参考此错误处理列表，实现适当的错误处理。
