2024-12-26 14:32:02 +08:00
|
|
|
|
<?php
|
|
|
|
|
|
|
2024-12-26 19:19:43 +08:00
|
|
|
|
namespace App\Services\WayBill\JingDong;
|
2024-12-26 14:32:02 +08:00
|
|
|
|
|
|
|
|
|
|
use App\Enum\Pickup\ConsignType;
|
|
|
|
|
|
use App\Models\BusinessOrder;
|
|
|
|
|
|
use App\Models\OrderItem;
|
|
|
|
|
|
use App\Models\Pickup;
|
|
|
|
|
|
use App\Models\Waybill;
|
|
|
|
|
|
use App\Services\Pickup\Exceptions\KdNiaoException;
|
|
|
|
|
|
use App\Utils\Env\EnvUtils;
|
|
|
|
|
|
use Carbon\Carbon;
|
|
|
|
|
|
use GuzzleHttp\Client;
|
|
|
|
|
|
use GuzzleHttp\Exception\GuzzleException;
|
|
|
|
|
|
use Illuminate\Support\Facades\Log;
|
|
|
|
|
|
use Lop\LopOpensdkPhp\Filters\ErrorResponseFilter;
|
|
|
|
|
|
use Lop\LopOpensdkPhp\Filters\IsvFilter;
|
|
|
|
|
|
use Lop\LopOpensdkPhp\Options;
|
|
|
|
|
|
use Lop\LopOpensdkPhp\Support\DefaultClient;
|
|
|
|
|
|
use Lop\LopOpensdkPhp\Support\GenericRequest;
|
|
|
|
|
|
use Psr\Http\Message\ResponseInterface;
|
|
|
|
|
|
|
|
|
|
|
|
class JingDongService
|
|
|
|
|
|
{
|
|
|
|
|
|
public $baseUrl;
|
|
|
|
|
|
public $appKey;
|
|
|
|
|
|
public $appSecret;
|
|
|
|
|
|
public $accessToken;
|
|
|
|
|
|
public $customerCode;
|
|
|
|
|
|
public static $CANCEL_TYPE = [
|
|
|
|
|
|
1 => '预约信息有误',
|
|
|
|
|
|
2 => '快递员无法取件',
|
|
|
|
|
|
3 => '上门太慢',
|
|
|
|
|
|
4 => '运费太贵',
|
|
|
|
|
|
7 => '联系不上快递员',
|
|
|
|
|
|
8 => '快递员要求取消',
|
|
|
|
|
|
11 => '其他(如疫情管控,无法寄 件)',
|
|
|
|
|
|
9 => '预约信息有误',
|
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
|
|
public function __construct()
|
|
|
|
|
|
{
|
|
|
|
|
|
$this->baseUrl = "https://api.jdl.com";
|
|
|
|
|
|
$this->appKey = "5ee218f6619e438db8755ee560c3eaa7";
|
|
|
|
|
|
$this->appSecret = "7ffb176f75014ebbb37061f051024bf3";
|
|
|
|
|
|
$this->accessToken = "4e411a1d178147cdb58b5579a0df378d";//每年都会过期 https://oauth.jdl.com/oauth/authorize?client_id=YOUR_APP_KEY&redirect_uri=urn:ietf:wg:oauth:2.0:oob&response_type=code
|
|
|
|
|
|
//生产环境域名:https://oauth.jdl.com 预发环境域名:https://uat-oauth.jdl.com
|
|
|
|
|
|
$this->domain = "FreshMedicineDelivery";//对接方案的编码 生鲜快递
|
|
|
|
|
|
$this->customerCode = "028K4188368";//月结编码
|
|
|
|
|
|
/*if (!EnvUtils::checkIsProduce()) {
|
|
|
|
|
|
//沙箱环境
|
|
|
|
|
|
$this->baseUrl = "https://test-api.jdl.com";
|
|
|
|
|
|
$this->appKey = "62d07644754843cc882fca7c01476c4f";
|
|
|
|
|
|
$this->appSecret = "0c2c8b6b7c10481ea639f6daa09ac02e";
|
|
|
|
|
|
$this->accessToken = "78c246c0ab564e67add6296a9eaf04a1";;//每年都会过期 https://oauth.jdl.com/oauth/authorize?client_id=YOUR_APP_KEY&redirect_uri=urn:ietf:wg:oauth:2.0:oob&response_type=code
|
|
|
|
|
|
$this->customerCode = "27K1234912";//月结编码
|
|
|
|
|
|
}*/
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public function request($body, $path)
|
|
|
|
|
|
{
|
|
|
|
|
|
// 生产环境: https://api.jdl.com
|
|
|
|
|
|
$client = new DefaultClient($this->baseUrl);
|
|
|
|
|
|
// 系统参数,应用的app_ley和app_secret,可从【控制台-应用管理-概览】中查看;access_token是用户授权时获取的令牌,用户授权相关说明请查看https://cloud.jdl.com/#/devSupport/53392
|
|
|
|
|
|
$isvFilter = new IsvFilter($this->appKey, $this->appSecret, $this->accessToken);
|
|
|
|
|
|
$errorResponseFilter = new ErrorResponseFilter();
|
|
|
|
|
|
|
|
|
|
|
|
$request = new GenericRequest();
|
|
|
|
|
|
$request->setDomain($this->domain);//对接方案的编码,应用订购对接方案后可在订阅记录查看
|
|
|
|
|
|
$request->setPath($path);//api的path,可在API文档查看
|
|
|
|
|
|
$request->setMethod("POST");//只支持POST
|
|
|
|
|
|
// 序列化后的JSON字符串
|
|
|
|
|
|
$request->setBody(json_encode([$body]));
|
|
|
|
|
|
|
|
|
|
|
|
// 为请求添加ISV模式过滤器,自动根据算法计算开放平台鉴权及签名信息
|
|
|
|
|
|
$request->addFilter($isvFilter);
|
|
|
|
|
|
// 为请求添加错误响应解析过滤器,如果不添加需要手动解析错误响应
|
|
|
|
|
|
$request->addFilter($errorResponseFilter);
|
|
|
|
|
|
|
|
|
|
|
|
$options = new Options();
|
|
|
|
|
|
|
|
|
|
|
|
$options->setAlgorithm(Options::MD5_SALT);
|
|
|
|
|
|
Log::info("京东请求body:{$path}", [$body]);
|
|
|
|
|
|
$response = $client->execute($request, $options);
|
|
|
|
|
|
$response = json_decode($response->getBody(), true);
|
|
|
|
|
|
Log::info("京东返回请求response", [$response]);
|
2024-12-26 19:19:43 +08:00
|
|
|
|
if (!isset($response['code']) || ($response['code'] != 0 && $response['code'] != 1 && $response['code'] != 1000)) {
|
2024-12-28 11:13:17 +08:00
|
|
|
|
throw new \Exception($response['message'] ?? "code异常");
|
2024-12-26 14:32:02 +08:00
|
|
|
|
}
|
|
|
|
|
|
return $response;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private function buildCargoes($extend)
|
|
|
|
|
|
{
|
|
|
|
|
|
return [
|
2024-12-26 19:19:43 +08:00
|
|
|
|
"quantity" => $extend["quantity"] ?? 1,
|
|
|
|
|
|
"goodsName" => "鲜花",
|
|
|
|
|
|
"volume" => ($extend['volume'] ?? 0) > 0 ? $extend['volume'] : 100,
|
|
|
|
|
|
"weight" => $extend['weight'] ?? 1,
|
|
|
|
|
|
"packageQty" => 1
|
2024-12-26 14:32:02 +08:00
|
|
|
|
];
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public function buildContact($params)
|
|
|
|
|
|
{
|
|
|
|
|
|
return [
|
|
|
|
|
|
'senderName' => $params['name'] ?? '',
|
|
|
|
|
|
'senderPhone' => $params['mobile'] ?? '',
|
|
|
|
|
|
'senderAddress' => substr($params['province_name'] . $params['city_name'] . $params['area_name'] . $params['address_detail'], 0, 350),
|
|
|
|
|
|
];
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public function createOrder(Waybill $pickup)
|
|
|
|
|
|
{
|
|
|
|
|
|
$path = "/freshmedicinedelivery/delivery/create/order/v1";
|
|
|
|
|
|
$pickupData = $pickup->toArray();
|
|
|
|
|
|
$body = [
|
2024-12-26 19:19:43 +08:00
|
|
|
|
"orderId" => $pickupData['order_sn'],
|
2024-12-26 14:32:02 +08:00
|
|
|
|
"senderContactRequest" => [
|
|
|
|
|
|
'senderName' => $pickupData['sender_name'] ?? '',
|
|
|
|
|
|
'senderPhone' => $pickupData['sender_mobile'] ?? '',
|
|
|
|
|
|
'senderAddress' => substr($pickupData['sender_province'] . $pickupData['sender_city']
|
|
|
|
|
|
. $pickupData['sender_district'] . $pickupData['sender_detail'], 0, 350)
|
|
|
|
|
|
],
|
|
|
|
|
|
"customerCode" => $this->customerCode,
|
|
|
|
|
|
"remark" => $pickup['note'] ?? '',
|
2024-12-26 19:19:43 +08:00
|
|
|
|
"salePlatform" => '0030001',//其他平台
|
2024-12-26 14:32:02 +08:00
|
|
|
|
"cargoesRequest" => $this->buildCargoes($pickup),
|
|
|
|
|
|
"receiverContactRequest" => [
|
|
|
|
|
|
'receiverName' => $pickupData['recipient_name'] ?? '',
|
|
|
|
|
|
'receiverPhone' => $pickupData['recipient_mobile'] ?? '',
|
|
|
|
|
|
'receiverAddress' => substr($pickupData['recipient_province'] . $pickupData['recipient_city'] . $pickupData['recipient_district'] . $pickupData['recipient_detail'], 0, 350)
|
|
|
|
|
|
],
|
|
|
|
|
|
"channelOrderId" => $pickupData['order_sn'],
|
|
|
|
|
|
"promiseTimeType" => 26,//22:医药冷链 26:冷链专送,29医药专送
|
|
|
|
|
|
"goodsType" => 7,//1:普通,2:生鲜常温,5:鲜活,6:控温,7:冷藏,8:冷冻,9:深冷;21:医药冷藏,23:医药控温,24:医药常温,25:医药冷冻,27:医药深冷
|
2024-12-27 11:05:33 +08:00
|
|
|
|
//"pickUpStartTime" => Carbon::today()->startOfDay()->addDays(2)->addHours(19)->toDateTimeString(),
|
|
|
|
|
|
//"pickUpEndTime" => Carbon::today()->startOfDay()->addDays(2)->addHours(21)->toDateTimeString(),
|
2024-12-26 14:32:02 +08:00
|
|
|
|
];
|
2024-12-26 19:19:43 +08:00
|
|
|
|
|
2024-12-26 14:32:02 +08:00
|
|
|
|
$response = $this->request($body, $path);
|
|
|
|
|
|
return $response['data'];
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public function cancelOrder(Waybill $pickup)
|
|
|
|
|
|
{
|
|
|
|
|
|
$path = "/freshmedicinedelivery/delivery/cancel/waybill/v1";
|
|
|
|
|
|
$pickupData = $pickup->toArray();
|
|
|
|
|
|
$body = [
|
|
|
|
|
|
"waybillNo" => $pickupData['waybill_code'],
|
|
|
|
|
|
"customerCode" => $this->customerCode,
|
|
|
|
|
|
"interceptReason" => "订单信息有误",
|
|
|
|
|
|
];
|
|
|
|
|
|
$response = $this->request($body, $path);
|
|
|
|
|
|
|
|
|
|
|
|
return $response['data'];
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2024-12-26 19:19:43 +08:00
|
|
|
|
public function pullData(Waybill $pickup)
|
|
|
|
|
|
{
|
|
|
|
|
|
//云打印
|
|
|
|
|
|
$this->domain = "jdcloudprint";
|
|
|
|
|
|
$path = "/PullDataService/pullData";
|
|
|
|
|
|
$pickupData = $pickup->toArray();
|
|
|
|
|
|
$body = [
|
|
|
|
|
|
"cpCode" => "JD",
|
|
|
|
|
|
"wayBillInfos" => [[
|
|
|
|
|
|
'orderNo' => $pickupData['order_sn'],
|
|
|
|
|
|
'jdWayBillCode' => $pickupData['waybill_code'],
|
|
|
|
|
|
]],
|
|
|
|
|
|
"parameters" => ["ewCustomerCode" => $this->customerCode],
|
|
|
|
|
|
"objectId" => $pickupData['object_id'],
|
|
|
|
|
|
];
|
|
|
|
|
|
$response = $this->request($body, $path);
|
|
|
|
|
|
|
|
|
|
|
|
return $response['prePrintDatas'];
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2024-12-26 14:32:02 +08:00
|
|
|
|
public function queryOrder(Waybill $pickup)
|
|
|
|
|
|
{
|
|
|
|
|
|
$path = "/ecap/v1/orders/details/query";
|
|
|
|
|
|
$pickupData = $pickup->toArray();
|
|
|
|
|
|
$body = [
|
|
|
|
|
|
"waybillCode" => $pickupData['ship_sn'] ?? '',
|
|
|
|
|
|
"orderCode" => $pickupData['out_order_sn'] ?? "",
|
|
|
|
|
|
"customerCode" => $this->customerCode,
|
|
|
|
|
|
"orderOrigin" => 2,
|
|
|
|
|
|
];
|
|
|
|
|
|
$response = $this->request($body, $path);
|
|
|
|
|
|
|
|
|
|
|
|
return $response['data'];
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public function subscribe(Waybill $pickup)
|
|
|
|
|
|
{
|
|
|
|
|
|
$path = "/jd/tracking/subscribe";
|
|
|
|
|
|
$pickupData = $pickup->toArray();
|
|
|
|
|
|
$body = [
|
|
|
|
|
|
"referenceNumber" => $pickupData['ship_sn'] ?? '',
|
|
|
|
|
|
"referenceType" => 20000,
|
|
|
|
|
|
"customerCode" => $this->customerCode,
|
|
|
|
|
|
];
|
|
|
|
|
|
$this->domain = "Tracking_JD";//对接方案的编码
|
|
|
|
|
|
$response = $this->request($body, $path);
|
|
|
|
|
|
|
|
|
|
|
|
return $response['data'];
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public function queryFee(Waybill $pickup)
|
|
|
|
|
|
{
|
|
|
|
|
|
$path = "/ecap/v1/orders/actualfee/query";
|
|
|
|
|
|
$pickupData = $pickup->toArray();
|
|
|
|
|
|
$body = [
|
|
|
|
|
|
"waybillCode" => $pickupData['ship_sn'] ?? '',
|
|
|
|
|
|
"orderCode" => $pickupData['out_order_sn'] ?? "",
|
|
|
|
|
|
"customerCode" => $this->customerCode,
|
|
|
|
|
|
"orderOrigin" => 2,
|
|
|
|
|
|
];
|
|
|
|
|
|
$response = $this->request($body, $path);
|
|
|
|
|
|
|
|
|
|
|
|
return $response['data'];
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2024-12-28 11:13:17 +08:00
|
|
|
|
public function queryTrace(Waybill $pickup)
|
|
|
|
|
|
{
|
|
|
|
|
|
$path = "/freshmedicinedelivery/delivery/query/waybill/gis/v1";
|
|
|
|
|
|
$pickupData = $pickup->toArray();
|
|
|
|
|
|
$body = [
|
|
|
|
|
|
"waybillNo" => $pickupData['waybill_code'] ?? '',
|
|
|
|
|
|
"customerCode" => $this->customerCode,
|
|
|
|
|
|
];
|
|
|
|
|
|
$response = $this->request($body, $path);
|
|
|
|
|
|
|
|
|
|
|
|
return $response['data'];
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2024-12-26 14:32:02 +08:00
|
|
|
|
}
|
|
|
|
|
|
|