On Android, I had been using expo-stripe-checkout for payments on an Expo managed app. Everything was working fine until I updated to the newest version of expo and react-native. Now, none of the callbacks, like onClose and onPaymentSuccess are working. It seems WebView was removed from react-native, so I'm importing directly from react-native-webview
.
Instead of using expo-stripe-checkout
, I created my own component, to try and work through what's happening, and it seems as if WebView's injectedJavaScript
isn't running at all, and therefore window.postMessage
or window.ReactNativeWebView.postMessage
isn't working.
package.json:
{"name": "example","version": "0.0.6","private": true,"devDependencies": {"jest-expo": "^37.0.0","react-test-renderer": "16.0.0","schedule": "^0.4.0" },"main": "./node_modules/expo/AppEntry.js","scripts": {"start": "expo start","eject": "expo eject","android": "expo start --android","ios": "expo start --ios","test": "node node_modules/jest/bin/jest.js --watch","prettier": "./node_modules/prettier/bin-prettier.js --single-quote --trailing-comma es5 --print-width 100 --write 'app/**/*.js' -l" },"jest": {"preset": "jest-expo" },"dependencies": {"@ptomasroos/react-native-multi-slider": "^1.0.0","@react-native-community/masked-view": "^0.1.10","@react-navigation/drawer": "^5.6.4","@react-navigation/native": "^5.2.3","@react-navigation/stack": "^5.2.18","axios": "^0.17.1","babel-plugin-transform-remove-console": "^6.9.4","emoji-utils": "^1.0.1","expo": "^37.0.0","expo-analytics": "^1.0.9","expo-apple-authentication": "^2.1.1","expo-av": "~8.1.0","expo-blur": "~8.1.0","expo-branch": "~2.1.0","expo-constants": "~9.0.0","expo-facebook": "~8.1.0","expo-font": "~8.1.0","expo-image-manipulator": "~8.1.0","expo-image-picker": "~8.1.0","expo-linear-gradient": "~8.1.0","expo-permissions": "~8.1.0","expo-stripe-checkout": "^1.0.1","immutability-helper": "^2.8.1","lottie-react-native": "~2.6.1","moment": "^2.22.1","prettier": "^1.12.1","react": "16.9.0","react-native": "0.61.4","react-native-animate-number": "^0.1.2","react-native-aws3": "0.0.9","react-native-branch": "4.2.1","react-native-calendars": "^1.20.0","react-native-circular-action-menu": "^0.5.0","react-native-circular-progress": "^1.0.1","react-native-datepicker": "^1.7.2","react-native-gesture-handler": "^1.6.1","react-native-gifted-chat": "0.13.0","react-native-google-places-autocomplete": "^1.4.0","react-native-invertible-scroll-view": "^1.1.1","react-native-keyboard-aware-scroll-view": "0.9.1","react-native-maps": "0.26.1","react-native-modal": "^11.5.3","react-native-modal-dropdown": "^0.6.2","react-native-reanimated": "^1.8.0","react-native-safe-area-context": "^0.7.3","react-native-screens": "^2.7.0","react-native-scroll-into-view": "^0.1.4","react-native-snap-carousel": "^3.7.2","react-native-status-bar-height": "^3.0.0-alpha.1","react-native-svg": "11.0.1","react-native-svg-icon": "^0.8.1","react-native-swipe-gestures": "^1.0.5","react-native-unimodules": "~0.8.1","react-native-webview": "^10.3.1","react-redux": "^5.0.7","react-timer-mixin": "^0.13.4","react-visibility-sensor": "^4.1.0","redux": "^4.0.0","redux-thunk": "^2.3.0","sentry-expo": "~2.0.0","socket.io-client": "^2.0.4" }}
I've tried several different suggestions from around the web, but nothing has worked:
StripeCheckout.js
import React, { Component } from 'react';import { Platform, View, ViewPropTypes } from 'react-native';import { PropTypes } from 'prop-types';import { WebView } from 'react-native-webview'class StripeCheckout extends Component { render() { const { publicKey, amount, allowRememberMe, currency, description, imageUrl, storeName, prepopulatedEmail, style, onPaymentSuccess, onClose } = this.props; const jsCode = `(function() { console.log('hello') var originalPostMessage = window.ReactNativeWebView.postMessage; var patchedPostMessage = function(message, targetOrigin, transfer) { originalPostMessage(message, targetOrigin, transfer); }; patchedPostMessage.toString = function() { return String(Object.hasOwnProperty).replace('hasOwnProperty', 'postMessage'); }; window.ReactNativeWebView.postMessage = patchedPostMessage; })();`; const runFirst = ` console.log('firstRun') window.isNativeApp = true; true; // note: this is required, or you'll sometimes get silent failures `; return (<WebView ref={(ref) => { this.webview = ref; }} javaScriptEnabled={true} injectedJavaScriptForMainFrameOnly={false} scrollEnabled={false} bounces={false} messagingEnabled={true} onMessage={(event) => console.log(event)} onPaymentSuccess(event.nativeEvent.data)} injectedJavaScriptBeforeContentLoaded={runFirst} injectedJavaScript={jsCode} source={{ html: `<script src="https://checkout.stripe.com/checkout.js"></script><script> var handler = StripeCheckout.configure({ key: '${publicKey}', image: '${imageUrl}', locale: 'auto', token: function(token) { window.ReactNativeWebView.postMessage(token.id, token.id); }, }); window.onload = function() { console.log('onload') handler.open({ image: '${imageUrl}', name: '${storeName}', description: '${description}', amount: ${amount}, currency: '${currency}', allowRememberMe: ${allowRememberMe}, email: '${prepopulatedEmail}', closed: function() { window.ReactNativeWebView.postMessage("WINDOW_CLOSED", "*"); } }); };</script>`}} style={[{ flex: 1 }, style]} scalesPageToFit={Platform.OS === 'android'} /> ); }}StripeCheckout.propTypes = { publicKey: PropTypes.string.isRequired, amount: PropTypes.number.isRequired, imageUrl: PropTypes.string.isRequired, storeName: PropTypes.string.isRequired, description: PropTypes.string.isRequired, allowRememberMe: PropTypes.bool.isRequired, onPaymentSuccess: PropTypes.func.isRequired, onClose: PropTypes.func.isRequired, currency: PropTypes.string, prepopulatedEmail: PropTypes.string, style: ViewPropTypes.object};StripeCheckout.defaultProps = { prepopulatedEmail: '', currency: 'USD',};export default StripeCheckout;
None of the console's are logging. The stripe integration pops up and returns a token successfully, but then nothing happens, and the component isn't receiving the token (i can see it's returning a token from the stripe logs).
Let me know if there's anything else I should post. Thanks!