﻿# 广告主接口说明（MVP V0.2）

> 适用范围：第一版只覆盖广告主关键词协作和推广数据拉取。  
> 调用双方：平台、广告主。  
> 目标：让平台可以把达人/用户/关键词传给广告主创建关键词，并拉取广告主实时维护的有效推广明细，用于归因和结算。

---

## 1. MVP 必须补充并锁定的点

1. **幂等 requestId 必须要有**：防止网络重试、平台重复提交、广告主重复处理导致关键词重复创建或数据重复入库。
2. **广告主关键词 ID 必须返回**：平台必须保存 `clientItemId / keyword / projectId / creatorId / advertiserKeywordId` 映射，否则无法把推广明细归因到达人。
3. **关键词唯一口径必须锁定**：同一广告主项目内关键词唯一；重复直接驳回，并返回失败原因。
4. **推广数据唯一 ID 必须锁定**：平台按 `dataId` 去重；广告主侧不得复用同一个 `dataId` 表达不同转化。
5. **修正数据必须用新增明细**：不要改原记录；新增一条 `recordType=correction`，填写 `originalDataId` 和修正原因。
6. **结算依据说明**：结算依据就是“平台最终用哪类广告主数据生成达人收益订单”。MVP 建议以广告主返回的有效推广明细为准，平台按项目内配置的 CPA/CPS 金额或比例计算。
7. **安全字段必须统一**：所有开放接口统一使用 API Key、时间戳、随机串、签名、请求 ID；用户敏感数据加密传输。

---

## 2. 通用安全规范

### 2.1 请求头

| Header | 必填 | 说明 |
|---|---:|---|
| X-Api-Key | 是 | 分配给调用方的 API Key |
| X-Timestamp | 是 | 毫秒时间戳，用于防重放 |
| X-Nonce | 是 | 随机字符串，用于防重放 |
| X-Signature | 是 | 签名，建议 HMAC-SHA256 |
| X-Request-Id | 是 | 请求唯一 ID，用于幂等和排查 |
| X-Version | 是 | 接口版本，如 `2026-09-08` |

### 2.2 签名建议

- 签名原文：`method + path + timestamp + nonce + bodyHash`
- 签名算法：HMAC-SHA256
- 时间戳允许误差：建议 5 分钟
- 平台与广告主双方都要配置 IP 白名单
- 用户手机号、设备号、账号标识等敏感数据必须加密后传输

### 2.3 通用返回

```json
{
  "code": 0,
  "message": "success",
  "requestId": "REQ-20260908-001"
}
```

---

## 3. 关键词同步接口

### 3.1 接口说明

平台把用户数据、达人信息、项目和关键词同步给广告主。广告主收到后先入库，返回受理成功；实际查重、创建、审核结果通过回调返回。

- 调用方向：平台 → 广告主
- URL：`POST /open-api/advertiser/keywords/sync`
- 支持：单条、批量
- 处理方式：异步创建 + 异步回调

### 3.2 请求字段

| 字段 | 必填 | 类型 | 说明 |
|---|---:|---|---|
| requestId | 是 | string | 本次请求唯一 ID，必须幂等 |
| batchId | 是 | string | 批次 ID，单条也生成批次 |
| projectId | 是 | string | 平台项目 ID |
| advertiserProjectId | 是 | string | 广告主项目 ID |
| items | 是 | array | 关键词明细 |
| items[].clientItemId | 是 | string | 平台关键词明细 ID |
| items[].keyword | 是 | string | 关键词，项目内唯一 |
| items[].creatorId | 是 | string | 达人 ID |
| items[].creatorName | 否 | string | 达人昵称 |
| items[].userData | 是 | object | 加密后的用户数据 |
| items[].userData.userKey | 是 | string | 加密用户标识 |
| items[].userData.phoneEnc | 否 | string | 加密手机号 |
| items[].remark | 否 | string | 备注 |

### 3.3 同步请求示例

```json
{
  "requestId": "REQ-KW-20260908-001",
  "batchId": "BATCH-KW-20260908-01",
  "projectId": "P20260908001",
  "advertiserProjectId": "ADV-PROJ-1001",
  "items": [
    {
      "clientItemId": "KW-ITEM-89021",
      "keyword": "短剧免费看入口",
      "creatorId": "C10231",
      "creatorName": "阿木剪辑",
      "userData": {
        "userKey": "enc:91c2****7a10",
        "phoneEnc": "enc:xxxx"
      }
    }
  ]
}
```

### 3.4 同步响应示例

```json
{
  "code": 0,
  "message": "accepted",
  "requestId": "REQ-KW-20260908-001",
  "batchId": "BATCH-KW-20260908-01",
  "acceptedCount": 1,
  "failedCount": 0
}
```

---

## 4. 关键词审核结果回调接口

### 4.1 接口说明

广告主在后台完成查重、创建和审核后，把结果回调平台。

- 调用方向：广告主 → 平台
- URL：`POST /open-api/platform/keywords/callback`

### 4.2 请求字段

| 字段 | 必填 | 类型 | 说明 |
|---|---:|---|---|
| requestId | 是 | string | 回调请求唯一 ID，必须幂等 |
| batchId | 是 | string | 原同步批次 ID |
| projectId | 是 | string | 平台项目 ID |
| advertiserProjectId | 是 | string | 广告主项目 ID |
| reviewTime | 是 | string | 审核时间 |
| results | 是 | array | 审核结果 |
| results[].clientItemId | 是 | string | 平台关键词明细 ID |
| results[].advertiserKeywordId | 是 | string | 广告主关键词 ID |
| results[].keyword | 是 | string | 关键词 |
| results[].status | 是 | string | `approved/rejected/disabled` |
| results[].rejectReason | 否 | string | 驳回时必填 |
| results[].disableReason | 否 | string | 停用时建议填写 |

