Skip to content

Commit

Permalink
Merge branch 'main' into signup-signin
Browse files Browse the repository at this point in the history
  • Loading branch information
ThisIsMani authored Nov 20, 2023
2 parents 3ceccf9 + 644709d commit a03cb5f
Show file tree
Hide file tree
Showing 19 changed files with 186 additions and 23 deletions.
9 changes: 9 additions & 0 deletions crates/api_models/src/admin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -609,6 +609,9 @@ pub struct MerchantConnectorCreate {
pub profile_id: Option<String>,

pub pm_auth_config: Option<serde_json::Value>,

#[schema(value_type = ConnectorStatus, example = "inactive")]
pub status: Option<api_enums::ConnectorStatus>,
}

#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
Expand Down Expand Up @@ -714,6 +717,9 @@ pub struct MerchantConnectorResponse {
pub applepay_verified_domains: Option<Vec<String>>,

pub pm_auth_config: Option<serde_json::Value>,

#[schema(value_type = ConnectorStatus, example = "inactive")]
pub status: api_enums::ConnectorStatus,
}

/// Create a new Merchant Connector for the merchant account. The connector could be a payment processor / facilitator / acquirer or specialized services like Fraud / Accounting etc."
Expand Down Expand Up @@ -788,6 +794,9 @@ pub struct MerchantConnectorUpdate {
pub connector_webhook_details: Option<MerchantConnectorWebhookDetails>,

pub pm_auth_config: Option<serde_json::Value>,

#[schema(value_type = ConnectorStatus, example = "inactive")]
pub status: Option<api_enums::ConnectorStatus>,
}

///Details of FrmConfigs are mentioned here... it should be passed in payment connector create api call, and stored in merchant_connector_table
Expand Down
22 changes: 22 additions & 0 deletions crates/common_enums/src/enums.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1857,3 +1857,25 @@ pub enum ApplePayFlow {
Simplified,
Manual,
}

