Custom Courier API (Merchant-Owned Provider)
Use this guide when a merchant already has their own courier, dispatch, or logistics provider with a private API.
This setup is not the eshopOS developer API.
It is a shipping adapter for calling the merchant's external provider directly during checkout and fulfillment.
What This Integration Is
This provider lets eshopOS:
- call the merchant's provider to get shipping quotes at checkout
- optionally create a shipment after payment
- optionally sync delivery updates through a polling endpoint
- optionally receive tracking updates through a webhook
- optionally verify webhook signatures with HMAC SHA-256
- fall back to the storefront tracking page when the provider does not return a tracking URL
What "Merchant API Key" Actually Means
In this shipping context, the stored key is:
- the courier/provider API key
- or the provider access token
It is not:
- an eshopOS merchant API key
- a dashboard login token
- a storefront token
If the provider gave the merchant a secret like sk_live_..., token_..., Bearer ..., or a private header value, that is the credential that belongs here.
Do We Need a Key From the Provider?
Not always.
Supported today:
- No auth
- Bearer token auth
- Custom header auth
- Basic auth
- OAuth client credentials
Not supported in this setup today:
- OAuth authorization-code / browser-consent providers
- signed-request schemes that need custom cryptographic logic
If a provider supports no auth, bearer token, custom header auth, basic auth, or OAuth client credentials, this generic adapter can connect directly.
If a provider only supports browser-consent OAuth or custom signed requests, this generic adapter is not the right fit yet. Use Local Rules for now, or build a provider-specific adapter.
Auth Modes
No Auth
Use this when the provider accepts server-to-server requests without any credential.
eshopOS sends the request directly with no auth header.
Bearer Token
Use this when the provider expects:
Authorization: Bearer <token>
The merchant pastes the provider-issued token into the setup flow.
Custom Header
Use this when the provider expects a secret in a named header such as:
X-API-Key: <token>
The merchant enters:
- the header name
- the provider API key or token
Basic Auth
Use this when the provider expects an HTTP basic auth username and password.
The merchant enters:
- provider username
- provider password
OAuth Client Credentials
Use this when the provider exposes a token endpoint for server-to-server access.
eshopOS requests an access token using:
- token URL
- client ID
- client secret
- optional scope
Then eshopOS uses that access token for provider API calls.
OAuth Browser / Consent Flows
This generic adapter does not handle user-consent redirects or browser-based OAuth authorization-code flows.
If the provider only supports those flows, that needs a dedicated adapter.
What The Merchant Must Obtain From The Provider
Before configuration, the merchant should ask their courier/provider for:
- Base API URL
Example:
https://api.courier.example - Quote endpoint path
Example:
/v1/shipping/quotes - Shipment creation endpoint path
Optional. Example:
/v1/shipments - Shipment status endpoint path
Optional. Example:
/v1/shipments/{{tracking_number}} - Auth material
This depends on the provider:
- nothing for
no auth - API key or token for
bearerorheader - username and password for
basic - client ID and client secret for
oauth client credentials
- nothing for
- Auth method One of: no auth, bearer token, custom header, basic auth, OAuth client credentials
- Header name
Only needed for custom-header auth. Example:
X-API-Key - Username Only needed for basic auth
- Password Only needed for basic auth
- OAuth token URL Only needed for OAuth client credentials
- OAuth client ID Only needed for OAuth client credentials
- OAuth client secret Only needed for OAuth client credentials
- OAuth scope Optional for OAuth client credentials
- Webhook support details Optional. Needed if the provider can push status changes to us
- Tracking URL format
Optional. Example:
https://provider.example/track/{{tracking_number}}
When To Use This Instead Of Shippo
Use Shippo when:
- the merchant wants a ready-made carrier network
- the merchant is comfortable using Shippo's own account and tracking model
Use Custom Courier API when:
- the merchant already has their own courier relationship
- the courier gave them a private API
- the merchant wants to use their own provider credentials instead of ours
Use Local Rules when:
- rates are manual or zone-based
- there is no provider API
- the merchant wants a simple built-in fallback
Configuration Flow In Merchant Hub
Path:
Settings -> Fulfillment -> Providers -> Custom Courier API -> Configure
Step 1: Connect API
Enter:
- Provider name
- Base URL
- Provider auth type
- Provider API key/token for bearer or custom-header auth
- Header name if the provider uses custom-header auth
- Username and password if the provider uses basic auth
- Token URL, client ID, and client secret if the provider uses OAuth client credentials
Important:
- the credential is the provider's secret, not eshopOS'
- the base URL should be only the API root, not a specific endpoint
- for OAuth client credentials, the token URL is separate from the base API URL
Step 2: Endpoints & Tracking
Enter:
- Quote path
- Shipment path if the provider supports shipment creation
- Status path if the provider supports polling
- Tracking URL template if the provider returns only a tracking number
Webhook URL:
- eshopOS generates this for the merchant
- give this URL to the provider only if they support webhooks
Webhook verification:
- optional for Custom Courier
- supported mode today:
HMAC SHA-256 - the provider sends a signature header
- eshopOS verifies the raw webhook body using the saved webhook secret
- if verification is enabled and the signature fails, the webhook is rejected
What Is Enough To Connect?
- For checkout rates: base URL + quote path + matching auth details are enough.
- For shipment creation: the provider also needs a shipment endpoint.
- For live tracking sync: use either a status endpoint for polling, a webhook for push updates, or both.
- A webhook is helpful, but not required for the initial connection.
Step 3: Test & Activate
Review readiness, then optionally run the advanced provider test.
The advanced test can:
- test quote calls
- optionally test shipment creation
- optionally test status polling
eshopOS also saves recent test results and recent webhook deliveries so the merchant can inspect the latest provider activity without re-running setup.
Use shipment/status tests carefully if the provider points to live infrastructure.
Required vs Optional Fields
Required to activate:
- Base URL
- Quote path
Conditionally required:
- Nothing, if auth type is
none - Provider API key/token, if auth type is
bearer - Header name, if auth type is
header - Provider API key/token, if auth type is
header - Username and password, if auth type is
basic - OAuth token URL, client ID, and client secret, if auth type is
oauth client credentials
Optional:
- Shipment path
- Status path
- Tracking URL template
- Webhook support
- Webhook signature verification
How Tracking Works
If the provider returns a tracking URL:
- eshopOS stores it
- customer emails can use it
- storefront order tracking can expose it
If the provider returns only a tracking number:
- eshopOS can build a tracking URL from the saved tracking template
If the provider returns neither:
- eshopOS falls back to the storefront tracking page
Example Mapping
Example provider details:
- Base URL:
https://api.fastdispatch.example - Quote path:
/v1/rates - Shipment path:
/v1/shipments - Status path:
/v1/shipments/{{tracking_number}} - Auth type:
header - Header name:
X-API-Key - API key:
fd_live_123456 - Tracking template:
https://fastdispatch.example/track/{{tracking_number}}
In Merchant Hub:
- Provider name:
Fast Dispatch - Base URL:
https://api.fastdispatch.example - Provider auth type:
Custom header - Header name:
X-API-Key - Provider API key/token:
fd_live_123456 - Quote path:
/v1/rates - Shipment path:
/v1/shipments - Status path:
/v1/shipments/{{tracking_number}} - Tracking URL template:
https://fastdispatch.example/track/{{tracking_number}}
Troubleshooting
"Credential Required"
This means the selected auth mode still needs its required auth material.
"Setup Needed"
Usually one of these is missing:
- base URL
- quote path
- provider auth details for the selected auth mode
- header name for header auth
The Provider Uses No Auth
That is now supported. Choose No auth in the setup flow.
The Provider Uses Basic Auth
That is now supported. Choose Basic auth, then enter the provider username and password.
The Provider Uses OAuth Or Custom Signing
If the provider only supports:
- browser-consent OAuth
- signed webhooks only
- custom request signing
then this generic setup is insufficient and needs a provider-specific adapter.
The Provider Uses OAuth Client Credentials
That is now supported. Choose OAuth client credentials, then enter:
- token URL
- client ID
- client secret
- optional scope