erp-backend/app/Services/Platform/TaobaoClient.php
2026-04-01 17:07:04 +08:00

159 lines
5.3 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
namespace App\Services\Platform;
use App\Models\ShopAuth;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Log;
class TaobaoClient
{
protected $shopAuth;
protected $appKey;
protected $appSecret;
public function __construct(ShopAuth $shopAuth)
{
$this->shopAuth = $shopAuth;
$this->appKey = config('platforms.taobao.app_key');
$this->appSecret = config('platforms.taobao.app_secret');
}
/**
* 拉取订单列表
*
* @param array $params
* @return array 标准化的订单数据
* @throws \Exception
*/
public function getOrders(array $params = [])
{
$this->ensureToken();
$requestParams = [
'method' => 'taobao.trades.sold.get',
'app_key' => $this->appKey,
'session' => $this->shopAuth->access_token,
'timestamp' => date('Y-m-d H:i:s'),
'v' => '2.0',
'format' => 'json',
'fields' => 'tid,type,status,payment,orders,receiver_name,receiver_phone,receiver_address,created,modified,pay_time',
'page_no' => $params['page_no'] ?? 1,
'page_size' => min($params['page_size'] ?? 40, 100),
];
if (!empty($params['start_time'])) {
$requestParams['start_created'] = $params['start_time'];
}
if (!empty($params['end_time'])) {
$requestParams['end_created'] = $params['end_time'];
}
$requestParams['sign'] = $this->generateSign($requestParams);
try {
$response = Http::timeout(30)->get('https://eco.taobao.com/router/rest', $requestParams);
$result = $response->json();
} catch (\Exception $e) {
Log::error('淘宝API请求失败', ['error' => $e->getMessage()]);
throw new \Exception('网络请求失败:' . $e->getMessage());
}
if (isset($result['error_response'])) {
$errorCode = $result['error_response']['code'];
$errorMsg = $result['error_response']['msg'];
// token 失效则刷新重试一次
if (in_array($errorCode, [26, 27])) {
$this->refreshToken();
return $this->getOrders($params);
}
throw new \Exception("淘宝API错误 [{$errorCode}]: {$errorMsg}");
}
$trades = $result['trades_sold_get_response']['trades']['trade'] ?? [];
return $this->transformOrders($trades);
}
protected function refreshToken()
{
$params = [
'method' => 'taobao.top.auth.token.refresh',
'app_key' => $this->appKey,
'session' => $this->shopAuth->refresh_token,
'timestamp' => date('Y-m-d H:i:s'),
'v' => '2.0',
'format' => 'json',
];
$params['sign'] = $this->generateSign($params);
$response = Http::get('https://eco.taobao.com/router/rest', $params);
$result = $response->json();
if (isset($result['error_response'])) {
throw new \Exception('刷新Token失败' . $result['error_response']['msg']);
}
$tokenData = $result['top_auth_token_refresh_response'];
$this->shopAuth->access_token = $tokenData['access_token'];
$this->shopAuth->expires_at = now()->addSeconds($tokenData['expires_in']);
$this->shopAuth->refresh_token = $tokenData['refresh_token'] ?? $this->shopAuth->refresh_token;
$this->shopAuth->save();
}
protected function ensureToken()
{
if ($this->shopAuth->expires_at && $this->shopAuth->expires_at->isPast()) {
$this->refreshToken();
}
}
protected function generateSign($params)
{
ksort($params);
$str = $this->appSecret;
foreach ($params as $k => $v) {
if ($k !== 'sign') {
$str .= $k . $v;
}
}
$str .= $this->appSecret;
return strtoupper(md5($str));
}
protected function transformOrders($trades)
{
$orders = [];
foreach ($trades as $trade) {
$orders[] = [
'platform_order_sn' => (string)$trade['tid'],
'order_time' => $trade['created'],
'payment_time' => $trade['pay_time'] ?? null,
'buyer_nick' => $trade['buyer_nick'] ?? '',
'receiver_name' => $trade['receiver_name'],
'receiver_phone' => $trade['receiver_phone'],
'receiver_address' => $trade['receiver_address'],
'goods_amount' => $trade['payment'] ?? 0,
'discount_amount' => 0,
'freight' => 0,
'total_amount' => $trade['payment'] ?? 0,
'platform_status' => $trade['status'],
'items' => $this->transformItems($trade['orders']['order'] ?? []),
];
}
return $orders;
}
protected function transformItems($items)
{
$result = [];
foreach ($items as $item) {
$result[] = [
'goods_name' => $item['title'],
'platform_sku' => (string)($item['sku_id'] ?? $item['num_iid']),
'quantity' => $item['num'],
'price' => $item['price'],
'total_amount' => $item['total_fee'],
];
}
return $result;
}
}