android-checkout-sdk icon indicating copy to clipboard operation
android-checkout-sdk copied to clipboard

Support for Jetpack Compose

Open ridiculouswaffle opened this issue 2 years ago • 8 comments

Is your feature request related to a problem? Please describe. Yes, I created a button and I started it using this documentation

Describe the solution you'd like Design the PayPal button in Jetpack Compose, start the SDK, and add it with the SDK future versions

Describe alternatives you've considered Creating a button and starting it programmatically is the current solution as of now.

Additional context NA

ridiculouswaffle avatar Mar 19 '22 04:03 ridiculouswaffle

@dscoder421 - Thanks for the feature request.

Are you able to include the PaymentButton View in Compose? https://developer.android.com/jetpack/compose/interop/interop-apis#views-in-compose

Is there another behavior or integration that you're looking for?

tdchow avatar Mar 21 '22 13:03 tdchow

Hi Tim Chow,

Are you able to include the PaymentButton View in Compose? https://developer.android.com/jetpack/compose/interop/interop-apis#views-in-compose

I can't use the PaymentButton view in Compose. When I use it I get this error (it is a pure Compose project and has no libraries such as androidx.appcompat:appcompat:1.4.0):

android.view.InflateException: Binary XML file line #25: Binary XML file line #25: Error inflating class com.google.android.material.progressindicator.CircularProgressIndicator
    Caused by: android.view.InflateException: Binary XML file line #25: Error inflating class com.google.android.material.progressindicator.CircularProgressIndicator
    Caused by: java.lang.reflect.InvocationTargetException
        at java.lang.reflect.Constructor.newInstance0(Native Method)
        at java.lang.reflect.Constructor.newInstance(Constructor.java:334)
        at android.view.LayoutInflater.createView(LayoutInflater.java:650)
        at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:797)
        at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:737)
        at android.view.LayoutInflater.rInflate(LayoutInflater.java:870)
        at android.view.LayoutInflater.inflate(LayoutInflater.java:489)
        at android.view.LayoutInflater.inflate(LayoutInflater.java:423)
        at com.paypal.checkout.paymentbutton.PaymentButton.<init>(PaymentButton.kt:239)
        at com.paypal.checkout.paymentbutton.PayPalButton.<init>(PayPalButton.kt:50)
        at com.paypal.checkout.paymentbutton.PayPalButton.<init>(PayPalButton.kt:46)
        at com.eartina.eartinaedu.ui.pages.PaymentsKt$Payments$2$3.invoke(Payments.kt:157)
        at com.eartina.eartinaedu.ui.pages.PaymentsKt$Payments$2$3.invoke(Payments.kt:156)
        at androidx.compose.ui.viewinterop.ViewFactoryHolder.setFactory(AndroidView.android.kt:156)
        at androidx.compose.ui.viewinterop.AndroidView_androidKt$AndroidView$1.invoke(AndroidView.android.kt:99)
        at androidx.compose.ui.viewinterop.AndroidView_androidKt$AndroidView$1.invoke(AndroidView.android.kt:96)
        at androidx.compose.ui.viewinterop.AndroidView_androidKt$AndroidView$$inlined$ComposeNode$1.invoke(Composables.kt:225)
        at androidx.compose.runtime.ComposerImpl$createNode$2.invoke(Composer.kt:1365)
        at androidx.compose.runtime.ComposerImpl$createNode$2.invoke(Composer.kt:1363)
        at androidx.compose.runtime.ComposerImpl$recordInsert$2.invoke(Composer.kt:2768)
        at androidx.compose.runtime.ComposerImpl$recordInsert$2.invoke(Composer.kt:2765)
        at androidx.compose.runtime.CompositionImpl.applyChanges(Composition.kt:637)
        at androidx.compose.runtime.Recomposer$runRecomposeAndApplyChanges$2$2.invoke(Recomposer.kt:488)
        at androidx.compose.runtime.Recomposer$runRecomposeAndApplyChanges$2$2.invoke(Recomposer.kt:425)
        at androidx.compose.ui.platform.AndroidUiFrameClock$withFrameNanos$2$callback$1.doFrame(AndroidUiFrameClock.android.kt:34)
        at androidx.compose.ui.platform.AndroidUiDispatcher.performFrameDispatch(AndroidUiDispatcher.android.kt:109)
        at androidx.compose.ui.platform.AndroidUiDispatcher.access$performFrameDispatch(AndroidUiDispatcher.android.kt:41)
        at androidx.compose.ui.platform.AndroidUiDispatcher$dispatchCallback$1.doFrame(AndroidUiDispatcher.android.kt:69)
        at android.view.Choreographer$CallbackRecord.run(Choreographer.java:1036)
        at android.view.Choreographer.doCallbacks(Choreographer.java:850)
        at android.view.Choreographer.doFrame(Choreographer.java:763)
        at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:1024)
        at android.os.Handler.handleCallback(Handler.java:790)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loop(Looper.java:200)
        at android.app.ActivityThread.main(ActivityThread.java:6971)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:524)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)

