PluginProbe
Welcart e-Commerce / 2.11.31
Welcart e-Commerce v2.11.31
2.12.4 2.12.3 2.11.35 2.12.2 2.12.1 2.11.34 2.11.33 2.11.32 2.11.31 2.11.30 1.3.16 1.3.17 1.3.2 1.3.3 1.3.4 1.3.5 1.3.6 1.3.7 1.3.8 1.3.9 1.4.0 1.4.1 1.4.10 1.4.11 1.4.12 All 292 releases
usc-e-shop / js / zeus_3ds.js

zeus_3ds.js in Welcart e-Commerce 2.11.31, at js/zeus_3ds.js

328 lines 9.2 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 /**
2 * iframeのID指定用変数
3 */
4 var iframeId;
5
6 /**
7 * EMV3DSecure認証コンテナ
8 */
9 var threedsContainer;
10
11 /**
12 * 加盟店webサーバのurl
13 */
14 var merchantUrl;
15
16 /**
17 * リスクベース認証結果の一時保存
18 */
19 var securePaData;
20
21 /**
22 * securePaのmd
23 */
24 var xid_sha512;
25
26 /**
27 * タイムアウト解除用の変数
28 */
29 let timeout;
30
31 // iframeからのイベント受信を行う。CROS対策方式
32 window.addEventListener("message", receiveMessage, false);
33 function receiveMessage(event) {
34 // 環境ごとに変化
35 if (event.origin !== "https://linkpt.cardservice.co.jp") {
36 return;
37 }
38
39 const jsonObj = JSON.parse(event.data);
40 if(jsonObj.event == '3DSMethodSkipped' || jsonObj.event == '3DSMethodFinished') {
41 clearTimeout(timeout);
42 _doAuth(xid_sha512, merchantUrl);
43 } else if(jsonObj.event === 'AuthResultReady') { // チャレンジフローの終了時にiframeから受信するメッセージ
44 securePaData.transStatus = jsonObj.transStatus;
45 _onAuthResult(securePaData); // PaResをフロントから送信する。
46 }
47 }
48
49 /**
50 * 加盟店利用関数3.PaReqで返されたパラメータ
51 * (EnrolReqの切っ掛けとなったリクエストへのレスポンス)
52 * をそのまま取得する。
53 * レスポンスで新しく画面を開く加盟店も、PaReq部分をこの関数に渡せばOK.
54 * ajaxの加盟店はレスポンスをそのままここに渡す。
55 * 2/16 paymentResultパラメータ不要化
56 * @param params
57 */
58 function setPareqParams(md,paReq,termUrl,threeDSMethod,iframeUrl) {
59 // 3DS認証可否の確認
60 if (threeDSMethod == null) {
61 // 決済成功ページを表示
62 doPost();
63 } else {
64 iframeId = String(Math.floor(100000 + Math.random() * 900000));
65
66 setThreedsContainer();
67
68 // 3DS認証利用OKの場合
69 // termUrlを加盟店サーバURLとしてグローバル変数にセット
70 merchantUrl = decodeTermurl(termUrl);
71 // mdの値をグローバル変数にセット
72 xid_sha512 = md;
73 // ブラウザ�
74 報収集用のiframeをコンテナに設置
75 var decodeUrl = decodeURIComponent(iframeUrl);
76 var appendNode = document.createElement('iframe');
77 appendNode.setAttribute('id', '3ds_secureapi_' + iframeId);
78 appendNode.setAttribute('width', '0');
79 appendNode.setAttribute('height', '0');
80 appendNode.setAttribute('style', 'visibility: hidden;');
81 appendNode.setAttribute('src', decodeUrl);
82 threedsContainer.appendChild(appendNode);
83
84 // 20秒�
85 ってもgpayからcallbackがない場合次の認証処理を実施するためのタイマーエラーになる想定
86 timeout = setTimeout( function() {
87 _doAuth(md, merchantUrl);
88 }, 20000 );
89 }
90 }
91
92 /**
93 * Get the authentication from Active Server
94 * @param threeDSServerTransID
95 * @param callbackFn
96 */
97 function result(threeDSServerTransID, callbackFn) {
98 getResult(threeDSServerTransID, callbackFn);
99 }
100
101 /**
102 * Post authData to 3ds requestor with url
103 * @param processName:呼出�
104
105 * @param url
106 * @param authData
107 * @param onSuccess
108 * @param onError
109 * @param contentType
110 */
111 function _doPost(processName, url, authData, onSuccess, onError, contentType="application/json") {
112 var request = new XMLHttpRequest();
113 request.open(
114 'POST',
115 url,
116 true,
117 );
118
119 request.setRequestHeader('Content-Type', contentType);
120 if (contentType === "application/json") {
121 authData = JSON.stringify(authData);
122 }
123
124 request.onload = function(data) {
125 // JQueryからXHRRequestへの変換時の互換性確保。JQueryのdate = XHRのdata.target.response
126 let response = data.target.response;
127
128 if (request.status >= 200 && request.status < 400) {
129 onSuccess(response);
130 } else {
131 onError({"message": "" + request.status + "" + processName + " 処理エラー"});
132 }
133 };
134
135 request.onerror = function(data) {
136 onError({"message": "" + request.status + "" + processName + " 処理エラー"});
137 };
138
139 request.send(authData);
140 }
141
142 /**
143 * リスクベース認証を要求し、フリクションレス/チャレンジフローを開始する.
144 * @param md
145 * @param termUrl
146 * @private
147 */
148 function _doAuth(md, termUrl) {
149 // 加盟店SecureAPI利用 PaReq送信
150
151 content =
152 '<?xml version="1.0" encoding="utf-8"?>'
153 + '<request service="secure_link_3d" action="securePa">'
154 + '<xid>' + md +'</xid>'
155 + '</request>';
156 _doPost(
157 'PaReq',
158 'https://linkpt.cardservice.co.jp/cgi-bin/token/token.cgi',
159 content,
160 function(xml) {
161 try {
162 // 結果に応じてチャレンジ/フリクションレスフローを開始する。
163 let domparser = new DOMParser();
164 let doc = domparser.parseFromString(xml, "application/xml");
165 var data = {};
166
167 if (typeof doc.getElementsByTagName("status")[0] !== 'undefined') {
168 data.status = doc.getElementsByTagName("status")[0].textContent;
169 } else {
170 data.status = 'maintenance';
171 }
172
173 if (typeof doc.getElementsByTagName("xid")[0] !== 'undefined') {
174 data.xid = doc.getElementsByTagName("xid")[0].textContent;
175 }
176
177 if (typeof doc.getElementsByTagName("transStatus")[0] !== 'undefined') {
178 data.transStatus = doc.getElementsByTagName("transStatus")[0].textContent;
179 } else {
180 data.transStatus = "N";
181 }
182
183 if (data.status == 'success' || data.status == 'outside') {
184 securePaData = data;
185
186 // フリクションレスのとき、challengeUrlを持たない。
187 // challengeUrlが設定されている(チャレンジ)時だけ、challengeUrlを設定して渡す
188 if (typeof doc.getElementsByTagName("challengeUrl")[0] !== 'undefined') {
189 data.challengeUrl = doc.getElementsByTagName("challengeUrl")[0].textContent;
190 }
191 } else {
192 data.xid = md; // doc.getElementsByTagName("xid")[0].textContent;
193 data.transStatus = "N";
194 }
195
196 } catch(error) {
197 // XMLパースエラーなど発生時、失敗時の関数を呼ぶ
198 _onError({"message": error.message});
199 }
200 _onDoAuthSuccess(data);
201 },
202 function(error) {
203 _onError({"message": error.message});
204 },
205 "application/xml"
206 );
207 }
208
209 /**
210 * Callback function for _doAuth
211 * @param data
212 * @private
213 */
214 // リスクベース認証完了後に動作
215 function _onDoAuthSuccess(data) {
216 if (data.transStatus === "C" || data.transStatus === "D") {
217 // チャレンジフロー(C, D)
218 data.challengeUrl ? startChallenge(data.challengeUrl) : _onError(
219 {"message": "追加認証要求URLがありません。"}
220 );
221 } else {
222 /* iframe remove */
223 var iframe = document.getElementById('3ds_secureapi_' + iframeId);
224 iframe.remove();
225 // チャレンジ以外
226 _onAuthResult(data);
227 }
228 }
229
230 /**
231 * Setup iframe for challenge flow (Step 14(C))
232 * @param url is the challenge url returned from 3DS Server
233 */
234 function startChallenge(url) {
235
236 var challengeUrl = decodeURIComponent(url);
237 var appendNode = document.createElement('iframe');
238 appendNode.setAttribute('id', '3ds_challenge');
239 appendNode.setAttribute('width', '100%');
240 // appendNode.setAttribute('height', '100%');
241 appendNode.setAttribute('height', '300px');
242 appendNode.setAttribute('style', 'border:0');
243 appendNode.setAttribute('src', challengeUrl);
244 appendNode.setAttribute('onload', 'loadedChallenge()');
245
246 setThreedsContainer();
247
248 threedsContainer.appendChild(appendNode);
249 }
250
251 /**
252 * チャレンジ/フリクションレスフロー完了時に呼ばれるメソッド
253 */
254 function _onAuthResult(data) {
255 sendPaRes(data);
256 }
257
258 /**
259 * PaResをPaReqで受け取ったTermUrlに向けて送信
260 */
261 function sendPaRes(data) {
262 var paResData = {};
263 paResData.MD = data.xid;
264 paResData.PaRes = data.transStatus;
265 paResData.status = data.status;
266 _doPost('PaRes', merchantUrl, paResData, _onPaResSuccess, _onError);
267 }
268
269 /**
270 * PaRes成功後のデフォルト関数。挙動なし。
271 * この宣言以降で同名関数の宣言によって挙動上書き可能。
272 */
273 function _onPaResSuccess(data) {
274 document.write(data);
275 }
276
277 /**
278 * この関数を上書きすることでエラー時の挙動を制御できます.
279 * @param error
280 * @private
281 */
282 function _onError(error) {
283 if (error.status === 404) {
284 error["New feature"] = "This feature is only supported by ActiveServer v1.1.2+";
285 }
286 // console.log('_onError='+error);
287 }
288
289 /**
290 * Set 3DS Container
291 */
292 function setThreedsContainer() {
293 threedsContainer = document.querySelector("div[id='3dscontainer']");
294 if (threedsContainer == null) {
295 var containerDiv = document.createElement("div");
296 containerDiv.id = '3dscontainer';
297 document.body.appendChild(containerDiv);
298 threedsContainer = document.querySelector("div[id='3dscontainer']");
299 }
300 }
301
302 /**
303 * Decode URL
304 */
305 function decodeTermurl(termUrl) {
306 var re = /^(https?:\/\/)/i;
307 var returnUrl;
308 // console.log('termUrl :', termUrl);
309
310 if (re.test(termUrl)) {
311 returnUrl = termUrl;
312 } else {
313 returnUrl = decodeURIComponent(termUrl);
314 }
315 // console.log('returnUrl :', returnUrl);
316 return returnUrl;
317 }
318
319 /**
320 * チャレンジ認証画面ロード完了時、加盟店側のメッセージを非表示とする関数
321 */
322 function loadedChallenge() {
323 var div_waiter;
324 if (div_waiter = document.querySelector("div[id='challenge_wait']")) {
325 div_waiter.style.display = 'none';
326 }
327 }
328