Click-To-Pay iFields Integration

<!-- Use the following src for the script on your form and replace ****version**** with the desired version: src="https://cdn.cardknox.com/ifields/****version****/ifields.min.js" -->     
<script src="ifields.min.js"></script> 
<script type="text/javascript">
    document.addEventListener("DOMContentLoaded", function(event) { 
        ckClick2Pay.enableClickToPay({
          environment: c2pEnvironment.sandbox, 
          externalClientId: "<Your externalClientId>",
          click2payContainer: "click2payContainer", 
          onPaymentPrefill: click2payRequest.paymentPrefill,
          onPaymentSuccess: click2payRequest.paymentSuccess,
          onPaymentError: click2payRequest.paymentCallback,
          onPaymentCancel: click2payRequest.paymentCallback,
          onButtonLoaded: click2payRequest.cpButtonLoaded
      });            
    });

    const click2payRequest = {
        paymentPrefill: function(){
            const result = {
                merchantRequestId: "Merchant defined request ID",
                currencyCode: "USD",
                description: "...corp Product",
                orderId: "Merchant defined order ID",
                promoCode: "Merchant defined promo code",
                subtotal: roundTo(getAmount(), 2),
                shippingHandling: "2.00",
                tax: "2.00",
                discount: "1.00",
                giftWrap: "2.00",
                misc: "1.00",
                setTotal:  function() {
                    this.total = roundTo(
                        roundToNumber(this.subtotal, 2)
                        + roundToNumber(this.shippingHandling, 2)
                        + roundToNumber(this.tax, 2)
                        + roundToNumber(this.giftWrap, 2)
                        + roundToNumber(this.misc, 2)
                        - roundToNumber(this.discount, 2)
                    , 2);
                    delete this.setTotal;
                    return this;
                },
            }.setTotal();
            logDebug({
                label: "paymentPrefill",
                data: result
            });
            return result;
        },
        authorize: function(payload) {
            return new Promise(function (resolve, reject) {
                var xhr = new XMLHttpRequest();
                xhr.open("POST", "https://<your domain>/<path to handle authorization>");
                xhr.onload = function () {
                    if (this.status >= 200 && this.status < 300) {
                        resolve(xhr.response);
                    } else {
                        reject({
                            status: this.status,
                            statusText: xhr.statusText
                        });
                    }
                };
                xhr.onerror = function () {
                    reject({
                        status: this.status,
                        statusText: xhr.statusText
                    });
                };
                xhr.setRequestHeader("Content-Type", "application/json");
                xhr.send(JSON.stringify(payload));
            });
        },
        paymentSuccess: async function(clickToPayResponse) {
            return new Promise((resolve, reject) => {
                try {
                    const response = await this.authorize(clickToPayResponse);
                    console.log(response);
                    const resp = JSON.parse(response);
                    if (!resp)
                        throw "Invalid response: "+ response;
                    if (resp.xError) {
                        throw resp;
                    }
                    resolve(response);
                } catch (err) {
                    console.error("paymentSuccess error.", JSON.stringify(err));
                    reject(err);
                }
            });
        },                
        paymentCallback: function (clickToPayResponse) {
            click2payRequest.setPayload(clickToPayResponse);
        },
        cpButtonLoaded: function(resp) {
            if (!resp) return;
            if (resp.status === iStatus.success) {
                showHide("click2payContainer", true);
            } else if (resp.reason) {
                console.log(resp.reason);
            }
        },
        setPayload: function (value) {
            document.getElementById('c2p-payload').value = JSON.stringify(value, null, 2);
            showHide("divC2PPayload", value);
        }
    };
    
    function showHide(elem, toShow) {
        if (typeof(elem) === "string") {
            elem = document.getElementById(elem);
        }
        if (elem) {
            toShow ? elem.classList.remove("hidden") : elem.classList.add("hidden");
        }
    }
    function getAmount () {
        return roundToNumber(document.getElementById("amount").value || "0", 2);
    }
</script>
<style> 
    body {
        margin: 10px;
    }
    div.main {
			width: 350px;
		}
    .c2p {
        display: block;
        border: 0;
        width: 260px;
        margin-bottom: 0;
    }
    .c2p .txt-signin{
        width: 90% !important;
    }

    input {
        border: 1px solid black;
        font-size: 14px;
        padding: 3px;
        width: 250px;
        margin-bottom: 12px;
    }

    .hidden {
        display: none;
    }

    textarea {
        border: 1px solid black;
        width: 100%;
    }
</style>
</head>
<body>
<div class="main">
<form id="payment-form" method="POST">
    <input id="amount" name="xAmount" placeholder="Amount" type="number" inputmode="decimal"></input>
    <br/>
    <div id="click2payContainer" class="c2p hidden">
        <br/>
    </div>
    <br/>
    <div id="divC2PPayload" class="hidden">
        <label id="lbc2pPayload">Click-To-Pay Payload: </label>
        <br />
        <textarea id="c2p-payload" rows="10" readonly="true"></textarea>
        <br/>
    </div>
</form>
</div>
</body>    

Last updated