API 对接文档

幻光扫码 · 更新于 2026-09-20(北京时间)· CDK 认证,无需申请单独的 API Key。

地址与认证

新 CDK 格式:后续新生成卡密使用 KSCAN 前缀及 8 组、每组 4 位十六进制随机字符,共 128 位随机数,例如 KSCAN-XXXX-XXXX-XXXX-XXXX-XXXX-XXXX-XXXX-XXXX(仅格式示例,不是可用卡密)。含分隔符总长 45 字符;旧 4 组卡密继续有效。请把 CDK 当作完整字符串传递,不按旧长度截断或固定匹配;查询、下单、合并接口及额度规则不变。合并后生成的新卡同样使用新格式。

https://masi.cc.cd

POST 请求使用 Content-Type: application/json。普通客户接口在请求体传 ticket(CDK);/api/integration/ 接口支持 X-CDK 请求头。使用订单密钥查询时传 X-Order-Secret。

Content-Type: application/json
User-Agent: MyApp/1.0

请求需携带 User-Agent。若遇到 Cloudflare 返回的 403 / error code: 1010,先检查请求头;其他 403 也可能来自访问防护规则。CDK、AT 和订单密钥均需妥善保管。

当前接单规则

工人接单保护

所有工人领取入口(网页、自动派单、工人 API、管理员指派)最多持有 1 单;等待付款、处理中及核验中都占用名额。客户批量提交不受此数量限制。工人 API 的 count 大于 1 仍最多返回一笔,返回 orders 数组结构不变,客户端必须按实际返回数量处理。

支付授权异常、状态未知或最终失败立即停止该工人新接单,不等累计3次。原有失败冷却、投诉封禁及扣款规则仍独立执行。异常不等于已确认工人的银行账号受限,申请恢复不能直接解锁。

UPI支付异常后强制下线,保留登录处理原订单和提交申请的能力,但不能上线、接新单或计入在线人数。首次异常可由老板核实提前批准,或满1小时后由员工确认更换UPI并恢复试单;不自动上线。恢复后的试单再次异常,强制冷却至少60分钟,老板和普通解禁/清零操作均不能提前恢复。冷却结束后仍须审核或确认更换UPI,恢复为单笔手动试单。其他封禁和冷却继续有效。

工人用原认证调用 POST /api/worker/recovery(工人API使用 /api/worker-integration/recovery),发送 {"action":"request","note":"已检查或更换付款账号的说明"} 申请老板审核。满1小时自助恢复发送 {"action":"self-recover","cycle_id":"状态返回的cycle_id","upi_changed":true};服务端检查时间、状态及其他限制,并记录员工确认,此确认不代表平台验证了银行账号。返回 payment_guard 增加 online_allowed、mandatory_seconds、self_recover_seconds、can_self_recover 字段。上线接口在受限时返回409,原领取接口及返回结构保持兼容。

管理员通过 POST /api/admin/worker-recovery 查询申请或传 worker_id、cycle_id、action=approve/reject 审核;老板只能审核自己下属。强制冷却、有持单、封禁或老板暂停时不能批准。审核或自助恢复后,工人须上线并手动领取1笔试单;最终成功后恢复正常接单,仍最多持有1单。

上线前已领取的多笔订单不强行转移,仍继续核验;全部结束前不能领取新单。旧历史失败不批量追溯封停,本次上线后的支付异常及失败实时触发保护。认证、客户提交格式和既有订单结算不变。

成功率与容量优先派单(兼容原 API)

新网页默认使用 dispatch_mode: "capacity_priority"。单条 /api/scan-orders、批量 /api/scan-orders/batch(最外层)、X-CDK /api/integration/orders 及合作方提交可主动传此参数接入;无需更改已有 API 客户端。

默认公共派单与 capacity_priority 共用服务端规则:按团队近7天已结算有效订单的真实成功率优先,满10单进入正式排名;成功率相同优先样本更多的团队,再按最近分配时间轮转。有自动接单权限、已开启自动接单、在线且无持单的工人才能自动接单,每人最多1单。按实际空闲容量逐队分配,超额订单留公共大厅。公共新单前10秒按空闲名额保护优先领取,超额部分立即开放;不会为离线或满载团队保留名额。接单时再次校验容量与剩余至少75秒门槛。

