From 571f47fbf41a2b4580f1b11db51b1dc624052928 Mon Sep 17 00:00:00 2001 From: Andreas Vettefors Date: Fri, 11 Oct 2024 16:37:18 +0200 Subject: [PATCH] Fix support for resetting paymentMethods --- .../paymentsession/PaymentSession.kt | 13 +- .../paymentsession/SessionOperationHandler.kt | 123 +++++++++--------- .../api/model/request/CustomizePayment.kt | 8 +- .../api/model/request/util/RequestUtil.kt | 28 ++-- .../exposedmodel/PaymentAttemptInstrument.kt | 2 +- 5 files changed, 95 insertions(+), 79 deletions(-) diff --git a/mobilesdk/src/main/java/com/swedbankpay/mobilesdk/paymentsession/PaymentSession.kt b/mobilesdk/src/main/java/com/swedbankpay/mobilesdk/paymentsession/PaymentSession.kt index ebe1c772..bc5a9de8 100644 --- a/mobilesdk/src/main/java/com/swedbankpay/mobilesdk/paymentsession/PaymentSession.kt +++ b/mobilesdk/src/main/java/com/swedbankpay/mobilesdk/paymentsession/PaymentSession.kt @@ -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() ) diff --git a/mobilesdk/src/main/java/com/swedbankpay/mobilesdk/paymentsession/SessionOperationHandler.kt b/mobilesdk/src/main/java/com/swedbankpay/mobilesdk/paymentsession/SessionOperationHandler.kt index f64293f6..b86c617f 100644 --- a/mobilesdk/src/main/java/com/swedbankpay/mobilesdk/paymentsession/SessionOperationHandler.kt +++ b/mobilesdk/src/main/java/com/swedbankpay/mobilesdk/paymentsession/SessionOperationHandler.kt @@ -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 { @@ -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 = @@ -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 @@ -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 diff --git a/mobilesdk/src/main/java/com/swedbankpay/mobilesdk/paymentsession/api/model/request/CustomizePayment.kt b/mobilesdk/src/main/java/com/swedbankpay/mobilesdk/paymentsession/api/model/request/CustomizePayment.kt index 0b18e0cd..b40406c9 100644 --- a/mobilesdk/src/main/java/com/swedbankpay/mobilesdk/paymentsession/api/model/request/CustomizePayment.kt +++ b/mobilesdk/src/main/java/com/swedbankpay/mobilesdk/paymentsession/api/model/request/CustomizePayment.kt @@ -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( @@ -13,4 +13,10 @@ internal data class CustomizePayment( val showConsentAffirmation: Boolean?, @SerializedName("restrictToPaymentMethods") val restrictToPaymentMethods: List? +) + +@Keep +internal data class ResetCustomizePayment( + @SerializedName("paymentMethod") + val paymentMethod: String? ) \ No newline at end of file diff --git a/mobilesdk/src/main/java/com/swedbankpay/mobilesdk/paymentsession/api/model/request/util/RequestUtil.kt b/mobilesdk/src/main/java/com/swedbankpay/mobilesdk/paymentsession/api/model/request/util/RequestUtil.kt index 51dd81a5..a7f9874c 100644 --- a/mobilesdk/src/main/java/com/swedbankpay/mobilesdk/paymentsession/api/model/request/util/RequestUtil.kt +++ b/mobilesdk/src/main/java/com/swedbankpay/mobilesdk/paymentsession/api/model/request/util/RequestUtil.kt @@ -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 @@ -36,6 +37,7 @@ internal object RequestUtil { notificationUrl: String = "", cRes: String = "", showConsentAffirmation: Boolean = false, + resetPaymentMethod: Boolean = false, googlePayResult: GooglePayResult? = null ) = when (this) { @@ -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 } @@ -122,14 +129,19 @@ internal object RequestUtil { private fun getCustomizePaymentData( instrument: PaymentAttemptInstrument? = null, showConsentAffirmation: Boolean? = null, - instrumentFilter: List? = null + instrumentFilter: List? = 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 { diff --git a/mobilesdk/src/main/java/com/swedbankpay/mobilesdk/paymentsession/exposedmodel/PaymentAttemptInstrument.kt b/mobilesdk/src/main/java/com/swedbankpay/mobilesdk/paymentsession/exposedmodel/PaymentAttemptInstrument.kt index 96442ba5..14ffecfa 100644 --- a/mobilesdk/src/main/java/com/swedbankpay/mobilesdk/paymentsession/exposedmodel/PaymentAttemptInstrument.kt +++ b/mobilesdk/src/main/java/com/swedbankpay/mobilesdk/paymentsession/exposedmodel/PaymentAttemptInstrument.kt @@ -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) :