feat(router): Add v2 endpoint to retrieve payment filters at merchant and profile level (#7171)

Co-authored-by: Aniket Burman <aniket.burman@Aniket-Burman-JDXHW2PH34.local>
Co-authored-by: hyperswitch-bot[bot] <148525504+hyperswitch-bot[bot]@users.noreply.github.com>
This commit is contained in:
Aniket Burman
2025-02-25 19:16:44 +05:30
committed by GitHub
parent 5e7e0d829a
commit 3d9d75cd66
7 changed files with 111 additions and 23 deletions

View File

@ -1360,6 +1360,9 @@ impl MerchantConnectorListResponse {
merchant_connector_id: self.merchant_connector_id.clone(), merchant_connector_id: self.merchant_connector_id.clone(),
} }
} }
pub fn get_connector_name(&self) -> String {
self.connector_name.clone()
}
} }
#[cfg(feature = "v2")] #[cfg(feature = "v2")]
@ -1416,6 +1419,9 @@ impl MerchantConnectorListResponse {
merchant_connector_id: self.id.clone(), merchant_connector_id: self.id.clone(),
} }
} }
pub fn get_connector_name(&self) -> common_enums::connector_enums::Connector {
self.connector_name
}
} }
/// 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." /// 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."
@ -1667,6 +1673,20 @@ pub struct PaymentMethodsEnabled {
#[schema(value_type = Option<Vec<RequestPaymentMethodTypes>>,example = json!(["credit"]))] #[schema(value_type = Option<Vec<RequestPaymentMethodTypes>>,example = json!(["credit"]))]
pub payment_method_types: Option<Vec<payment_methods::RequestPaymentMethodTypes>>, pub payment_method_types: Option<Vec<payment_methods::RequestPaymentMethodTypes>>,
} }
impl PaymentMethodsEnabled {
/// Get payment_method
#[cfg(feature = "v1")]
pub fn get_payment_method(&self) -> Option<common_enums::PaymentMethod> {
Some(self.payment_method)
}
/// Get payment_method_types
#[cfg(feature = "v1")]
pub fn get_payment_method_type(
&self,
) -> Option<&Vec<payment_methods::RequestPaymentMethodTypes>> {
self.payment_method_types.as_ref()
}
}
#[derive(PartialEq, Eq, Hash, Debug, Clone, serde::Serialize, Deserialize, ToSchema)] #[derive(PartialEq, Eq, Hash, Debug, Clone, serde::Serialize, Deserialize, ToSchema)]
#[serde( #[serde(

View File

@ -1513,6 +1513,13 @@ pub struct RequestPaymentMethodTypes {
#[schema(default = true, example = false)] #[schema(default = true, example = false)]
pub installment_payment_enabled: bool, pub installment_payment_enabled: bool,
} }
impl RequestPaymentMethodTypes {
/// Get payment_method_type
#[cfg(feature = "v1")]
pub fn get_payment_method_type(&self) -> Option<api_enums::PaymentMethodType> {
Some(self.payment_method_type)
}
}
#[cfg(all( #[cfg(all(
any(feature = "v1", feature = "v2"), any(feature = "v1", feature = "v2"),

View File

