快速入门

基本概念

client_id是对接入餐链开放平台的基本凭证,它代表的是一个第三方开发者对接实体。所有接入餐链开放平台的第三方应用开发商必须要申请。

accessToken是平台商户对第三方应用开发商的授权访问令牌,有此访问令牌才能访问商户的开放资源。

注解

  • accessToken访问令牌默认有效期为一年。
  • client_secret同client_id是配套的,为了保障安全,请不要泄漏client_secret,如有泄漏,请联系餐链服务人员及时更换。

系统级输入参数

API参数共由两部分组成,系统级参数指所有由 餐链 提供的API所必须的参数,应用级参数是指对应API所需的参数。所有编码统一采用UTF-8

参数名 类型 描述
timestamp long 进行接口调用时的时间戳,即当前时间戳,北京时间,单位为秒(s)
client_id string 餐链分配给第三方应用开发商的client_id
nonce string 随机字符串,能代表唯一的一次访问,最好加入client_id和timestamp来生成一个随机字符串
accessToken string 平台商户对第三方应用开发商授权后获取的访问令牌
sign string 输入参数计算后的签名结果

注解

不论接口是GET、POST、PUT、DELETE等HTTP方法,系统级参数都是以URL参数的方式传递的。

接口调用流程

针对每个接口的请求流程如下:

  1. 根据功能需求确认接口。
  2. 确认请求参数。
  3. 计算签名。
  4. 拼接请求地址。
  5. 针对不同接口,指定 request_bodycontent_type 和请求方法(GET/POST/DELETE/PUT)。

注解

关于request_body的说明:

  • 在某些POST或PUT等请求中,需要把json格式的参数体放在请求体(request_body)中。request_body不直接参与签名(sign)计算,但是这时候要先根据request_body生成bodySign参数,生成算法:Hex(SHA-256(request_body+client_secret)),Hex字符大写,得到bodySign。而bodySign需要参与签名(sign)的计算。
  • “Content-Type”为”application/json;charset:utf-8;”

签名计算

签名计算规则

  1. 对参数名称进行排序得到 字符串1

将所有参数(sign除外)按照参数名的字母顺序排序,并用 & 连接:

accessToken=93f37d1bcf5b2f022cebc0bc3efd9342&client_id=ae674b84-f266-4785-b37b-228c044be967&nonce=6B8C311E537B7C5B0D5E5EECEFE0BF941A262AC24A3744C249D9994DD55A3120&timestamp=1497583267

注解

计算sign时需要注意的以下几点:

  • 除特别申明不需要计算的参数之外(如包含在请求体中的参数),其他参数都需要包含在 字符串1

  • 在某些POST或PUT等请求中,需要把json格式的参数体放在请求体(request_body)中。request_body不直接参与签名(sign)计算,但是这时候要先根据request_body生成bodySign参数,生成算法:Hex(SHA-256(request_body+client_secret)),Hex字符大写,得到bodySign。而bodySign需要参与签名(sign)的计算。所以 字符串1 应该为:

    accessToken=93f37d1bcf5b2f022cebc0bc3efd9342&bodySign=013A660AC36F14BAE42EC538F7E42E7E7DCEBD1C383F380D6A9C132098C2188F&client_id=ae674b84-f266-4785-b37b-228c044be967&nonce=6B8C311E537B7C5B0D5E5EECEFE0BF941A262AC24A3744C249D9994DD55A3120&timestamp=1497583267
    
  • “Content-Type”为”application/json;charset:utf-8;”

  1. 计算 字符串2

按照请求url + ? + 字符串1 + client_secret的顺序进行连接,得到 字符串2

/stores?accessToken=93f37d1bcf5b2f022cebc0bc3efd9342&client_id=ae674b84-f266-4785-b37b-228c044be967&nonce=6B8C311E537B7C5B0D5E5EECEFE0BF941A262AC24A3744C249D9994DD55A3120&timestamp=14975832675ea0ac4f-90f5-4136-81ab-615cbca49f34
  1. 计算签名

字符串2 计算SHA-256哈希,得到签名(把字节转换成Hex,签名必须大写):

0B79D9513EB643B678607D7DC1B1676E2EA8B6D177C664F1B21A1D5ABF25EEEA
  1. 拼接请求URL

将得到的签名赋给sign作为HTTP请求的URL参数:

http://openapi.mealcome.cn/stores?accessToken=93f37d1bcf5b2f022cebc0bc3efd9342&client_id=ae674b84-f266-4785-b37b-228c044be967&nonce=0CA432789B15DEDF98431DE829B1A15BB64CA05AFCCFED17A994D975E92AB43A&timestamp=1497583611&sign=0B79D9513EB643B678607D7DC1B1676E2EA8B6D177C664F1B21A1D5ABF25EEEA
  1. 签名示例

接下来将使用例子示例签名的计算过程。

查询商户的所有门店基础信息(数据均为假数据,只为演示签名过程,以实际调用结果为准):

url: /store

client_id: ae674b84-f266-4785-b37b-228c044be967

