Bug: Need mapping for merchant_id passed in request to locke_id passed to EC



1. While creating merchant_account , locker_id needs to be assigned to the merchant
2. In case like swiggy, swiggy_instamart same locker_id needs to be assigned as they are the same and all payment_method can be used across there product
3. Every locker id has separate key assigned in locker system. We have pre-defined 999 keys generated i.e. m0001...m0999(needs to be rechecked)
diff --git a/crates/api_models/src/admin.rs b/crates/api_models/src/admin.rs
index 398888e140d..084d8bf93d3 100644
--- a/crates/api_models/src/admin.rs
+++ b/crates/api_models/src/admin.rs
@@ -24,6 +24,7 @@ pub struct CreateMerchantAccount {
     pub redirect_to_merchant_with_http_post: Option<bool>,
     pub metadata: Option<serde_json::Value>,
     pub publishable_key: Option<String>,
+    pub locker_id: Option<String>,
 }
 
 #[derive(Clone, Debug, Deserialize, Serialize)]
diff --git a/crates/router/src/core/admin.rs b/crates/router/src/core/admin.rs
index 269bfd50a59..efd4c5e380f 100644
--- a/crates/router/src/core/admin.rs
+++ b/crates/router/src/core/admin.rs
@@ -70,6 +70,7 @@ pub async fn create_merchant_account(
         payment_response_hash_key: req.payment_response_hash_key,
         redirect_to_merchant_with_http_post: req.redirect_to_merchant_with_http_post,
         publishable_key: Some(publishable_key.to_owned()),
+        locker_id: req.locker_id,
     };
 
     db.insert_merchant(merchant_account)
@@ -125,6 +126,7 @@ pub async fn get_merchant_account(
         ),
         metadata: None,
         publishable_key: merchant_account.publishable_key,
+        locker_id: merchant_account.locker_id,
     };
     Ok(service_api::BachResponse::Json(response))
 }
@@ -214,6 +216,9 @@ pub async fn merchant_account_update(
         publishable_key: req
             .publishable_key
             .or_else(|| merchant_account.publishable_key.clone()),
+        locker_id: req
+            .locker_id
+            .or_else(|| merchant_account.locker_id.to_owned()),
     };
     response.merchant_id = merchant_id.to_string();
     response.api_key = merchant_account.api_key.to_owned();
diff --git a/crates/router/src/core/mandate.rs b/crates/router/src/core/mandate.rs
index e1f5a4878a0..501b99fb073 100644
--- a/crates/router/src/core/mandate.rs
+++ b/crates/router/src/core/mandate.rs
@@ -31,7 +31,7 @@ pub async fn get_mandate(
         .await
         .map_err(|error| error.to_not_found_response(errors::ApiErrorResponse::MandateNotFound))?;
     Ok(services::BachResponse::Json(
-        mandates::MandateResponse::from_db_mandate(state, mandate).await?,
+        mandates::MandateResponse::from_db_mandate(state, mandate, &merchant_account).await?,
     ))
 }
 
@@ -77,7 +77,10 @@ pub async fn get_customer_mandates(
     } else {
         let mut response_vec = Vec::with_capacity(mandates.len());
         for mandate in mandates {
-            response_vec.push(mandates::MandateResponse::from_db_mandate(state, mandate).await?);
+            response_vec.push(
+                mandates::MandateResponse::from_db_mandate(state, mandate, &merchant_account)
+                    .await?,
+            );
         }
         Ok(services::BachResponse::Json(response_vec))
     }
@@ -87,6 +90,7 @@ pub async fn mandate_procedure<F, FData>(
     state: &AppState,
     mut resp: types::RouterData<F, FData, types::PaymentsResponseData>,
     maybe_customer: &Option<storage::Customer>,
+    merchant_account: &storage::MerchantAccount,
 ) -> errors::RouterResult<types::RouterData<F, FData, types::PaymentsResponseData>>
 where
     FData: MandateBehaviour,
