Files
usps_api_bridge/classes/UspsV3Client.php
2025-12-07 23:10:14 +02:00

94 lines
3.1 KiB
PHP

<?php
use Symfony\Component\HttpClient\HttpClient;
use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface;
use Symfony\Contracts\HttpClient\Exception\ClientExceptionInterface;
use Symfony\Contracts\HttpClient\Exception\ServerExceptionInterface;
class UspsV3Client
{
private $token;
private $isLive;
private $baseUrl;
public function __construct($token, $isLive = false)
{
$this->token = $token;
$this->isLive = $isLive;
// Base URLs per OpenAPI Spec
$this->baseUrl = $this->isLive
? 'https://apis.usps.com/prices/v3'
: 'https://apis-tem.usps.com/prices/v3';
}
/**
* Get Domestic Rate (Rates v3)
*/
public function getDomesticRate($payload)
{
return $this->post('/base-rates/search', $payload);
}
/**
* Get International Rate (Rates v3)
*/
public function getInternationalRate($payload)
{
// International endpoint uses a different base structure per spec
$intlBaseUrl = $this->isLive
? 'https://apis.usps.com/international-prices/v3'
: 'https://apis-tem.usps.com/international-prices/v3';
return $this->post('/base-rates/search', $payload, $intlBaseUrl);
}
/**
* Internal POST logic using Symfony HTTP Client
*/
private function post($endpoint, $payload, $overrideUrl = null)
{
$url = ($overrideUrl ? $overrideUrl : $this->baseUrl) . $endpoint;
$client = HttpClient::create([
'timeout' => 15,
'verify_peer' => false,
'verify_host' => false,
]);
try {
$response = $client->request('POST', $url, [
'headers' => [
'Authorization' => 'Bearer ' . $this->token,
'Content-Type' => 'application/json',
'Accept' => 'application/json'
],
'json' => $payload
]);
// toArray(false) prevents exception on 4xx/5xx responses so we can parse the error body
$data = $response->toArray(false);
$statusCode = $response->getStatusCode();
// Handle API Errors (400 Bad Request, 401 Unauthorized, etc)
if ($statusCode >= 400) {
$msg = isset($data['error']['message']) ? $data['error']['message'] : 'Unknown Error';
// Try to extract deeper error detail (e.g., from 'errors' array)
if (isset($data['error']['errors'][0]['detail'])) {
$msg .= ' - ' . $data['error']['errors'][0]['detail'];
} elseif (isset($data['error']['code'])) {
$msg .= ' (' . $data['error']['code'] . ')';
}
return ['error' => "API HTTP $statusCode: $msg"];
}
return $data;
} catch (TransportExceptionInterface $e) {
return ['error' => 'Network/Transport Error: ' . $e->getMessage()];
} catch (\Exception $e) {
return ['error' => 'Client Error: ' . $e->getMessage()];
}
}
}