Skip to content

Commit 692b603

Browse files
backend/feat/euler-wallets
1 parent bf55452 commit 692b603

10 files changed

Lines changed: 533 additions & 13 deletions

File tree

lib/mobility-core/mobility-core.cabal

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,7 @@ library
159159
Kernel.External.Payment.Juspay.Types.Mandate
160160
Kernel.External.Payment.Juspay.Types.Offer
161161
Kernel.External.Payment.Juspay.Types.UpdateOrder
162+
Kernel.External.Payment.Juspay.Types.Wallet
162163
Kernel.External.Payment.Juspay.Types.Webhook
163164
Kernel.External.Payment.Juspay.Webhook
164165
Kernel.External.Payment.Stripe.Config

lib/mobility-core/src/Kernel/External/Payment/Interface.hs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,32 @@ orderStatus serviceConfig mRoutingId req = case serviceConfig of
5757
JuspayConfig cfg -> Juspay.orderStatus cfg mRoutingId req
5858
StripeConfig _ -> throwError $ InternalError "Stripe Order Status not supported."
5959

60+
createWallet ::
61+
( EncFlow m r,
62+
CoreMetrics m,
63+
HasRequestId r,
64+
MonadReader r m
65+
) =>
66+
PaymentServiceConfig ->
67+
CreateWalletReq ->
68+
m CreateWalletResp
69+
createWallet serviceConfig req = case serviceConfig of
70+
JuspayConfig cfg -> Juspay.createWallet cfg req
71+
StripeConfig _ -> throwError $ InternalError "Stripe Create Wallet not supported."
72+
73+
refreshWallet ::
74+
( EncFlow m r,
75+
CoreMetrics m,
76+
HasRequestId r,
77+
MonadReader r m
78+
) =>
79+
PaymentServiceConfig ->
80+
RefreshWalletReq ->
81+
m RefreshWalletResp
82+
refreshWallet serviceConfig req = case serviceConfig of
83+
JuspayConfig cfg -> Juspay.refreshWallet cfg req
84+
StripeConfig _ -> throwError $ InternalError "Stripe Refresh Wallet not supported."
85+
6086
updateOrder ::
6187
( EncFlow m r,
6288
CoreMetrics m,

lib/mobility-core/src/Kernel/External/Payment/Interface/Juspay.hs

Lines changed: 177 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515
module Kernel.External.Payment.Interface.Juspay
1616
( module Reexport,
1717
createOrder,
18+
createWallet,
19+
refreshWallet,
1820
createCustomer,
1921
getCustomer,
2022
orderStatus,
@@ -80,6 +82,34 @@ createOrder config mRoutingId req = do
8082
logDebug $ "createOrder splitSettlementDetails: " <> show req.splitSettlementDetails
8183
Juspay.createOrder url apiKey merchantId mRoutingId orderReq
8284

85+
createWallet ::
86+
( Metrics.CoreMetrics m,
87+
EncFlow m r,
88+
HasRequestId r,
89+
MonadReader r m
90+
) =>
91+
JuspayCfg ->
92+
CreateWalletReq ->
93+
m CreateWalletResp
94+
createWallet config req = do
95+
let url = config.url
96+
apiKey <- decrypt config.apiKey
97+
fromJuspayCreateWalletResp <$> Juspay.createWallet url apiKey req.customerId (mkCreateWalletReq config req)
98+
99+
refreshWallet ::
100+
( Metrics.CoreMetrics m,
101+
EncFlow m r,
102+
HasRequestId r,
103+
MonadReader r m
104+
) =>
105+
JuspayCfg ->
106+
RefreshWalletReq ->
107+
m RefreshWalletResp
108+
refreshWallet config req = do
109+
let url = config.url
110+
apiKey <- decrypt config.apiKey
111+
fromJuspayRefreshWalletResp <$> Juspay.refreshWallet url apiKey req.walletId (mkRefreshWalletReq req)
112+
83113
updateOrder ::
84114
( Metrics.CoreMetrics m,
85115
EncFlow m r,
@@ -295,6 +325,74 @@ mandateRevoke config mRoutingId req = do
295325
void $ Juspay.mandateRevoke url apiKey merchantId mRoutingId req.mandateId Juspay.MandateRevokeReq {command = "revoke"}
296326
return Success
297327

328+
fromJuspayAuthParams :: Juspay.AuthParams -> WalletAuthParams
329+
fromJuspayAuthParams Juspay.AuthParams {..} =
330+
WalletAuthParams
331+
{ isResendAllowed = is_resend_allowed,
332+
resendWaitTime = resend_wait_time,
333+
isOtpRequired = is_otp_required,
334+
isSubmitAllowed = is_submit_allowed
335+
}
336+
337+
fromJuspaySubDetail :: Juspay.SubDetail -> WalletSubDetail
338+
fromJuspaySubDetail Juspay.SubDetail {..} =
339+
WalletSubDetail
340+
{ currentBalance = (readMaybe . T.unpack) =<< current_balance,
341+
lastRefreshed = last_refreshed,
342+
paymentMethod = payment_method,
343+
paymentMethodType = payment_method_type
344+
}
345+
346+
fromJuspayCreateWalletResp :: Juspay.CreateWalletResp -> CreateWalletResp
347+
fromJuspayCreateWalletResp Juspay.CreateWalletResp {..} =
348+
CreateWalletResp
349+
{ token = token,
350+
linked = linked,
351+
id = id,
352+
currentBalance = (readMaybe . T.unpack) =<< current_balance,
353+
wallet = wallet,
354+
authParams = fmap fromJuspayAuthParams auth_params,
355+
lastRefreshed = last_refreshed,
356+
subDetails = map fromJuspaySubDetail sub_details,
357+
object = object
358+
}
359+
360+
mkCreateWalletReq :: JuspayCfg -> CreateWalletReq -> Juspay.CreateWalletReq
361+
mkCreateWalletReq config CreateWalletReq {..} =
362+
Juspay.CreateWalletReq
363+
{ command = command,
364+
device_id = fromMaybe "" deviceId,
365+
gateway = fromMaybe "" config.walletGateway,
366+
payment_method = fromMaybe "" config.walletPaymentMethod,
367+
gateway_reference_id = fromMaybe "" config.gatewayReferenceId
368+
}
369+
370+
fromJuspayRefreshSubDetail :: Juspay.RefreshSubDetail -> RefreshWalletSubDetail
371+
fromJuspayRefreshSubDetail Juspay.RefreshSubDetail {..} =
372+
RefreshWalletSubDetail
373+
{ currentBalance = realToFrac <$> current_balance,
374+
lastRefreshed = last_refreshed,
375+
paymentMethod = payment_method,
376+
paymentMethodType = payment_method_type
377+
}
378+
379+
fromJuspayRefreshWalletResp :: Juspay.RefreshWalletResp -> RefreshWalletResp
380+
fromJuspayRefreshWalletResp Juspay.RefreshWalletResp {..} =
381+
RefreshWalletResp
382+
{ token = token,
383+
linked = linked,
384+
id = id,
385+
currentBalance = realToFrac <$> current_balance,
386+
wallet = wallet,
387+
lastRefreshed = last_refreshed,
388+
subDetails = map fromJuspayRefreshSubDetail sub_details,
389+
object = object
390+
}
391+
392+
mkRefreshWalletReq :: RefreshWalletReq -> Juspay.RefreshWalletReq
393+
mkRefreshWalletReq RefreshWalletReq {..} =
394+
Juspay.RefreshWalletReq {command = command}
395+
298396
mkCreateOrderReq :: (MonadTime m, MonadThrow m, Log m) => BaseUrl -> Maybe Int -> Text -> Text -> CreateOrderReq -> m Juspay.CreateOrderReq
299397
mkCreateOrderReq returnUrl autoRefundConflictThresholdMinutes clientId merchantId CreateOrderReq {..} =
300398
do
@@ -324,9 +422,35 @@ mkCreateOrderReq returnUrl autoRefundConflictThresholdMinutes clientId merchantI
324422
metadata_gateway_reference_id = metadataGatewayReferenceId,
325423
split_settlement_details = splitDetails,
326424
basket = decodeUtf8 . A.encode <$> basket,
327-
auto_refund_conflict_threshold_minutes = autoRefundConflictThresholdMinutes
425+
auto_refund_conflict_threshold_minutes = autoRefundConflictThresholdMinutes,
426+
payment_rules = mkPaymentRules <$> paymentRules
328427
}
329428

429+
mkPaymentRules :: PaymentRules -> Juspay.PaymentRules
430+
mkPaymentRules PaymentRules {..} =
431+
Juspay.PaymentRules
432+
{ payment_flows = mkPaymentFlows paymentFlows
433+
}
434+
435+
mkPaymentFlows :: PaymentFlows -> Juspay.PaymentFlows
436+
mkPaymentFlows PaymentFlows {..} =
437+
Juspay.PaymentFlows
438+
{ load_money = mkLoadMoney loadMoney
439+
}
440+
441+
mkLoadMoney :: LoadMoney -> Juspay.LoadMoney
442+
mkLoadMoney LoadMoney {..} =
443+
Juspay.LoadMoney
444+
{ status = status,
445+
info = mkLoadMoneyInfo info
446+
}
447+
448+
mkLoadMoneyInfo :: LoadMoneyInfo -> Juspay.LoadMoneyInfo
449+
mkLoadMoneyInfo LoadMoneyInfo {..} =
450+
Juspay.LoadMoneyInfo
451+
{ wallet_id = walletId
452+
}
453+
330454
mkSplitSettlementDetails :: (MonadThrow m, Log m) => SplitSettlementDetails -> m Juspay.SplitSettlementDetails
331455
mkSplitSettlementDetails splitDetails = do
332456
let result = case splitDetails of
@@ -429,7 +553,8 @@ mkOrderStatusResp Juspay.OrderData {..} =
429553
payerVpa = payer_vpa,
430554
upi = castUpi <$> upi,
431555
refunds = maybe [] mkRefundsData refunds,
432-
amountRefunded = realToFrac <$> amount_refunded
556+
amountRefunded = realToFrac <$> amount_refunded,
557+
txnList = fmap (map mkTxnData) txn_list
433558
}
434559
Nothing -> do
435560
let (isRetriedOrder, retargetPaymentLink, retargetPaymentLinkExpiry, isRetargetedOrder) = parseRetargetAndRetryData metadata links additional_info
@@ -464,14 +589,18 @@ mkOrderStatusResp Juspay.OrderData {..} =
464589
bankErrorMessage = if bank_error_message == Just "" then Nothing else bank_error_message,
465590
bankErrorCode = if bank_error_code == Just "" then Nothing else bank_error_code,
466591
dateCreated = date_created,
592+
isRetriedOrder = isRetriedOrder,
593+
isRetargetedOrder = isRetargetedOrder,
594+
retargetPaymentLink = retargetPaymentLink,
595+
retargetPaymentLinkExpiry = retargetPaymentLinkExpiry,
467596
refunds = maybe [] mkRefundsData refunds,
468597
amountRefunded = realToFrac <$> amount_refunded,
469598
payerVpa = payer_vpa,
470599
upi = castUpi <$> upi,
471600
card = castCard <$> card,
472601
splitSettlementResponse = mkSplitSettlementResponse <$> split_settlement_response,
473602
offers = maybe Nothing mkOffersData offers,
474-
..
603+
txnList = fmap (map mkTxnData) txn_list
475604
}
476605

