Documentation You are here: start » v » 2.0 » shipping » custom_code

Custom Shipping Code

The Custom Shipping Code option supports adding javascript code to your store's shipping section that is able to add new rates, or modifiy or remove existing rates that have been returned from other configured shipping rates for your store.

The Custom Shipping Code is processed after any other carriers that have been configured have run, including the Custom Shipping Endpoint. This means that those rates can also be modified as part of your custom code.

This custom code runs serverside, not client-side. Yes, it's javascript, but this javascript doesn't output to the browser. Instead, it's run serverside in Node.js (in a separate environment per store), so you can put private logic (such as coupon codes) in the code.

Enabling Custom Shipping Code

To enable Custom Shipping Code for your store, login to your store's Foxy administration and head to the “shipping” section. You'll find the option to “use custom code” as the last option on the page.

The Custom Shipping Code functionality behaves just like a normal carrier like USPS, FedEx or UPS, so requires that any categories that you'd like to have the shipping calculated with your custom code to have a delivery type of “Shipped using live shipping rates”.

Enabling the “use custom code” option will reveal a code editor where you can enter your custom JavaScript shipping code. Within this code editor, you'll also have access to a couple of objects:

  • rates: The rates object for the cart, which will be prepopulated with any rates returned from other options enabled for the store
  • cart: An object containing all of the information about the customers cart. For an overview of what this object looks like, see this page.

Within the code editor, you can enter and javascript logic you require for calculating your custom shipping rates. As you enter your shipping code, the code editor will provide in-context feedback for any issues it may detect. Hover over any icons or highlighted code for additional details.

We also have helper functions available for your custom code for working with custom rates. You can review the documentation on the Shipping API functions you can use in your logic here. We also have some examples further down this page.

We recommend enabling the “enable shipping rate signing” option on the shipping page settings as well. If you have any javascript snippets in your store's configuration outside of the custom code entered on the shipping page that affects the returned shipping rates, or the weight used to calculate the shipping rate, you will want to leave this unchecked however.

Once you have your shipping code entered as desired, click the green “Update” button at the bottom of the page. You will see a message that the shipping code is being deployed, and to refresh the page to get an updated status. Wait for 15-20 seconds and refresh the page - if you see your shipping code displayed again, then your code was successfully deployed!

Migrating from existing snippets

If you are migrating from one of our existing snippets, you can review notes on switching from the snippets to using custom shipping code here.

Auto-Select First Rate

If you'd like your cart to automatically select the first rate shown, you can use the snippet outlined here.

Example Shipping Code

The following are a selection of examples of shipping code to give you an idea of how it can be utilised for your store. For details on the functions available within the custom code, you can review the Shipping API here.

Adding a fallback shipping rate

This example simply checks to see if there were any rates returned from third-party carriers like USPS, UPS and FedEx, and if not, returns a fallback $15 rate to ensure your customers will always see a rate.

if (!rates.exists()) {
	rates.add(10001, 15, '', 'Standard Shipping');
}

Flat rates with conditional free shipping

Provide a standard and express flat rate shipping option, setting the standard option to be free if at least $40 of products are present in the cart.

rates.add(10001, 5, 'FoxyPost', 'Standard');
rates.add(10002, 15, 'FoxyPost', 'Express');
if (cart['_embedded']['fx:shipment']['total_item_price'] >= 40) {
	rates.filter(10001).price(0).service('Free Shipping');
}

Remove the "1-Day" and "2-Day" text from USPS rates

In some instances, USPS adds an estimated timeframe to their returned rates. While they may be valid for the estimated delivery time when shipped - it can create unrealistic expectations for customers if it may take a couple days to ship. This example removes those timeframe strings from any returned rates.

rates.removeDayTimeframes();

Providing flat rates based on the shipping country

The following example provides three tiers of shipping rates, one if the customer is within the UK (considered domestic in this example), another if the customer is within Europe, and another rate for anywhere else in the world.

const tier1 = ['GB'];
const tier2 = ['AL', 'AD', 'AM', 'AT', 'BY', 'BE', 'BA', 'BG', 'CH', 'CY', 'CZ', 'DE', 'DK', 'EE', 'ES', 'FO', 'FI', 'FR', 'GE', 'GI', 'GR', 'HU', 'HR', 'IE', 'IS', 'IT', 'LT', 'LU', 'LV', 'MC', 'MK', 'MT', 'NO', 'NL', 'PL', 'PT', 'RO', 'RU', 'SE', 'SI', 'SK', 'SM', 'TR', 'UA', 'VA'];
const country = cart['_embedded']['fx:shipment']['country'];
 
