Skip to content

Commit

Permalink
Merge branch 'main' into merchant-search
Browse files Browse the repository at this point in the history
  • Loading branch information
kanikabansal-juspay authored Feb 24, 2025
2 parents 213fedd + 1a0c94d commit 61f7798
Show file tree
Hide file tree
Showing 11 changed files with 297 additions and 26 deletions.
18 changes: 18 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,24 @@ All notable changes to this project will be documented in this file. See [conven

- - -

## 2025.02.24.0

### Features

- Added attempts table to revenue order details ([#2305](https://github.com/juspay/hyperswitch-control-center/pull/2305)) ([`2a6f34d`](https://github.com/juspay/hyperswitch-control-center/commit/2a6f34db1015dd4bf1d6c34a08e59fcc8b55e7ea))

### Testing

- Fix failing connector test ([#2310](https://github.com/juspay/hyperswitch-control-center/pull/2310)) ([`50e3bfc`](https://github.com/juspay/hyperswitch-control-center/commit/50e3bfc34acaf8cee00e3a193878e79be5fbd66d))

### Miscellaneous Tasks

- Implement v2 connector type ([#2315](https://github.com/juspay/hyperswitch-control-center/pull/2315)) ([`e061d8b`](https://github.com/juspay/hyperswitch-control-center/commit/e061d8ba15a8d4e83145d37377b89e1aec7c36d7))

**Full Changelog:** [`2025.02.20.0...2025.02.24.0`](https://github.com/juspay/hyperswitch-control-center/compare/2025.02.20.0...2025.02.24.0)

- - -

## 2025.02.20.0

### Features
Expand Down
2 changes: 2 additions & 0 deletions cypress/e2e/4-connectors/connector.cy.js
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,7 @@ describe("connector", () => {
cy.get("[data-testid=operations]").click();
cy.get("[data-testid=payments]").click();
cy.contains("Payment Operations").should("be.visible");
cy.get("span").contains("...").click();
cy.get("[data-table-location=Orders_tr1_td2]")
.invoke("text")
.then((expectedPaymentId) => {
Expand All @@ -219,6 +220,7 @@ describe("connector", () => {
.click()
.type(`${expectedPaymentId}{enter}`);
cy.get("[data-table-location=Orders_tr1_td1]").should("exist");
cy.get("span").contains("...").click();
cy.get("[data-table-location=Orders_tr1_td2]")
.invoke("text")
.should((actualPaymentId) => {
Expand Down
36 changes: 36 additions & 0 deletions src/Interface/ConnectorInterface/ConnectorInterface.res
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
open ConnectorTypes
open ConnectorInterfaceUtils
module type ConnectorMappperType = {
type output
let getProcessorPayloadType: Dict.t<JSON.t> => output
}

module V1: ConnectorMappperType with type output = connectorPayload = {
type output = connectorPayload
let getProcessorPayloadType = (dict: Dict.t<JSON.t>) => getProcessorPayloadType(dict)
}

module V2: ConnectorMappperType with type output = connectorPayloadV2 = {
type output = connectorPayloadV2
let getProcessorPayloadType = (dict: Dict.t<JSON.t>) => getProcessorPayloadTypeV2(dict)
}

type connectorMapper<'a> = module(ConnectorMappperType with type output = 'a)

let connectorMapperV1: connectorMapper<connectorPayload> = module(V1)
let connectorMapperV2: connectorMapper<connectorPayloadV2> = module(V2)

let getConnectorMapper = (type t, mapperModule: connectorMapper<t>, dict: Dict.t<JSON.t>): t => {
module L = unpack(mapperModule) // Extract the module
L.getProcessorPayloadType(dict) // Call the function
}

let useConnectorMapper = (type t, mapperModule: connectorMapper<t>, dict: Dict.t<JSON.t>): t => {
getConnectorMapper(mapperModule, dict)
}
// Example

let result1 = useConnectorMapper(connectorMapperV1, Dict.make())
let result2 = useConnectorMapper(connectorMapperV2, Dict.make())

let result3 = getConnectorMapper(connectorMapperV1, Dict.make())
211 changes: 211 additions & 0 deletions src/Interface/ConnectorInterface/ConnectorInterfaceUtils.res
Original file line number Diff line number Diff line change
@@ -0,0 +1,211 @@
open ConnectorTypes
open LogicUtils
let connectorAuthTypeMapper = (str): connectorAuthType => {
switch str->String.toLowerCase {
| "headerkey" => HeaderKey
| "bodykey" => BodyKey
| "signaturekey" => SignatureKey
| "multiauthkey" => MultiAuthKey
| "currencyauthkey" => CurrencyAuthKey
| "certificateauth" => CertificateAuth
| _ => UnKnownAuthType
}
}

let getHeaderAuth = (dict): headerKey => {
auth_type: dict->getString("auth_type", ""),
api_key: dict->getString("api_key", ""),
}
let getBodyKeyAuth = (dict): bodyKey => {
auth_type: dict->getString("auth_type", ""),
api_key: dict->getString("api_key", ""),
key1: dict->getString("key1", ""),
}
let getSignatureKeyAuth = (dict): signatureKey => {
auth_type: dict->getString("auth_type", ""),
api_key: dict->getString("api_key", ""),
key1: dict->getString("key1", ""),
api_secret: dict->getString("api_secret", ""),
}
let getMultiAuthKeyAuth = (dict): multiAuthKey => {
auth_type: dict->getString("auth_type", ""),
api_key: dict->getString("api_key", ""),
key1: dict->getString("key1", ""),
api_secret: dict->getString("api_secret", ""),
key2: dict->getString("key2", ""),
}

let getCurrencyAuthKey = (dict): currencyAuthKey => {
auth_type: dict->getString("auth_type", ""),
auth_key_map: dict->getDictfromDict("auth_key_map"),
}
let getCertificateAuth = (dict): certificateAuth => {
auth_type: dict->getString("auth_type", ""),
certificate: dict->getString("certificate", ""),
private_key: dict->getString("private_key", ""),
}

let getAccountDetails = (dict): connectorAuthTypeObj => {
let authType = dict->getString("auth_type", "")->connectorAuthTypeMapper
switch authType {
| HeaderKey => HeaderKey(dict->getHeaderAuth)
| BodyKey => BodyKey(dict->getBodyKeyAuth)
| SignatureKey => SignatureKey(dict->getSignatureKeyAuth)
| MultiAuthKey => MultiAuthKey(dict->getMultiAuthKeyAuth)
| CurrencyAuthKey => CurrencyAuthKey(dict->getCurrencyAuthKey)
| CertificateAuth => CertificateAuth(dict->getCertificateAuth)
| UnKnownAuthType => UnKnownAuthType(JSON.Encode.null)
}
}

let parsePaymentMethodType = paymentMethodType => {
let paymentMethodTypeDict = paymentMethodType->getDictFromJsonObject
{
payment_method_type: paymentMethodTypeDict->getString("payment_method_type", ""),
flow: paymentMethodTypeDict->getString("flow", ""),
action: paymentMethodTypeDict->getString("action", ""),
}
}
let parsePaymentMethodResponse = paymentMethod => {
let paymentMethodDict = paymentMethod->getDictFromJsonObject
let payment_method_types =
paymentMethodDict
->getArrayFromDict("payment_method_types", [])
->Array.map(parsePaymentMethodType)

let flow = paymentMethodDict->getString("flow", "")

{
payment_method: paymentMethodDict->getString("payment_method", ""),
payment_method_types,
flow,
}
}

let parsePaymentMethod = paymentMethod => {
let paymentMethodDict = paymentMethod->getDictFromJsonObject
let flow = paymentMethodDict->getString("flow", "")

{
payment_method: paymentMethodDict->getString("payment_method", ""),
flow,
}
}

let convertFRMConfigJsonToObjResponse = json => {
json->Array.map(config => {
let configDict = config->getDictFromJsonObject
let payment_methods =
configDict->getArrayFromDict("payment_methods", [])->Array.map(parsePaymentMethodResponse)

{
gateway: configDict->getString("gateway", ""),
payment_methods,
}
})
}

let convertFRMConfigJsonToObj = json => {
json->Array.map(config => {
let configDict = config->getDictFromJsonObject
let payment_methods =
configDict->getArrayFromDict("payment_methods", [])->Array.map(parsePaymentMethod)

{
gateway: configDict->getString("gateway", ""),
payment_methods,
}
})
}

let getPaymentMethodTypes = dict => {
open ConnectorUtils
{
payment_method_type: dict->getString("payment_method_type", ""),
payment_experience: dict->getOptionString("payment_experience"),
card_networks: dict->getStrArrayFromDict("card_networks", []),
accepted_countries: dict->getDictfromDict("accepted_countries")->acceptedValues,
accepted_currencies: dict->getDictfromDict("accepted_currencies")->acceptedValues,
minimum_amount: dict->getOptionInt("minimum_amount"),
maximum_amount: dict->getOptionInt("maximum_amount"),
recurring_enabled: dict->getOptionBool("recurring_enabled"),
installment_payment_enabled: dict->getOptionBool("installment_payment_enabled"),
}
}

let getPaymentMethodsEnabled: Dict.t<JSON.t> => paymentMethodEnabledType = dict => {
{
payment_method: dict->getString("payment_method", ""),
payment_method_types: dict
->Dict.get("payment_method_types")
->Option.getOr(Dict.make()->JSON.Encode.object)
->getArrayDataFromJson(getPaymentMethodTypes),
}
}

let getProcessorPayloadType = (dict): connectorPayload => {
{
connector_type: dict
->getString("connector_type", "")
->ConnectorUtils.connectorTypeStringToTypeMapper,
connector_name: dict->getString("connector_name", ""),
connector_label: dict->getString("connector_label", ""),
connector_account_details: dict
->getObj("connector_account_details", Dict.make())
->getAccountDetails,
test_mode: dict->getBool("test_mode", true),
disabled: dict->getBool("disabled", true),
payment_methods_enabled: dict
->Dict.get("payment_methods_enabled")
->Option.getOr(Dict.make()->JSON.Encode.object)
->getArrayDataFromJson(getPaymentMethodsEnabled),
profile_id: dict->getString("profile_id", ""),
merchant_connector_id: dict->getString("merchant_connector_id", ""),
frm_configs: dict->getArrayFromDict("frm_configs", [])->convertFRMConfigJsonToObjResponse,
status: dict->getString("status", "inactive"),
connector_webhook_details: dict
->Dict.get("connector_webhook_details")
->Option.getOr(JSON.Encode.null),
metadata: dict->getObj("metadata", Dict.make())->JSON.Encode.object,
additional_merchant_data: dict
->getObj("additional_merchant_data", Dict.make())
->JSON.Encode.object,
}
}

let getPaymentMethodsEnabledV2: Dict.t<JSON.t> => paymentMethodEnabledTypeV2 = dict => {
{
payment_method_type: dict->getString("payment_method_type", ""),
payment_method_subtypes: dict
->Dict.get("payment_method_types")
->Option.getOr(Dict.make()->JSON.Encode.object)
->getArrayDataFromJson(getPaymentMethodTypes),
}
}

let getProcessorPayloadTypeV2 = (dict): connectorPayloadV2 => {
{
connector_type: dict
->getString("connector_type", "")
->ConnectorUtils.connectorTypeStringToTypeMapper,
connector_name: dict->getString("connector_name", ""),
connector_label: dict->getString("connector_label", ""),
connector_account_details: dict
->getObj("connector_account_details", Dict.make())
->getAccountDetails,
test_mode: dict->getBool("test_mode", true),
disabled: dict->getBool("disabled", true),
payment_methods_enabled: dict
->getJsonObjectFromDict("payment_methods_enabled")
->getArrayDataFromJson(getPaymentMethodsEnabledV2),
profile_id: dict->getString("profile_id", ""),
merchant_connector_id: dict->getString("merchant_connector_id", ""),
frm_configs: dict->getArrayFromDict("frm_configs", [])->convertFRMConfigJsonToObjResponse,
status: dict->getString("status", "inactive"),
connector_webhook_details: dict->getJsonObjectFromDict("connector_webhook_details"),
metadata: dict->getObj("metadata", Dict.make())->JSON.Encode.object,
additional_merchant_data: dict
->getObj("additional_merchant_data", Dict.make())
->JSON.Encode.object,
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ let pmIcon = pm =>
| _ => ""
}

let checkKlaranRegion = connData =>
let checkKlaranRegion = (connData: connectorPayload) =>
switch connData.metadata
->getDictFromJsonObject
->getString("klarna_region", "")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ let make = (
let (selectedPMTIndex, setSelectedPMTIndex) = React.useState(_ => 0)

let {globalUIConfig: {font: {textColor}}} = React.useContext(ThemeProvider.themeContext)
let connData =
let connData: ConnectorTypes.connectorPayload =
formState.values->getDictFromJsonObject->ConnectorListMapper.getProcessorPayloadType
let availablePM =
paymentMethodValues
Expand Down
44 changes: 24 additions & 20 deletions src/screens/Connectors/ConnectorTypes.res
Original file line number Diff line number Diff line change
Expand Up @@ -207,17 +207,6 @@ type pmAuthPaymentMethods = {
mca_id: string,
}

type pmAuthDict = {enabled_payment_methods: array<pmAuthPaymentMethods>}

type paymentMethodConfig = {
bank_redirect?: option<array<string>>,
bank_transfer?: option<array<string>>,
credit_card?: option<array<string>>,
debit_card?: option<array<string>>,
pay_later?: option<array<string>>,
wallets?: option<array<string>>,
}

type wasmRequest = {
payment_methods_enabled: array<paymentMethodEnabled>,
connector: string,
Expand Down Expand Up @@ -286,20 +275,18 @@ type connectorAuthTypeObj =
| CertificateAuth(certificateAuth)
| UnKnownAuthType(JSON.t)

type connectorAccountDetails = {
auth_type: string,
api_secret?: string,
api_key?: string,
key1?: string,
key2?: string,
}

type paymentMethodEnabledType = {
payment_method: string,
mutable payment_method_types: array<paymentMethodConfigType>,
}

type paymentMethodEnabledTypeV2 = {
payment_method_type: string,
payment_method_subtypes: array<paymentMethodConfigType>,
}

type payment_methods_enabled = array<paymentMethodEnabledType>
type payment_methods_enabledV2 = array<paymentMethodEnabledTypeV2>

type frm_payment_method_type = {
payment_method_type: string,
Expand Down Expand Up @@ -334,7 +321,7 @@ type connectorPayload = {
connector_account_details: connectorAuthTypeObj,
test_mode: bool,
disabled: bool,
mutable payment_methods_enabled: payment_methods_enabled,
payment_methods_enabled: payment_methods_enabled,
profile_id: string,
metadata: JSON.t,
merchant_connector_id: string,
Expand All @@ -344,6 +331,23 @@ type connectorPayload = {
additional_merchant_data: JSON.t,
}

type connectorPayloadV2 = {
connector_type: connectorTypeVariants,
connector_name: string,
connector_label: string,
connector_account_details: connectorAuthTypeObj,
test_mode: bool,
disabled: bool,
payment_methods_enabled: payment_methods_enabledV2,
profile_id: string,
metadata: JSON.t,
merchant_connector_id: string,
frm_configs: array<frm_config>,
status: string,
connector_webhook_details: JSON.t,
additional_merchant_data: JSON.t,
}

type connector =
| FRMPlayer
| Processor
Expand Down
2 changes: 1 addition & 1 deletion src/screens/Connectors/FraudAndRisk/FRMUtils.res
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ let generateInitialValuesDict = (~selectedFRMName, ~isLiveMode) => {
}

let parseFRMConfig = json => {
json->JSON.Decode.array->Option.getOr([])->ConnectorListMapper.convertFRMConfigJsonToObj
json->JSON.Decode.array->Option.getOr([])->ConnectorInterfaceUtils.convertFRMConfigJsonToObj
}

let getPaymentMethod = paymentMethod => {
Expand Down
Loading

0 comments on commit 61f7798

Please sign in to comment.