开发者 API 和 Webhook

简介

爱发电提供了webhook和api两种方式为开发者提供便利。以下内容爱发电简称平台,开发者称开发者。

后台地址 https://afdian.net/dashboard/dev

  1. Webhook

    • 需要在配置通知地址,每当有订单时,平台会请求开发者配置的url(如果服务器异常,可能不保证能及时推送,因此建议结合API一起使用)

    • 此功能的url可在开发者后台找到对应配置,如下图所示

  2. API

    • 该功能需要开发者主动请求爱发电平台,目前可查询历史订单和赞助的人。

    • 此功能涉及到的 user_id、api token 可在开发者后台找到对应配置。如下图所示

Webhook

说明

此功能会将开发者相关的订单打给配置好的url,同时要求开发者返回固定结构,以明确表示成功收到回调。(不排除以后在异常时会重复请求,因此建议做幂等逻辑,支持重复推送)平台请求开发者配置的URL数据示例,目前 data.type 仅为 order ,data.order 对象具体订单字段见最下方解释

{
  "ec": 200,
  "em": "ok",
  "data": {
    "type": "order",
    "order": {
      "out_trade_no": "202106232138371083454010626",
      "user_id": "adf397fe8374811eaacee52540025c377",
      "user_private_id":"33这个是每个用户唯一的,相当于微信的 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/user/8a8e408a3aeb11eab26352540025c377/common/sfsfsff.jpg"
      }],
      "address_person": "",
      "address_phone": "",
      "address_address": ""
    }
  }
}

要求开发者响应的JSON示例,如果接口不返回ec 200 ,则平台认为回调失败

{"ec":200,"em":""}

API

当前功能需要用到 user_id 和 生成的API Token,以下简称 token。请求平台时可以为form表单或者json,平台返回的数据为json。

签名介绍

为了保证数据安全与灵活性,平台做了一个简单的签名逻辑。平台接收的参数如下。

user_id: 上面的 user_id,表明你是谁
params: 具体接口传参的json字符串
ts: 发出请求时秒级时间戳
sign: 针对上面3个数据的签名,防止伪造数据。

sign 的计算规则为:md5(token+请求数据按key排序拼接key和value)

具体到这次场景,参数key为固定值,只有上面四个字段 sign 签名可以简化为
sign = md5({token}params{params}ts{ts}user_id{user_id})
{}包的数据为具体数值

示例

假设当前数据如下
user_id abc
params  {"a":333}
ts      1624339905
token   123        注意这个不传递到服务端,仅参与签名计算

sign = md5('123params{"a":333}ts1624339905user_idabc')

sign = a4acc28b81598b7e5d84ebdc3e91710c

注意token直接写具体值,其它参数写kv,没有任何连接字符,直接拼接

JSON请求示例

{"user_id":"abc", "params": "{\"a\":333}", "ts": 1624339905, "sign":"a4acc28b81598b7e5d84ebdc3e91710c"}

检验签名是否准确

https://afdian.net/api/open/ping可用postman或其他工具请求测试接口。如果接口返回 ec = 200,则证明签名校验通过。如果签名不通过,会返回拼接的字符串,方便检查不通过的原因。比如下面这种场景就是签名不正确。可以直接复制里面的 debug.kv_string,离线计算sign值。如果token为123,由于签名计算规则为 sign=md5(tokenkv_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"
        }
    }
}

下面是ts过期的情况

{
    "ec": 400002,
    "em": "time was expired",
    "data": {
        "explain": "ts is outdated, 3600s latency was allowed"
    }
}

如果返回 ec 为 200,类似下面结构,说明没问题。

