Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
943e6a5
POUnit
vitalii-vanziak-cko Apr 30, 2024
6d01521
Basic activity and bottom sheet
vitalii-vanziak-cko Apr 30, 2024
297c286
Contract, launcher, basic configuration
vitalii-vanziak-cko Apr 30, 2024
1b6f00b
Extend example app
vitalii-vanziak-cko Apr 30, 2024
5150486
NativeAlternativePaymentEvent
vitalii-vanziak-cko May 2, 2024
2edb100
Basic interactor, VM and their states
vitalii-vanziak-cko May 2, 2024
18181bc
NativeAlternativePaymentScreen
vitalii-vanziak-cko May 2, 2024
6662f45
Extended PONativeAlternativePaymentConfiguration
vitalii-vanziak-cko May 2, 2024
4b5710a
POFieldLabels
vitalii-vanziak-cko May 2, 2024
2e0dbc4
Style
vitalii-vanziak-cko May 2, 2024
fc7d646
Default and custom style
vitalii-vanziak-cko May 3, 2024
271dc7c
Apply POCancellationConfiguration
vitalii-vanziak-cko May 3, 2024
7763c62
Validate configuration in bottom sheet onAttach()
vitalii-vanziak-cko May 3, 2024
c0d6da4
Init VM and interactor
vitalii-vanziak-cko May 3, 2024
14130c9
Options.validated()
vitalii-vanziak-cko May 3, 2024
b9e1f8e
PORetryStrategy (internal)
vitalii-vanziak-cko May 3, 2024
71e4c48
Init 'captureRetryStrategy'
vitalii-vanziak-cko May 3, 2024
05eb250
PODefaultNativeAlternativePaymentMethodEventDispatcher (internal)
vitalii-vanziak-cko May 3, 2024
387342f
Swap dispatchers order
vitalii-vanziak-cko May 3, 2024
b1356b9
Pass PODefaultNativeAlternativePaymentMethodEventDispatcher
vitalii-vanziak-cko May 3, 2024
c219982
Fix states
vitalii-vanziak-cko May 3, 2024
9578f42
Style KDoc
vitalii-vanziak-cko May 3, 2024
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 @@ -13,6 +13,9 @@ import com.processout.example.R
import com.processout.example.databinding.FragmentNativeApmBinding
import com.processout.example.shared.toMessage
import com.processout.example.ui.screen.base.BaseFragment
import com.processout.sdk.core.ProcessOutActivityResult
import com.processout.sdk.ui.napm.PONativeAlternativePaymentConfiguration
import com.processout.sdk.ui.napm.PONativeAlternativePaymentLauncher
import com.processout.sdk.ui.nativeapm.PONativeAlternativePaymentMethodConfiguration
import com.processout.sdk.ui.nativeapm.PONativeAlternativePaymentMethodLauncher
import com.processout.sdk.ui.nativeapm.PONativeAlternativePaymentMethodResult
Expand All @@ -29,21 +32,31 @@ class NativeApmFragment : BaseFragment<FragmentNativeApmBinding>(
}

private lateinit var launcher: PONativeAlternativePaymentMethodLauncher
private lateinit var launcherCompose: PONativeAlternativePaymentLauncher

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
launcher = PONativeAlternativePaymentMethodLauncher.create(
this, ::onNativeAlternativePaymentMethodResult
)
}

private fun onNativeAlternativePaymentMethodResult(result: PONativeAlternativePaymentMethodResult) {
viewModel.reset()
when (result) {
PONativeAlternativePaymentMethodResult.Success ->
showAlert(getString(R.string.success))
is PONativeAlternativePaymentMethodResult.Failure ->
showAlert(result.toMessage())
from = this
) { result ->
viewModel.reset()
when (result) {
PONativeAlternativePaymentMethodResult.Success ->
showAlert(getString(R.string.success))
is PONativeAlternativePaymentMethodResult.Failure ->
showAlert(result.toMessage())
}
}
launcherCompose = PONativeAlternativePaymentLauncher.create(
from = this
) { result ->
viewModel.reset()
when (result) {
is ProcessOutActivityResult.Success ->
showAlert(getString(R.string.success))
is ProcessOutActivityResult.Failure ->
showAlert(result.toMessage())
}
}
}

