Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
a97152c
Remove legacy NativeAlternativePayment UI
vitalii-vanziak-cko Oct 27, 2025
b99f395
Use FieldValue instead of TextFieldValue
vitalii-vanziak-cko Oct 27, 2025
b761086
Refactor 'with' to 'let'
vitalii-vanziak-cko Oct 27, 2025
5c366e9
Fix default values
vitalii-vanziak-cko Oct 27, 2025
815b952
Fix events
vitalii-vanziak-cko Oct 27, 2025
1f5dac3
Apply NativeAlternativePaymentContent, map events
vitalii-vanziak-cko Oct 27, 2025
88ddb99
Update events mapping
vitalii-vanziak-cko Oct 27, 2025
3667a3b
Handle nAPM redirect on DC
vitalii-vanziak-cko Oct 27, 2025
4758834
Update card event mapping
vitalii-vanziak-cko Oct 27, 2025
e3a17f0
Fix primary action state (text and icon)
vitalii-vanziak-cko Oct 28, 2025
92aa474
Remove unused values and functions
vitalii-vanziak-cko Oct 28, 2025
d7ca013
Move DynamicCheckoutScreen
vitalii-vanziak-cko Oct 28, 2025
ed2123e
Remove unused config 'showProgressIndicatorAfterSeconds'
vitalii-vanziak-cko Oct 28, 2025
b7a2f2d
'header = null' on DC
vitalii-vanziak-cko Oct 28, 2025
04bd6b3
Reorder init params in activity
vitalii-vanziak-cko Oct 28, 2025
2e4eaa0
'content = null' in DC
vitalii-vanziak-cko Oct 28, 2025
7e643de
Support custom nAPM content on DC
vitalii-vanziak-cko Oct 28, 2025
aac5927
Radio button style
vitalii-vanziak-cko Oct 28, 2025
bd55779
Remove unused 'radioButton' style from config
vitalii-vanziak-cko Oct 28, 2025
5b59752
Map nAPM style
vitalii-vanziak-cko Oct 29, 2025
3af501b
Stepper style
vitalii-vanziak-cko Oct 29, 2025
a03aa7b
POLabeledContent.Style
vitalii-vanziak-cko Oct 29, 2025
298fd56
Apply styles for 'labeledContent' and 'groupedContent'
vitalii-vanziak-cko Oct 29, 2025
f1f51ea
'subsectionTitle' style
vitalii-vanziak-cko Oct 29, 2025
32ee419
Remove 'po_icon_info.xml', replace with warning icon
vitalii-vanziak-cko Oct 29, 2025
9cabd1a
nAPM message text size s14
vitalii-vanziak-cko Oct 29, 2025
8c3ca86
Update message style
vitalii-vanziak-cko Oct 29, 2025
293d074
'codeField' style
vitalii-vanziak-cko Oct 29, 2025
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 @@ -2,10 +2,12 @@ package com.processout.sdk.ui.core.component

import androidx.compose.foundation.layout.*
import androidx.compose.runtime.Composable
import androidx.compose.runtime.Immutable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.text.font.FontWeight
import com.processout.sdk.ui.core.annotation.ProcessOutInternalApi
import com.processout.sdk.ui.core.style.POLabeledContentStyle
import com.processout.sdk.ui.core.theme.ProcessOutTheme.colors
import com.processout.sdk.ui.core.theme.ProcessOutTheme.spacing
import com.processout.sdk.ui.core.theme.ProcessOutTheme.typography
Expand Down Expand Up @@ -50,3 +52,35 @@ fun POLabeledContent(
}
}
}

