Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions lib/mobility-core/src/Kernel/External/Payment/Interface.hs
Original file line number Diff line number Diff line change
Expand Up @@ -546,7 +546,8 @@ createPayment serviceConfig mRoutingId req = case serviceConfig of
optionsGetUpiDeepLinks = req.optionsGetUpiDeepLinks,
metadataExpiryInMins = req.metadataExpiryInMins,
splitSettlementDetails = req.splitSettlementDetails,
basket = req.basket
basket = req.basket,
paymentRules = req.paymentRules
}
resp <- Juspay.createOrder cfg mRoutingId juspayReq
let clientSecret' = maybe "" (\p -> p.payload.clientAuthToken) (Just resp.sdk_payload)
Expand Down Expand Up @@ -601,7 +602,8 @@ createPayment serviceConfig mRoutingId req = case serviceConfig of
optionsGetUpiDeepLinks = req.optionsGetUpiDeepLinks,
metadataExpiryInMins = req.metadataExpiryInMins,
splitSettlementDetails = req.splitSettlementDetails,
basket = req.basket
basket = req.basket,
paymentRules = req.paymentRules
Comment on lines +605 to +606
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Check if PaytmEDC flow actually uses the paymentRules field
rg -n "paymentRules" lib/mobility-core/src/Kernel/External/Payment/PaytmEDC/

# Check the PaytmEDC sale request body structure
ast-grep --pattern 'data PaytmEDCSaleRequestBody = PaytmEDCSaleRequestBody { $$$ }'

Repository: nammayatri/shared-kernel

Length of output: 1066


🏁 Script executed:

# Check the actual code at lines 605-606 in Interface.hs
cat -n lib/mobility-core/src/Kernel/External/Payment/Interface.hs | sed -n '595,620p'

Repository: nammayatri/shared-kernel

Length of output: 1462


🏁 Script executed:

# Check what CreateOrderReq is being used for PaytmEDC
rg -n "CreateOrderReq" lib/mobility-core/src/Kernel/External/Payment/PaytmEDC/ -A 5

# Check if paymentRules is filtered or excluded for any provider
rg -n "paymentRules" lib/mobility-core/src/Kernel/External/Payment/ -B 3 -A 3

Repository: nammayatri/shared-kernel

Length of output: 3967


🏁 Script executed:

# Get the PaytmEDC Types file to understand all available request types
cat -n lib/mobility-core/src/Kernel/External/Payment/PaytmEDC/Types.hs

Repository: nammayatri/shared-kernel

Length of output: 15107


🏁 Script executed:

# Find PaytmEDCCreateOrderReq definition
rg -n "data PaytmEDCCreateOrderReq" lib/mobility-core/src/Kernel/External/Payment/ -A 20

# Check PaytmEDC implementation - how it converts the request
cat -n lib/mobility-core/src/Kernel/External/Payment/PaytmEDC/Impl.hs | head -100

Repository: nammayatri/shared-kernel

Length of output: 162


🏁 Script executed:

# Check if there's any handling of paymentRules in PaytmEDC flow
rg -n "paymentRules" lib/mobility-core/src/Kernel/External/Payment/Interface.hs -B 10 -A 3 | head -60

Repository: nammayatri/shared-kernel

Length of output: 1733


🏁 Script executed:

# Find PaytmEDCCreateOrderReq definition
rg -n "PaytmEDCCreateOrderReq" lib/mobility-core/src/Kernel/External/Payment/ -A 15

# Find PaytmEDC.createOrder implementation
rg -n "createOrder" lib/mobility-core/src/Kernel/External/Payment/PaytmEDC/ -A 10

Repository: nammayatri/shared-kernel

Length of output: 50


🏁 Script executed:

# List all PaytmEDC files
find lib/mobility-core/src/Kernel/External/Payment/PaytmEDC/ -type f -name "*.hs"

Repository: nammayatri/shared-kernel

Length of output: 326


🏁 Script executed:

# Find PaytmEDCCreateOrderReq - it might be in Interface/Types.hs
rg -n "PaytmEDCCreateOrderReq" lib/mobility-core/src/Kernel/External/Payment/Interface/Types.hs -A 20

# Check PaytmEDC Flow implementation
cat -n lib/mobility-core/src/Kernel/External/Payment/PaytmEDC/Flow.hs

Repository: nammayatri/shared-kernel

Length of output: 4392


🏁 Script executed:

