PayByCardForm3DSViewModel.kt 5.56 KB
Newer Older
1
2
3
4
package com.trustpayments.mobile.exampleapp.presentation

import android.app.Activity
import android.app.Application
Jakub Gugala's avatar
Jakub Gugala committed
5
import android.content.SharedPreferences
6
7
8
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.viewModelScope
9
import com.trustpayments.mobile.core.models.api.response.RequestType
10
import com.trustpayments.mobile.core.services.api.TrustPaymentsGatewayType
11
import com.trustpayments.mobile.core.services.transaction.ActivityResultProvider
12
import com.trustpayments.mobile.core.services.transaction.Error
13
import com.trustpayments.mobile.core.services.transaction.PaymentTransactionManager
14
import com.trustpayments.mobile.core.ui.ThreeDSecureWebActivityResult
15
import com.trustpayments.mobile.core.util.ResponseParser
16
import com.trustpayments.mobile.exampleapp.BuildConfig
17
import com.trustpayments.mobile.exampleapp.presentation.base.BaseViewModel
18
import com.trustpayments.mobile.exampleapp.presentation.model.ViewActionPayByCardForm3DS
Jakub Gugala's avatar
Jakub Gugala committed
19
import com.trustpayments.mobile.exampleapp.utils.Event
20
import com.trustpayments.mobile.exampleapp.utils.StandardTPPayload
Jakub Gugala's avatar
Jakub Gugala committed
21
22
23
import com.trustpayments.mobile.exampleapp.utils.ThemeHelper
import com.trustpayments.mobile.exampleapp.utils.errorMessage
import com.trustpayments.mobile.ui.model.PaymentInputType
24
25
26
27
28
29
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
import javax.inject.Inject
import kotlin.coroutines.Continuation
import kotlin.coroutines.suspendCoroutine

Jakub Gugala's avatar
Jakub Gugala committed
30
31
32
33
class PayByCardForm3DSViewModel @Inject constructor(
    app: Application,
    private val sharedPreferences: SharedPreferences
) : BaseViewModel(app) {
34
35
36
37
38
39
40
41
42
43
44
45

    private val _viewActions = MutableLiveData<Event<ViewActionPayByCardForm3DS>>()

    val viewActions: LiveData<Event<ViewActionPayByCardForm3DS>>
        get() = _viewActions

    val activityRequest = MutableLiveData<Continuation<Activity>>()

    private var PAN = ""
    private var expiryDate = ""
    private var CVV = ""

46
    private var currentActivityResultProvider: ActivityResultProvider? = null
47

48
    private val paymentTransactionManager =
49
        PaymentTransactionManager(app, TrustPaymentsGatewayType.EU, false, BuildConfig.MERCHANT_USERNAME)
50

51
52
53
    //please note that this session is created on page init intentionally
    private val paymentSession = paymentTransactionManager.createSession({buildToken()})

54
    private fun buildToken(): String {
55
56
        val claimPayload =
            StandardTPPayload(
57
58
59
60
                BuildConfig.SITE_REFERENCE,
                "GBP",
                1050,
                listOf(
61
62
                    RequestType.ThreeDQuery,
                    RequestType.Auth
63
                )
64
            )
65

66
67
        return buildJWT(BuildConfig.MERCHANT_USERNAME, claimPayload)
    }
68

69
    fun onActivityClosed(result: ThreeDSecureWebActivityResult) {
70
        currentActivityResultProvider?.result = result
71
72
    }

73
74
75
    fun onPayButtonClicked() {
        _isProgressDialogVisible.value = true

Jakub Gugala's avatar
Jakub Gugala committed
76
77
        paymentTransactionManager.isDarkThemeForced = getFromThemeSettings()

78
79
80
81
        viewModelScope.launch {
            trigger3DSAndAuthRequest()
        }
    }
82

83
84
85
86
    private suspend fun trigger3DSAndAuthRequest() {
        paymentSession.cardPan = PAN
        paymentSession.cardExpiryDate = expiryDate
        paymentSession.cardSecurityCode = CVV
87

88
        currentActivityResultProvider = ActivityResultProvider()
89
        val result = paymentTransactionManager.executeSession(paymentSession,
90
91
92
93
            {
                runBlocking {
                    requireActivity()
                }
94
            }, currentActivityResultProvider)
95
96
97
98
99
100
101
102
103

        _isProgressDialogVisible.value = false
        processResult(result)
    }

    private suspend fun requireActivity() = suspendCoroutine<Activity> { continuation ->
        activityRequest.value = continuation
    }

104
105
106
107
108
109
    private fun processResult(result: PaymentTransactionManager.Response) {
        if (result.error != null) {
            when (val error = result.error) {
                is Error.InitializationFailure -> {
                    val parsedResponse = ResponseParser.parse(error.jwt)
                    displayError(parsedResponse?.responses?.first()?.errorMessage)
110
                }
111
112
                is Error.SafetyError -> displayError(error.errorMessage(app))
                is Error.ThreeDSFailure -> _viewActions.value = Event(ViewActionPayByCardForm3DS.ShowTransactionFailedCardinalErrorDialog())
113
                else -> displayError()
114
            }
115
116
117
118
119
120
121
122
            return
        }

        val evaluationError = evaluateResponse(result, app)
        if (evaluationError != null) {
            displayError(evaluationError)
        } else {
            _viewActions.value = Event(ViewActionPayByCardForm3DS.ShowTransactionSuccessfulDialog())
123
124
125
        }
    }

126
127
128
129
    private fun displayError(errorMessage: String? = null) {
        if(errorMessage != null) {
            _viewActions.value = Event(ViewActionPayByCardForm3DS.ShowTransactionFailedDialog(errorMessage))
        } else {
130
            _viewActions.value = Event(ViewActionPayByCardForm3DS.ShowTransactionFailedParsingErrorDialog())
131
132
133
134
135
136
137
138
139
140
        }
    }

    fun updateCardData(paymentInputType: PaymentInputType, input: String) {
        when (paymentInputType) {
            PaymentInputType.PAN -> PAN = input
            PaymentInputType.ExpiryDate -> expiryDate = input
            PaymentInputType.CVV -> CVV = input
        }
    }
Jakub Gugala's avatar
Jakub Gugala committed
141
142
143
144
145
146
147

    private fun getFromThemeSettings(): Boolean? =
        when(sharedPreferences.getString(ThemeHelper.KEY_THEME, ThemeHelper.DEFAULT_MODE)) {
            ThemeHelper.DARK_MODE -> true
            ThemeHelper.LIGHT_MODE -> false
            else -> null
        }
148
}