Expand All @@ -58,21 +71,22 @@ class NativeApmFragment : BaseFragment<FragmentNativeApmBinding>(
}

private fun setOnClickListeners() {
binding.createInvoiceButton.setOnClickListener { onSubmitClick() }
binding.launchNativeApmButton.setOnClickListener { onSubmitClick(launchCompose = false) }
binding.launchNativeApmComposeButton.setOnClickListener { onSubmitClick(launchCompose = true) }
binding.currencyInput.setOnEditorActionListener { _, actionId, _ ->
if (actionId == EditorInfo.IME_ACTION_DONE) {
onSubmitClick()
onSubmitClick(launchCompose = false)
return@setOnEditorActionListener true
} else {
return@setOnEditorActionListener false
}
}
}

private fun onSubmitClick() {
private fun onSubmitClick(launchCompose: Boolean) {
val amount = binding.amountInput.text.toString()
val currency = binding.currencyInput.text.toString()
viewModel.createInvoice(amount, currency)
viewModel.createInvoice(amount, currency, launchCompose)
}

private fun handle(uiState: NativeApmUiState) {
Expand All @@ -85,12 +99,21 @@ class NativeApmFragment : BaseFragment<FragmentNativeApmBinding>(
}

private fun launch(uiModel: NativeApmUiModel) {
launcher.launch(
PONativeAlternativePaymentMethodConfiguration(
gatewayConfigurationId = uiModel.gatewayConfigurationId,
invoiceId = uiModel.invoiceId
if (uiModel.launchCompose) {
launcherCompose.launch(
PONativeAlternativePaymentConfiguration(
gatewayConfigurationId = uiModel.gatewayConfigurationId,
invoiceId = uiModel.invoiceId
)
)
} else {
launcher.launch(
PONativeAlternativePaymentMethodConfiguration(
gatewayConfigurationId = uiModel.gatewayConfigurationId,
invoiceId = uiModel.invoiceId
)
)
)
}
viewModel.onLaunched()
}

Expand All @@ -105,7 +128,8 @@ class NativeApmFragment : BaseFragment<FragmentNativeApmBinding>(
with(binding) {
amountInput.isEnabled = isEnabled
currencyInput.isEnabled = isEnabled
createInvoiceButton.isClickable = isEnabled
launchNativeApmButton.isClickable = isEnabled
launchNativeApmComposeButton.isClickable = isEnabled
amountInput.clearFocus()
currencyInput.clearFocus()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,6 @@ sealed class NativeApmUiState {

data class NativeApmUiModel(
val gatewayConfigurationId: String,
val invoiceId: String
val invoiceId: String,
val launchCompose: Boolean
)
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,11 @@ class NativeApmViewModel(
private val _uiState = MutableStateFlow<NativeApmUiState>(Initial)
val uiState = _uiState.asStateFlow()

fun createInvoice(amount: String, currency: String) {
fun createInvoice(
amount: String,
currency: String,
launchCompose: Boolean
) {
_uiState.value = Submitting
viewModelScope.launch {
val request = POCreateInvoiceRequest(
Expand All @@ -51,8 +55,14 @@ class NativeApmViewModel(
customerId = createCustomer()?.id
)
invoices.createInvoice(request)
.onSuccess {
_uiState.value = Submitted(NativeApmUiModel(gatewayConfigurationId, it.id))
.onSuccess { invoice ->
_uiState.value = Submitted(
NativeApmUiModel(
gatewayConfigurationId,
invoice.id,
launchCompose
)
)
}
.onFailure { _uiState.value = Failure(it) }
}
Expand Down
18 changes: 15 additions & 3 deletions example/src/main/res/layout/fragment_native_apm.xml
Original file line number Diff line number Diff line change
Expand Up @@ -82,18 +82,30 @@
android:layout_height="@dimen/po_borderWidth"
android:layout_marginBottom="@dimen/button_marginVertical"
android:background="@color/po_border_subtle"
app:layout_constraintBottom_toTopOf="@+id/create_invoice_button"
app:layout_constraintBottom_toTopOf="@id/launch_native_apm_button"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent" />

<Button
android:id="@+id/create_invoice_button"
android:id="@+id/launch_native_apm_button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/content_padding"
android:layout_marginEnd="@dimen/content_padding"
android:layout_marginBottom="@dimen/button_space_vertical"
android:text="@string/launch_native_apm"
app:layout_constraintBottom_toTopOf="@id/launch_native_apm_compose_button"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent" />

<Button
android:id="@+id/launch_native_apm_compose_button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/content_padding"
android:layout_marginEnd="@dimen/content_padding"
android:layout_marginBottom="@dimen/button_marginVertical"
android:text="@string/create_invoice"
android:text="@string/launch_native_apm_compose"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent" />
Expand Down
3 changes: 2 additions & 1 deletion example/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
<string name="app_name" translatable="false">ProcessOut SDK Example</string>

<string name="native_apm" translatable="false">Native Alternative Payment</string>
<string name="create_invoice" translatable="false">Create Invoice</string>
<string name="launch_native_apm" translatable="false">Launch Native APM</string>
<string name="launch_native_apm_compose" translatable="false">Launch Native APM (Compose WIP)</string>
<string name="authorize_invoice" translatable="false">Authorize Invoice</string>
<string name="invoice_details" translatable="false">Invoice Details</string>
<string name="amount" translatable="false">Amount</string>
Expand Down
4 changes: 2 additions & 2 deletions sdk/src/main/kotlin/com/processout/sdk/api/ProcessOut.kt
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import com.processout.sdk.BuildConfig
import com.processout.sdk.api.dispatcher.DefaultEventDispatchers
import com.processout.sdk.api.dispatcher.POEventDispatchers
import com.processout.sdk.api.dispatcher.PONativeAlternativePaymentMethodEventDispatcher
import com.processout.sdk.api.dispatcher.nativeapm.DefaultNativeAlternativePaymentMethodEventDispatcher
import com.processout.sdk.api.dispatcher.napm.PODefaultNativeAlternativePaymentMethodEventDispatcher
import com.processout.sdk.api.network.ApiConstants
import com.processout.sdk.api.repository.POCardsRepository
import com.processout.sdk.api.repository.POGatewayConfigurationsRepository
Expand Down Expand Up @@ -64,7 +64,7 @@ class ProcessOut private constructor(
replaceWith = ReplaceWith("dispatchers.nativeAlternativePaymentMethod")
)
val nativeAlternativePaymentMethodEventDispatcher: PONativeAlternativePaymentMethodEventDispatcher by lazy {
DefaultNativeAlternativePaymentMethodEventDispatcher
PODefaultNativeAlternativePaymentMethodEventDispatcher
}

/** Dispatchers that allows to handle events during various payment flows. */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,19 @@ import com.processout.sdk.api.dispatcher.card.tokenization.POCardTokenizationEve
import com.processout.sdk.api.dispatcher.card.tokenization.PODefaultCardTokenizationEventDispatcher
import com.processout.sdk.api.dispatcher.card.update.POCardUpdateEventDispatcher
import com.processout.sdk.api.dispatcher.card.update.PODefaultCardUpdateEventDispatcher
import com.processout.sdk.api.dispatcher.nativeapm.DefaultNativeAlternativePaymentMethodEventDispatcher
import com.processout.sdk.api.dispatcher.napm.PODefaultNativeAlternativePaymentMethodEventDispatcher

internal object DefaultEventDispatchers : POEventDispatchers {

override val cardUpdate: POCardUpdateEventDispatcher by lazy {
PODefaultCardUpdateEventDispatcher
override val nativeAlternativePaymentMethod: PONativeAlternativePaymentMethodEventDispatcher by lazy {
PODefaultNativeAlternativePaymentMethodEventDispatcher
}

override val cardTokenization: POCardTokenizationEventDispatcher by lazy {
PODefaultCardTokenizationEventDispatcher
}

override val nativeAlternativePaymentMethod: PONativeAlternativePaymentMethodEventDispatcher by lazy {
DefaultNativeAlternativePaymentMethodEventDispatcher
override val cardUpdate: POCardUpdateEventDispatcher by lazy {
PODefaultCardUpdateEventDispatcher
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,12 @@ import com.processout.sdk.api.dispatcher.card.update.POCardUpdateEventDispatcher
*/
interface POEventDispatchers {

/** Dispatcher that allows to handle events during card updates. */
val cardUpdate: POCardUpdateEventDispatcher
/** Dispatcher that allows to handle events during native alternative payments. */
val nativeAlternativePaymentMethod: PONativeAlternativePaymentMethodEventDispatcher

/** Dispatcher that allows to handle events during card tokenization. */
val cardTokenization: POCardTokenizationEventDispatcher

/** Dispatcher that allows to handle events during native alternative payments. */
val nativeAlternativePaymentMethod: PONativeAlternativePaymentMethodEventDispatcher
/** Dispatcher that allows to handle events during card updates. */
val cardUpdate: POCardUpdateEventDispatcher
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import com.processout.sdk.api.model.request.PONativeAlternativePaymentMethodDefa
import com.processout.sdk.api.model.response.PONativeAlternativePaymentMethodDefaultValuesResponse
import kotlinx.coroutines.flow.SharedFlow

// TODO: Move it to '.dispatcher.nativeapm' package before next major release.
// TODO: Move it to '.dispatcher.napm' package before next major release.

/**
* Dispatcher that allows to handle events during native alternative payments.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
package com.processout.sdk.api.dispatcher.nativeapm
package com.processout.sdk.api.dispatcher.napm

import com.processout.sdk.api.dispatcher.PONativeAlternativePaymentMethodEventDispatcher
import com.processout.sdk.api.model.event.PONativeAlternativePaymentMethodEvent
import com.processout.sdk.api.model.request.PONativeAlternativePaymentMethodDefaultValuesRequest
import com.processout.sdk.api.model.response.PONativeAlternativePaymentMethodDefaultValuesResponse
import com.processout.sdk.core.annotation.ProcessOutInternalApi
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.asSharedFlow

internal object DefaultNativeAlternativePaymentMethodEventDispatcher
: PONativeAlternativePaymentMethodEventDispatcher {
/** @suppress */
@ProcessOutInternalApi
object PODefaultNativeAlternativePaymentMethodEventDispatcher : PONativeAlternativePaymentMethodEventDispatcher {

private val _events = MutableSharedFlow<PONativeAlternativePaymentMethodEvent>()
override val events = _events.asSharedFlow()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,16 @@ import com.processout.sdk.core.ProcessOutCallback
import com.processout.sdk.core.ProcessOutResult
import com.processout.sdk.core.logger.POLogger
import com.processout.sdk.core.map
import com.processout.sdk.core.retry.RetryStrategy
import com.processout.sdk.core.retry.RetryStrategy.Exponential
import com.processout.sdk.core.retry.PORetryStrategy
import com.processout.sdk.core.retry.PORetryStrategy.Exponential
import kotlinx.coroutines.*
import retrofit2.Response
import java.io.IOException
import java.net.SocketTimeoutException

internal abstract class BaseRepository(
private val failureMapper: ApiFailureMapper,
private val retryStrategy: RetryStrategy = Exponential(
private val retryStrategy: PORetryStrategy = Exponential(
maxRetries = 4,
initialDelay = 100,
maxDelay = 1000,
Expand Down Expand Up @@ -63,7 +63,7 @@ internal abstract class BaseRepository(

private suspend fun <T : Any> retry(
apiMethod: suspend () -> Response<T>,
strategy: RetryStrategy
strategy: PORetryStrategy
): Response<T> {
val iterator = strategy.iterator
repeat(strategy.maxRetries - 1) {
Expand Down
11 changes: 11 additions & 0 deletions sdk/src/main/kotlin/com/processout/sdk/core/POUnit.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.processout.sdk.core

import android.os.Parcelable
import kotlinx.parcelize.Parcelize

/**
* Parcelable unit object.
* Represents the absence of meaningful value.
*/
@Parcelize
object POUnit : Parcelable
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
package com.processout.sdk.core.retry

import com.processout.sdk.core.annotation.ProcessOutInternalApi
import kotlin.math.roundToLong

internal sealed class RetryStrategy(
/** @suppress */
@ProcessOutInternalApi
sealed class PORetryStrategy(
val maxRetries: Int,
private val initialDelay: Long,
private val minDelay: Long,
Expand All @@ -13,7 +16,7 @@ internal sealed class RetryStrategy(
class Linear(
maxRetries: Int,
delay: Long
) : RetryStrategy(
) : PORetryStrategy(
maxRetries = maxRetries,
initialDelay = delay,
minDelay = delay,
Expand All @@ -27,7 +30,7 @@ internal sealed class RetryStrategy(
minDelay: Long = initialDelay,
maxDelay: Long,
factor: Double
) : RetryStrategy(
) : PORetryStrategy(
maxRetries = maxRetries,
initialDelay = initialDelay,
minDelay = minDelay,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import coil.request.ImageRequest
import coil.request.ImageResult
import com.processout.sdk.R
import com.processout.sdk.api.ProcessOut
import com.processout.sdk.api.dispatcher.nativeapm.DefaultNativeAlternativePaymentMethodEventDispatcher
import com.processout.sdk.api.dispatcher.napm.PODefaultNativeAlternativePaymentMethodEventDispatcher
import com.processout.sdk.api.model.event.PONativeAlternativePaymentMethodEvent
import com.processout.sdk.api.model.event.PONativeAlternativePaymentMethodEvent.*
import com.processout.sdk.api.model.request.PONativeAlternativePaymentMethodDefaultValuesRequest
Expand All @@ -33,8 +33,8 @@ import com.processout.sdk.core.POFailure
import com.processout.sdk.core.POFailure.Code.*
import com.processout.sdk.core.ProcessOutResult
import com.processout.sdk.core.logger.POLogger
import com.processout.sdk.core.retry.RetryStrategy
import com.processout.sdk.core.retry.RetryStrategy.Exponential
import com.processout.sdk.core.retry.PORetryStrategy
import com.processout.sdk.core.retry.PORetryStrategy.Exponential
import com.processout.sdk.core.util.escapedMarkdown
import com.processout.sdk.ui.nativeapm.NativeAlternativePaymentMethodUiState.*
import com.processout.sdk.ui.nativeapm.PONativeAlternativePaymentMethodConfiguration.Options
Expand All @@ -57,8 +57,8 @@ internal class NativeAlternativePaymentMethodViewModel(
private val gatewayConfigurationId: String,
private val invoiceId: String,
private val invoicesService: POInvoicesService,
private val eventDispatcher: DefaultNativeAlternativePaymentMethodEventDispatcher,
private val captureRetryStrategy: RetryStrategy,
private val eventDispatcher: PODefaultNativeAlternativePaymentMethodEventDispatcher,
private val captureRetryStrategy: PORetryStrategy,
val options: Options,
val logAttributes: Map<String, String>
) : AndroidViewModel(app) {
Expand All @@ -77,7 +77,7 @@ internal class NativeAlternativePaymentMethodViewModel(
gatewayConfigurationId = gatewayConfigurationId,
invoiceId = invoiceId,
invoicesService = invoices,
eventDispatcher = DefaultNativeAlternativePaymentMethodEventDispatcher,
eventDispatcher = PODefaultNativeAlternativePaymentMethodEventDispatcher,
captureRetryStrategy = Exponential(
maxRetries = Int.MAX_VALUE,
initialDelay = 150,
Expand Down
Loading