# Search for PaytmEDCCreateOrderReq in Interface types
rg -n "PaytmEDCCreateOrderReq" lib/mobility-core/src/Kernel/External/Payment/Interface/Types.hs -B 2 -A 20

# Also search where createOrder is called from PaytmEDC module
rg -n "PaytmEDC.createOrder" lib/mobility-core/src/Kernel/External/Payment/ -B 3 -A 10

Repository: nammayatri/shared-kernel

Length of output: 2768


🏁 Script executed:

# Check the whole Interface.hs createPaymentOrder function around line 605
cat -n lib/mobility-core/src/Kernel/External/Payment/Interface.hs | sed -n '560,625p'

Repository: nammayatri/shared-kernel

Length of output: 3282


🏁 Script executed:

# Find PaytmEDC module with createOrder function
find lib/mobility-core/src/Kernel/External/Payment -name "*.hs" -type f | xargs grep -l "createOrder.*PaytmEDC" | head -5

# Check PaytmEDC module exports
rg -n "module.*PaytmEDC" lib/mobility-core/src/Kernel/External/Payment/ -A 30

Repository: nammayatri/shared-kernel

Length of output: 14348


🏁 Script executed:

# Search for PaytmEDC.createOrder definition
rg -n "createOrder.*::" lib/mobility-core/src/Kernel/External/Payment/PaytmEDC/ -A 15

Repository: nammayatri/shared-kernel

Length of output: 50


🏁 Script executed:

# Get the full PaytmEDC createOrder implementation
cat -n lib/mobility-core/src/Kernel/External/Payment/Interface/PaytmEDC.hs

Repository: nammayatri/shared-kernel

Length of output: 15638


Remove unused paymentRules field from PaytmEDC payment request.

The paymentRules field is passed to PaytmEDC's CreateOrderReq but is never used in the implementation. The PaytmEDC flow only extracts and sends a subset of fields to the actual API request (PaytmEDCSaleRequestBody), excluding paymentRules entirely. Unlike Juspay which actively converts this field, PaytmEDC silently ignores it. Remove it to avoid confusion and keep the request object focused on fields that are actually used.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@lib/mobility-core/src/Kernel/External/Payment/Interface.hs` around lines 605
- 606, The PaytmEDC payment request construction includes an unused field
paymentRules (seen where CreateOrderReq is assembled with basket = req.basket,
paymentRules = req.paymentRules) but PaytmEDC only serializes a
PaytmEDCSaleRequestBody and never uses paymentRules; remove the paymentRules
assignment from the CreateOrderReq construction and any type/record fields
specific to PaytmEDC that reference paymentRules, update the
CreateOrderReq/PaytmEDC request type signatures and any callers to reflect the
removed field, and ensure PaytmEDCSaleRequestBody mapping continues to include
only the actual used fields (e.g., basket and other existing fields).

}
resp <- PaytmEDC.createOrder cfg mRoutingId paytmReq
let clientSecret' = maybe "" (\p -> p.payload.clientAuthToken) (Just resp.sdk_payload)
Expand Down
36 changes: 34 additions & 2 deletions lib/mobility-core/src/Kernel/External/Payment/Interface/Juspay.hs
Original file line number Diff line number Diff line change
Expand Up @@ -324,9 +324,35 @@ mkCreateOrderReq returnUrl autoRefundConflictThresholdMinutes clientId merchantI
metadata_gateway_reference_id = metadataGatewayReferenceId,
split_settlement_details = splitDetails,
basket = decodeUtf8 . A.encode <$> basket,
auto_refund_conflict_threshold_minutes = autoRefundConflictThresholdMinutes
auto_refund_conflict_threshold_minutes = autoRefundConflictThresholdMinutes,
payment_rules = mkPaymentRules <$> paymentRules
}

mkPaymentRules :: PaymentRules -> Juspay.PaymentRules
mkPaymentRules PaymentRules {..} =
Juspay.PaymentRules
{ payment_flows = mkPaymentFlows paymentFlows
}

mkPaymentFlows :: PaymentFlows -> Juspay.PaymentFlows
mkPaymentFlows PaymentFlows {..} =
Juspay.PaymentFlows
{ loyalty_os_topup = mkPaymentFlowStatus loyaltyOsTopup
}

mkPaymentFlowStatus :: PaymentFlowStatus -> Juspay.PaymentFlowStatus
mkPaymentFlowStatus PaymentFlowStatus {..} =
Juspay.PaymentFlowStatus
{ status = status,
info = mkPaymentFlowInfo <$> info
}

