CyberStore Ecommerce 2023 Documentation
Checkout Widget

A single-page checkout widget. Introduced in 2023.1. 

 Remarks

The Checkout widget is a single-page form that allows the user to quickly and seamlessly complete their current order. The widget allows the user to select a payment option Invoice or Credit Card. The user can select a shipping address for the current list of addresses for this customer or add a new address for this order.

 

 

The shopper can select the default shipping address which will be displayed on the page. They can click on the change address button, this will popup a form where the shopper has the option to select a previously saved address from the list or create a new one time address for this shipment.

 

 

The shopper has the option to check out and be billed with the invoice selection. Or if the company has set up the ability to process credit cards, the user can enter their credit card information and complete the purchase that way.

The form must be validated before it can be submitted. The validation requires that all fields have data and that the shipping address is a plausible and complete address. If payment type is credit card validation will confirm that the card type has been determined and the Luhn checksum passes, the month and year of expiration are valid numbers, and the CVN value has the correct number of characters. After shipping and payment information has been validated then the order will be submitted

Note:

The Checkout widget is only available when a shopper's account is on-file. B2C shoppers will be guided thorugh the traditional multi-step checkout process.

 Example

See an example of how to load and configure this widget in SitePages.config.

<!-- Example:
     The Checkout widget
-->
<Control src="LoadWidgetControl.ascx" FileLocation="Checkout.html" />
 Widget Source

The following is the source code for this widget.

Developer's Note:

To create a custom version of the widget, copy all of the code below into a file of the same name and place it into your Site's widgets folder (e.g., ../YourSiteFolder/Widgets). The CyberStore page engine will then override the default source with your customized version.

<style>
    * {
        -webkit-box-sizing: border-box;
        -moz-box-sizing: border-box;
        box-sizing: border-box;
    }

    #divCheckoutWrapper {
        min-height: 600px;
        background-repeat: no-repeat;
        background-image: url('images/checkout-loading-background.png');
    }

        #divCheckoutWrapper section {
            display: none;
        }

    #subpagecontent {
        background: #f4f4f4;
    }

    h2 {
        margin: 15px 0 15px 0;
    }

    .credit,
    .invoice,
    .gstTax {
        display: none;
    }

    .no-gutter {
        padding-left: 0;
        padding-right: 0;
    }

    .right-gutter {
        padding-left: 0;
        padding-right: 15px;
    }

    .left-gutter {
        padding-left: 15px;
        padding-right: 0;
    }

    section.row {
        margin: 20px 0;
        background: #fff;
        padding: 15px 15px 20px;
        box-shadow: 0 2px 6px rgba(69, 73, 91, .078);
        -webkit-box-shadow: 0 2px 6px rgba(69, 73, 91, .078);
        -moz-box-shadow: 0 2px 6px rgba(69, 73, 91, .078);
    }

        section.row.clear {
            background: transparent;
            box-shadow: none;
            -webkit-box-shadow: none;
            -moz-box-shadow: none;
        }

    section {
    }

    h3 span {
        color: #ee3a43;
    }

    label {
        font-weight: 400 !important;
        width: auto;
    }

    input[type="text"],
    input[type="password"] {
        border-radius: 5px;
        padding: 0px 10px !important;
    }

    #divMultiAddressWrapper {
        padding: 0 20px;
        display: none;
    }

    #divOneTimeAddressWrapper {
        padding: 0 20px;
        display: none;
    }

    .checkoutOrder label,
    .dx-field-item-label-text {
        color: #ee3a43;
    }

    #shippingInfo label,
    #shippingInfo .dx-field-item-label-text {
        color: #000
    }

    .checkoutOrder .inputRow input,
    .checkoutOrder .inputRow select {
        margin-top: 5px;
    }

    .checkoutIcon {
        font-family: 'Open Sans', Arial, sans-serif !important;
        font-size: 12px !important;
        max-width: 190px;
    }

        .checkoutIcon span {
            font-family: 'Open Sans', Arial, sans-serif !important;
            font-size: 12px !important;
            white-space: normal;
        }

    .dx-field-label {
        padding: 0;
    }

    .dx-button {
        border-width: 0px;
    }

    .dx-button-has-text .dx-button-content {
        padding: 3px;
    }

    .dx-field-value:not(.dx-switch):not(.dx-checkbox):not(.dx-button) {
        width: 100;
    }

    .dx-field-value:not(.dx-widget) > .dx-button, .dx-field-value:not(.dx-widget) > .dx-checkbox, .dx-field-value:not(.dx-widget) > .dx-switch {
        float: unset;
        /*    width;*/
        float: left;
        padding: 5px !important;
        border: 1px solid #e2e0e0;
        text-align: center;
        margin-bottom: 15px;
        margin-right: 15px;
        margin-top: 4px;
        font-size: 14px;
    }

    div#default-address {
        float: none;
        text-align: center;
    }

    div#invoiceBtn, div#credit-cardBtn, div#default-address, div#change-address {
        width: 100;
    }

    .dx-button-mode-contained.dx-state-hover {
        background-color: #fff;
    }

    .dx-button-mode-contained.dx-state-focused {
        background-color: #fff;
    }

    .dx-button-mode-contained.dx-state-active {
        background-color: #fff;
    }

    .checkoutIcon img,
    .checkoutIcon .dx-button-content img,
    .checkoutIcon .dx-button-mode-contained .dx-icon {
        display: block;
        margin: auto;
        width;
        min-width: 40px;
        height: auto;
        max-width: 60px;
    }

    .dx-datebox-wrapper-calendar .dx-calendar {
        margin: 5px;
    }

    .dx-calendar-navigator .dx-calendar-caption-button.dx-button .dx-button-content {
        padding: 2px 15px 4px;
        color: #ee3a43;
    }

    .dx-calendar-cell.dx-calendar-today {
        font-weight: bold;
        color: #ee3a43;
    }

    .dx-calendar-navigator-next-view.dx-button .dx-icon, .dx-calendar-navigator-next-month.dx-button .dx-icon,
    .dx-calendar-navigator-previous-view.dx-button .dx-icon, .dx-calendar-navigator-previous-month.dx-button .dx-icon {
        color: #ee3a43;
    }

    .dx-calendar-cell.dx-calendar-contoured-date {
        -webkit-box-shadow: inset 0 0 0 1px #e2b1b1;
        box-shadow: inset 0 0 0 1px #e2b1b1;
    }

    .dx-calendar-cell.dx-calendar-selected-date.dx-calendar-contoured-date, .dx-calendar-cell.dx-calendar-selected-date.dx-calendar-today.dx-calendar-contoured-date {
        -webkit-box-shadow: inset 0 0 0 1px#ee3a43, inset 0 0 0 1000px #ee3a43;
        box-shadow: inset 0 0 0 1px#ee3a43, inset 0 0 0 1000px #ee3a43;
    }

    .col-xs-12.shippingInfo {
        padding: 20px 15px;
        border-bottom: 1px solid gainsboro;
    }

    .inputRow.col-xs-12 {
        padding: 5px 0;
    }

    .inputRow > div {
        padding-left: 0;
        padding-bottom: 5px;
    }

    .inputRow input,
    .inputRow select {
        height: 30px;
        width: 100;
    }

    .inputRow textarea {
        width;
    }

    .checkoutOrder .inputRow input,
    .checkoutOrder .inputRow select,
    .inputRow textarea {
        margin-top: 5px;
    }

    input.purchaseOrder {
        max-width: 290px;
    }

    input.expiration {
        width: 130px;
    }

    input.promotion {
        width: 80;
        margin-right: 15px;
        height: 30px;
        margin-bottom: 0;
    }

    input[type=date] {
        line-height: 25px;
        width: 160px;
    }

    .amount span {
        float: right;
    }

    .totalpriceRow {
        font-weight: 600;
    }

    .cartTitles.row {
        padding: 15px 0;
        margin-right: 0;
        margin-left: 0;
    }

    .cartTitles .col-sm-2.hidden-xs {
        /*max-width: 223px;*/
    }

    .col-sm-2.price.totalprice {
        padding-left: 40px;
    }

    .cartDetails.row {
        padding: 20px 0;
        border-bottom: 1px solid #dddddd;
        display: flex;
        width;
        box-shadow: none;
    }

    .cartDetails {
        background: #fff;
        color: gray;
        font-size: 12px;
        text-align: center;
        box-shadow: 0 2px 6px rgba(69, 73, 91, .078);
        -webkit-box-shadow: 0 2px 6px rgba(69, 73, 91, .078);
        -moz-box-shadow: 0 2px 6px rgba(69, 73, 91, .078);
    }

        .cartDetails img {
            width: 100;
            min-width: 75px;
            max-width: 250px
        }

        .cartDetails.row div {
            display: flow-root;
            margin: auto 0;
        }

        .cartDetails .backorderQTY {
            color: #ee3a43;
        }

    .totalsRow {
        margin-bottom: 20px;
        padding-bottom: 15px;
        display: flex;
    }

    div#icon-submit {
        width;
        padding: 10px 5px !important;
    }

    #icon-submit.dx-button-has-text .dx-button-content {
        padding: 0px 18px 0px;
    }

        #icon-submit.dx-button-has-text .dx-button-content i {
            float: right;
            color: #fff;
        }

        #icon-submit.dx-button-has-text .dx-button-content span {
            float: left;
        }

    .checkoutSubmit {
        display: flow-root;
        margin: auto 0 0;
        max-width: 360px;
    }

        .checkoutSubmit button {
            width: 100;
            text-align: left;
        }

    .cartRow {
        width;
        padding: 0 !important;
    }

    .productDetails {
        text-align: left;
        /*max-width: 440px;*/
    }

    .cartDetails colgroup, .cartDetails .dx-datagrid-headers {
        display: none;
    }

    .cartDetails label.visible-xs {
        float: left;
    }

    .item-name.productDetails,
    .cartTitles,
    .cartDetails .price,
    .cartDetails .totalPrice {
        font-weight: 600;
    }

    @media (min-width: 326px) {

        .totalsRow,
        .cartDetails.row {
            display: block;
            /*      padding: 15px;*/
            margin: auto auto;
        }

        .tab-content {
            padding-left: 0;
        }

        .checkoutSubmit {
            margin: 20px 0;
        }

        .totalpriceRow {
            margin-bottom: 30px;
        }

        .cartDetails.row div {
            display: block;
            margin: auto 0;
            white-space: normal;
        }

        .cartDetails label.visible-xs {
            float: left;
            width: auto;
            padding-right: 15px;
            min-width: 60px;
        }

        .cartTitles,
        .cartDetails .price,
        .cartDetails .quantity,
        .cartDetails .backordered,
        .cartDetails .totalPrice {
            text-align: left;
            padding: 10px 15px
        }

        div#PromotionalCode {
            width: 75%;
            float: left;
            margin-right: 5px;
            margin-bottom: 10px;
            margin-top: 4px;
        }

        input.promotion {
            margin-bottom: 15px;
        }
    }

    @media (min-width: 767px) {

        .totalsRow,
        .cartDetails.row {
            display: flex;
            padding: 0 15px;
            margin-bottom: 20px;
        }

        .totalpriceRow {
            margin-bottom: 0px;
        }

        .checkoutSubmit {
            margin: auto 0 0;
        }

        .cartTitles,
        .cartDetails .price,
        .cartDetails .quantity,
        .cartDetails .backordered,
        .cartDetails .totalPrice {
            text-align: center;
            padding: 5px 15px
        }
    }

    h3,
    .h3-style {
        font-size: 20px;
        line-height: 26px;
        font-weight: 300;
        font-family: 'Open Sans', Arial, sans-serif;
        margin: 30px 0 30px;
    }

    .btn {
        border-width: 2px;
        text-transform: uppercase;
        font-weight: 500;
        letter-spacing: 1.7px;
        -webkit-transition: all 0.2s ease-in-out, color 0.2s ease-in-out, box-shadow 0.1s ease-in-out;
        transition: all 0.2s ease-in-out, color 0.2s ease-in-out, box-shadow 0.1s ease-in-out;
        outline-color: #ee3a43 !important;
        padding: 7px 12px 6px;
    }

    .btn-primary, .dx-toolbar-button .dx-button-mode-contained {
        color: #fff;
        background-color: #ee3a43;
        border-color: #ee3a43;
    }

    .btn-sm {
        font-size: 10px;
        padding: 6px 10px 5px;
        /*   line-height: 0.5;*/
        border-radius: 3px;
    }

    .btn-lg {
        padding: 11px 16px 10px;
        font-size: 15px;
        line-height: 1.33333;
        border-radius: 6px;
    }

    button {
        /* margin: 0px 6px !important;*/
    }

        button.btn.btn-primary {
            font-size: 1.0em;
            min-width: 115px;
        }

    .cartDetails #btnCancel {
        float: right;
        position: relative;
        top: -15px;
    }

    .dx-toolbar-button .dx-button-mode-contained {
        padding: 6px;
    }

        .dx-toolbar-button .dx-button-mode-contained .dx-icon {
            position: relative;
            left: -25px;
            color: #fff;
        }

        .btn.btn-primary:hover,
        .btn.btn-primary:focus,
        .dx-toolbar-button .dx-button-mode-contained.dx-state-hover {
            background-color: #000;
            color: white;
            border-color: #000;
            outline: none;
        }

    .dx-toolbar-button .dx-closebutton.dx-button-mode-contained.dx-state-hover {
        background: transparent;
        border: 1px solid transparent;
    }

    .popupToolbarButton {
        margin-top: -15px;
    }
