gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[taler-taler-android] 01/04: [pos] adapt history to new v1 API


From: gnunet
Subject: [taler-taler-android] 01/04: [pos] adapt history to new v1 API
Date: Thu, 30 Jul 2020 22:12:21 +0200

This is an automated email from the git hooks/post-receive script.

torsten-grote pushed a commit to branch master
in repository taler-android.

commit bc35e8924e652c323001f62f6781657545fa378f
Author: Torsten Grote <t@grobox.de>
AuthorDate: Tue Jul 28 17:16:57 2020 -0300

    [pos] adapt history to new v1 API
---
 .../main/java/net/taler/merchantlib/MerchantApi.kt | 19 ++++---
 .../java/net/taler/merchantlib/MerchantConfig.kt   |  2 +-
 .../{MerchantConfig.kt => OrderHistory.kt}         | 40 ++++++++------
 .../java/net/taler/merchantlib/PostOrderRequest.kt |  6 +--
 .../main/java/net/taler/merchantlib/Response.kt    |  7 ++-
 merchant-terminal/build.gradle                     |  3 --
 .../java/net/taler/merchantpos/MainViewModel.kt    |  8 +--
 .../taler/merchantpos/history/HistoryManager.kt    | 62 ++++++----------------
 .../merchantpos/history/MerchantHistoryFragment.kt | 34 +++++++-----
 .../taler/merchantpos/history/RefundFragment.kt    |  3 +-
 .../net/taler/merchantpos/history/RefundManager.kt | 11 ++--
 .../main/java/net/taler/common/ContractTerms.kt    |  2 +
 12 files changed, 91 insertions(+), 106 deletions(-)

diff --git a/merchant-lib/src/main/java/net/taler/merchantlib/MerchantApi.kt 
b/merchant-lib/src/main/java/net/taler/merchantlib/MerchantApi.kt
index e995724..db37586 100644
--- a/merchant-lib/src/main/java/net/taler/merchantlib/MerchantApi.kt
+++ b/merchant-lib/src/main/java/net/taler/merchantlib/MerchantApi.kt
@@ -16,7 +16,6 @@
 
 package net.taler.merchantlib
 
-import android.util.Log
 import io.ktor.client.HttpClient
 import io.ktor.client.engine.okhttp.OkHttp
 import io.ktor.client.features.json.JsonFeature
@@ -25,8 +24,6 @@ import io.ktor.client.request.delete
 import io.ktor.client.request.get
 import io.ktor.client.request.header
 import io.ktor.client.request.post
-import io.ktor.client.statement.HttpResponse
-import io.ktor.client.statement.readBytes
 import io.ktor.http.ContentType.Application.Json
 import io.ktor.http.HttpHeaders.Authorization
 import io.ktor.http.contentType
@@ -64,14 +61,16 @@ class MerchantApi(private val httpClient: HttpClient) {
     suspend fun deleteOrder(
         merchantConfig: MerchantConfig,
         orderId: String
-    ): Response<HttpResponse> = response {
-        val resp = 
httpClient.delete(merchantConfig.urlFor("private/orders/$orderId")) {
+    ): Response<Unit> = response {
+        httpClient.delete(merchantConfig.urlFor("private/orders/$orderId")) {
             header(Authorization, "ApiKey ${merchantConfig.apiKey}")
-        } as HttpResponse
-        // TODO remove when the API call was fixed
-        Log.e("TEST", "status: ${resp.status.value}")
-        Log.e("TEST", String(resp.readBytes()))
-        resp
+        } as Unit
+    }
+
+    suspend fun getOrderHistory(merchantConfig: MerchantConfig): 
Response<OrderHistory> = response {
+        httpClient.get(merchantConfig.urlFor("private/orders")) {
+            header(Authorization, "ApiKey ${merchantConfig.apiKey}")
+        } as OrderHistory
     }
 
 }
