Cardknox is now Sola
Learn More
LogoLogo
Contact Us
  • Introduction
  • πŸ”—API
    • Transaction API
      • Credit Card
      • Check (ACH)
      • EBT
      • Gift Card
      • Fraud
    • Customer and Recurring API
    • Reporting API
    • Account Boarding API
      • Account Boarding Merchant Agreement
      • Account Boarding Swagger UI
    • Code Samples
    • Error Codes
  • πŸ“¦SDK
    • .NET SDK
      • Transaction Workflow
    • iOS SDK
      • iOS SDK - Technical Guide
      • Workflow
    • Android SDK
      • Android SDK - Technical Guide
  • 🧰 Cardknox Products
    • 3D Secure 2.0
      • Client-Side Integration
        • Client-Side Integration (Non-iFields)
      • Server-Side Integration
    • Account Updater
    • Batch Processing
    • Browser-Based POS systems (BBPOS)
    • CloudIM Developer Guide
    • Deep Linking
      • Deep Linking Integration for Third-Party Websites
    • EBT Online
    • Gateway Emulators
    • iFields
      • Angular iFields
    • Merchant Portal
      • FAQ
    • Mobile App
    • Split Capture
    • Tap to Phone - Android
    • Partner Portal
    • PaymentSITE
      • QR Codes for PaymentSITE
    • Webhooks
  • πŸ“±Mobile Wallets
    • Apple Pay Hosted Checkout
      • Apple Pay Hosted Checkout Initial Setup
      • Apple Pay Prerequisites
      • Apple Pay Hosted Checkout Objects Reference (Request)
      • Apple Pay Hosted Checkout Objects Reference (Response)
      • Apple Pay iFields Integration
      • Apple Pay Hosted Checkout Sample Code
      • Apple Pay Features
      • Set up Apple Pay Merchant ID with Cardknox
    • Click-To-Pay - Hosted Checkout
      • Click-To-Pay Initial Setup
      • Click-To-Pay Sample Code
      • Click-To-Pay iFields Integration
      • Click-To-Pay Objects Reference (Request)
      • Click-To-Pay Objects Reference (Response)
    • Google Pay Hosted Checkout
      • Google Pay Control Object
      • Google Pay Request Objects
      • Google Pay Response Objects
      • Google Pay Sample Code
      • iFields Integration
      • Google Pay FAQ
  • πŸ”ŒPlugins
    • Netsuite
      • NetSuite Features and Demo
    • WooCommerce
    • Magento Plugin
    • RMH (Retail Management Hero)
    • RMS (Retail Management Systems)
  • πŸ“–Articles
    • Frequently Asked Questions
    • How to Build POS Integration Flows
    • Card Present Integration Guide
  • Glossary of Terms
Powered by GitBook
On this page

Was this helpful?

Export as PDF
  1. Mobile Wallets
  2. Apple Pay Hosted Checkout

Apple Pay Hosted Checkout Sample Code

Last updated 3 months ago

