Skip to content

Commit ede230c

Browse files
Merge pull request #223 from processout/chore/ignore-merchant-errors
fix: ignore merchant code errors
2 parents 2254b41 + 056afe1 commit ede230c

File tree

2 files changed

+49
-23
lines changed

2 files changed

+49
-23
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "processout.js",
3-
"version": "1.6.0",
3+
"version": "1.6.2",
44
"description": "ProcessOut.js is a JavaScript library for ProcessOut's payment processing API.",
55
"scripts": {
66
"build:processout": "tsc -p src/processout && uglifyjs --compress --keep-fnames --ie8 dist/processout.js -o dist/processout.js",

src/processout/cardfield.ts

Lines changed: 48 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,7 @@ module ProcessOut {
185185
if (!container) {
186186
throw new Exception("processout-js.undefined-field", `The card field for the ${options.type} does not exist in the given container.`);
187187
}
188+
188189
if (container instanceof HTMLInputElement) {
189190
throw new Exception("processout-js.invalid-field", `The card field for the ${options.type} must be an input field.`);
190191
}
@@ -209,6 +210,23 @@ module ProcessOut {
209210
this.spawn(success, error);
210211
}
211212

213+
214+
private postMessage(message: any, retries: number = 3, delay: number = 50): void {
215+
if (retries <= 0) {
216+
throw new Exception("processout-js.field.unavailable", "Tried to locate the iframe content window but failed.");
217+
}
218+
219+
if (!this.iframe || !this.iframe.contentWindow) {
220+
setTimeout(() => this.postMessage(message, retries - 1, delay), delay);
221+
return;
222+
}
223+
224+
try {
225+
this.iframe.contentWindow.postMessage(message, "*");
226+
} catch (e) {
227+
throw new Exception("processout-js.field.unavailable", "Iframe content window found but failed to post message: " + e.message);
228+
}
229+
}
212230
/**
213231
* Spawn spawns the iframe used to embed the field
214232
* @param {callback} success
@@ -248,7 +266,9 @@ module ProcessOut {
248266
// Firefox from (wrongfully) caching the iframe
249267
// content: https://bugzilla.mozilla.org/show_bug.cgi?id=354176
250268
if(navigator.userAgent.match(/firefox|fxios/i)) {
251-
this.iframe.contentWindow.location.replace(endpoint);
269+
if (this.iframe && this.iframe.contentWindow) {
270+
this.iframe.contentWindow.location.replace(endpoint);
271+
}
252272
}
253273
} catch(e) { /* ... */ }
254274
}.bind(this);
@@ -274,14 +294,15 @@ module ProcessOut {
274294
// and the iframe should reply with a ready state
275295

276296
if (data.action == "alive") {
297+
277298
// The field's iframe is available, let's set it up
278-
this.iframe.contentWindow.postMessage(JSON.stringify({
299+
this.postMessage(JSON.stringify({
279300
"namespace": Message.fieldNamespace,
280301
"projectID": this.instance.getProjectID(),
281302
"action": "setup",
282303
"formID": this.form.getUID(),
283304
"data": this.options
284-
}), "*");
305+
}));
285306
}
286307

287308
if (data.action == "ready") {
@@ -293,17 +314,17 @@ module ProcessOut {
293314
// Finally we also want to request for a resize, as some
294315
// browser fail to compute the height of the iframe
295316
// if it isn't displayed yet
296-
this.iframe.contentWindow.postMessage(JSON.stringify({
317+
this.postMessage(JSON.stringify({
297318
"namespace": Message.fieldNamespace,
298319
"projectID": this.instance.getProjectID(),
299320
"action": "resize"
300-
}), "*");
321+
}));
301322

302323
// Hook an event listener for the focus event to focus
303324
// on the input when the user presses tab on older
304325
// browser: otherwise the iframe would get focused, but
305326
// not the field within it (hello IE)
306-
this.iframe.addEventListener("focus", function (event) {
327+
this.iframe.addEventListener("focus", function () {
307328
this.focus();
308329
}.bind(this));
309330
}
@@ -364,8 +385,13 @@ module ProcessOut {
364385
case "event":
365386
if (data.data.name in this.handlers) {
366387
var handlers = this.handlers[data.data.name];
367-
for (var i = 0; i < handlers.length; i++)
368-
handlers[0](data.data.data);
388+
for (var i = 0; i < handlers.length; i++) {
389+
try {
390+
handlers[0](data.data.data);
391+
} catch (e) {
392+
// ignoring errors that come from the merchant's codebase
393+
}
394+
}
369395
}
370396
break;
371397
case "resize":
@@ -399,12 +425,12 @@ module ProcessOut {
399425
this.options.style = (<any>Object).assign(
400426
this.options.style, options.style);
401427

402-
this.iframe.contentWindow.postMessage(JSON.stringify({
428+
this.postMessage(JSON.stringify({
403429
"namespace": Message.fieldNamespace,
404430
"projectID": this.instance.getProjectID(),
405431
"action": "update",
406432
"data": this.options
407-
}), "*");
433+
}));
408434
}
409435

410436
/**
@@ -419,12 +445,12 @@ module ProcessOut {
419445
this.handlers[e] = [];
420446

421447
this.handlers[e].push(h);
422-
this.iframe.contentWindow.postMessage(JSON.stringify({
448+
this.postMessage(JSON.stringify({
423449
"namespace": Message.fieldNamespace,
424450
"projectID": this.instance.getProjectID(),
425451
"action": "registerEvent",
426452
"data": e
427-
}), "*");
453+
}));
428454
}
429455

430456
/**
@@ -442,25 +468,25 @@ module ProcessOut {
442468
* @return {void}
443469
*/
444470
public blur(): void {
445-
this.iframe.contentWindow.postMessage(JSON.stringify({
471+
this.postMessage(JSON.stringify({
446472
"messageID": Math.random().toString(),
447473
"namespace": Message.fieldNamespace,
448474
"projectID": this.instance.getProjectID(),
449475
"action": "blur"
450-
}), "*");
476+
}));
451477
}
452478

453479
/**
454480
* focus focuses on the card field
455481
* @return {void}
456482
*/
457483
public focus(): void {
458-
this.iframe.contentWindow.postMessage(JSON.stringify({
484+
this.postMessage(JSON.stringify({
459485
"messageID": Math.random().toString(),
460486
"namespace": Message.fieldNamespace,
461487
"projectID": this.instance.getProjectID(),
462488
"action": "focus"
463-
}), "*");
489+
}));
464490
}
465491

466492
/**
@@ -474,12 +500,12 @@ module ProcessOut {
474500
var id = Math.random().toString();
475501

476502
// Ask the iframe for its value
477-
this.iframe.contentWindow.postMessage(JSON.stringify({
503+
this.postMessage(JSON.stringify({
478504
"messageID": id,
479505
"namespace": Message.fieldNamespace,
480506
"projectID": this.instance.getProjectID(),
481507
"action": "validate"
482-
}), "*");
508+
}));
483509

484510
// Our timeout, just in case
485511
var fetchingTimeout =
@@ -523,7 +549,7 @@ module ProcessOut {
523549
// Tell our field it should start the tokenization process and
524550
// expect a response
525551
var id = Math.random().toString();
526-
this.iframe.contentWindow.postMessage(JSON.stringify({
552+
this.postMessage(JSON.stringify({
527553
"messageID": id,
528554
"namespace": Message.fieldNamespace,
529555
"projectID": this.instance.getProjectID(),
@@ -532,7 +558,7 @@ module ProcessOut {
532558
"fields": fields,
533559
"data": data
534560
}
535-
}), "*");
561+
}));
536562

537563
// Our timeout, just in case
538564
var fetchingTimeout =
@@ -571,13 +597,13 @@ module ProcessOut {
571597
// Tell our field it should start the tokenization process and
572598
// expect a response
573599
var id = Math.random().toString();
574-
this.iframe.contentWindow.postMessage(JSON.stringify({
600+
this.postMessage(JSON.stringify({
575601
"messageID": id,
576602
"namespace": Message.fieldNamespace,
577603
"projectID": this.instance.getProjectID(),
578604
"action": "refresh-cvc",
579605
"data": cardUID
580-
}), "*");
606+
}));
581607

582608
// Our timeout, just in case
583609
var fetchingTimeout =

0 commit comments

Comments
 (0)