样本不足团队在有合格团队竞争时,每第10次公共分配获得试单机会;没有合格团队可接时可承接试单,每个小样本团队自动派单最多同时1单。近30分钟至少5单、成功率低于50%且较7天成功率下降至少20个百分点时暂降优先级。已有工人异常、冷却与恢复限制继续生效。

兼容性:API用户无需更新地址、鉴权、参数或现有返回字段。不传 dispatch_mode 的公共订单也使用新派单规则;明确 team_id 的请求仍保留原团队限制和放开时间。非空 team_id 与 capacity_priority 不可同时使用(HTTP 400)。不改额度、重复提交或到账审核规则。capacity_priority 查询继续返回 dispatch_mode 和 dispatch_state(等待时为 public_hall)。

团队统计新增字段:dispatch_rate、dispatch_closed、dispatch_rank为近7天派单统计;idle_capacity、auto_capacity为当前空闲及自动接单容量;dispatch_capacity含小样本并发限制;dispatch_status为 priority / trial / demoted / full / offline。award_eligible、award_rank、volume_rank是当天奖励资格与两类名次;无资格时奖励名次为 null。旧字段继续保留。

每日奖励榜:沿用平台工人统计时区(当前 UTC+05:30),每天零点封存前一日榜单。当天成功+责任失败满10单参与评选;未领取的大厅过期、未结算核验单不计入。稳健分按 Wilson 95% 下限计算,成功单量榜只按成功数排序。并列第一保留并列资格,同团队可以同时获得两项;系统保存结果,奖励由管理员发放,不自动转账。过去结算结果不随后续订单修改而重算。

单条、批量、X-CDK 对接均执行同一套服务端链接校验。只有校验通过才创建订单并占用 1 次可用额度。

已恢复原有外部链接提交规则:不再要求平台预存支付链接与 AT 账号的绑定记录,也不再强制要求实时 Free 套餐基线。AT、邮箱、链接状态、75 秒门槛及额度校验继续生效。

无人在线的规则

网页、单条、批量和 X-CDK 对接均强制要求至少有一名在线工人。旧参数 require_online_workers 仅为兼容保留;省略或传 false 都不能关闭检查。提交开始和正式入单前均检查,避免检测链接期间工人下线仍然收单。

整批开始时无人在线,返回 HTTP 409;处理中无人在线,后续条目进入 failed,不影响此前已创建的订单。在线表示账号启用、非封禁、处于接单状态且最近 60 秒有心跳,不保证真人正在操作、开启自动接单或一定能领取指定团队订单。

单条提交

POST/api/scan-orders
{
  "ticket": "YOUR_CDK",
  "link": "https://payments.stripe.com/upi/instructions/YOUR_LINK",
  "access_token": "YOUR_FULL_ACCESS_TOKEN",
  "email": "buyer@example.com",
  "require_online_workers": true
}

请替换所有占位值。ticket、link、access_token 必填;email、require_online_workers、team_id 选填。AT 应为完整的 eyJ 开头的 access_token。

创建成功:HTTP 201

{
  "ok": true,
  "order": {
    "order_id": "ORDER_ID",
    "status": "awaiting_worker",
    "link": "https://payments.stripe.com/upi/instructions/YOUR_LINK",
    "qr_expires_at": 1790000000
  },
  "order_secret": "ORDER_SECRET",
  "ticket": {"available_uses": 9, "pending_uses": 1}
}

响应示例省略部分字段;自动派单后状态也可能直接为 claimed。请保存订单 ID 和 order_secret。时间戳均为 Unix 秒。

链接预检拒收:HTTP 400

{
  "ok": false,
  "error": "链接只剩 74 秒有效期,至少需要 75 秒,请重新生成链接。",
  "code": "link_too_short",
  "retryable": false,
  "created": false,
  "charged": false
}

检测不可用时可能返回 code: "link_check_unavailable"、retryable: true,同样不会建单或占额度。AT、CDK、暂停等其他错误可能只有 ok 和 error,客户端不能假设所有错误都有扩展字段。

无人在线拒收:HTTP 409

{
  "ok": false,
  "error": "当前没有在线工人,本次不扣额度。",
  "online_workers": 0,
  "code": "no_worker_online",
  "retryable": true,
  "retry_after_seconds": 60,
  "created": false,
  "charged": false
}

错误文字为示意,判断程序应优先使用 HTTP 状态和结构化字段。

批量提交

POST/api/scan-orders/batch

一次最多 200 条,逐条处理。ticket、team_id 和 require_online_workers 放在最外层,每条 item 分别携带链接、AT 和可选邮箱。

