Adyen / adyen-react-native

Adyen React Native
https://docs.adyen.com/checkout
MIT License
42 stars 32 forks source link

AdyenAction does not work #446

Closed RyanLinXiang closed 1 month ago

RyanLinXiang commented 1 month ago

Describe the bug AdyenAction.hide(true) does not close the drop-in AdyenAction.handle() crashes the app:

FATAL EXCEPTION: main
        android.view.InflateException: Binary XML file line #45 in :layout/view_payment_in_progress: Binary XML file line #45 in 
:layout/view_payment_in_progress: Error inflating class <unknown>
         Suppressed: kotlinx.coroutines.internal.DiagnosticCoroutineContextException: [StandaloneCoroutine{Cancelling}@badd56c, Dispatchers.Main.immediate]
        Caused by: android.view.InflateException: Binary XML file line #45 in :layout/view_payment_in_progress: Error inflating class <unknown>
        Caused by: java.lang.reflect.InvocationTargetException
         at java.lang.reflect.Constructor.newInstance0(Native Method)
         at java.lang.reflect.Constructor.newInstance(Constructor.java:343)
         at android.view.LayoutInflater.createView(LayoutInflater.java:876)
         at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:1028)
         at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:983)
         at android.view.LayoutInflater.rInflate(LayoutInflater.java:1145)
         at android.view.LayoutInflater.inflate(LayoutInflater.java:666)
         at android.view.LayoutInflater.inflate(LayoutInflater.java:544)
         at android.view.LayoutInflater.inflate(LayoutInflater.java:491)
         at com.adyen.checkout.ui.core.databinding.ViewPaymentInProgressBinding.inflate(ViewPaymentInProgressBinding.java:58)
         at com.adyen.checkout.ui.core.internal.ui.view.PaymentInProgressView.<init>(PaymentInProgressView.kt:39)
         at com.adyen.checkout.ui.core.internal.ui.view.PaymentInProgressView.<init>(PaymentInProgressView.kt:27)
         at com.adyen.checkout.redirect.internal.ui.RedirectViewProvider.getView(RedirectViewProvider.kt:23)
         at com.adyen.checkout.ui.core.AdyenComponentView.loadView(AdyenComponentView.kt:121)
         at com.adyen.checkout.ui.core.AdyenComponentView.access$loadView(AdyenComponentView.kt:48)
         at com.adyen.checkout.ui.core.AdyenComponentView$attach$1.invokeSuspend(AdyenComponentView.kt:104)
         at com.adyen.checkout.ui.core.AdyenComponentView$attach$1.invoke(Unknown Source:8)
         at com.adyen.checkout.ui.core.AdyenComponentView$attach$1.invoke(Unknown Source:4)
         at kotlinx.coroutines.flow.FlowKt__TransformKt$onEach$$inlined$unsafeTransform$1$2.emit(Emitters.kt:223)
         at kotlinx.coroutines.flow.StateFlowImpl.collect(StateFlow.kt:396)
         at kotlinx.coroutines.flow.StateFlowImpl$collect$1.invokeSuspend(Unknown Source:15)
         at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
         at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:108)
         at kotlinx.coroutines.EventLoop.processUnconfinedEvent(EventLoop.common.kt:68)
         at kotlinx.coroutines.internal.DispatchedContinuationKt.resumeCancellableWith(DispatchedContinuation.kt:375)
         at kotlinx.coroutines.intrinsics.CancellableKt.startCoroutineCancellable(Cancellable.kt:30)
         at kotlinx.coroutines.intrinsics.CancellableKt.startCoroutineCancellable$default(Cancellable.kt:25)
         at kotlinx.coroutines.CoroutineStart.invoke(CoroutineStart.kt:110)
         at kotlinx.coroutines.AbstractCoroutine.start(AbstractCoroutine.kt:126)
         at kotlinx.coroutines.BuildersKt__Builders_commonKt.launch(Builders.common.kt:56)
         at kotlinx.coroutines.BuildersKt.launch(Unknown Source:1)
         at kotlinx.coroutines.BuildersKt__Builders_commonKt.launch$default(Builders.common.kt:47)
         at kotlinx.coroutines.BuildersKt.launch$default(Unknown Source:1)
         at kotlinx.coroutines.flow.FlowKt__CollectKt.launchIn(Collect.kt:49)
         at kotlinx.coroutines.flow.FlowKt.launchIn(Unknown Source:1)
         at com.adyen.checkout.action.core.internal.ui.DefaultGenericActionDelegate.observeViewFlow(DefaultGenericActionDelegate.kt:167)
         at com.adyen.checkout.action.core.internal.ui.DefaultGenericActionDelegate.handleAction(DefaultGenericActionDelegate.kt:129)
         at com.adyen.checkout.action.core.GenericActionComponent.handleAction(GenericActionComponent.kt:66)
         at com.adyenreactnativesdk.cse.ActionFragment.handle(ActionFragment.kt:64)

I have one general question since AdyenAction standalone is so poorly documented: Does AdyenAction need to be embedded inside the component?

Thanks & BR

ChielBruin commented 1 month ago

Note that the boolean that you provide to the hide function indicates whether an error occurred, not whether the component should be hidden.

As far as I know, the .handle function takes a value as argument that you get from the callback function. So it could well be that it crashes when you don't provide any arguments.

I recommend taking a look at the example app in this repository on how to implement all the callbacks and server requests (https://github.com/Adyen/adyen-react-native/blob/develop/example/src/Views/Checkout/AdvancedCheckout.js)

RyanLinXiang commented 1 month ago

@ChielBruin of course I pass parameters to .handle() - I just put it as example in my original post. But I already resolved by following this solution(https://github.com/Adyen/adyen-react-native/issues/163).

Regarding AdyenAction.hide => here I don't get your point. Why does this method not close the drop in ? I call this method, but it does not do anything.

descorp commented 1 month ago

Hey @RyanLinXiang

But I already resolved

Were you missing a MaterialComponents in styles.xml?

AdyenAction.hide(true) does not close the drop-in

AdyenAction module is unrelated to a Drop-in (aka "list of available payment methods"). If you need to dismiss the Drop-in/Component UI - call nativeComponent.hide(xxx) in AdyenAction callbacks.

Does AdyenAction need to be embedded inside the component?

No, it doesn't need to. AdyenAction.handle(...) returns promise that needs to be awaited. See example code for storedPayment.