{
    "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

具体接口列表

查订单

https://afdian.net/api/open/query-order

可传的参数为

参数名

含义

示例

page

按页数倒序获取订单,按订单创建时间倒序

1 2 3累加

out_trade_no

指定订单号查询信息,如需要查多个,则英文逗号分隔

222225555,2222222666

参数为 page 可传 1,2,3 等(以后会支持传时间查询)即请求参数 params 的值为 {"page":1}

当前按订单创建时间倒序,每页50条数据返回数据结构示例

【注意层级和webhook结构有不同,这里的 order 对象是放到 list 里的】,具体订单含义见最下方解释

{
  "ec": 200,
  "em": "",
  "data": {
    "list": [{
      "out_trade_no": "202106232138371083454010626",
      "user_id": "adf397fe8374811eaacee52540025c377",
      "user_private_id":"33这个是每个用户唯一的,相当于微信的 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/user/8a8e408a3aeb11eab26352540025c377/common/sfsfsff.jpg"
      }],
      "address_person": "",
      "address_phone": "",
      "address_address": ""
    }],
    "total_count": 167,
    "total_page":11
  }
}

查赞助者

https://afdian.net/api/open/query-sponsor参数为 page 可传 1,2,3 等即请求参数 params 的值为 {"page":1}当前按建立关系时间倒序,每页20个返回结构示例

{
  "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/user/27f7sss7/avatar/2d9659585fc4798068efbb652e56c08a.jpg"
        }
      },
      {
        "sponsor_plans": [
          {
            "plan_id": "sdfsf",
            "rank": 0,
            "user_id": "34343",
            "status": 3,
            "name": "独立永久方案",
            "pic": "",
            "desc": "啊1;",
            "price": "1.00",
            "update_time": 1621084278,
            "pay_month": 1,
            "show_price": "1.00",
            "independent": 1,
            "permanent": 1,
            "can_buy_hide": 0,
            "need_address": 0,
            "product_type": 0,
            "sale_limit_count": -1,
            "need_invite_code": false,
            "expire_time": 2114352000,
            "sku_processed": [],
            "rankType": 21
          }
        ],
        "current_plan": {
          "plan_id": "sdfsfsf",
          "rank": 0,
          "user_id": "3453535",
          "status": 3,
          "name": "独立永久方案",
          "pic": "",
          "desc": "啊1;",
          "price": "1.00",
          "update_time": 1621084278,
          "pay_month": 1,
          "show_price": "1.00",
          "independent": 1,
          "permanent": 1,
          "can_buy_hide": 0,
          "need_address": 0,
          "product_type": 0,
          "sale_limit_count": -1,
          "need_invite_code": false,
          "expire_time": 2114352000,
          "sku_processed": [],
          "rankType": 21
        },
        "all_sum_amount": "13.00",
        "first_pay_time": 1576776221,
        "last_pay_time": 1581083107,
        "user": {
          "user_id": "sfff",
          "name": "sfsf:十五种幸福(新版)",
          "avatar": "https://pic1.afdiancdn.com/user/sdfsfsf/avatar/c13b6125cbd9fbe7810c79256df1f5b2_w4032_h3024_s3215.jpeg"
        }
      }
    ]
  }
}

字段说明

订单字段说明

total_count     赞助者总数
total_page      页数,默认每页x条,请求时,传 page ,curr_page < total_page则可继续请求


out_trade_no 订单号
user_id 下单用户ID
plan_id 方案ID,如自选,则为空
title 订单描述
month 赞助月份
total_amount 真实付款金额,如有兑换码,则为0.00
show_amount 显示金额,如有折扣则为折扣前金额
status 2 为交易成功。目前仅会推送此类型
remark 订单留言
redeem_id 兑换码ID
product_type 0表示常规方案 1表示售卖方案
discount 折扣
sku_detail 如果为售卖类型,以数组形式表示具体型号
address_person 收件人
address_phone 收件人电话
address_address 收件人地址

赞助者字段说明

total_count     赞助者总数
total_page      页数,默认每页x条,请求时,传 page ,curr_page < total_page则可继续请求

sponsor_plans    []数组类型,具体节点为多个赞助方案。
current_plan     当前赞助方案,如果节点仅有 name:"",不包含其它内容时,表示无方案
all_sum_amount   累计赞助金额,此处为折扣前金额。如有兑换码,则此处为虚拟金额,回比实际提现的多
create_time      int 秒级时间戳,表示成为赞助者的时间,即首次赞助时间
last_pay_time    int 秒级时间戳,最近一次赞助时间

user 节点表示用户属性
user_id    用户唯一ID
name        昵称,非唯一,可重复
avatar    头像

最后更新于