#[derive(
Clone,
Copy,
Debug,
Eq,
PartialEq,
strum::Display,
strum::EnumString,
serde::Deserialize,
serde::Serialize,
ToSchema,
Default,
)]
#[router_derive::diesel_enum(storage_type = "pg_enum")]
#[strum(serialize_all = "snake_case")]
#[serde(rename_all = "snake_case")]
pub enum ConnectorStatus {
#[default]
Inactive,
Active,
}
7 changes: 4 additions & 3 deletions crates/diesel_models/src/enums.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@ pub mod diesel_exports {
pub use super::{
DbAttemptStatus as AttemptStatus, DbAuthenticationType as AuthenticationType,
DbCaptureMethod as CaptureMethod, DbCaptureStatus as CaptureStatus,
DbConnectorType as ConnectorType, DbCountryAlpha2 as CountryAlpha2, DbCurrency as Currency,
DbDisputeStage as DisputeStage, DbDisputeStatus as DisputeStatus,
DbEventClass as EventClass, DbEventObjectType as EventObjectType, DbEventType as EventType,
DbConnectorStatus as ConnectorStatus, DbConnectorType as ConnectorType,
DbCountryAlpha2 as CountryAlpha2, DbCurrency as Currency, DbDisputeStage as DisputeStage,
DbDisputeStatus as DisputeStatus, DbEventClass as EventClass,
DbEventObjectType as EventObjectType, DbEventType as EventType,
DbFraudCheckStatus as FraudCheckStatus, DbFraudCheckType as FraudCheckType,
DbFutureUsage as FutureUsage, DbIntentStatus as IntentStatus,
DbMandateStatus as MandateStatus, DbMandateType as MandateType,
Expand Down
4 changes: 4 additions & 0 deletions crates/diesel_models/src/merchant_connector_account.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ pub struct MerchantConnectorAccount {
#[diesel(deserialize_as = super::OptionalDieselArray<String>)]
pub applepay_verified_domains: Option<Vec<String>>,
pub pm_auth_config: Option<serde_json::Value>,
pub status: storage_enums::ConnectorStatus,
}

#[derive(Clone, Debug, Insertable, router_derive::DebugAsDisplay)]
Expand Down Expand Up @@ -70,6 +71,7 @@ pub struct MerchantConnectorAccountNew {
#[diesel(deserialize_as = super::OptionalDieselArray<String>)]
pub applepay_verified_domains: Option<Vec<String>>,
pub pm_auth_config: Option<serde_json::Value>,
pub status: storage_enums::ConnectorStatus,
}

#[derive(Clone, Debug, AsChangeset, router_derive::DebugAsDisplay)]
Expand All @@ -93,6 +95,7 @@ pub struct MerchantConnectorAccountUpdateInternal {
#[diesel(deserialize_as = super::OptionalDieselArray<String>)]
pub applepay_verified_domains: Option<Vec<String>>,
pub pm_auth_config: Option<serde_json::Value>,
pub status: Option<storage_enums::ConnectorStatus>,
}

impl MerchantConnectorAccountUpdateInternal {
Expand All @@ -115,6 +118,7 @@ impl MerchantConnectorAccountUpdateInternal {
frm_config: self.frm_config,
modified_at: self.modified_at.unwrap_or(source.modified_at),
pm_auth_config: self.pm_auth_config,
status: self.status.unwrap_or(source.status),

..source
}
Expand Down
1 change: 1 addition & 0 deletions crates/diesel_models/src/schema.rs
Original file line number Diff line number Diff line change
Expand Up @@ -492,6 +492,7 @@ diesel::table! {
profile_id -> Nullable<Varchar>,
applepay_verified_domains -> Nullable<Array<Nullable<Text>>>,
pm_auth_config -> Nullable<Jsonb>,
status -> ConnectorStatus,
}
}

Expand Down
1 change: 1 addition & 0 deletions crates/kgraph_utils/benches/evaluation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ fn build_test_data<'a>(total_enabled: usize, total_pm_types: usize) -> graph::Kn
profile_id: None,
applepay_verified_domains: None,
pm_auth_config: None,
status: api_enums::ConnectorStatus::Inactive,
};

kgraph_utils::mca::make_mca_graph(vec![stripe_account]).expect("Failed graph construction")
Expand Down
1 change: 1 addition & 0 deletions crates/kgraph_utils/src/mca.rs
Original file line number Diff line number Diff line change
Expand Up @@ -410,6 +410,7 @@ mod tests {
profile_id: None,
applepay_verified_domains: None,
pm_auth_config: None,
status: api_enums::ConnectorStatus::Inactive,
};

make_mca_graph(vec![stripe_account]).expect("Failed graph construction")
Expand Down
48 changes: 33 additions & 15 deletions crates/router/src/connector/fiserv/transformers.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use common_utils::ext_traits::ValueExt;
use common_utils::{ext_traits::ValueExt, pii};
use error_stack::ResultExt;
use serde::{Deserialize, Serialize};

Expand Down Expand Up @@ -150,9 +150,11 @@ impl TryFrom<&FiservRouterData<&types::PaymentsAuthorizeRouterData>> for FiservP
merchant_transaction_id: item.router_data.connector_request_reference_id.clone(),
};
let metadata = item.router_data.get_connector_meta()?;
let session: SessionObject = metadata
.parse_value("SessionObject")
.change_context(errors::ConnectorError::RequestEncodingFailed)?;
let session: FiservSessionObject = metadata
.parse_value("FiservSessionObject")
.change_context(errors::ConnectorError::InvalidConnectorConfig {
config: "Merchant connector account metadata",
})?;