So I understood that the PaymentButton needs the native CircularProgressIndicator to function properly. So I added the dependency androidx.appcompat:appcompat:1.4.0, which provides me this error:

java.lang.StackOverflowError
	at com.google.common.collect.Lists.equalsImpl(Lists.java:973)
	at com.google.common.collect.ImmutableList.equals(ImmutableList.java:666)
	at kotlin.jvm.internal.Intrinsics.areEqual(Intrinsics.java:167)
	at com.android.build.gradle.internal.ide.dependencies.VariantKey.equals(ArtifactUtils.kt)
	at com.android.build.gradle.internal.ide.dependencies.FullDependencyGraphBuilder.handleDependency(FullDependencyGraphBuilder.kt:119)
	at com.android.build.gradle.internal.ide.dependencies.FullDependencyGraphBuilder.handleDependency(FullDependencyGraphBuilder.kt:182)
	at com.android.build.gradle.internal.ide.dependencies.FullDependencyGraphBuilder.handleDependency(FullDependencyGraphBuilder.kt:182)
	at com.android.build.gradle.internal.ide.dependencies.FullDependencyGraphBuilder.handleDependency(FullDependencyGraphBuilder.kt:182)
(Very big output with the above lines repeating)

And I can't use the Compose libraries on a XML project which provides me the same java.lang.StackOverflowError

Is there another behavior or integration that you're looking for?

Yes, I recommend creating a button as a pure compose function, and then using the SDK's internal functions to start the payment flow.

ridiculouswaffle avatar Mar 22 '22 08:03 ridiculouswaffle

Thanks for the stacktraces. We haven't had a chance to test our payment buttons within Compose. But I'll create a ticket for us to track the work. Will keep you updated here!

tdchow avatar Mar 22 '22 14:03 tdchow

Thanks

ridiculouswaffle avatar Mar 22 '22 15:03 ridiculouswaffle

Hi, I have the same issue. Is there a fix coming out soon ?

kilaniamine96 avatar Oct 20 '22 18:10 kilaniamine96

Hi, I have the same issue. Is there a fix coming out soon ?

I dont know @kilaniamine96, now my team uses Flutter and I still didn't get a response

ridiculouswaffle avatar Oct 25 '22 14:10 ridiculouswaffle

Hi! Any progress about the support for Compose?

estebanlamas avatar Dec 07 '22 16:12 estebanlamas

Hey guys I found a workaround while waiting for the support for Compose by looking inside Paypal SDK's code, inside your onClick on your Compose button, just do this :

                        PayPalCheckout.registerCallbacks(
                            onApprove = OnApprove { approval ->
                                approval.orderActions.capture { captureOrderResult ->
                                    Log.d("PAYPAL", captureOrderResult.toString())
                                }
                            },
                            onCancel = null,
                            onError = OnError {
                                Log.d("PAYPAL", "Error : ${it.reason}")
                            }
                        )
                        PayPalCheckout.startCheckout(CreateOrder { createOrderActions ->
                            val order =
                                Order(
                                    intent = OrderIntent.CAPTURE,
                                    appContext = AppContext(userAction = UserAction.PAY_NOW),
                                    purchaseUnitList =
                                    listOf(
                                        PurchaseUnit(
                                            payee = Payee(emailAddress = "[email protected]"),
                                            amount = Amount(currencyCode = CurrencyCode.USD, value = "10.00")
                                        )
                                    )
                                )
                            createOrderActions.create(order)
                        })

You can try to do something similar or play with it a little bit. Hope it helps a bit ! Don't hesitate to look inside Paypal's SDK to see how they do stuff and try to adapt it to Compose.

kilaniamine96 avatar Dec 07 '22 16:12 kilaniamine96