Shipping integration

Labels, tracking, and carrier APIs for seamless delivery

Overview

Current state

Sellers handle shipping independently, no tracking in-app.

Target state

  • In-app shipping label generation
  • Real-time tracking updates
  • Multiple carrier support
  • Shipping cost calculator

Tech stack

  • Carriers: Correios, Jadlog, Loggi (Brazil)
  • Aggregator: Melhor Envio or Frenet API
  • Tracking: Webhooks + polling
  • Labels: PDF generation

Features

For sellers

  • Generate shipping labels in-app
  • Compare carrier rates
  • Schedule pickups
  • Print labels at home or drop-off

For buyers

  • Real-time tracking updates
  • Delivery estimates
  • Push notifications on status changes
  • Proof of delivery

For platform

  • Shipping cost at checkout
  • Delivery time estimates
  • Lost package claims
  • Analytics on delivery times

Architecture

Rate calculation

packages/features/shipping/rates.ts
async function getShippingRates(params: {
  fromCep: string;
  toCep: string;
  weight: number;
  dimensions: { width: number; height: number; length: number };
}) {
  const response = await melhorEnvio.post('/shipment/calculate', {
    from: { postal_code: params.fromCep },
    to: { postal_code: params.toCep },
    package: {
      weight: params.weight,
      width: params.dimensions.width,
      height: params.dimensions.height,
      length: params.dimensions.length,
    },
  });

  return response.data.map(rate => ({
    carrier: rate.company.name,
    service: rate.name,
    price: rate.price,
    deliveryDays: rate.delivery_time,
  }));
}

Label generation

packages/features/shipping/labels.ts
async function createShippingLabel(order: Order, carrier: string) {
  const shipment = await melhorEnvio.post('/shipment/generate', {
    service: carrier,
    from: order.seller.address,
    to: order.buyer.address,
    package: order.packageInfo,
    invoice: {
      key: order.invoiceKey, // Nota fiscal
    },
  });

  await db.update(orders)
    .set({
      trackingCode: shipment.tracking,
      labelUrl: shipment.label_url,
    })
    .where(eq(orders.id, order.id));

  return shipment;
}

Tracking updates

apps/api/app/api/webhooks/tracking/route.ts
async function handleTrackingWebhook(payload: TrackingEvent) {
  const order = await getOrderByTracking(payload.tracking_code);

  await db.insert(trackingEvents).values({
    orderId: order.id,
    status: payload.status,
    description: payload.description,
    location: payload.location,
    timestamp: payload.timestamp,
  });

  // Notify buyer
  await sendPushNotification(order.buyerId, {
    title: 'Shipping Update',
    body: payload.description,
  });

  // Update order status
  if (payload.status === 'delivered') {
    await db.update(orders)
      .set({ status: 'delivered', deliveredAt: new Date() })
      .where(eq(orders.id, order.id));
  }
}

Implementation

Rate calculator

Integrate Melhor Envio API, add shipping calculator on item page, and CEP validation.

Label generation

Build seller shipping flow with label generation, download, and pickup scheduling.

Tracking

Create tracking page for orders, webhook integration, and push notifications.

Advanced features

Add insurance options, return labels, and lost package claims.

Checklist

Infrastructure

  • Melhor Envio account and API keys
  • Webhook endpoint for tracking
  • Tracking events table

Seller flow

  • Shipping label generation UI
  • Carrier selection
  • Label download/print
  • Pickup scheduling

Buyer flow

  • Shipping cost at checkout
  • Tracking page
  • Status notifications
  • Delivery confirmation

Admin

  • Shipping analytics
  • Dispute handling
  • Lost package claims