Skip to content

Commit aeaea1f

Browse files
feat(ad-hoc): Integrate nAPM v2 into Dynamic Checkout (#342)
1 parent 4590592 commit aeaea1f

16 files changed

Lines changed: 276 additions & 667 deletions

ui-core/src/main/kotlin/com/processout/sdk/ui/core/component/POLabeledContent.kt

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,12 @@ package com.processout.sdk.ui.core.component
22

33
import androidx.compose.foundation.layout.*
44
import androidx.compose.runtime.Composable
5+
import androidx.compose.runtime.Immutable
56
import androidx.compose.ui.Alignment
67
import androidx.compose.ui.Modifier
78
import androidx.compose.ui.text.font.FontWeight
89
import com.processout.sdk.ui.core.annotation.ProcessOutInternalApi
10+
import com.processout.sdk.ui.core.style.POLabeledContentStyle
911
import com.processout.sdk.ui.core.theme.ProcessOutTheme.colors
1012
import com.processout.sdk.ui.core.theme.ProcessOutTheme.spacing
1113
import com.processout.sdk.ui.core.theme.ProcessOutTheme.typography
@@ -50,3 +52,35 @@ fun POLabeledContent(
5052
}
5153
}
5254
}
55+
56+
/** @suppress */
57+
@ProcessOutInternalApi
58+
object POLabeledContent {
59+
60+
@Immutable
61+
data class Style(
62+
val label: POText.Style,
63+
val text: POText.Style,
64+
val copyButton: POButton.Style
65+
)
66+
67+
val default: Style
68+
@Composable get() = Style(
69+
label = POText.Style(
70+
color = colors.text.placeholder,
71+
textStyle = typography.s12(FontWeight.Medium)
72+
),
73+
text = POText.Style(
74+
color = colors.text.primary,
75+
textStyle = typography.s15(FontWeight.Medium)
76+
),
77+
copyButton = POCopyButton.default
78+
)
79+
80+
@Composable
81+
fun custom(style: POLabeledContentStyle) = Style(
82+
label = POText.custom(style = style.label),
83+
text = POText.custom(style = style.text),
84+
copyButton = default.copyButton
85+
)
86+
}

ui-core/src/main/kotlin/com/processout/sdk/ui/core/component/POTextWithIcon.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ object POTextWithIcon {
9393
)
9494
return Style(
9595
text = text,
96-
iconResId = R.drawable.po_icon_info,
96+
iconResId = R.drawable.po_icon_warning_diamond,
9797
iconColorFilter = ColorFilter.tint(color = text.color)
9898
)
9999
}