diff --git a/merchant-lib/src/main/java/net/taler/merchantlib/MerchantConfig.kt 
b/merchant-lib/src/main/java/net/taler/merchantlib/MerchantConfig.kt
index a01624e..a8d113e 100644
--- a/merchant-lib/src/main/java/net/taler/merchantlib/MerchantConfig.kt
+++ b/merchant-lib/src/main/java/net/taler/merchantlib/MerchantConfig.kt
@@ -31,7 +31,7 @@ data class MerchantConfig(
     fun urlFor(endpoint: String): String {
         val sb = StringBuilder(baseUrl)
         if (sb.last() != '/') sb.append('/')
-        sb.append("instances/$instance/")
+        instance?.let { sb.append("instances/$it/") }
         sb.append(endpoint)
         return sb.toString()
     }
diff --git a/merchant-lib/src/main/java/net/taler/merchantlib/MerchantConfig.kt 
b/merchant-lib/src/main/java/net/taler/merchantlib/OrderHistory.kt
similarity index 59%
copy from merchant-lib/src/main/java/net/taler/merchantlib/MerchantConfig.kt
copy to merchant-lib/src/main/java/net/taler/merchantlib/OrderHistory.kt
index a01624e..718bde5 100644
--- a/merchant-lib/src/main/java/net/taler/merchantlib/MerchantConfig.kt
+++ b/merchant-lib/src/main/java/net/taler/merchantlib/OrderHistory.kt
@@ -18,21 +18,29 @@ package net.taler.merchantlib
 
 import kotlinx.serialization.SerialName
 import kotlinx.serialization.Serializable
+import net.taler.common.Amount
+import net.taler.common.Timestamp
 
 @Serializable
-data class MerchantConfig(
-    @SerialName("base_url")
-    val baseUrl: String,
-    // TODO remove instance when it is part of baseURL
-    val instance: String? = null,
-    @SerialName("api_key")
-    val apiKey: String
-) {
-    fun urlFor(endpoint: String): String {
-        val sb = StringBuilder(baseUrl)
-        if (sb.last() != '/') sb.append('/')
-        sb.append("instances/$instance/")
-        sb.append(endpoint)
-        return sb.toString()
-    }
-}
+data class OrderHistory(
+    val orders: List<OrderHistoryEntry>
+)
+
+@Serializable
+data class OrderHistoryEntry(
+    // order ID of the transaction related to this entry.
+    @SerialName("order_id")
+    val orderId: String,
+
+    // when the order was created
+    val timestamp: Timestamp,
+
+    // the amount of money the order is for
+    val amount: Amount,
+
+    // the summary of the order
+    val summary: String,
+
+    // whether some part of the order is refundable
+    val refundable: Boolean
+)
diff --git 
a/merchant-lib/src/main/java/net/taler/merchantlib/PostOrderRequest.kt 
b/merchant-lib/src/main/java/net/taler/merchantlib/PostOrderRequest.kt
index a6e74d6..4854a80 100644
--- a/merchant-lib/src/main/java/net/taler/merchantlib/PostOrderRequest.kt
+++ b/merchant-lib/src/main/java/net/taler/merchantlib/PostOrderRequest.kt
@@ -48,11 +48,11 @@ sealed class CheckPaymentResponse {
         override fun deserialize(decoder: Decoder): CheckPaymentResponse {
             val input = decoder as JsonInput
             val tree = input.decodeJson() as JsonObject
-            val paid = tree.getPrimitive("paid").boolean
-//            return if (paid) decoder.json.fromJson(Paid.serializer(), tree)
+            val orderStatus = tree.getPrimitive("order_status").content
+//            return if (orderStatus == "paid") 
decoder.json.fromJson(Paid.serializer(), tree)
 //            else decoder.json.fromJson(Unpaid.serializer(), tree)
             // manual parsing due to 
https://github.com/Kotlin/kotlinx.serialization/issues/576
-            return if (paid) Paid(
+            return if (orderStatus == "paid") Paid(
                 refunded = tree.getPrimitive("refunded").boolean
             ) else Unpaid(
                 talerPayUri = tree.getPrimitive("taler_pay_uri").content
diff --git a/merchant-lib/src/main/java/net/taler/merchantlib/Response.kt 
b/merchant-lib/src/main/java/net/taler/merchantlib/Response.kt
index 1b49d78..9aefa5f 100644
--- a/merchant-lib/src/main/java/net/taler/merchantlib/Response.kt
+++ b/merchant-lib/src/main/java/net/taler/merchantlib/Response.kt
@@ -16,8 +16,11 @@
 
 package net.taler.merchantlib
 
+import android.util.Log
 import io.ktor.client.call.receive
 import io.ktor.client.features.ClientRequestException
+import io.ktor.client.features.ResponseException
+import io.ktor.client.features.ServerResponseException
 import kotlinx.serialization.Serializable
 
 class Response<out T> private constructor(
@@ -29,6 +32,7 @@ class Response<out T> private constructor(
             return try {
                 success(request())
             } catch (e: Throwable) {
+                Log.e("merchant-lib", "Error", e)
                 failure(e)
             }
         }
@@ -63,10 +67,11 @@ class Response<out T> private constructor(
 
     private suspend fun getFailureString(failure: Failure): String = when 
(failure.exception) {
         is ClientRequestException -> getExceptionString(failure.exception)
+        is ServerResponseException -> getExceptionString(failure.exception)
         else -> failure.exception.toString()
     }
 
-    private suspend fun getExceptionString(e: ClientRequestException): String {
+    private suspend fun getExceptionString(e: ResponseException): String {
         return try {
             val error: Error = e.response.receive()
             "Error ${error.code}: ${error.hint}"
diff --git a/merchant-terminal/build.gradle b/merchant-terminal/build.gradle
index 1cec0c5..4499892 100644
--- a/merchant-terminal/build.gradle
+++ b/merchant-terminal/build.gradle
@@ -73,9 +73,6 @@ dependencies {
 
     implementation "androidx.swiperefreshlayout:swiperefreshlayout:1.1.0"
 
-    // JSON parsing and serialization
-    implementation "com.fasterxml.jackson.module:jackson-module-kotlin:2.10.2"
-
     testImplementation 'androidx.test.ext:junit:1.1.1'
     testImplementation 'org.robolectric:robolectric:4.3.1'
 }
diff --git 
a/merchant-terminal/src/main/java/net/taler/merchantpos/MainViewModel.kt 
b/merchant-terminal/src/main/java/net/taler/merchantpos/MainViewModel.kt
index b62c550..905738b 100644
--- a/merchant-terminal/src/main/java/net/taler/merchantpos/MainViewModel.kt
+++ b/merchant-terminal/src/main/java/net/taler/merchantpos/MainViewModel.kt
@@ -20,9 +20,6 @@ import android.app.Application
 import androidx.lifecycle.AndroidViewModel
 import androidx.lifecycle.viewModelScope
 import com.android.volley.toolbox.Volley
-import 
com.fasterxml.jackson.databind.DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES
-import com.fasterxml.jackson.databind.ObjectMapper
-import com.fasterxml.jackson.module.kotlin.KotlinModule
 import net.taler.merchantlib.MerchantApi
 import net.taler.merchantlib.getDefaultHttpClient
 import net.taler.merchantpos.config.ConfigManager
@@ -35,9 +32,6 @@ class MainViewModel(app: Application) : AndroidViewModel(app) 
{
 
     private val httpClient = getDefaultHttpClient()
     private val api = MerchantApi(httpClient)
-    private val mapper = ObjectMapper()
-        .registerModule(KotlinModule())
-        .configure(FAIL_ON_UNKNOWN_PROPERTIES, false)
     private val queue = Volley.newRequestQueue(app)
 
     val orderManager = OrderManager(app)
@@ -45,7 +39,7 @@ class MainViewModel(app: Application) : AndroidViewModel(app) 
{
         addConfigurationReceiver(orderManager)
     }
     val paymentManager = PaymentManager(app, configManager, viewModelScope, 
api)
-    val historyManager = HistoryManager(configManager, queue, mapper)
+    val historyManager = HistoryManager(configManager, viewModelScope, api)
     val refundManager = RefundManager(configManager, queue)
 
     override fun onCleared() {
diff --git 
a/merchant-terminal/src/main/java/net/taler/merchantpos/history/HistoryManager.kt
 
b/merchant-terminal/src/main/java/net/taler/merchantpos/history/HistoryManager.kt
index 24c7a0c..cb77096 100644
--- 
a/merchant-terminal/src/main/java/net/taler/merchantpos/history/HistoryManager.kt
+++ 
b/merchant-terminal/src/main/java/net/taler/merchantpos/history/HistoryManager.kt
@@ -19,40 +19,22 @@ package net.taler.merchantpos.history
 import androidx.annotation.UiThread
 import androidx.lifecycle.LiveData
 import androidx.lifecycle.MutableLiveData
-import com.android.volley.Request.Method.GET
-import com.android.volley.RequestQueue
-import com.android.volley.Response.Listener
-import com.fasterxml.jackson.annotation.JsonIgnore
-import com.fasterxml.jackson.annotation.JsonProperty
-import com.fasterxml.jackson.databind.ObjectMapper
-import com.fasterxml.jackson.module.kotlin.readValue
-import net.taler.common.Amount
-import net.taler.common.Timestamp
-import net.taler.merchantpos.LogErrorListener
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.launch
+import net.taler.merchantlib.MerchantApi
+import net.taler.merchantlib.OrderHistoryEntry
 import net.taler.merchantpos.config.ConfigManager
-import net.taler.merchantpos.config.MerchantRequest
-import org.json.JSONObject
-
-data class HistoryItem(
-    @JsonProperty("order_id")
-    val orderId: String,
-    val amount: Amount,
-    val summary: String,
-    val timestamp: Timestamp
-) {
-    @get:JsonIgnore
-    val time = timestamp.ms
-}
 
 sealed class HistoryResult {
-    object Error : HistoryResult()
-    class Success(val items: List<HistoryItem>) : HistoryResult()
+    class Error(val msg: String) : HistoryResult()
+    class Success(val items: List<OrderHistoryEntry>) : HistoryResult()
 }
 
 class HistoryManager(
     private val configManager: ConfigManager,
-    private val queue: RequestQueue,
-    private val mapper: ObjectMapper
+    private val scope: CoroutineScope,
+    private val api: MerchantApi
 ) {
 
     private val mIsLoading = MutableLiveData(false)
@@ -65,29 +47,17 @@ class HistoryManager(
     internal fun fetchHistory() {
         mIsLoading.value = true
         val merchantConfig = configManager.merchantConfig!!
-        val params = mapOf("instance" to merchantConfig.instance!!)
-        val req = MerchantRequest(GET, merchantConfig, "history", params, null,
-            Listener { onHistoryResponse(it) },
-            LogErrorListener { onHistoryError() })
-        queue.add(req)
-    }
-
-    @UiThread
-    private fun onHistoryResponse(body: JSONObject) {
-        mIsLoading.value = false
-        val items = arrayListOf<HistoryItem>()
-        val historyJson = body.getJSONArray("history")
-        for (i in 0 until historyJson.length()) {
-            val historyItem: HistoryItem = 
mapper.readValue(historyJson.getString(i))
-            items.add(historyItem)
+        scope.launch(Dispatchers.IO) {
+            api.getOrderHistory(merchantConfig).handle(::onHistoryError) {
+                mIsLoading.postValue(false)
+                mItems.postValue(HistoryResult.Success(it.orders))
+            }
         }
-        mItems.value = HistoryResult.Success(items)
     }
 
-    @UiThread
-    private fun onHistoryError() {
+    private fun onHistoryError(msg: String) = scope.launch(Dispatchers.Main) {
         mIsLoading.value = false
-        mItems.value = HistoryResult.Error
+        mItems.value = HistoryResult.Error(msg)
     }
 
 }
diff --git 
a/merchant-terminal/src/main/java/net/taler/merchantpos/history/MerchantHistoryFragment.kt
 
b/merchant-terminal/src/main/java/net/taler/merchantpos/history/MerchantHistoryFragment.kt
index 6da3dd2..25805dc 100644
--- 
a/merchant-terminal/src/main/java/net/taler/merchantpos/history/MerchantHistoryFragment.kt
+++ 
b/merchant-terminal/src/main/java/net/taler/merchantpos/history/MerchantHistoryFragment.kt
@@ -20,6 +20,8 @@ import android.os.Bundle
 import android.util.Log
 import android.view.LayoutInflater
 import android.view.View
+import android.view.View.GONE
+import android.view.View.VISIBLE
 import android.view.ViewGroup
 import android.widget.ImageButton
 import android.widget.TextView
@@ -31,21 +33,22 @@ import 
androidx.recyclerview.widget.DividerItemDecoration.VERTICAL
 import androidx.recyclerview.widget.LinearLayoutManager
 import androidx.recyclerview.widget.RecyclerView.Adapter
 import androidx.recyclerview.widget.RecyclerView.ViewHolder
-import com.google.android.material.snackbar.BaseTransientBottomBar.LENGTH_SHORT
+import com.google.android.material.snackbar.BaseTransientBottomBar.LENGTH_LONG
 import com.google.android.material.snackbar.Snackbar
 import kotlinx.android.synthetic.main.fragment_merchant_history.*
 import net.taler.common.exhaustive
 import net.taler.common.navigate
 import net.taler.common.toRelativeTime
+import net.taler.merchantlib.OrderHistoryEntry
 import net.taler.merchantpos.MainViewModel
 import net.taler.merchantpos.R
 import net.taler.merchantpos.history.HistoryItemAdapter.HistoryItemViewHolder
 import 
net.taler.merchantpos.history.MerchantHistoryFragmentDirections.Companion.actionGlobalMerchantSettings
 import 
net.taler.merchantpos.history.MerchantHistoryFragmentDirections.Companion.actionNavHistoryToRefundFragment
-import java.util.*
+import java.util.ArrayList
 
 private interface RefundClickListener {
-    fun onRefundClicked(item: HistoryItem)
+    fun onRefundClicked(item: OrderHistoryEntry)
 }
 
 /**
@@ -87,7 +90,7 @@ class MerchantHistoryFragment : Fragment(), 
RefundClickListener {
         })
         historyManager.items.observe(viewLifecycleOwner, Observer { result ->
             when (result) {
-                is HistoryResult.Error -> onError()
+                is HistoryResult.Error -> onError(result.msg)
                 is HistoryResult.Success -> 
historyListAdapter.setData(result.items)
             }.exhaustive
         })
@@ -95,18 +98,18 @@ class MerchantHistoryFragment : Fragment(), 
RefundClickListener {
 
     override fun onStart() {
         super.onStart()
-        if (model.configManager.merchantConfig?.instance == null) {
+        if (model.configManager.merchantConfig?.baseUrl == null) {
             navigate(actionGlobalMerchantSettings())
         } else {
             historyManager.fetchHistory()
         }
     }
 
-    private fun onError() {
-        Snackbar.make(requireView(), R.string.error_network, 
LENGTH_SHORT).show()
+    private fun onError(msg: String) {
+        Snackbar.make(requireView(), msg, LENGTH_LONG).show()
     }
 
-    override fun onRefundClicked(item: HistoryItem) {
+    override fun onRefundClicked(item: OrderHistoryEntry) {
         refundManager.startRefund(item)
         navigate(actionNavHistoryToRefundFragment())
     }
@@ -116,7 +119,7 @@ class MerchantHistoryFragment : Fragment(), 
RefundClickListener {
 private class HistoryItemAdapter(private val listener: RefundClickListener) :
     Adapter<HistoryItemViewHolder>() {
 
-    private val items = ArrayList<HistoryItem>()
+    private val items = ArrayList<OrderHistoryEntry>()
 
     override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): 
HistoryItemViewHolder {
         val v =
@@ -130,7 +133,7 @@ private class HistoryItemAdapter(private val listener: 
RefundClickListener) :
         holder.bind(items[position])
     }
 
-    fun setData(items: List<HistoryItem>) {
+    fun setData(items: List<OrderHistoryEntry>) {
         this.items.clear()
         this.items.addAll(items)
         this.notifyDataSetChanged()
@@ -144,13 +147,18 @@ private class HistoryItemAdapter(private val listener: 
RefundClickListener) :
         private val orderIdView: TextView = v.findViewById(R.id.orderIdView)
         private val refundButton: ImageButton = 
v.findViewById(R.id.refundButton)
 
-        fun bind(item: HistoryItem) {
+        fun bind(item: OrderHistoryEntry) {
             orderSummaryView.text = item.summary
             val amount = item.amount
             orderAmountView.text = amount.toString()
             orderIdView.text = v.context.getString(R.string.history_ref_no, 
item.orderId)
-            orderTimeView.text = item.time.toRelativeTime(v.context)
-            refundButton.setOnClickListener { listener.onRefundClicked(item) }
+            orderTimeView.text = item.timestamp.ms.toRelativeTime(v.context)
+            if (item.refundable) {
+                refundButton.visibility = VISIBLE
+                refundButton.setOnClickListener { 
listener.onRefundClicked(item) }
+            } else {
+                refundButton.visibility = GONE
+            }
         }
 
     }
diff --git 
a/merchant-terminal/src/main/java/net/taler/merchantpos/history/RefundFragment.kt
 
b/merchant-terminal/src/main/java/net/taler/merchantpos/history/RefundFragment.kt
index eb3d46d..17d78f6 100644
--- 
a/merchant-terminal/src/main/java/net/taler/merchantpos/history/RefundFragment.kt
+++ 
b/merchant-terminal/src/main/java/net/taler/merchantpos/history/RefundFragment.kt
@@ -33,6 +33,7 @@ import net.taler.common.AmountParserException
 import net.taler.common.fadeIn
 import net.taler.common.fadeOut
 import net.taler.common.navigate
+import net.taler.merchantlib.OrderHistoryEntry
 import net.taler.merchantpos.MainViewModel
 import net.taler.merchantpos.R
 import 
net.taler.merchantpos.history.RefundFragmentDirections.Companion.actionRefundFragmentToRefundUriFragment
@@ -65,7 +66,7 @@ class RefundFragment : Fragment() {
         })
     }
 
-    private fun onRefundButtonClicked(item: HistoryItem) {
+    private fun onRefundButtonClicked(item: OrderHistoryEntry) {
         val inputAmount = try {
             Amount.fromString(item.amount.currency, 
amountInputView.text.toString())
         } catch (e: AmountParserException) {
diff --git 
a/merchant-terminal/src/main/java/net/taler/merchantpos/history/RefundManager.kt
 
b/merchant-terminal/src/main/java/net/taler/merchantpos/history/RefundManager.kt
index da642d6..7f9b4c5 100644
--- 
a/merchant-terminal/src/main/java/net/taler/merchantpos/history/RefundManager.kt
+++ 
b/merchant-terminal/src/main/java/net/taler/merchantpos/history/RefundManager.kt
@@ -25,6 +25,7 @@ import com.android.volley.RequestQueue
 import com.android.volley.Response.Listener
 import com.android.volley.VolleyError
 import net.taler.common.Amount
+import net.taler.merchantlib.OrderHistoryEntry
 import net.taler.merchantpos.LogErrorListener
 import net.taler.merchantpos.config.ConfigManager
 import net.taler.merchantpos.config.MerchantRequest
@@ -36,7 +37,7 @@ sealed class RefundResult {
     object AlreadyRefunded : RefundResult()
     class Success(
         val refundUri: String,
-        val item: HistoryItem,
+        val item: OrderHistoryEntry,
         val amount: Amount,
         val reason: String
     ) : RefundResult()
@@ -51,14 +52,14 @@ class RefundManager(
         val TAG = RefundManager::class.java.simpleName
     }
 
-    var toBeRefunded: HistoryItem? = null
+    var toBeRefunded: OrderHistoryEntry? = null
         private set
 
     private val mRefundResult = MutableLiveData<RefundResult>()
     internal val refundResult: LiveData<RefundResult> = mRefundResult
 
     @UiThread
-    internal fun startRefund(item: HistoryItem) {
+    internal fun startRefund(item: OrderHistoryEntry) {
         toBeRefunded = item
         mRefundResult.value = null
     }
@@ -70,7 +71,7 @@ class RefundManager(
     }
 
     @UiThread
-    internal fun refund(item: HistoryItem, amount: Amount, reason: String) {
+    internal fun refund(item: OrderHistoryEntry, amount: Amount, reason: 
String) {
         val merchantConfig = configManager.merchantConfig!!
         val refundRequest = mapOf(
             "order_id" to item.orderId,
@@ -89,7 +90,7 @@ class RefundManager(
     @UiThread
     private fun onRefundResponse(
         json: JSONObject,
-        item: HistoryItem,
+        item: OrderHistoryEntry,
         amount: Amount,
         reason: String
     ) {
diff --git 
a/taler-kotlin-common/src/main/java/net/taler/common/ContractTerms.kt 
b/taler-kotlin-common/src/main/java/net/taler/common/ContractTerms.kt
index c07127a..b891ef7 100644
--- a/taler-kotlin-common/src/main/java/net/taler/common/ContractTerms.kt
+++ b/taler-kotlin-common/src/main/java/net/taler/common/ContractTerms.kt
@@ -82,8 +82,10 @@ data class ContractMerchant(
     val name: String
 )
 
+@Serializable
 @JsonInclude(NON_EMPTY)
 class Timestamp(
+    @SerialName("t_ms")
     @JsonProperty("t_ms")
     val ms: Long
 )

-- 
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]