flexops / sdk
Official FlexOps multi-carrier shipping platform SDK
Requires
- php: >=8.1
- ext-curl: *
- ext-json: *
Requires (Dev)
- phpunit/phpunit: ^10.5 || ^11.0
Suggests
None
Provides
None
Conflicts
None
Replaces
None
This package is auto-updated.
Last update: 2026-09-19 01:49:14 UTC
README
Official PHP SDK for the FlexOps multi-carrier shipping platform. Supports USPS, UPS, FedEx, DHL, OnTrac, Australia Post, Canada Post, Royal Mail, and LSO with rate shopping, label generation, tracking, webhooks, wallet, insurance, returns, and more.
Installation
composer require flexops/sdk
Quick Start
<?php require __DIR__ . '/vendor/autoload.php'; use FlexOps\FlexOps; // API key authentication (recommended for server-to-server) $client = new FlexOps([ 'apiKey' => 'fxk_live_...', 'workspaceId' => 'ws_abc123', ]); // Get shipping rates from all carriers $rates = $client->shipping->getRates([ 'origin' => ['addressLine1' => '123 Main St', 'city' => 'New York', 'stateProvince' => 'NY', 'postalCode' => '10001'], 'destination' => ['addressLine1' => '456 Oak Ave', 'city' => 'Los Angeles', 'stateProvince' => 'CA', 'postalCode' => '90210'], 'package' => ['weight' => 16, 'weightUnit' => 'oz'], ]); $request = [ 'carrierCode' => 'USPS', 'serviceCode' => 'GROUND_ADVANTAGE', 'origin' => ['name' => 'Warehouse', 'addressLine1' => '123 Main St', 'city' => 'New York', 'stateProvince' => 'NY', 'postalCode' => '10001', 'countryCode' => 'US'], 'destination' => ['name' => 'Customer', 'addressLine1' => '456 Oak Ave', 'city' => 'Los Angeles', 'stateProvince' => 'CA', 'postalCode' => '90210', 'countryCode' => 'US'], 'package' => ['weight' => 16, 'weightUnit' => 'oz'], 'maximumPostageAmount' => 10.25, // Caller-approved ceiling in USD. ]; $preview = $client->shipping->createLabel($request); echo $preview['quotedPostageAmount']; // Invoke only after explicit caller approval, within five minutes. $purchaseApprovedLabel = function (string $purchaseKey) use ($client, $request, $preview) { $request['confirmationToken'] = $preview['confirmationToken']; return $client->shipping->createLabel($request, $purchaseKey); }; // Persist the purchase key and reuse it on retries. // Track a shipment $info = $client->shipping->track('9400111899223456789012');
Live label approval (1.1.0+)
The example below requires SDK 1.1.0 or later. Version 1.0.2 does not include the per-call idempotency argument.
For live domestic single-label requests, maximumPostageAmount is required: positive
USD, at most two decimal places, up to 1,000,000. Missing or invalid values return
400 ApprovalRequired. Omitting confirmationToken returns a raw 200 preview
(status, quotedPostageAmount, maximumPostageAmount, currency, expiresAt,
confirmationToken). After explicit approval, resubmit the same shipment and ceiling
with the token and a unique per-purchase Idempotency-Key header. The token expires
after five minutes. A successful purchase returns the raw 201 label, including
labelId, trackingNumber, carrierCode, and labelData, without a data wrapper.
Keep the same key and request across retries. An uncertain outcome needs reconciliation;
do not start another purchase with a new key. An expired approval returns 409
ApprovalExpired; obtain and explicitly approve a fresh preview when no purchase is
unresolved. The ceiling bounds postage authorization, not later adjustments or separate
fees. Sandbox execution bypasses approval; batch, return, and raw carrier routes have
separate contracts. The SDK never automatically confirms a preview.
Authentication
API key (recommended)
$client = new FlexOps([ 'apiKey' => 'fxk_live_...', 'workspaceId' => 'ws_abc123', ]);
Email / password
$client = new FlexOps(['baseUrl' => 'https://gateway.flexops.io']); $client->auth->login('user@example.com', 'password'); $client->workspaceId = 'ws_abc123';
Sandbox / test keys
Use fxk_test_... (instead of fxk_live_...) to route to the sandbox environment. Mock carriers respond, nothing hits real carrier APIs, no charges, no real labels. Perfect for CI and integration tests.
$client = new FlexOps([ 'apiKey' => 'fxk_test_...', 'workspaceId' => 'ws_abc123', ]);
Direct carrier operations
Access carrier-specific endpoints when you need full control:
// USPS domestic label $label = $client->carriers->usps->createDomesticLabel([ 'imageType' => 'PDF', 'mailClass' => 'PRIORITY_MAIL', 'weightInOunces' => 16, ]); // FedEx rate quote $rates = $client->carriers->fedex->getRates([...]); // UPS tracking $info = $client->carriers->ups->track(['trackingNumber' => '1Z999AA10123456784']); // DHL shipment $shipment = $client->carriers->dhl->createShipment([...]);
Webhook verification
use FlexOps\Resources\WebhooksResource; $valid = WebhooksResource::verifySignature( payload: file_get_contents('php://input'), signature: $_SERVER['HTTP_X_FLEXOPS_SIGNATURE'], secret: 'whsec_...' );
Curl quickstart
Every SDK method is a thin wrapper around the FlexOps REST API. If you want to verify the API before committing to the SDK — or you're integrating from a language we don't ship a SDK for — these curl invocations hit the same endpoints:
# Shop rates across all connected carriers curl -X POST https://gateway.flexops.io/api/shipping/rates \ -H "X-API-Key: fxk_live_..." \ -H "Content-Type: application/json" \ -d '{ "origin": {"addressLine1": "123 Main St", "city": "New York", "stateProvince": "NY", "postalCode": "10001", "countryCode": "US"}, "destination": {"addressLine1": "456 Oak Ave", "city": "Los Angeles", "stateProvince": "CA", "postalCode": "90210", "countryCode": "US"}, "package": {"weight": 16, "weightUnit": "oz"} }' # Preview a live label; this does not purchase it. curl -X POST https://gateway.flexops.io/api/workspaces/ws_abc123/shipping/labels \ -H "X-API-Key: fxk_live_..." \ -H "Content-Type: application/json" \ -d '{ "carrierCode": "USPS", "serviceCode": "GROUND_ADVANTAGE", "origin": {"name": "Warehouse", "addressLine1": "123 Main St", "city": "New York", "stateProvince": "NY", "postalCode": "10001", "countryCode": "US"}, "destination": {"name": "Customer", "addressLine1": "456 Oak Ave", "city": "Los Angeles", "stateProvince": "CA", "postalCode": "90210", "countryCode": "US"}, "package": {"weight": 16, "weightUnit": "oz"}, "maximumPostageAmount": 10.25 }' # After explicit approval, resend the same body with confirmationToken from # the preview and an Idempotency-Key header unique to this purchase. # See the SDK example above; retain that key for retries. # Track a shipment curl https://gateway.flexops.io/api/workspaces/ws_abc123/shipping/track/9400111899223456789012 \ -H "X-API-Key: fxk_live_..." # Cancel a label (via the unified carrier-agnostic endpoint) curl -X DELETE https://gateway.flexops.io/api/v3.0/shipping/Usps/cancel/9400111899223456789012 \ -H "X-API-Key: fxk_live_..."
Use an fxk_test_... key instead of fxk_live_... to hit the sandbox environment; mock carriers respond, no real charges, no real labels.
Resources
| Resource | Description |
|---|---|
$client->auth |
Login, register, password management |
$client->workspaces |
Workspace CRUD, membership, branding |
$client->shipping |
Rate shopping, labels, tracking, batch, cancel |
$client->carriers |
USPS, UPS, FedEx, DHL direct endpoints |
$client->webhooks |
Subscription CRUD, signature verification, delivery logs |
$client->wallet |
Balance, transactions, auto-reload |
$client->insurance |
Quotes, purchase, claims (first-party + U-PIC) |
$client->returns |
RMA lifecycle: create, batch, QR codes, photo upload, cost recovery |
$client->apiKeys |
Key creation, rotation, revocation |
$client->analytics |
Shipments, orders, carrier performance |
$client->orders |
Order management |
$client->inventory |
Warehouse inventory |
$client->pickups |
Carrier pickup scheduling |
$client->scanForms |
USPS scan forms |
$client->rules |
Shipping automation rules |
$client->offsets |
Carbon offset purchases |
$client->hsCodes |
HS code lookup for international customs |
$client->recurringShipments |
Scheduled recurring shipments |
$client->emailTemplates |
Branded post-purchase email templates |
$client->reports |
Report generation and scheduled delivery |
Configuration
$client = new FlexOps([ 'baseUrl' => 'https://gateway.flexops.io', // API base URL 'apiKey' => 'fxk_live_...', // API key auth 'workspaceId' => 'ws_abc123', // Default workspace 'timeout' => 30, // Request timeout (seconds) ]);
Requirements
- PHP 8.1+
ext-curlext-json
License
MIT © FlexOps, LLC. See LICENSE for full text.