# 🎓 SheerID 全渠道开放 API & 通用卡密 (CDKey) 官方对接白皮书 (v3.0)
> **适用对象**:发卡网店主、Telegram / Discord / QQ 机器人开发者、独立核销站长、B2B 渠道代理商、自动化脚本工作室
> **在线交互式文档与调试沙盒**:`https://www.geminipass.si/api-docs`
> **终端买家零代码自助核销页**:`https://www.geminipass.si/` (支持带参自动填卡:`/?cdkey=VIP1-XXXX`)
> **VIP 实时通过率看板**:`https://www.geminipass.si/pass`
> **大客户独享 API Key 申请与阶梯批发客服 (Telegram)**:`https://t.me/jdkdai` (`@jdkdai`)
---
## 🌟 一、 三种合作与接入模式全景对比(按需任选,也可混合使用)
本平台同时支持 **「🎫 通用卡密 (CDK) 直连(发卡网自助购买)」** 与 **「🔑 固定开发者 API Key (`sk_api_...`) 总额度池(定向合作开通,按量阶梯议价)」** 两大底层体系。无论您的下游是**零代码卖卡**,还是**自己开发网站/机器人并分发他自己的卡密**,均能无缝接入:
| 对比维度 | 🟢 模式一:免开发网页核销 (`/redeem`) | 🎫 模式二:CDK 卡密直连 API (`/api/v1/cdkey/*`) | 🔑 模式三:固定 API Key 总额度池 (`/api/open/v1/*`) |
| :--- | :--- | :--- | :--- |
| **获取方式** | 直接在发卡网 24h 自助购买 `CDK` | 直接在发卡网 24h 自助购买 `CDK` | **定向开放**:直接联系负责人按采购量(100 / 500 / 1000+ 档)阶梯议价开通 |
| **核心凭证** | 通用卡密 `CDK`(如 `VIP1-8A9F-3C2D`) | 通用卡密 `CDK`(1次卡 / 5次卡 / 100次批发卡均可) | 固定开发者密钥 `sk_api_xxxxxxxxxxxxxxxxxx` |
| **是否需要写代码** | ❌ **完全不需要**(0 代码即买即卖) | ⚡ **极简对接**(卡密本身就是临时 API Token) | 🛠️ **标准 B2B 对接**(适合自建平台 / 机器人 / 独立发卡) |
| **能否自己造卡/分发下级** | 直接转卖上游生成的 `CDK` 卡密 | 直接使用上游 `CDK`,或让客户在您前端填上游 `CDK` | ✅ **完全自由!** 您可在自己数据库随便生成自己的卡密、会员积分或次卡,后端统一用您的 `sk_api_...` 扣减总额度池 |
| **充值与续费方式** | 发卡网随时自助提卡 / 拿货 | 用完在发卡网买新 `CDK` 即可 | 1️⃣ 联系负责人按需求量档位阶梯价直充额度
2️⃣ 调 `POST /api/open/v1/redeem` 用发卡网购买的 `CDK` 自助充值 |
| **扣费与退费铁律** | **100% 只扣成功**:失败/死链/风控熔断秒退回原卡密 | **100% 只扣成功**:失败/死链/风控熔断秒退回原卡密 | **100% 只扣成功**:失败/死链/风控熔断秒退回 `API Key` 余额 |
| **数据安全与白标** | 100% 纯白标无痕页面(无任何上游品牌/联系方式) | 100% 纯黑盒 JSON(绝不暴露内部学校、模板、学生档案) | 100% 纯黑盒 JSON(绝不暴露内部学校、模板、学生档案) |
---
## 🛡️ 二、 核心商业承诺:【100% 只扣成功 (Success-Only Billing)】
无论是使用 **`CDK` 卡密** 还是 **固定 `API Key (sk_api_...)`**,系统底层均采用金融级分布式原子事务,严格执行 **「只扣成功」** 铁律:
1. **提单预冻结 (`QUEUED` / `PROCESSING`)**:
- 每次提交 1 条有效 SheerID 验证链接,系统原子预冻结 `1` 次可用额度。
- **幂等防重保护**:若同一个 `verificationId`(24位十六进制ID)当前已在队列或正在处理中,重复提交会直接返回原任务 `taskId`(`deduplicated: true`),**绝不重复扣除额度**。
2. **过审实扣 (`SUCCESS`)**:
- 仅当 SheerID 官方最终审核通过(返回 `status: "SUCCESS"` 及官方权益领取跳转链接 `redirectUrl`)时,本次预冻结的 `1` 次额度才正式核销完成。
3. **未过审 / 异常 100% 秒级退回 (`FAILED` / `ABORTED_SAFE`)**:
- **`ABORTED_SAFE`(零损耗风控熔断)**:在上传文档前发现 IP/通道异常或前置拦截,系统在未触碰原链接的情况下安全中止,**原验证链接 100% 完好未受损,且 `1` 次额度立即自动退回原卡密或 API Key 余额**。
- **`FAILED`(验证未通过 / 死链 / 过期链)**:即使因凭证被拒或链接本身失效导致未通过,系统依然触发 **「只扣成功保护」**,**自动将 `1` 次额度退回原卡密或 API Key 余额**(返回 `creditRefunded: 1, netCreditsCost: 0`)。
---
## 🔐 三、 接口基础信息与鉴权方式
### 1. 接口根地址 (Base URL)
```text
http://<您的服务器IP或域名>:8888
```
*(注:主控端口与对外客户端端口 `:8888` 均已同步挂载全套接口,推荐对外统一分发 `:8888` 端口或反代后的 HTTPS 域名)*
### 2. 统一鉴权传参方式(4 种任选其一,全接口通用)
无论调用哪套接口,您都可以通过以下任意一种方式传入您的 `CDK` 卡密或 `sk_api_...` 密钥:
| 方式 | 传参位置 | 示例 |
| :--- | :--- | :--- |
| **方式 A(推荐·标准 Header)** | `X-API-Key` 请求头 | `X-API-Key: sk_api_8X9mK2pQ7vR4nL5wT3` 或 `X-API-Key: VIP1-8A9F-3C2D` |
| **方式 B(推荐·卡密 Header)** | `X-CDKey` 请求头 | `X-CDKey: VIP1-8A9F-3C2D` |
| **方式 C(Bearer Token)** | `Authorization` 请求头 | `Authorization: Bearer sk_api_8X9mK2pQ7vR4nL5wT3` |
| **方式 D(最省事·JSON Body)** | POST 请求 JSON 体字段 | `{"apiKey": "sk_api_..."}` 或 `{"cdkey": "VIP1-..."}` |
> 💡 **智能跨通道兼容特性**:
> `/api/open/v1/*` 接口不仅支持 `sk_api_...` 密钥,**如果您直接把 `CDK` 卡密传给 `/api/open/v1/verify`、`/api/open/v1/status/{taskId}`、`/api/open/v1/balance`,系统也会自动识别并走卡密核销通道!**
---
## 🎫 四、 【模式二】通用卡密 (CDK) 直连 API 详解 (`/api/v1/cdkey/*`)
> **适用场景**:您从我方批量采购了 `CDK` 卡密(如 1次零售卡、5次小额卡、100次/500次批发大卡),希望无需开通固定账户,直接在脚本、机器人或前端网页中传入 `cdkey` 调用。
### 4.1 提交验证任务(支持单条 / 批量)
- **请求路径**:`POST /api/v1/cdkey/verify`
- **Content-Type**:`application/json`
#### 请求参数 (JSON Body)
| 参数名 | 类型 | 必填 | 说明 |
| :--- | :--- | :---: | :--- |
| `cdkey` | `string` | ✅ | 您的通用卡密(如 `"VIP1-8A9F-3C2D"`),也可通过请求头 `X-CDKey` 传递 |
| `url` | `string` | 二选一 | 单条 SheerID 验证链接,或直接传 24 位十六进制 `verificationId` |
| `urls` | `array` | 二选一 | 批量提交多条验证链接数组(系统将按有效条数依次预冻额度) |
| `webhookUrl` | `string` | 选填 | 异步回调地址(`http://` 或 `https://`),任务完结后系统主动 `POST` 推送结果 |
#### 请求示例
```bash
curl -X POST "http://127.0.0.1:8888/api/v1/cdkey/verify" \
-H "Content-Type: application/json" \
-d '{
"cdkey": "VIP1-8A9F-3C2D",
"url": "https://services.sheerid.com/verify/67c8c14f5f17a83b745e3f82/?verificationId=69a0123456789abcdef01234",
"webhookUrl": "https://your-domain.com/webhook/sheerid"
}'
```
#### 成功响应示例 (`200 OK`)
```json
{
"code": 0,
"message": "任务已提交(只扣成功,失败/死链/风控熔断 100% 自动退回原卡密)",
"data": {
"cdkey": "VIP1-8A9F-3C2D",
"taskId": "tsk_9f8e7d6c5b4a",
"verificationId": "69a0123456789abcdef01234",
"status": "QUEUED",
"message": "✅ 已进入 VIP 王牌通道排队(只扣成功,失败/熔断自动退回原卡密)",
"creditDeducted": 1,
"creditsRemaining": 4,
"submittedCount": 1,
"taskIds": ["tsk_9f8e7d6c5b4a"],
"items": [
{
"taskId": "tsk_9f8e7d6c5b4a",
"verificationId": "69a0123456789abcdef01234",
"status": "QUEUED",
"deduplicated": false,
"creditDeducted": 1,
"creditsRemaining": 4,
"message": "✅ 已进入 VIP 王牌通道排队(只扣成功,失败/熔断自动退回原卡密)"
}
],
"errors": []
}
}
```
---
### 4.2 轮询查询任务状态与过审领取链接
- **请求路径 A(URL 路径传参)**:`GET /api/v1/cdkey/status/{taskId}` (也支持 `POST`)
- `{taskId}` 支持传 `tsk_...` 任务号、24位 `verificationId`,或用英文逗号分隔的多个任务号(如 `tsk_111,tsk_222`)
- **请求路径 B(JSON Body 传参)**:`POST /api/v1/cdkey/status`
- 请求体:`{"cdkey": "VIP1-8A9F-3C2D", "taskId": "tsk_9f8e7d6c5b4a"}`(或 `"taskIds": ["tsk_1", "tsk_2"]`)
- **建议轮询间隔**:每 **3 秒** 查询一次,通常 **18 ~ 45 秒** 内进入终态。
#### 响应示例 1:验证通过 (`SUCCESS` —— 实扣 1 次)
```json
{
"code": 0,
"data": {
"taskId": "tsk_9f8e7d6c5b4a",
"verificationId": "69a0123456789abcdef01234",
"cdkey": "VIP1-8A9F-3C2D",
"status": "SUCCESS",
"redirectUrl": "https://services.sheerid.com/redirect/...",
"message": "✅ 学生身份资格认证已通过 (Verification Approved)",
"creditDeducted": 1,
"creditRefunded": 0,
"netCreditsCost": 1,
"refundReason": "",
"creditsRemaining": 4,
"elapsedSeconds": 24.6,
"createdAt": 1775000000,
"completedAt": 1775000025
}
}
```
#### 响应示例 2:验证未通过或熔断 (`FAILED` / `ABORTED_SAFE` —— 自动退回 1 次)
```json
{
"code": 0,
"data": {
"taskId": "tsk_9f8e7d6c5b4a",
"verificationId": "69a0123456789abcdef01234",
"cdkey": "VIP1-8A9F-3C2D",
"status": "FAILED",
"redirectUrl": "",
"message": "❌ 本次验证未通过(只扣成功保护:1 次额度已自动退回原卡密,可换新链接继续使用)",
"creditDeducted": 1,
"creditRefunded": 1,
"netCreditsCost": 0,
"refundReason": "只扣成功保护:本次验证未通过·已自动退回1次卡密额度",
"creditsRemaining": 5,
"elapsedSeconds": 21.3,
"createdAt": 1775000000,
"completedAt": 1775000021
}
}
```
---
### 4.3 查询卡密剩余次数与历史核销账单
- **请求路径**:`POST /api/v1/cdkey/query` 或 `GET /api/v1/cdkey/query?cdkey=VIP1-8A9F-3C2D`
#### 成功响应示例
```json
{
"code": 0,
"data": {
"cdkey": "VIP1-8A9F-3C2D",
"cardStatus": "ACTIVE",
"cardStatusLabel": "🟢 有效可用",
"enabled": true,
"totalCredits": 5,
"usedCredits": 1,
"frozenCredits": 0,
"creditsRemaining": 4,
"credits": 4,
"billingRule": "SUCCESS_ONLY (只扣成功,失败/死链/风控熔断 100% 自动退回原卡密)",
"expiresAt": 0,
"recentTasks": [
{
"taskId": "tsk_9f8e7d6c5b4a",
"verificationId": "69a0123456789abcdef01234",
"status": "SUCCESS",
"redirectUrl": "https://services.sheerid.com/redirect/...",
"netCreditsCost": 1,
"elapsedSeconds": 24.6,
"createdAt": 1775000000
}
]
}
}
```
---
## 🔑 五、 【模式三】固定开发者 API Key (`sk_api_...`) 总额度池接口详解 (`/api/open/v1/*`)
> **适用场景**:
> 1. 您有自己的**发卡网站、核销前端、Telegram/Discord/QQ 机器人或 SaaS 平台**;
> 2. 您希望**在自己的系统里生成并向终端客户售卖您自己定义的卡密/积分/会员次卡**;
> 3. 当您的客户在您的平台上提交验证链接时,您的后端服务器首先校验您自己的卡密,然后统一携带我方为您开通的固定密钥 `X-API-Key: sk_api_xxxxxx` 请求我方 `/api/open/v1/*` 接口,从您的总额度池中扣减次数;
> 4. 您的 API Key 额度快用完时,既可以联系管理员直接加额度,也可以随时购买我方发卡网的 `CDK` 卡密,调用 `POST /api/open/v1/redeem` **全自动给您的 API Key 充值续费**!
---
### 5.1 提交验证任务(进入 API 供应商专属高并发池)
- **请求路径**:`POST /api/open/v1/verify`
- **请求头**:`X-API-Key: sk_api_xxxxxxxxxxxxxxxxxx`(或放在 JSON Body 的 `apiKey` 字段中)
- **Content-Type**:`application/json`
#### 请求参数 (JSON Body)
| 参数名 | 类型 | 必填 | 说明 |
| :--- | :--- | :---: | :--- |
| `apiKey` | `string` | 选填 | 若未在 Header 传 `X-API-Key`,可在 JSON Body 中传入 `"sk_api_..."` |
| `url` | `string` | 二选一 | 单条 SheerID 验证链接,或 24 位 `verificationId` |
| `urls` | `array` | 二选一 | 批量提交多条验证链接(支持数组或换行分隔的字符串) |
| `webhookUrl` | `string` | 选填 | 本单专属异步回调 URL(若不传则默认使用您在后台配置的全局 Webhook URL) |
#### 请求示例
```bash
curl -X POST "http://127.0.0.1:8888/api/open/v1/verify" \
-H "Content-Type: application/json" \
-H "X-API-Key: sk_api_8X9mK2pQ7vR4nL5wT3" \
-d '{
"url": "https://services.sheerid.com/verify/67c8c14f5f17a83b745e3f82/?verificationId=69a0123456789abcdef01234",
"webhookUrl": "https://your-platform.com/api/callback/sheerid"
}'
```
#### 成功响应示例 (`200 OK`)
```json
{
"code": 0,
"message": "提交成功(只扣成功,失败/死链/零损耗熔断 100% 自动退回额度)",
"data": {
"taskId": "tsk_3a4b5c6d7e8f",
"verificationId": "69a0123456789abcdef01234",
"status": "QUEUED",
"message": "任务已进入 API 供应商专属并发池排队执行(只扣成功,失败/熔断自动退回额度)",
"creditDeducted": 1,
"creditsRemaining": 499,
"submittedCount": 1,
"taskIds": ["tsk_3a4b5c6d7e8f"],
"items": [
{
"taskId": "tsk_3a4b5c6d7e8f",
"verificationId": "69a0123456789abcdef01234",
"status": "QUEUED",
"deduplicated": false,
"creditDeducted": 1,
"creditsRemaining": 499,
"message": "任务已进入 API 供应商专属并发池排队执行(只扣成功,失败/熔断自动退回额度)"
}
],
"errors": [],
"runningCount": 1,
"queuedCount": 0,
"apiPoolRunning": 2,
"apiPoolQueued": 0,
"apiPoolConcurrency": 10,
"maxConcurrency": 10
}
}
```
---
### 5.2 查询任务状态与过审领取链接 (`redirectUrl`)
- **请求路径 A(GET / POST 路径传参)**:`GET /api/open/v1/status/{taskId}` (别名:`/api/open/v1/task/{taskId}`)
- 支持传单个 `taskId`、24位 `verificationId`,或用英文逗号分隔的多个任务 ID(最多 100 个,如 `tsk_1,tsk_2`)
- **请求路径 B(POST JSON Body 传参)**:`POST /api/open/v1/status`
- 请求体:`{"apiKey": "sk_api_...", "taskId": "tsk_3a4b5c6d7e8f"}`
- **请求头**:`X-API-Key: sk_api_xxxxxxxxxxxxxxxxxx`
#### 成功响应示例
```json
{
"code": 0,
"data": {
"taskId": "tsk_3a4b5c6d7e8f",
"verificationId": "69a0123456789abcdef01234",
"status": "SUCCESS",
"redirectUrl": "https://services.sheerid.com/redirect/...",
"message": "✅ 学生身份认证已通过 (Approved)",
"creditDeducted": 1,
"creditRefunded": 0,
"netCreditsCost": 1,
"refundReason": "",
"creditsRemaining": 499,
"elapsedSeconds": 22.4,
"createdAt": 1775000100,
"completedAt": 1775000122
}
}
```
---
### 5.3 查询 API Key 总额度池余额、今日战绩与并发水位
- **请求路径**:`GET /api/open/v1/balance` (别名:`GET /api/open/v1/me`,同时支持 `POST`)
- **请求头**:`X-API-Key: sk_api_xxxxxxxxxxxxxxxxxx`
#### 成功响应示例
```json
{
"code": 0,
"data": {
"resellerId": "rsl_7a8b9c0d",
"name": "极速核销独立站",
"enabled": true,
"creditsRemaining": 499,
"credits": 499,
"todaySubmits": 58,
"todaySuccess": 51,
"todayFailed": 5,
"todayAbortedSafe": 2,
"todayRefunded": 7,
"todayCreditsUsed": 51,
"todayPassRate": 91.1,
"totalRecharged": 1000,
"totalUsed": 501,
"totalSubmits": 560,
"successCount": 501,
"failedCount": 42,
"abortedSafeCount": 17,
"passRate": 92.3,
"runningCount": 1,
"queuedCount": 0,
"apiPoolRunning": 2,
"apiPoolQueued": 0,
"apiPoolConcurrency": 10,
"maxConcurrency": 10,
"billingRule": "SUCCESS_ONLY (只扣成功,失败/死链/熔断 100% 自动退回额度)",
"refundOnAborted": true,
"refundOnFailed": true
}
}
```
---
### 5.4 使用 CDK 卡密给自己的 API Key 自助充值续费
> 当您的 `sk_api_...` 余额不足时,无需等待人工客服,直接用任意未使用的 `CDK` 卡密调用本接口,卡密内的可用次数将 **100% 实时充入您的 `API Key` 总额度池**!
- **请求路径**:`POST /api/open/v1/redeem`
- **请求头**:`X-API-Key: sk_api_xxxxxxxxxxxxxxxxxx`
- **Content-Type**:`application/json`
#### 请求体示例
```json
{
"apiKey": "sk_api_8X9mK2pQ7vR4nL5wT3",
"code": "VIP100-9A8B-7C6D"
}
```
#### 成功响应示例
```json
{
"code": 0,
"message": "✅ CDK 卡密核销成功!已为 API Key【极速核销独立站】充入 +100 次额度,当前剩余 599 次",
"data": {
"code": "VIP100-9A8B-7C6D",
"resellerId": "rsl_7a8b9c0d",
"name": "极速核销独立站",
"addedCredits": 100,
"creditsRemaining": 599
}
}
```
---
## 🔔 六、 Webhook 异步回调通知规范
如果您在提单时传入了 `webhookUrl`(或为您的 API Key 绑定了默认 Webhook 地址),当任务进入终态(`SUCCESS` / `FAILED` / `ABORTED_SAFE`)时,系统会自动向该地址发起 `HTTP POST` 请求(`Content-Type: application/json`,超时时间 10 秒):
```json
{
"event": "verification.completed",
"taskId": "tsk_3a4b5c6d7e8f",
"verificationId": "69a0123456789abcdef01234",
"status": "SUCCESS",
"redirectUrl": "https://services.sheerid.com/redirect/...",
"creditRefunded": 0,
"refundReason": "",
"completedAt": 1775000122
}
```
> *(注:若为模式二 `CDK` 提单触发的回调,JSON 中还会额外包含 `"cdkey": "VIP1-..."` 字段。)*
---
## 📊 七、 任务状态码 (`status`) 与 HTTP 错误码速查表
### 1. 任务状态枚举 (`data.status`)
| 状态值 (`status`) | 是否终态 | 计费结果 | 含义与前端处理建议 |
| :--- | :---: | :---: | :--- |
| `QUEUED` | 否 | 预冻结 1 次 | 正在高优队列中等待空闲并发窗口,**继续每 3 秒轮询** |
| `PROCESSING` | 否 | 预冻结 1 次 | 正在自动填表、上传凭证并轮询 SheerID 官方审核结果,**继续每 3 秒轮询** |
| `SUCCESS` | ✅ **是** | **实扣 1 次** | **验证通过!** 请将 `data.redirectUrl` 展示给用户点击领取学生优惠权益 |
| `ABORTED_SAFE` | ✅ **是** | **退回 1 次 (净扣 0)** | **通道保护安全中止**:未提交文档,**原验证链接 100% 完好未受损**,额度已自动退回,可直接用原链接重提 |
| `FAILED` | ✅ **是** | **退回 1 次 (净扣 0)** | **验证未通过**:额度已自动退回原卡密或 API Key 余额,请提示用户刷新活动页获取新验证链接后重试 |
### 2. HTTP 状态码与异常处理
| HTTP 状态码 | 触发原因 | 解决方案 |
| :---: | :--- | :--- |
| `200` | 请求成功 | 读取 `data` 字段中的业务数据 |
| `400` | 参数错误 / 链接格式无效 | 检查 `url` 是否包含合法的 24 位十六进制 `verificationId` |
| `401` | `API Key` 或 `CDKey` 不存在 | 检查 `X-API-Key` / `cdkey` 是否有空格或拼写错误 |
| `402` | 剩余可用额度不足 (`Insufficient credits`) | 请更换新卡密,或调用 `/api/open/v1/redeem` 为您的 API Key 充值 |
| `403` | 卡密已作废 (`VOID`) / 已过期 / API Key 已停用 | 联系上游管理员核查该卡密或 API Key 状态 |
| `404` | 未找到对应的 `taskId` | 确认 `taskId` 是否由当前 `API Key` / `CDKey` 提交 |
| `429` | 共享并发队列排队已满 | 稍候 5~10 秒再重试提交 |
---
## 💻 八、 多语言生产级对接代码模板(复制即用)
### 1. Python 完整实战示例(兼容 `sk_api_...` 与 `CDK` 卡密)
```python
import time
import requests
BASE_URL = "http://127.0.0.1:8888"
# 既可填固定开发者密钥 sk_api_xxxx,也可直接填通用卡密 VIP1-xxxx
AUTH_TOKEN = "sk_api_8X9mK2pQ7vR4nL5wT3"
def verify_sheerid_url(sheerid_url: str, token: str = AUTH_TOKEN) -> dict:
headers = {"X-API-Key": token, "Content-Type": "application/json"}
# 1. 提交验证任务 (/api/open/v1/verify 同时兼容 sk_api_ 与 CDK 卡密)
resp = requests.post(
f"{BASE_URL}/api/open/v1/verify",
headers=headers,
json={"url": sheerid_url},
timeout=15,
)
if resp.status_code != 200:
raise RuntimeError(f"提单失败 (HTTP {resp.status_code}): {resp.text}")
submit_data = resp.json()["data"]
task_id = submit_data["taskId"]
print(f"[+] 提单成功! taskId={task_id} | 当前剩余额度={submit_data['creditsRemaining']} 次")
# 2. 轮询结果 (每 3 秒查一次)
for _ in range(60):
time.sleep(3)
st_resp = requests.get(
f"{BASE_URL}/api/open/v1/status/{task_id}",
headers=headers,
timeout=10,
)
info = st_resp.json()["data"]
status = info["status"]
print(f" [{info['elapsedSeconds']}s] 状态: {status} | {info['message']}")
if status == "SUCCESS":
print(f"[🎉 认证成功] 激活链接: {info['redirectUrl']} | 剩余额度: {info['creditsRemaining']}")
return info
elif status in ("FAILED", "ABORTED_SAFE"):
print(f"[🛡️ 未扣费退回] 原因: {info['refundReason']} | 剩余额度: {info['creditsRemaining']}")
return info
raise TimeoutError("轮询超时,请稍后通过 status 接口继续查询")
if __name__ == "__main__":
verify_sheerid_url("https://services.sheerid.com/verify/67c8c14f5f17a83b745e3f82/?verificationId=69a0123456789abcdef01234")
```
### 2. Node.js (JavaScript / TypeScript) 完整示例
```javascript
const BASE_URL = "http://127.0.0.1:8888";
const AUTH_TOKEN = "sk_api_8X9mK2pQ7vR4nL5wT3"; // 或直接填卡密 "VIP1-8A9F-3C2D"
async function runVerification(sheeridUrl) {
const headers = {
"Content-Type": "application/json",
"X-API-Key": AUTH_TOKEN,
};
// 1. 提交验证链接
const subRes = await fetch(`${BASE_URL}/api/open/v1/verify`, {
method: "POST",
headers,
body: JSON.stringify({ url: sheeridUrl }),
});
const subJson = await subRes.json();
if (!subRes.ok || subJson.code !== 0) {
throw new Error(subJson.detail || subJson.message || "Submit failed");
}
const { taskId, creditsRemaining } = subJson.data;
console.log(`[+] 任务已创建: ${taskId}, 预冻后剩余额度: ${creditsRemaining}`);
// 2. 每 3 秒轮询任务状态
while (true) {
await new Promise((r) => setTimeout(r, 3000));
const stRes = await fetch(`${BASE_URL}/api/open/v1/status/${taskId}`, { headers });
const stJson = await stRes.json();
const d = stJson.data;
console.log(`[${d.elapsedSeconds}s] ${d.status}: ${d.message}`);
if (["SUCCESS", "FAILED", "ABORTED_SAFE"].includes(d.status)) {
return d;
}
}
}
```
### 3. PHP 对接示例(适合独角数卡 / 彩虹发卡 / WordPress 插件二开)
```php
true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"X-API-Key: {$apiKey}"
],
CURLOPT_POSTFIELDS => json_encode(["url" => $verifyUrl]),
CURLOPT_TIMEOUT => 15,
]);
$res = json_decode(curl_exec($ch), true);
curl_close($ch);
if (($res['code'] ?? -1) !== 0) {
die("提单失败: " . ($res['detail'] ?? $res['message'] ?? 'Unknown error'));
}
$taskId = $res['data']['taskId'];
echo "提单成功,TaskID: {$taskId},剩余可用次数: {$res['data']['creditsRemaining']}\n";
```
### 4. Go (Golang) 对接示例
```go
package main
import (
"bytes"
"encoding/json"
"fmt"
"io"
"net/http"
)
func main() {
baseURL := "http://127.0.0.1:8888"
apiKey := "sk_api_8X9mK2pQ7vR4nL5wT3" // 支持 sk_api_... 或 VIP1-... 卡密
bodyBytes, _ := json.Marshal(map[string]string{
"url": "https://services.sheerid.com/verify/67c8c14f5f17a83b745e3f82/?verificationId=69a0123456789abcdef01234",
})
req, _ := http.NewRequest("POST", baseURL+"/api/open/v1/verify", bytes.NewBuffer(bodyBytes))
req.Header.Set("Content-Type", "application/json")
req.Header.Set("X-API-Key", apiKey)
resp, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
raw, _ := io.ReadAll(resp.Body)
fmt.Println("Response:", string(raw))
}
```