PHP에서 cURL 확장 또는 Guzzle HTTP 클라이언트를 활용해 택배 조회 API를 연동하는 방법을 단계별로 안내합니다. 기본 cURL부터 Laravel 프레임워크 연동까지 다양한 환경에 맞는 예제를 제공합니다.
• PHP cURL은 대부분의 서버에 기본 설치됨 — 별도 라이브러리 없이 즉시 연동 가능
• Guzzle을 사용하면 더 깔끔한 코드 작성 가능
• Laravel HTTP 파사드로 프레임워크 네이티브 연동 지원
1. API 키 설정
API 키와 Secret Key는 회원가입 후 대시보드에서 발급받을 수 있습니다. 환경 변수 또는 설정 파일에 저장하세요.
# .env
DELIVERY_API_KEY=pk_live_xxxxxxxxxxxxxxxx
DELIVERY_SECRET_KEY=sk_live_xxxxxxxxxxxxxxxx <?php
// config.php
$apiKey = getenv('DELIVERY_API_KEY');
$secretKey = getenv('DELIVERY_SECRET_KEY');
// or load from .env file manually
// $apiKey = trim(file_get_contents(__DIR__ . '/.env.api_key')); Secret Key는 서버에서만 사용하세요. 프론트엔드 코드나 GitHub 등 공개 저장소에 노출되지 않도록 주의하세요.
.env 파일은 반드시 .gitignore에 추가하세요.
2. cURL로 조회하기 (기본)
PHP에 기본 내장된 cURL 확장을 사용하는 가장 기본적인 방법입니다. 별도 라이브러리 설치 없이 바로 사용할 수 있습니다.
<?php
$apiKey = getenv('DELIVERY_API_KEY');
$secretKey = getenv('DELIVERY_SECRET_KEY');
$ch = curl_init('https://api.deliveryapi.co.kr/v1/tracking/trace');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Content-Type: application/json',
'Authorization: Bearer ' . $apiKey . ':' . $secretKey,
],
CURLOPT_POSTFIELDS => json_encode([
'items' => [
[
'courierCode' => 'cj',
'trackingNumber' => '1234567890',
],
],
]),
]);
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
$data = json_decode($response, true); 3. 응답 처리
API 응답은 JSON 형식입니다. json_decode()로 파싱한 후 각 결과의 success 필드를 확인하세요.
<?php
// Check overall HTTP status
if ($httpCode !== 200) {
echo "HTTP Error: " . $httpCode;
exit;
}
// Check individual result
$result = $data['data']['results'][0];
if ($result['success']) {
$tracking = $result['data'];
echo "Status: " . $tracking['deliveryStatusText'] . "\n"; // "배송중"
echo "Location: " . $tracking['progresses'][0]['location']; // "서울 허브"
} else {
echo "Error: " . $result['error']['code']; // "NOT_FOUND"
} 개별 조회 건이 실패해도 전체 HTTP 요청은 200으로 응답합니다. 반드시 result['success']로 건별 성공 여부를 확인하세요.
4. 다건 조회
items 배열에 여러 항목을 넣으면 한 번의 API 호출로 최대 50건까지 동시 조회할 수 있습니다. clientId에 주문번호를 넣으면 응답에서 쉽게 매칭할 수 있습니다.
<?php
$ch = curl_init('https://api.deliveryapi.co.kr/v1/tracking/trace');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Content-Type: application/json',
'Authorization: Bearer ' . $apiKey . ':' . $secretKey,
],
CURLOPT_POSTFIELDS => json_encode([
'items' => [
['courierCode' => 'cj', 'trackingNumber' => '1111111111', 'clientId' => 'order_001'],
['courierCode' => 'lotte', 'trackingNumber' => '2222222222', 'clientId' => 'order_002'],
['courierCode' => 'hanjin', 'trackingNumber' => '3333333333', 'clientId' => 'order_003'],
],
]),
]);
$response = curl_exec($ch);
curl_close($ch);
$data = json_decode($response, true);
$summary = $data['data']['summary'];
echo "Total: {$summary['total']}, Success: {$summary['successful']}, Failed: {$summary['failed']}\n";
foreach ($data['data']['results'] as $result) {
if ($result['success']) {
echo "[{$result['clientId']}] {$result['data']['deliveryStatusText']}\n";
}
} 5. Guzzle 사용하기
Guzzle은 PHP에서 가장 널리 사용되는 HTTP 클라이언트 라이브러리입니다. Composer로 설치하세요.
composer require guzzlehttp/guzzle <?php
require 'vendor/autoload.php';
use GuzzleHttp\Client;
$client = new Client(['base_uri' => 'https://api.deliveryapi.co.kr']);
$response = $client->post('/v1/tracking/trace', [
'headers' => [
'Authorization' => 'Bearer ' . $apiKey . ':' . $secretKey,
],
'json' => [
'items' => [
['courierCode' => 'cj', 'trackingNumber' => '1234567890'],
],
],
]);
$data = json_decode($response->getBody(), true); Guzzle을 사용하면 json 옵션으로 자동 JSON 인코딩이 되어 코드가 한결 깔끔해집니다.
6. Laravel 연동
Laravel의 Http 파사드를 사용하면 프레임워크 스타일에 맞는 깔끔한 코드를 작성할 수 있습니다. API 키는 config/services.php에 설정하세요.
<?php
// app/Services/DeliveryService.php
namespace App\Services;
use Illuminate\Support\Facades\Http;
class DeliveryService
{
private string $baseUrl = 'https://api.deliveryapi.co.kr';
public function track(string $courierCode, string $trackingNumber): array
{
$apiKey = config('services.delivery.api_key');
$secretKey = config('services.delivery.secret_key');
$response = Http::withHeaders([
'Authorization' => 'Bearer ' . $apiKey . ':' . $secretKey,
])->post($this->baseUrl . '/v1/tracking/trace', [
'items' => [
[
'courierCode' => $courierCode,
'trackingNumber' => $trackingNumber,
],
],
]);
return $response->json();
}
}
// Usage in controller
// $service = new DeliveryService();
// $data = $service->track('cj', '1234567890'); 7. 에러 처리
네트워크 오류, 인증 실패, 요청 한도 초과 등 다양한 에러 상황에 대비하세요. HTTP 상태 코드별로 적절히 처리하는 것이 중요합니다.
<?php
function trackPackage(string $courierCode, string $trackingNumber): array
{
$apiKey = getenv('DELIVERY_API_KEY');
$secretKey = getenv('DELIVERY_SECRET_KEY');
$ch = curl_init('https://api.deliveryapi.co.kr/v1/tracking/trace');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTPHEADER => [
'Content-Type: application/json',
'Authorization: Bearer ' . $apiKey . ':' . $secretKey,
],
CURLOPT_POSTFIELDS => json_encode([
'items' => [
['courierCode' => $courierCode, 'trackingNumber' => $trackingNumber],
],
]),
]);
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
$curlError = curl_error($ch);
curl_close($ch);
// Network error
if ($curlError) {
throw new \RuntimeException('cURL error: ' . $curlError);
}
// HTTP error handling
switch ($httpCode) {
case 200:
return json_decode($response, true);
case 401:
throw new \RuntimeException('Authentication failed — check API keys');
case 429:
throw new \RuntimeException('Rate limit exceeded — retry later');
default:
throw new \RuntimeException("HTTP error: {$httpCode}");
}
}