diff --git a/sdk/src/main/kotlin/com/processout/sdk/api/model/event/PONativeAlternativePaymentMethodEvent.kt b/sdk/src/main/kotlin/com/processout/sdk/api/model/event/PONativeAlternativePaymentMethodEvent.kt index 6189042a..2d142dd2 100644 --- a/sdk/src/main/kotlin/com/processout/sdk/api/model/event/PONativeAlternativePaymentMethodEvent.kt +++ b/sdk/src/main/kotlin/com/processout/sdk/api/model/event/PONativeAlternativePaymentMethodEvent.kt @@ -1,5 +1,6 @@ package com.processout.sdk.api.model.event +import com.processout.sdk.api.model.response.PONativeAlternativePaymentMethodParameter import com.processout.sdk.core.ProcessOutResult /** @@ -20,14 +21,26 @@ sealed class PONativeAlternativePaymentMethodEvent { /** * Event is sent when user changes any editable value. + * + * @param[parameter] Parameter definition. + * @param[value] Parameter plain value. __Warning:__ may contain sensitive information. */ - data object ParametersChanged : PONativeAlternativePaymentMethodEvent() + data class ParametersChanged( + val parameter: PONativeAlternativePaymentMethodParameter, + val value: String + ) : PONativeAlternativePaymentMethodEvent() /** * Event is sent just before submitting user input. * This is usually a result of a user action, e.g. button press. + * + * @param[parameters] Parameter definitions. + * @param[values] Parameter plain values. __Warning:__ may contain sensitive information. */ - data object WillSubmitParameters : PONativeAlternativePaymentMethodEvent() + data class WillSubmitParameters( + val parameters: List, + val values: Map + ) : PONativeAlternativePaymentMethodEvent() /** * Event is sent when parameters were submitted successfully. diff --git a/sdk/src/main/kotlin/com/processout/sdk/ui/nativeapm/NativeAlternativePaymentMethodViewModel.kt b/sdk/src/main/kotlin/com/processout/sdk/ui/nativeapm/NativeAlternativePaymentMethodViewModel.kt index 916ef05a..51508039 100644 --- a/sdk/src/main/kotlin/com/processout/sdk/ui/nativeapm/NativeAlternativePaymentMethodViewModel.kt +++ b/sdk/src/main/kotlin/com/processout/sdk/ui/nativeapm/NativeAlternativePaymentMethodViewModel.kt @@ -285,7 +285,14 @@ internal class NativeAlternativePaymentMethodViewModel private constructor( inputParameters = updatedInputParameters ) ) - dispatch(ParametersChanged) + updatedInputParameters.find { it.parameter.key == key }?.let { + dispatch( + ParametersChanged( + parameter = it.parameter, + value = it.plainValue() + ) + ) + } POLogger.debug("Payment parameters updated: %s", updatedInputParameters) } } @@ -303,7 +310,12 @@ internal class NativeAlternativePaymentMethodViewModel private constructor( fun submitPayment() { _uiState.value.doWhenUserInput { uiModel -> POLogger.info("Will submit payment parameters.") - dispatch(WillSubmitParameters) + dispatch( + WillSubmitParameters( + parameters = uiModel.inputParameters.map { it.parameter }, + values = uiModel.inputParameters.values() + ) + ) val invalidFields = uiModel.inputParameters.mapNotNull { it.validate() } if (invalidFields.isNotEmpty()) { @@ -322,6 +334,14 @@ internal class NativeAlternativePaymentMethodViewModel private constructor( } } + private fun List.values(): Map { + val values = mutableMapOf() + forEach { + values[it.parameter.key] = it.plainValue() + } + return values + } + private fun InputParameter.validate(): POFailure.InvalidField? { val value = plainValue() if (parameter.required && value.isBlank()) @@ -358,12 +378,10 @@ internal class NativeAlternativePaymentMethodViewModel private constructor( private fun initiatePayment(uiModel: NativeAlternativePaymentMethodUiModel) { viewModelScope.launch { - val data = mutableMapOf() - uiModel.inputParameters.forEach { - data[it.parameter.key] = it.plainValue() - } val request = PONativeAlternativePaymentMethodRequest( - invoiceId, gatewayConfigurationId, data + invoiceId = invoiceId, + gatewayConfigurationId = gatewayConfigurationId, + parameters = uiModel.inputParameters.values() ) when (val result = invoicesService.initiatePayment(request)) { is ProcessOutResult.Success -> with(result.value) { diff --git a/ui/src/main/kotlin/com/processout/sdk/ui/napm/NativeAlternativePaymentInteractor.kt b/ui/src/main/kotlin/com/processout/sdk/ui/napm/NativeAlternativePaymentInteractor.kt index 3dc3e1f3..e6d66eb9 100644 --- a/ui/src/main/kotlin/com/processout/sdk/ui/napm/NativeAlternativePaymentInteractor.kt +++ b/ui/src/main/kotlin/com/processout/sdk/ui/napm/NativeAlternativePaymentInteractor.kt @@ -22,6 +22,7 @@ import com.processout.sdk.api.model.request.PONativeAlternativePaymentMethodRequ import com.processout.sdk.api.model.response.* import com.processout.sdk.api.model.response.PONativeAlternativePaymentMethodParameter.ParameterType import com.processout.sdk.api.model.response.PONativeAlternativePaymentMethodParameter.ParameterType.* +import com.processout.sdk.api.model.response.PONativeAlternativePaymentMethodParameter.ParameterValue import com.processout.sdk.api.model.response.PONativeAlternativePaymentMethodState.* import com.processout.sdk.api.service.POInvoicesService import com.processout.sdk.core.POFailure.Code.* @@ -270,6 +271,7 @@ internal class NativeAlternativePaymentInteractor( text = it.displayName ) }, + rawType = rawType, type = type(), length = length, displayName = displayName, @@ -280,6 +282,21 @@ internal class NativeAlternativePaymentInteractor( } } + private fun Field.toParameter() = PONativeAlternativePaymentMethodParameter( + key = id, + length = length, + required = required, + rawType = rawType, + displayName = displayName, + availableValues = availableValues?.map { + ParameterValue( + value = it.value, + displayName = it.text, + default = null + ) + } + ) + private fun startUserInput(stateValue: UserInputStateValue) { _state.update { UserInput(stateValue) } enableUserInputSecondaryAction() @@ -390,7 +407,14 @@ internal class NativeAlternativePaymentInteractor( _state.update { UserInput(updatedStateValue) } if (isTextChanged) { POLogger.debug("Field is edited by the user: %s", id) - dispatch(ParametersChanged) + updatedStateValue.fields.find { it.id == id }?.let { + dispatch( + ParametersChanged( + parameter = it.toParameter(), + value = it.value.text + ) + ) + } if (updatedStateValue.areAllFieldsValid()) { _state.update { UserInput(updatedStateValue.copy(submitAllowed = true)) } } @@ -431,7 +455,12 @@ internal class NativeAlternativePaymentInteractor( private fun submit() { _state.whenUserInput { stateValue -> POLogger.info("Will submit payment parameters.") - dispatch(WillSubmitParameters) + dispatch( + WillSubmitParameters( + parameters = stateValue.fields.map { it.toParameter() }, + values = stateValue.fields.values() + ) + ) val invalidFields = stateValue.fields.mapNotNull { it.validate() } if (invalidFields.isNotEmpty()) { val failure = ProcessOutResult.Failure( @@ -457,6 +486,14 @@ internal class NativeAlternativePaymentInteractor( } } + private fun List.values(): Map { + val values = mutableMapOf() + forEach { + values[it.id] = it.value.text + } + return values + } + private fun Field.validate(): InvalidField? { val value = value.text if (required && value.isBlank()) { @@ -496,14 +533,10 @@ internal class NativeAlternativePaymentInteractor( private fun initiatePayment() { _state.whenUserInput { stateValue -> interactorScope.launch { - val parameters = mutableMapOf() - stateValue.fields.forEach { - parameters[it.id] = it.value.text - } val request = PONativeAlternativePaymentMethodRequest( invoiceId = invoiceId, gatewayConfigurationId = gatewayConfigurationId, - parameters = parameters + parameters = stateValue.fields.values() ) invoicesService.initiatePayment(request) .onSuccess { payment -> diff --git a/ui/src/main/kotlin/com/processout/sdk/ui/napm/NativeAlternativePaymentInteractorState.kt b/ui/src/main/kotlin/com/processout/sdk/ui/napm/NativeAlternativePaymentInteractorState.kt index ed529f56..54712b2d 100644 --- a/ui/src/main/kotlin/com/processout/sdk/ui/napm/NativeAlternativePaymentInteractorState.kt +++ b/ui/src/main/kotlin/com/processout/sdk/ui/napm/NativeAlternativePaymentInteractorState.kt @@ -60,6 +60,7 @@ internal sealed interface NativeAlternativePaymentInteractorState { val id: String, val value: TextFieldValue, val availableValues: List?, + val rawType: String, val type: ParameterType, val length: Int?, val displayName: String,