feat(router): add merchant_connector_account create v2 api flow (#5385)

This commit is contained in:
Sai Harsha Vardhan
2024-07-25 00:57:13 +05:30
committed by GitHub
parent 83dbb7a8da
commit 98349a0c3b
20 changed files with 1761 additions and 776 deletions

File diff suppressed because it is too large Load Diff

View File

@ -2656,7 +2656,7 @@ pub async fn list_payment_methods(
.pm_auth_config
.as_ref()
.map(|config| {
serde_json::from_value::<PaymentMethodAuthConfig>(config.clone())
serde_json::from_value::<PaymentMethodAuthConfig>(config.clone().expose())
.change_context(errors::StorageError::DeserializationFailed)
.attach_printable("Failed to deserialize Payment Method Auth config")
})

View File

@ -3069,12 +3069,7 @@ pub async fn get_payment_filters(
.connector_label
.as_ref()
.map(|label| {
let info = MerchantConnectorInfo {
connector_label: label.clone(),
merchant_connector_id: merchant_connector_account
.merchant_connector_id
.clone(),
};
let info = merchant_connector_account.to_merchant_connector_info(label);
(merchant_connector_account.connector_name.clone(), info)
})
})

View File

@ -989,13 +989,15 @@ pub async fn get_filters_for_refunds(
let connector_map = merchant_connector_accounts
.into_iter()
.filter_map(|merchant_connector_account| {
merchant_connector_account.connector_label.map(|label| {
let info = MerchantConnectorInfo {
connector_label: label,
merchant_connector_id: merchant_connector_account.merchant_connector_id,
};
(merchant_connector_account.connector_name, info)
})
merchant_connector_account
.connector_label
.clone()
.map(|label| {
let info = merchant_connector_account
.clone()
.to_merchant_connector_info(&label.clone());
(merchant_connector_account.connector_name, info)
})
})
.fold(
HashMap::new(),

View File

@ -243,6 +243,10 @@ pub async fn delete_merchant_account(
/// Merchant Connector - Create
///
/// 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."
#[cfg(all(
any(feature = "v1", feature = "v2"),
not(feature = "merchant_connector_account_v2")
))]
#[utoipa::path(
post,
path = "/accounts/{account_id}/connectors",
@ -263,12 +267,56 @@ pub async fn payment_connector_create(
json_payload: web::Json<admin::MerchantConnectorCreate>,
) -> HttpResponse {
let flow = Flow::MerchantConnectorsCreate;
let payload = json_payload.into_inner();
let merchant_id = path.into_inner();
Box::pin(api::server_wrap(
flow,
state,
&req,
json_payload.into_inner(),
payload,
|state, _, req, _| create_payment_connector(state, req, &merchant_id),
auth::auth_type(
&auth::AdminApiAuth,
&auth::JWTAuthMerchantFromRoute {
merchant_id: merchant_id.clone(),
required_permission: Permission::MerchantConnectorAccountWrite,
},
req.headers(),
),
api_locking::LockAction::NotApplicable,
))
.await
}
/// Merchant Connector - Create
///
/// 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."
#[cfg(all(feature = "v2", feature = "merchant_connector_account_v2"))]
#[utoipa::path(
post,
path = "/accounts/{account_id}/connectors",
request_body = MerchantConnectorCreate,
responses(
(status = 200, description = "Merchant Connector Created", body = MerchantConnectorResponse),
(status = 400, description = "Missing Mandatory fields"),
),
tag = "Merchant Connector Account",
operation_id = "Create a Merchant Connector",
security(("admin_api_key" = []))
)]
#[instrument(skip_all, fields(flow = ?Flow::MerchantConnectorsCreate))]
pub async fn payment_connector_create(
state: web::Data<AppState>,
req: HttpRequest,
json_payload: web::Json<admin::MerchantConnectorCreate>,
) -> HttpResponse {
let flow = Flow::MerchantConnectorsCreate;
let payload = json_payload.into_inner();
let merchant_id = payload.merchant_id.clone();
Box::pin(api::server_wrap(
flow,
state,
&req,
payload,
|state, _, req, _| create_payment_connector(state, req, &merchant_id),
auth::auth_type(
&auth::AdminApiAuth,

View File

@ -58,7 +58,7 @@ use crate::analytics::AnalyticsProvider;
use crate::routes::fraud_check as frm_routes;
#[cfg(all(feature = "recon", feature = "olap"))]
use crate::routes::recon as recon_routes;
#[cfg(feature = "olap")]
#[cfg(all(feature = "olap", not(feature = "v2")))]
use crate::routes::verify_connector::payment_connector_verify;
pub use crate::{
configs::settings,
@ -1082,7 +1082,31 @@ impl MerchantAccount {
pub struct MerchantConnectorAccount;
#[cfg(any(feature = "olap", feature = "oltp"))]
#[cfg(all(
any(feature = "olap", feature = "oltp"),
feature = "v2",
feature = "merchant_connector_account_v2"
))]
impl MerchantConnectorAccount {
pub fn server(state: AppState) -> Scope {
let mut route = web::scope("/connector_accounts").app_data(web::Data::new(state));
#[cfg(feature = "olap")]
{
use super::admin::*;
route =
route.service(web::resource("").route(web::post().to(payment_connector_create)));
}
route
}
}
#[cfg(all(
any(feature = "olap", feature = "oltp"),
any(feature = "v1", feature = "v2"),
not(feature = "merchant_connector_account_v2")
))]
impl MerchantConnectorAccount {
pub fn server(state: AppState) -> Scope {
let mut route = web::scope("/account").app_data(web::Data::new(state));

View File

@ -35,7 +35,7 @@ pub struct MerchantConnectorAccount {
pub connector_webhook_details: Option<pii::SecretSerdeValue>,
pub profile_id: Option<String>,
pub applepay_verified_domains: Option<Vec<String>>,
pub pm_auth_config: Option<serde_json::Value>,
pub pm_auth_config: Option<pii::SecretSerdeValue>,
pub status: enums::ConnectorStatus,
pub connector_wallets_details: Option<Encryptable<Secret<serde_json::Value>>>,
pub additional_merchant_data: Option<Encryptable<Secret<serde_json::Value>>>,
@ -55,7 +55,7 @@ pub enum MerchantConnectorAccountUpdate {
frm_configs: Option<Vec<Secret<serde_json::Value>>>,
connector_webhook_details: Option<pii::SecretSerdeValue>,
applepay_verified_domains: Option<Vec<String>>,
pm_auth_config: Option<serde_json::Value>,
pm_auth_config: Option<pii::SecretSerdeValue>,
connector_label: Option<String>,
status: Option<enums::ConnectorStatus>,
connector_wallets_details: Option<Encryptable<Secret<serde_json::Value>>>,

View File

@ -949,7 +949,51 @@ impl TryFrom<domain::MerchantConnectorAccount> for api_models::admin::MerchantCo
}
None => None,
};
Ok(Self {
#[cfg(all(feature = "v2", feature = "merchant_connector_account_v2"))]
let response = Self {
connector_type: item.connector_type,
connector_name: item.connector_name,
connector_label: item.connector_label,
connector_id: item.merchant_connector_id,
connector_account_details: item.connector_account_details.into_inner(),
disabled: item.disabled,
payment_methods_enabled,
metadata: item.metadata,
frm_configs,
connector_webhook_details: item
.connector_webhook_details
.map(|webhook_details| {
serde_json::Value::parse_value(
webhook_details.expose(),
"MerchantConnectorWebhookDetails",
)
.attach_printable("Unable to deserialize connector_webhook_details")
.change_context(errors::ApiErrorResponse::InternalServerError)
})
.transpose()?,
profile_id: item.profile_id,
applepay_verified_domains: item.applepay_verified_domains,
pm_auth_config: item.pm_auth_config,
status: item.status,
additional_merchant_data: item
.additional_merchant_data
.map(|data| {
let data = data.into_inner();
serde_json::Value::parse_value::<router_types::AdditionalMerchantData>(
data.expose(),
"AdditionalMerchantData",
)
.attach_printable("Unable to deserialize additional_merchant_data")
.change_context(errors::ApiErrorResponse::InternalServerError)
})
.transpose()?
.map(api_models::admin::AdditionalMerchantData::foreign_from),
};
#[cfg(all(
any(feature = "v1", feature = "v2"),
not(feature = "merchant_connector_account_v2")
))]
let response = Self {
connector_type: item.connector_type,
connector_name: item.connector_name,
connector_label: item.connector_label,
@ -991,7 +1035,8 @@ impl TryFrom<domain::MerchantConnectorAccount> for api_models::admin::MerchantCo
})
.transpose()?
.map(api_models::admin::AdditionalMerchantData::foreign_from),
})
};
Ok(response)
}
}