I am a developer

Salesforce CC

Installing Paazls extension for SFCC SiteGenesis

This article explains how to install Paazl's extension in your Salesforce CC SiteGenesis implementation.


Note


The Paazl LINK cartridge can be used out of the box with a controller-based SiteGenesis - version 104.0.0.


You can use it with other versions but you may need to make additional adjustments.


Step 1. Install LINK cartridge


Install the int_paazl_controllers and int_paazl_core cartridges in Commerce Cloud UX-studio.


Step 2. Import metadata


To add Paazl configuration functionality to Business Manager, import Paazl's predefined metadata as follows:


  1. Download the Paazl LINK installation package from https://github.com/SalesforceCommerceCloud/link_paazl
  2. Open the link_paazl-master/site_import/sites/ folder
  3. Rename the yourSiteId folder to your site's ID in Salesforce CC Business Manager
  4. Zip the site_import folder
  5. Import the zipped file into Business Manager (Administration > Site Development > Site Import & Export)

After the import, the following changes will have been made to Business Manager.


Paazl attributes will have been added to:


  • Administration > Site Development > System Object Types > Site Preferences > Attribute Definitions
  • Administration > Site Development > System Object Types > Order > Attribute Definitions
  • Administration > Site Development > System Object Types > Shipment > Attribute Definitions
  • Administration > Site Development > System Object Types > Basket > Attribute Definitions

The following services will have been added to Administration > Operations > Services:


  • service.paazl.rest.gettoken
  • service.paazl.rest.getSelectedOption

The paazl shipping method will have been added to [yourSiteId] > Merchant Tools > Ordering > Shipping Methods.


Step 3. Customize Storefront code


If you are using SiteGenesis, you need to add Paazl-specific code to the Storefront Controller (app_storefront_controller) and Storefront Core (app_storefront_core). The files you need to modify and the code changes you need to make are given below.


Storefront controller


The files you need to modify are:


  • controllers/COShipping.js
  • controllers/COBilling.js
  • controllers/COSummary.js

You will find them under app_storefront_controllers > cartridge.


COShipping.js


Modify the 'updateShippingMethodList' function in COShipping.js as follows.


Original

// line # 348
app.getView({
    Basket: cart.object,
    ApplicableShippingMethods: applicableShippingMethods,
    ShippingCosts: shippingCosts
}).render('checkout/shipping/shippingmethods');

Modified

// paazl related changes
var template = 'checkout/shipping/shippingmethods';
var paazlHelper = require('*/cartridge/scripts/helpers/paazlHelper');
var currentPaazlShippingMethodID = paazlHelper.getShippingMethodID();
var paazlStatus = paazlHelper.getPaazlStatus(cart.object && cart.object.defaultShipment);
var paazlWidgetInit;
var paazlWidgetCustomizedStyle;
if (paazlStatus.applicable) {
    template = 'checkout/shipping/paazl_shippingmethods';
    if (cart) {
        var currentBasket = cart.object;
        paazlHelper.updateTokenInBasket(currentBasket);
        paazlWidgetInit = require('*/cartridge/scripts/init/initPaazlWidget').initPaazlWidget()
    }

    // If 'paazlWidgetPredefinedStyle' is set on CUSTOMIZED, fetch the customized style from the 'paazlWidgetCustomizedStyle' site preferences
    var paazlWidgetPredefinedStyle = Site.current.getCustomPreferenceValue('paazlWidgetPredefinedStyle');
    if (paazlWidgetPredefinedStyle.value === 'CUSTOMIZED') {
        paazlWidgetCustomizedStyle = Site.current.getCustomPreferenceValue('paazlWidgetCustomizedStyle');
    }

    var isPaazlUniqueShippingOption = false;
    if (applicableShippingMethods && applicableShippingMethods.length === 1) {
        if (applicableShippingMethods[0].ID === currentPaazlShippingMethodID) {
            isPaazlUniqueShippingOption = true;
        }
    }
}

app.getView({
    Basket: cart.object,
    ApplicableShippingMethods: applicableShippingMethods,
    ShippingCosts: shippingCosts,
    paazlWidgetInit: paazlWidgetInit,             // paazl view-data variables
    paazlStatus: paazlStatus,                     // paazl view-data variables
    paazlWidgetCustomizedStyle: paazlWidgetCustomizedStyle, // paazl view-data variables
    currentPaazlShippingMethodID: currentPaazlShippingMethodID, // paazl view-data variables
    isPaazlUniqueShippingOption: isPaazlUniqueShippingOption // paazl view-data variables
}).render(template);

Modify the 'singleShipping' function in COShipping.js as follows.


Original

// line # 222
handleShippingSettings(cart)

