初始化

This commit is contained in:
hfk2022@hotmail.com 2023-09-15 16:34:34 +08:00
parent 816ea8219d
commit b29142fc95
19 changed files with 1022 additions and 0 deletions

3
.gitignore vendored Normal file
View File

@ -0,0 +1,3 @@
/vendor/
/.idea/
/composer.lock

16
README.md Normal file
View File

@ -0,0 +1,16 @@
### 顺丰快递开放平台接口 SDK
# 说明
本 SDK 仅个人项目使用不保证能使用所有项目
- [顺丰开放平台接口文档](https://open.sf-express.com/Api?category=1&apiClassify=1)
# 使用
请参照 examples 目录内的样例使用
## 目前已对接
- 下订单接口-速运类API
- 预下单接口-速运类API
- 订单结果查询接口-速运类API
- 路由查询接口接口-速运类API
- 订单确认/取消接口-速运类API

21
composer.json Normal file
View File

@ -0,0 +1,21 @@
{
"name": "root/sfexpress_sdk",
"description": "顺丰SDK",
"type": "library",
"require": {
"php": "7.2.*",
"guzzlehttp/guzzle": "^7.8"
},
"license": "MIT",
"autoload": {
"psr-4": {
"Gzlbw\\sfexpress\\": "src/"
}
},
"authors": [
{
"name": "Li Bo Wen",
"email": "gzbw79@163.com"
}
]
}

View File

@ -0,0 +1,19 @@
<?php
/**
* Write by BoWen 2023/9/15 下午4:12
* Email: gzbw79@163.com
* 云打印面单打印2.0接口-面单类API
* 文档https://open.sf-express.com/Api/ApiDetails?level3=317&interName=%E4%BA%91%E6%89%93%E5%8D%B0%E9%9D%A2%E5%8D%952.0%E6%8E%A5%E5%8F%A3-COM_RECE_CLOUD_PRINT_WAYBILLS
*/
require __DIR__ . "/../vendor/autoload.php";
$handle = new \Gzlbw\sfexpress\CloudPrintWaybills("XTYSWNJt2vpS", "2cIBZs3r1QvOhqYCSoAR8ntmhTgYAqdF", true);
// 添加要打印的面单快递单号
$handle->addWayBills("SF7444471043754");
// 获取面单文件
$ret = $handle->req([
'templateCode' => 'fm_150_standard_XTYSWNJt2vpS', // 模板编码
'sync' => true, //
]);
var_dump($ret);

47
examples/create_order.php Normal file
View File

@ -0,0 +1,47 @@
<?php
/**
* Write by BoWen 2023/9/15 下午3:01
* Email: gzbw79@163.com
* 下订单接口-速运类API
*/
require __DIR__ . "/../vendor/autoload.php";
$handle = new \Gzlbw\sfexpress\CreateOrder("XTYSWbTkcFef", "lrgdnHl21IOb6wEmPYB6def9C4JG2Se5", true);
// 业务订单编号
$order_no = date("YmdHi") . rand(1000, 9999);
$handle->setOrderId($order_no);
// 寄件人信息
$handle->addContractInfo("from", "天河区天河南二路丰兴广场", "小李", "", "13800138000", "广东省", "广州市");
// 收件人信息
$handle->addContractInfo("to", "天河区天河路611号摩登百货", "小张", "", "13800138001", "广东省", "广州市");
// 货物信息
$handle->addCargoDetail("文件 1份", "1", [
'amount' => 10, // 声明价值
'currency' => 'CNY' // 价值结算货币
]);
// 发送请求
$ret = $handle->req([
'monthlyCard' => '7551234567', // 月结卡号
'payMethod' => 1, // 付款方式,支持以下值: 1:寄方付 2:收方付 3:第三方付
'expressTypeId' => 2, // 快件产品类别, https://open.sf-express.com/developSupport/734349?activeIndex=324604
'remark' => '派件前请电话联系', // 备注
'isReturnRoutelabel' => 1, // 是否返回路由标签: 默认1 1返回路由标签 0不返回除部分特殊用户外其余用户都默认返回
'isReturnSignBackRoutelabel' => 0, // 是否返回签回单路由标签: 默认0 1返回路由标签 0不返回
'totalWeight' => 1.000 // 订单货物总重量(郑州空港海关必填), 若为子母件必填, 单位千克, 精确到小数点后3位如果提供此值 必须>0 (子母件需>6)
]);
var_dump($ret);
/**
* 响应数据样例
* array(4) {
["apiErrorMsg"]=>
string(0) ""
["apiResponseID"]=>
string(32) "00018A97BCE25C3FE59E04A28E84E33F"
["apiResultCode"]=>
string(5) "A1000"
["apiResultData"]=>
string(349) "{"success":true,"errorCode":"S0000","errorMsg":null,"msgData":[{"serviceDate":"2023-09-15","startTime":"2023-09-15 08:00:00","endTime":"2023-09-15 21:30:00"},{"serviceDate":"2023-09-16","startTime":"2023-09-16 08:00:00","endTime":"2023-09-16 21:30:00"},{"serviceDate":"2023-09-17","startTime":"2023-09-17 08:00:00","endTime":"2023-09-17 21:30:00"}]}"
}
*/

View File

@ -0,0 +1,39 @@
<?php
/**
* Write by BoWen 2023/9/15 下午3:01
* Email: gzbw79@163.com
* 预下单接口样例 - 用于校验收件地址是否支持派送和收件
*/
require __DIR__ . "/../vendor/autoload.php";
$handle = new \Gzlbw\sfexpress\PreCreateOrder("XTYSWbTkcFef", "lrgdnHl21IOb6wEmPYB6def9C4JG2Se5", true);
// 业务订单编号
$order_no = date("YmdHi") . rand(1000, 9999);
$handle->setOrderId($order_no);
// 寄件人信息
$handle->addContractInfo("from", "天河区天河南二路丰兴广场", "小李", "", "13800138000", "广东省", "广州市");
// 收件人信息
$handle->addContractInfo("to", "天河区天河路611号摩登百货", "小张", "", "13800138001", "广东省", "广州市");
// 发送请求
$ret = $handle->req([
'monthlyCard' => '7551234567', // 月结卡号
'payMethod' => 1, // 付款方式,支持以下值: 1:寄方付 2:收方付 3:第三方付
'expressTypeId' => 2, // 快件产品类别, https://open.sf-express.com/developSupport/734349?activeIndex=324604
'remark' => '派件前请电话联系', // 备注
]);
var_dump($ret);
/**
* 响应数据样例
* array(4) {
["apiErrorMsg"]=>
string(0) ""
["apiResponseID"]=>
string(32) "00018A97B28A9D3F9F66B7A2B880603F"
["apiResultCode"]=>
string(5) "A1000"
["apiResultData"]=>
string(1710) "{"success":true,"errorCode":"S0000","errorMsg":null,"msgData":{"orderId":"2023091515166449","originCode":"020","destCode":"020","filterResult":2,"remark":"","url":null,"paymentLink":null,"isUpstairs":null,"isSpecialWarehouseService":null,"mappingMark":null,"agentMailno":null,"returnExtraInfoList":null,"waybillNoInfoList":[{"waybillType":1,"waybillNo":"SF7444471039325","boxNo":null,"length":null,"width":null,"height":null,"weight":null,"volume":null}],"routeLabelInfo":[{"code":"1000","routeLabelData":{"waybillNo":"SF7444471039325","sourceTransferCode":"020W","sourceCityCode":"020","sourceDeptCode":"020","sourceTeamCode":"","destCityCode":"020","destDeptCode":"020Z069","destDeptCodeMapping":"","destTeamCode":"006","destTeamCodeMapping":"","destTransferCode":"020W","destRouteLabel":"020W-Z069-006","proName":"","cargoTypeCode":"T6","limitTypeCode":"T6","expressTypeCode":"B1","codingMapping":"H7","codingMappingOut":"","xbFlag":"0","printFlag":"000000000","twoDimensionCode":"MMM={'k1':'020W','k2':'020Z069','k3':'006','k4':'T4','k5':'SF7444471039325','k6':'','k7':'dfa46974'}","proCode":"T 标快","printIcon":"00000000","abFlag":"","destPortCode":"","destCountry":"","destPostCode":"","goodsValueTotal":"","currencySymbol":"","cusBatch":"","goodsNumber":"","errMsg":"","checkCode":"dfa46974","proIcon":"","fileIcon":"","fbaIcon":"","icsmIcon":"","destGisDeptCode":"020Z069","newIcon":null,"sendAreaCode":null,"destinationStationCode":null,"sxLabelDestCode":null,"sxDestTransferCode":null,"sxCompany":null,"newAbFlag":null,"destAddrKeyWord":"","rongType":null,"waybillIconList":null},"message":"SF7444471039325:"}],"contactInfoList":null,"sendStartTm":null,"customerRights":null,"expressTypeId":null}}"
}
*/

26
examples/search_order.php Normal file
View File

@ -0,0 +1,26 @@
<?php
/**
* Write by BoWen 2023/9/15 下午3:35
* Email: gzbw79@163.com
* 订单结果查询接口
*/
require __DIR__ . "/../vendor/autoload.php";
$handle = new \Gzlbw\sfexpress\SearchOrder("XTYSWbTkcFef", "lrgdnHl21IOb6wEmPYB6def9C4JG2Se5", true);
$ret = $handle->data("2023091515166449");
var_dump($ret);
/**
* 响应数据样例
* array(4) {
["apiErrorMsg"]=>
string(0) ""
["apiResponseID"]=>
string(32) "00018A97C54DF13FE1EDD4F4A9445A3F"
["apiResultCode"]=>
string(5) "A1000"
["apiResultData"]=>
string(1333) "{"success":true,"errorCode":"S0000","errorMsg":null,"msgData":{"orderId":"2023091515166449","returnExtraInfoList":null,"waybillNoInfoList":[{"waybillType":1,"waybillNo":"SF7444471039325"}],"origincode":"020","destcode":"020","filterResult":"2","remark":"派件前请电话联系","routeLabelInfo":[{"code":"1000","routeLabelData":{"waybillNo":"SF7444471039325","sourceTransferCode":"020W","sourceCityCode":"020","sourceDeptCode":"020","sourceTeamCode":"","destCityCode":"020","destDeptCode":"020Z069","destDeptCodeMapping":"","destTeamCode":"006","destTeamCodeMapping":"","destTransferCode":"020W","destRouteLabel":"020W-Z069-006","proName":"顺丰标快","cargoTypeCode":"T6","limitTypeCode":"T6","expressTypeCode":"B1","codingMapping":"H7","codingMappingOut":"","xbFlag":"0","printFlag":"000000000","twoDimensionCode":"MMM={'k1':'020W','k2':'020Z069','k3':'006','k4':'T801','k5':'SF7444471039325','k6':'','k7':'b96667f8'}","proCode":"T801","printIcon":"00000000","abFlag":"","destPortCode":"","destCountry":"","destPostCode":"","goodsValueTotal":"","currencySymbol":"","cusBatch":"","goodsNumber":"","errMsg":"","checkCode":"b96667f8","proIcon":"","fileIcon":"","fbaIcon":"","icsmIcon":"","destGisDeptCode":"020Z069","newIcon":null},"message":"SF7444471039325:"}],"contactInfo":null,"clientCode":"XTYSWbTkcFef","serviceList":null}}"
}
*/

View File

@ -0,0 +1,28 @@
<?php
/**
* Write by BoWen 2023/9/15 下午3:38
* Email: gzbw79@163.com
* 路由查询接口
*/
require __DIR__ . "/../vendor/autoload.php";
$handle = new \Gzlbw\sfexpress\SearchRoutes("XTYSWbTkcFef", "lrgdnHl21IOb6wEmPYB6def9C4JG2Se5", true);
$ret = $handle->req([
'trackingNumber' => ["SF7444471039325"]
]);
var_dump($ret);
/**
* 响应报文样例
* array(4) {
["apiErrorMsg"]=>
string(0) ""
["apiResponseID"]=>
string(32) "00018A97CE03FB3FE9D58FC7BD17AB3F"
["apiResultCode"]=>
string(5) "A1000"
["apiResultData"]=>
string(238) "{"success":true,"errorCode":"S0000","errorMsg":null,"msgData":{"routeResps":[{"mailNo":"SF7444471039325","routes":[{"acceptAddress":"深圳市","acceptTime":"2023-09-15 15:46:15","remark":"顺丰速运 已收取快件","opCode":"50"}]}]}}"
}
*/

43
examples/update_order.php Normal file
View File

@ -0,0 +1,43 @@
<?php
/**
* Write by BoWen 2023/9/15 下午3:53
* Email: gzbw79@163.com
* 订单确认/取消接口-速运类API
*/
require __DIR__ . "/../vendor/autoload.php";
$handle = new \Gzlbw\sfexpress\UpdateOrder("XTYSWbTkcFef", "lrgdnHl21IOb6wEmPYB6def9C4JG2Se5", true);
// 确认订单
$ret = $handle->confirm("2023091515166449");
var_dump($ret);
/**
* 报文响应样例
* array(4) {
["apiErrorMsg"]=>
string(0) ""
["apiResponseID"]=>
string(32) "00018A97D907F13FDD618D201CAB603F"
["apiResultCode"]=>
string(5) "A1000"
["apiResultData"]=>
string(74) "{"success":false,"errorCode":"8037","errorMsg":"已消单","msgData":null}"
}
*/
// 撤销订单
$ret = $handle->cancel("2023091515166449");
var_dump($ret);
/**
* 报文响应样例
* array(4) {
["apiErrorMsg"]=>
string(0) ""
["apiResponseID"]=>
string(32) "00018A97D895433FCB8D4B1C739C303F"
["apiResultCode"]=>
string(5) "A1000"
["apiResultData"]=>
string(198) "{"success":true,"errorCode":"S0000","errorMsg":null,"msgData":{"orderId":"2023091515166449","waybillNoInfoList":[{"waybillType":1,"waybillNo":"SF7444471039325"}],"resStatus":2,"extraInfoList":null}}"
}
*/

View File

@ -0,0 +1,52 @@
<?php
/**
* Write by BoWen 2023/9/15 下午4:01
* Email: gzbw79@163.com
* 云打印面单打印2.0接口-面单类API
*/
namespace Gzlbw\sfexpress;
class CloudPrintWaybills extends Handler implements IHandler
{
protected $serviceCode = 'COM_RECE_CLOUD_PRINT_WAYBILLS';
/**
* 业务数据
* @var array
*/
protected $documents = [];
public function req(array $msgData, array $options = [])
{
$this->timestamp = $this->get_time();
// 获取公共请求参数
$params = $this->common_params($this->serviceCode);
// 合并请求参数
$msgData = array_merge($msgData, [
'version' => '2.0',
'documents' => $this->documents
]);
$params = array_merge($params, ['msgData' => $msgData], $options);
// 数据签名
$params['msgDigest'] = $this->sign($params['msgData'], $this->timestamp);
// 多维数组转成一维
$this->convert_params($params);
return $this->fire('/std/service', ['form_params' => $params]);
}
/**
* 除主运单号是必须外其余为条件
* 一批不要超过20个运单字段定义参考 2.3.1 模板固定字段
* @param string $master_no 主运单号(必须)
* @param array $options 其余参数,参考顺丰文档
*/
public function addWayBills(string $master_no, array $options = []) {
$this->documents[] = array_merge([
'masterWaybillNo' => $master_no,
], $options);
return $this;
}
}

101
src/CreateOrder.php Normal file
View File

@ -0,0 +1,101 @@
<?php
/**
* Write by BoWen 2023/9/15 下午1:53
* Email: gzbw79@163.com
* 下单接口
* 顺丰文档https://open.sf-express.com/Api/ApiDetails?level3=393&interName=%E4%B8%8B%E8%AE%A2%E5%8D%95%E6%8E%A5%E5%8F%A3-EXP_RECE_CREATE_ORDER
*/
namespace Gzlbw\sfexpress;
class CreateOrder extends OrderCommon implements IHandler
{
protected $serviceCode = 'EXP_RECE_CREATE_ORDER';
/**
* 联系信息
* @var array
*/
protected $contractInfo = [
'contactType' => 1,
'company' => '',
'contact' => '',
'tel' => '',
'mobile' => '',
'zoneCode' => '',
'country' => '',
'province' => '',
'city' => '',
'county' => '',
'address' => '',
'postCode' => '',
'email' => '',
'taxNo' => ''
];
/**
* 订单号
* @var string
*/
protected $order_id = '';
/**
* 发件人
* @var array
*/
protected $sender = [];
/**
* 收件人
* @var array
*/
protected $receiver = [];
/**
* 订单原始信息
* @var
*/
protected $orderSource;
/**
* 货物详情
* @var array
*/
protected $cargoDetail = [];
/**
* 是否需求分配运单号1分配 0不分配若带单号下单请传值0
* @var int
*/
protected $isGenWaybillNo = 1;
/**
* @param array $msgData 业务数据,参照顺丰文档 下订单接口-速运类API 元素<请求> Order
* @param array $options 其它请求参数
* @return mixed
* @throws \Exception
*/
public function req(array $msgData, array $options = [])
{
$this->timestamp = $this->get_time();
$common = $this->common_params($this->serviceCode);
// 业务数据
$msgData = array_merge($msgData, [
'orderId' => $this->order_id,
'cargoDetails' => $this->cargoDetail,
'contactInfoList' => [
$this->sender,
$this->receiver
],
'orderSource' => $this->orderSource,
'isGenWaybillNo' => $this->isGenWaybillNo
]);
// 合并请求参数
$params = array_merge($common, ['msgData' => $msgData], $options);
// 数据签名
$params['msgDigest'] = $this->sign($params['msgData'], $this->timestamp);
// 多维数组转成一维
$this->convert_params($params);
return $this->fire('/std/service', ['form_params' => $params]);
}
}

269
src/Handler.php Normal file
View File

@ -0,0 +1,269 @@
<?php
/**
* Write by BoWen 2023/9/15 下午1:38
* Email: gzbw79@163.com
*
*/
namespace Gzlbw\sfexpress;
use GuzzleHttp\Client;
class Handler
{
/**
* 是否沙盒环境
* @var bool
*/
protected $sandbox = false;
/**
* 顾客编码
* @var string
*/
protected $app_id = '';
/**
* 校验码
* @var string
*/
protected $app_key = '';
/**
* 服务代码
* @var string
*/
protected $serviceCode = '';
/**
* 生产地址
* @var string
*/
protected $product_uri = 'https://bspgw.sf-express.com';
/**
* 沙盒地址
* @var string
*/
protected $sandbox_uri = 'https://sfapi-sbox.sf-express.com';
/**
* 临时目录
* @var string
*/
protected $temp_path = '';
/**
* 请求时间戳
* @var int
*/
protected $timestamp;
/**
* 数据签名
* @var string
*/
protected $sign;
/**
* Handler constructor.
* @param string $app_id 客户编号
* @param string $app_key 应用验证码(接口签名需要)
* @param bool $sandbox 是否沙盒模式
* @param string $temp_path 临时目录路径
*/
public function __construct(string $app_id, string $app_key, bool $sandbox = false, string $temp_path = '')
{
$this->app_id = $app_id;
$this->app_key = $app_key;
$this->sandbox = $sandbox;
$this->temp_path = (empty($temp_path)) ? __DIR__ . "/../temp" : $temp_path;
if (!file_exists($this->temp_path)) {
@mkdir($this->temp_path, 0755, true);
}
}
/**
* 数据签名
* @param array $data 需要参与签名的数据
* @param int $timestamp 时间戳
* @return string
*/
protected function sign(array $data, int $timestamp = 0) {
$this->timestamp = ($timestamp > 0) ? $timestamp : $this->get_time();
$encode = json_encode($data, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
$sign = sprintf("%s%s%s", $encode, $this->timestamp, $this->app_key);
$sign = urlencode($sign);
$sign = md5($sign, true);
return base64_encode($sign);
}
/**
* 创建UUID
* @return string
*/
protected function create_uuid() {
$chars = md5(uniqid(mt_rand(), true));
return implode("-", [
substr ( $chars, 0, 8 ),
substr ( $chars, 8, 4 ),
substr ( $chars, 12, 4 ),
substr ( $chars, 16, 4 ),
substr ( $chars, 20, 12 )
]);
}
/**
* 转换参数,将参数中属于数组的要转成 json
* @param $params
* @return void
*/
public function convert_params(&$params) {
foreach ($params as &$vo) {
if (is_array($vo)) {
$vo = json_encode($vo, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
}
}
}
/**
* 获取 access_token
* @param bool $update 是否取最新 token
* @return string
*/
public function access_token(bool $update = false) {
$cache_file = $this->temp_path . "/" . $this->app_id . "_token.json";
if (file_exists($cache_file) && $update === false) {
$token = json_decode(file_get_contents($cache_file), true);
if ((int)$token['expire_at'] > time()) return $token['accessToken'];
}
$client = new Client($this->client_config());
$request = $client->post('/oauth2/accessToken', [
'query' => [
'partnerID' => $this->app_id,
'secret' => $this->app_key,
'grantType' => 'password'
]
]);
/**
* 成功报文
* {
"apiResultCode": "A1000",
"apiErrorMsg": "success",
"apiResponseID": "000180E0AC18933F963C52701B18C03F",
"accessToken": "20D02FC4F63B4A4AA7C9A236EAD5B0A1",
"expiresIn": 5150
}
*/
$body = (string)$request->getBody();
$response = json_decode($body, true);
if (empty($response['accessToken'])) {
throw new \Exception($body);
}
// 写入缓存
$response = array_merge($response, ['expire_at' => time() + $response['expiresIn'] - 20]);
file_put_contents($cache_file, json_encode($response, JSON_UNESCAPED_UNICODE));
return $response['accessToken'];
}
/**
* 统一请求方法
* @param string $uri_path 请求路径
* @param array $options 请求参数
* @param string $method 请求方法
*/
public function fire(string $uri_path, array $options, string $method = 'post') {
$client = new Client($this->client_config());
$request = $client->request($method, $uri_path, $options);
$body = (string)$request->getBody();
$response = json_decode($body, true);
if (!$response) throw new \Exception($body);
return $response;
}
/**
* 组合公共参数
* @param string $service_code
* @param bool $update_token
* @return array
*/
public function common_params(string $service_code, bool $update_token = false) {
$token = $this->access_token($update_token);
$request_id = $this->create_uuid();
return [
'partnerID' => $this->app_id,
'requestID' => $request_id,
'serviceCode' => $service_code,
'timestamp' => $this->timestamp,
'accessToken' => $token,
'msgDigest' => '',
'msgData' => ''
];
}
/**
* 客户端HTTP通用参数
* @return array
*/
private function client_config() {
return [
'base_uri' => ($this->sandbox) ? $this->sandbox_uri : $this->product_uri,
'verify' => false,
'headers' => [
'Content-type' => 'application/x-www-form-urlencoded;charset=UTF-8'
]
];
}
/**
* 返回时间戳
* @return false|float
*/
public function get_time() {
return ceil(microtime(true) * 1000);
}
/**
* 过滤空值参数
* @param $data
* @return array
*/
protected function filter_empty($data) {
return array_filter($data, function ($v, $k) {
return !empty($v);
}, ARRAY_FILTER_USE_BOTH);
}
/**
* 请求接口
* @param array $msgData
* @param array $options
* @return mixed
* @throws \Exception
*/
public function req(array $msgData, array $options = [])
{
$this->timestamp = $this->get_time();
// 获取公共请求参数
$params = $this->common_params($this->serviceCode);
// 合并请求参数
$params = array_merge($params, ['msgData' => $msgData], $options);
// 数据签名
$params['msgDigest'] = $this->sign($params['msgData'], $this->timestamp);
// 多维数组转成一维
$this->convert_params($params);
return $this->fire('/std/service', ['form_params' => $params]);
}
}

20
src/IHandler.php Normal file
View File

@ -0,0 +1,20 @@
<?php
/**
* Write by BoWen 2023/9/15 下午1:46
* Email: gzbw79@163.com
*
*/
namespace Gzlbw\sfexpress;
interface IHandler
{
/**
* 触发请求处理
* @param array $msgData
* @param array $options
* @return mixed
*/
public function req(array $msgData, array $options = []);
}

139
src/OrderCommon.php Normal file
View File

@ -0,0 +1,139 @@
<?php
/**
* Write by BoWen 2023/9/15 下午3:21
* Email: gzbw79@163.com
* 订单相关公共类,用于创建或预创建订单使用
*/
namespace Gzlbw\sfexpress;
abstract class OrderCommon extends Handler
{
/**
* 联系信息
* @var array
*/
protected $contractInfo = [
'contactType' => 1,
'company' => '',
'contact' => '',
'tel' => '',
'mobile' => '',
'zoneCode' => '',
'country' => '',
'province' => '',
'city' => '',
'county' => '',
'address' => '',
'postCode' => '',
'email' => '',
'taxNo' => ''
];
/**
* 订单号
* @var string
*/
protected $order_id = '';
/**
* 发件人
* @var array
*/
protected $sender = [];
/**
* 收件人
* @var array
*/
protected $receiver = [];
/**
* 订单原始信息
* @var
*/
protected $orderSource;
/**
* 货物详情
* @var array
*/
protected $cargoDetail = [];
/**
* 是否需求分配运单号1分配 0不分配若带单号下单请传值0
* @var int
*/
protected $isGenWaybillNo = 1;
/**
* 添加收发信息
* @param string $type 地址类型: 1,寄件方信息 2,到件方信息
* @param string $address 详细地址
* @param string $name 姓名
* @param string $tel 座机号码(座机和手机只能选一项)
* @param string $mobile 手机号码(座机和手机只能选一项)
* @param string $province 省名称
* @param string $city 城市名称
* @param string $country 国家或地区代码 例如内地件CN 香港852 参照顺丰API附录《城市代码表》
* @param array $options 其它可用参数,参照顺丰下订单接口-速运类API ContactInfo元素文档
* @return $this
*/
public function addContractInfo(string $type, string $address, string $name, string $tel, string $mobile, string $province, string $city, string $country = 'CN', array $options = []) {
$contractType = ($type == "from") ? 1 : 2;
$tmp = array_merge($this->contractInfo, [
'contactType' => $contractType,
'contact' => $name,
'address' => $address,
'tel' => $tel,
'mobile' => $mobile,
'province' => $province,
'city' => $city,
'county' => $country
], $options);
$tmp = $this->filter_empty($tmp);
if ($contractType == 1) {
$this->sender = $tmp;
} else {
$this->receiver = $tmp;
}
return $this;
}
/**
* 添加货物明细
* @param $name
* @param string $count
* @param array $options
* @return $this
*/
public function addCargoDetail(string $name, string $count = '',array $options = []) {
$tmp = array_merge(compact('name', 'count'), $options);
$tmp = $this->filter_empty($tmp);
$this->cargoDetail[] = $tmp;
return $this;
}
/**
* 设置业务单号
* @param string $orderId
* @return $this
*/
public function setOrderId(string $orderId) {
$this->order_id = $orderId;
return $this;
}
/**
* 订单平台类型 (对于平台类客户, 如果需要在订单中 区分订单来源, 则可使用此字段) 天猫:tmall 拼多多pinduoduo 京东 : jd 等平台类型编码
* @param string $src
* @return $this
*/
public function orderSource(string $src) {
$this->orderSource = $src;
return $this;
}
}

44
src/PreCreateOrder.php Normal file
View File

@ -0,0 +1,44 @@
<?php
/**
* Write by BoWen 2023/9/15 下午3:19
* Email: gzbw79@163.com
* 预下单接口 - 客户通过传入地址信息等参数,校验是否能下单成功
* 顺丰文档https://open.sf-express.com/Api/ApiDetails?level3=392&interName=%E9%A2%84%E4%B8%8B%E5%8D%95%E6%8E%A5%E5%8F%A3-EXP_RECE_PRE_ORDER
*/
namespace Gzlbw\sfexpress;
class PreCreateOrder extends OrderCommon implements IHandler
{
protected $serviceCode = 'EXP_RECE_PRE_ORDER';
/**
* @param array $msgData 业务数据,参照顺丰文档 预下单接口-速运类API 元素<请求> Order
* @param array $options 其它请求参数
* @return mixed
* @throws \Exception
*/
public function req(array $msgData, array $options = [])
{
$this->timestamp = $this->get_time();
$common = $this->common_params($this->serviceCode);
// 业务数据
$msgData = array_merge($msgData, [
'orderId' => $this->order_id,
'cargoDetails' => $this->cargoDetail,
'contactInfoList' => [
$this->sender,
$this->receiver
],
'orderSource' => $this->orderSource,
'isGenWaybillNo' => $this->isGenWaybillNo
]);
// 合并请求参数
$params = array_merge($common, ['msgData' => $msgData], $options);
// 数据签名
$params['msgDigest'] = $this->sign($params['msgData'], $this->timestamp);
// 多维数组转成一维
$this->convert_params($params);
return $this->fire('/std/service', ['form_params' => $params]);
}
}

50
src/SearchOrder.php Normal file
View File

@ -0,0 +1,50 @@
<?php
/**
* Write by BoWen 2023/9/15 下午3:32
* Email: gzbw79@163.com
* 订单结果查询接口-速运类API
* 顺丰文档https://open.sf-express.com/Api/ApiDetails?level3=396&interName=%E8%AE%A2%E5%8D%95%E7%BB%93%E6%9E%9C%E6%9F%A5%E8%AF%A2%E6%8E%A5%E5%8F%A3-EXP_RECE_SEARCH_ORDER_RESP
*/
namespace Gzlbw\sfexpress;
class SearchOrder extends Handler implements IHandler
{
protected $serviceCode = 'EXP_RECE_SEARCH_ORDER_RESP';
/**
* 请求接口
* @param array $msgData
* @param array $options
* @return mixed
* @throws \Exception
*/
public function req(array $msgData, array $options = [])
{
$this->timestamp = (int)(microtime(true) * 1000);
$params = $this->common_params($this->serviceCode);
// 合并请求参数
$params = array_merge($params, ['msgData' => $msgData], $options);
// 数据签名
$params['msgDigest'] = $this->sign($params['msgData'], $this->timestamp);
// 多维数组转成一维
$this->convert_params($params);
return $this->fire('/std/service', ['form_params' => $params]);
}
/**
*
* @param string $orderId 业务订单编号
* @param int $searchType 查询类型1正向单 2退货单
* @param string $language 响应报文的语言, 缺省值为zh-CN目前支持以下值zh-CN 表示中文简体, zh-TW或zh-HK或 zh-MO表示中文繁体 en表示英文
* @return mixed
*/
public function data(string $orderId, $searchType = 1, $language = 'zh-CN') {
return $this->req([
'orderId' => $orderId,
'searchType' => $searchType,
'language' => $language
]);
}
}

33
src/SearchRoutes.php Normal file
View File

@ -0,0 +1,33 @@
<?php
/**
* Write by BoWen 2023/9/15 下午3:37
* Email: gzbw79@163.com
* 路由查询接口接口-速运类API
* 顺丰文档https://open.sf-express.com/Api/ApiDetails?level3=397&interName=%E8%B7%AF%E7%94%B1%E6%9F%A5%E8%AF%A2%E6%8E%A5%E5%8F%A3-EXP_RECE_SEARCH_ROUTES
*/
namespace Gzlbw\sfexpress;
class SearchRoutes extends Handler implements IHandler
{
protected $serviceCode = 'EXP_RECE_SEARCH_ROUTES';
public function req(array $msgData, array $options = [])
{
$this->timestamp = (int)(microtime(true) * 1000);
$params = $this->common_params($this->serviceCode);
$msgData = array_merge($msgData, [
'language' => 0, // 0=中文
'trackingType' => 1, // 1=根据顺丰运单号查询,2=根据客户订单号查询
'methodType' => 1, // 1=标准路由查询2=定制路由查询
]);
// 合并请求参数
$params = array_merge($params, ['msgData' => $msgData], $options);
// 数据签名
$params['msgDigest'] = $this->sign($params['msgData'], $this->timestamp);
// 多维数组转成一维
$this->convert_params($params);
return $this->fire('/std/service', ['form_params' => $params]);
}
}

70
src/UpdateOrder.php Normal file
View File

@ -0,0 +1,70 @@
<?php
/**
* Write by BoWen 2023/9/15 下午3:47
* Email: gzbw79@163.com
* 订单确认/取消接口-速运类API
*/
namespace Gzlbw\sfexpress;
class UpdateOrder extends Handler implements IHandler
{
protected $serviceCode = 'EXP_RECE_UPDATE_ORDER';
protected $waybillNoInfoList = [];
public function req(array $msgData, array $options = [])
{
$this->timestamp = $this->get_time();
// 获取公共请求参数
$params = $this->common_params($this->serviceCode);
// 合并请求参数
$params = array_merge($params, ['msgData' => $msgData], $options);
// 数据签名
$params['msgDigest'] = $this->sign($params['msgData'], $this->timestamp);
// 多维数组转成一维
$this->convert_params($params);
return $this->fire('/std/service', ['form_params' => $params]);
}
/**
* 取消订单
* @param string $order_no 业务单号
* @param string $express_no 快递单号
* @param int $type 运单号类型 1:母单 2 :子单 3 : 签回单
* @param array $msgData 其它业务参数
*/
public function cancel(string $order_no, string $express_no = '', int $type = 1, array $msgData = []) {
if (!empty($express_no)) {
$this->waybillNoInfoList[] = ['waybillType' => $type, 'waybillNo' => $express_no];
}
return $this->req(array_merge([
'dealType' => 2,
'language' => 'zh-CN',
'orderId' => $order_no,
'waybillNoInfoList' => $this->waybillNoInfoList
], $msgData));
}
/**
* 确认订单
* @param string $order_no 业务单号
* @param string $express_no 快递单号
* @param int $type 运单号类型 1:母单 2 :子单 3 : 签回单
* @param array $msgData 其它业务参数
*/
public function confirm(string $order_no, string $express_no = '', int $type = 1, array $msgData = []) {
if (!empty($express_no)) {
$this->waybillNoInfoList[] = ['waybillType' => $type, 'waybillNo' => $express_no];
}
return $this->req(array_merge([
'dealType' => 1,
'language' => 'zh-CN',
'orderId' => $order_no,
'waybillNoInfoList' => $this->waybillNoInfoList
], $msgData));
}
}

2
temp/.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
*
!.gitignore