#wulff-13-android-confirm

1 messages ยท Page 1 of 1 (latest)

limber geode
weary sparrow
#

this is my code to give a better understanding

private fun postUpgradeIdentity(paymentMethod: String?) {
        // TODO handle for past due (this requires no payment plan or last edit)
        val requestBody = UpgradeIdentityRequestBody(
            paymentMethod = paymentMethod,
            paymentPlanId = paymentPlan!!.id,
            paymentPlanLastEdit = upgrade!!.lastEdit
        )
        NyxService.instance.upgradeIdentity(identity.id, requestBody)
            .enqueue(object : NyxCallback<SCAResponse>(this) {
                override fun onSuccess(response: Response<SCAResponse>) {
                    val scaResponse = response.body()!!
                    val status = scaResponse.status
                    if (status == SCAResponseStatus.SUCCESS) {
                        showSuccessDialog()
                    } else {
                        // SCA required
                        handleSCAAuthentication(
                            scaResponse.sca.clientSecret,
                            scaResponse.sca.stripeAccount!!
                        )
                    }
                }

                override fun onRequestEnd() {
                    // TODO
                }
            })
    }

    private fun handleSCAAuthentication(clientSecret: String, stripeAccountId: String) {
        // Stripe needed for 3ds confirmation of payment
        val paymentConfiguration = PaymentConfiguration.getInstance(requireContext())
        paymentLauncher = PaymentLauncher.Companion.create(
            this,
            paymentConfiguration.publishableKey,
            paymentConfiguration.stripeAccountId,
            ::onPaymentResult
        )

        val confirmParams = ConfirmPaymentIntentParams.create(clientSecret)
        paymentLauncher.confirm(confirmParams)
    }
#

and it is in a fragment

limber geode
#

thanks for that, was just about to ask for a snippet ๐Ÿ˜„

weary sparrow
#

So my question is how I can confirm the payment without the confirmation needs to be in the onCreate()/onAttach() method in a fragment

#

or like the paymentLaucher configuration

#

Should I provide more info?

limber geode
#

Nope, just juggling lots of folks, please bear with us

weary sparrow
#

roger ๐Ÿ™‚

weary sparrow
#

@limber geode any update? ๐Ÿ™‚

limber geode
#

actually looking at this rn ๐Ÿ™‚

#

I do not have the clientSecret and stripeAccountId before after a call to the backend

#

Can you clarify this? before/after what call?

weary sparrow
#

I first have the clientId and stripeAccountId after an api call to our backend

#

so I dont have them from the beginning and can therefor not provide them in onCreate() in the fragment

#

@limber geode can we please finish this thread? I can literally not move on before I have found a solution to this challenge ๐Ÿ™‚

limber geode
#

Which call exactly hits the error?

weary sparrow
#

it is because the payment launcher is not constructed in onCreate() : paymentLauncher = PaymentLauncher.Companion.create(
this,
paymentConfiguration.publishableKey,
paymentConfiguration.stripeAccountId,
::onPaymentResult
)

#

and then when I confirm the payment with paymentLauncher.confirm(confirmParams) to trigger the action which causes the error

limber geode
#

ahhhh

#

ok, i get it now

#

sorry, was struggling to diff this to our recommended patterns

#

that's for clarifying, and for your pateince here

weary sparrow
#

That totally okay, I also think this is confusing haha ๐Ÿ˜†

limber geode
#

ok, so why do you need to defer the launcher creation, because you dont know why account id?

#

the client secret is expected to come later, right? its only needed to trigger confirm

weary sparrow
#

yes yes, but I only receives the stripe account id after the api call

limber geode
#

so, there error isnt there though, right, its on the confirmation

weary sparrow
#

the error comes bc I do not create the laucher in onCreate, and then I get the startActivityForResult error

#

this error comes when the confirm is triggered

#

so my question is if it is possible to set the stripe account id later or something like that?

#

so I can construct the launcher in onCreate but later set the received stripe account id

