diff --git a/sample/src/main/java/ru/tinkoff/acquiring/sample/ui/AttachCardManuallyDialog.kt b/sample/src/main/java/ru/tinkoff/acquiring/sample/ui/AttachCardManuallyDialog.kt index 391885ca..40e251e7 100644 --- a/sample/src/main/java/ru/tinkoff/acquiring/sample/ui/AttachCardManuallyDialog.kt +++ b/sample/src/main/java/ru/tinkoff/acquiring/sample/ui/AttachCardManuallyDialog.kt @@ -11,9 +11,9 @@ import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import ru.tinkoff.acquiring.sample.R import ru.tinkoff.acquiring.sample.SampleApplication -import ru.tinkoff.acquiring.sample.ui.MainActivity.Companion.toast import ru.tinkoff.acquiring.sample.utils.SessionParams import ru.tinkoff.acquiring.sample.utils.TerminalsManager +import ru.tinkoff.acquiring.sample.utils.toast import ru.tinkoff.acquiring.sdk.models.enums.ResponseStatus import ru.tinkoff.acquiring.sdk.models.options.screen.BaseAcquiringOptions import ru.tinkoff.acquiring.sdk.models.paysources.CardData @@ -89,4 +89,4 @@ class AttachCardManuallyDialogFragment : DialogFragment() { const val TAG = "AttachCardManuallyDialogFragment" } -} \ No newline at end of file +} diff --git a/sample/src/main/java/ru/tinkoff/acquiring/sample/ui/CartActivity.kt b/sample/src/main/java/ru/tinkoff/acquiring/sample/ui/CartActivity.kt index 194f79c9..2ffbe8c0 100644 --- a/sample/src/main/java/ru/tinkoff/acquiring/sample/ui/CartActivity.kt +++ b/sample/src/main/java/ru/tinkoff/acquiring/sample/ui/CartActivity.kt @@ -31,6 +31,7 @@ import ru.tinkoff.acquiring.sample.R import ru.tinkoff.acquiring.sample.adapters.CartListAdapter import ru.tinkoff.acquiring.sample.models.BooksRegistry import ru.tinkoff.acquiring.sample.models.Cart +import ru.tinkoff.acquiring.sample.ui.payable.PayableActivity import ru.tinkoff.acquiring.sdk.utils.Money /** @@ -166,10 +167,6 @@ class CartActivity : PayableActivity(), CartListAdapter.DeleteCartItemListener { return result.toString() } - private fun setupRecurrentParentPayment(hasRecurrent: Boolean) { - recurrentButton.isVisible = hasRecurrent - } - companion object { fun start(context: Context) { diff --git a/sample/src/main/java/ru/tinkoff/acquiring/sample/ui/DetailsActivity.kt b/sample/src/main/java/ru/tinkoff/acquiring/sample/ui/DetailsActivity.kt index f6cacfd1..728fd2bf 100644 --- a/sample/src/main/java/ru/tinkoff/acquiring/sample/ui/DetailsActivity.kt +++ b/sample/src/main/java/ru/tinkoff/acquiring/sample/ui/DetailsActivity.kt @@ -25,8 +25,6 @@ import android.view.View import android.widget.ImageView import android.widget.TextView import android.widget.Toast -import androidx.activity.result.ActivityResult -import androidx.activity.result.contract.ActivityResultContracts import androidx.lifecycle.lifecycleScope import kotlinx.coroutines.CancellationException import kotlinx.coroutines.Dispatchers @@ -35,6 +33,7 @@ import ru.tinkoff.acquiring.sample.R import ru.tinkoff.acquiring.sample.models.Book import ru.tinkoff.acquiring.sample.models.BooksRegistry import ru.tinkoff.acquiring.sample.models.Cart +import ru.tinkoff.acquiring.sample.ui.payable.PayableActivity import ru.tinkoff.acquiring.sdk.AcquiringSdk import ru.tinkoff.acquiring.sdk.models.options.screen.PaymentOptions import ru.tinkoff.acquiring.sdk.payment.methods.InitConfigurator.configure diff --git a/sample/src/main/java/ru/tinkoff/acquiring/sample/ui/MainActivity.kt b/sample/src/main/java/ru/tinkoff/acquiring/sample/ui/MainActivity.kt index bd665fb2..1e7fd879 100644 --- a/sample/src/main/java/ru/tinkoff/acquiring/sample/ui/MainActivity.kt +++ b/sample/src/main/java/ru/tinkoff/acquiring/sample/ui/MainActivity.kt @@ -16,14 +16,12 @@ package ru.tinkoff.acquiring.sample.ui -import android.app.Activity import android.content.Intent import android.os.Bundle import android.view.Menu import android.view.MenuItem import android.widget.ListView import android.widget.Toast -import androidx.annotation.StringRes import androidx.appcompat.app.AppCompatActivity import ru.tinkoff.acquiring.sample.R import ru.tinkoff.acquiring.sample.SampleApplication @@ -33,6 +31,7 @@ import ru.tinkoff.acquiring.sample.models.BooksRegistry import ru.tinkoff.acquiring.sample.ui.environment.AcqEnvironmentDialog import ru.tinkoff.acquiring.sample.utils.SettingsSdkManager import ru.tinkoff.acquiring.sample.utils.TerminalsManager +import ru.tinkoff.acquiring.sample.utils.toast import ru.tinkoff.acquiring.sdk.localization.AsdkSource import ru.tinkoff.acquiring.sdk.localization.Language import ru.tinkoff.acquiring.sdk.models.options.FeaturesOptions @@ -247,17 +246,8 @@ class MainActivity : AppCompatActivity(), BooksListAdapter.BookDetailsClickListe } companion object { - private const val STATIC_QR_REQUEST_CODE = 12 const val NOTIFICATION_PAYMENT_REQUEST_CODE = 14 const val THREE_DS_REQUEST_CODE = 15 - - fun Activity.toast(message: String) = runOnUiThread { - Toast.makeText(this, message, Toast.LENGTH_SHORT).show() - } - - fun Activity.toast(@StringRes message: Int) = runOnUiThread { - Toast.makeText(this, message, Toast.LENGTH_SHORT).show() - } } } diff --git a/sample/src/main/java/ru/tinkoff/acquiring/sample/ui/PayableActivity.kt b/sample/src/main/java/ru/tinkoff/acquiring/sample/ui/payable/PayableActivity.kt similarity index 61% rename from sample/src/main/java/ru/tinkoff/acquiring/sample/ui/PayableActivity.kt rename to sample/src/main/java/ru/tinkoff/acquiring/sample/ui/payable/PayableActivity.kt index 55eb254f..cd34feeb 100644 --- a/sample/src/main/java/ru/tinkoff/acquiring/sample/ui/PayableActivity.kt +++ b/sample/src/main/java/ru/tinkoff/acquiring/sample/ui/payable/PayableActivity.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package ru.tinkoff.acquiring.sample.ui +package ru.tinkoff.acquiring.sample.ui.payable import android.annotation.SuppressLint import android.app.AlertDialog @@ -22,17 +22,15 @@ import android.content.Intent import android.os.Bundle import android.view.MenuItem import android.view.View -import android.widget.TextView import android.widget.Toast import androidx.appcompat.app.AppCompatActivity import androidx.core.view.isVisible import androidx.fragment.app.commit import kotlinx.coroutines.Dispatchers -import androidx.lifecycle.lifecycleScope -import kotlinx.coroutines.launch import ru.tinkoff.acquiring.sample.R import ru.tinkoff.acquiring.sample.SampleApplication -import ru.tinkoff.acquiring.sample.ui.MainActivity.Companion.toast +import ru.tinkoff.acquiring.sample.ui.PaymentResultActivity +import ru.tinkoff.acquiring.sample.ui.payable.delegates.* import ru.tinkoff.acquiring.sample.utils.CombInitDelegate import ru.tinkoff.acquiring.sample.utils.SettingsSdkManager import ru.tinkoff.acquiring.sample.utils.TerminalsManager @@ -40,24 +38,12 @@ import ru.tinkoff.acquiring.sdk.AcquiringSdk.Companion.log import ru.tinkoff.acquiring.sdk.exceptions.AcquiringSdkTimeoutException import ru.tinkoff.acquiring.sdk.localization.AsdkSource import ru.tinkoff.acquiring.sdk.localization.Language -import ru.tinkoff.acquiring.sdk.models.Card import ru.tinkoff.acquiring.sdk.models.options.screen.PaymentOptions import ru.tinkoff.acquiring.sdk.models.options.screen.SavedCardsOptions import ru.tinkoff.acquiring.sdk.payment.* -import ru.tinkoff.acquiring.sdk.redesign.cards.list.ChooseCardLauncher import ru.tinkoff.acquiring.sdk.redesign.common.LauncherConstants.EXTRA_ERROR import ru.tinkoff.acquiring.sdk.redesign.common.LauncherConstants.EXTRA_PAYMENT_ID import ru.tinkoff.acquiring.sdk.redesign.common.LauncherConstants.RESULT_ERROR -import ru.tinkoff.acquiring.sdk.threeds.ThreeDsHelper -import ru.tinkoff.acquiring.sdk.redesign.mainform.MainFormLauncher -import ru.tinkoff.acquiring.sdk.redesign.mirpay.MirPayLauncher -import ru.tinkoff.acquiring.sdk.redesign.payment.PaymentByCardLauncher -import ru.tinkoff.acquiring.sdk.redesign.recurrent.RecurrentPayLauncher -import ru.tinkoff.acquiring.sdk.redesign.sbp.SbpPayLauncher -import ru.tinkoff.acquiring.sdk.redesign.tpay.TpayLauncher -import ru.tinkoff.acquiring.sdk.redesign.tpay.models.enableMirPay -import ru.tinkoff.acquiring.sdk.redesign.tpay.models.enableTinkoffPay -import ru.tinkoff.acquiring.sdk.redesign.tpay.models.getTinkoffPayVersion import ru.tinkoff.acquiring.sdk.utils.Money import ru.tinkoff.acquiring.sdk.utils.getLongOrNull import ru.tinkoff.acquiring.yandexpay.YandexButtonFragment @@ -67,86 +53,35 @@ import ru.tinkoff.acquiring.yandexpay.models.YandexPayData import ru.tinkoff.acquiring.yandexpay.models.enableYandexPay import ru.tinkoff.acquiring.yandexpay.models.mapYandexPayData import java.util.* -import kotlin.collections.ArrayList import kotlin.math.abs /** * @author Mariya Chernyadieva */ @SuppressLint("Registered") -open class PayableActivity : AppCompatActivity() { +open class PayableActivity : AppCompatActivity(), + TpayPaymentDelegate by TpayPayment(), + MirPayPaymentDelegate by MirPayPayment(), + SbpPayPaymentDelegate by SbpPayPayment(), + MainFormPaymentDelegate by MainFormPayment(), + RecurrentPaymentDelegate by RecurrentPayment(), + CardsForRecurrentDelegate by CardsForRecurrent(), + RecurrentParentPaymentDelegate by RecurrentParentPayment() { protected var totalPrice: Money = Money() protected var title: String = "" protected var description: String = "" - protected lateinit var settings: SettingsSdkManager + lateinit var settings: SettingsSdkManager private lateinit var progressDialog: AlertDialog private var errorDialog: AlertDialog? = null private var isProgressShowing = false private var isErrorShowing = false - protected var tinkoffAcquiring = SampleApplication.tinkoffAcquiring + val tinkoffAcquiring = SampleApplication.tinkoffAcquiring private val orderId: String get() = abs(Random().nextInt()).toString() private var acqFragment: YandexButtonFragment? = null - private val combInitDelegate: CombInitDelegate = CombInitDelegate(tinkoffAcquiring.sdk, Dispatchers.IO) - private val byCardPayment = registerForActivityResult(PaymentByCardLauncher.Contract) { result -> - when (result) { - is PaymentByCardLauncher.Success -> { - toast("byCardPayment Success : ${result.paymentId}") - } - is PaymentByCardLauncher.Error -> toast(result.error.message ?: getString(R.string.error_title)) - is PaymentByCardLauncher.Canceled -> toast("byCardPayment canceled") - } - } - private val spbPayment = registerForActivityResult(SbpPayLauncher.Contract) { result -> - when (result) { - is SbpPayLauncher.Success -> { - toast("SBP Success") - } - is SbpPayLauncher.Error -> toast(result.error.message ?: getString(R.string.error_title)) - is SbpPayLauncher.Canceled -> toast("SBP canceled") - is SbpPayLauncher.NoBanks -> Unit - } - } - private val byMainFormPayment = registerForActivityResult(MainFormLauncher.Contract) { result -> - when (result) { - is MainFormLauncher.Canceled -> toast("payment canceled") - is MainFormLauncher.Error -> toast(result.error.message ?: getString(R.string.error_title)) - is MainFormLauncher.Success -> toast("payment Success- paymentId:${result.paymentId}") - } - } - private val recurrentPayment = registerForActivityResult(RecurrentPayLauncher.Contract) { result -> - when (result) { - is RecurrentPayLauncher.Canceled -> toast("payment canceled") - is RecurrentPayLauncher.Error -> toast(result.error.message ?: getString(R.string.error_title)) - is RecurrentPayLauncher.Success -> toast("payment Success- paymentId:${result.paymentId}") - } - } - private val cardsForRecurrent = - registerForActivityResult(ChooseCardLauncher.Contract) { result -> - when (result) { - is ChooseCardLauncher.Canceled -> Unit - is ChooseCardLauncher.Error -> Unit - is ChooseCardLauncher.Success -> launchRecurrent(result.card) - is ChooseCardLauncher.NeedInputNewCard -> Unit - } - } - - private val tpayPayment = registerForActivityResult(TpayLauncher.Contract) { result -> - when (result) { - is TpayLauncher.Canceled -> toast("tpay canceled") - is TpayLauncher.Error -> toast(result.error.message ?: getString(R.string.error_title)) - is TpayLauncher.Success -> toast("payment Success- paymentId:${result.paymentId}") - } - } - private val mirPayment = registerForActivityResult(MirPayLauncher.Contract) { result -> - when (result) { - is MirPayLauncher.Canceled -> toast("MirPay canceled") - is MirPayLauncher.Error -> toast(result.error.message ?: getString(R.string.error_title)) - is MirPayLauncher.Success -> toast("payment Success- paymentId:${result.paymentId}") - } - } + val combInitDelegate: CombInitDelegate = CombInitDelegate(tinkoffAcquiring.sdk, Dispatchers.IO) override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) @@ -161,6 +96,13 @@ open class PayableActivity : AppCompatActivity() { settings = SettingsSdkManager(this) initDialogs() + initSbpPayPayment(this) + initTpayPaymentDelegate(this) + initMirPayPaymentDelegate(this) + initMainFormPaymentDelegate(this) + initRecurrentPaymentDelegate(this) + initCardsForRecurrentDelegate(this) + initRecurrentParentPaymentDelegate(this) } override fun onDestroy() { @@ -175,7 +117,8 @@ open class PayableActivity : AppCompatActivity() { override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { when (requestCode) { - PAYMENT_REQUEST_CODE, DYNAMIC_QR_PAYMENT_REQUEST_CODE -> handlePaymentResult(resultCode, data) + PAYMENT_REQUEST_CODE, + DYNAMIC_QR_PAYMENT_REQUEST_CODE -> handlePaymentResult(resultCode, data) YANDEX_PAY_REQUEST_CODE -> handleYandexPayResult(resultCode, data) else -> super.onActivityResult(requestCode, resultCode, data) } @@ -207,17 +150,9 @@ open class PayableActivity : AppCompatActivity() { protected fun initPayment() { if (settings.isRecurrentPayment) { - RecurrentPaymentProcess.init(SampleApplication.tinkoffAcquiring.sdk, application, ThreeDsHelper.CollectData) - cardsForRecurrent.launch(createSavedCardOptions()) + launchCardsScreen() } else { - val options = createPaymentOptions().apply { - this.setTerminalParams( - terminalKey = TerminalsManager.selectedTerminal.terminalKey, - publicKey = TerminalsManager.selectedTerminal.publicKey - ) - } - PaymentByCardProcess.init(SampleApplication.tinkoffAcquiring.sdk, application, ThreeDsHelper.CollectData) - byMainFormPayment.launch(MainFormLauncher.StartData(options)) + launchMainFormPayment() } } @@ -225,75 +160,6 @@ open class PayableActivity : AppCompatActivity() { tinkoffAcquiring.openDynamicQrScreen(this, createPaymentOptions(), DYNAMIC_QR_PAYMENT_REQUEST_CODE) } - protected fun startSbpPayment() { - lifecycleScope.launch { - val opt = createPaymentOptions() - opt.setTerminalParams( - TerminalsManager.selectedTerminal.terminalKey, - TerminalsManager.selectedTerminal.publicKey - ) - if (settings.isEnableCombiInit) { - showProgressDialog() - runCatching { combInitDelegate.sendInit(opt).paymentId!! } - .onFailure { - hideProgressDialog() - showErrorDialog() - } - .onSuccess { - hideProgressDialog() - tinkoffAcquiring.initSbpPaymentSession() - spbPayment.launch(SbpPayLauncher.StartData(it, opt)) - } - } else { - tinkoffAcquiring.initSbpPaymentSession() - spbPayment.launch(SbpPayLauncher.StartData(opt)) - } - } - } - - protected fun setupTinkoffPay() { - if (!settings.isTinkoffPayEnabled) return - - val tinkoffPayButton = findViewById(R.id.tinkoff_pay_button) - - tinkoffAcquiring.checkTerminalInfo({ status -> - if (status.enableTinkoffPay().not()) return@checkTerminalInfo - - tinkoffPayButton.visibility = View.VISIBLE - - val opt = createPaymentOptions() - opt.setTerminalParams( - TerminalsManager.selectedTerminal.terminalKey, - TerminalsManager.selectedTerminal.publicKey - ) - val version = checkNotNull(status?.getTinkoffPayVersion()) - tinkoffAcquiring.initTinkoffPayPaymentSession() - tinkoffPayButton.setOnClickListener { - tpayPayment.launch(TpayLauncher.StartData(opt, version)) - } - }) - } - - protected fun setupMirPay() { - val mirPayButton = findViewById(R.id.mir_pay_button) - - tinkoffAcquiring.checkTerminalInfo({ status -> - if (status.enableMirPay().not()) return@checkTerminalInfo - - mirPayButton.visibility = View.VISIBLE - - val opt = createPaymentOptions() - opt.setTerminalParams( - TerminalsManager.selectedTerminal.terminalKey, - TerminalsManager.selectedTerminal.publicKey - ) - tinkoffAcquiring.initMirPayPaymentSession() - mirPayButton.setOnClickListener { - mirPayment.launch(MirPayLauncher.StartData(opt)) - } - }) - } - protected fun setupYandexPay(theme: Int? = null, savedInstanceState: Bundle?) { if (!settings.yandexPayEnabled) return @@ -324,22 +190,7 @@ open class PayableActivity : AppCompatActivity() { }) } - protected fun setupRecurrentParentPayment() { - val recurrentButton : TextView? = findViewById(R.id.recurrent_pay) - recurrentButton?.isVisible = settings.isRecurrentPayment - recurrentButton?.setOnClickListener { - val paymentOptions = createPaymentOptions().apply { - val session = TerminalsManager.selectedTerminal - this.setTerminalParams( - terminalKey = session.terminalKey, publicKey = session.publicKey - ) - } - PaymentByCardProcess.init(SampleApplication.tinkoffAcquiring.sdk, application, ThreeDsHelper.CollectData) - byCardPayment.launch(PaymentByCardLauncher.StartData(paymentOptions, ArrayList())) - } - } - - private fun createPaymentOptions(): PaymentOptions { + fun createPaymentOptions(): PaymentOptions { val sessionParams = TerminalsManager.selectedTerminal return PaymentOptions() @@ -376,10 +227,14 @@ open class PayableActivity : AppCompatActivity() { userCanSelectCard = true duplicateEmailToReceipt = true } + setTerminalParams( + sessionParams.terminalKey, + sessionParams.publicKey + ) } } - private fun createSavedCardOptions(): SavedCardsOptions { + fun createSavedCardOptions(): SavedCardsOptions { val settings = SettingsSdkManager(this) val params = TerminalsManager.selectedTerminal @@ -426,7 +281,7 @@ open class PayableActivity : AppCompatActivity() { } } - protected fun showErrorDialog() { + fun showErrorDialog() { errorDialog = AlertDialog.Builder(this).apply { setTitle(R.string.error_title) setMessage(getString(R.string.error_message)) @@ -485,12 +340,12 @@ open class PayableActivity : AppCompatActivity() { ) } - protected fun showProgressDialog() { + fun showProgressDialog() { progressDialog.show() isProgressShowing = true } - protected fun hideProgressDialog() { + fun hideProgressDialog() { progressDialog.dismiss() isProgressShowing = false } @@ -510,18 +365,6 @@ open class PayableActivity : AppCompatActivity() { } } - private fun launchRecurrent(card: Card) { - val options = createPaymentOptions().apply { - this.setTerminalParams( - terminalKey = TerminalsManager.selectedTerminal.terminalKey, - publicKey = TerminalsManager.selectedTerminal.publicKey - ) - } - recurrentPayment.launch( - RecurrentPayLauncher.StartData(card, options) - ) - } - private fun commonErrorHandler(data: Intent?) { val error = getErrorFromIntent(data) val paymentIdFromIntent = data?.getLongOrNull(EXTRA_PAYMENT_ID) @@ -531,7 +374,6 @@ open class PayableActivity : AppCompatActivity() { Toast.makeText(this, message, Toast.LENGTH_SHORT).show() } - private fun configureToastMessage(error: Throwable?, paymentId: Long?): String { val acqSdkTimeout = error as? AcquiringSdkTimeoutException val payment = paymentId ?: acqSdkTimeout?.paymentId @@ -545,7 +387,6 @@ open class PayableActivity : AppCompatActivity() { } } - companion object { const val PAYMENT_REQUEST_CODE = 1 diff --git a/sample/src/main/java/ru/tinkoff/acquiring/sample/ui/payable/delegates/CardsForRecurrentDelegate.kt b/sample/src/main/java/ru/tinkoff/acquiring/sample/ui/payable/delegates/CardsForRecurrentDelegate.kt new file mode 100644 index 00000000..3ff82109 --- /dev/null +++ b/sample/src/main/java/ru/tinkoff/acquiring/sample/ui/payable/delegates/CardsForRecurrentDelegate.kt @@ -0,0 +1,47 @@ +package ru.tinkoff.acquiring.sample.ui.payable.delegates + +import androidx.activity.result.ActivityResultLauncher +import ru.tinkoff.acquiring.sample.SampleApplication +import ru.tinkoff.acquiring.sample.ui.payable.PayableActivity +import ru.tinkoff.acquiring.sdk.models.options.screen.SavedCardsOptions +import ru.tinkoff.acquiring.sdk.payment.RecurrentPaymentProcess +import ru.tinkoff.acquiring.sdk.redesign.cards.list.ChooseCardLauncher +import ru.tinkoff.acquiring.sdk.threeds.ThreeDsHelper + +/** + * @author k.shpakovskiy + */ +interface CardsForRecurrentDelegate { + fun initCardsForRecurrentDelegate(activity: PayableActivity) + fun launchCardsScreen() +} + +class CardsForRecurrent : CardsForRecurrentDelegate { + private lateinit var activity: PayableActivity + private lateinit var cardsForRecurrent: ActivityResultLauncher + + override fun initCardsForRecurrentDelegate(activity: PayableActivity) { + this.activity = activity + with(activity) { + cardsForRecurrent = registerForActivityResult(ChooseCardLauncher.Contract) { result -> + when (result) { + is ChooseCardLauncher.Canceled -> Unit + is ChooseCardLauncher.Error -> Unit + is ChooseCardLauncher.Success -> launchRecurrent(result.card) + is ChooseCardLauncher.NeedInputNewCard -> Unit + } + } + } + } + + override fun launchCardsScreen() { + with(activity) { + RecurrentPaymentProcess.init( + sdk = SampleApplication.tinkoffAcquiring.sdk, + application = application, + threeDsDataCollector = ThreeDsHelper.CollectData + ) + cardsForRecurrent.launch(createSavedCardOptions()) + } + } +} diff --git a/sample/src/main/java/ru/tinkoff/acquiring/sample/ui/payable/delegates/InitRequestDelegate.kt b/sample/src/main/java/ru/tinkoff/acquiring/sample/ui/payable/delegates/InitRequestDelegate.kt new file mode 100644 index 00000000..6d615a35 --- /dev/null +++ b/sample/src/main/java/ru/tinkoff/acquiring/sample/ui/payable/delegates/InitRequestDelegate.kt @@ -0,0 +1,48 @@ +package ru.tinkoff.acquiring.sample.ui.payable.delegates + +import androidx.lifecycle.lifecycleScope +import kotlinx.coroutines.launch +import ru.tinkoff.acquiring.sample.ui.payable.PayableActivity +import ru.tinkoff.acquiring.sdk.models.options.screen.PaymentOptions +import ru.tinkoff.acquiring.sdk.utils.checkNotNull + +/** + * @author k.shpakovskiy + */ +interface InitRequestDelegate { + fun startInitRequest( + activity: PayableActivity, + options: PaymentOptions, + result: (PaymentOptions) -> Unit + ) +} + +class InitRequestDelegateImpl : InitRequestDelegate { + + override fun startInitRequest( + activity: PayableActivity, + options: PaymentOptions, + result: (PaymentOptions) -> Unit + ) { + with(activity) { + lifecycleScope.launch { + showProgressDialog() + runCatching { + combInitDelegate + .sendInit(options) + .paymentId + .checkNotNull { "payment id mustn't null" } + } + .onFailure { + hideProgressDialog() + showErrorDialog() + } + .onSuccess { paymentId -> + hideProgressDialog() + options.paymentId = paymentId + result(options) + } + } + } + } +} diff --git a/sample/src/main/java/ru/tinkoff/acquiring/sample/ui/payable/delegates/MainFormPaymentDelegate.kt b/sample/src/main/java/ru/tinkoff/acquiring/sample/ui/payable/delegates/MainFormPaymentDelegate.kt new file mode 100644 index 00000000..5e299dfa --- /dev/null +++ b/sample/src/main/java/ru/tinkoff/acquiring/sample/ui/payable/delegates/MainFormPaymentDelegate.kt @@ -0,0 +1,56 @@ +package ru.tinkoff.acquiring.sample.ui.payable.delegates + +import androidx.activity.result.ActivityResultLauncher +import ru.tinkoff.acquiring.sample.R +import ru.tinkoff.acquiring.sample.SampleApplication +import ru.tinkoff.acquiring.sample.ui.payable.PayableActivity +import ru.tinkoff.acquiring.sample.utils.toast +import ru.tinkoff.acquiring.sdk.payment.PaymentByCardProcess +import ru.tinkoff.acquiring.sdk.redesign.mainform.MainFormLauncher +import ru.tinkoff.acquiring.sdk.threeds.ThreeDsHelper + +/** + * @author k.shpakovskiy + */ +interface MainFormPaymentDelegate { + fun initMainFormPaymentDelegate(activity: PayableActivity) + fun launchMainFormPayment() +} + +class MainFormPayment : MainFormPaymentDelegate, + InitRequestDelegate by InitRequestDelegateImpl() { + private lateinit var activity: PayableActivity + private lateinit var mainFormLauncher: ActivityResultLauncher + + override fun initMainFormPaymentDelegate(activity: PayableActivity) { + this.activity = activity + with(activity) { + mainFormLauncher = registerForActivityResult(MainFormLauncher.Contract) { result -> + when (result) { + is MainFormLauncher.Canceled -> toast("payment canceled") + is MainFormLauncher.Error -> toast(result.error.message ?: getString(R.string.error_title)) + is MainFormLauncher.Success -> toast("payment Success- paymentId:${result.paymentId}") + } + } + } + } + + override fun launchMainFormPayment() { + with(activity) { + val options = createPaymentOptions() + PaymentByCardProcess.init( + sdk = SampleApplication.tinkoffAcquiring.sdk, + application = application, + threeDsDataCollector = ThreeDsHelper.CollectData + ) + + if (settings.isEnableCombiInit) { + startInitRequest(activity, options) { optionsWithPaymentId -> + mainFormLauncher.launch(MainFormLauncher.StartData(optionsWithPaymentId)) + } + } else { + mainFormLauncher.launch(MainFormLauncher.StartData(options)) + } + } + } +} diff --git a/sample/src/main/java/ru/tinkoff/acquiring/sample/ui/payable/delegates/MirPayPaymentDelegate.kt b/sample/src/main/java/ru/tinkoff/acquiring/sample/ui/payable/delegates/MirPayPaymentDelegate.kt new file mode 100644 index 00000000..2ed0263b --- /dev/null +++ b/sample/src/main/java/ru/tinkoff/acquiring/sample/ui/payable/delegates/MirPayPaymentDelegate.kt @@ -0,0 +1,64 @@ +package ru.tinkoff.acquiring.sample.ui.payable.delegates + +import android.view.View +import androidx.activity.result.ActivityResultLauncher +import ru.tinkoff.acquiring.sample.R +import ru.tinkoff.acquiring.sample.ui.payable.PayableActivity +import ru.tinkoff.acquiring.sample.utils.SettingsSdkManager +import ru.tinkoff.acquiring.sample.utils.toast +import ru.tinkoff.acquiring.sdk.models.options.screen.PaymentOptions +import ru.tinkoff.acquiring.sdk.redesign.mirpay.MirPayLauncher +import ru.tinkoff.acquiring.sdk.redesign.tpay.models.enableMirPay + +/** + * @author k.shpakovskiy + */ +interface MirPayPaymentDelegate { + fun initMirPayPaymentDelegate(activity: PayableActivity) + fun setupMirPay() +} + +class MirPayPayment : MirPayPaymentDelegate, + InitRequestDelegate by InitRequestDelegateImpl() { + private lateinit var activity: PayableActivity + private lateinit var mirPayment: ActivityResultLauncher + + override fun initMirPayPaymentDelegate(activity: PayableActivity) { + this.activity = activity + mirPayment = with(activity) { + registerForActivityResult(MirPayLauncher.Contract) { result -> + when (result) { + is MirPayLauncher.Canceled -> toast("MirPay canceled") + is MirPayLauncher.Error -> toast(result.error.message ?: getString(R.string.error_title)) + is MirPayLauncher.Success -> toast("payment Success - paymentId:${result.paymentId}") + } + } + } + } + + override fun setupMirPay() { + with(activity) { + val mirPayButton = findViewById(R.id.mir_pay_button) + + tinkoffAcquiring.checkTerminalInfo({ status -> + if (status.enableMirPay().not()) return@checkTerminalInfo + + mirPayButton.visibility = View.VISIBLE + + tinkoffAcquiring.initMirPayPaymentSession() + val options = createPaymentOptions() + mirPayButton.setOnClickListener { launchMirPayPayment(settings, options) } + }) + } + } + + private fun launchMirPayPayment(settings: SettingsSdkManager, options: PaymentOptions) { + if (settings.isEnableCombiInit) { + startInitRequest(activity, options) { optionsWithPaymentId -> + mirPayment.launch(MirPayLauncher.StartData(optionsWithPaymentId)) + } + } else { + mirPayment.launch(MirPayLauncher.StartData(options)) + } + } +} diff --git a/sample/src/main/java/ru/tinkoff/acquiring/sample/ui/payable/delegates/RecurrentParentPaymentDelegate.kt b/sample/src/main/java/ru/tinkoff/acquiring/sample/ui/payable/delegates/RecurrentParentPaymentDelegate.kt new file mode 100644 index 00000000..521dd8d4 --- /dev/null +++ b/sample/src/main/java/ru/tinkoff/acquiring/sample/ui/payable/delegates/RecurrentParentPaymentDelegate.kt @@ -0,0 +1,74 @@ +package ru.tinkoff.acquiring.sample.ui.payable.delegates + +import android.widget.TextView +import androidx.activity.result.ActivityResultLauncher +import androidx.core.view.isVisible +import ru.tinkoff.acquiring.sample.R +import ru.tinkoff.acquiring.sample.SampleApplication +import ru.tinkoff.acquiring.sample.ui.payable.PayableActivity +import ru.tinkoff.acquiring.sample.utils.toast +import ru.tinkoff.acquiring.sdk.models.options.screen.PaymentOptions +import ru.tinkoff.acquiring.sdk.payment.PaymentByCardProcess +import ru.tinkoff.acquiring.sdk.redesign.payment.PaymentByCardLauncher +import ru.tinkoff.acquiring.sdk.threeds.ThreeDsHelper + +/** + * @author k.shpakovskiy + */ +interface RecurrentParentPaymentDelegate { + fun initRecurrentParentPaymentDelegate(activity: PayableActivity) + fun setupRecurrentParentPayment() +} + +class RecurrentParentPayment : RecurrentParentPaymentDelegate, + InitRequestDelegate by InitRequestDelegateImpl() { + private lateinit var activity: PayableActivity + private lateinit var recurrentParentPaymentLauncher: ActivityResultLauncher + + override fun initRecurrentParentPaymentDelegate(activity: PayableActivity) { + this.activity = activity + recurrentParentPaymentLauncher = with(activity) { + registerForActivityResult(PaymentByCardLauncher.Contract) { result -> + when (result) { + is PaymentByCardLauncher.Success -> { + toast("byCardPayment Success : ${result.paymentId}") + } + is PaymentByCardLauncher.Error -> toast(result.error.message ?: getString(R.string.error_title)) + is PaymentByCardLauncher.Canceled -> toast("byCardPayment canceled") + } + } + } + } + + override fun setupRecurrentParentPayment() { + with(activity) { + val recurrentButton : TextView? = findViewById(R.id.recurrent_pay) + recurrentButton?.isVisible = settings.isRecurrentPayment + recurrentButton?.setOnClickListener { + PaymentByCardProcess.init( + sdk = SampleApplication.tinkoffAcquiring.sdk, + application = application, + threeDsDataCollector = ThreeDsHelper.CollectData + ) + + val options = createPaymentOptions() + if (settings.isEnableCombiInit) { + startInitRequest(activity, options) { optionsWithPaymentId -> + launchPaymentByCard(optionsWithPaymentId) + } + } else { + launchPaymentByCard(options) + } + } + } + } + + private fun launchPaymentByCard(options: PaymentOptions) { + recurrentParentPaymentLauncher.launch( + PaymentByCardLauncher.StartData( + paymentOptions = options, + cards = ArrayList() + ) + ) + } +} diff --git a/sample/src/main/java/ru/tinkoff/acquiring/sample/ui/payable/delegates/RecurrentPaymentDelegate.kt b/sample/src/main/java/ru/tinkoff/acquiring/sample/ui/payable/delegates/RecurrentPaymentDelegate.kt new file mode 100644 index 00000000..06023e33 --- /dev/null +++ b/sample/src/main/java/ru/tinkoff/acquiring/sample/ui/payable/delegates/RecurrentPaymentDelegate.kt @@ -0,0 +1,43 @@ +package ru.tinkoff.acquiring.sample.ui.payable.delegates + +import androidx.activity.result.ActivityResultLauncher +import ru.tinkoff.acquiring.sample.R +import ru.tinkoff.acquiring.sample.ui.payable.PayableActivity +import ru.tinkoff.acquiring.sample.utils.toast +import ru.tinkoff.acquiring.sdk.models.Card +import ru.tinkoff.acquiring.sdk.redesign.recurrent.RecurrentPayLauncher + +/** + * @author k.shpakovskiy + */ +interface RecurrentPaymentDelegate { + fun initRecurrentPaymentDelegate(activity: PayableActivity) + fun launchRecurrent(card: Card) +} + +class RecurrentPayment : RecurrentPaymentDelegate { + private lateinit var activity: PayableActivity + private lateinit var recurrentPayment: ActivityResultLauncher + + override fun initRecurrentPaymentDelegate(activity: PayableActivity) { + this.activity = activity + with(activity) { + recurrentPayment = registerForActivityResult(RecurrentPayLauncher.Contract) { result -> + when (result) { + is RecurrentPayLauncher.Canceled -> toast("payment canceled") + is RecurrentPayLauncher.Error -> toast(result.error.message ?: getString(R.string.error_title)) + is RecurrentPayLauncher.Success -> toast("payment Success- paymentId:${result.paymentId}") + } + } + } + } + + override fun launchRecurrent(card: Card) { + with(activity) { + val options = createPaymentOptions() + recurrentPayment.launch( + RecurrentPayLauncher.StartData(card, options) + ) + } + } +} diff --git a/sample/src/main/java/ru/tinkoff/acquiring/sample/ui/payable/delegates/SbpPayPaymentDelegate.kt b/sample/src/main/java/ru/tinkoff/acquiring/sample/ui/payable/delegates/SbpPayPaymentDelegate.kt new file mode 100644 index 00000000..4e23bcec --- /dev/null +++ b/sample/src/main/java/ru/tinkoff/acquiring/sample/ui/payable/delegates/SbpPayPaymentDelegate.kt @@ -0,0 +1,51 @@ +package ru.tinkoff.acquiring.sample.ui.payable.delegates + +import androidx.activity.result.ActivityResultLauncher +import ru.tinkoff.acquiring.sample.R +import ru.tinkoff.acquiring.sample.ui.payable.PayableActivity +import ru.tinkoff.acquiring.sample.utils.toast +import ru.tinkoff.acquiring.sdk.redesign.sbp.SbpPayLauncher + +/** + * @author k.shpakovskiy + */ +interface SbpPayPaymentDelegate { + fun initSbpPayPayment(activity: PayableActivity) + fun startSbpPayment() +} + +class SbpPayPayment : SbpPayPaymentDelegate, + InitRequestDelegate by InitRequestDelegateImpl() { + private lateinit var sbpPayment: ActivityResultLauncher + private lateinit var activity: PayableActivity + + override fun initSbpPayPayment(activity: PayableActivity) { + this.activity = activity + with(activity) { + sbpPayment = activity.registerForActivityResult(SbpPayLauncher.Contract) { result -> + when (result) { + is SbpPayLauncher.Success -> { + toast("SBP Success") + } + is SbpPayLauncher.Error -> toast(result.error.message ?: getString(R.string.error_title)) + is SbpPayLauncher.Canceled -> toast("SBP canceled") + is SbpPayLauncher.NoBanks -> Unit + } + } + } + } + + override fun startSbpPayment() { + with(activity) { + val options = createPaymentOptions() + tinkoffAcquiring.initSbpPaymentSession() + if (settings.isEnableCombiInit) { + startInitRequest(activity, options) { optionsWithPaymentId -> + sbpPayment.launch(SbpPayLauncher.StartData(optionsWithPaymentId)) + } + } else { + sbpPayment.launch(SbpPayLauncher.StartData(options)) + } + } + } +} diff --git a/sample/src/main/java/ru/tinkoff/acquiring/sample/ui/payable/delegates/TpayPaymentDelegate.kt b/sample/src/main/java/ru/tinkoff/acquiring/sample/ui/payable/delegates/TpayPaymentDelegate.kt new file mode 100644 index 00000000..6b606115 --- /dev/null +++ b/sample/src/main/java/ru/tinkoff/acquiring/sample/ui/payable/delegates/TpayPaymentDelegate.kt @@ -0,0 +1,64 @@ +package ru.tinkoff.acquiring.sample.ui.payable.delegates + +import android.view.View +import androidx.activity.result.ActivityResultLauncher +import ru.tinkoff.acquiring.sample.R +import ru.tinkoff.acquiring.sample.ui.payable.PayableActivity +import ru.tinkoff.acquiring.sample.utils.toast +import ru.tinkoff.acquiring.sdk.redesign.tpay.TpayLauncher +import ru.tinkoff.acquiring.sdk.redesign.tpay.models.enableTinkoffPay +import ru.tinkoff.acquiring.sdk.redesign.tpay.models.getTinkoffPayVersion + +/** + * @author k.shpakovskiy + */ +interface TpayPaymentDelegate { + fun initTpayPaymentDelegate(activity: PayableActivity) + fun setupTinkoffPay() +} + +class TpayPayment : TpayPaymentDelegate, + InitRequestDelegate by InitRequestDelegateImpl() { + private lateinit var activity: PayableActivity + private lateinit var tpayPayment: ActivityResultLauncher + + override fun initTpayPaymentDelegate(activity: PayableActivity) { + this.activity = activity + tpayPayment = with(activity) { + registerForActivityResult(TpayLauncher.Contract) { result -> + when (result) { + is TpayLauncher.Canceled -> toast("tpay canceled") + is TpayLauncher.Error -> toast(result.error.message ?: activity.getString(R.string.error_title)) + is TpayLauncher.Success -> toast("payment Success- paymentId:${result.paymentId}") + } + } + } + } + + override fun setupTinkoffPay() { + with(activity) { + if (!settings.isTinkoffPayEnabled) return + + val tinkoffPayButton = findViewById(R.id.tinkoff_pay_button) + + tinkoffAcquiring.checkTerminalInfo({ status -> + if (status.enableTinkoffPay().not()) return@checkTerminalInfo + + tinkoffPayButton.visibility = View.VISIBLE + val version = checkNotNull(status?.getTinkoffPayVersion()) + + tinkoffAcquiring.initTinkoffPayPaymentSession() + tinkoffPayButton.setOnClickListener { + val options = createPaymentOptions() + if (settings.isEnableCombiInit) { + startInitRequest(activity, options) { optionsWithPaymentId -> + tpayPayment.launch(TpayLauncher.StartData(optionsWithPaymentId, version)) + } + } else { + tpayPayment.launch(TpayLauncher.StartData(options, version)) + } + } + }) + } + } +} diff --git a/sample/src/main/java/ru/tinkoff/acquiring/sample/utils/Ext.kt b/sample/src/main/java/ru/tinkoff/acquiring/sample/utils/Ext.kt new file mode 100644 index 00000000..26d3f095 --- /dev/null +++ b/sample/src/main/java/ru/tinkoff/acquiring/sample/utils/Ext.kt @@ -0,0 +1,16 @@ +package ru.tinkoff.acquiring.sample.utils + +import android.app.Activity +import android.widget.Toast +import androidx.annotation.StringRes + +/** + * @author k.shpakovskiy + */ +fun Activity.toast(message: String) = runOnUiThread { + Toast.makeText(this, message, Toast.LENGTH_SHORT).show() +} + +fun Activity.toast(@StringRes message: Int) = runOnUiThread { + Toast.makeText(this, message, Toast.LENGTH_SHORT).show() +} diff --git a/ui/src/main/java/ru/tinkoff/acquiring/sdk/models/options/screen/PaymentOptions.kt b/ui/src/main/java/ru/tinkoff/acquiring/sdk/models/options/screen/PaymentOptions.kt index b8cdde54..dc2441bd 100644 --- a/ui/src/main/java/ru/tinkoff/acquiring/sdk/models/options/screen/PaymentOptions.kt +++ b/ui/src/main/java/ru/tinkoff/acquiring/sdk/models/options/screen/PaymentOptions.kt @@ -49,6 +49,12 @@ class PaymentOptions() : BaseAcquiringOptions(), Parcelable { */ var asdkState: AsdkState = DefaultState + /** + * Номер платежа, полученного после инициализации + * платежа на стороне бекенда мерчанта. + */ + var paymentId: Long? = null + /** * Аналитика главной формы */ @@ -65,6 +71,7 @@ class PaymentOptions() : BaseAcquiringOptions(), Parcelable { features = readParcelable(FeaturesOptions::class.java.classLoader)!! asdkState = readSerializable() as AsdkState analyticsOptions = readParcelable(AnalyticsOptions::class.java.classLoader)!! + paymentId = readSerializable() as? Long? } } @@ -77,6 +84,7 @@ class PaymentOptions() : BaseAcquiringOptions(), Parcelable { writeParcelable(features, flags) writeSerializable(asdkState) writeParcelable(analyticsOptions, flags) + writeSerializable(paymentId) } } diff --git a/ui/src/main/java/ru/tinkoff/acquiring/sdk/payment/MirPayProcess.kt b/ui/src/main/java/ru/tinkoff/acquiring/sdk/payment/MirPayProcess.kt index 3c9c37d0..f584baf5 100644 --- a/ui/src/main/java/ru/tinkoff/acquiring/sdk/payment/MirPayProcess.kt +++ b/ui/src/main/java/ru/tinkoff/acquiring/sdk/payment/MirPayProcess.kt @@ -36,12 +36,9 @@ class MirPayProcess internal constructor( val state = MutableStateFlow(MirPayPaymentState.Created(null)) private var looperJob: Job = Job() - fun start( - paymentOptions: PaymentOptions, - paymentId: Long? = null, - ) { + fun start(paymentOptions: PaymentOptions) { scope.launch { - runCatching { startFlow(paymentOptions, paymentId) } + runCatching { startFlow(paymentOptions) } .onFailure { handlePaymentFlowFailure(it) } } } @@ -73,14 +70,11 @@ class MirPayProcess internal constructor( } } - private suspend fun startFlow( - paymentOptions: PaymentOptions, - paymentId: Long? = null - ) { - val _paymentId = paymentId ?: linkMethods.init(paymentOptions) - state.value = MirPayPaymentState.Started(_paymentId) - val link = linkMethods.getLink(_paymentId) - state.value = MirPayPaymentState.NeedChooseOnUi(_paymentId, link) + private suspend fun startFlow(paymentOptions: PaymentOptions) { + val paymentId = paymentOptions.paymentId ?: linkMethods.init(paymentOptions) + state.value = MirPayPaymentState.Started(paymentId) + val link = linkMethods.getLink(paymentId) + state.value = MirPayPaymentState.NeedChooseOnUi(paymentId, link) } private fun handlePaymentFlowFailure(ex: Throwable) { diff --git a/ui/src/main/java/ru/tinkoff/acquiring/sdk/payment/PaymentByCardProcess.kt b/ui/src/main/java/ru/tinkoff/acquiring/sdk/payment/PaymentByCardProcess.kt index b858804c..4555a9a4 100644 --- a/ui/src/main/java/ru/tinkoff/acquiring/sdk/payment/PaymentByCardProcess.kt +++ b/ui/src/main/java/ru/tinkoff/acquiring/sdk/payment/PaymentByCardProcess.kt @@ -77,36 +77,42 @@ class PaymentByCardProcess internal constructor( private suspend fun startFlow( card: CardSource, - paymentOptions: PaymentOptions, + options: PaymentOptions, email: String?, ) { this.paymentSource = card - val paymentId = initMethods - .init(paymentOptions, email) - .paymentId - .checkNotNull { "paymentId must be not null" } + + val paymentId = options.paymentId + ?: initMethods + .init(options, email) + .requiredPaymentId() val data3ds = check3DsVersionMethods.callCheck3DsVersion( - paymentId, card, paymentOptions, email + paymentId = paymentId, + paymentSource = card, + paymentOptions = options, + email = email ) + val finish = finishAuthorizeMethods.finish( - paymentId, - card, - paymentOptions, - email, - data3ds.additionalData, - data3ds.threeDsVersion, - data3ds.threeDsTransaction + paymentId = paymentId, + paymentSource = card, + paymentOptions = options, + email = email, + data = data3ds.additionalData, + threeDsVersion = data3ds.threeDsVersion, + threeDsTransaction = data3ds.threeDsTransaction ) + _state.value = when (finish) { is FinishAuthorizeMethods.Result.Need3ds -> PaymentByCardState.ThreeDsUiNeeded( - finish.threeDsState, - paymentOptions + threeDsState = finish.threeDsState, + paymentOptions = options ) is FinishAuthorizeMethods.Result.Success -> PaymentByCardState.Success( - finish.paymentId, - finish.cardId, - finish.rebillId + paymentId = finish.paymentId, + cardId = finish.cardId, + rebillId = finish.rebillId ) } } diff --git a/ui/src/main/java/ru/tinkoff/acquiring/sdk/payment/RecurrentPaymentProcess.kt b/ui/src/main/java/ru/tinkoff/acquiring/sdk/payment/RecurrentPaymentProcess.kt index 0dc47f14..354cfcb3 100644 --- a/ui/src/main/java/ru/tinkoff/acquiring/sdk/payment/RecurrentPaymentProcess.kt +++ b/ui/src/main/java/ru/tinkoff/acquiring/sdk/payment/RecurrentPaymentProcess.kt @@ -18,6 +18,7 @@ import ru.tinkoff.acquiring.sdk.responses.ChargeResponse import ru.tinkoff.acquiring.sdk.threeds.ThreeDsDataCollector import ru.tinkoff.acquiring.sdk.threeds.ThreeDsHelper import ru.tinkoff.acquiring.sdk.utils.CoroutineManager +import ru.tinkoff.acquiring.sdk.utils.checkNotNull import kotlin.coroutines.resume import kotlin.coroutines.suspendCoroutine @@ -105,11 +106,20 @@ class RecurrentPaymentProcess internal constructor( paymentOptions: PaymentOptions, email: String? ) { - val init = initMethods.init(paymentOptions, email) - val paymentId = checkNotNull(init.paymentId) { "paymentId must be not null" } - _state.value = PaymentByCardState.Started(paymentOptions, email, paymentId) - val charge = chargeMethods.charge(init.paymentId, cardData.rebillId) - charge.emitSuccess(cardData.rebillId) + val paymentId = paymentOptions.paymentId + ?: initMethods + .init(paymentOptions, email) + .requiredPaymentId() + + _state.value = PaymentByCardState.Started( + paymentOptions = paymentOptions, + email = email, + paymentId = paymentId + ) + + chargeMethods + .charge(paymentId = paymentId, rebillId = cardData.rebillId) + .emitSuccess(rebillId = cardData.rebillId) } private suspend fun startRejectedFlow( @@ -120,14 +130,35 @@ class RecurrentPaymentProcess internal constructor( email: String? ) { _state.value = PaymentByCardState.CvcUiInProcess - val card = - AttachedCard(chargeMethods.getCardByRebillId(rebillId, paymentOptions).cardId, cvc) - val init = chargeMethods.init(paymentOptions, email, rejectedId) - val paymentId = checkNotNull(init.paymentId) { "paymentId must be not null" } + + val cardId = chargeMethods + .getCardByRebillId( + rebillId = rebillId, + paymentOptions = paymentOptions + ) + .cardId + + val card = AttachedCard(cardId = cardId, cvv = cvc) + + val paymentId = paymentOptions.paymentId + ?: chargeMethods + .init( + paymentOptions = paymentOptions, + email = email, + rejectedPaymentId = rejectedId + ) + .requiredPaymentId() + _state.value = PaymentByCardState.Started(paymentOptions, email, paymentId) - val data3ds = check3DsVersionMethods.callCheck3DsVersion( - paymentId, card, paymentOptions, email - ) + + val data3ds = check3DsVersionMethods + .callCheck3DsVersion( + paymentId, + card, + paymentOptions, + email + ) + val finish = finishAuthorizeMethods.finish( paymentId, card, @@ -211,4 +242,4 @@ class RecurrentPaymentProcess internal constructor( ) } } -} \ No newline at end of file +} diff --git a/ui/src/main/java/ru/tinkoff/acquiring/sdk/payment/SbpPaymentProcess.kt b/ui/src/main/java/ru/tinkoff/acquiring/sdk/payment/SbpPaymentProcess.kt index 1cb7e6e0..e05a3d6c 100644 --- a/ui/src/main/java/ru/tinkoff/acquiring/sdk/payment/SbpPaymentProcess.kt +++ b/ui/src/main/java/ru/tinkoff/acquiring/sdk/payment/SbpPaymentProcess.kt @@ -13,6 +13,7 @@ import ru.tinkoff.acquiring.sdk.models.enums.ResponseStatus import ru.tinkoff.acquiring.sdk.models.options.screen.PaymentOptions import ru.tinkoff.acquiring.sdk.payment.methods.InitConfigurator.configure import ru.tinkoff.acquiring.sdk.payment.base.PaymentUiEvent +import ru.tinkoff.acquiring.sdk.payment.methods.requiredPaymentId import ru.tinkoff.acquiring.sdk.payment.pooling.GetStatusPooling import ru.tinkoff.acquiring.sdk.redesign.sbp.util.NspkBankAppsProvider import ru.tinkoff.acquiring.sdk.redesign.sbp.util.NspkInstalledAppsChecker @@ -45,15 +46,15 @@ class SbpPaymentProcess internal constructor( val state = MutableStateFlow(SbpPaymentState.Created) private var looperJob: Job = Job() - fun start(paymentOptions: PaymentOptions, paymentId: Long? = null) { + fun start(options: PaymentOptions) { scope.launch { runOrCatch { val nspkApps = nspkBankProvider.getNspkApps() - val id = paymentId ?: sendInit(paymentOptions) - state.value = SbpPaymentState.Started(id) - val deeplink = sendGetQr(id) + val paymentId = options.paymentId ?: sendInit(options) + state.value = SbpPaymentState.Started(paymentId) + val deeplink = sendGetQr(paymentId) val installedApps = bankAppsProvider.checkInstalledApps(nspkApps, deeplink) - state.value = SbpPaymentState.NeedChooseOnUi(id, PaymentUiEvent.ShowApps(installedApps)) + state.value = SbpPaymentState.NeedChooseOnUi(paymentId, PaymentUiEvent.ShowApps(installedApps)) } } } @@ -101,7 +102,7 @@ class SbpPaymentProcess internal constructor( private suspend fun sendInit(paymentOptions: PaymentOptions): Long { val response = sdk.init { configure(paymentOptions) }.performSuspendRequest().getOrThrow() - return response.paymentId!! + return response.requiredPaymentId() } private suspend fun sendGetQr(paymentId: Long): String = checkNotNull( diff --git a/ui/src/main/java/ru/tinkoff/acquiring/sdk/payment/TpayProcess.kt b/ui/src/main/java/ru/tinkoff/acquiring/sdk/payment/TpayProcess.kt index ee033cd4..e73f1897 100644 --- a/ui/src/main/java/ru/tinkoff/acquiring/sdk/payment/TpayProcess.kt +++ b/ui/src/main/java/ru/tinkoff/acquiring/sdk/payment/TpayProcess.kt @@ -6,7 +6,6 @@ import kotlinx.coroutines.flow.catch import kotlinx.coroutines.flow.collectLatest import kotlinx.coroutines.flow.map import ru.tinkoff.acquiring.sdk.AcquiringSdk -import ru.tinkoff.acquiring.sdk.exceptions.AcquiringApiException import ru.tinkoff.acquiring.sdk.exceptions.AcquiringSdkException import ru.tinkoff.acquiring.sdk.exceptions.AcquiringSdkTimeoutException import ru.tinkoff.acquiring.sdk.exceptions.getErrorCodeIfApiError @@ -15,7 +14,6 @@ import ru.tinkoff.acquiring.sdk.models.options.screen.PaymentOptions import ru.tinkoff.acquiring.sdk.payment.methods.GetTpayLinkMethodsSdkImpl import ru.tinkoff.acquiring.sdk.payment.methods.TpayMethods import ru.tinkoff.acquiring.sdk.payment.pooling.GetStatusPooling -import kotlin.coroutines.CoroutineContext /** * Created by i.golovachev @@ -41,11 +39,10 @@ class TpayProcess internal constructor( fun start( paymentOptions: PaymentOptions, tpayVersion: String, - paymentId: Long? = null, ) { scope.launch { try { - startFlow(paymentOptions, tpayVersion, paymentId) + startFlow(paymentOptions, tpayVersion) } catch (ignored: CancellationException) { throw ignored } catch (e: Exception) { @@ -84,12 +81,11 @@ class TpayProcess internal constructor( private suspend fun startFlow( paymentOptions: PaymentOptions, tpayVersion: String, - paymentId: Long? = null, ) { - val _paymentId = paymentId ?: init(paymentOptions) - state.value = TpayPaymentState.Started(_paymentId) - val link = getLink(_paymentId, tpayVersion) - state.value = TpayPaymentState.NeedChooseOnUi(_paymentId, link) + val paymentId = paymentOptions.paymentId ?: init(paymentOptions) + state.value = TpayPaymentState.Started(paymentId) + val link = getLink(paymentId, tpayVersion) + state.value = TpayPaymentState.NeedChooseOnUi(paymentId, link) } private suspend fun init(paymentOptions: PaymentOptions): Long { diff --git a/ui/src/main/java/ru/tinkoff/acquiring/sdk/payment/methods/Ext.kt b/ui/src/main/java/ru/tinkoff/acquiring/sdk/payment/methods/Ext.kt new file mode 100644 index 00000000..d7dee36c --- /dev/null +++ b/ui/src/main/java/ru/tinkoff/acquiring/sdk/payment/methods/Ext.kt @@ -0,0 +1,11 @@ +package ru.tinkoff.acquiring.sdk.payment.methods + +import ru.tinkoff.acquiring.sdk.responses.InitResponse +import ru.tinkoff.acquiring.sdk.utils.checkNotNull + +/** + * @author k.shpakovskiy + */ +fun InitResponse.requiredPaymentId(): Long { + return paymentId.checkNotNull { "paymentId must be not null" } +} diff --git a/ui/src/main/java/ru/tinkoff/acquiring/sdk/payment/methods/MirPayMethods.kt b/ui/src/main/java/ru/tinkoff/acquiring/sdk/payment/methods/MirPayMethods.kt index c8d75291..8f7957f9 100644 --- a/ui/src/main/java/ru/tinkoff/acquiring/sdk/payment/methods/MirPayMethods.kt +++ b/ui/src/main/java/ru/tinkoff/acquiring/sdk/payment/methods/MirPayMethods.kt @@ -19,9 +19,9 @@ internal class MirPayMethodsImpl( ) : MirPayMethods { override suspend fun init(paymentOptions: PaymentOptions): Long { - return checkNotNull( - acquiringSdk.configureInit(paymentOptions).execute().paymentId - ) + return acquiringSdk.configureInit(paymentOptions) + .execute() + .requiredPaymentId() } override suspend fun getLink(paymentId: Long): String { diff --git a/ui/src/main/java/ru/tinkoff/acquiring/sdk/payment/methods/TpayMethods.kt b/ui/src/main/java/ru/tinkoff/acquiring/sdk/payment/methods/TpayMethods.kt index e51bae24..e5418181 100644 --- a/ui/src/main/java/ru/tinkoff/acquiring/sdk/payment/methods/TpayMethods.kt +++ b/ui/src/main/java/ru/tinkoff/acquiring/sdk/payment/methods/TpayMethods.kt @@ -23,7 +23,7 @@ internal class GetTpayLinkMethodsSdkImpl( override suspend fun init( paymentOptions: PaymentOptions ): Long { - return checkNotNull(acquiringSdk.configureInit(paymentOptions).execute().paymentId) + return acquiringSdk.configureInit(paymentOptions).execute().requiredPaymentId() } override suspend fun tinkoffPayLink(paymentId: Long, version: String): String { diff --git a/ui/src/main/java/ru/tinkoff/acquiring/sdk/redesign/mainform/MainFormLauncher.kt b/ui/src/main/java/ru/tinkoff/acquiring/sdk/redesign/mainform/MainFormLauncher.kt index 27b3c447..5a473719 100644 --- a/ui/src/main/java/ru/tinkoff/acquiring/sdk/redesign/mainform/MainFormLauncher.kt +++ b/ui/src/main/java/ru/tinkoff/acquiring/sdk/redesign/mainform/MainFormLauncher.kt @@ -35,14 +35,14 @@ object MainFormLauncher { } @Parcelize - class StartData( - val paymentOptions: PaymentOptions, - val paymentId: Int? = null - ) : Parcelable + class StartData(val paymentOptions: PaymentOptions) : Parcelable object Contract : ActivityResultContract() { override fun createIntent(context: Context, input: StartData) = - MainPaymentFormActivity.intent(input.paymentOptions, context) + MainPaymentFormActivity.intent( + context = context, + options = input.paymentOptions + ) override fun parseResult(resultCode: Int, intent: Intent?): Result = when (resultCode) { RESULT_OK -> { diff --git a/ui/src/main/java/ru/tinkoff/acquiring/sdk/redesign/mainform/ui/MainPaymentFormActivity.kt b/ui/src/main/java/ru/tinkoff/acquiring/sdk/redesign/mainform/ui/MainPaymentFormActivity.kt index 0487de65..94fae679 100644 --- a/ui/src/main/java/ru/tinkoff/acquiring/sdk/redesign/mainform/ui/MainPaymentFormActivity.kt +++ b/ui/src/main/java/ru/tinkoff/acquiring/sdk/redesign/mainform/ui/MainPaymentFormActivity.kt @@ -419,7 +419,10 @@ internal class MainPaymentFormActivity : AppCompatActivity() { } internal companion object { - fun intent(options: PaymentOptions, context: Context): Intent { + fun intent( + context: Context, + options: PaymentOptions, + ): Intent { val intent = Intent(context, MainPaymentFormActivity::class.java) intent.putOptions(options) return intent diff --git a/ui/src/main/java/ru/tinkoff/acquiring/sdk/redesign/mirpay/MirPayLauncher.kt b/ui/src/main/java/ru/tinkoff/acquiring/sdk/redesign/mirpay/MirPayLauncher.kt index 5b755eee..d5097ec1 100644 --- a/ui/src/main/java/ru/tinkoff/acquiring/sdk/redesign/mirpay/MirPayLauncher.kt +++ b/ui/src/main/java/ru/tinkoff/acquiring/sdk/redesign/mirpay/MirPayLauncher.kt @@ -42,10 +42,7 @@ object MirPayLauncher { ) : Result(), AcqPaymentResult.Error, java.io.Serializable @Parcelize - class StartData( - val paymentOptions: PaymentOptions, - val paymentId: Long? = null - ) : Parcelable + class StartData(val paymentOptions: PaymentOptions) : Parcelable object Contract : ActivityResultContract () { diff --git a/ui/src/main/java/ru/tinkoff/acquiring/sdk/redesign/mirpay/presentation/MirPayViewModel.kt b/ui/src/main/java/ru/tinkoff/acquiring/sdk/redesign/mirpay/presentation/MirPayViewModel.kt index deccc95d..c46c61be 100644 --- a/ui/src/main/java/ru/tinkoff/acquiring/sdk/redesign/mirpay/presentation/MirPayViewModel.kt +++ b/ui/src/main/java/ru/tinkoff/acquiring/sdk/redesign/mirpay/presentation/MirPayViewModel.kt @@ -11,6 +11,7 @@ import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.mapNotNull import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.launch +import kotlinx.coroutines.processNextEventInCurrentThread import ru.tinkoff.acquiring.sdk.TinkoffAcquiring import ru.tinkoff.acquiring.sdk.models.options.screen.PaymentOptions import ru.tinkoff.acquiring.sdk.payment.MirPayProcess @@ -42,10 +43,7 @@ internal class MirPayViewModel( } fun pay() { - mirPayProcess.start( - paymentOptions = startData.paymentOptions, - paymentId = startData.paymentId - ) + mirPayProcess.start(paymentOptions = startData.paymentOptions) } fun goingToBankApp() { @@ -64,6 +62,11 @@ internal class MirPayViewModel( } } + override fun onCleared() { + mirPayProcess.stop() + super.onCleared() + } + companion object { fun factory(application: Application, paymentOptions: PaymentOptions) = viewModelFactory { val acq = TinkoffAcquiring( diff --git a/ui/src/main/java/ru/tinkoff/acquiring/sdk/redesign/mirpay/ui/MirPayFlowActivity.kt b/ui/src/main/java/ru/tinkoff/acquiring/sdk/redesign/mirpay/ui/MirPayFlowActivity.kt index 17233ff3..fbbf0349 100644 --- a/ui/src/main/java/ru/tinkoff/acquiring/sdk/redesign/mirpay/ui/MirPayFlowActivity.kt +++ b/ui/src/main/java/ru/tinkoff/acquiring/sdk/redesign/mirpay/ui/MirPayFlowActivity.kt @@ -10,7 +10,6 @@ import androidx.lifecycle.lifecycleScope import androidx.lifecycle.whenResumed import kotlinx.coroutines.flow.collectLatest import kotlinx.coroutines.launch -import ru.tinkoff.acquiring.sdk.TinkoffAcquiring import ru.tinkoff.acquiring.sdk.databinding.AcqMirPayActivityBinding import ru.tinkoff.acquiring.sdk.redesign.common.LauncherConstants.EXTRA_CARD_ID import ru.tinkoff.acquiring.sdk.redesign.common.LauncherConstants.EXTRA_ERROR diff --git a/ui/src/main/java/ru/tinkoff/acquiring/sdk/redesign/payment/PaymentByCardLauncher.kt b/ui/src/main/java/ru/tinkoff/acquiring/sdk/redesign/payment/PaymentByCardLauncher.kt index 205d8133..7b3861f6 100644 --- a/ui/src/main/java/ru/tinkoff/acquiring/sdk/redesign/payment/PaymentByCardLauncher.kt +++ b/ui/src/main/java/ru/tinkoff/acquiring/sdk/redesign/payment/PaymentByCardLauncher.kt @@ -4,15 +4,12 @@ import android.content.Context import android.content.Intent import android.os.Parcelable import androidx.activity.result.contract.ActivityResultContract -import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity.RESULT_OK import kotlinx.android.parcel.Parcelize -import ru.tinkoff.acquiring.sdk.TinkoffAcquiring import ru.tinkoff.acquiring.sdk.models.Card import ru.tinkoff.acquiring.sdk.models.options.screen.PaymentOptions import ru.tinkoff.acquiring.sdk.models.result.PaymentResult import ru.tinkoff.acquiring.sdk.redesign.common.LauncherConstants.EXTRA_CARD_ID -import ru.tinkoff.acquiring.sdk.redesign.common.LauncherConstants.EXTRA_ERROR import ru.tinkoff.acquiring.sdk.redesign.common.LauncherConstants.EXTRA_PAYMENT_ID import ru.tinkoff.acquiring.sdk.redesign.common.LauncherConstants.EXTRA_REBILL_ID import ru.tinkoff.acquiring.sdk.redesign.common.LauncherConstants.EXTRA_SAVED_CARDS @@ -20,7 +17,6 @@ import ru.tinkoff.acquiring.sdk.redesign.common.LauncherConstants.RESULT_ERROR import ru.tinkoff.acquiring.sdk.redesign.common.result.AcqPaymentResult import ru.tinkoff.acquiring.sdk.redesign.payment.ui.PaymentByCardActivity import ru.tinkoff.acquiring.sdk.utils.getError -import ru.tinkoff.acquiring.sdk.utils.getExtra object PaymentByCardLauncher { @@ -40,7 +36,7 @@ object PaymentByCardLauncher { @Parcelize class StartData( val paymentOptions: PaymentOptions, - val list: ArrayList, + val cards: ArrayList, val withArrowBack: Boolean = false ) : Parcelable @@ -54,9 +50,9 @@ object PaymentByCardLauncher { return intent } - override fun createIntent(context: Context, startData: StartData): Intent = + override fun createIntent(context: Context, input: StartData): Intent = Intent(context, PaymentByCardActivity::class.java).apply { - putExtra(EXTRA_SAVED_CARDS, startData) + putExtra(EXTRA_SAVED_CARDS, input) } override fun parseResult(resultCode: Int, intent: Intent?): Result = when (resultCode) { diff --git a/ui/src/main/java/ru/tinkoff/acquiring/sdk/redesign/payment/ui/PaymentByCardViewModel.kt b/ui/src/main/java/ru/tinkoff/acquiring/sdk/redesign/payment/ui/PaymentByCardViewModel.kt index 5317ae66..5406db5c 100644 --- a/ui/src/main/java/ru/tinkoff/acquiring/sdk/redesign/payment/ui/PaymentByCardViewModel.kt +++ b/ui/src/main/java/ru/tinkoff/acquiring/sdk/redesign/payment/ui/PaymentByCardViewModel.kt @@ -29,7 +29,7 @@ internal class PaymentByCardViewModel( private val startData = savedStateHandle.get(EXTRA_SAVED_CARDS)!! - private val chosenCard = startData.list.firstOrNull { it.status == CardStatus.ACTIVE }?.let { + private val chosenCard = startData.cards.firstOrNull { it.status == CardStatus.ACTIVE }?.let { CardChosenModel(it, bankCaptionProvider(it.pan!!)) } diff --git a/ui/src/main/java/ru/tinkoff/acquiring/sdk/redesign/sbp/SbpPayLauncher.kt b/ui/src/main/java/ru/tinkoff/acquiring/sdk/redesign/sbp/SbpPayLauncher.kt index 10a01b45..5d2630d0 100644 --- a/ui/src/main/java/ru/tinkoff/acquiring/sdk/redesign/sbp/SbpPayLauncher.kt +++ b/ui/src/main/java/ru/tinkoff/acquiring/sdk/redesign/sbp/SbpPayLauncher.kt @@ -24,16 +24,7 @@ object SbpPayLauncher { class NoBanks : Result() @Parcelize - class StartData private constructor( - val paymentOptions: PaymentOptions, val paymentId: Long? - ) : Parcelable { - - // для обычного платежа - constructor(paymentOptions: PaymentOptions) : this(paymentOptions, null) - - // если вызов init был на стороне вашего сервера - constructor(paymentId: Long, paymentOptions: PaymentOptions) : this(paymentOptions, paymentId) - } + class StartData(val paymentOptions: PaymentOptions) : Parcelable object Contract: ActivityResultContract() { internal const val SBP_BANK_RESULT_CODE_NO_BANKS = 501 diff --git a/ui/src/main/java/ru/tinkoff/acquiring/sdk/redesign/sbp/ui/SbpPaymentActivity.kt b/ui/src/main/java/ru/tinkoff/acquiring/sdk/redesign/sbp/ui/SbpPaymentActivity.kt index 2ad75104..212fee3e 100644 --- a/ui/src/main/java/ru/tinkoff/acquiring/sdk/redesign/sbp/ui/SbpPaymentActivity.kt +++ b/ui/src/main/java/ru/tinkoff/acquiring/sdk/redesign/sbp/ui/SbpPaymentActivity.kt @@ -79,7 +79,7 @@ internal class SbpPaymentActivity : AppCompatActivity(), OnPaymentSheetCloseList setContentView(R.layout.acq_activity_bank_list) if (savedInstanceState == null) { - viewModel.loadData(startData.paymentOptions, startData.paymentId) + viewModel.loadData(startData.paymentOptions) } initToolbar() @@ -161,7 +161,7 @@ internal class SbpPaymentActivity : AppCompatActivity(), OnPaymentSheetCloseList buttonTextRes = R.string.acq_generic_button_stubnet ) stubButtonView.setOnClickListener { - viewModel.loadData(startData.paymentOptions, startData.paymentId) + viewModel.loadData(startData.paymentOptions) } } is SpbBankListState.Empty -> { diff --git a/ui/src/main/java/ru/tinkoff/acquiring/sdk/redesign/sbp/ui/SbpPaymentViewModel.kt b/ui/src/main/java/ru/tinkoff/acquiring/sdk/redesign/sbp/ui/SbpPaymentViewModel.kt index 8129e1c0..c5c81e02 100644 --- a/ui/src/main/java/ru/tinkoff/acquiring/sdk/redesign/sbp/ui/SbpPaymentViewModel.kt +++ b/ui/src/main/java/ru/tinkoff/acquiring/sdk/redesign/sbp/ui/SbpPaymentViewModel.kt @@ -32,13 +32,13 @@ internal class SbpPaymentViewModel( } } - fun loadData(paymentOptions: PaymentOptions, paymentId: Long?) { + fun loadData(paymentOptions: PaymentOptions) { if (connectionChecker.isOnline().not()) { stateUiFlow.value = SpbBankListState.NoNetwork return } stateUiFlow.value = SpbBankListState.Shimmer - sbpPaymentProcess.start(paymentOptions, paymentId) + sbpPaymentProcess.start(paymentOptions) } fun onGoingToBankApp() { diff --git a/ui/src/main/java/ru/tinkoff/acquiring/sdk/redesign/tpay/TpayLauncher.kt b/ui/src/main/java/ru/tinkoff/acquiring/sdk/redesign/tpay/TpayLauncher.kt index 00a63da8..f6dec16c 100644 --- a/ui/src/main/java/ru/tinkoff/acquiring/sdk/redesign/tpay/TpayLauncher.kt +++ b/ui/src/main/java/ru/tinkoff/acquiring/sdk/redesign/tpay/TpayLauncher.kt @@ -63,7 +63,6 @@ object TpayLauncher { class StartData( val paymentOptions: PaymentOptions, val version: String, - val paymentId: Long? = null ) : Parcelable object Contract : ActivityResultContract() { diff --git a/ui/src/main/java/ru/tinkoff/acquiring/sdk/redesign/tpay/presentation/TpayViewModel.kt b/ui/src/main/java/ru/tinkoff/acquiring/sdk/redesign/tpay/presentation/TpayViewModel.kt index ae1443a9..682ae17e 100644 --- a/ui/src/main/java/ru/tinkoff/acquiring/sdk/redesign/tpay/presentation/TpayViewModel.kt +++ b/ui/src/main/java/ru/tinkoff/acquiring/sdk/redesign/tpay/presentation/TpayViewModel.kt @@ -40,7 +40,6 @@ internal class TpayViewModel( tpayProcess.start( paymentOptions = startData.paymentOptions, tpayVersion = startData.version, - paymentId = startData.paymentId ) } @@ -60,6 +59,11 @@ internal class TpayViewModel( } } + override fun onCleared() { + tpayProcess.stop() + super.onCleared() + } + companion object { fun factory(application: Application, paymentOptions: PaymentOptions) = viewModelFactory { val acq = TinkoffAcquiring( diff --git a/ui/src/main/java/ru/tinkoff/acquiring/sdk/viewmodel/AttachCardViewModel.kt b/ui/src/main/java/ru/tinkoff/acquiring/sdk/viewmodel/AttachCardViewModel.kt index ad955aac..85afdadd 100644 --- a/ui/src/main/java/ru/tinkoff/acquiring/sdk/viewmodel/AttachCardViewModel.kt +++ b/ui/src/main/java/ru/tinkoff/acquiring/sdk/viewmodel/AttachCardViewModel.kt @@ -67,10 +67,13 @@ internal class AttachCardViewModel( this.checkType = checkType } - coroutine.call(addCardRequest, + coroutine + .call( + request = addCardRequest, onSuccess = { check3dsVersionIfNeed(cardData, it.paymentId, it.requestKey!!,data) - }) + } + ) } fun submitRandomAmount(requestKey: String, amount: Long) { diff --git a/ui/src/test/java/ru/tinkoff/acquiring/sdk/payment/TpayProcessTest.kt b/ui/src/test/java/ru/tinkoff/acquiring/sdk/payment/TpayProcessTest.kt index 3af93d8b..cf631e79 100644 --- a/ui/src/test/java/ru/tinkoff/acquiring/sdk/payment/TpayProcessTest.kt +++ b/ui/src/test/java/ru/tinkoff/acquiring/sdk/payment/TpayProcessTest.kt @@ -13,12 +13,11 @@ import ru.tinkoff.acquiring.sdk.payment.pooling.GetStatusPooling class TpayProcessTest { @Test - fun `test recreate process`() { + fun `test standart flow process`() { TpayProcessEnv().runWithEnv( given = { setInitAndLingResult(defaultPaymentId) }, `when` = { - tpayProcess.stop() - tpayProcess.start(PaymentOptions(), versionTpay, defaultPaymentId) + tpayProcess.start(PaymentOptions(), versionTpay) }, then = { assertByClassName( @@ -34,10 +33,16 @@ class TpayProcessTest { TpayProcessEnv().runWithEnv( given = {}, `when` = { - tpayProcess.start(PaymentOptions(), versionTpay, defaultPaymentId) - assertByClassName(TpayPaymentState.PaymentFailed(defaultPaymentId,IllegalStateException()), tpayProcess.state.value) + tpayProcess.start(PaymentOptions(), versionTpay) + assertByClassName( + TpayPaymentState.PaymentFailed( + defaultPaymentId, + IllegalStateException() + ), + tpayProcess.state.value + ) setInitAndLingResult(defaultPaymentId) - tpayProcess.start(PaymentOptions(), versionTpay, defaultPaymentId) + tpayProcess.start(PaymentOptions(), versionTpay) }, then = { assertByClassName(TpayPaymentState.NeedChooseOnUi(defaultPaymentId,deeplink), tpayProcess.state.value) @@ -72,4 +77,4 @@ internal fun TpayProcessEnv.runWithEnv( launch { `when`.invoke(this@runWithEnv) }.join() launch { then.invoke(this@runWithEnv) }.join() } -} \ No newline at end of file +}