DHL Modul v0.5 Shipping Label ok
This commit is contained in:
parent
480fdc65ed
commit
8fdaa0ba1d
122 changed files with 17938 additions and 2239 deletions
198
packages/acme-laravel-dhl/src/Support/DhlClient.php
Normal file
198
packages/acme-laravel-dhl/src/Support/DhlClient.php
Normal file
|
|
@ -0,0 +1,198 @@
|
|||
<?php
|
||||
|
||||
namespace Acme\Dhl\Support;
|
||||
|
||||
use Illuminate\Support\Facades\Http;
|
||||
use Illuminate\Http\Client\RequestException;
|
||||
use Illuminate\Http\Client\ConnectionException;
|
||||
use Acme\Dhl\Exceptions\DhlApiException;
|
||||
use Acme\Dhl\Exceptions\DhlAuthenticationException;
|
||||
use Acme\Dhl\Exceptions\DhlValidationException;
|
||||
use Exception;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
/**
|
||||
* DHL API Client for handling HTTP requests to DHL services
|
||||
*/
|
||||
class DhlClient
|
||||
{
|
||||
public function __construct(
|
||||
protected string $baseUrl,
|
||||
protected ?string $apiKey,
|
||||
protected ?string $username,
|
||||
protected ?string $password
|
||||
) {}
|
||||
|
||||
/**
|
||||
* Make HTTP request to DHL API
|
||||
*
|
||||
* @param string $method HTTP method (get, post, put, delete)
|
||||
* @param string $uri API endpoint URI
|
||||
* @param array $payload Request body data
|
||||
* @param array $query Query parameters
|
||||
* @return array Response data as array
|
||||
* @throws Exception When API request fails or returns error
|
||||
*/
|
||||
public function request(string $method, string $uri, array $payload = [], array $query = []): array
|
||||
{
|
||||
try {
|
||||
$request = Http::baseUrl($this->baseUrl)
|
||||
->withHeaders($this->buildHeaders())
|
||||
->timeout(30)
|
||||
->retry(3, 300, function ($exception, $attempt) {
|
||||
if ($exception instanceof RequestException && $exception->response->status() === 429) {
|
||||
$delay = min(1000000 * $attempt, 10000000); // Max 10 seconds
|
||||
usleep($delay); // Microseconds
|
||||
return true;
|
||||
}
|
||||
return $exception instanceof ConnectionException ||
|
||||
($exception instanceof RequestException && in_array($exception->response->status(), [500, 502, 503, 504]));
|
||||
}, false);
|
||||
|
||||
// Add authentication if provided
|
||||
if ($this->username && $this->password) {
|
||||
$request = $request->withBasicAuth($this->username, $this->password);
|
||||
}
|
||||
|
||||
// Make the request
|
||||
$response = match (strtolower($method)) {
|
||||
'get' => $request->get($uri, $query),
|
||||
'post' => $request->post($uri . '?' . http_build_query($query), $payload),
|
||||
'put' => $request->put($uri, $payload),
|
||||
'delete' => $request->delete($uri),
|
||||
default => throw new Exception("Unsupported HTTP method: {$method}")
|
||||
};
|
||||
|
||||
// Handle response
|
||||
if ($response->failed()) {
|
||||
// Log additional debug info for 400 errors
|
||||
if ($response->status() === 400) {
|
||||
Log::error('[DHL API] HTTP 400 Bad Request Details', [
|
||||
'method' => $method,
|
||||
'uri' => $uri,
|
||||
'request_payload' => $payload,
|
||||
'response_body' => $response->body(),
|
||||
'response_json' => $response->json(),
|
||||
'status_code' => $response->status(),
|
||||
'headers' => $response->headers()
|
||||
]);
|
||||
}
|
||||
|
||||
$this->handleErrorResponse($response, $method, $uri);
|
||||
}
|
||||
|
||||
return $response->json() ?? [];
|
||||
} catch (RequestException $e) {
|
||||
Log::error('DHL API request failed', ['error' => $e->getMessage(), 'method' => $method, 'uri' => $uri]);
|
||||
throw new DhlApiException("DHL API request failed: {$e->getMessage()}", $e->getCode(), $e);
|
||||
} catch (Exception $e) {
|
||||
Log::error('DHL API error', ['error' => $e->getMessage()]);
|
||||
// Re-throw our own exceptions
|
||||
if ($e instanceof DhlApiException) {
|
||||
throw $e;
|
||||
}
|
||||
throw new DhlApiException("DHL API error: {$e->getMessage()}", $e->getCode(), $e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Build HTTP headers for DHL API requests
|
||||
*/
|
||||
private function buildHeaders(): array
|
||||
{
|
||||
$headers = [
|
||||
'Accept' => 'application/json',
|
||||
'Content-Type' => 'application/json',
|
||||
'User-Agent' => 'acme-laravel-dhl/1.0'
|
||||
];
|
||||
|
||||
if ($this->apiKey) {
|
||||
$headers['dhl-api-key'] = $this->apiKey;
|
||||
}
|
||||
|
||||
return $headers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle error responses from DHL API
|
||||
*/
|
||||
private function handleErrorResponse($response, string $method, string $uri): void
|
||||
{
|
||||
$status = $response->status();
|
||||
$body = $response->json();
|
||||
|
||||
$errorMessage = $this->extractErrorMessage($body) ?? "HTTP {$status} error";
|
||||
|
||||
match (true) {
|
||||
$status === 401 => throw new DhlAuthenticationException("DHL API authentication failed: {$errorMessage}"),
|
||||
$status === 403 => throw new DhlAuthenticationException("DHL API access forbidden: {$errorMessage}"),
|
||||
$status === 404 => throw new DhlApiException("DHL API endpoint not found: {$method} {$uri}"),
|
||||
$status === 422 => throw new DhlValidationException("DHL API validation error: {$errorMessage}"),
|
||||
$status === 429 => throw new DhlApiException("DHL API rate limit exceeded. Please try again later."),
|
||||
$status >= 500 => throw new DhlApiException("DHL API server error: {$errorMessage}"),
|
||||
default => throw new DhlApiException("DHL API error ({$status}): {$errorMessage}")
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract error message from DHL API response
|
||||
*/
|
||||
private function extractErrorMessage(?array $body): ?string
|
||||
{
|
||||
if (!$body) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Try different possible error message fields
|
||||
return $body['message']
|
||||
?? $body['error']
|
||||
?? $body['detail']
|
||||
?? data_get($body, 'errors.0.message')
|
||||
?? data_get($body, 'error.message')
|
||||
?? null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test connection to DHL API
|
||||
*
|
||||
* @return bool True if connection successful
|
||||
*/
|
||||
public function testConnection(): bool
|
||||
{
|
||||
try {
|
||||
// Check basic connectivity and authentication
|
||||
// Use the simplest possible endpoint to minimize permission issues
|
||||
$response = Http::baseUrl($this->baseUrl)
|
||||
->withHeaders($this->buildHeaders())
|
||||
->withBasicAuth($this->username, $this->password)
|
||||
->timeout(10)
|
||||
->get('/');
|
||||
|
||||
// If we get any response (even 404), the connection and auth are working
|
||||
if ($response->status() === 401) {
|
||||
Log::error('DHL API authentication failed: Invalid username/password');
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($response->status() === 403 && str_contains($response->body(), 'api-key')) {
|
||||
Log::error('DHL API authentication failed: Invalid API key');
|
||||
return false;
|
||||
}
|
||||
|
||||
// Any other response code (including 404, 403 for endpoint access) means connection works
|
||||
Log::info('DHL API connection test successful', [
|
||||
'status' => $response->status(),
|
||||
'has_api_key' => !empty($this->apiKey),
|
||||
'has_credentials' => !empty($this->username) && !empty($this->password)
|
||||
]);
|
||||
|
||||
return true;
|
||||
} catch (Exception $e) {
|
||||
Log::error('DHL API connection test failed', [
|
||||
'error' => $e->getMessage(),
|
||||
'base_url' => $this->baseUrl
|
||||
]);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue