AstroBaaS

Orders & fulfilment

Shipping Labels & Carrier Sync

Paid pluginsize Lplanned, not built

Indicative price, not an offer: $19-49/mo per carrier tier; anchor: Easyship $15 entry

Generated from docs/plan/paid/shipping-labels-carrier-sync/PLAN.md in the AstroBaaS repository. Nothing described below is implemented — it is the written plan for it.

Merged from duplicate proposals: “Shipping Labels & Carrier Sync”

Manual label printing is slow and error-prone. This paid module generates shipping labels automatically via carrier APIs (FedEx, UPS, DHL, USPS) and syncs carrier tracking updates.

The problem

I spend 30 minutes daily printing shipping labels, adding tracking numbers manually, and correcting carrier data entry errors. I need automatic label generation and carrier sync to save time and reduce mistakes.

What it does

  • Integrate with carrier APIs: FedEx, UPS, DHL, USPS (pluggable carrier adapters for extensibility)
  • Store carrier API credentials (encrypted) in settings or per-merchant vault (not in CLAUDE.md)
  • On shipment creation, automatically request shipping label from selected carrier
  • Store label_url and tracking_number in shipments collection
  • Generate label PDF or thermal printer format; download or print directly from order detail
  • Sync carrier tracking status: webhook listener receives carrier webhooks (shipped, in_transit, delivered, exception)
  • Auto-update shipments.status based on carrier webhook (pending → shipped → in_transit → delivered)
  • Show tracking link in order detail (customer-facing storefront + admin)
  • Fallback: if carrier API fails, allow manual label entry (tracking number only, no auto-sync)

What it deliberately does NOT do

Each boundary carries its reason. A boundary without a reason gets crossed by the next person who reads this.

  • Negotiated carrier rates (e.g., FedEx account pricing) — that requires carrier contracts and complexity; core only uses list rates
  • Multi-carrier rate shopping at checkout (Easyship, 17TRACK integrations) — that is separate rate-shopping feature
  • International duty/customs forms — that requires per-country rules; defer to country-specific paid module

Data model

carrier_credentials collection: {id, carrier_name, credentials (encrypted), merchant_id, is_active}. shipments.label_url, tracking_number, tracking_url, carrier_status (from carrier API), carrier_status_updated_at. No migration if columns are additive.

API

  • POST /api/admin/shipments/:shipmentId/generate-label — request label from carrier
  • GET /api/admin/shipments/:shipmentId/label — download label PDF
  • POST /api/webhooks/carrier/:carrier/tracking — carrier webhook endpoint (FedEx, UPS, etc.)
  • POST /api/admin/carrier-credentials — add/update carrier API credentials (admin only)

Every route added here must also appear in src/pages/openapi.json.ts — a test fails the build if it does not.

Admin

Shipment creation modal adds ‘Carrier’ dropdown (FedEx, UPS, DHL, USPS). Select carrier and address, click ‘Generate Label’. Label downloads or shows preview. Shipment shows: tracking number (clickable link to carrier tracking), label PDF link, carrier status (In Transit, Delivered, etc.), carrier status last updated timestamp.

The seam — why this is paid

Paid module owns carrier integrations, API credential handling, webhook listeners, and auto-sync logic. Core (shipment-management-tracking) owns shipment entity and status state machine. Merchant must pay to integrate carriers; core provides the foundation.

Paid module owns carrier API credentials (FedEx, UPS, DHL, etc.), label rendering, and rate calculation; core owns order-to-shipment state only

Dependencies

  • shipment-management-tracking (core feature)
  • email layer (optional, to notify customer of tracking)
  • webhook system (to receive carrier status updates)

Acceptance checks

Each of these must be able to fail. Before claiming this is done, break the code deliberately and watch each one go red.

  • Add FedEx credentials and create shipment; confirm API is called and label_url + tracking_number are stored
  • Verify label PDF is downloadable or printable
  • Simulate carrier webhook: send ‘shipped’ status; confirm shipments.status updates to ‘shipped’ within 1 minute
  • Verify tracking link in order detail directs to carrier tracking page
  • Remove carrier credentials and create shipment; confirm error is shown and fallback to manual entry is available

Risks

Storing carrier API credentials requires encryption and PCI-DSS compliance. Use merchant’s own credentials (not shared pool) so merchant owns the relationship. Carrier webhook delays (24-48 hours for some carriers) mean tracking data may be stale. Carrier API rate limits can block label generation during peak times; implement queue and retry logic.

Commercial context

Suggested price$19-49/mo per carrier tier; anchor: Easyship $15 entry
Rival anchorEasyship freemium (550+ carriers, label generation $15-99/mo for rate comparison); 17TRACK basic tracking free

The anchor is what the nearest equivalent charges on Shopify or Magento today. It is context for a pricing decision, not the decision.


Generated from the commerce plan. See docs/COMMERCE-PLAN.md for the full catalogue and ../../AI-GUIDE.md for how to work on this repository.