@@ -132,7 +136,7 @@ where
             if resp.request.get_setup_mandate_details().is_some() {
                 let payment_method_id = helpers::call_payment_method(
                     state,
-                    &resp.merchant_id,
+                    merchant_account,
                     Some(&resp.request.get_payment_method_data()),
                     Some(resp.payment_method),
                     maybe_customer,
diff --git a/crates/router/src/core/payment_methods/cards.rs b/crates/router/src/core/payment_methods/cards.rs
index 414d5076759..873d64c771a 100644
--- a/crates/router/src/core/payment_methods/cards.rs
+++ b/crates/router/src/core/payment_methods/cards.rs
@@ -50,13 +50,13 @@ pub async fn create_payment_method(
 pub async fn add_payment_method(
     state: &routes::AppState,
     req: api::CreatePaymentMethod,
-    merchant_id: String,
+    merchant_account: &storage::MerchantAccount,
 ) -> errors::RouterResponse<api::PaymentMethodResponse> {
     req.validate()?;
-
+    let merchant_id = &merchant_account.merchant_id;
     let customer_id = req.customer_id.clone().get_required_value("customer_id")?;
     match req.card.clone() {
-        Some(card) => add_card(state, req, card, customer_id, &merchant_id)
+        Some(card) => add_card(state, req, card, customer_id, merchant_account)
             .await
             .change_context(errors::ApiErrorResponse::InternalServerError)
             .attach_printable("Add Card Failed"),
@@ -67,14 +67,14 @@ pub async fn add_payment_method(
                 &req,
                 &customer_id,
                 &payment_method_id,
-                &merchant_id,
+                merchant_id,
             )
             .await
             .map_err(|error| {
                 error.to_duplicate_response(errors::ApiErrorResponse::DuplicatePaymentMethod)
             })?;
             Ok(api::PaymentMethodResponse {
-                merchant_id,
+                merchant_id: merchant_id.to_string(),
                 customer_id: Some(customer_id),
                 payment_method_id: payment_method_id.to_string(),
                 payment_method: req.payment_method,
@@ -124,7 +124,7 @@ pub async fn update_customer_payment_method(
         metadata: req.metadata,
         customer_id: Some(pm.customer_id),
     };
-    add_payment_method(state, new_pm, merchant_account.merchant_id).await
+    add_payment_method(state, new_pm, &merchant_account).await
 }
 
 #[instrument(skip_all)]
@@ -133,11 +133,25 @@ pub async fn add_card(
     req: api::CreatePaymentMethod,
     card: api::CardDetail,
     customer_id: String,
-    merchant_id: &str,
+    merchant_account: &storage::MerchantAccount,
 ) -> errors::CustomResult<api::PaymentMethodResponse, errors::CardVaultError> {
     let locker = &state.conf.locker;
     let db = &*state.store;
-    let request = payment_methods::mk_add_card_request(locker, &card, &customer_id, &req)?;
+    let merchant_id = &merchant_account.merchant_id;
+    let locker_id = merchant_account
+        .locker_id
+        .to_owned()
+        .get_required_value("locker_id")
+        .change_context(errors::CardVaultError::SaveCardFailed)?;
+
+    let request = payment_methods::mk_add_card_request(
+        locker,
+        &card,
+        &customer_id,
+        &req,
+        &locker_id,
+        merchant_id,
+    )?;
     let response = if !locker.mock_locker {
         let response = services::call_connector_api(state, request)
             .await
@@ -278,11 +292,11 @@ pub async fn mock_delete_card<'a>(
 #[instrument(skip_all)]
 pub async fn get_card_from_legacy_locker<'a>(
     state: &'a routes::AppState,
-    merchant_id: &'a str,
+    locker_id: &'a str,
     card_id: &'a str,
 ) -> errors::RouterResult<payment_methods::GetCardResponse> {
     let locker = &state.conf.locker;
-    let request = payment_methods::mk_get_card_request(locker, merchant_id, card_id)
+    let request = payment_methods::mk_get_card_request(locker, locker_id, card_id)
         .change_context(errors::ApiErrorResponse::InternalServerError)
         .attach_printable("Making get card request failed")?;
     let get_card_result = if !locker.mock_locker {
@@ -519,7 +533,11 @@ pub async fn list_customer_payment_method(
     for pm in resp.into_iter() {
         let payment_token = generate_id(consts::ID_LENGTH, "token");
         let card = if pm.payment_method == enums::PaymentMethodType::Card {
-            Some(get_lookup_key_from_locker(state, &payment_token, &pm).await?)
+            let locker_id = merchant_account
+                .locker_id
+                .to_owned()
+                .get_required_value("locker_id")?;
+            Some(get_lookup_key_from_locker(state, &payment_token, &pm, &locker_id).await?)
         } else {
             None
         };
@@ -557,13 +575,10 @@ pub async fn get_lookup_key_from_locker(
     state: &routes::AppState,
     payment_token: &str,
     pm: &storage::PaymentMethod,
+    locker_id: &str,
 ) -> errors::RouterResult<api::CardDetailFromLocker> {
-    let get_card_resp = get_card_from_legacy_locker(
-        state,
-        pm.merchant_id.as_str(),
-        pm.payment_method_id.as_str(),
-    )
-    .await?;
+    let get_card_resp =
+        get_card_from_legacy_locker(state, locker_id, pm.payment_method_id.as_str()).await?;
     let card_detail = payment_methods::get_card_detail(pm, get_card_resp.card)
         .change_context(errors::ApiErrorResponse::InternalServerError)
         .attach_printable("Get Card Details Failed")?;
@@ -717,6 +732,7 @@ pub async fn get_card_info_from_value(
 pub async fn retrieve_payment_method(
     state: &routes::AppState,
     pm: api::PaymentMethodId,
+    merchant_account: storage::MerchantAccount,
 ) -> errors::RouterResponse<api::PaymentMethodResponse> {
     let db = &*state.store;
     let pm = db
@@ -726,8 +742,9 @@ pub async fn retrieve_payment_method(
             error.to_not_found_response(errors::ApiErrorResponse::PaymentMethodNotFound)
         })?;
     let card = if pm.payment_method == enums::PaymentMethodType::Card {
+        let locker_id = merchant_account.locker_id.get_required_value("locker_id")?;
         let get_card_resp =
-            get_card_from_legacy_locker(state, &pm.merchant_id, &pm.payment_method_id).await?;
+            get_card_from_legacy_locker(state, &locker_id, &pm.payment_method_id).await?;
         let card_detail = payment_methods::get_card_detail(&pm, get_card_resp.card)
             .change_context(errors::ApiErrorResponse::InternalServerError)?;
         Some(card_detail)
diff --git a/crates/router/src/core/payment_methods/transformers.rs b/crates/router/src/core/payment_methods/transformers.rs
index 40f5caea93d..46377c3c1ef 100644
--- a/crates/router/src/core/payment_methods/transformers.rs
+++ b/crates/router/src/core/payment_methods/transformers.rs
@@ -68,16 +68,20 @@ pub fn mk_add_card_request(
     card: &api::CardDetail,
     customer_id: &str,
     _req: &api::CreatePaymentMethod,
+    locker_id: &str,
+    _merchant_id: &str,
 ) -> CustomResult<services::Request, errors::CardVaultError> {
+    #[cfg(feature = "sandbox")]
+    let customer_id = format!("{}::{}", customer_id, _merchant_id);
     let add_card_req = AddCardRequest {
         card_number: card.card_number.clone(),
-        customer_id,
+        customer_id: &customer_id,
         card_exp_month: card.card_exp_month.clone(),
         card_exp_year: card.card_exp_year.clone(),
-        merchant_id: "m0010", // [#253]: Need mapping for application mid to lockeId
+        merchant_id: locker_id,
         email_address: Some("dummy@gmail.com".to_string().into()), //
-        name_on_card: Some("juspay".to_string().into()), // [#256]
-        nickname: Some("router".to_string()), //
+        name_on_card: Some("juspay".to_string().into()),           // [#256]
+        nickname: Some("router".to_string()),                      //
     };
     let body = utils::Encode::<AddCardRequest<'_>>::encode(&add_card_req)
         .change_context(errors::CardVaultError::RequestEncodingFailed)?;
@@ -128,11 +132,11 @@ pub fn mk_add_card_response(
 
 pub fn mk_get_card_request<'a>(
     locker: &Locker,
-    _mid: &'a str,
+    locker_id: &'a str,
     card_id: &'a str,
 ) -> CustomResult<services::Request, errors::CardVaultError> {
     let get_card_req = GetCard {
-        merchant_id: "m0010", // [#253]: need to assign locker id to every merchant
+        merchant_id: locker_id,
         card_id,
     };
 
diff --git a/crates/router/src/core/payments.rs b/crates/router/src/core/payments.rs
index bd6bd7b467c..5c36a499c90 100644
--- a/crates/router/src/core/payments.rs
+++ b/crates/router/src/core/payments.rs
@@ -74,10 +74,9 @@ where
         .get_trackers(
             state,
             &validate_result.payment_id,
-            validate_result.merchant_id,
             &req,
             validate_result.mandate_type,
-            validate_result.storage_scheme,
+            &merchant_account,
         )
         .await?;
 
@@ -323,7 +322,7 @@ where
             &connector,
             customer,
             call_connector_action,
-            merchant_account.storage_scheme,
+            merchant_account,
         )
         .await;
 
@@ -387,7 +386,7 @@ where
             connector,
             customer,
             CallConnectorAction::Trigger,
-            merchant_account.storage_scheme,
+            merchant_account,
         );
 
         join_handlers.push(res);
diff --git a/crates/router/src/core/payments/flows.rs b/crates/router/src/core/payments/flows.rs
index 63e29ecf8c8..d685daa34a4 100644
--- a/crates/router/src/core/payments/flows.rs
+++ b/crates/router/src/core/payments/flows.rs
@@ -11,10 +11,7 @@ use crate::{
     core::{errors::RouterResult, payments},
     routes::AppState,
     services,
-    types::{
-        self, api,
-        storage::{self, enums},
-    },
+    types::{self, api, storage},
 };
 
 #[async_trait]
@@ -35,7 +32,7 @@ pub trait Feature<F, T> {
         connector: &api::ConnectorData,
         maybe_customer: &Option<storage::Customer>,
         call_connector_action: payments::CallConnectorAction,
-        storage_scheme: enums::MerchantStorageScheme,
+        merchant_account: &storage::MerchantAccount,
     ) -> RouterResult<Self>
     where
         Self: Sized,
diff --git a/crates/router/src/core/payments/flows/authorize_flow.rs b/crates/router/src/core/payments/flows/authorize_flow.rs
index e36007772de..dc7fe558aa1 100644
--- a/crates/router/src/core/payments/flows/authorize_flow.rs
+++ b/crates/router/src/core/payments/flows/authorize_flow.rs
@@ -10,10 +10,7 @@ use crate::{
     routes::AppState,
     scheduler::metrics,
     services,
-    types::{
-        self, api,
-        storage::{self, enums as storage_enums},
-    },
+    types::{self, api, storage},
 };
 
 #[async_trait]
@@ -54,7 +51,7 @@ impl Feature<api::Authorize, types::PaymentsAuthorizeData> for types::PaymentsAu
         connector: &api::ConnectorData,
         customer: &Option<storage::Customer>,
         call_connector_action: payments::CallConnectorAction,
-        storage_scheme: storage_enums::MerchantStorageScheme,
+        merchant_account: &storage::MerchantAccount,
     ) -> RouterResult<Self> {
         let resp = self
             .decide_flow(
@@ -63,7 +60,7 @@ impl Feature<api::Authorize, types::PaymentsAuthorizeData> for types::PaymentsAu
                 customer,
                 Some(true),
                 call_connector_action,
-                storage_scheme,
+                merchant_account,
             )
             .await;
 
@@ -81,7 +78,7 @@ impl types::PaymentsAuthorizeRouterData {
         maybe_customer: &Option<storage::Customer>,
         confirm: Option<bool>,
         call_connector_action: payments::CallConnectorAction,
-        _storage_scheme: storage_enums::MerchantStorageScheme,
+        merchant_account: &storage::MerchantAccount,
     ) -> RouterResult<Self> {
         match confirm {
             Some(true) => {
@@ -100,7 +97,10 @@ impl types::PaymentsAuthorizeRouterData {
                 .await
                 .map_err(|error| error.to_payment_failed_response())?;
 
-                Ok(mandate::mandate_procedure(state, resp, maybe_customer).await?)
+                Ok(
+                    mandate::mandate_procedure(state, resp, maybe_customer, merchant_account)
+                        .await?,
+                )
             }
             _ => Ok(self.clone()),
         }
diff --git a/crates/router/src/core/payments/flows/cancel_flow.rs b/crates/router/src/core/payments/flows/cancel_flow.rs
index e54f5a970b9..2dfb74505c5 100644
--- a/crates/router/src/core/payments/flows/cancel_flow.rs
+++ b/crates/router/src/core/payments/flows/cancel_flow.rs
@@ -8,10 +8,7 @@ use crate::{
     },
     routes::AppState,
     services,
-    types::{
-        self, api,
-        storage::{self, enums},
-    },
+    types::{self, api, storage},
 };
 
 #[async_trait]
@@ -44,7 +41,7 @@ impl Feature<api::Void, types::PaymentsCancelData>
         connector: &api::ConnectorData,
         customer: &Option<storage::Customer>,
         call_connector_action: payments::CallConnectorAction,
-        _storage_scheme: enums::MerchantStorageScheme,
+        _merchant_account: &storage::MerchantAccount,
     ) -> RouterResult<Self> {
         self.decide_flow(
             state,
diff --git a/crates/router/src/core/payments/flows/capture_flow.rs b/crates/router/src/core/payments/flows/capture_flow.rs
index 1fc736bcccb..7b84d8f5029 100644
--- a/crates/router/src/core/payments/flows/capture_flow.rs
+++ b/crates/router/src/core/payments/flows/capture_flow.rs
@@ -8,10 +8,7 @@ use crate::{
     },
     routes::AppState,
     services,
-    types::{
-        self, api,
-        storage::{self, enums},
-    },
+    types::{self, api, storage},
 };
 
 #[async_trait]
@@ -45,7 +42,7 @@ impl Feature<api::Capture, types::PaymentsCaptureData>
         connector: &api::ConnectorData,
         customer: &Option<storage::Customer>,
         call_connector_action: payments::CallConnectorAction,
-        _storage_scheme: enums::MerchantStorageScheme,
+        _merchant_account: &storage::MerchantAccount,
     ) -> RouterResult<Self> {
         self.decide_flow(
             state,
diff --git a/crates/router/src/core/payments/flows/psync_flow.rs b/crates/router/src/core/payments/flows/psync_flow.rs
index 1e471b593b1..fafc0d6d03a 100644
--- a/crates/router/src/core/payments/flows/psync_flow.rs
+++ b/crates/router/src/core/payments/flows/psync_flow.rs
@@ -8,10 +8,7 @@ use crate::{
     },
     routes::AppState,
     services,
-    types::{
-        self, api,
-        storage::{self, enums},
-    },
+    types::{self, api, storage},
 };
 
 #[async_trait]
@@ -46,7 +43,7 @@ impl Feature<api::PSync, types::PaymentsSyncData>
         connector: &api::ConnectorData,
         customer: &Option<storage::Customer>,
         call_connector_action: payments::CallConnectorAction,
-        _storage_scheme: enums::MerchantStorageScheme,
+        _merchant_account: &storage::MerchantAccount,
     ) -> RouterResult<Self> {
         self.decide_flow(
             state,
diff --git a/crates/router/src/core/payments/flows/session_flow.rs b/crates/router/src/core/payments/flows/session_flow.rs
index e76eb518a3c..c0cdaffefc7 100644
--- a/crates/router/src/core/payments/flows/session_flow.rs
+++ b/crates/router/src/core/payments/flows/session_flow.rs
@@ -9,10 +9,7 @@ use crate::{
         payments::{self, transformers, PaymentData},
     },
     routes, services,
-    types::{
-        self, api,
-        storage::{self, enums},
-    },
+    types::{self, api, storage},
     utils::OptionExt,
 };
 
@@ -45,7 +42,7 @@ impl Feature<api::Session, types::PaymentsSessionData> for types::PaymentsSessio
         connector: &api::ConnectorData,
         customer: &Option<storage::Customer>,
         call_connector_action: payments::CallConnectorAction,
-        _storage_schema: enums::MerchantStorageScheme,
+        _merchant_account: &storage::MerchantAccount,
     ) -> RouterResult<Self> {
         self.decide_flow(
             state,
diff --git a/crates/router/src/core/payments/flows/verfiy_flow.rs b/crates/router/src/core/payments/flows/verfiy_flow.rs
index ef019350d47..284f2cd4647 100644
--- a/crates/router/src/core/payments/flows/verfiy_flow.rs
+++ b/crates/router/src/core/payments/flows/verfiy_flow.rs
@@ -9,10 +9,7 @@ use crate::{
     },
     routes::AppState,
     services,
-    types::{
-        self, api,
-        storage::{self, enums},
-    },
+    types::{self, api, storage},
 };
 
 #[async_trait]
@@ -43,7 +40,7 @@ impl Feature<api::Verify, types::VerifyRequestData> for types::VerifyRouterData
         connector: &api::ConnectorData,
         customer: &Option<storage::Customer>,
         call_connector_action: payments::CallConnectorAction,
-        storage_scheme: enums::MerchantStorageScheme,
+        merchant_account: &storage::MerchantAccount,
     ) -> RouterResult<Self> {
         self.decide_flow(
             state,
@@ -51,7 +48,7 @@ impl Feature<api::Verify, types::VerifyRequestData> for types::VerifyRouterData
             customer,
             Some(true),
             call_connector_action,
-            storage_scheme,
+            merchant_account,
         )
         .await
     }
@@ -65,7 +62,7 @@ impl types::VerifyRouterData {
         maybe_customer: &Option<storage::Customer>,
         confirm: Option<bool>,
         call_connector_action: payments::CallConnectorAction,
-        _storage_scheme: enums::MerchantStorageScheme,
+        merchant_account: &storage::MerchantAccount,
     ) -> RouterResult<Self> {
         match confirm {
             Some(true) => {
@@ -83,7 +80,10 @@ impl types::VerifyRouterData {
                 )
                 .await
                 .map_err(|err| err.to_verify_failed_response())?;
-                Ok(mandate::mandate_procedure(state, resp, maybe_customer).await?)
+                Ok(
+                    mandate::mandate_procedure(state, resp, maybe_customer, merchant_account)
+                        .await?,
+                )
             }
             _ => Ok(self.clone()),
         }
diff --git a/crates/router/src/core/payments/helpers.rs b/crates/router/src/core/payments/helpers.rs
index 85e817434b4..fec8d8a51f5 100644
--- a/crates/router/src/core/payments/helpers.rs
+++ b/crates/router/src/core/payments/helpers.rs
@@ -101,7 +101,7 @@ pub async fn get_token_pm_type_mandate_details(
     state: &AppState,
     request: &api::PaymentsRequest,
     mandate_type: Option<api::MandateTxnType>,
-    merchant_id: &str,
+    merchant_account: &storage::MerchantAccount,
 ) -> RouterResult<(
     Option<String>,
     Option<storage_enums::PaymentMethodType>,
@@ -121,7 +121,7 @@ pub async fn get_token_pm_type_mandate_details(
         }
         Some(api::MandateTxnType::RecurringMandateTxn) => {
             let (token_, payment_method_type_) =
-                get_token_for_recurring_mandate(state, request, merchant_id).await?;
+                get_token_for_recurring_mandate(state, request, merchant_account).await?;
             Ok((token_, payment_method_type_, None))
         }
         None => Ok((
@@ -135,13 +135,13 @@ pub async fn get_token_pm_type_mandate_details(
 pub async fn get_token_for_recurring_mandate(
     state: &AppState,
     req: &api::PaymentsRequest,
-    merchant_id: &str,
+    merchant_account: &storage::MerchantAccount,
 ) -> RouterResult<(Option<String>, Option<storage_enums::PaymentMethodType>)> {
     let db = &*state.store;
     let mandate_id = req.mandate_id.clone().get_required_value("mandate_id")?;
 
     let mandate = db
-        .find_mandate_by_merchant_id_mandate_id(merchant_id, mandate_id.as_str())
+        .find_mandate_by_merchant_id_mandate_id(&merchant_account.merchant_id, mandate_id.as_str())
         .await
         .map_err(|error| error.to_not_found_response(errors::ApiErrorResponse::MandateNotFound))?;
 
@@ -176,8 +176,11 @@ pub async fn get_token_for_recurring_mandate(
         })?;
 
     let token = Uuid::new_v4().to_string();
-
-    let _ = cards::get_lookup_key_from_locker(state, &token, &payment_method).await?;
+    let locker_id = merchant_account
+        .locker_id
+        .to_owned()
+        .get_required_value("locker_id")?;
+    let _ = cards::get_lookup_key_from_locker(state, &token, &payment_method, &locker_id).await?;
 
     if let Some(payment_method_from_request) = req.payment_method {
         let pm: storage_enums::PaymentMethodType = payment_method_from_request.foreign_into();
@@ -509,7 +512,7 @@ where
 #[instrument(skip_all)]
 pub(crate) async fn call_payment_method(
     state: &AppState,
-    merchant_id: &str,
+    merchant_account: &storage::MerchantAccount,
     payment_method: Option<&api::PaymentMethod>,
     payment_method_type: Option<storage_enums::PaymentMethodType>,
     maybe_customer: &Option<storage::Customer>,
@@ -539,7 +542,7 @@ pub(crate) async fn call_payment_method(
                             let resp = cards::add_payment_method(
                                 state,
                                 payment_method_request,
-                                merchant_id.to_string(),
+                                merchant_account,
                             )
                             .await
                             .attach_printable("Error on adding payment method")?;
@@ -567,13 +570,10 @@ pub(crate) async fn call_payment_method(
                         metadata: None,
                         customer_id: None,
                     };
-                    let resp = cards::add_payment_method(
-                        state,
-                        payment_method_request,
-                        merchant_id.to_string(),
-                    )
-                    .await
-                    .attach_printable("Error on adding payment method")?;
+                    let resp =
+                        cards::add_payment_method(state, payment_method_request, merchant_account)
+                            .await
+                            .attach_printable("Error on adding payment method")?;
                     match resp {
                         crate::services::BachResponse::Json(payment_method) => Ok(payment_method),
                         _ => Err(report!(errors::ApiErrorResponse::InternalServerError)
diff --git a/crates/router/src/core/payments/operations.rs b/crates/router/src/core/payments/operations.rs
index 5d127c205ac..33000465ea0 100644
--- a/crates/router/src/core/payments/operations.rs
+++ b/crates/router/src/core/payments/operations.rs
@@ -88,10 +88,9 @@ pub trait GetTracker<F, D, R>: Send {
         &'a self,
         state: &'a AppState,
         payment_id: &api::PaymentIdType,
-        merchant_id: &str,
         request: &R,
         mandate_type: Option<api::MandateTxnType>,
-        storage_scheme: enums::MerchantStorageScheme,
+        merchant_account: &storage::MerchantAccount,
     ) -> RouterResult<(BoxedOperation<'a, F, R>, D, Option<CustomerDetails>)>;
 }
 
diff --git a/crates/router/src/core/payments/operations/payment_cancel.rs b/crates/router/src/core/payments/operations/payment_cancel.rs
index 6377231744f..ca13a66298f 100644
--- a/crates/router/src/core/payments/operations/payment_cancel.rs
+++ b/crates/router/src/core/payments/operations/payment_cancel.rs
@@ -32,16 +32,17 @@ impl<F: Send + Clone> GetTracker<F, PaymentData<F>, api::PaymentsCancelRequest>
         &'a self,
         state: &'a AppState,
         payment_id: &api::PaymentIdType,
-        merchant_id: &str,
         request: &api::PaymentsCancelRequest,
         _mandate_type: Option<api::MandateTxnType>,
-        storage_scheme: enums::MerchantStorageScheme,
+        merchant_account: &storage::MerchantAccount,
     ) -> RouterResult<(
         BoxedOperation<'a, F, api::PaymentsCancelRequest>,
         PaymentData<F>,
         Option<CustomerDetails>,
     )> {
         let db = &*state.store;
+        let merchant_id = &merchant_account.merchant_id;
+        let storage_scheme = merchant_account.storage_scheme;
         let payment_id = payment_id
             .get_payment_intent_id()
             .change_context(errors::ApiErrorResponse::PaymentNotFound)?;
diff --git a/crates/router/src/core/payments/operations/payment_capture.rs b/crates/router/src/core/payments/operations/payment_capture.rs
index ef8d6aad42c..e0d9b5ef263 100644
--- a/crates/router/src/core/payments/operations/payment_capture.rs
+++ b/crates/router/src/core/payments/operations/payment_capture.rs
@@ -33,16 +33,17 @@ impl<F: Send + Clone> GetTracker<F, payments::PaymentData<F>, api::PaymentsCaptu
         &'a self,
         state: &'a AppState,
         payment_id: &api::PaymentIdType,
-        merchant_id: &str,
         request: &api::PaymentsCaptureRequest,
         _mandate_type: Option<api::MandateTxnType>,
-        storage_scheme: enums::MerchantStorageScheme,
+        merchant_account: &storage::MerchantAccount,
     ) -> RouterResult<(
         BoxedOperation<'a, F, api::PaymentsCaptureRequest>,
         payments::PaymentData<F>,
         Option<payments::CustomerDetails>,
     )> {
         let db = &*state.store;
+        let merchant_id = &merchant_account.merchant_id;
+        let storage_scheme = merchant_account.storage_scheme;
         let (payment_intent, mut payment_attempt, currency, amount);
 
         let payment_id = 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 af0c1cc3303..f58c98e411a 100644
--- a/crates/router/src/core/payments/operations/payment_confirm.rs
+++ b/crates/router/src/core/payments/operations/payment_confirm.rs
@@ -34,16 +34,17 @@ impl<F: Send + Clone> GetTracker<F, PaymentData<F>, api::PaymentsRequest> for Pa
         &'a self,
         state: &'a AppState,
         payment_id: &api::PaymentIdType,
-        merchant_id: &str,
         request: &api::PaymentsRequest,
         mandate_type: Option<api::MandateTxnType>,
-        storage_scheme: enums::MerchantStorageScheme,
+        merchant_account: &storage::MerchantAccount,
     ) -> RouterResult<(
         BoxedOperation<'a, F, api::PaymentsRequest>,
         PaymentData<F>,
         Option<CustomerDetails>,
     )> {
         let db = &*state.store;
+        let merchant_id = &merchant_account.merchant_id;
+        let storage_scheme = merchant_account.storage_scheme;
         let (mut payment_intent, mut payment_attempt, currency, amount, connector_response);
 
         let payment_id = payment_id
@@ -51,8 +52,13 @@ impl<F: Send + Clone> GetTracker<F, PaymentData<F>, api::PaymentsRequest> for Pa
             .change_context(errors::ApiErrorResponse::PaymentNotFound)?;
 
         let (token, payment_method_type, setup_mandate) =
-            helpers::get_token_pm_type_mandate_details(state, request, mandate_type, merchant_id)
-                .await?;
+            helpers::get_token_pm_type_mandate_details(
+                state,
+                request,
+                mandate_type,
+                merchant_account,
+            )
+            .await?;
 
         payment_intent = db
             .find_payment_intent_by_payment_id_merchant_id(&payment_id, merchant_id, storage_scheme)
diff --git a/crates/router/src/core/payments/operations/payment_create.rs b/crates/router/src/core/payments/operations/payment_create.rs
index eb1cf1d5339..86ef9aa31ba 100644
--- a/crates/router/src/core/payments/operations/payment_create.rs
+++ b/crates/router/src/core/payments/operations/payment_create.rs
@@ -39,10 +39,9 @@ impl<F: Send + Clone> GetTracker<F, PaymentData<F>, api::PaymentsRequest> for Pa
         &'a self,
         state: &'a AppState,
         payment_id: &api::PaymentIdType,
-        merchant_id: &str,
         request: &api::PaymentsRequest,
         mandate_type: Option<api::MandateTxnType>,
-        storage_scheme: enums::MerchantStorageScheme,
+        merchant_account: &storage::MerchantAccount,
     ) -> RouterResult<(
         BoxedOperation<'a, F, api::PaymentsRequest>,
         PaymentData<F>,
@@ -50,6 +49,9 @@ impl<F: Send + Clone> GetTracker<F, PaymentData<F>, api::PaymentsRequest> for Pa
     )> {
         let db = &*state.store;
 
+        let merchant_id = &merchant_account.merchant_id;
+        let storage_scheme = merchant_account.storage_scheme;
+
         let (payment_intent, payment_attempt, connector_response);
 
         let money @ (amount, currency) = payments_create_request_validation(request)?;
@@ -61,8 +63,13 @@ impl<F: Send + Clone> GetTracker<F, PaymentData<F>, api::PaymentsRequest> for Pa
             .change_context(errors::ApiErrorResponse::PaymentNotFound)?;
 
         let (token, payment_method_type, setup_mandate) =
-            helpers::get_token_pm_type_mandate_details(state, request, mandate_type, merchant_id)
-                .await?;
+            helpers::get_token_pm_type_mandate_details(
+                state,
+                request,
+                mandate_type,
+                merchant_account,
+            )
+            .await?;
 
         let shipping_address = helpers::get_address_for_payment_request(
             db,
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 c57b499ff22..cb7c9276b35 100644
--- a/crates/router/src/core/payments/operations/payment_method_validate.rs
+++ b/crates/router/src/core/payments/operations/payment_method_validate.rs
@@ -66,16 +66,19 @@ impl<F: Send + Clone> GetTracker<F, PaymentData<F>, api::VerifyRequest> for Paym
         &'a self,
         state: &'a AppState,
         payment_id: &api::PaymentIdType,
-        merchant_id: &str,
         request: &api::VerifyRequest,
         _mandate_type: Option<api::MandateTxnType>,
-        storage_scheme: storage_enums::MerchantStorageScheme,
+        merchant_account: &storage::MerchantAccount,
     ) -> RouterResult<(
         BoxedOperation<'a, F, api::VerifyRequest>,
         PaymentData<F>,
         Option<payments::CustomerDetails>,
     )> {
         let db = &state.store;
+
+        let merchant_id = &merchant_account.merchant_id;
+        let storage_scheme = merchant_account.storage_scheme;
+
         let (payment_intent, payment_attempt, connector_response);
 
         let payment_id = payment_id
diff --git a/crates/router/src/core/payments/operations/payment_session.rs b/crates/router/src/core/payments/operations/payment_session.rs
index d104eead109..2ce4b169762 100644
--- a/crates/router/src/core/payments/operations/payment_session.rs
+++ b/crates/router/src/core/payments/operations/payment_session.rs
@@ -37,10 +37,9 @@ impl<F: Send + Clone> GetTracker<F, PaymentData<F>, api::PaymentsSessionRequest>
         &'a self,
         state: &'a AppState,
         payment_id: &api::PaymentIdType,
-        merchant_id: &str,
         request: &api::PaymentsSessionRequest,
         _mandate_type: Option<api::MandateTxnType>,
-        storage_scheme: enums::MerchantStorageScheme,
+        merchant_account: &storage::MerchantAccount,
     ) -> RouterResult<(
         BoxedOperation<'a, F, api::PaymentsSessionRequest>,
         PaymentData<F>,
@@ -51,6 +50,8 @@ impl<F: Send + Clone> GetTracker<F, PaymentData<F>, api::PaymentsSessionRequest>
             .change_context(errors::ApiErrorResponse::PaymentNotFound)?;
 
         let db = &*state.store;
+        let merchant_id = &merchant_account.merchant_id;
+        let storage_scheme = merchant_account.storage_scheme;
 
         let mut payment_attempt = db
             .find_payment_attempt_by_payment_id_merchant_id(
diff --git a/crates/router/src/core/payments/operations/payment_start.rs b/crates/router/src/core/payments/operations/payment_start.rs
index 6ffb441de2a..76d710aadaf 100644
--- a/crates/router/src/core/payments/operations/payment_start.rs
+++ b/crates/router/src/core/payments/operations/payment_start.rs
@@ -34,10 +34,9 @@ impl<F: Send + Clone> GetTracker<F, PaymentData<F>, api::PaymentsStartRequest> f
         &'a self,
         state: &'a AppState,
         payment_id: &api::PaymentIdType,
-        merchant_id: &str,
         _request: &api::PaymentsStartRequest,
         _mandate_type: Option<api::MandateTxnType>,
-        storage_scheme: enums::MerchantStorageScheme,
+        merchant_account: &storage::MerchantAccount,
     ) -> RouterResult<(
         BoxedOperation<'a, F, api::PaymentsStartRequest>,
         PaymentData<F>,
@@ -46,6 +45,8 @@ impl<F: Send + Clone> GetTracker<F, PaymentData<F>, api::PaymentsStartRequest> f
         let (mut payment_intent, payment_attempt, currency, amount);
         let db = &*state.store;
 
+        let merchant_id = &merchant_account.merchant_id;
+        let storage_scheme = merchant_account.storage_scheme;
         let payment_id = payment_id
             .get_payment_intent_id()
             .change_context(errors::ApiErrorResponse::PaymentNotFound)?;
diff --git a/crates/router/src/core/payments/operations/payment_status.rs b/crates/router/src/core/payments/operations/payment_status.rs
index 7736ffdf874..aa514323f14 100644
--- a/crates/router/src/core/payments/operations/payment_status.rs
+++ b/crates/router/src/core/payments/operations/payment_status.rs
@@ -152,10 +152,9 @@ impl<F: Send + Clone> GetTracker<F, PaymentData<F>, api::PaymentsRetrieveRequest
         &'a self,
         state: &'a AppState,
         payment_id: &api::PaymentIdType,
-        merchant_id: &str,
         request: &api::PaymentsRetrieveRequest,
         _mandate_type: Option<api::MandateTxnType>,
-        storage_scheme: enums::MerchantStorageScheme,
+        merchant_account: &storage::MerchantAccount,
     ) -> RouterResult<(
         BoxedOperation<'a, F, api::PaymentsRetrieveRequest>,
         PaymentData<F>,
@@ -163,11 +162,11 @@ impl<F: Send + Clone> GetTracker<F, PaymentData<F>, api::PaymentsRetrieveRequest
     )> {
         get_tracker_for_sync(
             payment_id,
-            merchant_id,
+            &merchant_account.merchant_id,
             &*state.store,
             request,
             self,
-            storage_scheme,
+            merchant_account.storage_scheme,
         )
         .await
     }
diff --git a/crates/router/src/core/payments/operations/payment_update.rs b/crates/router/src/core/payments/operations/payment_update.rs
index 5641f13670e..0e1e6646ae6 100644
--- a/crates/router/src/core/payments/operations/payment_update.rs
+++ b/crates/router/src/core/payments/operations/payment_update.rs
@@ -33,10 +33,9 @@ impl<F: Send + Clone> GetTracker<F, PaymentData<F>, api::PaymentsRequest> for Pa
         &'a self,
         state: &'a AppState,
         payment_id: &api::PaymentIdType,
-        merchant_id: &str,
         request: &api::PaymentsRequest,
         mandate_type: Option<api::MandateTxnType>,
-        storage_scheme: enums::MerchantStorageScheme,
+        merchant_account: &storage::MerchantAccount,
     ) -> RouterResult<(
         BoxedOperation<'a, F, api::PaymentsRequest>,
         PaymentData<F>,
@@ -47,11 +46,18 @@ impl<F: Send + Clone> GetTracker<F, PaymentData<F>, api::PaymentsRequest> for Pa
         let payment_id = payment_id
             .get_payment_intent_id()
             .change_context(errors::ApiErrorResponse::PaymentNotFound)?;
+        let merchant_id = &merchant_account.merchant_id;
+        let storage_scheme = merchant_account.storage_scheme;
 
         let db = &*state.store;
         let (token, payment_method_type, setup_mandate) =
-            helpers::get_token_pm_type_mandate_details(state, request, mandate_type, merchant_id)
-                .await?;
+            helpers::get_token_pm_type_mandate_details(
+                state,
+                request,
+                mandate_type,
+                merchant_account,
+            )
+            .await?;
 
         payment_attempt = db
             .find_payment_attempt_by_payment_id_merchant_id(
diff --git a/crates/router/src/db/merchant_account.rs b/crates/router/src/db/merchant_account.rs
index d0e48d114e5..dfeeb4ea6e9 100644
--- a/crates/router/src/db/merchant_account.rs
+++ b/crates/router/src/db/merchant_account.rs
@@ -143,6 +143,7 @@ impl MerchantAccountInterface for MockDb {
             parent_merchant_id: merchant_account.parent_merchant_id,
             publishable_key: merchant_account.publishable_key,
             storage_scheme: enums::MerchantStorageScheme::PostgresOnly,
+            locker_id: merchant_account.locker_id,
         };
         accounts.push(account.clone());
         Ok(account)
diff --git a/crates/router/src/routes/payment_methods.rs b/crates/router/src/routes/payment_methods.rs
index 410f6d69d15..7d98bac58d6 100644
--- a/crates/router/src/routes/payment_methods.rs
+++ b/crates/router/src/routes/payment_methods.rs
@@ -21,9 +21,7 @@ pub async fn create_payment_method_api(
         &req,
         json_payload.into_inner(),
         |state, merchant_account, req| async move {
-            let merchant_id = merchant_account.merchant_id.clone();
-
-            cards::add_payment_method(state, req, merchant_id).await
+            cards::add_payment_method(state, req, &merchant_account).await
         },
         api::MerchantAuthentication::ApiKey,
     )
@@ -101,7 +99,7 @@ pub async fn payment_method_retrieve_api(
         &state,
         &req,
         payload,
-        |state, _, pm| cards::retrieve_payment_method(state, pm),
+        |state, merchant_account, pm| cards::retrieve_payment_method(state, pm, merchant_account),
         api::MerchantAuthentication::ApiKey,
     )
     .await
diff --git a/crates/router/src/services/api.rs b/crates/router/src/services/api.rs
index 9d8b3e4a458..d48bce91684 100644
--- a/crates/router/src/services/api.rs
+++ b/crates/router/src/services/api.rs
@@ -562,6 +562,7 @@ pub async fn authenticate_merchant<'a>(
                 redirect_to_merchant_with_http_post: false,
                 publishable_key: None,
                 storage_scheme: enums::MerchantStorageScheme::PostgresOnly,
+                locker_id: None,
             })
         }
 
diff --git a/crates/router/src/types/api/mandates.rs b/crates/router/src/types/api/mandates.rs
index f38b96e06fe..68dadc8d8d6 100644
--- a/crates/router/src/types/api/mandates.rs
+++ b/crates/router/src/types/api/mandates.rs
@@ -15,6 +15,7 @@ use crate::{
         storage::{self, enums as storage_enums},
         transformers::ForeignInto,
     },
+    utils::OptionExt,
 };
 
 newtype!(
@@ -24,12 +25,20 @@ newtype!(
 
 #[async_trait::async_trait]
 pub(crate) trait MandateResponseExt: Sized {
-    async fn from_db_mandate(state: &AppState, mandate: storage::Mandate) -> RouterResult<Self>;
+    async fn from_db_mandate(
+        state: &AppState,
+        mandate: storage::Mandate,
+        merchant_account: &storage::MerchantAccount,
+    ) -> RouterResult<Self>;
 }
 
 #[async_trait::async_trait]
 impl MandateResponseExt for MandateResponse {
-    async fn from_db_mandate(state: &AppState, mandate: storage::Mandate) -> RouterResult<Self> {
+    async fn from_db_mandate(
+        state: &AppState,
+        mandate: storage::Mandate,
+        merchant_account: &storage::MerchantAccount,
+    ) -> RouterResult<Self> {
         let db = &*state.store;
         let payment_method = db
             .find_payment_method(&mandate.payment_method_id)
@@ -39,9 +48,13 @@ impl MandateResponseExt for MandateResponse {
             })?;
 
         let card = if payment_method.payment_method == storage_enums::PaymentMethodType::Card {
+            let locker_id = merchant_account
+                .locker_id
+                .to_owned()
+                .get_required_value("locker_id")?;
             let get_card_resp = payment_methods::cards::get_card_from_legacy_locker(
                 state,
-                &payment_method.merchant_id,
+                &locker_id,
                 &payment_method.payment_method_id,
             )
             .await?;
diff --git a/crates/storage_models/src/merchant_account.rs b/crates/storage_models/src/merchant_account.rs
index 3f72800dcfd..6fca810056c 100644
--- a/crates/storage_models/src/merchant_account.rs
+++ b/crates/storage_models/src/merchant_account.rs
@@ -22,6 +22,7 @@ pub struct MerchantAccount {
     pub parent_merchant_id: Option<String>,
     pub publishable_key: Option<String>,
     pub storage_scheme: storage_enums::MerchantStorageScheme,
+    pub locker_id: Option<String>,
 }
 
 #[derive(Clone, Debug, Default, Insertable, router_derive::DebugAsDisplay)]
@@ -41,6 +42,7 @@ pub struct MerchantAccountNew {
     pub payment_response_hash_key: Option<String>,
     pub redirect_to_merchant_with_http_post: Option<bool>,
     pub publishable_key: Option<String>,
+    pub locker_id: Option<String>,
 }
 
 #[derive(Debug)]
@@ -60,6 +62,7 @@ pub enum MerchantAccountUpdate {
         payment_response_hash_key: Option<String>,
         redirect_to_merchant_with_http_post: Option<bool>,
         publishable_key: Option<String>,
+        locker_id: Option<String>,
     },
 }
 
@@ -80,6 +83,7 @@ pub struct MerchantAccountUpdateInternal {
     payment_response_hash_key: Option<String>,
     redirect_to_merchant_with_http_post: Option<bool>,
     publishable_key: Option<String>,
+    locker_id: Option<String>,
 }
 
 impl From<MerchantAccountUpdate> for MerchantAccountUpdateInternal {
@@ -100,6 +104,7 @@ impl From<MerchantAccountUpdate> for MerchantAccountUpdateInternal {
                 payment_response_hash_key,
                 redirect_to_merchant_with_http_post,
                 publishable_key,
+                locker_id,
             } => Self {
                 merchant_id: Some(merchant_id),
                 merchant_name,
@@ -115,6 +120,7 @@ impl From<MerchantAccountUpdate> for MerchantAccountUpdateInternal {
                 payment_response_hash_key,
                 redirect_to_merchant_with_http_post,
                 publishable_key,
+                locker_id,
             },
         }
     }
diff --git a/crates/storage_models/src/schema.rs b/crates/storage_models/src/schema.rs
index 88adb01fb8d..298a995614c 100644
--- a/crates/storage_models/src/schema.rs
+++ b/crates/storage_models/src/schema.rs
@@ -159,6 +159,7 @@ diesel::table! {
         parent_merchant_id -> Nullable<Varchar>,
         publishable_key -> Nullable<Varchar>,
         storage_scheme -> MerchantStorageScheme,
+        locker_id -> Nullable<Varchar>,
     }
 }
 
diff --git a/migrations/2023-01-03-122401_update_merchant_account/down.sql b/migrations/2023-01-03-122401_update_merchant_account/down.sql
new file mode 100644
index 00000000000..581e025dc7e
--- /dev/null
+++ b/migrations/2023-01-03-122401_update_merchant_account/down.sql
@@ -0,0 +1,3 @@
+-- This file should undo anything in `up.sql`
+ALTER TABLE merchant_account
+DROP COLUMN locker_id;
\ No newline at end of file
diff --git a/migrations/2023-01-03-122401_update_merchant_account/up.sql b/migrations/2023-01-03-122401_update_merchant_account/up.sql
new file mode 100644
index 00000000000..1c7ce757be5
--- /dev/null
+++ b/migrations/2023-01-03-122401_update_merchant_account/up.sql
@@ -0,0 +1,3 @@
+-- Your SQL goes here
+ALTER TABLE merchant_account
+ADD COLUMN locker_id VARCHAR(64);
\ No newline at end of file

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

- [x] Bugfix
- [ ] New feature
- [ ] Enhancement
- [ ] Refactoring
- [ ] Dependency updates

## Description
Add locker_id to merchant_account which shall be passed to legacy locker
use merchant_id::customer_id in place of customer_id if the locker is default locker_id


### Additional Changes

- [x] 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 its 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`
- [x] I addressed lints thrown by `cargo clippy`
- [x] I reviewed submitted code
