<?php
# 一开始使用的是API方式对接,所以我这里是API的方式+SDK的结合 (除了获取token之外都是使用SDK方式,所以看到的朋友还是直接使用纯SDK方式对接最好),因为我这里使用API的方式获取存储 token 所以我在饿了么的SDK包中有需要使用的方法中 把原来调token的方式注释了,用我自己的!
# 兄弟们不要学我,如果有SDK最好还是全用SDK的好! 我后面也会改全用SDK
# 需要注意引入路劲 其他的大多数再SDK都给你写好了 饿了么的SDK到开放平台下载,有意思的是,他给的推送响应参数示例和给出的响应结构体有个别少数存在参数单词错误,不对应。(例:响应结构体中给 shop_name,在响应示例中给的可能是 shopName)。 需要自己仔细看报错信息(如果有的话,至少我在修改店铺信息的时候遇到了)。
# 目前我下载的这版本SDK中饿了么已将返回的json字符串做了转数组的操作。
# 当然我这里还有部分需要优化的 我这里就先简单粗暴
# 为了不麻烦,建议大伙写一个排程,定时每多少天(正式环境     30天     35天,沙箱环境     1天     15天)的某个点自动更新token 防止过期
# 这里特别注意:我后期的修改为 拿到确认付款订单的id直接保存临时表,之后单独排程跑这张临时表 拿订单id去饿了么获取订单详情 立马返回“ok”给饿了么,因为饿了么那边回再3秒内(若没有接收到我们的回复 会再次推送),一开始我理解成了3秒,但是后来上了当 才明白他说的3秒内是什么意思。
     根据我的日志显示 他几乎在同一秒推了我俩次,导致我数据库存了相同的订单【判断有相同也没用】
# 饿了么开发者账号信息  企业用户服务器必须在阿里云 因为饿了么对接的是阿里的蜂鸟快递(企业对接也必须使用他们的快递 否则需要申请个人应用 个人应用和企业的对接方式基本一样,需要注意的是个人应用获取TOKEN的方式略有不同) 测试环境 推送信息栏可多选,你需要什么就选什么。

这里需要配置授权店铺 授权完成之后,pc端点击上图的“前往登录” 即可登录到测试店铺,需要配置店铺信息 修改店铺定位(手机进入测试店铺会自动定位你的位置 不修改测试店铺的定位 可能造成超出配送范围)

手机访问上图中的 测试店铺URL 就可以下单了。pc端点击上图的“前往登录” 即可登录到测试店铺





