diff --git a/crates/api_models/src/admin.rs b/crates/api_models/src/admin.rs index 27a137eef7..944f0b20fa 100644 --- a/crates/api_models/src/admin.rs +++ b/crates/api_models/src/admin.rs @@ -345,8 +345,20 @@ pub struct MerchantConnector { /// You can specify up to 50 keys, with key names up to 40 characters long and values up to 500 characters long. Metadata is useful for storing additional, structured information on an object. #[schema(value_type = Option,max_length = 255,example = json!({ "city": "NY", "unit": "245" }))] pub metadata: Option, + pub frm_configs: Option, + //contains the frm configs for the merchant... it should be of this format:: "\"frm_configs\" : { \"frm_enabled_pms\" : [\"card\"], \"frm_enabled_pm_types\" : [\"credit\"], \"frm_enabled_gateways\" : [\"stripe\"], \"frm_action\": \"cancel_txn\", \"frm_preferred_flow_type\" : \"pre\" }" } +//Details of FrmConfigs are mentioned here... it should be passed in payment connector create api call, and stored in merchant_connector_table +#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)] +#[serde(deny_unknown_fields)] +pub struct FrmConfigs { + pub frm_enabled_pms: Option>, + pub frm_enabled_pm_types: Option>, + pub frm_enabled_gateways: Option>, + pub frm_action: api_enums::FrmAction, //What should be the action if FRM declines the txn (autorefund/cancel txn/manual review) + pub frm_preferred_flow_type: api_enums::FrmPreferredFlowTypes, +} /// Details of all the payment methods enabled for the connector for the given merchant account #[derive(Debug, Clone, Serialize, Deserialize, ToSchema)] #[serde(deny_unknown_fields)] diff --git a/crates/api_models/src/enums.rs b/crates/api_models/src/enums.rs index 3b4fce23d2..c20fe28f9e 100644 --- a/crates/api_models/src/enums.rs +++ b/crates/api_models/src/enums.rs @@ -823,3 +823,38 @@ pub enum DisputeStatus { // dispute has been unsuccessfully challenged DisputeLost, } + +#[derive( + Clone, + Debug, + serde::Deserialize, + serde::Serialize, + strum::Display, + strum::EnumString, + frunk::LabelledGeneric, + ToSchema, +)] +#[strum(serialize_all = "snake_case")] +#[serde(rename_all = "snake_case")] +pub enum FrmAction { + CancelTxn, + AutoRefund, + ManualReview, +} + +#[derive( + Clone, + Debug, + serde::Deserialize, + serde::Serialize, + strum::Display, + strum::EnumString, + frunk::LabelledGeneric, + ToSchema, +)] +#[strum(serialize_all = "snake_case")] +#[serde(rename_all = "snake_case")] +pub enum FrmPreferredFlowTypes { + Pre, + Post, +} diff --git a/crates/router/src/core/admin.rs b/crates/router/src/core/admin.rs index ca6234d367..fb395157c5 100644 --- a/crates/router/src/core/admin.rs +++ b/crates/router/src/core/admin.rs @@ -309,6 +309,12 @@ pub async fn create_payment_connector( field_name: "connector_account_details".to_string(), expected_format: "auth_type and api_key".to_string(), })?; + let configs_for_frm_value = req + .frm_configs + .ok_or_else(|| errors::ApiErrorResponse::ConfigNotFound)?; + let frm_value: serde_json::Value = + utils::Encode::::encode_to_value(&configs_for_frm_value) + .change_context(errors::ApiErrorResponse::ConfigNotFound)?; let merchant_connector_account = storage::MerchantConnectorAccountNew { merchant_id: Some(merchant_id.to_string()), @@ -320,6 +326,7 @@ pub async fn create_payment_connector( test_mode: req.test_mode, disabled: req.disabled, metadata: req.metadata, + frm_configs: Some(frm_value), }; let mca = store @@ -419,7 +426,13 @@ pub async fn update_payment_connector( }) .collect::>() }); - + let configs_for_frm_value = req + .frm_configs + .as_ref() + .ok_or_else(|| errors::ApiErrorResponse::ConfigNotFound)?; + let frm_value: serde_json::Value = + utils::Encode::::encode_to_value(&configs_for_frm_value) + .change_context(errors::ApiErrorResponse::ConfigNotFound)?; let payment_connector = storage::MerchantConnectorAccountUpdate::Update { merchant_id: Some(merchant_id.to_string()), connector_type: Some(req.connector_type.foreign_into()), @@ -430,6 +443,7 @@ pub async fn update_payment_connector( test_mode: req.test_mode, disabled: req.disabled, metadata: req.metadata, + frm_configs: Some(frm_value), }; let updated_mca = db @@ -460,6 +474,7 @@ pub async fn update_payment_connector( disabled: updated_mca.disabled, payment_methods_enabled: updated_pm_enabled, metadata: updated_mca.metadata, + frm_configs: req.frm_configs, }; Ok(service_api::ApplicationResponse::Json(response)) } diff --git a/crates/router/src/core/payments/flows/authorize_flow.rs b/crates/router/src/core/payments/flows/authorize_flow.rs index 642b9fb867..11c05911a4 100644 --- a/crates/router/src/core/payments/flows/authorize_flow.rs +++ b/crates/router/src/core/payments/flows/authorize_flow.rs @@ -41,7 +41,6 @@ impl .await } } - #[async_trait] impl Feature for types::PaymentsAuthorizeRouterData { async fn decide_flows<'a>( diff --git a/crates/router/src/db/merchant_connector_account.rs b/crates/router/src/db/merchant_connector_account.rs index f29944a01c..df16c6d64f 100644 --- a/crates/router/src/db/merchant_connector_account.rs +++ b/crates/router/src/db/merchant_connector_account.rs @@ -287,6 +287,7 @@ impl MerchantConnectorAccountInterface for MockDb { merchant_connector_id: t.merchant_connector_id, payment_methods_enabled: t.payment_methods_enabled, metadata: t.metadata, + frm_configs: t.frm_configs, connector_type: t .connector_type .unwrap_or(crate::types::storage::enums::ConnectorType::FinOperations), diff --git a/crates/router/src/types/transformers.rs b/crates/router/src/types/transformers.rs index bcc29fd3fe..28ba0362a5 100644 --- a/crates/router/src/types/transformers.rs +++ b/crates/router/src/types/transformers.rs @@ -341,6 +341,16 @@ impl ForeignTryFrom for api_models::admin::Me .change_context(errors::ApiErrorResponse::InternalServerError)?, None => None, }; + let configs_for_frm_value = merchant_ca + .frm_configs + .ok_or_else(|| errors::ApiErrorResponse::ConfigNotFound)?; + let configs_for_frm : api_models::admin::FrmConfigs = configs_for_frm_value + // .clone() + .parse_value("FrmConfigs") + .change_context(errors::ApiErrorResponse::InvalidDataFormat { + field_name: "frm_configs".to_string(), + expected_format: "\"frm_configs\" : { \"frm_enabled_pms\" : [\"card\"], \"frm_enabled_pm_types\" : [\"credit\"], \"frm_enabled_gateways\" : [\"stripe\"], \"frm_action\": \"cancel_txn\", \"frm_preferred_flow_type\" : \"pre\" }".to_string(), + })?; Ok(Self { connector_type: merchant_ca.connector_type.foreign_into(), @@ -353,6 +363,7 @@ impl ForeignTryFrom for api_models::admin::Me disabled: merchant_ca.disabled, metadata: merchant_ca.metadata, payment_methods_enabled, + frm_configs: Some(configs_for_frm), }) } } diff --git a/crates/storage_models/src/merchant_connector_account.rs b/crates/storage_models/src/merchant_connector_account.rs index 08d3fa21fa..0da7c2b130 100644 --- a/crates/storage_models/src/merchant_connector_account.rs +++ b/crates/storage_models/src/merchant_connector_account.rs @@ -28,6 +28,7 @@ pub struct MerchantConnectorAccount { pub payment_methods_enabled: Option>, pub connector_type: storage_enums::ConnectorType, pub metadata: Option, + pub frm_configs: Option, //Option } #[derive(Clone, Debug, Default, Insertable, router_derive::DebugAsDisplay)] @@ -42,6 +43,7 @@ pub struct MerchantConnectorAccountNew { pub merchant_connector_id: String, pub payment_methods_enabled: Option>, pub metadata: Option, + pub frm_configs: Option, } #[derive(Debug)] @@ -56,6 +58,7 @@ pub enum MerchantConnectorAccountUpdate { merchant_connector_id: Option, payment_methods_enabled: Option>, metadata: Option, + frm_configs: Option, }, } #[derive(Clone, Debug, Default, AsChangeset, router_derive::DebugAsDisplay)] @@ -70,6 +73,7 @@ pub struct MerchantConnectorAccountUpdateInternal { merchant_connector_id: Option, payment_methods_enabled: Option>, metadata: Option, + frm_configs: Option, } impl From for MerchantConnectorAccountUpdateInternal { @@ -85,6 +89,7 @@ impl From for MerchantConnectorAccountUpdateInte merchant_connector_id, payment_methods_enabled, metadata, + frm_configs, } => Self { merchant_id, connector_type, @@ -95,6 +100,7 @@ impl From for MerchantConnectorAccountUpdateInte merchant_connector_id, payment_methods_enabled, metadata, + frm_configs, }, } } diff --git a/crates/storage_models/src/schema.rs b/crates/storage_models/src/schema.rs index 737d1b6453..373063b4b8 100644 --- a/crates/storage_models/src/schema.rs +++ b/crates/storage_models/src/schema.rs @@ -241,6 +241,7 @@ diesel::table! { payment_methods_enabled -> Nullable>>, connector_type -> ConnectorType, metadata -> Nullable, + frm_configs -> Nullable, } } diff --git a/migrations/2023-04-03-082335_update_mca_frm_configs/down.sql b/migrations/2023-04-03-082335_update_mca_frm_configs/down.sql new file mode 100644 index 0000000000..411ea83d84 --- /dev/null +++ b/migrations/2023-04-03-082335_update_mca_frm_configs/down.sql @@ -0,0 +1 @@ +ALTER TABLE "merchant_connector_account" DROP COLUMN frm_configs; \ No newline at end of file diff --git a/migrations/2023-04-03-082335_update_mca_frm_configs/up.sql b/migrations/2023-04-03-082335_update_mca_frm_configs/up.sql new file mode 100644 index 0000000000..72d5e7e237 --- /dev/null +++ b/migrations/2023-04-03-082335_update_mca_frm_configs/up.sql @@ -0,0 +1 @@ +ALTER TABLE "merchant_connector_account" ADD COLUMN frm_configs jsonb; \ No newline at end of file