tigusigalpa / shiptime-php
Modern PHP/Laravel client library for the ShipTime REST API
Installs: 0
Dependents: 0
Suggesters: 0
Security: 0
Stars: 0
Watchers: 0
Forks: 0
Open Issues: 0
pkg:composer/tigusigalpa/shiptime-php
Requires
- php: ^8.1
- guzzlehttp/guzzle: ^7.0
- illuminate/support: ^9.0|^10.0|^11.0|^12.0
Requires (Dev)
- mockery/mockery: ^1.5
- orchestra/testbench: ^8.0|^9.0
- phpunit/phpunit: ^10.0
README
A modern, robust, and well-documented PHP/Laravel client library for the ShipTime REST API. Built with modern PHP 8.1+ features including strict typing, enums, and readonly properties.
Features
- 🚀 Modern PHP 8.1+ - Leverages the latest PHP features
- 🎯 Strict Typing - Full type safety with scalar types and return types
- 📦 Complete API Coverage - All public ShipTime API endpoints
- 🔧 Laravel Integration - Service provider for seamless Laravel integration
- 🛡️ Robust Error Handling - Specific exceptions for different error types
- 📝 Comprehensive Documentation - Fully documented with PHPDoc
- ✅ Well Tested - Comprehensive test suite
- 🎨 Clean Architecture - Service-oriented design with DTOs
Requirements
- PHP 8.1 or higher
- Laravel 9.x, 10.x, 11.x, or 12.x (for Laravel integration)
- Guzzle HTTP client 7.x
Installation
Install the package via Composer:
composer require tigusigalpa/shiptime-php
Laravel Installation
The package will automatically register its service provider.
Publish the configuration file:
php artisan vendor:publish --tag=shiptime-config
Add your ShipTime API credentials to your .env file:
SHIPTIME_API_KEY=your_api_key SHIPTIME_API_SECRET=your_api_secret
Usage
Standalone PHP Usage
use Tigusigalpa\ShipTime\ShipTime; $shiptime = new ShipTime( apiKey: 'your_api_key', apiSecret: 'your_api_secret' ); // Get shipping rates $rates = $shiptime->rates()->getRates($rateRequest); // Create a shipment $shipment = $shiptime->shipments()->createShipment($shipRequest); // Track a shipment $tracking = $shiptime->track()->track($shipmentId);
Laravel Usage
Inject the ShipTime client via dependency injection:
use Tigusigalpa\ShipTime\ShipTime; class ShippingController extends Controller { public function __construct( private ShipTime $shiptime ) {} public function getRates(Request $request) { $rates = $this->shiptime->rates()->getRates($rateRequest); return response()->json($rates); } }
Or use the facade:
use Tigusigalpa\ShipTime\Facades\ShipTime; $rates = ShipTime::rates()->getRates($rateRequest);
API Reference
Orders
Create and manage preliminary shipment orders.
Get Orders
use Tigusigalpa\ShipTime\ShipTime; $shiptime = new ShipTime($apiKey, $apiSecret); // Get paginated list of orders $orders = $shiptime->orders()->getOrders( page: 0, size: 10, status: 'PENDING', orderDate: '2024-01-15' ); foreach ($orders->content as $order) { echo "Order ID: {$order['orderId']}\n"; }
Create Order
use Tigusigalpa\ShipTime\DTOs\OrderRequest; use Tigusigalpa\ShipTime\DTOs\ShipTo; use Tigusigalpa\ShipTime\DTOs\Package; use Tigusigalpa\ShipTime\DTOs\Dimensions; $shipTo = new ShipTo( streetAddress: '123 Main St', city: 'New York', state: 'NY', postalCode: '10001', countryCode: 'US', companyName: 'Acme Corp', attention: 'John Doe', phone: '555-1234' ); $package = new Package( weight: 5.5, dimensions: new Dimensions(length: 12, width: 8, height: 6), type: 'PACKAGE' ); $orderRequest = new OrderRequest( orderNumber: 'ORD-12345', shipTo: $shipTo, unitOfMeasurement: 'IMPERIAL', packages: [$package] ); $response = $shiptime->orders()->createOrder($orderRequest); echo "Order created with ID: {$response->orderId}\n";
Cancel Order
$cancelResponse = $shiptime->orders()->cancelOrder(orderId: 12345); if ($cancelResponse->success) { echo "Order cancelled successfully\n"; }
Rates
Get shipping rates for your shipments.
use Tigusigalpa\ShipTime\DTOs\RateRequest; use Tigusigalpa\ShipTime\DTOs\Address; use Tigusigalpa\ShipTime\DTOs\LineItem; use Tigusigalpa\ShipTime\Enums\PackageType; use Tigusigalpa\ShipTime\Enums\UnitOfMeasurement; $from = new Address( companyName: 'My Company', streetAddress: '123 Sender St', city: 'Los Angeles', countryCode: 'US', state: 'CA', postalCode: '90001', attention: 'Sender Name', phone: '555-0001' ); $to = new Address( companyName: 'Customer Co', streetAddress: '456 Receiver Ave', city: 'New York', countryCode: 'US', state: 'NY', postalCode: '10001', attention: 'Receiver Name', phone: '555-0002' ); $lineItem = new LineItem( length: 12.0, width: 8.0, height: 6.0, weight: 5.5 ); $rateRequest = new RateRequest( from: $from, to: $to, packageType: PackageType::PACKAGE, lineItems: [$lineItem], unitOfMeasurement: UnitOfMeasurement::IMPERIAL, shipDate: '2024-02-20' ); $rateResponse = $shiptime->rates()->getRates($rateRequest); foreach ($rateResponse->availableRates as $quote) { echo "Carrier: {$quote->carrierName}\n"; echo "Service: {$quote->serviceName}\n"; echo "Total: {$quote->totalCharge->currency->value} {$quote->totalCharge->amount}\n"; echo "Transit Days: {$quote->transitDays}\n\n"; }
Shipments
Create, retrieve, and manage shipments.
Create Shipment
use Tigusigalpa\ShipTime\DTOs\ShipRequest; // Option 1: Using a quote ID from a previous rate request $shipRequest = new ShipRequest( quoteId: 'quote_abc123' ); // Option 2: Using rate request with carrier and service selection $shipRequest = new ShipRequest( rateRequest: $rateRequest, carrierId: 'UPS', serviceId: 'UPS_GROUND', ref1: 'Reference 1', ref2: 'Reference 2' ); $shipResponse = $shiptime->shipments()->createShipment($shipRequest); echo "Shipment ID: {$shipResponse->shipId}\n"; echo "Tracking Number: {$shipResponse->trackingNumbers[0]}\n"; echo "Label URL: {$shipResponse->labelUrl}\n";
Get Shipments
$shipments = $shiptime->shipments()->getShipments( page: 0, size: 20, shipDate: '2024-02-15' ); foreach ($shipments->content as $shipment) { echo "Shipment: {$shipment['shipId']}\n"; }
Get Shipment Details
$shipment = $shiptime->shipments()->getShipment(shipmentId: 12345); echo "Status: {$shipment->status->value}\n"; echo "Carrier: {$shipment->carrierName}\n"; echo "Service: {$shipment->serviceName}\n";
Get Shipping Label (PDF)
$labelPdf = $shiptime->shipments()->getLabel(shipmentId: 12345); // Save to file file_put_contents('label.pdf', $labelPdf); // Or send as download header('Content-Type: application/pdf'); header('Content-Disposition: attachment; filename="shipping-label.pdf"'); echo $labelPdf;
Get Customs Invoice (PDF)
$invoicePdf = $shiptime->shipments()->getCustomsInvoice(shipmentId: 12345); file_put_contents('customs-invoice.pdf', $invoicePdf);
Cancel Shipment
$cancelResponse = $shiptime->shipments()->cancelShipment(shipmentId: 12345); if ($cancelResponse->success) { echo "Shipment cancelled\n"; }
Tracking
Track shipments and get delivery status.
$trackResponse = $shiptime->track()->track( shipmentId: 12345, includeTime: true ); $tracking = $trackResponse->trackingRecord; echo "Current Status: {$tracking->currentStatus->value}\n"; foreach ($tracking->history as $event) { echo "{$event->timestamp} - {$event->name} at {$event->location}\n"; } // Proof of delivery if ($tracking->podInfo) { echo "Signed by: {$tracking->podInfo->signedBy}\n"; echo "Delivered at: {$tracking->podInfo->timestamp}\n"; }
Pickups
Schedule and manage pickups.
Schedule Pickup
use Tigusigalpa\ShipTime\DTOs\PickupRequest; use Tigusigalpa\ShipTime\DTOs\PickupDetail; use Tigusigalpa\ShipTime\Enums\PickupLocation; $pickupDetail = new PickupDetail( location: PickupLocation::FRONT_DOOR, pickupDate: '2024-02-20', readyTime: '09:00', closeTime: '17:00' ); $pickupRequest = new PickupRequest( shipId: 12345, pickupDetail: $pickupDetail ); $pickup = $shiptime->pickups()->schedulePickup($pickupRequest); echo "Pickup scheduled: {$pickup->confirmationNumber}\n";
Get Pickups
$pickups = $shiptime->pickups()->getPickups(page: 0, size: 10); foreach ($pickups->content as $pickup) { echo "Pickup ID: {$pickup['id']}\n"; }
Cancel Pickup
$response = $shiptime->pickups()->cancelPickup(pickupId: 'pickup123'); if ($response->success) { echo "Pickup cancelled\n"; }
Get Available Pickups for Shipment
$availablePickups = $shiptime->pickups()->getAvailablePickupsForShipment( shipmentId: 12345 ); if ($availablePickups->pickup) { echo "Available pickup: {$availablePickups->pickup->confirmationNumber}\n"; }
Boxes
Get available box configurations.
$boxes = $shiptime->boxes()->getBoxes(); foreach ($boxes as $box) { echo "Box: {$box->name}\n"; echo "Dimensions: {$box->length}x{$box->width}x{$box->height}\n"; echo "Weight: {$box->weight}\n\n"; }
Accounts
Get account information and available services.
$servicesResponse = $shiptime->accounts()->getAvailableServices(); foreach ($servicesResponse->carrierServices as $service) { echo "Carrier: {$service->carrierName}\n"; echo "Service: {$service->serviceName}\n\n"; }
Location
Lookup location information by postal code.
use Tigusigalpa\ShipTime\Enums\CountryCode; $location = $shiptime->location()->lookup( countryCode: CountryCode::US, postalCode: '10001' ); echo "City: {$location->city}\n"; echo "State: {$location->state}\n";
Error Handling
The library provides specific exception classes for different error scenarios:
use Tigusigalpa\ShipTime\Exceptions\AuthenticationException; use Tigusigalpa\ShipTime\Exceptions\ValidationException; use Tigusigalpa\ShipTime\Exceptions\NotFoundException; use Tigusigalpa\ShipTime\Exceptions\ForbiddenException; use Tigusigalpa\ShipTime\Exceptions\ServerErrorException; use Tigusigalpa\ShipTime\Exceptions\ShipTimeException; try { $rates = $shiptime->rates()->getRates($rateRequest); } catch (AuthenticationException $e) { // Invalid API credentials echo "Authentication failed: {$e->getMessage()}\n"; } catch (ValidationException $e) { // Invalid request data echo "Validation error: {$e->getMessage()}\n"; } catch (NotFoundException $e) { // Resource not found echo "Not found: {$e->getMessage()}\n"; } catch (ForbiddenException $e) { // Access forbidden echo "Forbidden: {$e->getMessage()}\n"; } catch (ServerErrorException $e) { // Server error (5xx) echo "Server error: {$e->getMessage()}\n"; } catch (ShipTimeException $e) { // Any other ShipTime API error echo "API error: {$e->getMessage()}\n"; }
International Shipments
For international shipments, you need to provide customs information:
use Tigusigalpa\ShipTime\DTOs\CustomsInvoice; use Tigusigalpa\ShipTime\DTOs\DutiesAndTaxes; use Tigusigalpa\ShipTime\DTOs\InvoiceItem; use Tigusigalpa\ShipTime\DTOs\InvoiceContact; use Tigusigalpa\ShipTime\Enums\Currency; use Tigusigalpa\ShipTime\Enums\ReasonForExport; use Tigusigalpa\ShipTime\Enums\DutiesPaidBy; $invoiceContact = new InvoiceContact( companyName: 'Exporter Inc', streetAddress: '123 Export St', city: 'Toronto', countryCode: 'CA', state: 'ON', postalCode: 'M5H 2N2', attention: 'Export Manager', phone: '416-555-0001' ); $dutiesAndTaxes = new DutiesAndTaxes( dutiable: true, paidBy: DutiesPaidBy::CONSIGNEE ); $invoiceItem = new InvoiceItem( quantity: 2, code: '123456', description: 'Electronic Components', origin: 'CA', provinceOrState: 'ON', unitPrice: 5000 // in cents ); $customsInvoice = new CustomsInvoice( dutiesAndTaxes: $dutiesAndTaxes, invoiceContact: $invoiceContact, currency: Currency::CAD, invoiceItems: [$invoiceItem], reasonForExport: ReasonForExport::COMMERCIAL ); // Add customs invoice to rate request $rateRequest = new RateRequest( from: $from, to: $to, packageType: PackageType::PACKAGE, lineItems: [$lineItem], unitOfMeasurement: UnitOfMeasurement::METRIC, shipDate: '2024-02-20', customsInvoice: $customsInvoice );
Testing
Run the test suite:
composer test
Run tests with coverage:
composer test:coverage
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add some amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
License
The MIT License (MIT). Please see License File for more information.
Credits
Support
For support, please contact sovletig@gmail.com or open an issue on GitHub.