class ELMController extends commonController {
const SANDBOX_KEY = '你的 SANDBOX_KEY';
const SANDBOX_SECRET = '你的 SANDBOX_SECRET'; # 正式饿了么开发参数
const KEY = '';
const SECRET = ''; # 饿了么 沙箱 + 正式 获取TOKEN 地址 【因为我是用API的方式去获取token 所以我这里需要保留】
const ELM_SANDBOX_TOKEN_URL = 'https://open-api-sandbox.shop.ele.me/token';
const ELM_TOKEN_URL = 'https://open-api.shop.ele.me/token'; # 回调地址
const JT_TEST_URL = '你的测试回调地址';
const ZP_URL = '你的正式回调地址'; /**
* 获取授权地址
*/
public function getOauthUrlAction(){
$Config = Config::getInstance();
$webSite = $Config->getWebSiteConfig();
$secret = (($webSite['debug']) ? self::SANDBOX_SECRET : self::SECRET);
$key = (($webSite['debug']) ? self::SANDBOX_KEY : self::KEY);
$Rurl = (($webSite['debug']) ? self::JT_TEST_URL : self::ZP_URL).'?md=service&cl=ELM&at=ELMReturn';
$config = new ElemeOpenApi\Config\Config($key,$secret,$webSite['debug']);
$UserService = new ElemeOpenApi\OAuth\OAuthClient($config);
$UUIDStr = $this->UUIDStr();
$r = $UserService->get_auth_url($UUIDStr,'all',$Rurl);
file_put_contents('logs/OauthUrl.log', date('Y-m-d H:i:s') . ' reception:' . $r . PHP_EOL, FILE_APPEND);
echo '<pre>';
var_dump($r);die;
} /**
* 获取饿了么推送订单
*/
public function ELMOrdersAction() {
$cancelOrderData = file_get_contents("php://input");
file_put_contents('logs/Porders.log', date('Y-m-d H:i:s') . ' reception:' . $cancelOrderData . ' &end' . PHP_EOL, FILE_APPEND);
$orderDatas = json_decode($cancelOrderData, true);
$orderInfo = json_decode($orderDatas['message'], true);
$Order = $this->getOrdersAction($orderInfo['orderId']); # 订单详情
# 店铺详情
$Store = $this->getStoresByStoreIDAction($orderInfo['shopId']);
file_put_contents('logs/synthesize_store.log', date('Y-m-d H:i:s') . ' storeInfo:' . json_encode($Store) .' &' . PHP_EOL, FILE_APPEND);
file_put_contents('logs/synthesize_order.log', date('Y-m-d H:i:s') . ' orderInfo:' . json_encode($Order) .' &' . PHP_EOL, FILE_APPEND);
echo '<pre>';
var_dump($Order);
var_dump($Store);
# 以下是第一次配置推送URL的时候 需要给饿了么返的信息,如果没有,或者写错 都可能造成回调地址配置不成功的问题。
$r = ['message'=>'ok'];
echo json_encode($r);
} /**
* 回调 很多地方需要用到
   * 获取 code
*/
public function ELMReturnAction() {
$Config = Config::getInstance();
$webSite = $Config->getWebSiteConfig();
$key = (($webSite['debug']) ? self::SANDBOX_KEY : self::KEY);
$Rurl = (($webSite['debug']) ? self::JT_TEST_URL : self::ZP_URL).'?md=service&cl=ELM&at=ELMReturn';
$Tokencurl = (($webSite['debug']) ? self::ELM_SANDBOX_TOKEN_URL : self::ELM_TOKEN_URL);
$TokenParameter['code'] = $_GET['code'];
$TokenParameter['grant_type'] = 'authorization_code';
$TokenParameter['redirect_uri'] = $Rurl;
$TokenParameter['client_id'] = $key;
if(!empty($TokenParameter['code'])){
$tr = $this->GetAccessToken($Tokencurl, $TokenParameter);
file_put_contents('logs/getToken.log', date('Y-m-d H:i:s') .$tr. PHP_EOL, FILE_APPEND); $TokenData = json_decode($tr, true);
$TokenData['t'] = time();
# 令牌有效时间,单位秒,在令牌有效期内可以重复使用。有效期限制(access_token:沙箱环境为1天、正式环境为30天,refresh_token:沙箱环境为15天、正式环境为35天)
file_put_contents('logs/TokenStr.txt', json_encode($TokenData)); echo '<pre>';
var_dump($TokenData);
} } /**
* 刷新token
* curl -i -XPOST -H "Content-Type: application/x-www-form-urlencoded"
* -H "Authorization: Basic OU9LV2JtVXJLcjoyZGRiZTc2NTkzOWZhZjI5ZDEwNTU3MDg3MzVjOGViNw=="
* -d "grant_type=refresh_token&refresh_token=21a5b98083e13676c5fc3948df4f0852"
* https://open-api-sandbox.shop.ele.me/token
*/
public function refreshTokenAction($refresh_token) {
$Config = Config::getInstance();
$webSite = $Config->getWebSiteConfig();
$Tokencurl = (($webSite['debug']) ? self::ELM_SANDBOX_TOKEN_URL : self::ELM_TOKEN_URL);
$TokenParameter['grant_type'] = 'refresh_token';
$TokenParameter['refresh_token'] = $refresh_token;
$tr = $this->GetAccessToken($Tokencurl, $TokenParameter);
$TokenData = json_decode($tr, true);
$TokenData['t'] = time();
file_put_contents('logs/refreshToken.log', date('Y-m-d H:i:s') . ' reception:' . $tr . PHP_EOL, FILE_APPEND);
file_put_contents('logs/TokenStr.txt', json_encode($TokenData));
return $TokenData;
} /**
* 获取Token
* @param $url
* @param $post_data
* @return bool|false|string
* curl -i -XPOST -H "Content-Type: application/x-www-form-urlencoded"
* -H "Authorization: Basic OU9LV2JtVXJLcjoyZGRiZTc2NTkzOWZhZjI5ZDEwNTU3MDg3MzVjOGViNw=="
* -d "grant_type=authorization_code&code=f5d9280fce5cedc761f1f19ef484e7e0&redirect_uri=[redirect_uri]&client_id=9OKWbmUrKr"
* https://open-api-sandbox.shop.ele.me/token
*/
function GetAccessToken($url, $post_data) {
$Config = Config::getInstance();
$webSite = $Config->getWebSiteConfig();
$key = (($webSite['debug']) ? self::SANDBOX_KEY : self::KEY);
$secret = (($webSite['debug']) ? self::SANDBOX_SECRET : self::SECRET);
$Basic = base64_encode($key .":". $secret);
$header_data[] = "Content-type:application/x-www-form-urlencoded";
$header_data[] = "Authorization:Basic ". $Basic;
$ch = curl_init();
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HTTPHEADER, $header_data);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($post_data));
$sResult = curl_exec($ch);
if($sError=curl_error($ch)){
die($sError);
}
curl_close($ch);
return $sResult;
} /**
* 获取饿了么订单 根据id
* @param $K 应用的app key
* @param $orderID 订单ID
*/
public function getOrdersAction($orderID){
$Config = Config::getInstance();
$webSite = $Config->getWebSiteConfig();
$secret = (($webSite['debug']) ? self::SANDBOX_SECRET : self::SECRET);
$key = (($webSite['debug']) ? self::SANDBOX_KEY : self::KEY);
$str = file_get_contents('logs/TokenStr.txt');
$str = json_decode($str,true);
$token = $str['access_token'];
$ntime = time();
$otime = $str['t'];
$expires_in = $str['expires_in'];
$otime = $otime + ($expires_in - 60); # 我这边所有使用到token的地方 过期时间都会减去一分钟 判断提前过期,防止存在时差
if($ntime >= $otime){
$TokenData = $this->refreshTokenAction($str['refresh_token']);
$token = $TokenData['access_token'];
}
$config = new ElemeOpenApi\Config\Config($key,$secret,$webSite['debug']);
$UserService = new \ElemeOpenApi\Api\OrderService($token,$config);
$r = $UserService->get_order($orderID);
file_put_contents('logs/order_ID_log', date('Y-m-d H:i:s') . ' reception:' . json_encode($r) . PHP_EOL, FILE_APPEND);
return $r;
// echo '<pre>';
// var_dump($r);die;
} /**
* 获取门店ID 通过token
* Q:我想知道哪个token对应哪个门店,我该如何获取店铺ID?(门店授权如何知道这是哪家门店?)
* A:可以调取接口eleme.user.getUser 获取店铺ID。
*/
public function getStoresAction() {
$Config = Config::getInstance();
$webSite = $Config->getWebSiteConfig();
$secret = (($webSite['debug']) ? self::SANDBOX_SECRET : self::SECRET);
$key = (($webSite['debug']) ? self::SANDBOX_KEY : self::KEY);
$str = file_get_contents('logs/TokenStr.txt');
$str = json_decode($str,true);
$token = $str['access_token'];
$ntime = time();
$otime = $str['t'];
$expires_in = $str['expires_in'];
$otime = $otime + ($expires_in - 60);
if($ntime >= $otime){
$TokenData = $this->refreshTokenAction($str['refresh_token']);
$token = $TokenData['access_token'];
}
$config = new ElemeOpenApi\Config\Config($key,$secret,$webSite['debug']);
$UserService = new ElemeOpenApi\Api\UserService($token,$config);
$r = $UserService->get_user();
file_put_contents('logs/order_token_log.log', date('Y-m-d H:i:s') .json_encode($r). PHP_EOL, FILE_APPEND); echo '<pre>';
var_dump($r);
} /**
* 获取门店信息 通过店铺ID
*/
public function getStoresByStoreIDAction($storeID) {
$Config = Config::getInstance();
$webSite = $Config->getWebSiteConfig();
$secret = (($webSite['debug']) ? self::SANDBOX_SECRET : self::SECRET);
$key = (($webSite['debug']) ? self::SANDBOX_KEY : self::KEY);
$str = file_get_contents('logs/TokenStr.txt');
$str = json_decode($str,true);
$token = $str['access_token'];
$ntime = time();
$otime = $str['t'];
$expires_in = $str['expires_in'];
$otime = $otime + ($expires_in - 60);
if($ntime >= $otime){
$TokenData = $this->refreshTokenAction($str['refresh_token']);
$token = $TokenData['access_token'];
}
$config = new ElemeOpenApi\Config\Config($key,$secret,$webSite['debug']);
$ShopService = new \ElemeOpenApi\Api\ShopService($token,$config);
$r = $ShopService->get_shop($storeID);
file_put_contents('logs/getStoresByStoreID.log', date('Y-m-d H:i:s') .json_encode($r). PHP_EOL, FILE_APPEND); return $r;
// echo '<pre>';
// var_dump($r);
} /**
* 修改店铺
*/
public function updateStoreAction() {
$Config = Config::getInstance();
$webSite = $Config->getWebSiteConfig();
$secret = (($webSite['debug']) ? self::SANDBOX_SECRET : self::SECRET);
$key = (($webSite['debug']) ? self::SANDBOX_KEY : self::KEY);
$str = file_get_contents('logs/TokenStr.txt');
$str = json_decode($str,true);
$token = $str['access_token'];
$ntime = time();
$otime = $str['t'];
$expires_in = $str['expires_in'];
$otime = $otime + ($expires_in - 60);
if($ntime >= $otime){
$TokenData = $this->refreshTokenAction($str['refresh_token']);
$token = $TokenData['access_token'];
} $shopID = 305179207;
$properties = array();
$properties["addressText"] = "上海市长宁区龙溪路虹桥路1923号";
$properties["geo"] = "121.223,31.233";
$properties["agentFee"] = 3.0;
$properties["closeDescription"] = "正常营业";
$properties["deliverDescription"] = "超过5公里,100元起送";
// $properties["deliverGeoJson"] = '{"type":"FeatureCollection","features":[{"geometry":{"type":"Polygon","coordinates":[[[121.381303,31.243521],[121.380938,31.242778],[121.381679,31.243297],[121.381303,31.243521]]]},"type":"Feature","properties":{"area_agent_fee":20,"delivery_price":10,"manual_weight":0,"system_weight":0,"weight_type\":1}}]}';
$properties["description"] = "便宜好吃的小食";
$properties["name"] = "烤鸭大王";
$properties["isBookable"] = 1;
$properties["openTime"] = "10:00-13:00,18:00-21:00";
$properties["phone"] = "13666666666";
// $properties["logoImageHash"] = "13666666666";
$properties["promotionInfo"] = "本周全场半价";
$properties["invoice"] = 1;
$properties["invoiceMinAmount"] = 100.0;
$properties["noAgentFeeTotal"] = 20.0;
$properties["isOpen"] = 1;
$properties["packingFee"] = 2.0;
$properties["openId"] = "10046"; $config = new ElemeOpenApi\Config\Config($key,$secret,$webSite['debug']);
$ShopService = new \ElemeOpenApi\Api\ShopService($token,$config);
$r = $ShopService->update_shop($shopID, $properties); file_put_contents('logs/updateStore.log', date('Y-m-d H:i:s') .json_encode($r). PHP_EOL, FILE_APPEND); echo '<pre>';
var_dump($r);
} /**
* POST 请求 API
* @param $url
* @param $post_data
* @return bool|string
*/
function http_post($url, $post_data) {
$header_data[] = "application/json;charset=utf-8";
$ch = curl_init();
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HTTPHEADER, $header_data);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($post_data));
$sResult = curl_exec($ch);
$info = curl_getinfo($ch);
if($sError=curl_error($ch)){
die($sError);
}
curl_close($ch);
print_r($info);
return $sResult;
} /**
* @return string 随机字符串
*/
private function UUIDStr(){
return sprintf('%04x%04x-%04x-%04x-%04x-%04x%04x%04x',
mt_rand(0, 0xffff), mt_rand(0, 0xffff),
mt_rand(0, 0xffff),
mt_rand(0, 0x0fff) | 0x4000,
mt_rand(0, 0x3fff) | 0x8000,
mt_rand(0, 0xffff), mt_rand(0, 0xffff), mt_rand(0, 0xffff)
);
}
}

