Skip to main content

接入必读

接口地址

环境地址
生产https://openapi-neptune.meituan.com/
测试https://openapineptune.test.sankuai.com/

|

协议说明

  • 提交方式:采用POST方式提交
  • 数据格式:提交和返回数据都为JSON格式
  • 字符编码:统一采用UTF-8字符编码
  • 签名算法:HMAC-SHA1
  • 签名要求:请求参数需要校验签名,详细方法请参考安全规范

接口公共参数

公共请求参数
参数类型示例示例
accessKeyString883838483843843访问Key
methodStringDevice.Surrounding.QueryQrCode
formatStringJSON仅支持JSON
charsetStringutf-8仅支持utf-8
signTypeStringHMAC-SHA1签名算法类型
signString详见安全规范请求参数的签名串
timestampString20210224120000请求的时间,格式"yyyyMMddHHmmss"
versionString1.0接口版本,固定为:1.0
nonceString112121313131唯一随机数。用于防止网络重放攻击,用户在不同请求中要使用不同的随机数值
bizContentString{\"para1\":\"value1\",\"para2\":\"value2\"}JSON格式的字符串,代码如: QuerySurroundingQrCodeRequest request = new QuerySurroundingQrCodeRequest(); request.setDeviceId("device1");则bizContent为JsonUtil.Serialize(request)
请求示例
{
"accessKey" : "LTAI5tCTTPxEQ9UKYtDf1234",
"bizContent" : "{\"para1\":\"value1\",\"para2\":\"value2\"}",
"charset" : "utf-8",
"format" : "JSON",
"method" : "device.livein.wmall",
"nonce" : "12920",
"sign" : "KZCVHFeDinsjqcAWpq7DSJ4UlCI=",
"signType" : "HMAC-SHA1",
"timestamp" : "20220505102024",
"version" : "1.0"
}
公共响应参数
参数类型示例示例
codeint0公共返回码
messageString成功返回描述
dataObject业务响应参数
requestIdString请求唯一标识
响应示例
{
"code": 0,
"message": "成功",
"data": {
"url": "http://yyy.com",
"qrCode": null
},
"requestId": "-8772792304184320571"
}

安全规范

  1. 排序拼接:将公共请求参数(sign除外)按照参数名ASCII码从小到大排序(字典序),使用URL键值对的格式,形如:PlainString=key1=value1&key2=value2…
  2. URL编码:对步骤1得到的plainStr进行URL编码,结果为StringToSign,形如:StringToSign=URLEncoder.encode(PlainString,"utf8")
  3. 计算HMAC的字节码:使用步骤2得到的字符串StringToSign计算签名HMAC值。形如: SignatureByte =HMAC-SHA1( AccessSecret, StringToSign)
  4. 计算签名值:按照Base64编码规则把步骤3中的HMAC值编码成字符串,即得到签名值(Signature),形如:Signature= Base64(SignatureByte)
  • 备注:签名参数时:sign参数需要去掉、空值参数参与签名计算

签名示例

以调用周边游二维码接口为例。假设您的AccessKey=1234567890123456,AccessKeySecret=123456789012345678901234567890,DeviceId=device1

  1. 排序拼接: accessKey=1234567890123456&bizContent={"deviceId":"device1"}&charset=utf-8&format=JSON&method=Device.Surrounding.QueryQrCode&nonce=123330230554&signType=HMAC-SHA1&timestamp=20211125120000&version=1.0
  2. URL编码: accessKey%3D1234567890123456%26bizContent%3D%7B%22deviceId%22%3A%22device1%22%7D%26charset%3Dutf-8%26format%3DJSON%26method%3DDevice.Surrounding.QueryQrCode%26nonce%3D123330230554%26signType%3DHMAC-SHA1%26timestamp%3D20211125120000%26version%3D1.0
  3. 计算签名: LAk2gNVUlujfttI3dKhGMAtB7n8=

Java代码示例

以下为签名的Java Demo供您参考

  1. 配置文件IotConfig.java
public class IotConfig {
public static String accessKey = "1234567890123456";
public static String accessKeySecret = "123456789012345678901234567890";

public final static String CHARSET_UTF8 = "utf8";
}
  1. 签名工具SignatureUtil.java
public class SignatureUtil {
private final static String CHARSET_UTF8 = "utf8";
private final static String ALGORITHM = "HmacSHA1";
private final static String SEPARATOR = "&";

public static Map<String, String> splitQueryString(String url)
throws URISyntaxException, UnsupportedEncodingException {
URI uri = new URI(url);
String query = uri.getQuery();
final String[] pairs = query.split("&");
TreeMap<String, String> queryMap = new TreeMap<String, String>();
for (String pair : pairs) {
final int idx = pair.indexOf("=");
final String key = idx > 0 ? pair.substring(0, idx) : pair;
if (!queryMap.containsKey(key)) {
queryMap.put(key, URLDecoder.decode(pair.substring(idx + 1), CHARSET_UTF8));
}
}
return queryMap;
}

public static String generate(Map<String, String> parameter, String accessKeySecret)
throws Exception {
String plainString = generateSignString(parameter);
System.out.println("plainString---" + plainString);
String stringToSign = URLEncoder.encode(plainString, CHARSET_UTF8);
System.out.println("stringToSign---" + stringToSign);
byte[] signBytes = hmacSHA1Signature(accessKeySecret, stringToSign);
String signature = newStringByBase64(signBytes);
System.out.println("signature----" + signature);
return signature;
}

public static String generateSignString(Map<String, String> parameter) throws IOException {
TreeMap<String, String> sortParameter = new TreeMap<>(parameter);

StringBuilder signBuilder = new StringBuilder();
for (Map.Entry<String, String> entry : sortParameter.entrySet()) {
signBuilder.append(entry.getKey()).append("=").append(entry.getValue()).append("&");
}
if (signBuilder.length() > 1) {
signBuilder.setLength(signBuilder.length() - 1);
}
return signBuilder.toString();
}

public static byte[] hmacSHA1Signature(String secret, String baseString) throws Exception {
if (StringUtils.isEmpty(secret)) {
throw new IOException("secret can not be empty");
}
if (StringUtils.isEmpty(baseString)) {
return null;
}
Mac mac = Mac.getInstance("HmacSHA1");
SecretKeySpec keySpec = new SecretKeySpec(secret.getBytes(CHARSET_UTF8), ALGORITHM);
mac.init(keySpec);
return mac.doFinal(baseString.getBytes(CHARSET_UTF8));
}

public static String newStringByBase64(byte[] bytes) throws UnsupportedEncodingException {
if (bytes == null || bytes.length == 0) {
return null;
}
return new String(Base64.encodeBase64(bytes, false), CHARSET_UTF8);
}
}
  1. 入口文件IotSignatureTest.java
public class IotSignatureTest {
// 1.需要修改Config.java中的AccessKey信息。
// 2.建议使用方法二,所有参数都需要一一填写。
// 3."最终signature"才是您需要的签名最终结果。
public static void main(String[] args) throws UnsupportedEncodingException {
// 方法一
System.out.println("方法一:");
String str = "accessKey%3D1234567890123456%26bizContent%3D%7B%22
deviceId%22%3A%22device1%22%7D%26charset%3Dutf-8%26format%3DJSON%26method%3DDevice.Surrounding.QueryQrCode
%26nonce%3D123330230554%26signType%3DHMAC-SHA1%26timestamp%3D20211125120000%26version%3D1.0";
byte[] signBytes;
try {
signBytes = SignatureUtil.hmacSHA1Signature(IotConfig.accessKeySecret, str);
String signature = SignatureUtil.newStringByBase64(signBytes);
System.out.println("signString---" + str);
System.out.println("最终signature----" + signature);
} catch (Exception e) {
e.printStackTrace();
}
System.out.println();

// 方法二
System.out.println("方法二:");
Map<String, String> map = new HashMap<String, String>();
// 请求参数
QuerySurroundingQrCodeRequest request = new QuerySurroundingQrCodeRequest();
request.setDeviceId("device1");
// 公共参数
map.put("accessKey", IotConfig.accessKey);
map.put("method", "Device.Surrounding.QueryQrCode");
map.put("format", "JSON");
map.put("charset", "utf-8");
map.put("signType", "HMAC-SHA1");
map.put("timestamp", "20211125120000");
map.put("version", "1.0");
map.put("nonce", "123330230554");
map.put("bizContent", JsonUtil.Serialize(request));
try {
String signature = SignatureUtil.generate(map, IotConfig.accessKeySecret);
System.out.println("最终signature: " + signature);
} catch (Exception e) {
e.printStackTrace();
}
System.out.println();
}
}