1. Home
  2. Knowledge Base
  3. Getting Started
  4. Shopify checkout.js file for FlavorCloud customers

Shopify checkout.js file for FlavorCloud customers

Please refer to “How do I enable breakout of duties and taxes on the right-hand side at checkout in Shopify?” for more information on how to use this file.

console.log('I am from Checkout page'); 

// CONFIG 

const APP_ID = 'YOUR_APP_ID_HERE'; 

const REST_API_KEY = 'YOUR_REST_API_KEY_HERE'; 

const API_URL = "https://partnerapi.flavorcloud.com"; 

const RATE_DETAIL_API_OLD = `${API_URL}/api/Carrierrates/fetch-rate-detail`; 

const RATE_DETAIL_API = `${API_URL}/RateDetail`; 

 
 

// Error Message Mappings 

const NO_RATE_SELECTED = 'No Selected-Rate Found From DOM'; 

const HASHKEY_PARSE_ERROR = 'Rate HashKey Not Found (Could not parse hashkey from the selectedRate-DOM value)'; 

const RATEOBJ_NOT_OBTAINED = 'Could not fetch Rate detail from FlavorCloud Service'; 

const INVALID_HASH_KEY_LENGTHY_ERROR = 'The obtained value is not hashKey, since its length is greater than 9'; 

const INVALID_HASH_KEY_SHORTER_ERROR = 'The obtained value is not hashKey, since its length is less than 5'; 

 
 

//DOM'S 

const BODY = 'body'; 

const SHIPPING_METHOD_CARD = '.main__content'; 

const A_SHIPPING_METHOD = '[data-shipping-method] input'; 

const SELECTED_SHIPPING_METHOD = '[data-shipping-method] input:checked'; 

const RIGHT_SUMMARY_TBL = 'tbody.total-line-table__tbody'; 

const SHOPIFY_SHIPPING_ROW = 'tr.total-line.total-line--shipping'; 

const FC_SHIPPING_ROW = 'tr.total-line.total-line--FCshipping'; 

const FC_DUTY_ROW = 'tr.total-line.total-line--FCduty'; 

const FC_TAXES_ROW = 'tr.total-line.total-line--FCtaxes'; 

const FC_FEES_ROW = 'tr.total-line.total-line--FCfees'; 

 
 
 

let fcStorage = {}; 

 
 

const init = () => { 

if (window.location.search.indexOf('step=shipping_method') > 0) //TODO: Add strong check condition for "is checkout page?" 

bindEvents(); 

} 

 
 

const bindEvents = () => { 

$(SHIPPING_METHOD_CARD).on('DOMNodeInserted', (e) => { 

startCalc(); 

}); 

 
 

$(BODY).on('change', A_SHIPPING_METHOD, function() { 

startCalc(); 

}); 

} 

 
 

const startCalc = async () => { 

let returnVal = null; 

try { 

console.log('START CALCULATING SPLITUPS'); 

let rate = getSelectedRate(); 

if (!rate) 

throw NO_RATE_SELECTED; 

 
 

let hashKey = parseHashKey(rate); 

if (!hashKey) 

throw HASHKEY_PARSE_ERROR; 

 
 

let rateObj = await getRateDetailsFromFlavorcloud(hashKey); 

if (!rateObj) 

throw RATEOBJ_NOT_OBTAINED; 

 
 

if (rateObj.IsDDP) 

returnVal = constructResult(rateObj); 

else 

resetDom(); 

 
 

updateUI(returnVal); 

} catch (e) { 

console.log(e); 

resetDom(); 

} finally { 

return returnVal; 

} 

} 

 
 

const parseHashKey = (rate) => { 

try { 

let splits = rate.split('-'); 

let hashKey = splits[1]; 

if (hashKey) { 

if (hashKey.length > 9) 

throw INVALID_HASH_KEY_LENGTHY_ERROR; 

else if (hashKey.length < 5) 

throw INVALID_HASH_KEY_SHORTER_ERROR; 

} 

return hashKey; 

} catch (e) { 

console.log(e); 

return null; 

} 

} 

 
 

const parseTotalShippingCost = (rate) => { 

try { 

let splits = rate.split('-'); 

let shippingCost = splits[2]; 

return shippingCost; 

} catch (e) { 

console.log(e); 

return null; 

} 

} 

 
 

const getRateDetailsFromFlavorcloud = (hashKey) => { 

return new Promise((resolve, reject) => { 

try { 

if (fcStorage[hashKey]) { 

return resolve(fcStorage[hashKey]); 

} else { 

$.ajax({ 

type: "GET", 

url: `${RATE_DETAIL_API}/${APP_ID}/${REST_API_KEY}/${hashKey}`, 

dataType: "json", 

success: function(result, status, xhr) { 

fcStorage[hashKey] = result; 

if (status == "success") { 

if (result) 

return resolve(result); 

else 

return resolve(null); 

} else { 

return reject(null); 

} 

}, 

error: function(result, status, error) { 

return reject(result.responseJSON); 

} 

}); 

} 

} catch (e) { 

console.log(e); 

return reject(e); 

} 

}); 

} 

 
 

const getSelectedRate = () => { 

let selectedRateDom = $(SELECTED_SHIPPING_METHOD); 

let rate = null; 

if (selectedRateDom && selectedRateDom[0]) 

rate = selectedRateDom[0].value; 

return rate; 

} 

 
 

const getPureNumberPrice = (priceWithChar) => { 

let price = ''; 

priceWithChar.split("").forEach(el => { 

if (el == '.') price += el; 

else if (!isNaN(parseInt(el))) price += el; 

}); 

return parseInt(price); 

} 

 
 

