<?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. win10 + 独显 + Anaconda3 + tensorflow_gpu1.13 安装教程(跑bert模型)

    这里面有很多坑,最大的坑是发现各方面都装好了结果报错  Loaded runtime CuDNN library: 7.3.1 but source was compiled with: 7.4.1, ...

  2. PHP两个变量值互换(不用第三变量)

    <?php /**  * 双方变量为数字或者字符串时  * 使用list()和array()方法可以达到交换变量值得目的  */ $a = "This is A"; // a ...

  3. 【u212】&&【t036】最大和

    Time Limit: 1 second Memory Limit: 128 MB [问题描述] N个数围成一圈,要求从中选择若干个连续的数(注意每个数最多只能选一次)加起来,问能形成的最大的和. [ ...

  4. 2018-12-25-WPF-如何在-WriteableBitmap-写文字

    title author date CreateTime categories WPF 如何在 WriteableBitmap 写文字 lindexi 2018-12-25 09:13:57 +080 ...

  5. Jenkins 配置自动合并 release 分支到 master 分支

    本文告诉大家如何在 Jenkins 配置合并到 release 的内容自动合并到 gitlab 的 master 分支 首先需要两个仓库,一个是 gitlab 的仓库,另一个是 Jenkins 的仓库 ...

  6. 前端导出&配置问题

    <button class="search" onclick="method5('dataTable');">导出</button> 在 ...

  7. 一道非常棘手的 Java 面试题:i++ 是线程安全的吗

    转载自  一道非常棘手的 Java 面试题:i++ 是线程安全的吗 i++ 是线程安全的吗? 相信很多中高级的 Java 面试者都遇到过这个问题,很多对这个不是很清楚的肯定是一脸蒙逼.内心肯定还在质疑 ...

  8. 纯CSS制作空心三角形和实心三角形及其实现原理

    纯CSS制作空心三角形和实心三角形及其实现原理 在一次项目中需要使用到空心三角形,我瞬间懵逼了.查阅了一些资料加上自己的分析思考,终于是达到了效果,个人感觉制作三角形是使用频率很高的,因此记录下来,供 ...

  9. POJ - 3415 Common Substrings (后缀数组)

    A substring of a string T is defined as: T( i, k)= TiTi +1... Ti+k -1, 1≤ i≤ i+k-1≤| T|. Given two s ...

  10. jenkins+Git+Gitlab+Ansible实现持续集成自动化部署静态网站(二)

    引言:首先我们可以实现一键部署网站,但在实际生产环境网站部署完成之后,我们的开发隔三差五要修改下网站的内容,难道都要我们运维手动执行命令吗?没有一种方法使得开发人员修改完代码自己测试,部署上线呢,那这 ...