Modified

if (!handleShippingSettings(cart)) {
    // If selected shipping method is Paazl but no Paazl shipping options are available or selected, stay on the Shipping page
    app.getController('COShipping').Start();
    return;
}

Open COShipping.js, go to 'handleShippingSettings' function line 125 and replace the entire function with the one below.


/**
 * Handles the selected shipping address and shipping method. Copies the
 * address details and gift options to the basket's default shipment. Sets the
 * selected shipping method to the default shipment.
 *
 * @transactional
 * @param {module:models/CartModel~CartModel} cart - A CartModel wrapping the current Basket.
 * @returns {boolean} return status
 */
function handleShippingSettings(cart) {
    var result = true;
    Transaction.wrap(function () {
        var defaultShipment, shippingAddress;
        defaultShipment = cart.getDefaultShipment();
        shippingAddress = cart.createShipmentShippingAddress(defaultShipment.getID());
        shippingAddress.setFirstName(session.forms.singleshipping.shippingAddress.addressFields.firstName.value);
        shippingAddress.setLastName(session.forms.singleshipping.shippingAddress.addressFields.lastName.value);
        shippingAddress.setAddress1(session.forms.singleshipping.shippingAddress.addressFields.address1.value);
        shippingAddress.setAddress2(session.forms.singleshipping.shippingAddress.addressFields.address2.value);
        shippingAddress.setCity(session.forms.singleshipping.shippingAddress.addressFields.city.value);
        shippingAddress.setPostalCode(session.forms.singleshipping.shippingAddress.addressFields.postal.value);
        shippingAddress.setStateCode(session.forms.singleshipping.shippingAddress.addressFields.states.state.value);
        shippingAddress.setCountryCode(session.forms.singleshipping.shippingAddress.addressFields.country.value);
        shippingAddress.setPhone(session.forms.singleshipping.shippingAddress.addressFields.phone.value);
        defaultShipment.setGift(session.forms.singleshipping.shippingAddress.isGift.value);
        defaultShipment.setGiftMessage(session.forms.singleshipping.shippingAddress.giftMessage.value);
        var paazlHelper = require('*/cartridge/scripts/helpers/paazlHelper');
        paazlHelper.resetSelectedShippingOption(cart.object);
        var paazlStatus = paazlHelper.getPaazlStatus(cart.object && cart.object.defaultShipment);
        if (paazlStatus.active) {
            var paazlShippingOption = paazlHelper.getSelectedShippingOption(cart.object);
            if (!paazlShippingOption) {
                result = false;
            }
        } else {
            cart.updateShipmentShippingMethod(cart.getDefaultShipment().getID(), session.forms.singleshipping.shippingAddress.shippingMethodID.value, null, null);
        }
        cart.calculate();
        cart.validateForCheckout();
    });
    return result;
}

Modify the 'start' function in COShipping.js as follows.


Original

// line # 109
app.getView({
    ContinueURL: URLUtils.https('COShipping-SingleShipping'),
    Basket: cart.object,
    HomeDeliveries: homeDeliveries
}).render('checkout/shipping/singleshipping');

Modified

// Paazl related changes
var paazlHelper = require('*/cartridge/scripts/helpers/paazlHelper');
var paazlStatus = paazlHelper.getPaazlStatus(cart.object && cart.object.defaultShipment);
var paazlWidgetInit;
if (paazlStatus.applicable) {
    if (cart) {
        var currentBasket = cart.object;
        paazlHelper.updateTokenInBasket(currentBasket);
        paazlWidgetInit = require('*/cartridge/scripts/init/initPaazlWidget').initPaazlWidget()
    }
}
app.getView({
    ContinueURL: URLUtils.https('COShipping-SingleShipping'),
    Basket: cart.object,
    HomeDeliveries: homeDeliveries,
    paazlWidgetInit: paazlWidgetInit, // Paazl view-data variables
    paazlStatus: paazlStatus          // Paazl view-data variables
}).render('checkout/shipping/singleshipping');

COBilling.js


Modify the 'publicStart' function in COBilling.js as follows.


Original

// line # 191
start(cart, {ApplicableCreditCards: creditCardList.ApplicableCreditCards});

Modified

var params = {
    ApplicableCreditCards: creditCardList.ApplicableCreditCards
};
var paazlHelper = require('*/cartridge/scripts/helpers/paazlHelper');
var paazlStatus = paazlHelper.getPaazlStatus(cart.object && cart.object.defaultShipment);
params.paazlStatus = paazlStatus;
// Check whether or not Paazl is enabled
if (paazlStatus.active) {
    // If Paazl is active, add Paazl selected shipping option info to the data model
    var paazlShippingModel = paazlHelper.getPaazlShippingModel(cart.object);
    params.paazlShipment = paazlShippingModel;
}
start(cart, params);

