|

Add a shipping adapter

Connect a local shipping module or an independently deployed HTTP adapter.

Openfront's shipping adapter dispatcher supports two provider modes:

  • a local module such as shippo, shipengine, or manual under features/integrations/shipping;
  • an external HTTP route app selected by the operation URLs stored on a ShippingProvider record.

The route-app mode lets a merchant connect custom shipping logic without adding that implementation to the Openfront repository.

Adapter operations

The configurable fields are:

  • getRatesFunction
  • validateAddressFunction
  • createLabelFunction
  • trackShipmentFunction
  • cancelLabelFunction

features/keystone/utils/shippingProviderAdapter.ts reads the relevant field. If it starts with http, Openfront sends the route a JSON POST containing the selected provider object and the operation arguments. Otherwise, it imports features/integrations/shipping/<value>.ts and calls the corresponding export.

Examples of operation arguments include:

  • rates: order and dimensions;
  • address validation: address;
  • label creation: order, rateId, dimensions, and lineItems;
  • tracking: trackingNumber;
  • cancellation: labelId.

The external route returns the same provider-neutral JSON shape expected from a local module.

Configure an external route app

  1. Deploy trusted HTTPS endpoints for the operations the app supports.
  2. Create a ShippingProvider with its name, active state, access token, from-address, regions, metadata, and operation URLs.
  3. Have the route app translate Openfront's operation payload into the external service's API and normalize the result back into Openfront's rate, validation, label, tracking, or cancellation shape.
  4. Test every enabled operation against synthetic addresses, disposable orders, and sandbox credentials.
  5. Verify duplicate, timeout, provider-failure, and reconciliation behavior before buying real labels.

The current bridge sends the selected provider object—including its queried access token—and order, address, parcel, or tracking data to the configured destination. Provider routing is therefore privileged integration configuration. Restrict who can edit it, use trusted HTTPS routes, authenticate requests to the adapter app, minimize the payload, validate responses, add timeouts, and enforce the deployment's outbound-network policy. Preserve external route adapters; harden their trust boundary.

Current source limitations

The backend dispatcher and ShippingProvider model support operation URLs, but the dashboard paths are inconsistent:

  • the order-level “new provider” form collects an API URL but stores it only in metadata.apiUrl instead of the five operation fields;
  • the general custom-provider drawer stores custom as a local module token even though no features/integrations/shipping/custom.ts module exists;
  • the HTTP bridge has no built-in timeout, destination validation, adapter authentication, or runtime response schema;
  • separate operations do not include an explicit operation name in the POST body, so a shared endpoint must infer it from the payload unless the protocol is extended.

Configure the operation fields directly through a trusted administrative path until those UI paths are repaired. Do not treat successful provider-row creation as proof that route dispatch works.

Required verification

  • unauthorized users cannot read the access token or alter adapter destinations;
  • operation URLs cannot be changed through untrusted storefront input;
  • the adapter authenticates the Openfront caller;
  • rate, address, order, and line-item relationships are checked before provider work;
  • label purchase and cancellation are idempotent;
  • malformed, delayed, partial, or oversized responses fail closed;
  • adapter credentials and customer addresses are redacted from logs and client responses;
  • tracking replay is deduplicated;
  • label cost, status, tracking, and cancellation reconcile with the fulfillment record.

See Shipping providers.

On this page