{
  "ticket": "YOUR_CDK",
  "require_online_workers": true,
  "items": [
    {"link": "https://payments.stripe.com/upi/instructions/LINK_A", "access_token": "FULL_AT_A", "email": "a@example.com"},
    {"link": "https://payments.stripe.com/upi/instructions/LINK_B", "access_token": "FULL_AT_B", "email": "b@example.com"}
  ]
}

逐条处理完成:HTTP 201

{
  "ok": true,
  "count": 1,
  "created": [{"order_id": "ORDER_ID", "order_secret": "ORDER_SECRET", "link": "https://payments.stripe.com/upi/instructions/LINK_A", "email": "a@example.com"}],
  "duplicated": [],
  "duplicate_count": 0,
  "failed": [{"index": 1, "link": "https://payments.stripe.com/upi/instructions/LINK_B", "error": "支付链接已过期,请重新生成链接。", "code": "link_expired", "retryable": false}],
  "ticket": {"available_uses": 9, "pending_uses": 1}
}

批量接口同步逐条检测,大批量或网络慢时可能超过网关等待时间。建议脚本逐条调用单条接口,并立即保存每条结果。超时不等于服务端没有创建订单;不要盲目重发整个批次。

X-CDK 对接接口

POST/api/integration/orders
X-CDK: YOUR_CDK
Content-Type: application/json
User-Agent: MyApp/1.0
{
  "link": "https://payments.stripe.com/upi/instructions/YOUR_LINK",
  "access_token": "YOUR_FULL_ACCESS_TOKEN",
  "email": "buyer@example.com"
}

支持 url 作为 link 的别名,支持可选 team_id。也可以把 CDK 放在请求体 ticket 中;若请求头和请求体都提供,两者必须一致。创建返回 201,复用重复订单返回 200,并带 duplicate 布尔值。

链接、AT、在线工人及额度规则与单条接口一致。无人在线返回 HTTP 409 和 no_worker_online;其他校验拒收返回 HTTP 400,并提供 code、retryable、created=false、charged=false。无需额外参数启用在线检查。

{"ok": false, "error": "支付链接已过期,请重新生成链接。", "code": "link_expired", "retryable": false, "created": false, "charged": false}

缺少 CDK 返回 401;require_online_workers=false 也不能绕过在线检查。

GET/api/integration/orders/{order_id}

使用 X-CDK 请求头查询属于该 CDK 的订单;没有匹配订单返回 404。成功返回 {"ok": true, "order": {...}}。

POST/api/integration/tickets/status

使用 X-CDK 请求头并发送 {},或在 JSON 请求体传 ticket,查询卡密额度。

订单查询与到账结算

GET/api/orders/{order_id}

请求头传提交时得到的 X-Order-Secret。建议每 3–5 秒查询一次。

POST/api/orders/query

也可以使用订单 ID 和 CDK 查询:

{"order_id": "ORDER_ID", "ticket": "YOUR_CDK"}

工人确认后的 AT 核验

工人点确认完成后,订单先保持 claimed 并返回 verifying: true。以提交完成为起点,第 5 秒首检;未达到成功条件则在第 30 秒复检,第 60 秒做最后一次检测,最多三次。任一次达到条件即提前结束。接口响应耗时另计;若上一请求尚未结束,下一次顺延,不并发检测,也不能把 60 秒当成硬性完成时限。核验期间不提前结算、退回大厅或按链接到期处理。

恢复后新提交订单使用 legacy 原有规则:工人确认不立即结算,按第 5、30、60 秒的检测安排核验客户 AT。提交时不是已失效、完成后检测为 invalid 时按原规则结算;检测窗口结束仍未达到条件则失败并释放额度。Stripe 单独成功和 JWT 自带套餐不作为这轮 AT 核验通过的依据。

legacy 是平台原有的 AT 变化判定,并不等同于独立证明账号新增了 Plus 权益。之前已接收的 entitlement_v2 订单仍按其原有证据规则核验;本次不改写旧订单、不伪造绑定或基线、不重新结算历史。

订单查询增加 verification_policy(entitlement_v2 或 legacy)、verification_reason;核验中提供 verification_deadline 兜底期限。成功/失败仍使用原有 completed/failed;核验中保持 claimed、verifying=true。

