{"id":31807861,"url":"https://github.com/kalimeromk/postal-tracking-package","last_synced_at":"2026-05-09T05:32:33.115Z","repository":{"id":318711118,"uuid":"1072501739","full_name":"KalimeroMK/postal-tracking-package","owner":"KalimeroMK","description":"A lightweight PHP library for tracking postal shipments from Posta na Severna Makedonija. Features multi-framework support (Laravel, Yii, native PHP), automatic data transformation, comprehensive error handling, and real-time tracking capabilities. Perfect for e-commerce and logistics applications.","archived":false,"fork":false,"pushed_at":"2025-10-08T20:28:51.000Z","size":32,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2025-10-10T14:27:51.742Z","etag":null,"topics":["laravel","php","rest-api","yii2"],"latest_commit_sha":null,"homepage":"","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/KalimeroMK.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-10-08T20:06:35.000Z","updated_at":"2025-10-10T09:58:27.000Z","dependencies_parsed_at":"2025-10-10T14:27:56.016Z","dependency_job_id":"995c2cac-1160-49c5-a33a-f690fbdd56ac","html_url":"https://github.com/KalimeroMK/postal-tracking-package","commit_stats":null,"previous_names":["kalimeromk/postal-tracking-package"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/KalimeroMK/postal-tracking-package","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/KalimeroMK%2Fpostal-tracking-package","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/KalimeroMK%2Fpostal-tracking-package/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/KalimeroMK%2Fpostal-tracking-package/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/KalimeroMK%2Fpostal-tracking-package/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/KalimeroMK","download_url":"https://codeload.github.com/KalimeroMK/postal-tracking-package/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/KalimeroMK%2Fpostal-tracking-package/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":279006245,"owners_count":26084061,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-11T02:00:06.511Z","response_time":55,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["laravel","php","rest-api","yii2"],"created_at":"2025-10-11T04:38:23.280Z","updated_at":"2025-10-11T04:38:24.810Z","avatar_url":"https://github.com/KalimeroMK.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Postal Tracking Package 📦\n\nAdvanced PHP package for tracking postal shipments from Posta na Severna Makedonija with multi-framework support, comprehensive error handling, and high-performance tracking capabilities. Features Laravel integration, Yii framework support, and **Native PHP** usage with configurable caching, retry mechanisms, and automatic data transformation.\n\n## 📋 Table of Contents\n\n- [Features](#features)\n- [Installation](#installation)\n- [Quick Start](#quick-start)\n- [Framework Integration](#framework-integration)\n  - [Laravel Setup](#laravel-setup)\n  - [Yii Framework Setup](#yii-framework-setup)\n  - [Native PHP Setup](#native-php-setup)\n- [Usage Examples](#usage-examples)\n- [API Reference](#api-reference)\n- [Configuration](#configuration)\n- [Testing](#testing)\n- [Development](#development)\n- [Contributing](#contributing)\n- [License](#license)\n\n## ✨ Features\n\n- ✅ **Track postal shipments** from Posta na Severna Makedonija\n- 🚀 **Laravel integration** with service provider and facade\n- 🎯 **Yii framework support** with native integration\n- 🔥 **Native PHP support** - No framework required!\n- 📊 **JSON API responses** with structured data\n- 🔄 **Automatic data transformation** and localization\n- 🛡️ **Comprehensive error handling** and validation\n- ⚡ **High-performance** with configurable timeouts and retries\n- 🔧 **Configurable settings** via environment variables\n- 📝 **Comprehensive documentation** and examples\n- 🧪 **Full test coverage** with PHPUnit\n- 📦 **PSR-4 autoloading** and Composer integration\n\n## 📦 Installation\n\n### Requirements\n\n- PHP 8.1 or higher\n- cURL extension\n- JSON extension\n\n### Install via Composer\n\n```bash\ncomposer require kalimeromk/postal-tracking\n```\n\n### Verify Installation\n\n```bash\ncomposer show kalimeromk/postal-tracking\n```\n\n## 🚀 Quick Start\n\n### Basic Usage\n\n```php\n\u003c?php\nrequire_once 'vendor/autoload.php';\n\nuse KalimeroMK\\PostalTracking\\Services\\PostalTrackingService;\n\n$service = new PostalTrackingService();\n$result = $service-\u003etrackShipment('CQ117742716DE');\n\nif ($result['success']) {\n    echo \"Tracking successful!\\n\";\n    echo \"Total events: \" . count($result['data']) . \"\\n\";\n\n    foreach ($result['data'] as $event) {\n        echo \"- {$event['Забелешка']} on {$event['Датум']}\\n\";\n    }\n} else {\n    echo \"Error: \" . $result['error'] . \"\\n\";\n}\n?\u003e\n```\n\n### With Configuration\n\n```php\n\u003c?php\nuse KalimeroMK\\PostalTracking\\Services\\PostalTrackingService;\n\n$service = new PostalTrackingService(\n    timeout: 30,           // API timeout in seconds\n    retryAttempts: 3,      // Number of retry attempts\n    transformData: true    // Transform API response data\n);\n\n$result = $service-\u003etrackShipment('CQ117742716DE');\n?\u003e\n```\n\n## 🔧 Framework Integration\n\n### Laravel Setup\n\nThe package auto-registers its service provider and facade. No additional configuration required!\n\n#### Basic Usage\n\n```php\nuse KalimeroMK\\PostalTracking\\Facades\\PostalTracking;\n\n// Track a shipment\n$result = PostalTracking::trackShipment('CQ117742716DE');\n\n// With options\n$result = PostalTracking::trackShipment('CQ117742716DE', [\n    'timeout' =\u003e 30,\n    'retry_attempts' =\u003e 3,\n    'transform' =\u003e true\n]);\n```\n\n#### Controller Example\n\n```php\n\u003c?php\nnamespace App\\Http\\Controllers;\n\nuse Illuminate\\Http\\Request;\nuse KalimeroMK\\PostalTracking\\Facades\\PostalTracking;\n\nclass TrackingController extends Controller\n{\n    public function track(Request $request)\n    {\n        try {\n            $trackingCode = $request-\u003eget('tracking_code');\n            $result = PostalTracking::trackShipment($trackingCode);\n\n            return response()-\u003ejson($result);\n        } catch (\\Exception $e) {\n            return response()-\u003ejson([\n                'success' =\u003e false,\n                'error' =\u003e $e-\u003egetMessage()\n            ], 422);\n        }\n    }\n}\n?\u003e\n```\n\n#### Publish Configuration (Optional)\n\n```bash\nphp artisan vendor:publish --provider=\"KalimeroMK\\PostalTracking\\Laravel\\PostalTrackingServiceProvider\"\n```\n\n#### Service Provider Registration\n\nThe package automatically registers itself. If you need manual registration, add to `config/app.php`:\n\n```php\n'providers' =\u003e [\n    // ...\n    KalimeroMK\\PostalTracking\\Laravel\\PostalTrackingServiceProvider::class,\n],\n\n'aliases' =\u003e [\n    // ...\n    'PostalTracking' =\u003e KalimeroMK\\PostalTracking\\Laravel\\Facades\\PostalTracking::class,\n],\n```\n\n### Yii Framework Setup\n\nUse the service directly in your controllers or components.\n\n#### Basic Usage\n\n```php\nuse KalimeroMK\\PostalTracking\\Services\\PostalTrackingService;\n\n// In your controller\n$service = new PostalTrackingService();\n$trackingData = $service-\u003etrackShipment('CQ117742716DE');\n\n// Return as JSON\nYii::$app-\u003eresponse-\u003eformat = Response::FORMAT_JSON;\nreturn $trackingData;\n```\n\n#### Controller Example\n\n```php\n\u003c?php\nnamespace app\\controllers;\n\nuse yii\\web\\Controller;\nuse yii\\web\\Response;\nuse KalimeroMK\\PostalTracking\\Services\\PostalTrackingService;\n\nclass TrackingController extends Controller\n{\n    public function actionTrack()\n    {\n        Yii::$app-\u003eresponse-\u003eformat = Response::FORMAT_JSON;\n\n        try {\n            $trackingCode = Yii::$app-\u003erequest-\u003eget('tracking_code');\n            $service = new PostalTrackingService();\n            $result = $service-\u003etrackShipment($trackingCode);\n\n            return $result;\n        } catch (\\Exception $e) {\n            Yii::$app-\u003eresponse-\u003estatusCode = 422;\n            return [\n                'success' =\u003e false,\n                'error' =\u003e $e-\u003egetMessage()\n            ];\n        }\n    }\n}\n?\u003e\n```\n\n#### Component Registration\n\nAdd to your `config/web.php` or `config/console.php`:\n\n```php\n'components' =\u003e [\n    'postalTracking' =\u003e [\n        'class' =\u003e KalimeroMK\\PostalTracking\\Services\\PostalTrackingService::class,\n        'timeout' =\u003e 30,\n        'retryAttempts' =\u003e 3,\n        'transformData' =\u003e true,\n    ],\n],\n```\n\n### Native PHP Setup\n\nNo framework required! Perfect for standalone applications, microservices, or CLI tools.\n\n#### Simple Tracker Class\n\n```php\n\u003c?php\nrequire_once 'vendor/autoload.php';\n\nuse KalimeroMK\\PostalTracking\\Services\\PostalTrackingService;\n\nclass SimplePostalTracker\n{\n    private PostalTrackingService $service;\n\n    public function __construct()\n    {\n        $this-\u003eservice = new PostalTrackingService();\n    }\n\n    public function track(string $code): array\n    {\n        try {\n            return $this-\u003eservice-\u003etrackShipment($code);\n        } catch (\\Exception $e) {\n            return [\n                'success' =\u003e false,\n                'error' =\u003e $e-\u003egetMessage(),\n                'code' =\u003e $code\n            ];\n        }\n    }\n\n    public function isValidCode(string $code): bool\n    {\n        return preg_match('/^[A-Z]{2}\\d{9}[A-Z]{2}$/', strtoupper($code)) === 1;\n    }\n\n    public function isDelivered(string $code): bool\n    {\n        $result = $this-\u003etrack($code);\n\n        if ($result['success'] \u0026\u0026 !empty($result['data'])) {\n            $lastEvent = end($result['data']);\n            return strpos($lastEvent['Забелешка'], 'Испорачана') !== false;\n        }\n\n        return false;\n    }\n}\n\n// Usage\n$tracker = new SimplePostalTracker();\n\nif ($tracker-\u003eisValidCode('CQ117742716DE')) {\n    $result = $tracker-\u003etrack('CQ117742716DE');\n\n    if ($result['success']) {\n        echo \"Tracking successful!\\n\";\n        echo \"Total events: \" . count($result['data']) . \"\\n\";\n        echo \"Is delivered: \" . ($tracker-\u003eisDelivered('CQ117742716DE') ? 'Yes' : 'No') . \"\\n\";\n\n        // Show all events\n        foreach ($result['data'] as $event) {\n            echo \"- {$event['Забелешка']} on {$event['Датум']}\\n\";\n        }\n    }\n}\n?\u003e\n```\n\n#### Web Application\n\n```php\n\u003c?php\nrequire_once 'vendor/autoload.php';\n\nuse KalimeroMK\\PostalTracking\\Services\\PostalTrackingService;\n\n// Handle tracking request\nif (isset($_GET['tracking_code'])) {\n    $service = new PostalTrackingService();\n    $trackingCode = $_GET['tracking_code'];\n\n    try {\n        $result = $service-\u003etrackShipment($trackingCode);\n\n        header('Content-Type: application/json');\n        echo json_encode($result, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);\n    } catch (\\Exception $e) {\n        http_response_code(422);\n        echo json_encode([\n            'success' =\u003e false,\n            'error' =\u003e $e-\u003egetMessage()\n        ]);\n    }\n} else {\n    // Show tracking form\n    ?\u003e\n    \u003c!DOCTYPE html\u003e\n    \u003chtml\u003e\n    \u003chead\u003e\n        \u003ctitle\u003ePostal Tracking\u003c/title\u003e\n        \u003cmeta charset=\"UTF-8\"\u003e\n        \u003cstyle\u003e\n            body { font-family: Arial, sans-serif; margin: 40px; }\n            .form-group { margin: 20px 0; }\n            input[type=\"text\"] { padding: 10px; width: 300px; }\n            button { padding: 10px 20px; background: #007cba; color: white; border: none; cursor: pointer; }\n            button:hover { background: #005a87; }\n            .result { margin-top: 20px; padding: 20px; background: #f5f5f5; border-radius: 5px; }\n        \u003c/style\u003e\n    \u003c/head\u003e\n    \u003cbody\u003e\n        \u003ch1\u003eTrack Your Package\u003c/h1\u003e\n        \u003cform method=\"GET\"\u003e\n            \u003cdiv class=\"form-group\"\u003e\n                \u003clabel for=\"tracking_code\"\u003eTracking Code:\u003c/label\u003e\u003cbr\u003e\n                \u003cinput type=\"text\" id=\"tracking_code\" name=\"tracking_code\"\n                       placeholder=\"CQ117742716DE\" required\u003e\n            \u003c/div\u003e\n            \u003cbutton type=\"submit\"\u003eTrack Package\u003c/button\u003e\n        \u003c/form\u003e\n\n        \u003cdiv class=\"result\"\u003e\n            \u003ch3\u003eExample Tracking Codes:\u003c/h3\u003e\n            \u003cul\u003e\n                \u003cli\u003e\u003cstrong\u003eCQ117742716DE\u003c/strong\u003e - Package from Germany\u003c/li\u003e\n                \u003cli\u003e\u003cstrong\u003eRA123456789MK\u003c/strong\u003e - Macedonian postal code format\u003c/li\u003e\n            \u003c/ul\u003e\n        \u003c/div\u003e\n    \u003c/body\u003e\n    \u003c/html\u003e\n    \u003c?php\n}\n?\u003e\n```\n\n#### Command Line Usage\n\n```php\n\u003c?php\nrequire_once 'vendor/autoload.php';\n\nuse KalimeroMK\\PostalTracking\\Services\\PostalTrackingService;\n\nif ($argc \u003c 2) {\n    echo \"Usage: php track.php \u003ctracking_code\u003e\\n\";\n    echo \"Example: php track.php CQ117742716DE\\n\";\n    exit(1);\n}\n\n$trackingCode = $argv[1];\n$service = new PostalTrackingService();\n\ntry {\n    $result = $service-\u003etrackShipment($trackingCode);\n\n    if ($result['success']) {\n        echo \"✅ Tracking successful!\\n\";\n        echo \"📦 Tracking Code: {$result['tracking_code']}\\n\";\n        echo \"📊 Total events: \" . count($result['data']) . \"\\n\";\n        echo \"🕒 Last update: {$result['metadata']['last_update']}\\n\\n\";\n\n        echo \"📋 Tracking Events:\\n\";\n        foreach ($result['data'] as $index =\u003e $event) {\n            echo ($index + 1) . \". {$event['Забелешка']}\\n\";\n            echo \"   📍 From: {$event['Од']}\\n\";\n            echo \"   📍 To: {$event['До']}\\n\";\n            echo \"   📅 Date: {$event['Датум']}\\n\\n\";\n        }\n    }\n} catch (\\Exception $e) {\n    echo \"❌ Error: \" . $e-\u003egetMessage() . \"\\n\";\n    exit(1);\n}\n?\u003e\n```\n\n## 📚 Usage Examples\n\n### Advanced Configuration\n\n```php\n\u003c?php\nuse KalimeroMK\\PostalTracking\\Services\\PostalTrackingService;\n\n// Create service with custom configuration\n$service = new PostalTrackingService(\n    timeout: 60,           // 60 seconds timeout\n    retryAttempts: 5,      // 5 retry attempts\n    transformData: true    // Enable data transformation\n);\n\n// Track with additional options\n$result = $service-\u003etrackShipment('CQ117742716DE', [\n    'timeout' =\u003e 30,       // Override default timeout\n    'retry_attempts' =\u003e 2, // Override default retries\n    'transform' =\u003e false   // Disable transformation for this call\n]);\n?\u003e\n```\n\n### Batch Processing\n\n```php\n\u003c?php\nuse KalimeroMK\\PostalTracking\\Services\\PostalTrackingService;\n\n$service = new PostalTrackingService();\n$trackingCodes = [\n    'CQ117742716DE',\n    'RA123456789MK',\n    'DE987654321US'\n];\n\n$results = [];\n\nforeach ($trackingCodes as $code) {\n    try {\n        $result = $service-\u003etrackShipment($code);\n        $results[$code] = $result;\n    } catch (\\Exception $e) {\n        $results[$code] = [\n            'success' =\u003e false,\n            'error' =\u003e $e-\u003egetMessage()\n        ];\n    }\n}\n\n// Process results\nforeach ($results as $code =\u003e $result) {\n    if ($result['success']) {\n        echo \"✅ {$code}: \" . count($result['data']) . \" events\\n\";\n    } else {\n        echo \"❌ {$code}: {$result['error']}\\n\";\n    }\n}\n?\u003e\n```\n\n### Error Handling\n\n```php\n\u003c?php\nuse KalimeroMK\\PostalTracking\\Services\\PostalTrackingService;\nuse KalimeroMK\\PostalTracking\\Exceptions\\PostalTrackingException;\nuse KalimeroMK\\PostalTracking\\Exceptions\\InvalidTrackingCodeException;\nuse KalimeroMK\\PostalTracking\\Exceptions\\ApiException;\n\n$service = new PostalTrackingService();\n\ntry {\n    $result = $service-\u003etrackShipment('INVALID_CODE');\n} catch (InvalidTrackingCodeException $e) {\n    echo \"Invalid tracking code: \" . $e-\u003egetMessage() . \"\\n\";\n} catch (ApiException $e) {\n    echo \"API error: \" . $e-\u003egetMessage() . \"\\n\";\n} catch (PostalTrackingException $e) {\n    echo \"General error: \" . $e-\u003egetMessage() . \"\\n\";\n}\n?\u003e\n```\n\n## 📖 API Reference\n\n### PostalTrackingService Class\n\n#### Constructor\n\n```php\npublic function __construct(\n    int $timeout = 30,\n    int $retryAttempts = 3,\n    bool $transformData = true\n)\n```\n\n#### Methods\n\n##### trackShipment()\n\n```php\npublic function trackShipment(string $trackingCode, array $options = []): array\n```\n\n**Parameters:**\n\n- `$trackingCode` (string): The tracking code to look up\n- `$options` (array): Additional options\n  - `timeout` (int): API timeout in seconds\n  - `retry_attempts` (int): Number of retry attempts\n  - `transform` (bool): Enable/disable data transformation\n\n**Returns:** `array` - Tracking data with success status\n\n##### Configuration Methods\n\n```php\n// Getter methods\npublic function getTimeout(): int\npublic function getRetryAttempts(): int\npublic function getTransformData(): bool\n\n// Setter methods (fluent interface)\npublic function setTimeout(int $timeout): self\npublic function setRetryAttempts(int $retryAttempts): self\npublic function setTransformData(bool $transformData): self\n```\n\n### Response Format\n\n#### Success Response\n\n```json\n{\n  \"success\": true,\n  \"tracking_code\": \"CQ117742716DE\",\n  \"data\": [\n    {\n      \"Од\": \"Северна Македонија\",\n      \"До\": \"1006 - CARINA\",\n      \"Датум\": \"2025-01-15\",\n      \"Забелешка\": \"Испорачана\"\n    }\n  ],\n  \"metadata\": {\n    \"total_events\": 1,\n    \"last_update\": \"2025-01-15T10:30:00Z\",\n    \"api_url\": \"https://www.posta.com.mk/api/api.php/shipment?code=CQ117742716DE\"\n  }\n}\n```\n\n#### Error Response\n\n```json\n{\n  \"success\": false,\n  \"error\": \"Invalid tracking code format\",\n  \"code\": \"INVALID_CODE\",\n  \"tracking_code\": \"INVALID123\"\n}\n```\n\n### Exception Classes\n\n#### PostalTrackingException\n\nBase exception class for all postal tracking related errors.\n\n#### InvalidTrackingCodeException\n\nThrown when the tracking code format is invalid.\n\n#### ApiException\n\nThrown when API communication fails.\n\n## ⚙️ Configuration\n\n### Environment Variables\n\nCreate a `.env` file in your project root:\n\n```env\n# Postal Tracking Configuration\nPOSTAL_TRACKING_API_URL=https://www.posta.com.mk/api/api.php/shipment\nPOSTAL_TRACKING_TIMEOUT=30\nPOSTAL_TRACKING_RETRY_ATTEMPTS=3\nPOSTAL_TRACKING_TRANSFORM_DATA=true\n```\n\n### Programmatic Configuration\n\n```php\n\u003c?php\nuse KalimeroMK\\PostalTracking\\Services\\PostalTrackingService;\n\n// Create service with custom configuration\n$service = new PostalTrackingService(\n    timeout: 60,           // 60 seconds timeout\n    retryAttempts: 5,      // 5 retry attempts\n    transformData: true    // Enable data transformation\n);\n\n// Or configure after instantiation\n$service = new PostalTrackingService();\n$service-\u003esetTimeout(60)\n        -\u003esetRetryAttempts(5)\n        -\u003esetTransformData(true);\n?\u003e\n```\n\n### Framework-Specific Configuration\n\n#### Laravel\n\nPublish the config file:\n\n```bash\nphp artisan vendor:publish --provider=\"KalimeroMK\\PostalTracking\\Laravel\\PostalTrackingServiceProvider\"\n```\n\nThen edit `config/postal-tracking.php`:\n\n```php\n\u003c?php\nreturn [\n    'timeout' =\u003e env('POSTAL_TRACKING_TIMEOUT', 30),\n    'retry_attempts' =\u003e env('POSTAL_TRACKING_RETRY_ATTEMPTS', 3),\n    'transform_data' =\u003e env('POSTAL_TRACKING_TRANSFORM_DATA', true),\n];\n?\u003e\n```\n\n#### Yii\n\nAdd to your configuration:\n\n```php\n'components' =\u003e [\n    'postalTracking' =\u003e [\n        'class' =\u003e KalimeroMK\\PostalTracking\\Services\\PostalTrackingService::class,\n        'timeout' =\u003e 30,\n        'retryAttempts' =\u003e 3,\n        'transformData' =\u003e true,\n    ],\n],\n```\n\n## 🧪 Testing\n\nThe package includes comprehensive test coverage with PHPUnit.\n\n### Run Tests\n\n```bash\n# Run all tests\ncomposer test\n\n# Run specific test suites\n./vendor/bin/phpunit tests/PostalTrackingServiceTest.php\n\n# Run with coverage\n./vendor/bin/phpunit --coverage-html coverage/\n```\n\n### Test Coverage\n\n- **Unit tests** for all service methods\n- **Integration tests** with real API calls\n- **Exception handling** tests\n- **Configuration** tests\n- **Framework integration** tests\n\n### Example Test\n\n```php\n\u003c?php\nuse PHPUnit\\Framework\\TestCase;\nuse KalimeroMK\\PostalTracking\\Services\\PostalTrackingService;\n\nclass PostalTrackingServiceTest extends TestCase\n{\n    public function testTrackShipmentWithValidCode()\n    {\n        $service = new PostalTrackingService();\n        $result = $service-\u003etrackShipment('CQ117742716DE');\n\n        $this-\u003eassertTrue($result['success']);\n        $this-\u003eassertArrayHasKey('data', $result);\n        $this-\u003eassertArrayHasKey('metadata', $result);\n    }\n\n    public function testTrackShipmentWithInvalidCode()\n    {\n        $this-\u003eexpectException(InvalidTrackingCodeException::class);\n\n        $service = new PostalTrackingService();\n        $service-\u003etrackShipment('INVALID_CODE');\n    }\n}\n?\u003e\n```\n\n## 🛠️ Development\n\n### Code Style\n\nThe package follows PSR-12 coding standards.\n\n```bash\n# Fix code style\ncomposer cs-fix\n\n# Check code style\ncomposer cs-check\n```\n\n### Static Analysis\n\n```bash\n# Run PHPStan\n./vendor/bin/phpstan analyse src/\n```\n\n### Development Setup\n\n1. Clone the repository\n2. Install dependencies: `composer install`\n3. Run tests: `composer test`\n4. Fix code style: `composer cs-fix`\n\n### Contributing Guidelines\n\n1. Follow PSR-12 coding standards\n2. Write tests for new features\n3. Update documentation\n4. Ensure all tests pass\n5. Submit a pull request\n\n## 🤝 Contributing\n\nContributions are welcome! Please feel free to submit a Pull Request.\n\n1. Fork the repository\n2. Create your feature branch (`git checkout -b feature/AmazingFeature`)\n3. Commit your changes (`git commit -m 'Add some AmazingFeature'`)\n4. Push to the branch (`git push origin feature/AmazingFeature`)\n5. Open a Pull Request\n\n### Development Commands\n\n```bash\n# Install dependencies\ncomposer install\n\n# Run tests\ncomposer test\n\n# Fix code style\ncomposer cs-fix\n\n# Check code style\ncomposer cs-check\n\n# Run static analysis\n./vendor/bin/phpstan analyse src/\n```\n\n## 📄 License\n\nThis project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.\n\n---\n\n**Made with ❤️ by KalimeroMK**\n\n## 📞 Support\n\nIf you encounter any issues or have questions:\n\n- 📧 Email: zbogoevski@gmail.com\n- 🐛 Issues: [GitHub Issues](https://github.com/KalimeroMK/postal-tracking-package/issues)\n- 📖 Documentation: [GitHub Wiki](https://github.com/KalimeroMK/postal-tracking-package/wiki)\n\n## 🔗 Related Projects\n\n- [Email Check Package](https://github.com/KalimeroMK/email-check) - Advanced PHP email validation library\n- [Macedonian Postal API](https://www.posta.com.mk) - Official postal service API\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkalimeromk%2Fpostal-tracking-package","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkalimeromk%2Fpostal-tracking-package","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkalimeromk%2Fpostal-tracking-package/lists"}