/** * Fetch IKEA product name and canonical ID via Search API */ function getIkeaProductInfo($country, $productId) { $country = strtolower($country); $lang = ($country == 'ca') ? 'en' : 'en'; // Simple map for now $url = "https://sik.search.blue.cdtapps.com/{$country}/{$lang}/search-result-page?q={$productId}"; $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_TIMEOUT, 10); curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36"); curl_setopt($ch, CURLOPT_HTTPHEADER, [ "Accept: application/json", "Referer: https://www.ikea.com/{$country}/{$lang}/" ]); $response = curl_exec($ch); $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); if ($httpCode != 200 || !$response) { return ['name' => "Article $productId", 'canonical_id' => $productId]; } $data = json_decode($response, true); $items = $data['searchResultPage']['products']['main']['items'] ?? []; foreach ($items as $item) { $p = $item['product'] ?? []; $itemNo = $p['itemNo'] ?? ''; $name = $p['name'] ?? ''; $type = $p['typeName'] ?? ''; if ($itemNo == $productId || stripos($name, $productId) !== false) { return [ 'name' => trim("$name $type"), 'canonical_id' => $itemNo ]; } } return ['name' => "Article $productId", 'canonical_id' => $productId]; } /** * Fetch IKEA stock availability */ function getIkeaAvailability($country, $productId, $canonicalId, $storeId = null) { if (!$canonicalId) return ['stock' => 0, 'status' => "Invalid ID", 'restock' => null]; $baseUrl = "https://api.ingka.ikea.com/cia/availabilities"; $clientId = "da465052-7912-43b2-82fa-9dc39cdccef8"; if ($storeId) { $url = "{$baseUrl}/sto/{$storeId}?itemNos={$canonicalId}&expand=Restocks"; } else { $url = "{$baseUrl}/ru/" . strtolower($country) . "?itemNos={$canonicalId}&expand=Restocks"; } $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_HTTPHEADER, [ "X-Client-ID: $clientId", "Accept: application/json;version=1", "Referer: https://www.ikea.com/", "Origin: https://www.ikea.com" ]); curl_setopt($ch, CURLOPT_TIMEOUT, 15); curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36"); $response = curl_exec($ch); $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); if ($httpCode == 403) { return [ 'stock' => 0, 'status' => "Blocked (403)", 'restock' => null ]; } if ($httpCode != 200 || !$response) { return [ 'stock' => 0, 'status' => "API Error ($httpCode)", 'restock' => null ]; } $data = json_decode($response, true); $availabilities = $data['availabilities'] ?? []; if (empty($availabilities)) { return [ 'stock' => 0, 'status' => "Not Found", 'restock' => null ]; } // Usually there's only one item in the list for a specific sto/ru call with one itemNo $item = $availabilities[0]; $avail = $item['buyingOption']['cashCarry']['availability'] ?? null; if (!$avail && $item['classUnitKey']['classUnitType'] == 'RU') { $avail = $item['buyingOption']['homeDelivery']['availability'] ?? null; } if (!$avail) { return [ 'stock' => 0, 'status' => "No Data", 'restock' => null ]; } $stock = $avail['quantity'] ?? 0; $prob = $avail['probability']['thisDay']['messageType'] ?? 'UNKNOWN'; $restock = null; $restocks = $avail['restocks'] ?? []; if (!empty($restocks)) { $restock = $restocks[0]['earliestDate'] ?? $restocks[0]['date'] ?? null; } return [ 'stock' => $stock, 'status' => strtoupper($prob), 'restock' => $restock ]; } /** * List of stores for selection */ function getIkeaStores($country) { // Subset of stores for CA as requested $stores = [ 'ca' => [ ['buCode' => '216', 'name' => 'Calgary'], ['buCode' => '004', 'name' => 'Ottawa'], ['buCode' => '149', 'name' => 'Toronto North York'], ['buCode' => '039', 'name' => 'Montréal'], ['buCode' => '003', 'name' => 'Vancouver Richmond'], ['buCode' => '659', 'name' => 'Toronto Downtown'], ['buCode' => '313', 'name' => 'Coquitlam'], ['buCode' => '349', 'name' => 'Edmonton'], ['buCode' => '256', 'name' => 'Etobicoke'], ['buCode' => '529', 'name' => 'Halifax'], ['buCode' => '559', 'name' => 'Québec City'], ['buCode' => '372', 'name' => 'Vaughan'], ['buCode' => '249', 'name' => 'Winnipeg'], ['buCode' => '414', 'name' => 'Boucherville'], ['buCode' => '040', 'name' => 'Burlington'], ] ]; return $stores[strtolower($country)] ?? []; } ?> Repair Prices Outerregion

Repair Prices

This page has been removed.