if (tier1.indexOf(country) > -1) {
  // United Kingdom
  rates.add(10001, 10, 'FoxyPost', 'Standard');
} else if (tier2.indexOf(country) > -1) {
  // Europe
  rates.add(10002, 20, 'FoxyPost', 'International');
} else {
  // Rest of world
  rates.add(10003, 30, 'FoxyPost', 'International');
}

Hiding specific shipping rates depending on the shipping state

This option hides rates any express options if the shipping state is outside of the contiguous US

const contiguous = ['AL', 'AZ', 'AR', 'CA', 'CO', 'CT', 'DE', 'FL', 'GA', 'ID', 'IL', 'IN', 'IA', 'KS', 'KY', 'LA', 'ME', 'MD', 'MA', 'MI', 'MN', 'MS', 'MO', 'MT', 'NE', 'NV', 'NH', 'NJ', 'NM', 'NY', 'NC', 'ND', 'OH', 'OK', 'OR', 'PA', 'RI', 'SC', 'SD', 'TN', 'TX', 'UT', 'VT', 'VA', 'WA', 'WV', 'WI', 'WY', 'DC'];
const country = cart['_embedded']['fx:shipment']['country'];
const region = cart['_embedded']['fx:shipment']['region'];
 
if (country == "US" && contiguous.indexOf(region) == -1) {
	rates.filter('express').hide();
}

Adjust rates based on weight and item count

Provides three flat rates, increasing the costs if the weight exceeds 10, and removes the express option if there are more than 5 products.

rates.add(10001, 5, 'FoxyPost', 'Standard');
rates.add(10002, 9.45, 'FoxyPost', 'Priority');
rates.add(10003, 10, 'FoxyPost', 'Express (Next Day)');
 
if (cart['_embedded']['fx:shipment']['total_weight'] > 10) {
  rates.filter(10001).price(6);
  rates.filter(10002).price(10);
  rates.filter(10003).price(11.99);
}
 
if (cart['_embedded']['fx:shipment']['item_count'] > 5) {
  rates.filter(10003).hide();
}

Free shipping based on a coupon

If a specific coupon code (or a code that ends in a specific suffix) is present on the transaction, the following example hides all of the returned rates and instead adds a custom free shipping rate. NOTE that you may want additional logic here, as you may only want to allow free shipping for the contiguous US states, or only within your country, or excluding specific products.

This example would allow free shipping if a coupon with a code of freeshipping was present, or one that had a suffix of -fs, like mycode-fs or h3Sif4yg-fs

for (let d in cart['_embedded']['fx:discounts']) {
  let code = cart['_embedded']['fx:discounts'][d]['code'];
  if (
    code == "freeshipping" // example of a specific code
    || code.match(/-fs$/) // example of a code suffix
  ) {
    rates.hide();
    rates.add(10001, 0, '', 'Free Shipping');
  }
}

Restricting available rates based on product categories

If the customer has ordered products from the 'food' category, this example will only show overnight delivery options. If the customer has ordered 3 or more food items, update the priority overnight option to be free.

let food = 0;
for (let p in cart['_embedded']['fx:items']) {
  let item = cart['_embedded']['fx:items'][p];
  switch (item['_embedded']['fx:item_category']['code']) {
    case "food":
      food += item['quantity'];
      break;
  }
}
 
if (food > 0) {
  // Hide all shipping options, but show overnight rates
  rates.hide().filter("overnight").show();
 
  // If 3 or more food items, update priority overnight to be free
  if (food >= 3) rates.filter('priority overnight').price(0);
}

Restricting to a single carrier for a specific country

This example, will only provide FedEx rates to Canada, but allow any other configured live rate carriers for any other countries

if (cart['_embedded']['fx:shipment']['country'] == "CA") {
	rates.hide().filter("fedex").show();
}

Calculating shipping fees from custom product options

This approach allows for shipping fees to be set per product via a custom product option called shipping. It relies on your product add to carts including an attribute like &shipping=12.5.

If there are shipping rates already present (from the native live carrier integrations or the custom shipping endpoint), then the product level shipping fees are added onto the existing rates, otherwise it creates a new rate with a label of “Standard Shipping”.

let product_shipping = 0;
for (let p in cart['_embedded']['fx:items']) {
    let item = cart['_embedded']['fx:items'][p];
    for (let o in item['_embedded']['fx:item_options']) {
        let item_option = item['_embedded']['fx:item_options'][o];
        if (item_option['name'] == "shipping" && !isNaN(parseFloat(item_option['value']))) {
            product_shipping += parseFloat(item_option['value']);
        }
    }
}
 
if (product_shipping > 0) {
    if (rates.exists()) {
        rates.price("+" + product_shipping);
    } else {
        rates.add(10000, product_shipping, '', 'Standard Shipping');
    }
}

Increase rates by a percentage

This example filters rates on USPS and adds a 15% increase to all USPS prices.

rates.filter('USPS').price('+15%');

Site Tools