Download the PHP package starmile/partner-sdk without Composer

On this page you can find all versions of the php package starmile/partner-sdk. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.

FAQ

After the download, you have to make one include require_once('vendor/autoload.php');. After that you have to import the classes with use statements.

Example:
If you use only one package a project is not needed. But if you use more then one package, without a project it is not possible to import the classes with use statements.

In general, it is recommended to use always a project to download your libraries. In an application normally there is more than one library needed.
Some PHP packages are not free to download and because of that hosted in private repositories. In this case some credentials are needed to access such packages. Please use the auth.json textarea to insert credentials, if a package is coming from a private repository. You can look here for more information.

  • Some hosting areas are not accessible by a terminal or SSH. Then it is not possible to use Composer.
  • To use Composer is sometimes complicated. Especially for beginners.
  • Composer needs much resources. Sometimes they are not available on a simple webspace.
  • If you are using private repositories you don't need to share your credentials. You can set up everything on our site and then you provide a simple download link to your team member.
  • Simplify your Composer build process. Use our own command line tool to download the vendor folder as binary. This makes your build process faster and you don't need to expose your credentials for private repositories.
Please rate this library. Is it a good library?

Informations about the package partner-sdk

Starmile Partner SDK (PHP)

Official PHP SDK for the Starmile Partner API — the partner-facing integration surface of the Starmile cross-border logistics platform. It wraps every Partner API capability behind a small, typed, dependency-free client: catalogue lookup, order intake and management, the pull-based status pool, and inbound lifecycle events.

This package is a thin, faithful client over the HTTP API. The HTTP API remains the canonical contract; the public reference lives at api.starmile.io.

Installation

Requires PHP 7.1+ with the curl and json extensions.

Authentication

The Partner API uses OAuth2 client credentials. Your organization's back office issues you a client_id and client_secret (a Partner API credential). The SDK exchanges them for a short-lived bearer token at POST /oauth/token and attaches it to every call — you never touch the token endpoint directly.

Keep the client_secret server-side. Read it (and the base URL) from the environment — never hardcode credentials or per-environment hosts.

Configuration options

Client::create($clientId, $clientSecret, $options) accepts:

Option Default Description
base_url https://api.starmile.io API host. Point at your sandbox/staging outside production.
scopes all granted Subset of the credential's scopes to request on the token.
http_client bundled cURL client Any HttpClientInterface (Guzzle/Symfony/PSR-18 adapter, a mock).
token_storage in-memory A TokenStorageInterface to share one token across processes.
verify_tls true TLS verification (keep on in production).
connect_timeout 10 Connection timeout (seconds).
timeout 30 Total request timeout (seconds).
user_agent starmile-partner-sdk-php/x Override the User-Agent.
max_attempts 3 Total attempts for safe (GET) calls on transient failure. 1 disables auto-retry.
retry_base_delay_ms 200 Base backoff between retries (exponential + jitter).
retry_max_delay_ms 5000 Cap on the computed backoff.

Capabilities

The Partner API surface is reached through four resource groups, each gated by the scopes on your credential.

Resource Scope(s) Endpoints
$starmile->catalogue() catalogue:read GET /api/v1/services, GET /api/v1/rates
$starmile->orders() orders:create, orders:update, orders:cancel POST /api/v1/orders, PATCH /api/v1/orders/{order}/parcels/{parcel}, POST /api/v1/orders/{order}/parcels/{parcel}/cancel, POST /api/v1/orders/{order}/cancel
$starmile->statusPool() status:read GET /api/v1/partner/changes
$starmile->events() events:transport, events:pudo, events:customs, leg:handoff POST /api/v1/partner/events

Catalogue

Each rate's service_id is a Service's own id (the same value you send on order creation), so a rate maps to exactly one Service — correlate a rate to a service by matching $rate['service_id'] to $service['id'].

Orders

Build an order with the fluent builders (or pass a raw array matching the API body). The corridor and delivery type come from the Service; you do not send a rate — Starmile resolves the billing rate automatically.

Creating an order is idempotent on your order_id. Re-sending one you already used (a retry after a timeout, a double submit) creates nothing: the original order is replayed — HTTP 200 instead of 201, duplicate is true, and order_id, region_status and items[] are exactly what you got the first time. Use it to recover our ids when you are unsure a create landed; to change an accepted order, use updateParcel() instead — the rest of the body is ignored on a replay.

For a Home Delivery service the destination region is resolved from your own (parent_region, region) reference, map-only per partner. If it is not mapped yet the order is still accepted and comes back with region_status pending_mapping — an operator maps your region in Starmile and the waiting order resolves automatically, so you do not resend it. mapped means the region was resolved; not_applicable means the service has no home region (PUDO / locker / clearance). Compare against Starmile\PartnerSdk\Enum\RegionStatus.