所有订单查询均返回 verification_offsets_seconds: [5, 30, 60]。legacy 完成提示统一为“已按原有 AT 变化规则完成结算”,不能展示为“已确认 Plus 到账”;旧订单中推定的 landing.plan 在客户响应中显示为 unknown,不修改原始订单或结算。严格订单按其原有证据规则解释。

重新派送已下线:订单查询统一返回 can_redispatch: false 及 redispatch_hint;调用 POST /api/orders/{order_id}/redispatch 返回 HTTP 410。不可仅凭剩余时间显示可重新派送,也不能把不可派送提示理解为订单已退款。

{
  "ok": true,
  "order": {
    "order_id": "ORDER_ID",
    "status": "claimed",
    "verifying": true,
    "qr_expires_at": 1790000000,
    "message": "正在核验到账"
  }
}

landing 存在时包含 status、message、plan 等结果;常见状态有 checking、landed、failed、no_at、unknown。以订单最终 status 为准。verifying 仅在核验中返回,缺省按 false 处理。

订单状态含义与处理
awaiting_worker已入任务池,等待领取,额度已预占。
claimed工人已领取;verifying=true 时等待 AT 核验结果,不提前认定完成。
completed满足接收时对应的核验规则,已完成结算;新提交订单当前使用 legacy 原有规则。
failed失败,释放额度;读取 error、message 或 landing 了解原因。
expired订单过期,释放额度;重新生成有效链接后再提交。
cancelled订单取消,释放额度。

qr_expires_at 是支付页标注的期限,不保证授权一直有效。当前客户订单查询尚未返回工人端的 link_check 状态和具体失效原因;不要仅根据倒计时推断支付链接可用。

重复提交

同一链接或同一笔 Stripe 授权的订单仍在排队、处理中,或命中短时间重复窗口时,在本次预检通过的前提下复用已有订单,不重复占额度。单条和对接接口返回 HTTP 200、duplicate: true;批量放在 duplicated 数组。

同一 CDK 的重复订单会返回查询密钥;跨 CDK 命中时不会返回对方的 order_secret。链接已付款、已失效或剩余时间不足时,可能先被预检拒收,不保证每次重试都返回原订单。已拿到 order_id 后应查询原订单。

额度、团队及服务状态

POST/api/tickets/redeem
{"ticket": "YOUR_CDK"}

读取 ticket 中的 total_uses(总额度)、used_uses(已使用)、pending_uses(预占)和 available_uses(可用)。

GET/api/platform/teams

获取 teams 列表,包含 team_id、name、members、online、completed、closed、rate 及近期统计等字段。rate 为完成数占已结束订单数的百分比;展示时可直接使用服务端返回值。

提交时可传 team_id 指定团队,不传则所有符合条件的工人可接。指定团队等待达到服务端配置的时长后会放开给其他工人,目前默认 60 秒。team_fallback_seconds 不是可设置的提交参数,传入不会修改等待时长。

GET/health

读取 ok、online_workers 等当前服务状态。查询与提交之间在线人数仍可能变化。

投诉

POST/api/orders/complaint
{
  "order_id": "ORDER_ID",
  "order_secret": "ORDER_SECRET",
  "reason": "领取后未完成,导致订单过期",
  "category": "timeout"
}

只有失败或过期且有工人领取过的订单可投诉;成功和进行中的订单不可投诉,同一订单只能投诉一次。category 可用 timeout 或 not_landed,也可省略按状态判断。投诉同步给工人、老板和管理端,后续处理以管理端结果为准。

错误处理

HTTP含义
200 / 201查询、复用或创建成功;批量仍需逐条检查 failed。
400校验拒收:链接、AT、CDK、额度、团队、暂停等,读取 error。
401缺少所需认证,如对接接口缺少 CDK。
403可能来自前置访问防护;1010 时检查 User-Agent。
404订单不存在或查询凭证不匹配等。
409当前无人在线,所有新扫码任务强制拒收,不建单、不占额度。
410旧提炼入口 /api/orders 和 /api/batches 已下线,请使用扫码提交接口。
429限流或尝试过多,按返回信息退避。
5xx / 超时服务或网关异常,结果可能不确定;先核对已有订单与额度,不盲目整批重发。

常见链接错误码

以下 code 用于单条、X-CDK 对接提交的错误响应及批量 failed 项。错误码不是穷举,须兼容未知值。

