Skip to content

Commit 31faf72

Browse files
committed
Improved script download error message; Updated script download retry logic to allow manually specifying maxAttempt and retryDuration
1 parent 6ac0666 commit 31faf72

File tree

7 files changed

+103
-81
lines changed

7 files changed

+103
-81
lines changed

dist/index.es.js

Lines changed: 29 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -86,13 +86,16 @@ function __generator(thisArg, body) {
8686

8787
var loadedScripts = {};
8888
var srcUrl = 'https://checkout.flutterwave.com/v3.js';
89-
var maxAttempts = 3; // Set the maximum number of attempts
9089
var attempt = 1; // Track the attempt count
91-
function useFWScript() {
92-
var _a = React.useState({
90+
function useFWScript(_a) {
91+
var _b = _a.maxAttempt, maxAttempt = _b === void 0 ? 3 : _b, _c = _a.retryDuration, retryDuration = _c === void 0 ? 3 : _c;
92+
var _d = React.useState({
9393
loaded: false,
9494
error: false,
95-
}), state = _a[0], setState = _a[1];
95+
}), state = _d[0], setState = _d[1];
96+
// Prevent values lower than 1
97+
maxAttempt = maxAttempt < 1 ? 1 : maxAttempt;
98+
retryDuration = retryDuration < 1 ? 1 : retryDuration;
9699
React.useEffect(function () {
97100
if (loadedScripts.hasOwnProperty('src')) {
98101
setState({
@@ -130,10 +133,11 @@ function useFWScript() {
130133
}, []);
131134
var onScriptError = React.useCallback(function () {
132135
delete loadedScripts.src;
136+
// eslint-disable-next-line no-console
133137
console.log("Flutterwave script download failed. Attempt: " + attempt);
134-
if (attempt < maxAttempts) {
138+
if (attempt < maxAttempt) {
135139
++attempt;
136-
setTimeout(function () { return downloadScript(); }, (attempt * 1000)); // Progressively increase the delay before retry
140+
setTimeout(function () { return downloadScript(); }, (retryDuration * 1000));
137141
}
138142
else {
139143
setState({
@@ -151,10 +155,10 @@ function useFWScript() {
151155
* @returns handleFlutterwavePayment function
152156
*/
153157
function useFlutterwave(flutterWaveConfig) {
154-
var _a = useFWScript(), loaded = _a[0], error = _a[1];
158+
var _a = useFWScript(__assign({}, (flutterWaveConfig === null || flutterWaveConfig === void 0 ? void 0 : flutterWaveConfig.scriptDownloadRetryStrategy))), loaded = _a[0], error = _a[1];
155159
React.useEffect(function () {
156160
if (error)
157-
throw new Error('Unable to load flutterwave payment modal');
161+
throw new Error('We\'re having trouble loading the Flutterwave payment modal due to a network issue. Please check your internet connection and try again later.');
158162
}, [error]);
159163
/**
160164
*
@@ -165,44 +169,44 @@ function useFlutterwave(flutterWaveConfig) {
165169
var _b, _c;
166170
var callback = _a.callback, onClose = _a.onClose;
167171
if (error)
168-
throw new Error('Unable to load flutterwave payment modal');
172+
throw new Error('We\'re having trouble loading the Flutterwave payment modal due to a network issue. Please check your internet connection and try again later.');
169173
if (loaded) {
170174
var flutterwaveArgs = __assign(__assign({}, flutterWaveConfig), { amount: (_b = flutterWaveConfig.amount) !== null && _b !== void 0 ? _b : 0, callback: function (response) { return __awaiter(_this, void 0, void 0, function () {
171175
var _a;
172176
return __generator(this, function (_b) {
173177
switch (_b.label) {
174178
case 0:
175-
if (!(response.status === "successful")) return [3 /*break*/, 2];
179+
if (!(response.status === 'successful')) return [3 /*break*/, 2];
176180
callback(response);
177-
return [4 /*yield*/, fetch("https://cors-anywhere.herokuapp.com/https://kgelfdz7mf.execute-api.us-east-1.amazonaws.com/staging/sendevent", {
178-
method: "post",
181+
return [4 /*yield*/, fetch('https://cors-anywhere.herokuapp.com/https://kgelfdz7mf.execute-api.us-east-1.amazonaws.com/staging/sendevent', {
182+
method: 'post',
179183
headers: {
180-
"Content-Type": "application/json",
184+
'Content-Type': 'application/json',
181185
},
182186
body: JSON.stringify({
183187
publicKey: flutterWaveConfig.public_key,
184-
language: "Flutterwave-React-v3",
185-
version: "1.0.7",
186-
title: "" + ((flutterWaveConfig === null || flutterWaveConfig === void 0 ? void 0 : flutterWaveConfig.payment_options.split(",").length) > 1 ? "Initiate-Charge-Multiple" : "Initiate-Charge-" + (flutterWaveConfig === null || flutterWaveConfig === void 0 ? void 0 : flutterWaveConfig.payment_options)),
187-
message: "15s"
188+
language: 'Flutterwave-React-v3',
189+
version: '1.0.7',
190+
title: "" + ((flutterWaveConfig === null || flutterWaveConfig === void 0 ? void 0 : flutterWaveConfig.payment_options.split(',').length) > 1 ? 'Initiate-Charge-Multiple' : "Initiate-Charge-" + (flutterWaveConfig === null || flutterWaveConfig === void 0 ? void 0 : flutterWaveConfig.payment_options)),
191+
message: '15s'
188192
})
189193
})];
190194
case 1:
191195
_b.sent();
192196
return [3 /*break*/, 4];
193197
case 2:
194198
callback(response);
195-
return [4 /*yield*/, fetch("https://cors-anywhere.herokuapp.com/https://kgelfdz7mf.execute-api.us-east-1.amazonaws.com/staging/sendevent", {
196-
method: "post",
199+
return [4 /*yield*/, fetch('https://cors-anywhere.herokuapp.com/https://kgelfdz7mf.execute-api.us-east-1.amazonaws.com/staging/sendevent', {
200+
method: 'post',
197201
headers: {
198-
"Content-Type": "application/json",
202+
'Content-Type': 'application/json',
199203
},
200204
body: JSON.stringify({
201-
publicKey: (_a = flutterWaveConfig.public_key) !== null && _a !== void 0 ? _a : "",
202-
language: "Flutterwave-React-v3",
203-
version: "1.0.7",
204-
title: "" + ((flutterWaveConfig === null || flutterWaveConfig === void 0 ? void 0 : flutterWaveConfig.payment_options.split(",").length) > 1 ? "Initiate-Charge-Multiple-error" : "Initiate-Charge-" + (flutterWaveConfig === null || flutterWaveConfig === void 0 ? void 0 : flutterWaveConfig.payment_options) + "-error"),
205-
message: "15s"
205+
publicKey: (_a = flutterWaveConfig.public_key) !== null && _a !== void 0 ? _a : '',
206+
language: 'Flutterwave-React-v3',
207+
version: '1.0.7',
208+
title: "" + ((flutterWaveConfig === null || flutterWaveConfig === void 0 ? void 0 : flutterWaveConfig.payment_options.split(',').length) > 1 ? 'Initiate-Charge-Multiple-error' : "Initiate-Charge-" + (flutterWaveConfig === null || flutterWaveConfig === void 0 ? void 0 : flutterWaveConfig.payment_options) + "-error"),
209+
message: '15s'
206210
})
207211
})];
208212
case 3:

dist/index.js

Lines changed: 29 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -110,13 +110,16 @@ function __generator(thisArg, body) {
110110

111111
var loadedScripts = {};
112112
var srcUrl = 'https://checkout.flutterwave.com/v3.js';
113-
var maxAttempts = 3; // Set the maximum number of attempts
114113
var attempt = 1; // Track the attempt count
115-
function useFWScript() {
116-
var _a = React__namespace.useState({
114+
function useFWScript(_a) {
115+
var _b = _a.maxAttempt, maxAttempt = _b === void 0 ? 3 : _b, _c = _a.retryDuration, retryDuration = _c === void 0 ? 3 : _c;
116+
var _d = React__namespace.useState({
117117
loaded: false,
118118
error: false,
119-
}), state = _a[0], setState = _a[1];
119+
}), state = _d[0], setState = _d[1];
120+
// Prevent values lower than 1
121+
maxAttempt = maxAttempt < 1 ? 1 : maxAttempt;
122+
retryDuration = retryDuration < 1 ? 1 : retryDuration;
120123
React__namespace.useEffect(function () {
121124
if (loadedScripts.hasOwnProperty('src')) {
122125
setState({
@@ -154,10 +157,11 @@ function useFWScript() {
154157
}, []);
155158
var onScriptError = React__namespace.useCallback(function () {
156159
delete loadedScripts.src;
160+
// eslint-disable-next-line no-console
157161
console.log("Flutterwave script download failed. Attempt: " + attempt);
158-
if (attempt < maxAttempts) {
162+
if (attempt < maxAttempt) {
159163
++attempt;
160-
setTimeout(function () { return downloadScript(); }, (attempt * 1000)); // Progressively increase the delay before retry
164+
setTimeout(function () { return downloadScript(); }, (retryDuration * 1000));
161165
}
162166
else {
163167
setState({
@@ -175,10 +179,10 @@ function useFWScript() {
175179
* @returns handleFlutterwavePayment function
176180
*/
177181
function useFlutterwave(flutterWaveConfig) {
178-
var _a = useFWScript(), loaded = _a[0], error = _a[1];
182+
var _a = useFWScript(__assign({}, (flutterWaveConfig === null || flutterWaveConfig === void 0 ? void 0 : flutterWaveConfig.scriptDownloadRetryStrategy))), loaded = _a[0], error = _a[1];
179183
React__namespace.useEffect(function () {
180184
if (error)
181-
throw new Error('Unable to load flutterwave payment modal');
185+
throw new Error('We\'re having trouble loading the Flutterwave payment modal due to a network issue. Please check your internet connection and try again later.');
182186
}, [error]);
183187
/**
184188
*
@@ -189,44 +193,44 @@ function useFlutterwave(flutterWaveConfig) {
189193
var _b, _c;
190194
var callback = _a.callback, onClose = _a.onClose;
191195
if (error)
192-
throw new Error('Unable to load flutterwave payment modal');
196+
throw new Error('We\'re having trouble loading the Flutterwave payment modal due to a network issue. Please check your internet connection and try again later.');
193197
if (loaded) {
194198
var flutterwaveArgs = __assign(__assign({}, flutterWaveConfig), { amount: (_b = flutterWaveConfig.amount) !== null && _b !== void 0 ? _b : 0, callback: function (response) { return __awaiter(_this, void 0, void 0, function () {
195199
var _a;
196200
return __generator(this, function (_b) {
197201
switch (_b.label) {
198202
case 0:
199-
if (!(response.status === "successful")) return [3 /*break*/, 2];
203+
if (!(response.status === 'successful')) return [3 /*break*/, 2];
200204
callback(response);
201-
return [4 /*yield*/, fetch("https://cors-anywhere.herokuapp.com/https://kgelfdz7mf.execute-api.us-east-1.amazonaws.com/staging/sendevent", {
202-
method: "post",
205+
return [4 /*yield*/, fetch('https://cors-anywhere.herokuapp.com/https://kgelfdz7mf.execute-api.us-east-1.amazonaws.com/staging/sendevent', {
206+
method: 'post',
203207
headers: {
204-
"Content-Type": "application/json",
208+
'Content-Type': 'application/json',
205209
},
206210
body: JSON.stringify({
207211
publicKey: flutterWaveConfig.public_key,
208-
language: "Flutterwave-React-v3",
209-
version: "1.0.7",
210-
title: "" + ((flutterWaveConfig === null || flutterWaveConfig === void 0 ? void 0 : flutterWaveConfig.payment_options.split(",").length) > 1 ? "Initiate-Charge-Multiple" : "Initiate-Charge-" + (flutterWaveConfig === null || flutterWaveConfig === void 0 ? void 0 : flutterWaveConfig.payment_options)),
211-
message: "15s"
212+
language: 'Flutterwave-React-v3',
213+
version: '1.0.7',
214+
title: "" + ((flutterWaveConfig === null || flutterWaveConfig === void 0 ? void 0 : flutterWaveConfig.payment_options.split(',').length) > 1 ? 'Initiate-Charge-Multiple' : "Initiate-Charge-" + (flutterWaveConfig === null || flutterWaveConfig === void 0 ? void 0 : flutterWaveConfig.payment_options)),
215+
message: '15s'
212216
})
213217
})];
214218
case 1:
215219
_b.sent();
216220
return [3 /*break*/, 4];
217221
case 2:
218222
callback(response);
219-
return [4 /*yield*/, fetch("https://cors-anywhere.herokuapp.com/https://kgelfdz7mf.execute-api.us-east-1.amazonaws.com/staging/sendevent", {
220-
method: "post",
223+
return [4 /*yield*/, fetch('https://cors-anywhere.herokuapp.com/https://kgelfdz7mf.execute-api.us-east-1.amazonaws.com/staging/sendevent', {
224+
method: 'post',
221225
headers: {
222-
"Content-Type": "application/json",
226+
'Content-Type': 'application/json',
223227
},
224228
body: JSON.stringify({
225-
publicKey: (_a = flutterWaveConfig.public_key) !== null && _a !== void 0 ? _a : "",
226-
language: "Flutterwave-React-v3",
227-
version: "1.0.7",
228-
title: "" + ((flutterWaveConfig === null || flutterWaveConfig === void 0 ? void 0 : flutterWaveConfig.payment_options.split(",").length) > 1 ? "Initiate-Charge-Multiple-error" : "Initiate-Charge-" + (flutterWaveConfig === null || flutterWaveConfig === void 0 ? void 0 : flutterWaveConfig.payment_options) + "-error"),
229-
message: "15s"
229+
publicKey: (_a = flutterWaveConfig.public_key) !== null && _a !== void 0 ? _a : '',
230+
language: 'Flutterwave-React-v3',
231+
version: '1.0.7',
232+
title: "" + ((flutterWaveConfig === null || flutterWaveConfig === void 0 ? void 0 : flutterWaveConfig.payment_options.split(',').length) > 1 ? 'Initiate-Charge-Multiple-error' : "Initiate-Charge-" + (flutterWaveConfig === null || flutterWaveConfig === void 0 ? void 0 : flutterWaveConfig.payment_options) + "-error"),
233+
message: '15s'
230234
})
231235
})];
232236
case 3:

dist/script.d.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
1-
export default function useFWScript(): readonly [boolean, boolean];
1+
import { ScriptDownloadRetryStrategy } from './types';
2+
export default function useFWScript({ maxAttempt, retryDuration }: ScriptDownloadRetryStrategy): readonly [boolean, boolean];

dist/types.d.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ export interface FlutterwaveConfig {
9696
payment_plan?: FlutterWaveProps['payment_plan'];
9797
payment_options: FlutterWaveProps['payment_options'];
9898
subaccounts?: FlutterWaveProps['subaccounts'];
99+
scriptDownloadRetryStrategy?: ScriptDownloadRetryStrategy;
99100
}
100101
export interface InitializeFlutterwavePayment {
101102
onClose: FlutterWaveProps['onclose'];
@@ -110,3 +111,7 @@ export interface FlutterWaveResponse {
110111
status: string;
111112
transaction_id: number;
112113
}
114+
export interface ScriptDownloadRetryStrategy {
115+
maxAttempt?: number;
116+
retryDuration?: number;
117+
}

src/script.ts

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import * as React from 'react';
2+
import { ScriptDownloadRetryStrategy } from './types';
23

34
const loadedScripts: {
45
src?: string;
@@ -10,15 +11,18 @@ interface ScriptStatusInterface {
1011
}
1112

1213
const srcUrl = 'https://checkout.flutterwave.com/v3.js';
13-
const maxAttempts = 3; // Set the maximum number of attempts
1414
let attempt = 1;// Track the attempt count
1515

16-
export default function useFWScript(): readonly [boolean, boolean] {
16+
export default function useFWScript({ maxAttempt = 3, retryDuration = 3 }: ScriptDownloadRetryStrategy): readonly [boolean, boolean] {
1717
const [state, setState] = React.useState<ScriptStatusInterface>({
1818
loaded: false,
1919
error: false,
2020
});
2121

22+
// Prevent values lower than 1
23+
maxAttempt = maxAttempt < 1 ? 1 : maxAttempt;
24+
retryDuration = retryDuration < 1 ? 1 : retryDuration;
25+
2226
React.useEffect((): (() => void) | void => {
2327
if (loadedScripts.hasOwnProperty('src')) {
2428
setState({
@@ -64,12 +68,12 @@ export default function useFWScript(): readonly [boolean, boolean] {
6468
const onScriptError = React.useCallback((): void => {
6569
delete loadedScripts.src;
6670

71+
// eslint-disable-next-line no-console
6772
console.log(`Flutterwave script download failed. Attempt: ${attempt}`);
6873

69-
if (attempt < maxAttempts) {
74+
if (attempt < maxAttempt) {
7075
++attempt;
71-
72-
setTimeout(() => downloadScript(), (attempt * 1000)); // Progressively increase the delay before retry
76+
setTimeout(() => downloadScript(), (retryDuration * 1000));
7377
} else {
7478
setState({
7579
loaded: true,

src/types.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@ export interface FlutterwaveConfig {
9999
payment_plan?: FlutterWaveProps['payment_plan'];
100100
payment_options: FlutterWaveProps['payment_options'];
101101
subaccounts?: FlutterWaveProps['subaccounts'];
102+
scriptDownloadRetryStrategy?: ScriptDownloadRetryStrategy
102103
}
103104

104105
export interface InitializeFlutterwavePayment {
@@ -115,3 +116,8 @@ export interface FlutterWaveResponse {
115116
status: string;
116117
transaction_id: number;
117118
}
119+
120+
export interface ScriptDownloadRetryStrategy {
121+
maxAttempt?: number;
122+
retryDuration?: number;
123+
}

0 commit comments

Comments
 (0)