@ -19,6 +19,20 @@ pub struct PaymentMethodsEnabled {
pub payment_method_subtypes: Option<Vec<RequestPaymentMethodTypes>>, pub payment_method_subtypes: Option<Vec<RequestPaymentMethodTypes>>,
} }
impl PaymentMethodsEnabled {
/// Get payment_method_type
#[cfg(feature = "v2")]
pub fn get_payment_method(&self) -> Option<common_enums::PaymentMethod> {
Some(self.payment_method_type)
}
/// Get payment_method_subtypes
#[cfg(feature = "v2")]
pub fn get_payment_method_type(&self) -> Option<&Vec<RequestPaymentMethodTypes>> {
self.payment_method_subtypes.as_ref()
}
}
/// Details of a specific payment method subtype enabled for the connector for the given merchant account /// Details of a specific payment method subtype enabled for the connector for the given merchant account
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, ToSchema, PartialEq, Eq, Hash)] #[derive(Debug, Clone, serde::Serialize, serde::Deserialize, ToSchema, PartialEq, Eq, Hash)]
pub struct RequestPaymentMethodTypes { pub struct RequestPaymentMethodTypes {
@ -69,6 +83,13 @@ pub struct RequestPaymentMethodTypes {
pub installment_payment_enabled: bool, pub installment_payment_enabled: bool,
} }
impl RequestPaymentMethodTypes {
///Get payment_method_subtype
pub fn get_payment_method_type(&self) -> Option<common_enums::PaymentMethodType> {
Some(self.payment_method_subtype)
}
}
#[derive(PartialEq, Eq, Hash, Debug, Clone, serde::Serialize, Deserialize, ToSchema)] #[derive(PartialEq, Eq, Hash, Debug, Clone, serde::Serialize, Deserialize, ToSchema)]
#[serde( #[serde(
deny_unknown_fields, deny_unknown_fields,

View File

@ -33,8 +33,8 @@ payouts = ["api_models/payouts", "common_enums/payouts", "hyperswitch_connectors
payout_retry = ["payouts"] payout_retry = ["payouts"]
recon = ["email", "api_models/recon"] recon = ["email", "api_models/recon"]
retry = [] retry = []
v2 = ["customer_v2", "payment_methods_v2", "common_default", "api_models/v2", "diesel_models/v2", "hyperswitch_domain_models/v2", "storage_impl/v2", "kgraph_utils/v2", "common_utils/v2", "hyperswitch_connectors/v2","hyperswitch_interfaces/v2"] v2 = ["customer_v2", "payment_methods_v2", "common_default", "api_models/v2", "diesel_models/v2", "hyperswitch_domain_models/v2", "storage_impl/v2", "kgraph_utils/v2", "common_utils/v2", "hyperswitch_connectors/v2","hyperswitch_interfaces/v2", "common_types/v2"]
v1 = ["common_default", "api_models/v1", "diesel_models/v1", "hyperswitch_domain_models/v1", "storage_impl/v1", "hyperswitch_interfaces/v1", "kgraph_utils/v1", "common_utils/v1", "hyperswitch_connectors/v1"] v1 = ["common_default", "api_models/v1", "diesel_models/v1", "hyperswitch_domain_models/v1", "storage_impl/v1", "hyperswitch_interfaces/v1", "kgraph_utils/v1", "common_utils/v1", "hyperswitch_connectors/v1", "common_types/v1"]
customer_v2 = ["api_models/customer_v2", "diesel_models/customer_v2", "hyperswitch_domain_models/customer_v2", "storage_impl/customer_v2"] customer_v2 = ["api_models/customer_v2", "diesel_models/customer_v2", "hyperswitch_domain_models/customer_v2", "storage_impl/customer_v2"]
payment_methods_v2 = ["api_models/payment_methods_v2", "diesel_models/payment_methods_v2", "hyperswitch_domain_models/payment_methods_v2", "storage_impl/payment_methods_v2", "common_utils/payment_methods_v2"] payment_methods_v2 = ["api_models/payment_methods_v2", "diesel_models/payment_methods_v2", "hyperswitch_domain_models/payment_methods_v2", "storage_impl/payment_methods_v2", "common_utils/payment_methods_v2"]
dynamic_routing = ["external_services/dynamic_routing", "storage_impl/dynamic_routing", "api_models/dynamic_routing"] dynamic_routing = ["external_services/dynamic_routing", "storage_impl/dynamic_routing", "api_models/dynamic_routing"]

View File

@ -5459,7 +5459,7 @@ pub async fn get_filters_for_payments(
)) ))
} }
#[cfg(all(feature = "olap", feature = "v1"))] #[cfg(feature = "olap")]
pub async fn get_payment_filters( pub async fn get_payment_filters(
state: SessionState, state: SessionState,
merchant: domain::MerchantAccount, merchant: domain::MerchantAccount,
@ -5489,12 +5489,12 @@ pub async fn get_payment_filters(
.as_ref() .as_ref()
.map(|label| { .map(|label| {
let info = merchant_connector_account.to_merchant_connector_info(label); let info = merchant_connector_account.to_merchant_connector_info(label);
(merchant_connector_account.connector_name.clone(), info) (merchant_connector_account.get_connector_name(), info)
}) })
}) })
.for_each(|(connector_name, info)| { .for_each(|(connector_name, info)| {
connector_map connector_map
.entry(connector_name.clone()) .entry(connector_name.to_string())
.or_default() .or_default()
.push(info); .push(info);
}); });
@ -5510,23 +5510,31 @@ pub async fn get_payment_filters(
.iter() .iter()
.filter_map(|payment_method_enabled| { .filter_map(|payment_method_enabled| {
payment_method_enabled payment_method_enabled
.payment_method_types .get_payment_method_type()
.as_ref() .map(|types_vec| {
.map(|types_vec| (payment_method_enabled.payment_method, types_vec.clone())) (
payment_method_enabled.get_payment_method(),
types_vec.clone(),
)
})
}) })
}) })
.for_each(|payment_methods_enabled| { .for_each(|payment_methods_enabled| {
payment_methods_enabled.for_each(|(payment_method, payment_method_types_vec)| { payment_methods_enabled.for_each(
|(payment_method_option, payment_method_types_vec)| {
if let Some(payment_method) = payment_method_option {
payment_method_types_map payment_method_types_map
.entry(payment_method) .entry(payment_method)
.or_default() .or_default()
.extend( .extend(payment_method_types_vec.iter().filter_map(
payment_method_types_vec |req_payment_method_types| {
.iter() req_payment_method_types.get_payment_method_type()
.map(|p| p.payment_method_type), },
));
}
},
); );
}); });
});
Ok(services::ApplicationResponse::Json( Ok(services::ApplicationResponse::Json(
api::PaymentListFiltersV2 { api::PaymentListFiltersV2 {

View File

@ -567,14 +567,19 @@ impl Payments {
pub fn server(state: AppState) -> Scope { pub fn server(state: AppState) -> Scope {
let mut route = web::scope("/v2/payments").app_data(web::Data::new(state)); let mut route = web::scope("/v2/payments").app_data(web::Data::new(state));
route = route route = route
.service(
web::resource("")
.route(web::post().to(payments::payments_create_and_confirm_intent)),
)
.service( .service(
web::resource("/create-intent") web::resource("/create-intent")
.route(web::post().to(payments::payments_create_intent)), .route(web::post().to(payments::payments_create_intent)),
) )
.service(web::resource("/filter").route(web::get().to(payments::get_payment_filters)))
.service(
web::resource("/profile/filter")
.route(web::get().to(payments::get_payment_filters_profile)),
)
.service(
web::resource("")
.route(web::post().to(payments::payments_create_and_confirm_intent)),
)
.service(web::resource("/list").route(web::get().to(payments::payments_list))) .service(web::resource("/list").route(web::get().to(payments::payments_list)))
.service( .service(
web::resource("/aggregate").route(web::get().to(payments::get_payments_aggregates)), web::resource("/aggregate").route(web::get().to(payments::get_payments_aggregates)),

View File

@ -1386,7 +1386,7 @@ pub async fn get_filters_for_payments(
} }
#[instrument(skip_all, fields(flow = ?Flow::PaymentsFilters))] #[instrument(skip_all, fields(flow = ?Flow::PaymentsFilters))]
#[cfg(all(feature = "olap", feature = "v1"))] #[cfg(feature = "olap")]
pub async fn get_payment_filters( pub async fn get_payment_filters(
state: web::Data<app::AppState>, state: web::Data<app::AppState>,
req: actix_web::HttpRequest, req: actix_web::HttpRequest,
@ -1408,6 +1408,33 @@ pub async fn get_payment_filters(
.await .await
} }
#[instrument(skip_all, fields(flow = ?Flow::PaymentsFilters))]
#[cfg(all(feature = "olap", feature = "v2"))]
pub async fn get_payment_filters_profile(
state: web::Data<app::AppState>,
req: actix_web::HttpRequest,
) -> impl Responder {
let flow = Flow::PaymentsFilters;
Box::pin(api::server_wrap(
flow,
state,
&req,
(),
|state, auth: auth::AuthenticationData, _, _| {
payments::get_payment_filters(
state,
auth.merchant_account,
Some(vec![auth.profile.get_id().clone()]),
)
},
&auth::JWTAuth {
permission: Permission::ProfilePaymentRead,
},
api_locking::LockAction::NotApplicable,
))
.await
}
#[instrument(skip_all, fields(flow = ?Flow::PaymentsFilters))] #[instrument(skip_all, fields(flow = ?Flow::PaymentsFilters))]
#[cfg(all(feature = "olap", feature = "v1"))] #[cfg(all(feature = "olap", feature = "v1"))]
pub async fn get_payment_filters_profile( pub async fn get_payment_filters_profile(