Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.launchmystore.io/llms.txt

Use this file to discover all available pages before exploring further.

Pickup Point Options

pickup_point_options functions return a list of carrier-operated parcel lockers and partner pickup points (DHL Packstation, UPS Access Point, InPost Paczkomat, La Poste Pickup, etc.) that the customer can choose as a delivery destination. Use it when:
  • You integrate with a carrier API that exposes nearby drop-off lockers.
  • You want to offer cheaper “last mile” parcel delivery without home signature.
  • Some markets (PL, FR, DE, NL) where parcel-locker delivery is the norm.
For your own retail locations / warehouses use local_pickup_options instead.
Manifest is honored; runtime dispatch is reserved. You may declare pickup_point_options in your app.json and ship a .wasm today — LaunchMyStore stores it, lints it, and surfaces it in the developer portal. Wiring into the React checkout shipping step lands in the delivery-options release; until then, returned options are not yet shown to customers. Build now for forward-compat — your function will start firing once the consumer is enabled.

Manifest

{
  "type": "pickup_point_options",
  "handle": "dhl-packstation",
  "title": "DHL Packstation",
  "entrypoint": "dist/pickup-points.wasm",
  "network_access": true,
  "allowed_hosts": ["api.dhl.com"],
  "inputFields": {
    "shippingAddress": ["countryCode", "city", "postalCode", "latitude", "longitude"]
  }
}
Per-shop cap: 5 active pickup_point_options apps. WASM execution timeout: 2000ms (configurable via WASM_TIMEOUT_PICKUP_POINT_OPTIONS). The default is higher than local_pickup_options because these functions typically call out to a carrier API — see Network access.

Input

interface PickupPointOptionsFunctionInput {
  cart: {
    id?: string;
    lines: Array<{
      id: string;
      quantity: number;
      merchandise: {
        id: string;
        productId: string;
        sku?: string;
        weight?: number;
        attributes?: Record<string, string>;
      };
      cost: { subtotal: { amount: string; currencyCode: string } };
    }>;
    cost: {
      subtotal: { amount: string; currencyCode: string };
      total: { amount: string; currencyCode: string };
    };
  };
  shippingAddress?: {
    address1?: string;
    city?: string;
    province?: string;
    countryCode?: string;
    postalCode?: string;
    latitude?: number;
    longitude?: number;
  };
  currency: string; // ISO-4217 of the cart presentment currency
}

Output

interface PickupPointOptionsFunctionOutput {
  pickupOptions: Array<{
    id: string;             // carrier point id, e.g. "DHL_PACKSTATION_104"
    title: string;          // shown in checkout, e.g. "Packstation 104 - Berlin"
    address: {
      address1?: string;
      address2?: string;
      city?: string;
      province?: string;
      countryCode?: string;
      postalCode?: string;
      latitude?: number;
      longitude?: number;
    };
    hours?: string;         // free-text, e.g. "24/7"
    distance?: number;      // straight-line km from shippingAddress
    fee?: number;           // surcharge in cart currency (default 0)
  }>;
}
Return pickupOptions: [] if the carrier returned no points in range — the customer will fall back to regular shipping zones.

Example — DHL Packstation lookup

export default async function main(input) {
  const ship = input.shippingAddress;
  if (!ship?.postalCode || ship.countryCode !== 'DE') {
    return { pickupOptions: [] };
  }

  const res = await fetch(
    `https://api.dhl.com/location-finder/v1/find-by-address?countryCode=DE&postalCode=${encodeURIComponent(ship.postalCode)}&limit=5`,
    { headers: { 'DHL-API-Key': '<your-key>' } },
  );

  if (!res.ok) return { pickupOptions: [] };
  const data = await res.json();

  const pickupOptions = (data.locations ?? []).map((loc) => ({
    id: `DHL_${loc.locationType}_${loc.id}`,
    title: loc.name,
    address: {
      address1: loc.address.streetAddress,
      city: loc.address.addressLocality,
      countryCode: 'DE',
      postalCode: loc.address.postalCode,
      latitude: loc.geo?.latitude,
      longitude: loc.geo?.longitude,
    },
    hours: loc.openingHours ?? '24/7',
    distance: loc.distance,
    fee: 0,
  }));

  return { pickupOptions };
}

Caching carrier lookups

Carrier point APIs are usually slow (300-800ms) and rate-limited. Two strategies:
  • Cache inside your app server — proxy the carrier through your own HTTPS endpoint and cache aggressively keyed by countryCode+postalCode. Then allowed_hosts: ["<your-domain>"] in the manifest.
  • Trim the input with inputFields so the same input → same output, letting LaunchMyStore’s per-cart output cache do the work.
Both reduce WASM runtime and stay under the 2000ms timeout.

Persistence

Selected pickup point is stored on the order at additionalFields.pickupPointOption:
{
  "pickupPointOption": {
    "appHandle": "my-dhl-app",
    "functionHandle": "dhl-packstation",
    "id": "DHL_PACKSTATION_104",
    "title": "Packstation 104 - Berlin",
    "address": { "address1": "...", "city": "Berlin", "postalCode": "10115", "countryCode": "DE" },
    "fee": 0
  }
}
The carrier point address replaces the customer’s shipping address on the carrier label so the parcel is delivered there. The customer’s contact address is preserved for receipts and notifications.

See also