Bug: [REFACTOR] add support for passing context generic to api calls



### Feature Description

Add support for including a new generic, context, which will be passed during api call (server_wrap) to call the related implementation depending on context

### Possible Implementation

To have multiple implementation to a particular object and calling the respective implementation during runtime depending on the context passed

### Have you spent some time checking if this feature request has been raised before?

- [X] I checked and didn't find a similar issue

### Have you read the Contributing Guidelines?

- [X] I have read the [Contributing Guidelines](https://github.com/juspay/hyperswitch/blob/main/docs/CONTRIBUTING.md)

### Are you willing to submit a PR?

Yes, I am willing to submit a PR!
diff --git a/crates/router/src/compatibility/stripe/payment_intents.rs b/crates/router/src/compatibility/stripe/payment_intents.rs
index e44ce0a1fd3..1076dfe410f 100644
--- a/crates/router/src/compatibility/stripe/payment_intents.rs
+++ b/crates/router/src/compatibility/stripe/payment_intents.rs
@@ -6,7 +6,7 @@ use router_env::{instrument, tracing, Flow};
 
 use crate::{
     compatibility::{stripe::errors, wrap},
-    core::{api_locking::GetLockingInput, payments},
+    core::{api_locking::GetLockingInput, payment_methods::Oss, payments},
     routes,
     services::{api, authentication as auth},
     types::api::{self as api_types},
@@ -50,7 +50,7 @@ pub async fn payment_intents_create(
         &req,
         create_payment_req,
         |state, auth, req| {
-            payments::payments_core::<api_types::Authorize, api_types::PaymentsResponse, _, _, _>(
+            payments::payments_core::<api_types::Authorize, api_types::PaymentsResponse, _, _, _,Oss>(
                 state,
                 auth.merchant_account,
                 auth.key_store,
@@ -109,7 +109,7 @@ pub async fn payment_intents_retrieve(
         &req,
         payload,
         |state, auth, payload| {
-            payments::payments_core::<api_types::PSync, api_types::PaymentsResponse, _, _, _>(
+            payments::payments_core::<api_types::PSync, api_types::PaymentsResponse, _, _, _, Oss>(
                 state,
                 auth.merchant_account,
                 auth.key_store,
@@ -172,7 +172,7 @@ pub async fn payment_intents_retrieve_with_gateway_creds(
         &req,
         payload,
         |state, auth, req| {
-            payments::payments_core::<api_types::PSync, payment_types::PaymentsResponse, _, _, _>(
+            payments::payments_core::<api_types::PSync, payment_types::PaymentsResponse, _, _, _,Oss>(
                 state,
                 auth.merchant_account,
                 auth.key_store,
@@ -236,7 +236,7 @@ pub async fn payment_intents_update(
         &req,
         payload,
         |state, auth, req| {
-            payments::payments_core::<api_types::Authorize, api_types::PaymentsResponse, _, _, _>(
+            payments::payments_core::<api_types::Authorize, api_types::PaymentsResponse, _, _, _,Oss>(
                 state,
                 auth.merchant_account,
                 auth.key_store,
@@ -302,7 +302,7 @@ pub async fn payment_intents_confirm(
         &req,
         payload,
         |state, auth, req| {
-            payments::payments_core::<api_types::Authorize, api_types::PaymentsResponse, _, _, _>(
+            payments::payments_core::<api_types::Authorize, api_types::PaymentsResponse, _, _, _,Oss>(
                 state,
                 auth.merchant_account,
                 auth.key_store,
@@ -358,7 +358,7 @@ pub async fn payment_intents_capture(
         &req,
         payload,
         |state, auth, payload| {
-            payments::payments_core::<api_types::Capture, api_types::PaymentsResponse, _, _, _>(
+            payments::payments_core::<api_types::Capture, api_types::PaymentsResponse, _, _, _,Oss>(
                 state,
                 auth.merchant_account,
                 auth.key_store,
@@ -418,7 +418,7 @@ pub async fn payment_intents_cancel(
         &req,
         payload,
         |state, auth, req| {
-            payments::payments_core::<api_types::Void, api_types::PaymentsResponse, _, _, _>(
+            payments::payments_core::<api_types::Void, api_types::PaymentsResponse, _, _, _, Oss>(
                 state,
                 auth.merchant_account,
                 auth.key_store,
diff --git a/crates/router/src/compatibility/stripe/setup_intents.rs b/crates/router/src/compatibility/stripe/setup_intents.rs
index b9da2f8e3ee..311498e1af5 100644
--- a/crates/router/src/compatibility/stripe/setup_intents.rs
+++ b/crates/router/src/compatibility/stripe/setup_intents.rs
@@ -9,7 +9,7 @@ use crate::{
         stripe::{errors, payment_intents::types as stripe_payment_types},
         wrap,
     },
-    core::{api_locking, payments},
+    core::{api_locking, payment_methods::Oss, payments},
     routes,
     services::{api, authentication as auth},
     types::api as api_types,
@@ -54,7 +54,14 @@ pub async fn setup_intents_create(
         &req,
         create_payment_req,
         |state, auth, req| {
-            payments::payments_core::<api_types::SetupMandate, api_types::PaymentsResponse, _, _, _>(
+            payments::payments_core::<
+                api_types::SetupMandate,
+                api_types::PaymentsResponse,
+                _,
+                _,
+                _,
+                Oss,
+            >(
                 state,
                 auth.merchant_account,
                 auth.key_store,
@@ -113,7 +120,7 @@ pub async fn setup_intents_retrieve(
         &req,
         payload,
         |state, auth, payload| {
-            payments::payments_core::<api_types::PSync, api_types::PaymentsResponse, _, _, _>(
+            payments::payments_core::<api_types::PSync, api_types::PaymentsResponse, _, _, _, Oss>(
                 state,
                 auth.merchant_account,
                 auth.key_store,
@@ -178,7 +185,14 @@ pub async fn setup_intents_update(
         &req,
         payload,
         |state, auth, req| {
-            payments::payments_core::<api_types::SetupMandate, api_types::PaymentsResponse, _, _, _>(
+            payments::payments_core::<
+                api_types::SetupMandate,
+                api_types::PaymentsResponse,
+                _,
+                _,
+                _,
+                Oss,
+            >(
                 state,
                 auth.merchant_account,
                 auth.key_store,
@@ -244,7 +258,14 @@ pub async fn setup_intents_confirm(
         &req,
         payload,
         |state, auth, req| {
-            payments::payments_core::<api_types::SetupMandate, api_types::PaymentsResponse, _, _, _>(
+            payments::payments_core::<
+                api_types::SetupMandate,
+                api_types::PaymentsResponse,
+                _,
+                _,
+                _,
+                Oss,
+            >(
                 state,
                 auth.merchant_account,
                 auth.key_store,
diff --git a/crates/router/src/core/payment_methods.rs b/crates/router/src/core/payment_methods.rs
index f1d641adbe5..850daeba75f 100644
--- a/crates/router/src/core/payment_methods.rs
+++ b/crates/router/src/core/payment_methods.rs
@@ -1,3 +1,99 @@
 pub mod cards;
 pub mod transformers;
 pub mod vault;
+
+pub use api_models::{
+    enums::{Connector, PayoutConnectors},
+    payouts as payout_types,
+};
+pub use common_utils::request::RequestBody;
+use data_models::payments::{payment_attempt::PaymentAttempt, payment_intent::PaymentIntent};
+use diesel_models::enums;
+
+use crate::{
+    core::{errors::RouterResult, payments::helpers},
+    routes::AppState,
+    types::api::{self, payments},
+};
+
+pub struct Oss;
+
+#[async_trait::async_trait]
+pub trait PaymentMethodRetrieve {
+    async fn retrieve_payment_method(
+        pm_data: &Option<payments::PaymentMethodData>,
+        state: &AppState,
+        payment_intent: &PaymentIntent,
+        payment_attempt: &PaymentAttempt,
+    ) -> RouterResult<(Option<payments::PaymentMethodData>, Option<String>)>;
+}
+
+#[async_trait::async_trait]
+impl PaymentMethodRetrieve for Oss {
+    async fn retrieve_payment_method(
+        pm_data: &Option<payments::PaymentMethodData>,
+        state: &AppState,
+        payment_intent: &PaymentIntent,
+        payment_attempt: &PaymentAttempt,
+    ) -> RouterResult<(Option<payments::PaymentMethodData>, Option<String>)> {
+        match pm_data {
+            pm_opt @ Some(pm @ api::PaymentMethodData::Card(_)) => {
+                let payment_token = helpers::store_payment_method_data_in_vault(
+                    state,
+                    payment_attempt,
+                    payment_intent,
+                    enums::PaymentMethod::Card,
+                    pm,
+                )
+                .await?;
+
+                Ok((pm_opt.to_owned(), payment_token))
+            }
+            pm @ Some(api::PaymentMethodData::PayLater(_)) => Ok((pm.to_owned(), None)),
+            pm @ Some(api::PaymentMethodData::Crypto(_)) => Ok((pm.to_owned(), None)),
+            pm @ Some(api::PaymentMethodData::BankDebit(_)) => Ok((pm.to_owned(), None)),
+            pm @ Some(api::PaymentMethodData::Upi(_)) => Ok((pm.to_owned(), None)),
+            pm @ Some(api::PaymentMethodData::Voucher(_)) => Ok((pm.to_owned(), None)),
+            pm @ Some(api::PaymentMethodData::Reward) => Ok((pm.to_owned(), None)),
+            pm @ Some(api::PaymentMethodData::CardRedirect(_)) => Ok((pm.to_owned(), None)),
+            pm @ Some(api::PaymentMethodData::GiftCard(_)) => Ok((pm.to_owned(), None)),
+            pm_opt @ Some(pm @ api::PaymentMethodData::BankTransfer(_)) => {
+                let payment_token = helpers::store_payment_method_data_in_vault(
+                    state,
+                    payment_attempt,
+                    payment_intent,
+                    enums::PaymentMethod::BankTransfer,
+                    pm,
+                )
+                .await?;
+
+                Ok((pm_opt.to_owned(), payment_token))
+            }
+            pm_opt @ Some(pm @ api::PaymentMethodData::Wallet(_)) => {
+                let payment_token = helpers::store_payment_method_data_in_vault(
+                    state,
+                    payment_attempt,
+                    payment_intent,
+                    enums::PaymentMethod::Wallet,
+                    pm,
+                )
+                .await?;
+
+                Ok((pm_opt.to_owned(), payment_token))
+            }
+            pm_opt @ Some(pm @ api::PaymentMethodData::BankRedirect(_)) => {
+                let payment_token = helpers::store_payment_method_data_in_vault(
+                    state,
+                    payment_attempt,
+                    payment_intent,
+                    enums::PaymentMethod::BankRedirect,
+                    pm,
+                )
+                .await?;
+
+                Ok((pm_opt.to_owned(), payment_token))
+            }
+            _ => Ok((None, None)),
+        }
+    }
+}
diff --git a/crates/router/src/core/payments.rs b/crates/router/src/core/payments.rs
index 1b6d93596f1..cc84a13616d 100644
--- a/crates/router/src/core/payments.rs
+++ b/crates/router/src/core/payments.rs
@@ -18,6 +18,8 @@ use futures::future::join_all;
 use helpers::ApplePayData;
 use masking::Secret;
 use router_env::{instrument, tracing};
+#[cfg(feature = "olap")]
+use router_types::transformers::ForeignFrom;
 use scheduler::{db::process_tracker::ProcessTrackerExt, errors as sch_errors, utils as pt_utils};
 use time;
 
@@ -31,12 +33,11 @@ use self::{
     operations::{payment_complete_authorize, BoxedOperation, Operation},
 };
 use super::errors::StorageErrorExt;
-#[cfg(feature = "olap")]
-use crate::types::transformers::ForeignFrom;
 use crate::{
     configs::settings::PaymentMethodTypeTokenFilter,
     core::{
         errors::{self, CustomResult, RouterResponse, RouterResult},
+        payment_methods::PaymentMethodRetrieve,
         utils,
     },
     db::StorageInterface,
@@ -56,7 +57,7 @@ use crate::{
 
 #[allow(clippy::too_many_arguments)]
 #[instrument(skip_all, fields(payment_id, merchant_id))]
-pub async fn payments_operation_core<F, Req, Op, FData>(
+pub async fn payments_operation_core<F, Req, Op, FData, Ctx>(
     state: &AppState,
     merchant_account: domain::MerchantAccount,
     key_store: domain::MerchantKeyStore,
@@ -69,7 +70,7 @@ pub async fn payments_operation_core<F, Req, Op, FData>(
 where
     F: Send + Clone + Sync,
     Req: Authenticate,
-    Op: Operation<F, Req> + Send + Sync,
+    Op: Operation<F, Req, Ctx> + Send + Sync,
 
     // To create connector flow specific interface data
     PaymentData<F>: ConstructFlowSpecificData<F, FData, router_types::PaymentsResponseData>,
@@ -80,10 +81,11 @@ where
         services::api::ConnectorIntegration<F, FData, router_types::PaymentsResponseData>,
 
     // To perform router related operation for PaymentResponse
-    PaymentResponse: Operation<F, FData>,
+    PaymentResponse: Operation<F, FData, Ctx>,
     FData: Send + Sync,
+    Ctx: PaymentMethodRetrieve,
 {
-    let operation: BoxedOperation<'_, F, Req> = Box::new(operation);
+    let operation: BoxedOperation<'_, F, Req, Ctx> = Box::new(operation);
 
     tracing::Span::current().record("merchant_id", merchant_account.merchant_id.as_str());
     let (operation, validate_result) = operation
@@ -239,7 +241,7 @@ where
 }
 
 #[allow(clippy::too_many_arguments)]
-pub async fn payments_core<F, Res, Req, Op, FData>(
+pub async fn payments_core<F, Res, Req, Op, FData, Ctx>(
     state: AppState,
     merchant_account: domain::MerchantAccount,
     key_store: domain::MerchantKeyStore,
@@ -252,31 +254,33 @@ pub async fn payments_core<F, Res, Req, Op, FData>(
 where
     F: Send + Clone + Sync,
     FData: Send + Sync,
-    Op: Operation<F, Req> + Send + Sync + Clone,
+    Op: Operation<F, Req, Ctx> + Send + Sync + Clone,
     Req: Debug + Authenticate,
     Res: transformers::ToResponse<Req, PaymentData<F>, Op>,
     // To create connector flow specific interface data
     PaymentData<F>: ConstructFlowSpecificData<F, FData, router_types::PaymentsResponseData>,
     router_types::RouterData<F, FData, router_types::PaymentsResponseData>: Feature<F, FData>,
+    Ctx: PaymentMethodRetrieve,
 
     // To construct connector flow specific api
     dyn router_types::api::Connector:
         services::api::ConnectorIntegration<F, FData, router_types::PaymentsResponseData>,
 
     // To perform router related operation for PaymentResponse
-    PaymentResponse: Operation<F, FData>,
+    PaymentResponse: Operation<F, FData, Ctx>,
 {
-    let (payment_data, req, customer, connector_http_status_code) = payments_operation_core(
-        &state,
-        merchant_account,
-        key_store,
-        operation.clone(),
-        req,
-        call_connector_action,
-        auth_flow,
-        header_payload,
-    )
-    .await?;
+    let (payment_data, req, customer, connector_http_status_code) =
+        payments_operation_core::<_, _, _, _, Ctx>(
+            &state,
+            merchant_account,
+            key_store,
+            operation.clone(),
+            req,
+            call_connector_action,
+            auth_flow,
+            header_payload,
+        )
+        .await?;
 
     Res::generate_response(
         Some(req),
@@ -306,7 +310,7 @@ pub struct PaymentsRedirectResponseData {
 }
 
 #[async_trait::async_trait]
-pub trait PaymentRedirectFlow: Sync {
+pub trait PaymentRedirectFlow<Ctx: PaymentMethodRetrieve>: Sync {
     async fn call_payment_flow(
         &self,
         state: &AppState,
@@ -402,7 +406,7 @@ pub trait PaymentRedirectFlow: Sync {
 pub struct PaymentRedirectCompleteAuthorize;
 
 #[async_trait::async_trait]
-impl PaymentRedirectFlow for PaymentRedirectCompleteAuthorize {
+impl<Ctx: PaymentMethodRetrieve> PaymentRedirectFlow<Ctx> for PaymentRedirectCompleteAuthorize {
     async fn call_payment_flow(
         &self,
         state: &AppState,
@@ -422,7 +426,7 @@ impl PaymentRedirectFlow for PaymentRedirectCompleteAuthorize {
             }),
             ..Default::default()
         };
-        payments_core::<api::CompleteAuthorize, api::PaymentsResponse, _, _, _>(
+        payments_core::<api::CompleteAuthorize, api::PaymentsResponse, _, _, _, Ctx>(
             state.clone(),
             merchant_account,
             merchant_key_store,
@@ -492,7 +496,7 @@ impl PaymentRedirectFlow for PaymentRedirectCompleteAuthorize {
 pub struct PaymentRedirectSync;
 
 #[async_trait::async_trait]
-impl PaymentRedirectFlow for PaymentRedirectSync {
+impl<Ctx: PaymentMethodRetrieve> PaymentRedirectFlow<Ctx> for PaymentRedirectSync {
     async fn call_payment_flow(
         &self,
         state: &AppState,
@@ -517,7 +521,7 @@ impl PaymentRedirectFlow for PaymentRedirectSync {
             expand_attempts: None,
             expand_captures: None,
         };
-        payments_core::<api::PSync, api::PaymentsResponse, _, _, _>(
+        payments_core::<api::PSync, api::PaymentsResponse, _, _, _, Ctx>(
             state.clone(),
             merchant_account,
             merchant_key_store,
@@ -552,12 +556,12 @@ impl PaymentRedirectFlow for PaymentRedirectSync {
 
 #[allow(clippy::too_many_arguments)]
 #[instrument(skip_all)]
-pub async fn call_connector_service<F, RouterDReq, ApiRequest>(
+pub async fn call_connector_service<F, RouterDReq, ApiRequest, Ctx>(
     state: &AppState,
     merchant_account: &domain::MerchantAccount,
     key_store: &domain::MerchantKeyStore,
     connector: api::ConnectorData,
-    operation: &BoxedOperation<'_, F, ApiRequest>,
+    operation: &BoxedOperation<'_, F, ApiRequest, Ctx>,
     payment_data: &mut PaymentData<F>,
     customer: &Option<domain::Customer>,
     call_connector_action: CallConnectorAction,
@@ -573,6 +577,7 @@ where
     PaymentData<F>: ConstructFlowSpecificData<F, RouterDReq, router_types::PaymentsResponseData>,
     router_types::RouterData<F, RouterDReq, router_types::PaymentsResponseData>:
         Feature<F, RouterDReq> + Send,
+    Ctx: PaymentMethodRetrieve,
 
     // To construct connector flow specific api
     dyn api::Connector:
@@ -767,7 +772,7 @@ where
     router_data_res
 }
 
-pub async fn call_multiple_connectors_service<F, Op, Req>(
+pub async fn call_multiple_connectors_service<F, Op, Req, Ctx>(
     state: &AppState,
     merchant_account: &domain::MerchantAccount,
     key_store: &domain::MerchantKeyStore,
@@ -787,9 +792,10 @@ where
     // To construct connector flow specific api
     dyn api::Connector:
         services::api::ConnectorIntegration<F, Req, router_types::PaymentsResponseData>,
+    Ctx: PaymentMethodRetrieve,
 
     // To perform router related operation for PaymentResponse
-    PaymentResponse: Operation<F, Req>,
+    PaymentResponse: Operation<F, Req, Ctx>,
 {
     let call_connectors_start_time = Instant::now();
     let mut join_handlers = Vec::with_capacity(connectors.len());
@@ -969,12 +975,12 @@ where
     }
 }
 
-async fn complete_preprocessing_steps_if_required<F, Req, Q>(
+async fn complete_preprocessing_steps_if_required<F, Req, Q, Ctx>(
     state: &AppState,
     connector: &api::ConnectorData,
     payment_data: &PaymentData<F>,
     mut router_data: router_types::RouterData<F, Req, router_types::PaymentsResponseData>,
-    operation: &BoxedOperation<'_, F, Q>,
+    operation: &BoxedOperation<'_, F, Q, Ctx>,
     should_continue_payment: bool,
 ) -> RouterResult<(
     router_types::RouterData<F, Req, router_types::PaymentsResponseData>,
@@ -1256,15 +1262,16 @@ pub enum TokenizationAction {
 }
 
 #[allow(clippy::too_many_arguments)]
-pub async fn get_connector_tokenization_action_when_confirm_true<F, Req>(
+pub async fn get_connector_tokenization_action_when_confirm_true<F, Req, Ctx>(
     state: &AppState,
-    operation: &BoxedOperation<'_, F, Req>,
+    operation: &BoxedOperation<'_, F, Req, Ctx>,
     payment_data: &mut PaymentData<F>,
     validate_result: &operations::ValidateResult<'_>,
     merchant_connector_account: &helpers::MerchantConnectorAccountType,
 ) -> RouterResult<(PaymentData<F>, TokenizationAction)>
 where
     F: Send + Clone,
+    Ctx: PaymentMethodRetrieve,
 {
     let connector = payment_data.payment_attempt.connector.to_owned();
 
@@ -1364,14 +1371,15 @@ where
     Ok(payment_data_and_tokenization_action)
 }
 
-pub async fn tokenize_in_router_when_confirm_false<F, Req>(
+pub async fn tokenize_in_router_when_confirm_false<F, Req, Ctx>(
     state: &AppState,
-    operation: &BoxedOperation<'_, F, Req>,
+    operation: &BoxedOperation<'_, F, Req, Ctx>,
     payment_data: &mut PaymentData<F>,
     validate_result: &operations::ValidateResult<'_>,
 ) -> RouterResult<PaymentData<F>>
 where
     F: Send + Clone,
+    Ctx: PaymentMethodRetrieve,
 {
     // On confirm is false and only router related
     let payment_data = if !is_operation_confirm(operation) {
@@ -1454,15 +1462,16 @@ pub struct CustomerDetails {
     pub phone_country_code: Option<String>,
 }
 
-pub fn if_not_create_change_operation<'a, Op, F>(
+pub fn if_not_create_change_operation<'a, Op, F, Ctx>(
     status: storage_enums::IntentStatus,
     confirm: Option<bool>,
     current: &'a Op,
-) -> BoxedOperation<'_, F, api::PaymentsRequest>
+) -> BoxedOperation<'_, F, api::PaymentsRequest, Ctx>
 where
     F: Send + Clone,
-    Op: Operation<F, api::PaymentsRequest> + Send + Sync,
-    &'a Op: Operation<F, api::PaymentsRequest>,
+    Op: Operation<F, api::PaymentsRequest, Ctx> + Send + Sync,
+    &'a Op: Operation<F, api::PaymentsRequest, Ctx>,
+    Ctx: PaymentMethodRetrieve,
 {
     if confirm.unwrap_or(false) {
         Box::new(PaymentConfirm)
@@ -1476,15 +1485,16 @@ where
     }
 }
 
-pub fn is_confirm<'a, F: Clone + Send, R, Op>(
+pub fn is_confirm<'a, F: Clone + Send, R, Op, Ctx>(
     operation: &'a Op,
     confirm: Option<bool>,
-) -> BoxedOperation<'_, F, R>
+) -> BoxedOperation<'_, F, R, Ctx>
 where
-    PaymentConfirm: Operation<F, R>,
-    &'a PaymentConfirm: Operation<F, R>,
-    Op: Operation<F, R> + Send + Sync,
-    &'a Op: Operation<F, R>,
+    PaymentConfirm: Operation<F, R, Ctx>,
+    &'a PaymentConfirm: Operation<F, R, Ctx>,
+    Op: Operation<F, R, Ctx> + Send + Sync,
+    &'a Op: Operation<F, R, Ctx>,
+    Ctx: PaymentMethodRetrieve,
 {
     if confirm.unwrap_or(false) {
         Box::new(&PaymentConfirm)
@@ -1777,8 +1787,8 @@ where
     Ok(())
 }
 
-pub async fn get_connector_choice<F, Req>(
-    operation: &BoxedOperation<'_, F, Req>,
+pub async fn get_connector_choice<F, Req, Ctx>(
+    operation: &BoxedOperation<'_, F, Req, Ctx>,
     state: &AppState,
     req: &Req,
     merchant_account: &domain::MerchantAccount,
@@ -1787,6 +1797,7 @@ pub async fn get_connector_choice<F, Req>(
 ) -> RouterResult<Option<api::ConnectorCallType>>
 where
     F: Send + Clone,
+    Ctx: PaymentMethodRetrieve,
 {
     let connector_choice = operation
         .to_domain()?
diff --git a/crates/router/src/core/payments/helpers.rs b/crates/router/src/core/payments/helpers.rs
index d9c1d719c73..44c9b516dc5 100644
--- a/crates/router/src/core/payments/helpers.rs
+++ b/crates/router/src/core/payments/helpers.rs
@@ -36,7 +36,7 @@ use crate::{
     consts::{self, BASE64_ENGINE},
     core::{
         errors::{self, CustomResult, RouterResult, StorageErrorExt},
-        payment_methods::{cards, vault},
+        payment_methods::{cards, vault, PaymentMethodRetrieve},
         payments,
     },
     db::StorageInterface,
@@ -936,10 +936,11 @@ where
     }
 }
 
-pub fn response_operation<'a, F, R>() -> BoxedOperation<'a, F, R>
+pub fn response_operation<'a, F, R, Ctx>() -> BoxedOperation<'a, F, R, Ctx>
 where
     F: Send + Clone,
-    PaymentResponse: Operation<F, R>,
+    Ctx: PaymentMethodRetrieve,
+    PaymentResponse: Operation<F, R, Ctx>,
 {
     Box::new(PaymentResponse)
 }
@@ -1149,14 +1150,14 @@ pub async fn get_connector_default(
 }
 
 #[instrument(skip_all)]
-pub async fn create_customer_if_not_exist<'a, F: Clone, R>(
-    operation: BoxedOperation<'a, F, R>,
+pub async fn create_customer_if_not_exist<'a, F: Clone, R, Ctx>(
+    operation: BoxedOperation<'a, F, R, Ctx>,
     db: &dyn StorageInterface,
     payment_data: &mut PaymentData<F>,
     req: Option<CustomerDetails>,
     merchant_id: &str,
     key_store: &domain::MerchantKeyStore,
-) -> CustomResult<(BoxedOperation<'a, F, R>, Option<domain::Customer>), errors::StorageError> {
+) -> CustomResult<(BoxedOperation<'a, F, R, Ctx>, Option<domain::Customer>), errors::StorageError> {
     let request_customer_details = req
         .get_required_value("customer")
         .change_context(errors::StorageError::ValueNotFound("customer".to_owned()))?;
@@ -1302,12 +1303,15 @@ pub async fn create_customer_if_not_exist<'a, F: Clone, R>(
     ))
 }
 
-pub async fn make_pm_data<'a, F: Clone, R>(
-    operation: BoxedOperation<'a, F, R>,
+pub async fn make_pm_data<'a, F: Clone, R, Ctx: PaymentMethodRetrieve>(
+    operation: BoxedOperation<'a, F, R, Ctx>,
     state: &'a AppState,
     payment_data: &mut PaymentData<F>,
-) -> RouterResult<(BoxedOperation<'a, F, R>, Option<api::PaymentMethodData>)> {
-    let request = &payment_data.payment_method_data;
+) -> RouterResult<(
+    BoxedOperation<'a, F, R, Ctx>,
+    Option<api::PaymentMethodData>,
+)> {
+    let request = &payment_data.payment_method_data.clone();
     let token = payment_data.token.clone();
 
     let hyperswitch_token = match payment_data.mandate_id {
@@ -1418,89 +1422,19 @@ pub async fn make_pm_data<'a, F: Clone, R>(
                 None => None,
             })
         }
-        (pm_opt @ Some(pm @ api::PaymentMethodData::Card(_)), _) => {
-            if should_store_payment_method_data_in_vault(
-                &state.conf.temp_locker_disable_config,
-                payment_data.payment_attempt.connector.clone(),
-                enums::PaymentMethod::Card,
-            ) {
-                let parent_payment_method_token = store_in_vault_and_generate_ppmt(
-                    state,
-                    pm,
-                    &payment_data.payment_intent,
-                    &payment_data.payment_attempt,
-                    enums::PaymentMethod::Card,
-                )
-                .await?;
 
-                payment_data.token = Some(parent_payment_method_token);
-            }
-            Ok(pm_opt.to_owned())
-        }
-        (pm @ Some(api::PaymentMethodData::PayLater(_)), _) => Ok(pm.to_owned()),
-        (pm @ Some(api::PaymentMethodData::Crypto(_)), _) => Ok(pm.to_owned()),
-        (pm @ Some(api::PaymentMethodData::BankDebit(_)), _) => Ok(pm.to_owned()),
-        (pm @ Some(api::PaymentMethodData::Upi(_)), _) => Ok(pm.to_owned()),
-        (pm @ Some(api::PaymentMethodData::Voucher(_)), _) => Ok(pm.to_owned()),
-        (pm @ Some(api::PaymentMethodData::Reward), _) => Ok(pm.to_owned()),
-        (pm @ Some(api::PaymentMethodData::CardRedirect(_)), _) => Ok(pm.to_owned()),
-        (pm @ Some(api::PaymentMethodData::GiftCard(_)), _) => Ok(pm.to_owned()),
-        (pm_opt @ Some(pm @ api::PaymentMethodData::BankTransfer(_)), _) => {
-            if should_store_payment_method_data_in_vault(
-                &state.conf.temp_locker_disable_config,
-                payment_data.payment_attempt.connector.clone(),
-                enums::PaymentMethod::BankTransfer,
-            ) {
-                let parent_payment_method_token = store_in_vault_and_generate_ppmt(
-                    state,
-                    pm,
-                    &payment_data.payment_intent,
-                    &payment_data.payment_attempt,
-                    enums::PaymentMethod::BankTransfer,
-                )
-                .await?;
-
-                payment_data.token = Some(parent_payment_method_token);
-            }
+        (Some(_), _) => {
+            let payment_method_data = Ctx::retrieve_payment_method(
+                request,
+                state,
+                &payment_data.payment_intent,
+                &payment_data.payment_attempt,
+            )
+            .await?;
 
-            Ok(pm_opt.to_owned())
-        }
-        (pm_opt @ Some(pm @ api::PaymentMethodData::Wallet(_)), _) => {
-            if should_store_payment_method_data_in_vault(
-                &state.conf.temp_locker_disable_config,
-                payment_data.payment_attempt.connector.clone(),
-                enums::PaymentMethod::Wallet,
-            ) {
-                let parent_payment_method_token = store_in_vault_and_generate_ppmt(
-                    state,
-                    pm,
-                    &payment_data.payment_intent,
-                    &payment_data.payment_attempt,
-                    enums::PaymentMethod::Wallet,
-                )
-                .await?;
+            payment_data.token = payment_method_data.1;
 
-                payment_data.token = Some(parent_payment_method_token);
-            }
-            Ok(pm_opt.to_owned())
-        }
-        (pm_opt @ Some(pm @ api::PaymentMethodData::BankRedirect(_)), _) => {
-            if should_store_payment_method_data_in_vault(
-                &state.conf.temp_locker_disable_config,
-                payment_data.payment_attempt.connector.clone(),
-                enums::PaymentMethod::BankRedirect,
-            ) {
-                let parent_payment_method_token = store_in_vault_and_generate_ppmt(
-                    state,
-                    pm,
-                    &payment_data.payment_intent,
-                    &payment_data.payment_attempt,
-                    enums::PaymentMethod::BankRedirect,
-                )
-                .await?;
-                payment_data.token = Some(parent_payment_method_token);
-            }
-            Ok(pm_opt.to_owned())
+            Ok(payment_method_data.0)
         }
         _ => Ok(None),
     }?;
@@ -1538,6 +1472,32 @@ pub async fn store_in_vault_and_generate_ppmt(
     Ok(parent_payment_method_token)
 }
 
+pub async fn store_payment_method_data_in_vault(
+    state: &AppState,
+    payment_attempt: &PaymentAttempt,
+    payment_intent: &PaymentIntent,
+    payment_method: enums::PaymentMethod,
+    payment_method_data: &api::PaymentMethodData,
+) -> RouterResult<Option<String>> {
+    if should_store_payment_method_data_in_vault(
+        &state.conf.temp_locker_disable_config,
+        payment_attempt.connector.clone(),
+        payment_method,
+    ) {
+        let parent_payment_method_token = store_in_vault_and_generate_ppmt(
+            state,
+            payment_method_data,
+            payment_intent,
+            payment_attempt,
+            payment_method,
+        )
+        .await?;
+
+        return Ok(Some(parent_payment_method_token));
+    }
+
+    Ok(None)
+}
 pub fn should_store_payment_method_data_in_vault(
     temp_locker_disable_config: &TempLockerDisableConfig,
     option_connector: Option<String>,
diff --git a/crates/router/src/core/payments/operations.rs b/crates/router/src/core/payments/operations.rs
index b0c7a5ae126..d198cd562a7 100644
--- a/crates/router/src/core/payments/operations.rs
+++ b/crates/router/src/core/payments/operations.rs
@@ -27,7 +27,10 @@ pub use self::{
 };
 use super::{helpers, CustomerDetails, PaymentData};
 use crate::{
-    core::errors::{self, CustomResult, RouterResult},
+    core::{
+        errors::{self, CustomResult, RouterResult},
+        payment_methods::PaymentMethodRetrieve,
+    },
     db::StorageInterface,
     routes::AppState,
     services,
@@ -38,26 +41,26 @@ use crate::{
     },
 };
 
-pub type BoxedOperation<'a, F, T> = Box<dyn Operation<F, T> + Send + Sync + 'a>;
+pub type BoxedOperation<'a, F, T, Ctx> = Box<dyn Operation<F, T, Ctx> + Send + Sync + 'a>;
 
-pub trait Operation<F: Clone, T>: Send + std::fmt::Debug {
-    fn to_validate_request(&self) -> RouterResult<&(dyn ValidateRequest<F, T> + Send + Sync)> {
+pub trait Operation<F: Clone, T, Ctx: PaymentMethodRetrieve>: Send + std::fmt::Debug {
+    fn to_validate_request(&self) -> RouterResult<&(dyn ValidateRequest<F, T, Ctx> + Send + Sync)> {
         Err(report!(errors::ApiErrorResponse::InternalServerError))
             .attach_printable_lazy(|| format!("validate request interface not found for {self:?}"))
     }
     fn to_get_tracker(
         &self,
-    ) -> RouterResult<&(dyn GetTracker<F, PaymentData<F>, T> + Send + Sync)> {
+    ) -> RouterResult<&(dyn GetTracker<F, PaymentData<F>, T, Ctx> + Send + Sync)> {
         Err(report!(errors::ApiErrorResponse::InternalServerError))
             .attach_printable_lazy(|| format!("get tracker interface not found for {self:?}"))
     }
-    fn to_domain(&self) -> RouterResult<&dyn Domain<F, T>> {
+    fn to_domain(&self) -> RouterResult<&dyn Domain<F, T, Ctx>> {
         Err(report!(errors::ApiErrorResponse::InternalServerError))
             .attach_printable_lazy(|| format!("domain interface not found for {self:?}"))
     }
     fn to_update_tracker(
         &self,
-    ) -> RouterResult<&(dyn UpdateTracker<F, PaymentData<F>, T> + Send + Sync)> {
+    ) -> RouterResult<&(dyn UpdateTracker<F, PaymentData<F>, T, Ctx> + Send + Sync)> {
         Err(report!(errors::ApiErrorResponse::InternalServerError))
             .attach_printable_lazy(|| format!("update tracker interface not found for {self:?}"))
     }
@@ -80,16 +83,16 @@ pub struct ValidateResult<'a> {
 }
 
 #[allow(clippy::type_complexity)]
-pub trait ValidateRequest<F, R> {
+pub trait ValidateRequest<F, R, Ctx: PaymentMethodRetrieve> {
     fn validate_request<'a, 'b>(
         &'b self,
         request: &R,
         merchant_account: &'a domain::MerchantAccount,
-    ) -> RouterResult<(BoxedOperation<'b, F, R>, ValidateResult<'a>)>;
+    ) -> RouterResult<(BoxedOperation<'b, F, R, Ctx>, ValidateResult<'a>)>;
 }
 
 #[async_trait]
-pub trait GetTracker<F, D, R>: Send {
+pub trait GetTracker<F, D, R, Ctx: PaymentMethodRetrieve>: Send {
     #[allow(clippy::too_many_arguments)]
     async fn get_trackers<'a>(
         &'a self,
@@ -100,11 +103,11 @@ pub trait GetTracker<F, D, R>: Send {
         merchant_account: &domain::MerchantAccount,
         mechant_key_store: &domain::MerchantKeyStore,
         auth_flow: services::AuthFlow,
-    ) -> RouterResult<(BoxedOperation<'a, F, R>, D, Option<CustomerDetails>)>;
+    ) -> RouterResult<(BoxedOperation<'a, F, R, Ctx>, D, Option<CustomerDetails>)>;
 }
 
 #[async_trait]
-pub trait Domain<F: Clone, R>: Send + Sync {
+pub trait Domain<F: Clone, R, Ctx: PaymentMethodRetrieve>: Send + Sync {
     /// This will fetch customer details, (this operation is flow specific)
     async fn get_or_create_customer_details<'a>(
         &'a self,
@@ -112,7 +115,7 @@ pub trait Domain<F: Clone, R>: Send + Sync {
         payment_data: &mut PaymentData<F>,
         request: Option<CustomerDetails>,
         merchant_key_store: &domain::MerchantKeyStore,
-    ) -> CustomResult<(BoxedOperation<'a, F, R>, Option<domain::Customer>), errors::StorageError>;
+    ) -> CustomResult<(BoxedOperation<'a, F, R, Ctx>, Option<domain::Customer>), errors::StorageError>;
 
     #[allow(clippy::too_many_arguments)]
     async fn make_pm_data<'a>(
@@ -120,7 +123,10 @@ pub trait Domain<F: Clone, R>: Send + Sync {
         state: &'a AppState,
         payment_data: &mut PaymentData<F>,
         storage_scheme: enums::MerchantStorageScheme,
-    ) -> RouterResult<(BoxedOperation<'a, F, R>, Option<api::PaymentMethodData>)>;
+    ) -> RouterResult<(
+        BoxedOperation<'a, F, R, Ctx>,
+        Option<api::PaymentMethodData>,
+    )>;
 
     async fn add_task_to_process_tracker<'a>(
         &'a self,
@@ -144,7 +150,7 @@ pub trait Domain<F: Clone, R>: Send + Sync {
 
 #[async_trait]
 #[allow(clippy::too_many_arguments)]
-pub trait UpdateTracker<F, D, Req>: Send {
+pub trait UpdateTracker<F, D, Req, Ctx: PaymentMethodRetrieve>: Send {
     async fn update_trackers<'b>(
         &'b self,
         db: &dyn StorageInterface,
@@ -155,7 +161,7 @@ pub trait UpdateTracker<F, D, Req>: Send {
         mechant_key_store: &domain::MerchantKeyStore,
         frm_suggestion: Option<FrmSuggestion>,
         header_payload: api::HeaderPayload,
-    ) -> RouterResult<(BoxedOperation<'b, F, Req>, D)>
+    ) -> RouterResult<(BoxedOperation<'b, F, Req, Ctx>, D)>
     where
         F: 'b + Send;
 }
@@ -175,10 +181,13 @@ pub trait PostUpdateTracker<F, D, R>: Send {
 }
 
 #[async_trait]
-impl<F: Clone + Send, Op: Send + Sync + Operation<F, api::PaymentsRetrieveRequest>>
-    Domain<F, api::PaymentsRetrieveRequest> for Op
+impl<
+        F: Clone + Send,
+        Ctx: PaymentMethodRetrieve,
+        Op: Send + Sync + Operation<F, api::PaymentsRetrieveRequest, Ctx>,
+    > Domain<F, api::PaymentsRetrieveRequest, Ctx> for Op
 where
-    for<'a> &'a Op: Operation<F, api::PaymentsRetrieveRequest>,
+    for<'a> &'a Op: Operation<F, api::PaymentsRetrieveRequest, Ctx>,
 {
     #[instrument(skip_all)]
     async fn get_or_create_customer_details<'a>(
@@ -189,7 +198,7 @@ where
         merchant_key_store: &domain::MerchantKeyStore,
     ) -> CustomResult<
         (
-            BoxedOperation<'a, F, api::PaymentsRetrieveRequest>,
+            BoxedOperation<'a, F, api::PaymentsRetrieveRequest, Ctx>,
             Option<domain::Customer>,
         ),
         errors::StorageError,
@@ -225,7 +234,7 @@ where
         payment_data: &mut PaymentData<F>,
         _storage_scheme: enums::MerchantStorageScheme,
     ) -> RouterResult<(
-        BoxedOperation<'a, F, api::PaymentsRetrieveRequest>,
+        BoxedOperation<'a, F, api::PaymentsRetrieveRequest, Ctx>,
         Option<api::PaymentMethodData>,
     )> {
         helpers::make_pm_data(Box::new(self), state, payment_data).await
@@ -233,10 +242,13 @@ where
 }
 
 #[async_trait]
-impl<F: Clone + Send, Op: Send + Sync + Operation<F, api::PaymentsCaptureRequest>>
-    Domain<F, api::PaymentsCaptureRequest> for Op
+impl<
+        F: Clone + Send,
+        Ctx: PaymentMethodRetrieve,
+        Op: Send + Sync + Operation<F, api::PaymentsCaptureRequest, Ctx>,
+    > Domain<F, api::PaymentsCaptureRequest, Ctx> for Op
 where
-    for<'a> &'a Op: Operation<F, api::PaymentsCaptureRequest>,
+    for<'a> &'a Op: Operation<F, api::PaymentsCaptureRequest, Ctx>,
 {
     #[instrument(skip_all)]
     async fn get_or_create_customer_details<'a>(
@@ -247,7 +259,7 @@ where
         merchant_key_store: &domain::MerchantKeyStore,
     ) -> CustomResult<
         (
-            BoxedOperation<'a, F, api::PaymentsCaptureRequest>,
+            BoxedOperation<'a, F, api::PaymentsCaptureRequest, Ctx>,
             Option<domain::Customer>,
         ),
         errors::StorageError,
@@ -271,7 +283,7 @@ where
         _payment_data: &mut PaymentData<F>,
         _storage_scheme: enums::MerchantStorageScheme,
     ) -> RouterResult<(
-        BoxedOperation<'a, F, api::PaymentsCaptureRequest>,
+        BoxedOperation<'a, F, api::PaymentsCaptureRequest, Ctx>,
         Option<api::PaymentMethodData>,
     )> {
         Ok((Box::new(self), None))
@@ -290,10 +302,13 @@ where
 }
 
 #[async_trait]
-impl<F: Clone + Send, Op: Send + Sync + Operation<F, api::PaymentsCancelRequest>>
-    Domain<F, api::PaymentsCancelRequest> for Op
+impl<
+        F: Clone + Send,
+        Ctx: PaymentMethodRetrieve,
+        Op: Send + Sync + Operation<F, api::PaymentsCancelRequest, Ctx>,
+    > Domain<F, api::PaymentsCancelRequest, Ctx> for Op
 where
-    for<'a> &'a Op: Operation<F, api::PaymentsCancelRequest>,
+    for<'a> &'a Op: Operation<F, api::PaymentsCancelRequest, Ctx>,
 {
     #[instrument(skip_all)]
     async fn get_or_create_customer_details<'a>(
@@ -304,7 +319,7 @@ where
         merchant_key_store: &domain::MerchantKeyStore,
     ) -> CustomResult<
         (
-            BoxedOperation<'a, F, api::PaymentsCancelRequest>,
+            BoxedOperation<'a, F, api::PaymentsCancelRequest, Ctx>,
             Option<domain::Customer>,
         ),
         errors::StorageError,
@@ -329,7 +344,7 @@ where
         _payment_data: &mut PaymentData<F>,
         _storage_scheme: enums::MerchantStorageScheme,
     ) -> RouterResult<(
-        BoxedOperation<'a, F, api::PaymentsCancelRequest>,
+        BoxedOperation<'a, F, api::PaymentsCancelRequest, Ctx>,
         Option<api::PaymentMethodData>,
     )> {
         Ok((Box::new(self), None))
@@ -348,10 +363,13 @@ where
 }
 
 #[async_trait]
-impl<F: Clone + Send, Op: Send + Sync + Operation<F, api::PaymentsRejectRequest>>
-    Domain<F, api::PaymentsRejectRequest> for Op
+impl<
+        F: Clone + Send,
+        Ctx: PaymentMethodRetrieve,
+        Op: Send + Sync + Operation<F, api::PaymentsRejectRequest, Ctx>,
+    > Domain<F, api::PaymentsRejectRequest, Ctx> for Op
 where
-    for<'a> &'a Op: Operation<F, api::PaymentsRejectRequest>,
+    for<'a> &'a Op: Operation<F, api::PaymentsRejectRequest, Ctx>,
 {
     #[instrument(skip_all)]
     async fn get_or_create_customer_details<'a>(
@@ -362,7 +380,7 @@ where
         _merchant_key_store: &domain::MerchantKeyStore,
     ) -> CustomResult<
         (
-            BoxedOperation<'a, F, api::PaymentsRejectRequest>,
+            BoxedOperation<'a, F, api::PaymentsRejectRequest, Ctx>,
             Option<domain::Customer>,
         ),
         errors::StorageError,
@@ -377,7 +395,7 @@ where
         _payment_data: &mut PaymentData<F>,
         _storage_scheme: enums::MerchantStorageScheme,
     ) -> RouterResult<(
-        BoxedOperation<'a, F, api::PaymentsRejectRequest>,
+        BoxedOperation<'a, F, api::PaymentsRejectRequest, Ctx>,
         Option<api::PaymentMethodData>,
     )> {
         Ok((Box::new(self), None))
diff --git a/crates/router/src/core/payments/operations/payment_approve.rs b/crates/router/src/core/payments/operations/payment_approve.rs
index 871e906ee9d..d7b3d743b95 100644
--- a/crates/router/src/core/payments/operations/payment_approve.rs
+++ b/crates/router/src/core/payments/operations/payment_approve.rs
@@ -11,6 +11,7 @@ use super::{BoxedOperation, Domain, GetTracker, Operation, UpdateTracker, Valida
 use crate::{
     core::{
         errors::{self, CustomResult, RouterResult, StorageErrorExt},
+        payment_methods::PaymentMethodRetrieve,
         payments::{self, helpers, operations, CustomerDetails, PaymentAddress, PaymentData},
         utils as core_utils,
     },
@@ -31,7 +32,9 @@ use crate::{
 pub struct PaymentApprove;
 
 #[async_trait]
-impl<F: Send + Clone> GetTracker<F, PaymentData<F>, api::PaymentsRequest> for PaymentApprove {
+impl<F: Send + Clone, Ctx: PaymentMethodRetrieve>
+    GetTracker<F, PaymentData<F>, api::PaymentsRequest, Ctx> for PaymentApprove
+{
     #[instrument(skip_all)]
     async fn get_trackers<'a>(
         &'a self,
@@ -43,7 +46,7 @@ impl<F: Send + Clone> GetTracker<F, PaymentData<F>, api::PaymentsRequest> for Pa
         key_store: &domain::MerchantKeyStore,
         _auth_flow: services::AuthFlow,
     ) -> RouterResult<(
-        BoxedOperation<'a, F, api::PaymentsRequest>,
+        BoxedOperation<'a, F, api::PaymentsRequest, Ctx>,
         PaymentData<F>,
         Option<CustomerDetails>,
     )> {
@@ -262,7 +265,9 @@ impl<F: Send + Clone> GetTracker<F, PaymentData<F>, api::PaymentsRequest> for Pa
 }
 
 #[async_trait]
-impl<F: Clone + Send> Domain<F, api::PaymentsRequest> for PaymentApprove {
+impl<F: Clone + Send, Ctx: PaymentMethodRetrieve> Domain<F, api::PaymentsRequest, Ctx>
+    for PaymentApprove
+{
     #[instrument(skip_all)]
     async fn get_or_create_customer_details<'a>(
         &'a self,
@@ -272,7 +277,7 @@ impl<F: Clone + Send> Domain<F, api::PaymentsRequest> for PaymentApprove {
         key_store: &domain::MerchantKeyStore,
     ) -> CustomResult<
         (
-            BoxedOperation<'a, F, api::PaymentsRequest>,
+            BoxedOperation<'a, F, api::PaymentsRequest, Ctx>,
             Option<domain::Customer>,
         ),
         errors::StorageError,
@@ -295,7 +300,7 @@ impl<F: Clone + Send> Domain<F, api::PaymentsRequest> for PaymentApprove {
         payment_data: &mut PaymentData<F>,
         _storage_scheme: storage_enums::MerchantStorageScheme,
     ) -> RouterResult<(
-        BoxedOperation<'a, F, api::PaymentsRequest>,
+        BoxedOperation<'a, F, api::PaymentsRequest, Ctx>,
         Option<api::PaymentMethodData>,
     )> {
         let (op, payment_method_data) =
@@ -334,7 +339,9 @@ impl<F: Clone + Send> Domain<F, api::PaymentsRequest> for PaymentApprove {
 }
 
 #[async_trait]
-impl<F: Clone> UpdateTracker<F, PaymentData<F>, api::PaymentsRequest> for PaymentApprove {
+impl<F: Clone, Ctx: PaymentMethodRetrieve>
+    UpdateTracker<F, PaymentData<F>, api::PaymentsRequest, Ctx> for PaymentApprove
+{
     #[instrument(skip_all)]
     async fn update_trackers<'b>(
         &'b self,
@@ -346,7 +353,10 @@ impl<F: Clone> UpdateTracker<F, PaymentData<F>, api::PaymentsRequest> for Paymen
         _merchant_key_store: &domain::MerchantKeyStore,
         _frm_suggestion: Option<FrmSuggestion>,
         _header_payload: api::HeaderPayload,
-    ) -> RouterResult<(BoxedOperation<'b, F, api::PaymentsRequest>, PaymentData<F>)>
+    ) -> RouterResult<(
+        BoxedOperation<'b, F, api::PaymentsRequest, Ctx>,
+        PaymentData<F>,
+    )>
     where
         F: 'b + Send,
     {
@@ -366,14 +376,16 @@ impl<F: Clone> UpdateTracker<F, PaymentData<F>, api::PaymentsRequest> for Paymen
     }
 }
 
-impl<F: Send + Clone> ValidateRequest<F, api::PaymentsRequest> for PaymentApprove {
+impl<F: Send + Clone, Ctx: PaymentMethodRetrieve> ValidateRequest<F, api::PaymentsRequest, Ctx>
+    for PaymentApprove
+{
     #[instrument(skip_all)]
     fn validate_request<'a, 'b>(
         &'b self,
         request: &api::PaymentsRequest,
         merchant_account: &'a domain::MerchantAccount,
     ) -> RouterResult<(
-        BoxedOperation<'b, F, api::PaymentsRequest>,
+        BoxedOperation<'b, F, api::PaymentsRequest, Ctx>,
         operations::ValidateResult<'a>,
     )> {
         let given_payment_id = match &request.payment_id {
diff --git a/crates/router/src/core/payments/operations/payment_cancel.rs b/crates/router/src/core/payments/operations/payment_cancel.rs
index f2964a4e48c..72006946c20 100644
--- a/crates/router/src/core/payments/operations/payment_cancel.rs
+++ b/crates/router/src/core/payments/operations/payment_cancel.rs
@@ -11,6 +11,7 @@ use super::{BoxedOperation, Domain, GetTracker, Operation, UpdateTracker, Valida
 use crate::{
     core::{
         errors::{self, RouterResult, StorageErrorExt},
+        payment_methods::PaymentMethodRetrieve,
         payments::{helpers, operations, CustomerDetails, PaymentAddress, PaymentData},
     },
     db::StorageInterface,
@@ -29,7 +30,9 @@ use crate::{
 pub struct PaymentCancel;
 
 #[async_trait]
-impl<F: Send + Clone> GetTracker<F, PaymentData<F>, api::PaymentsCancelRequest> for PaymentCancel {
+impl<F: Send + Clone, Ctx: PaymentMethodRetrieve>
+    GetTracker<F, PaymentData<F>, api::PaymentsCancelRequest, Ctx> for PaymentCancel
+{
     #[instrument(skip_all)]
     async fn get_trackers<'a>(
         &'a self,
@@ -41,7 +44,7 @@ impl<F: Send + Clone> GetTracker<F, PaymentData<F>, api::PaymentsCancelRequest>
         key_store: &domain::MerchantKeyStore,
         _auth_flow: services::AuthFlow,
     ) -> RouterResult<(
-        BoxedOperation<'a, F, api::PaymentsCancelRequest>,
+        BoxedOperation<'a, F, api::PaymentsCancelRequest, Ctx>,
         PaymentData<F>,
         Option<CustomerDetails>,
     )> {
@@ -176,7 +179,9 @@ impl<F: Send + Clone> GetTracker<F, PaymentData<F>, api::PaymentsCancelRequest>
 }
 
 #[async_trait]
-impl<F: Clone> UpdateTracker<F, PaymentData<F>, api::PaymentsCancelRequest> for PaymentCancel {
+impl<F: Clone, Ctx: PaymentMethodRetrieve>
+    UpdateTracker<F, PaymentData<F>, api::PaymentsCancelRequest, Ctx> for PaymentCancel
+{
     #[instrument(skip_all)]
     async fn update_trackers<'b>(
         &'b self,
@@ -189,7 +194,7 @@ impl<F: Clone> UpdateTracker<F, PaymentData<F>, api::PaymentsCancelRequest> for
         _frm_suggestion: Option<FrmSuggestion>,
         _header_payload: api::HeaderPayload,
     ) -> RouterResult<(
-        BoxedOperation<'b, F, api::PaymentsCancelRequest>,
+        BoxedOperation<'b, F, api::PaymentsCancelRequest, Ctx>,
         PaymentData<F>,
     )>
     where
@@ -231,14 +236,16 @@ impl<F: Clone> UpdateTracker<F, PaymentData<F>, api::PaymentsCancelRequest> for
     }
 }
 
-impl<F: Send + Clone> ValidateRequest<F, api::PaymentsCancelRequest> for PaymentCancel {
+impl<F: Send + Clone, Ctx: PaymentMethodRetrieve>
+    ValidateRequest<F, api::PaymentsCancelRequest, Ctx> for PaymentCancel
+{
     #[instrument(skip_all)]
     fn validate_request<'a, 'b>(
         &'b self,
         request: &api::PaymentsCancelRequest,
         merchant_account: &'a domain::MerchantAccount,
     ) -> RouterResult<(
-        BoxedOperation<'b, F, api::PaymentsCancelRequest>,
+        BoxedOperation<'b, F, api::PaymentsCancelRequest, Ctx>,
         operations::ValidateResult<'a>,
     )> {
         Ok((
diff --git a/crates/router/src/core/payments/operations/payment_capture.rs b/crates/router/src/core/payments/operations/payment_capture.rs
index c3b915f9d34..bd64ebac632 100644
--- a/crates/router/src/core/payments/operations/payment_capture.rs
+++ b/crates/router/src/core/payments/operations/payment_capture.rs
@@ -11,6 +11,7 @@ use super::{BoxedOperation, Domain, GetTracker, Operation, UpdateTracker, Valida
 use crate::{
     core::{
         errors::{self, RouterResult, StorageErrorExt},
+        payment_methods::PaymentMethodRetrieve,
         payments::{self, helpers, operations, types::MultipleCaptureData},
     },
     db::StorageInterface,
@@ -29,8 +30,8 @@ use crate::{
 pub struct PaymentCapture;
 
 #[async_trait]
-impl<F: Send + Clone> GetTracker<F, payments::PaymentData<F>, api::PaymentsCaptureRequest>
-    for PaymentCapture
+impl<F: Send + Clone, Ctx: PaymentMethodRetrieve>
+    GetTracker<F, payments::PaymentData<F>, api::PaymentsCaptureRequest, Ctx> for PaymentCapture
 {
     #[instrument(skip_all)]
     async fn get_trackers<'a>(
@@ -43,7 +44,7 @@ impl<F: Send + Clone> GetTracker<F, payments::PaymentData<F>, api::PaymentsCaptu
         key_store: &domain::MerchantKeyStore,
         _auth_flow: services::AuthFlow,
     ) -> RouterResult<(
-        BoxedOperation<'a, F, api::PaymentsCaptureRequest>,
+        BoxedOperation<'a, F, api::PaymentsCaptureRequest, Ctx>,
         payments::PaymentData<F>,
         Option<payments::CustomerDetails>,
     )> {
@@ -236,7 +237,8 @@ impl<F: Send + Clone> GetTracker<F, payments::PaymentData<F>, api::PaymentsCaptu
 }
 
 #[async_trait]
-impl<F: Clone> UpdateTracker<F, payments::PaymentData<F>, api::PaymentsCaptureRequest>
+impl<F: Clone, Ctx: PaymentMethodRetrieve>
+    UpdateTracker<F, payments::PaymentData<F>, api::PaymentsCaptureRequest, Ctx>
     for PaymentCapture
 {
     #[instrument(skip_all)]
@@ -251,7 +253,7 @@ impl<F: Clone> UpdateTracker<F, payments::PaymentData<F>, api::PaymentsCaptureRe
         _frm_suggestion: Option<FrmSuggestion>,
         _header_payload: api::HeaderPayload,
     ) -> RouterResult<(
-        BoxedOperation<'b, F, api::PaymentsCaptureRequest>,
+        BoxedOperation<'b, F, api::PaymentsCaptureRequest, Ctx>,
         payments::PaymentData<F>,
     )>
     where
@@ -274,14 +276,16 @@ impl<F: Clone> UpdateTracker<F, payments::PaymentData<F>, api::PaymentsCaptureRe
     }
 }
 
-impl<F: Send + Clone> ValidateRequest<F, api::PaymentsCaptureRequest> for PaymentCapture {
+impl<F: Send + Clone, Ctx: PaymentMethodRetrieve>
+    ValidateRequest<F, api::PaymentsCaptureRequest, Ctx> for PaymentCapture
+{
     #[instrument(skip_all)]
     fn validate_request<'a, 'b>(
         &'b self,
         request: &api::PaymentsCaptureRequest,
         merchant_account: &'a domain::MerchantAccount,
     ) -> RouterResult<(
-        BoxedOperation<'b, F, api::PaymentsCaptureRequest>,
+        BoxedOperation<'b, F, api::PaymentsCaptureRequest, Ctx>,
         operations::ValidateResult<'a>,
     )> {
         Ok((
diff --git a/crates/router/src/core/payments/operations/payment_complete_authorize.rs b/crates/router/src/core/payments/operations/payment_complete_authorize.rs
index 1ee7bec135f..db2c9e27c9b 100644
--- a/crates/router/src/core/payments/operations/payment_complete_authorize.rs
+++ b/crates/router/src/core/payments/operations/payment_complete_authorize.rs
@@ -10,6 +10,7 @@ use super::{BoxedOperation, Domain, GetTracker, Operation, UpdateTracker, Valida
 use crate::{
     core::{
         errors::{self, CustomResult, RouterResult, StorageErrorExt},
+        payment_methods::PaymentMethodRetrieve,
         payments::{self, helpers, operations, CustomerDetails, PaymentAddress, PaymentData},
         utils as core_utils,
     },
@@ -30,7 +31,9 @@ use crate::{
 pub struct CompleteAuthorize;
 
 #[async_trait]
-impl<F: Send + Clone> GetTracker<F, PaymentData<F>, api::PaymentsRequest> for CompleteAuthorize {
+impl<F: Send + Clone, Ctx: PaymentMethodRetrieve>
+    GetTracker<F, PaymentData<F>, api::PaymentsRequest, Ctx> for CompleteAuthorize
+{
     #[instrument(skip_all)]
     async fn get_trackers<'a>(
         &'a self,
@@ -42,7 +45,7 @@ impl<F: Send + Clone> GetTracker<F, PaymentData<F>, api::PaymentsRequest> for Co
         key_store: &domain::MerchantKeyStore,
         _auth_flow: services::AuthFlow,
     ) -> RouterResult<(
-        BoxedOperation<'a, F, api::PaymentsRequest>,
+        BoxedOperation<'a, F, api::PaymentsRequest, Ctx>,
         PaymentData<F>,
         Option<CustomerDetails>,
     )> {
@@ -257,7 +260,9 @@ impl<F: Send + Clone> GetTracker<F, PaymentData<F>, api::PaymentsRequest> for Co
 }
 
 #[async_trait]
-impl<F: Clone + Send> Domain<F, api::PaymentsRequest> for CompleteAuthorize {
+impl<F: Clone + Send, Ctx: PaymentMethodRetrieve> Domain<F, api::PaymentsRequest, Ctx>
+    for CompleteAuthorize
+{
     #[instrument(skip_all)]
     async fn get_or_create_customer_details<'a>(
         &'a self,
@@ -267,7 +272,7 @@ impl<F: Clone + Send> Domain<F, api::PaymentsRequest> for CompleteAuthorize {
         key_store: &domain::MerchantKeyStore,
     ) -> CustomResult<
         (
-            BoxedOperation<'a, F, api::PaymentsRequest>,
+            BoxedOperation<'a, F, api::PaymentsRequest, Ctx>,
             Option<domain::Customer>,
         ),
         errors::StorageError,
@@ -290,7 +295,7 @@ impl<F: Clone + Send> Domain<F, api::PaymentsRequest> for CompleteAuthorize {
         payment_data: &mut PaymentData<F>,
         _storage_scheme: storage_enums::MerchantStorageScheme,
     ) -> RouterResult<(
-        BoxedOperation<'a, F, api::PaymentsRequest>,
+        BoxedOperation<'a, F, api::PaymentsRequest, Ctx>,
         Option<api::PaymentMethodData>,
     )> {
         let (op, payment_method_data) =
@@ -329,7 +334,9 @@ impl<F: Clone + Send> Domain<F, api::PaymentsRequest> for CompleteAuthorize {
 }
 
 #[async_trait]
-impl<F: Clone> UpdateTracker<F, PaymentData<F>, api::PaymentsRequest> for CompleteAuthorize {
+impl<F: Clone, Ctx: PaymentMethodRetrieve>
+    UpdateTracker<F, PaymentData<F>, api::PaymentsRequest, Ctx> for CompleteAuthorize
+{
     #[instrument(skip_all)]
     async fn update_trackers<'b>(
         &'b self,
@@ -341,7 +348,10 @@ impl<F: Clone> UpdateTracker<F, PaymentData<F>, api::PaymentsRequest> for Comple
         _merchant_key_store: &domain::MerchantKeyStore,
         _frm_suggestion: Option<FrmSuggestion>,
         _header_payload: api::HeaderPayload,
-    ) -> RouterResult<(BoxedOperation<'b, F, api::PaymentsRequest>, PaymentData<F>)>
+    ) -> RouterResult<(
+        BoxedOperation<'b, F, api::PaymentsRequest, Ctx>,
+        PaymentData<F>,
+    )>
     where
         F: 'b + Send,
     {
@@ -349,14 +359,16 @@ impl<F: Clone> UpdateTracker<F, PaymentData<F>, api::PaymentsRequest> for Comple
     }
 }
 
-impl<F: Send + Clone> ValidateRequest<F, api::PaymentsRequest> for CompleteAuthorize {
+impl<F: Send + Clone, Ctx: PaymentMethodRetrieve> ValidateRequest<F, api::PaymentsRequest, Ctx>
+    for CompleteAuthorize
+{
     #[instrument(skip_all)]
     fn validate_request<'a, 'b>(
         &'b self,
         request: &api::PaymentsRequest,
         merchant_account: &'a domain::MerchantAccount,
     ) -> RouterResult<(
-        BoxedOperation<'b, F, api::PaymentsRequest>,
+        BoxedOperation<'b, F, api::PaymentsRequest, Ctx>,
         operations::ValidateResult<'a>,
     )> {
         let given_payment_id = match &request.payment_id {
diff --git a/crates/router/src/core/payments/operations/payment_confirm.rs b/crates/router/src/core/payments/operations/payment_confirm.rs
index 2d35ef61ff6..761264e4798 100644
--- a/crates/router/src/core/payments/operations/payment_confirm.rs
+++ b/crates/router/src/core/payments/operations/payment_confirm.rs
@@ -12,6 +12,7 @@ use super::{BoxedOperation, Domain, GetTracker, Operation, UpdateTracker, Valida
 use crate::{
     core::{
         errors::{self, CustomResult, RouterResult, StorageErrorExt},
+        payment_methods::PaymentMethodRetrieve,
         payments::{self, helpers, operations, CustomerDetails, PaymentAddress, PaymentData},
     },
     db::StorageInterface,
@@ -30,7 +31,9 @@ use crate::{
 #[operation(ops = "all", flow = "authorize")]
 pub struct PaymentConfirm;
 #[async_trait]
-impl<F: Send + Clone> GetTracker<F, PaymentData<F>, api::PaymentsRequest> for PaymentConfirm {
+impl<F: Send + Clone, Ctx: PaymentMethodRetrieve>
+    GetTracker<F, PaymentData<F>, api::PaymentsRequest, Ctx> for PaymentConfirm
+{
     #[instrument(skip_all)]
     async fn get_trackers<'a>(
         &'a self,
@@ -42,7 +45,7 @@ impl<F: Send + Clone> GetTracker<F, PaymentData<F>, api::PaymentsRequest> for Pa
         key_store: &domain::MerchantKeyStore,
         auth_flow: services::AuthFlow,
     ) -> RouterResult<(
-        BoxedOperation<'a, F, api::PaymentsRequest>,
+        BoxedOperation<'a, F, api::PaymentsRequest, Ctx>,
         PaymentData<F>,
         Option<CustomerDetails>,
     )> {
@@ -364,7 +367,9 @@ impl<F: Send + Clone> GetTracker<F, PaymentData<F>, api::PaymentsRequest> for Pa
 }
 
 #[async_trait]
-impl<F: Clone + Send> Domain<F, api::PaymentsRequest> for PaymentConfirm {
+impl<F: Clone + Send, Ctx: PaymentMethodRetrieve> Domain<F, api::PaymentsRequest, Ctx>
+    for PaymentConfirm
+{
     #[instrument(skip_all)]
     async fn get_or_create_customer_details<'a>(
         &'a self,
@@ -374,7 +379,7 @@ impl<F: Clone + Send> Domain<F, api::PaymentsRequest> for PaymentConfirm {
         key_store: &domain::MerchantKeyStore,
     ) -> CustomResult<
         (
-            BoxedOperation<'a, F, api::PaymentsRequest>,
+            BoxedOperation<'a, F, api::PaymentsRequest, Ctx>,
             Option<domain::Customer>,
         ),
         errors::StorageError,
@@ -397,7 +402,7 @@ impl<F: Clone + Send> Domain<F, api::PaymentsRequest> for PaymentConfirm {
         payment_data: &mut PaymentData<F>,
         _storage_scheme: storage_enums::MerchantStorageScheme,
     ) -> RouterResult<(
-        BoxedOperation<'a, F, api::PaymentsRequest>,
+        BoxedOperation<'a, F, api::PaymentsRequest, Ctx>,
         Option<api::PaymentMethodData>,
     )> {
         let (op, payment_method_data) =
@@ -436,7 +441,9 @@ impl<F: Clone + Send> Domain<F, api::PaymentsRequest> for PaymentConfirm {
 }
 
 #[async_trait]
-impl<F: Clone> UpdateTracker<F, PaymentData<F>, api::PaymentsRequest> for PaymentConfirm {
+impl<F: Clone, Ctx: PaymentMethodRetrieve>
+    UpdateTracker<F, PaymentData<F>, api::PaymentsRequest, Ctx> for PaymentConfirm
+{
     #[instrument(skip_all)]
     async fn update_trackers<'b>(
         &'b self,
@@ -448,7 +455,10 @@ impl<F: Clone> UpdateTracker<F, PaymentData<F>, api::PaymentsRequest> for Paymen
         key_store: &domain::MerchantKeyStore,
         frm_suggestion: Option<FrmSuggestion>,
         header_payload: api::HeaderPayload,
-    ) -> RouterResult<(BoxedOperation<'b, F, api::PaymentsRequest>, PaymentData<F>)>
+    ) -> RouterResult<(
+        BoxedOperation<'b, F, api::PaymentsRequest, Ctx>,
+        PaymentData<F>,
+    )>
     where
         F: 'b + Send,
     {
@@ -597,14 +607,16 @@ impl<F: Clone> UpdateTracker<F, PaymentData<F>, api::PaymentsRequest> for Paymen
     }
 }
 
-impl<F: Send + Clone> ValidateRequest<F, api::PaymentsRequest> for PaymentConfirm {
+impl<F: Send + Clone, Ctx: PaymentMethodRetrieve> ValidateRequest<F, api::PaymentsRequest, Ctx>
+    for PaymentConfirm
+{
     #[instrument(skip_all)]
     fn validate_request<'a, 'b>(
         &'b self,
         request: &api::PaymentsRequest,
         merchant_account: &'a domain::MerchantAccount,
     ) -> RouterResult<(
-        BoxedOperation<'b, F, api::PaymentsRequest>,
+        BoxedOperation<'b, F, api::PaymentsRequest, Ctx>,
         operations::ValidateResult<'a>,
     )> {
         helpers::validate_customer_details_in_request(request)?;
diff --git a/crates/router/src/core/payments/operations/payment_create.rs b/crates/router/src/core/payments/operations/payment_create.rs
index 17d8d5f6c3d..479b0e2ccee 100644
--- a/crates/router/src/core/payments/operations/payment_create.rs
+++ b/crates/router/src/core/payments/operations/payment_create.rs
@@ -14,6 +14,7 @@ use crate::{
     consts,
     core::{
         errors::{self, CustomResult, RouterResult, StorageErrorExt},
+        payment_methods::PaymentMethodRetrieve,
         payments::{self, helpers, operations, CustomerDetails, PaymentAddress, PaymentData},
         utils::{self as core_utils},
     },
@@ -39,7 +40,9 @@ pub struct PaymentCreate;
 /// The `get_trackers` function for `PaymentsCreate` is an entrypoint for new payments
 /// This will create all the entities required for a new payment from the request
 #[async_trait]
-impl<F: Send + Clone> GetTracker<F, PaymentData<F>, api::PaymentsRequest> for PaymentCreate {
+impl<F: Send + Clone, Ctx: PaymentMethodRetrieve>
+    GetTracker<F, PaymentData<F>, api::PaymentsRequest, Ctx> for PaymentCreate
+{
     #[instrument(skip_all)]
     async fn get_trackers<'a>(
         &'a self,
@@ -51,7 +54,7 @@ impl<F: Send + Clone> GetTracker<F, PaymentData<F>, api::PaymentsRequest> for Pa
         merchant_key_store: &domain::MerchantKeyStore,
         _auth_flow: services::AuthFlow,
     ) -> RouterResult<(
-        BoxedOperation<'a, F, api::PaymentsRequest>,
+        BoxedOperation<'a, F, api::PaymentsRequest, Ctx>,
         PaymentData<F>,
         Option<CustomerDetails>,
     )> {
@@ -231,7 +234,7 @@ impl<F: Send + Clone> GetTracker<F, PaymentData<F>, api::PaymentsRequest> for Pa
             .await
             .transpose()?;
 
-        let operation = payments::if_not_create_change_operation::<_, F>(
+        let operation = payments::if_not_create_change_operation::<_, F, Ctx>(
             payment_intent.status,
             request.confirm,
             self,
@@ -299,7 +302,9 @@ impl<F: Send + Clone> GetTracker<F, PaymentData<F>, api::PaymentsRequest> for Pa
 }
 
 #[async_trait]
-impl<F: Clone + Send> Domain<F, api::PaymentsRequest> for PaymentCreate {
+impl<F: Clone + Send, Ctx: PaymentMethodRetrieve> Domain<F, api::PaymentsRequest, Ctx>
+    for PaymentCreate
+{
     #[instrument(skip_all)]
     async fn get_or_create_customer_details<'a>(
         &'a self,
@@ -309,7 +314,7 @@ impl<F: Clone + Send> Domain<F, api::PaymentsRequest> for PaymentCreate {
         key_store: &domain::MerchantKeyStore,
     ) -> CustomResult<
         (
-            BoxedOperation<'a, F, api::PaymentsRequest>,
+            BoxedOperation<'a, F, api::PaymentsRequest, Ctx>,
             Option<domain::Customer>,
         ),
         errors::StorageError,
@@ -332,7 +337,7 @@ impl<F: Clone + Send> Domain<F, api::PaymentsRequest> for PaymentCreate {
         payment_data: &mut PaymentData<F>,
         _storage_scheme: enums::MerchantStorageScheme,
     ) -> RouterResult<(
-        BoxedOperation<'a, F, api::PaymentsRequest>,
+        BoxedOperation<'a, F, api::PaymentsRequest, Ctx>,
         Option<api::PaymentMethodData>,
     )> {
         helpers::make_pm_data(Box::new(self), state, payment_data).await
@@ -362,7 +367,9 @@ impl<F: Clone + Send> Domain<F, api::PaymentsRequest> for PaymentCreate {
 }
 
 #[async_trait]
-impl<F: Clone> UpdateTracker<F, PaymentData<F>, api::PaymentsRequest> for PaymentCreate {
+impl<F: Clone, Ctx: PaymentMethodRetrieve>
+    UpdateTracker<F, PaymentData<F>, api::PaymentsRequest, Ctx> for PaymentCreate
+{
     #[instrument(skip_all)]
     async fn update_trackers<'b>(
         &'b self,
@@ -374,7 +381,10 @@ impl<F: Clone> UpdateTracker<F, PaymentData<F>, api::PaymentsRequest> for Paymen
         _merchant_key_store: &domain::MerchantKeyStore,
         _frm_suggestion: Option<FrmSuggestion>,
         _header_payload: api::HeaderPayload,
-    ) -> RouterResult<(BoxedOperation<'b, F, api::PaymentsRequest>, PaymentData<F>)>
+    ) -> RouterResult<(
+        BoxedOperation<'b, F, api::PaymentsRequest, Ctx>,
+        PaymentData<F>,
+    )>
     where
         F: 'b + Send,
     {
@@ -444,14 +454,16 @@ impl<F: Clone> UpdateTracker<F, PaymentData<F>, api::PaymentsRequest> for Paymen
     }
 }
 
-impl<F: Send + Clone> ValidateRequest<F, api::PaymentsRequest> for PaymentCreate {
+impl<F: Send + Clone, Ctx: PaymentMethodRetrieve> ValidateRequest<F, api::PaymentsRequest, Ctx>
+    for PaymentCreate
+{
     #[instrument(skip_all)]
     fn validate_request<'a, 'b>(
         &'b self,
         request: &api::PaymentsRequest,
         merchant_account: &'a domain::MerchantAccount,
     ) -> RouterResult<(
-        BoxedOperation<'b, F, api::PaymentsRequest>,
+        BoxedOperation<'b, F, api::PaymentsRequest, Ctx>,
         operations::ValidateResult<'a>,
     )> {
         helpers::validate_customer_details_in_request(request)?;
diff --git a/crates/router/src/core/payments/operations/payment_method_validate.rs b/crates/router/src/core/payments/operations/payment_method_validate.rs
index 2f260ee3e0a..0ff49279f3c 100644
--- a/crates/router/src/core/payments/operations/payment_method_validate.rs
+++ b/crates/router/src/core/payments/operations/payment_method_validate.rs
@@ -12,6 +12,7 @@ use crate::{
     consts,
     core::{
         errors::{self, RouterResult, StorageErrorExt},
+        payment_methods::PaymentMethodRetrieve,
         payments::{self, helpers, operations, Operation, PaymentData},
         utils as core_utils,
     },
@@ -31,14 +32,16 @@ use crate::{
 #[operation(ops = "all", flow = "verify")]
 pub struct PaymentMethodValidate;
 
-impl<F: Send + Clone> ValidateRequest<F, api::VerifyRequest> for PaymentMethodValidate {
+impl<F: Send + Clone, Ctx: PaymentMethodRetrieve> ValidateRequest<F, api::VerifyRequest, Ctx>
+    for PaymentMethodValidate
+{
     #[instrument(skip_all)]
     fn validate_request<'a, 'b>(
         &'b self,
         request: &api::VerifyRequest,
         merchant_account: &'a domain::MerchantAccount,
     ) -> RouterResult<(
-        BoxedOperation<'b, F, api::VerifyRequest>,
+        BoxedOperation<'b, F, api::VerifyRequest, Ctx>,
         operations::ValidateResult<'a>,
     )> {
         let request_merchant_id = request.merchant_id.as_deref();
@@ -63,7 +66,9 @@ impl<F: Send + Clone> ValidateRequest<F, api::VerifyRequest> for PaymentMethodVa
 }
 
 #[async_trait]
-impl<F: Send + Clone> GetTracker<F, PaymentData<F>, api::VerifyRequest> for PaymentMethodValidate {
+impl<F: Send + Clone, Ctx: PaymentMethodRetrieve>
+    GetTracker<F, PaymentData<F>, api::VerifyRequest, Ctx> for PaymentMethodValidate
+{
     #[instrument(skip_all)]
     async fn get_trackers<'a>(
         &'a self,
@@ -75,7 +80,7 @@ impl<F: Send + Clone> GetTracker<F, PaymentData<F>, api::VerifyRequest> for Paym
         _mechant_key_store: &domain::MerchantKeyStore,
         _auth_flow: services::AuthFlow,
     ) -> RouterResult<(
-        BoxedOperation<'a, F, api::VerifyRequest>,
+        BoxedOperation<'a, F, api::VerifyRequest, Ctx>,
         PaymentData<F>,
         Option<payments::CustomerDetails>,
     )> {
@@ -204,7 +209,9 @@ impl<F: Send + Clone> GetTracker<F, PaymentData<F>, api::VerifyRequest> for Paym
 }
 
 #[async_trait]
-impl<F: Clone> UpdateTracker<F, PaymentData<F>, api::VerifyRequest> for PaymentMethodValidate {
+impl<F: Clone, Ctx: PaymentMethodRetrieve> UpdateTracker<F, PaymentData<F>, api::VerifyRequest, Ctx>
+    for PaymentMethodValidate
+{
     #[instrument(skip_all)]
     async fn update_trackers<'b>(
         &'b self,
@@ -216,7 +223,10 @@ impl<F: Clone> UpdateTracker<F, PaymentData<F>, api::VerifyRequest> for PaymentM
         _mechant_key_store: &domain::MerchantKeyStore,
         _frm_suggestion: Option<FrmSuggestion>,
         _header_payload: api::HeaderPayload,
-    ) -> RouterResult<(BoxedOperation<'b, F, api::VerifyRequest>, PaymentData<F>)>
+    ) -> RouterResult<(
+        BoxedOperation<'b, F, api::VerifyRequest, Ctx>,
+        PaymentData<F>,
+    )>
     where
         F: 'b + Send,
     {
@@ -245,11 +255,11 @@ impl<F: Clone> UpdateTracker<F, PaymentData<F>, api::VerifyRequest> for PaymentM
 }
 
 #[async_trait]
-impl<F, Op> Domain<F, api::VerifyRequest> for Op
+impl<F, Op, Ctx: PaymentMethodRetrieve> Domain<F, api::VerifyRequest, Ctx> for Op
 where
     F: Clone + Send,
-    Op: Send + Sync + Operation<F, api::VerifyRequest>,
-    for<'a> &'a Op: Operation<F, api::VerifyRequest>,
+    Op: Send + Sync + Operation<F, api::VerifyRequest, Ctx>,
+    for<'a> &'a Op: Operation<F, api::VerifyRequest, Ctx>,
 {
     #[instrument(skip_all)]
     async fn get_or_create_customer_details<'a>(
@@ -260,7 +270,7 @@ where
         key_store: &domain::MerchantKeyStore,
     ) -> CustomResult<
         (
-            BoxedOperation<'a, F, api::VerifyRequest>,
+            BoxedOperation<'a, F, api::VerifyRequest, Ctx>,
             Option<domain::Customer>,
         ),
         errors::StorageError,
@@ -283,7 +293,7 @@ where
         payment_data: &mut PaymentData<F>,
         _storage_scheme: storage_enums::MerchantStorageScheme,
     ) -> RouterResult<(
-        BoxedOperation<'a, F, api::VerifyRequest>,
+        BoxedOperation<'a, F, api::VerifyRequest, Ctx>,
         Option<api::PaymentMethodData>,
     )> {
         helpers::make_pm_data(Box::new(self), state, payment_data).await
diff --git a/crates/router/src/core/payments/operations/payment_reject.rs b/crates/router/src/core/payments/operations/payment_reject.rs
index fe52d1b89d5..c9a24b8fb84 100644
--- a/crates/router/src/core/payments/operations/payment_reject.rs
+++ b/crates/router/src/core/payments/operations/payment_reject.rs
@@ -10,6 +10,7 @@ use super::{BoxedOperation, Domain, GetTracker, Operation, UpdateTracker, Valida
 use crate::{
     core::{
         errors::{self, RouterResult, StorageErrorExt},
+        payment_methods::PaymentMethodRetrieve,
         payments::{helpers, operations, CustomerDetails, PaymentAddress, PaymentData},
     },
     db::StorageInterface,
@@ -28,7 +29,9 @@ use crate::{
 pub struct PaymentReject;
 
 #[async_trait]
-impl<F: Send + Clone> GetTracker<F, PaymentData<F>, PaymentsRejectRequest> for PaymentReject {
+impl<F: Send + Clone, Ctx: PaymentMethodRetrieve>
+    GetTracker<F, PaymentData<F>, PaymentsRejectRequest, Ctx> for PaymentReject
+{
     #[instrument(skip_all)]
     async fn get_trackers<'a>(
         &'a self,
@@ -40,7 +43,7 @@ impl<F: Send + Clone> GetTracker<F, PaymentData<F>, PaymentsRejectRequest> for P
         key_store: &domain::MerchantKeyStore,
         _auth_flow: services::AuthFlow,
     ) -> RouterResult<(
-        BoxedOperation<'a, F, PaymentsRejectRequest>,
+        BoxedOperation<'a, F, PaymentsRejectRequest, Ctx>,
         PaymentData<F>,
         Option<CustomerDetails>,
     )> {
@@ -162,7 +165,9 @@ impl<F: Send + Clone> GetTracker<F, PaymentData<F>, PaymentsRejectRequest> for P
 }
 
 #[async_trait]
-impl<F: Clone> UpdateTracker<F, PaymentData<F>, PaymentsRejectRequest> for PaymentReject {
+impl<F: Clone, Ctx: PaymentMethodRetrieve>
+    UpdateTracker<F, PaymentData<F>, PaymentsRejectRequest, Ctx> for PaymentReject
+{
     #[instrument(skip_all)]
     async fn update_trackers<'b>(
         &'b self,
@@ -174,7 +179,10 @@ impl<F: Clone> UpdateTracker<F, PaymentData<F>, PaymentsRejectRequest> for Payme
         _mechant_key_store: &domain::MerchantKeyStore,
         _should_decline_transaction: Option<FrmSuggestion>,
         _header_payload: api::HeaderPayload,
-    ) -> RouterResult<(BoxedOperation<'b, F, PaymentsRejectRequest>, PaymentData<F>)>
+    ) -> RouterResult<(
+        BoxedOperation<'b, F, PaymentsRejectRequest, Ctx>,
+        PaymentData<F>,
+    )>
     where
         F: 'b + Send,
     {
@@ -220,14 +228,16 @@ impl<F: Clone> UpdateTracker<F, PaymentData<F>, PaymentsRejectRequest> for Payme
     }
 }
 
-impl<F: Send + Clone> ValidateRequest<F, PaymentsRejectRequest> for PaymentReject {
+impl<F: Send + Clone, Ctx: PaymentMethodRetrieve> ValidateRequest<F, PaymentsRejectRequest, Ctx>
+    for PaymentReject
+{
     #[instrument(skip_all)]
     fn validate_request<'a, 'b>(
         &'b self,
         request: &PaymentsRejectRequest,
         merchant_account: &'a domain::MerchantAccount,
     ) -> RouterResult<(
-        BoxedOperation<'b, F, PaymentsRejectRequest>,
+        BoxedOperation<'b, F, PaymentsRejectRequest, Ctx>,
         operations::ValidateResult<'a>,
     )> {
         Ok((
diff --git a/crates/router/src/core/payments/operations/payment_response.rs b/crates/router/src/core/payments/operations/payment_response.rs
index d3cb4f818f0..712515b2e87 100644
--- a/crates/router/src/core/payments/operations/payment_response.rs
+++ b/crates/router/src/core/payments/operations/payment_response.rs
@@ -11,6 +11,7 @@ use crate::{
     core::{
         errors::{self, RouterResult, StorageErrorExt},
         mandate,
+        payment_methods::PaymentMethodRetrieve,
         payments::{types::MultipleCaptureData, PaymentData},
         utils as core_utils,
     },
diff --git a/crates/router/src/core/payments/operations/payment_session.rs b/crates/router/src/core/payments/operations/payment_session.rs
index 938441962b2..261275296f1 100644
--- a/crates/router/src/core/payments/operations/payment_session.rs
+++ b/crates/router/src/core/payments/operations/payment_session.rs
@@ -11,6 +11,7 @@ use super::{BoxedOperation, Domain, GetTracker, Operation, UpdateTracker, Valida
 use crate::{
     core::{
         errors::{self, RouterResult, StorageErrorExt},
+        payment_methods::PaymentMethodRetrieve,
         payments::{self, helpers, operations, PaymentData},
     },
     db::StorageInterface,
@@ -29,8 +30,8 @@ use crate::{
 pub struct PaymentSession;
 
 #[async_trait]
-impl<F: Send + Clone> GetTracker<F, PaymentData<F>, api::PaymentsSessionRequest>
-    for PaymentSession
+impl<F: Send + Clone, Ctx: PaymentMethodRetrieve>
+    GetTracker<F, PaymentData<F>, api::PaymentsSessionRequest, Ctx> for PaymentSession
 {
     #[instrument(skip_all)]
     async fn get_trackers<'a>(
@@ -43,7 +44,7 @@ impl<F: Send + Clone> GetTracker<F, PaymentData<F>, api::PaymentsSessionRequest>
         key_store: &domain::MerchantKeyStore,
         _auth_flow: services::AuthFlow,
     ) -> RouterResult<(
-        BoxedOperation<'a, F, api::PaymentsSessionRequest>,
+        BoxedOperation<'a, F, api::PaymentsSessionRequest, Ctx>,
         PaymentData<F>,
         Option<payments::CustomerDetails>,
     )> {
@@ -198,7 +199,9 @@ impl<F: Send + Clone> GetTracker<F, PaymentData<F>, api::PaymentsSessionRequest>
 }
 
 #[async_trait]
-impl<F: Clone> UpdateTracker<F, PaymentData<F>, api::PaymentsSessionRequest> for PaymentSession {
+impl<F: Clone, Ctx: PaymentMethodRetrieve>
+    UpdateTracker<F, PaymentData<F>, api::PaymentsSessionRequest, Ctx> for PaymentSession
+{
     #[instrument(skip_all)]
     async fn update_trackers<'b>(
         &'b self,
@@ -211,7 +214,7 @@ impl<F: Clone> UpdateTracker<F, PaymentData<F>, api::PaymentsSessionRequest> for
         _frm_suggestion: Option<FrmSuggestion>,
         _header_payload: api::HeaderPayload,
     ) -> RouterResult<(
-        BoxedOperation<'b, F, api::PaymentsSessionRequest>,
+        BoxedOperation<'b, F, api::PaymentsSessionRequest, Ctx>,
         PaymentData<F>,
     )>
     where
@@ -234,14 +237,16 @@ impl<F: Clone> UpdateTracker<F, PaymentData<F>, api::PaymentsSessionRequest> for
     }
 }
 
-impl<F: Send + Clone> ValidateRequest<F, api::PaymentsSessionRequest> for PaymentSession {
+impl<F: Send + Clone, Ctx: PaymentMethodRetrieve>
+    ValidateRequest<F, api::PaymentsSessionRequest, Ctx> for PaymentSession
+{
     #[instrument(skip_all)]
     fn validate_request<'a, 'b>(
         &'b self,
         request: &api::PaymentsSessionRequest,
         merchant_account: &'a domain::MerchantAccount,
     ) -> RouterResult<(
-        BoxedOperation<'b, F, api::PaymentsSessionRequest>,
+        BoxedOperation<'b, F, api::PaymentsSessionRequest, Ctx>,
         operations::ValidateResult<'a>,
     )> {
         //paymentid is already generated and should be sent in the request
@@ -261,10 +266,13 @@ impl<F: Send + Clone> ValidateRequest<F, api::PaymentsSessionRequest> for Paymen
 }
 
 #[async_trait]
-impl<F: Clone + Send, Op: Send + Sync + Operation<F, api::PaymentsSessionRequest>>
-    Domain<F, api::PaymentsSessionRequest> for Op
+impl<
+        F: Clone + Send,
+        Ctx: PaymentMethodRetrieve,
+        Op: Send + Sync + Operation<F, api::PaymentsSessionRequest, Ctx>,
+    > Domain<F, api::PaymentsSessionRequest, Ctx> for Op
 where
-    for<'a> &'a Op: Operation<F, api::PaymentsSessionRequest>,
+    for<'a> &'a Op: Operation<F, api::PaymentsSessionRequest, Ctx>,
 {
     #[instrument(skip_all)]
     async fn get_or_create_customer_details<'a>(
@@ -275,7 +283,7 @@ where
         key_store: &domain::MerchantKeyStore,
     ) -> errors::CustomResult<
         (
-            BoxedOperation<'a, F, api::PaymentsSessionRequest>,
+            BoxedOperation<'a, F, api::PaymentsSessionRequest, Ctx>,
             Option<domain::Customer>,
         ),
         errors::StorageError,
@@ -298,7 +306,7 @@ where
         _payment_data: &mut PaymentData<F>,
         _storage_scheme: storage_enums::MerchantStorageScheme,
     ) -> RouterResult<(
-        BoxedOperation<'b, F, api::PaymentsSessionRequest>,
+        BoxedOperation<'b, F, api::PaymentsSessionRequest, Ctx>,
         Option<api::PaymentMethodData>,
     )> {
         //No payment method data for this operation
diff --git a/crates/router/src/core/payments/operations/payment_start.rs b/crates/router/src/core/payments/operations/payment_start.rs
index 2d34d409979..07015810039 100644
--- a/crates/router/src/core/payments/operations/payment_start.rs
+++ b/crates/router/src/core/payments/operations/payment_start.rs
@@ -10,6 +10,7 @@ use super::{BoxedOperation, Domain, GetTracker, Operation, UpdateTracker, Valida
 use crate::{
     core::{
         errors::{self, CustomResult, RouterResult, StorageErrorExt},
+        payment_methods::PaymentMethodRetrieve,
         payments::{helpers, operations, CustomerDetails, PaymentAddress, PaymentData},
     },
     db::StorageInterface,
@@ -28,7 +29,9 @@ use crate::{
 pub struct PaymentStart;
 
 #[async_trait]
-impl<F: Send + Clone> GetTracker<F, PaymentData<F>, api::PaymentsStartRequest> for PaymentStart {
+impl<F: Send + Clone, Ctx: PaymentMethodRetrieve>
+    GetTracker<F, PaymentData<F>, api::PaymentsStartRequest, Ctx> for PaymentStart
+{
     #[instrument(skip_all)]
     async fn get_trackers<'a>(
         &'a self,
@@ -40,7 +43,7 @@ impl<F: Send + Clone> GetTracker<F, PaymentData<F>, api::PaymentsStartRequest> f
         mechant_key_store: &domain::MerchantKeyStore,
         _auth_flow: services::AuthFlow,
     ) -> RouterResult<(
-        BoxedOperation<'a, F, api::PaymentsStartRequest>,
+        BoxedOperation<'a, F, api::PaymentsStartRequest, Ctx>,
         PaymentData<F>,
         Option<CustomerDetails>,
     )> {
@@ -171,7 +174,9 @@ impl<F: Send + Clone> GetTracker<F, PaymentData<F>, api::PaymentsStartRequest> f
 }
 
 #[async_trait]
-impl<F: Clone> UpdateTracker<F, PaymentData<F>, api::PaymentsStartRequest> for PaymentStart {
+impl<F: Clone, Ctx: PaymentMethodRetrieve>
+    UpdateTracker<F, PaymentData<F>, api::PaymentsStartRequest, Ctx> for PaymentStart
+{
     #[instrument(skip_all)]
     async fn update_trackers<'b>(
         &'b self,
@@ -184,7 +189,7 @@ impl<F: Clone> UpdateTracker<F, PaymentData<F>, api::PaymentsStartRequest> for P
         _frm_suggestion: Option<FrmSuggestion>,
         _header_payload: api::HeaderPayload,
     ) -> RouterResult<(
-        BoxedOperation<'b, F, api::PaymentsStartRequest>,
+        BoxedOperation<'b, F, api::PaymentsStartRequest, Ctx>,
         PaymentData<F>,
     )>
     where
@@ -194,14 +199,16 @@ impl<F: Clone> UpdateTracker<F, PaymentData<F>, api::PaymentsStartRequest> for P
     }
 }
 
-impl<F: Send + Clone> ValidateRequest<F, api::PaymentsStartRequest> for PaymentStart {
+impl<F: Send + Clone, Ctx: PaymentMethodRetrieve> ValidateRequest<F, api::PaymentsStartRequest, Ctx>
+    for PaymentStart
+{
     #[instrument(skip_all)]
     fn validate_request<'a, 'b>(
         &'b self,
         request: &api::PaymentsStartRequest,
         merchant_account: &'a domain::MerchantAccount,
     ) -> RouterResult<(
-        BoxedOperation<'b, F, api::PaymentsStartRequest>,
+        BoxedOperation<'b, F, api::PaymentsStartRequest, Ctx>,
         operations::ValidateResult<'a>,
     )> {
         let request_merchant_id = Some(&request.merchant_id[..]);
@@ -227,10 +234,13 @@ impl<F: Send + Clone> ValidateRequest<F, api::PaymentsStartRequest> for PaymentS
 }
 
 #[async_trait]
-impl<F: Clone + Send, Op: Send + Sync + Operation<F, api::PaymentsStartRequest>>
-    Domain<F, api::PaymentsStartRequest> for Op
+impl<
+        F: Clone + Send,
+        Ctx: PaymentMethodRetrieve,
+        Op: Send + Sync + Operation<F, api::PaymentsStartRequest, Ctx>,
+    > Domain<F, api::PaymentsStartRequest, Ctx> for Op
 where
-    for<'a> &'a Op: Operation<F, api::PaymentsStartRequest>,
+    for<'a> &'a Op: Operation<F, api::PaymentsStartRequest, Ctx>,
 {
     #[instrument(skip_all)]
     async fn get_or_create_customer_details<'a>(
@@ -241,7 +251,7 @@ where
         key_store: &domain::MerchantKeyStore,
     ) -> CustomResult<
         (
-            BoxedOperation<'a, F, api::PaymentsStartRequest>,
+            BoxedOperation<'a, F, api::PaymentsStartRequest, Ctx>,
             Option<domain::Customer>,
         ),
         errors::StorageError,
@@ -264,7 +274,7 @@ where
         payment_data: &mut PaymentData<F>,
         _storage_scheme: storage_enums::MerchantStorageScheme,
     ) -> RouterResult<(
-        BoxedOperation<'a, F, api::PaymentsStartRequest>,
+        BoxedOperation<'a, F, api::PaymentsStartRequest, Ctx>,
         Option<api::PaymentMethodData>,
     )> {
         if payment_data
diff --git a/crates/router/src/core/payments/operations/payment_status.rs b/crates/router/src/core/payments/operations/payment_status.rs
index 80830efd13d..6e0ef2f4bac 100644
--- a/crates/router/src/core/payments/operations/payment_status.rs
+++ b/crates/router/src/core/payments/operations/payment_status.rs
@@ -11,7 +11,11 @@ use super::{BoxedOperation, Domain, GetTracker, Operation, UpdateTracker, Valida
 use crate::{
     core::{
         errors::{self, CustomResult, RouterResult, StorageErrorExt},
-        payments::{helpers, operations, types, CustomerDetails, PaymentAddress, PaymentData},
+        payment_methods::PaymentMethodRetrieve,
+        payments::{
+            helpers, operations, types as payment_types, CustomerDetails, PaymentAddress,
+            PaymentData,
+        },
     },
     db::StorageInterface,
     routes::AppState,
@@ -27,31 +31,39 @@ use crate::{
 #[operation(ops = "all", flow = "sync")]
 pub struct PaymentStatus;
 
-impl<F: Send + Clone> Operation<F, api::PaymentsRequest> for PaymentStatus {
-    fn to_domain(&self) -> RouterResult<&dyn Domain<F, api::PaymentsRequest>> {
+impl<F: Send + Clone, Ctx: PaymentMethodRetrieve> Operation<F, api::PaymentsRequest, Ctx>
+    for PaymentStatus
+{
+    fn to_domain(&self) -> RouterResult<&dyn Domain<F, api::PaymentsRequest, Ctx>> {
         Ok(self)
     }
     fn to_update_tracker(
         &self,
-    ) -> RouterResult<&(dyn UpdateTracker<F, PaymentData<F>, api::PaymentsRequest> + Send + Sync)>
-    {
+    ) -> RouterResult<
+        &(dyn UpdateTracker<F, PaymentData<F>, api::PaymentsRequest, Ctx> + Send + Sync),
+    > {
         Ok(self)
     }
 }
-impl<F: Send + Clone> Operation<F, api::PaymentsRequest> for &PaymentStatus {
-    fn to_domain(&self) -> RouterResult<&dyn Domain<F, api::PaymentsRequest>> {
+impl<F: Send + Clone, Ctx: PaymentMethodRetrieve> Operation<F, api::PaymentsRequest, Ctx>
+    for &PaymentStatus
+{
+    fn to_domain(&self) -> RouterResult<&dyn Domain<F, api::PaymentsRequest, Ctx>> {
         Ok(*self)
     }
     fn to_update_tracker(
         &self,
-    ) -> RouterResult<&(dyn UpdateTracker<F, PaymentData<F>, api::PaymentsRequest> + Send + Sync)>
-    {
+    ) -> RouterResult<
+        &(dyn UpdateTracker<F, PaymentData<F>, api::PaymentsRequest, Ctx> + Send + Sync),
+    > {
         Ok(*self)
     }
 }
 
 #[async_trait]
-impl<F: Clone + Send> Domain<F, api::PaymentsRequest> for PaymentStatus {
+impl<F: Clone + Send, Ctx: PaymentMethodRetrieve> Domain<F, api::PaymentsRequest, Ctx>
+    for PaymentStatus
+{
     #[instrument(skip_all)]
     async fn get_or_create_customer_details<'a>(
         &'a self,
@@ -61,7 +73,7 @@ impl<F: Clone + Send> Domain<F, api::PaymentsRequest> for PaymentStatus {
         key_store: &domain::MerchantKeyStore,
     ) -> CustomResult<
         (
-            BoxedOperation<'a, F, api::PaymentsRequest>,
+            BoxedOperation<'a, F, api::PaymentsRequest, Ctx>,
             Option<domain::Customer>,
         ),
         errors::StorageError,
@@ -84,7 +96,7 @@ impl<F: Clone + Send> Domain<F, api::PaymentsRequest> for PaymentStatus {
         payment_data: &mut PaymentData<F>,
         _storage_scheme: enums::MerchantStorageScheme,
     ) -> RouterResult<(
-        BoxedOperation<'a, F, api::PaymentsRequest>,
+        BoxedOperation<'a, F, api::PaymentsRequest, Ctx>,
         Option<api::PaymentMethodData>,
     )> {
         helpers::make_pm_data(Box::new(self), state, payment_data).await
@@ -114,7 +126,9 @@ impl<F: Clone + Send> Domain<F, api::PaymentsRequest> for PaymentStatus {
 }
 
 #[async_trait]
-impl<F: Clone> UpdateTracker<F, PaymentData<F>, api::PaymentsRequest> for PaymentStatus {
+impl<F: Clone, Ctx: PaymentMethodRetrieve>
+    UpdateTracker<F, PaymentData<F>, api::PaymentsRequest, Ctx> for PaymentStatus
+{
     async fn update_trackers<'b>(
         &'b self,
         _db: &dyn StorageInterface,
@@ -125,7 +139,10 @@ impl<F: Clone> UpdateTracker<F, PaymentData<F>, api::PaymentsRequest> for Paymen
         _key_store: &domain::MerchantKeyStore,
         _frm_suggestion: Option<FrmSuggestion>,
         _header_payload: api::HeaderPayload,
-    ) -> RouterResult<(BoxedOperation<'b, F, api::PaymentsRequest>, PaymentData<F>)>
+    ) -> RouterResult<(
+        BoxedOperation<'b, F, api::PaymentsRequest, Ctx>,
+        PaymentData<F>,
+    )>
     where
         F: 'b + Send,
     {
@@ -134,7 +151,9 @@ impl<F: Clone> UpdateTracker<F, PaymentData<F>, api::PaymentsRequest> for Paymen
 }
 
 #[async_trait]
-impl<F: Clone> UpdateTracker<F, PaymentData<F>, api::PaymentsRetrieveRequest> for PaymentStatus {
+impl<F: Clone, Ctx: PaymentMethodRetrieve>
+    UpdateTracker<F, PaymentData<F>, api::PaymentsRetrieveRequest, Ctx> for PaymentStatus
+{
     async fn update_trackers<'b>(
         &'b self,
         _db: &dyn StorageInterface,
@@ -146,7 +165,7 @@ impl<F: Clone> UpdateTracker<F, PaymentData<F>, api::PaymentsRetrieveRequest> fo
         _frm_suggestion: Option<FrmSuggestion>,
         _header_payload: api::HeaderPayload,
     ) -> RouterResult<(
-        BoxedOperation<'b, F, api::PaymentsRetrieveRequest>,
+        BoxedOperation<'b, F, api::PaymentsRetrieveRequest, Ctx>,
         PaymentData<F>,
     )>
     where
@@ -157,8 +176,8 @@ impl<F: Clone> UpdateTracker<F, PaymentData<F>, api::PaymentsRetrieveRequest> fo
 }
 
 #[async_trait]
-impl<F: Send + Clone> GetTracker<F, PaymentData<F>, api::PaymentsRetrieveRequest>
-    for PaymentStatus
+impl<F: Send + Clone, Ctx: PaymentMethodRetrieve>
+    GetTracker<F, PaymentData<F>, api::PaymentsRetrieveRequest, Ctx> for PaymentStatus
 {
     #[instrument(skip_all)]
     async fn get_trackers<'a>(
@@ -171,7 +190,7 @@ impl<F: Send + Clone> GetTracker<F, PaymentData<F>, api::PaymentsRetrieveRequest
         key_store: &domain::MerchantKeyStore,
         _auth_flow: services::AuthFlow,
     ) -> RouterResult<(
-        BoxedOperation<'a, F, api::PaymentsRetrieveRequest>,
+        BoxedOperation<'a, F, api::PaymentsRetrieveRequest, Ctx>,
         PaymentData<F>,
         Option<CustomerDetails>,
     )> {
@@ -191,7 +210,8 @@ impl<F: Send + Clone> GetTracker<F, PaymentData<F>, api::PaymentsRetrieveRequest
 async fn get_tracker_for_sync<
     'a,
     F: Send + Clone,
-    Op: Operation<F, api::PaymentsRetrieveRequest> + 'a + Send + Sync,
+    Ctx: PaymentMethodRetrieve,
+    Op: Operation<F, api::PaymentsRetrieveRequest, Ctx> + 'a + Send + Sync,
 >(
     payment_id: &api::PaymentIdType,
     merchant_account: &domain::MerchantAccount,
@@ -201,7 +221,7 @@ async fn get_tracker_for_sync<
     operation: Op,
     storage_scheme: enums::MerchantStorageScheme,
 ) -> RouterResult<(
-    BoxedOperation<'a, F, api::PaymentsRetrieveRequest>,
+    BoxedOperation<'a, F, api::PaymentsRetrieveRequest, Ctx>,
     PaymentData<F>,
     Option<CustomerDetails>,
 )> {
@@ -282,7 +302,7 @@ async fn get_tracker_for_sync<
                 .attach_printable_lazy(|| {
                     format!("Error while retrieving capture list for, merchant_id: {}, payment_id: {payment_id_str}", merchant_account.merchant_id)
                 })?;
-        Some(types::MultipleCaptureData::new_for_sync(
+        Some(payment_types::MultipleCaptureData::new_for_sync(
             captures,
             request.expand_captures,
         )?)
@@ -388,13 +408,15 @@ async fn get_tracker_for_sync<
     ))
 }
 
-impl<F: Send + Clone> ValidateRequest<F, api::PaymentsRetrieveRequest> for PaymentStatus {
+impl<F: Send + Clone, Ctx: PaymentMethodRetrieve>
+    ValidateRequest<F, api::PaymentsRetrieveRequest, Ctx> for PaymentStatus
+{
     fn validate_request<'a, 'b>(
         &'b self,
         request: &api::PaymentsRetrieveRequest,
         merchant_account: &'a domain::MerchantAccount,
     ) -> RouterResult<(
-        BoxedOperation<'b, F, api::PaymentsRetrieveRequest>,
+        BoxedOperation<'b, F, api::PaymentsRetrieveRequest, Ctx>,
         operations::ValidateResult<'a>,
     )> {
         let request_merchant_id = request.merchant_id.as_deref();
diff --git a/crates/router/src/core/payments/operations/payment_update.rs b/crates/router/src/core/payments/operations/payment_update.rs
index 04f36d51c2c..9e0ef76d3e7 100644
--- a/crates/router/src/core/payments/operations/payment_update.rs
+++ b/crates/router/src/core/payments/operations/payment_update.rs
@@ -11,6 +11,7 @@ use super::{BoxedOperation, Domain, GetTracker, Operation, UpdateTracker, Valida
 use crate::{
     core::{
         errors::{self, CustomResult, RouterResult, StorageErrorExt},
+        payment_methods::PaymentMethodRetrieve,
         payments::{self, helpers, operations, CustomerDetails, PaymentAddress, PaymentData},
         utils as core_utils,
     },
@@ -30,7 +31,9 @@ use crate::{
 pub struct PaymentUpdate;
 
 #[async_trait]
-impl<F: Send + Clone> GetTracker<F, PaymentData<F>, api::PaymentsRequest> for PaymentUpdate {
+impl<F: Send + Clone, Ctx: PaymentMethodRetrieve>
+    GetTracker<F, PaymentData<F>, api::PaymentsRequest, Ctx> for PaymentUpdate
+{
     #[instrument(skip_all)]
     async fn get_trackers<'a>(
         &'a self,
@@ -42,7 +45,7 @@ impl<F: Send + Clone> GetTracker<F, PaymentData<F>, api::PaymentsRequest> for Pa
         key_store: &domain::MerchantKeyStore,
         auth_flow: services::AuthFlow,
     ) -> RouterResult<(
-        BoxedOperation<'a, F, api::PaymentsRequest>,
+        BoxedOperation<'a, F, api::PaymentsRequest, Ctx>,
         PaymentData<F>,
         Option<CustomerDetails>,
     )> {
@@ -268,7 +271,7 @@ impl<F: Send + Clone> GetTracker<F, PaymentData<F>, api::PaymentsRequest> for Pa
             })
             .await
             .transpose()?;
-        let next_operation: BoxedOperation<'a, F, api::PaymentsRequest> =
+        let next_operation: BoxedOperation<'a, F, api::PaymentsRequest, Ctx> =
             if request.confirm.unwrap_or(false) {
                 Box::new(operations::PaymentConfirm)
             } else {
@@ -350,7 +353,9 @@ impl<F: Send + Clone> GetTracker<F, PaymentData<F>, api::PaymentsRequest> for Pa
 }
 
 #[async_trait]
-impl<F: Clone + Send> Domain<F, api::PaymentsRequest> for PaymentUpdate {
+impl<F: Clone + Send, Ctx: PaymentMethodRetrieve> Domain<F, api::PaymentsRequest, Ctx>
+    for PaymentUpdate
+{
     #[instrument(skip_all)]
     async fn get_or_create_customer_details<'a>(
         &'a self,
@@ -360,7 +365,7 @@ impl<F: Clone + Send> Domain<F, api::PaymentsRequest> for PaymentUpdate {
         key_store: &domain::MerchantKeyStore,
     ) -> CustomResult<
         (
-            BoxedOperation<'a, F, api::PaymentsRequest>,
+            BoxedOperation<'a, F, api::PaymentsRequest, Ctx>,
             Option<domain::Customer>,
         ),
         errors::StorageError,
@@ -383,7 +388,7 @@ impl<F: Clone + Send> Domain<F, api::PaymentsRequest> for PaymentUpdate {
         payment_data: &mut PaymentData<F>,
         _storage_scheme: storage_enums::MerchantStorageScheme,
     ) -> RouterResult<(
-        BoxedOperation<'a, F, api::PaymentsRequest>,
+        BoxedOperation<'a, F, api::PaymentsRequest, Ctx>,
         Option<api::PaymentMethodData>,
     )> {
         helpers::make_pm_data(Box::new(self), state, payment_data).await
@@ -413,7 +418,9 @@ impl<F: Clone + Send> Domain<F, api::PaymentsRequest> for PaymentUpdate {
 }
 
 #[async_trait]
-impl<F: Clone> UpdateTracker<F, PaymentData<F>, api::PaymentsRequest> for PaymentUpdate {
+impl<F: Clone, Ctx: PaymentMethodRetrieve>
+    UpdateTracker<F, PaymentData<F>, api::PaymentsRequest, Ctx> for PaymentUpdate
+{
     #[instrument(skip_all)]
     async fn update_trackers<'b>(
         &'b self,
@@ -425,7 +432,10 @@ impl<F: Clone> UpdateTracker<F, PaymentData<F>, api::PaymentsRequest> for Paymen
         _key_store: &domain::MerchantKeyStore,
         _frm_suggestion: Option<FrmSuggestion>,
         _header_payload: api::HeaderPayload,
-    ) -> RouterResult<(BoxedOperation<'b, F, api::PaymentsRequest>, PaymentData<F>)>
+    ) -> RouterResult<(
+        BoxedOperation<'b, F, api::PaymentsRequest, Ctx>,
+        PaymentData<F>,
+    )>
     where
         F: 'b + Send,
     {
@@ -556,14 +566,16 @@ impl<F: Clone> UpdateTracker<F, PaymentData<F>, api::PaymentsRequest> for Paymen
     }
 }
 
-impl<F: Send + Clone> ValidateRequest<F, api::PaymentsRequest> for PaymentUpdate {
+impl<F: Send + Clone, Ctx: PaymentMethodRetrieve> ValidateRequest<F, api::PaymentsRequest, Ctx>
+    for PaymentUpdate
+{
     #[instrument(skip_all)]
     fn validate_request<'a, 'b>(
         &'b self,
         request: &api::PaymentsRequest,
         merchant_account: &'a domain::MerchantAccount,
     ) -> RouterResult<(
-        BoxedOperation<'b, F, api::PaymentsRequest>,
+        BoxedOperation<'b, F, api::PaymentsRequest, Ctx>,
         operations::ValidateResult<'a>,
     )> {
         helpers::validate_customer_details_in_request(request)?;
diff --git a/crates/router/src/core/webhooks.rs b/crates/router/src/core/webhooks.rs
index b647c8a97d7..530d445b50d 100644
--- a/crates/router/src/core/webhooks.rs
+++ b/crates/router/src/core/webhooks.rs
@@ -20,6 +20,7 @@ use crate::{
     core::{
         api_locking,
         errors::{self, ConnectorErrorExt, CustomResult, RouterResponse},
+        payment_methods::PaymentMethodRetrieve,
         payments, refunds,
     },
     db::StorageInterface,
@@ -39,7 +40,10 @@ use crate::{
 const OUTGOING_WEBHOOK_TIMEOUT_SECS: u64 = 5;
 const MERCHANT_ID: &str = "merchant_id";
 
-pub async fn payments_incoming_webhook_flow<W: types::OutgoingWebhookType>(
+pub async fn payments_incoming_webhook_flow<
+    W: types::OutgoingWebhookType,
+    Ctx: PaymentMethodRetrieve,
+>(
     state: AppState,
     merchant_account: domain::MerchantAccount,
     key_store: domain::MerchantKeyStore,
@@ -74,27 +78,28 @@ pub async fn payments_incoming_webhook_flow<W: types::OutgoingWebhookType>(
                 .perform_locking_action(&state, merchant_account.merchant_id.to_string())
                 .await?;
 
-            let response = payments::payments_core::<api::PSync, api::PaymentsResponse, _, _, _>(
-                state.clone(),
-                merchant_account.clone(),
-                key_store,
-                payments::operations::PaymentStatus,
-                api::PaymentsRetrieveRequest {
-                    resource_id: id,
-                    merchant_id: Some(merchant_account.merchant_id.clone()),
-                    force_sync: true,
-                    connector: None,
-                    param: None,
-                    merchant_connector_details: None,
-                    client_secret: None,
-                    expand_attempts: None,
-                    expand_captures: None,
-                },
-                services::AuthFlow::Merchant,
-                consume_or_trigger_flow,
-                HeaderPayload::default(),
-            )
-            .await;
+            let response =
+                payments::payments_core::<api::PSync, api::PaymentsResponse, _, _, _, Ctx>(
+                    state.clone(),
+                    merchant_account.clone(),
+                    key_store,
+                    payments::operations::PaymentStatus,
+                    api::PaymentsRetrieveRequest {
+                        resource_id: id,
+                        merchant_id: Some(merchant_account.merchant_id.clone()),
+                        force_sync: true,
+                        connector: None,
+                        param: None,
+                        merchant_connector_details: None,
+                        client_secret: None,
+                        expand_attempts: None,
+                        expand_captures: None,
+                    },
+                    services::AuthFlow::Merchant,
+                    consume_or_trigger_flow,
+                    HeaderPayload::default(),
+                )
+                .await;
 
             lock_action
                 .free_lock_action(&state, merchant_account.merchant_id.to_owned())
@@ -531,7 +536,7 @@ pub async fn disputes_incoming_webhook_flow<W: types::OutgoingWebhookType>(
     }
 }
 
-async fn bank_transfer_webhook_flow<W: types::OutgoingWebhookType>(
+async fn bank_transfer_webhook_flow<W: types::OutgoingWebhookType, Ctx: PaymentMethodRetrieve>(
     state: AppState,
     merchant_account: domain::MerchantAccount,
     key_store: domain::MerchantKeyStore,
@@ -553,7 +558,7 @@ async fn bank_transfer_webhook_flow<W: types::OutgoingWebhookType>(
             payment_token: payment_attempt.payment_token,
             ..Default::default()
         };
-        payments::payments_core::<api::Authorize, api::PaymentsResponse, _, _, _>(
+        payments::payments_core::<api::Authorize, api::PaymentsResponse, _, _, _, Ctx>(
             state.clone(),
             merchant_account.to_owned(),
             key_store,
@@ -824,7 +829,7 @@ pub async fn trigger_webhook_to_merchant<W: types::OutgoingWebhookType>(
     Ok(())
 }
 
-pub async fn webhooks_wrapper<W: types::OutgoingWebhookType>(
+pub async fn webhooks_wrapper<W: types::OutgoingWebhookType, Ctx: PaymentMethodRetrieve>(
     state: AppState,
     req: &actix_web::HttpRequest,
     merchant_account: domain::MerchantAccount,
@@ -832,7 +837,7 @@ pub async fn webhooks_wrapper<W: types::OutgoingWebhookType>(
     connector_name_or_mca_id: &str,
     body: actix_web::web::Bytes,
 ) -> RouterResponse<serde_json::Value> {
-    let (application_response, _webhooks_response_tracker) = webhooks_core::<W>(
+    let (application_response, _webhooks_response_tracker) = webhooks_core::<W, Ctx>(
         state,
         req,
         merchant_account,
@@ -846,7 +851,8 @@ pub async fn webhooks_wrapper<W: types::OutgoingWebhookType>(
 }
 
 #[instrument(skip_all)]
-pub async fn webhooks_core<W: types::OutgoingWebhookType>(
+
+pub async fn webhooks_core<W: types::OutgoingWebhookType, Ctx: PaymentMethodRetrieve>(
     state: AppState,
     req: &actix_web::HttpRequest,
     merchant_account: domain::MerchantAccount,
@@ -1044,7 +1050,7 @@ pub async fn webhooks_core<W: types::OutgoingWebhookType>(
         };
 
         match flow_type {
-            api::WebhookFlow::Payment => payments_incoming_webhook_flow::<W>(
+            api::WebhookFlow::Payment => payments_incoming_webhook_flow::<W, Ctx>(
                 state.clone(),
                 merchant_account,
                 key_store,
@@ -1078,7 +1084,7 @@ pub async fn webhooks_core<W: types::OutgoingWebhookType>(
             .await
             .attach_printable("Incoming webhook flow for disputes failed")?,
 
-            api::WebhookFlow::BankTransfer => bank_transfer_webhook_flow::<W>(
+            api::WebhookFlow::BankTransfer => bank_transfer_webhook_flow::<W, Ctx>(
                 state.clone(),
                 merchant_account,
                 key_store,
diff --git a/crates/router/src/routes/payments.rs b/crates/router/src/routes/payments.rs
index 9d7cf220a3a..b760aa83aaa 100644
--- a/crates/router/src/routes/payments.rs
+++ b/crates/router/src/routes/payments.rs
@@ -10,6 +10,7 @@ use crate::{
     self as app,
     core::{
         errors::http_not_implemented,
+        payment_methods::{Oss, PaymentMethodRetrieve},
         payments::{self, PaymentRedirectFlow},
     },
     openapi::examples::{
@@ -106,7 +107,7 @@ pub async fn payments_create(
         &req,
         payload,
         |state, auth, req| {
-            authorize_verify_select(
+            authorize_verify_select::<_, Oss>(
                 payments::PaymentCreate,
                 state,
                 auth.merchant_account,
@@ -160,8 +161,15 @@ pub async fn payments_start(
         state,
         &req,
         payload,
-        |state,auth, req| {
-            payments::payments_core::<api_types::Authorize, payment_types::PaymentsResponse, _, _, _>(
+        |state, auth, req| {
+            payments::payments_core::<
+                api_types::Authorize,
+                payment_types::PaymentsResponse,
+                _,
+                _,
+                _,
+                Oss,
+            >(
                 state,
                 auth.merchant_account,
                 auth.key_store,
@@ -227,7 +235,7 @@ pub async fn payments_retrieve(
         &req,
         payload,
         |state, auth, req| {
-            payments::payments_core::<api_types::PSync, payment_types::PaymentsResponse, _, _, _>(
+            payments::payments_core::<api_types::PSync, payment_types::PaymentsResponse, _, _, _,Oss>(
                 state,
                 auth.merchant_account,
                 auth.key_store,
@@ -288,7 +296,7 @@ pub async fn payments_retrieve_with_gateway_creds(
         &req,
         payload,
         |state, auth, req| {
-            payments::payments_core::<api_types::PSync, payment_types::PaymentsResponse, _, _, _>(
+            payments::payments_core::<api_types::PSync, payment_types::PaymentsResponse, _, _, _,Oss>(
                 state,
                 auth.merchant_account,
                 auth.key_store,
@@ -354,7 +362,7 @@ pub async fn payments_update(
         &req,
         payload,
         |state, auth, req| {
-            authorize_verify_select(
+            authorize_verify_select::<_, Oss>(
                 payments::PaymentUpdate,
                 state,
                 auth.merchant_account,
@@ -430,7 +438,7 @@ pub async fn payments_confirm(
         &req,
         payload,
         |state, auth, req| {
-            authorize_verify_select(
+            authorize_verify_select::<_, Oss>(
                 payments::PaymentConfirm,
                 state,
                 auth.merchant_account,
@@ -485,7 +493,14 @@ pub async fn payments_capture(
         &req,
         payload,
         |state, auth, payload| {
-            payments::payments_core::<api_types::Capture, payment_types::PaymentsResponse, _, _, _>(
+            payments::payments_core::<
+                api_types::Capture,
+                payment_types::PaymentsResponse,
+                _,
+                _,
+                _,
+                Oss,
+            >(
                 state,
                 auth.merchant_account,
                 auth.key_store,
@@ -539,6 +554,7 @@ pub async fn payments_connector_session(
                 _,
                 _,
                 _,
+                Oss,
             >(
                 state,
                 auth.merchant_account,
@@ -600,7 +616,8 @@ pub async fn payments_redirect_response(
         &req,
         payload,
         |state, auth, req| {
-            payments::PaymentRedirectSync {}.handle_payments_redirect_response(
+            <payments::PaymentRedirectSync as PaymentRedirectFlow<Oss>>::handle_payments_redirect_response(
+                &payments::PaymentRedirectSync {},
                 state,
                 auth.merchant_account,
                 auth.key_store,
@@ -657,7 +674,8 @@ pub async fn payments_redirect_response_with_creds_identifier(
         &req,
         payload,
         |state, auth, req| {
-            payments::PaymentRedirectSync {}.handle_payments_redirect_response(
+           <payments::PaymentRedirectSync as PaymentRedirectFlow<Oss>>::handle_payments_redirect_response(
+                &payments::PaymentRedirectSync {},
                 state,
                 auth.merchant_account,
                 auth.key_store,
@@ -696,7 +714,9 @@ pub async fn payments_complete_authorize(
         &req,
         payload,
         |state, auth, req| {
-            payments::PaymentRedirectCompleteAuthorize {}.handle_payments_redirect_response(
+
+            <payments::PaymentRedirectCompleteAuthorize as PaymentRedirectFlow<Oss>>::handle_payments_redirect_response(
+                &payments::PaymentRedirectCompleteAuthorize {},
                 state,
                 auth.merchant_account,
                 auth.key_store,
@@ -745,7 +765,7 @@ pub async fn payments_cancel(
         &req,
         payload,
         |state, auth, req| {
-            payments::payments_core::<api_types::Void, payment_types::PaymentsResponse, _, _, _>(
+            payments::payments_core::<api_types::Void, payment_types::PaymentsResponse, _, _, _,Oss>(
                 state,
                 auth.merchant_account,
                 auth.key_store,
@@ -846,7 +866,7 @@ pub async fn get_filters_for_payments(
     )
     .await
 }
-async fn authorize_verify_select<Op>(
+async fn authorize_verify_select<Op, Ctx>(
     operation: Op,
     state: app::AppState,
     merchant_account: domain::MerchantAccount,
@@ -856,13 +876,18 @@ async fn authorize_verify_select<Op>(
     auth_flow: api::AuthFlow,
 ) -> app::core::errors::RouterResponse<api_models::payments::PaymentsResponse>
 where
+    Ctx: PaymentMethodRetrieve,
     Op: Sync
         + Clone
         + std::fmt::Debug
-        + payments::operations::Operation<api_types::Authorize, api_models::payments::PaymentsRequest>
         + payments::operations::Operation<
+            api_types::Authorize,
+            api_models::payments::PaymentsRequest,
+            Ctx,
+        > + payments::operations::Operation<
             api_types::SetupMandate,
             api_models::payments::PaymentsRequest,
+            Ctx,
         >,
 {
     // TODO: Change for making it possible for the flow to be inferred internally or through validation layer
@@ -874,23 +899,26 @@ where
     match req.payment_type.unwrap_or_default() {
         api_models::enums::PaymentType::Normal
         | api_models::enums::PaymentType::RecurringMandate
-        | api_models::enums::PaymentType::NewMandate => payments::payments_core::<
-            api_types::Authorize,
-            payment_types::PaymentsResponse,
-            _,
-            _,
-            _,
-        >(
-            state,
-            merchant_account,
-            key_store,
-            operation,
-            req,
-            auth_flow,
-            payments::CallConnectorAction::Trigger,
-            header_payload,
-        )
-        .await,
+        | api_models::enums::PaymentType::NewMandate => {
+            payments::payments_core::<
+                api_types::Authorize,
+                payment_types::PaymentsResponse,
+                _,
+                _,
+                _,
+                Ctx,
+            >(
+                state,
+                merchant_account,
+                key_store,
+                operation,
+                req,
+                auth_flow,
+                payments::CallConnectorAction::Trigger,
+                header_payload,
+            )
+            .await
+        }
         api_models::enums::PaymentType::SetupMandate => {
             payments::payments_core::<
                 api_types::SetupMandate,
@@ -898,6 +926,7 @@ where
                 _,
                 _,
                 _,
+                Ctx,
             >(
                 state,
                 merchant_account,
diff --git a/crates/router/src/routes/webhooks.rs b/crates/router/src/routes/webhooks.rs
index 0bbc6add436..f9fee54d16f 100644
--- a/crates/router/src/routes/webhooks.rs
+++ b/crates/router/src/routes/webhooks.rs
@@ -5,6 +5,7 @@ use super::app::AppState;
 use crate::{
     core::{
         api_locking,
+        payment_methods::Oss,
         webhooks::{self, types},
     },
     services::{api, authentication as auth},
@@ -26,7 +27,7 @@ pub async fn receive_incoming_webhook<W: types::OutgoingWebhookType>(
         &req,
         body,
         |state, auth, body| {
-            webhooks::webhooks_wrapper::<W>(
+            webhooks::webhooks_wrapper::<W, Oss>(
                 state.to_owned(),
                 &req,
                 auth.merchant_account,
diff --git a/crates/router/src/workflows/payment_sync.rs b/crates/router/src/workflows/payment_sync.rs
index 744cce31327..4dbf97081a6 100644
--- a/crates/router/src/workflows/payment_sync.rs
+++ b/crates/router/src/workflows/payment_sync.rs
@@ -8,7 +8,10 @@ use scheduler::{
 };
 
 use crate::{
-    core::payments::{self as payment_flows, operations},
+    core::{
+        payment_methods::Oss,
+        payments::{self as payment_flows, operations},
+    },
     db::StorageInterface,
     errors,
     routes::AppState,
@@ -55,7 +58,7 @@ impl ProcessTrackerWorkflow<AppState> for PaymentsSyncWorkflow {
             .await?;
 
         let (payment_data, _, _, _) =
-            payment_flows::payments_operation_core::<api::PSync, _, _, _>(
+            payment_flows::payments_operation_core::<api::PSync, _, _, _, Oss>(
                 state,
                 merchant_account.clone(),
                 key_store,
diff --git a/crates/router/tests/payments.rs b/crates/router/tests/payments.rs
index 1bff639d346..551960ac138 100644
--- a/crates/router/tests/payments.rs
+++ b/crates/router/tests/payments.rs
@@ -4,7 +4,7 @@ mod utils;
 
 use router::{
     configs,
-    core::payments,
+    core::{payment_methods::Oss, payments},
     db::StorageImpl,
     routes, services,
     types::{
@@ -361,7 +361,7 @@ async fn payments_create_core() {
     let expected_response =
         services::ApplicationResponse::JsonWithHeaders((expected_response, vec![]));
     let actual_response =
-        payments::payments_core::<api::Authorize, api::PaymentsResponse, _, _, _>(
+        payments::payments_core::<api::Authorize, api::PaymentsResponse, _, _, _, Oss>(
             state,
             merchant_account,
             key_store,
@@ -531,7 +531,7 @@ async fn payments_create_core_adyen_no_redirect() {
         vec![],
     ));
     let actual_response =
-        payments::payments_core::<api::Authorize, api::PaymentsResponse, _, _, _>(
+        payments::payments_core::<api::Authorize, api::PaymentsResponse, _, _, _, Oss>(
             state,
             merchant_account,
             key_store,
diff --git a/crates/router/tests/payments2.rs b/crates/router/tests/payments2.rs
index 91b2a454eea..96ed131dc6f 100644
--- a/crates/router/tests/payments2.rs
+++ b/crates/router/tests/payments2.rs
@@ -3,7 +3,7 @@
 mod utils;
 
 use router::{
-    core::payments,
+    core::{payment_methods::Oss, payments},
     db::StorageImpl,
     types::api::{self, enums as api_enums},
     *,
@@ -120,19 +120,25 @@ async fn payments_create_core() {
     };
     let expected_response =
         services::ApplicationResponse::JsonWithHeaders((expected_response, vec![]));
-    let actual_response =
-        router::core::payments::payments_core::<api::Authorize, api::PaymentsResponse, _, _, _>(
-            state,
-            merchant_account,
-            key_store,
-            payments::PaymentCreate,
-            req,
-            services::AuthFlow::Merchant,
-            payments::CallConnectorAction::Trigger,
-            api::HeaderPayload::default(),
-        )
-        .await
-        .unwrap();
+    let actual_response = router::core::payments::payments_core::<
+        api::Authorize,
+        api::PaymentsResponse,
+        _,
+        _,
+        _,
+        Oss,
+    >(
+        state,
+        merchant_account,
+        key_store,
+        payments::PaymentCreate,
+        req,
+        services::AuthFlow::Merchant,
+        payments::CallConnectorAction::Trigger,
+        api::HeaderPayload::default(),
+    )
+    .await
+    .unwrap();
     assert_eq!(expected_response, actual_response);
 }
 
@@ -292,18 +298,24 @@ async fn payments_create_core_adyen_no_redirect() {
         },
         vec![],
     ));
-    let actual_response =
-        router::core::payments::payments_core::<api::Authorize, api::PaymentsResponse, _, _, _>(
-            state,
-            merchant_account,
-            key_store,
-            payments::PaymentCreate,
-            req,
-            services::AuthFlow::Merchant,
-            payments::CallConnectorAction::Trigger,
-            api::HeaderPayload::default(),
-        )
-        .await
-        .unwrap();
+    let actual_response = router::core::payments::payments_core::<
+        api::Authorize,
+        api::PaymentsResponse,
+        _,
+        _,
+        _,
+        Oss,
+    >(
+        state,
+        merchant_account,
+        key_store,
+        payments::PaymentCreate,
+        req,
+        services::AuthFlow::Merchant,
+        payments::CallConnectorAction::Trigger,
+        api::HeaderPayload::default(),
+    )
+    .await
+    .unwrap();
     assert_eq!(expected_response, actual_response);
 }
diff --git a/crates/router_derive/src/macros/operation.rs b/crates/router_derive/src/macros/operation.rs
index cf71370a293..fb0ef35ef58 100644
--- a/crates/router_derive/src/macros/operation.rs
+++ b/crates/router_derive/src/macros/operation.rs
@@ -61,7 +61,7 @@ impl Derives {
         let req_type = Conversion::get_req_type(self);
         quote! {
             #[automatically_derived]
-            impl<F:Send+Clone> Operation<F,#req_type> for #struct_name {
+            impl<F:Send+Clone,Ctx: PaymentMethodRetrieve,> Operation<F,#req_type,Ctx> for #struct_name {
                 #(#fns)*
             }
         }
@@ -75,7 +75,7 @@ impl Derives {
         let req_type = Conversion::get_req_type(self);
         quote! {
             #[automatically_derived]
-            impl<F:Send+Clone> Operation<F,#req_type> for &#struct_name {
+            impl<F:Send+Clone,Ctx: PaymentMethodRetrieve,> Operation<F,#req_type,Ctx> for &#struct_name {
                 #(#ref_fns)*
             }
         }
@@ -138,22 +138,22 @@ impl Conversion {
         let req_type = Self::get_req_type(ident);
         match self {
             Self::ValidateRequest => quote! {
-                fn to_validate_request(&self) -> RouterResult<&(dyn ValidateRequest<F,#req_type> + Send + Sync)> {
+                fn to_validate_request(&self) -> RouterResult<&(dyn ValidateRequest<F,#req_type,Ctx> + Send + Sync)> {
                     Ok(self)
                 }
             },
             Self::GetTracker => quote! {
-                fn to_get_tracker(&self) -> RouterResult<&(dyn GetTracker<F,PaymentData<F>,#req_type> + Send + Sync)> {
+                fn to_get_tracker(&self) -> RouterResult<&(dyn GetTracker<F,PaymentData<F>,#req_type,Ctx> + Send + Sync)> {
                     Ok(self)
                 }
             },
             Self::Domain => quote! {
-                fn to_domain(&self) -> RouterResult<&dyn Domain<F,#req_type>> {
+                fn to_domain(&self) -> RouterResult<&dyn Domain<F,#req_type,Ctx>> {
                     Ok(self)
                 }
             },
             Self::UpdateTracker => quote! {
-                fn to_update_tracker(&self) -> RouterResult<&(dyn UpdateTracker<F,PaymentData<F>,#req_type> + Send + Sync)> {
+                fn to_update_tracker(&self) -> RouterResult<&(dyn UpdateTracker<F,PaymentData<F>,#req_type,Ctx> + Send + Sync)> {
                     Ok(self)
                 }
             },
@@ -186,22 +186,22 @@ impl Conversion {
         let req_type = Self::get_req_type(ident);
         match self {
             Self::ValidateRequest => quote! {
-                fn to_validate_request(&self) -> RouterResult<&(dyn ValidateRequest<F,#req_type> + Send + Sync)> {
+                fn to_validate_request(&self) -> RouterResult<&(dyn ValidateRequest<F,#req_type,Ctx> + Send + Sync)> {
                     Ok(*self)
                 }
             },
             Self::GetTracker => quote! {
-                fn to_get_tracker(&self) -> RouterResult<&(dyn GetTracker<F,PaymentData<F>,#req_type> + Send + Sync)> {
+                fn to_get_tracker(&self) -> RouterResult<&(dyn GetTracker<F,PaymentData<F>,#req_type,Ctx> + Send + Sync)> {
                     Ok(*self)
                 }
             },
             Self::Domain => quote! {
-                fn to_domain(&self) -> RouterResult<&(dyn Domain<F,#req_type>)> {
+                fn to_domain(&self) -> RouterResult<&(dyn Domain<F,#req_type,Ctx>)> {
                     Ok(*self)
                 }
             },
             Self::UpdateTracker => quote! {
-                fn to_update_tracker(&self) -> RouterResult<&(dyn UpdateTracker<F,PaymentData<F>,#req_type> + Send + Sync)> {
+                fn to_update_tracker(&self) -> RouterResult<&(dyn UpdateTracker<F,PaymentData<F>,#req_type,Ctx> + Send + Sync)> {
                     Ok(*self)
                 }
             },

## Type of Change
<!-- Put an `x` in the boxes that apply -->

- [ ] Bugfix
- [ ] New feature
- [ ] Enhancement
- [x] Refactoring
- [ ] Dependency updates
- [ ] Documentation
- [ ] CI/CD

## Description
<!-- Describe your changes in detail -->
This PR includes changes for adding a new generic, context, which will be passed during api call (server_wrap) to call the related implementation depending on context

### Additional Changes

- [ ] This PR modifies the API contract
- [ ] This PR modifies the database schema
- [ ] This PR modifies application configuration/environment variables

<!--
Provide links to the files with corresponding changes.

Following are the paths where you can find config files:
1. `config`
2. `crates/router/src/configs`
3. `loadtest/config`
-->


## Motivation and Context
<!--
Why is this change required? What problem does it solve?
If it fixes an open issue, please link to the issue here.

If you don't have an issue, we'd recommend starting with one first so the PR
can focus on the implementation (unless it is an obvious bug or documentation fix
that will have little conversation).
-->


## How did you test it?
<!--
Did you write an integration/unit/API test to verify the code changes?
Or did you test this change manually (provide relevant screenshots)?
-->


## Checklist
<!-- Put an `x` in the boxes that apply -->

- [x] I formatted the code `cargo +nightly fmt --all`
- [x] I addressed lints thrown by `cargo clippy`
- [x] I reviewed the submitted code
- [ ] I added unit tests for my changes where possible
- [ ] I added a [CHANGELOG](/CHANGELOG.md) entry if applicable
