aboutsummaryrefslogtreecommitdiff
path: root/merchant-lib
diff options
context:
space:
mode:
authorTorsten Grote <t@grobox.de>2020-08-04 09:46:38 -0300
committerTorsten Grote <t@grobox.de>2020-08-04 09:46:38 -0300
commit35f7ed512ed7445362d6caee1bf60441f4ce979e (patch)
tree08fb02c802ff36065dd85fb9dcb95a0adabc03c3 /merchant-lib
parentd3a035c59c508b7b0ef3c06a1b0f1f3c0a077bb8 (diff)
downloadtaler-android-35f7ed512ed7445362d6caee1bf60441f4ce979e.tar.gz
taler-android-35f7ed512ed7445362d6caee1bf60441f4ce979e.tar.bz2
taler-android-35f7ed512ed7445362d6caee1bf60441f4ce979e.zip
[pos] Implement new refund API (untested since there is no wallet support)
Also do a bit of code cleanup and minor refactorings This also removes the volley HTTP library which is not needed anymore
Diffstat (limited to 'merchant-lib')
-rw-r--r--merchant-lib/src/main/AndroidManifest.xml1
-rw-r--r--merchant-lib/src/main/java/net/taler/merchantlib/Config.kt (renamed from merchant-lib/src/main/java/net/taler/merchantlib/MerchantConfig.kt)15
-rw-r--r--merchant-lib/src/main/java/net/taler/merchantlib/MerchantApi.kt12
-rw-r--r--merchant-lib/src/main/java/net/taler/merchantlib/Orders.kt (renamed from merchant-lib/src/main/java/net/taler/merchantlib/PostOrderRequest.kt)0
-rw-r--r--merchant-lib/src/main/java/net/taler/merchantlib/Refunds.kt (renamed from merchant-lib/src/main/java/net/taler/merchantlib/ConfigResponse.kt)23
-rw-r--r--merchant-lib/src/test/java/net/taler/merchantlib/MerchantApiTest.kt98
6 files changed, 137 insertions, 12 deletions
diff --git a/merchant-lib/src/main/AndroidManifest.xml b/merchant-lib/src/main/AndroidManifest.xml
index 7318c07..1408b33 100644
--- a/merchant-lib/src/main/AndroidManifest.xml
+++ b/merchant-lib/src/main/AndroidManifest.xml
@@ -17,7 +17,6 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="net.taler.merchantlib">
- <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
</manifest>
diff --git a/merchant-lib/src/main/java/net/taler/merchantlib/MerchantConfig.kt b/merchant-lib/src/main/java/net/taler/merchantlib/Config.kt
index a8d113e..eb09485 100644
--- a/merchant-lib/src/main/java/net/taler/merchantlib/MerchantConfig.kt
+++ b/merchant-lib/src/main/java/net/taler/merchantlib/Config.kt
@@ -20,6 +20,21 @@ import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
@Serializable
+data class ConfigResponse(
+ /**
+ * libtool-style representation of the Merchant protocol version, see
+ * https://www.gnu.org/software/libtool/manual/html_node/Versioning.html#Versioning
+ * The format is "current:revision:age".
+ */
+ val version: String,
+
+ /**
+ Currency supported by this backend.
+ */
+ val currency: String
+)
+
+@Serializable
data class MerchantConfig(
@SerialName("base_url")
val baseUrl: String,
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 96892f5..c92d4d2 100644
--- a/merchant-lib/src/main/java/net/taler/merchantlib/MerchantApi.kt
+++ b/merchant-lib/src/main/java/net/taler/merchantlib/MerchantApi.kt
@@ -72,6 +72,18 @@ class MerchantApi(private val httpClient: HttpClient) {
} as OrderHistory
}
+ suspend fun giveRefund(
+ merchantConfig: MerchantConfig,
+ orderId: String,
+ request: RefundRequest
+ ): Response<RefundResponse> = response {
+ httpClient.post(merchantConfig.urlFor("private/orders/$orderId/refund")) {
+ header(Authorization, "ApiKey ${merchantConfig.apiKey}")
+ contentType(Json)
+ body = request
+ } as RefundResponse
+ }
+
}
fun getDefaultHttpClient(): HttpClient = HttpClient(OkHttp) {
diff --git a/merchant-lib/src/main/java/net/taler/merchantlib/PostOrderRequest.kt b/merchant-lib/src/main/java/net/taler/merchantlib/Orders.kt
index 783dd19..783dd19 100644
--- a/merchant-lib/src/main/java/net/taler/merchantlib/PostOrderRequest.kt
+++ b/merchant-lib/src/main/java/net/taler/merchantlib/Orders.kt
diff --git a/merchant-lib/src/main/java/net/taler/merchantlib/ConfigResponse.kt b/merchant-lib/src/main/java/net/taler/merchantlib/Refunds.kt
index 49164e6..61f0ab7 100644
--- a/merchant-lib/src/main/java/net/taler/merchantlib/ConfigResponse.kt
+++ b/merchant-lib/src/main/java/net/taler/merchantlib/Refunds.kt
@@ -16,19 +16,28 @@
package net.taler.merchantlib
+import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
+import net.taler.common.Amount
@Serializable
-data class ConfigResponse(
+data class RefundRequest(
/**
- * libtool-style representation of the Merchant protocol version, see
- * https://www.gnu.org/software/libtool/manual/html_node/Versioning.html#Versioning
- * The format is "current:revision:age".
+ * Amount to be refunded
*/
- val version: String,
+ val refund: Amount,
/**
- Currency supported by this backend.
+ * Human-readable refund justification
*/
- val currency: String
+ val reason: String
+)
+
+@Serializable
+data class RefundResponse(
+ /**
+ * URL (handled by the backend) that the wallet should access to trigger refund processing.
+ */
+ @SerialName("taler_refund_uri")
+ val talerRefundUri: String
)
diff --git a/merchant-lib/src/test/java/net/taler/merchantlib/MerchantApiTest.kt b/merchant-lib/src/test/java/net/taler/merchantlib/MerchantApiTest.kt
index 437697b..f9f5e87 100644
--- a/merchant-lib/src/test/java/net/taler/merchantlib/MerchantApiTest.kt
+++ b/merchant-lib/src/test/java/net/taler/merchantlib/MerchantApiTest.kt
@@ -16,11 +16,12 @@
package net.taler.merchantlib
-import io.ktor.http.HttpStatusCode
+import io.ktor.http.HttpStatusCode.Companion.NotFound
import kotlinx.coroutines.runBlocking
import net.taler.common.Amount
import net.taler.common.ContractProduct
import net.taler.common.ContractTerms
+import net.taler.common.Timestamp
import net.taler.merchantlib.MockHttpClient.giveJsonResponse
import net.taler.merchantlib.MockHttpClient.httpClient
import org.junit.Assert.assertEquals
@@ -35,6 +36,7 @@ class MerchantApiTest {
instance = "testInstance",
apiKey = "apiKeyFooBar"
)
+ private val orderId = "orderIdFoo"
@Test
fun testGetConfig() = runBlocking {
@@ -95,7 +97,7 @@ class MerchantApiTest {
httpClient.giveJsonResponse(
"http://example.net/instances/testInstance/private/orders",
- statusCode = HttpStatusCode.NotFound
+ statusCode = NotFound
) {
"""{
"code": 2000,
@@ -110,7 +112,6 @@ class MerchantApiTest {
@Test
fun testCheckOrder() = runBlocking {
- val orderId = "orderIdFoo"
val unpaidResponse = CheckPaymentResponse.Unpaid(false, "http://taler.net/foo")
httpClient.giveJsonResponse("http://example.net/instances/testInstance/private/orders/$orderId") {
"""{
@@ -125,7 +126,7 @@ class MerchantApiTest {
httpClient.giveJsonResponse(
"http://example.net/instances/testInstance/private/orders/$orderId",
- statusCode = HttpStatusCode.NotFound
+ statusCode = NotFound
) {
"""{
"code": 2909,
@@ -138,4 +139,93 @@ class MerchantApiTest {
}
}
+ @Test
+ fun testDeleteOrder() = runBlocking {
+ httpClient.giveJsonResponse("http://example.net/instances/testInstance/private/orders/$orderId") {
+ "{}"
+ }
+ api.deleteOrder(merchantConfig, orderId).assertSuccess {}
+
+ httpClient.giveJsonResponse(
+ "http://example.net/instances/testInstance/private/orders/$orderId",
+ statusCode = NotFound
+ ) {
+ """{
+ "code": 2511,
+ "hint": "Order unknown"
+ }
+ """.trimIndent()
+ }
+ api.deleteOrder(merchantConfig, orderId).assertFailure {
+ assertTrue(it.contains("2511"))
+ assertTrue(it.contains("Order unknown"))
+ }
+ }
+
+ @Test
+ fun testGetOrderHistory() = runBlocking {
+ httpClient.giveJsonResponse("http://example.net/instances/testInstance/private/orders") {
+ """{ "orders": [
+ {
+ "order_id": "2020.217-0281FGXCS25P2",
+ "row_id": 183,
+ "timestamp": {
+ "t_ms": 1596542338000
+ },
+ "amount": "TESTKUDOS:1",
+ "summary": "Chips",
+ "refundable": true,
+ "paid": true
+ },
+ {
+ "order_id": "2020.216-01G2ZPXSP6BYT",
+ "row_id": 154,
+ "timestamp": {
+ "t_ms": 1596468174000
+ },
+ "amount": "TESTKUDOS:0.8",
+ "summary": "Peanuts",
+ "refundable": false,
+ "paid": false
+ }
+ ]
+ }""".trimIndent()
+ }
+ api.getOrderHistory(merchantConfig).assertSuccess {
+ assertEquals(2, it.orders.size)
+
+ val order1 = it.orders[0]
+ assertEquals(Amount("TESTKUDOS", 1, 0), order1.amount)
+ assertEquals("2020.217-0281FGXCS25P2", order1.orderId)
+ assertEquals(true, order1.paid)
+ assertEquals(true, order1.refundable)
+ assertEquals("Chips", order1.summary)
+ assertEquals(Timestamp(1596542338000), order1.timestamp)
+
+ val order2 = it.orders[1]
+ assertEquals(Amount("TESTKUDOS", 0, 80000000), order2.amount)
+ assertEquals("2020.216-01G2ZPXSP6BYT", order2.orderId)
+ assertEquals(false, order2.paid)
+ assertEquals(false, order2.refundable)
+ assertEquals("Peanuts", order2.summary)
+ assertEquals(Timestamp(1596468174000), order2.timestamp)
+ }
+ }
+
+ @Test
+ fun testGiveRefund() = runBlocking {
+ httpClient.giveJsonResponse("http://example.net/instances/testInstance/private/orders/$orderId/refund") {
+ """{
+ "taler_refund_uri": "taler://refund/foo/bar"
+ }""".trimIndent()
+ }
+ val request = RefundRequest(
+ refund = Amount("TESTKUDOS", 5, 0),
+ reason = "Give me my money back now!!!"
+ )
+ api.giveRefund(merchantConfig, orderId, request).assertSuccess {
+ assertEquals("taler://refund/foo/bar", it.talerRefundUri)
+ }
+ }
+
}