#wulff-13-android-confirm
1 messages ยท Page 1 of 1 (latest)
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
thanks for that, was just about to ask for a snippet ๐
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?
Nope, just juggling lots of folks, please bear with us
roger ๐
@limber geode any update? ๐
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?
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 ๐
Which call exactly hits the error?
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
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
That totally okay, I also think this is confusing haha ๐
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
yes yes, but I only receives the stripe account id after the api call
so, there error isnt there though, right, its on the confirmation
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
Ok so looking eg at this explanation: https://stackoverflow.com/a/63883427
This feels similar to our example use of lifecycleScope.launch -- which i dont see in your snippet
Thanks I will try that ๐
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).
@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
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 ๐
Ahhhhhh, yes okay thanks for clarifying
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
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?
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
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?
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)
gotcha
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
I'm curious how you do this on web. Do you have 2 separate Stripe.js instance?
gotcha
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 ๐
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.
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
I always figured that would be a case for one charge and multilpe transfers to connected accounts
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)
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
all good, so yeah for now you have to rework your backend I think