Apple Pay Hosted Checkout Sample Code
Last updated
Was this helpful?
Last updated
Was this helpful?
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);
}
}
}
Letβs enable Apple Pay for the website:
document.addEventListener("DOMContentLoaded", function(event) {
.....
ckApplePay.enableApplePay({
initFunction: 'apRequest.initAP',
amountField: 'amount'
});
.....
}
To see the full solution please click .