Skip to content

IllegalStateException: AdyenCheckout MessageBus is not initialized — DropInService crashes after Android process death during onAdditionalDetails #1158

Description

@HannesArni

Description

AdyenPaymentPackage.messageBus is a static companion getter that throws when _messageBus is null:

// AdyenPaymentPackage.kt:53
val messageBus: MessageBus
  get() = _messageBus ?: throw IllegalStateException("AdyenCheckout MessageBus is not initialized")

_messageBus is only populated in createNativeModules() (via getOrCreateMessageBus), i.e. when the React Native bridge initializes. However, AdvancedCheckoutService is an Android bound DropInService that the OS can recreate after process death independently of the RN bridge. When it delivers a pending result it calls the throwing getter unconditionally:

// AdvancedCheckoutService.kt (identical in 2.9.1 and current 2.11.1)
override fun onAdditionalDetails(actionComponentData: ActionComponentData) {
  AdyenPaymentPackage.messageBus.onAdditionalDetails(actionComponentData) // <-- throws if bus is null
}

So if Android kills the app process during a 3DS additional-details step (e.g. while the user is redirected to a bank app/browser), the restored DropInActivity rebinds the service and calls onAdditionalDetails before RN has re-initialized, and the app crashes.

Stack trace

java.lang.IllegalStateException
  at com.adyenreactnativesdk.AdyenPaymentPackage$Companion.getMessageBus (AdyenPaymentPackage.kt:53)
  at com.adyenreactnativesdk.component.dropin.AdvancedCheckoutService.onAdditionalDetails (AdvancedCheckoutService.kt:31)
  at com.adyen.checkout.dropin.DropInService.requestDetailsCall (DropInService.kt:36)
  at com.adyen.checkout.dropin.internal.ui.DropInActivity.requestDetailsCall (DropInActivity.kt:250)
  at com.adyen.checkout.dropin.internal.ui.DropInActivity$serviceConnection$1.onServiceConnected (DropInActivity.kt:115)
  at android.app.LoadedApk$ServiceDispatcher.doConnected (LoadedApk.java:2325)
  at android.app.LoadedApk$ServiceDispatcher$RunConnection.run (LoadedApk.java:2362)
  at android.os.Handler.handleCallback (Handler.java:959)
  at android.os.Handler.dispatchMessage (Handler.java:100)
  at android.os.Looper.loopOnce (Looper.java:257)
  at android.os.Looper.loop (Looper.java:342)
  at android.app.ActivityThread.main (ActivityThread.java:9638)
  at java.lang.reflect.Method.invoke
  at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run (RuntimeInit.java:619)
  at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:929)

Steps to reproduce

  1. Start an advanced-flow card payment and reach a 3DS challenge/redirect (onAdditionalDetails).
  2. While the app is backgrounded (e.g. redirected to a bank app/browser), force process death: adb shell am kill <package>, or Developer Options → "Don't keep activities", or apply memory pressure.
  3. Return to the app. The OS restores DropInActivity → rebinds the service → onAdditionalDetails fires before RN re-initializes → crash.

Expected behavior

The SDK should not crash when the message bus is unavailable after process death. It should dismiss the drop-in / surface a recoverable error so the user can retry.

Actual behavior

IllegalStateException: AdyenCheckout MessageBus is not initialized crashes the app.

Environment

  • @adyen/react-native: 2.9.1 — the offending code path is also present in 2.11.1 (verified against the 2.11.1 tag)
  • react-native: 0.79.6 (New Architecture / bridgeless)
  • Platform: Android
  • Flow: Advanced (AdvancedCheckoutService)

Suggested fix

The SDK already exposes internal fun messageBusOrNull(): MessageBus?. The *CheckoutService callbacks (onAdditionalDetails, onSubmit, onBalanceCheck, onOrderRequest, …) could use it and, when null, dismiss via DropInServiceResult.Error(dismissDropIn = true) instead of dereferencing the throwing getter — for both AdvancedCheckoutService and SessionCheckoutService. This is the same "restore DropIn after app gets killed" scenario tracked in Adyen/adyen-android#151.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bug reportwhen a bug report is created

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions