顺丰开放平台API PHP SDK demo
in PHP with 6 comments

顺丰开放平台API PHP SDK demo

in PHP with 6 comments

顺丰开放平台Api PHP SDK demo

引用

顺丰开放平台
接口接入规范 V1.1.6

对接前期工作

接入注意事项

Demo

SDK Demo

<?php
/**
 * 顺丰 api 接口使用
 * Date: 2017/10/19
 * Time: 9:36
 * @author zlh <root@rooot.me>
 */

class SfApi {

    /**
     * @var string
     */
    protected $app_id;

    /**
     * @var string
     */
    protected $app_key;

    /**
     * @var string
     */
    public $access_token;

    /**
     * @var string
     */
    public $refresh_token;

    /**
     * @var string
     */
    private $uri;

    /**
     * SfApi constructor.
     * @param string  $app_id
     * @param string $app_key
     * @param bool $online
     * @return void
     */
    public function __construct ($app_id, $app_key, $online = false) {
        $this->app_id = $app_id;
        $this->app_key = $app_key;
        $this->url = $online ? 'https://open-prod.sf-express.com/' : 'https://open-sbox.sf-express.com/';
    }

    /**
     * 快速创建订单
     * @param array $req_body
     * @return bool|string
     */
    public function order ($req_body) {
        $req_body = array(
            'orderId' => $req_body['orderId'],
            'expressType' => $req_body['expressType'],
            'payMethod' => $req_body['payMethod'],
            'custId' => $req_body['custId'],
            'payArea' => isset($req_body['payArea']) ? $req_body['payArea'] : 'SFCM10008035754399',
            //'remark' => $req_body['remark'],
            'consigneeInfo' => array(
                'company' => isset($req_body['consigneeInfo']['company']) ? $req_body['consigneeInfo']['company'] : '个人',
                'contact' => $req_body['consigneeInfo']['contact'],
                'tel' => $req_body['consigneeInfo']['tel'],
                'province' => $req_body['consigneeInfo']['province'],
                'city' => $req_body['consigneeInfo']['city'],
                'county' => $req_body['consigneeInfo']['county'],
                'address' => $req_body['consigneeInfo']['address'],
                'mobile' => $req_body['consigneeInfo']['mobile'],
            ),
            'cargoInfo' => array(
                'cargo' => $req_body['cargoInfo']['cargo'],
            ),
            'addedServices' => $req_body['addedServices'],
        );

        $res = $this->send('order', $req_body);
        $res_tmp = json_decode($res, true);

        if(empty($res_tmp['head']['code'])) {
            return '系统错误!';
        }elseif(substr($res_tmp['head']['code'], -3) != '200') {
            return $res_tmp['head']['message'];
        }else{
            return true;
        }
    }

    /**
     * 订单结果查询
     * @param string $order_id
     * @return json
     */
    public function orderQuery ($order_id) {
        $req_body = array(
            'orderId' => $order_id
        );
        return $this->send('order/query', $req_body);
    }

    /**
     * 根据 运单号/订单号 查询物流路由
     * @param array $req_body
     * @return json
     */
    public function routeQuery ($req_body) {
        $req_body = array(
            'trackingType' => $req_body['trackingType'],
            'trackingNumber' => $req_body['trackingNumber'],
            'methodType' => $req_body['methodType'],
        );
        return $this->send('route/query', $req_body);
    }

    /**
     * 电子运单图片下载
     * @param string $orderId
     * @param bool $isLogo
     * @return json (image参数为BASE64编码的字符串)
     */
    public function wayBillImage ($orderId, $isLogo = false) {
        $req_body = array(
            'orderId' => $orderId,
            'isLogo' => $isLogo ? 1 : 0
        );
        return $this->send('waybill/image', $req_body);
    }

    /**
     * 获取顺丰授权
     * @return json
     */
    public function getToken () {
        return $this->send('security/access_token');
    }

    /**
     * 刷新授权令牌
     * @param string $access_token
     * @param string $refresh_token
     * @return json
     */
    public function refreshToken ($access_token, $refresh_token) {
        $this->access_token = $access_token;
        $this->refresh_token = $refresh_token;
        return $this->send('security/refresh_token');
    }

    /**
     * 忘记 access_token 查询
     * @return json
     */
    public function queryToken () {
        return $this->send('security/access_token/query');
    }

    /**
     * 根据请求的接口创建相应的 Uri
     * @param string $resource 要请求的resource(前后不带'/')
     * @return string
     */
    protected function buildUri ($resource) {
        $query = '/sf_appid/' . $this->app_id . '/sf_appkey/' . $this->app_key;

        if ($resource == 'security/refresh_token') {
            $query = "/access_token/$this->access_token/refresh_token/$this->refresh_token" . $query;
        }elseif (substr($resource, 0, 8) != 'security') {
            $query = '/access_token/' . $this->access_token . $query;
        }

        $uri = $this->url . $this->transType()[$resource]['type'] . '/v1.0/' . $resource . $query;

        return $uri;
    }

    /**
     * 向顺丰接口发送请求
     * SSL POST JSON
     * @param string $resource 要请求的resource(前后不带'/')
     * @param array $body 请求报文(参数)
     * @return json
     */
    protected function send ($resource, $body = array()) {

        $this->uri = $this->buildUri($resource);

        $req_data = array(
            'head' => array(
                'transType' => $this->transType()[$resource]['transType'],
                'transMessageId' => date('Ymd') . substr_replace(time(), mt_rand(10,99),0,2),
            )
        );

        if(!empty($body)) {
            $req_data['body'] = $body;
        }

        $header = array(
            "Content-Type: application/json",
        );

        $ch = curl_init();

        curl_setopt($ch, CURLOPT_URL, $this->uri);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // 跳过证书检查
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, true);  // 从证书中检查SSL加密算法是否存在
        curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($req_data));

        $response = curl_exec($ch);

        curl_close($ch);

        return $response;
    }

    /**
     * 顺丰开放平台各接口对应的资源类型
     * @return array
     */
    private function transType () {
        return array(
            'order' => array('transType' => 200, 'type' => 'rest'),
            'order/query' => array('transType' => 203, 'type' => 'rest'),
            'filter' => array('transType' => 204, 'type' => 'rest'),
            'route/query' => array('transType' => 501, 'type' => 'rest'),
            'route/inc/query' => array('transType' => 504, 'type' => 'rest'),
            'waybill/image' => array('transType' => 205, 'type' => 'rest'),
            'product/basic/query' => array('transType' => 250, 'type' => 'rest'),
            'product/additional/query' => array('transType' => 251, 'type' => 'rest'),
            'security/access_token/query' => array('transType' => 300, 'type' => 'public'),
            'security/access_token' => array('transType' => 301, 'type' => 'public'),
            'security/refresh_token' => array('transType' => 302, 'type' => 'public'),
        );
        /**
            快速下单 /order/ 200
            订单查询 /order/query/ 203
            订单筛选 /filter/ 204
            路由查询 /route/query/ 501
            路由增量查询 /route/inc/query/ 504
            电子运单图片下载 /waybill/image/ 205
            基础服务查询 /product/basic/query/ 250
            附加服务查询 /product/additional/query/ 251
            申请访问令牌 /security/access_token/ 301
            查询访问令牌 /security/access_token/query/ 300
            刷新访问令牌 /security/refresh_token/ 302
         */
    }

}

使用

  1. 引入该类文件

  2. 并实例化,参数分别为 app_id, app_secret, 是否用于生产环节 (true|false),默认为 false

  3. 检查 access_token 并设置。

  4. 调用对应方法即可,详细使用请参考方法注释和顺丰接口文档。

例子

// 实例化对象并传入参数
$sf = new SfApi('your app_id', 'your app_secret', false);

// 获取 access_token
$token_res = $sf->getToken();
var_dump($token_res);

// 为对象设置 access_token 属性
$sf->access_token = json_decode($token_res, true)['body']['accessToken'];

// 下单
$req_body = array(
    'orderId' => 'SF201710091507536283',
    'expressType' => 1,
    'payMethod' => 3,
    'custId' => 'your custId',
    'payArea' => '010EU',
    'remark' => '备注',
    'consigneeInfo' => array(
        'company' => '个人',
        'contact' => '测试对象',
        'tel' => '17600000000',
        'province' => '北京市',
        'city' => '北京市',
        'county' => '朝阳区',
        'address' => '十里河',
        'mobile' => '17600000000',
    ),
    'cargoInfo' => array(
        'cargo' => '产品名',
    ),
    // 代收货款需填,标准快递则不需要如下参数
    'addedServices' => array(
        array(
            'name' => 'COD',
            'value' => '698',
        ),
        array(
            'name' => 'CUSTID',
            'value' => 'your custId'
        )
    )
);
$order_res= $sf->order($req_body);
var_dump($order_res);

// 获取运单图片
$image_res = $sf->wayBillImage('SF201710091507536283');
$image_res = json_decode($image_res, true);
file_put_contents('./SF201710091507536283.jpg', base64_decode($image_res['body']['images'][0]));

echo '<img src="./SF201710091507536283.jpg" />';

运单图片

示例

sf2

