Listening to webview actions to implement paystack in RN

730 Views Asked by At

I am trying to run paystack inside a webview however it has a button called cancel payment that doesn't do anything. I am told that the button runs a function called onClose that runs window.close but since its in a webview it doesn't work.

Now I am trying to hook into that function and ideally make a navigation action but for now just a console.log or alert would be good enough.

This is what the webview looks like now

<WebView 
      source={{ uri: authorization_url }}
      onNavigationStateChange={() => console.log('navstate changed')}
      cacheEnabled={false}
      cacheMode={'LOAD_NO_CACHE'}
      onMessage={(e) => {
          console.log('pressed')
          JSON.parse(e.nativeEvent?.data);
      }}
      onClose={() => {
        console.log('on close')
        navigation.navigate(callBackRoute)
      }}
    />

I thought of adding injectedJavaScript prop but i cant work out what to put in it, I've tried a bunch of things so far without any success.

Below is link to payfast documentation https://paystack.com/docs/guides/using_the_paystack_checkout_in_a_mobile_webview/

Update: I got this working with a timeout hack, would definitely prefer to find a way to remove the timeout and just make it work correctly but the following code is functional

const js = `
      setTimeout(function() {
      var buttons = document.getElementsByTagName('button')
      buttons.forEach((button) => {
        if(button.innerHTML.includes('Cancel Payment')) {
          button.addEventListener("click", function() {  
              var resp = {event:'cancelled'};
              window.ReactNativeWebView.postMessage(JSON.stringify(resp))
              });
        }
      })
    }, 3000);
      true; // note: this is required, or you'll sometimes get silent failures
    `

and

const onNavigationStateChange = state => {
    const { url } = state;
    webViewRef.current.injectJavaScript(js)
    // other navigationStateChangeCode
  }
1

There are 1 best solutions below

3
david_bzura On

You can try using the window.onload event which is fired once the document has finished loading, instead of setting a timeout.

function onButtonClick() {
  var resp = {event:'cancelled'};
  window.ReactNativeWebView.postMessage(JSON.stringify(resp))
}

window.onload = function() {
  var buttons = document.getElementsByTagName('button');
  buttons.forEach((button) => {
    if(button.innerHTML.includes('Cancel Payment')) {
      button.addEventListener("click", onButtonClick);
    }
  })
}