PHP 对接 饿了么开放平台 接单的更多相关文章

  1. 基于PHP的对接免费电子面单接口平台的案例-快宝开放平台

    一.电子面单对接平台 电子面单对接平台分为两类: 1 .各大快递公司自有的电子面单接口开放平台:对接起来麻烦,需要每个快递公司分别调试接口,费时费力. 2 .第三方快递开放平台:如快宝开放平台(htt ...

  2. 基于PHP的地址智能解析案例-快宝开放平台

    快宝地址智能解析,批量录入收件人.发件人最好的解决方案,广泛应用于快递行业,电商行业,ERP应用等. 一.对接前准备 注册快宝开放平台,获得开发者账号,查看如何注册. 二.对接联调 快宝开放平台支持多 ...

  3. 基于PHP的地址清洗调用案例-快宝开放平台

    快宝地址清洗,纠正错误地址.识别不完整地址.地址补全,并输出结构化地址数据的通用解决方案.广泛应用于快递行业,电商行业,ERP应用等. 快宝开放平台-地址清洗对接API:http://open.kua ...

  4. 基于PHP的快递查询免费开放平台案例-快宝开放平台

    快递查询是快递业务中极其重要的业务,免费的快递查询开放平台:快宝开放平台. 快宝开放平台:http://open.kuaidihelp.com/home,已经对接100多家快递公司,实现快递物流信息实 ...

  5. 各种电子面单Api接口免费对接-快宝开放平台

    1.什么是电子面单? 快递公司联合向商家提供的一种通过热敏纸打印输出纸质物流面单的物流服务,并且承载分单自动化算法等数据服务,是快递行业赋能的基础产品和服务. 2.电子面单长什么样? 各快递公司有自己 ...

  6. 淘宝开放平台TOP SDK调用对接淘宝或天猫

    如果在淘宝/天猫上开了网店,用户自己也有一套自己的管理平台,这时可能会考虑和淘宝进行数据对接.这就需要考虑调用阿里提供的开发接口来推送和接收数据. 对接的方式有2种,一种是通过http接口,另外一种是 ...

  7. 【IoT】物联网NB-IoT之电信物联网开放平台对接流程浅析

    版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明.本文链接:https://blog.csdn.net/liwei16611/article/de ...

  8. Java对接拼多多开放平台API(加密上云等全流程)

    前言 本文为[小小赫下士 blog]原创,搬运请保留本段,或请在醒目位置设置原文地址和原作者. 作者:小小赫下士 原文地址:Java对接拼多多开放平台API(加密上云等全流程) 本文章为企业ERP(I ...

  9. 各开放平台API接口通用 SDK 前言

    最近两年一直在做API接口相关的工作,在平时工作中以及网上看到很多刚接触API接口调用的新人一开始会感到很不适应,包括自己刚开始做API接口调用的相关工作时,也是比较抓狂的,所有写一序列文章把之前的工 ...

随机推荐

  1. redis 写入数据 越来越慢 是什么原因

    redis并不会因为key的增加而导致写入明显变慢,肯定是其他因素.如果redis开启了持久化,在进行持久化时,性能必然下降,可以使用config命令查看持久化设置了没有.另外考虑是否是内存不足,一般 ...

  2. windows/Linux/Mac下安装maven,maven作用

    Linux下安装maven 1.首先到Maven官网下载安装文件,目前最新版本为3.0.3,下载文件为apache-maven-3.3.9-bin.tar.gz,下载可以使用wget命令: 2.进入下 ...

  3. linux mysql 查看默认端口号和修改端口号

    如何查看mysql 默认端口号和修改端口号 2015-03-19 17:42:18 1. 登录mysql [root@test /]# mysql -u root -p Enter password: ...

  4. P1082 数列分段

    题目描述 对于给定的一个长度为 \(N\) 的正整数数列 \(A_i\) ,现要将其分成连续的若干段,并且每段和不超过 \(M\) (可以等于 \(M\) ),问最少能将其分成多少段使得满足要求. 输 ...

  5. win10 uwp 使用 LayoutTransformer

    如果需要使用旋转,那么很容易把图片旋转的布局被裁剪.如果需要旋转的控件还在指定的 Grid 内,就需要使用布局的旋转.本文告诉大家如何使用 LayoutTransformer.需要知道,uwp是没有 ...

  6. HDU 1540 Tunnel Warfare (线段树)

    Tunnel Warfare Problem Description During the War of Resistance Against Japan, tunnel warfare was ca ...

  7. C# 命令行如何静默调用 del 删除文件

    如果在 C# 命令行调用 del 删除文件,很多时候会提示是否需要删除,本文告诉大家如何调用命令行的时候静默删除 在C# 命令行 调用 del 删除文件的时候,会提示是否删除,通过在命令行加上 \Q ...

  8. linux seqlock 锁

    内核包含了一对新机制打算来提供快速地, 无锁地存取一个共享资源. seqlock 在这 种情况下工作, 要保护的资源小, 简单, 并且常常被存取, 并且很少写存取但是必须要快. 基本上, 它们通过允许 ...

  9. Codevs 四子连棋 (迭代加深搜索)

    题目描述 Description 在一个4*4的棋盘上摆放了14颗棋子,其中有7颗白色棋子,7颗黑色棋子,有两个空白地带,任何一颗黑白棋子都可以向上下左右四个方向移动到相邻的空格,这叫行棋一步,黑白双 ...

  10. logisim自动生成电路

    之前再做有关logisim有关的实验时,一直在傻乎乎地连线,而我是看了mooc有关的视频时,才知道logisim有自动连线的功能. 自动连线需要事先知道输入与输出的真值表或者全部的表达式,将其填入lo ...