Was this helpful?

  1. Let's define a helper object with all necessary components:

    const window.apRequest = {
        buttonOptions: {
            buttonContainer: "ap-container",
            buttonColor: APButtonColor.black,
            buttonType: APButtonType.pay
        },
        totalAmount: null,
        taxAmt: null,
        shippingMethod: null,
        creditType: null,
        getTransactionInfo: function (taxAmt, shippingMethod, creditType) {
            try {
                this.shippingMethod = shippingMethod || this.shippingMethod || {
                            "label": "Free Shipping",
                            "amount": "0.00",
                            "type": "final"
                        };
                this.taxAmt = roundToNumber(taxAmt, 4) || this.taxAmt || 0.07;
                this.creditType = creditType || this.creditType;
                const amt = getAmount();
                const lineItems = [
                    {
                        "label": "Subtotal",
                        "type": "final",
                        "amount": amt
                    },
                    this.shippingMethod
                ];
                if (this.creditType === "credit") {
                    lineItems.push({
                        "label": "Credit Card Fee",
                        "amount": roundTo(0.0275*amt, 2),
                        "type": "final"
                    });
                }
                lineItems.push({
                    "label": "Estimated Tax",
                    "amount": roundTo(this.taxAmt*amt, 2),
                    "type": "final"
                });
                let totalAmt = 0;
                lineItems.forEach((item) => {
                    totalAmt += parseFloat(item.amount)||0;
                });
                totalAmt = roundTo(totalAmt, 2);
                this.totalAmount = totalAmt;
                
                return {
                    'lineItems': lineItems,  
                    total: {
                            type:  'final',
                            label: 'Total',
                            amount: totalAmt,
                        }
                };                        
            } catch (err) {
                console.error("getTransactionInfo error ", exMsg(err));
            }
        },  
        onGetTransactionInfo: function () {
            try {
                return this.getTransactionInfo();
            } catch (err) {
                console.error("onGetTransactionInfo error ", exMsg(err));
            }
        },  
        onGetShippingMethods: function()  {
            return [
                {
                    label: 'Free Shipping',
                    amount: '0.00',
                    identifier: 'free',
                    detail: 'Delivers in five business days',
                },
                {
                    label: 'Express Shipping',
                    amount: '5.00',
                    identifier: 'express',
                    detail: 'Delivers in two business days',
                },
            ];
        },
        onShippingContactSelected: function(shippingContact) {
            const self = this;
            return new Promise((resolve, reject) => {
                try {
                    console.log("shippingContact", JSON.stringify(shippingContact));
                    let taxAmt = 0.1;
                    const newShippingMethods = [
                        {
                            label: 'Free Shipping',
                            amount: '0.00',
                            identifier: 'free',
                            detail: 'Delivers in five business days',
                        }                                
                    ];
                    if (shippingContact && shippingContact.administrativeArea) {
                        if (shippingContact.administrativeArea === "NY") {
                            taxAmt = 0.0875;
                            newShippingMethods.push(
                                    {
                                        label: 'Overnight Shipping',
                                        amount: '10.00',
                                        identifier: 'overnight',
                                        detail: 'Delivers in one business days',
                                    }
                                );
                        } else if (shippingContact.administrativeArea === "NJ") {
                            taxAmt = 0.07;
                            newShippingMethods.push(
                                {
                                    label: 'Express Shipping',
                                    amount: '5.00',
                                    identifier: 'express',
                                    detail: 'Delivers in two business days',
                                }
                            );
                        }
                    }
                    const resp = self.getTransactionInfo(taxAmt, newShippingMethods[0]);
                    resp.shippingMethods = newShippingMethods;
                    resolve(resp);                            
                } catch (err) {
                    const apErr = {
                        code: "-101",
                        contactField: "",
                        message: exMsg(err)
                    }
                    console.error("onShippingContactSelected error.", exMsg(err));
                    reject({errors: [err]});
                }
            })                
        },
        onShippingMethodSelected: function(shippingMethod) {
            const self = this;
            return new Promise(function (resolve, reject) {
                try {
                    console.log("shippingMethod", JSON.stringify(shippingMethod));
                    const resp = self.getTransactionInfo(null, shippingMethod);
                    resolve(resp);                            
                } catch (err) {
                    const apErr = {
                        code: "-102",
                        contactField: "",
                        message: exMsg(err)
                    }
                    console.error("onShippingMethodSelected error.", exMsg(err));
                    reject({errors: [err]});
                }
            })                
        },
        onPaymentMethodSelected: function(paymentMethod) {
            const self = this;
            return new Promise((resolve, reject) => {
                try {
                    console.log("paymentMethod", JSON.stringify(paymentMethod));
                    const resp = self.getTransactionInfo(null, null, paymentMethod.type);
                    resolve(resp);                            
                } catch (err) {
                    const apErr = {
                        code: "-102",
                        contactField: "",
                        message: exMsg(err)
                    }
                    console.error("onPaymentMethodSelected error.", exMsg(err));
                    reject({errors: [err]});
                }
            })                
        },
        validateApplePayMerchant: function () {
            return new Promise((resolve, reject) => {
                try {
                    var xhr = new XMLHttpRequest();
                    xhr.open("POST", "https://api.cardknox.com/applepay/validate");
                    xhr.onload = function () {
                        if (this.status >= 200 && this.status < 300) {
                            console.log("validateApplePayMerchant", JSON.stringify(xhr.response));
                            resolve(xhr.response);
                        } else {
                            console.error("validateApplePayMerchant", JSON.stringify(xhr.response), this.status);
                            reject({
                                status: this.status,
                                statusText: xhr.response
                            });
                        }
                    };
                    xhr.onerror = function () {
                        console.error("validateApplePayMerchant", xhr.statusText, this.status);
                        reject({
                            status: this.status,
                            statusText: xhr.statusText
                        });
                    };
                    xhr.setRequestHeader("Content-Type", "application/json");
                    xhr.send();
                } catch (err) {
                    setTimeout(function () { console.log("getApplePaySession error: " + exMsg(err)) }, 100);
                }
            });
        },
        onValidateMerchant: function() {
            return new Promise((resolve, reject) => {
                try {
                    this.validateApplePayMerchant()
                    .then((response) => {
                        try {
                            console.log(response);
                            resolve(response);
                        } catch (err) {
                            console.error("validateApplePayMerchant exception.", JSON.stringify(err));
                            reject(err);
                        }
                    })
                    .catch((err) => {
                        console.error("validateApplePayMerchant error.", JSON.stringify(err));
                        reject(err);
                    });    
                } catch (err) {
                    console.error("onValidateMerchant error.", JSON.stringify(err));
                    reject(err);
                }
            });
        },
        authorize: function(applePayload, totalAmount) {
            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
                    });
                };
                const data = {
                    amount: totalAmount,
                    payload: applePayload
                };
                xhr.setRequestHeader("Content-Type", "application/json");
                xhr.send(JSON.stringify(data));
            });
        },
        onPaymentAuthorize: function(applePayload) {
            return new Promise((resolve, reject) => {
                try {
                    this.authorize(applePayload, this.totalAmount)
                    .then((response) => {
                        try {
                            console.log(response);
                            const resp = JSON.parse(response);
                            if (!resp)
                                throw "Invalid response: "+ response;
                            if (resp.xError) {
                                throw resp;
                            }
                            resolve(response);
                        } catch (err) {
                            throw err;
                            // reject(err);
                        }
                    })
                    .catch((err) => {
                        console.error("authorizeAPay error.", JSON.stringify(err));
                        apRequest.handleAPError(err);
                        reject(err);
                    });    
                } catch (err) {
                    console.error("onPaymentAuthorize error.", JSON.stringify(err));
                    apRequest.handleAPError(err);
                    reject(err);
                }
            });
        },
        onPaymentComplete: function(paymentComplete) {
            if (paymentComplete.response) { //Success
                const resp = JSON.parse(paymentComplete.response);
                if (resp.xRefNum) {
                    setTimeout(function(){ console.log("Thank you for your order:("+resp.xRefNum+")")}, 100);
                } else {
                    setTimeout(function(){ console.log("Thank you for your order.")}, 100);
                }
            } else if (paymentComplete.error) {
                console.error("onPaymentComplete", exMsg(paymentComplete.error));
                handleAPError(paymentComplete.error);
            }                        
        },
        handleAPError: function(err) {
            if (err && err.xRefNum) {
                setTimeout(function(){ alert("There was a problem with your order:("+err.xRefNum+")")}, 100);
            } else {
                setTimeout(function(){ alert("There was a problem with your order:"+exMsg(err))}, 100);
            }
        },
        initAP: function() {
            return {
                buttonOptions: this.buttonOptions,
                merchantIdentifier: "<Your Apple Merchant ID>",
                requiredBillingContactFields: ['postalAddress', 'name', 'phone', 'email'],
                requiredShippingContactFields: ['postalAddress', 'name', 'phone', 'email'],
                onGetTransactionInfo: "apRequest.onGetTransactionInfo",
                onGetShippingMethods: "apRequest.onGetShippingMethods",
                onShippingContactSelected: "apRequest.onShippingContactSelected",
                onShippingMethodSelected: "apRequest.onShippingMethodSelected",
                onPaymentMethodSelected: "apRequest.onPaymentMethodSelected",
                onValidateMerchant: "apRequest.onValidateMerchant",
                onPaymentAuthorize: "apRequest.onPaymentAuthorize",
                onPaymentComplete: "apRequest.onPaymentComplete",
                onAPButtonLoaded: "apRequest.apButtonLoaded",
                isDebug: true
            };
        },
        apButtonLoaded: function(resp) {
            if (!resp) return;
            if (resp.status === iStatus.success) {
                showHide(this.buttonOptions.buttonContainer, true);
                showHide("lbAPPayload", true);
            } else if (resp.reason) {
                console.log(resp.reason);
            }
        }
    }
  2. Let’s enable Apple Pay for the website:

    document.addEventListener("DOMContentLoaded", function(event) { 
        .....
        ckApplePay.enableApplePay({
            initFunction: 'apRequest.initAP',
            amountField: 'amount'
        });
        .....
    }
  3. To see the full solution please click .

πŸ“±
here