Orders and parcels are addressed by your own references afterwards — the order_id you sent, and a parcel's item_id (which the parcel carries back as partner_tracking in responses):

Parcel labels (PDF)

Download a SINGLE parcel's label as a PDF, rendered from your organization's default parcel label template. Address the parcel by its merchant_tracking (sticker code) or its parcel_id (our parcel id, returned as items[].parcel_id on create). The method returns the raw PDF bytes. Scope: labels:read.

Status pool (replaces webhooks)

Poll the pool with the cursor you last processed; you receive every change after it, in order. Persist the returned cursor to resume next time.

An order's feed opens with the status it was created in (typically waiting_for_arrival), carrying previous_status: null — so the first row you read for an order is always the point we took it on, not whichever hub event came first. previous_status is non-null on every row after that.

external_parent_id is your own reference for the order. external_id is your reference for a single parcel (the item_id you sent on create) and is present only on parcel-scoped changes — e.g. a parcel received at the hub — so you can act on that exact parcel; order-level changes leave external_id null. country is the ISO-2 country the change occurred in (the hub's country), so you can tell an origin event (e.g. CN) apart from a destination one (e.g. AZ). occurred_at is a plain Y-m-d H:i:s timestamp (e.g. 2026-06-20 09:14:00); timezone gives the IANA zone it is expressed in (e.g. UTC) — parse occurred_at in that zone.

Why a change happened

A change that has a reason carries reason — a stable code from Enum\Reason — and sometimes reason_detail, free text a person wrote. Branch on reason; show reason_detail to a human.

Codes cover customs holds (missing_declaration, inaccurate_information, prohibited_content_restricted_item, commercial_quantity_personal_allowance_exceeded), failed deliveries (customer_absent, address_not_found, customer_refused, could_not_reach_customer, wrong_or_incomplete_address) and cancellations (cancelled_by_partner, cancelled_by_customer, cancelled_by_operator). When you report an event whose data carries a reason, sending one of these codes publishes it on the merchant's feed as a code they can act on automatically; any other wording is passed through untouched as free text.

Inbound events

Report a lifecycle event for a package you handle as a carrier (shipment.*), PUDO point (parcel.*), customs broker (customs.*), or foreign organization on the next leg (leg.*). The EventBuilder validates the type and its data fields locally — an unknown type or field throws before a request is made.

Each accepted event advances the package. An event that is not a legal next step for the package's current status is rejected with a 422 carrying an error and a hint (see error handling below).

The recognised event types, their scope, and their data fields are exposed on the EventType enum:

Error handling

Non-2xx responses raise a typed exception; all extend StarmileException.

Exception HTTP Meaning
AuthenticationException 401 Missing/expired/invalid token or bad credentials.
AuthorizationException 403 Credential lacks the scope, is revoked, or API off.
NotFoundException 404 Unknown resource (or another partner's).
ConflictException 409 No longer changeable (shipment received / in custody).
ValidationException 422 Validation failed; field errors + event hint.
RateLimitException 429 Too many requests; carries getRetryAfter().
ApiException other Any other non-2xx; base for the above.
TransportException Network failure (no response).

Retries & resilience

By default the SDK retries safe (GET) requests on transient failures — network errors, 429, and 5xx — with exponential backoff + jitter, honoring a Retry-After header. Non-idempotent writes (POST /orders, POST /partner/events) are never retried automatically, so a flaky response can't create a duplicate order. Tune or disable this with max_attempts (see options above). Creating an order is safe to retry either way — it is idempotent on your order_id.

When you do want a write retried, opt in per call with retry() — mirroring Laravel's HTTP client. It returns a one-off client; the original is unchanged:

When a failure can't be decoded as JSON (e.g. a gateway's HTML 502), the raw body is preserved on the exception via getRawBody():

Constants

The SDK ships the server vocabularies verbatim so you compare against names, not magic strings:

Custom HTTP transport

Replace the default cURL transport with anything implementing HttpClientInterface (e.g. to reuse a configured Guzzle client, add retries, or mock in tests):

Token sharing across processes

By default the token lives in process memory. Implement TokenStorageInterface (backed by APCu, Redis, a PSR-16 cache, or a file) and pass it as token_storage to reuse one token across requests/workers and avoid re-hitting /oauth/token.

Testing

The suite drives the client through a scripted in-memory transport — no network.

Versioning & support

Semantic Versioning. New Partner API capabilities are added here in lockstep with the server; see the CHANGELOG.

License

MIT — see LICENSE.


All versions of partner-sdk with dependencies

PHP Build Version
Package Version
Requires php Version >=7.1
ext-curl Version *
ext-json Version *
Composer command for our command line client (download client) This client runs in each environment. You don't need a specific PHP version etc. The first 20 API calls are free. Standard composer command

The package starmile/partner-sdk contains the following files

Loading the files please wait ...