mkPaymentFlowInfo :: PaymentFlowInfo -> Juspay.PaymentFlowInfo
mkPaymentFlowInfo PaymentFlowInfo {..} =
Juspay.PaymentFlowInfo
{ program_id = programId
}

mkSplitSettlementDetails :: (MonadThrow m, Log m) => SplitSettlementDetails -> m Juspay.SplitSettlementDetails
mkSplitSettlementDetails splitDetails = do
let result = case splitDetails of
Expand Down Expand Up @@ -472,6 +498,8 @@ mkOrderStatusResp Juspay.OrderData {..} =
splitSettlementResponse = mkSplitSettlementResponse <$> split_settlement_response,
offers = maybe Nothing mkOffersData offers,
txnDetail = castTxnDetail <$> txn_detail,
loyaltyInfo = loyalty_info,
txnList = txn_list,
..
}

Expand All @@ -482,7 +510,7 @@ castCard :: Juspay.CardInfo -> CardInfo
castCard Juspay.CardInfo {..} = CardInfo {cardType = card_type, lastFourDigits = last_four_digits, nameOnCard = name_on_card, cardBrand = card_brand, cardIsin = card_isin, cardIssuer = card_issuer}

castTxnDetail :: Juspay.TxnDetail -> TxnDetail
castTxnDetail Juspay.TxnDetail {..} = TxnDetail {gateway = gateway, surchargeAmount = realToFrac <$> surcharge_amount, taxAmount = realToFrac <$> tax_amount, netAmount = realToFrac <$> net_amount}
castTxnDetail Juspay.TxnDetail {..} = TxnDetail {..}