</style>
<!-- priley -->
<script src='/ECommerce/Site/Shop/js/geographicData.js'></script>
<script type="text/javascript">
    /*
        ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
        ' Checkout Widget
        ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
        '                                 (c) 1999-2020
        '                      by Dovetail Internet Technologies, LLC
        '             www.dovetailinternet.com       www.CyberStoreForSYSPRO.com
        '                         sales@CyberStoreForSYSPRO.com
        ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
        ' All rights reserved. Not to be used without permission.
        ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
        ' Filename: Checkout.html
        ' Version:  CyberStore For SYSPRO v2020.0.0
        ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
        ' Development Date: August 2020
        ' Revision: 1.0.18
        ' Modified: 8/9/2020
        ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
        ' Purpose: present shopper with single-page checkout experience.
        ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
        ' Documentation: http://documentation.cyberstoreforsyspro.com/#CheckoutWidget.html
        ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
        '
     */

    $('#myTabs a').click(function (e) {
        e.preventDefault()
        $(this).tab('show')
    });

    var CheckoutLoadPanel = null,
        OrderData = {},
        CheckOutUrl = '',
        PaymentMethod = {},
        InvoiceMethod = {},
        CCMethod = {},
        AddressData = [],
        CustomOrderData = {},
        AccountProfile = {},
        ShippingOptions = { ShippingMethodID: -1, SpecialInstructions: '', OrderHeaderComments: '', AlternateKey: '', RequestedShipDate: '' },
        OneTimeAddressData = { ShipToName: '', FirstName: '', LastName: '', Address1: '', Address2: '', Address3: '', City: '', State: '', Zip: '', Phone: '', IsDropShip: true, AddressCode: '' },
        OrderAddresses = { BillingAddress: {}, ShippingAddress: {} };

    // TODO: move this to global.js or check if there is a simpler function for this
    function DateToMMDDYYYY(dateNum) {
        let date = new Date(dateNum);
        return ((date.getMonth().toString().length > 1) ? (date.getMonth() + 1) : ('0' + (date.getMonth() + 1))) + '/' + ((date.getDate().toString().length > 1) ? date.getDate() : ('0' + date.getDate())) + '/' + date.getFullYear();
    }

    function Today() {
        var today = new Date();
        return today.getFullYear() + '-' + (today.getMonth() + 1) + '-' + today.getDate();
    }

    $(function () {
        _.templateSettings.variable = 'item';

        CheckoutLoadPanel = $('#divLoadPanel').dxLoadPanel({
            shadingColor: 'rgba(0,0,0,0.7)',
            visible: true,
            showIndicator: true,
            showPane: true,
            closeOnOutsideClick: false,
            message: 'Loading order preferences ...',
        }).dxLoadPanel('instance');

        function loadData(DATA, options) {
            if (ValidAJAXResponse(DATA)) {
                // build our objects for handling
                var response = JSON.parse(DATA);
                if (!response.Result.Success) {
                    var alertResult = DevExpress.ui.dialog.alert(response.Result.Message, 'Message');
                    alertResult.done(function () {
                        CheckoutLoadPanel.option('message', 'Returning to your cart ...')
                        window.location.replace(SITE_PATHS.application + '/ShoppingCart.aspx');
                    });

                    return;
                }
                else {
                    OrderData = response.Data;
                    CheckOutUrl = OrderData.CheckOutPageUrl;
                    itemDetails.option('dataSource', OrderData.Details);

                    // purchase order
                    orderDetailsForm.getEditor('PO').option('value', OrderData.PO);

                    // requested ship date
                    if ('RequestedShipDate' in OrderData) {
                        if (OrderData.RequestedShipDate !== '') {
                            orderDetailsForm.getEditor('RequestedShipDate').option({
                                value: Date.parse(OrderData.RequestedShipDate)
                            });

                        }
                        orderDetailsForm.getEditor('RequestedShipDate').option({
                            disabled: (OrderData.CanChangeShipDate != null)
                                ? !OrderData.CanChangeShipDate
                                : true,
                        });
                        if (OrderData.CanChangeShipDate) {
                            orderDetailsForm.getEditor('RequestedShipDate').option({
                                value: Date.parse(OrderData.MinimumShipDate),
                                min: ('MinimumShipDate' in OrderData) ? Date.parse(OrderData.MinimumShipDate) : Today(),
                                max: ('MaximumShipDate' in OrderData) ? Date.parse(OrderData.MaximumShipDate) : null,
                                onValueChanged: function (e) {
                                    ShippingOptions.RequestedShipDate = DateToMMDDYYYY(e.value);
                                }
                            });
                            ShippingOptions.RequestedShipDate = OrderData.MinimumShipDate;
                        }
                    }
                    else {
                        orderDetailsForm.itemOption('section1.RequestedShipDate', {
                            visible: false,
                        });
                    }

                    /* TODO: figure out how to handle hiding the WEBXXXX PO when desired

                    if (widgetOptions.useDefaultPONumber !== null) {
                        if (widgetOptions.useDefaultPONumber) {
                            orderDetailsForm.getEditor('PO').option('value', OrderData.PO);
                        }
                    }
                    else {
                        orderDetailsForm.getEditor('PO').option('value', OrderData.PO);
                    }

                    */

                    // special instructions
                    shippingInfoForm.getEditor('SpecialInstructions').option('value', OrderData.SpecialInstructions);

                    // alternate key
                    if ('AlternateKeyLabelText' in OrderData) {
                        shippingInfoForm.itemOption('section2.AlternateKey', {
                            visible: true,
                            label: {
                                text: OrderData.AlternateKeyLabelText
                            }
                        });
                    }
                    else {
                    }
                    // shipping
                    displayShippingAddress({
                        ShipToName: (OrderData.CompanyName != '')
                            ? OrderData.CompanyName
                            : OrderData.Name,
                        FirstName: OrderData.FirstName,
                        LastName: OrderData.LastName,
                        Address1: OrderData.ShipppingAddress1,
                        Address2: OrderData.ShipppingAddress2,
                        Address3: OrderData.ShipppingAddress3,
                        City: OrderData.City,
                        State: OrderData.State,
                        Zip: OrderData.Zip,
                        Country: OrderData.Country,
                        Phone: OrderData.Phone,
                        TaxCity: OrderData.TaxCity,
                        TaxState: OrderData.TaxState,
                        TaxArea: OrderData.TaxArea,
                        TaxCountyZip: OrderData.TaxCountyZip
                    });

                    // billing
                    displayBillingAddress({
                        FirstName: OrderData.FirstName,
                        LastName: OrderData.LastName,
                        Address1: OrderData.BillingAddress1,
                        Address2: OrderData.BillingAddress2,
                        Address3: OrderData.BillingAddress3,
                        City: OrderData.BillingCity,
                        State: OrderData.BillingState,
                        Zip: OrderData.BillingZip,
                        Country: OrderData.BillingCountry,
                        Phone: OrderData.BillingPhone
                    });


                    $('#divBillingCompany').text(OrderData.Name);

                    $('#divEmail').text(OrderData.Email);

                    // promo
                    if (OrderData.WebPromotionCode !== null) {
                        promoCodeDetail.option('value', OrderData.WebPromotionCode);
                    }

                    // order totals
                    $('#spnSubtotal').text(OrderData.OrderSubTotal);
                    if (OrderData.ShippingCostAmount != null) {
                        $('#spnShippingCost').text(OrderData.ShippingCost);
                    }
                    else {
                        $('#spnShippingCost').text('TBD');
                    }
                    $('#spnTax').text(OrderData.Tax);
                    if (OrderData.GSTTaxAmount > 0) {
                        $('#spnGSTTax').text(OrderData.GSTTax);
                        $('.gstTax').css('display', 'block');
                        if (OrderData.TaxAmount == 0) {
                            $('.tax').css('display', 'none');
                        }
                    }
                    if (OrderData.WebPromotionValueAmount != 0) {
                        $('#spnPromoValue').text(OrderData.WebPromotionValue);
                        $('.promo').css('display', 'block');
                    }
                    else {
                        $('.promo').css('display', 'none');
                    }
                    $('#spnOrderTotal').text(OrderData.OrderTotal);
                }
                var getShipping = true, getPayments = true, getProfile = true;
                if (!_.isEmpty(options)) {
                    if ('getShipping' in options) { getShipping = options.getShipping; }
                    if ('getPayments' in options) { getPayments = options.getPayments; }
                    if ('getProfile' in options) { getProfile = options.getProfile; }
                }

                if (getProfile) { MakeAJAXCall('Visitor.GetAccountProfile', {}, populateProfile, response); }

                // paint the checkout form
                $('#divCheckoutWrapper').css('background-image', 'none');
                $('#divCheckoutWrapper section').css('display', 'block');
                CheckoutLoadPanel.hide();
                if (orderDetailsForm.getEditor('PO').option('value') === '') {
                    orderDetailsForm.getEditor('PO').focus();
                }

                if (getShipping) { MakeAJAXCall('Order.GetShippingMethods', {}, populateShipping); }
                if (getPayments) { MakeAJAXCall('Order.GetPaymentMethods', {}, buildPaymentMethods); }
            }
        }

        var orderDetailsForm = $('#orderDetails').dxForm({
            items: [{
                itemType: 'group',
                name: 'section1',
                cssClass: 'inputRow',
                colCount: 3,
                items: [{
                    dataField: 'PO',
                    editorType: 'dxTextBox',
                    label: {
                        text: 'PO Number',
                        location: 'top'
                    },
                    editorOptions: {
                        placeholder: 'Your PO Number',
                        onChange: function () {
                            MakeAJAXCall('Order.SaveOrderPayment', getPaymentParams());
                        },
                        maxLength: 30
                    }
                },
                {
                    dataField: 'RequestedShipDate',
                    editorType: 'dxDateBox',
                    label: {
                        text: 'Requested Ship Date',
                        location: 'top',
                    },
                    editorOptions: {
                        width: '100',
                        calendarOptions: {
                            showTodayButton: true
                        }
                    }
                },
                {
                    dataField: 'ATPendDate',
                    visible: false,
                    editorType: 'dxDateBox',
                    label: {
                        location: 'top'
                    },
                    editorOptions: {
                        width'
                    }
                }]
            }]
        }).dxForm('instance');


        // SHIPPING INFORMATION
        var shippingInfoForm = $('#shippingInfo').dxForm({
            items: [{
                itemType: 'group',
                cssClass: 'inputRow',
                name: 'section2',
                colCount: 1,
                items: [{
                    dataField: 'ShippingMethod',
                    editorType: 'dxSelectBox',
                    editorOptions: {
                        dataSource: [{ Method_ID: 0, Description: 'Calculating Options ...' }],
                        valueExpr: 'Method_ID',
                        displayExpr: 'Description',
                        value: 0,
                        placeholder: 'Calculating Options ...',
                        disabled: true,
                        onValueChanged: function (e) {
                            var val = e.value;
                            ShippingOptions.ShippingMethodID = (typeof val === 'string') ? val.substring(val.indexOf("_") + 1) : val;
                        }
                    },
                },
                {
                    dataField: 'SpecialInstructions',
                    editorType: 'dxTextBox',
                    label: {
                        text: 'Special Instructions'
                    },
                    editorOptions: {
                        placeholder: 'Type any special instructions',
                        onChange: function (e) {
                            ShippingOptions.SpecialInstructions = e.component.option('value');
                        },
                        maxLength: 50
                    }
                },
                {
                    dataField: 'AlternateKey',
                    visible: false,
                    editorType: 'dxTextBox',
                    editorOptions: {
                        onChange: function (e) {
                            ShippingOptions.AlternateKey = e.component.option('value');
                        },
                        maxLength: 10,
                        width: 150
                    }
                }
                ]
            }]
        }).dxForm('instance');

        //ADDRESS BUTTONS
        $('#default-address').dxButton({
            icon: '/Ecommerce/site/themes/images/defaultAddress.png',
            text: 'Default Address',
            onClick: function () {
                var defaultAddress = GetObjectFromArrayByKeyValue(AddressData.Addresses, 'AddressCode', AddressData.DefaultShippingAddressCode);
                displayShippingAddress(Array.isArray(defaultAddress)
                    ? defaultAddress[0]
                    : defaultAddress);
                saveAddresses();
            }
        });

        var changeAddressButton = $('#change-address').dxButton({
            icon: '/Ecommerce/site/themes/images/changeAddress.png',
            text: 'Change Address',
            disabled: true,
            onClick: function () {
                addressPopUp.show();
            },
        }).dxButton('instance');

        //PAYMENT BUTTONS
        var btnInvoice = $('#invoiceBtn').dxButton({
            icon: '/Ecommerce/site/themes/images/invoice.png',
            text: 'Invoice',
            visible: false,
            onClick: function (e) {
                PaymentMethod == InvoiceMethod;
                //switchPaymentMethod(InvoiceMethod);
            }
        }).dxButton('instance');

        var btnCreditCard = $('#credit-cardBtn').dxButton({
            icon: '/Ecommerce/site/themes/images/creditCard.png',
            text: 'Credit Card',
            visible: false,
            onClick: function (e) {
                PaymentMethod = CCMethod;
                //switchPaymentMethod(CCMethod);
            }
        }).dxButton('instance');

        var btnCancel = $('#btnCancel').dxButton({
            text: 'Cancel',
            elementAttr: {
                class: 'btn btn-primary btn-sm'
            },
            onClick: function () {
                var result = DevExpress.ui.dialog.confirm('Are you sure you want to cancel checkout and return to the cart?', 'Cancel Checkout');
                result.done(function (success) {
                    if (success) {
                        CheckoutLoadPanel.option('message', 'Cancelling Checkout ...');
                        CheckoutLoadPanel.show();
                        MakeAJAXCall('Order.CancelCheckOut', {}, validateCancel);

                    }
                });
            }
        }).dxButton('instance');

        // PAYMENT DETAIL SCRIPTS

        var ccDetailForm = $('#ccDetails').dxForm({
            items: [{
                itemType: 'group',
                cssClass: 'inputRow',
                name: 'section4',
                colCount: 1,
                items: [{
                    dataField: 'CardHolder',
                    editorType: 'dxTextBox',
                    label: {
                        location: 'top'
                    },
                    editorOptions: {
                        placeholder: 'Name on Card',
                    }
                },
                {
                    dataField: 'CardNumber',
                    editorType: 'dxTextBox',
                    label: {
                        location: 'top'
                    },
                    editorOptions: {
                        placeholder: 'XXXX XXXX XXXX XXXX',
                        elementAttr: { id: 'txtCreditCardNumber' },
                        onValueChanged: function (e) {
                        }
                    }
                },
                {
                    dataField: 'ExpiryDate',
                    editorType: 'dxTextBox',
                    label: {
                        location: 'top'
                    },
                    editorOptions: {
                        width: '45',
                        placeholder: 'MM/YYYY'
                    }
                },
                {
                    dataField: 'CVS',
                    editorType: 'dxTextBox',
                    label: {
                        location: 'top'
                    },
                    editorOptions: {
                        width',
                        placeholder: 'XXX'
                    }
                }]
            }],
            visible: false,
        }).dxForm('instance');

        //PROMO CODE

        var promoCodeDetail = $('#PromotionalCode').dxTextBox({
            placeholder: 'Enter Code and Apply',
        }).dxTextBox('instance');

        var promoButton = $('#btnApplyPromo').dxButton({
            text: 'APPLY',
            onClick: function (e) {
                var promoCode = promoCodeDetail.option('value');
                if (promoCode !== null && promoCode !== '') {
                    // validate and apply the promo
                    MakeAJAXCall("Order.ApplyWebPromotion", {
                        PromotionCode: promoCode
                    }, validatePromo);
                }
                else {
                    // remove any existing promo
                    MakeAJAXCall("Order.RemoveWebPromotion", {}, validatePromo);
                }
            }
        });

        $('#icon-submit').dxButton({
            icon: 'fa fa-long-arrow-right',
            text: 'Submit Order',
            onClick: function (e) {
                // do we show a speedbump or go right to checkout processing?
                if ('ConfirmationMessageText' in OrderData) {
                    // show confirmation message
                    var result = DevExpress.ui.dialog.confirm(OrderData.ConfirmationMessageText, 'Confirm Order');
                    result.done(function (success) {
                        if (success) {
                            processOrder();
                        }
                    });
                }
                else {
                    // no confirmation message, just go and process the order
                    processOrder();
                }
            }
        });


        var formatDate = new Intl.DateTimeFormat('en-US').format;

        var itemDetails = $('#cart-grid').dxDataGrid({
            rowTemplate: function (container, item) {
                var data = item.data,

                    markup = '<div class="cartRow ' + ((data.rowIndex % 2) ? 'dx-row-alt' : '') + '">' +
                        '<div class="cartDetails row">' +
                        '<div class="col-sm-2 col-md-2 col-lg-1"><img src="' + data.Photo1 + '" /></div>' +
                        '<div class="col-sm-2 col-md-2 col-lg-3">' +
                        '<div class="item-name productDetails">' + data.Description + '</div>' +
                        '<div class="item-stockcode productDetails">' + data.StockCode + '</div>' +
                        '</div>' +
                        '<div class="col-sm-2 price"><label class="visible-xs">Price:</label>' + data.WebPrice + '</div>' +
                        '<div class="col-xs-6 col-sm-2 quantity"><label class="visible-xs">Qty: </label>' + data.Quantity + '</div>' +
                        '<div class="col-sm-2 price"><label class="visible-xs">Backordered:</label>' + ((data.IsBackordered) ? 'Yes' : '') + '</div>' +
                        '<div class="col-sm-2 price"><label class="visible-xs">Total Price:</label>' + data.TotalPrice + '</div>' +
                        '</div>' +
                        '</div>';
                container.append(markup);
            },
            loadPanel: {
                enabled: false
            },
            showBorders: false,
            columns: [
                'column'
            ]

        }).dxDataGrid('instance');


        var addressList = $('#divMultiAddressList').dxList({
            visible: true,
            itemTemplate: $('#tmplMultiAddress'),
            showSelectionControls: true,
            selectionMode: 'single',
            height: 400,
            keyExpr: 'AddressCode',
        }).dxList('instance');

        var oneTimeAddressForm = $('#divOneTimeAddressForm').dxForm({
            items: [{
                itemType: 'group',
                cssClass: 'inputRow',
                colCount: 1,
                items: [{
                    dataField: 'ShipToName',
                    editorType: 'dxTextBox',
                    label: {
                        location: 'top',
                        text: 'Ship To Name'
                    },
                    editorOptions: {
                        onValueChanged: function (e) {
                            OneTimeAddressData.ShipToName = e.value;
                            if (e.value.indexOf(' ') < 1) {
                                oneTimeAdressData.FirstName = e.value;
                            }
                            else {
                                var arrName = e.value.split(" ");
                                OneTimeAddressData.FirstName = arrName.slice(0, 1).join(' ');
                                OneTimeAddressData.LastName = arrName.slice(1, arrName.length).join(' ');
                            }
                        },
                    }
                },
                {
                    dataField: 'Addresss1',
                    editorType: 'dxTextBox',
                    label: {
                        location: 'top',
                        text: 'Address'
                    },
                    editorOptions: {
                        onValueChanged: function (e) {
                            OneTimeAddressData.Address1 = e.value;
                        },
                    }
                },
                {
                    dataField: 'Address2',
                    editorType: 'dxTextBox',
                    label: {
                        visible: false,
                    },
                    editorOptions: {
                        onValueChanged: function (e) {
                            OneTimeAddressData.Address2 = e.value;
                        },
                    }
                },
                {
                    dataField: 'Address3',
                    editorType: 'dxTextBox',
                    label: {
                        visible: false,
                    },
                    editorOptions: {
                        onValueChanged: function (e) {
                            OneTimeAddressData.Address3 = e.value;
                        },
                    }
                }
                ]
            },
            {
                itemType: 'group',
                cssClass: 'inputRow',
                colCount: 3,
                items: [{
                    dataField: 'City',
                    editorType: 'dxTextBox',
                    label: {
                        location: 'top',
                        text: 'City'
                    },
                    editorOptions: {
                        onValueChanged: function (e) {
                            OneTimeAddressData.City = e.value;
                        },
                    }
                },
                {
                    dataField: 'State',
                    editorType: 'dxSelectBox',
                    label: {
                        location: 'top',
                        text: 'State'
                    },
                    editorOptions: {
                        dataSource: {
                            store: GetStateStoreByCountry(_Currency.CountryCode),
                            pageSize: 5,
                            paginate: true,
                        },
                        elementAttr: {
                            id: 'stateSelectId',
                        },
                        inputAttr: {
                            autocomplete: 'test-autocomplete'
                        },
                        displayExpr: 'StateName',
                        valueExpr: 'StateCode',
                        searchEnabled: true,
                        onValueChanged: function (e) {
                            OneTimeAddressData.State = e.value;
                        }
                    }
                },
                {
                    dataField: 'Zip',
                    editorType: 'dxTextBox',
                    label: {
                        location: 'top',
                        text: 'Zip'
                    },
                    editorOptions: {
                        onValueChanged: function (e) {
                            OneTimeAddressData.Zip = e.value;
                        },
                    }
                },
                ]
            },
            {
                itemType: 'group',
                cssClass: 'inputRow',
                colCount: 2,
                items: [
                    {
                        dataField: 'Country',
                        editorType: 'dxSelectBox',
                        label: {
                            location: 'top',
                            text: 'Country'
                        },
                        editorOptions: {
                            dataSource: {
                                store: _CountryStore._array.filter(getVisibleCountries => getVisibleCountries.UseCountry == true),
                                pageSize: 5,
                                paginate: true,
                            },
                            elementAttr: {
                                id: 'CountrySelectId',
                            },
                            inputAttr: {
                                autocomplete: 'test-autocomplete'
                            },
                            displayExpr: 'CountryName',
                            valueExpr: 'CountryCode',
                            searchEnabled: true,
                            onValueChanged: function (e) {
                                oneTimeAddressForm.getEditor('State').reset();
                                oneTimeAddressForm.getEditor('State').option('dataSource', GetStateStoreByCountry(e.value));
                                OneTimeAddressData.Country = e.value;
                            },
                            onInitialized: function (e) {
                                var c = GetObjectFromArrayByKeyValue(_CountryStore._array, 'CountryCode', _Currency.CountryCode.toUpperCase());
                                e.component.option('value', c[0].CountryCode.toUpperCase());
                                OneTimeAddressData.Country = c[0].CountryCode.toUpperCase();
                            }
                        }
                    },

                    {
                        dataField: 'Phone',
                        editorType: 'dxTextBox',
                        label: {
                            location: 'top',
                            text: 'Phone'
                        },
                        editorOptions: {
                            onValueChanged: function (e) {
                                OneTimeAddressData.Phone = e.value;
                            },
                        }
                    }]
            }],
        }).dxForm('instance');

        var addressPopUp = $('#popMultiAddress').dxPopup({
            title: 'Additional Shipping Address',
            visible: false,
            height: 600,
            width: 600,
            onShowing: function () {
                if ($('#divMultiAddressWrapper').css('display') == 'none' &&
                    $('#divOneTimeAddressWrapper').css('display') == 'none') {
                    $('#divMultiAddressWrapper').css('display', 'block');
                }
            },
            toolbarItems: [{
                widget: 'dxButton',
                location: 'before',
                toolbar: 'bottom',
                options: {
                    text: '+ Add a One-Time Address',
                    onClick: function () {
                        $('#btnAddOneTimeAddress').dxButton('instance').option('visible', false);
                        $('#btnSelectOnFile').dxButton('instance').option('visible', true);

                        $('#divMultiAddressWrapper').css('display', 'none');
                        $('#divOneTimeAddressWrapper').css('display', 'block');
                    },
                    elementAttr: {
                        class: 'popupToolbarButton add',
                        id: 'btnAddOneTimeAddress'
                    },
                }
            }, {
                widget: 'dxButton',
                location: 'before',
                toolbar: 'bottom',
                options: {
                    text: 'Back to Address List',
                    onClick: function () {
                        $('#btnSelectOnFile').dxButton('instance').option('visible', false);
                        $('#btnAddOneTimeAddress').dxButton('instance').option('visible', true);
                        $('#divOneTimeAddressWrapper').css('display', 'none');
                        $('#divMultiAddressWrapper').css('display', 'block');
                    },
                    elementAttr: {
                        class: 'popupToolbarButton add',
                        id: 'btnSelectOnFile'
                    },
                    visible: false
                }
            }, {
                widget: 'dxButton',
                location: 'after',
                toolbar: 'bottom',
                options: {
                    text: 'Use This Address',
                    onClick: function (e) {
                        if ($('#btnSelectOnFile').dxButton('instance').option('visible')) {
                            displayShippingAddress(OneTimeAddressData);
                        }
                        else {
                            var selectedKey = addressList.option('selectedItemKeys');
                            var selectedKeyIndex = AddressData.Addresses.findIndex(function (address) {
                                return address.AddressCode == selectedKey
                            });
                            displayShippingAddress(AddressData.Addresses[selectedKeyIndex]);
                        }
                        addressPopUp.hide();
                        saveAddresses();
                    },
                    elementAttr: {
                        class: 'popupToolbarButton change',
                        id: 'btnUseThisAddress'
                    },
                }
            }],
        }).dxPopup('instance');

        function populateShipping(DATA) {
            if (ValidAJAXResponse(DATA)) {
                // build our objects for handling
                var d = JSON.parse(DATA);
                var methods = d.Data.Methods;
                if (methods.length == 0) {
                    // no methods returned, set messaging and fallback vale of shipping method ID
                    shippingInfoForm.itemOption('section2.ShippingMethod', {
                        label: {
                            text: 'Shipping To Be Set Off-line'
                        }
                    });
                    shippingInfoForm.getEditor('ShippingMethod').option({
                        visible: false
                    });
                    ShippingOptions.ShippingMethodID = -1;
                    $('#spnShippingCost').text('TBD');

                }
                else {
                    // get the method_ID into the value of the drop down to extract
                    // shipping ID from the text string in the editor's onValueChanged function
                    shippingInfoForm.getEditor('ShippingMethod').option({
                        dataSource: methods,
                        value: (methods.length > 0)
                            ? methods[0].Method_ID
                            : -1,
                        disabled: false
                    });
                }

            }
        }

        function buildPaymentMethods(DATA) {
            if (ValidAJAXResponse(DATA)) {
                // build our objects for handling
                var d = JSON.parse(DATA);
                var methods = d.Data.Methods;

                if (d.Data.MethodCount > 0) {
                    for (var i = 0; i < methods.length; i++) {
                        if (methods[i].MethodType == 'IN') {
                            InvoiceMethod = methods[i];
                            showInvoice();
                            break;
                        }
                    }
                    for (var i = 0; i < methods.length; i++) {
                        if (methods[i].MethodType == 'CC') {
                            CCMethod = methods[i];
                            showCreditCard();
                            break;
                        }
                    }
                }
                var p = GetObjectFromArrayByKeyValue(methods, 'MethodName', OrderData.MethodName);
                PaymentMethod = (Array.isArray(p))
                    ? p[0]
                    : p;

                MakeAJAXCall('Visitor.GetShippingAddresses', {}, populateAddresses);
            }
        }

        function populateProfile(DATA, setupResponse) {
            if (ValidAJAXResponse(DATA)) {
                // build our objects for handling
                var response = JSON.parse(DATA);
                var result = response.Result;
                if (result.Success) {
                    AccountProfile = response.Data;
                }

                // run any custom load processing before painting the checkout form
                if (typeof populateProfile_customization === 'function') { populateProfile_customization(setupResponse.Result, setupResponse.Data); }
            }
        }


        // Modify the body of the populateProfile_customization function to accomodate any custom processing requirements that are conditional on
        // the presence of any data contained in the Account Profile, if any
        // if no customizations, then leave the body blank with just a return statement like so
        //
        /*
            function populateProfile_customization(resultObj, dataObj) {
                return;
            }
        */
        function populateProfile_customization(resultObj, dataObj) {
            return;
        }

        function showInvoice() {
            $('.checkoutIcon.invoice').css('display', 'block')
            btnInvoice.option('visible', true);
            $('.invoice').css('display', 'block');
        }

        function showCreditCard() {
            $('.checkoutIcon.cc').css('display', 'block')
            btnCreditCard.option('visible', true);
            ccDetailForm.option('visible', true);
            $('.credit').css('display', 'block');
        }

        function getPaymentParams() {
            var cardType = '',
                ccNumber = '',
                ccCVN = '',
                ccMonth = '',
                ccYear = '',
                ccFirst = ''
            ccLast = '';

            if (PaymentMethod.MethodType == 'CC') {
                $('#txtCreditCardNumber').find('input').validateCreditCard(function (result) {
                    cardType = result.card_type.name;
                });
                ccNumber = ccDetailForm.getEditor('CardNumber').option('value');
                ccCVN = ccDetailForm.getEditor('CVS').option('value');
                ccMonth = ccDetailForm.getEditor('ExpiryDate').option('value').substring(0, 2);
                ccYear = ccDetailForm.getEditor('ExpiryDate').option('value').substring(3);
                var name = ccDetailForm.getEditor('CardHolder').option('value').split(' ');
                ccFirst = name[0];
                if (name.length > 1) {
                    ccLast = name[name.length - 1].trim();
                }
            }

            var paymentInfo = {
                PaymentMethod_ID: PaymentMethod.PaymentMethod_ID,
                CreditCardType: cardType.toUpperCase(),
                CreditCardNumber: ccNumber,
                CreditCardVerification: ccCVN,
                CreditCardMonth: ccMonth,
                CreditCardYear: ccYear,
                CreditCardFirstName: ccFirst,
                CreditCardLastName: ccLast,
                PONumber: orderDetailsForm.getEditor('PO').option('value')
            }
            return paymentInfo;
        }


        function saveAddresses() {
            MakeAJAXCall("Order.SaveOrderAddresses", {
                ShippingCode: OrderAddresses.ShippingAddress.AddressCode,
                ShippingFirstName: OrderAddresses.ShippingAddress.FirstName,
                ShippingLastName: OrderAddresses.ShippingAddress.LastName,
                ShippingAddress1: OrderAddresses.ShippingAddress.Address1,
                ShippingAddress2: OrderAddresses.ShippingAddress.Address2,
                ShippingAddress3: OrderAddresses.ShippingAddress.Address3,
                ShippingCity: OrderAddresses.ShippingAddress.City,
                ShippingState: OrderAddresses.ShippingAddress.State,
                ShippingZip: OrderAddresses.ShippingAddress.Zip,
                ShippingCountry: OrderAddresses.ShippingAddress.Country,
                ShippingPhone: OrderAddresses.ShippingAddress.Phone,
                ShippingTaxArea: OrderAddresses.ShippingAddress.TaxArea || '',
                ShippingTaxCity: OrderAddresses.ShippingAddress.TaxCity || '',
                ShippingTaxState: OrderAddresses.ShippingAddress.TaxState || '',
                ShippingTaxCountyZip: OrderAddresses.ShippingAddress.TaxCountyZip || '',
                ShippingIsDropShip: OrderAddresses.ShippingAddress.IsDropShip,
                BillingFirstName: OrderAddresses.BillingAddress.FirstName,
                BillingLastName: OrderAddresses.BillingAddress.LastName,
                BillingAddress1: OrderAddresses.BillingAddress.Address1,
                BillingAddress2: OrderAddresses.BillingAddress.Address2,
                BillingAddress3: OrderAddresses.BillingAddress.Address2,
                BillingCity: OrderAddresses.BillingAddress.City,
                BillingState: OrderAddresses.BillingAddress.State,
                BillingZip: OrderAddresses.BillingAddress.Zip,
                BillingCountry: OrderAddresses.BillingAddress.Country,
                BillingPhone: OrderAddresses.BillingAddress.Phone

            }, shippingUpdated);
        }

        function shippingUpdated(DATA) {
            if (ValidAJAXResponse(DATA)) {
                // build our objects for handling
                var response = JSON.parse(DATA);
                var result = response.Result;
                if (result.Success) {
                    MakeAJAXCall('Order.SetupOrder', {}, loadData, {
                        getPayments: false,
                        getProfile: false
                    });
                    ToastAlert("Shipping address updated.", true, 5000);
                } else {
                    ToastAlert(result.Message, false);
                }
            }
        }

        function validatePromo(DATA) {
            if (ValidAJAXResponse(DATA)) {
                // build our objects for handling
                var response = JSON.parse(DATA);
                var result = response.Result;

                var promoCode = promoCodeDetail.option('value');

                if (result.Success) {
                    // promo was applied tell the user what happened
                    ToastAlert(result.Message, true, 5000);
                    // reload the order
                    MakeAJAXCall('Order.SetupOrder', {}, loadData, {
                        getShipping: false,
                        getPayments: false,
                        getProfile: false
                    });
                }
                else {
                    // promo not applied
                    ToastAlert(String.Format('The web promotion code \'{0}\' could not be applied. {0}. Please try again.', promoCode, result.Message), false);
                    promoCodeDetail.option('value', '');
                }
            }
            else {
                ToastAlert(String.Format('The web promotion entered could not be applied. {0}. Please try again.', result.Message), false);
            }
        }

        function validateCancel(DATA) {
            if (ValidAJAXResponse(DATA)) {
                // build our objects for handling
                var response = JSON.parse(DATA);
                var result = response.Result;
                if (result.Success) {
                    window.location.replace(SITE_PATHS.application + '/ShoppingCart.aspx');
                    return;
                }
            }
            CheckoutLoadPanel.hide();
            DevExpress.ui.dialog.alert('There was a problem while attempting to cancel your checkout. Please try again.', 'Alert');
        }

        function populateAddresses(DATA) {
            if (DATA === '') { return; }
            // build our objects for handling
            var response = JSON.parse(DATA);
            var result = response.Result;

            if (result.Success) {
                AddressData = response.Data;

                AddressData.Addresses.forEach(function (address, i) {
                    if (address.AddressCode === AddressData.DefaultShippingAddressCode) {
                        AddressData.Addresses.splice(i, 1);
                        AddressData.Addresses.unshift(address);
                    }
                });

                addressList.option({
                    dataSource: AddressData.Addresses
                });

                var defaultAddressIndex = AddressData.Addresses.findIndex(function (address) {
                    return address.AddressCode == AddressData.DefaultShippingAddressCode
                });

                addressList.selectItem(defaultAddressIndex);

                changeAddressButton.option('disabled', false);
            }
        }

        function displayShippingAddress(address) {
            if (!('IsDropShip' in address)) {
                address.IsDropShip = false;
            }
            OrderAddresses.ShippingAddress = address;
            $('#divShippingCompany').text((address.ShipToName == null) ? '' : address.ShipToName);
            if (address.ShipToName != address.FirstName && address.ShipToName != address.FirstName + ' ' + address.LastName) {
                $('#spnShippingFirstName').text((address.FirstName == null) ? '' : address.FirstName);
                $('#spnShippingLastName').text((address.LastName == null) ? '' : address.LastName);
            }
            else {
                $('#spnShippingFirstName').text('');
                $('#spnShippingLastName').text('');
            }
            $('#divShippingAddress1').text((address.Address1 == null) ? '' : address.Address1);
            $('#divShippingAddress2').text((address.Address2 == null) ? '' : address.Address2);
            $('#divShippingAddress3').text((address.Address3 == null) ? '' : address.Address3);
            $('#spnShippingCity').text((address.City == null) ? '' : address.City);
            $('#spnShippingState').text((address.State == null) ? '' : address.State);
            $('#spnShippingZipCode').text((address.Zip == null) ? '' : address.Zip);
            $('#divShippingCountry').text((address.Country == null) ? '' : address.Country);
        }

        function displayBillingAddress(address) {
            OrderAddresses.BillingAddress = address;
            $('#divBillingAddress1').text(OrderData.BillingAddress1);
            $('#divBillingAddress2').text(OrderData.BillingAddress2);
            $('#divBillingAddress3').text(OrderData.BillingAddress3);
            $('#spnBillingCity').text(OrderData.BillingCity);
            $('#spnBillingState').text(OrderData.BillingState);
            $('#spnBillingZipCode').text(OrderData.BillingZip);
            $('#divBillingCountry').text(OrderData.BillingCountry);
            $('#divBillingPhone').text(OrderData.BillingPhone);
        }

        function finishOrder(DATA) {
            if (ValidAJAXResponse(DATA)) {
                // build our objects for handling
                var response = JSON.parse(DATA);
                var result = response.Result;
                if (result.Success) {
                    window.location.replace(SITE_PATHS.application + '/CheckOutDisplayOrderReceipt.aspx');
                }
                else {
                    DevExpress.ui.dialog.alert(result.Message, 'Order Error');
                    CheckoutLoadPanel.hide();
                }
            }
        }

        // TODO: this won't work, the fields disappear
        /*
        function switchPaymentMethod(methodObj) {
            PaymentMethod = methodObj;
            if ('PODisplay' in methodObj) {
                switch (methodObj.PODisplay) {
                    case "R": // ask for PO AND required
                        if ('ReferenceLabel' in methodObj) {
                            orderDetailsForm.itemOption('section1.PO', {
                                label: {
                                    text: methodObj.ReferenceLabel,
                                    location: top
                                },
                                visible: true,
                                validationRules: [{
                                    type: 'required',
                                    message: String.Format('{0} is required.', methodObj.ReferenceLabel || 'A PO')
                                }],
                            });
                        }
                        break;

                    case "N": // Don't ask for PO
                        orderDetailsForm.itemOption('section1.PO', {
                            visible: false,
                            validationRules: [],
                        });
                        break;

                    case "Y": // ask for PO, not required
                        if ('ReferenceLabel' in methodObj) {
                            orderDetailsForm.itemOption('section1.PO', {
                                label: {
                                    text: methodObj.ReferenceLabel,
                                    location: top
                                },
                                validationRules: [],
                                visible: true
                            });
                        }

                        break;
                }
            }

        }
        */

        function validateShippingOptions(DATA) {
            if (ValidAJAXResponse(DATA)) {
                // build our objects for handling
                var response = JSON.parse(DATA);
                var result = response.Result;
                // check for success
                if (!result.Success) {
                    CheckoutLoadPanel.hide();
                    DevExpress.ui.dialog.alert(result.Message);
                }
                else {
                    MakeAJAXCall('Order.SaveOrderPayment', getPaymentParams(), validatePayment);
                }
            }
        }

        function validatePayment(DATA) {
            if (ValidAJAXResponse(DATA)) {
                // build our objects for handling
                var response = JSON.parse(DATA);
                var result = response.Result;
                // check for failure
                if (!result.Success) {
                    CheckoutLoadPanel.hide();
                    DevExpress.ui.dialog.alert(result.Message);
                }
                else {
                    //
                    // we succeeded getting data back from the previous MakeAJAXCall, so let's now process the order
                    //
                    if (_.isEmpty(CustomOrderData)) {
                        // process the order without CustomData
                        MakeAJAXCall('Order.ProcessOrder', {}, finishOrder);
                    }
                    else {
                        // the CustomOrderData object has been populated, so we will process the order with the CustomData
                        MakeAJAXCall('Order.ProcessOrderWithCustomData', { CustomData: CustomOrderData }, finishOrder);
                    }
                }
            }
        }

        function processOrder() {
            CheckoutLoadPanel.option('message', 'Processing Order ...');
            CheckoutLoadPanel.show();
            MakeAJAXCall('Order.SaveShippingOptions', ShippingOptions, validateShippingOptions);
        }

       
        ///-------------------------------------------------------------------------------------------------
        /// <summary>
        ///     returns an Array of States based on the countryCode.
        /// </summary>
        ///
        /// <param name='countryCode'>
        ///     countryCode inthis case currency CountyCode
        /// </param>
        ///
        /// <returns>
        ///     returns an Array of States
        /// </returns>
        ///-------------------------------------------------------------------------------------------------
        function GetStateStoreByCountry(CountryCode) {
            try {
                var statesArr;
                var vCountries = [];
                var vCountries = _CountryStore._array.filter(getVisibleCountries => getVisibleCountries.UseCountry == true);

                if (!vCountries.some(item => item.CountryCode === CountryCode.toUpperCase())) {
                    statesArr = [];
                    return statesArr;
                }
                if (CountryCode === null || CountryCode == "undefined" || CountryCode === "") {
                    statesArr = [];
                    return statesArr;
                }
                var c = GetObjectFromArrayByKeyValue(_CountryStore._array, 'CountryCode', CountryCode.toUpperCase());
                if (c[0].States.length > 0) {
                    allStatesArr = c[0].States;
                    statesArr = allStatesArr.filter(getvisibleStates => getvisibleStates.UseState == true);
                } else {
                    statesArr = [];
                }
                return statesArr;
            } catch (err) {
                statesArr = [];
                return statesArr;
            }
        }

        // now that everything is setup, let's setup the order and get going
        MakeAJAXCall('Order.SetupOrder', {}, loadData);
    });