code含义 / 建议
link_too_short不足 75 秒,重新生成链接。
no_worker_online没有在线工人;retryable=true,建议 60 秒后重新检查,不保证旧链接届时仍有效。
link_expired已过期,重新生成链接。
canceled授权已取消,重新生成链接。
generic_decline / insufficient_funds / processing_error / payment_method_provider_decline / setup_attempt_failed / requires_payment_method支付授权不可用,按 error 中说明处理,再生成新链接。
unsupported_link / not_upi / invalid_link域名、协议或链接类型不支持,改用可核验的 Stripe HTTPS UPI 页面。
link_check_unavailable / check_unavailable / expiry_unknown检测或有效期无法确认,通常 retryable=true,稍后重试或重新生成链接。
link_unavailable其他不可接收状态,例如已支付或处理中;读取 error 和 retryable。
at_storage_unavailableAT 核验凭据暂时无法保存;未建单、未占额度,稍后重试。
submit_failed批量项的其他提交错误,例如 AT、CDK 校验失败,读取 error。

retryable=true 表示允许稍后重试,不保证原链接届时仍满足时间门槛;retryable=false 时先解决拒收原因。保留完整 error,不能把所有 HTTP 400 都展示成“链接过期”。

完整示例

Python:单条提交和查询

运行前设置环境变量 UPI_CDK、UPI_LINK、UPI_ACCESS_TOKEN。示例会打印每次查询结果,并最多等待 10 分钟;本地停止等待不会取消服务端订单。

import json
import os
import time
import urllib.error
import urllib.request

BASE = "https://masi.cc.cd"
HEADERS = {"Content-Type": "application/json", "User-Agent": "MyApp/1.0"}

def call(path, body=None, extra=None):
    data = json.dumps(body).encode() if body is not None else None
    request = urllib.request.Request(BASE + path, data=data, headers={**HEADERS, **(extra or {})})
    try:
        with urllib.request.urlopen(request, timeout=90) as response:
            return response.status, json.load(response)
    except urllib.error.HTTPError as error:
        raw = error.read().decode("utf-8", "replace")
        try:
            payload = json.loads(raw)
        except ValueError:
            payload = {"ok": False, "error": raw[:300]}
        return error.code, payload
    except (urllib.error.URLError, TimeoutError) as error:
        raise SystemExit("网络结果不确定,请先核对已有订单,不要自动重复提交:" + str(error))

status, result = call("/api/scan-orders", {
    "ticket": os.environ["UPI_CDK"],
    "link": os.environ["UPI_LINK"],
    "access_token": os.environ["UPI_ACCESS_TOKEN"],
    "require_online_workers": True,
})
if status not in (200, 201) or not result.get("ok"):
    print(json.dumps(result, ensure_ascii=False))
    raise SystemExit("提交未成功,请按错误原因处理。")

order_id = result["order"]["order_id"]
print("请保存订单 ID:", order_id)
deadline = time.monotonic() + 600
while time.monotonic() < deadline:
    status, result = call("/api/orders/query", {
        "order_id": order_id,
        "ticket": os.environ["UPI_CDK"],
    })
    if status != 200 or not result.get("ok"):
        print(json.dumps(result, ensure_ascii=False))
        raise SystemExit("查询未成功;跨 CDK 的重复订单不能用当前 CDK 查询。")
    order = result["order"]
    print(order["status"], order.get("message", ""), order.get("verifying", False))
    if order["status"] in ("completed", "failed", "expired", "cancelled"):
        break
    time.sleep(4)
else:
    print("本地停止等待,请保留订单 ID,稍后继续查询。")

curl:单条提交和查询

适用于 Bash 等终端;先设置 UPI_CDK、UPI_LINK、UPI_ACCESS_TOKEN。使用 Python 生成 JSON,避免手工拼接令请求体损坏。

python3 -c 'import json, os; print(json.dumps({"ticket": os.environ["UPI_CDK"], "link": os.environ["UPI_LINK"], "access_token": os.environ["UPI_ACCESS_TOKEN"], "require_online_workers": True}))' |
curl --max-time 90 -X POST 'https://masi.cc.cd/api/scan-orders' \
  -H 'Content-Type: application/json' -H 'User-Agent: MyApp/1.0' \
  --data-binary @-

curl 'https://masi.cc.cd/api/orders/ORDER_ID' \
  -H 'X-Order-Secret: YOUR_ORDER_SECRET' \
  -H 'User-Agent: MyApp/1.0'

先保存提交响应里的 order_id 和 order_secret,再替换查询命令中的占位值。完整 AT、CDK、订单密钥不要写入公开日志。