let merchant_details = MerchantDetails {
merchant_id: auth.merchant_account,
Expand Down Expand Up @@ -230,9 +232,11 @@ impl TryFrom<&types::PaymentsCancelRouterData> for FiservCancelRequest {
fn try_from(item: &types::PaymentsCancelRouterData) -> Result<Self, Self::Error> {
let auth: FiservAuthType = FiservAuthType::try_from(&item.connector_auth_type)?;
let metadata = item.get_connector_meta()?;
let session: SessionObject = metadata
.parse_value("SessionObject")
.change_context(errors::ConnectorError::RequestEncodingFailed)?;
let session: FiservSessionObject = metadata
.parse_value("FiservSessionObject")
.change_context(errors::ConnectorError::InvalidConnectorConfig {
config: "Merchant connector account metadata",
})?;
Ok(Self {
merchant_details: MerchantDetails {
merchant_id: auth.merchant_account,
Expand Down Expand Up @@ -418,11 +422,21 @@ pub struct ReferenceTransactionDetails {
}

#[derive(Debug, Default, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct SessionObject {
pub struct FiservSessionObject {
pub terminal_id: String,
}

impl TryFrom<&Option<pii::SecretSerdeValue>> for FiservSessionObject {
type Error = error_stack::Report<errors::ConnectorError>;
fn try_from(meta_data: &Option<pii::SecretSerdeValue>) -> Result<Self, Self::Error> {
let metadata: Self = utils::to_connector_meta_from_secret::<Self>(meta_data.clone())
.change_context(errors::ConnectorError::InvalidConnectorConfig {
config: "metadata",
})?;
Ok(metadata)
}
}

impl TryFrom<&FiservRouterData<&types::PaymentsCaptureRouterData>> for FiservCaptureRequest {
type Error = error_stack::Report<errors::ConnectorError>;
fn try_from(
Expand All @@ -434,9 +448,11 @@ impl TryFrom<&FiservRouterData<&types::PaymentsCaptureRouterData>> for FiservCap
.connector_meta_data
.clone()
.ok_or(errors::ConnectorError::RequestEncodingFailed)?;
let session: SessionObject = metadata
.parse_value("SessionObject")
.change_context(errors::ConnectorError::RequestEncodingFailed)?;
let session: FiservSessionObject = metadata
.parse_value("FiservSessionObject")
.change_context(errors::ConnectorError::InvalidConnectorConfig {
config: "Merchant connector account metadata",
})?;
Ok(Self {
amount: Amount {
total: item.amount.clone(),
Expand Down Expand Up @@ -527,9 +543,11 @@ impl<F> TryFrom<&FiservRouterData<&types::RefundsRouterData<F>>> for FiservRefun
.connector_meta_data
.clone()
.ok_or(errors::ConnectorError::RequestEncodingFailed)?;
let session: SessionObject = metadata
.parse_value("SessionObject")
.change_context(errors::ConnectorError::RequestEncodingFailed)?;
let session: FiservSessionObject = metadata
.parse_value("FiservSessionObject")
.change_context(errors::ConnectorError::InvalidConnectorConfig {
config: "Merchant connector account metadata",
})?;
Ok(Self {
amount: Amount {
total: item.amount.clone(),
Expand Down
1 change: 1 addition & 0 deletions crates/router/src/connector/square/transformers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -334,6 +334,7 @@ impl TryFrom<&types::ConnectorAuthType> for SquareAuthType {
| types::ConnectorAuthType::SignatureKey { .. }
| types::ConnectorAuthType::MultiAuthKey { .. }
| types::ConnectorAuthType::CurrencyAuthKey { .. }
| types::ConnectorAuthType::TemporaryAuth { .. }
| types::ConnectorAuthType::NoKey { .. } => {
Err(errors::ConnectorError::FailedToObtainAuthType.into())
}
Expand Down
63 changes: 61 additions & 2 deletions crates/router/src/core/admin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -868,6 +868,15 @@ pub async fn create_payment_connector(
.change_context(errors::ApiErrorResponse::InternalServerError)
.attach_printable("error updating the merchant account when creating payment connector")?;

let (connector_status, disabled) = validate_status_and_disabled(
req.status,
req.disabled,
auth,
// The validate_status_and_disabled function will use this value only
// when the status can be active. So we are passing this as fallback.
api_enums::ConnectorStatus::Active,
)?;

let merchant_connector_account = domain::MerchantConnectorAccount {
merchant_id: merchant_id.to_string(),
connector_type: req.connector_type,
Expand All @@ -886,7 +895,7 @@ pub async fn create_payment_connector(
.attach_printable("Unable to encrypt connector account details")?,
payment_methods_enabled,
test_mode: req.test_mode,
disabled: req.disabled,
disabled,
metadata: req.metadata,
frm_configs,
connector_label: Some(connector_label),
Expand All @@ -911,6 +920,7 @@ pub async fn create_payment_connector(
profile_id: Some(profile_id.clone()),
applepay_verified_domains: None,
pm_auth_config: req.pm_auth_config.clone(),
status: connector_status,
};

let mut default_routing_config =
Expand Down Expand Up @@ -1083,6 +1093,19 @@ pub async fn update_payment_connector(

let frm_configs = get_frm_config_as_secret(req.frm_configs);

let auth: types::ConnectorAuthType = req
.connector_account_details
.clone()
.unwrap_or(mca.connector_account_details.clone().into_inner())
.parse_value("ConnectorAuthType")
.change_context(errors::ApiErrorResponse::InvalidDataFormat {
field_name: "connector_account_details".to_string(),
expected_format: "auth_type and api_key".to_string(),
})?;

let (connector_status, disabled) =
validate_status_and_disabled(req.status, req.disabled, auth, mca.status)?;

let payment_connector = storage::MerchantConnectorAccountUpdate::Update {
merchant_id: None,
connector_type: Some(req.connector_type),
Expand All @@ -1098,7 +1121,7 @@ pub async fn update_payment_connector(
.change_context(errors::ApiErrorResponse::InternalServerError)
.attach_printable("Failed while encrypting data")?,
test_mode: req.test_mode,
disabled: req.disabled,
disabled,
payment_methods_enabled,
metadata: req.metadata,
frm_configs,
Expand All @@ -1115,6 +1138,7 @@ pub async fn update_payment_connector(
},
applepay_verified_domains: None,
pm_auth_config: req.pm_auth_config,
status: Some(connector_status),
};

let updated_mca = db
Expand Down Expand Up @@ -1565,6 +1589,7 @@ pub(crate) fn validate_auth_and_metadata_type(
}
api_enums::Connector::Fiserv => {
fiserv::transformers::FiservAuthType::try_from(val)?;
fiserv::transformers::FiservSessionObject::try_from(connector_meta_data)?;
Ok(())
}
api_enums::Connector::Forte => {
Expand Down Expand Up @@ -1722,3 +1747,37 @@ pub async fn validate_dummy_connector_enabled(
Ok(())
}
}

pub fn validate_status_and_disabled(
status: Option<api_enums::ConnectorStatus>,
disabled: Option<bool>,
auth: types::ConnectorAuthType,
current_status: api_enums::ConnectorStatus,
) -> RouterResult<(api_enums::ConnectorStatus, Option<bool>)> {
let connector_status = match (status, auth) {
(Some(common_enums::ConnectorStatus::Active), types::ConnectorAuthType::TemporaryAuth) => {
return Err(errors::ApiErrorResponse::InvalidRequestData {
message: "Connector status cannot be active when using TemporaryAuth".to_string(),
}
.into());
}
(Some(status), _) => status,
(None, types::ConnectorAuthType::TemporaryAuth) => common_enums::ConnectorStatus::Inactive,
(None, _) => current_status,
};

let disabled = match (disabled, connector_status) {
(Some(true), common_enums::ConnectorStatus::Inactive) => {
return Err(errors::ApiErrorResponse::InvalidRequestData {
message: "Connector cannot be enabled when connector_status is inactive or when using TemporaryAuth"
.to_string(),
}
.into());
}
(Some(disabled), _) => Some(disabled),
(None, common_enums::ConnectorStatus::Inactive) => Some(true),
(None, _) => None,
};

Ok((connector_status, disabled))
}
1 change: 1 addition & 0 deletions crates/router/src/core/verification/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ pub async fn check_existence_and_add_domain_to_db(
applepay_verified_domains: Some(already_verified_domains.clone()),
pm_auth_config: None,
connector_label: None,
status: None,
};
state
.store
Expand Down
2 changes: 2 additions & 0 deletions crates/router/src/db/merchant_connector_account.rs
Original file line number Diff line number Diff line change
Expand Up @@ -643,6 +643,7 @@ impl MerchantConnectorAccountInterface for MockDb {
profile_id: t.profile_id,
applepay_verified_domains: t.applepay_verified_domains,
pm_auth_config: t.pm_auth_config,
status: t.status,
};
accounts.push(account.clone());
account
Expand Down Expand Up @@ -839,6 +840,7 @@ mod merchant_connector_account_cache_tests {
profile_id: Some(profile_id.to_string()),
applepay_verified_domains: None,
pm_auth_config: None,
status: common_enums::ConnectorStatus::Inactive,
};

db.insert_merchant_connector_account(mca.clone(), &merchant_key)
Expand Down
1 change: 1 addition & 0 deletions crates/router/src/openapi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,7 @@ Never share your secret api keys. Keep them guarded and secure.
api_models::enums::AttemptStatus,
api_models::enums::CaptureStatus,
api_models::enums::ReconStatus,
api_models::enums::ConnectorStatus,
api_models::admin::MerchantConnectorCreate,
api_models::admin::MerchantConnectorUpdate,
api_models::admin::PrimaryBusinessDetails,
Expand Down
1 change: 1 addition & 0 deletions crates/router/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -900,6 +900,7 @@ pub struct ResponseRouterData<Flow, R, Request, Response> {
#[derive(Default, Debug, Clone, serde::Deserialize)]
#[serde(tag = "auth_type")]
pub enum ConnectorAuthType {
TemporaryAuth,
HeaderKey {
api_key: Secret<String>,
},
Expand Down
Loading

0 comments on commit a03cb5f

Please sign in to comment.