Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix logic for entering 3DS2 challenge flow #1587

Merged
merged 1 commit into from
Sep 19, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,7 @@ internal open class PaymentController @VisibleForTesting constructor(

@VisibleForTesting
fun getClientSecret(data: Intent): String {
return data.getStringExtra(StripeIntentResultExtras.CLIENT_SECRET)
return requireNotNull(data.getStringExtra(StripeIntentResultExtras.CLIENT_SECRET))
}

/**
Expand Down Expand Up @@ -438,7 +438,7 @@ internal open class PaymentController @VisibleForTesting constructor(
override fun onSuccess(result: Stripe3ds2AuthResult) {
val ares = result.ares
if (ares != null) {
if (ares.shouldChallenge()) {
if (ares.isChallenge) {
startChallengeFlow(ares)
} else {
startFrictionlessFlow()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package com.stripe.android.model

import com.stripe.android.ObjectBuilder
import com.stripe.android.model.StripeJsonUtils.optString
import java.util.HashMap
import org.json.JSONArray
import org.json.JSONException
import org.json.JSONObject
Expand Down Expand Up @@ -91,9 +90,10 @@ internal data class Stripe3ds2AuthResult constructor(
private val messageExtension: List<MessageExtension>?,
private val messageType: String?,
private val messageVersion: String?,
private val sdkTransId: String?
private val sdkTransId: String?,
private val transStatus: String?
) {
fun shouldChallenge() = VALUE_YES == acsChallengeMandated
val isChallenge = VALUE_CHALLENGE == transStatus

internal class Builder : ObjectBuilder<Ares> {
private var threeDSServerTransId: String? = null
Expand All @@ -107,6 +107,7 @@ internal data class Stripe3ds2AuthResult constructor(
private var messageType: String? = null
private var messageVersion: String? = null
private var sdkTransId: String? = null
private var transStatus: String? = null

fun setThreeDSServerTransId(threeDSServerTransId: String?): Builder {
this.threeDSServerTransId = threeDSServerTransId
Expand Down Expand Up @@ -163,11 +164,17 @@ internal data class Stripe3ds2AuthResult constructor(
return this
}

fun setTransStatus(transStatus: String?): Builder {
this.transStatus = transStatus
return this
}

override fun build(): Ares {
return Ares(threeDSServerTransId, acsChallengeMandated,
acsSignedContent, acsTransId, acsUrl, authenticationType,
cardholderInfo, messageExtension, messageType, messageVersion,
sdkTransId)
return Ares(
threeDSServerTransId, acsChallengeMandated, acsSignedContent, acsTransId,
acsUrl, authenticationType, cardholderInfo, messageExtension, messageType,
messageVersion, sdkTransId, transStatus
)
}
}

Expand All @@ -182,9 +189,10 @@ internal data class Stripe3ds2AuthResult constructor(
private const val FIELD_MESSAGE_TYPE = "messageType"
private const val FIELD_MESSAGE_VERSION = "messageVersion"
private const val FIELD_SDK_TRANS_ID = "sdkTransID"
private const val FIELD_TRANS_STATUS = "transStatus"
private const val FIELD_THREE_DS_SERVER_TRANS_ID = "threeDSServerTransID"

internal const val VALUE_YES = "Y"
internal const val VALUE_CHALLENGE = "C"

@JvmStatic
@Throws(JSONException::class)
Expand All @@ -202,6 +210,7 @@ internal data class Stripe3ds2AuthResult constructor(
.setMessageType(aresJson.getString(FIELD_MESSAGE_TYPE))
.setMessageVersion(aresJson.getString(FIELD_MESSAGE_VERSION))
.setSdkTransId(optString(aresJson, FIELD_SDK_TRANS_ID))
.setTransStatus(optString(aresJson, FIELD_TRANS_STATUS))
.setMessageExtension(MessageExtension.fromJson(
aresJson.optJSONArray(FIELD_MESSAGE_EXTENSION)))
.build()
Expand Down Expand Up @@ -277,14 +286,15 @@ internal data class Stripe3ds2AuthResult constructor(

@Throws(JSONException::class)
private fun fromJson(json: JSONObject): MessageExtension {
val data = HashMap<String, String>()
val dataJson = json.optJSONObject(FIELD_DATA)
if (dataJson != null) {
val keys = dataJson.keys()
while (keys.hasNext()) {
val key = keys.next()
data[key] = dataJson.getString(key)
}
val data = if (dataJson != null) {
val keys = dataJson.names() ?: JSONArray()
(0 until keys.length())
.map { idx -> keys.getString(idx) }
.map { key -> mapOf(key to dataJson.getString(key)) }
.reduce { acc, map -> acc.plus(map) }
} else {
emptyMap()
}

return MessageExtension(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,11 @@ internal object Stripe3ds2AuthResultFixtures {
@JvmField
val ARES_CHALLENGE_FLOW = Stripe3ds2AuthResult.Builder()
.setAres(Stripe3ds2AuthResult.Ares.Builder()
.setAcsChallengeMandated(Stripe3ds2AuthResult.Ares.VALUE_YES)
.setAcsChallengeMandated("Y")
.setAcsTransId(UUID.randomUUID().toString())
.setSdkTransId(UUID.randomUUID().toString())
.setThreeDSServerTransId(UUID.randomUUID().toString())
.setTransStatus(Stripe3ds2AuthResult.Ares.VALUE_CHALLENGE)
.setMessageVersion("2.1.0")
.setMessageType("ARes")
.build())
Expand Down
Loading