最近对接美团配送,在初次调用接口的时候,就遇到了几个坑,尽管美团配送开发文档比较规范,可还是有不够详尽的地方,在对接的时候容易踩坑。
一、参数传递
在调用接口传参的时候,都使用post请求方式,我尝试了将参数以数组、json、XML的形式传递,皆返回错误信息:缺少xxx参数,我仔细检查,参数都有!
没办法对接到他们的技术,而且他们的客服又不懂,能查的资料又很少,费好大劲终于知道参数要自己拼接成类似于a=&c=3&b=1的字符串,然后传递过去。
二、签名加密
鉴于参数传递要拼接成key1=value1&key2=value2的形式,我就偷懒直接使用了http_build_query()函数来处理参数,结果一直报签名错误。
原因在于:http_build_query()方法会将中文进行urlencode编码,也就是自己在生成签名的时候,用的是中文,但是传递参数的时候中文就成了urlencode编码之后的字符串,很自然而然的对不上。
原始数据:
$product = [
'id' => 1,
'title' => '茅台飞天52°',
'product_class_title' => '酒水/饮料',
'price' => 9.01,
];
http_build_query()函数处理后数据:
id=1&title=%E8%8C%85%E5%8F%B0%E9%A3%9E%E5%A4%A952%C2%B0&product_class_title=%E9%85%92%E6%B0%B4%2F%E9%A5%AE%E6%96%99&price=9.01
实际需要的数据:
id=1&title=茅台飞天52°&product_class_title=酒水/饮料&price=9.01
解决方法:勤快点,自己手动拼接参数,方法如下:
/**
* Notes:构造请求参数
* @param array $params
* @return string
* Author: 江南极客
* Date: 2020/7/16
*/
public static function buildParams($params = []){
if(empty($params)){
throw new \LogicException('缺少请求参数',2);
}
//系统参数(美团系统参数)
$sys_params = [
'appkey' => static::getConfig('app_key'),
'timestamp' => time(),
'version' => '1.0',
];
if(static::$is_debug){
$sys_params['appkey'] = static::getConfig('test_app_key');
}
//将系统参数和业务参数合并
$mt_params = array_merge($sys_params,$params);
//将合并后的参数,进行签名加密
$mt_params['sign'] = self::sign($mt_params);
//构造参数,将参数拼接成key1=value1&key2=value2的形式
$post_data = '';
foreach ($mt_params as $k => $v){
$post_data .= $k.'='.$v.'&';
}
$post_data = substr($post_data,0,-1);
return $post_data;
}
/**
* Notes:参数加密
* @param array $params
* @return string
* Author: 江南极客
* Date: 2020/7/16
*/
private static function sign($params = [])
{
$secret = static::getConfig('app_secret');
if(static::$is_debug){
$secret = static::getConfig('test_app_secret');
}
if(empty($params) || empty($secret)){
throw new \LogicException('构造参数缺失',2);
}
$signPars = "";
ksort($params);
foreach($params as $k => $v) {
if("" != $v && "sign" != $k) {
$signPars .= $k.$v;
}
}
$signPars = $secret . $signPars;
$sign = strtolower(sha1($signPars));
return $sign;
}
/**
* Notes:验签(美团配送订单回调的时候,对要对回调接收的参数进行验签)
* @param $params
* @return bool
* Author: 江南极客
* Date: 2020/7/24
*/
public static function verifyMtSign($params)
{
try{
if(empty($params) || empty($params['sign'])){
throw new \LogicException('参数错误');
}
$get_sign = $params['sign'];
unset($params['sign']);
$new_sign = self::sign($params);
if($get_sign != $new_sign){
throw new \LogicException('验签失败');
}
return true;
}catch (\LogicException $exception){
return false;
}
}
三、联调测试接口
联调接口: https://peisongopen.meituan.com/api/test/order/arrange (根据文档说明,容易弄错)