You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

590 lines
22 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<?php
namespace app\common\shipping;
use GuzzleHttp\Client;
use Ecpay\Sdk\Factories\Factory;
use Ecpay\Sdk\Services\CheckMacValueService;
use app\common\shipping\Ishipping;
use think\facade\Db;
use think\facade\Log;
//實作物流串接介面
class EcpayShipping implements Ishipping
{
private $api_url;
private $MerchantId;
private $HashIv;
private $HashKey;
private $SenderName;
private $SenderPhone;
public function __construct()
{
$shipping = Db::name('shipping')
->where('shipping_code', 'ecpay')
->find();
$config = json_decode($shipping['shipping_config'], true);
if ($shipping['is_test'] == 0) {
$this->api_url = 'https://logistics-stage.ecpay.com.tw';
$this->MerchantId = '2000933';
$this->HashIv = 'h1ONHk4P4yqbl5LK';
$this->HashKey = 'XBERn1YOvpM9nfZc';
$this->SenderName = isset($config['SenderName']) ? $config['SenderName'] : '測試人員';
$this->SenderPhone = isset($config['SenderPhone']) ? $config['SenderPhone'] : '0900000001';
} else {
if (empty($config['MerchantId']) || empty($config['HashIv']) || empty($config['HashKey'])) {
throw new \Exception('請先設定綠界物流參數');
}
$this->api_url = 'https://logistics.ecpay.com.tw';
$this->MerchantId = $config['MerchantId'];
$this->HashIv = $config['HashIv'];
$this->HashKey = $config['HashKey'];
$this->SenderName = isset($config['SenderName']) ? $config['SenderName'] : getConfigValue('service_company');
$this->SenderPhone = isset($config['SenderPhone']) ? $config['SenderPhone'] : getConfigValue('service_phone');
}
}
public function request($order)
{
$subType['1'] = 'UNIMARTC2C';
$subType['2'] = 'FAMIC2C';
$subType['3'] = 'HILIFEC2C';
$subType['4'] = 'OKMARTC2C';
$goods_list = '';
foreach ($order['goods_list'] as $goods) {
$goods_list .= $goods['goods_name'] . "#";
//如果$goods_list結尾是#,則去掉
if (substr($goods_list, -1) == '#') {
$goods_list = substr($goods_list, 0, -1);
}
}
$logistics = json_decode($order['address'], true);
// 綠界物流串接
$factory = new Factory([
'hashKey' => $this->HashKey,
'hashIv' => $this->HashIv,
'hashMethod' => 'md5',
]);
$ecService = $factory->create('PostWithCmvStrResponseService');
$shipping_data = [
'MerchantID' => $this->MerchantId,
'LogisticsType' => 'CVS',
'MerchantTradeNo' => $order['order_sn'],
'MerchantTradeDate' => date('Y/m/d H:i:s'),
'LogisticsSubType' => $subType[$logistics['type']],
'GoodsAmount' => $order['order_amount'],
'CollectionAmount' => $order['order_amount'],
'IsCollection' => $order['pay_id'] == 0 ? 'Y' : 'N',
'GoodsName' => $goods_list,
'SenderName' => $this->SenderName,
'SenderPhone' => $this->SenderPhone,
'SenderCellPhone' => $this->SenderPhone,
'ReceiverName' => $order['consignee'],
// 'ReceiverPhone' => $user_info['mobile_phone'],
'ReceiverCellPhone' => $order['mobile'],
'ReceiverStoreID' => $logistics['store_id'],
'ServerReplyURL' => getUrl() . '/appapi/v1/shipping/response/shippingcode/ecpay/',
];
$action = $this->api_url . '/Express/Create';
$rtn = $ecService->post($shipping_data, $action);
$rtn = explode("|", $rtn['body']);
if ($rtn[0] === '1') {
parse_str($rtn[1], $data);
//更新訂單資料
try {
Db::name('order_info')
->where('order_sn', $order['order_sn'])
->update([
'shipping_status' => 3,
'shipping_token' => $data['AllPayLogisticsID'],
'shipping_data' => json_encode($data)
]);
// $order = Db::name('order_info')
// ->where('order_sn', $order['order_sn'])
// ->find();
//更新訂單操縱紀錄
// $order_action = [
// 'order_id' => $order['order_id'],
// 'action_user' => '綠界科技',
// 'order_status' => $order['order_status'],
// 'shipping_status' => $order['shipping_status'],
// 'pay_status' => $order['pay_status'],
// 'action_note' => '綠界物流:' . $data['LogisticsSubType'] . '' . $data['RtnMsg'],
// 'log_time' => strtotime($data['UpdateStatusDate'])
// ];
// Db::name('order_action')->insert($order_action);
} catch (\Exception $e) {
return ['code' => 500, 'msg' => $e->getMessage()];
}
return ['code' => 200, 'msg' => '更新成功'];
} else {
return ['code' => 500, 'msg' => $rtn[1]];
}
}
public function response($data)
{
Log::write('綠界物流回傳:' . json_encode($data));
//判斷是否為綠界回傳資料
if (!isset($data['AllPayLogisticsID'])) {
return FALSE;
}
//TODO: 檢查碼驗證
//建立checkMacValueService物件
// $checkMacValueService = new CheckMacValueService($this->HashKey, $this->HashIv, 'md5');
//檢查碼驗證
// $checkMacValue = $checkMacValueService->generate($data);
// if($checkMacValue != $data['CheckMacValue']){
// return FALSE;
// }
$code = 201;
$message = '';
$order = Db::name('order_info')->where('order_sn', $data['MerchantTradeNo'])->find();
switch ($data['LogisticsSubType']) {
case 'UNIMARTC2C':
switch ($data['RtnCode']) {
case '300':
$update_data = [
'shipping_status' => 3,
];
break;
case '2073':
//物流已達取件門市,訂單完成
$update_data = [
'shipping_status' => 7,
];
break;
case '2067':
//物流已領取,訂單完成
$update_data = [
'shipping_status' => 2,
'order_status' => 7,
'pay_status' => 2,
];
$code = 200;
break;
case '2074':
//物流未領,訂單取消
$update_data = [
'shipping_status' => 4,
'order_status' => 6,
'pay_status' => 0,
];
//判斷是否為SlashCard商品並且為貨到付款
$order = Db::name('order_info')->where('order_sn', $data['MerchantTradeNo'])->find();
$is_main = Db::name('order_goods')
->where('order_id', $order['order_id'])
->where('goods_id', 1)
->find();
if ($is_main && $order['pay_id'] == 0) {
//將slashcard訂單取消
$rtn = \app\service\Card::cancelUser([
'order_sn' => $order['order_sn'],
'user_id' => Db::name('users')->where('user_id', $order['user_id'])->value('sso_user_id'),
]);
if ($rtn['code'] != 200) {
// 扣除點數失敗
}
}
break;
default:
$update_data = [
'shipping_status' => 1,
];
break;
}
break;
case 'FAMIC2C':
switch ($data['RtnCode']) {
case '3032':
//至超商寄貨
$update_data = [
'shipping_status' => 5,
'order_status' => $order['order_status'],
'pay_status' => $order['pay_status'],
];
break;
case '3018':
//物流已達取件門市,訂單完成
$update_data = [
'shipping_status' => 7,
];
break;
case '3022':
$update_data = [
'shipping_status' => 2,
'order_status' => 7,
'pay_status' => 2,
];
$code = 200;
break;
case '3020':
//物流未領,訂單取消
$update_data = [
'shipping_status' => 4,
'order_status' => 6,
'pay_status' => 0,
];
//判斷是否為SlashCard商品並且為貨到付款
$order = Db::name('order_info')->where('order_sn', $data['MerchantTradeNo'])->find();
$is_main = Db::name('order_goods')
->where('order_id', $order['order_id'])
->where('goods_id', 1)
->find();
if ($is_main && $order['pay_id'] == 0) {
//將slashcard訂單取消
$rtn = \app\service\Card::cancelUser([
'order_sn' => $order['order_sn'],
'user_id' => Db::name('users')->where('user_id', $order['user_id'])->value('sso_user_id'),
]);
if ($rtn['code'] != 200) {
// 扣除點數失敗
}
}
break;
default:
$update_data = [
'shipping_status' => 1,
'order_status' => $order['order_status'],
'pay_status' => $order['pay_status'],
];
break;
}
break;
case 'HILIFEC2C':
switch ($data['RtnCode']) {
case '2001':
//物流單成立
$update_data = [
'shipping_status' => 3,
];
break;
case '3018':
case '2063':
//物流已達取件門市,訂單完成
$update_data = [
'shipping_status' => 7,
];
break;
case '3022':
case '2067':
$update_data = [
'shipping_status' => 2,
'order_status' => 7,
'pay_status' => 2,
];
$code = 200;
break;
case '3020':
case '2074':
//物流未領,訂單取消
$update_data = [
'shipping_status' => 4,
'order_status' => 6,
'pay_status' => 0,
];
//判斷是否為SlashCard商品並且為貨到付款
$order = Db::name('order_info')->where('order_sn', $data['MerchantTradeNo'])->find();
$is_main = Db::name('order_goods')
->where('order_id', $order['order_id'])
->where('goods_id', 1)
->find();
if ($is_main && $order['pay_id'] == 0) {
//將slashcard訂單取消
$rtn = \app\service\Card::cancelUser([
'order_sn' => $order['order_sn'],
'user_id' => Db::name('users')->where('user_id', $order['user_id'])->value('sso_user_id'),
]);
if ($rtn['code'] != 200) {
// 扣除點數失敗
}
}
break;
default:
$update_data = [
'shipping_status' => 1,
'order_status' => $order['order_status'],
'pay_status' => $order['pay_status'],
];
break;
}
break;
case 'OKMARTC2C':
switch ($data['RtnCode']) {
case '300':
$update_data = [
'shipping_status' => 3,
];
break;
case '2073':
//物流已達取件門市,訂單完成
$update_data = [
'shipping_status' => 7,
];
break;
case '3022':
$update_data = [
'shipping_status' => 2,
'order_status' => 7,
'pay_status' => 2,
];
$code = 200;
break;
case '3032':
//至超商寄貨
$update_data = [
'shipping_status' => 1, //已發貨
'order_status' => $order['order_status'],
'pay_status' => $order['pay_status'],
];
break;
case '2074':
//物流未領,訂單取消
$update_data = [
'shipping_status' => 4,
'order_status' => 6,
'pay_status' => 0,
];
//判斷是否為SlashCard商品並且為貨到付款
$order = Db::name('order_info')->where('order_sn', $data['MerchantTradeNo'])->find();
$is_main = Db::name('order_goods')
->where('order_id', $order['order_id'])
->where('goods_id', 1)
->find();
if ($is_main && $order['pay_id'] == 0) {
//將slashcard訂單取消
$rtn = \app\service\Card::cancelUser([
'order_sn' => $order['order_sn'],
'user_id' => Db::name('users')->where('user_id', $order['user_id'])->value('sso_user_id'),
]);
if ($rtn['code'] != 200) {
// 扣除點數失敗
}
}
break;
default:
$update_data = [
'shipping_status' => 1,
'order_status' => $order['order_status'],
'pay_status' => $order['pay_status'],
];
break;
}
break;
default:
$code = 500;
break;
}
try {
//新增物流紀錄到order_shipping
$shipping_data = [
'order_id' => Db::name('order_info')->where('order_sn', $data['MerchantTradeNo'])->value('order_id'),
'code' => $data['RtnCode'],
'note' => $data['RtnMsg'],
'create_time' => strtotime($data['UpdateStatusDate']),
];
Db::name('order_shipping')->insert($shipping_data);
//更新訂單資料
if (isset($update_data)) {
Db::name('order_info')
->where('order_sn', $data['MerchantTradeNo'])
->update($update_data);
}
//更新訂單操作記錄
$order_info = Db::name('order_info')
->where('order_sn', $data['MerchantTradeNo'])
->find();
Db::name('order_action')
->insert(
[
'order_id' => $order_info['order_id'],
'action_user' => '綠界科技',
'order_status' => $order_info['order_status'],
'shipping_status' => $order_info['shipping_status'],
'pay_status' => $order_info['pay_status'],
'action_note' => '綠界物流:' . $data['LogisticsSubType'] . '' . $data['RtnMsg'],
'log_time' => strtotime($data['UpdateStatusDate'])
]
);
} catch (\Exception $e) {
$code = 500;
$message = $e->getMessage();
}
$rtn = [
'code' => $code,
'shippingcode' => 'ecpay',
'msg' => $message,
'order_sn' => $data['MerchantTradeNo'],
];
return $rtn;
}
public function map($params)
{
// 綠界物流地圖串接
$factory = new Factory([
'hashKey' => $this->HashKey,
'hashIv' => $this->HashIv,
'hashMethod' => 'md5',
]);
$formService = $factory->create('ReturnSubmitFormWithCmvService');
$input = [
'MerchantID' => $this->MerchantId,
'LogisticsType' => 'CVS',
'ServerReplyURL' => getUrl() . '/appapi/v1/shipping/mapresponse/shippingcode/ecpay/',
];
$input = array_merge($input, $params);
$action = $this->api_url . '/Express/map';
return $formService->generate($input, $action);
}
public function mapResponse($data)
{
//將LogisticsSubType轉換成數字
switch ($data['LogisticsSubType']) {
case 'UNIMARTC2C':
$data['LogisticsSubType'] = 1;
break;
case 'FAMIC2C':
$data['LogisticsSubType'] = 2;
break;
case 'HILIFEC2C':
$data['LogisticsSubType'] = 3;
break;
case 'OKMARTC2C':
$data['LogisticsSubType'] = 4;
break;
default:
return FALSE;
break;
}
$iData = [
'user_id' => getIdBySsoId($data['ExtraData']),
'type' => $data['LogisticsSubType'],
'store_id' => $data['CVSStoreID'],
'store_name' => $data['CVSStoreName'],
'store_address' => $data['CVSAddress'],
'store_tel' => $data['CVSTelephone'],
'is_default' => 1,
];
//將$data寫入user_cvs資料庫
$is_exist = Db::name('user_cvs')
->where('store_id', $data['CVSStoreID'])
->where('user_id', getIdBySsoId($data['ExtraData']))
->count();
try {
//將所有的is_default設為0
Db::name('user_cvs')
->where('user_id', getIdBySsoId($data['ExtraData']))
->update(['is_default' => 0]);
if (!$is_exist) {
Db::name('user_cvs')->insert($iData);
} else {
//將該筆資料的is_default設為1
Db::name('user_cvs')
->where('user_id', getIdBySsoId($data['ExtraData']))
->where('store_id', $data['CVSStoreID'])
->update(['is_default' => 1]);
}
} catch (\Exception $e) {
return FALSE;
}
$result['redirect_url'] = getUrl() . '/m/order/shipping?is_return=1';
return $result;
}
public function printLabel($params)
{
$factory = new Factory([
'hashKey' => $this->HashKey,
'hashIv' => $this->HashIv,
'hashMethod' => 'md5',
]);
$formService = $factory->create('AutoSubmitFormWithCmvService');
$input = [
'MerchantID' => $this->MerchantId,
'PlatformID' => '',
];
$input = array_merge($input, $params);
switch ($params['type']) {
case 'UNIMARTC2C':
$action = $this->api_url . '/Express/PrintUniMartC2COrderInfo';
break;
case 'FAMIC2C':
$action = $this->api_url . '/Express/PrintFAMIC2COrderInfo';
break;
case 'HILIFEC2C':
$action = $this->api_url . '/Express/PrintHiLifeC2COrderInfo';
break;
case 'OKMARTC2C':
$action = $this->api_url . '/Express/PrintOKMARTC2COrderInfo';
break;
}
return $formService->generate($input, $action);
}
}