Просмотр исходного кода

Merge branch 'dev' of http://gogs.hnwmzp.cn/chengwenliang/nshop into dev

chengwl 4 дней назад
Родитель
Сommit
79b7d9bc0f

+ 20 - 4
packages/Longyi/Pay/Afterpay/src/Config/system.php

@@ -38,16 +38,32 @@ return [
                 'channel_based' => false,
                 'locale_based' => true,
             ], [
-                'name' => 'client_id',
-                'title' => 'Merchant ID',
+                'name' => 'client_id_us',
+                'title' => 'Merchant ID (US)',
                 'type' => 'text',
                 'depend' => 'active:1',
                 'validation' => 'required_if:active,1',
                 'channel_based' => false,
                 'locale_based' => true,
             ], [
-                'name' => 'secret_id',
-                'title' => 'Merchant Key',
+                'name' => 'secret_id_us',
+                'title' => 'Merchant Key (US)',
+                'type' => 'password',
+                'depend' => 'active:1',
+                'validation' => 'required_if:active,1',
+                'channel_based' => false,
+                'locale_based' => true,
+            ], [
+                'name' => 'client_id_ca',
+                'title' => 'Merchant ID (CA)',
+                'type' => 'text',
+                'depend' => 'active:1',
+                'validation' => 'required_if:active,1',
+                'channel_based' => false,
+                'locale_based' => true,
+            ], [
+                'name' => 'secret_id_ca',
+                'title' => 'Merchant Key (CA)',
                 'type' => 'password',
                 'depend' => 'active:1',
                 'validation' => 'required_if:active,1',

+ 42 - 3
packages/Longyi/Pay/Afterpay/src/Payment/Afterpay.php

@@ -29,11 +29,36 @@ class Afterpay extends Payment
             $this->capturePaymentUlr = 'https://global-api.afterpay.com/v2/payments/capture';
             $this->configurationUlr = 'https://global-api.afterpay.com/v2/configuration';
         }
-        $this->clientId = $this->getConfigData('client_id');
-        $this->apikey = $this->getConfigData('secret_id');
+        $this->clientId = $this->getConfigData('client_id_us');
+        $this->apikey = $this->getConfigData('secret_id_us');
         $this->secret = $this->getConfigData('webhook_id');
     }
 
+    /**
+     * 根据国家代码动态解析并设置 Afterpay 凭证
+     * 美国用 US 凭证,加拿大用 CA 凭证
+     */
+    protected function resolveCredentials(?string $countryCode = null): void
+    {
+        if ($countryCode === 'CA') {
+            $this->clientId = $this->getConfigData('client_id_ca');
+            $this->apikey = $this->getConfigData('secret_id_ca');
+        } else {
+            // 默认使用美国凭证 (US)
+            $this->clientId = $this->getConfigData('client_id_us');
+            $this->apikey = $this->getConfigData('secret_id_us');
+        }
+    }
+
+    /**
+     * 从当前订单或购物车获取国家代码
+     */
+    protected function getCurrentCountryCode(): ?string
+    {
+        $info = $this->getOrder() ?: Cart::getCart();
+        return $info->billing_address->country ?? null;
+    }
+
     protected $code  = 'afterpay';
 
     public function getRedirectUrl()
