token = $token; } // ------------------------------------------------------------------------- // Listings // ------------------------------------------------------------------------- public function getListings($page = 1, $per_page = 50) { return $this->request('GET', '/my/listings', [ 'page' => $page, 'per_page' => $per_page, ]); } public function createListing(array $data) { return $this->request('POST', '/listings', [], $data); } public function updateListing($listing_id, array $data) { return $this->request('PUT', '/listings/' . urlencode($listing_id), [], $data); } public function endListing($listing_id) { return $this->request('PUT', '/listings/' . urlencode($listing_id) . '/end'); } public function uploadPhoto($listing_id, $image_url) { return $this->request('POST', '/my/listings/' . urlencode($listing_id) . '/photos', [], [ 'image_url' => $image_url, ]); } // ------------------------------------------------------------------------- // Orders // ------------------------------------------------------------------------- public function getOrders($page = 1, $per_page = 50) { return $this->request('GET', '/my/orders', [ 'page' => $page, 'per_page' => $per_page, ]); } public function getOrder($order_number) { return $this->request('GET', '/my/orders/' . urlencode($order_number)); } // ------------------------------------------------------------------------- // Metadata // ------------------------------------------------------------------------- public function getCategories() { return $this->request('GET', '/categories/flat'); } public function getListingConditions() { return $this->request('GET', '/listing_conditions'); } // ------------------------------------------------------------------------- // Webhooks // ------------------------------------------------------------------------- public function registerWebhook($url, $event) { return $this->request('POST', '/webhooks', [], [ 'url' => $url, 'event' => $event, ]); } public function getWebhooks() { return $this->request('GET', '/webhooks'); } public function deleteWebhook($webhook_id) { return $this->request('DELETE', '/webhooks/' . (int)$webhook_id); } // ------------------------------------------------------------------------- // HTTP transport // ------------------------------------------------------------------------- private function request($method, $endpoint, array $params = [], $body = null) { $url = self::BASE_URL . $endpoint; if (!empty($params)) { $url .= '?' . http_build_query($params); } $headers = [ 'Authorization: Bearer ' . $this->token, 'Accept-Version: ' . self::API_VERSION, 'Content-Type: application/hal+json', 'Accept: application/json', ]; $ch = curl_init(); curl_setopt_array($ch, [ CURLOPT_URL => $url, CURLOPT_RETURNTRANSFER => true, CURLOPT_HTTPHEADER => $headers, CURLOPT_TIMEOUT => 30, CURLOPT_SSL_VERIFYPEER => true, CURLOPT_USERAGENT => 'OpenCart-Reverb/1.0', ]); if (in_array($method, ['POST', 'PUT', 'DELETE'])) { if ($method === 'POST') { curl_setopt($ch, CURLOPT_POST, true); } else { curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method); } if ($body !== null) { curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($body)); } } $response = curl_exec($ch); $http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE); $curl_error = curl_error($ch); curl_close($ch); if ($curl_error) { throw new RuntimeException('cURL error: ' . $curl_error); } $decoded = json_decode($response, true); if ($http_code >= 400) { $message = 'HTTP ' . $http_code; if (!empty($decoded['message'])) { $message = $decoded['message']; } elseif (!empty($decoded['errors'])) { $message = implode(', ', (array)$decoded['errors']); } throw new RuntimeException('Reverb API error: ' . $message, $http_code); } return $decoded; } }