图中马赛克为手打

运单图片处理

处理图片使用 GDimagemagick 等处理图片的库。
一般来说需要隐藏客户的收件信息,下附上图片处理相关函数。

/** 图片局部打马赛克 
* @param  String  $source 原图 
* @param  Stirng  $dest   生成的图片 
* @param  int     $x1     起点横坐标 
* @param  int     $y1     起点纵坐标 
* @param  int     $x2     终点横坐标 
* @param  int     $y2     终点纵坐标 
* @param  int     $deep   深度,数字越大越模糊 
* @param  bool    $fill   是否只填充白色
* @return boolean 
*/  
function imageMosaics($source, $dest, $x1, $y1, $x2, $y2, $deep, $fill = false){  
  
    // 判断原图是否存在  
    if(!file_exists($source)){  
        return false;  
    }  
  
    // 获取原图信息  
    list($owidth, $oheight, $otype) = getimagesize($source);  
  
    // 判断区域是否超出图片  
    if($x1>$owidth || $x1<0 || $x2>$owidth || $x2<0 || $y1>$oheight || $y1<0 || $y2>$oheight || $y2<0){  
        return false;  
    }  
  
    switch($otype){  
        case 1: $source_img = imagecreatefromgif($source); break;  
        case 2: $source_img = imagecreatefromjpeg($source); break;  
        case 3: $source_img = imagecreatefrompng($source); break;  
        default:  
            return false;  
    }
  
    // 打马赛克  
    if($fill === false) {
        for($x=$x1; $x<$x2; $x=$x+$deep){  
            for($y=$y1; $y<$y2; $y=$y+$deep){  
                $color = imagecolorat($source_img, $x+round($deep/2), $y+round($deep/2));
                imagefilledrectangle($source_img, $x, $y, $x+$deep, $y+$deep, $color);  
            }  
        } 
    }else{
        $im = imagecreatetruecolor(200, 200);
        $fill = imagecolorallocate($im, 255, 255, 255);
        imagefilledrectangle($source_img, $x1, $y1, $x2, $y2, $fill); 
    }
  
    // 生成图片  
    switch($otype){  
        case 1: imagegif($source_img, $dest); break;  
        case 2: imagejpeg($source_img, $dest); break;  
        case 3: imagepng($source_img, $dest); break;  
    }  
  
    return is_file($dest)? true : false;  
  
}
// 使用
$source = $dest = './201710244108826825.jpg';  
// 5,5  1125,100 区域填充白色(应对带有顺丰logo的打印纸)
$flag = imageMosaics($source, $dest, 5, 5, 1125, 100, 4, true);  
// (120)215, 250   810,400 区域马赛克
$flag = imageMosaics($source, $dest, 215, 250, 810, 400, 7);  
// (110)210,1207  678,1314 区域马赛克
$flag = imageMosaics($source, $dest, 210, 1207, 678, 1314, 7);  
echo '<img width="400px" src="'.$source.'">';
  

该函数为以前网络上找到并改造的,未找到原作者。如有侵权请联系我删除。

处理后示例

sf1

图中 logo 处和收件人处为函数生成的马赛克、填充白色,其余区域为手打马赛克。

其他

代码写的比较仓促,不过一般的与顺丰对接也就这些基本功能,还有一些接口本文没有用到的,可以参考上面 SDK 中对应函数的注释和接口文档。

注:转载请注明出处。

Responses
icon_mrgreen.gificon_neutral.gificon_twisted.gificon_arrow.gificon_eek.gificon_smile.gificon_confused.gificon_cool.gificon_evil.gificon_biggrin.gificon_idea.gificon_redface.gificon_razz.gificon_rolleyes.gificon_wink.gificon_cry.gificon_surprised.gificon_lol.gificon_mad.gificon_sad.gificon_exclaim.gificon_question.gif
  1. fast easy cash loan payday loans without cosigner payday loan cash advance places first american loans cash till payday best personal loan loans bad credit bad credit loans need money fast 500 cash loan installment loans online installment loans i need cash now installment loans what are good credit scores online direct lenders loans online loans online

    Reply
  2. quick loans no credit check payday loans houston tx online loans online loans installment loan installment loans installment loan online installment loans

    Reply
  3. cash installment loans faxless payday loan loan payday loan payday

    Reply
  4. payday loans best payday loans online payday loans online payday loans instant approval

    Reply
  5. personal loans personal loans speedy payday loans tribal loans guaranteed approval installment loan installment installment loan money loans bad credit loans loans with bad credit payday loans tulsa ok online loans for bad credit

    Reply
  6. loans online payday loans online loans online sun loan

    Reply