爱发电API整理
爱发电为开发者提供 Webhook、OpenAPI、OAuth2 三套能力。本文基于官方 Webhook 与 API 文档整理,域名 afdian.com / afdian.net / ifdian.net 等价,下文统一写 afdian.com。
Note
开发者后台:https://afdian.com/dashboard/dev
官方指南:开发者 API 和 Webhook · OAuth2
Webhook
订单支付成功后平台 POST 到你的 URL。要做幂等,建议与 API 并用。
OpenAPI
用 user_id + token 签名后主动查订单、赞助者、方案、私信等。
OAuth2
需向官方申请。authorization_code 模式,换取用户 user_id。
接入准备
打开开发者后台
登录后进入 dashboard/dev。
配置 Webhook
填写可公网访问的通知 URL。服务器异常时推送可能延迟或丢失,必须配合 API 对账。
获取 API 凭证
记下
user_id与 API Token(下文称token)。token只参与签名,不放进请求体。
Warning
token / client_secret 只放服务端。泄露立刻联系官方客服重置。
Webhook
订单相关事件会 POST 到你配置的 URL。当前 data.type 仅为 order。异常时可能重复推送,必须幂等(按 out_trade_no 去重)。
推送体
{ "ec": 200, "em": "ok", "data": { "type": "order", "order": { "out_trade_no": "202106232138371083454010626", "custom_order_id": "Steam12345", "user_id": "adf397fe8374811eaacee52540025c377", "user_private_id": "等价于微信 unionid 的跨主体用户标识", "plan_id": "a45353328af911eb973052540025c377", "month": 1, "total_amount": "5.00", "show_amount": "5.00", "status": 2, "remark": "", "redeem_id": "", "product_type": 0, "discount": "0.00", "sku_detail": [{ "sku_id": "b082342c4aba11ebb5cb52540025c377", "count": 1, "name": "15000 赏金/货币 兑换码", "album_id": "", "pic": "https://pic1.afdiancdn.com/..." }], "address_person": "", "address_phone": "", "address_address": "" }, "sign": "xxxxxxxx" }}Tip
custom_order_id 等字段可由前端跳转 URL 传参写入,详见开发者功能汇总。
你必须返回
接口不返回 ec: 200 时,平台视为回调失败。
{"ec":200,"em":""}Webhook 签名校验(2025-07)
签名字段在 data.sign。待签字符串由订单字段依次拼接:
sign_str = out_trade_no + user_id + plan_id + total_amount用平台公钥做 SHA256 + openssl_verify,sign 为 Base64。
-----BEGIN PUBLIC KEY-----MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwwdaCg1Bt+UKZKs0R54ylYnuANma49IpgoOwNmk3a0rhg/PQuhUJ0EOZSowIC44l0K3+fqGns3Ygi4AfmEfS4EKbdk1ahSxu7Zkp2rHMt+R9GarQFQkwSS/5x1dYiHNVMiR8oIXDgjmvxuNes2Cr8fw9dEF0xNBKdkKgG2qAawcN1nZrdyaKWtPVT9m2Hl0ddOO9thZmVLFOb9NVzgYfjEgI+KWX6aY19Ka/ghv/L4t1IXmz9pctablN5S0CRWpJW3Cn0k6zSXgjVdKm4uN7jRlgSRaf/Ind46vMCm3N2sgwxu/g3bnooW+db0iLo13zzuvyn727Q3UDQ0MmZcEWMQIDAQAB-----END PUBLIC KEY-----public function verifySign(string $sign_str, string $sign): bool{ $publicKey = '上面的公钥'; $key = openssl_get_publickey($publicKey); return openssl_verify($sign_str, base64_decode($sign), $key, 'SHA256') === 1;}OpenAPI 通用约定
请求可用 form 或 JSON,响应一律 JSON。公共信封:
| 字段 | 含义 |
|---|---|
ec | 业务码,200 成功 |
em | 文本说明 |
data | 业务数据 |
请求公共参数
string创作者 user_id,标识调用方。
string(JSON 文本)接口业务参数的 JSON 字符串,不是对象。无参时也要传合法 JSON,例如 "{}" 或 '{"page":1}'。
int秒级时间戳。与服务器偏差超过 3600s 判过期。
string签名。token 不上传,只参与计算。
签名算法
sign = md5( token + "params" + params + "ts" + ts + "user_id" + user_id )参数按 key 排序后拼接 key+value;当前固定四字段,可直接按上式。没有任何分隔符,token 直接前置。
手算示例
| 项 | 值 |
|---|---|
| user_id | abc |
| params | {"a":333} |
| ts | 1624339905 |
| token | 123(不上传) |
拼接串:
123params{"a":333}ts1624339905user_idabc结果:
sign = a4acc28b81598b7e5d84ebdc3e91710c请求体:
{ "user_id": "abc", "params": "{\"a\":333}", "ts": 1624339905, "sign": "a4acc28b81598b7e5d84ebdc3e91710c"}function afdian_sign(string $token, string $userId, string $paramsJson, int $ts): string{ return md5($token . 'params' . $paramsJson . 'ts' . $ts . 'user_id' . $userId);}import hashlibdef afdian_sign(token: str, user_id: str, params_json: str, ts: int) -> str: raw = f"{token}params{params_json}ts{ts}user_id{user_id}" return hashlib.md5(raw.encode("utf-8")).hexdigest()import { createHash } from "node:crypto";function afdianSign(token, userId, paramsJson, ts) { return createHash("md5") .update(`${token}params${paramsJson}ts${ts}user_id${userId}`) .digest("hex");}验签探针 ping
POST https://afdian.com/api/open/ping
ec = 200 表示签名正确。失败时 data.debug.kv_string 给出服务端看到的拼接串,便于离线复算(sign = md5(token + kv_string))。
签名错误:
{ "ec": 400005, "em": "sign validation failed", "data": { "explain": "plz check the desc", "debug": { "kv_string": "params{\"a\":333}ts1636732646user_idxxxxx" }, "request": { "user_id": "xxxxxxx", "params": "{\"a\":333}", "ts": 1636732646, "sign": "a9fc8cafd2c1e290cac00fc26f38e2d" } }}时间戳过期:
{ "ec": 400002, "em": "time was expired", "data": { "explain": "ts is outdated, 3600s latency was allowed" }}成功:
{ "ec": 200, "em": "pong", "data": { "uid": "xxxxxxx", "request": { "user_id": "xxxxxxx", "params": "{\"a\":333}", "ts": 1636732646, "sign": "a9fc8cafd2c1e2902cac00fc26f38e2d" } }}错误码
| ec | 含义 |
|---|---|
400001 | params incomplete |
400002 | time was expired |
400003 | params was not valid json string |
400004 | no valid token found |
400005 | sign validation failed |
接口列表
查订单
POST https://afdian.com/api/open/query-order
按创建时间倒序,默认每页 50 条。
int页码,从 1 累加。
string指定订单号;多个用英文逗号分隔。
int50
每页条数,范围 1–100。
params 示例:{"page":1} 或 {"out_trade_no":"222225555,2222222666"}。
Important
与 Webhook 结构不同:订单对象在 data.list[] 里,不在 data.order。
{ "ec": 200, "em": "", "data": { "list": [{ "out_trade_no": "202106232138371083454010626", "custom_order_id": "Steam12345", "user_id": "adf397fe8374811eaacee52540025c377", "user_private_id": "跨主体唯一用户标识", "plan_id": "a45353328af911eb973052540025c377", "month": 1, "total_amount": "5.00", "show_amount": "5.00", "status": 2, "remark": "", "redeem_id": "", "product_type": 0, "discount": "0.00", "sku_detail": [], "address_person": "", "address_phone": "", "address_address": "" }], "total_count": 167, "total_page": 11 }}查赞助者
POST https://afdian.com/api/open/query-sponsor
按建立关系时间倒序,默认每页 20 条。
int页码。
int20
每页条数,范围 1–100。
string指定用户赞助情况;多个用英文逗号分隔。
params 示例:{"page":1}。
{ "ec": 200, "em": "", "data": { "total_count": 14, "total_page": 2, "list": [ { "sponsor_plans": [], "current_plan": { "name": "" }, "all_sum_amount": "0.00", "create_time": 1581011280, "last_pay_time": 1598852327, "user": { "user_id": "3524370d11e8ae8852540025c377", "name": "Hee", "avatar": "https://pic1.afdiancdn.com/..." } } ] }}current_plan 仅有 name: "" 时表示当前无方案。
查订单随机自动回复
POST https://afdian.com/api/open/query-random-reply(2025-05-14)
string订单号;多个用英文逗号分隔。
{ "ec": 200, "em": "success", "data": { "list": [{ "out_trade_no": "202505141538455397541020050", "content": "999" }] }}更新方案/商品自动回复
POST https://afdian.com/api/open/update-plan-reply(2025-05-14)
用于补货、发码等场景。
string订阅方案 ID。更新订阅时传这个。
string商品型号 ID。更新商品时传这个。
string非空则覆盖普通自动回复;空或不传则不改。
string非空才更新随机自动回复内容。
string更新随机回复时必填。取值:append 追加(平台会在内容前加换行),overwrite 覆盖。
Caution
plan_id 与 sku_id 二选一。商品误传 plan_id 会报错。
发送私信
POST https://afdian.com/api/open/send-msg(2025-08-14)
string接收用户 ID。
string私信内容。
Warning
频率限制:10 次/秒,1000 次/小时。
查看方案
POST https://afdian.com/api/open/query-plan(2025-08-14)
string方案 ID。
{ "ec": 200, "em": "获取方案成功", "data": { "plan": { "plan_id": "436af0d0e0xxxxxxxxxxxxxx25c377", "price": "5.00", "name": "测试售卖动机2", "product_type": 1, "desc": "", "reply_content": "", "replay_random_content": "", "independent": 0, "permanent": 0, "pay_month": 1, "skus": [{ "sku_id": "436eba6cexxxxxxxxxxxxxx025c377", "plan_id": "436af0d0e0xxxxxxxxxxxxxx25c377", "name": "型号1", "desc": "", "stock": "", "price": "5.00", "reply_content": "", "reply_random_content": "" }] } }}product_type | 含义 |
|---|---|
0 | 订阅 |
1 | 商品 |
2 | 捆绑包 |
3 | 自选包 |
4 | 售票 |
| 字段 | 含义 |
|---|---|
independent | 0 非独立 / 1 独立 |
permanent | 0 非永久 / 1 永久 |
pay_month | 1 月费 / 3 季费 / 12 年费 |
订阅方案响应里没有 skus。
字段说明
订单
string订单号。
string自定义信息(可由前端 URL 传入)。
string下单用户 ID。
string跨主体唯一用户标识,类似微信 unionid。
string方案 ID;自选金额时为空。
string订单描述。
int赞助月份。
string真实付款金额;兑换码场景为 0.00。
string展示金额;有折扣时为折前金额。
int2 = 交易成功。Webhook 目前只推这种。
string订单留言。
string兑换码 ID。
int0 常规方案 / 1 售卖方案。
string折扣。
array售卖类型的型号明细。
string收件人。
string收件人电话。
string收件人地址。
分页:total_count / total_page;当 curr_page < total_page 时可继续翻页。
赞助者
array该用户关联的多个赞助方案。
object当前方案;仅 { "name": "" } 表示无方案。
string累计赞助(折前)。兑换码场景是虚拟金额,会高于实际可提现。
int首次成为赞助者的秒级时间戳。
int最近一次赞助时间。
string用户唯一 ID。
string昵称,可重复。
string头像 URL。
OAuth2 关联授权
让用户用爱发电账号登录你的应用。需向官方申请,支持 authorization_code(必须有服务端)。
申请
私信官方客服,提供:
- 应用名称
- 应用用途
- 可信域名
clientSecret(可不填,官方随机生成)
官方回发 client_id 与 client_secret。未认证可先点此认证。
流程
跳转授权页
https://afdian.com/oauth2/authorize?response_type=code&scope=basic&client_id={client_id}&redirect_uri={urlencoded_uri}&state={state}测试可用 http;生产用 https。
state做 CSRF 校验。用户同意
重定向到
redirect_uri,带上code与state。拒绝则不重定向。服务端换用户信息
POST https://afdian.com/api/oauth2/access_token(application/x-www-form-urlencoded)
stringauthorization_code
固定值。
string官方分配。
string仅服务端保存。
string上一步拿到的 code。
string与授权时一致,此处不要再手动 encode。
{ "ec": 200, "em": "ok", "data": { "user_id": "网站的用户ID", "user_private_id": "同 OpenAPI 的 user_private_id", "name": "昵称", "avatar": "头像" }}Caution
换票接口必须服务端 + HTTPS 调用。client_secret 泄露立刻找官方重置。
变更时间线
随机自动回复 API
新增 query-random-reply、update-plan-reply,支持补货/发码。
2025-05-14
Webhook 增加签名
data.sign + RSA 公钥校验,防伪造回调。
2025-07-01
私信与查方案
新增 send-msg、query-plan;签名规则说明同步更新。
2025-08-14
参考
官方 Webhook 与 API 文档
本文主要依据
开发者功能汇总
Webhook / API / OAuth2 / 网页嵌入总览
GitBook:API 和 Webhook
结构化官方指南
GitBook:OAuth2
授权登录细节
需求缺口可填开发者需求问卷。