苏岛代理充值 API v1
接口地址:https://zovotao.aishoppi.com/api/v1
在线文档:https://zovotao.aishoppi.com/docs/api
OpenAPI 文件:https://zovotao.aishoppi.com/docs/openapi.json
本接口供代理服务器使用:持有有效 API Key 和苏岛签发的 SD- 卡密,完成账号确认、充值申请及订单查询。套餐和地区固定在卡密内,代理不能覆盖。API Key 不提供发码、付款卡管理、平台余额或其他代理订单的访问权限。只支持本文列出的本站自有码。
1. 获取 API Key
由站主登录 https://zovotao.aishoppi.com/,进入“代理 API”,填写代理名称并点击“生成 API Key”。完整密钥只显示一次,可下载后私密交付对应代理。不要交付站主管理密码。密钥丢失时,由站主对原代理执行“重置密钥”;原订单归属保留,旧密钥立即失效。不要重新创建一个代理来代替原代理,否则新身份不能查询原代理订单。
每次请求携带以下请求头:
Authorization: Bearer sk_sd_你的密钥
Content-Type: application/json
Accept: application/json
密钥只保存在代理服务器。不要放进网页 JavaScript、URL、客户端安装包、聊天群或日志。接口不开放跨域浏览器调用,也不使用后台登录 Cookie 作为 API 凭据。
2. 套餐、地区与卡密
| plan | 套餐名称 | 卡密套餐标识 |
| plus | Plus 月卡 | PLUS |
| go | Go | GO |
| pro_5x | Pro100(5x) | PRO100 |
| pro_20x | Pro200(20x) | PRO200 |
| pro_50x | Pro500(50x) | PRO500 |
| country | 地区 | 币种 | 卡密地区标识 |
| PH | 菲律宾 | PHP | PP |
| EG | 埃及 | EGP | EG |
| CL | 智利 | CLP | CL |
格式示例:SD-PLUS-PP-XXXXXXXX-XXXXXXXX-XXXXXXXX-XXXXXXXX。X 为占位符,不是有效卡密。Pro100/200/500 是套餐名称,不代表当地币种报价。能否提交以卡密状态、实时套餐可用性和账号预检结果为准。现有订阅升级或续费不保证适用,请先向站主确认售卖规则。
3. 标准接入流程
1. 调用“校验卡密”,确认套餐、地区和是否未使用。
2. 在用户授权后获取其完整 Session JSON。调用“预览账号”,向用户显示返回的邮箱、套餐和地区。
3. 用户确认后,保存你业务系统的唯一订单号 client_request_id,再提交充值。consent 必须为 true。
4. 保存响应中的 order_id,每隔至少 10 秒查询一次,直到 completed 或需要人工处理。
5. 提交超时先按原 client_request_id 查单。不要换卡密、换请求号或把超时当失败重充。
session_payload 是完整 Session JSON 序列化后的字符串,不是嵌套 JSON 对象。其中应包含账号邮箱和有效的 accessToken 或 sessionToken;接口不接收邮箱密码。请求正文最大 70 KiB,Session 字符串最大 64 KiB。预览只做本地账号确认,不是支付成功或上游资格通过的证明。
4. 通用响应与限流
成功响应使用 code: 0。HTTP 202 只表示本地充值申请已受理,可能仍在等待付款卡,不能据此交付“开通成功”。只有订单 status: completed 表示充值流程确认完成。
{"code":0,"data":{},"message":"ok"}
错误响应使用非零 code;代理应同时检查 HTTP 状态码和 code,不要解析中文错误消息判断业务状态。
{"code":"INVALID_API_KEY","data":null,"message":"请提供有效的 Bearer API Key。"}
每个代理密钥每滚动 60 秒最多 60 次请求,其中新建和恢复充值合计最多 10 次。相同请求号的已受理重放不占新建次数,但仍占总请求次数。另有站点 IP 和上游限流。收到 HTTP 429 时按 Retry-After 等待;如响应没有该头,至少等待 30 秒。不要无限并发或密集轮询。客户端超时建议 45 秒。
5. 查询套餐
GET /products
无需请求正文。返回 data.products 数组,每项包含 plan、name、country、region_name、currency、code_prefix、enabled。enabled 表示当时的套餐地区配置可用,不保证任何账号或付款卡都能完成支付。
6. 校验卡密
POST /codes/verify
{"code":"SD-PLUS-PP-完整卡密"}
返回 valid、plan、country、plan_name、status、can_redeem、order_id。未使用卡密的 order_id 为 null;已由当前代理登记的卡密返回原订单号。已由其他代理登记的卡密返回 404。此接口不扣费、不消耗卡密、不绑定代理归属。
7. 预览充值账号
POST /recharges/preview
{
"code":"SD-PLUS-PP-完整卡密",
"session_payload":"{\"user\":{\"email\":\"user@example.com\"},\"accessToken\":\"用户凭据占位符\"}"
}
返回 email、name、plan_name、plan、country、confirmation_token、expires_in: 300。请让用户核对邮箱后再提交充值。确认令牌绑定当前代理、卡密及原始 Session 字符串;五分钟内有效。重新预览会替换该代理对这张卡密的旧令牌。服务重启后需重新预览。
8. 提交充值
POST /recharges
| 字段 | 类型 | 必填 | 说明 |
| code | string | 是 | 完整 SD 卡密 |
| session_payload | string | 是 | 与预览时逐字一致的 Session JSON 字符串 |
| confirmation_token | string | 是 | 当前预览返回的确认令牌 |
| client_request_id | string | 是 | 当前代理下唯一的业务订单号,8–80 位,仅字母、数字、点、下划线、冒号和短横线 |
| consent | boolean | 是 | 用户已确认账号、套餐、地区及凭据转交授权后传 true |
{
"code":"SD-PLUS-PP-完整卡密",
"session_payload":"与预览时完全相同的字符串",
"confirmation_token":"预览接口返回值",
"client_request_id":"merchant-order-20261104-0001",
"consent":true
}
成功返回 HTTP 202,以下仅为示例:
{
"code":0,
"data":{
"order_id":"11111111-1111-4111-8111-111111111111",
"client_request_id":"merchant-order-20261104-0001",
"status":"waiting_card",
"plan":"plus",
"country":"PH",
"plan_name":"Plus 月卡 · 菲律宾",
"account_email":"us***@example.com",
"message":"订单已登记,正在等待供货商准备付款卡。",
"can_resume":false,
"poll_after_ms":10000,
"created_at":"2026-11-04T06:30:00.000Z",
"completed_at":"",
"replayed":false
},
"message":"ok"
}
order_id 是本站固定订单号,不是上游订单号。第一次受理后,订单绑定当前代理身份和 client_request_id。同一请求号、同一卡密和同一原始 Session 字符串再次提交会返回原订单,并带 replayed: true;不会重复付款,已受理后的重放不要求确认令牌仍有效。同一请求号改用其他卡密或 Session 内容返回 409 IDEMPOTENCY_CONFLICT。同一卡密换请求号也不会创建第二单。
请求号必须在你的业务数据库中先保存后发送。每笔业务订单使用自己的请求号;网络超时、程序重启、响应丢失后继续使用原号,不要临时重新生成。
9. 查询订单
GET /recharges/{order_id}
或者在提交响应丢失时使用:
GET /recharges/by-request?client_request_id=merchant-order-20261104-0001
两者返回相同订单结构,不包含上游主密钥、客户 Session 或付款卡信息。只允许查询当前代理的订单。请求号包含特殊字符时请做 URL 编码。按请求号暂时查不到不证明上一次请求最终未受理;先等待并保持原请求号核对,必要时联系站主。
| status | 含义 | 代理处理 |
| waiting_card | 已登记,等待处理或付款卡准备 | 保留原单,继续查询 |
| needs_account | 尚未付款,需要重新确认同一账号 | 按第 10 节恢复原单 |
| submitting | 已开始确认是否被充值服务受理,结果尚未明确 | 继续查询,不能新建补单 |
| processing | 充值处理中 | 继续查询 |
| completed | 充值流程已确认完成 | 标记成功,停止轮询 |
| review | 需要人工核对 | 联系站主,不自动补充付款或换码重充 |
校验卡密接口还可能返回 unused。被停用的未使用卡密直接返回错误。失败或人工核对不等于已经退款,不要自行释放卡密或重新付款。
10. 凭据过期后恢复原单
等待订单的账号凭据只在内存保留最多十分钟。超时或服务重启后,尚未付款的订单进入 needs_account。从用户处重新取得同一账号的 Session,使用原卡密再次调用 /recharges/preview,然后提交:
POST /recharges/{order_id}/resume
{
"session_payload":"本次重新预览的 Session JSON 字符串",
"confirmation_token":"本次预览返回的令牌",
"consent":true
}
返回 HTTP 202 和原订单。此接口保留原 order_id、请求号及代理归属。已开始支付或已在排队的订单收到重复恢复请求,只返回原进度,不重新付款。新 Session 不要用原 /recharges 创建请求重放,需走此恢复接口。
11. 错误处理
| HTTP / code | 说明 | 处理 |
| 401 INVALID_API_KEY | 缺少、错误或已停用的密钥 | 联系站主,核对 Bearer 请求头 |
| 400 INVALID_REQUEST_ID | 业务请求号格式无效 | 提交前修正格式 |
| 400 CONSENT_REQUIRED | 未传用户确认 | 确认后传 consent: true |
| 400 INVALID_SESSION / OWN_CDK_ERROR / ZOVO_ERROR | Session 或卡密参数无效 | 核对参数,错误消息仅供展示 |
| 400/404 CDK_UNAVAILABLE | 卡密不可用或不属于当前代理订单 | 核对完整卡密及代理身份 |
| 404 ORDER_NOT_FOUND | 当前代理没有可查询的对应订单 | 核对订单号、请求号和密钥身份 |
| 409 CONFIRMATION_REQUIRED | 确认令牌过期或 Session 内容改变 | 重新预览;已受理的原单优先查单 |
| 409 IDEMPOTENCY_CONFLICT | 请求号已绑定另一份参数 | 查原单,不自动换号重试 |
| 409 CDK_IN_USE / RESUME_NOT_ALLOWED | 卡密已登记或不允许恢复 | 查询原单或联系站主 |
| 429 RATE_LIMITED / rate_limited | 触发请求限制 | 按 Retry-After 等待 |
| 503 或其他 5xx | 暂停、存储或服务异常 | 提交后先按原请求号查单,勿自动换码重充 |
所有写请求超时和 5xx 都按“结果待确认”处理。站点代理层的错误可能是 HTML 而非 JSON,请先检查状态和 Content-Type,并保留你自己的请求号。站主停用密钥只阻止后续 API 请求,已受理订单继续处理;请联系站主查询或核对结果。
12. Python 接入示例
此示例只使用 Python 标准库。密钥和卡密通过环境变量读取;session.json 为用户提供的完整 Session 对象。请把示例的文件存储替换为业务数据库,并按每笔订单分别保存请求号及原始 Session 字符串;不要把真实凭据、密钥或卡密写入日志。示例不会自动重试充值。
import json
import os
import urllib.request
import urllib.error
BASE = "https://zovotao.aishoppi.com/api/v1"
API_KEY = os.environ["SD_API_KEY"]
def api(method, path, body=None):
data = None if body is None else json.dumps(body).encode("utf-8")
req = urllib.request.Request(BASE + path, data=data, method=method, headers={
"Authorization": "Bearer " + API_KEY,
"Content-Type": "application/json",
"Accept": "application/json",
"User-Agent": "SudaoAgentIntegration/1.0",
})
try:
with urllib.request.urlopen(req, timeout=45) as response:
payload = json.load(response)
except urllib.error.HTTPError as error:
# 不输出错误正文、请求头、Session 或完整卡密。
raise RuntimeError("HTTP " + str(error.code) + "; 查询原请求号后处理") from None
if payload.get("code") != 0:
raise RuntimeError(str(payload.get("code")))
return payload["data"]
code = os.environ["SD_CDK"]
with open("session.json", encoding="utf-8") as f:
session_payload = json.dumps(json.load(f), ensure_ascii=False)
# 必须使用已经保存在业务数据库中的该笔订单号。
request_id = os.environ["SD_CLIENT_REQUEST_ID"]
verified = api("POST", "/codes/verify", {"code": code})
preview = api("POST", "/recharges/preview", {
"code": code, "session_payload": session_payload,
})
# 在你的页面向用户展示 preview["email"]、套餐及地区,取得明确确认。
confirmed = input("用户已核对账号、套餐、地区并授权?输入 YES:") == "YES"
if not confirmed:
raise SystemExit("未提交充值")
order = api("POST", "/recharges", {
"code": code,
"session_payload": session_payload,
"confirmation_token": preview["confirmation_token"],
"client_request_id": request_id,
"consent": True,
})
# 将 order_id 保存到业务数据库;至少间隔 10 秒后查询。
print("本站订单号:", order["order_id"], "状态:", order["status"])
# api("GET", "/recharges/" + order["order_id"])
提交超时的恢复示例(仍使用原请求号):
from urllib.parse import urlencode
order = api("GET", "/recharges/by-request?" + urlencode({
"client_request_id": request_id,
}))
13. 范围与验收
接口不提供代理余额充值、自动采购卡密、自动开卡、代理之间转移订单或回调通知;订单结果使用轮询获取。代理 API 本身不额外扣取代理余额,站主与代理的供货结算按双方约定。卡密生成不发起充值;执行充值时实际服务费及订阅费用由站主配置的充值账户承担。
接入后先验证鉴权、套餐、无效卡密及查单错误处理。真实卡密提交会触发真实充值,请使用明确授权的测试账号和一张指定测试卡密。模拟测试、HTTP 202 和能够选卡都不能代替真实充值成功验收。