# 服务端接入

厂商后端保管应用密钥。浏览器先请求厂商后端，由厂商后端向 CS2View 申请短期进入凭证。凭证通过 SDK 传给 iframe，不放在 URL、日志或持久化存储中。

## 申请进入凭证

```js
// 在你的后端运行；先验证本站用户、SKU、档位及允许的来源。
const response=await fetch('https://api.cs2view.com/v1/commercial/grants',{
  method:'POST',
  headers:{
    'Authorization':`Bearer ${process.env.CS2VIEW_APP_KEY}`,
    'Content-Type':'application/json',
    'Idempotency-Key':request.openId
  },
  body:JSON.stringify({
    openId:request.openId,
    parentOrigin:'https://your-company.example',
    tier:'inspect', // 由你的后端确定，不能盲信浏览器请求
    item:{inspect:trustedInspectLink} // 从已验证商品取得检视链接
  }),
  signal:AbortSignal.timeout(10000)
});
const result=await response.json();
// 成功后只将 grant、openId、expiresAt、tier 返回给本站 SDK。
```

该接口只接受服务端请求，不接受带浏览器 Origin 的长期密钥请求。后端不要转发任意用户提供的 API URL，也不要把自己的密钥回传给浏览器。

## 请求与响应

| 字段 | 含义 |
| --- | --- |
| openId | 本次 iframe 文档或 load 产生的 UUID；重试保持不变 |
| parentOrigin | 精确来源，例如 https://your-company.example，不含路径 |
| tier | inspect、first_person、third_person 或 editor |
| item | 检视档只接受 inspect；editor 接受 query 或 inspect，二选一 |
| Idempotency-Key | 厂商请求编号，建议使用 openId |

```json
{
  "grant":"grant_<短期凭证>",
  "openId":"00000000-0000-4000-8000-000000000001",
  "expiresAt":"2026-10-06T12:02:00.000Z",
  "tier":"inspect"
}
```

未兑换凭证默认 120 秒有效；兑换成功后的 visit 没有时长限制，不设置倒计时。重复申请相同编号、相同参数会得到相同凭证；改变物品或档位返回 `IDEMPOTENCY_CONFLICT`。过期后不要在后台无限重试：提示用户重新进入，以新的访问编号申请。

## 厂商必须做的校验

验证本站用户或明确的访客策略；把商品、档位和来源与自己的业务配置绑定；增加每用户/IP 的频率与每日额度限制。不要把申请凭证接口做成任何人都能使用你的余额的公共代理。

申请凭证不扣费。余额等条件会在申请及兑换时检查，最终扣费在首次批准进入的事务中完成。
