libeufin

Integration and sandbox testing for FinTech APIs and data formats
Log | Files | Refs | Submodules | README | LICENSE

commit e752f6538fb2da4f285ddfabbde29cb1bfb83fff
parent f73bdadef153acf43c0393e92c34abd00021d67c
Author: Marcello Stanisci <ms@taler.net>
Date:   Fri,  8 May 2020 23:17:03 +0200

POST ../prepared-payments

Diffstat:
Mnexus/src/main/kotlin/tech/libeufin/nexus/Helpers.kt | 9+++++++++
Mnexus/src/main/kotlin/tech/libeufin/nexus/JSON.kt | 12++++++++++++
Mnexus/src/main/kotlin/tech/libeufin/nexus/Main.kt | 30++++++++++++++++++++++--------
Mnexus/src/main/kotlin/tech/libeufin/nexus/taler.kt | 11-----------
Mutil/src/main/kotlin/strings.kt | 13+++++++++++++
5 files changed, 56 insertions(+), 19 deletions(-)

diff --git a/nexus/src/main/kotlin/tech/libeufin/nexus/Helpers.kt b/nexus/src/main/kotlin/tech/libeufin/nexus/Helpers.kt @@ -61,6 +61,15 @@ fun extractFirstBic(bankCodes: List<EbicsTypes.AbstractBankCode>?): String? { return null } +fun getBankAccount(id: String): BankAccountEntity { + return transaction { + BankAccountEntity.findById(id) + } ?: throw NexusError( + HttpStatusCode.NotFound, + "Bank account '$id' not found" + ) +} + /** * Given a nexus user id, returns the _list_ of bank accounts associated to it. * diff --git a/nexus/src/main/kotlin/tech/libeufin/nexus/JSON.kt b/nexus/src/main/kotlin/tech/libeufin/nexus/JSON.kt @@ -141,6 +141,18 @@ class TestSubscriber() /** PAYMENT INSTRUCTIONS TYPES */ +data class PreparedPaymentRequest( + val iban: String, + val bic: String, + val name: String, + val amount: String, + val subject: String +) + +data class PreparedPaymentResponse( + val uuid: String +) + /** This structure is used to INSTRUCT the nexus to prepare such payment. */ data class Pain001Data( val creditorIban: String, diff --git a/nexus/src/main/kotlin/tech/libeufin/nexus/Main.kt b/nexus/src/main/kotlin/tech/libeufin/nexus/Main.kt @@ -187,27 +187,19 @@ fun main() { post("/bank-accounts/{accountid}/prepared-payments/submit") { val userId = authenticateRequest(call.request.headers["Authorization"]) val body = call.receive<SubmitPayment>() - - // 1 find payment. val preparedPayment = transaction { Pain001Entity.findById(body.uuid) } ?: throw NexusError( HttpStatusCode.NotFound, "Could not find prepared payment: ${body.uuid}" ) - - // 2 check if was submitted yet if (preparedPayment.submitted) { throw NexusError( HttpStatusCode.PreconditionFailed, "Payment ${body.uuid} was submitted already" ) } - - // 3 submit val pain001document = createPain001document(preparedPayment) - - // 4 check if the user has a instance in such bank transport. when (body.transport) { "ebics" -> { val subscriberDetails = getSubscriberDetailsFromNexusUserId(userId) @@ -250,6 +242,28 @@ fun main() { * Adds a new prepared payment. */ post("/bank-accounts/{accountid}/prepared-payments") { + val userId = authenticateRequest(call.request.headers["Authorization"]) + val body = call.receive<PreparedPaymentRequest>() + val debitBankAccount = getBankAccount(expectId(call.parameters["accountid"])) + val amount = parseAmount(body.amount) + val paymentEntity = createPain001entity( + Pain001Data( + creditorIban = body.iban, + creditorBic = body.bic, + creditorName = body.name, + debitorIban = debitBankAccount.iban, + debitorBic = debitBankAccount.bankCode, + debitorName = debitBankAccount.accountHolder, + sum = amount.amount, + currency = amount.currency, + subject = body.subject + ), + extractNexusUser(userId) + ) + call.respond( + HttpStatusCode.OK, + PreparedPaymentResponse(uuid = paymentEntity.id.value) + ) return@post } /** diff --git a/nexus/src/main/kotlin/tech/libeufin/nexus/taler.kt b/nexus/src/main/kotlin/tech/libeufin/nexus/taler.kt @@ -90,11 +90,6 @@ class Taler(app: Route) { val iban: String, val bic: String = "NOTGIVEN" ) - data class AmountWithCurrency( - val currency: String, - val amount: Amount - ) - /** * Helper functions */ @@ -130,12 +125,6 @@ class Taler(app: Route) { throw NexusError(HttpStatusCode.BadRequest, "invalid payto URI ($paytoUri)") } - fun parseAmount(amount: String): AmountWithCurrency { - val match = Regex("([A-Z]+):([0-9]+(\\.[0-9]+)?)").find(amount) ?: throw - NexusError(HttpStatusCode.BadRequest, "invalid payto URI ($amount)") - val (currency, number) = match.destructured - return AmountWithCurrency(currency, Amount(number)) - } /** Sort query results in descending order for negative deltas, and ascending otherwise. */ private fun <T : Entity<Long>> SizedIterable<T>.orderTaler(delta: Int): List<T> { return if (delta < 0) { diff --git a/util/src/main/kotlin/strings.kt b/util/src/main/kotlin/strings.kt @@ -1,5 +1,6 @@ package tech.libeufin.util +import io.ktor.http.HttpStatusCode import java.math.BigInteger import java.util.* @@ -69,4 +70,16 @@ fun chunkString(input: String): String { ret.append(input[i]) } return ret.toString().toUpperCase() +} + +data class AmountWithCurrency( + val currency: String, + val amount: Amount +) + +fun parseAmount(amount: String): AmountWithCurrency { + val match = Regex("([A-Z]+):([0-9]+(\\.[0-9]+)?)").find(amount) ?: throw + UtilError(HttpStatusCode.BadRequest, "invalid payto URI ($amount)") + val (currency, number) = match.destructured + return AmountWithCurrency(currency, Amount(number)) } \ No newline at end of file