Links

Click-To-Pay iFields Integration

1
<!-- 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" -->
2
<script src="ifields.min.js"></script>
3
<script type="text/javascript">
4
document.addEventListener("DOMContentLoaded", function(event) {
5
ckClick2Pay.enableClickToPay({
6
environment: c2pEnvironment.sandbox,
7
externalClientId: "<Your externalClientId>",
8
click2payContainer: "click2payContainer",
9
onPaymentPrefill: click2payRequest.paymentPrefill,
10
onPaymentSuccess: click2payRequest.paymentSuccess,
11
onPaymentError: click2payRequest.paymentCallback,
12
onPaymentCancel: click2payRequest.paymentCallback,
13
onButtonLoaded: click2payRequest.cpButtonLoaded
14
});
15
});
16
17
const click2payRequest = {
18
paymentPrefill: function(){
19
const result = {
20
merchantRequestId: "Merchant defined request ID",
21
currencyCode: "USD",
22
description: "...corp Product",
23
orderId: "Merchant defined order ID",
24
promoCode: "Merchant defined promo code",
25
subtotal: roundTo(getAmount(), 2),
26
shippingHandling: "2.00",
27
tax: "2.00",
28
discount: "1.00",
29
giftWrap: "2.00",
30
misc: "1.00",
31
setTotal: function() {
32
this.total = roundTo(
33
roundToNumber(this.subtotal, 2)
34
+ roundToNumber(this.shippingHandling, 2)
35
+ roundToNumber(this.tax, 2)
36
+ roundToNumber(this.giftWrap, 2)
37
+ roundToNumber(this.misc, 2)
38
- roundToNumber(this.discount, 2)
39
, 2);
40
delete this.setTotal;
41
return this;
42
},
43
}.setTotal();
44
logDebug({
45
label: "paymentPrefill",
46
data: result
47
});
48
return result;
49
},
50
authorize: function(payload) {
51
return new Promise(function (resolve, reject) {
52
var xhr = new XMLHttpRequest();
53
xhr.open("POST", "https://<your domain>/<path to handle authorization>");
54
xhr.onload = function () {
55
if (this.status >= 200 && this.status < 300) {
56
resolve(xhr.response);
57
} else {
58
reject({
59
status: this.status,
60
statusText: xhr.statusText
61
});
62
}
63
};
64
xhr.onerror = function () {
65
reject({
66
status: this.status,
67
statusText: xhr.statusText
68
});
69
};
70
xhr.setRequestHeader("Content-Type", "application/json");
71
xhr.send(JSON.stringify(payload));
72
});
73
},
74
paymentSuccess: async function(clickToPayResponse) {
75
return new Promise((resolve, reject) => {
76
try {
77
const response = await this.authorize(clickToPayResponse);
78
console.log(response);
79
const resp = JSON.parse(response);
80
if (!resp)
81
throw "Invalid response: "+ response;
82
if (resp.xError) {
83
throw resp;
84
}
85
resolve(response);
86
} catch (err) {
87
console.error("paymentSuccess error.", JSON.stringify(err));
88
reject(err);
89
}
90
});
91
},
92
paymentCallback: function (clickToPayResponse) {
93
click2payRequest.setPayload(clickToPayResponse);
94
},
95
cpButtonLoaded: function(resp) {
96
if (!resp) return;
97
if (resp.status === iStatus.success) {
98
showHide("click2payContainer", true);
99
} else if (resp.reason) {
100
console.log(resp.reason);
101
}
102
},
103
setPayload: function (value) {
104
document.getElementById('c2p-payload').value = JSON.stringify(value, null, 2);
105
showHide("divC2PPayload", value);
106
}
107
};
108
109
function showHide(elem, toShow) {
110
if (typeof(elem) === "string") {
111
elem = document.getElementById(elem);
112
}
113
if (elem) {
114
toShow ? elem.classList.remove("hidden") : elem.classList.add("hidden");
115
}
116
}
117
function getAmount () {
118
return roundToNumber(document.getElementById("amount").value || "0", 2);
119
}
120
</script>
121
<style>
122
body {
123
margin: 10px;
124
}
125
div.main {
126
width: 350px;
127
}
128
.c2p {
129
display: block;
130
border: 0;
131
width: 260px;
132
margin-bottom: 0;
133
}
134
.c2p .txt-signin{
135
width: 90% !important;
136
}
137
138
input {
139
border: 1px solid black;
140
font-size: 14px;
141
padding: 3px;
142
width: 250px;
143
margin-bottom: 12px;
144
}
145
146
.hidden {
147
display: none;
148
}
149
150
textarea {
151
border: 1px solid black;
152
width: 100%;
153
}
154
</style>
155
</head>
156
<body>
157
<div class="main">
158
<form id="payment-form" method="POST">
159
<input id="amount" name="xAmount" placeholder="Amount" type="number" inputmode="decimal"></input>
160
<br/>
161
<div id="click2payContainer" class="c2p hidden">
162
<br/>
163
</div>
164
<br/>
165
<div id="divC2PPayload" class="hidden">
166
<label id="lbc2pPayload">Click-To-Pay Payload: </label>
167
<br />
168
<textarea id="c2p-payload" rows="10" readonly="true"></textarea>
169
<br/>
170
</div>
171
</form>
172
</div>
173
</body>