1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
|
package net.taler.wallet.payment
import android.util.Log
import androidx.annotation.UiThread
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import net.taler.wallet.Amount
import net.taler.wallet.TAG
import net.taler.wallet.backend.WalletBackendApi
import org.json.JSONObject
class PaymentManager(private val walletBackendApi: WalletBackendApi) {
private val mPayStatus = MutableLiveData<PayStatus>(PayStatus.None)
internal val payStatus: LiveData<PayStatus> = mPayStatus
private var currentPayRequestId = 0
@UiThread
fun preparePay(url: String) {
mPayStatus.value = PayStatus.Loading
val args = JSONObject(mapOf("url" to url))
currentPayRequestId += 1
val payRequestId = currentPayRequestId
walletBackendApi.sendRequest("preparePay", args) { isError, result ->
when {
isError -> {
Log.v(TAG, "got preparePay error result")
mPayStatus.value = PayStatus.Error(result.toString())
}
payRequestId != this.currentPayRequestId -> {
Log.v(TAG, "preparePay result was for old request")
}
else -> {
val status = result.getString("status")
mPayStatus.postValue(getPayStatusUpdate(status, result))
}
}
}
}
private fun getPayStatusUpdate(status: String, json: JSONObject) = when (status) {
"payment-possible" -> PayStatus.Prepared(
contractTerms = getContractTerms(json),
proposalId = json.getString("proposalId"),
totalFees = Amount.fromJson(json.getJSONObject("totalFees"))
)
"paid" -> PayStatus.AlreadyPaid(getContractTerms(json))
"insufficient-balance" -> PayStatus.InsufficientBalance(getContractTerms(json))
"error" -> PayStatus.Error("got some error")
else -> PayStatus.Error("unknown status")
}
private fun getContractTerms(json: JSONObject): ContractTerms {
val ctJson = JSONObject(json.getString("contractTermsRaw"))
val amount = Amount.fromString(ctJson.getString("amount"))
val summary = ctJson.getString("summary")
return ContractTerms(summary, amount)
}
fun confirmPay(proposalId: String) {
val args = JSONObject(mapOf("proposalId" to proposalId))
walletBackendApi.sendRequest("confirmPay", args) { _, _ ->
mPayStatus.postValue(PayStatus.Success)
}
}
fun abortProposal(proposalId: String) {
val args = JSONObject(mapOf("proposalId" to proposalId))
Log.i(TAG, "aborting proposal")
walletBackendApi.sendRequest("abortProposal", args) { isError, _ ->
if (isError) {
Log.e(TAG, "received error response to abortProposal")
return@sendRequest
}
mPayStatus.postValue(PayStatus.None)
}
}
@UiThread
fun resetPayStatus() {
mPayStatus.value = PayStatus.None
}
}
sealed class PayStatus {
object None : PayStatus()
object Loading : PayStatus()
data class Prepared(
val contractTerms: ContractTerms,
val proposalId: String,
val totalFees: Amount
) : PayStatus()
data class InsufficientBalance(val contractTerms: ContractTerms) : PayStatus()
data class AlreadyPaid(val contractTerms: ContractTerms) : PayStatus()
data class Error(val error: String) : PayStatus()
object Success : PayStatus()
}
data class ContractTerms(val summary: String, val amount: Amount)
|