@@ -75,6 +100,10 @@ class Afterpay extends Payment
 
     public function createPayment($order, $override, $input = null)
     {
+        // 根据订单 billing 国家解析对应凭证
+        $countryCode = $order->billing_address->country ?? null;
+        $this->resolveCredentials($countryCode);
+
         $shop = $order->shipping_address;
         $bill = $order->billing_address;
         $telephone = $shop->phone ?: $bill->phone;
@@ -187,6 +216,10 @@ class Afterpay extends Payment
         if ($order->status != Order::STATUS_PENDING) {
             return new \Exception('order status is error');
         }
+        // 根据订单 billing 国家解析对应凭证
+        $countryCode = $order->billing_address->country ?? null;
+        $this->resolveCredentials($countryCode);
+
         $additional = $order->payment->additional;
         $token = $additional['gateway_order_id'];
         if ($transactionId != $token) {
@@ -221,9 +254,15 @@ class Afterpay extends Payment
 
 
 
-    public function fetchConfiguration(string $code = 'afterpay'): ?array
+    public function fetchConfiguration(string $code = 'afterpay', ?string $countryCode = null): ?array
     {
         try {
+            // 如果未指定国家,尝试从当前订单/购物车获取
+            if ($countryCode === null) {
+                $countryCode = $this->getCurrentCountryCode();
+            }
+            $this->resolveCredentials($countryCode);
+
             $client = new Client();
             $response = $client->request('GET', $this->configurationUlr, [
                 'headers' => [

+ 7 - 9
packages/Longyi/Pay/Afterpay/src/Payment/Clearpay.php

@@ -133,15 +133,13 @@ class Clearpay extends Afterpay
             return false;
         }
         $info = $this->getOrder() ?: Cart::getCart();
-        if ($info && $billingCountry = $info->billing_address->country ?? false) {
-//            $allowedCountries = $this->getConfigData('allowed_countries');
-//            if (empty($allowedCountries)) {
-//                return true;
-//            }
-//            $allowedCountries = explode(',', $allowedCountries);
-//            return in_array($billingCountry, $allowedCountries);
-            $allowedCountries = ['GB'];//英国
-            return in_array($billingCountry, $allowedCountries);
+        if ($info) {
+            $billingCountry = $info->billing_address->country ?? false;
+            $currency = $info->order_currency_code ?? $info->cart_currency_code ?? false;
+            // 仅当国家为 GB 且货币为 GBP 时才显示 Clearpay
+            if ($billingCountry === 'GB' && $currency === 'GBP') {
+                return true;
+            }
         }
         return false;
     }

+ 105 - 0
packages/Webkul/Shop/src/Http/Controllers/API/OrderController.php

@@ -277,6 +277,111 @@ class OrderController extends APIController
         ];
     }
 
+    /**
+     * 物流轨迹查询
+     *
+     * GET /api/customer/orders/tracking?track_number=xxx
+     *
+     * @param  Request  $request
+     * @return JsonResponse
+     */
+    public function tracking(Request $request): JsonResponse
+    {
+        $trackNumber = $request->input('track_number');
+
+        if (empty($trackNumber)) {
+            return ApiResponse::validationError('track_number is required');
+        }
+        if (mb_strlen($trackNumber) > 100) {
+            return ApiResponse::validationError('track_number must not exceed 100 characters');
+        }
+        $type = $request->input('type');
+        try {
+            $info = $this->gettrack_erp($trackNumber,$type);
+            $data=array();
+            if($info['success']){
+                $data['trackinfo']=$info['track']['data'];
+                return ApiResponse::success($data);
+            }else{
+                return ApiResponse::error($info['msg']);
+            }
+        } catch (\Exception $e) {
+            return ApiResponse::error('Tracking query failed: ' . $e->getMessage());
+        }
+    }
+
+    /**
+     * 调用 ERP 物流查询 API
+     */
+    public function gettrack_erp($track_number,$type)
+    {
+        $data = [
+            'shop'     => 2,
+            'order_no' => $track_number,
+            'time'     => time(),
+            'key'      => $this->getTrackKey(time()),
+        ];
+        if($type){
+            $data['type']=$type;
+        }
+        $datas     = json_encode($data);
+        $requestUrl = 'https://1.wepolicy.cn/apiexpress/logistics';
+        $result    = $this->_getApiData($requestUrl, 'POST', $datas, 1);
+        if(preg_match('/^\xEF\xBB\xBF/',$result))
+        {
+            $result = substr($result,3);
+        }
+        $res = json_decode(trim($result),true);
+        return $res;
+    }
+
+    /**
+     * 生成物流查询加密 Key
+     */
+    public function getTrackKey($time)
+    {
+        $key = "6amg!pnfrlbpnjgirv";
+        $iv = "6ook4k!2w94m6jtm";
+        $serect = "asteriahair";
+        $decrypt = $serect . "+" . $time;
+
+        return openssl_encrypt($decrypt, 'AES-128-CBC', $key, 0, $iv);
+    }
+
+    /**
+     * 通用 HTTP 请求
+     */
+    private function _getApiData($url, $method = 'GET', $data = null, $timeout = 30)
+    {
+        $ch = curl_init();
+
+        curl_setopt($ch, CURLOPT_URL, $url);
+        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
+        curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);
+        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
+        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
+
+        if (strtoupper($method) === 'POST') {
+            curl_setopt($ch, CURLOPT_POST, true);
+            curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
+            curl_setopt($ch, CURLOPT_HTTPHEADER, [
+                'Content-Type: application/json',
+                'Content-Length: ' . strlen($data),
+            ]);
+        }
+
+        $response = curl_exec($ch);
+        $error    = curl_error($ch);
+
+        curl_close($ch);
+
+        if ($error) {
+            throw new \Exception('CURL Error: ' . $error);
+        }
+
+        return $response;
+    }
+
     /**
      * 获取状态中文标签
      */

+ 1 - 0
packages/Webkul/Shop/src/Routes/api-token.php

@@ -41,6 +41,7 @@ Route::group(['prefix' => 'api'], function () {
         ->prefix('customer/orders')
         ->group(function () {
             Route::get('', 'index')->name('shop.api.token.customer.orders.index');
+            Route::get('tracking', 'tracking')->name('shop.api.token.customer.orders.tracking');
             Route::get('{id}', 'show')->name('shop.api.token.customer.orders.show');
         });