COSummary.js


Modify the 'showConfirmation' function in COSummary.js as follows.


Original

// line # 97
app.getView({
    Order: order,
    ContinueURL: URLUtils.https('Account-RegistrationForm') // needed by registration form after anonymous checkouts
}).render('checkout/confirmation/confirmation');

Modified

// Paazl related changes
var params = {
    Order: order,
    ContinueURL: URLUtils.https('Account-RegistrationForm') // needed by registration form after anonymous checkouts
};
var shipment = order.defaultShipment;
var paazlHelper = require('*/cartridge/scripts/helpers/paazlHelper');
var paazlStatus = paazlHelper.getPaazlStatus(shipment);
// Check whether or not Paazl is enabled
if (paazlStatus.active) {
    // If Paazl is active, update the order shipping address with Paazl shipping address - only in case of pickup location delivery
    paazlHelper.updateShipment(order);
    // Add Paazl selected shipping option info to the data model
    var paazlShippingModel = paazlHelper.getPaazlShippingModel(order);
    params.paazlShipment = paazlShippingModel;
    params.paazlStatus = paazlStatus;
}
app.getView(params).render('checkout/confirmation/confirmation');

Modify the 'start' function in COSummary.js as follows.


Original

// line # 48
var pageMeta = require('~/cartridge/scripts/meta');
var viewContext = require('app_storefront_core/cartridge/scripts/common/extend').immutable(context, {
    Basket: cart.object
});
pageMeta.update({
    pageTitle: Resource.msg('summary.meta.pagetitle', 'checkout', 'SiteGenesis Checkout')
});
app.getView(viewContext).render('checkout/summary/summary');

Modified

var pageMeta = require('~/cartridge/scripts/meta');
pageMeta.update({
    pageTitle: Resource.msg('summary.meta.pagetitle', 'checkout', 'SiteGenesis Checkout')
});
// Paazl related changes
var params = {
    Basket: cart.object
};
var paazlHelper = require('*/cartridge/scripts/helpers/paazlHelper');
var paazlStatus = paazlHelper.getPaazlStatus(cart.object && cart.object.defaultShipment);
params.paazlStatus = paazlStatus;
// Check whether or not Paazl is enabled
if (paazlStatus.active) {
    // If Paazl is active add paazl select shipping option info to the data model
    var paazlShippingModel = paazlHelper.getPaazlShippingModel(cart.object);
    params.paazlShipment = paazlShippingModel;
}
var viewContext = require('app_storefront_core/cartridge/scripts/common/extend').immutable(context, params);
app.getView(viewContext).render('checkout/summary/summary');

Storefront core


The files you need to modify are:


  • scripts/cart/calculate.js
  • templates/default/checkout/minisummary.isml
  • templates/default/checkout/pt_checkout.isml
  • templates/default/checkout/shipping/singleshipping.isml
  • templates/default/components/order/orderdetails.isml
  • js/pages/checkout/shipping.js
  • scss/default/_checkout.scss

You will find them under app_storefront_core > cartridge.


calculate.js


Modify calculate.js as follows.


Original

// line # 62
ShippingMgr.applyShippingCost(basket);

Modified

ShippingMgr.applyShippingCost(basket);
var paazlHelper = require('*/cartridge/scripts/helpers/paazlHelper');
paazlStatus = paazlHelper.getPaazlStatus(basket.defaultShipment);
// If Paazl is active, apply Paazl shipping rate to the current basket
if (paazlStatus.active) {
   paazlHelper.calculateShipping(basket);
}

minisummary.isml


Modify minisummary.isml as follows.


Original

// line # 48
<isinclude template="checkout/shipping/minishipments"/>

Modified

<iscomment>If Paazl enabled and selected, use the template paazl_minishipments to render the shipment summary</iscomment>
<isif condition="${pdict.paazlStatus && pdict.paazlStatus.active}" >
   <isinclude template="checkout/shipping/paazl_minishipments" />
<iselse/>
   <isinclude template="checkout/shipping/minishipments"/>
</isif>

pt_checkout.isml


Open pt_checkout.isml and add the following code to the <head></head> section of the template.


<isif condition="${dw.system.Site.current.getCustomPreferenceValue('paazlEnabled') && dw.system.Site.current.getCustomPreferenceValue('paazlWidgetEndpoint')}">
    <script type="text/javascript" src="${dw.system.Site.current.getCustomPreferenceValue('paazlWidgetEndpoint')}"></script>
    <script src="${URLUtils.staticURL('/js/paazl.js')}" defer></script>
</isif>

