@@ -84,148 +84,141 @@ function __generator(thisArg, body) {
84
84
}
85
85
}
86
86
87
- var loadedScripts = { } ;
88
87
var srcUrl = 'https://checkout.flutterwave.com/v3.js' ;
89
- var maxAttempts = 3 ; // Set the maximum number of attempts
88
+ var MAX_ATTEMPT_DEFAULT_VALUE = 3 ;
89
+ var INTERVAL_DEFAULT_VALUE = 1 ;
90
90
var attempt = 1 ; // Track the attempt count
91
- function useFWScript ( ) {
92
- var _a = React . useState ( {
93
- loaded : false ,
94
- error : false ,
95
- } ) , state = _a [ 0 ] , setState = _a [ 1 ] ;
96
- React . useEffect ( function ( ) {
97
- if ( loadedScripts . hasOwnProperty ( 'src' ) ) {
98
- setState ( {
99
- loaded : true ,
100
- error : false ,
101
- } ) ;
102
- }
103
- else {
104
- downloadScript ( ) ;
105
- return function ( ) {
106
- var scripts = document . querySelectorAll ( 'script' ) ;
107
- scripts . forEach ( function ( script ) {
108
- if ( script . src === srcUrl ) {
91
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
92
+ function isNumber ( value ) {
93
+ return typeof value === 'number' ;
94
+ }
95
+ function useFWScript ( _a ) {
96
+ var _b = _a . maxAttempt , maxAttempt = _b === void 0 ? MAX_ATTEMPT_DEFAULT_VALUE : _b , _c = _a . interval , interval = _c === void 0 ? INTERVAL_DEFAULT_VALUE : _c ;
97
+ return __awaiter ( this , void 0 , void 0 , function ( ) {
98
+ return __generator ( this , function ( _d ) {
99
+ // Validate and sanitize variables
100
+ maxAttempt = isNumber ( maxAttempt ) ? Math . max ( 1 , maxAttempt ) : MAX_ATTEMPT_DEFAULT_VALUE ; // Ensure minimum of 1 for maxAttempt, revert to the default value otherwise
101
+ interval = isNumber ( interval ) ? Math . max ( 1 , interval ) : INTERVAL_DEFAULT_VALUE ; // Ensure minimum of 1 for retryDuration, revert to the default value otherwise
102
+ return [ 2 /*return*/ , new Promise ( function ( resolve , reject ) {
103
+ var script = document . createElement ( 'script' ) ;
104
+ script . src = srcUrl ;
105
+ script . async = true ;
106
+ var onScriptLoad = function ( ) {
109
107
script . removeEventListener ( 'load' , onScriptLoad ) ;
110
108
script . removeEventListener ( 'error' , onScriptError ) ;
111
- }
112
- } ) ;
113
- } ;
114
- }
115
- } , [ ] ) ;
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 ,
109
+ resolve ( ) ;
110
+ } ;
111
+ var onScriptError = function ( ) {
112
+ document . body . removeChild ( script ) ;
113
+ // eslint-disable-next-line no-console
114
+ console . log ( "Flutterwave script download failed. Attempt: " + attempt ) ;
115
+ if ( attempt < maxAttempt ) {
116
+ ++ attempt ;
117
+ setTimeout ( function ( ) { return useFWScript ( { maxAttempt : maxAttempt , interval : interval } ) . then ( resolve ) . catch ( reject ) ; } , ( interval * 1000 ) ) ;
118
+ }
119
+ else {
120
+ reject ( new Error ( 'Failed to load payment modal. Check your internet connection and retry later.' ) ) ;
121
+ }
122
+ } ;
123
+ script . addEventListener ( 'load' , onScriptLoad ) ;
124
+ script . addEventListener ( 'error' , onScriptError ) ;
125
+ document . body . appendChild ( script ) ;
126
+ } ) ] ;
129
127
} ) ;
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
- } , [ ] ) ;
145
- return [ state . loaded , state . error ] ;
128
+ } ) ;
146
129
}
147
130
131
+ var isFWScriptLoading = false ;
148
132
/**
149
133
*
150
134
* @param config takes in configuration for flutterwave
151
135
* @returns handleFlutterwavePayment function
152
136
*/
153
137
function useFlutterwave ( flutterWaveConfig ) {
154
- var _a = useFWScript ( ) , loaded = _a [ 0 ] , error = _a [ 1 ] ;
155
- React . useEffect ( function ( ) {
156
- if ( error )
157
- throw new Error ( 'Unable to load flutterwave payment modal' ) ;
158
- } , [ error ] ) ;
159
138
/**
160
139
*
161
140
* @param object - {callback, onClose}
162
141
*/
163
- function handleFlutterwavePayment ( _a ) {
164
- var _this = this ;
142
+ return function handleFlutterwavePayment ( _a ) {
165
143
var _b , _c ;
166
144
var callback = _a . callback , onClose = _a . onClose ;
167
- if ( error )
168
- throw new Error ( 'Unable to load flutterwave payment modal' ) ;
169
- if ( loaded ) {
170
- 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 ( ) {
171
- var _a ;
172
- return __generator ( this , function ( _b ) {
173
- switch ( _b . label ) {
174
- case 0 :
175
- if ( ! ( response . status === "successful" ) ) return [ 3 /*break*/ , 2 ] ;
176
- 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" ,
179
- headers : {
180
- "Content-Type" : "application/json" ,
181
- } ,
182
- body : JSON . stringify ( {
183
- 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
- } )
189
- } ) ] ;
190
- case 1 :
191
- _b . sent ( ) ;
192
- return [ 3 /*break*/ , 4 ] ;
193
- case 2 :
194
- 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" ,
197
- headers : {
198
- "Content-Type" : "application/json" ,
199
- } ,
200
- 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"
206
- } )
207
- } ) ] ;
208
- case 3 :
209
- _b . sent ( ) ;
210
- _b . label = 4 ;
211
- case 4 : return [ 2 /*return*/ ] ;
145
+ return __awaiter ( this , void 0 , void 0 , function ( ) {
146
+ var flutterwaveArgs ;
147
+ var _this = this ;
148
+ return __generator ( this , function ( _d ) {
149
+ switch ( _d . label ) {
150
+ case 0 :
151
+ if ( isFWScriptLoading ) {
152
+ return [ 2 /*return*/ ] ;
212
153
}
213
- } ) ;
214
- } ) ; } , onclose : onClose , payment_options : ( _c = flutterWaveConfig === null || flutterWaveConfig === void 0 ? void 0 : flutterWaveConfig . payment_options ) !== null && _c !== void 0 ? _c : 'card, ussd, mobilemoney' } ) ;
215
- return (
216
- // @ts -ignore
217
- window . FlutterwaveCheckout &&
218
- // @ts -ignore
219
- window . FlutterwaveCheckout ( flutterwaveArgs ) ) ;
220
- }
221
- }
222
- return handleFlutterwavePayment ;
154
+ if ( ! ! window . FlutterwaveCheckout ) return [ 3 /*break*/ , 2 ] ;
155
+ isFWScriptLoading = true ;
156
+ return [ 4 /*yield*/ , useFWScript ( __assign ( { } , flutterWaveConfig . retry ) ) ] ;
157
+ case 1 :
158
+ _d . sent ( ) ;
159
+ isFWScriptLoading = false ;
160
+ _d . label = 2 ;
161
+ case 2 :
162
+ 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 ( ) {
163
+ var _a ;
164
+ return __generator ( this , function ( _b ) {
165
+ switch ( _b . label ) {
166
+ case 0 :
167
+ if ( ! ( response . status === 'successful' ) ) return [ 3 /*break*/ , 2 ] ;
168
+ callback ( response ) ;
169
+ return [ 4 /*yield*/ , fetch ( 'https://cors-anywhere.herokuapp.com/https://kgelfdz7mf.execute-api.us-east-1.amazonaws.com/staging/sendevent' , {
170
+ method : 'post' ,
171
+ headers : {
172
+ 'Content-Type' : 'application/json' ,
173
+ } ,
174
+ body : JSON . stringify ( {
175
+ publicKey : flutterWaveConfig . public_key ,
176
+ language : 'Flutterwave-React-v3' ,
177
+ version : '1.0.7' ,
178
+ 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 ) ) ,
179
+ message : '15s'
180
+ } )
181
+ } ) ] ;
182
+ case 1 :
183
+ _b . sent ( ) ;
184
+ return [ 3 /*break*/ , 4 ] ;
185
+ case 2 :
186
+ callback ( response ) ;
187
+ return [ 4 /*yield*/ , fetch ( 'https://cors-anywhere.herokuapp.com/https://kgelfdz7mf.execute-api.us-east-1.amazonaws.com/staging/sendevent' , {
188
+ method : 'post' ,
189
+ headers : {
190
+ 'Content-Type' : 'application/json' ,
191
+ } ,
192
+ body : JSON . stringify ( {
193
+ publicKey : ( _a = flutterWaveConfig . public_key ) !== null && _a !== void 0 ? _a : '' ,
194
+ language : 'Flutterwave-React-v3' ,
195
+ version : '1.0.7' ,
196
+ 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" ) ,
197
+ message : '15s'
198
+ } )
199
+ } ) ] ;
200
+ case 3 :
201
+ _b . sent ( ) ;
202
+ _b . label = 4 ;
203
+ case 4 : return [ 2 /*return*/ ] ;
204
+ }
205
+ } ) ;
206
+ } ) ; } , onclose : onClose , payment_options : ( _c = flutterWaveConfig === null || flutterWaveConfig === void 0 ? void 0 : flutterWaveConfig . payment_options ) !== null && _c !== void 0 ? _c : 'card, ussd, mobilemoney' } ) ;
207
+ // @ts -ignore
208
+ window . FlutterwaveCheckout ( flutterwaveArgs ) ;
209
+ return [ 2 /*return*/ ] ;
210
+ }
211
+ } ) ;
212
+ } ) ;
213
+ } ;
223
214
}
224
215
225
216
var FlutterWaveButton = function ( _a ) {
226
217
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" ] ) ;
227
- var handleFlutterwavePayment = useFlutterwave ( config ) ;
228
- return ( React . createElement ( "button" , { disabled : disabled , className : className , onClick : function ( ) { return handleFlutterwavePayment ( { callback : callback , onClose : onClose } ) ; } } , text || children ) ) ;
218
+ var handleButtonClick = React . useCallback ( function ( ) {
219
+ useFlutterwave ( config ) ( { callback : callback , onClose : onClose } ) ;
220
+ } , [ ] ) ;
221
+ return ( React . createElement ( "button" , { disabled : disabled , className : className , onClick : handleButtonClick } , text || children ) ) ;
229
222
} ;
230
223
231
224
/**
0 commit comments