Closed timatpam closed 5 months ago
Hi @timatpam, thanks for reaching out and providing logs. I need a few more details to investigate this:
Don't keep activities
switch turned on or off?PaymentDropInService
? Especially the places where you call sendResult
in onSubmit
and onAdditionalDetails
.Hi @jreij.
Don't keep activities
is turned off. override fun onSubmit(state: PaymentComponentState<*>) {
launch(Dispatchers.IO) {
sendResult(
interactor.onPaymentsCallRequested(state)
)
}
}
override fun onAdditionalDetails(actionComponentData: ActionComponentData) {
launch(Dispatchers.IO) {
sendResult(
interactor.makeDetailsCall(actionComponentData)
)
}
}
In the interactor we perform a blocking request to our backend and map the response to DropInServiceResult:
DropInServiceResult.Finished(PaymentDropInResult.SUCCESS_RESULT)
when payment completes successfully;DropInServiceResult.Action(action)
when 3ds is required; the action
is obtained from the backend response:fun map(param: Payment3dsResponse): Action =
when {
param.fingerprintToken?.isNotBlank().orFalse() ->
Threeds2FingerprintAction(
type = Threeds2FingerprintAction.ACTION_TYPE,
paymentData = param.paymentData.orEmpty(),
paymentMethodType = "scheme",
token = param.fingerprintToken.orEmpty(),
)
param.challengeToken?.isNotBlank().orFalse() ->
Threeds2ChallengeAction(
type = Threeds2ChallengeAction.ACTION_TYPE,
paymentData = param.paymentData.orEmpty(),
paymentMethodType = "scheme",
token = param.challengeToken.orEmpty(),
)
param.issuerUrl?.isNotBlank().orFalse() ->
RedirectAction(
type = RedirectAction.ACTION_TYPE,
paymentData = param.paymentData.orEmpty(),
paymentMethodType = "scheme",
url = param.issuerUrl.orEmpty(),
method = null,
)
else ->
throw IllegalArgumentException("Unable to determine action type")
}
@timatpam thanks for providing the answers. I noticed that you are using the Threeds2FingerprintAction
and Threeds2ChallengeAction
in combination with API v71. Generally these actions are used with API v66 and below, with API v71 we use Threeds2Action
.
Can you check the response received on your backend? Specifically the action
object in the responses of /payments
and /payments/details
.
It should look like the sample below:
"action": {
"paymentData": "Ab02b4c0...",
"paymentMethodType": "scheme",
"authorisationToken": "Ab02b4c0...",
"subtype": "fingerprint",
"token": "eyJ...",
"type": "threeDS2"
}
In that case I suggest you forward the action
json as it is to the app and deserialize it to the correct action type using Threeds2Action.SERIALIZER.deserialize(actionJsonResponse)
then pass that object to sendResult
.
But it can be that your backend is receiving 2 different actions with 2 different subtypes, such as:
"action": {
"paymentData": "Ab02b4c0...",
"paymentMethodType": "scheme",
"token": "eyJ...",
"type": "threeDS2Fingerprint"
}
and
"action": {
"paymentData": "Ab02b4c0...",
"paymentMethodType": "scheme",
"token": "eyJ...",
"type": "threeDS2Challenge"
}
In that case I would suggest you discuss with your team the possibility of switching to the default flow. This flow has many benefits but especially the fact that you will not receive 2 actions anymore but only one, so your /payments/details
API call will not return any additional actions to be sent to the SDK and you will not need to make an additional /payments/details
calls which greatly reduces friction.
The issue was solved by switching of the mapping of both fingerprintToken and challengeToken to Threeds2Action.
Description: We have encountered a critical issue with the 3DS2 authentication process in our Android application after upgrading from Drop-in v4.x to Drop-in v5.x. The problem arises specifically during the 3DS2 fingerprint flow when a challengeToken is required after the fingerprint step. Notably, the same backend configuration works without issues on iOS and with the Android Drop-in v4.x, suggesting that the problem is isolated to the Drop-in v5.x implementation.
Steps to Reproduce:
Technical Details:
During payment initialization in DropInService's onSubmit, we send a request to our backend and receive a fingerprintToken and paymentData, convert it to DropInServiceResult.Action(action) with a Threeds2FingerprintAction:
Drop-in processes this action and triggers again onAdditionalDetails in the service, where we forward the fingerprintResult from Drop-in to our backend. Our backend responds with a 3ds2 challengeToken, which we convert to a Threeds2ChallengeAction and pass to DropInServiceResult.Action(action) with
At this point, Drop-in fails to handle this action and logs the error "Failed to make challenge, missing reference to initial transaction." Debugging reveals that Drop-in recreates the DefaultAdyen3DS2Delegate upon receiving the second action with null currentTransaction reference.
The log output from Drop-in is:
It appears that there is a problem with state retention between the fingerprint and challenge phases in the Drop-in v5.x, which prevents the successful completion of the 3DS2 authentication process.
We would greatly appreciate your assistance in investigating and fixing this issue. Thank you for your support.