Welcome to the Jose Madrid Salsa developer docs — explore features, APIs, and deployment guides.
Jose Madrid SalsaJMS Docs

Shipping Configuration

Configure shipping rates, carriers, and the warehouse origin address

Shipping Configuration

The shipping system in Jose Madrid Salsa uses a multi-tier strategy: real carrier API rates with fallback to estimate-based rates, ensuring checkout is never blocked.

How Shipping Calculation Works

The calculateShipping function in lib/shipping-calculator.ts follows this strategy:

Resolve the Warehouse Origin

Every quote needs an origin. getShippingOrigin() reads the admin setting first, then the SHIPPING_ORIGIN_* environment variables, and returns nothing rather than a placeholder when the address is incomplete — an unresolved origin falls back to flat-rate estimates instead of pricing from a made-up address.

const origin = await getShippingOrigin()

if (!origin.ok) {
  console.error(describeMissingOrigin(origin.missing))
  return calculateEstimateRates(input, true)
}

Call Carrier API

For domestic orders under the threshold, the system calls the carrier API with calculated parcel dimensions:

const parcel = calculateParcelDimensions(items)
const shipmentRequest: ShipmentRequest = {
  fromAddress: DEFAULT_ORIGIN_ADDRESS,
  toAddress: { ... },
  parcel,
}
const ratesResponse = await getShippingRates(shipmentRequest)

Filter and Sort Rates

Rates are filtered based on address type (PO Box addresses only get USPS options) and sorted by cost:

if (isPoBox) {
  filteredRates = ratesResponse.rates.filter((rate) =>
    rate.carrier.toUpperCase().includes('USPS')
  )
}
const sortedRates = [...filteredRates].sort((a, b) => a.rate - b.rate)

Fallback to Estimates

If the API fails or returns no rates, the system falls back to estimate-based rates to never block checkout:

catch (error) {
  console.error('[Shipping Calculator] Error:', error)
  return calculateEstimateRates(input, true)
}

Shipping Rate Configuration

Rates come from the ShippingSettings singleton where a store has set them, and fall back field-by-field to the built-in defaults in lib/shipping/rate-config.ts:

export const DEFAULT_RATE_CONFIG: ShippingRateConfig = {
  flatRateCents: 699,
  weightSurchargeBaseCents: 499,
  weightSurchargePerLbCents: 50,
  weightSurchargeThresholdLb: 5,
  internationalRateCents: 2499,
  stateSurcharges: { AK: 1.5, HI: 1.5, PR: 2.0 },
}

These are carriage only. A flat $4.00 packaging-and-materials fee (lib/shipping/handling-fee.ts) is added once per order to every customer-facing quote — live carrier rates included — so what the customer actually sees is:

MethodCarriageCustomer pays
Standard domestic$6.99$10.99
International$24.99$28.99

The fee is not scaled by the state surcharge or the weight surcharge, which price carriage rather than packaging. The admin label routes call getShippingRates directly and do not include it — buying postage is a cost, not a quote.

Origin Address Configuration

Set the shipping origin via environment variables:

SHIPPING_ORIGIN_ADDRESS="123 Main St"
SHIPPING_ORIGIN_CITY="San Francisco"
SHIPPING_ORIGIN_STATE="CA"
SHIPPING_ORIGIN_ZIP="94111"
SHIPPING_API_KEY="..."  # Carrier API key

PO Box Detection

The system automatically detects PO Box addresses and restricts shipping options to USPS-only:

function isPOBox(address: string | undefined): boolean {
  const patterns = [
    /\bP\s*O\s+BOX\b/,
    /\bPOST\s+OFFICE\s+BOX\b/,
    /^\s*BOX\s+\d+/,
  ]
  return patterns.some(p => p.test(address.toUpperCase()))
}

Address Validation

Use the built-in validation before submitting shipping requests:

import { validateShippingAddress } from '@/lib/shipping-calculator'

const result = validateShippingAddress({
  address1: '123 Main St',
  city: 'San Francisco',
  state: 'CA',
  postalCode: '94111',
  country: 'US',
})

if (!result.valid) {
  console.error(result.errors)
  // ["State must be a 2-letter code (e.g., CA, NY)"]
}

Frontend Shipping Estimates

For real-time shipping previews, use the lightweight estimate function:

import { getShippingEstimate } from '@/lib/shipping-calculator'

const estimate = await getShippingEstimate({
  subtotal: 35.00,
  state: 'CA',
  country: 'US',
})
// Returns: 10.99 — the $6.99 carriage plus the $4.00 packaging fee.
// Shipping is charged on every order, and the preview matches what checkout will charge.

Parcel Dimensions

The system calculates parcel dimensions from order items:

  • Weight: Sum of all item weights (defaults to 1 lb per item), converted to ounces
  • Length/Width: Maximum dimensions across items
  • Height: Sum of heights, capped at 24 inches

Weight Defaults

If a product has no weight set in the database, the calculator defaults to 1 pound per item. Set accurate weights in the product editor for better rate accuracy.

Key Files

shipping-calculator.ts
shipping-api.ts
shipping-carriers.ts

How is this guide?

Edit on GitHub

Last updated on

On this page