PHP 对接 饿了么开放平台【企业】 接单


<?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 '
';
        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 '
';
        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 '
';
//        var_dump($r);die;
    }


}