limber geode
#

This feels similar to our example use of lifecycleScope.launch -- which i dont see in your snippet

weary sparrow
#

Thanks I will try that ๐Ÿ™‚

surreal shard
#

Hey guys. The problem seems to come down to the fact that we can't reassign the stripeAccountId parameter after the PaymentConfiguration has been initialised. We can do this in iOS (STPAPIClient.shared.stripeAccount = 'acct_xxx') at will, at any time. Is there a similar solution for the Android SDK or do we have to work around this? We could provide the Stripe account in an earlier API request so that we don't have this chicken-and-egg situation (that the account ID is returned after making a request for payment, which requires the PaymentLauncher, which takes an account ID and must be in the onCreate method).

chilly lintel
#

@surreal shard just to confirm, do you have the same issue? Or are you rewording their ask based on your understanding of the Android/iOS SDKs

surreal shard
#

wulff works for me, so it's the same actual issue

#

He's right next to me, I am helping him

#

I should probably have mentioned that ๐Ÿ˜„

chilly lintel
#

Ahhhhhh, yes okay thanks for clarifying

surreal shard
#

This might also help you understand what we do, as it's the same "atypical" flow where we provide a payment method to the server in exchange for a payment intent. This response also includes the Stripe account ID.

#

same endpoint, just Android now instead of iOS

chilly lintel
#

I don't really know this flow you have sorry, you likely didn't talk to me. How do you create a PaymentMethod if you don't know which account to create it on?

surreal shard
#

It is attached to the platform first

#

then replicated to cnnected accounts

#

then we charge connected account customer

#

to make sure every user only has 1 card, and that that card is identical in all connected accounts

chilly lintel
#

so you create the PaymentMEthod on the platform, and then later want to go back client-side in the mobile app, change the stripeAccount (from nothing, since it was your platform, to the connected account's) to do a "direct charge" flow?

surreal shard
#

Only if 3DS is required, otherwise we do it all in one request

#

But if 3DS is required, we return the stripe account id, the payment intent client secret and such to the client

#

client does confirmation and webhooks complete the sale (regardless of 3ds or not)

chilly lintel
#

gotcha

surreal shard
#

The first point being that we do the whole "replace platform card, replicate to connect, attempt to charge customer" in one sync request

#

So this works fine for both web and iOS, as we can change the stripe account quite easily on the client side, but as you can see this is giving us problems on Android

chilly lintel
#

I'm curious how you do this on web. Do you have 2 separate Stripe.js instance?

surreal shard
#

Yeah we just init a new one and call confirm on that object

#

I think

chilly lintel
#

gotcha

surreal shard
#

that or it's a replaceable property

#

not sure

chilly lintel
#

yeah it's not, so you must do multiple Stripe.js instances, damn if you were to charge across N accounts that doesn't sound fun ๐Ÿ˜…

surreal shard
#

I don't see how we could purchase something from two different connected accounts with direct charges at one time

#

At least it's not a case we're planning for

#

The most obvious solution is to provide the stripe account earlier in our flow, so that the Android app can init its PaymentLauncher with the correct account, but I'd prefer not do make changes to our API if there is an easier solution to this on the client side.

chilly lintel
#

Gotcha. It's extremely common as a flow when you split across vendors. Imagine an aggregator like aliexpress but ordering from N vendors for example

#

And yeah that's what @strange zodiac recommended to me internally too for now as the SDK doesn't support the flow you want

surreal shard
#

I always figured that would be a case for one charge and multilpe transfers to connected accounts

chilly lintel
#

The alternative would be to wait for us to implement it, but I have no idea if we'd do this soon

#

well one charge + transfers doesn't work with Standard accounts which you're using (otherwise you hold all liability for disputes and refunds)

surreal shard
#

Okay, we don't use transfers at all so not really an expert on that

#

But anyway, that's not going to happen for us so I'm not worried about this case

chilly lintel
#

all good, so yeah for now you have to rework your backend I think