595 lines
20 KiB
PHP
595 lines
20 KiB
PHP
<?php
|
||
|
||
namespace addon\ali1688\model;
|
||
|
||
use app\model\BaseModel;
|
||
use think\facade\Cache;
|
||
use addon\ali1688\model\Config as ConfigModel;
|
||
|
||
class CloudApi extends BaseModel
|
||
{
|
||
public $appKey = '5551517';
|
||
public $appSecret = 'eIXulHBjO4UK';
|
||
public $gatewayHost = 'https://gw.open.1688.com/openapi/param2/1/';
|
||
public $site_id;
|
||
|
||
public $access_token;
|
||
public $config;
|
||
|
||
public $public = [];
|
||
public $agent_baseURL = 'https://1688.sopvip.com/agent';
|
||
public $redirect_uri = 'https://1688.sopvip.com/getAuth';
|
||
public $notify_status = 'https://1688.sopvip.com/notifyStatus';
|
||
|
||
public function __construct($site_id = 0)
|
||
{
|
||
$this->site_id = $site_id;
|
||
$this->public = [
|
||
'client_id' => $this->appKey,
|
||
'client_secret' => $this->appSecret,
|
||
];
|
||
if (request()->param('code') && request()->param('state')) {
|
||
$state = explode('|', base64_decode(request()->param('state')));
|
||
$this->site_id = $state[1];
|
||
$this->getAccessToken(request()->param('code'));
|
||
if (!cache(request()->param('code'))) {
|
||
cache(request()->param('code'), 1);
|
||
$this->getAccessToken(request()->param('code'));
|
||
} else {
|
||
$this->access_token = Cache::store('redis_public')->get($this->site_id . '1688access_token');
|
||
}
|
||
} else {
|
||
$this->refreshToken();
|
||
}
|
||
}
|
||
|
||
|
||
/***
|
||
* 获取授权码
|
||
* @param $_uri
|
||
* @param $redirect_uri
|
||
* @return string
|
||
*/
|
||
public function getAuthorization_codeurl($_uri = '', $redirect_uri = '')
|
||
{
|
||
$redirect = $_uri ?: addon_url('ali1688/shop/auth/index');
|
||
$codeData = [
|
||
'grant_type' => 'authorization_code',
|
||
'client_id' => $this->appKey,
|
||
'site' => 1688,
|
||
'state' => base64_encode($redirect . '|' . $this->site_id),
|
||
'redirect_uri' => $redirect_uri ?: $this->redirect_uri,
|
||
];
|
||
return 'https://auth.1688.com/oauth/authorize?' . http_build_query($codeData);
|
||
}
|
||
|
||
/***
|
||
* 查询是否免密支付
|
||
* @return void
|
||
*/
|
||
public function getTradeIsopenProtocolPay()
|
||
{
|
||
$api = 'com.alibaba.trade/alibaba.trade.pay.protocolPay.isopen';
|
||
$result = $this->requestApi($api, []);
|
||
$result = json_decode($result, true);
|
||
$data['ispayopen'] = false;
|
||
$data['signUrl'] = 'https://tradeconfig.1688.com/foundation/withhold_manage.htm';
|
||
if (isset($result['success'])) {
|
||
$paymentAgreements = $result['result']['paymentAgreements'];
|
||
foreach ($paymentAgreements as $item) {
|
||
$data['signUrl'] = $item['signUrl'];
|
||
if ($item['bindingStatus'] == 'true' && $item['signedStatus'] == 'true') {
|
||
$data['ispayopen'] = true;
|
||
} else {
|
||
$data['ispayopen'] = false;
|
||
continue;
|
||
}
|
||
}
|
||
}
|
||
return $data;
|
||
}
|
||
|
||
public function getAppBuyInfo()
|
||
{
|
||
// $api = 'cn.alibaba.open/alibaba.app.pieceorder.get';
|
||
$api = 'cn.alibaba.open/app.order.get';
|
||
// var_dump($this->config);die;
|
||
// var_dump(date('Y-m-d H:i:s',time());
|
||
// var_dump(date('YmdHis',time())+'000+0800');die;
|
||
$result = $this->requestApi($api, [
|
||
'gmtCreate' => json_encode([date('YmdHis', $this->config['create_time']) . '000+0800', date('YmdHis', time()) . '000+0800']),
|
||
// 'gmtCreate'=>$this->config['create_time']*1000,
|
||
// 'memberId'=>$this->config['value']['memberId']??'',
|
||
'aliId' => $this->config['value']['aliId'] ?? '',
|
||
'bizStatusList' => json_encode(['S', 'E', 'B'])
|
||
]);
|
||
// var_dump($this->config['value']['memberId'],$this->config['create_time'],$result);die;
|
||
$result = json_decode($result, true);
|
||
$data = [
|
||
'isbuyapp' => false,
|
||
'expire_time' => -1,
|
||
];
|
||
if (isset($result['returnValue'])) {
|
||
return $result['returnValue'];
|
||
}
|
||
return $data;
|
||
}
|
||
|
||
|
||
/***
|
||
* 地址解析
|
||
* @param $addressInfo
|
||
* @return mixed
|
||
* @throws \Exception
|
||
*/
|
||
public function getTradeAddresscodeParse($addressInfo = '')
|
||
{
|
||
$api = 'com.alibaba.trade/alibaba.trade.addresscode.parse';
|
||
$result = $this->requestApi($api, [
|
||
'addressInfo' => $addressInfo
|
||
]);
|
||
$result = json_decode($result, true);
|
||
return $result;
|
||
}
|
||
|
||
/***
|
||
* 创建订单预览
|
||
* @param $data
|
||
* @return mixed
|
||
* @throws \Exception
|
||
*/
|
||
public function createOrderPreview($data = [])
|
||
{
|
||
$api = 'com.alibaba.trade/alibaba.createOrder.preview';
|
||
$result = $this->requestApi($api, $data);
|
||
$result = json_decode($result, true);
|
||
return $result;
|
||
}
|
||
|
||
|
||
/****
|
||
* 创建订单
|
||
* @param $data
|
||
* @return mixed
|
||
* @throws \Exception
|
||
*/
|
||
public function fastCreateOrder($data = [])
|
||
{
|
||
$api = 'com.alibaba.trade/alibaba.trade.fastCreateOrder';
|
||
$result = $this->requestApi($api, $data);
|
||
$result = json_decode($result, true);
|
||
return $result;
|
||
}
|
||
|
||
|
||
/***
|
||
* 取消订单
|
||
* @param $orderID
|
||
* @return mixed
|
||
* @throws \Exception
|
||
*/
|
||
public function cancelOrder($tradeID, $cancelReason, $remark = '')
|
||
{
|
||
$api = 'com.alibaba.trade/alibaba.trade.cancel';
|
||
$result = $this->requestApi($api, ['webSite' => 1688, 'tradeID' => implode(',', $tradeID), 'cancelReason' => $cancelReason, 'remark' => $remark]);
|
||
$result = json_decode($result, true);
|
||
return $result;
|
||
}
|
||
|
||
/***
|
||
* 获取1688分类
|
||
* @param $categoryID
|
||
* @return mixed
|
||
* @throws \Exception
|
||
*/
|
||
public function getAlibabaCategory($categoryID = 0)
|
||
{
|
||
$Cache = Cache::get('1688categoryInfo' . $categoryID);
|
||
if ($Cache) {
|
||
return $Cache;
|
||
}
|
||
$api = 'com.alibaba.product/alibaba.category.get';
|
||
$result = $this->requestApi($api, ['categoryID' => $categoryID]);
|
||
$result = json_decode($result, true);
|
||
if (isset($result['categoryInfo'])) {
|
||
if ($categoryID == 0) {
|
||
Cache::set('1688categoryInfo' . $categoryID, $result['categoryInfo'][0]['childCategorys']);
|
||
return $result['categoryInfo'][0]['childCategorys'];
|
||
}
|
||
}
|
||
return $result;
|
||
}
|
||
|
||
|
||
public function getAlibabaProductFilter()
|
||
{
|
||
$Cache = Cache::get('1688productFilter');
|
||
if ($Cache) {
|
||
return $Cache;
|
||
}
|
||
$api = 'com.alibaba.fenxiao/jxhy.productFilter.get';
|
||
$result = $this->requestApi($api);
|
||
$result = json_decode($result, true);
|
||
if (isset($result['result']['result'])) {
|
||
$result = $result['result']['result'];
|
||
Cache::set('1688productFilter', $result);
|
||
return $result;
|
||
}
|
||
return [];
|
||
}
|
||
|
||
/***
|
||
* 获取授权令牌
|
||
* @param $code
|
||
* @return mixed
|
||
* @throws \Psr\SimpleCache\InvalidArgumentException
|
||
*/
|
||
public function getAccessToken($code = '')
|
||
{
|
||
$ConfigModel = new ConfigModel();
|
||
$config = (array)$ConfigModel->getConfig($this->site_id)['data']['value'];
|
||
if ($code == '' && isset($config['expire_tiem']) && intval($config['expire_tiem']) > time()) {
|
||
$this->access_token = $config['access_token'];
|
||
Cache::store('redis_public')->set($this->site_id . '1688access_token', $this->access_token, $config['expire_tiem'] - time());
|
||
return $this->access_token;
|
||
}
|
||
$url = "https://gw.open.1688.com/openapi/http/1/system.oauth2/getToken/{$this->appKey}";
|
||
$urlData = array_merge($this->public, [
|
||
'grant_type' => 'authorization_code',
|
||
'need_refresh_token' => true,
|
||
'client_id' => $this->appKey,
|
||
'client_secret' => $this->appSecret,
|
||
'code' => $code,
|
||
'redirect_uri' => addon_url('ali1688/shop/auth/info'),
|
||
]);
|
||
if ($this->agent_baseURL) {
|
||
$baseData = [
|
||
'baseURL' => $url,
|
||
'domain' => addon_url('ali1688/api/notify/index'),
|
||
'site_id' => $this->site_id,
|
||
'event' => 'AccessToken',
|
||
'data' => json_encode(array_merge($this->public, $urlData))
|
||
];
|
||
$result = $this->http_post_data($this->agent_baseURL, $baseData);
|
||
} else {
|
||
$result = http($url, 30, [], $urlData);
|
||
}
|
||
$json = json_decode($result, true);
|
||
if ($json && isset($json['access_token'])) {
|
||
$json['expire_tiem'] = time() + intval($json['expires_in']);
|
||
Cache::store('redis_public')->set($this->site_id . '1688access_token', $json['access_token'], intval($json['expires_in']) - 500);
|
||
$ConfigModel->setConfig(array_merge($config, $json), $this->site_id, 1);
|
||
$this->access_token = $json['access_token'];
|
||
} else {
|
||
return '';
|
||
}
|
||
return $this->access_token;
|
||
}
|
||
|
||
|
||
/***
|
||
* 重置TOKEN
|
||
* @return mixed|string
|
||
* @throws \Psr\SimpleCache\InvalidArgumentException
|
||
*/
|
||
public function refreshToken()
|
||
{
|
||
$ConfigModel = new ConfigModel();
|
||
$config = $ConfigModel->getConfig($this->site_id)['data']['value'];
|
||
$this->config = $ConfigModel->getConfig($this->site_id)['data'];
|
||
if (isset($config['expire_tiem']) && intval($config['expire_tiem']) > time()) {
|
||
$this->access_token = $config['access_token'];
|
||
Cache::store('redis_public')->set($this->site_id . '1688access_token', $this->access_token, $config['expire_tiem'] - time());
|
||
return $this->access_token;
|
||
}
|
||
$url = "https://gw.open.1688.com/openapi/param2/1/system.oauth2/getToken/{$this->appKey}";
|
||
$urlData = array_merge($this->public, [
|
||
'grant_type' => 'refresh_token',
|
||
'refresh_token' => $config['refresh_token'] ?? '',
|
||
'client_id' => $this->appKey,
|
||
'client_secret' => $this->appSecret,
|
||
]);
|
||
if ($this->agent_baseURL) {
|
||
$baseData = [
|
||
'baseURL' => $url,
|
||
'domain' => addon_url('ali1688/api/notify/index'),
|
||
'site_id' => $this->site_id,
|
||
'event' => 'AccessToken',
|
||
'data' => json_encode(array_merge($this->public, $urlData))
|
||
];
|
||
$result = $this->http_post_data($this->agent_baseURL, $baseData);
|
||
} else {
|
||
$result = http($url, 30, [], $urlData);
|
||
}
|
||
$json = json_decode($result, true);
|
||
if ($json && isset($json['access_token'])) {
|
||
$json['expire_tiem'] = time() + intval($json['expires_in']);
|
||
Cache::store('redis_public')->set($this->site_id . '1688access_token', $json['access_token'], intval($json['expires_in']) - 500);
|
||
$ConfigModel->setConfig(array_merge($config, $json), $this->site_id, 1);
|
||
$this->access_token = $json['access_token'];
|
||
} else {
|
||
return '';
|
||
}
|
||
return $this->access_token;
|
||
}
|
||
|
||
|
||
//获取商品详情
|
||
public function productInfoGet($data)
|
||
{
|
||
$api = 'com.alibaba.fenxiao/alibaba.fenxiao.productInfo.get';
|
||
return json_decode($this->requestApi($api, ['openOfferId' => $data['open_offer_id']]), true);
|
||
}
|
||
|
||
//添加分销店铺(买家)
|
||
public function buyerOutshopAdd()
|
||
{
|
||
$api = 'com.alibaba.fenxiao/alibaba.fenxiao.buyer.outshop.add';
|
||
|
||
return json_decode($this->requestApi($api, ['outShopCode' => $this->site_id, 'channel' => 'other']), true);
|
||
}
|
||
|
||
//添加分销商品关系(买家)
|
||
public function buyerOutproductRelationAdd()
|
||
{
|
||
$api = 'com.alibaba.fenxiao/alibaba.fenxiao.buyer.outproduct.relation.add';
|
||
$data = [
|
||
'channel' => 'other',
|
||
'outShopCode' => $this->site_id,
|
||
'outItemCode' => '6',
|
||
'openOfferId' => 'BgnuDNkhiXPv88gpE3sfbA==',
|
||
];
|
||
return json_decode($this->requestApi($api, $data), true);
|
||
}
|
||
|
||
|
||
/***
|
||
* 获取物流公司列表
|
||
* @return array|mixed
|
||
* @throws \Psr\SimpleCache\InvalidArgumentException
|
||
*/
|
||
public function getLogisticCompanyList()
|
||
{
|
||
$LogisticCompanyList = Cache::store('redis_public')->get('OpQueryLogisticCompanyList');
|
||
if ($LogisticCompanyList) {
|
||
return $LogisticCompanyList;
|
||
} else {
|
||
$api = 'com.alibaba.logistics/alibaba.logistics.OpQueryLogisticCompanyList.offline';
|
||
$res = json_decode($this->requestApi($api), true);
|
||
if (isset($res['result']) && $res['result']) {
|
||
$list = array_column($res['result'], null, 'companyNo');
|
||
Cache::store('redis_public')->set('OpQueryLogisticCompanyList', $list);
|
||
return $list;
|
||
}
|
||
return [];
|
||
}
|
||
}
|
||
|
||
|
||
//根据地址解析地区码
|
||
public function addressCodeParse($address)
|
||
{
|
||
$api = 'com.alibaba.trade/alibaba.trade.addresscode.parse';
|
||
return json_decode($this->requestApi($api, ['addressInfo' => $address]), true)['result'];
|
||
}
|
||
|
||
//查询订单可以支持的支付渠道
|
||
|
||
/***
|
||
* 查询支付渠道
|
||
* @param $orderId
|
||
* @return mixed
|
||
* @throws \Exception
|
||
*/
|
||
public function payWayQuery($orderId)
|
||
{
|
||
$api = 'com.alibaba.trade/alibaba.trade.payWay.query';
|
||
return json_decode($this->requestApi($api, ['orderId' => $orderId]), true);
|
||
}
|
||
|
||
|
||
/***
|
||
* 发起在线支付
|
||
* @param $orderIds
|
||
* @param $type PC或WIRELESS
|
||
* @return mixed
|
||
* @throws \Exception
|
||
*/
|
||
public function GroupPayUrl($orderIds, $type = 'PC')
|
||
{
|
||
$api = 'com.alibaba.trade/alibaba.trade.grouppay.url.get';
|
||
return json_decode($this->requestApi($api, ['orderIds' => $orderIds, 'payPlatformType' => $type]), true);
|
||
}
|
||
|
||
/***
|
||
* 发起免密支付
|
||
* @param $orderId
|
||
* @return mixed
|
||
* @throws \Exception
|
||
*/
|
||
public function protocolPayPreparePay($orderId)
|
||
{
|
||
$api = 'com.alibaba.trade/alibaba.trade.pay.protocolPay.preparePay';
|
||
return json_decode($this->requestApi($api, ['tradeWithholdPreparePayParam' =>json_encode(['orderId' => $orderId])]), true);
|
||
}
|
||
|
||
|
||
//获取交易订单的物流信息
|
||
public function getLogisticsInfos($orderId)
|
||
{
|
||
$api = 'com.alibaba.logistics/alibaba.trade.getLogisticsInfos.buyerView';
|
||
return json_decode($this->requestApi($api, ['orderId' => $orderId]), true);
|
||
}
|
||
|
||
//获取交易订单的物流跟踪信息
|
||
public function getLogisticsTraceInfo($orderId)
|
||
{
|
||
$api = 'com.alibaba.logistics/alibaba.trade.getLogisticsTraceInfo.buyerView';
|
||
return json_decode($this->requestApi($api, ['orderId' => $orderId, 'webSite' => '1688']), true);
|
||
}
|
||
|
||
//查询退款退货原因(用于创建退款退货)
|
||
public function getRefundReasonList($data)
|
||
{
|
||
$api = 'com.alibaba.trade/alibaba.trade.getRefundReasonList';
|
||
$array = [
|
||
'orderId' => $data['orderId'],
|
||
'orderEntryIds' => $data['orderEntryIds'],
|
||
'goodsStatus' => $data['goodsStatus'],
|
||
];
|
||
return json_decode($this->requestApi($api, $array), true);
|
||
}
|
||
|
||
//创建退款退货申请
|
||
public function createRefund($data)
|
||
{
|
||
$api = 'com.alibaba.trade/alibaba.trade.createRefund';
|
||
$array = [
|
||
'orderId' => $data['orderId'],
|
||
'orderEntryIds' => $data['orderEntryIds'],
|
||
'disputeRequest' => $data['disputeRequest'],
|
||
'applyPayment' => $data['applyPayment'],
|
||
'applyCarriage' => $data['applyCarriage'],
|
||
'applyReasonId' => $data['applyReasonId'],
|
||
'description' => $data['description'],
|
||
'goodsStatus' => $data['goodsStatus'],
|
||
];
|
||
return json_decode($this->requestApi($api, $array), true);
|
||
}
|
||
|
||
//上传退款退货凭证
|
||
public function uploadRefundVoucher($imageData)
|
||
{
|
||
$api = 'com.alibaba.trade/alibaba.trade.uploadRefundVoucher';
|
||
return json_decode($this->requestApi($api, ['imageData' => $imageData]), true);
|
||
}
|
||
|
||
//查询退款单列表(买家视角)
|
||
public function queryOrderRefundList($data)
|
||
{
|
||
$api = 'com.alibaba.trade/alibaba.trade.refund.buyer.queryOrderRefundList';
|
||
return json_decode($this->requestApi($api, $data), true);
|
||
}
|
||
|
||
//查询退款单详情-根据订单ID(买家视角)
|
||
public function OpQueryBatchRefundByOrderIdAndStatus($data)
|
||
{
|
||
$api = 'com.alibaba.trade/alibaba.trade.refund.OpQueryBatchRefundByOrderIdAndStatus';
|
||
return json_decode($this->requestApi($api, $data), true);
|
||
}
|
||
|
||
//查询退款单详情-根据退款单ID(买家视角)
|
||
public function OpQueryOrderRefund($data)
|
||
{
|
||
$api = 'com.alibaba.trade/alibaba.trade.refund.OpQueryOrderRefund';
|
||
return json_decode($this->requestApi($api, $data), true);
|
||
}
|
||
|
||
//退款单操作记录列表(买家视角)
|
||
public function OpQueryOrderRefundOperationList($data)
|
||
{
|
||
$api = 'com.alibaba.trade/alibaba.trade.refund.OpQueryOrderRefundOperationList';
|
||
return json_decode($this->requestApi($api, $data), true);
|
||
}
|
||
|
||
//买家提交退款货信息
|
||
public function refundReturnGoods($data)
|
||
{
|
||
$api = 'com.alibaba.trade:alibaba.trade.refund.returnGoods';
|
||
return json_decode($this->requestApi($api, $data), true);
|
||
}
|
||
|
||
//订购的订单列表
|
||
public function pieceorderGet($data)
|
||
{
|
||
$api = 'cn.alibaba.open/alibaba.app.pieceorder.get';
|
||
return json_decode($this->requestApi($api, $data), true);
|
||
}
|
||
|
||
//app 在服务市场被订购的订单列表
|
||
public function orderGet($data)
|
||
{
|
||
$api = 'cn.alibaba.open/app.order.get';
|
||
return json_decode($this->requestApi($api, $data), true);
|
||
}
|
||
|
||
|
||
//获取某个应用最近一个月的到期订单信息
|
||
public function expireGet($data)
|
||
{
|
||
$api = 'cn.alibaba.open/app.expire.get';
|
||
return json_decode($this->requestApi($api, $data), true);
|
||
}
|
||
|
||
/***
|
||
* 获取签名
|
||
* @param $path
|
||
* @param $postData
|
||
* @return string
|
||
*/
|
||
public function getSign($path, $postData)
|
||
{
|
||
$paramsToSign = array();
|
||
foreach ($postData as $k => $v) {
|
||
$paramToSign = $k . $v;
|
||
array_push($paramsToSign, $paramToSign);
|
||
}
|
||
sort($paramsToSign);
|
||
$implodeParams = implode($paramsToSign);
|
||
$pathAndParams = $path . $implodeParams;
|
||
$sign = hash_hmac("sha1", $pathAndParams, $this->appSecret, true);
|
||
$signHexWithLowcase = bin2hex($sign);
|
||
$signHexUppercase = strtoupper($signHexWithLowcase);
|
||
return $signHexUppercase;
|
||
}
|
||
|
||
/***
|
||
* 请求接口
|
||
* @param string $api
|
||
* @param $data
|
||
* @return array|bool|mixed|string
|
||
* @throws \Exception
|
||
*/
|
||
public function requestApi(string $api, $data = [], $extend = '')
|
||
{
|
||
$event = $api;
|
||
// 信息处理 获取请求签名
|
||
$api .= '/' . $this->appKey;
|
||
$timestamp = round(microtime(true) * 1000);
|
||
$data['_aop_timestamp'] = $timestamp;
|
||
$data['access_token'] = $this->access_token;
|
||
$data['_aop_signature'] = $this->getSign($api, $data);
|
||
// 发起请求
|
||
$link = $this->gatewayHost . $api;
|
||
if ($this->agent_baseURL) {
|
||
$bestdata = [
|
||
'domain' => config('domain.url') . '/ali1688/api/notify/index',
|
||
'site_id' => $this->site_id,
|
||
'event' => $event,
|
||
'baseURL' => $link,
|
||
'data' => json_encode(array_merge($this->public, $data))
|
||
];
|
||
|
||
return $this->http_post_data($this->agent_baseURL, $bestdata);
|
||
} else {
|
||
return http($link, 30, [], array_merge($this->public, $data));
|
||
}
|
||
}
|
||
|
||
public function http_post_data($url, $params = array())
|
||
{
|
||
if (is_array($params)) {
|
||
$params = http_build_query($params, null, '&');
|
||
}
|
||
$ch = curl_init();
|
||
curl_setopt($ch, CURLOPT_POST, 1);
|
||
curl_setopt($ch, CURLOPT_URL, $url);
|
||
curl_setopt($ch, CURLOPT_POSTFIELDS, $params);
|
||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
|
||
curl_setopt($ch, CURLOPT_TIMEOUT, 30);
|
||
$response = curl_exec($ch);
|
||
curl_close($ch);
|
||
return $response;
|
||
}
|
||
}
|