> This page is for Afterpay Online Developer, version Chinese.
> For other versions, use one of these documentation indexes:
> - Main (default): https://developers.afterpay.com/afterpay-online-developer/main/llms.txt
> - v1: https://developers.afterpay.com/afterpay-online-developer/v-1/llms.txt
> - Chinese: https://developers.afterpay.com/afterpay-online-developer/chinese/llms.txt

> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://developers.afterpay.com/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://developers.afterpay.com/_mcp/server.

# 上传和获取文件

本节包含以下主题：

* [上传文件](#上传文件)
* [获取文件](#获取文件)
* [错误](#错误)
* [Diffie-Hellman 密钥交换](#密钥交换)

## 上传文件

> **Warning**
>
> 最大上传文件大小为 10MB。

文件的商户 ID 将与上传的文件一起保存。

> **Info**
>
> 文件只能由上传者获取。

Afterpay 支持的文件类型有：

* Gif
* Pdf
* Jpeg
* Png

### 上传文件 - 端点

```
POST https://{afterpay_global_url}/v2/disputes/files
```

#### 连接超时

| 超时类型    | 时间（秒） |
| ------- | ----- |
| `OPEN`  | 10    |
| `Read ` | 20    |

#### 请求头

| 头部           | 类型     | 示例                                                                                                                   |
| ------------ | ------ | -------------------------------------------------------------------------------------------------------------------- |
| `User-Agent` | String | `MyAfterpayModule/1.0.0 (E-Commerce Platform Name/1.0.0; PHP/7.0.0; Merchant/60032000) https://merchant.example.com` |

| 头部             | 类型     | 默认值              |
| -------------- | ------ | ---------------- |
| `Accept`       | String | application/json |
| `Content-Type` | String | application/json |

### 请求参数

| 字段名称       | 数据类型   | 状态 | 描述                               |
| ---------- | ------ | -- | -------------------------------- |
| `file`     | File   | 必需 | 您要上传的文件。                         |
| `fileType` | String | 必需 | 文件类型，我们目前只支持 `dispute_evidence`。 |

### 响应

| 字段名称        | 数据类型     | 描述                                             |
| ----------- | -------- | ---------------------------------------------- |
| `id`        | String   | 文件的 ID 令牌。                                     |
| `createdAt` | Datetime | 表示文件上传时间的时间戳。（格式：2022-04-19T02:58:44.086829）   |
| `expiresAt` | Datetime | 表示上传文件过期时间的时间戳。（格式：2022-04-19T02:58:44.086829） |

### 响应示例

| 字段名称        | 数据类型     | 示例                         |
| ----------- | -------- | -------------------------- |
| `id`        | String   | fi\_7wvZBQqWzoPGLxvaMkpTjX |
| `createdAt` | Datetime | 2023-08-18T02:05:23.121893 |
| `expiresAt` | Datetime | 2023-08-18T02:05:23.121893 |

## 获取文件

### 获取文件 - 端点

```
GET https://{afterpay_global_url}/v2/disputes/files/{id}
```

#### 连接超时

| 超时类型    | 时间（秒） |
| ------- | ----- |
| `OPEN`  | 10    |
| `Read ` | 20    |

#### 请求头

| 头部           | 类型     | 示例                                                                                                                     |
| ------------ | ------ | ---------------------------------------------------------------------------------------------------------------------- |
| `User-Agent` | String | `MyAfterpayModule/1.0.0 (E-Commerce Platform Name/1.0.0; PHP/7.0.0; Merchant/60032000) <https://merchant.example.com>` |

| 头部       | 类型     | 默认值              |
| -------- | ------ | ---------------- |
| `Accept` | String | application/json |

### 请求参数

| 字段名称 | 数据类型   | 状态 | 描述            |
| ---- | ------ | -- | ------------- |
| `id` | String | 必需 | 要获取的文件的文件 ID。 |

### 响应

| 字段名称        | 数据类型     | 描述                                           |
| ----------- | -------- | -------------------------------------------- |
| `url`       | String   | 要获取的文件的链接。                                   |
| `expiresAt` | Datetime | 表示链接过期时间的时间戳。（格式：2022-04-19T02:58:44.086829） |

### 响应示例

| 字段名称        | 数据类型     | 示例                                                                                                                                              |
| ----------- | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------- |
| `url`       | String   | [https://dispute-attachment.s3.amazonaws.com/fi\_7GciehSJnhRdUF9acxsB63](https://dispute-attachment.s3.amazonaws.com/fi_7GciehSJnhRdUF9acxsB63) |
| `expiresAt` | Datetime | 2023-08-18T02:05:23.121893                                                                                                                      |

## 错误

| 错误代码                           | 描述                                                |
| ------------------------------ | ------------------------------------------------- |
| 401 - Unauthorized             | 无效的商户凭证。                                          |
| 404 - Not Found                | 找不到商户对应的实体。                                       |
| 412 - Precondition Failed      | 争议案例的无效操作，或退款金额大于可退款金额。                           |
| 413 - Request Entity Too Large | 上传的文件太大。必须小于 10 MB。                               |
| 415 - Unsupported Media Type   | Afterpay 不支持上传文件的文件类型。必须是以下之一：Gif、Pdf、Jpeg 或 Png。 |
| 422 - Unprocessable Entity     | 争议 API 请求中的参数无效。                                  |
| 429 - Too Many Requests        | 短时间内请求太多，稍后重试。                                    |

## 密钥交换

### Diffie-Hellman 密钥交换

**Wiki 页面：** [https://wiki.openssl.org/index.php/Diffie\_Hellman](https://wiki.openssl.org/index.php/Diffie_Hellman)

### 依赖

Openssl 版本 = LibreSSL 2.8.3

### 密钥交换过程中的步骤

假设 Alice 和 Bob 正在进行密钥交换，Alice 在公司 A 工作，Bob 在公司 B 工作。

1. Alice 在当前目录中生成一个 pem 文件，其中包含 `DH` 算法中的参数 `g` 和 `p`。

   ```
   openssl genpkey -genparam -algorithm DH -out dhp1.pem  -pkeyopt      dh_paramgen_prime_len:2048
   ```

2. Alice 公开将 `dhp1.pem` 文件发送给 Bob。

3. Alice 在她的笔记本电脑上生成私钥，并导出公钥。
   ```
   openssl genpkey -paramfile dhp1.pem -out dhkey1.pem
   openssl pkey -in dhkey1.pem -pubout -out dhpub1.pem
   ```

4. Bob 在他的笔记本电脑上生成私钥。
   ```
   openssl genpkey -paramfile dhp1.pem -out dhkey2.pem
   openssl pkey -in dhkey2.pem -pubout -out dhpub2.pem
   ```

5. Alice 和 Bob 公开交换公钥，Alice 获得 `dhpub2.pem` 文件，Bob 获得 `dhpub1.pem` 文件。

6. Alice 生成密钥。

   ```
   openssl pkeyutl -derive -inkey dhkey1.pem -peerkey dhpub2.pem -out secret1
   ```

7. Bob 生成密钥。
   ```
   openssl pkeyutl -derive -inkey dhkey2.pem -peerkey dhpub1.pem -out secret2
   ```

8. 现在 Alice 和 Bob 应该有相同的密钥，这是完全安全的。`(secret1 == secret2)`

### 加密和解密

1. Alice 想要安全地向 Bob 发送文件。她使用 `secret1` 加密文件。假设原始文件名为 text。
   ```
   openssl enc -aes-256-cbc -pass file:secret1 -in text -out     text.enc -p
   ```
2. Alice 公开将加密文件 `text.enc` 发送给 Bob。
3. Bob 使用 `secret2` 解密文件。
   ```
   openssl enc -aes-256-cbc -pass file:secret2 -in text.enc -out        text.origin -p -d
   ```