From f8ea88fe8a1bc1a638ecb6f4689281c249f8ea5c Mon Sep 17 00:00:00 2001 From: kuldeepkumawat144 Date: Tue, 2 Jun 2026 16:30:19 +0530 Subject: [PATCH] Revert "backend/feat: Stripe payout dynamic transfer top-up for Fleet VA insufficient balance (#1320)" This reverts commit 1e3abfa323ecbceb3273282da1d6fe3965f1a4dd. --- .../src/Kernel/External/Payout/Interface.hs | 58 +++++-------------- .../External/Payout/Interface/Juspay.hs | 2 - .../External/Payout/Interface/Stripe.hs | 22 ------- .../Kernel/External/Payout/Interface/Types.hs | 3 +- .../src/Kernel/External/Payout/Stripe/Flow.hs | 40 ------------- 5 files changed, 14 insertions(+), 111 deletions(-) diff --git a/lib/mobility-core/src/Kernel/External/Payout/Interface.hs b/lib/mobility-core/src/Kernel/External/Payout/Interface.hs index f39369b7f..0940712ec 100644 --- a/lib/mobility-core/src/Kernel/External/Payout/Interface.hs +++ b/lib/mobility-core/src/Kernel/External/Payout/Interface.hs @@ -41,39 +41,7 @@ createPayoutOrder serviceConfig req = case serviceConfig of JuspayConfig cfg -> Juspay.createPayoutOrder cfg req StripeConfig cfg -> do connectedAccountId <- req.mConnectedAccountId & fromMaybeM (InvalidRequest "connectedAccountId required for Stripe payout") - - -- Check Fleet VA available balance and compute adjusted transfer amount if needed. - -- If fleetAvail + transferAmount < payoutAmount, top up the transfer to cover the shortfall. - let computeAdjustedTransfer = do - fleetBalance <- Stripe.getBalance cfg (Just connectedAccountId) - let fleetAvail = Stripe.getAvailableForCurrency req.currency fleetBalance - if fleetAvail + req.transferAmount >= req.amount - then pure (req.transferAmount, Nothing) - else do - let topUp = req.amount - fleetAvail - req.transferAmount - adjustedAmt = req.transferAmount + topUp - -- Verify merchant (platform) VA can cover the increased transfer - merchantBalance <- Stripe.getBalance cfg Nothing - let merchantAvail = Stripe.getAvailableForCurrency req.currency merchantBalance - when (merchantAvail < adjustedAmt) $ - throwError $ - InvalidRequest $ - "Merchant platform account has insufficient balance. Available: " - <> show merchantAvail - <> ", Required: " - <> show adjustedAmt - logInfo $ - "Fleet VA balance insufficient (available: " - <> show fleetAvail - <> "). Topping up transfer by " - <> show topUp - <> " -> adjusted transfer: " - <> show adjustedAmt - pure (adjustedAmt, Just topUp) - - (adjustedTransferAmount, merchantTopUpAmount) <- computeAdjustedTransfer - - createTransferResp <- Stripe.createTransfer cfg (mkTransferReq connectedAccountId adjustedTransferAmount req) + createTransferResp <- Stripe.createTransfer cfg (mkTransferReq connectedAccountId req) -- In case if external payout api call failed, we still need to store transferId and transferStatus result <- withTryCatch "createExternalPayout" $ Stripe.createExternalPayout cfg req createExternalPayoutResp <- case result of @@ -92,20 +60,22 @@ createPayoutOrder serviceConfig req = case serviceConfig of amount = req.amount, customerId = Just req.customerId } - pure $ mkCreatePayoutOrderResp merchantTopUpAmount createTransferResp createExternalPayoutResp + pure $ mkCreatePayoutOrderResp createTransferResp createExternalPayoutResp where - mkTransferReq :: Text -> HighPrecMoney -> CreatePayoutOrderReq -> CreateTransferReq - mkTransferReq connectedAccountId adjustedTransferAmount CreatePayoutOrderReq {..} = + mkTransferReq :: Text -> CreatePayoutOrderReq -> CreateTransferReq + mkTransferReq connectedAccountId CreatePayoutOrderReq {..} = do + let senderAccountId = TransferPlatformAccount + destinationAccount = TransferConnectedAccount connectedAccountId CreateTransferReq - { amount = adjustedTransferAmount, + { amount = transferAmount, currency, - senderAccountId = TransferPlatformAccount, - destinationAccount = TransferConnectedAccount connectedAccountId, + senderAccountId, + destinationAccount, description = Just remark } - mkCreatePayoutOrderResp :: Maybe HighPrecMoney -> CreateTransferResp -> CreateExternalPayoutResp -> CreatePayoutOrderResp - mkCreatePayoutOrderResp merchantTopUpAmount CreateTransferResp {transferId, transferStatus} CreateExternalPayoutResp {..} = + mkCreatePayoutOrderResp :: CreateTransferResp -> CreateExternalPayoutResp -> CreatePayoutOrderResp + mkCreatePayoutOrderResp CreateTransferResp {transferId, transferStatus} CreateExternalPayoutResp {..} = CreatePayoutOrderResp { orderId, status, @@ -122,8 +92,7 @@ createPayoutOrder serviceConfig req = case serviceConfig of refunds = Nothing, payments = Nothing, fulfillments = Nothing, - customerId, - merchantTopUpAmount + customerId } payoutOrderStatus :: @@ -159,8 +128,7 @@ payoutOrderStatus serviceConfig req = case serviceConfig of refunds = Nothing, payments = Nothing, fulfillments = Nothing, - customerId, - merchantTopUpAmount = Nothing + customerId } createTransfer :: diff --git a/lib/mobility-core/src/Kernel/External/Payout/Interface/Juspay.hs b/lib/mobility-core/src/Kernel/External/Payout/Interface/Juspay.hs index 76904099c..cc98021e3 100644 --- a/lib/mobility-core/src/Kernel/External/Payout/Interface/Juspay.hs +++ b/lib/mobility-core/src/Kernel/External/Payout/Interface/Juspay.hs @@ -116,7 +116,6 @@ createPayoutOrder config req = do transferStatus = Nothing, transferId = Nothing, idAssignedByServiceProvider = Nothing, - merchantTopUpAmount = Nothing, .. } @@ -151,7 +150,6 @@ payoutOrderStatus config req = do transferStatus = Nothing, transferId = Nothing, idAssignedByServiceProvider = Nothing, - merchantTopUpAmount = Nothing, .. } diff --git a/lib/mobility-core/src/Kernel/External/Payout/Interface/Stripe.hs b/lib/mobility-core/src/Kernel/External/Payout/Interface/Stripe.hs index 9f62d9744..2c286769d 100644 --- a/lib/mobility-core/src/Kernel/External/Payout/Interface/Stripe.hs +++ b/lib/mobility-core/src/Kernel/External/Payout/Interface/Stripe.hs @@ -2,8 +2,6 @@ module Kernel.External.Payout.Interface.Stripe ( createExternalPayout, externalPayoutOrderStatus, createTransfer, - getBalance, - getAvailableForCurrency, payoutStripeServiceEventWebhook, castPayoutStatus, unPayoutId, @@ -134,26 +132,6 @@ createTransfer config req = do mkCreateTransferResp :: Stripe.TransferObject -> CreateTransferResp mkCreateTransferResp Stripe.TransferObject {..} = CreateTransferResp {transferId = id, transferStatus = TRANSFERRED} -getBalance :: - ( Metrics.CoreMetrics m, - EncFlow m r, - HasRequestId r, - MonadReader r m - ) => - StripeConfig -> - Maybe Text -> - m Stripe.BalanceResp -getBalance config mbConnectedAccountId = do - apiKey <- decrypt config.apiKey - Stripe.getBalance config.url apiKey mbConnectedAccountId - --- | Extract available balance for a specific currency from a Stripe BalanceResp. --- Stripe amounts are in smallest currency unit (cents); converts to HighPrecMoney. -getAvailableForCurrency :: Currency -> Stripe.BalanceResp -> HighPrecMoney -getAvailableForCurrency currency Stripe.BalanceResp {available} = - let currencyText = T.toLower $ show currency - in sum [centsToUsd f.amount | f <- available, f.currency == currencyText] - payoutStripeServiceEventWebhook :: ( EncFlow m r, HasRequestId r, diff --git a/lib/mobility-core/src/Kernel/External/Payout/Interface/Types.hs b/lib/mobility-core/src/Kernel/External/Payout/Interface/Types.hs index 18c92d2ec..223e7b365 100644 --- a/lib/mobility-core/src/Kernel/External/Payout/Interface/Types.hs +++ b/lib/mobility-core/src/Kernel/External/Payout/Interface/Types.hs @@ -88,8 +88,7 @@ data CreatePayoutOrderResp = CreatePayoutOrderResp refunds :: Maybe [Text], payments :: Maybe [Text], fulfillments :: Maybe [Fulfillment], - customerId :: Maybe Text, - merchantTopUpAmount :: Maybe HighPrecMoney -- Stripe specific: extra amount transferred to cover Fleet VA shortfall + customerId :: Maybe Text } deriving (Show, Generic) deriving anyclass (FromJSON, ToJSON, ToSchema) diff --git a/lib/mobility-core/src/Kernel/External/Payout/Stripe/Flow.hs b/lib/mobility-core/src/Kernel/External/Payout/Stripe/Flow.hs index 06580f3bb..32589ead9 100644 --- a/lib/mobility-core/src/Kernel/External/Payout/Stripe/Flow.hs +++ b/lib/mobility-core/src/Kernel/External/Payout/Stripe/Flow.hs @@ -1,5 +1,3 @@ -{-# LANGUAGE DerivingStrategies #-} - module Kernel.External.Payout.Stripe.Flow where import qualified EulerHS.Types as Euler @@ -141,41 +139,3 @@ createTransfer url apiKey connectedAccountId transferReq = do let proxy = Proxy @CreateTransferAPI eulerClient = Euler.client proxy (PaymentFlow.mkBasicAuthData apiKey) connectedAccountId transferReq PaymentFlow.callStripeAPI url eulerClient "create-transfer" proxy - --- Balance types -data BalanceFund = BalanceFund - { amount :: Int, -- Stripe amount in smallest currency unit (e.g. cents) - currency :: Text -- lowercase currency code, e.g. "eur" - } - deriving stock (Show, Generic) - deriving anyclass (FromJSON, ToJSON) - -data BalanceResp = BalanceResp - { available :: [BalanceFund], - pending :: [BalanceFund] - } - deriving stock (Show, Generic) - deriving anyclass (FromJSON, ToJSON) - --- GET /v1/balance -type GetBalanceAPI = - "v1" - :> "balance" - :> BasicAuth "secretkey-password" BasicAuthData - :> Header "Stripe-Account" Text -- Nothing = platform account, Just accountId = connected account - :> Get '[JSON] BalanceResp - -getBalance :: - ( Metrics.CoreMetrics m, - MonadFlow m, - HasRequestId r, - MonadReader r m - ) => - BaseUrl -> - Text -> - Maybe Text -> - m BalanceResp -getBalance url apiKey connectedAccountId = do - let proxy = Proxy @GetBalanceAPI - eulerClient = Euler.client proxy (PaymentFlow.mkBasicAuthData apiKey) connectedAccountId - PaymentFlow.callStripeAPI url eulerClient "get-balance" proxy