National Commerce Docs
ShipHero Handler

Shipping Zones & State Derivation

How the worker calculates USPS shipping zones from ZIP codes and recovers missing US states.

Two ZIP-code-driven calculations run near the end of the pipeline: deriving a customer's state when it is missing, and calculating the shipping zone for each shipment.

Shipping zone

Once an order and its shipments exist, the worker calculates a shipping zone from two ZIP codes:

  • Warehouse ZIP: zip_code from the warehouse looked up at the start of the request.
  • Customer ZIP: Zip_Code from the linked End Customer (Amazon buyer) row.

If both are present, calculateShippingZone POSTs them to the National Commerce zone API and stamps the result onto the shipments:

POST https://national-commerce.vercel.app/api/shipment-zones/get-zone
x-api-key: <ZONE_CALC_API_KEY>
{ "warehouseZip": "...", "customerZip": "..." }

The response drives six columns on the Shipments row: shipping_zone, zone_distance_miles, zone_calculation_status, zone_type, zone_calculated_at, and zone_error_details.

The zone math lives in the portal

The worker only calls the zone endpoint; the distance-to-zone mapping itself lives in the National Commerce app. See Shipping zones in Data Flows and the calculate_zone_from_distance database function.

Status codes

The zone_calculation_status column records what happened:

SituationStatus written
Both ZIPs present, API succeededvalue from the API (e.g. success)
API call failedcalculation_error
Warehouse ZIP missingno_warehouse_zip
Customer ZIP missingno_customer_zip

Whenever a status is set, zone_calculated_at is stamped and zone_error_details explains the miss. Because zone data is written in a standalone block that always runs, the status is recorded even for shipments that were already linked to an order. See Webhook Processing.

State derivation

When the worker creates a customer and the ShipHero shipping address has a blank state, it derives the US state from the ZIP code with getStateFromZipCode. The function reads the first three digits of the ZIP and maps that prefix to a state using USPS ZIP-prefix assignments, including territories (PR, VI, GU).

If no mapping matches, it logs ⚠️ Unable to derive state from ZIP code and stores a null state rather than guessing.

Why this matters

Zone calculations only need ZIP codes, so a shipment can get a valid zone while its customer's state is blank. Without derivation those customers show up as "Unknown" on the zone-analysis dashboard. Deriving the state keeps the reporting clean. The same helper powers the customer-state backfill.

On this page