mkNotificationReq :: MandateNotificationReq -> Juspay.MandateNotificationReq
mkNotificationReq mandateNotificationReq =
Expand Down Expand Up @@ -646,6 +674,8 @@ mkWebhookOrderStatusResp now (eventName, Juspay.OrderAndNotificationStatusConten
splitSettlementResponse = mkSplitSettlementResponse <$> justOrder.split_settlement_response,
offers = maybe Nothing mkOffersData justOrder.offers,
txnDetail = castTxnDetail <$> justOrder.txn_detail,
loyaltyInfo = justOrder.loyalty_info,
txnList = justOrder.txn_list,
..
}
(Nothing, Just justMandate, _, _) ->
Expand Down Expand Up @@ -701,6 +731,8 @@ mkWebhookOrderStatusResp now (eventName, Juspay.OrderAndNotificationStatusConten
effectiveAmount = Just $ realToFrac justTransaction.txn_amount,
offers = Nothing,
txnDetail = castTxnDetail <$> justTransaction.txn_detail,
loyaltyInfo = Nothing,
txnList = Nothing, --Not Sure
..
}
(_, _, Nothing, _) -> BadStatusResp
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -339,5 +339,7 @@ mkOrderStatusResp response orderId =
splitSettlementResponse = Nothing,
effectiveAmount = Nothing,
offers = Nothing,
txnDetail = Nothing
txnDetail = Nothing,
loyaltyInfo = respBody.loyaltyInfo,
txnList = respBody.txnDetails
}
60 changes: 45 additions & 15 deletions lib/mobility-core/src/Kernel/External/Payment/Interface/Types.hs
Original file line number Diff line number Diff line change
Expand Up @@ -17,18 +17,19 @@
{-# OPTIONS_GHC -Wwarn=incomplete-record-updates #-}

module Kernel.External.Payment.Interface.Types
( module Kernel.External.Payment.Interface.Types,
module Reexport,
( module Reexport,
module Kernel.External.Payment.Interface.Types,
)
where

import Control.Lens
import Data.Aeson.Types
import Data.OpenApi hiding (description, email, name, title)
-- import qualified Data.Map as Map
import Data.OpenApi hiding (description, email, info, name, title)
import Data.Time
import Kernel.Beam.Lib.UtilsTH (mkBeamInstancesForEnum)
import qualified Kernel.External.Payment.Juspay.Config as Juspay
import Kernel.External.Payment.Juspay.Types as Reexport (CreateOrderResp (..), MandateFrequency (..), MandateStatus (..), MandateType (..), NotificationStatus (..), OfferListStatus (..), OfferState (..), OfferStatus (..), PaymentLinks (..), PaymentStatus (..), TransactionStatus (..))
import Kernel.External.Payment.Juspay.Types as Reexport (CreateOrderResp (..), LoyaltyBurnApplicable (..), LoyaltyBurnDetail (..), LoyaltyBurnIneligibleReason (..), LoyaltyBurnOptionSelected (..), LoyaltyEarnApplied (..), LoyaltyEarnCampaign (..), LoyaltyEarnDetail (..), LoyaltyInfo (..), MandateFrequency (..), MandateStatus (..), MandateType, NotificationStatus (..), OfferListStatus (..), OfferState (..), OfferStatus (..), PaymentLinks (..), PaymentStatus (..), TransactionStatus (..), TxnAmountBreakup (..), TxnDetail (..), TxnList (..))
import qualified Kernel.External.Payment.PaytmEDC.Config as PaytmEDC
import qualified Kernel.External.Payment.Stripe.Config as Stripe
import Kernel.External.Payment.Stripe.Types as Reexport hiding (RefundStatus (..))
Expand Down Expand Up @@ -89,7 +90,33 @@ data CreateOrderReq = CreateOrderReq
optionsGetUpiDeepLinks :: Maybe Bool,
metadataExpiryInMins :: Maybe Int,
splitSettlementDetails :: Maybe SplitSettlementDetails,
basket :: Maybe [Basket]
basket :: Maybe [Basket],
paymentRules :: Maybe PaymentRules
}
deriving stock (Show, Eq, Generic)
deriving anyclass (FromJSON, ToJSON, ToSchema)

data PaymentRules = PaymentRules
{ paymentFlows :: PaymentFlows
}
deriving stock (Show, Eq, Generic)
deriving anyclass (FromJSON, ToJSON, ToSchema)

data PaymentFlows = PaymentFlows
{ loyaltyOsTopup :: PaymentFlowStatus
}
deriving stock (Show, Eq, Generic)
deriving anyclass (FromJSON, ToJSON, ToSchema)

data PaymentFlowStatus = PaymentFlowStatus
{ status :: Text,
info :: Maybe PaymentFlowInfo
}
deriving stock (Show, Eq, Generic)
deriving anyclass (FromJSON, ToJSON, ToSchema)

newtype PaymentFlowInfo = PaymentFlowInfo
{ programId :: Text
}
deriving stock (Show, Eq, Generic)
deriving anyclass (FromJSON, ToJSON, ToSchema)
Expand Down Expand Up @@ -229,7 +256,9 @@ data OrderStatusResp
splitSettlementResponse :: Maybe SplitSettlementResponse,
effectiveAmount :: Maybe HighPrecMoney,
offers :: Maybe [Offer],
txnDetail :: Maybe TxnDetail
txnDetail :: Maybe TxnDetail,
loyaltyInfo :: Maybe LoyaltyInfo,
txnList :: Maybe [TxnList]
}
| MandateOrderStatusResp
{ eventName :: Maybe PaymentStatus,
Expand Down Expand Up @@ -323,14 +352,14 @@ data CardInfo = CardInfo
deriving stock (Show, Read, Eq, Generic)
deriving anyclass (FromJSON, ToJSON, ToSchema)

data TxnDetail = TxnDetail
{ gateway :: Maybe Text,
surchargeAmount :: Maybe HighPrecMoney,
taxAmount :: Maybe HighPrecMoney,
netAmount :: Maybe HighPrecMoney
}
deriving stock (Show, Read, Eq, Generic)
deriving anyclass (FromJSON, ToJSON, ToSchema)
-- data TxnDetail = TxnDetail
-- { gateway :: Maybe Text,
-- surchargeAmount :: Maybe HighPrecMoney,
-- taxAmount :: Maybe HighPrecMoney,
-- netAmount :: Maybe HighPrecMoney
-- }
-- deriving stock (Show, Read, Eq, Generic)
-- deriving anyclass (FromJSON, ToJSON, ToSchema)

-- notification request --
data MandateNotificationReq = MandateNotificationReq
Expand Down Expand Up @@ -828,7 +857,8 @@ data CreatePaymentReq = CreatePaymentReq
metadataGatewayReferenceId :: Maybe Text,
optionsGetUpiDeepLinks :: Maybe Bool,
metadataExpiryInMins :: Maybe Int,
basket :: Maybe [Basket]
basket :: Maybe [Basket],
paymentRules :: Maybe PaymentRules
}
deriving stock (Show, Eq, Generic)
deriving anyclass (FromJSON, ToJSON, ToSchema)
Expand Down
Loading
Loading