| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130 |
- <?php
- declare(strict_types=1);
- namespace SixShop\Wangdian\Http;
- use GuzzleHttp\Client;
- use GuzzleHttp\Exception\GuzzleException;
- use GuzzleHttp\Exception\RequestException;
- use Psr\Http\Client\ClientInterface;
- use Psr\Log\LoggerInterface;
- use Psr\Log\NullLogger;
- use SixShop\Wangdian\Config\Config;
- use SixShop\Wangdian\Exception\HttpException;
- /**
- * HTTP client wrapper for making API requests
- */
- class HttpClient
- {
- private readonly ClientInterface $client;
- private readonly LoggerInterface $logger;
- public function __construct(
- private readonly Config $config,
- ?ClientInterface $client = null,
- ?LoggerInterface $logger = null
- ) {
- $this->client = $client ?? new Client([
- 'timeout' => $this->config->timeout,
- 'verify' => !$this->config->isSandbox(), // Disable SSL verification for sandbox
- 'headers' => [
- 'User-Agent' => 'SixShop-Wangdian-SDK/1.0',
- 'Accept' => 'application/json',
- ],
- ]);
- $this->logger = $logger ?? new NullLogger();
- }
- /**
- * Make a POST request to the API
- */
- public function post(string $endpoint, array $data = []): array
- {
- $url = $this->config->getEndpoint($endpoint);
- try {
- $this->logger->info('Making API request', [
- 'url' => $url,
- 'data_keys' => array_keys($data),
- ]);
- $response = $this->client->request('POST', $url, [
- 'form_params' => $data,
- 'headers' => [
- 'Content-Type' => 'application/x-www-form-urlencoded',
- ],
- ]);
- $statusCode = $response->getStatusCode();
- $body = $response->getBody()->getContents();
- $this->logger->info('API response received', [
- 'status_code' => $statusCode,
- 'response_length' => strlen($body),
- ]);
- if ($statusCode !== 200) {
- throw new HttpException(
- message: "HTTP request failed with status code: {$statusCode}",
- httpStatusCode: $statusCode,
- context: ['response_body' => $body]
- );
- }
- return $this->parseResponse($body);
- } catch (RequestException $e) {
- $this->logger->error('HTTP request failed', [
- 'url' => $url,
- 'error' => $e->getMessage(),
- ]);
- throw new HttpException(
- message: 'HTTP request failed: ' . $e->getMessage(),
- previous: $e,
- httpStatusCode: $e->getResponse()?->getStatusCode(),
- context: ['url' => $url, 'data' => $data]
- );
- } catch (GuzzleException $e) {
- $this->logger->error('Guzzle exception', [
- 'url' => $url,
- 'error' => $e->getMessage(),
- ]);
- throw new HttpException(
- message: 'HTTP client error: ' . $e->getMessage(),
- previous: $e,
- context: ['url' => $url, 'data' => $data]
- );
- }
- }
- /**
- * Parse JSON response
- */
- private function parseResponse(string $body): array
- {
- if (empty($body)) {
- throw new HttpException('Empty response body received');
- }
- $decoded = json_decode($body, true);
- if (json_last_error() !== JSON_ERROR_NONE) {
- $this->logger->error('Failed to parse JSON response', [
- 'json_error' => json_last_error_msg(),
- 'response_body' => $this->config->debug ? $body : '[hidden]',
- ]);
- throw new HttpException(
- message: 'Failed to parse JSON response: ' . json_last_error_msg(),
- context: ['response_body' => $body]
- );
- }
- return $decoded;
- }
- }
|