From 5f9980b2dd416a47e07b4066ad81bd1433742c44 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Manciot?= Date: Tue, 23 Dec 2025 09:39:00 +0100 Subject: [PATCH 1/2] update transfer api adding order uuid in case of transfer failure + allowing transfer from stripe account to connected account --- .gitignore | 3 +- build.sbt | 2 +- .../message/payment/transaction.proto | 1 + .../persistence/typed/PaymentBehavior.scala | 87 ++++++++++++------- .../payment/spi/StripeTransferApi.scala | 1 + 5 files changed, 60 insertions(+), 34 deletions(-) diff --git a/.gitignore b/.gitignore index 2f2c52c..161f68f 100644 --- a/.gitignore +++ b/.gitignore @@ -3,4 +3,5 @@ sbt.json target .metals -*.log \ No newline at end of file +*.log +tmp \ No newline at end of file diff --git a/build.sbt b/build.sbt index f970912..cf2b14e 100644 --- a/build.sbt +++ b/build.sbt @@ -2,7 +2,7 @@ ThisBuild / organization := "app.softnetwork" name := "payment" -ThisBuild / version := "0.8.2" +ThisBuild / version := "0.8.3" ThisBuild / scalaVersion := "2.12.18" diff --git a/common/src/main/protobuf/message/payment/transaction.proto b/common/src/main/protobuf/message/payment/transaction.proto index 9fd1402..2a61b0d 100644 --- a/common/src/main/protobuf/message/payment/transaction.proto +++ b/common/src/main/protobuf/message/payment/transaction.proto @@ -139,6 +139,7 @@ message TransferFailedEvent { required string resultMessage = 2; optional app.softnetwork.payment.model.Transaction transaction = 3; optional string externalReference = 4; + optional string orderUuid = 5; } message DirectDebitedEvent { diff --git a/core/src/main/scala/app/softnetwork/payment/persistence/typed/PaymentBehavior.scala b/core/src/main/scala/app/softnetwork/payment/persistence/typed/PaymentBehavior.scala index 534a302..bd02919 100644 --- a/core/src/main/scala/app/softnetwork/payment/persistence/typed/PaymentBehavior.scala +++ b/core/src/main/scala/app/softnetwork/payment/persistence/typed/PaymentBehavior.scala @@ -471,37 +471,57 @@ trait PaymentBehavior case Some(authorId) => paymentAccount.walletId match { case Some(debitedWalletId) => - // load credited payment account - paymentDao.loadPaymentAccount(creditedAccount, clientId) complete () match { - case Success(s) => - maybeCreditedPaymentAccount = s - maybeCreditedPaymentAccount match { - case Some(creditedPaymentAccount) => // credited account - creditedPaymentAccount.userId match { - case Some(creditedUserId) => - creditedPaymentAccount.walletId match { - case Some(creditedWalletId) => - Some( - TransferTransaction.defaultInstance - .withDebitedAmount(debitedAmount) - .withFeesAmount(feesAmount) - .withCurrency(currency) - .withAuthorId(authorId) - .withDebitedWalletId(debitedWalletId) - .withCreditedUserId(creditedUserId) - .withCreditedWalletId(creditedWalletId) - .copy( - orderUuid = orderUuid, - externalReference = externalReference - ) - ) - case _ => None - } - case _ => None - } - case _ => None - } - case Failure(_) => None + if(debitedAccount == creditedAccount) { // direct transfer from the platform account to authorId + val creditedUserId = authorId + val creditedWalletId = debitedWalletId + Some( + TransferTransaction.defaultInstance + .withDebitedAmount(debitedAmount) + .withFeesAmount(feesAmount) + .withCurrency(currency) + .withAuthorId(authorId) + .withDebitedWalletId(debitedWalletId) + .withCreditedUserId(creditedUserId) + .withCreditedWalletId(creditedWalletId) + .copy( + orderUuid = orderUuid, + externalReference = externalReference + ) + ) + } + else{ + // load credited payment account + paymentDao.loadPaymentAccount(creditedAccount, clientId) complete () match { + case Success(s) => + maybeCreditedPaymentAccount = s + maybeCreditedPaymentAccount match { + case Some(creditedPaymentAccount) => // credited account + creditedPaymentAccount.userId match { + case Some(creditedUserId) => + creditedPaymentAccount.walletId match { + case Some(creditedWalletId) => + Some( + TransferTransaction.defaultInstance + .withDebitedAmount(debitedAmount) + .withFeesAmount(feesAmount) + .withCurrency(currency) + .withAuthorId(authorId) + .withDebitedWalletId(debitedWalletId) + .withCreditedUserId(creditedUserId) + .withCreditedWalletId(creditedWalletId) + .copy( + orderUuid = orderUuid, + externalReference = externalReference + ) + ) + case _ => None + } + case _ => None + } + case _ => None + } + case Failure(_) => None + } } case _ => None } @@ -579,7 +599,10 @@ trait PaymentBehavior .withDebitedAccount(paymentAccount.externalUuid) .withResultMessage(transaction.resultMessage) .withTransaction(transaction) - .copy(externalReference = externalReference) + .copy( + externalReference = externalReference, + orderUuid = orderUuid + ) ) :+ transactionUpdatedEvent ) .thenRun(_ => diff --git a/stripe/src/main/scala/app/softnetwork/payment/spi/StripeTransferApi.scala b/stripe/src/main/scala/app/softnetwork/payment/spi/StripeTransferApi.scala index a5a28c2..47a905c 100644 --- a/stripe/src/main/scala/app/softnetwork/payment/spi/StripeTransferApi.scala +++ b/stripe/src/main/scala/app/softnetwork/payment/spi/StripeTransferApi.scala @@ -150,6 +150,7 @@ trait StripeTransferApi extends TransferApi { _: StripeContext => .setAmount(Math.min(amountToTransfer, availableAmount)) .setDestination(transferTransaction.creditedUserId) .setCurrency(transferTransaction.currency) + // .setSourceType(TransferCreateParams.SourceType.CARD) .putMetadata("available_amount", availableAmount.toString) .putMetadata("debited_amount", transferTransaction.debitedAmount.toString) .putMetadata("fees_amount", transferTransaction.feesAmount.toString) From af66daff920691d889b0855e82942227be2137bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Manciot?= Date: Tue, 23 Dec 2025 09:39:39 +0100 Subject: [PATCH 2/2] formating --- .../payment/persistence/typed/PaymentBehavior.scala | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/core/src/main/scala/app/softnetwork/payment/persistence/typed/PaymentBehavior.scala b/core/src/main/scala/app/softnetwork/payment/persistence/typed/PaymentBehavior.scala index bd02919..8575a40 100644 --- a/core/src/main/scala/app/softnetwork/payment/persistence/typed/PaymentBehavior.scala +++ b/core/src/main/scala/app/softnetwork/payment/persistence/typed/PaymentBehavior.scala @@ -471,7 +471,7 @@ trait PaymentBehavior case Some(authorId) => paymentAccount.walletId match { case Some(debitedWalletId) => - if(debitedAccount == creditedAccount) { // direct transfer from the platform account to authorId + if (debitedAccount == creditedAccount) { // direct transfer from the platform account to authorId val creditedUserId = authorId val creditedWalletId = debitedWalletId Some( @@ -488,8 +488,7 @@ trait PaymentBehavior externalReference = externalReference ) ) - } - else{ + } else { // load credited payment account paymentDao.loadPaymentAccount(creditedAccount, clientId) complete () match { case Success(s) =>