<?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); } /** * 刷新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; } }