一、核心流程
所有语言(Python / 易语言 / C++ / Java / C# / Go / PHP / JavaScript / 按键精灵)的对接原理完全一致:一次 HTTP 请求,返回一个字符串。
你的软件 ──① 发送卡密 + 设备码 ──▶ 迅胜卡密 API
你的软件 ◀── ② 返回验证结果(成功/失败 + 剩余时间 + 签名) ── API
二、请求格式
GET https://jm.1009.cloud/kami/{用户名}/check.php?card=卡密&mac=设备码&app=应用名&heart=1&t=时间戳
| 参数 | 含义 | 示例 |
|---|---|---|
card | 用户输入的卡密 | A1B2C3D4E5 |
mac | 当前设备的唯一标识 | 2CF05DDC86C8 |
app | 应用名称(默认 a) | a |
heart | 心跳保活(可选,填 1) | 1 |
t | 时间戳(毫秒,防重放) | 1789007258000 |
三、返回格式
// ✅ 成功示例
ok|valid|30|43200|1791599357|1789007357|sign=1b7696301b90c7a86880e946e777fc81
// ❌ 失败示例
error|expired|1789007357|sign=...
| 字段 | 含义 |
|---|---|
ok | 验证通过 |
valid | 卡密有效(非首次激活) |
activate | 首次激活成功 |
permanent | 终身卡,永久有效 |
error|xxx | 验证失败,xxx 为错误码 |
| 剩余天数 | 如 30 |
| 剩余分钟数 | 如 43200 |
| 到期时间戳 | Unix 秒 |
| 当前时间戳 | Unix 秒 |
sign=xxx | MD5 签名(防篡改) |
四、返回码说明
| 返回体 | 含义 |
|---|---|
ok|valid|30|43200|... | ✅ 验证通过,剩余 30 天 |
ok|permanent|... | ✅ 终身卡,永久有效 |
ok|activate|30|43200|... | ✅ 首次激活成功 |
error|invalid_card | ❌ 卡密不存在 |
error|expired | ❌ 卡密已过期 |
error|banned | ❌ 卡密已被禁用 |
error|device_mismatch | ❌ 设备不匹配(已绑定其他设备) |
error|online_limit_reached | ❌ 在线设备数已满 |
error|too_frequent | ❌ 请求太频繁(50 秒内重复验证) |
error|system_locked | ❌ 系统已被管理员锁死 |
五、签名机制(防篡改)
返回结果带 MD5 签名,客户端必须验签通过才认可结果,防止中间人篡改。
# 原始数据(去掉 |sign= 之后的部分)
body = "ok|valid|30|43200|1791599357|1789007357"
# 待签名字符串 = 原始数据 + 你的签名密钥
str = body + SIGN_KEY
# 签名
sign = md5(str)
# 校验:本地算出的 sign 必须等于服务端返回的 sign
六、时间戳防重放
ts = 服务端返回的时间戳
now = 当前 UTC 时间戳
if (now - ts) > 120: # 超过 120 秒视为过期
拒绝
✅ 签名校验 → 防篡改 ✅ 时间戳校验 → 防重放。两者都通过,才认可验证结果。
七、多语言示例
Python
import requests, hashlib, time
USER, APP, SIGN_KEY = "你的用户名", "a", "你的签名密钥"
URL = f"https://jm.1009.cloud/kami/{USER}/check.php"
def check_card(card, mac):
params = {"card": card, "mac": mac, "app": APP, "heart": 1, "t": int(time.time() * 1000)}
raw = requests.get(URL, params=params, timeout=8).text.strip()
body, _, sign = raw.rpartition("|sign=")
if hashlib.md5((body + SIGN_KEY).encode()).hexdigest() != sign:
return False, "签名校验失败"
if body.startswith("ok"):
return True, body.split("|")[2] + " 天"
return False, body
C# / .NET
using var http = new HttpClient();
long ts = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
string url = $"{URL}?card={card}&mac={mac}&app={APP}&heart=1&t={ts}";
string raw = http.GetStringAsync(url).Result.Trim();
int i = raw.LastIndexOf("|sign=");
string body = raw[..i], sign = raw[(i + 6)..];
using var md5 = MD5.Create();
string local = Convert.ToHexString(md5.ComputeHash(Encoding.UTF8.GetBytes(body + SIGN_KEY))).ToLower();
bool ok = local == sign && body.StartsWith("ok");
Go
q := url.Values{"card": {card}, "mac": {mac}, "app": {APP}, "heart": {"1"},
"t": {fmt.Sprint(time.Now().UnixMilli())}}
resp, _ := http.Get(URL + "?" + q.Encode())
b, _ := io.ReadAll(resp.Body)
raw := strings.TrimSpace(string(b))
idx := strings.LastIndex(raw, "|sign=")
body, sign := raw[:idx], raw[idx+6:]
sum := md5.Sum([]byte(body + SIGN_KEY))
ok := hex.EncodeToString(sum[:]) == sign && strings.HasPrefix(body, "ok")
更多语言(易语言 / Java / C++ / PHP / JavaScript / 按键精灵)的完整示例,登录后台后可在「对接代码」页一键复制(已自动填入你的用户名与应用名)。
八、扩展接口
| 接口 | 说明 |
|---|---|
check.php?act=self_unbind&card=..&mac=..&app=.. | 自助解绑(需在后台开启,可配置扣减天数) |
check.php?act=merge_card&card_a=..&card_b=..&app=.. | 卡密合并(把 B 的剩余时长并入 A) |
check.php?act=get_notice&app=.. | 获取应用公告 |
check.php?act=get_version&app=.. | 获取应用版本号 |
check.php?act=get_custom1|get_custom2&app=.. | 获取自定义字段 |