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.

Delivery Customization Functions

Delivery customization functions let your app modify how shipping/delivery options appear during checkout. Use them to rename options for clarity, hide unavailable methods, or reorder them by preference.

How It Works

Function Manifest

{
  "handle": "my-delivery-app",
  "name": "Delivery Customizer",
  "version": "1.0.0",
  "functions": {
    "delivery_customization": {
      "handle": "delivery-rules",
      "name": "Delivery Display Rules",
      "config": {
        "renameStandard": "Economy Shipping",
        "hideExpressWeekends": true
      }
    }
  }
}

Input Schema

interface DeliveryCustomizationInput {
  cart: {
    items: CartItem[];
    subtotal: number;
    total: number;
    totalWeight: number;
    currency: string;
  };
  deliveryOptions: DeliveryOption[];
  shippingAddress: Address;
  customer: Customer | null;
  shop: Shop;
}

interface DeliveryOption {
  id: string;
  name: string;
  price: number;
  code: string;
  carrierIdentifier: string;
  deliveryRange: {
    min: number;
    max: number;
  } | null;
  source: 'store' | 'app';  // Store-configured or app-provided
}

Output Schema

interface DeliveryCustomizationOutput {
  operations: DeliveryOperation[];
}

type DeliveryOperation = 
  | { hide: { deliveryOptionId: string } }
  | { rename: { deliveryOptionId: string; name: string } }
  | { reorder: { deliveryOptionId: string; position: number } };

Operations

Rename Delivery Options

Change how shipping options are displayed:
{
  operations: [
    {
      rename: {
        deliveryOptionId: 'standard',
        name: 'Economy Shipping (5-7 days)'
      }
    },
    {
      rename: {
        deliveryOptionId: 'express',
        name: 'Priority Express (2-3 days)'
      }
    }
  ]
}

Hide Delivery Options

Remove options that shouldn’t be shown:
{
  operations: [
    { hide: { deliveryOptionId: 'overnight' } },
    { hide: { deliveryOptionId: 'same_day' } }
  ]
}

Reorder Delivery Options

Change the display order:
{
  operations: [
    { reorder: { deliveryOptionId: 'free_shipping', position: 0 } },
    { reorder: { deliveryOptionId: 'express', position: 1 } },
    { reorder: { deliveryOptionId: 'standard', position: 2 } }
  ]
}

Example Implementations

Add Delivery Dates to Names

function customizeDelivery(input, config) {
  const operations = [];
  
  // Calculate delivery dates based on delivery range
  const today = new Date();
  
  for (const option of input.deliveryOptions) {
    if (option.deliveryRange) {
      const minDate = addBusinessDays(today, option.deliveryRange.min);
      const maxDate = addBusinessDays(today, option.deliveryRange.max);
      
      const dateRange = formatDateRange(minDate, maxDate);
      
      operations.push({
        rename: {
          deliveryOptionId: option.id,
          name: `${option.name} - Arrives ${dateRange}`
        }
      });
    }
  }
  
  return { operations };
}

function formatDateRange(min, max) {
  const options = { month: 'short', day: 'numeric' };
  if (min.getTime() === max.getTime()) {
    return min.toLocaleDateString('en-US', options);
  }
  return `${min.toLocaleDateString('en-US', options)} - ${max.toLocaleDateString('en-US', options)}`;
}

Hide Express on Weekends

function customizeDelivery(input, config) {
  const operations = [];
  
  const today = new Date();
  const dayOfWeek = today.getDay();
  const isWeekend = dayOfWeek === 0 || dayOfWeek === 6;
  
  if (isWeekend && config.hideExpressWeekends) {
    // Hide express options that can't be fulfilled on weekends
    const expressOptions = input.deliveryOptions.filter(
      opt => opt.code.includes('express') || opt.code.includes('overnight')
    );
    
    for (const option of expressOptions) {
      operations.push({
        hide: { deliveryOptionId: option.id }
      });
    }
  }
  
  return { operations };
}

Location-Based Customization

function customizeDelivery(input, config) {
  const operations = [];
  const { shippingAddress, deliveryOptions } = input;
  
  // Rural areas: Hide same-day delivery
  const ruralZipPrefixes = ['123', '456', '789']; // Example prefixes
  const isRural = ruralZipPrefixes.some(
    prefix => shippingAddress.zip.startsWith(prefix)
  );
  
  if (isRural) {
    const sameDayOption = deliveryOptions.find(
      opt => opt.code === 'same_day'
    );
    if (sameDayOption) {
      operations.push({
        hide: { deliveryOptionId: sameDayOption.id }
      });
    }
    
    // Add note to express shipping
    const expressOption = deliveryOptions.find(
      opt => opt.code === 'express'
    );
    if (expressOption) {
      operations.push({
        rename: {
          deliveryOptionId: expressOption.id,
          name: `${expressOption.name} (Rural area - add 1-2 days)`
        }
      });
    }
  }
  
  // Alaska/Hawaii: Different messaging
  if (['AK', 'HI'].includes(shippingAddress.provinceCode)) {
    for (const option of deliveryOptions) {
      operations.push({
        rename: {
          deliveryOptionId: option.id,
          name: `${option.name} (Extended delivery to ${shippingAddress.provinceCode})`
        }
      });
    }
  }
  
  return { operations };
}

Product-Based Rules

