Implement a shipping adapter
Implement shipping operations in a local module or external route app.
Use features/keystone/utils/shippingProviderAdapter.ts as the dispatch contract. The shippo.ts and shipengine.ts files in features/integrations/shipping are working examples. manual.ts is a placeholder. A separately deployed app can implement the same operations through URLs stored on the ShippingProvider record.
Operations
getRatesFunction({ provider, order, dimensions })
validateAddressFunction({ provider, address })
createLabelFunction({ provider, order, rateId, dimensions, lineItems, idempotencyKey })
trackShipmentFunction({ provider, trackingNumber })
cancelLabelFunction({ provider, labelId })For an HTTP adapter, Openfront sends POST JSON with provider plus these arguments. The body does not name the operation, so use one URL per operation or infer it from the payload.
What the callers expect back
The GraphQL result types show the shapes:
- rates: a list of
ShippingRatewithid,provider,service,carrier,priceandestimatedDays; - validation:
AddressValidationResultwithisValid,normalizedAddressanderrors; - label:
ProviderShippingLabeldata withstatus,trackingNumber,trackingUrlandlabelUrl; - tracking:
ShipmentTrackingResultwithstatus,estimatedDeliveryDateandtrackingEvents; - cancellation:
LabelCancellationResultwithsuccess,refundStatusanderror.
Rules
- Openfront checks permissions, the order and unfulfilled quantities before calling the adapter. Do not repeat that logic, but do validate input.
- Pass
idempotencyKeyto the carrier when buying labels. - Authenticate requests from Openfront to an HTTP adapter. The bridge sends no signature.
- Use the
provider.accessTokenOpenfront sends; do not log it. - Return errors for operations you do not support.
Configuration gap
The dashboard forms do not set URL operation fields. One stores metadata.apiUrl; the other sets a local custom module that does not exist. Set the five fields on the generic /dashboard/shipping-providers editor.
Verify
- Run rates, validation, label, tracking and cancellation in the carrier sandbox.
- Retry one label purchase with the same idempotency key and confirm a single label.
- Send malformed and slow replies and confirm no fulfillment record is written.
See Add a shipping adapter for configuration.