Skip to content

Commit 36d8b67

Browse files
Merge pull request #55 from Flutterwave/dev
[Hotfix] Retry support for checkout script
2 parents a9ded21 + 99565e8 commit 36d8b67

File tree

3 files changed

+159
-88
lines changed

3 files changed

+159
-88
lines changed

dist/index.es.js

+48-32
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { useState, useEffect, createElement } from 'react';
1+
import * as React from 'react';
22

33
/**
44
* Check out {@link https://developer.flutterwave.com/docs/flutterwave-standard} for more information.
@@ -8,7 +8,7 @@ var types = /*#__PURE__*/Object.freeze({
88
__proto__: null
99
});
1010

11-
/*! *****************************************************************************
11+
/******************************************************************************
1212
Copyright (c) Microsoft Corporation.
1313
1414
Permission to use, copy, modify, and/or distribute this software for any
@@ -62,7 +62,7 @@ function __generator(thisArg, body) {
6262
function verb(n) { return function (v) { return step([n, v]); }; }
6363
function step(op) {
6464
if (f) throw new TypeError("Generator is already executing.");
65-
while (_) try {
65+
while (g && (g = 0, op[0] && (_ = 0)), _) try {
6666
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
6767
if (y = 0, t) op = [op[0] & 2, t.value];
6868
switch (op[0]) {
@@ -85,47 +85,63 @@ function __generator(thisArg, body) {
8585
}
8686

8787
var loadedScripts = {};
88-
var src = 'https://checkout.flutterwave.com/v3.js';
88+
var srcUrl = 'https://checkout.flutterwave.com/v3.js';
89+
var maxAttempts = 3; // Set the maximum number of attempts
90+
var attempt = 1; // Track the attempt count
8991
function useFWScript() {
90-
var _a = useState({
92+
var _a = React.useState({
9193
loaded: false,
9294
error: false,
9395
}), state = _a[0], setState = _a[1];
94-
useEffect(function () {
95-
if (loadedScripts.hasOwnProperty(src)) {
96+
React.useEffect(function () {
97+
if (loadedScripts.hasOwnProperty('src')) {
9698
setState({
9799
loaded: true,
98100
error: false,
99101
});
100102
}
101103
else {
102-
loadedScripts.src = src;
103-
var script_1 = document.createElement('script');
104-
script_1.src = src;
105-
script_1.async = true;
106-
var onScriptLoad_1 = function () {
107-
setState({
108-
loaded: true,
109-
error: false,
110-
});
111-
};
112-
var onScriptError_1 = function () {
113-
delete loadedScripts.src;
114-
setState({
115-
loaded: true,
116-
error: true,
117-
});
118-
};
119-
script_1.addEventListener('load', onScriptLoad_1);
120-
script_1.addEventListener('complete', onScriptLoad_1);
121-
script_1.addEventListener('error', onScriptError_1);
122-
document.body.appendChild(script_1);
104+
downloadScript();
123105
return function () {
124-
script_1.removeEventListener('load', onScriptLoad_1);
125-
script_1.removeEventListener('error', onScriptError_1);
106+
var scripts = document.querySelectorAll('script');
107+
scripts.forEach(function (script) {
108+
if (script.src === srcUrl) {
109+
script.removeEventListener('load', onScriptLoad);
110+
script.removeEventListener('error', onScriptError);
111+
}
112+
});
126113
};
127114
}
128115
}, []);
116+
var downloadScript = React.useCallback(function () {
117+
loadedScripts.src = srcUrl;
118+
var script = document.createElement('script');
119+
script.src = srcUrl;
120+
script.async = true;
121+
script.addEventListener('load', onScriptLoad);
122+
script.addEventListener('error', onScriptError);
123+
document.body.appendChild(script);
124+
}, []);
125+
var onScriptLoad = React.useCallback(function () {
126+
setState({
127+
loaded: true,
128+
error: false,
129+
});
130+
}, []);
131+
var onScriptError = React.useCallback(function () {
132+
delete loadedScripts.src;
133+
console.log("Flutterwave script download failed. Attempt: " + attempt);
134+
if (attempt < maxAttempts) {
135+
++attempt;
136+
setTimeout(function () { return downloadScript(); }, (attempt * 1000)); // Progressively increase the delay before retry
137+
}
138+
else {
139+
setState({
140+
loaded: true,
141+
error: true,
142+
});
143+
}
144+
}, []);
129145
return [state.loaded, state.error];
130146
}
131147

@@ -136,7 +152,7 @@ function useFWScript() {
136152
*/
137153
function useFlutterwave(flutterWaveConfig) {
138154
var _a = useFWScript(), loaded = _a[0], error = _a[1];
139-
useEffect(function () {
155+
React.useEffect(function () {
140156
if (error)
141157
throw new Error('Unable to load flutterwave payment modal');
142158
}, [error]);
@@ -209,7 +225,7 @@ function useFlutterwave(flutterWaveConfig) {
209225
var FlutterWaveButton = function (_a) {
210226
var text = _a.text, className = _a.className, children = _a.children, callback = _a.callback, onClose = _a.onClose, disabled = _a.disabled, config = __rest(_a, ["text", "className", "children", "callback", "onClose", "disabled"]);
211227
var handleFlutterwavePayment = useFlutterwave(config);
212-
return (createElement("button", { disabled: disabled, className: className, onClick: function () { return handleFlutterwavePayment({ callback: callback, onClose: onClose }); } }, text || children));
228+
return (React.createElement("button", { disabled: disabled, className: className, onClick: function () { return handleFlutterwavePayment({ callback: callback, onClose: onClose }); } }, text || children));
213229
};
214230

215231
/**

dist/index.js

+67-31
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,26 @@ Object.defineProperty(exports, '__esModule', { value: true });
44

55
var React = require('react');
66

7+
function _interopNamespace(e) {
8+
if (e && e.__esModule) return e;
9+
var n = Object.create(null);
10+
if (e) {
11+
Object.keys(e).forEach(function (k) {
12+
if (k !== 'default') {
13+
var d = Object.getOwnPropertyDescriptor(e, k);
14+
Object.defineProperty(n, k, d.get ? d : {
15+
enumerable: true,
16+
get: function () { return e[k]; }
17+
});
18+
}
19+
});
20+
}
21+
n["default"] = e;
22+
return Object.freeze(n);
23+
}
24+
25+
var React__namespace = /*#__PURE__*/_interopNamespace(React);
26+
727
/**
828
* Check out {@link https://developer.flutterwave.com/docs/flutterwave-standard} for more information.
929
*/
@@ -12,7 +32,7 @@ var types = /*#__PURE__*/Object.freeze({
1232
__proto__: null
1333
});
1434

15-
/*! *****************************************************************************
35+
/******************************************************************************
1636
Copyright (c) Microsoft Corporation.
1737
1838
Permission to use, copy, modify, and/or distribute this software for any
@@ -66,7 +86,7 @@ function __generator(thisArg, body) {
6686
function verb(n) { return function (v) { return step([n, v]); }; }
6787
function step(op) {
6888
if (f) throw new TypeError("Generator is already executing.");
69-
while (_) try {
89+
while (g && (g = 0, op[0] && (_ = 0)), _) try {
7090
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
7191
if (y = 0, t) op = [op[0] & 2, t.value];
7292
switch (op[0]) {
@@ -89,47 +109,63 @@ function __generator(thisArg, body) {
89109
}
90110

91111
var loadedScripts = {};
92-
var src = 'https://checkout.flutterwave.com/v3.js';
112+
var srcUrl = 'https://checkout.flutterwave.com/v3.js';
113+
var maxAttempts = 3; // Set the maximum number of attempts
114+
var attempt = 1; // Track the attempt count
93115
function useFWScript() {
94-
var _a = React.useState({
116+
var _a = React__namespace.useState({
95117
loaded: false,
96118
error: false,
97119
}), state = _a[0], setState = _a[1];
98-
React.useEffect(function () {
99-
if (loadedScripts.hasOwnProperty(src)) {
120+
React__namespace.useEffect(function () {
121+
if (loadedScripts.hasOwnProperty('src')) {
100122
setState({
101123
loaded: true,
102124
error: false,
103125
});
104126
}
105127
else {
106-
loadedScripts.src = src;
107-
var script_1 = document.createElement('script');
108-
script_1.src = src;
109-
script_1.async = true;
110-
var onScriptLoad_1 = function () {
111-
setState({
112-
loaded: true,
113-
error: false,
114-
});
115-
};
116-
var onScriptError_1 = function () {
117-
delete loadedScripts.src;
118-
setState({
119-
loaded: true,
120-
error: true,
121-
});
122-
};
123-
script_1.addEventListener('load', onScriptLoad_1);
124-
script_1.addEventListener('complete', onScriptLoad_1);
125-
script_1.addEventListener('error', onScriptError_1);
126-
document.body.appendChild(script_1);
128+
downloadScript();
127129
return function () {
128-
script_1.removeEventListener('load', onScriptLoad_1);
129-
script_1.removeEventListener('error', onScriptError_1);
130+
var scripts = document.querySelectorAll('script');
131+
scripts.forEach(function (script) {
132+
if (script.src === srcUrl) {
133+
script.removeEventListener('load', onScriptLoad);
134+
script.removeEventListener('error', onScriptError);
135+
}
136+
});
130137
};
131138
}
132139
}, []);
140+
var downloadScript = React__namespace.useCallback(function () {
141+
loadedScripts.src = srcUrl;
142+
var script = document.createElement('script');
143+
script.src = srcUrl;
144+
script.async = true;
145+
script.addEventListener('load', onScriptLoad);
146+
script.addEventListener('error', onScriptError);
147+
document.body.appendChild(script);
148+
}, []);
149+
var onScriptLoad = React__namespace.useCallback(function () {
150+
setState({
151+
loaded: true,
152+
error: false,
153+
});
154+
}, []);
155+
var onScriptError = React__namespace.useCallback(function () {
156+
delete loadedScripts.src;
157+
console.log("Flutterwave script download failed. Attempt: " + attempt);
158+
if (attempt < maxAttempts) {
159+
++attempt;
160+
setTimeout(function () { return downloadScript(); }, (attempt * 1000)); // Progressively increase the delay before retry
161+
}
162+
else {
163+
setState({
164+
loaded: true,
165+
error: true,
166+
});
167+
}
168+
}, []);
133169
return [state.loaded, state.error];
134170
}
135171

@@ -140,7 +176,7 @@ function useFWScript() {
140176
*/
141177
function useFlutterwave(flutterWaveConfig) {
142178
var _a = useFWScript(), loaded = _a[0], error = _a[1];
143-
React.useEffect(function () {
179+
React__namespace.useEffect(function () {
144180
if (error)
145181
throw new Error('Unable to load flutterwave payment modal');
146182
}, [error]);
@@ -213,7 +249,7 @@ function useFlutterwave(flutterWaveConfig) {
213249
var FlutterWaveButton = function (_a) {
214250
var text = _a.text, className = _a.className, children = _a.children, callback = _a.callback, onClose = _a.onClose, disabled = _a.disabled, config = __rest(_a, ["text", "className", "children", "callback", "onClose", "disabled"]);
215251
var handleFlutterwavePayment = useFlutterwave(config);
216-
return (React.createElement("button", { disabled: disabled, className: className, onClick: function () { return handleFlutterwavePayment({ callback: callback, onClose: onClose }); } }, text || children));
252+
return (React__namespace.createElement("button", { disabled: disabled, className: className, onClick: function () { return handleFlutterwavePayment({ callback: callback, onClose: onClose }); } }, text || children));
217253
};
218254

219255
/**

src/script.ts

+44-25
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,9 @@ interface ScriptStatusInterface {
99
error: boolean;
1010
}
1111

12-
const src = 'https://checkout.flutterwave.com/v3.js';
12+
const srcUrl = 'https://checkout.flutterwave.com/v3.js';
13+
const maxAttempts = 3; // Set the maximum number of attempts
14+
let attempt = 1;// Track the attempt count
1315

1416
export default function useFWScript(): readonly [boolean, boolean] {
1517
const [state, setState] = React.useState<ScriptStatusInterface>({
@@ -18,44 +20,61 @@ export default function useFWScript(): readonly [boolean, boolean] {
1820
});
1921

2022
React.useEffect((): (() => void) | void => {
21-
if (loadedScripts.hasOwnProperty(src)) {
23+
if (loadedScripts.hasOwnProperty('src')) {
2224
setState({
2325
loaded: true,
2426
error: false,
2527
});
2628
} else {
27-
loadedScripts.src = src;
29+
downloadScript();
2830

29-
const script = document.createElement('script');
30-
script.src = src;
31-
script.async = true;
31+
return () => {
32+
const scripts = document.querySelectorAll('script');
3233

33-
const onScriptLoad = (): void => {
34-
setState({
35-
loaded: true,
36-
error: false,
34+
scripts.forEach(script => {
35+
if (script.src === srcUrl) {
36+
script.removeEventListener('load', onScriptLoad);
37+
script.removeEventListener('error', onScriptError);
38+
}
3739
});
3840
};
41+
}
42+
}, []);
3943

40-
const onScriptError = (): void => {
41-
delete loadedScripts.src;
44+
const downloadScript = React.useCallback((): void => {
45+
loadedScripts.src = srcUrl;
4246

43-
setState({
44-
loaded: true,
45-
error: true,
46-
});
47-
};
47+
const script = document.createElement('script');
48+
script.src = srcUrl;
49+
script.async = true;
4850

49-
script.addEventListener('load', onScriptLoad);
50-
script.addEventListener('complete', onScriptLoad);
51-
script.addEventListener('error', onScriptError);
51+
script.addEventListener('load', onScriptLoad);
52+
script.addEventListener('error', onScriptError);
5253

53-
document.body.appendChild(script);
54+
document.body.appendChild(script);
55+
}, []);
5456

55-
return () => {
56-
script.removeEventListener('load', onScriptLoad);
57-
script.removeEventListener('error', onScriptError);
58-
};
57+
const onScriptLoad = React.useCallback((): void => {
58+
setState({
59+
loaded: true,
60+
error: false,
61+
});
62+
}, []);
63+
64+
const onScriptError = React.useCallback((): void => {
65+
delete loadedScripts.src;
66+
67+
console.log(`Flutterwave script download failed. Attempt: ${attempt}`);
68+
69+
if (attempt < maxAttempts) {
70+
++attempt;
71+
72+
setTimeout(() => downloadScript(), (attempt * 1000)); // Progressively increase the delay before retry
73+
} else {
74+
setState({
75+
loaded: true,
76+
error: true,
77+
});
5978
}
6079
}, []);
6180

0 commit comments

Comments
 (0)