Skip to content

Commit

Permalink
feat: added authentication details block in payment details
Browse files Browse the repository at this point in the history
  • Loading branch information
vsrivatsa-juspay committed May 23, 2024
1 parent 41b9d0d commit 25656f7
Show file tree
Hide file tree
Showing 5 changed files with 121 additions and 8 deletions.
4 changes: 2 additions & 2 deletions src/screens/Analytics/AnalyticsTypes.res
Original file line number Diff line number Diff line change
Expand Up @@ -229,7 +229,7 @@ type paymentTableType = {

type authenticationSingleStat = {
three_ds_sdk_count: int,
authentication_successful_count: int,
authentication_success_count: int,
authentication_attempt_count: int,
challenge_flow_count: int,
challenge_flow_attempt_count: int,
Expand All @@ -240,7 +240,7 @@ type authenticationSingleStat = {

type authenticationSingleStatSeries = {
three_ds_sdk_count: int,
authentication_successful_count: int,
authentication_success_count: int,
authentication_attempt_count: int,
challenge_flow_count: int,
challenge_flow_attempt_count: int,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ let domain = "auth_events"

let singleStatInitialValue = {
three_ds_sdk_count: 0,
authentication_successful_count: 0,
authentication_success_count: 0,
authentication_attempt_count: 0,
challenge_flow_count: 0,
challenge_flow_attempt_count: 0,
Expand All @@ -18,7 +18,7 @@ let singleStatInitialValue = {

let singleStatSeriesInitialValue = {
three_ds_sdk_count: 0,
authentication_successful_count: 0,
authentication_success_count: 0,
authentication_attempt_count: 0,
challenge_flow_count: 0,
challenge_flow_attempt_count: 0,
Expand All @@ -33,7 +33,7 @@ let singleStatItemToObjMapper = json => {
->JSON.Decode.object
->Option.map(dict => {
three_ds_sdk_count: dict->getInt("three_ds_sdk_count", 0),
authentication_successful_count: dict->getInt("authentication_successful_count", 0),
authentication_success_count: dict->getInt("authentication_success_count", 0),
authentication_attempt_count: dict->getInt("authentication_attempt_count", 0),
challenge_flow_count: dict->getInt("challenge_flow_count", 0),
challenge_flow_attempt_count: dict->getInt("challenge_flow_attempt_count", 0),
Expand All @@ -52,7 +52,7 @@ let singleStatSeriesItemToObjMapper = json => {
->Option.map(dict => {
time_series: dict->getString("time_bucket", ""),
three_ds_sdk_count: dict->getInt("three_ds_sdk_count", 0),
authentication_successful_count: dict->getInt("authentication_successful_count", 0),
authentication_success_count: dict->getInt("authentication_success_count", 0),
authentication_attempt_count: dict->getInt("authentication_attempt_count", 0),
challenge_flow_count: dict->getInt("challenge_flow_count", 0),
challenge_flow_attempt_count: dict->getInt("challenge_flow_attempt_count", 0),
Expand Down Expand Up @@ -122,7 +122,7 @@ let constructData = (key, singlestatTimeseriesData: array<authenticationSingleSt
singlestatTimeseriesData->Array.map(ob => {
(
ob.time_series->DateTimeUtils.parseAsFloat,
ob.authentication_successful_count->Int.toFloat *.
ob.authentication_success_count->Int.toFloat *.
100. /.
ob.authentication_attempt_count->Int.toFloat,
)
Expand Down Expand Up @@ -194,7 +194,7 @@ let getStatData = (
title: "Authentication Success Rate",
tooltipText: "Successful Authentication Requests over Total Requests.",
deltaTooltipComponent: _ => React.null,
value: singleStatData.authentication_successful_count->Int.toFloat *.
value: singleStatData.authentication_success_count->Int.toFloat *.
100.0 /.
singleStatData.authentication_attempt_count->Int.toFloat,
delta: 0.0,
Expand Down
61 changes: 61 additions & 0 deletions src/screens/Order/OrderEntity.res
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,23 @@ let getFrmCell = (orderDetais: order, frmColType: frmColType): Table.cell => {
}
}

let getAuthenticationCell = (orderDetais: order, colType: authenticationColType): Table.cell => {
let authenticationDetails =
orderDetais.external_authentication_details
->Option.getOr(JSON.Encode.null)
->getDictFromJsonObject
switch colType {
| AuthenticationFlow => Text(authenticationDetails->getString("authentication_flow", ""))
| DsTransactionId => Text(authenticationDetails->getString("ds_transaction_id", ""))
| ElectronicCommerceIndicator =>
Text(authenticationDetails->getString("electronic_commerce_indicator", ""))
| ErrorCode => Text(authenticationDetails->getString("error_code", ""))
| ErrorMessage => Text(authenticationDetails->getString("error_message", ""))
| Status => Text(authenticationDetails->getString("status", ""))
| Version => Text(authenticationDetails->getString("version", ""))
}
}

let refundColumns: array<refundsColType> = [Created, LastUpdated, Amount, PaymentId, RefundStatus]

let attemptsColumns: array<attemptColType> = [
Expand All @@ -129,6 +146,16 @@ let frmColumns: array<frmColType> = [
MerchantDecision,
]

let authenticationColumns: array<authenticationColType> = [
AuthenticationFlow,
DsTransactionId,
ElectronicCommerceIndicator,
ErrorCode,
ErrorMessage,
Status,
Version,
]

let refundDetailsFields = [
RefundId,
PaymentId,
Expand Down Expand Up @@ -252,6 +279,32 @@ let getFrmHeading = (frmDetailsColType: frmColType) => {
}
}

let getAuthenticationHeading = (authenticationDetailsColType: authenticationColType) => {
switch authenticationDetailsColType {
| AuthenticationFlow =>
Table.makeHeaderInfo(
~key="authentication_flow",
~title="Authentication Flow",
~showSort=true,
(),
)
| DsTransactionId =>
Table.makeHeaderInfo(~key="ds_transaction_id", ~title="Ds Transaction Id", ~showSort=true, ())
| ElectronicCommerceIndicator =>
Table.makeHeaderInfo(
~key="electronic_commerce_indicator",
~title="Electronic Commerce Indicator",
~showSort=true,
(),
)
| ErrorCode => Table.makeHeaderInfo(~key="error_code", ~title="Error Code", ~showSort=true, ())
| ErrorMessage =>
Table.makeHeaderInfo(~key="error_message", ~title="Error Message", ~showSort=true, ())
| Status => Table.makeHeaderInfo(~key="status", ~title="Status", ~showSort=true, ())
| Version => Table.makeHeaderInfo(~key="version", ~title="Version", ~showSort=true, ())
}
}

let refundMetaitemToObjMapper = dict => {
{
udf1: LogicUtils.getString(dict, "udf1", ""),
Expand Down Expand Up @@ -840,6 +893,14 @@ let itemToObjMapper = dict => {
| _ => None
}
},
external_authentication_details: {
let externalAuthenticationDetails =
dict->getJsonObjectFromDict("external_authentication_details")
switch externalAuthenticationDetails->JSON.Classify.classify {
| Object(_) => Some(externalAuthenticationDetails)
| _ => None
}
},
payment_token: dict->getString("payment_token", ""),
shipping: dict
->getDictfromDict("shipping")
Expand Down
10 changes: 10 additions & 0 deletions src/screens/Order/OrderTypes.res
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ type order = {
payment_method: string,
payment_method_type: string,
payment_method_data: option<JSON.t>,
external_authentication_details: option<JSON.t>,
payment_token: string,
shipping: string,
billing: string,
Expand Down Expand Up @@ -121,6 +122,15 @@ type frmColType =
| FRMMessage
| MerchantDecision

type authenticationColType =
| AuthenticationFlow
| DsTransactionId
| ElectronicCommerceIndicator
| ErrorCode
| ErrorMessage
| Status
| Version

type attemptColType =
| AttemptId
| Status
Expand Down
42 changes: 42 additions & 0 deletions src/screens/Order/ShowOrder.res
Original file line number Diff line number Diff line change
Expand Up @@ -576,6 +576,33 @@ module FraudRiskBannerDetails = {
}
}

module AuthenticationDetails = {
open OrderEntity
@react.component
let make = (~order: order) => {
<div
className="w-full bg-white dark:bg-jp-gray-lightgray_background rounded-md px-4 pb-5 h-full">
<div
className={`flex flex-wrap dark:bg-jp-gray-lightgray_background dark:border-jp-gray-no_data_border`}>
{authenticationColumns
->Array.mapWithIndex((colType, i) => {
<div className="w-1/3" key={i->Int.toString}>
<DisplayKeyValueParams
heading={getAuthenticationHeading(colType)}
value={getAuthenticationCell(order, colType)}
customMoneyStyle="!font-normal !text-sm"
labelMargin="!py-0 mt-2"
overiddingHeadingStyles="text-black text-sm font-medium"
textColor="!font-normal !text-jp-gray-700"
/>
</div>
})
->React.array}
</div>
</div>
}
}

module FraudRiskBanner = {
@react.component
let make = (~frmMessage: frmMessage, ~refElement: React.ref<Js.nullable<Dom.element>>) => {
Expand Down Expand Up @@ -837,6 +864,21 @@ let make = (~id) => {
]}
/>
</UIUtils.RenderIf>
<UIUtils.RenderIf condition={order.external_authentication_details->Option.isSome}>
<RenderAccordian
accordion={[
{
title: "External Authentication Details",
renderContent: () => {
<div className="bg-white p-2">
<AuthenticationDetails order />
</div>
},
renderContentOnTop: None,
},
]}
/>
</UIUtils.RenderIf>
<UIUtils.RenderIf condition={!(order.metadata->LogicUtils.isEmptyDict)}>
<RenderAccordian
accordion={[
Expand Down

0 comments on commit 25656f7

Please sign in to comment.