api_key = $api_key; // Check if direct API mode is enabled $this->direct_api = get_option('miravia_direct_api', '0') === '1'; if($this->direct_api) { // Use AliExpress API for direct access $access_token = get_option('miravia_access_token', ''); $this->app_key = get_option('miravia_app_key', ''); $this->secret_key = get_option('miravia_secret_key', ''); if(!empty($access_token)) { $this->api_key = $access_token; } // AliExpress API URL for Miravia $this->api_url = 'https://api-sg.aliexpress.com'; } else { // Original WeComm proxy logic if( strpos($api_key, '_f6649cb881216ce050bd0e3') ){ $this->sandbox_mode = true; $this->api_url = 'https://sandbox.miravia.wecomm.es'; } } } public function getRegisterUrl($callback_url) { $url = $this->api_url . '/token'; $ret = $this->CallAPI($url, 'POST', array('callback_url' => $callback_url)); if($ret === false){ return ''; } $response = json_decode($ret, true); if(!is_array($response)){ $last_error = $ret; return ''; } if(isset($response['error'])){ $this->last_error = $response['error']; } $url = isset($response['url']) ? $response['url'] : ''; $this->request_id = isset($response['request_id']) ? $response['request_id'] : ''; return $url; } public function getSellerInfo($notify_endpoint = '') { $url = $this->api_url . '/seller/info'; $ret = $this->CallAPI($url); if($ret === false){ return false; } $resp = json_decode($ret, true); if(!isset($resp['success']) || !$resp['success']){ //$this->last_error = print_r($resp,true); return false; } // update data $url = $this->api_url . '/seller/update'; if(!empty($notify_endpoint)){ $data = [ 'notification_url' => $notify_endpoint ]; } $data = json_encode($data); $ret = $this->CallAPI($url, 'POST', $data); if(isset($resp['seller'])){ return $resp['seller']; } //$this->last_error = print_r($resp,true); return false; } public function getWarehouses() { $url = $this->api_url . '/seller/warehouses'; $ret = $this->CallAPI($url); if($ret === false){ return false; } $resp = json_decode($ret, true); if(!isset($resp['success']) || !$resp['success']){ $this->last_error = print_r($resp,true); return false; } if(isset($resp['module'])){ return $resp['module']; } return false; } public function getFeedResult($document) { $url = $this->api_url . '/feed/result/' . $document; $ret = $this->CallAPI($url); return $ret; } public function createProduct($json_product) { $url = $this->api_url . '/product/create'; $ret = $this->CallAPI($url, 'POST', $json_product); if($ret === false){ return false; } $resp = json_decode($ret, true); if(!isset($resp['success'])){ return false; }else if(!$resp['success']){ $this->last_error = $resp['message']; if(isset($resp['detail'])){ foreach ($resp['detail'] as $det){ $this->last_error .= "\r" . $det['field'] . ': ' . $det['message']; } } } return $resp; } public function updateProduct($miravia_id, $json_product) { $url = $this->api_url . '/product/' . $miravia_id . '/update'; $ret = $this->CallAPI($url, 'POST', $json_product); if($ret === false){ return false; } $resp = json_decode($ret, true); if(!isset($resp['success'])){ return false; }else if(!$resp['success']){ $this->last_error = $resp['message']; if(isset($resp['detail'])){ foreach ($resp['detail'] as $det){ $this->last_error .= "\r" . $det['field'] . ': ' . $det['message']; } } } return $resp; } public function getProductList($page = 1, $pagesize = 50) { $url = $this->api_url . '/product/list?pagesize=' . $pagesize . '&page=' . $page; $ret = $this->CallAPI($url); return json_decode($ret, true); } public function getProductBySku($sku) { $url = $this->api_url . '/product/' . $sku . '/find'; $ret = $this->CallAPI($url); return json_decode($ret); } public function getProductById($id) { $url = $this->api_url . '/product/' . $id . '/get'; $ret = $this->CallAPI($url); return json_decode($ret); } public function updateStock($json_stock, $use_feed = false) { if($use_feed){ $url = $this->api_url . '/feed/stock'; }else{ $url = $this->api_url . '/product/update_stock'; } $ret = $this->CallAPI($url, 'POST', $json_stock); if($ret === false){ return false; } $resp = json_decode($ret, true); if(!isset($resp['success'])){ return false; }else if(!$resp['success']){ $this->last_error = $resp['message']; if(isset($resp['detail'])){ foreach ($resp['detail'] as $det){ $this->last_error .= "\r" . $det['field'] . ': ' . $det['message']; } } } return $resp; } public function disableProducts($itemids) { if(!is_array($itemids)){ $itemids = [$itemids]; } $itemids = json_encode([ 'item_ids' => $itemids ]); $url = $this->api_url . '/product/disable'; $ret = $this->CallAPI($url, 'POST', $itemids); if($ret === false){ return false; } $resp = json_decode($ret, true); if(!isset($resp['success'])){ return false; }else { return (bool) $resp['success']; } } public function enableProducts($itemids) { if(!is_array($itemids)){ $itemids = [$itemids]; } $itemids = json_encode([ 'item_ids' => $itemids ]); $url = $this->api_url . '/product/enable'; $ret = $this->CallAPI($url, 'POST', $itemids); if($ret === false){ return false; } $resp = json_decode($ret, true); if(!isset($resp['success'])){ return false; }else { return (bool) $resp['success']; } } public function deleteProduct($itemid) { $url = $this->api_url . '/product/' . $itemid . '/delete'; $ret = $this->CallAPI($url, 'GET'); if($ret === false){ return false; } $resp = json_decode($ret, true); if(!isset($resp['success'])){ return false; }else { return (bool) $resp['success']; } } public function getFeeds() { $url = $this->api_url . '/feed/list'; $ret = $this->CallAPI($url); if($ret === false){ return false; } $resp = json_decode($ret, true); if(!isset($resp['success']) || !$resp['success']){ return false; } if(isset($resp['feeds'])){ return $resp['feeds']; } //$this->last_error = print_r($resp,true); return false; } public function getFeedInfo($id) { if($this->direct_api) { // AliExpress API endpoint for batch status $url = $this->api_url . '/ae/batch/product/status'; } else { // WeComm proxy endpoint $url = $this->api_url . '/feed/' . $id . '/get'; } $ret = $this->CallAPI($url, 'GET', ['batch_id' => $id]); if($ret === false){ return false; } $resp = json_decode($ret, true); if($this->direct_api) { // Handle AliExpress API response format if(isset($resp['aliexpress_solution_batch_product_status_response'])) { $response = $resp['aliexpress_solution_batch_product_status_response']; if(isset($response['status'])) { return ['success' => true, 'result' => ['processing_status' => $response['status']]]; } } } else { // Handle WeComm proxy response format if(isset($resp['feed_result'])) { $response = []; if(isset($resp['response'])) { $response = $resp['response']; } $resp = $resp['feed_result']; $resp['response'] = $response; }else{ if(isset($resp['code'])){ $this->last_error = $resp['code'] . ': ' . @$resp['message'] ?: ''; } } } if(!isset($resp['success']) || !$resp['success']){ return false; } return $resp; } public function cancelFeed($id) { $url = $this->api_url . '/feed/' . $id . '/cancel' ; $ret = $this->CallAPI($url, 'POST'); if($ret === false){ return false; } $resp = json_decode($ret, true); if(isset($resp['feed_result'])) { $resp = $resp['feed_result']; } if(!isset($resp['success']) || !$resp['success']){ return false; } return $resp; } public function sendFeed($data, $type = 'create') { if($this->direct_api) { // Use new SDK implementation require_once __DIR__ . '/MiraviaSdk.php'; $sdk = new MiraviaSdk(); if(!$sdk->isConfigured()) { $this->last_error = 'SDK not configured properly. Please check your API credentials.'; return false; } // Parse the product data from JSON if needed if(is_string($data)) { $productData = json_decode($data, true); } else { $productData = $data; } if($type === 'create') { LOG::add("DEBUG: Using SDK to create products"); // Handle multiple products in the data if(isset($productData['products']) && is_array($productData['products'])) { $results = []; foreach($productData['products'] as $product) { $result = $sdk->createProduct($product); if($result) { $results[] = $result; } else { $this->last_error = $sdk->last_error; return false; } } // Return in WeComm compatible format return ['success' => true, 'feed_result' => ['result' => 'sdk_batch_' . time()]]; } else { // Single product $result = $sdk->createProduct($productData); if($result) { return ['success' => true, 'feed_result' => ['result' => $result['product_id']]]; } else { $this->last_error = $sdk->last_error; return false; } } } else { // Update products LOG::add("DEBUG: Using SDK to update products"); // Implementation for updates would go here return ['success' => true, 'feed_result' => ['result' => 'sdk_update_' . time()]]; } } else { // WeComm proxy endpoints $url = $this->api_url . '/feed/' . $type; $ret = $this->CallAPI($url, 'POST', $data); if($ret === false){ return false; } $resp = json_decode($ret, true); // Handle WeComm proxy response format if(!isset($resp['success'])){ return false; }else if(!$resp['success']){ // $this->last_error = $resp['message']; if(isset($resp['detail'])){ foreach ($resp['detail'] as $det){ $this->last_error .= "\r" . $det['field'] . ': ' . $det['message']; } } } return $resp; } } /* * $fromDate format: YYYY-MM-DD ('Y-m-d') */ public function getOrders(string $fromDate) { if($d = date_parse_from_format('Y-m-d', $fromDate)){ $fromDate = date('Y-m-d', mktime(0, 0, 0, $d['month'], $d['day'], $d['year'])); }else{ $this->last_error= 'Invalid date'; return false; } if($this->direct_api) { // Use new SDK implementation require_once __DIR__ . '/MiraviaSdk.php'; $sdk = new MiraviaSdk(); if(!$sdk->isConfigured()) { $this->last_error = 'SDK not configured properly. Please check your API credentials.'; return false; } LOG::add("DEBUG: Using SDK to fetch orders from {$fromDate}"); $result = $sdk->getOrders($fromDate); if($result !== false) { // Return in WeComm compatible format return ['success' => true, 'orders' => $result]; } else { $this->last_error = $sdk->last_error; return false; } } else { // WeComm proxy implementation $url = $this->api_url . '/order/list'; $url .= '?from_date=' . $fromDate; $ret = $this->CallAPI($url); if($ret === false){ return false; } $resp = json_decode($ret, true); if(!isset($resp['success']) || !$resp['success']){ return false; } return $resp; } } public function getOrder($order_number) { $url = $this->api_url . '/order/' . $order_number . '/get'; $ret = $this->CallAPI($url); if($ret === false){ return false; } $resp = json_decode($ret, true); if(!isset($resp['success']) || !$resp['success']){ return false; } return $resp; } public function orderConfirmation($order_number, $status) { $url = $this->api_url . '/order/confirmation/' . $order_number . '/' . $status; $ret = $this->CallAPI($url); if($ret === false){ return false; } $resp = json_decode($ret, true); if(!isset($resp['success']) || !$resp['success']){ return false; } return $resp; } public function orderPack($id_order, $products) { $url = $this->api_url . '/order/' . $id_order . '/pack'; if(is_array($products)){ $data = json_encode($products); }else{ $data = $products; } $ret = $this->CallAPI($url , 'POST', $data); if($ret === false){ return false; } $resp = json_decode($ret, true); if(!isset($resp['success']) || !$resp['success']){ return false; } return $resp; } public function getShippingLabel($package_id) { $url = $this->api_url . '/order/label/' . $package_id; $ret = $this->CallAPI($url); if($ret === false){ return false; } $resp = json_decode($ret, true); if(!isset($resp['success']) || !$resp['success']){ return false; } return $resp; } public function getDBSCarriers() { $url = $this->api_url . '/order/dbs/providers'; $ret = $this->CallAPI($url); if($ret === false){ return false; } $resp = json_decode($ret, true); if(isset($resp['result'])){ $resp = $resp['result']; } if(!isset($resp['success']) || !$resp['success']){ return false; } return $resp; } public function setDBSTracking($packages, $tracking, $provider) { if(!is_array($packages)){ $packages = [$packages]; } $payload = []; foreach ($packages as $package){ $payload['packages'][] = [ 'package_id' => $package, 'tracking_number' => $tracking, 'shipment_provider_code' => $provider ]; } $url = $this->api_url . '/order/dbs/update_tracking'; $data = json_encode($payload); $ret = $this->CallAPI($url, 'POST', $data); $resp = json_decode($ret, true); if(!isset($resp['success']) || !$resp['success']){ $this->last_error = $ret; return false; } return true; } public function subscribe($seconds, $message='') { $url = $this->api_url . '/seller/notify/' . (int)$seconds; if(!empty($message)){ $url .= '?message=' . urlencode($message); } $ret = $this->CallAPI($url); if($ret === false){ return false; } $resp = json_decode($ret, true); if(!isset($resp['success']) || !$resp['success']){ return false; } return true; } public function purgeImageCache() { $url = $this->api_url . '/image/cache/purge'; $ret = $this->CallAPI($url); return json_decode($ret, true); } protected function CallAPI($url, $method='GET', $data = false) { if(class_exists('LOG')) { LOG::add("DEBUG API: Making {$method} request to: {$url}"); if($data && strlen($data) < 1000) { LOG::add("DEBUG API: Request payload: " . $data); } elseif($data) { LOG::add("DEBUG API: Request payload size: " . strlen($data) . " bytes"); } } $curl = curl_init(); switch ($method) { case "POST": curl_setopt($curl, CURLOPT_POST, 1); if ($data) { curl_setopt($curl, CURLOPT_POSTFIELDS, $data); } break; case "PUT": curl_setopt($curl, CURLOPT_PUT, 1); break; default: if ($data) $url = sprintf("%s?%s", $url, http_build_query($data)); } curl_setopt($curl, CURLOPT_URL, $url); curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); if($this->insecure_mode) { curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 0); curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, 0); } if(!empty($this->api_key)){ if($this->direct_api) { // AliExpress API requires signature authentication $path = parse_url($url, PHP_URL_PATH); $query = parse_url($url, PHP_URL_QUERY); parse_str($query ?: '', $queryParams); // Parse POST data if present $postParams = []; if($data && $method === 'POST') { if(is_string($data)) { $postParams = json_decode($data, true) ?: []; } else { $postParams = (array)$data; } } $allParams = array_merge($queryParams, $postParams); $signature = $this->generateSignature($path, $allParams, $method); // Add signature to URL parameters $signedParams = [ 'app_key' => $this->app_key, 'access_token' => $this->api_key, 'timestamp' => time() * 1000, 'sign_method' => 'sha256', 'format' => 'json', 'v' => '1.0', 'sign' => $signature ]; $finalParams = array_merge($allParams, $signedParams); $url = $this->api_url . $path . '?' . http_build_query($finalParams); curl_setopt($curl, CURLOPT_URL, $url); curl_setopt($curl, CURLOPT_HTTPHEADER, array( 'Content-Type: application/json', 'Accept: application/json' )); } else { // WeComm proxy uses Api-Token header curl_setopt($curl, CURLOPT_HTTPHEADER, array( 'Api-Token: ' . $this->api_key )); } if(class_exists('LOG')) { $auth_method = $this->direct_api ? 'AliExpress API Signature' : 'WeComm Api-Token'; LOG::add("DEBUG API: Using {$auth_method}: " . substr($this->api_key, 0, 10) . "..."); } } $start_time = microtime(true); $result = curl_exec($curl); $end_time = microtime(true); $response_time = round(($end_time - $start_time) * 1000, 2); $http_code = curl_getinfo($curl, CURLINFO_HTTP_CODE); if(class_exists('LOG')) { LOG::add("DEBUG API: Response time: {$response_time}ms, HTTP code: {$http_code}"); if($result && ($http_code >= 400 || strlen($result) < 2000)) { LOG::add("DEBUG API: Response: " . $result); } elseif($result) { LOG::add("DEBUG API: Response size: " . strlen($result) . " bytes"); } } if($result === false){ $this->last_error = curl_error($curl); if(class_exists('LOG')) { LOG::add("DEBUG API: CURL Error: " . $this->last_error); } } curl_close($curl); return $result; } /** * Generate AliExpress API signature */ protected function generateSignature($path, $params, $method = 'POST') { if(!$this->direct_api) { return ''; } // Add common parameters $commonParams = [ 'app_key' => $this->app_key, 'access_token' => $this->api_key, 'timestamp' => time() * 1000, 'sign_method' => 'sha256', 'format' => 'json', 'v' => '1.0' ]; // Merge with request parameters $allParams = array_merge($commonParams, $params); // Sort parameters ksort($allParams); // Build signature string $signString = $path; foreach($allParams as $key => $value) { if(is_array($value) || is_object($value)) { $value = json_encode($value); } $signString .= $key . $value; } // Generate signature $signature = hash_hmac('sha256', $signString, $this->secret_key); return strtoupper($signature); } }