diff --git a/android/src/main/java/com/reactnativestripesdk/CollectBankAccountLauncherFragment.kt b/android/src/main/java/com/reactnativestripesdk/CollectBankAccountLauncherFragment.kt index 28756dfdc..3e99e5f19 100644 --- a/android/src/main/java/com/reactnativestripesdk/CollectBankAccountLauncherFragment.kt +++ b/android/src/main/java/com/reactnativestripesdk/CollectBankAccountLauncherFragment.kt @@ -8,6 +8,7 @@ import android.widget.FrameLayout import androidx.appcompat.app.AppCompatActivity import androidx.fragment.app.Fragment import com.facebook.react.bridge.Promise +import com.facebook.react.bridge.ReactApplicationContext import com.stripe.android.model.PaymentIntent import com.stripe.android.model.SetupIntent import com.stripe.android.model.StripeIntent @@ -16,7 +17,7 @@ import com.stripe.android.payments.bankaccount.CollectBankAccountLauncher import com.stripe.android.payments.bankaccount.navigation.CollectBankAccountResult class CollectBankAccountLauncherFragment( - private val activity: AppCompatActivity, + private val context: ReactApplicationContext, private val publishableKey: String, private val clientSecret: String, private val isPaymentIntent: Boolean, @@ -77,7 +78,7 @@ class CollectBankAccountLauncherFragment( promise.resolve(createError(ErrorType.Failed.toString(), result.error)) } } - activity.supportFragmentManager.beginTransaction().remove(this).commit() + (context.currentActivity as? AppCompatActivity)?.supportFragmentManager?.beginTransaction()?.remove(this)?.commit() } } } diff --git a/android/src/main/java/com/reactnativestripesdk/GooglePayPaymentMethodLauncherFragment.kt b/android/src/main/java/com/reactnativestripesdk/GooglePayPaymentMethodLauncherFragment.kt index d98647547..9a2402c89 100644 --- a/android/src/main/java/com/reactnativestripesdk/GooglePayPaymentMethodLauncherFragment.kt +++ b/android/src/main/java/com/reactnativestripesdk/GooglePayPaymentMethodLauncherFragment.kt @@ -8,11 +8,12 @@ import android.widget.FrameLayout import androidx.appcompat.app.AppCompatActivity import androidx.fragment.app.Fragment import com.facebook.react.bridge.Promise +import com.facebook.react.bridge.ReactApplicationContext import com.stripe.android.googlepaylauncher.GooglePayEnvironment import com.stripe.android.googlepaylauncher.GooglePayPaymentMethodLauncher class GooglePayPaymentMethodLauncherFragment( - private val activity: AppCompatActivity, + private val context: ReactApplicationContext, private val isTestEnv: Boolean, private val paymentMethodRequired: Boolean, private val promise: Promise @@ -36,7 +37,7 @@ class GooglePayPaymentMethodLauncherFragment( ), readyCallback = { promise.resolve(it) - activity.supportFragmentManager.beginTransaction().remove(this).commit() + (context.currentActivity as? AppCompatActivity)?.supportFragmentManager?.beginTransaction()?.remove(this)?.commit() }, resultCallback = {} ) diff --git a/android/src/main/java/com/reactnativestripesdk/StripeSdkModule.kt b/android/src/main/java/com/reactnativestripesdk/StripeSdkModule.kt index 1d358a7e7..aa30463bd 100644 --- a/android/src/main/java/com/reactnativestripesdk/StripeSdkModule.kt +++ b/android/src/main/java/com/reactnativestripesdk/StripeSdkModule.kt @@ -24,7 +24,7 @@ import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch @ReactModule(name = StripeSdkModule.NAME) -class StripeSdkModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaModule(reactContext) { +class StripeSdkModule(private val reactContext: ReactApplicationContext) : ReactContextBaseJavaModule(reactContext) { var cardFieldView: CardFieldView? = null var cardFormView: CardFormView? = null @@ -216,21 +216,23 @@ class StripeSdkModule(reactContext: ReactApplicationContext) : ReactContextBaseJ PaymentConfiguration.init(reactApplicationContext, publishableKey, stripeAccountId) paymentLauncherFragment = PaymentLauncherFragment(stripe, publishableKey, stripeAccountId) - (currentActivity as AppCompatActivity).supportFragmentManager.beginTransaction() - .add(paymentLauncherFragment, "payment_launcher_fragment") - .commit() + getCurrentActivityOrResolveWithError(promise)?.let { + it.supportFragmentManager.beginTransaction() + .add(paymentLauncherFragment, "payment_launcher_fragment") + .commit() - val localBroadcastManager = LocalBroadcastManager.getInstance(reactApplicationContext) - localBroadcastManager.registerReceiver(mPaymentSheetReceiver, IntentFilter(ON_PAYMENT_RESULT_ACTION)) - localBroadcastManager.registerReceiver(mPaymentSheetReceiver, IntentFilter(ON_PAYMENT_OPTION_ACTION)) - localBroadcastManager.registerReceiver(mPaymentSheetReceiver, IntentFilter(ON_CONFIGURE_FLOW_CONTROLLER)) - localBroadcastManager.registerReceiver(mPaymentSheetReceiver, IntentFilter(ON_INIT_PAYMENT_SHEET)) + val localBroadcastManager = LocalBroadcastManager.getInstance(reactApplicationContext) + localBroadcastManager.registerReceiver(mPaymentSheetReceiver, IntentFilter(ON_PAYMENT_RESULT_ACTION)) + localBroadcastManager.registerReceiver(mPaymentSheetReceiver, IntentFilter(ON_PAYMENT_OPTION_ACTION)) + localBroadcastManager.registerReceiver(mPaymentSheetReceiver, IntentFilter(ON_CONFIGURE_FLOW_CONTROLLER)) + localBroadcastManager.registerReceiver(mPaymentSheetReceiver, IntentFilter(ON_INIT_PAYMENT_SHEET)) - localBroadcastManager.registerReceiver(googlePayReceiver, IntentFilter(ON_INIT_GOOGLE_PAY)) - localBroadcastManager.registerReceiver(googlePayReceiver, IntentFilter(ON_GOOGLE_PAY_RESULT)) - localBroadcastManager.registerReceiver(googlePayReceiver, IntentFilter(ON_GOOGLE_PAYMENT_METHOD_RESULT)) + localBroadcastManager.registerReceiver(googlePayReceiver, IntentFilter(ON_INIT_GOOGLE_PAY)) + localBroadcastManager.registerReceiver(googlePayReceiver, IntentFilter(ON_GOOGLE_PAY_RESULT)) + localBroadcastManager.registerReceiver(googlePayReceiver, IntentFilter(ON_GOOGLE_PAYMENT_METHOD_RESULT)) - promise.resolve(null) + promise.resolve(null) + } } @ReactMethod @@ -555,14 +557,14 @@ class StripeSdkModule(reactContext: ReactApplicationContext) : ReactContextBaseJ @ReactMethod @SuppressWarnings("unused") fun isGooglePaySupported(params: ReadableMap?, promise: Promise) { - getCurrentActivityOrResolveWithError(promise)?.let { - val fragment = GooglePayPaymentMethodLauncherFragment( - it, - getBooleanOrFalse(params, "testEnv"), - getBooleanOrFalse(params, "existingPaymentMethodRequired"), - promise - ) + val fragment = GooglePayPaymentMethodLauncherFragment( + reactContext, + getBooleanOrFalse(params, "testEnv"), + getBooleanOrFalse(params, "existingPaymentMethodRequired"), + promise + ) + getCurrentActivityOrResolveWithError(promise)?.let { it.supportFragmentManager.beginTransaction() .add(fragment, "google_pay_support_fragment") .commit() @@ -643,17 +645,18 @@ class StripeSdkModule(reactContext: ReactApplicationContext) : ReactContextBaseJ ) val fragment = CollectBankAccountLauncherFragment( - currentActivity as AppCompatActivity, + reactContext, publishableKey, clientSecret, isPaymentIntent, collectParams, promise ) - - (currentActivity as AppCompatActivity).supportFragmentManager.beginTransaction() - .add(fragment, "collect_bank_account_launcher_fragment") - .commit() + getCurrentActivityOrResolveWithError(promise)?.let { + it.supportFragmentManager.beginTransaction() + .add(fragment, "collect_bank_account_launcher_fragment") + .commit() + } } @ReactMethod @@ -724,6 +727,18 @@ class StripeSdkModule(reactContext: ReactApplicationContext) : ReactContextBaseJ } } + /** + * Safely get and cast the current activity as an AppCompatActivity. If that fails, the promise + * provided will be resolved with an error message instructing the user to retry the method. + */ + private fun getCurrentActivityOrResolveWithError(promise: Promise?): AppCompatActivity? { + (currentActivity as? AppCompatActivity)?.let { + return it + } + promise?.resolve(createMissingActivityError()) + return null + } + companion object { const val NAME = "StripeSdk" }