</script>
<div id="divLoadPanel"></div>

<div id="divCheckoutWrapper" class="container-fluid no-gutter">
    <h2>Checkout</h2>
    <section class="row checkoutOrder">
        <h3><span>1.</span>Order Details</h3>
        <div class="col-xs-12">
            <div class="inputRow col-xs-12">
                <div id="orderDetails"></div>
            </div>
        </div>
    </section>
    <section class="row checkoutShipping">
        <h3><span>2.</span> Shipping Information</h3>
        <div class="col-xs-12 no-gutter">
            <div class="col-sm-6">
                <div id="shippingInfo"></div>
            </div>
            <div class="col-sm-5">
                <div class="checkoutIcon col-xs-5">
                    <div class="dx-field">
                        <div class="dx-field-value">
                            <div id="default-address"></div>
                        </div>
                    </div>
                </div>
                <div class="checkoutIcon col-xs-5">
                    <div class="dx-field-value">
                        <div id="change-address"></div>
                    </div>
                </div>
                <div class="col-xs-12 shippingInfo">
                    <div id="divShippingCompany"></div>
                    <div><span id="spnShippingFirstName"></span> <span id="spnShippingLastName"></span></div>
                    <div id="divShippingAddress1"></div>
                    <div id="divShippingAddress2"></div>
                    <div id="divShippingAddress3"></div>
                    <div><span id="spnShippingCity"></span>, <span id="spnShippingState"></span> <span id="spnShippingZipCode"></span></div>
                    <div id="divShippingCountry"></div>

                </div>
                <div class="col-xs-12 billingInfo">
                    <h3>Billing Info</h3>
                    <div class="col-sm-6 no-gutter">
                        <div id="divBillingCompany"></div>
                        <div id="divBillingAddress1"></div>
                        <div id="divBillingAddress2"></div>
                        <div id="divBillingAddress3"></div>
                        <div><span id="spnBillingCity"></span>, <span id="spnBillingState"></span> <span id="spnBillingZipCode"></span></div>
                        <div id="divBillingCountry"></div>
                    </div>
                    <div class="col-sm-6 no-gutter">
                        <div id="divBillingPhone"></div>
                        <div id="divEmail"></div>
                    </div>
                </div>
            </div>
    </section>
    <section class="row checkoutPayment">
        <h3><span>3.</span>Payment Info</h3>
        <div class="col-xs-12 no-gutter">
            <div class="col-sm-6">
                <!-- Nav tabs -->
                <ul class="nav col-sm-4 right-gutter" role="tablist">
                    <li role="presentation">
                        <div class="checkoutIcon col-xs-5 col-sm-12 invoice">
                            <a href="#invoice" aria-controls="invoice" role="tab" data-toggle="tab">
                                <div class="dx-field">
                                    <div class="dx-field-value">
                                        <div id="invoiceBtn"></div>
                                    </div>
                                </div>
                            </a>
                        </div>
                    </li>
                    <li role="presentation">
                        <div class="checkoutIcon col-xs-5 col-sm-12 credit">
                            <a href="#credit" aria-controls="credit" role="tab" data-toggle="tab">
                                <div class="dx-field">
                                    <div class="dx-field-value">
                                        <div id="credit-cardBtn"></div>
                                    </div>
                                </div>
                            </a>
                        </div>
                    </li>
                </ul>
                <!-- Tab panes -->
                <div class="tab-content col-sm-7">
                    <div role="tabpanel" class="tab-pane active" id="invoice">
                        <div id="invoiceDetails"></div>
                    </div>
                    <div role="tabpanel" class="tab-pane " id="credit">
                        <div id="ccDetails"></div>
                    </div>
                </div>
            </div>
            <div class="col-sm-5">
                <div class="inputRow col-xs-12 no-gutter">
                    <div class="dx-field">
                        <div class="dx-field-label">Promotional Code:</div>
                        <div class="dx-field-value">
                            <div id="PromotionalCode"></div>
                            <div id="btnApplyPromo" class="btn btn-primary btn-sm"></div>
                        </div>
                    </div>
                    <div class="alert col-xs-12 no-gutter">
                        <p>Credit card accounts receive a pre-authorization of 10% to cover shipping costs. This will fall off when the lowest shipping rate has been calculated, similar to a hotel or gas pump.</p>
                    </div>
                </div>
            </div>
    </section>
    <section class="row clear checkoutDetails">
        <div class="col-xs-12 totalsRow">
            <div class="col-sm-12 col-md-5 col-md-offset-1">
                <div class="inputRow col-xs-12">
                    <div class="col-xs-7"><span>Subtotal</span></div>
                    <div class="col-xs-4 amount"><span id="spnSubtotal"></span></div>
                </div>
                <div class="inputRow col-xs-12">
                    <div class="col-xs-7"><span>Estimated Shipping</span></div>
                    <div class="col-xs-4 amount"><span id="spnShippingCost"></span></div>
                </div>
                <div class="inputRow col-xs-12 tax">
                    <div class="col-xs-7"><span>Estimated Taxes</span></div>
                    <div class="col-xs-4 amount"><span id="spnTax"></span></div>
                </div>
                <div class="inputRow col-xs-12 gstTax">
                    <div class="col-xs-7"><span>Estimated GST Taxes</span></div>
                    <div class="col-xs-4 amount"><span id="spnGSTTax"></span></div>
                </div>
                <div class="inputRow col-xs-12 promo">
                    <div class="col-xs-7"><span>Promotional Discount</span></div>
                    <div class="col-xs-4 amount"><span id="spnPromoValue"></span></div>
                </div>
                <div class="inputRow totalpriceRow col-xs-12">
                    <div class="col-xs-7"><span>Total</span></div>
                    <div class="col-xs-4 amount"><span id="spnOrderTotal"></span></div>
                </div>
            </div>
            <div class="col-sm-1 hidden-xs"></div>

            <div class="dx-field-value col-sm-12 col-md-4 checkoutSubmit">
                <div id="icon-submit" class="btn btn-primary btn-lgd"></div>
            </div>
        </div>
        <div class="cartDetails col-xs-12">

            <div class="cartTitles row">
                <div class="col-sm-4 productDetails">Product Details</div>
                <div class="col-sm-2  hidden-xs">Price</div>
                <div class="col-sm-2  hidden-xs">Quantity</div>
                <div class="col-sm-2  hidden-xs">Backordered</div>
                <div class="col-sm-2  hidden-xs">Total Price</div>
            </div>
            <div id="cart-grid"></div>
            <div id="btnCancel"></div>
        </div>
    </section>
</div>

<div id="popMultiAddress">
    <div id="divMultiAddressWrapper">
        <h4>Choose from the Available Ship To Addresses below.</h4>
        <div id="divMultiAddressList"></div>

    </div>
    <div id="divOneTimeAddressWrapper">
        <h4>Enter a One-Time Shipping Address below.</h4>
        <div id="divOneTimeAddressForm"></div>
    </div>
</div>

<script type="text/html" id="tmplMultiAddress">
    <div><b><%= item.FirstName + ' ' + item.LastName %></b></div>
    <div><%= item.Address1 %></div>
    <div><%= item.Address2 %></div>
    <div><%= item.Address3 %></div>
    <div><%= item.City %> <%= item.State %> <%= item.Zip %></div>
    <div><%= item.Country %></div>
</script>

<script src="js/jquery-creditcardvalidator/jquery.creditCardValidator.js"></script>