const parseCurrencySymbol = (priceWithSymbol) => { 

try { 

let symbol = ""; 

priceWithSymbol.split("").forEach(el => { 

if (!parseInt(el) && el !== "0") symbol += el; 

}); 

return symbol.trim(); 

} catch (e) { 

console.log(e); 

} 

} 

 
 

const getTotalShippingCostFromDOM = (options) => { 

let yy = $(SELECTED_SHIPPING_METHOD)[0]; 

let costValWithCurrency = $(yy).attr('data-checkout-total-shipping'); 

let returnVal = costValWithCurrency; 

if (options && options.excludeCurrency) 

returnVal = getPureNumberPrice(costValWithCurrency); 

return returnVal; 

} 

 
 
 

const getCartCurrency = () => { 

return $.cookie('cart_currency'); 

} 

 
 

const constructResult = (flclRateObj) => { 

let returnVal = null; 

try { 

let currency = getCartCurrency(); 

if (currency == 'USD') { 

returnVal = { 

duty: flclRateObj.AppliedDuty, 

taxes: flclRateObj.AppliedTaxes, 

fees: flclRateObj.AppliedFees, 

shippingCost: flclRateObj.AppliedShippingCost 

} 

} else { 

let totalShippingCostInDOM = getTotalShippingCostFromDOM({ 

excludeCurrency: true 

}); 

let convertedValues = convertToCartCurrency(flclRateObj, totalShippingCostInDOM); 

returnVal = { 

duty: convertedValues.dutyVal, 

taxes: convertedValues.taxVal, 

fees: convertedValues.feesVal, 

shippingCost: convertedValues.shippingCostVal 

} 

} 

console.log('CONSTRUCTED SPLIT UP Values: ', returnVal); 

} catch (e) { 

console.log(e); 

} finally { 

return returnVal; 

} 

} 

 
 

const convertToCartCurrency = (rateObj, totalShippingCostInDOM) => { // totalShippingCostInDOM = 2400 

try { 

let shippingCostPercentage = toFixed((rateObj.AppliedShippingCost / rateObj.TotalShippingVal) * 100); // (25.09/31.09)*100 = 80.70% 

let landedCostPercentage = toFixed((rateObj.AppliedLandedCost / rateObj.TotalShippingVal) * 100); // (6/31.09)*100 = 19.30% 

let dutyPercentage = 0; 

let taxPercentage = 0; 

let feesPercentage = 0; 

if (rateObj.AppliedLandedCost) { 

dutyPercentage = toFixed((rateObj.AppliedDuty / rateObj.AppliedLandedCost) * 100); // (3/6*100) = 50% 

taxPercentage = toFixed((rateObj.AppliedTaxes / rateObj.AppliedLandedCost) * 100); // (1/6*100) = 16.67% 

feesPercentage = toFixed((rateObj.AppliedFees / rateObj.AppliedLandedCost) * 100); // (2/6*100) = 33.33% 

} 

 
 

let shippingCostVal = toFixed((totalShippingCostInDOM * shippingCostPercentage) / 100); // (2400*80.7)/100 = 1936.8 

let landedCostVal = toFixed((totalShippingCostInDOM * landedCostPercentage) / 100); // (2400*19.3)/100 = 463.2 

let dutyVal = toFixed((landedCostVal * dutyPercentage) / 100); // (463.2*50)/100 = 231.6 

let taxVal = toFixed((landedCostVal * taxPercentage) / 100); // (463.2*50)/100 = 77.22 

let feesVal = toFixed((landedCostVal * feesPercentage) / 100); // (463.2*50)/100 = 154.38 

 
 

return { 

dutyVal, 

taxVal, 

feesVal, 

shippingCostVal 

} 

} catch (e) { 

console.log(e); 

} 

} 

 
 

const toFixed = (aNumber) => { 

return aNumber.toFixed(2); 

} 

 
 

const getARow = (label, val) => { 

let dom = ( 

`<tr class="total-line total-line--FC${label.toLowerCase()}"> 

<th class="total-line__name" scope="row"> 

            <span>${label}</span> 

</th> 

<td class="total-line__price"> 

        <span class="skeleton-while-loading order-summary__emphasis">${getCurrency()}${val}</span> 

</td> 

</tr>` 

); 

return dom; 

} 

 
 

const constructDom = (splitUps) => { 

let dom = [ 

getARow('Shipping', splitUps.shippingCost), 

getARow('Duty', splitUps.duty), 

getARow('Taxes', splitUps.taxes), 

getARow('Fees', splitUps.fees) 

]; 

return dom; 

} 

 
 

const hideExistingShippingDom = () => { 

$(SHOPIFY_SHIPPING_ROW).addClass("hidden"); 

} 

 
 

const removeFcDom = () => { 

$(FC_SHIPPING_ROW).remove(); 

$(FC_DUTY_ROW).remove(); 

$(FC_TAXES_ROW).remove(); 

$(FC_FEES_ROW).remove(); 

} 

 
 

const addFcDom = (dom) => { 

$(RIGHT_SUMMARY_TBL).append(dom); 

} 

 
 

const showShopifyDom = () => { 

$(SHOPIFY_SHIPPING_ROW).removeClass("hidden"); 

} 

 
 

const updateUI = (splitUps) => { 

let dom = constructDom(splitUps); 

hideExistingShippingDom(); 

removeFcDom(); 

addFcDom(dom); 

} 

 
 

const resetDom = () => { 

removeFcDom(); 

showShopifyDom(); 

} 

 
 

const getCurrency = () => { 

let priceWithCurrency = document.getElementsByClassName('order-summary__emphasis skeleton-while-loading')[1].innerText[0]; 

return parseCurrencySymbol(priceWithCurrency); 

} 

 
 

init(); 
Was this article helpful?

Related Articles

Need Support?

Can't find the answer you're looking for?
Contact Support