激活码
一个激活码就是一份已付款的订阅,由客户自己开通:输入激活码、提交账号信息,我们为其开通套餐。您用余额购买激活码,再把它们作为商品分发。
激活码是什么样的
激活码为 16 个字符,每 4 个一组,由字母和数字组成:7K2M-9QXH-4RWD-P8NY。其中没有容易混淆的字母——输入时 O 与 0、I 与 1 视为同一字符,最后一位是校验位:页面能立即发现输错,且不会因此消耗尝试次数。激活码无法靠穷举猜出:页面限制为 10 分钟内最多尝试 5 次。
每个激活码都附带一个链接 https://activate.astrum.shop/——打开后激活码会自动填入。激活码位于地址中 # 之后的片段:浏览器不会把它发送到服务器。
激活码就是商品
谁知道激活码,谁就能用它开通订阅。请加密保存激活码,不要写入日志,只通过您自己的渠道交给买家。
状态
status |
激活码的情况 |
|---|---|
available |
未使用:客户尚未提交信息——可以交给任何人 |
activating |
客户已提交信息——正在开通订阅 |
activated |
订阅已开通;从此刻起享有 7 天 质保 |
expired |
45 天 内未激活——已作废,价格不予退还 |
refunded |
价格已退回余额——激活码已注销 |
availableactivatingactivated开通未成功——尝试关闭后,激活码重新变为 available
供应商拒绝,或客户提交了错误账号的信息——激活码仍为 activating:客户可以提交其他信息,由我们处理这次尝试。尝试关闭后(客户拒绝身份验证,或由我们关闭),激活码才重新变为未使用,有效期不变(available,事件 key.attempt_failed)。这时可以把它交给同一位客户换一个账号使用,也可以交给其他客户。
只在页面上输入激活码不会占用它:只有客户提交了信息,激活码才被占用。客户凭同一个激活码回来时,看到的是开通的进展或结果,而不是错误。两个人同时输入同一个激活码——以先提交信息的人为准。
激活码有效期
激活码自购买起有效 45 天,截止到 expires_at。在此期间未激活即作废,价格不予退还。到期前 7 天 我们会推送 key.expiring 事件并发送 Telegram 消息。客户已提交信息、正在开通的激活码不会作废。客户拿着已作废的激活码来找您——请联系我们:我们可以为其延期,激活码将重新变为 available,有效期重新计算。
商品目录
GET /v1/catalog — 每个套餐有一个 product_id,交付给客户的方式见 delivery_methods:每种方式都有自己的价格 price_usdt 和期限 subscription_days。商品目录每 1 分钟 更新一次。
商品目录中只有可以用激活码购买的套餐:交付方式为 activation 和 card_payment,这些方式的订阅由客户在开通页面上自行开通。卡密或现成账号(key、account)以及「我们提供的新账号」(new_account)不以激活码形式销售:商品目录中没有它们,用这些 delivery_method 购买会返回 40006 delivery_method_unavailable。
一种交付方式可能有多个期限,例如 30 天和 90 天的订阅。全部期限都在该方式的 terms 中,最短的排在最前:它的价格和期限也直接显示在该方式这一行中。
订阅可能有多种类型——此时一种交付方式会有多行,每行都有自己的价格和 kind 字段:
kind |
订阅类型 |
|---|---|
app_store |
App Store 开通——使用供应商的卡密;之后只能通过 App Store 升级套餐 |
web |
网页开通——在服务方网站上用银行卡支付订阅,客户可以自行升级和续订 |
web_payment |
网页激活(我方银行卡)——由我方用自己的银行卡在客户账号上支付订阅(交付方式 card_payment) |
null |
该交付方式没有类型之分 |
购买激活码
POST /v1/keys — 套餐、数量和您那边的订单号:价格从余额中扣除,响应中包含激活码和给客户的链接。每次最多购买同一套餐的 100 个激活码。
ref— 您那边的订单号。使用相同的ref和相同的请求体重试,会返回同样的激活码(200)且不会重复扣款——因此连接中断后可以放心重试。相同的ref、不同的请求体会返回51002 ref_conflict。delivery_method— 仅当套餐有多种交付方式时需要。不传时返回40005 delivery_method_required,details中列出可选方式:不能替您随意选择,不同方式价格不同。subscription_days— 仅当有多个期限时需要。不传时取最短期限;该方式没有的期限返回40007 subscription_days_unavailable。kind— 仅当有多种类型时需要。不传时返回40008 kind_required,details中列出可选类型;该方式没有的类型返回40009 kind_unavailable。
示例:从余额购买激活码
{
"product_id": "3f6c0e7e-2b1d-4c1a-9a57-4d0f1b8e2c11",
"quantity": 1,
"ref": "order-58213"
}
{
"ref": "order-58213",
"keys": [
{
"key_id": "9b2f6c1e-4d7a-4b0e-8f3c-1a5d2e7c9b40",
"code": "7K2M-9QXH-4RWD-P8NY",
"link": "https://activate.astrum.shop/#k=7K2M-9QXH-4RWD-P8NY",
"status": "available",
"product_id": "3f6c0e7e-2b1d-4c1a-9a57-4d0f1b8e2c11",
"title": "ChatGPT Plus",
"delivery_method": "activation",
"kind": "web",
"subscription_days": 30,
"price_usdt": "20.00",
"ref": "order-58213",
"created_at": "2026-10-14T10:14:03Z",
"expires_at": "2026-11-28T10:14:03Z",
"activated_at": null,
"warranty_until": null,
"last_attempt_failed_at": null,
"last_attempt_reason": null
}
],
"price_usdt": "20.00",
"charged_usdt": "20.00",
"balance_usdt": "80.00"
}
价格与批发
激活码的价格是您专属的价格:取批发阶梯价与个人价(如有)中较低者。阶梯按您在 30 天 内购买的激活码数量计算,包含本次购买:一次买 20 个——这些激活码就按「20+」的价格计算。
GET /v1/catalog中该套餐的price_usdt——购买下一个激活码时扣除的金额:阶梯已把它计算在内。- 同一套餐的
prices——各阶梯的价格:min_keys表示 30 天 内激活码达到多少个时适用该价格,price_usdt为该阶梯上的激活码价格。购买后激活码数量不少于min_keys时,整笔购买都按该价格计算。同样的价格也可在后台「价格」标签页查看。 - 购买响应中,
price_usdt为单个激活码的价格,charged_usdt为本次购买的总额。
列表与按编号查询
GET /v1/keys — 您商店的激活码,最新的在前;可按 status、ref 和 product_id 筛选,分页参数为 page,每页 50 个(响应中有 total 和 pages)。超过最后一页时 keys 为空:在 page 小于 pages 时继续翻页。GET /v1/keys/ — 单个激活码:状态、有效期、激活时间以及质保截止时间(warranty_until)。两个响应中都包含激活码本身(code)和链接(link)。
查询激活码
POST /v1/keys/ —— 手上没有编号、只有激活码本身时按激活码查询:比如客户把激活码发给了客服。请求体中放 codes,每次最多 100 个激活码;大小写、空格和连字符不影响结果。响应中的 results 按相同顺序,每个激活码一行:
found—— 您店铺的激活码,key中是完整的激活码信息,与GET /v1/keys/相同;{key_id} not_found—— 您的店铺没有这个激活码:其他店铺的激活码与不存在的激活码返回相同结果;typo—— 不是激活码:长度不对、含有无效字符或校验位不符。
激活码放在请求体中而不是地址里:地址会留在服务器日志中。
示例:查询客户发来的激活码
{
"codes": [
"7k2m 9qxh 4rwd p8ny",
"7K2M-9QXH-4RWD-P8N"
]
}
{
"results": [
{
"code": "7k2m 9qxh 4rwd p8ny",
"result": "found",
"key": {
"key_id": "9b2f6c1e-4d7a-4b0e-8f3c-1a5d2e7c9b40",
"code": "7K2M-9QXH-4RWD-P8NY",
"link": "https://activate.astrum.shop/#k=7K2M-9QXH-4RWD-P8NY",
"status": "activated",
"product_id": "3f6c0e7e-2b1d-4c1a-9a57-4d0f1b8e2c11",
"title": "ChatGPT Plus",
"delivery_method": "activation",
"kind": "web",
"subscription_days": 30,
"price_usdt": "20.00",
"ref": "order-58213",
"created_at": "2026-10-14T10:14:03Z",
"expires_at": "2026-11-28T10:14:03Z",
"activated_at": "2026-10-15T09:02:41Z",
"warranty_until": "2026-10-22T09:02:41Z",
"last_attempt_failed_at": null,
"last_attempt_reason": null
}
},
{
"code": "7K2M-9QXH-4RWD-P8N",
"result": "typo",
"key": null
}
]
}
需要备多少
我们不为激活码备库存:客户输入激活码时才向供应商采购套餐——因此购买激活码也不受商品目录中 in_stock 的限制。如果某个套餐在供应商处无法再开通,我们会注销该套餐所有未使用的激活码,并把它们的价格退回余额——同时发送 Telegram 消息并推送 key.refunded 事件。
错误
请根据 code 而不是文字做分支判断:message 面向人阅读,内容可能变化。访问相关的错误所有接口通用,完整列表见「错误码」一节。
10006 terms_not_accepteddetails.terms_version。30001 not_enough_balanceGET /v1/balance/top-up-addresses )后重试。40001 product_not_foundGET /v1/catalog 获取 product_id。40005 delivery_method_requireddetails.delivery_methods 及商品目录。40006 delivery_method_unavailabledetails.delivery_methods 及商品目录。40007 subscription_days_unavailabledetails.subscription_days 及商品目录中的 terms。不传 subscription_days 时,购买使用最短时长。40008 kind_requireddetails.kinds 及商品目录中各交付方式行的 kind。40009 kind_unavailabledetails.kinds 及商品目录中各交付方式行的 kind。51002 ref_conflictref 重试时请求体必须相同——这样会返回同样的激活码。新的购买请使用新的 ref。20002 too_many_ordersRetry-After 秒。限额见 GET /v1/account。20004 daily_order_limit_reached20005 daily_spend_limit_reachedGET /v1/balance 中的 available_today_usdt。额度在 UTC 时间 00:00 重置。11006 validation_errordetails.errors:字段及原因。