# ByteMax API

将BRL Pix收款兑换至CNY或USD钱包。币种在开通账户时确定，之后不可更改。通过HTTPS和JSON查询订单及退款。

- 基础 URL: https://bytemax.exchange/api/v1
- [下载 OpenAPI 3.1](https://bytemax.exchange/api-v1.openapi.json)
- [文档页面](https://bytemax.exchange/zh-CN/docs/api)

## 开始使用

集成时，您会用到：

- API 密钥：每次调用都放在 `Authorization` 请求头中。
- `Idempotency-Key`：每个操作使用一个密钥。因网络故障或 5xx 需要重复同一操作时，请复用同一个密钥（金额与幂等性）。
- `payment.url`：引导付款人前往的支付链接。
- `order.completed` webhook：通知您订单已支付；请用 `GET /orders/{id}` 确认（[webhook](https://bytemax.exchange/zh-CN/docs/webhooks)）。

每笔订单都有两方：

| 字段 | 含义 | 币种 |
| --- | --- | --- |
| `source_*` | 付款人支付的部分 | `BRL` |
| `target_*` | 您收到的部分 | `CNY` / `USD` |

四步创建第一笔订单。

1. **创建 API 密钥**
   在您控制台的 [API](https://bytemax.exchange/zh-CN/api) 页面创建密钥并保存在您的服务器上：它只显示一次，并且可以访问您的整个账户。建议启用允许的 IP 列表，并填入将要调用 API 的服务器地址。列表关闭时，任何 IP 都可以使用该密钥。

2. **发送请求头**
   每次调用都要发送 `Authorization`。`POST` 和 `PATCH` 还要发送 `Content-Type: application/json` 和 UTF-8 编码的 JSON 正文，即使正文是 `{}`。创建订单和退款时，还要加上 `Idempotency-Key`：参见金额与幂等性。

   **每次调用**

   ```http
   Authorization: Bearer <API_KEY>
   ```

   **POST 和 PATCH**

   ```http
   Content-Type: application/json
   ```

3. **获取报价（可选）**
   报价不会创建任何内容。用它来确认密钥是否有效，并查看兑换金额。

   ```bash
   curl --request GET "https://bytemax.exchange/api/v1/quote?source_currency=BRL&target_currency=CNY&source_amount_cents=10000" \
     --header "Authorization: Bearer <API_KEY>"
   ```

   **响应 200**

   ```json
   {
     "source_currency": "BRL",
     "source_amount_cents": "10000",
     "target_currency": "CNY",
     "target_amount_cents": "12500"
   }
   ```

4. **创建第一笔订单**
   使用新的 `Idempotency-Key` 调用 `POST /orders`，会创建一笔真实订单。将付款人引导至 `payment.url`，付款人在那里付款。如果未付款，订单会在 `expires_at` 过期，即创建后 48 小时。

   ```bash
   curl --request POST "https://bytemax.exchange/api/v1/orders" \
     --header "Authorization: Bearer <API_KEY>" \
     --header "Idempotency-Key: order-8412" \
     --header "Content-Type: application/json" \
     --data '{"source_currency":"BRL","source_amount_cents":"10000","target_currency":"CNY"}'
   ```

   **响应 201**

   ```json
   {
     "id": "ord_example",
     "status": "pending_payment",
     "source_currency": "BRL",
     "source_amount_cents": "10000",
     "target_currency": "CNY",
     "target_amount_cents": "12500",
     "refunded_source_amount_cents": "0",
     "blocked_source_amount_cents": "0",
     "payment": {
       "url": "https://bytemax.exchange/pt-br/payment/0123456789abcdef0123456789abcdef",
       "pix_copy_paste": "00020101021226820014br.gov.bcb.pix2560pix.example/qr/v2/0123456789abcdef0123456789abcdef5204000053039865406100.005802BR5907BYTEMAX6009SAO PAULO62070503***6304ABCD"
     },
     "created_at": "2026-09-10T13:05:00.000Z",
     "expires_at": "2026-09-12T13:05:00.000Z"
   }
   ```

## 支付流程

订单从等待支付开始，最终变为已完成（已支付）、已过期或已取消。可以通过 Webhook 或查询来跟踪。

1. **报价（可选）**
   `GET /quote` 告诉您付款人支付多少、您收到多少。这只是预估：订单使用创建时刻的报价，Pix 的最低金额和上限也在那时才检查。

2. **创建订单**
   `POST /orders`，传入两个币种以及两个金额之一：付款人支付的金额或您收到的金额。响应包含支付链接 `payment.url`，以及 `payment.pix_copy_paste`，即付款人可以粘贴到银行应用中的 Pix 代码。

3. **把付款人引导到支付链接**
   将付款人重定向到 `payment.url`，或把该链接发给付款人。付款完成后，页面会在 5 秒后自动带付款人返回您在控制台 [API](https://bytemax.exchange/zh-CN/api) 页面配置的返回 URL；支付页面上的“返回商家”链接也指向该地址。未配置该 URL 时，付款人会回到来源网站。

4. **跟踪订单**
   注册一个 [Webhook](https://bytemax.exchange/zh-CN/docs/webhooks)：订单支付后会收到 `order.completed`，`GET /orders/{id}` 可确认其当前状态。

5. **需要时办理退款**
   `POST /orders/{id}/refunds`，传入您要从已收款项中退还的金额（CNY或USD）。该金额从您的余额中扣除，ByteMax 按原订单的比例计算付款人收回的 BRL：退还已收款项的一半，付款人就收回所付雷亚尔的一半。如果响应为 202，说明退款仍在处理中：用 `GET /orders/{id}/refunds/{refund_id}` 跟踪，不要再创建另一笔。

### 订单状态

- `pending_payment`: 等待支付。Pix 代码可在 `expires_at` 之前支付，即创建后 48 小时内。
- `completed`: 已支付。CNY或USD 金额已计入您的余额。最终状态。
- `expired`: 未在 `expires_at` 之前支付。最终状态。
- `canceled`: 由 ByteMax 取消，例如付款无法被接受并已退还给付款人。最终状态。

### 退款状态

- `processing`: 处理中。请持续查询，直到进入最终状态。如果退款长时间处于 `processing`，说明 ByteMax 正在审核：请联系客服。
- `succeeded`: 已完成。最终状态。
- `failed`: 退款无法完成。CNY或USD 金额会退回您的余额。最终状态。

## 金额与幂等性

### 金额与 ID

所有金额均为以分为单位的正整数字符串，不得以零开头，也不得包含符号、小数点或科学计数法。BRL、CNY和USD均使用2位精度："20000"代表指定币种的200单位。仅发送一个金额：`source_amount_cents`或`target_amount_cents`。

最低金额和 Pix 上限在创建订单时检查，报价时不检查。付款人至少需支付 R$ 30.00（`ORDER_MINIMUM_NOT_MET`）。Pix 支付的上限随汇率变动：超过时 API 返回 `PIX_RECEIPT_LIMIT_EXCEEDED`，`message` 中会说明当前的 BRL 上限。在任何调用中，您发送的金额都不能超过 `"100000000"`（1,000,000.00）。

所有 ID 也都是字符串：请以文本形式存储和比较，不要转换为数字。退款 ID（例如 `"9007199254741001"`）可能超过 JavaScript 能精确表示的最大整数。

### 幂等性

- 每个操作使用一个 `Idempotency-Key`：每笔新订单或新退款都有自己的密钥。
- 因网络故障或收到 5xx 响应而需要重复同一操作时，请复用相同的密钥和相同的正文。API 会返回已创建的订单或退款及其当前状态，不会重复创建。
- 请在您的系统中把密钥和对应的购买记录一起保存。

密钥长度为 1 到 80 个字符，可包含字母、数字、`.`、`_`、`:` 和 `-`。不要使用仅大小写不同的密钥。密钥不会过期，订单密钥也涵盖通过旧版 API 创建的订单。重复请求时，订单返回 200；退款在处理中时返回 202，之后返回 200。

特殊情况：相同密钥搭配不同正文会返回 409 `IDEMPOTENCY_CONFLICT`。密钥被预留前的拒绝不会占用它。为创建订单预留密钥后，收费或持久化失败可能使密钥保持处理中，即使订单尚未创建。发生网络故障或 5xx 后，请用相同密钥重复相同意图；不要更改正文，也不要换用新密钥重试。该密钥的创建操作仍在处理中时，重复请求会返回 409 `CONFLICT`。

## 参考

共五个操作。示例使用 `<API_KEY>` 和虚构的 ID。

### 报价

`GET /quote`

返回一次兑换的金额，不创建任何内容。报价不会被锁定，也不检查 Pix 的最低金额和上限：报价过的金额在创建订单时仍可能被拒绝。查询参数中传两个币种和两个金额之一。

**请求参数**

| 参数 | 位置 | 必填 |
| --- | --- | --- |
| `source_currency` | 查询参数 | 是 |
| `target_currency` | 查询参数 | 是 |
| `source_amount_cents` | 查询参数 | 条件必填 |
| `target_amount_cents` | 查询参数 | 条件必填 |

**请求**

```bash
curl --request GET "https://bytemax.exchange/api/v1/quote?source_currency=BRL&target_currency=CNY&source_amount_cents=10000" \
  --header "Authorization: Bearer <API_KEY>"
```

**响应 200**

```json
{
  "source_currency": "BRL",
  "source_amount_cents": "10000",
  "target_currency": "CNY",
  "target_amount_cents": "12500"
}
```

### 创建订单

`POST /orders`

创建订单并返回支付链接。需要 `Idempotency-Key`。

**请求参数**

| 参数 | 位置 | 必填 |
| --- | --- | --- |
| `Idempotency-Key` | 请求头 | 是 |

**JSON 正文**

| 字段 | 类型 | 必填 | 说明 |
| --- | --- | --- | --- |
| `source_currency` | `string` | 是 | 付款人支付的币种。目前仅支持 `BRL`。 |
| `target_currency` | `string` | 是 | 收款币种：`CNY`或`USD`，必须与钱包币种相同。 |
| `source_amount_cents` | `string` | 条件必填 | 付款人支付的金额，以 BRL 的分为单位。 |
| `target_amount_cents` | `string` | 条件必填 | 您收到的金额，以 CNY或USD 的分为单位。 |

`source_amount_cents` 和 `target_amount_cents` 两者只能传其一，订单会计算另一个。

**请求**

```bash
curl --request POST "https://bytemax.exchange/api/v1/orders" \
  --header "Authorization: Bearer <API_KEY>" \
  --header "Idempotency-Key: order-8412" \
  --header "Content-Type: application/json" \
  --data '{"source_currency":"BRL","source_amount_cents":"10000","target_currency":"CNY"}'
```

**响应 201**

```json
{
  "id": "ord_example",
  "status": "pending_payment",
  "source_currency": "BRL",
  "source_amount_cents": "10000",
  "target_currency": "CNY",
  "target_amount_cents": "12500",
  "refunded_source_amount_cents": "0",
  "blocked_source_amount_cents": "0",
  "payment": {
    "url": "https://bytemax.exchange/pt-br/payment/0123456789abcdef0123456789abcdef",
    "pix_copy_paste": "00020101021226820014br.gov.bcb.pix2560pix.example/qr/v2/0123456789abcdef0123456789abcdef5204000053039865406100.005802BR5907BYTEMAX6009SAO PAULO62070503***6304ABCD"
  },
  "created_at": "2026-09-10T13:05:00.000Z",
  "expires_at": "2026-09-12T13:05:00.000Z"
}
```

### 查询订单

`GET /orders/{id}`

订单的当前状态和金额。`refunded_source_amount_cents` 是已退还给付款人的金额，`blocked_source_amount_cents` 是因争议被冻结的金额，均以 BRL 的分为单位。`expires_at` 是付款期限的截止时间，即 `created_at` 之后 48 小时：届时仍为 `pending_payment` 的订单将无法再支付，并变为 `expired`。此后该字段仍保留在订单中；要判断订单是否已支付，请查看 `status`。

**请求参数**

| 参数 | 位置 | 必填 |
| --- | --- | --- |
| `id` | 路径 | 是 |

**请求**

```bash
curl --request GET "https://bytemax.exchange/api/v1/orders/ord_example" \
  --header "Authorization: Bearer <API_KEY>"
```

**响应 200**

```json
{
  "id": "ord_example",
  "status": "pending_payment",
  "source_currency": "BRL",
  "source_amount_cents": "10000",
  "target_currency": "CNY",
  "target_amount_cents": "12500",
  "refunded_source_amount_cents": "0",
  "blocked_source_amount_cents": "0",
  "payment": {
    "url": "https://bytemax.exchange/pt-br/payment/0123456789abcdef0123456789abcdef",
    "pix_copy_paste": "00020101021226820014br.gov.bcb.pix2560pix.example/qr/v2/0123456789abcdef0123456789abcdef5204000053039865406100.005802BR5907BYTEMAX6009SAO PAULO62070503***6304ABCD"
  },
  "created_at": "2026-09-10T13:05:00.000Z",
  "expires_at": "2026-09-12T13:05:00.000Z"
}
```

### 创建退款

`POST /orders/{id}/refunds`

退还已收款项的部分或全部，金额以 CNY或USD 的分为单位。需要 `Idempotency-Key`。只有 `completed` 状态的订单可以退款，同一时间只能有一笔退款在处理，并且您的 CNY或USD 余额必须足以支付该金额。退款处理中时响应 202，已结束时响应 200：请查看 `status`。

**请求参数**

| 参数 | 位置 | 必填 |
| --- | --- | --- |
| `id` | 路径 | 是 |
| `Idempotency-Key` | 请求头 | 是 |

**JSON 正文**

| 字段 | 类型 | 必填 | 说明 |
| --- | --- | --- | --- |
| `target_amount_cents` | `string` | 是 | 退款金额，以 CNY或USD 的分为单位，从您的余额中扣除。付款人按相同比例收回所付的 BRL，四舍五入到分（见响应中的 `source_amount_cents`）。 |

**请求**

```bash
curl --request POST "https://bytemax.exchange/api/v1/orders/ord_example/refunds" \
  --header "Authorization: Bearer <API_KEY>" \
  --header "Idempotency-Key: refund-8412-1" \
  --header "Content-Type: application/json" \
  --data '{"target_amount_cents":"2500"}'
```

**响应 202**

```json
{
  "id": "9007199254741001",
  "order_id": "ord_example",
  "status": "processing",
  "source_currency": "BRL",
  "source_amount_cents": "2000",
  "target_currency": "CNY",
  "target_amount_cents": "2500",
  "created_at": "2026-09-10T13:05:00.000Z",
  "updated_at": "2026-09-10T13:05:00.000Z"
}
```

### 查询退款

`GET /orders/{id}/refunds/{refund_id}`

由您的账户通过 API 或控制台发起的退款的当前状态。

**请求参数**

| 参数 | 位置 | 必填 |
| --- | --- | --- |
| `id` | 路径 | 是 |
| `refund_id` | 路径 | 是 |

**请求**

```bash
curl --request GET "https://bytemax.exchange/api/v1/orders/ord_example/refunds/9007199254741001" \
  --header "Authorization: Bearer <API_KEY>"
```

**响应 200**

```json
{
  "id": "9007199254741001",
  "order_id": "ord_example",
  "status": "processing",
  "source_currency": "BRL",
  "source_amount_cents": "2000",
  "target_currency": "CNY",
  "target_amount_cents": "2500",
  "created_at": "2026-09-10T13:05:00.000Z",
  "updated_at": "2026-09-10T13:05:00.000Z"
}
```

## 错误与限制

每个错误响应都包含 `code` 和 `message`。请根据 `code` 编写处理逻辑：`message` 是供您记录日志的文本，可能会变化。请保留 `X-Request-Id` 响应头：联系客服时它用于识别这次调用。未知字段和重复参数会以 400 拒绝。维护或故障期间，响应可能不带 `code`：请把任何 5xx 或非 JSON 的正文视为临时故障。

```json
{
  "code": "INVALID_INPUT",
  "message": "Use source_currency BRL and the supplier wallet currency, CNY or USD."
}
```

### HTTP 状态码

| HTTP 状态码 | 何时发生 |
| --- | --- |
| 400 | 数据无效、金额超出限额或不支持的货币对。 |
| 401 | API 密钥缺失或无效。 |
| 403 | IP 地址不在您的允许列表中，或您的账户无权执行此操作。 |
| 404 | 找不到订单、退款、Webhook 或事件，或 API 中不存在该地址。 |
| 409 | 请求与当前状态冲突：幂等密钥重复使用但正文不同或仍在使用中、订单尚不能退款、仍有退款在处理中，或已存在相同 URL 的 Webhook。 |
| 410 | 订单通过已停用的方式支付，无法通过 API 退款。 |
| 413 | 正文超过 1 MB。 |
| 415 | `POST` 或 `PATCH` 未带 `Content-Type: application/json`，即使正文是 `{}`。 |
| 429 | 超过调用限制。请等待 `Retry-After` 指定的时间后再试。 |
| 500 | 意外故障。请几秒后重试；创建类请求请使用相同的 `Idempotency-Key`。 |
| 503 | 服务不可用。请几秒后重试，并逐次延长等待时间。 |

### 错误代码

以下为最常见的代码。也可能出现其他代码：未知代码若状态码为 4xx，请视为重试也不会通过的拒绝；若为 5xx，请视为临时故障。

- `WALLET_CURRENCY_MISMATCH` (HTTP 409): 目标币种必须与您账户的余额币种一致。
- `UNAUTHORIZED` (HTTP 401): API 密钥缺失、格式错误或已失效。请检查 `Authorization: Bearer <API_KEY>` 请求头；如果您创建了新密钥，旧密钥即停止工作。
- `API_IP_NOT_ALLOWED` (HTTP 403): 调用来自允许的 IP 列表之外的地址。请在 [API](https://bytemax.exchange/zh-CN/api) 页面添加您服务器的地址。
- `USER_BLOCKED` (HTTP 403): 您的账户已被封锁或关闭。[联系客服](https://bytemax.exchange/zh-CN/support)。
- `KYC_KYB_REQUIRED` (HTTP 403): 您的账户暂时无法创建订单。请在控制面板中完成身份验证；如果已经审核通过，请联系客服。
- `INVALID_INPUT` (HTTP 400): 请求格式错误：某个字段、参数或请求头缺失、未知、重复或无效；正文不是 JSON；货币对不是 BRL → CNY或USD；或金额超过 `"100000000"`（1,000,000.00）。`message` 会说明需要修正的内容。金额必须是大于零的纯数字字符串，例如 `"10000"`。
- `JSON_REQUIRED` (HTTP 415): 每个 `POST` 和 `PATCH` 都要带 `Content-Type: application/json`，即使正文是 `{}`。
- `ORDER_MINIMUM_NOT_MET` (HTTP 400): 付款人支付的金额低于 R$ 30.00 的最低限额。只传 CNY或USD 金额时同样适用。
- `PIX_RECEIPT_LIMIT_EXCEEDED` (HTTP 400): 付款人支付的金额超过当前的 Pix 上限，具体数值见 `message`。请用更低的金额重新创建订单，可以继续使用相同的 `Idempotency-Key`。
- `IDEMPOTENCY_CONFLICT` (HTTP 409): 该密钥已用于正文不同的请求。新的操作请使用新密钥。
- `CONFLICT` (HTTP 409): 使用该密钥的订单仍在创建中。请等待几秒，再使用相同的 `Idempotency-Key` 重试。
- `ORDER_NOT_FOUND` (HTTP 404): 您的账户中没有该 ID 的订单。已过期的订单会在创建 6 个月后移除。
- `ORDER_NOT_REFUNDABLE` (HTTP 409): 订单尚未支付、已过期或已取消。只有 `completed` 状态的订单可以退款。
- `REFUND_NOT_FOUND` (HTTP 404): 该订单下没有此 ID 的退款。只显示由您的账户发起的退款。
- `REFUND_AMOUNT_NOT_AVAILABLE` (HTTP 400): 金额超过仍可退款的部分：订单的一部分已经退款，或因争议被冻结。
- `REFUND_INVALID_AMOUNT_OR_RATIO` (HTTP 400): 金额过小，无法换算为 BRL 退款。
- `REFUND_IN_PROGRESS` (HTTP 409): 该订单的另一笔退款尚未结束。请等它进入最终状态。
- `INSUFFICIENT_BALANCE` (HTTP 400): 您的 CNY或USD 余额不足以支付这笔退款。
- `PAYMENT_METHOD_RETIRED` (HTTP 410): 订单通过已停用的方式支付。如需退款，请联系客服。
- `NOT_FOUND` (HTTP 404): API 中不存在该地址或方法。没有列出订单或取消订单的操作。
- `PAYLOAD_TOO_LARGE` (HTTP 413): 正文超过 1 MB。
- `SECURITY_BLOCKED` (HTTP 403): 安全过滤器因 URL 或正文中的异常字符序列而拒绝了请求。立即重复同一请求会收到 429 `RATE_LIMIT_EXCEEDED`。如果您的数据属正常内容，请联系客服并提供 `X-Request-Id`。
- `RATE_LIMIT_EXCEEDED` (HTTP 429): 超过调用限制。请等待 `Retry-After` 指定的时间。
- `SERVICE_UNAVAILABLE` (HTTP 503): 操作所需的服务暂时不可用，或兑换已暂停。请几秒后使用相同的 `Idempotency-Key` 重试，并逐次延长等待时间。
- `INTERNAL_ERROR` (HTTP 500): 意外故障。请几秒后使用相同的 `Idempotency-Key` 重试。如果问题持续，请联系客服并提供 `X-Request-Id`。

### 调用限制

每个 IP 地址每分钟最多向 ByteMax 发送 300 次请求（API 和网站合计）。`GET /quote` 每个账户每分钟 300 次，创建退款每个账户每分钟 30 次（包括在控制台发起的退款）。收到 429 时，请等待 `Retry-After` 指定的秒数后再重试。报价和退款的响应还会在下面的 `RateLimit-*` 响应头中报告账户限额；`RateLimit-Reset` 表示距离窗口重新开始的秒数。跟踪订单请使用 Webhook，而不是每隔几秒查询一次。

```http
HTTP/1.1 429 Too Many Requests
Retry-After: 60
RateLimit-Policy: 300;w=60
RateLimit-Limit: 300
RateLimit-Remaining: 0
RateLimit-Reset: 60
```

## 集成摘要

一笔已支付订单的完整流程：

1. **创建订单**
   调用 `POST /orders`，为这笔购买使用一个新的 `Idempotency-Key`。

2. **保存 `id`**
   在您的系统中将订单 `id` 与这笔购买一起保存。

3. **将付款人重定向到 `payment.url`**
   或在您的结账页面显示 `payment.pix_copy_paste`。

4. **接收 `order.completed`**
   在您的 [Webhook](https://bytemax.exchange/zh-CN/docs/webhooks) 中验证签名，并保存事件 `id`。

5. **查询 `GET /orders/{id}`**
   事件仅作通知；查询返回当前状态。

6. **`status` 为 `completed` 时交付**
   每笔订单只交付一次，即使事件重复送达。

集成有疑问？[联系客服](https://bytemax.exchange/zh-CN/support)。