477606
castUpi :: Juspay.Upi -> Upi
@@ -480,6 +609,39 @@ castUpi Juspay.Upi {..} = Upi {payerApp = payer_app, payerAppName = payer_app_na
480609
castCard :: Juspay.CardInfo -> CardInfo
481610
castCard Juspay.CardInfo {..} = CardInfo {cardType = card_type, lastFourDigits = last_four_digits}
482611

612+
mkTxnData :: Juspay.TxnData -> TxnData
613+
mkTxnData Juspay.TxnData {..} =
614+
TxnData
615+
{ txnUuid = txn_uuid,
616+
txnId = txn_id,
617+
transactionStatus = status,
618+
paymentMethodType = payment_method_type,
619+
paymentMethod = payment_method,
620+
paymentGatewayResponse =
621+
payment_gateway_response
622+
<&> ( \pgResp ->
623+
PaymentGatewayResponse
624+
{ respCode = pgResp.resp_code,
625+
rrn = pgResp.rrn,
626+
created = pgResp.created,
627+
epgTxnId = pgResp.epg_txn_id,
628+
respMessage = pgResp.resp_message,
629+
authIdCode = pgResp.auth_id_code,
630+
txnId = pgResp.txn_id
631+
}
632+
),
633+
respMessage = resp_message,
634+
respCode = resp_code,
635+
gatewayReferenceId = gateway_reference_id,
636+
bankErrorCode = if bank_error_code == Just "" then Nothing else bank_error_code,
637+
bankErrorMessage = if bank_error_message == Just "" then Nothing else bank_error_message,
638+
upi = castUpi <$> upi,
639+
card = castCard <$> card,
640+
metadata = metadata,
641+
effectiveAmount = realToFrac <$> effective_amount,
642+
offers = maybe Nothing mkOffersData offers
643+
}
644+
483645
mkNotificationReq :: MandateNotificationReq -> Juspay.MandateNotificationReq
484646
mkNotificationReq mandateNotificationReq =
485647
Juspay.MandateNotificationReq
@@ -599,7 +761,8 @@ mkWebhookOrderStatusResp now (eventName, Juspay.OrderAndNotificationStatusConten
599761
payerVpa = justOrder.payer_vpa,
600762
upi = castUpi <$> justOrder.upi,
601763
refunds = maybe [] mkRefundsData justOrder.refunds,
602-
amountRefunded = realToFrac <$> justOrder.amount_refunded -- not adding split
764+
amountRefunded = realToFrac <$> justOrder.amount_refunded,
765+
txnList = fmap (map mkTxnData) justOrder.txn_list
603766
}
604767
Nothing -> do
605768
let (isRetriedOrder, retargetPaymentLink, retargetPaymentLinkExpiry, isRetargetedOrder) = parseRetargetAndRetryData justOrder.metadata justOrder.links justOrder.additional_info
@@ -634,14 +797,18 @@ mkWebhookOrderStatusResp now (eventName, Juspay.OrderAndNotificationStatusConten
634797
effectiveAmount = realToFrac <$> justOrder.effective_amount,
635798
currency = justOrder.currency,
636799
dateCreated = justOrder.date_created,
800+
isRetriedOrder = isRetriedOrder,
801+
isRetargetedOrder = isRetargetedOrder,
802+
retargetPaymentLink = retargetPaymentLink,
803+
retargetPaymentLinkExpiry = retargetPaymentLinkExpiry,
637804
refunds = maybe [] mkRefundsData justOrder.refunds,
638805
amountRefunded = realToFrac <$> justOrder.amount_refunded,
639806
payerVpa = justOrder.payer_vpa,
640807
upi = castUpi <$> justOrder.upi,
641808
card = castCard <$> justOrder.card,
642809
splitSettlementResponse = mkSplitSettlementResponse <$> justOrder.split_settlement_response,
643810
offers = maybe Nothing mkOffersData justOrder.offers,
644-
..
811+
txnList = fmap (map mkTxnData) justOrder.txn_list
645812
}
646813
(Nothing, Just justMandate, _, _) ->
647814
MandateStatusResp
@@ -695,7 +862,11 @@ mkWebhookOrderStatusResp now (eventName, Juspay.OrderAndNotificationStatusConten
695862
splitSettlementResponse = Nothing,
696863
effectiveAmount = Just $ realToFrac justTransaction.txn_amount,
697864
offers = Nothing,
698-
..
865+
isRetriedOrder = isRetriedOrder,
866+
isRetargetedOrder = isRetargetedOrder,
867+
retargetPaymentLink = retargetPaymentLink,
868+
retargetPaymentLinkExpiry = retargetPaymentLinkExpiry,
869+
txnList = Nothing
699870
}
700871
(_, _, Nothing, _) -> BadStatusResp
701872

0 commit comments

Comments
 (0)