/** @suppress */
@ProcessOutInternalApi
object POLabeledContent {

@Immutable
data class Style(
val label: POText.Style,
val text: POText.Style,
val copyButton: POButton.Style
)

val default: Style
@Composable get() = Style(
label = POText.Style(
color = colors.text.placeholder,
textStyle = typography.s12(FontWeight.Medium)
),
text = POText.Style(
color = colors.text.primary,
textStyle = typography.s15(FontWeight.Medium)
),
copyButton = POCopyButton.default
)

@Composable
fun custom(style: POLabeledContentStyle) = Style(
label = POText.custom(style = style.label),
text = POText.custom(style = style.text),
copyButton = default.copyButton
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ object POTextWithIcon {
)
return Style(
text = text,
iconResId = R.drawable.po_icon_info,
iconResId = R.drawable.po_icon_warning_diamond,
iconColorFilter = ColorFilter.tint(color = text.color)
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -256,7 +256,7 @@ object PORadioField {
else if (isError) style.error
else style.normal

internal fun Style.radioButtonStyle() = PORadioButton.Style(
fun Style.radioButtonStyle() = PORadioButton.Style(
normalColor = normal.radioButtonColor,
selectedColor = selected.radioButtonColor,
errorColor = error.radioButtonColor,
Expand Down
9 changes: 0 additions & 9 deletions ui-core/src/main/res/drawable/po_icon_info.xml

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
package com.processout.sdk.ui.checkout

import androidx.compose.ui.text.input.TextFieldValue
import com.processout.sdk.api.model.response.POAlternativePaymentMethodResponse
import com.processout.sdk.api.model.response.POGooglePayCardTokenizationData
import com.processout.sdk.core.ProcessOutResult
import com.processout.sdk.ui.card.scanner.recognition.POScannedCard
import com.processout.sdk.ui.savedpaymentmethods.POSavedPaymentMethodsConfiguration
import com.processout.sdk.ui.shared.state.FieldValue
import org.json.JSONObject

internal sealed interface DynamicCheckoutEvent {
Expand All @@ -16,7 +16,7 @@ internal sealed interface DynamicCheckoutEvent {
data class FieldValueChanged(
val paymentMethodId: String,
val fieldId: String,
val value: TextFieldValue
val value: FieldValue
) : DynamicCheckoutEvent

data class FieldFocusChanged(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,10 @@ import coil.request.ImageRequest
import coil.request.ImageResult
import com.processout.sdk.R
import com.processout.sdk.api.dispatcher.POEventDispatcher
import com.processout.sdk.api.model.event.PONativeAlternativePaymentMethodEvent.WillSubmitParameters
import com.processout.sdk.api.model.request.*
import com.processout.sdk.api.model.request.POCardTokenizationProcessingRequest
import com.processout.sdk.api.model.request.POCardTokenizationShouldContinueRequest
import com.processout.sdk.api.model.request.POInvoiceAuthorizationRequest
import com.processout.sdk.api.model.request.POInvoiceRequest
import com.processout.sdk.api.model.request.POInvoiceRequest.ExpandedProperty.Companion.paymentMethods
import com.processout.sdk.api.model.request.POInvoiceRequest.ExpandedProperty.Companion.transaction
import com.processout.sdk.api.model.response.*
Expand Down Expand Up @@ -59,7 +61,9 @@ import com.processout.sdk.ui.checkout.delegate.PODynamicCheckoutEvent.*
import com.processout.sdk.ui.napm.*
import com.processout.sdk.ui.napm.PONativeAlternativePaymentConfiguration.*
import com.processout.sdk.ui.napm.PONativeAlternativePaymentConfiguration.Flow
import com.processout.sdk.ui.napm.delegate.PONativeAlternativePaymentEvent
import com.processout.sdk.ui.napm.delegate.v2.NativeAlternativePaymentDefaultValuesRequest
import com.processout.sdk.ui.napm.delegate.v2.PONativeAlternativePaymentEvent
import com.processout.sdk.ui.napm.delegate.v2.PONativeAlternativePaymentEvent.WillSubmitParameters
import com.processout.sdk.ui.savedpaymentmethods.POSavedPaymentMethodsConfiguration
import com.processout.sdk.ui.shared.extension.orElse
import com.processout.sdk.ui.shared.state.FieldValue
Expand Down Expand Up @@ -148,8 +152,8 @@ internal class DynamicCheckoutInteractor(
}

private fun cancelWebAuthorization() {
with(_state.value) {
if (selectedPaymentMethod != null || pendingSubmitPaymentMethod != null) {
_state.value.let {
if (it.selectedPaymentMethod != null || it.pendingSubmitPaymentMethod != null) {
interactorScope.launch {
_sideEffects.send(DynamicCheckoutSideEffect.CancelWebAuthorization)
}
Expand Down Expand Up @@ -432,8 +436,8 @@ internal class DynamicCheckoutInteractor(
_state.value.paymentMethods.find { it.id == id }

private fun activePaymentMethod(): PaymentMethod? =
with(_state.value) {
processingPaymentMethod ?: selectedPaymentMethod
_state.value.let {
it.processingPaymentMethod ?: it.selectedPaymentMethod
}

private fun onPaymentMethodSelected(event: PaymentMethodSelected) {
Expand Down Expand Up @@ -569,20 +573,24 @@ internal class DynamicCheckoutInteractor(

private fun onFieldValueChanged(event: FieldValueChanged) {
when (val paymentMethod = paymentMethod(event.paymentMethodId)) {
is Card -> cardTokenization.onEvent(
CardTokenizationEvent.FieldValueChanged(event.fieldId, event.value)
)
is Card -> if (event.value is FieldValue.Text) {
cardTokenization.onEvent(
CardTokenizationEvent.FieldValueChanged(event.fieldId, event.value.value)
)
}
is NativeAlternativePayment -> nativeAlternativePayment.onEvent(
NativeAlternativePaymentEvent.FieldValueChanged(event.fieldId, FieldValue.Text(event.value))
NativeAlternativePaymentEvent.FieldValueChanged(event.fieldId, event.value)
)
else -> _state.update { state ->
state.copy(
paymentMethods = state.paymentMethods.map {
if (it.id == paymentMethod?.id) {
updatedPaymentMethod(it, event.fieldId, event.value)
} else it
}
)
else -> if (event.value is FieldValue.Text) {
_state.update { state ->
state.copy(
paymentMethods = state.paymentMethods.map {
if (it.id == paymentMethod?.id) {
updatedPaymentMethod(it, event.fieldId, event.value.value)
} else it
}
)
}
}
}
}
Expand All @@ -593,9 +601,11 @@ internal class DynamicCheckoutInteractor(
value: TextFieldValue
): PaymentMethod = when (paymentMethod) {
is AlternativePayment -> when (fieldId) {
FieldId.SAVE_PAYMENT_METHOD -> with(paymentMethod) {
FieldId.SAVE_PAYMENT_METHOD -> {
POLogger.debug("Field is edited by the user: %s = %s", fieldId, value.text)
copy(savePaymentMethodField = savePaymentMethodField?.copy(value = value))
paymentMethod.copy(
savePaymentMethodField = paymentMethod.savePaymentMethodField?.copy(value = value)
)
}
else -> paymentMethod
}
Expand Down Expand Up @@ -840,16 +850,21 @@ internal class DynamicCheckoutInteractor(
if (paymentMethod.id != paymentMethodId) {
return
}
result.onSuccess { response ->
authorizeInvoice(
paymentMethod = paymentMethod,
source = response.gatewayToken,
allowFallbackToSale = true
)
}.onFailure { failure ->
invalidateInvoice(
reason = PODynamicCheckoutInvoiceInvalidationReason.Failure(failure)
when (paymentMethod) {
is NativeAlternativePayment -> nativeAlternativePayment.onEvent(
NativeAlternativePaymentEvent.RedirectResult(result)
)
else -> result.onSuccess { response ->
authorizeInvoice(
paymentMethod = paymentMethod,
source = response.gatewayToken,
allowFallbackToSale = true
)
}.onFailure { failure ->
invalidateInvoice(
reason = PODynamicCheckoutInvoiceInvalidationReason.Failure(failure)
)
}
}
}
}
Expand Down Expand Up @@ -1081,7 +1096,7 @@ internal class DynamicCheckoutInteractor(
eventDispatcher.send(request.toResponse(shouldContinue))
}
}
eventDispatcher.subscribeForRequest<PONativeAlternativePaymentMethodDefaultValuesRequest>(
eventDispatcher.subscribeForRequest<NativeAlternativePaymentDefaultValuesRequest>(
coroutineScope = interactorScope
) { request ->
activePaymentMethod()?.let { paymentMethod ->
Expand Down Expand Up @@ -1128,9 +1143,17 @@ internal class DynamicCheckoutInteractor(
_sideEffects.send(permissionRequest)
POLogger.info("System permission requested: %s", permissionRequest)
}
is NativeAlternativePaymentSideEffect.Redirect -> {
// TODO
}
is NativeAlternativePaymentSideEffect.Redirect ->
activePaymentMethod()?.let { paymentMethod ->
_state.update { it.copy(processingPaymentMethod = paymentMethod) }
_sideEffects.send(
DynamicCheckoutSideEffect.AlternativePayment(
paymentMethodId = paymentMethod.id,
redirectUrl = sideEffect.redirectUrl,
returnUrl = sideEffect.returnUrl
)
)
}
}
}
}
Expand Down
Loading