1+ import  React ,  {  createContext ,  useCallback ,  useMemo ,  useState  }  from  'react' ; 
2+ import  {  Modal ,  View ,  ActivityIndicator ,  }  from  'react-native' ; 
3+ import  {  WebView ,  WebViewMessageEvent  }  from  'react-native-webview' ; 
4+ import  { 
5+     PaystackParams , 
6+     PaystackProviderProps , 
7+ }  from  './types' ; 
8+ import  {  validateParams ,  paystackHtmlContent ,  generatePaystackParams ,  handlePaystackMessage  }  from  './utils' ; 
9+ import  {  styles  }  from  './styles' ; 
10+ 
11+ export  const  PaystackContext  =  createContext < { 
12+     popup : { 
13+         checkout : ( params : PaystackParams )  =>  void ; 
14+         newTransaction : ( params : PaystackParams )  =>  void ; 
15+     } ; 
16+ }  |  null > ( null ) ; 
17+ 
18+ export  const  PaystackProvider : React . FC < PaystackProviderProps >  =  ( { 
19+     publicKey, 
20+     currency =  'NGN' , 
21+     defaultChannels =  [ 'card' ] , 
22+     debug =  false , 
23+     children, 
24+     onGlobalSuccess, 
25+     onGlobalCancel, 
26+ } )  =>  { 
27+     const  [ visible ,  setVisible ]  =  useState ( false ) ; 
28+     const  [ params ,  setParams ]  =  useState < PaystackParams  |  null > ( null ) ; 
29+     const  [ method ,  setMethod ]  =  useState < 'checkout'  |  'newTransaction' > ( 'checkout' ) ; 
30+ 
31+     const  fallbackRef  =  useMemo ( ( )  =>  `ref_${ Date . now ( ) }  ,  [ ] ) ; 
32+ 
33+     const  open  =  useCallback ( 
34+         ( params : PaystackParams ,  selectedMethod : 'checkout'  |  'newTransaction' )  =>  { 
35+             if  ( debug )  console . log ( `[Paystack] Opening modal with method: ${ selectedMethod }  ) ; 
36+             if  ( ! validateParams ( params ,  debug ) )  return ; 
37+             setParams ( params ) ; 
38+             setMethod ( selectedMethod ) ; 
39+             setVisible ( true ) ; 
40+         } , 
41+         [ debug ] 
42+     ) ; 
43+ 
44+     const  checkout  =  ( params : PaystackParams )  =>  open ( params ,  'checkout' ) ; 
45+     const  newTransaction  =  ( params : PaystackParams )  =>  open ( params ,  'newTransaction' ) ; 
46+ 
47+     const  close  =  ( )  =>  { 
48+         setVisible ( false ) ; 
49+         setParams ( null ) ; 
50+     } 
51+ 
52+     const  handleMessage  =  ( event : WebViewMessageEvent )  =>  { 
53+         handlePaystackMessage ( { 
54+             event, 
55+             debug, 
56+             params, 
57+             onGlobalSuccess, 
58+             onGlobalCancel, 
59+             close, 
60+         } ) ; 
61+     } ; 
62+ 
63+     const  paystackHTML  =  useMemo ( ( )  =>  { 
64+         if  ( ! params )  return  '' ; 
65+         return  paystackHtmlContent ( 
66+             generatePaystackParams ( { 
67+                 publicKey, 
68+                 email : params . email , 
69+                 amount : params . amount , 
70+                 reference : params . reference  ||  fallbackRef , 
71+                 metadata : params . metadata , 
72+                 currency, 
73+                 channels : defaultChannels , 
74+             } ) , 
75+             method 
76+         ) ; 
77+     } ,  [ params ,  method ] ) ; 
78+ 
79+     if  ( debug  &&  visible )  { 
80+         console . log ( '[Paystack] HTML Injected:' ,  paystackHTML ) ; 
81+     } 
82+ 
83+     return  ( 
84+         < PaystackContext . Provider  value = { {  popup : {  checkout,  newTransaction }  } } > 
85+             { children } 
86+             < Modal  visible = { visible }  transparent  animationType = "slide" > 
87+                 < View  style = { styles . container } > 
88+                     < WebView 
89+                         originWhitelist = { [ "*" ] } 
90+                         source = { {  html : paystackHTML  } } 
91+                         onMessage = { handleMessage } 
92+                         javaScriptEnabled 
93+                         domStorageEnabled 
94+                         startInLoadingState 
95+                         onLoadStart = { ( )  =>  debug  &&  console . log ( '[Paystack] WebView Load Start' ) } 
96+                         onLoadEnd = { ( )  =>  debug  &&  console . log ( '[Paystack] WebView Load End' ) } 
97+                         renderLoading = { ( )  =>  < ActivityIndicator  size = "large"  /> } 
98+                     /> 
99+                 </ View > 
100+             </ Modal > 
101+         </ PaystackContext . Provider > 
102+     ) ; 
103+ } ; 
0 commit comments