Differences
This shows you the differences between two versions of the page.
Previous revision | |||
— | v:2.0:shipping:custom_code [2024/06/25 10:20] (current) – [Free shipping based on a coupon] adam | ||
---|---|---|---|
Line 1: | Line 1: | ||
+ | ====== Custom Shipping Code ====== | ||
+ | The Custom Shipping Code option supports adding javascript code to 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. | ||
+ | |||
+ | <wrap tip> | ||
+ | |||
+ | ===== Example Payload ===== | ||
+ | The custom shipping code receives the same payload as the custom shipping endpoint. See a [[./ | ||
+ | |||
+ | ===== Category Settings ===== | ||
+ | You'll need to set each [[https:// | ||
+ | ===== Enabling Custom Shipping Code ===== | ||
+ | |||
+ | ==== Enable custom code ==== | ||
+ | |||
+ | To enable Custom Shipping Code for your store, login to your store' | ||
+ | |||
+ | Enabling the "use custom code" option will reveal a code editor where you can enter your custom JavaScript shipping code. | ||
+ | |||
+ | <WRAP center round info 60%> | ||
+ | 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 " | ||
+ | </ | ||
+ | |||
+ | ==== Write your custom shipping code ==== | ||
+ | |||
+ | We have a [[v: | ||
+ | |||
+ | Within the shipping code editor, you will also have access to a couple of objects: | ||
+ | |||
+ | * '' | ||
+ | * '' | ||
+ | |||
+ | The code is processed within a Node.js v14 instance, UTC timezone, with access to the following Node modules: | ||
+ | |||
+ | * [[https:// | ||
+ | * [[https:// | ||
+ | * [[https:// | ||
+ | * [[https:// | ||
+ | |||
+ | Within the code editor, you can enter any 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 (note that there is a known issue with the code validations relating to lines of code containing '' | ||
+ | |||
+ | <WRAP center round tip 90%> | ||
+ | We recommend enabling the " | ||
+ | </ | ||
+ | |||
+ | ==== Deploy your shipping code ==== | ||
+ | |||
+ | Once you have your shipping code entered as desired, click the green " | ||
+ | |||
+ | ===== Migrating from existing snippets ===== | ||
+ | |||
+ | If you are migrating from one of our existing snippets, you can [[v: | ||
+ | |||
+ | ===== Auto-Select First Rate ===== | ||
+ | |||
+ | If you'd like your cart to automatically select the first rate shown, you can use the snippet outlined [[v: | ||
+ | ===== 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 [[v: | ||
+ | |||
+ | <note important> | ||
+ | ==== 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. | ||
+ | |||
+ | <code javascript> | ||
+ | if (!rates.exists()) { | ||
+ | rates.add(10001, | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | ==== 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. | ||
+ | |||
+ | <code javascript> | ||
+ | rates.add(10001, | ||
+ | rates.add(10002, | ||
+ | if (cart[' | ||
+ | rates.filter(10001).price(0).service(' | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | |||
+ | ==== Flat rates based on order total ==== | ||
+ | |||
+ | Different flat rates based on the product subtotal, with a "pick up" option if a threshold isn't met. | ||
+ | |||
+ | <code javascript> | ||
+ | const total_item_price = cart[' | ||
+ | |||
+ | rates.add(10001, | ||
+ | if (total_item_price <= 200) { | ||
+ | // Orders $200 and under can only be picked up. | ||
+ | rates.filter(10001).price(0).service(' | ||
+ | } else if (total_item_price <= 500) { | ||
+ | // Orders from $200.01 to $500 ship for $75 | ||
+ | rates.filter(10001).price(75); | ||
+ | } else if (total_item_price <= 1000) { | ||
+ | rates.filter(10001).price(150); | ||
+ | } else { | ||
+ | // Orders over $1000, from the last if statement | ||
+ | rates.filter(10001).price(300); | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | ==== Remove the " | ||
+ | |||
+ | 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. | ||
+ | |||
+ | <code javascript> | ||
+ | rates.removeDayTimeframes(); | ||
+ | </ | ||
+ | |||
+ | ==== Adding extra text to shipping rate labels === | ||
+ | |||
+ | If you want to modify a returned shipping rate label to have a different service, you can do that using the API like this: | ||
+ | |||
+ | <code javascript> | ||
+ | rates.filter(' | ||
+ | </ | ||
+ | |||
+ | That would change the rate '' | ||
+ | |||
+ | You can also append to the existing service text though, so it will still use whatever the shipping provider returns. For example, the following would use FedEx Home Delivery again, but would append " (Signature Required)" | ||
+ | |||
+ | <code javascript> | ||
+ | let home_delivery = rates.filter(' | ||
+ | if (home_delivery.exists()) { | ||
+ | home_delivery.service(home_delivery.service() + ' (Signature Required)' | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | If you wanted to make a similar adjustment to a lot of different rates, for example adding " (Signature Required)" | ||
+ | |||
+ | <code javascript> | ||
+ | rates.filter(' | ||
+ | this.service(this.service() + ' (Signature Required)' | ||
+ | }); | ||
+ | </ | ||
+ | ==== 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. | ||
+ | |||
+ | <code javascript> | ||
+ | const tier1 = [' | ||
+ | const tier2 = [' | ||
+ | const country = cart[' | ||
+ | |||
+ | if (tier1.indexOf(country) > -1) { | ||
+ | // United Kingdom | ||
+ | rates.add(10001, | ||
+ | } else if (tier2.indexOf(country) > -1) { | ||
+ | // Europe | ||
+ | rates.add(10002, | ||
+ | } else { | ||
+ | // Rest of world | ||
+ | rates.add(10003, | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | ==== Returning a flat rate for international orders ==== | ||
+ | |||
+ | This example is a simple approach for only showing a flat rate option for international orders. | ||
+ | |||
+ | <code javascript> | ||
+ | const country = cart[' | ||
+ | |||
+ | if (country != " | ||
+ | // The customer is shipping outside the US | ||
+ | rates.hide(); | ||
+ | rates.add(10001, | ||
+ | } | ||
+ | </ | ||
+ | ==== Restricting shipping to only a specific set of postcodes ==== | ||
+ | |||
+ | This example can be used to prevent customers from being able to complete the checkout if they don't have a shipping address within a specific set of postcodes. The '' | ||
+ | |||
+ | <code javascript> | ||
+ | const allowed_postcodes = [55115, 55116]; | ||
+ | const postal_code = Number(cart[' | ||
+ | |||
+ | if (allowed_postcodes.includes(postal_code)) { | ||
+ | rates.add(10001, | ||
+ | } else { | ||
+ | rates.error(' | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | ===Example using non-numerical postcodes=== | ||
+ | |||
+ | Since some countries may use postcodes that include alphabetic characters, the example needs to be a little different in that case. Here is an example for postcodes in UK. | ||
+ | |||
+ | <code javascript> | ||
+ | const allowed_postcodes = [' | ||
+ | const postal_code = (cart[' | ||
+ | |||
+ | if (allowed_postcodes.includes(postal_code)) { | ||
+ | rates.add(10001, | ||
+ | } else { | ||
+ | rates.error(' | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | ==== 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 | ||
+ | |||
+ | <code javascript> | ||
+ | const contiguous = [' | ||
+ | const country = cart[' | ||
+ | const region = cart[' | ||
+ | |||
+ | if (country == " | ||
+ | rates.filter(' | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | |||
+ | ==== 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. | ||
+ | |||
+ | <code javascript> | ||
+ | rates.add(10001, | ||
+ | rates.add(10002, | ||
+ | rates.add(10003, | ||
+ | |||
+ | if (cart[' | ||
+ | rates.filter(10001).price(6); | ||
+ | rates.filter(10002).price(10); | ||
+ | rates.filter(10003).price(11.99); | ||
+ | } | ||
+ | |||
+ | if (cart[' | ||
+ | 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, | ||
+ | |||
+ | This example would allow free shipping if a coupon with a code of '' | ||
+ | |||
+ | If you don't want to give a discount for the products and only free shipping, your coupon can be set to all the default settings with a '' | ||
+ | |||
+ | <code javascript> | ||
+ | for (let d in cart[' | ||
+ | let code = cart[' | ||
+ | if ( | ||
+ | code == " | ||
+ | || code.match(/ | ||
+ | ) { | ||
+ | rates.hide(); | ||
+ | rates.add(11000, | ||
+ | } | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | |||
+ | ==== Free shipping over a certain amount ==== | ||
+ | This example provides free shipping if the subtotal for the order (total item price less any coupons) is greater than $50. | ||
+ | |||
+ | <code javascript> | ||
+ | const total_item_price = cart[' | ||
+ | |||
+ | let discounts = 0; | ||
+ | for (let d in cart[' | ||
+ | discounts += cart[' | ||
+ | } | ||
+ | |||
+ | rates.add(10001, | ||
+ | |||
+ | if (total_item_price + discounts > 50) { | ||
+ | rates.hide(); | ||
+ | rates.add(10002, | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | |||
+ | ==== Modifying Rates by Customer Attributes ==== | ||
+ | If you use '' | ||
+ | |||
+ | <code javascript> | ||
+ | let loyaltyLevel = false; | ||
+ | |||
+ | if ( | ||
+ | cart._embedded[" | ||
+ | cart._embedded[" | ||
+ | cart._embedded[" | ||
+ | cart._embedded[" | ||
+ | cart._embedded[" | ||
+ | ) { | ||
+ | for ( | ||
+ | let i = 0; | ||
+ | i < cart._embedded[" | ||
+ | i++ | ||
+ | ) { | ||
+ | const attr = cart._embedded[" | ||
+ | if (attr.name === " | ||
+ | loyaltyLevel = attr.value; | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | |||
+ | if (loyaltyLevel && loyaltyLevel.match(/ | ||
+ | rates.hide().add(10003, | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | ==== Restricting available rates based on product categories ==== | ||
+ | If the customer has ordered products from the ' | ||
+ | |||
+ | <code javascript> | ||
+ | let food = 0; | ||
+ | for (let p in cart[' | ||
+ | let item = cart[' | ||
+ | switch (item[' | ||
+ | case " | ||
+ | food += item[' | ||
+ | break; | ||
+ | } | ||
+ | } | ||
+ | |||
+ | if (food > 0) { | ||
+ | // Hide all shipping options, but show overnight rates | ||
+ | rates.hide().filter(" | ||
+ | | ||
+ | // If 3 or more food items, update priority overnight to be free | ||
+ | if (food >= 3) rates.filter(' | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | |||
+ | ==== Restricting available rates based on custom fields ==== | ||
+ | This example is similar to the above, but checks the value of a custom field from the session/ | ||
+ | |||
+ | <code javascript> | ||
+ | let my_field = ''; | ||
+ | for (let c in cart[' | ||
+ | let custom_field = cart[' | ||
+ | if (custom_field.name == ' | ||
+ | my_field = custom_field.value.toLowerCase(); | ||
+ | } | ||
+ | } | ||
+ | |||
+ | rates.add(10001, | ||
+ | rates.add(10002, | ||
+ | |||
+ | if (my_field == ' | ||
+ | rates.hide(); | ||
+ | rates.filter(10002).price(" | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | ==== 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 | ||
+ | |||
+ | <code javascript> | ||
+ | if (cart[' | ||
+ | rates.hide().filter(" | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | ==== Calculating shipping fees from custom product options ==== | ||
+ | This approach allows for shipping fees to be set per product via a custom product option called '' | ||
+ | |||
+ | 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 " | ||
+ | |||
+ | If you want to hide the custom product option on the cart, you can do that from the " | ||
+ | |||
+ | <code javascript> | ||
+ | let product_shipping = 0; | ||
+ | for (let p in cart[' | ||
+ | let item = cart[' | ||
+ | for (let o in item[' | ||
+ | let item_option = item[' | ||
+ | if (item_option[' | ||
+ | product_shipping += parseFloat(item_option[' | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | |||
+ | if (product_shipping > 0) { | ||
+ | if (rates.exists()) { | ||
+ | rates.price(" | ||
+ | } else { | ||
+ | rates.add(10000, | ||
+ | } | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | ==== Increase rates by a percentage ==== | ||
+ | |||
+ | This example filters rates on USPS and adds a 15% increase to all USPS prices. | ||
+ | |||
+ | <code javascript> | ||
+ | rates.filter(' | ||
+ | </ | ||
+ | |||
+ | ==== Increase rates by an amount ==== | ||
+ | |||
+ | This example filters rates on UPS and adds 4 units of the appropriate currency to all UPS prices. | ||
+ | |||
+ | <code javascript> | ||
+ | rates.filter(' | ||
+ | </ | ||
+ | |||
+ | ==== Getting shipping rates from Third Party Providers ==== | ||
+ | |||
+ | If you're needing to get rates from other providers that Foxy doesn' | ||
+ | |||
+ | * [[v: | ||
+ | * [[v: | ||
+ | * [[v: | ||
+ | * [[v: | ||
+ | ==== Calculate flat rate shipping based on distance ==== | ||
+ | |||
+ | For stores that want to calculate a flat rate shipping cost based on the distance, rather than using a live rate provider like USPS, FedEx or UPS, this approach can use the Google Maps API to calculate the distance between the store address and the customers. | ||
+ | |||
+ | [[v: | ||
+ | |||
+ | ==== Restricting shipping to a specific map area ==== | ||
+ | |||
+ | If you have a specific geographical area that you allow shipping to, you can use Google Maps with the custom shipping code to only show certain options if the customers shipping address is within that area. | ||
+ | |||
+ | [[v: |