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

v1.0.0 2026-02-17 02:22 UTC

This package is auto-updated.

Last update: 2026-02-17 02:25:29 UTC


README

ShipTime PHP SDK

Latest Version on Packagist License

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.

  1. Fork the repository
  2. Create your feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add some amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. 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.

Links