From 35f7ed512ed7445362d6caee1bf60441f4ce979e Mon Sep 17 00:00:00 2001 From: Torsten Grote Date: Tue, 4 Aug 2020 09:46:38 -0300 Subject: [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 --- .../src/main/java/net/taler/merchantlib/Config.kt | 53 ++++++++++++++ .../java/net/taler/merchantlib/ConfigResponse.kt | 34 --------- .../main/java/net/taler/merchantlib/MerchantApi.kt | 12 +++ .../java/net/taler/merchantlib/MerchantConfig.kt | 38 ---------- .../src/main/java/net/taler/merchantlib/Orders.kt | 85 ++++++++++++++++++++++ .../java/net/taler/merchantlib/PostOrderRequest.kt | 85 ---------------------- .../src/main/java/net/taler/merchantlib/Refunds.kt | 43 +++++++++++ 7 files changed, 193 insertions(+), 157 deletions(-) create mode 100644 merchant-lib/src/main/java/net/taler/merchantlib/Config.kt delete mode 100644 merchant-lib/src/main/java/net/taler/merchantlib/ConfigResponse.kt delete mode 100644 merchant-lib/src/main/java/net/taler/merchantlib/MerchantConfig.kt create mode 100644 merchant-lib/src/main/java/net/taler/merchantlib/Orders.kt delete mode 100644 merchant-lib/src/main/java/net/taler/merchantlib/PostOrderRequest.kt create mode 100644 merchant-lib/src/main/java/net/taler/merchantlib/Refunds.kt (limited to 'merchant-lib/src/main/java') diff --git a/merchant-lib/src/main/java/net/taler/merchantlib/Config.kt b/merchant-lib/src/main/java/net/taler/merchantlib/Config.kt new file mode 100644 index 0000000..eb09485 --- /dev/null +++ b/merchant-lib/src/main/java/net/taler/merchantlib/Config.kt @@ -0,0 +1,53 @@ +/* + * This file is part of GNU Taler + * (C) 2020 Taler Systems S.A. + * + * GNU Taler is free software; you can redistribute it and/or modify it under the + * terms of the GNU General Public License as published by the Free Software + * Foundation; either version 3, or (at your option) any later version. + * + * GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * GNU Taler; see the file COPYING. If not, see + */ + +package net.taler.merchantlib + +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, + // 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('/') + instance?.let { sb.append("instances/$it/") } + sb.append(endpoint) + return sb.toString() + } +} diff --git a/merchant-lib/src/main/java/net/taler/merchantlib/ConfigResponse.kt b/merchant-lib/src/main/java/net/taler/merchantlib/ConfigResponse.kt deleted file mode 100644 index 49164e6..0000000 --- a/merchant-lib/src/main/java/net/taler/merchantlib/ConfigResponse.kt +++ /dev/null @@ -1,34 +0,0 @@ -/* - * This file is part of GNU Taler - * (C) 2020 Taler Systems S.A. - * - * GNU Taler is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 3, or (at your option) any later version. - * - * GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - * A PARTICULAR PURPOSE. See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along with - * GNU Taler; see the file COPYING. If not, see - */ - -package net.taler.merchantlib - -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 -) 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 = 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/MerchantConfig.kt b/merchant-lib/src/main/java/net/taler/merchantlib/MerchantConfig.kt deleted file mode 100644 index a8d113e..0000000 --- a/merchant-lib/src/main/java/net/taler/merchantlib/MerchantConfig.kt +++ /dev/null @@ -1,38 +0,0 @@ -/* - * This file is part of GNU Taler - * (C) 2020 Taler Systems S.A. - * - * GNU Taler is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 3, or (at your option) any later version. - * - * GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - * A PARTICULAR PURPOSE. See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along with - * GNU Taler; see the file COPYING. If not, see - */ - -package net.taler.merchantlib - -import kotlinx.serialization.SerialName -import kotlinx.serialization.Serializable - -@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('/') - instance?.let { sb.append("instances/$it/") } - sb.append(endpoint) - return sb.toString() - } -} diff --git a/merchant-lib/src/main/java/net/taler/merchantlib/Orders.kt b/merchant-lib/src/main/java/net/taler/merchantlib/Orders.kt new file mode 100644 index 0000000..783dd19 --- /dev/null +++ b/merchant-lib/src/main/java/net/taler/merchantlib/Orders.kt @@ -0,0 +1,85 @@ +/* + * This file is part of GNU Taler + * (C) 2020 Taler Systems S.A. + * + * GNU Taler is free software; you can redistribute it and/or modify it under the + * terms of the GNU General Public License as published by the Free Software + * Foundation; either version 3, or (at your option) any later version. + * + * GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * GNU Taler; see the file COPYING. If not, see + */ + +package net.taler.merchantlib + +import kotlinx.serialization.Decoder +import kotlinx.serialization.Encoder +import kotlinx.serialization.KSerializer +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable +import kotlinx.serialization.Serializer +import kotlinx.serialization.json.JsonInput +import kotlinx.serialization.json.JsonObject +import net.taler.common.ContractTerms +import net.taler.common.Duration + +@Serializable +data class PostOrderRequest( + @SerialName("order") + val contractTerms: ContractTerms, + @SerialName("refund_delay") + val refundDelay: Duration? = null +) + +@Serializable +data class PostOrderResponse( + @SerialName("order_id") + val orderId: String +) + +@Serializable +sealed class CheckPaymentResponse { + abstract val paid: Boolean + + @Serializer(forClass = CheckPaymentResponse::class) + companion object : KSerializer { + override fun deserialize(decoder: Decoder): CheckPaymentResponse { + val input = decoder as JsonInput + val tree = input.decodeJson() as JsonObject + 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 (orderStatus == "paid") Paid( + refunded = tree.getPrimitive("refunded").boolean + ) else Unpaid( + talerPayUri = tree.getPrimitive("taler_pay_uri").content + ) + } + + override fun serialize(encoder: Encoder, value: CheckPaymentResponse) = when (value) { + is Unpaid -> Unpaid.serializer().serialize(encoder, value) + is Paid -> Paid.serializer().serialize(encoder, value) + } + } + + @Serializable + data class Unpaid( + override val paid: Boolean = false, + @SerialName("taler_pay_uri") + val talerPayUri: String, + @SerialName("already_paid_order_id") + val alreadyPaidOrderId: String? = null + ) : CheckPaymentResponse() + + @Serializable + data class Paid( + override val paid: Boolean = true, + val refunded: Boolean + ) : CheckPaymentResponse() + +} diff --git a/merchant-lib/src/main/java/net/taler/merchantlib/PostOrderRequest.kt b/merchant-lib/src/main/java/net/taler/merchantlib/PostOrderRequest.kt deleted file mode 100644 index 783dd19..0000000 --- a/merchant-lib/src/main/java/net/taler/merchantlib/PostOrderRequest.kt +++ /dev/null @@ -1,85 +0,0 @@ -/* - * This file is part of GNU Taler - * (C) 2020 Taler Systems S.A. - * - * GNU Taler is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 3, or (at your option) any later version. - * - * GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - * A PARTICULAR PURPOSE. See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along with - * GNU Taler; see the file COPYING. If not, see - */ - -package net.taler.merchantlib - -import kotlinx.serialization.Decoder -import kotlinx.serialization.Encoder -import kotlinx.serialization.KSerializer -import kotlinx.serialization.SerialName -import kotlinx.serialization.Serializable -import kotlinx.serialization.Serializer -import kotlinx.serialization.json.JsonInput -import kotlinx.serialization.json.JsonObject -import net.taler.common.ContractTerms -import net.taler.common.Duration - -@Serializable -data class PostOrderRequest( - @SerialName("order") - val contractTerms: ContractTerms, - @SerialName("refund_delay") - val refundDelay: Duration? = null -) - -@Serializable -data class PostOrderResponse( - @SerialName("order_id") - val orderId: String -) - -@Serializable -sealed class CheckPaymentResponse { - abstract val paid: Boolean - - @Serializer(forClass = CheckPaymentResponse::class) - companion object : KSerializer { - override fun deserialize(decoder: Decoder): CheckPaymentResponse { - val input = decoder as JsonInput - val tree = input.decodeJson() as JsonObject - 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 (orderStatus == "paid") Paid( - refunded = tree.getPrimitive("refunded").boolean - ) else Unpaid( - talerPayUri = tree.getPrimitive("taler_pay_uri").content - ) - } - - override fun serialize(encoder: Encoder, value: CheckPaymentResponse) = when (value) { - is Unpaid -> Unpaid.serializer().serialize(encoder, value) - is Paid -> Paid.serializer().serialize(encoder, value) - } - } - - @Serializable - data class Unpaid( - override val paid: Boolean = false, - @SerialName("taler_pay_uri") - val talerPayUri: String, - @SerialName("already_paid_order_id") - val alreadyPaidOrderId: String? = null - ) : CheckPaymentResponse() - - @Serializable - data class Paid( - override val paid: Boolean = true, - val refunded: Boolean - ) : CheckPaymentResponse() - -} diff --git a/merchant-lib/src/main/java/net/taler/merchantlib/Refunds.kt b/merchant-lib/src/main/java/net/taler/merchantlib/Refunds.kt new file mode 100644 index 0000000..61f0ab7 --- /dev/null +++ b/merchant-lib/src/main/java/net/taler/merchantlib/Refunds.kt @@ -0,0 +1,43 @@ +/* + * This file is part of GNU Taler + * (C) 2020 Taler Systems S.A. + * + * GNU Taler is free software; you can redistribute it and/or modify it under the + * terms of the GNU General Public License as published by the Free Software + * Foundation; either version 3, or (at your option) any later version. + * + * GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * GNU Taler; see the file COPYING. If not, see + */ + +package net.taler.merchantlib + +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable +import net.taler.common.Amount + +@Serializable +data class RefundRequest( + /** + * Amount to be refunded + */ + val refund: Amount, + + /** + * Human-readable refund justification + */ + 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 +) -- cgit v1.2.3