function customizeDelivery(input, config) {
  const operations = [];
  const { cart, deliveryOptions } = input;
  
  // Check cart contents
  const hasFragile = cart.items.some(
    item => item.tags.includes('fragile')
  );
  
  const hasHazmat = cart.items.some(
    item => item.tags.includes('hazmat')
  );
  
  const hasOversized = cart.items.some(
    item => item.properties?.oversized === 'true'
  );
  
  // Fragile items: Hide economy shipping
  if (hasFragile) {
    const economyOptions = deliveryOptions.filter(
      opt => opt.code.includes('economy') || opt.code.includes('ground')
    );
    for (const option of economyOptions) {
      operations.push({
        hide: { deliveryOptionId: option.id }
      });
    }
  }
  
  // Hazmat items: Only ground shipping
  if (hasHazmat) {
    for (const option of deliveryOptions) {
      if (option.code.includes('air') || option.code.includes('express')) {
        operations.push({
          hide: { deliveryOptionId: option.id }
        });
      } else {
        operations.push({
          rename: {
            deliveryOptionId: option.id,
            name: `${option.name} (Ground shipping required for hazmat)`
          }
        });
      }
    }
  }
  
  // Oversized items: Add surcharge note
  if (hasOversized) {
    for (const option of deliveryOptions) {
      operations.push({
        rename: {
          deliveryOptionId: option.id,
          name: `${option.name} (Includes oversized item handling)`
        }
      });
    }
  }
  
  return { operations };
}

Carrier-Specific Branding

function customizeDelivery(input, config) {
  const operations = [];
  
  const carrierBranding = {
    'ups': 'UPS',
    'fedex': 'FedEx',
    'usps': 'USPS',
    'dhl': 'DHL Express'
  };
  
  const serviceNames = {
    'ups_ground': 'UPS Ground',
    'ups_2day': 'UPS 2nd Day Air',
    'ups_overnight': 'UPS Next Day Air',
    'fedex_ground': 'FedEx Ground',
    'fedex_express': 'FedEx Express Saver',
    'fedex_overnight': 'FedEx Priority Overnight',
    'usps_priority': 'USPS Priority Mail',
    'usps_express': 'USPS Priority Mail Express'
  };
  
  for (const option of input.deliveryOptions) {
    const brandedName = serviceNames[option.code];
    if (brandedName) {
      operations.push({
        rename: {
          deliveryOptionId: option.id,
          name: brandedName
        }
      });
    }
  }
  
  // Prioritize certain carriers
  const preferredOrder = ['fedex', 'ups', 'usps', 'dhl'];
  let position = 0;
  
  for (const carrier of preferredOrder) {
    const carrierOptions = input.deliveryOptions.filter(
      opt => opt.carrierIdentifier?.toLowerCase() === carrier
    );
    for (const option of carrierOptions) {
      operations.push({
        reorder: { deliveryOptionId: option.id, position: position++ }
      });
    }
  }
  
  return { operations };
}

Free Shipping Promotions

function customizeDelivery(input, config) {
  const operations = [];
  const { cart, deliveryOptions } = input;
  
  const freeShippingThreshold = config.freeShippingThreshold || 5000;
  const amountToFree = freeShippingThreshold - cart.subtotal;
  
  // Find free/cheapest shipping option
  const sortedOptions = [...deliveryOptions].sort((a, b) => a.price - b.price);
  const cheapestOption = sortedOptions[0];
  
  if (amountToFree > 0 && cheapestOption?.price > 0) {
    // Show how much more for free shipping
    operations.push({
      rename: {
        deliveryOptionId: cheapestOption.id,
        name: `${cheapestOption.name} - Add $${(amountToFree / 100).toFixed(2)} more for FREE shipping!`
      }
    });
    
    // Move it to the top
    operations.push({
      reorder: { deliveryOptionId: cheapestOption.id, position: 0 }
    });
  } else if (cheapestOption?.price === 0) {
    // Highlight the free option
    operations.push({
      rename: {
        deliveryOptionId: cheapestOption.id,
        name: 'FREE Shipping - You qualified!'
      }
    });
    operations.push({
      reorder: { deliveryOptionId: cheapestOption.id, position: 0 }
    });
  }
  
  return { operations };
}

Checkout Display

After your function runs:
Shipping Method
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

○ FREE Shipping - You qualified!           ← Renamed + reordered
  5-7 business days
  
○ FedEx Express Saver - Arrives Jan 15-17 ← Renamed with date
  $12.99
  
○ FedEx Priority Overnight - Arrives Jan 13 ← Renamed with date
  $24.99
                                           
                                           ← Same Day hidden

Error Handling

function customizeDelivery(input, config) {
  try {
    const operations = [];
    
    // Your customization logic
    
    return { operations };
  } catch (error) {
    // Return empty operations on error
    console.error('Delivery customization error:', error);
    return { operations: [] };
  }
}
Never hide all delivery options. Ensure at least one option remains visible, or checkout will be blocked.

Testing

{
  "cart": {
    "items": [{ "title": "Product", "price": 2999 }],
    "subtotal": 2999
  },
  "deliveryOptions": [
    { "id": "standard", "name": "Standard", "price": 599, "code": "standard" },
    { "id": "express", "name": "Express", "price": 1299, "code": "express" },
    { "id": "overnight", "name": "Overnight", "price": 2499, "code": "overnight" }
  ],
  "shippingAddress": {
    "provinceCode": "CA",
    "countryCode": "US"
  }
}

Best Practices

Don’t make delivery option names too long. Keep essential info visible.
Customers care most about when their order arrives. Include dates when possible.
If free shipping is available, make it prominent with naming and positioning.
If you hide options, consider renaming visible ones to explain why (e.g., “Ground only for hazmat”).
If you have weekend/holiday rules, test them thoroughly across time zones.

See Also