Open pt_checkout.isml, and, just above the <isreplace/> tag in the <body></body> section, replace <div id="primary" class="primary-content"> with the following code:


<div id="primary" class="primary-content js-addressservice-url" data-addressservice-url="${URLUtils.https('Paazl-AddressNL')}">

Open pt_checkout.isml and add the following code to the <body></body> section of the template just below the <isreplace/> tag.


<isreplace/>
<isif condition="${dw.system.Site.current.getCustomPreferenceValue('paazlEnabled')}" >
   <isinclude template="/checkout/initPaazlWidget" />
</isif>

singleshipping.isml


Modify singleshipping.isml as follows.


Original

// line # 24
<form action="${URLUtils.continueURL()}" method="post" id="${pdict.CurrentForms.singleshipping.shippingAddress.htmlName}" class="checkout-shipping address form-horizontal">

Modified

<form action="${URLUtils.continueURL()}" method="post" id="${pdict.CurrentForms.singleshipping.shippingAddress.htmlName}" name="${pdict.CurrentForms.singleshipping.shippingAddress.htmlName}" class="checkout-shipping address form-horizontal ${pdict.paazlStatus && pdict.paazlStatus.applicable ? 'js-paazlwidget-form': ''}">

orderdetails.isml


Modify orderdetails.isml as follows.


Original

// line # 114
<isif condition="${!empty(shipment.shippingMethod)}">
   <div class="value"><isprint value="${shipment.shippingMethod.displayName}"/></div>
<iselse/>
   <div class="value"><isprint value="${shipment.shippingMethodID}"/></div>
</isif>

Modified

<isif condition="${pdict.paazlStatus && pdict.paazlStatus.active}">
   <iscomment>If paazl enabled, use passed paazlShipment instead </iscomment>
   <div class="value"><isprint value="${pdict.paazlShipment.shippingMethodModel.description}"/></div>
<iselseif condition="${!empty(shipment.custom.paazlSelectedShippingMethod)}">
   <div class="value"><isprint value="${shipment.custom.paazlSelectedShippingMethod}"/></div>
<iselseif condition="${!empty(shipment.shippingMethod)}">
   <div class="value"><isprint value="${shipment.shippingMethod.displayName}"/></div>
<iselse/>
   <div class="value"><isprint value="${shipment.shippingMethodID}"/></div>
</isif>

And:


Original

// line # 92
<isminishippingaddress p_shipment="${shipment}" p_editable="${false}" p_showmethod="${false}" p_showpromos="${false}"/>

Modified

<isif condition="${pdict.paazlStatus && pdict.paazlStatus.active}">
   <iscomment>If paazl enabled and selected, use the passed paazlShipment object instead </iscomment>
   <isminishippingaddress p_shipment="${pdict.paazlShipment}" p_editable="${false}" p_showmethod="${false}" p_showpromos="${false}"/>
<iselse/>
   <isminishippingaddress p_shipment="${shipment}" p_editable="${false}" p_showmethod="${false}" p_showpromos="${false}"/>
</isif>

shipping.js


Open shipping.js and add the following lines of code after the '}' at line 138.


//Paazl related changes
$('body').trigger('shipping:updateShippingMethods', {
    shipping: {
         shippingMethodID: $shippingMethodList.find('.input-radio:checked').val()
    }
});

Modify shipping.js as follows.


Original

// line # 124
$shippingMethodList.load(smlUrl, function () {

Modified

// line # 124
$shippingMethodList.load(smlUrl, function (data) {

Open shipping.js and add the following line of code after line 77.


//Paazl related changes
$('body').trigger('shipping:updateShippingMethods', { shipping : {shippingMethodID: shippingMethodID} });

_checkout.scss


Open _checkout.scss and add the following lines of code to the end of the file.


#paazl-checkout {
    footer {
        background-color: inherit;
    }
}

Step 4. Compile JS and CSS


The Paazl JS and CSS files are part of the int_paazl_core cartridge.


  1. Compile the JS and CSS code of the app_storefront_core cartridge as explained in SiteGenesis README.md.
  2. Compile the JS and CSS code of the int_paazl_corecartridge.
    1. Go to the top level of your project (just above the cartridges folder).
    2. Make sure that you are using the package.json and webpack.config.js files in the link_paazl repository in GitHub.
    3. Execute the following command:

      npm install
    4. Execute the following commands:

      npm run compile:js && npm run compile:scss

Was this article helpful?

That’s Great!

Thank you for your feedback

Sorry! We couldn't be helpful

Thank you for your feedback

Let us know how can we improve this article!

Select at least one of the reasons
CAPTCHA verification is required.

Feedback sent

We appreciate your effort and will try to fix the article