commit 37725bb893974f0a0c566b7acd9db435611c94bb
parent f23911edb73eddbbedca29d03196c95a10e419ed
Author: MS <ms@taler.net>
Date: Sat, 7 Jan 2023 13:42:11 +0100
Debit check at server side EBICS.
Diffstat:
2 files changed, 24 insertions(+), 4 deletions(-)
diff --git a/sandbox/src/main/kotlin/tech/libeufin/sandbox/EbicsProtocolBackend.kt b/sandbox/src/main/kotlin/tech/libeufin/sandbox/EbicsProtocolBackend.kt
@@ -67,7 +67,7 @@ data class PainParseResult(
open class EbicsRequestError(
val errorText: String,
val errorCode: String
-) : Exception("$errorText ($errorCode)")
+) : Exception("$errorText (EBICS error code: $errorCode)")
class EbicsNoDownloadDataAvailable(reason: String? = null) : EbicsRequestError(
"[EBICS_NO_DOWNLOAD_DATA_AVAILABLE]" + if (reason != null) " $reason" else "",
@@ -126,6 +126,11 @@ class EbicsProcessingError(detail: String) : EbicsRequestError(
"091116"
)
+class EbicsAmountCheckError(detail: String): EbicsRequestError(
+ "[EBICS_AMOUNT_CHECK_FAILED] $detail",
+ "091303"
+)
+
suspend fun respondEbicsTransfer(
call: ApplicationCall,
errorText: String,
@@ -697,8 +702,12 @@ private fun parsePain001(paymentRequest: String): PainParseResult {
}
/**
- * Process a payment request in the pain.001 format.
- */
+ * Process a payment request in the pain.001 format. Note:
+ * the receiver IBAN is NOT checked to have one account at
+ * the Sandbox. That's because (1) it leaves open to send
+ * payments outside of the running Sandbox and (2) may ease
+ * tests where the preparation logic can skip creating also
+ * the receiver account. */
private fun handleCct(paymentRequest: String,
requestingSubscriber: EbicsSubscriberEntity
) {
@@ -731,7 +740,17 @@ private fun handleCct(paymentRequest: String,
"[EBICS_PROCESSING_ERROR] Currency (${parseResult.currency}) not supported.",
"091116"
)
- // FIXME: check that debtor IBAN _is_ the requesting subscriber.
+ // Check for the debit case.
+ val maybeAmount = try {
+ BigDecimal(parseResult.amount)
+ } catch (e: Exception) {
+ logger.warn("Although PAIN validated, BigDecimal didn't parse its amount (${parseResult.amount})!")
+ throw EbicsProcessingError("The CCT request contains an invalid amount: ${parseResult.amount}")
+ }
+ if (maybeDebit(bankAccount.label, maybeAmount))
+ throw EbicsAmountCheckError("The requested amount (${parseResult.amount}) would exceed the debit threshold")
+
+ // Get the two parties.
BankAccountTransactionEntity.new {
account = bankAccount
demobank = bankAccount.demoBank
diff --git a/util/src/main/kotlin/Ebics.kt b/util/src/main/kotlin/Ebics.kt
@@ -366,6 +366,7 @@ enum class EbicsReturnCode(val errorCode: String) {
EBICS_INVALID_USER_OR_USER_STATE("091002"),
EBICS_PROCESSING_ERROR("091116"),
EBICS_ACCOUNT_AUTHORISATION_FAILED("091302"),
+ EBICS_AMOUNT_CHECK_FAILED("091303"),
EBICS_NO_DOWNLOAD_DATA_AVAILABLE("090005");
companion object {