ui-core/src/main/kotlin/com/processout/sdk/ui/core/component/field/radio/PORadioField.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -256,7 +256,7 @@ object PORadioField {
256256
else if (isError) style.error
257257
else style.normal
258258

259-
internal fun Style.radioButtonStyle() = PORadioButton.Style(
259+
fun Style.radioButtonStyle() = PORadioButton.Style(
260260
normalColor = normal.radioButtonColor,
261261
selectedColor = selected.radioButtonColor,
262262
errorColor = error.radioButtonColor,

ui-core/src/main/res/drawable/po_icon_info.xml

Lines changed: 0 additions & 9 deletions
This file was deleted.

ui/src/main/kotlin/com/processout/sdk/ui/checkout/DynamicCheckoutEvent.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
package com.processout.sdk.ui.checkout
22

3-
import androidx.compose.ui.text.input.TextFieldValue
43
import com.processout.sdk.api.model.response.POAlternativePaymentMethodResponse
54
import com.processout.sdk.api.model.response.POGooglePayCardTokenizationData
65
import com.processout.sdk.core.ProcessOutResult
76
import com.processout.sdk.ui.card.scanner.recognition.POScannedCard
87
import com.processout.sdk.ui.savedpaymentmethods.POSavedPaymentMethodsConfiguration
8+
import com.processout.sdk.ui.shared.state.FieldValue
99
import org.json.JSONObject
1010

1111
internal sealed interface DynamicCheckoutEvent {
@@ -16,7 +16,7 @@ internal sealed interface DynamicCheckoutEvent {
1616
data class FieldValueChanged(
1717
val paymentMethodId: String,
1818
val fieldId: String,
19-
val value: TextFieldValue
19+
val value: FieldValue
2020
) : DynamicCheckoutEvent
2121

2222
data class FieldFocusChanged(

ui/src/main/kotlin/com/processout/sdk/ui/checkout/DynamicCheckoutInteractor.kt

Lines changed: 57 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,10 @@ import coil.request.ImageRequest
1111
import coil.request.ImageResult
1212
import com.processout.sdk.R
1313
import com.processout.sdk.api.dispatcher.POEventDispatcher
14-
import com.processout.sdk.api.model.event.PONativeAlternativePaymentMethodEvent.WillSubmitParameters
15-
import com.processout.sdk.api.model.request.*
14+
import com.processout.sdk.api.model.request.POCardTokenizationProcessingRequest
15+
import com.processout.sdk.api.model.request.POCardTokenizationShouldContinueRequest
16+
import com.processout.sdk.api.model.request.POInvoiceAuthorizationRequest
17+
import com.processout.sdk.api.model.request.POInvoiceRequest
1618
import com.processout.sdk.api.model.request.POInvoiceRequest.ExpandedProperty.Companion.paymentMethods
1719
import com.processout.sdk.api.model.request.POInvoiceRequest.ExpandedProperty.Companion.transaction
1820
import com.processout.sdk.api.model.response.*
@@ -59,7 +61,9 @@ import com.processout.sdk.ui.checkout.delegate.PODynamicCheckoutEvent.*
5961
import com.processout.sdk.ui.napm.*
6062
import com.processout.sdk.ui.napm.PONativeAlternativePaymentConfiguration.*
6163
import com.processout.sdk.ui.napm.PONativeAlternativePaymentConfiguration.Flow
62-
import com.processout.sdk.ui.napm.delegate.PONativeAlternativePaymentEvent
64+
import com.processout.sdk.ui.napm.delegate.v2.NativeAlternativePaymentDefaultValuesRequest
65+
import com.processout.sdk.ui.napm.delegate.v2.PONativeAlternativePaymentEvent
66+
import com.processout.sdk.ui.napm.delegate.v2.PONativeAlternativePaymentEvent.WillSubmitParameters
6367
import com.processout.sdk.ui.savedpaymentmethods.POSavedPaymentMethodsConfiguration
6468
import com.processout.sdk.ui.shared.extension.orElse
6569
import com.processout.sdk.ui.shared.state.FieldValue
@@ -148,8 +152,8 @@ internal class DynamicCheckoutInteractor(
148152
}
149153

150154
private fun cancelWebAuthorization() {
151-
with(_state.value) {
152-
if (selectedPaymentMethod != null || pendingSubmitPaymentMethod != null) {
155+
_state.value.let {
156+
if (it.selectedPaymentMethod != null || it.pendingSubmitPaymentMethod != null) {
153157
interactorScope.launch {
154158
_sideEffects.send(DynamicCheckoutSideEffect.CancelWebAuthorization)
155159
}
@@ -432,8 +436,8 @@ internal class DynamicCheckoutInteractor(
432436
_state.value.paymentMethods.find { it.id == id }
433437

434438
private fun activePaymentMethod(): PaymentMethod? =
435-
with(_state.value) {
436-
processingPaymentMethod ?: selectedPaymentMethod
439+
_state.value.let {
440+
it.processingPaymentMethod ?: it.selectedPaymentMethod
437441
}
438442

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

570574
private fun onFieldValueChanged(event: FieldValueChanged) {
571575
when (val paymentMethod = paymentMethod(event.paymentMethodId)) {
572-
is Card -> cardTokenization.onEvent(
573-
CardTokenizationEvent.FieldValueChanged(event.fieldId, event.value)
574-
)
576+
is Card -> if (event.value is FieldValue.Text) {
577+
cardTokenization.onEvent(
578+
CardTokenizationEvent.FieldValueChanged(event.fieldId, event.value.value)
579+
)
580+
}
575581
is NativeAlternativePayment -> nativeAlternativePayment.onEvent(
576-
NativeAlternativePaymentEvent.FieldValueChanged(event.fieldId, FieldValue.Text(event.value))
582+
NativeAlternativePaymentEvent.FieldValueChanged(event.fieldId, event.value)
577583
)
578-
else -> _state.update { state ->
579-
state.copy(
580-
paymentMethods = state.paymentMethods.map {
581-
if (it.id == paymentMethod?.id) {
582-
updatedPaymentMethod(it, event.fieldId, event.value)
583-
} else it
584-
}
585-
)
584+
else -> if (event.value is FieldValue.Text) {
585+
_state.update { state ->
586+
state.copy(
587+
paymentMethods = state.paymentMethods.map {
588+
if (it.id == paymentMethod?.id) {
589+
updatedPaymentMethod(it, event.fieldId, event.value.value)
590+
} else it
591+
}
592+
)
593+
}
586594
}
587595
}
588596
}
@@ -593,9 +601,11 @@ internal class DynamicCheckoutInteractor(
593601
value: TextFieldValue
594602
): PaymentMethod = when (paymentMethod) {
595603
is AlternativePayment -> when (fieldId) {
596-
FieldId.SAVE_PAYMENT_METHOD -> with(paymentMethod) {
604+
FieldId.SAVE_PAYMENT_METHOD -> {
597605
POLogger.debug("Field is edited by the user: %s = %s", fieldId, value.text)
598-
copy(savePaymentMethodField = savePaymentMethodField?.copy(value = value))
606+
paymentMethod.copy(
607+
savePaymentMethodField = paymentMethod.savePaymentMethodField?.copy(value = value)
608+
)
599609
}
600610
else -> paymentMethod
601611
}
@@ -840,16 +850,21 @@ internal class DynamicCheckoutInteractor(
840850
if (paymentMethod.id != paymentMethodId) {
841851
return
842852
}
843-
result.onSuccess { response ->
844-
authorizeInvoice(
845-
paymentMethod = paymentMethod,
846-
source = response.gatewayToken,
847-
allowFallbackToSale = true
848-
)
849-
}.onFailure { failure ->
850-
invalidateInvoice(
851-
reason = PODynamicCheckoutInvoiceInvalidationReason.Failure(failure)
853+
when (paymentMethod) {
854+
is NativeAlternativePayment -> nativeAlternativePayment.onEvent(
855+
NativeAlternativePaymentEvent.RedirectResult(result)
852856
)
857+
else -> result.onSuccess { response ->
858+
authorizeInvoice(
859+
paymentMethod = paymentMethod,
860+
source = response.gatewayToken,
861+
allowFallbackToSale = true
862+
)
863+
}.onFailure { failure ->
864+
invalidateInvoice(
865+
reason = PODynamicCheckoutInvoiceInvalidationReason.Failure(failure)
866+
)
867+
}
853868
}
854869
}
855870
}
@@ -1081,7 +1096,7 @@ internal class DynamicCheckoutInteractor(
10811096
eventDispatcher.send(request.toResponse(shouldContinue))
10821097
}
10831098
}
1084-
eventDispatcher.subscribeForRequest<PONativeAlternativePaymentMethodDefaultValuesRequest>(
1099+
eventDispatcher.subscribeForRequest<NativeAlternativePaymentDefaultValuesRequest>(
10851100
coroutineScope = interactorScope
10861101
) { request ->
10871102
activePaymentMethod()?.let { paymentMethod ->
@@ -1128,9 +1143,17 @@ internal class DynamicCheckoutInteractor(
11281143
_sideEffects.send(permissionRequest)
11291144
POLogger.info("System permission requested: %s", permissionRequest)
11301145
}
1131-
is NativeAlternativePaymentSideEffect.Redirect -> {
1132-
// TODO
1133-
}
1146+
is NativeAlternativePaymentSideEffect.Redirect ->
1147+
activePaymentMethod()?.let { paymentMethod ->
1148+
_state.update { it.copy(processingPaymentMethod = paymentMethod) }
1149+
_sideEffects.send(
1150+
DynamicCheckoutSideEffect.AlternativePayment(
1151+
paymentMethodId = paymentMethod.id,
1152+
redirectUrl = sideEffect.redirectUrl,
1153+
returnUrl = sideEffect.returnUrl
1154+
)
1155+
)
1156+
}
11341157
}
11351158
}
11361159
}

0 commit comments

Comments
 (0)