client_secret: 5ea0ac4f-90f5-4136-81ab-615cbca49f34

nonce: 6B8C311E537B7C5B0D5E5EECEFE0BF941A262AC24A3744C249D9994DD55A3120

timestamp: 1497583267

accessToken: 93f37d1bcf5b2f022cebc0bc3efd9342

用于计算签名的字符串为:

/store?accessToken=93f37d1bcf5b2f022cebc0bc3efd9342&client_id=ae674b84-f266-4785-b37b-228c044be967&nonce=6B8C311E537B7C5B0D5E5EECEFE0BF941A262AC24A3744C249D9994DD55A3120&timestamp=1497583267

请求url为:

http://openapi.mealcome.com/store?accessToken=93f37d1bcf5b2f022cebc0bc3efd9342&client_id=ae674b84-f266-4785-b37b-228c044be967&nonce=0CA432789B15DEDF98431DE829B1A15BB64CA05AFCCFED17A994D975E92AB43A&timestamp=1497583611&sign=40EE0C1E5C6D267B1FBD25904652D5AE25C80D7A83B032570FB57632D4D99D9F

response body里的数据为(此为演示数据,实际调用结果不同):

{
"code": 200,
"data": {
        "id": 1,
        "name": "格林店",
        "code": "1",
        "pinyin": null,
        "address": null,
        "longitude": null,
        "latitude": null,
        "note": null,
        "cityName": "",
        "proviceName": "",
        "tenantId": 1
},
"message": null,
"error": null
}

注解

  • URL路径中的参数作为url一部分已参与签名计算,为了避免冗余,不再作为request params的一部分进行签名计算。
名称 类型 可空 描述
code int 非空 返回的调用状态码
data object 可空 返回的业务数据
message string 可空 描述业务非正常处理原因
error string 可空 描述业务非正常处理的错误码

注解

string的类型为字符类型(包含所有中英文字符,utf8编码),单个字符其长度都统一为1,字节数以实际存储为准。

注解

目前签名验证比较常见的问题:

  • 生成的时间戳在请求当前的时间前后15分钟范围之外
  • 签名重复使用
  • 时间戳是以秒为单位,也就是10位的时间戳。容易弄错成13位的时间戳
  • POST方式的请求需要考虑中文乱码的情况,可能我方接到body中的中文是乱码的,从而导致签名计算跟实际情况不匹配

code码

状态码含义:

具体详情见下表。
code 类型
200 业务正常处理
400 参数异常
500 业务异常
600 未知异常,未检查异常
700 应用程序错误,已检查异常
800 框架调用异常

访问异常错误返回

{
        "timestamp": 1495094151006,
        "status": 500,
        "error": "Internal Server Error",
        "exception": "BusinessException",
        "message": "javax.servlet.ServletException: BusinessException{errorCode='50003001', errorMessage='该随机字符串无效!'}",
        "path": "/units"
}

接口测试信息

餐链开放平台请求的基础地址为:

http://120.26.164.191:8092

商家测试

餐链提供了以下体验店信息以供接口开发测试

python测试程序

# python 3.0以上版本
import http.client
import urllib.parse
import time
import uuid
import hashlib

headers = {"Content-type": "application/json;charset:utf-8;", "Content-Encoding": "UTF-8"}

host = "openapi.mealcome.cn"
clientId = "8fa2bc6957b24a8b8bf3dfcbe3a34c81"
clientSecret = "79753124b23147fb82309b0ed9e14533"
accessToken = "7c89d63940654f93988639532ce2c447"

def base():
    mytime = int(time.time())
    base_params = {"client_id": clientId, "accessToken": accessToken,
                   "timestamp": str(mytime), "nonce": uuid.uuid1()}
    return base_params

def get(url, params):
    base_params = base()
    if params is not None:
        urlParams = dict(base_params, **params)
    else:
        urlParams = base_params
    # 排序
    urlParams = sorted(urlParams.items(), key=lambda dict: dict[0])

    # 创建签名字符串并生成签名
    url = url + "?" + urllib.parse.urlencode(urlParams, False, "", "utf-8", None, urllib.parse.quote)
    md = (urllib.parse.unquote(url) + clientSecret).encode("utf-8")
    sign = hashlib.sha256(md).hexdigest()

    # 请求接口
    request = url + "&sign=" + str(sign).upper()
    print("http://" + host + request)
    httpClient = http.client.HTTPConnection(host)
    httpClient.request("GET", request)
    response = httpClient.getresponse()
    print(response.read())

if __name__ == '__main__':
    get("/store", None)
    params = {"begin": "2017-11-04 10:00:00", "end": "2017-11-05 11:00:00"}
    get("/material/changes", params)

接口生产环境信息

餐链开放平台请求的基础地址为:

http://openapi.mealcome.cn

接口特别说明

  • 所有涉及到地址位置坐标的,均使用的是百度坐标系

接口更新日志

随着使用方需求变更已经系统升级,OpenAPI接口可能会发生改变。

相应的改变会记录在此文档内。