Skip to content

Commit

Permalink
Fix support for resetting paymentMethods
Browse files Browse the repository at this point in the history
  • Loading branch information
andreasvettefors committed Oct 11, 2024
1 parent 001471b commit 571f47f
Show file tree
Hide file tree
Showing 5 changed files with 95 additions and 79 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -429,20 +429,17 @@ class PaymentSession(private var orderInfo: ViewPaymentOrderInfo? = null) {
currentPaymentOutputModel?.let {
paymentAttemptInstrument = instrument

val paymentAttemptOperation = SessionOperationHandler.getOperationStepForPaymentAttempt(
it,
instrument
executeNextStepUntilFurtherInstructions(
OperationStep(
instructions = listOf(StepInstruction.OverrideApiCall(it))
)
)

if (paymentAttemptOperation != null) {
executeNextStepUntilFurtherInstructions(paymentAttemptOperation)
}

BeaconService.logEvent(
eventAction = EventAction.SDKMethodInvoked(
method = MethodModel(
name = "makeNativePaymentAttempt",
succeeded = paymentAttemptOperation != null
succeeded = true
),
extensions = instrument.toExtensionsModel()
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@ import com.swedbankpay.mobilesdk.paymentsession.exposedmodel.PaymentAttemptInstr
import com.swedbankpay.mobilesdk.paymentsession.exposedmodel.mapper.toAvailableInstrument
import com.swedbankpay.mobilesdk.paymentsession.exposedmodel.mapper.toSemiColonSeparatedString
import com.swedbankpay.mobilesdk.paymentsession.exposedmodel.toInstrument
import com.swedbankpay.mobilesdk.paymentsession.googlepay.model.GooglePayResult
import com.swedbankpay.mobilesdk.paymentsession.sca.ScaMethodService
import com.swedbankpay.mobilesdk.paymentsession.util.extension.safeLet
import com.swedbankpay.mobilesdk.paymentsession.googlepay.model.GooglePayResult
import java.net.URL

internal object SessionOperationHandler {
Expand Down Expand Up @@ -114,26 +114,48 @@ internal object SessionOperationHandler {
instructions = instructions
)
}
//endregion


// region CUSTOMIZE_PAYMENT
val customizePayment =
operations.firstOrNull { it.rel == OperationRel.CUSTOMIZE_PAYMENT }
paymentOutputModel.operations.filterNotNull()
.firstOrNull { it.rel == OperationRel.CUSTOMIZE_PAYMENT }

if (paymentAttemptInstrument is PaymentAttemptInstrument.NewCreditCard
&& customizePayment != null
) {
return OperationStep(
requestMethod = customizePayment.method,
url = URL(customizePayment.href),
operationRel = customizePayment.rel,
data = customizePayment.rel?.getRequestDataIfAny(
paymentAttemptInstrument,
paymentOutputModel.paymentSession.culture,
showConsentAffirmation = paymentAttemptInstrument.enabledPaymentDetailsConsentCheckbox
),
instructions = instructions
)
if (customizePayment != null) {
if (paymentOutputModel.paymentSession.instrumentModePaymentMethod != null
&& paymentAttemptInstrument?.identifier != paymentOutputModel.paymentSession.instrumentModePaymentMethod
) {
return OperationStep(
requestMethod = customizePayment.method,
url = URL(customizePayment.href),
operationRel = customizePayment.rel,
data = customizePayment.rel?.getRequestDataIfAny(
paymentAttemptInstrument,
paymentOutputModel.paymentSession.culture,
resetPaymentMethod = true
),
instructions = instructions
)
}

if (paymentAttemptInstrument is PaymentAttemptInstrument.NewCreditCard
) {
return OperationStep(
requestMethod = customizePayment.method,
url = URL(customizePayment.href),
operationRel = customizePayment.rel,
data = customizePayment.rel?.getRequestDataIfAny(
paymentAttemptInstrument,
paymentOutputModel.paymentSession.culture,
showConsentAffirmation = paymentAttemptInstrument.enabledPaymentDetailsConsentCheckbox
),
instructions = instructions
)
}
}
//endregion
// endregion


//region Search for OperationRel.START_PAYMENT_ATTEMPT
val startPaymentAttempt =
Expand Down Expand Up @@ -379,6 +401,29 @@ internal object SessionOperationHandler {
}
//endregion

// If we have a paymentAttemptInstrument this far down in the logic. Check if we can do something with it
if (paymentAttemptInstrument != null) {
val paymentAttemptInstrumentOperation = paymentOutputModel.paymentSession.methods
?.firstOrNull { it?.instrument == paymentAttemptInstrument.toInstrument() }
?.operations
?.firstOrNull {
it?.rel == OperationRel.EXPAND_METHOD
|| it?.rel == OperationRel.START_PAYMENT_ATTEMPT
}

if (paymentAttemptInstrumentOperation != null) {
return OperationStep(
requestMethod = paymentAttemptInstrumentOperation.method,
url = URL(paymentAttemptInstrumentOperation.href),
operationRel = paymentAttemptInstrumentOperation.rel,
data = paymentAttemptInstrumentOperation.rel?.getRequestDataIfAny(
paymentAttemptInstrument,
paymentOutputModel.paymentSession.culture
)
)
}
}

//region Search for OperationRel.GET_PAYMENT
// If we come here and find OperationRel.GET_PAYMENT we want to start polling for a result we can
// do something with
Expand All @@ -403,50 +448,6 @@ internal object SessionOperationHandler {
)
}

/**
* This method is used to get an operation to start the payment with chosen instrument.
*
* Payment session can be in different states when calling this method.
* First time calling this method will result in an operation containing [OperationRel.EXPAND_METHOD].
* If problem occurs and you call this method again with the same instrument you will have
* an operation containing [OperationRel.START_PAYMENT_ATTEMPT] or if a polling has occurred it will have [OperationRel.GET_PAYMENT].
* If you call it again after the problem with a different instrument you will again have [OperationRel.EXPAND_METHOD]
* on that operation.
*/
fun getOperationStepForPaymentAttempt(
paymentOutputModel: PaymentOutputModel,
paymentAttemptInstrument: PaymentAttemptInstrument
): OperationStep? {
if (paymentAttemptInstrument is PaymentAttemptInstrument.NewCreditCard) {
return OperationStep(
instructions = listOf(StepInstruction.OverrideApiCall(paymentOutputModel))
)
}

val op = paymentOutputModel.paymentSession.methods
?.firstOrNull { it?.instrument == paymentAttemptInstrument.toInstrument() }
?.operations
?.firstOrNull {
it?.rel == OperationRel.EXPAND_METHOD
|| it?.rel == OperationRel.START_PAYMENT_ATTEMPT
|| it?.rel == OperationRel.GET_PAYMENT
}

return if (op != null) {
OperationStep(
requestMethod = op.method,
url = URL(op.href),
operationRel = op.rel,
data = op.rel?.getRequestDataIfAny(
paymentAttemptInstrument,
paymentOutputModel.paymentSession.culture
)
)
} else {
return null
}
}

fun getOperationStepForAbortPayment(paymentOutputModel: PaymentOutputModel): OperationStep? {
val abortPayment = paymentOutputModel.operations.firstOrNull {
it?.rel == OperationRel.ABORT_PAYMENT
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package com.swedbankpay.mobilesdk.paymentsession.api.model.request

import com.google.gson.annotations.SerializedName
import androidx.annotation.Keep
import com.google.gson.annotations.SerializedName

@Keep
internal data class CustomizePayment(
Expand All @@ -13,4 +13,10 @@ internal data class CustomizePayment(
val showConsentAffirmation: Boolean?,
@SerializedName("restrictToPaymentMethods")
val restrictToPaymentMethods: List<String?>?
)

@Keep
internal data class ResetCustomizePayment(
@SerializedName("paymentMethod")
val paymentMethod: String?
)
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import com.swedbankpay.mobilesdk.paymentsession.api.model.request.CustomizePayme
import com.swedbankpay.mobilesdk.paymentsession.api.model.request.GooglePayAttempt
import com.swedbankpay.mobilesdk.paymentsession.api.model.request.InstrumentView
import com.swedbankpay.mobilesdk.paymentsession.api.model.request.Integration
import com.swedbankpay.mobilesdk.paymentsession.api.model.request.ResetCustomizePayment
import com.swedbankpay.mobilesdk.paymentsession.api.model.request.SwishAttempt
import com.swedbankpay.mobilesdk.paymentsession.api.model.response.OperationRel
import com.swedbankpay.mobilesdk.paymentsession.api.model.response.OperationRel.ATTEMPT_PAYLOAD
Expand All @@ -36,6 +37,7 @@ internal object RequestUtil {
notificationUrl: String = "",
cRes: String = "",
showConsentAffirmation: Boolean = false,
resetPaymentMethod: Boolean = false,
googlePayResult: GooglePayResult? = null
) =
when (this) {
Expand All @@ -48,7 +50,12 @@ internal object RequestUtil {
)

COMPLETE_AUTHENTICATION -> getCompleteAuthenticationData(cRes)
CUSTOMIZE_PAYMENT -> getCustomizePaymentData(instrument, showConsentAffirmation)
CUSTOMIZE_PAYMENT -> getCustomizePaymentData(
instrument,
showConsentAffirmation,
resetPaymentMethod = resetPaymentMethod
)

ATTEMPT_PAYLOAD -> getAttemptPayloadData(googlePayResult)
else -> null
}
Expand Down Expand Up @@ -122,14 +129,19 @@ internal object RequestUtil {
private fun getCustomizePaymentData(
instrument: PaymentAttemptInstrument? = null,
showConsentAffirmation: Boolean? = null,
instrumentFilter: List<String>? = null
instrumentFilter: List<String>? = null,
resetPaymentMethod: Boolean = false
): String {
return CustomizePayment(
paymentMethod = instrument?.identifier ?: "Menu",
hideStoredPaymentOptions = if (instrument != null) true else null,
showConsentAffirmation = showConsentAffirmation,
restrictToPaymentMethods = instrumentFilter
).toJsonString()
return if (resetPaymentMethod) {
ResetCustomizePayment(null).toJsonString()
} else {
CustomizePayment(
paymentMethod = instrument?.identifier ?: "Menu",
hideStoredPaymentOptions = if (instrument != null) true else null,
showConsentAffirmation = showConsentAffirmation,
restrictToPaymentMethods = instrumentFilter
).toJsonString()
}
}

private fun getAttemptPayloadData(googlePayResult: GooglePayResult?): String {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ sealed class PaymentAttemptInstrument(
@Keep
data class NewCreditCard(
val enabledPaymentDetailsConsentCheckbox: Boolean
) : PaymentAttemptInstrument(null, "NewCreditCard")
) : PaymentAttemptInstrument(null, "CreditCard")

@Keep
class GooglePay(internal val activity: Activity) :
Expand Down

0 comments on commit 571f47f

Please sign in to comment.