### 4.3 回调示例

```json
{
  "requestId": "CALLBACK-KW-20260908-004",
  "batchId": "BATCH-KW-20260908-01",
  "projectId": "P20260908001",
  "advertiserProjectId": "ADV-PROJ-1001",
  "reviewTime": "2026-09-08 10:45:00",
  "results": [
    {
      "clientItemId": "KW-ITEM-89021",
      "advertiserKeywordId": "ADV-KW-778120",
      "keyword": "短剧免费看入口",
      "status": "approved"
    }
  ]
}
```

---

## 5. 关键词状态查询接口

### 5.1 接口说明

回调失败或状态不一致时，平台可以兜底查询广告主关键词状态。

- 调用方向：平台 → 广告主
- URL：`GET /open-api/advertiser/keywords/status`

### 5.2 请求参数

| 参数 | 必填 | 说明 |
|---|---:|---|
| advertiserKeywordId | 是 | 广告主关键词 ID |
| projectId | 否 | 平台项目 ID |
| advertiserProjectId | 否 | 广告主项目 ID |
| keyword | 否 | 关键词 |

### 5.3 返回字段

| 字段 | 必填 | 说明 |
|---|---:|---|
| advertiserKeywordId | 是 | 广告主关键词 ID |
| status | 是 | `pending/approved/rejected/disabled` |
| rejectReason | 否 | 驳回原因 |
| updateTime | 是 | 更新时间 |

---

## 6. 推广数据拉取接口

### 6.1 接口说明

平台主动从广告主拉取实时有效推广明细，用于归因结算。

- 调用方向：平台 → 广告主
- URL：`GET /open-api/advertiser/promotion-data`
- 拉取方式：定时 + 手动
- 数据范围：增量明细
- 数据状态：广告主只返回有效数据

### 6.2 请求参数

| 参数 | 必填 | 说明 |
|---|---:|---|
| requestId | 是 | 请求唯一 ID |
| projectId | 是 | 平台项目 ID |
| advertiserProjectId | 是 | 广告主项目 ID |
| fromTime | 是 | 增量开始时间 |
| toTime | 是 | 增量结束时间 |
| cursor | 否 | 分页游标 |
| pageSize | 否 | 每页数量，建议最大 500 |
| keyword | 否 | 关键词筛选 |
| creatorId | 否 | 达人 ID 筛选 |

### 6.3 返回字段

| 字段 | 必填 | 说明 |
|---|---:|---|
| code | 是 | 返回码 |
| message | 是 | 返回信息 |
| requestId | 是 | 请求 ID |
| nextCursor | 否 | 下一页游标 |
| hasMore | 是 | 是否还有更多 |
| dataList | 是 | 明细列表 |

### 6.4 明细字段

| 字段 | 必填 | 说明 |
|---|---:|---|
| dataId | 是 | 数据唯一 ID，平台按此去重 |
| projectId | 是 | 平台项目 ID |
| advertiserProjectId | 是 | 广告主项目 ID |
| advertiserKeywordId | 是 | 广告主关键词 ID |
| keyword | 是 | 关键词 |
| creatorId | 是 | 达人 ID |
| creatorName | 否 | 达人昵称 |
| conversionType | 是 | 转化类型，如 `new_user/order` |
| userKey | 否 | 加密用户标识 |
| conversionTime | 是 | 转化时间 |
| amount | 是 | 金额，CPA 可为单价，CPS 可为订单金额或佣金计算基数 |
| recordType | 是 | `normal/correction` |
| originalDataId | 修正必填 | 原始数据 ID |
| correctionReason | 修正必填 | 修正原因 |
| updateTime | 是 | 广告主侧更新时间 |

### 6.5 返回示例

```json
{
  "code": 0,
  "message": "success",
  "requestId": "REQ-DATA-20260908-021",
  "nextCursor": "cur_20260908_1040",
  "hasMore": false,
  "dataList": [
    {
      "dataId": "DATA-20260908-000928",
      "projectId": "P20260908001",
      "advertiserProjectId": "ADV-PROJ-1001",
      "advertiserKeywordId": "ADV-KW-778120",
      "keyword": "短剧免费看入口",
      "creatorId": "C10231",
      "creatorName": "阿木剪辑",
      "conversionType": "new_user",
      "userKey": "enc:91c2****7a10",
      "conversionTime": "2026-09-08 10:41:12",
      "amount": "18.00",
      "recordType": "normal",
      "updateTime": "2026-09-08 10:41:30"
    }
  ]
}
```

---

## 7. 状态枚举

### 7.1 关键词状态

| 状态 | 说明 |
|---|---|
| pending | 待审核 |
| approved | 审核通过 |
| rejected | 已驳回 |
| disabled | 已停用 |

### 7.2 推广明细记录类型

| 类型 | 说明 |
|---|---|
| normal | 正常明细 |
| correction | 修正明细 |

### 7.3 转化类型 MVP 建议

| 类型 | 说明 |
|---|---|
| new_user | 拉新 |
| active_user | 拉活 |
| order | 订单 |

---

## 8. MVP 不做范围

- 不做子账号和复杂权限矩阵
- 不做导出中心
- 不做自动重试平台
- 不做关键词更新、删除、重建
- 不做独立的无效数据接口，广告主只返回有效数据
- 不做群链路、作品回填、充值分佣独立回传
