Issue:
Bug: [FEATURE]: Integrate encryption service with hyperswitch



### Feature Description

PCI compliance requires application to follow some standards where encryption and decryption should not happen within the application as snapshot might have DEK and data together. So separate service should be used for encryption and decryption. In application wherever we are calling encrypt and decrypt it will be replaced by API call to encryption service.

### Possible Implementation

replace all internal encryption and decryption implementation with API call to encryption service

### 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!

Pull request description:
## Type of Change
<!-- Put an `x` in the boxes that apply -->

- [ ] Bugfix
- [x] New feature
- [ ] Enhancement
- [ ] Refactoring
- [ ] Dependency updates
- [ ] Documentation
- [ ] CI/CD

## Description



### 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
PCI compliance requires application to follow some standards where encryption and decryption should not happen within the application as snapshot might have DEK and data together. So separate service should be used for encryption and decryption. In application wherever we are calling encrypt and decrypt it will be replaced by API call to encryption service.

## How did you test it?
Changes can be verified only through logs. Look for "Fall back to Application Encryption" or "Fall back to Application Decryption" in the logs post deployment after running below tests. If logs are present encryption/decryption failed with encryption service and fall back to the application encryption which has to be investigated.

**Test with merchant created before the changes deployed**
       1. Create Payment
       2. Retrieve Payment
       3. Create Refund
       4. Retrieve Payment
**Test with merchant created after the changes deployed**
       1. Create Merchant
       2. Create API Key
       3. Create MCA
       4. Create Payment
       6. Retrieve Payment
       7. Create Refund
       8. Retrieve Payment
**Requires sanity on all the flows**
       
## 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


Testing:
Changes can be verified only through logs. Look for "Fall back to Application Encryption" or "Fall back to Application Decryption" in the logs post deployment after running below tests. If logs are present encryption/decryption failed with encryption service and fall back to the application encryption which has to be investigated.

**Test with merchant created before the changes deployed**
       1. Create Payment
       2. Retrieve Payment
       3. Create Refund
       4. Retrieve Payment
**Test with merchant created after the changes deployed**
       1. Create Merchant
       2. Create API Key
       3. Create MCA
       4. Create Payment
       6. Retrieve Payment
       7. Create Refund
       8. Retrieve Payment
**Requires sanity on all the flows**

Patch:
diff --git a/Cargo.lock b/Cargo.lock
index 193f19453b9..66b38d09c1f 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -2006,6 +2006,7 @@ name = "common_utils"
 version = "0.1.0"
 dependencies = [
  "async-trait",
+ "base64 0.22.0",
  "blake3",
  "bytes 1.6.0",
  "common_enums",
@@ -2704,6 +2705,7 @@ dependencies = [
  "masking",
  "router_derive",
  "router_env",
+ "rustc-hash",
  "serde",
  "serde_json",
  "strum 0.26.2",
@@ -3858,6 +3860,7 @@ dependencies = [
  "mime",
  "router_derive",
  "router_env",
+ "rustc-hash",
  "serde",
  "serde_json",
  "serde_with",
diff --git a/crates/api_models/src/customers.rs b/crates/api_models/src/customers.rs
index 37c4cd0f1b8..73fb5264ed9 100644
--- a/crates/api_models/src/customers.rs
+++ b/crates/api_models/src/customers.rs
@@ -1,5 +1,12 @@
-use common_utils::{crypto, custom_serde, id_type, pii};
-use masking::Secret;
+use common_utils::{
+    crypto, custom_serde,
+    encryption::Encryption,
+    id_type,
+    pii::{self, EmailStrategy},
+    types::keymanager::ToEncryptable,
+};
+use euclid::dssa::graph::euclid_graph_prelude::FxHashMap;
+use masking::{ExposeInterface, Secret, SwitchStrategy};
 use serde::{Deserialize, Serialize};
 use utoipa::ToSchema;
 
@@ -40,6 +47,85 @@ pub struct CustomerRequest {
     pub metadata: Option<pii::SecretSerdeValue>,
 }
 
+pub struct CustomerRequestWithEmail {
+    pub name: Option<Secret<String>>,
+    pub email: Option<pii::Email>,
+    pub phone: Option<Secret<String>>,
+}
+
+pub struct CustomerRequestWithEncryption {
+    pub name: Option<Encryption>,
+    pub phone: Option<Encryption>,
+    pub email: Option<Encryption>,
+}
+
+pub struct EncryptableCustomer {
+    pub name: crypto::OptionalEncryptableName,
+    pub phone: crypto::OptionalEncryptablePhone,
+    pub email: crypto::OptionalEncryptableEmail,
+}
+
+impl ToEncryptable<EncryptableCustomer, Secret<String>, Encryption>
+    for CustomerRequestWithEncryption
+{
+    fn to_encryptable(self) -> FxHashMap<String, Encryption> {
+        let mut map = FxHashMap::with_capacity_and_hasher(3, Default::default());
+        self.name.map(|x| map.insert("name".to_string(), x));
+        self.phone.map(|x| map.insert("phone".to_string(), x));
+        self.email.map(|x| map.insert("email".to_string(), x));
+        map
+    }
+
+    fn from_encryptable(
+        mut hashmap: FxHashMap<String, crypto::Encryptable<Secret<String>>>,
+    ) -> common_utils::errors::CustomResult<EncryptableCustomer, common_utils::errors::ParsingError>
+    {
+        Ok(EncryptableCustomer {
+            name: hashmap.remove("name"),
+            phone: hashmap.remove("phone"),
+            email: hashmap.remove("email").map(|email| {
+                let encryptable: crypto::Encryptable<Secret<String, EmailStrategy>> =
+                    crypto::Encryptable::new(
+                        email.clone().into_inner().switch_strategy(),
+                        email.into_encrypted(),
+                    );
+                encryptable
+            }),
+        })
+    }
+}
+
+impl ToEncryptable<EncryptableCustomer, Secret<String>, Secret<String>>
+    for CustomerRequestWithEmail
+{
+    fn to_encryptable(self) -> FxHashMap<String, Secret<String>> {
+        let mut map = FxHashMap::with_capacity_and_hasher(3, Default::default());
+        self.name.map(|x| map.insert("name".to_string(), x));
+        self.phone.map(|x| map.insert("phone".to_string(), x));
+        self.email
+            .map(|x| map.insert("email".to_string(), x.expose().switch_strategy()));
+        map
+    }
+
+    fn from_encryptable(
+        mut hashmap: FxHashMap<String, crypto::Encryptable<Secret<String>>>,
+    ) -> common_utils::errors::CustomResult<EncryptableCustomer, common_utils::errors::ParsingError>
+    {
+        Ok(EncryptableCustomer {
+            name: hashmap.remove("name"),
+            email: hashmap.remove("email").map(|email| {
+                let encryptable: crypto::Encryptable<Secret<String, EmailStrategy>> =
+                    crypto::Encryptable::new(
+                        email.clone().into_inner().switch_strategy(),
+                        email.into_encrypted(),
+                    );
+                encryptable
+            }),
+            phone: hashmap.remove("phone"),
+        })
+    }
+}
+
 #[derive(Debug, Clone, Serialize, ToSchema)]
 pub struct CustomerResponse {
     /// The identifier for the customer object
diff --git a/crates/api_models/src/payments.rs b/crates/api_models/src/payments.rs
index 619f345a333..5ac8d0edcc3 100644
--- a/crates/api_models/src/payments.rs
+++ b/crates/api_models/src/payments.rs
@@ -11,10 +11,11 @@ use common_utils::{
     ext_traits::{ConfigExt, Encode},
     hashing::HashedString,
     id_type,
-    pii::{self, Email},
-    types::{MinorUnit, StringMajorUnit},
+    pii::{self, Email, EmailStrategy},
+    types::{keymanager::ToEncryptable, MinorUnit, StringMajorUnit},
 };
-use masking::{PeekInterface, Secret, WithType};
+use euclid::dssa::graph::euclid_graph_prelude::FxHashMap;
+use masking::{ExposeInterface, PeekInterface, Secret, SwitchStrategy, WithType};
 use router_derive::Setter;
 use serde::{
     de::{self, Unexpected, Visitor},
@@ -3187,6 +3188,72 @@ impl AddressDetails {
     }
 }
 
+pub struct AddressDetailsWithPhone {
+    pub address: Option<AddressDetails>,
+    pub phone_number: Option<Secret<String>>,
+    pub email: Option<Email>,
+}
+
+pub struct EncryptableAddressDetails {
+    pub line1: crypto::OptionalEncryptableSecretString,
+    pub line2: crypto::OptionalEncryptableSecretString,
+    pub line3: crypto::OptionalEncryptableSecretString,
+    pub state: crypto::OptionalEncryptableSecretString,
+    pub zip: crypto::OptionalEncryptableSecretString,
+    pub first_name: crypto::OptionalEncryptableSecretString,
+    pub last_name: crypto::OptionalEncryptableSecretString,
+    pub phone_number: crypto::OptionalEncryptableSecretString,
+    pub email: crypto::OptionalEncryptableEmail,
+}
+
+impl ToEncryptable<EncryptableAddressDetails, Secret<String>, Secret<String>>
+    for AddressDetailsWithPhone
+{
+    fn from_encryptable(
+        mut hashmap: FxHashMap<String, crypto::Encryptable<Secret<String>>>,
+    ) -> common_utils::errors::CustomResult<
+        EncryptableAddressDetails,
+        common_utils::errors::ParsingError,
+    > {
+        Ok(EncryptableAddressDetails {
+            line1: hashmap.remove("line1"),
+            line2: hashmap.remove("line2"),
+            line3: hashmap.remove("line3"),
+            state: hashmap.remove("state"),
+            zip: hashmap.remove("zip"),
+            first_name: hashmap.remove("first_name"),
+            last_name: hashmap.remove("last_name"),
+            phone_number: hashmap.remove("phone_number"),
+            email: hashmap.remove("email").map(|x| {
+                let inner: Secret<String, EmailStrategy> = x.clone().into_inner().switch_strategy();
+                crypto::Encryptable::new(inner, x.into_encrypted())
+            }),
+        })
+    }
+
+    fn to_encryptable(self) -> FxHashMap<String, Secret<String>> {
+        let mut map = FxHashMap::with_capacity_and_hasher(9, Default::default());
+        self.address.map(|address| {
+            address.line1.map(|x| map.insert("line1".to_string(), x));
+            address.line2.map(|x| map.insert("line2".to_string(), x));
+            address.line3.map(|x| map.insert("line3".to_string(), x));
+            address.state.map(|x| map.insert("state".to_string(), x));
+            address.zip.map(|x| map.insert("zip".to_string(), x));
+            address
+                .first_name
+                .map(|x| map.insert("first_name".to_string(), x));
+            address
+                .last_name
+                .map(|x| map.insert("last_name".to_string(), x));
+        });
+        self.email
+            .map(|x| map.insert("email".to_string(), x.expose().switch_strategy()));
+        self.phone_number
+            .map(|x| map.insert("phone_number".to_string(), x));
+        map
+    }
+}
+
 #[derive(Debug, Clone, Default, Eq, PartialEq, ToSchema, serde::Deserialize, serde::Serialize)]
 pub struct PhoneDetails {
     /// The contact number
diff --git a/crates/common_utils/Cargo.toml b/crates/common_utils/Cargo.toml
index df6b4400633..61d96a21737 100644
--- a/crates/common_utils/Cargo.toml
+++ b/crates/common_utils/Cargo.toml
@@ -10,6 +10,7 @@ license.workspace = true
 [features]
 keymanager = ["dep:router_env"]
 keymanager_mtls = ["reqwest/rustls-tls"]
+encryption_service = ["dep:router_env"]
 signals = ["dep:signal-hook-tokio", "dep:signal-hook", "dep:tokio", "dep:router_env", "dep:futures"]
 async_ext = ["dep:async-trait", "dep:futures"]
 logs = ["dep:router_env"]
@@ -17,6 +18,7 @@ metrics = ["dep:router_env", "dep:futures"]
 
 [dependencies]
 async-trait = { version = "0.1.79", optional = true }
+base64 = "0.22.0"
 blake3 = { version = "1.5.1", features = ["serde"] }
 bytes = "1.6.0"
 diesel = "2.1.5"
diff --git a/crates/common_utils/src/consts.rs b/crates/common_utils/src/consts.rs
index 848189cd899..e52d24c9baa 100644
--- a/crates/common_utils/src/consts.rs
+++ b/crates/common_utils/src/consts.rs
@@ -99,6 +99,8 @@ pub const MAX_ALLOWED_MERCHANT_REFERENCE_ID_LENGTH: u8 = 64;
 /// Minimum allowed length for MerchantReferenceId
 pub const MIN_REQUIRED_MERCHANT_REFERENCE_ID_LENGTH: u8 = 1;
 
+/// General purpose base64 engine
+pub const BASE64_ENGINE: base64::engine::GeneralPurpose = base64::engine::general_purpose::STANDARD;
 /// Regex for matching a domain
 /// Eg -
 /// http://www.example.com
diff --git a/crates/diesel_models/src/encryption.rs b/crates/common_utils/src/encryption.rs
similarity index 88%
rename from crates/diesel_models/src/encryption.rs
rename to crates/common_utils/src/encryption.rs
index 6c6063c1604..9c566432782 100644
--- a/crates/diesel_models/src/encryption.rs
+++ b/crates/common_utils/src/encryption.rs
@@ -1,40 +1,13 @@
-use common_utils::pii::EncryptionStrategy;
 use diesel::{
     backend::Backend,
     deserialize::{self, FromSql, Queryable},
+    expression::AsExpression,
     serialize::ToSql,
-    sql_types, AsExpression,
+    sql_types,
 };
 use masking::Secret;
 
-#[derive(Debug, AsExpression, Clone, serde::Serialize, serde::Deserialize, Eq, PartialEq)]
-#[diesel(sql_type = sql_types::Binary)]
-#[repr(transparent)]
-pub struct Encryption {
-    inner: Secret<Vec<u8>, EncryptionStrategy>,
-}
-
-impl<T: Clone> From<common_utils::crypto::Encryptable<T>> for Encryption {
-    fn from(value: common_utils::crypto::Encryptable<T>) -> Self {
-        Self::new(value.into_encrypted())
-    }
-}
-
-impl Encryption {
-    pub fn new(item: Secret<Vec<u8>, EncryptionStrategy>) -> Self {
-        Self { inner: item }
-    }
-
-    #[inline]
-    pub fn into_inner(self) -> Secret<Vec<u8>, EncryptionStrategy> {
-        self.inner
-    }
-
-    #[inline]
-    pub fn get_inner(&self) -> &Secret<Vec<u8>, EncryptionStrategy> {
-        &self.inner
-    }
-}
+use crate::{crypto::Encryptable, pii::EncryptionStrategy};
 
 impl<DB> FromSql<sql_types::Binary, DB> for Encryption
 where
@@ -69,3 +42,32 @@ where
         Ok(Self { inner: row })
     }
 }
+
+#[derive(Debug, AsExpression, Clone, serde::Serialize, serde::Deserialize, Eq, PartialEq)]
+#[diesel(sql_type = sql_types::Binary)]
+#[repr(transparent)]
+pub struct Encryption {
+    inner: Secret<Vec<u8>, EncryptionStrategy>,
+}
+
+impl<T: Clone> From<Encryptable<T>> for Encryption {
+    fn from(value: Encryptable<T>) -> Self {
+        Self::new(value.into_encrypted())
+    }
+}
+
+impl Encryption {
+    pub fn new(item: Secret<Vec<u8>, EncryptionStrategy>) -> Self {
+        Self { inner: item }
+    }
+
+    #[inline]
+    pub fn into_inner(self) -> Secret<Vec<u8>, EncryptionStrategy> {
+        self.inner
+    }
+
+    #[inline]
+    pub fn get_inner(&self) -> &Secret<Vec<u8>, EncryptionStrategy> {
+        &self.inner
+    }
+}
diff --git a/crates/common_utils/src/keymanager.rs b/crates/common_utils/src/keymanager.rs
index ecdb9b63ad5..9d6e9315074 100644
--- a/crates/common_utils/src/keymanager.rs
+++ b/crates/common_utils/src/keymanager.rs
@@ -3,22 +3,26 @@
 use core::fmt::Debug;
 use std::str::FromStr;
 
+use base64::Engine;
 use error_stack::ResultExt;
 use http::{HeaderMap, HeaderName, HeaderValue, Method, StatusCode};
-#[cfg(feature = "keymanager_mtls")]
-use masking::PeekInterface;
+use masking::{PeekInterface, StrongSecret};
 use once_cell::sync::OnceCell;
 use router_env::{instrument, logger, tracing};
 
 use crate::{
+    consts::BASE64_ENGINE,
     errors,
     types::keymanager::{
-        DataKeyCreateResponse, EncryptionCreateRequest, EncryptionTransferRequest, KeyManagerState,
+        BatchDecryptDataRequest, DataKeyCreateResponse, DecryptDataRequest,
+        EncryptionCreateRequest, EncryptionTransferRequest, KeyManagerState,
+        TransientBatchDecryptDataRequest, TransientDecryptDataRequest,
     },
 };
 
 const CONTENT_TYPE: &str = "Content-Type";
 static ENCRYPTION_API_CLIENT: OnceCell<reqwest::Client> = OnceCell::new();
+static DEFAULT_ENCRYPTION_VERSION: &str = "v1";
 
 /// Get keymanager client constructed from the url and state
 #[instrument(skip_all)]
@@ -68,7 +72,7 @@ pub async fn send_encryption_request<T>(
     request_body: T,
 ) -> errors::CustomResult<reqwest::Response, errors::KeyManagerClientError>
 where
-    T: serde::Serialize,
+    T: ConvertRaw,
 {
     let client = get_api_encryption_client(state)?;
     let url = reqwest::Url::parse(&url)
@@ -76,7 +80,7 @@ where
 
     client
         .request(method, url)
-        .json(&request_body)
+        .json(&ConvertRaw::convert_raw(request_body)?)
         .headers(headers)
         .send()
         .await
@@ -94,7 +98,7 @@ pub async fn call_encryption_service<T, R>(
     request_body: T,
 ) -> errors::CustomResult<R, errors::KeyManagerClientError>
 where
-    T: serde::Serialize + Send + Sync + 'static + Debug,
+    T: ConvertRaw + Send + Sync + 'static + Debug,
     R: serde::de::DeserializeOwned,
 {
     let url = format!("{}/{endpoint}", &state.url);
@@ -152,6 +156,62 @@ where
     }
 }
 
+/// Trait to convert the raw data to the required format for encryption service request
+pub trait ConvertRaw {
+    /// Return type of the convert_raw function
+    type Output: serde::Serialize;
+    /// Function to convert the raw data to the required format for encryption service request
+    fn convert_raw(self) -> Result<Self::Output, errors::KeyManagerClientError>;
+}
+
+impl<T: serde::Serialize> ConvertRaw for T {
+    type Output = T;
+    fn convert_raw(self) -> Result<Self::Output, errors::KeyManagerClientError> {
+        Ok(self)
+    }
+}
+
+impl ConvertRaw for TransientDecryptDataRequest {
+    type Output = DecryptDataRequest;
+    fn convert_raw(self) -> Result<Self::Output, errors::KeyManagerClientError> {
+        let data = match String::from_utf8(self.data.peek().clone()) {
+            Ok(data) => data,
+            Err(_) => {
+                let data = BASE64_ENGINE.encode(self.data.peek().clone());
+                format!("{DEFAULT_ENCRYPTION_VERSION}:{data}")
+            }
+        };
+        Ok(DecryptDataRequest {
+            identifier: self.identifier,
+            data: StrongSecret::new(data),
+        })
+    }
+}
+
+impl ConvertRaw for TransientBatchDecryptDataRequest {
+    type Output = BatchDecryptDataRequest;
+    fn convert_raw(self) -> Result<Self::Output, errors::KeyManagerClientError> {
+        let data = self
+            .data
+            .iter()
+            .map(|(k, v)| {
+                let value = match String::from_utf8(v.peek().clone()) {
+                    Ok(data) => data,
+                    Err(_) => {
+                        let data = BASE64_ENGINE.encode(v.peek().clone());
+                        format!("{DEFAULT_ENCRYPTION_VERSION}:{data}")
+                    }
+                };
+                (k.to_owned(), StrongSecret::new(value))
+            })
+            .collect();
+        Ok(BatchDecryptDataRequest {
+            data,
+            identifier: self.identifier,
+        })
+    }
+}
+
 /// A function to create the key in keymanager
 #[instrument(skip_all)]
 pub async fn create_key_in_key_manager(
diff --git a/crates/common_utils/src/lib.rs b/crates/common_utils/src/lib.rs
index 9b339fb956e..e93b0c66ceb 100644
--- a/crates/common_utils/src/lib.rs
+++ b/crates/common_utils/src/lib.rs
@@ -13,6 +13,8 @@ pub mod access_token;
 pub mod consts;
 pub mod crypto;
 pub mod custom_serde;
+#[allow(missing_docs)] // Todo: add docs
+pub mod encryption;
 pub mod errors;
 #[allow(missing_docs)] // Todo: add docs
 pub mod events;
@@ -31,6 +33,7 @@ pub mod request;
 pub mod signals;
 #[allow(missing_docs)] // Todo: add docs
 pub mod static_cache;
+pub mod transformers;
 pub mod types;
 pub mod validation;
 
diff --git a/crates/common_utils/src/transformers.rs b/crates/common_utils/src/transformers.rs
new file mode 100644
index 00000000000..3799522e16d
--- /dev/null
+++ b/crates/common_utils/src/transformers.rs
@@ -0,0 +1,15 @@
+//! Utilities for converting between foreign types
+
+/// Trait for converting from one foreign type to another
+pub trait ForeignFrom<F> {
+    /// Convert from a foreign type to the current type
+    fn foreign_from(from: F) -> Self;
+}
+
+/// Trait for converting from one foreign type to another
+pub trait ForeignTryFrom<F>: Sized {
+    /// Custom error for conversion failure
+    type Error;
+    /// Convert from a foreign type to the current type and return an error if the conversion fails
+    fn foreign_try_from(from: F) -> Result<Self, Self::Error>;
+}
diff --git a/crates/common_utils/src/types/keymanager.rs b/crates/common_utils/src/types/keymanager.rs
index 356ccdd4832..5a7b87d0ce0 100644
--- a/crates/common_utils/src/types/keymanager.rs
+++ b/crates/common_utils/src/types/keymanager.rs
@@ -1,8 +1,24 @@
 #![allow(missing_docs)]
 
-#[cfg(feature = "keymanager_mtls")]
-use masking::Secret;
-use serde::{Deserialize, Serialize};
+use core::fmt;
+
+use base64::Engine;
+use masking::{ExposeInterface, PeekInterface, Secret, Strategy, StrongSecret};
+#[cfg(feature = "encryption_service")]
+use router_env::logger;
+use rustc_hash::FxHashMap;
+use serde::{
+    de::{self, Unexpected, Visitor},
+    ser, Deserialize, Deserializer, Serialize,
+};
+
+use crate::{
+    consts::BASE64_ENGINE,
+    crypto::Encryptable,
+    encryption::Encryption,
+    errors::{self, CustomResult},
+    transformers::{ForeignFrom, ForeignTryFrom},
+};
 
 #[derive(Debug)]
 pub struct KeyManagerState {
@@ -18,6 +34,7 @@ pub struct KeyManagerState {
 pub enum Identifier {
     User(String),
     Merchant(String),
+    UserAuth(String),
 }
 
 #[derive(Serialize, Deserialize, Debug, Eq, PartialEq, Clone)]
@@ -39,3 +56,420 @@ pub struct DataKeyCreateResponse {
     pub identifier: Identifier,
     pub key_version: String,
 }
+
+#[derive(Serialize, Deserialize, Debug)]
+pub struct BatchEncryptDataRequest {
+    #[serde(flatten)]
+    pub identifier: Identifier,
+    pub data: DecryptedDataGroup,
+}
+
+impl<S> From<(Secret<Vec<u8>, S>, Identifier)> for EncryptDataRequest
+where
+    S: Strategy<Vec<u8>>,
+{
+    fn from((secret, identifier): (Secret<Vec<u8>, S>, Identifier)) -> Self {
+        Self {
+            identifier,
+            data: DecryptedData(StrongSecret::new(secret.expose())),
+        }
+    }
+}
+
+impl<S> From<(FxHashMap<String, Secret<Vec<u8>, S>>, Identifier)> for BatchEncryptDataRequest
+where
+    S: Strategy<Vec<u8>>,
+{
+    fn from((map, identifier): (FxHashMap<String, Secret<Vec<u8>, S>>, Identifier)) -> Self {
+        let group = map
+            .into_iter()
+            .map(|(key, value)| (key, DecryptedData(StrongSecret::new(value.expose()))))
+            .collect();
+        Self {
+            identifier,
+            data: DecryptedDataGroup(group),
+        }
+    }
+}
+
+impl<S> From<(Secret<String, S>, Identifier)> for EncryptDataRequest
+where
+    S: Strategy<String>,
+{
+    fn from((secret, identifier): (Secret<String, S>, Identifier)) -> Self {
+        Self {
+            data: DecryptedData(StrongSecret::new(secret.expose().as_bytes().to_vec())),
+            identifier,
+        }
+    }
+}
+
+impl<S> From<(Secret<serde_json::Value, S>, Identifier)> for EncryptDataRequest
+where
+    S: Strategy<serde_json::Value>,
+{
+    fn from((secret, identifier): (Secret<serde_json::Value, S>, Identifier)) -> Self {
+        Self {
+            data: DecryptedData(StrongSecret::new(
+                secret.expose().to_string().as_bytes().to_vec(),
+            )),
+            identifier,
+        }
+    }
+}
+
+impl<S> From<(FxHashMap<String, Secret<serde_json::Value, S>>, Identifier)>
+    for BatchEncryptDataRequest
+where
+    S: Strategy<serde_json::Value>,
+{
+    fn from(
+        (map, identifier): (FxHashMap<String, Secret<serde_json::Value, S>>, Identifier),
+    ) -> Self {
+        let group = map
+            .into_iter()
+            .map(|(key, value)| {
+                (
+                    key,
+                    DecryptedData(StrongSecret::new(
+                        value.expose().to_string().as_bytes().to_vec(),
+                    )),
+                )
+            })
+            .collect();
+        Self {
+            data: DecryptedDataGroup(group),
+            identifier,
+        }
+    }
+}
+
+impl<S> From<(FxHashMap<String, Secret<String, S>>, Identifier)> for BatchEncryptDataRequest
+where
+    S: Strategy<String>,
+{
+    fn from((map, identifier): (FxHashMap<String, Secret<String, S>>, Identifier)) -> Self {
+        let group = map
+            .into_iter()
+            .map(|(key, value)| {
+                (
+                    key,
+                    DecryptedData(StrongSecret::new(value.expose().as_bytes().to_vec())),
+                )
+            })
+            .collect();
+        Self {
+            data: DecryptedDataGroup(group),
+            identifier,
+        }
+    }
+}
+
+#[derive(Serialize, Deserialize, Debug)]
+pub struct EncryptDataRequest {
+    #[serde(flatten)]
+    pub identifier: Identifier,
+    pub data: DecryptedData,
+}
+
+#[derive(Debug, Serialize, serde::Deserialize)]
+pub struct DecryptedDataGroup(pub FxHashMap<String, DecryptedData>);
+
+#[derive(Debug, Serialize, Deserialize)]
+pub struct BatchEncryptDataResponse {
+    pub data: EncryptedDataGroup,
+}
+
+#[derive(Debug, Serialize, Deserialize)]
+pub struct EncryptDataResponse {
+    pub data: EncryptedData,
+}
+
+#[derive(Debug, Serialize, serde::Deserialize)]
+pub struct EncryptedDataGroup(pub FxHashMap<String, EncryptedData>);
+#[derive(Debug)]
+pub struct TransientBatchDecryptDataRequest {
+    pub identifier: Identifier,
+    pub data: FxHashMap<String, StrongSecret<Vec<u8>>>,
+}
+
+#[derive(Debug)]
+pub struct TransientDecryptDataRequest {
+    pub identifier: Identifier,
+    pub data: StrongSecret<Vec<u8>>,
+}
+
+#[derive(Debug, Serialize, Deserialize)]
+pub struct BatchDecryptDataRequest {
+    #[serde(flatten)]
+    pub identifier: Identifier,
+    pub data: FxHashMap<String, StrongSecret<String>>,
+}
+
+#[derive(Debug, Serialize, Deserialize)]
+pub struct DecryptDataRequest {
+    #[serde(flatten)]
+    pub identifier: Identifier,
+    pub data: StrongSecret<String>,
+}
+
+impl<T, S> ForeignFrom<(FxHashMap<String, Secret<T, S>>, BatchEncryptDataResponse)>
+    for FxHashMap<String, Encryptable<Secret<T, S>>>
+where
+    T: Clone,
+    S: Strategy<T> + Send,
+{
+    fn foreign_from(
+        (mut masked_data, response): (FxHashMap<String, Secret<T, S>>, BatchEncryptDataResponse),
+    ) -> Self {
+        response
+            .data
+            .0
+            .into_iter()
+            .flat_map(|(k, v)| {
+                masked_data.remove(&k).map(|inner| {
+                    (
+                        k,
+                        Encryptable::new(inner.clone(), v.data.peek().clone().into()),
+                    )
+                })
+            })
+            .collect()
+    }
+}
+
+impl<T, S> ForeignFrom<(Secret<T, S>, EncryptDataResponse)> for Encryptable<Secret<T, S>>
+where
+    T: Clone,
+    S: Strategy<T> + Send,
+{
+    fn foreign_from((masked_data, response): (Secret<T, S>, EncryptDataResponse)) -> Self {
+        Self::new(masked_data, response.data.data.peek().clone().into())
+    }
+}
+
+pub trait DecryptedDataConversion<T: Clone, S: Strategy<T> + Send>: Sized {
+    fn convert(
+        value: &DecryptedData,
+        encryption: Encryption,
+    ) -> CustomResult<Self, errors::CryptoError>;
+}
+
+impl<S: Strategy<String> + Send> DecryptedDataConversion<String, S>
+    for Encryptable<Secret<String, S>>
+{
+    fn convert(
+        value: &DecryptedData,
+        encryption: Encryption,
+    ) -> CustomResult<Self, errors::CryptoError> {
+        let string = String::from_utf8(value.clone().inner().peek().clone()).map_err(|_err| {
+            #[cfg(feature = "encryption_service")]
+            logger::error!("Decryption error {:?}", _err);
+            errors::CryptoError::DecodingFailed
+        })?;
+        Ok(Self::new(Secret::new(string), encryption.into_inner()))
+    }
+}
+
+impl<S: Strategy<serde_json::Value> + Send> DecryptedDataConversion<serde_json::Value, S>
+    for Encryptable<Secret<serde_json::Value, S>>
+{
+    fn convert(
+        value: &DecryptedData,
+        encryption: Encryption,
+    ) -> CustomResult<Self, errors::CryptoError> {
+        let val = serde_json::from_slice(value.clone().inner().peek()).map_err(|_err| {
+            #[cfg(feature = "encryption_service")]
+            logger::error!("Decryption error {:?}", _err);
+            errors::CryptoError::DecodingFailed
+        })?;
+        Ok(Self::new(Secret::new(val), encryption.clone().into_inner()))
+    }
+}
+
+impl<S: Strategy<Vec<u8>> + Send> DecryptedDataConversion<Vec<u8>, S>
+    for Encryptable<Secret<Vec<u8>, S>>
+{
+    fn convert(
+        value: &DecryptedData,
+        encryption: Encryption,
+    ) -> CustomResult<Self, errors::CryptoError> {
+        Ok(Self::new(
+            Secret::new(value.clone().inner().peek().clone()),
+            encryption.clone().into_inner(),
+        ))
+    }
+}
+
+impl<T, S> ForeignTryFrom<(Encryption, DecryptDataResponse)> for Encryptable<Secret<T, S>>
+where
+    T: Clone,
+    S: Strategy<T> + Send,
+    Self: DecryptedDataConversion<T, S>,
+{
+    type Error = error_stack::Report<errors::CryptoError>;
+    fn foreign_try_from(
+        (encrypted_data, response): (Encryption, DecryptDataResponse),
+    ) -> Result<Self, Self::Error> {
+        Self::convert(&response.data, encrypted_data)
+    }
+}
+
+impl<T, S> ForeignTryFrom<(FxHashMap<String, Encryption>, BatchDecryptDataResponse)>
+    for FxHashMap<String, Encryptable<Secret<T, S>>>
+where
+    T: Clone,
+    S: Strategy<T> + Send,
+    Encryptable<Secret<T, S>>: DecryptedDataConversion<T, S>,
+{
+    type Error = error_stack::Report<errors::CryptoError>;
+    fn foreign_try_from(
+        (mut encrypted_data, response): (FxHashMap<String, Encryption>, BatchDecryptDataResponse),
+    ) -> Result<Self, Self::Error> {
+        response
+            .data
+            .0
+            .into_iter()
+            .map(|(k, v)| match encrypted_data.remove(&k) {
+                Some(encrypted) => Ok((k.clone(), Encryptable::convert(&v, encrypted.clone())?)),
+                None => Err(errors::CryptoError::DecodingFailed)?,
+            })
+            .collect()
+    }
+}
+
+impl From<(Encryption, Identifier)> for TransientDecryptDataRequest {
+    fn from((encryption, identifier): (Encryption, Identifier)) -> Self {
+        Self {
+            data: StrongSecret::new(encryption.clone().into_inner().expose()),
+            identifier,
+        }
+    }
+}
+
+impl From<(FxHashMap<String, Encryption>, Identifier)> for TransientBatchDecryptDataRequest {
+    fn from((map, identifier): (FxHashMap<String, Encryption>, Identifier)) -> Self {
+        let data = map
+            .into_iter()
+            .map(|(k, v)| (k, StrongSecret::new(v.clone().into_inner().expose())))
+            .collect();
+        Self { data, identifier }
+    }
+}
+
+#[derive(Debug, Serialize, Deserialize)]
+pub struct BatchDecryptDataResponse {
+    pub data: DecryptedDataGroup,
+}
+
+#[derive(Debug, Serialize, Deserialize)]
+pub struct DecryptDataResponse {
+    pub data: DecryptedData,
+}
+
+#[derive(Clone, Debug)]
+pub struct DecryptedData(StrongSecret<Vec<u8>>);
+
+impl Serialize for DecryptedData {
+    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+    where
+        S: serde::Serializer,
+    {
+        let data = BASE64_ENGINE.encode(self.0.peek());
+        serializer.serialize_str(&data)
+    }
+}
+
+impl<'de> Deserialize<'de> for DecryptedData {
+    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
+    where
+        D: Deserializer<'de>,
+    {
+        struct DecryptedDataVisitor;
+
+        impl<'de> Visitor<'de> for DecryptedDataVisitor {
+            type Value = DecryptedData;
+
+            fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
+                formatter.write_str("string of the format {version}:{base64_encoded_data}'")
+            }
+
+            fn visit_str<E>(self, value: &str) -> Result<DecryptedData, E>
+            where
+                E: de::Error,
+            {
+                let dec_data = BASE64_ENGINE.decode(value).map_err(|err| {
+                    let err = err.to_string();
+                    E::invalid_value(Unexpected::Str(value), &err.as_str())
+                })?;
+
+                Ok(DecryptedData(dec_data.into()))
+            }
+        }
+
+        deserializer.deserialize_str(DecryptedDataVisitor)
+    }
+}
+
+impl DecryptedData {
+    pub fn from_data(data: StrongSecret<Vec<u8>>) -> Self {
+        Self(data)
+    }
+
+    pub fn inner(self) -> StrongSecret<Vec<u8>> {
+        self.0
+    }
+}
+
+#[derive(Debug)]
+pub struct EncryptedData {
+    pub data: StrongSecret<Vec<u8>>,
+}
+
+impl Serialize for EncryptedData {
+    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+    where
+        S: serde::Serializer,
+    {
+        let data = String::from_utf8(self.data.peek().clone()).map_err(ser::Error::custom)?;
+        serializer.serialize_str(data.as_str())
+    }
+}
+
+impl<'de> Deserialize<'de> for EncryptedData {
+    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
+    where
+        D: Deserializer<'de>,
+    {
+        struct EncryptedDataVisitor;
+
+        impl<'de> Visitor<'de> for EncryptedDataVisitor {
+            type Value = EncryptedData;
+
+            fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
+                formatter.write_str("string of the format {version}:{base64_encoded_data}'")
+            }
+
+            fn visit_str<E>(self, value: &str) -> Result<EncryptedData, E>
+            where
+                E: de::Error,
+            {
+                Ok(EncryptedData {
+                    data: StrongSecret::new(value.as_bytes().to_vec()),
+                })
+            }
+        }
+
+        deserializer.deserialize_str(EncryptedDataVisitor)
+    }
+}
+
+/// A trait which converts the struct to Hashmap required for encryption and back to struct
+pub trait ToEncryptable<T, S: Clone, E>: Sized {
+    /// Serializes the type to a hashmap
+    fn to_encryptable(self) -> FxHashMap<String, E>;
+    /// Deserializes the hashmap back to the type
+    fn from_encryptable(
+        hashmap: FxHashMap<String, Encryptable<S>>,
+    ) -> CustomResult<T, errors::ParsingError>;
+}
diff --git a/crates/diesel_models/Cargo.toml b/crates/diesel_models/Cargo.toml
index f33427aaf30..10890ef0cf0 100644
--- a/crates/diesel_models/Cargo.toml
+++ b/crates/diesel_models/Cargo.toml
@@ -15,6 +15,7 @@ kv_store = []
 async-bb8-diesel = { git = "https://github.com/jarnura/async-bb8-diesel", rev = "53b4ab901aab7635c8215fd1c2d542c8db443094" }
 diesel = { version = "2.1.5", features = ["postgres", "serde_json", "time", "64-column-tables"] }
 error-stack = "0.4.1"
+rustc-hash = "1.1.0"
 serde = { version = "1.0.197", features = ["derive"] }
 serde_json = "1.0.115"
 strum = { version = "0.26.2", features = ["derive"] }
diff --git a/crates/diesel_models/src/address.rs b/crates/diesel_models/src/address.rs
index d695d2a0e70..57c4e36c786 100644
--- a/crates/diesel_models/src/address.rs
+++ b/crates/diesel_models/src/address.rs
@@ -1,9 +1,17 @@
-use common_utils::id_type;
+use common_utils::{
+    crypto::{self, Encryptable},
+    encryption::Encryption,
+    id_type,
+    pii::EmailStrategy,
+    types::keymanager::ToEncryptable,
+};
 use diesel::{AsChangeset, Identifiable, Insertable, Queryable, Selectable};
+use masking::{Secret, SwitchStrategy};
+use rustc_hash::FxHashMap;
 use serde::{Deserialize, Serialize};
 use time::PrimitiveDateTime;
 
-use crate::{encryption::Encryption, enums, schema::address};
+use crate::{enums, schema::address};
 
 #[derive(Clone, Debug, Insertable, Serialize, Deserialize, router_derive::DebugAsDisplay)]
 #[diesel(table_name = address)]
@@ -54,6 +62,62 @@ pub struct Address {
     pub email: Option<Encryption>,
 }
 
+#[derive(Clone)]
+// Intermediate struct to convert HashMap to Address
+pub struct EncryptableAddress {
+    pub line1: crypto::OptionalEncryptableSecretString,
+    pub line2: crypto::OptionalEncryptableSecretString,
+    pub line3: crypto::OptionalEncryptableSecretString,
+    pub state: crypto::OptionalEncryptableSecretString,
+    pub zip: crypto::OptionalEncryptableSecretString,
+    pub first_name: crypto::OptionalEncryptableSecretString,
+    pub last_name: crypto::OptionalEncryptableSecretString,
+    pub phone_number: crypto::OptionalEncryptableSecretString,
+    pub email: crypto::OptionalEncryptableEmail,
+}
+
+impl ToEncryptable<EncryptableAddress, Secret<String>, Encryption> for Address {
+    fn to_encryptable(self) -> FxHashMap<String, Encryption> {
+        let mut map = FxHashMap::with_capacity_and_hasher(9, Default::default());
+        self.line1.map(|x| map.insert("line1".to_string(), x));
+        self.line2.map(|x| map.insert("line2".to_string(), x));
+        self.line3.map(|x| map.insert("line3".to_string(), x));
+        self.zip.map(|x| map.insert("zip".to_string(), x));
+        self.state.map(|x| map.insert("state".to_string(), x));
+        self.first_name
+            .map(|x| map.insert("first_name".to_string(), x));
+        self.last_name
+            .map(|x| map.insert("last_name".to_string(), x));
+        self.phone_number
+            .map(|x| map.insert("phone_number".to_string(), x));
+        self.email.map(|x| map.insert("email".to_string(), x));
+        map
+    }
+
+    fn from_encryptable(
+        mut hashmap: FxHashMap<String, Encryptable<Secret<String>>>,
+    ) -> common_utils::errors::CustomResult<EncryptableAddress, common_utils::errors::ParsingError>
+    {
+        Ok(EncryptableAddress {
+            line1: hashmap.remove("line1"),
+            line2: hashmap.remove("line2"),
+            line3: hashmap.remove("line3"),
+            zip: hashmap.remove("zip"),
+            state: hashmap.remove("state"),
+            first_name: hashmap.remove("first_name"),
+            last_name: hashmap.remove("last_name"),
+            phone_number: hashmap.remove("phone_number"),
+            email: hashmap.remove("email").map(|email| {
+                let encryptable: Encryptable<Secret<String, EmailStrategy>> = Encryptable::new(
+                    email.clone().into_inner().switch_strategy(),
+                    email.into_encrypted(),
+                );
+                encryptable
+            }),
+        })
+    }
+}
+
 #[derive(Clone, Debug, AsChangeset, router_derive::DebugAsDisplay, Serialize, Deserialize)]
 #[diesel(table_name = address)]
 pub struct AddressUpdateInternal {
diff --git a/crates/diesel_models/src/business_profile.rs b/crates/diesel_models/src/business_profile.rs
index 6bd1e1f9e41..b964b290a9e 100644
--- a/crates/diesel_models/src/business_profile.rs
+++ b/crates/diesel_models/src/business_profile.rs
@@ -1,7 +1,7 @@
-use common_utils::pii;
+use common_utils::{encryption::Encryption, pii};
 use diesel::{AsChangeset, Identifiable, Insertable, Queryable, Selectable};
 
-use crate::{encryption::Encryption, schema::business_profile};
+use crate::schema::business_profile;
 
 #[derive(
     Clone,
diff --git a/crates/diesel_models/src/customers.rs b/crates/diesel_models/src/customers.rs
index deb1ac73f41..302772b7f9e 100644
--- a/crates/diesel_models/src/customers.rs
+++ b/crates/diesel_models/src/customers.rs
@@ -1,8 +1,8 @@
-use common_utils::{id_type, pii};
+use common_utils::{encryption::Encryption, id_type, pii};
 use diesel::{AsChangeset, Identifiable, Insertable, Queryable, Selectable};
 use time::PrimitiveDateTime;
 
-use crate::{encryption::Encryption, schema::customers};
+use crate::schema::customers;
 
 #[derive(
     Clone, Debug, Insertable, router_derive::DebugAsDisplay, serde::Deserialize, serde::Serialize,
diff --git a/crates/diesel_models/src/events.rs b/crates/diesel_models/src/events.rs
index b3b1230441f..99879dafaf9 100644
--- a/crates/diesel_models/src/events.rs
+++ b/crates/diesel_models/src/events.rs
@@ -1,11 +1,15 @@
-use common_utils::custom_serde;
+use common_utils::{
+    crypto::OptionalEncryptableSecretString, custom_serde, encryption::Encryption,
+    types::keymanager::ToEncryptable,
+};
 use diesel::{
     expression::AsExpression, AsChangeset, Identifiable, Insertable, Queryable, Selectable,
 };
+use masking::Secret;
 use serde::{Deserialize, Serialize};
 use time::PrimitiveDateTime;
 
-use crate::{encryption::Encryption, enums as storage_enums, schema::events};
+use crate::{enums as storage_enums, schema::events};
 
 #[derive(Clone, Debug, Insertable, router_derive::DebugAsDisplay)]
 #[diesel(table_name = events)]
@@ -59,6 +63,38 @@ pub struct Event {
     pub metadata: Option<EventMetadata>,
 }
 
+pub struct EventWithEncryption {
+    pub request: Option<Encryption>,
+    pub response: Option<Encryption>,
+}
+
+pub struct EncryptableEvent {
+    pub request: OptionalEncryptableSecretString,
+    pub response: OptionalEncryptableSecretString,
+}
+
+impl ToEncryptable<EncryptableEvent, Secret<String>, Encryption> for EventWithEncryption {
+    fn to_encryptable(self) -> rustc_hash::FxHashMap<String, Encryption> {
+        let mut map = rustc_hash::FxHashMap::default();
+        self.request.map(|x| map.insert("request".to_string(), x));
+        self.response.map(|x| map.insert("response".to_string(), x));
+        map
+    }
+
+    fn from_encryptable(
+        mut hashmap: rustc_hash::FxHashMap<
+            String,
+            common_utils::crypto::Encryptable<Secret<String>>,
+        >,
+    ) -> common_utils::errors::CustomResult<EncryptableEvent, common_utils::errors::ParsingError>
+    {
+        Ok(EncryptableEvent {
+            request: hashmap.remove("request"),
+            response: hashmap.remove("response"),
+        })
+    }
+}
+
 #[derive(Clone, Debug, Deserialize, Serialize, AsExpression, diesel::FromSqlRow)]
 #[diesel(sql_type = diesel::sql_types::Jsonb)]
 pub enum EventMetadata {
diff --git a/crates/diesel_models/src/lib.rs b/crates/diesel_models/src/lib.rs
index 67061bf6c33..6af1e0e5208 100644
--- a/crates/diesel_models/src/lib.rs
+++ b/crates/diesel_models/src/lib.rs
@@ -12,7 +12,6 @@ pub mod blocklist;
 pub mod blocklist_fingerprint;
 pub mod customers;
 pub mod dispute;
-pub mod encryption;
 pub mod enums;
 pub mod ephemeral_key;
 pub mod errors;
diff --git a/crates/diesel_models/src/merchant_account.rs b/crates/diesel_models/src/merchant_account.rs
index 71c437bbb41..5c48ade55c0 100644
--- a/crates/diesel_models/src/merchant_account.rs
+++ b/crates/diesel_models/src/merchant_account.rs
@@ -1,7 +1,7 @@
-use common_utils::pii;
+use common_utils::{encryption::Encryption, pii};
 use diesel::{AsChangeset, Identifiable, Insertable, Queryable, Selectable};
 
-use crate::{encryption::Encryption, enums as storage_enums, schema::merchant_account};
+use crate::{enums as storage_enums, schema::merchant_account};
 
 #[derive(
     Clone,
diff --git a/crates/diesel_models/src/merchant_connector_account.rs b/crates/diesel_models/src/merchant_connector_account.rs
index 05707f71737..5a549892dca 100644
--- a/crates/diesel_models/src/merchant_connector_account.rs
+++ b/crates/diesel_models/src/merchant_connector_account.rs
@@ -1,10 +1,10 @@
 use std::fmt::Debug;
 
-use common_utils::pii;
+use common_utils::{encryption::Encryption, pii};
 use diesel::{AsChangeset, Identifiable, Insertable, Queryable, Selectable};
 use masking::Secret;
 
-use crate::{encryption::Encryption, enums as storage_enums, schema::merchant_connector_account};
+use crate::{enums as storage_enums, schema::merchant_connector_account};
 
 #[derive(
     Clone,
diff --git a/crates/diesel_models/src/merchant_key_store.rs b/crates/diesel_models/src/merchant_key_store.rs
index 30781927e94..b11d9970532 100644
--- a/crates/diesel_models/src/merchant_key_store.rs
+++ b/crates/diesel_models/src/merchant_key_store.rs
@@ -1,8 +1,8 @@
-use common_utils::custom_serde;
+use common_utils::{custom_serde, encryption::Encryption};
 use diesel::{AsChangeset, Identifiable, Insertable, Queryable, Selectable};
 use time::PrimitiveDateTime;
 
-use crate::{encryption::Encryption, schema::merchant_key_store};
+use crate::schema::merchant_key_store;
 
 #[derive(
     Clone,
diff --git a/crates/diesel_models/src/payment_intent.rs b/crates/diesel_models/src/payment_intent.rs
index 499d72a648a..e4d8dcc315a 100644
--- a/crates/diesel_models/src/payment_intent.rs
+++ b/crates/diesel_models/src/payment_intent.rs
@@ -1,10 +1,10 @@
 use common_enums::RequestIncrementalAuthorization;
-use common_utils::{id_type, pii, types::MinorUnit};
+use common_utils::{encryption::Encryption, id_type, pii, types::MinorUnit};
 use diesel::{AsChangeset, Identifiable, Insertable, Queryable, Selectable};
 use serde::{Deserialize, Serialize};
 use time::PrimitiveDateTime;
 
-use crate::{encryption::Encryption, enums as storage_enums, schema::payment_intent};
+use crate::{enums as storage_enums, schema::payment_intent};
 
 #[derive(Clone, Debug, PartialEq, Identifiable, Queryable, Selectable, Serialize, Deserialize)]
 #[diesel(table_name = payment_intent, primary_key(payment_id, merchant_id), check_for_backend(diesel::pg::Pg))]
diff --git a/crates/diesel_models/src/payment_method.rs b/crates/diesel_models/src/payment_method.rs
index a9db90abb20..6bb40e4b166 100644
--- a/crates/diesel_models/src/payment_method.rs
+++ b/crates/diesel_models/src/payment_method.rs
@@ -1,11 +1,11 @@
 use common_enums::MerchantStorageScheme;
-use common_utils::{id_type, pii};
+use common_utils::{encryption::Encryption, id_type, pii};
 use diesel::{AsChangeset, Identifiable, Insertable, Queryable, Selectable};
 use masking::Secret;
 use serde::{Deserialize, Serialize};
 use time::PrimitiveDateTime;
 
-use crate::{encryption::Encryption, enums as storage_enums, schema::payment_methods};
+use crate::{enums as storage_enums, schema::payment_methods};
 
 #[derive(
     Clone, Debug, Eq, PartialEq, Identifiable, Queryable, Selectable, Serialize, Deserialize,
diff --git a/crates/diesel_models/src/user.rs b/crates/diesel_models/src/user.rs
index 56c6f00f2b0..9d6514916d8 100644
--- a/crates/diesel_models/src/user.rs
+++ b/crates/diesel_models/src/user.rs
@@ -1,11 +1,9 @@
-use common_utils::pii;
+use common_utils::{encryption::Encryption, pii};
 use diesel::{AsChangeset, Identifiable, Insertable, Queryable, Selectable};
 use masking::Secret;
 use time::PrimitiveDateTime;
 
-use crate::{
-    diesel_impl::OptionalDieselArray, encryption::Encryption, enums::TotpStatus, schema::users,
-};
+use crate::{diesel_impl::OptionalDieselArray, enums::TotpStatus, schema::users};
 
 pub mod dashboard_metadata;
 
diff --git a/crates/diesel_models/src/user_authentication_method.rs b/crates/diesel_models/src/user_authentication_method.rs
index 18a65b9f104..76e1abe7575 100644
--- a/crates/diesel_models/src/user_authentication_method.rs
+++ b/crates/diesel_models/src/user_authentication_method.rs
@@ -1,7 +1,8 @@
+use common_utils::encryption::Encryption;
 use diesel::{AsChangeset, Identifiable, Insertable, Queryable, Selectable};
 use time::PrimitiveDateTime;
 
-use crate::{encryption::Encryption, enums, schema::user_authentication_methods};
+use crate::{enums, schema::user_authentication_methods};
 
 #[derive(Clone, Debug, Identifiable, Queryable, Selectable)]
 #[diesel(table_name = user_authentication_methods, check_for_backend(diesel::pg::Pg))]
diff --git a/crates/diesel_models/src/user_key_store.rs b/crates/diesel_models/src/user_key_store.rs
index 1b19ef31a49..4d880ebf8f9 100644
--- a/crates/diesel_models/src/user_key_store.rs
+++ b/crates/diesel_models/src/user_key_store.rs
@@ -1,7 +1,8 @@
+use common_utils::encryption::Encryption;
 use diesel::{Identifiable, Insertable, Queryable, Selectable};
 use time::PrimitiveDateTime;
 
-use crate::{encryption::Encryption, schema::user_key_store};
+use crate::schema::user_key_store;
 
 #[derive(
     Clone, Debug, serde::Serialize, serde::Deserialize, Identifiable, Queryable, Selectable,
diff --git a/crates/hyperswitch_domain_models/Cargo.toml b/crates/hyperswitch_domain_models/Cargo.toml
index ab569464684..310c2731b42 100644
--- a/crates/hyperswitch_domain_models/Cargo.toml
+++ b/crates/hyperswitch_domain_models/Cargo.toml
@@ -9,6 +9,7 @@ license.workspace = true
 
 [features]
 default = ["olap", "payouts", "frm"]
+encryption_service =[]
 olap = []
 payouts = ["api_models/payouts"]
 frm = ["api_models/frm"]
@@ -18,7 +19,7 @@ frm = ["api_models/frm"]
 api_models = { version = "0.1.0", path = "../api_models", features = ["errors"] }
 cards = { version = "0.1.0", path = "../cards" }
 common_enums = { version = "0.1.0", path = "../common_enums" }
-common_utils = { version = "0.1.0", path = "../common_utils", features = ["async_ext", "metrics"] }
+common_utils = { version = "0.1.0", path = "../common_utils", features = ["async_ext", "metrics",  "encryption_service", "keymanager"] }
 diesel_models = { version = "0.1.0", path = "../diesel_models", features = ["kv_store"] }
 masking = { version = "0.1.0", path = "../masking" }
 router_derive = { version = "0.1.0", path = "../router_derive" }
@@ -31,6 +32,7 @@ error-stack = "0.4.1"
 futures = "0.3.30"
 http = "0.2.12"
 mime = "0.3.17"
+rustc-hash = "1.1.0"
 serde = { version = "1.0.197", features = ["derive"] }
 serde_json = "1.0.115"
 serde_with = "3.7.0"
diff --git a/crates/hyperswitch_domain_models/src/behaviour.rs b/crates/hyperswitch_domain_models/src/behaviour.rs
index 9976dd25a98..07911e8ea69 100644
--- a/crates/hyperswitch_domain_models/src/behaviour.rs
+++ b/crates/hyperswitch_domain_models/src/behaviour.rs
@@ -1,4 +1,7 @@
-use common_utils::errors::{CustomResult, ValidationError};
+use common_utils::{
+    errors::{CustomResult, ValidationError},
+    types::keymanager::KeyManagerState,
+};
 use masking::Secret;
 
 /// Trait for converting domain types to storage models
@@ -9,8 +12,10 @@ pub trait Conversion {
     async fn convert(self) -> CustomResult<Self::DstType, ValidationError>;
 
     async fn convert_back(
+        state: &KeyManagerState,
         item: Self::DstType,
         key: &Secret<Vec<u8>>,
+        key_store_ref_id: String,
     ) -> CustomResult<Self, ValidationError>
     where
         Self: Sized;
@@ -20,12 +25,22 @@ pub trait Conversion {
 
 #[async_trait::async_trait]
 pub trait ReverseConversion<SrcType: Conversion> {
-    async fn convert(self, key: &Secret<Vec<u8>>) -> CustomResult<SrcType, ValidationError>;
+    async fn convert(
+        self,
+        state: &KeyManagerState,
+        key: &Secret<Vec<u8>>,
+        key_store_ref_id: String,
+    ) -> CustomResult<SrcType, ValidationError>;
 }
 
 #[async_trait::async_trait]
 impl<T: Send, U: Conversion<DstType = T>> ReverseConversion<U> for T {
-    async fn convert(self, key: &Secret<Vec<u8>>) -> CustomResult<U, ValidationError> {
-        U::convert_back(self, key).await
+    async fn convert(
+        self,
+        state: &KeyManagerState,
+        key: &Secret<Vec<u8>>,
+        key_store_ref_id: String,
+    ) -> CustomResult<U, ValidationError> {
+        U::convert_back(state, self, key, key_store_ref_id).await
     }
 }
diff --git a/crates/hyperswitch_domain_models/src/merchant_account.rs b/crates/hyperswitch_domain_models/src/merchant_account.rs
index e42f21dc7c7..a430673c59a 100644
--- a/crates/hyperswitch_domain_models/src/merchant_account.rs
+++ b/crates/hyperswitch_domain_models/src/merchant_account.rs
@@ -1,13 +1,14 @@
 use common_utils::{
     crypto::{OptionalEncryptableName, OptionalEncryptableValue},
     date_time,
+    encryption::Encryption,
     errors::{CustomResult, ValidationError},
     ext_traits::ValueExt,
     pii,
+    types::keymanager,
 };
 use diesel_models::{
-    encryption::Encryption, enums::MerchantStorageScheme,
-    merchant_account::MerchantAccountUpdateInternal,
+    enums::MerchantStorageScheme, merchant_account::MerchantAccountUpdateInternal,
 };
 use error_stack::ResultExt;
 use masking::{PeekInterface, Secret};
@@ -195,8 +196,10 @@ impl super::behaviour::Conversion for MerchantAccount {
     }
 
     async fn convert_back(
+        state: &keymanager::KeyManagerState,
         item: Self::DstType,
         key: &Secret<Vec<u8>>,
+        key_store_ref_id: String,
     ) -> CustomResult<Self, ValidationError>
     where
         Self: Sized,
@@ -206,7 +209,7 @@ impl super::behaviour::Conversion for MerchantAccount {
                 .ok_or(ValidationError::MissingRequiredField {
                     field_name: "publishable_key".to_string(),
                 })?;
-
+        let identifier = keymanager::Identifier::Merchant(key_store_ref_id.clone());
         async {
             Ok::<Self, error_stack::Report<common_utils::errors::CryptoError>>(Self {
                 id: Some(item.id),
@@ -217,11 +220,11 @@ impl super::behaviour::Conversion for MerchantAccount {
                 redirect_to_merchant_with_http_post: item.redirect_to_merchant_with_http_post,
                 merchant_name: item
                     .merchant_name
-                    .async_lift(|inner| decrypt(inner, key.peek()))
+                    .async_lift(|inner| decrypt(state, inner, identifier.clone(), key.peek()))
                     .await?,
                 merchant_details: item
                     .merchant_details
-                    .async_lift(|inner| decrypt(inner, key.peek()))
+                    .async_lift(|inner| decrypt(state, inner, identifier.clone(), key.peek()))
                     .await?,
                 webhook_details: item.webhook_details,
                 sub_merchants_enabled: item.sub_merchants_enabled,
diff --git a/crates/hyperswitch_domain_models/src/merchant_key_store.rs b/crates/hyperswitch_domain_models/src/merchant_key_store.rs
index 29050b7eb49..76acf0f1404 100644
--- a/crates/hyperswitch_domain_models/src/merchant_key_store.rs
+++ b/crates/hyperswitch_domain_models/src/merchant_key_store.rs
@@ -2,6 +2,7 @@ use common_utils::{
     crypto::{Encryptable, GcmAes256},
     custom_serde, date_time,
     errors::{CustomResult, ValidationError},
+    types::keymanager::{Identifier, KeyManagerState},
 };
 use error_stack::ResultExt;
 use masking::{PeekInterface, Secret};
@@ -30,14 +31,17 @@ impl super::behaviour::Conversion for MerchantKeyStore {
     }
 
     async fn convert_back(
+        state: &KeyManagerState,
         item: Self::DstType,
         key: &Secret<Vec<u8>>,
+        _key_store_ref_id: String,
     ) -> CustomResult<Self, ValidationError>
     where
         Self: Sized,
     {
+        let identifier = Identifier::Merchant(item.merchant_id.clone());
         Ok(Self {
-            key: Encryptable::decrypt(item.key, key.peek(), GcmAes256)
+            key: Encryptable::decrypt_via_api(state, item.key, identifier, key.peek(), GcmAes256)
                 .await
                 .change_context(ValidationError::InvalidValue {
                     message: "Failed while decrypting customer data".to_string(),
diff --git a/crates/hyperswitch_domain_models/src/payments/payment_attempt.rs b/crates/hyperswitch_domain_models/src/payments/payment_attempt.rs
index 6ff74a95e46..5f8dd3934a2 100644
--- a/crates/hyperswitch_domain_models/src/payments/payment_attempt.rs
+++ b/crates/hyperswitch_domain_models/src/payments/payment_attempt.rs
@@ -1,9 +1,10 @@
 use api_models::enums::Connector;
 use common_enums as storage_enums;
 use common_utils::{
+    encryption::Encryption,
     errors::{CustomResult, ValidationError},
     pii,
-    types::MinorUnit,
+    types::{keymanager::KeyManagerState, MinorUnit},
 };
 use error_stack::ResultExt;
 use masking::PeekInterface;
@@ -479,8 +480,7 @@ impl ForeignIDRef for PaymentAttempt {
 }
 
 use diesel_models::{
-    encryption::Encryption, PaymentIntent as DieselPaymentIntent,
-    PaymentIntentNew as DieselPaymentIntentNew,
+    PaymentIntent as DieselPaymentIntent, PaymentIntentNew as DieselPaymentIntentNew,
 };
 
 #[async_trait::async_trait]
@@ -542,14 +542,23 @@ impl behaviour::Conversion for PaymentIntent {
     }
 
     async fn convert_back(
+        state: &KeyManagerState,
         storage_model: Self::DstType,
         key: &masking::Secret<Vec<u8>>,
+        key_store_ref_id: String,
     ) -> CustomResult<Self, ValidationError>
     where
         Self: Sized,
     {
         async {
-            let inner_decrypt = |inner| decrypt(inner, key.peek());
+            let inner_decrypt = |inner| {
+                decrypt(
+                    state,
+                    inner,
+                    common_utils::types::keymanager::Identifier::Merchant(key_store_ref_id.clone()),
+                    key.peek(),
+                )
+            };
             Ok::<Self, error_stack::Report<common_utils::errors::CryptoError>>(Self {
                 payment_id: storage_model.payment_id,
                 merchant_id: storage_model.merchant_id,
diff --git a/crates/hyperswitch_domain_models/src/payments/payment_intent.rs b/crates/hyperswitch_domain_models/src/payments/payment_intent.rs
index 6eb35616729..f4f6be97055 100644
--- a/crates/hyperswitch_domain_models/src/payments/payment_intent.rs
+++ b/crates/hyperswitch_domain_models/src/payments/payment_intent.rs
@@ -2,9 +2,10 @@ use common_enums as storage_enums;
 use common_utils::{
     consts::{PAYMENTS_LIST_MAX_LIMIT_V1, PAYMENTS_LIST_MAX_LIMIT_V2},
     crypto::Encryptable,
+    encryption::Encryption,
     id_type,
     pii::{self, Email},
-    types::MinorUnit,
+    types::{keymanager::KeyManagerState, MinorUnit},
 };
 use masking::{Deserialize, Secret};
 use serde::Serialize;
@@ -16,6 +17,7 @@ use crate::{errors, merchant_key_store::MerchantKeyStore, RemoteStorageObject};
 pub trait PaymentIntentInterface {
     async fn update_payment_intent(
         &self,
+        state: &KeyManagerState,
         this: PaymentIntent,
         payment_intent: PaymentIntentUpdate,
         merchant_key_store: &MerchantKeyStore,
@@ -24,6 +26,7 @@ pub trait PaymentIntentInterface {
 
     async fn insert_payment_intent(
         &self,
+        state: &KeyManagerState,
         new: PaymentIntent,
         merchant_key_store: &MerchantKeyStore,
         storage_scheme: storage_enums::MerchantStorageScheme,
@@ -31,6 +34,7 @@ pub trait PaymentIntentInterface {
 
     async fn find_payment_intent_by_payment_id_merchant_id(
         &self,
+        state: &KeyManagerState,
         payment_id: &str,
         merchant_id: &str,
         merchant_key_store: &MerchantKeyStore,
@@ -46,6 +50,7 @@ pub trait PaymentIntentInterface {
     #[cfg(feature = "olap")]
     async fn filter_payment_intent_by_constraints(
         &self,
+        state: &KeyManagerState,
         merchant_id: &str,
         filters: &PaymentIntentFetchConstraints,
         merchant_key_store: &MerchantKeyStore,
@@ -55,6 +60,7 @@ pub trait PaymentIntentInterface {
     #[cfg(feature = "olap")]
     async fn filter_payment_intents_by_time_range_constraints(
         &self,
+        state: &KeyManagerState,
         merchant_id: &str,
         time_range: &api_models::payments::TimeRange,
         merchant_key_store: &MerchantKeyStore,
@@ -64,6 +70,7 @@ pub trait PaymentIntentInterface {
     #[cfg(feature = "olap")]
     async fn get_filtered_payment_intents_attempt(
         &self,
+        state: &KeyManagerState,
         merchant_id: &str,
         constraints: &PaymentIntentFetchConstraints,
         merchant_key_store: &MerchantKeyStore,
@@ -467,7 +474,7 @@ impl From<PaymentIntentUpdate> for PaymentIntentUpdateInternal {
 }
 
 use diesel_models::{
-    encryption::Encryption, PaymentIntentUpdate as DieselPaymentIntentUpdate,
+    PaymentIntentUpdate as DieselPaymentIntentUpdate,
     PaymentIntentUpdateFields as DieselPaymentIntentUpdateFields,
 };
 
diff --git a/crates/hyperswitch_domain_models/src/type_encryption.rs b/crates/hyperswitch_domain_models/src/type_encryption.rs
index 82d904ccf49..d656afc9251 100644
--- a/crates/hyperswitch_domain_models/src/type_encryption.rs
+++ b/crates/hyperswitch_domain_models/src/type_encryption.rs
@@ -1,14 +1,30 @@
 use async_trait::async_trait;
 use common_utils::{
     crypto,
+    encryption::Encryption,
     errors::{self, CustomResult},
     ext_traits::AsyncExt,
     metrics::utils::record_operation_time,
+    types::keymanager::{Identifier, KeyManagerState},
 };
-use diesel_models::encryption::Encryption;
 use error_stack::ResultExt;
 use masking::{PeekInterface, Secret};
 use router_env::{instrument, tracing};
+use rustc_hash::FxHashMap;
+#[cfg(feature = "encryption_service")]
+use {
+    common_utils::{
+        keymanager::call_encryption_service,
+        transformers::{ForeignFrom, ForeignTryFrom},
+        types::keymanager::{
+            BatchDecryptDataResponse, BatchEncryptDataRequest, BatchEncryptDataResponse,
+            DecryptDataResponse, EncryptDataRequest, EncryptDataResponse,
+            TransientBatchDecryptDataRequest, TransientDecryptDataRequest,
+        },
+    },
+    http::Method,
+    router_env::logger,
+};
 
 #[async_trait]
 pub trait TypeEncryption<
@@ -17,6 +33,22 @@ pub trait TypeEncryption<
     S: masking::Strategy<T>,
 >: Sized
 {
+    async fn encrypt_via_api(
+        state: &KeyManagerState,
+        masked_data: Secret<T, S>,
+        identifier: Identifier,
+        key: &[u8],
+        crypt_algo: V,
+    ) -> CustomResult<Self, errors::CryptoError>;
+
+    async fn decrypt_via_api(
+        state: &KeyManagerState,
+        encrypted_data: Encryption,
+        identifier: Identifier,
+        key: &[u8],
+        crypt_algo: V,
+    ) -> CustomResult<Self, errors::CryptoError>;
+
     async fn encrypt(
         masked_data: Secret<T, S>,
         key: &[u8],
@@ -28,31 +60,141 @@ pub trait TypeEncryption<
         key: &[u8],
         crypt_algo: V,
     ) -> CustomResult<Self, errors::CryptoError>;
+
+    async fn batch_encrypt_via_api(
+        state: &KeyManagerState,
+        masked_data: FxHashMap<String, Secret<T, S>>,
+        identifier: Identifier,
+        key: &[u8],
+        crypt_algo: V,
+    ) -> CustomResult<FxHashMap<String, Self>, errors::CryptoError>;
+
+    async fn batch_decrypt_via_api(
+        state: &KeyManagerState,
+        encrypted_data: FxHashMap<String, Encryption>,
+        identifier: Identifier,
+        key: &[u8],
+        crypt_algo: V,
+    ) -> CustomResult<FxHashMap<String, Self>, errors::CryptoError>;
+
+    async fn batch_encrypt(
+        masked_data: FxHashMap<String, Secret<T, S>>,
+        key: &[u8],
+        crypt_algo: V,
+    ) -> CustomResult<FxHashMap<String, Self>, errors::CryptoError>;
+
+    async fn batch_decrypt(
+        encrypted_data: FxHashMap<String, Encryption>,
+        key: &[u8],
+        crypt_algo: V,
+    ) -> CustomResult<FxHashMap<String, Self>, errors::CryptoError>;
 }
 
 #[async_trait]
 impl<
         V: crypto::DecodeMessage + crypto::EncodeMessage + Send + 'static,
-        S: masking::Strategy<String> + Send,
+        S: masking::Strategy<String> + Send + Sync,
     > TypeEncryption<String, V, S> for crypto::Encryptable<Secret<String, S>>
 {
     #[instrument(skip_all)]
+    #[allow(unused_variables)]
+    async fn encrypt_via_api(
+        state: &KeyManagerState,
+        masked_data: Secret<String, S>,
+        identifier: Identifier,
+        key: &[u8],
+        crypt_algo: V,
+    ) -> CustomResult<Self, errors::CryptoError> {
+        #[cfg(not(feature = "encryption_service"))]
+        {
+            Self::encrypt(masked_data, key, crypt_algo).await
+        }
+        #[cfg(feature = "encryption_service")]
+        {
+            let result: Result<
+                EncryptDataResponse,
+                error_stack::Report<errors::KeyManagerClientError>,
+            > = call_encryption_service(
+                state,
+                Method::POST,
+                "data/encrypt",
+                EncryptDataRequest::from((masked_data.clone(), identifier)),
+            )
+            .await;
+            match result {
+                Ok(response) => Ok(ForeignFrom::foreign_from((masked_data.clone(), response))),
+                Err(err) => {
+                    logger::error!("Encryption error {:?}", err);
+                    metrics::ENCRYPTION_API_FAILURES.add(&metrics::CONTEXT, 1, &[]);
+                    logger::info!("Fall back to Application Encryption");
+                    Self::encrypt(masked_data, key, crypt_algo).await
+                }
+            }
+        }
+    }
+
+    #[instrument(skip_all)]
+    #[allow(unused_variables)]
+    async fn decrypt_via_api(
+        state: &KeyManagerState,
+        encrypted_data: Encryption,
+        identifier: Identifier,
+        key: &[u8],
+        crypt_algo: V,
+    ) -> CustomResult<Self, errors::CryptoError> {
+        #[cfg(not(feature = "encryption_service"))]
+        {
+            Self::decrypt(encrypted_data, key, crypt_algo).await
+        }
+        #[cfg(feature = "encryption_service")]
+        {
+            let result: Result<
+                DecryptDataResponse,
+                error_stack::Report<errors::KeyManagerClientError>,
+            > = call_encryption_service(
+                state,
+                Method::POST,
+                "data/decrypt",
+                TransientDecryptDataRequest::from((encrypted_data.clone(), identifier)),
+            )
+            .await;
+            let decrypted = match result {
+                Ok(decrypted_data) => {
+                    ForeignTryFrom::foreign_try_from((encrypted_data.clone(), decrypted_data))
+                }
+                Err(err) => {
+                    logger::error!("Decryption error {:?}", err);
+                    Err(err.change_context(errors::CryptoError::DecodingFailed))
+                }
+            };
+
+            match decrypted {
+                Ok(de) => Ok(de),
+                Err(_) => {
+                    metrics::DECRYPTION_API_FAILURES.add(&metrics::CONTEXT, 1, &[]);
+                    logger::info!("Fall back to Application Decryption");
+                    Self::decrypt(encrypted_data, key, crypt_algo).await
+                }
+            }
+        }
+    }
+
     async fn encrypt(
         masked_data: Secret<String, S>,
         key: &[u8],
         crypt_algo: V,
     ) -> CustomResult<Self, errors::CryptoError> {
+        metrics::APPLICATION_ENCRYPTION_COUNT.add(&metrics::CONTEXT, 1, &[]);
         let encrypted_data = crypt_algo.encode_message(key, masked_data.peek().as_bytes())?;
-
         Ok(Self::new(masked_data, encrypted_data.into()))
     }
 
-    #[instrument(skip_all)]
     async fn decrypt(
         encrypted_data: Encryption,
         key: &[u8],
         crypt_algo: V,
     ) -> CustomResult<Self, errors::CryptoError> {
+        metrics::APPLICATION_DECRYPTION_COUNT.add(&metrics::CONTEXT, 1, &[]);
         let encrypted = encrypted_data.into_inner();
         let data = crypt_algo.decode_message(key, encrypted.clone())?;
 
@@ -62,25 +204,227 @@ impl<
 
         Ok(Self::new(value.into(), encrypted))
     }
+
+    #[allow(unused_variables)]
+    async fn batch_encrypt_via_api(
+        state: &KeyManagerState,
+        masked_data: FxHashMap<String, Secret<String, S>>,
+        identifier: Identifier,
+        key: &[u8],
+        crypt_algo: V,
+    ) -> CustomResult<FxHashMap<String, Self>, errors::CryptoError> {
+        #[cfg(not(feature = "encryption_service"))]
+        {
+            Self::batch_encrypt(masked_data, key, crypt_algo).await
+        }
+
+        #[cfg(feature = "encryption_service")]
+        {
+            let result: Result<
+                BatchEncryptDataResponse,
+                error_stack::Report<errors::KeyManagerClientError>,
+            > = call_encryption_service(
+                state,
+                Method::POST,
+                "data/encrypt",
+                BatchEncryptDataRequest::from((masked_data.clone(), identifier)),
+            )
+            .await;
+            match result {
+                Ok(response) => Ok(ForeignFrom::foreign_from((masked_data, response))),
+                Err(err) => {
+                    metrics::ENCRYPTION_API_FAILURES.add(&metrics::CONTEXT, 1, &[]);
+                    logger::error!("Encryption error {:?}", err);
+                    logger::info!("Fall back to Application Encryption");
+                    Self::batch_encrypt(masked_data, key, crypt_algo).await
+                }
+            }
+        }
+    }
+
+    #[allow(unused_variables)]
+    async fn batch_decrypt_via_api(
+        state: &KeyManagerState,
+        encrypted_data: FxHashMap<String, Encryption>,
+        identifier: Identifier,
+        key: &[u8],
+        crypt_algo: V,
+    ) -> CustomResult<FxHashMap<String, Self>, errors::CryptoError> {
+        #[cfg(not(feature = "encryption_service"))]
+        {
+            Self::batch_decrypt(encrypted_data, key, crypt_algo).await
+        }
+
+        #[cfg(feature = "encryption_service")]
+        {
+            let result: Result<
+                BatchDecryptDataResponse,
+                error_stack::Report<errors::KeyManagerClientError>,
+            > = call_encryption_service(
+                state,
+                Method::POST,
+                "data/decrypt",
+                TransientBatchDecryptDataRequest::from((encrypted_data.clone(), identifier)),
+            )
+            .await;
+            let decrypted = match result {
+                Ok(decrypted_data) => {
+                    ForeignTryFrom::foreign_try_from((encrypted_data.clone(), decrypted_data))
+                }
+                Err(err) => {
+                    logger::error!("Decryption error {:?}", err);
+                    Err(err.change_context(errors::CryptoError::DecodingFailed))
+                }
+            };
+            match decrypted {
+                Ok(de) => Ok(de),
+                Err(_) => {
+                    metrics::DECRYPTION_API_FAILURES.add(&metrics::CONTEXT, 1, &[]);
+                    logger::info!("Fall back to Application Decryption");
+                    Self::batch_decrypt(encrypted_data, key, crypt_algo).await
+                }
+            }
+        }
+    }
+
+    async fn batch_encrypt(
+        masked_data: FxHashMap<String, Secret<String, S>>,
+        key: &[u8],
+        crypt_algo: V,
+    ) -> CustomResult<FxHashMap<String, Self>, errors::CryptoError> {
+        metrics::APPLICATION_ENCRYPTION_COUNT.add(&metrics::CONTEXT, 1, &[]);
+        masked_data
+            .into_iter()
+            .map(|(k, v)| {
+                Ok((
+                    k,
+                    Self::new(
+                        v.clone(),
+                        crypt_algo.encode_message(key, v.peek().as_bytes())?.into(),
+                    ),
+                ))
+            })
+            .collect()
+    }
+
+    async fn batch_decrypt(
+        encrypted_data: FxHashMap<String, Encryption>,
+        key: &[u8],
+        crypt_algo: V,
+    ) -> CustomResult<FxHashMap<String, Self>, errors::CryptoError> {
+        metrics::APPLICATION_DECRYPTION_COUNT.add(&metrics::CONTEXT, 1, &[]);
+        encrypted_data
+            .into_iter()
+            .map(|(k, v)| {
+                let data = crypt_algo.decode_message(key, v.clone().into_inner())?;
+                let value: String = std::str::from_utf8(&data)
+                    .change_context(errors::CryptoError::DecodingFailed)?
+                    .to_string();
+                Ok((k, Self::new(value.into(), v.into_inner())))
+            })
+            .collect()
+    }
 }
 
 #[async_trait]
 impl<
         V: crypto::DecodeMessage + crypto::EncodeMessage + Send + 'static,
-        S: masking::Strategy<serde_json::Value> + Send,
+        S: masking::Strategy<serde_json::Value> + Send + Sync,
     > TypeEncryption<serde_json::Value, V, S>
     for crypto::Encryptable<Secret<serde_json::Value, S>>
 {
+    #[instrument(skip_all)]
+    #[allow(unused_variables)]
+    async fn encrypt_via_api(
+        state: &KeyManagerState,
+        masked_data: Secret<serde_json::Value, S>,
+        identifier: Identifier,
+        key: &[u8],
+        crypt_algo: V,
+    ) -> CustomResult<Self, errors::CryptoError> {
+        #[cfg(not(feature = "encryption_service"))]
+        {
+            Self::encrypt(masked_data, key, crypt_algo).await
+        }
+        #[cfg(feature = "encryption_service")]
+        {
+            let result: Result<
+                EncryptDataResponse,
+                error_stack::Report<errors::KeyManagerClientError>,
+            > = call_encryption_service(
+                state,
+                Method::POST,
+                "data/encrypt",
+                EncryptDataRequest::from((masked_data.clone(), identifier)),
+            )
+            .await;
+            match result {
+                Ok(response) => Ok(ForeignFrom::foreign_from((masked_data.clone(), response))),
+                Err(err) => {
+                    logger::error!("Encryption error {:?}", err);
+                    metrics::ENCRYPTION_API_FAILURES.add(&metrics::CONTEXT, 1, &[]);
+                    logger::info!("Fall back to Application Encryption");
+                    Self::encrypt(masked_data, key, crypt_algo).await
+                }
+            }
+        }
+    }
+
+    #[instrument(skip_all)]
+    #[allow(unused_variables)]
+    async fn decrypt_via_api(
+        state: &KeyManagerState,
+        encrypted_data: Encryption,
+        identifier: Identifier,
+        key: &[u8],
+        crypt_algo: V,
+    ) -> CustomResult<Self, errors::CryptoError> {
+        #[cfg(not(feature = "encryption_service"))]
+        {
+            Self::decrypt(encrypted_data, key, crypt_algo).await
+        }
+        #[cfg(feature = "encryption_service")]
+        {
+            let result: Result<
+                DecryptDataResponse,
+                error_stack::Report<errors::KeyManagerClientError>,
+            > = call_encryption_service(
+                state,
+                Method::POST,
+                "data/decrypt",
+                TransientDecryptDataRequest::from((encrypted_data.clone(), identifier)),
+            )
+            .await;
+            let decrypted = match result {
+                Ok(decrypted_data) => {
+                    ForeignTryFrom::foreign_try_from((encrypted_data.clone(), decrypted_data))
+                }
+                Err(err) => {
+                    logger::error!("Decryption error {:?}", err);
+                    Err(err.change_context(errors::CryptoError::EncodingFailed))
+                }
+            };
+            match decrypted {
+                Ok(de) => Ok(de),
+                Err(_) => {
+                    metrics::DECRYPTION_API_FAILURES.add(&metrics::CONTEXT, 1, &[]);
+                    logger::info!("Fall back to Application Decryption");
+                    Self::decrypt(encrypted_data, key, crypt_algo).await
+                }
+            }
+        }
+    }
+
     #[instrument(skip_all)]
     async fn encrypt(
         masked_data: Secret<serde_json::Value, S>,
         key: &[u8],
         crypt_algo: V,
     ) -> CustomResult<Self, errors::CryptoError> {
+        metrics::APPLICATION_ENCRYPTION_COUNT.add(&metrics::CONTEXT, 1, &[]);
         let data = serde_json::to_vec(&masked_data.peek())
             .change_context(errors::CryptoError::DecodingFailed)?;
         let encrypted_data = crypt_algo.encode_message(key, &data)?;
-
         Ok(Self::new(masked_data, encrypted_data.into()))
     }
 
@@ -90,30 +434,229 @@ impl<
         key: &[u8],
         crypt_algo: V,
     ) -> CustomResult<Self, errors::CryptoError> {
+        metrics::APPLICATION_DECRYPTION_COUNT.add(&metrics::CONTEXT, 1, &[]);
         let encrypted = encrypted_data.into_inner();
         let data = crypt_algo.decode_message(key, encrypted.clone())?;
 
         let value: serde_json::Value =
             serde_json::from_slice(&data).change_context(errors::CryptoError::DecodingFailed)?;
-
         Ok(Self::new(value.into(), encrypted))
     }
+
+    #[allow(unused_variables)]
+    async fn batch_encrypt_via_api(
+        state: &KeyManagerState,
+        masked_data: FxHashMap<String, Secret<serde_json::Value, S>>,
+        identifier: Identifier,
+        key: &[u8],
+        crypt_algo: V,
+    ) -> CustomResult<FxHashMap<String, Self>, errors::CryptoError> {
+        #[cfg(not(feature = "encryption_service"))]
+        {
+            Self::batch_encrypt(masked_data, key, crypt_algo).await
+        }
+        #[cfg(feature = "encryption_service")]
+        {
+            let result: Result<
+                BatchEncryptDataResponse,
+                error_stack::Report<errors::KeyManagerClientError>,
+            > = call_encryption_service(
+                state,
+                Method::POST,
+                "data/encrypt",
+                BatchEncryptDataRequest::from((masked_data.clone(), identifier)),
+            )
+            .await;
+            match result {
+                Ok(response) => Ok(ForeignFrom::foreign_from((masked_data, response))),
+                Err(err) => {
+                    metrics::ENCRYPTION_API_FAILURES.add(&metrics::CONTEXT, 1, &[]);
+                    logger::error!("Encryption error {:?}", err);
+                    logger::info!("Fall back to Application Encryption");
+                    Self::batch_encrypt(masked_data, key, crypt_algo).await
+                }
+            }
+        }
+    }
+
+    #[allow(unused_variables)]
+    async fn batch_decrypt_via_api(
+        state: &KeyManagerState,
+        encrypted_data: FxHashMap<String, Encryption>,
+        identifier: Identifier,
+        key: &[u8],
+        crypt_algo: V,
+    ) -> CustomResult<FxHashMap<String, Self>, errors::CryptoError> {
+        #[cfg(not(feature = "encryption_service"))]
+        {
+            Self::batch_decrypt(encrypted_data, key, crypt_algo).await
+        }
+        #[cfg(feature = "encryption_service")]
+        {
+            let result: Result<
+                BatchDecryptDataResponse,
+                error_stack::Report<errors::KeyManagerClientError>,
+            > = call_encryption_service(
+                state,
+                Method::POST,
+                "data/decrypt",
+                TransientBatchDecryptDataRequest::from((encrypted_data.clone(), identifier)),
+            )
+            .await;
+            let decrypted = match result {
+                Ok(decrypted_data) => {
+                    ForeignTryFrom::foreign_try_from((encrypted_data.clone(), decrypted_data))
+                }
+                Err(err) => {
+                    logger::error!("Decryption error {:?}", err);
+                    Err(err.change_context(errors::CryptoError::DecodingFailed))
+                }
+            };
+            match decrypted {
+                Ok(de) => Ok(de),
+                Err(_) => {
+                    metrics::DECRYPTION_API_FAILURES.add(&metrics::CONTEXT, 1, &[]);
+                    logger::info!("Fall back to Application Decryption");
+                    Self::batch_decrypt(encrypted_data, key, crypt_algo).await
+                }
+            }
+        }
+    }
+
+    async fn batch_encrypt(
+        masked_data: FxHashMap<String, Secret<serde_json::Value, S>>,
+        key: &[u8],
+        crypt_algo: V,
+    ) -> CustomResult<FxHashMap<String, Self>, errors::CryptoError> {
+        metrics::APPLICATION_ENCRYPTION_COUNT.add(&metrics::CONTEXT, 1, &[]);
+        masked_data
+            .into_iter()
+            .map(|(k, v)| {
+                let data = serde_json::to_vec(v.peek())
+                    .change_context(errors::CryptoError::DecodingFailed)?;
+                Ok((
+                    k,
+                    Self::new(v, crypt_algo.encode_message(key, &data)?.into()),
+                ))
+            })
+            .collect()
+    }
+
+    async fn batch_decrypt(
+        encrypted_data: FxHashMap<String, Encryption>,
+        key: &[u8],
+        crypt_algo: V,
+    ) -> CustomResult<FxHashMap<String, Self>, errors::CryptoError> {
+        metrics::APPLICATION_DECRYPTION_COUNT.add(&metrics::CONTEXT, 1, &[]);
+        encrypted_data
+            .into_iter()
+            .map(|(k, v)| {
+                let data = crypt_algo.decode_message(key, v.clone().into_inner().clone())?;
+
+                let value: serde_json::Value = serde_json::from_slice(&data)
+                    .change_context(errors::CryptoError::DecodingFailed)?;
+                Ok((k, Self::new(value.into(), v.into_inner())))
+            })
+            .collect()
+    }
 }
 
 #[async_trait]
 impl<
         V: crypto::DecodeMessage + crypto::EncodeMessage + Send + 'static,
-        S: masking::Strategy<Vec<u8>> + Send,
+        S: masking::Strategy<Vec<u8>> + Send + Sync,
     > TypeEncryption<Vec<u8>, V, S> for crypto::Encryptable<Secret<Vec<u8>, S>>
 {
+    #[instrument(skip_all)]
+    #[allow(unused_variables)]
+    async fn encrypt_via_api(
+        state: &KeyManagerState,
+        masked_data: Secret<Vec<u8>, S>,
+        identifier: Identifier,
+        key: &[u8],
+        crypt_algo: V,
+    ) -> CustomResult<Self, errors::CryptoError> {
+        #[cfg(not(feature = "encryption_service"))]
+        {
+            Self::encrypt(masked_data, key, crypt_algo).await
+        }
+        #[cfg(feature = "encryption_service")]
+        {
+            let result: Result<
+                EncryptDataResponse,
+                error_stack::Report<errors::KeyManagerClientError>,
+            > = call_encryption_service(
+                state,
+                Method::POST,
+                "data/encrypt",
+                EncryptDataRequest::from((masked_data.clone(), identifier)),
+            )
+            .await;
+            match result {
+                Ok(response) => Ok(ForeignFrom::foreign_from((masked_data.clone(), response))),
+                Err(err) => {
+                    logger::error!("Encryption error {:?}", err);
+                    metrics::ENCRYPTION_API_FAILURES.add(&metrics::CONTEXT, 1, &[]);
+                    logger::info!("Fall back to Application Encryption");
+                    Self::encrypt(masked_data, key, crypt_algo).await
+                }
+            }
+        }
+    }
+
+    #[instrument(skip_all)]
+    #[allow(unused_variables)]
+    async fn decrypt_via_api(
+        state: &KeyManagerState,
+        encrypted_data: Encryption,
+        identifier: Identifier,
+        key: &[u8],
+        crypt_algo: V,
+    ) -> CustomResult<Self, errors::CryptoError> {
+        #[cfg(not(feature = "encryption_service"))]
+        {
+            Self::decrypt(encrypted_data, key, crypt_algo).await
+        }
+        #[cfg(feature = "encryption_service")]
+        {
+            let result: Result<
+                DecryptDataResponse,
+                error_stack::Report<errors::KeyManagerClientError>,
+            > = call_encryption_service(
+                state,
+                Method::POST,
+                "data/decrypt",
+                TransientDecryptDataRequest::from((encrypted_data.clone(), identifier)),
+            )
+            .await;
+            let decrypted = match result {
+                Ok(decrypted_data) => {
+                    ForeignTryFrom::foreign_try_from((encrypted_data.clone(), decrypted_data))
+                }
+                Err(err) => {
+                    logger::error!("Decryption error {:?}", err);
+                    Err(err.change_context(errors::CryptoError::DecodingFailed))
+                }
+            };
+            match decrypted {
+                Ok(de) => Ok(de),
+                Err(_) => {
+                    metrics::DECRYPTION_API_FAILURES.add(&metrics::CONTEXT, 1, &[]);
+                    logger::info!("Fall back to Application Decryption");
+                    Self::decrypt(encrypted_data, key, crypt_algo).await
+                }
+            }
+        }
+    }
+
     #[instrument(skip_all)]
     async fn encrypt(
         masked_data: Secret<Vec<u8>, S>,
         key: &[u8],
         crypt_algo: V,
     ) -> CustomResult<Self, errors::CryptoError> {
+        metrics::APPLICATION_ENCRYPTION_COUNT.add(&metrics::CONTEXT, 1, &[]);
         let encrypted_data = crypt_algo.encode_message(key, masked_data.peek())?;
-
         Ok(Self::new(masked_data, encrypted_data.into()))
     }
 
@@ -123,11 +666,131 @@ impl<
         key: &[u8],
         crypt_algo: V,
     ) -> CustomResult<Self, errors::CryptoError> {
+        metrics::APPLICATION_DECRYPTION_COUNT.add(&metrics::CONTEXT, 1, &[]);
         let encrypted = encrypted_data.into_inner();
         let data = crypt_algo.decode_message(key, encrypted.clone())?;
-
         Ok(Self::new(data.into(), encrypted))
     }
+
+    #[allow(unused_variables)]
+    async fn batch_encrypt_via_api(
+        state: &KeyManagerState,
+        masked_data: FxHashMap<String, Secret<Vec<u8>, S>>,
+        identifier: Identifier,
+        key: &[u8],
+        crypt_algo: V,
+    ) -> CustomResult<FxHashMap<String, Self>, errors::CryptoError> {
+        #[cfg(not(feature = "encryption_service"))]
+        {
+            Self::batch_encrypt(masked_data, key, crypt_algo).await
+        }
+
+        #[cfg(feature = "encryption_service")]
+        {
+            let result: Result<
+                BatchEncryptDataResponse,
+                error_stack::Report<errors::KeyManagerClientError>,
+            > = call_encryption_service(
+                state,
+                Method::POST,
+                "data/encrypt",
+                BatchEncryptDataRequest::from((masked_data.clone(), identifier)),
+            )
+            .await;
+            match result {
+                Ok(response) => Ok(ForeignFrom::foreign_from((masked_data, response))),
+                Err(err) => {
+                    metrics::ENCRYPTION_API_FAILURES.add(&metrics::CONTEXT, 1, &[]);
+                    logger::error!("Encryption error {:?}", err);
+                    logger::info!("Fall back to Application Encryption");
+                    Self::batch_encrypt(masked_data, key, crypt_algo).await
+                }
+            }
+        }
+    }
+
+    #[allow(unused_variables)]
+    async fn batch_decrypt_via_api(
+        state: &KeyManagerState,
+        encrypted_data: FxHashMap<String, Encryption>,
+        identifier: Identifier,
+        key: &[u8],
+        crypt_algo: V,
+    ) -> CustomResult<FxHashMap<String, Self>, errors::CryptoError> {
+        #[cfg(not(feature = "encryption_service"))]
+        {
+            Self::batch_decrypt(encrypted_data, key, crypt_algo).await
+        }
+        #[cfg(feature = "encryption_service")]
+        {
+            let result: Result<
+                BatchDecryptDataResponse,
+                error_stack::Report<errors::KeyManagerClientError>,
+            > = call_encryption_service(
+                state,
+                Method::POST,
+                "data/decrypt",
+                TransientBatchDecryptDataRequest::from((encrypted_data.clone(), identifier)),
+            )
+            .await;
+            let decrypted = match result {
+                Ok(response) => {
+                    ForeignTryFrom::foreign_try_from((encrypted_data.clone(), response))
+                }
+                Err(err) => {
+                    logger::error!("Decryption error {:?}", err);
+                    Err(err.change_context(errors::CryptoError::DecodingFailed))
+                }
+            };
+            match decrypted {
+                Ok(de) => Ok(de),
+                Err(_) => {
+                    metrics::DECRYPTION_API_FAILURES.add(&metrics::CONTEXT, 1, &[]);
+                    logger::info!("Fall back to Application Decryption");
+                    Self::batch_decrypt(encrypted_data, key, crypt_algo).await
+                }
+            }
+        }
+    }
+
+    async fn batch_encrypt(
+        masked_data: FxHashMap<String, Secret<Vec<u8>, S>>,
+        key: &[u8],
+        crypt_algo: V,
+    ) -> CustomResult<FxHashMap<String, Self>, errors::CryptoError> {
+        metrics::APPLICATION_ENCRYPTION_COUNT.add(&metrics::CONTEXT, 1, &[]);
+        masked_data
+            .into_iter()
+            .map(|(k, v)| {
+                Ok((
+                    k,
+                    Self::new(v.clone(), crypt_algo.encode_message(key, v.peek())?.into()),
+                ))
+            })
+            .collect()
+    }
+
+    async fn batch_decrypt(
+        encrypted_data: FxHashMap<String, Encryption>,
+        key: &[u8],
+        crypt_algo: V,
+    ) -> CustomResult<FxHashMap<String, Self>, errors::CryptoError> {
+        metrics::APPLICATION_DECRYPTION_COUNT.add(&metrics::CONTEXT, 1, &[]);
+        encrypted_data
+            .into_iter()
+            .map(|(k, v)| {
+                Ok((
+                    k,
+                    Self::new(
+                        crypt_algo
+                            .decode_message(key, v.clone().into_inner().clone())?
+                            .into(),
+                        v.into_inner(),
+                    ),
+                ))
+            })
+            .collect()
+    }
 }
 
 pub trait Lift<U> {
@@ -178,7 +841,9 @@ impl<U, V: Lift<U> + Lift<U, SelfWrapper<U> = V> + Send> AsyncLift<U> for V {
 
 #[inline]
 pub async fn encrypt<E: Clone, S>(
+    state: &KeyManagerState,
     inner: Secret<E, S>,
+    identifier: Identifier,
     key: &[u8],
 ) -> CustomResult<crypto::Encryptable<Secret<E, S>>, errors::CryptoError>
 where
@@ -186,7 +851,7 @@ where
     crypto::Encryptable<Secret<E, S>>: TypeEncryption<E, crypto::GcmAes256, S>,
 {
     record_operation_time(
-        crypto::Encryptable::encrypt(inner, key, crypto::GcmAes256),
+        crypto::Encryptable::encrypt_via_api(state, inner, identifier, key, crypto::GcmAes256),
         &metrics::ENCRYPTION_TIME,
         &metrics::CONTEXT,
         &[],
@@ -194,9 +859,41 @@ where
     .await
 }
 
+#[inline]
+pub async fn batch_encrypt<E: Clone, S>(
+    state: &KeyManagerState,
+    inner: FxHashMap<String, Secret<E, S>>,
+    identifier: Identifier,
+    key: &[u8],
+) -> CustomResult<FxHashMap<String, crypto::Encryptable<Secret<E, S>>>, errors::CryptoError>
+where
+    S: masking::Strategy<E>,
+    crypto::Encryptable<Secret<E, S>>: TypeEncryption<E, crypto::GcmAes256, S>,
+{
+    if !inner.is_empty() {
+        record_operation_time(
+            crypto::Encryptable::batch_encrypt_via_api(
+                state,
+                inner,
+                identifier,
+                key,
+                crypto::GcmAes256,
+            ),
+            &metrics::ENCRYPTION_TIME,
+            &metrics::CONTEXT,
+            &[],
+        )
+        .await
+    } else {
+        Ok(FxHashMap::default())
+    }
+}
+
 #[inline]
 pub async fn encrypt_optional<E: Clone, S>(
+    state: &KeyManagerState,
     inner: Option<Secret<E, S>>,
+    identifier: Identifier,
     key: &[u8],
 ) -> CustomResult<Option<crypto::Encryptable<Secret<E, S>>>, errors::CryptoError>
 where
@@ -204,19 +901,26 @@ where
     S: masking::Strategy<E>,
     crypto::Encryptable<Secret<E, S>>: TypeEncryption<E, crypto::GcmAes256, S>,
 {
-    inner.async_map(|f| encrypt(f, key)).await.transpose()
+    inner
+        .async_map(|f| encrypt(state, f, identifier, key))
+        .await
+        .transpose()
 }
 
 #[inline]
 pub async fn decrypt<T: Clone, S: masking::Strategy<T>>(
+    state: &KeyManagerState,
     inner: Option<Encryption>,
+    identifier: Identifier,
     key: &[u8],
 ) -> CustomResult<Option<crypto::Encryptable<Secret<T, S>>>, errors::CryptoError>
 where
     crypto::Encryptable<Secret<T, S>>: TypeEncryption<T, crypto::GcmAes256, S>,
 {
     record_operation_time(
-        inner.async_map(|item| crypto::Encryptable::decrypt(item, key, crypto::GcmAes256)),
+        inner.async_map(|item| {
+            crypto::Encryptable::decrypt_via_api(state, item, identifier, key, crypto::GcmAes256)
+        }),
         &metrics::DECRYPTION_TIME,
         &metrics::CONTEXT,
         &[],
@@ -225,8 +929,38 @@ where
     .transpose()
 }
 
+#[inline]
+pub async fn batch_decrypt<E: Clone, S>(
+    state: &KeyManagerState,
+    inner: FxHashMap<String, Encryption>,
+    identifier: Identifier,
+    key: &[u8],
+) -> CustomResult<FxHashMap<String, crypto::Encryptable<Secret<E, S>>>, errors::CryptoError>
+where
+    S: masking::Strategy<E>,
+    crypto::Encryptable<Secret<E, S>>: TypeEncryption<E, crypto::GcmAes256, S>,
+{
+    if !inner.is_empty() {
+        record_operation_time(
+            crypto::Encryptable::batch_decrypt_via_api(
+                state,
+                inner,
+                identifier,
+                key,
+                crypto::GcmAes256,
+            ),
+            &metrics::ENCRYPTION_TIME,
+            &metrics::CONTEXT,
+            &[],
+        )
+        .await
+    } else {
+        Ok(FxHashMap::default())
+    }
+}
+
 pub(crate) mod metrics {
-    use router_env::{global_meter, histogram_metric, metrics_context, once_cell};
+    use router_env::{counter_metric, global_meter, histogram_metric, metrics_context, once_cell};
 
     metrics_context!(CONTEXT);
     global_meter!(GLOBAL_METER, "ROUTER_API");
@@ -234,4 +968,8 @@ pub(crate) mod metrics {
     // Encryption and Decryption metrics
     histogram_metric!(ENCRYPTION_TIME, GLOBAL_METER);
     histogram_metric!(DECRYPTION_TIME, GLOBAL_METER);
+    counter_metric!(ENCRYPTION_API_FAILURES, GLOBAL_METER);
+    counter_metric!(DECRYPTION_API_FAILURES, GLOBAL_METER);
+    counter_metric!(APPLICATION_ENCRYPTION_COUNT, GLOBAL_METER);
+    counter_metric!(APPLICATION_DECRYPTION_COUNT, GLOBAL_METER);
 }
diff --git a/crates/router/Cargo.toml b/crates/router/Cargo.toml
index 1379b17eec4..b9488a0804e 100644
--- a/crates/router/Cargo.toml
+++ b/crates/router/Cargo.toml
@@ -11,12 +11,13 @@ license.workspace = true
 [features]
 default = ["kv_store", "stripe", "oltp", "olap", "accounts_cache", "dummy_connector", "payouts", "payout_retry", "retry", "frm", "tls"]
 tls = ["actix-web/rustls-0_22"]
-keymanager_mtls = ["reqwest/rustls-tls", "common_utils/keymanager_mtls"]
+keymanager_mtls = ["reqwest/rustls-tls","common_utils/keymanager_mtls"]
+encryption_service = ["hyperswitch_domain_models/encryption_service", "common_utils/encryption_service"]
 email = ["external_services/email", "scheduler/email", "olap"]
 keymanager_create = []
 frm = ["api_models/frm", "hyperswitch_domain_models/frm"]
 stripe = ["dep:serde_qs"]
-release = ["stripe", "email", "accounts_cache", "kv_store", "vergen", "recon", "external_services/aws_kms", "external_services/aws_s3", "keymanager_mtls", "keymanager_create"]
+release = ["stripe", "email", "accounts_cache", "kv_store", "vergen", "recon", "external_services/aws_kms", "external_services/aws_s3", "keymanager_mtls", "keymanager_create", "encryption_service"]
 olap = ["hyperswitch_domain_models/olap", "storage_impl/olap", "scheduler/olap", "api_models/olap", "dep:analytics"]
 oltp = ["storage_impl/oltp"]
 kv_store = ["scheduler/kv_store"]
@@ -114,7 +115,7 @@ analytics = { version = "0.1.0", path = "../analytics", optional = true }
 api_models = { version = "0.1.0", path = "../api_models", features = ["errors"] }
 cards = { version = "0.1.0", path = "../cards" }
 common_enums = { version = "0.1.0", path = "../common_enums" }
-common_utils = { version = "0.1.0", path = "../common_utils", features = ["signals", "async_ext", "logs", "metrics", "keymanager"] }
+common_utils = { version = "0.1.0", path = "../common_utils", features = ["signals", "async_ext", "logs", "metrics", "keymanager", "encryption_service"] }
 currency_conversion = { version = "0.1.0", path = "../currency_conversion" }
 diesel_models = { version = "0.1.0", path = "../diesel_models", features = ["kv_store"] }
 euclid = { version = "0.1.0", path = "../euclid", features = ["valued_jit"] }
diff --git a/crates/router/src/bin/scheduler.rs b/crates/router/src/bin/scheduler.rs
index 61f9c473a22..269c7d5b3b4 100644
--- a/crates/router/src/bin/scheduler.rs
+++ b/crates/router/src/bin/scheduler.rs
@@ -38,7 +38,11 @@ async fn main() -> CustomResult<(), ProcessTrackerError> {
     let api_client = Box::new(
         services::ProxyClient::new(
             conf.proxy.clone(),
-            services::proxy_bypass_urls(&conf.locker, &conf.proxy.bypass_proxy_urls),
+            services::proxy_bypass_urls(
+                conf.key_manager.get_inner(),
+                &conf.locker,
+                &conf.proxy.bypass_proxy_urls,
+            ),
         )
         .change_context(ProcessTrackerError::ConfigurationError)?,
     );
diff --git a/crates/router/src/consts.rs b/crates/router/src/consts.rs
index d3091875f48..bdf8db2828e 100644
--- a/crates/router/src/consts.rs
+++ b/crates/router/src/consts.rs
@@ -2,6 +2,7 @@ pub mod opensearch;
 #[cfg(feature = "olap")]
 pub mod user;
 pub mod user_role;
+use common_utils::consts;
 pub use hyperswitch_interfaces::consts::{NO_ERROR_CODE, NO_ERROR_MESSAGE};
 // ID generation
 pub(crate) const ID_LENGTH: usize = 20;
@@ -43,8 +44,9 @@ pub(crate) const CANNOT_CONTINUE_AUTH: &str =
 pub(crate) const DEFAULT_NOTIFICATION_SCRIPT_LANGUAGE: &str = "en-US";
 
 // General purpose base64 engines
-pub(crate) const BASE64_ENGINE: base64::engine::GeneralPurpose =
-    base64::engine::general_purpose::STANDARD;
+
+pub(crate) const BASE64_ENGINE: base64::engine::GeneralPurpose = consts::BASE64_ENGINE;
+
 pub(crate) const BASE64_ENGINE_URL_SAFE: base64::engine::GeneralPurpose =
     base64::engine::general_purpose::URL_SAFE;
 
diff --git a/crates/router/src/core/admin.rs b/crates/router/src/core/admin.rs
index 8a7854d658b..a851be95d5e 100644
--- a/crates/router/src/core/admin.rs
+++ b/crates/router/src/core/admin.rs
@@ -8,9 +8,8 @@ use common_utils::{
     date_time,
     ext_traits::{AsyncExt, ConfigExt, Encode, ValueExt},
     id_type, pii,
+    types::keymanager as km_types,
 };
-#[cfg(all(feature = "keymanager_create", feature = "olap"))]
-use common_utils::{keymanager, types::keymanager as km_types};
 use diesel_models::configs;
 use error_stack::{report, FutureExt, ResultExt};
 use futures::future::try_join_all;
@@ -111,6 +110,9 @@ pub async fn create_merchant_account(
     state: SessionState,
     req: api::MerchantAccountCreate,
 ) -> RouterResponse<api::MerchantAccountResponse> {
+    #[cfg(feature = "keymanager_create")]
+    use common_utils::keymanager;
+
     let db = state.store.as_ref();
 
     let key = services::generate_aes256_key()
@@ -119,27 +121,16 @@ pub async fn create_merchant_account(
 
     let master_key = db.get_master_key();
 
+    let key_manager_state = &(&state).into();
     let merchant_id = req.get_merchant_reference_id().get_string_repr().to_owned();
-
-    let key_store = domain::MerchantKeyStore {
-        merchant_id: merchant_id.clone(),
-        key: domain_types::encrypt(key.to_vec().into(), master_key)
-            .await
-            .change_context(errors::ApiErrorResponse::InternalServerError)
-            .attach_printable("Failed to decrypt data from key store")?,
-        created_at: date_time::now(),
-    };
-
-    let domain_merchant_account = req
-        .create_domain_model_from_request(db, key_store.clone())
-        .await?;
+    let identifier = km_types::Identifier::Merchant(merchant_id.clone());
 
     #[cfg(feature = "keymanager_create")]
     {
         keymanager::create_key_in_key_manager(
-            &(&state).into(),
+            key_manager_state,
             km_types::EncryptionCreateRequest {
-                identifier: km_types::Identifier::Merchant(merchant_id.clone()),
+                identifier: identifier.clone(),
             },
         )
         .await
@@ -147,12 +138,34 @@ pub async fn create_merchant_account(
         .attach_printable("Failed to insert key to KeyManager")?;
     }
 
-    db.insert_merchant_key_store(key_store.clone(), &master_key.to_vec().into())
+    let key_store = domain::MerchantKeyStore {
+        merchant_id: merchant_id.clone(),
+        key: domain_types::encrypt(
+            key_manager_state,
+            key.to_vec().into(),
+            identifier.clone(),
+            master_key,
+        )
         .await
-        .to_duplicate_response(errors::ApiErrorResponse::DuplicateMerchantAccount)?;
+        .change_context(errors::ApiErrorResponse::InternalServerError)
+        .attach_printable("Failed to decrypt data from key store")?,
+        created_at: date_time::now(),
+    };
+
+    let domain_merchant_account = req
+        .create_domain_model_from_request(&state, key_store.clone())
+        .await?;
+    let key_manager_state = &(&state).into();
+    db.insert_merchant_key_store(
+        key_manager_state,
+        key_store.clone(),
+        &master_key.to_vec().into(),
+    )
+    .await
+    .to_duplicate_response(errors::ApiErrorResponse::DuplicateMerchantAccount)?;
 
     let merchant_account = db
-        .insert_merchant(domain_merchant_account, &key_store)
+        .insert_merchant(key_manager_state, domain_merchant_account, &key_store)
         .await
         .to_duplicate_response(errors::ApiErrorResponse::DuplicateMerchantAccount)?;
 
@@ -172,7 +185,7 @@ pub async fn create_merchant_account(
 trait MerchantAccountCreateBridge {
     async fn create_domain_model_from_request(
         self,
-        db: &dyn StorageInterface,
+        state: &SessionState,
         key: domain::MerchantKeyStore,
     ) -> RouterResult<domain::MerchantAccount>;
 }
@@ -182,9 +195,10 @@ trait MerchantAccountCreateBridge {
 impl MerchantAccountCreateBridge for api::MerchantAccountCreate {
     async fn create_domain_model_from_request(
         self,
-        db: &dyn StorageInterface,
+        state: &SessionState,
         key_store: domain::MerchantKeyStore,
     ) -> RouterResult<domain::MerchantAccount> {
+        let db = &*state.store;
         let publishable_key = create_merchant_publishable_key();
 
         let primary_business_details = self.get_primary_details_as_value().change_context(
@@ -229,7 +243,7 @@ impl MerchantAccountCreateBridge for api::MerchantAccountCreate {
         let payment_response_hash_key = self.get_payment_response_hash_key();
 
         let parent_merchant_id = get_parent_merchant(
-            db,
+            state,
             self.sub_merchants_enabled,
             self.parent_merchant_id,
             &key_store,
@@ -241,6 +255,7 @@ impl MerchantAccountCreateBridge for api::MerchantAccountCreate {
             .await?;
 
         let key = key_store.key.clone().into_inner();
+        let key_manager_state = state.into();
 
         let mut merchant_account = async {
             Ok::<_, error_stack::Report<common_utils::errors::CryptoError>>(
@@ -248,10 +263,24 @@ impl MerchantAccountCreateBridge for api::MerchantAccountCreate {
                     merchant_id: self.merchant_id.get_string_repr().to_owned(),
                     merchant_name: self
                         .merchant_name
-                        .async_lift(|inner| domain_types::encrypt_optional(inner, key.peek()))
+                        .async_lift(|inner| {
+                            domain_types::encrypt_optional(
+                                &key_manager_state,
+                                inner,
+                                km_types::Identifier::Merchant(key_store.merchant_id.clone()),
+                                key.peek(),
+                            )
+                        })
                         .await?,
                     merchant_details: merchant_details
-                        .async_lift(|inner| domain_types::encrypt_optional(inner, key.peek()))
+                        .async_lift(|inner| {
+                            domain_types::encrypt_optional(
+                                &key_manager_state,
+                                inner,
+                                km_types::Identifier::Merchant(key_store.merchant_id.clone()),
+                                key.peek(),
+                            )
+                        })
                         .await?,
                     return_url: self.return_url.map(|a| a.to_string()),
                     webhook_details,
@@ -293,7 +322,7 @@ impl MerchantAccountCreateBridge for api::MerchantAccountCreate {
         .change_context(errors::ApiErrorResponse::InternalServerError)?;
 
         CreateBusinessProfile::new(self.primary_business_details.clone())
-            .create_business_profiles(db, &mut merchant_account, &key_store)
+            .create_business_profiles(state, &mut merchant_account, &key_store)
             .await?;
 
         Ok(merchant_account)
@@ -385,7 +414,7 @@ impl CreateBusinessProfile {
 
     async fn create_business_profiles(
         &self,
-        db: &dyn StorageInterface,
+        state: &SessionState,
         merchant_account: &mut domain::MerchantAccount,
         key_store: &domain::MerchantKeyStore,
     ) -> RouterResult<()> {
@@ -394,7 +423,7 @@ impl CreateBusinessProfile {
                 primary_business_details,
             } => {
                 let business_profiles = Self::create_business_profiles_for_each_business_details(
-                    db,
+                    state,
                     merchant_account.clone(),
                     primary_business_details,
                     key_store,
@@ -410,7 +439,7 @@ impl CreateBusinessProfile {
             }
             Self::CreateDefaultBusinessProfile => {
                 let business_profile = self
-                    .create_default_business_profile(db, merchant_account.clone(), key_store)
+                    .create_default_business_profile(state, merchant_account.clone(), key_store)
                     .await?;
 
                 merchant_account.default_profile = Some(business_profile.profile_id);
@@ -423,12 +452,12 @@ impl CreateBusinessProfile {
     /// Create default business profile
     async fn create_default_business_profile(
         &self,
-        db: &dyn StorageInterface,
+        state: &SessionState,
         merchant_account: domain::MerchantAccount,
         key_store: &domain::MerchantKeyStore,
     ) -> RouterResult<diesel_models::business_profile::BusinessProfile> {
         let business_profile = create_and_insert_business_profile(
-            db,
+            state,
             api_models::admin::BusinessProfileCreate::default(),
             merchant_account.clone(),
             key_store,
@@ -442,7 +471,7 @@ impl CreateBusinessProfile {
     /// If there is no default profile in merchant account and only one primary_business_detail
     /// is available, then create a default business profile.
     async fn create_business_profiles_for_each_business_details(
-        db: &dyn StorageInterface,
+        state: &SessionState,
         merchant_account: domain::MerchantAccount,
         primary_business_details: &Vec<admin_types::PrimaryBusinessDetails>,
         key_store: &domain::MerchantKeyStore,
@@ -462,7 +491,7 @@ impl CreateBusinessProfile {
             };
 
             create_and_insert_business_profile(
-                db,
+                state,
                 business_profile_create_request,
                 merchant_account.clone(),
                 key_store,
@@ -486,10 +515,11 @@ impl CreateBusinessProfile {
 impl MerchantAccountCreateBridge for api::MerchantAccountCreate {
     async fn create_domain_model_from_request(
         self,
-        db: &dyn StorageInterface,
+        state: &SessionState,
         key_store: domain::MerchantKeyStore,
     ) -> RouterResult<domain::MerchantAccount> {
         let publishable_key = create_merchant_publishable_key();
+        let db = &*state.store;
 
         let metadata = self.get_metadata_as_secret().change_context(
             errors::ApiErrorResponse::InvalidDataValue {
@@ -514,24 +544,36 @@ impl MerchantAccountCreateBridge for api::MerchantAccountCreate {
             .await?;
 
         let key = key_store.key.into_inner();
+        let merchant_id = self
+            .get_merchant_reference_id()
+            .get_string_repr()
+            .to_owned();
+        let key_manager_state = state.into();
+        let identifier = km_types::Identifier::Merchant(merchant_id.clone());
 
         async {
             Ok::<_, error_stack::Report<common_utils::errors::CryptoError>>(
                 domain::MerchantAccount {
-                    merchant_id: self
-                        .get_merchant_reference_id()
-                        .get_string_repr()
-                        .to_owned(),
+                    merchant_id,
                     merchant_name: Some(
                         domain_types::encrypt(
+                            &key_manager_state,
                             self.merchant_name
                                 .map(|merchant_name| merchant_name.into_inner()),
+                            identifier.clone(),
                             key.peek(),
                         )
                         .await?,
                     ),
                     merchant_details: merchant_details
-                        .async_lift(|inner| domain_types::encrypt_optional(inner, key.peek()))
+                        .async_lift(|inner| {
+                            domain_types::encrypt_optional(
+                                &key_manager_state,
+                                inner,
+                                identifier.clone(),
+                                key.peek(),
+                            )
+                        })
                         .await?,
                     return_url: None,
                     webhook_details: None,
@@ -577,7 +619,7 @@ pub async fn list_merchant_account(
 ) -> RouterResponse<Vec<api::MerchantAccountResponse>> {
     let merchant_accounts = state
         .store
-        .list_merchant_accounts_by_organization_id(&req.organization_id)
+        .list_merchant_accounts_by_organization_id(&(&state).into(), &req.organization_id)
         .await
         .to_not_found_response(errors::ApiErrorResponse::MerchantAccountNotFound)?;
 
@@ -600,8 +642,10 @@ pub async fn get_merchant_account(
     req: api::MerchantId,
 ) -> RouterResponse<api::MerchantAccountResponse> {
     let db = state.store.as_ref();
+    let key_manager_state = &(&state).into();
     let key_store = db
         .get_merchant_key_store_by_merchant_id(
+            key_manager_state,
             &req.merchant_id,
             &db.get_master_key().to_vec().into(),
         )
@@ -609,7 +653,7 @@ pub async fn get_merchant_account(
         .to_not_found_response(errors::ApiErrorResponse::MerchantAccountNotFound)?;
 
     let merchant_account = db
-        .find_merchant_account_by_merchant_id(&req.merchant_id, &key_store)
+        .find_merchant_account_by_merchant_id(key_manager_state, &req.merchant_id, &key_store)
         .await
         .to_not_found_response(errors::ApiErrorResponse::MerchantAccountNotFound)?;
 
@@ -623,13 +667,15 @@ pub async fn get_merchant_account(
 /// For backwards compatibility, whenever new business labels are passed in
 /// primary_business_details, create a business profile
 pub async fn create_business_profile_from_business_labels(
+    state: &SessionState,
     db: &dyn StorageInterface,
     key_store: &domain::MerchantKeyStore,
     merchant_id: &str,
     new_business_details: Vec<admin_types::PrimaryBusinessDetails>,
 ) -> RouterResult<()> {
+    let key_manager_state = &state.into();
     let merchant_account = db
-        .find_merchant_account_by_merchant_id(merchant_id, key_store)
+        .find_merchant_account_by_merchant_id(key_manager_state, merchant_id, key_store)
         .await
         .to_not_found_response(errors::ApiErrorResponse::MerchantAccountNotFound)?;
 
@@ -657,7 +703,7 @@ pub async fn create_business_profile_from_business_labels(
         };
 
         let business_profile_create_result = create_and_insert_business_profile(
-            db,
+            state,
             business_profile_create_request,
             merchant_account.clone(),
             key_store,
@@ -673,9 +719,14 @@ pub async fn create_business_profile_from_business_labels(
         // If a business_profile is created, then unset the default profile
         if business_profile_create_result.is_ok() && merchant_account.default_profile.is_some() {
             let unset_default_profile = domain::MerchantAccountUpdate::UnsetDefaultProfile;
-            db.update_merchant(merchant_account.clone(), unset_default_profile, key_store)
-                .await
-                .to_not_found_response(errors::ApiErrorResponse::MerchantAccountNotFound)?;
+            db.update_merchant(
+                key_manager_state,
+                merchant_account.clone(),
+                unset_default_profile,
+                key_store,
+            )
+            .await
+            .to_not_found_response(errors::ApiErrorResponse::MerchantAccountNotFound)?;
         }
     }
 
@@ -758,8 +809,10 @@ pub async fn merchant_account_update(
     req: api::MerchantAccountUpdate,
 ) -> RouterResponse<api::MerchantAccountResponse> {
     let db = state.store.as_ref();
+    let key_manager_state = &(&state).into();
     let key_store = db
         .get_merchant_key_store_by_merchant_id(
+            key_manager_state,
             &req.merchant_id,
             &db.get_master_key().to_vec().into(),
         )
@@ -817,6 +870,7 @@ pub async fn merchant_account_update(
         .clone()
         .async_map(|primary_business_details| async {
             let _ = create_business_profile_from_business_labels(
+                &state,
                 db,
                 &key_store,
                 merchant_id,
@@ -845,11 +899,14 @@ pub async fn merchant_account_update(
     // Update the business profile, This is for backwards compatibility
     update_business_profile_cascade(state.clone(), req.clone(), merchant_id.to_string()).await?;
 
+    let identifier = km_types::Identifier::Merchant(key_store.merchant_id.clone());
     let updated_merchant_account = storage::MerchantAccountUpdate::Update {
         merchant_name: req
             .merchant_name
             .map(Secret::new)
-            .async_lift(|inner| domain_types::encrypt_optional(inner, key))
+            .async_lift(|inner| {
+                domain_types::encrypt_optional(key_manager_state, inner, identifier.clone(), key)
+            })
             .await
             .change_context(errors::ApiErrorResponse::InternalServerError)
             .attach_printable("Unable to encrypt merchant name")?,
@@ -862,7 +919,9 @@ pub async fn merchant_account_update(
             .change_context(errors::ApiErrorResponse::InternalServerError)
             .attach_printable("Unable to convert merchant_details to a value")?
             .map(Secret::new)
-            .async_lift(|inner| domain_types::encrypt_optional(inner, key))
+            .async_lift(|inner| {
+                domain_types::encrypt_optional(key_manager_state, inner, identifier.clone(), key)
+            })
             .await
             .change_context(errors::ApiErrorResponse::InternalServerError)
             .attach_printable("Unable to encrypt merchant details")?,
@@ -880,7 +939,7 @@ pub async fn merchant_account_update(
         sub_merchants_enabled: req.sub_merchants_enabled,
 
         parent_merchant_id: get_parent_merchant(
-            db,
+            &state,
             req.sub_merchants_enabled,
             req.parent_merchant_id,
             &key_store,
@@ -905,7 +964,12 @@ pub async fn merchant_account_update(
     };
 
     let response = db
-        .update_specific_fields_in_merchant(merchant_id, updated_merchant_account, &key_store)
+        .update_specific_fields_in_merchant(
+            key_manager_state,
+            merchant_id,
+            updated_merchant_account,
+            &key_store,
+        )
         .await
         .to_not_found_response(errors::ApiErrorResponse::MerchantAccountNotFound)?;
 
@@ -924,9 +988,10 @@ pub async fn merchant_account_delete(
 ) -> RouterResponse<api::MerchantAccountDeleteResponse> {
     let mut is_deleted = false;
     let db = state.store.as_ref();
-
+    let key_manager_state = &(&state).into();
     let merchant_key_store = db
         .get_merchant_key_store_by_merchant_id(
+            key_manager_state,
             &merchant_id,
             &state.store.get_master_key().to_vec().into(),
         )
@@ -934,7 +999,7 @@ pub async fn merchant_account_delete(
         .to_not_found_response(errors::ApiErrorResponse::MerchantAccountNotFound)?;
 
     let merchant_account = db
-        .find_merchant_account_by_merchant_id(&merchant_id, &merchant_key_store)
+        .find_merchant_account_by_merchant_id(key_manager_state, &merchant_id, &merchant_key_store)
         .await
         .to_not_found_response(errors::ApiErrorResponse::MerchantAccountNotFound)?;
 
@@ -988,7 +1053,7 @@ pub async fn merchant_account_delete(
 }
 
 async fn get_parent_merchant(
-    db: &dyn StorageInterface,
+    state: &SessionState,
     sub_merchants_enabled: Option<bool>,
     parent_merchant: Option<String>,
     key_store: &domain::MerchantKeyStore,
@@ -1004,7 +1069,7 @@ async fn get_parent_merchant(
                         message: "If `sub_merchants_enabled` is `true`, then `parent_merchant_id` is mandatory".to_string(),
                     })
                 })
-                .map(|id| validate_merchant_id(db, id,key_store).change_context(
+                .map(|id| validate_merchant_id(state, id,key_store).change_context(
                     errors::ApiErrorResponse::InvalidDataValue { field_name: "parent_merchant_id" }
                 ))?
                 .await?
@@ -1016,11 +1081,12 @@ async fn get_parent_merchant(
 }
 
 async fn validate_merchant_id<S: Into<String>>(
-    db: &dyn StorageInterface,
+    state: &SessionState,
     merchant_id: S,
     key_store: &domain::MerchantKeyStore,
 ) -> RouterResult<domain::MerchantAccount> {
-    db.find_merchant_account_by_merchant_id(&merchant_id.into(), key_store)
+    let db = &*state.store;
+    db.find_merchant_account_by_merchant_id(&state.into(), &merchant_id.into(), key_store)
         .await
         .to_not_found_response(errors::ApiErrorResponse::MerchantAccountNotFound)
 }
@@ -1066,10 +1132,12 @@ pub async fn create_payment_connector(
     merchant_id: &String,
 ) -> RouterResponse<api_models::admin::MerchantConnectorResponse> {
     let store = state.store.as_ref();
+    let key_manager_state = &(&state).into();
     #[cfg(feature = "dummy_connector")]
     validate_dummy_connector_enabled(&state, &req.connector_name).await?;
     let key_store = store
         .get_merchant_key_store_by_merchant_id(
+            key_manager_state,
             merchant_id,
             &state.store.get_master_key().to_vec().into(),
         )
@@ -1083,7 +1151,7 @@ pub async fn create_payment_connector(
 
     let merchant_account = state
         .store
-        .find_merchant_account_by_merchant_id(merchant_id, &key_store)
+        .find_merchant_account_by_merchant_id(key_manager_state, merchant_id, &key_store)
         .await
         .to_not_found_response(errors::ApiErrorResponse::MerchantAccountNotFound)?;
 
@@ -1221,6 +1289,7 @@ pub async fn create_payment_connector(
     state
         .store
         .update_specific_fields_in_merchant(
+            key_manager_state,
             merchant_id,
             storage::MerchantAccountUpdate::ModifiedAtUpdate,
             &key_store,
@@ -1242,7 +1311,7 @@ pub async fn create_payment_connector(
         if let Some(val) = req.pm_auth_config.clone() {
             validate_pm_auth(
                 val,
-                &*state.clone().store,
+                &state,
                 merchant_id.clone().as_str(),
                 &key_store,
                 merchant_account,
@@ -1256,14 +1325,15 @@ pub async fn create_payment_connector(
         .change_context(errors::ApiErrorResponse::InternalServerError)
         .attach_printable("Failed while encoding ConnectorAuthType to serde_json::Value")?;
     let conn_auth = Secret::new(connector_auth);
-
+    let identifier = km_types::Identifier::Merchant(key_store.merchant_id.clone());
     let merchant_connector_account = domain::MerchantConnectorAccount {
         merchant_id: merchant_id.to_string(),
         connector_type: req.connector_type,
         connector_name: req.connector_name.to_string(),
         merchant_connector_id: utils::generate_id(consts::ID_LENGTH, "mca"),
-        connector_account_details: domain_types::encrypt(
+        connector_account_details: domain_types::encrypt(key_manager_state,
             conn_auth,
+            identifier.clone(),
             key_store.key.peek(),
         )
         .await
@@ -1296,10 +1366,11 @@ pub async fn create_payment_connector(
         applepay_verified_domains: None,
         pm_auth_config: req.pm_auth_config.clone(),
         status: connector_status,
-        connector_wallets_details: helpers::get_encrypted_apple_pay_connector_wallets_details(&key_store, &req.metadata).await?,
+        connector_wallets_details: helpers::get_encrypted_apple_pay_connector_wallets_details(&state, &key_store, &req.metadata).await?,
         additional_merchant_data: if let Some(mcd) =  merchant_recipient_data {
-            Some(domain_types::encrypt(
+            Some(domain_types::encrypt(key_manager_state,
                 Secret::new(mcd),
+                identifier,
                 key_store.key.peek(),
             )
             .await
@@ -1329,7 +1400,11 @@ pub async fn create_payment_connector(
 
     let mca = state
         .store
-        .insert_merchant_connector_account(merchant_connector_account, &key_store)
+        .insert_merchant_connector_account(
+            key_manager_state,
+            merchant_connector_account,
+            &key_store,
+        )
         .await
         .to_duplicate_response(
             errors::ApiErrorResponse::DuplicateMerchantConnectorAccount {
@@ -1382,7 +1457,7 @@ pub async fn create_payment_connector(
 
 async fn validate_pm_auth(
     val: serde_json::Value,
-    db: &dyn StorageInterface,
+    state: &SessionState,
     merchant_id: &str,
     key_store: &domain::MerchantKeyStore,
     merchant_account: domain::MerchantAccount,
@@ -1394,8 +1469,10 @@ async fn validate_pm_auth(
         })
         .attach_printable("Failed to deserialize Payment Method Auth config")?;
 
-    let all_mcas = db
+    let all_mcas = &*state
+        .store
         .find_merchant_connector_account_by_merchant_id_and_disabled_list(
+            &state.into(),
             merchant_id,
             true,
             key_store,
@@ -1407,8 +1484,7 @@ async fn validate_pm_auth(
 
     for conn_choice in config.enabled_payment_methods {
         let pm_auth_mca = all_mcas
-            .clone()
-            .into_iter()
+            .iter()
             .find(|mca| mca.merchant_connector_id == conn_choice.mca_id)
             .ok_or(errors::ApiErrorResponse::GenericNotFoundError {
                 message: "payment method auth connector account not found".to_string(),
@@ -1432,8 +1508,10 @@ pub async fn retrieve_payment_connector(
     merchant_connector_id: String,
 ) -> RouterResponse<api_models::admin::MerchantConnectorResponse> {
     let store = state.store.as_ref();
+    let key_manager_state = &(&state).into();
     let key_store = store
         .get_merchant_key_store_by_merchant_id(
+            key_manager_state,
             &merchant_id,
             &store.get_master_key().to_vec().into(),
         )
@@ -1441,12 +1519,13 @@ pub async fn retrieve_payment_connector(
         .to_not_found_response(errors::ApiErrorResponse::MerchantAccountNotFound)?;
 
     let _merchant_account = store
-        .find_merchant_account_by_merchant_id(&merchant_id, &key_store)
+        .find_merchant_account_by_merchant_id(key_manager_state, &merchant_id, &key_store)
         .await
         .to_not_found_response(errors::ApiErrorResponse::MerchantAccountNotFound)?;
 
     let mca = store
         .find_by_merchant_connector_account_merchant_id_merchant_connector_id(
+            key_manager_state,
             &merchant_id,
             &merchant_connector_id,
             &key_store,
@@ -1464,8 +1543,10 @@ pub async fn list_payment_connectors(
     merchant_id: String,
 ) -> RouterResponse<Vec<api_models::admin::MerchantConnectorResponse>> {
     let store = state.store.as_ref();
+    let key_manager_state = &(&state).into();
     let key_store = store
         .get_merchant_key_store_by_merchant_id(
+            key_manager_state,
             &merchant_id,
             &store.get_master_key().to_vec().into(),
         )
@@ -1474,12 +1555,13 @@ pub async fn list_payment_connectors(
 
     // Validate merchant account
     store
-        .find_merchant_account_by_merchant_id(&merchant_id, &key_store)
+        .find_merchant_account_by_merchant_id(key_manager_state, &merchant_id, &key_store)
         .await
         .to_not_found_response(errors::ApiErrorResponse::MerchantAccountNotFound)?;
 
     let merchant_connector_accounts = store
         .find_merchant_connector_account_by_merchant_id_and_disabled_list(
+            key_manager_state,
             &merchant_id,
             true,
             &key_store,
@@ -1503,18 +1585,24 @@ pub async fn update_payment_connector(
     req: api_models::admin::MerchantConnectorUpdate,
 ) -> RouterResponse<api_models::admin::MerchantConnectorResponse> {
     let db = state.store.as_ref();
+    let key_manager_state = &(&state).into();
     let key_store = db
-        .get_merchant_key_store_by_merchant_id(merchant_id, &db.get_master_key().to_vec().into())
+        .get_merchant_key_store_by_merchant_id(
+            key_manager_state,
+            merchant_id,
+            &db.get_master_key().to_vec().into(),
+        )
         .await
         .to_not_found_response(errors::ApiErrorResponse::MerchantAccountNotFound)?;
 
     let merchant_account = db
-        .find_merchant_account_by_merchant_id(merchant_id, &key_store)
+        .find_merchant_account_by_merchant_id(key_manager_state, merchant_id, &key_store)
         .await
         .to_not_found_response(errors::ApiErrorResponse::MerchantAccountNotFound)?;
 
     let mca = db
         .find_by_merchant_connector_account_merchant_id_merchant_connector_id(
+            key_manager_state,
             merchant_id,
             merchant_connector_id,
             &key_store,
@@ -1559,7 +1647,7 @@ pub async fn update_payment_connector(
         if let Some(val) = req.pm_auth_config.clone() {
             validate_pm_auth(
                 val,
-                db,
+                &state,
                 merchant_id,
                 &key_store,
                 merchant_account,
@@ -1568,7 +1656,6 @@ pub async fn update_payment_connector(
             .await?;
         }
     }
-
     let payment_connector = storage::MerchantConnectorAccountUpdate::Update {
         merchant_id: None,
         connector_type: Some(req.connector_type),
@@ -1578,7 +1665,12 @@ pub async fn update_payment_connector(
         connector_account_details: req
             .connector_account_details
             .async_lift(|inner| {
-                domain_types::encrypt_optional(inner, key_store.key.get_inner().peek())
+                domain_types::encrypt_optional(
+                    key_manager_state,
+                    inner,
+                    km_types::Identifier::Merchant(key_store.merchant_id.clone()),
+                    key_store.key.get_inner().peek(),
+                )
             })
             .await
             .change_context(errors::ApiErrorResponse::InternalServerError)
@@ -1600,7 +1692,7 @@ pub async fn update_payment_connector(
         pm_auth_config: req.pm_auth_config,
         status: Some(connector_status),
         connector_wallets_details: helpers::get_encrypted_apple_pay_connector_wallets_details(
-            &key_store, &metadata,
+            &state, &key_store, &metadata,
         )
         .await?,
     };
@@ -1615,7 +1707,12 @@ pub async fn update_payment_connector(
     let request_connector_label = req.connector_label;
 
     let updated_mca = db
-        .update_merchant_connector_account(mca, payment_connector.into(), &key_store)
+        .update_merchant_connector_account(
+            key_manager_state,
+            mca,
+            payment_connector.into(),
+            &key_store,
+        )
         .await
         .change_context(
             errors::ApiErrorResponse::DuplicateMerchantConnectorAccount {
@@ -1638,18 +1735,24 @@ pub async fn delete_payment_connector(
     merchant_connector_id: String,
 ) -> RouterResponse<api::MerchantConnectorDeleteResponse> {
     let db = state.store.as_ref();
+    let key_manager_state = &(&state).into();
     let key_store = db
-        .get_merchant_key_store_by_merchant_id(&merchant_id, &db.get_master_key().to_vec().into())
+        .get_merchant_key_store_by_merchant_id(
+            key_manager_state,
+            &merchant_id,
+            &db.get_master_key().to_vec().into(),
+        )
         .await
         .to_not_found_response(errors::ApiErrorResponse::MerchantAccountNotFound)?;
 
     let _merchant_account = db
-        .find_merchant_account_by_merchant_id(&merchant_id, &key_store)
+        .find_merchant_account_by_merchant_id(key_manager_state, &merchant_id, &key_store)
         .await
         .to_not_found_response(errors::ApiErrorResponse::MerchantAccountNotFound)?;
 
     let _mca = db
         .find_by_merchant_connector_account_merchant_id_merchant_connector_id(
+            key_manager_state,
             &merchant_id,
             &merchant_connector_id,
             &key_store,
@@ -1683,14 +1786,19 @@ pub async fn kv_for_merchant(
     enable: bool,
 ) -> RouterResponse<api_models::admin::ToggleKVResponse> {
     let db = state.store.as_ref();
+    let key_manager_state = &(&state).into();
     let key_store = db
-        .get_merchant_key_store_by_merchant_id(&merchant_id, &db.get_master_key().to_vec().into())
+        .get_merchant_key_store_by_merchant_id(
+            key_manager_state,
+            &merchant_id,
+            &db.get_master_key().to_vec().into(),
+        )
         .await
         .to_not_found_response(errors::ApiErrorResponse::MerchantAccountNotFound)?;
 
     // check if the merchant account exists
     let merchant_account = db
-        .find_merchant_account_by_merchant_id(&merchant_id, &key_store)
+        .find_merchant_account_by_merchant_id(key_manager_state, &merchant_id, &key_store)
         .await
         .to_not_found_response(errors::ApiErrorResponse::MerchantAccountNotFound)?;
 
@@ -1707,6 +1815,7 @@ pub async fn kv_for_merchant(
             }
 
             db.update_merchant(
+                key_manager_state,
                 merchant_account,
                 storage::MerchantAccountUpdate::StorageSchemeUpdate {
                     storage_scheme: MerchantStorageScheme::RedisKv,
@@ -1717,6 +1826,7 @@ pub async fn kv_for_merchant(
         }
         (false, MerchantStorageScheme::RedisKv) => {
             db.update_merchant(
+                key_manager_state,
                 merchant_account,
                 storage::MerchantAccountUpdate::StorageSchemeUpdate {
                     storage_scheme: MerchantStorageScheme::PostgresOnly,
@@ -1779,14 +1889,19 @@ pub async fn check_merchant_account_kv_status(
     merchant_id: String,
 ) -> RouterResponse<api_models::admin::ToggleKVResponse> {
     let db = state.store.as_ref();
+    let key_manager_state = &(&state).into();
     let key_store = db
-        .get_merchant_key_store_by_merchant_id(&merchant_id, &db.get_master_key().to_vec().into())
+        .get_merchant_key_store_by_merchant_id(
+            key_manager_state,
+            &merchant_id,
+            &db.get_master_key().to_vec().into(),
+        )
         .await
         .to_not_found_response(errors::ApiErrorResponse::MerchantAccountNotFound)?;
 
     // check if the merchant account exists
     let merchant_account = db
-        .find_merchant_account_by_merchant_id(&merchant_id, &key_store)
+        .find_merchant_account_by_merchant_id(key_manager_state, &merchant_id, &key_store)
         .await
         .to_not_found_response(errors::ApiErrorResponse::MerchantAccountNotFound)?;
 
@@ -1825,17 +1940,19 @@ pub fn get_frm_config_as_secret(
 }
 
 pub async fn create_and_insert_business_profile(
-    db: &dyn StorageInterface,
+    state: &SessionState,
     request: api::BusinessProfileCreate,
     merchant_account: domain::MerchantAccount,
     key_store: &domain::MerchantKeyStore,
 ) -> RouterResult<storage::business_profile::BusinessProfile> {
     let business_profile_new =
-        admin::create_business_profile(merchant_account, request, key_store).await?;
+        admin::create_business_profile(state, merchant_account, request, key_store).await?;
 
     let profile_name = business_profile_new.profile_name.clone();
 
-    db.insert_business_profile(business_profile_new)
+    state
+        .store
+        .insert_business_profile(business_profile_new)
         .await
         .to_duplicate_response(errors::ApiErrorResponse::GenericDuplicateError {
             message: format!(
@@ -1859,15 +1976,20 @@ pub async fn create_business_profile(
     }
 
     let db = state.store.as_ref();
+    let key_manager_state = &(&state).into();
     let key_store = db
-        .get_merchant_key_store_by_merchant_id(merchant_id, &db.get_master_key().to_vec().into())
+        .get_merchant_key_store_by_merchant_id(
+            key_manager_state,
+            merchant_id,
+            &db.get_master_key().to_vec().into(),
+        )
         .await
         .to_not_found_response(errors::ApiErrorResponse::MerchantAccountNotFound)?;
 
     // Get the merchant account, if few fields are not passed, then they will be inherited from
     // merchant account
     let merchant_account = db
-        .find_merchant_account_by_merchant_id(merchant_id, &key_store)
+        .find_merchant_account_by_merchant_id(key_manager_state, merchant_id, &key_store)
         .await
         .to_not_found_response(errors::ApiErrorResponse::MerchantAccountNotFound)?;
 
@@ -1882,18 +2004,23 @@ pub async fn create_business_profile(
     }
 
     let business_profile =
-        create_and_insert_business_profile(db, request, merchant_account.clone(), &key_store)
+        create_and_insert_business_profile(&state, request, merchant_account.clone(), &key_store)
             .await?;
 
     if merchant_account.default_profile.is_some() {
         let unset_default_profile = domain::MerchantAccountUpdate::UnsetDefaultProfile;
-        db.update_merchant(merchant_account, unset_default_profile, &key_store)
-            .await
-            .to_not_found_response(errors::ApiErrorResponse::MerchantAccountNotFound)?;
+        db.update_merchant(
+            key_manager_state,
+            merchant_account,
+            unset_default_profile,
+            &key_store,
+        )
+        .await
+        .to_not_found_response(errors::ApiErrorResponse::MerchantAccountNotFound)?;
     }
 
     Ok(service_api::ApplicationResponse::Json(
-        admin::business_profile_response(business_profile, &key_store)
+        admin::business_profile_response(&state, business_profile, &key_store)
             .change_context(errors::ApiErrorResponse::InternalServerError)
             .attach_printable("Failed to parse business profile details")
             .await?,
@@ -1906,7 +2033,11 @@ pub async fn list_business_profile(
 ) -> RouterResponse<Vec<api_models::admin::BusinessProfileResponse>> {
     let db = state.store.as_ref();
     let key_store = db
-        .get_merchant_key_store_by_merchant_id(&merchant_id, &db.get_master_key().to_vec().into())
+        .get_merchant_key_store_by_merchant_id(
+            &(&state).into(),
+            &merchant_id,
+            &db.get_master_key().to_vec().into(),
+        )
         .await
         .to_not_found_response(errors::ApiErrorResponse::MerchantAccountNotFound)?;
     let profiles = db
@@ -1916,7 +2047,7 @@ pub async fn list_business_profile(
         .clone();
     let mut business_profiles = Vec::new();
     for profile in profiles {
-        let business_profile = admin::business_profile_response(profile, &key_store)
+        let business_profile = admin::business_profile_response(&state, profile, &key_store)
             .await
             .change_context(errors::ApiErrorResponse::InternalServerError)
             .attach_printable("Failed to parse business profile details")?;
@@ -1933,7 +2064,11 @@ pub async fn retrieve_business_profile(
 ) -> RouterResponse<api_models::admin::BusinessProfileResponse> {
     let db = state.store.as_ref();
     let key_store = db
-        .get_merchant_key_store_by_merchant_id(&merchant_id, &db.get_master_key().to_vec().into())
+        .get_merchant_key_store_by_merchant_id(
+            &(&state).into(),
+            &merchant_id,
+            &db.get_master_key().to_vec().into(),
+        )
         .await
         .to_not_found_response(errors::ApiErrorResponse::MerchantAccountNotFound)?;
     let business_profile = db
@@ -1944,7 +2079,7 @@ pub async fn retrieve_business_profile(
         })?;
 
     Ok(service_api::ApplicationResponse::Json(
-        admin::business_profile_response(business_profile, &key_store)
+        admin::business_profile_response(&state, business_profile, &key_store)
             .change_context(errors::ApiErrorResponse::InternalServerError)
             .attach_printable("Failed to parse business profile details")
             .await?,
@@ -1982,6 +2117,7 @@ pub async fn update_business_profile(
         })?;
     let key_store = db
         .get_merchant_key_store_by_merchant_id(
+            &(&state).into(),
             merchant_id,
             &state.store.get_master_key().to_vec().into(),
         )
@@ -2051,7 +2187,7 @@ pub async fn update_business_profile(
         .map(Secret::new);
     let outgoing_webhook_custom_http_headers = request
         .outgoing_webhook_custom_http_headers
-        .async_map(|headers| create_encrypted_data(&key_store, headers))
+        .async_map(|headers| create_encrypted_data(&state, &key_store, headers))
         .await
         .transpose()
         .change_context(errors::ApiErrorResponse::InternalServerError)
@@ -2119,7 +2255,7 @@ pub async fn update_business_profile(
         })?;
 
     Ok(service_api::ApplicationResponse::Json(
-        admin::business_profile_response(updated_business_profile, &key_store)
+        admin::business_profile_response(&state, updated_business_profile, &key_store)
             .change_context(errors::ApiErrorResponse::InternalServerError)
             .attach_printable("Failed to parse business profile details")
             .await?,
diff --git a/crates/router/src/core/api_keys.rs b/crates/router/src/core/api_keys.rs
index df8a55cd718..6af82a6b7a8 100644
--- a/crates/router/src/core/api_keys.rs
+++ b/crates/router/src/core/api_keys.rs
@@ -122,6 +122,7 @@ pub async fn create_api_key(
     // non-existence of a merchant account.
     store
         .get_merchant_key_store_by_merchant_id(
+            &(&state).into(),
             merchant_id.as_str(),
             &store.get_master_key().to_vec().into(),
         )
diff --git a/crates/router/src/core/apple_pay_certificates_migration.rs b/crates/router/src/core/apple_pay_certificates_migration.rs
index 327358bda50..87c15935715 100644
--- a/crates/router/src/core/apple_pay_certificates_migration.rs
+++ b/crates/router/src/core/apple_pay_certificates_migration.rs
@@ -1,5 +1,5 @@
 use api_models::apple_pay_certificates_migration;
-use common_utils::errors::CustomResult;
+use common_utils::{errors::CustomResult, types::keymanager::Identifier};
 use error_stack::ResultExt;
 use masking::{PeekInterface, Secret};
 
@@ -28,11 +28,12 @@ pub async fn apple_pay_certificates_migration(
 
     let mut migration_successful_merchant_ids = vec![];
     let mut migration_failed_merchant_ids = vec![];
-
+    let key_manager_state = &(&state).into();
     for merchant_id in merchant_id_list {
         let key_store = state
             .store
             .get_merchant_key_store_by_merchant_id(
+                key_manager_state,
                 merchant_id,
                 &state.store.get_master_key().to_vec().into(),
             )
@@ -41,6 +42,7 @@ pub async fn apple_pay_certificates_migration(
 
         let merchant_connector_accounts = db
             .find_merchant_connector_account_by_merchant_id_and_disabled_list(
+                key_manager_state,
                 merchant_id,
                 true,
                 &key_store,
@@ -63,11 +65,13 @@ pub async fn apple_pay_certificates_migration(
                     .ok();
             if let Some(apple_pay_metadata) = connector_apple_pay_metadata {
                 let encrypted_apple_pay_metadata = domain_types::encrypt(
+                    &(&state).into(),
                     Secret::new(
                         serde_json::to_value(apple_pay_metadata)
                             .change_context(errors::ApiErrorResponse::InternalServerError)
                             .attach_printable("Failed to serialize apple pay metadata as JSON")?,
                     ),
+                    Identifier::Merchant(merchant_id.clone()),
                     key_store.key.get_inner().peek(),
                 )
                 .await
diff --git a/crates/router/src/core/blocklist/utils.rs b/crates/router/src/core/blocklist/utils.rs
index 97324effa80..c739a86ee51 100644
--- a/crates/router/src/core/blocklist/utils.rs
+++ b/crates/router/src/core/blocklist/utils.rs
@@ -398,6 +398,7 @@ where
     if should_payment_be_blocked {
         // Update db for attempt and intent status.
         db.update_payment_intent(
+            &state.into(),
             payment_data.payment_intent.clone(),
             storage::PaymentIntentUpdate::RejectUpdate {
                 status: common_enums::IntentStatus::Failed,
diff --git a/crates/router/src/core/cards_info.rs b/crates/router/src/core/cards_info.rs
index b0c1aca5322..98719b5a1e6 100644
--- a/crates/router/src/core/cards_info.rs
+++ b/crates/router/src/core/cards_info.rs
@@ -30,7 +30,7 @@ pub async fn retrieve_card_info(
 
     verify_iin_length(&request.card_iin)?;
     helpers::verify_payment_intent_time_and_client_secret(
-        db,
+        &state,
         &merchant_account,
         &key_store,
         request.client_secret,
diff --git a/crates/router/src/core/conditional_config.rs b/crates/router/src/core/conditional_config.rs
index f740c6dfcc2..c34f8e7116d 100644
--- a/crates/router/src/core/conditional_config.rs
+++ b/crates/router/src/core/conditional_config.rs
@@ -102,7 +102,7 @@ pub async fn upsert_conditional_config(
 
             algo_id.update_conditional_config_id(key.clone());
             let config_key = cache::CacheKind::DecisionManager(key.into());
-            update_merchant_active_algorithm_ref(db, &key_store, config_key, algo_id)
+            update_merchant_active_algorithm_ref(&state, &key_store, config_key, algo_id)
                 .await
                 .change_context(errors::ApiErrorResponse::InternalServerError)
                 .attach_printable("Failed to update routing algorithm ref")?;
@@ -138,7 +138,7 @@ pub async fn upsert_conditional_config(
 
             algo_id.update_conditional_config_id(key.clone());
             let config_key = cache::CacheKind::DecisionManager(key.into());
-            update_merchant_active_algorithm_ref(db, &key_store, config_key, algo_id)
+            update_merchant_active_algorithm_ref(&state, &key_store, config_key, algo_id)
                 .await
                 .change_context(errors::ApiErrorResponse::InternalServerError)
                 .attach_printable("Failed to update routing algorithm ref")?;
@@ -168,7 +168,7 @@ pub async fn delete_conditional_config(
         .unwrap_or_default();
     algo_id.config_algo_id = None;
     let config_key = cache::CacheKind::DecisionManager(key.clone().into());
-    update_merchant_active_algorithm_ref(db, &key_store, config_key, algo_id)
+    update_merchant_active_algorithm_ref(&state, &key_store, config_key, algo_id)
         .await
         .change_context(errors::ApiErrorResponse::InternalServerError)
         .attach_printable("Failed to update deleted algorithm ref")?;
diff --git a/crates/router/src/core/customers.rs b/crates/router/src/core/customers.rs
index c0e0291b8c4..e9126200acc 100644
--- a/crates/router/src/core/customers.rs
+++ b/crates/router/src/core/customers.rs
@@ -1,10 +1,12 @@
+use api_models::customers::CustomerRequestWithEmail;
 use common_utils::{
     crypto::{Encryptable, GcmAes256},
     errors::ReportSwitchExt,
     ext_traits::OptionExt,
+    types::keymanager::{Identifier, ToEncryptable},
 };
 use error_stack::{report, ResultExt};
-use masking::ExposeInterface;
+use masking::{Secret, SwitchStrategy};
 use router_env::{instrument, tracing};
 
 use crate::{
@@ -19,7 +21,7 @@ use crate::{
         api::customers,
         domain::{
             self,
-            types::{self, AsyncLift, TypeEncryption},
+            types::{self, TypeEncryption},
         },
         storage::{self, enums},
     },
@@ -43,6 +45,7 @@ pub async fn create_customer(
 
     let merchant_id = &merchant_account.merchant_id;
     merchant_id.clone_into(&mut customer_data.merchant_id);
+    let key_manager_state = &(&state).into();
 
     // We first need to validate whether the customer with the given customer id already exists
     // this may seem like a redundant db call, as the insert_customer will anyway return this error
@@ -51,6 +54,7 @@ pub async fn create_customer(
     // it errors out, now the address that was inserted is not deleted
     match db
         .find_customer_by_customer_id_merchant_id(
+            key_manager_state,
             &customer_id,
             merchant_id,
             &key_store,
@@ -76,6 +80,7 @@ pub async fn create_customer(
 
         let address = customer_data
             .get_domain_address(
+                &state,
                 customer_address,
                 merchant_id,
                 &customer_id,
@@ -87,7 +92,7 @@ pub async fn create_customer(
             .attach_printable("Failed while encrypting address")?;
 
         Some(
-            db.insert_address_for_customers(address, &key_store)
+            db.insert_address_for_customers(key_manager_state, address, &key_store)
                 .await
                 .switch()
                 .attach_printable("Failed while inserting new address")?,
@@ -96,40 +101,46 @@ pub async fn create_customer(
         None
     };
 
-    let new_customer = async {
-        Ok(domain::Customer {
-            customer_id: customer_id.to_owned(),
-            merchant_id: merchant_id.to_string(),
-            name: customer_data
-                .name
-                .async_lift(|inner| types::encrypt_optional(inner, key))
-                .await?,
-            email: customer_data
-                .email
-                .async_lift(|inner| types::encrypt_optional(inner.map(|inner| inner.expose()), key))
-                .await?,
-            phone: customer_data
-                .phone
-                .async_lift(|inner| types::encrypt_optional(inner, key))
-                .await?,
-            description: customer_data.description,
-            phone_country_code: customer_data.phone_country_code,
-            metadata: customer_data.metadata,
-            id: None,
-            connector_customer: None,
-            address_id: address.clone().map(|addr| addr.address_id),
-            created_at: common_utils::date_time::now(),
-            modified_at: common_utils::date_time::now(),
-            default_payment_method_id: None,
-            updated_by: None,
-        })
-    }
+    let encrypted_data = types::batch_encrypt(
+        &(&state).into(),
+        CustomerRequestWithEmail::to_encryptable(CustomerRequestWithEmail {
+            name: customer_data.name.clone(),
+            email: customer_data.email.clone(),
+            phone: customer_data.phone.clone(),
+        }),
+        Identifier::Merchant(key_store.merchant_id.clone()),
+        key,
+    )
     .await
     .switch()
     .attach_printable("Failed while encrypting Customer")?;
+    let encryptable_customer = CustomerRequestWithEmail::from_encryptable(encrypted_data)
+        .change_context(errors::CustomersErrorResponse::InternalServerError)?;
+    let new_customer = domain::Customer {
+        customer_id: customer_id.to_owned(),
+        merchant_id: merchant_id.to_string(),
+        name: encryptable_customer.name,
+        email: encryptable_customer.email,
+        phone: encryptable_customer.phone,
+        description: customer_data.description,
+        phone_country_code: customer_data.phone_country_code,
+        metadata: customer_data.metadata,
+        id: None,
+        connector_customer: None,
+        address_id: address.clone().map(|addr| addr.address_id),
+        created_at: common_utils::date_time::now(),
+        modified_at: common_utils::date_time::now(),
+        default_payment_method_id: None,
+        updated_by: None,
+    };
 
     let customer = db
-        .insert_customer(new_customer, &key_store, merchant_account.storage_scheme)
+        .insert_customer(
+            key_manager_state,
+            new_customer,
+            &key_store,
+            merchant_account.storage_scheme,
+        )
         .await
         .to_duplicate_response(errors::CustomersErrorResponse::CustomerAlreadyExists)?;
 
@@ -148,8 +159,10 @@ pub async fn retrieve_customer(
     req: customers::CustomerId,
 ) -> errors::CustomerResponse<customers::CustomerResponse> {
     let db = state.store.as_ref();
+    let key_manager_state = &(&state).into();
     let response = db
         .find_customer_by_customer_id_merchant_id(
+            key_manager_state,
             &req.customer_id,
             &merchant_account.merchant_id,
             &key_store,
@@ -159,7 +172,7 @@ pub async fn retrieve_customer(
         .switch()?;
     let address = match &response.address_id {
         Some(address_id) => Some(api_models::payments::AddressDetails::from(
-            db.find_address_by_address_id(address_id, &key_store)
+            db.find_address_by_address_id(key_manager_state, address_id, &key_store)
                 .await
                 .switch()?,
         )),
@@ -179,7 +192,7 @@ pub async fn list_customers(
     let db = state.store.as_ref();
 
     let domain_customers = db
-        .list_customers_by_merchant_id(&merchant_id, &key_store)
+        .list_customers_by_merchant_id(&(&state).into(), &merchant_id, &key_store)
         .await
         .switch()?;
 
@@ -199,9 +212,10 @@ pub async fn delete_customer(
     key_store: domain::MerchantKeyStore,
 ) -> errors::CustomerResponse<customers::CustomerDeleteResponse> {
     let db = &state.store;
-
+    let key_manager_state = &(&state).into();
     let customer_orig = db
         .find_customer_by_customer_id_merchant_id(
+            key_manager_state,
             &req.customer_id,
             &merchant_account.merchant_id,
             &key_store,
@@ -262,17 +276,24 @@ pub async fn delete_customer(
     };
 
     let key = key_store.key.get_inner().peek();
+    let identifier = Identifier::Merchant(key_store.merchant_id.clone());
+    let redacted_encrypted_value: Encryptable<Secret<_>> = Encryptable::encrypt_via_api(
+        key_manager_state,
+        REDACTED.to_string().into(),
+        identifier.clone(),
+        key,
+        GcmAes256,
+    )
+    .await
+    .switch()?;
 
-    let redacted_encrypted_value: Encryptable<masking::Secret<_>> =
-        Encryptable::encrypt(REDACTED.to_string().into(), key, GcmAes256)
-            .await
-            .switch()?;
-
-    let redacted_encrypted_email: Encryptable<
-        masking::Secret<_, common_utils::pii::EmailStrategy>,
-    > = Encryptable::encrypt(REDACTED.to_string().into(), key, GcmAes256)
-        .await
-        .switch()?;
+    let redacted_encrypted_email = Encryptable::new(
+        redacted_encrypted_value
+            .clone()
+            .into_inner()
+            .switch_strategy(),
+        redacted_encrypted_value.clone().into_encrypted(),
+    );
 
     let update_address = storage::AddressUpdate::Update {
         city: Some(REDACTED.to_string()),
@@ -292,6 +313,7 @@ pub async fn delete_customer(
 
     match db
         .update_address_by_merchant_id_customer_id(
+            key_manager_state,
             &req.customer_id,
             &merchant_account.merchant_id,
             update_address,
@@ -314,9 +336,15 @@ pub async fn delete_customer(
     let updated_customer = storage::CustomerUpdate::Update {
         name: Some(redacted_encrypted_value.clone()),
         email: Some(
-            Encryptable::encrypt(REDACTED.to_string().into(), key, GcmAes256)
-                .await
-                .switch()?,
+            Encryptable::encrypt_via_api(
+                key_manager_state,
+                REDACTED.to_string().into(),
+                identifier,
+                key,
+                GcmAes256,
+            )
+            .await
+            .switch()?,
         ),
         phone: Box::new(Some(redacted_encrypted_value.clone())),
         description: Some(REDACTED.to_string()),
@@ -326,6 +354,7 @@ pub async fn delete_customer(
         address_id: None,
     };
     db.update_customer_by_customer_id_merchant_id(
+        key_manager_state,
         req.customer_id.clone(),
         merchant_account.merchant_id,
         customer_orig,
@@ -362,9 +391,10 @@ pub async fn update_customer(
         .get_required_value("customer_id")
         .change_context(errors::CustomersErrorResponse::InternalServerError)
         .attach("Missing required field `customer_id`")?;
-
+    let key_manager_state = &(&state).into();
     let customer = db
         .find_customer_by_customer_id_merchant_id(
+            key_manager_state,
             customer_id,
             &merchant_account.merchant_id,
             &key_store,
@@ -380,12 +410,18 @@ pub async fn update_customer(
             Some(address_id) => {
                 let customer_address: api_models::payments::AddressDetails = addr.clone();
                 let update_address = update_customer
-                    .get_address_update(customer_address, key, merchant_account.storage_scheme)
+                    .get_address_update(
+                        &state,
+                        customer_address,
+                        key,
+                        merchant_account.storage_scheme,
+                        merchant_account.merchant_id.clone(),
+                    )
                     .await
                     .switch()
                     .attach_printable("Failed while encrypting Address while Update")?;
                 Some(
-                    db.update_address(address_id, update_address, &key_store)
+                    db.update_address(key_manager_state, address_id, update_address, &key_store)
                         .await
                         .switch()
                         .attach_printable(format!(
@@ -399,6 +435,7 @@ pub async fn update_customer(
 
                 let address = update_customer
                     .get_domain_address(
+                        &state,
                         customer_address,
                         &merchant_account.merchant_id,
                         &customer.customer_id,
@@ -409,7 +446,7 @@ pub async fn update_customer(
                     .switch()
                     .attach_printable("Failed while encrypting address")?;
                 Some(
-                    db.insert_address_for_customers(address, &key_store)
+                    db.insert_address_for_customers(key_manager_state, address, &key_store)
                         .await
                         .switch()
                         .attach_printable("Failed while inserting new address")?,
@@ -419,47 +456,44 @@ pub async fn update_customer(
     } else {
         match &customer.address_id {
             Some(address_id) => Some(
-                db.find_address_by_address_id(address_id, &key_store)
+                db.find_address_by_address_id(key_manager_state, address_id, &key_store)
                     .await
                     .switch()?,
             ),
             None => None,
         }
     };
+    let encrypted_data = types::batch_encrypt(
+        &(&state).into(),
+        CustomerRequestWithEmail::to_encryptable(CustomerRequestWithEmail {
+            name: update_customer.name.clone(),
+            email: update_customer.email.clone(),
+            phone: update_customer.phone.clone(),
+        }),
+        Identifier::Merchant(key_store.merchant_id.clone()),
+        key,
+    )
+    .await
+    .switch()?;
+    let encryptable_customer = CustomerRequestWithEmail::from_encryptable(encrypted_data)
+        .change_context(errors::CustomersErrorResponse::InternalServerError)?;
 
     let response = db
         .update_customer_by_customer_id_merchant_id(
+            key_manager_state,
             customer_id.to_owned(),
             merchant_account.merchant_id.to_owned(),
             customer,
-            async {
-                Ok(storage::CustomerUpdate::Update {
-                    name: update_customer
-                        .name
-                        .async_lift(|inner| types::encrypt_optional(inner, key))
-                        .await?,
-                    email: update_customer
-                        .email
-                        .async_lift(|inner| {
-                            types::encrypt_optional(inner.map(|inner| inner.expose()), key)
-                        })
-                        .await?,
-                    phone: Box::new(
-                        update_customer
-                            .phone
-                            .async_lift(|inner| types::encrypt_optional(inner, key))
-                            .await?,
-                    ),
-                    phone_country_code: update_customer.phone_country_code,
-                    metadata: update_customer.metadata,
-                    description: update_customer.description,
-                    connector_customer: None,
-                    address_id: address.clone().map(|addr| addr.address_id),
-                })
-            }
-            .await
-            .switch()
-            .attach_printable("Failed while encrypting while updating customer")?,
+            storage::CustomerUpdate::Update {
+                name: encryptable_customer.name,
+                email: encryptable_customer.email,
+                phone: Box::new(encryptable_customer.phone),
+                phone_country_code: update_customer.phone_country_code,
+                metadata: update_customer.metadata,
+                description: update_customer.description,
+                connector_customer: None,
+                address_id: address.clone().map(|addr| addr.address_id),
+            },
             &key_store,
             merchant_account.storage_scheme,
         )
diff --git a/crates/router/src/core/disputes.rs b/crates/router/src/core/disputes.rs
index 2d2d7bbcaeb..6a7f531f5a0 100644
--- a/crates/router/src/core/disputes.rs
+++ b/crates/router/src/core/disputes.rs
@@ -89,6 +89,7 @@ pub async fn accept_dispute(
     )?;
     let payment_intent = db
         .find_payment_intent_by_payment_id_merchant_id(
+            &(&state).into(),
             &dispute.payment_id,
             &merchant_account.merchant_id,
             &key_store,
@@ -202,6 +203,7 @@ pub async fn submit_evidence(
     .await?;
     let payment_intent = db
         .find_payment_intent_by_payment_id_merchant_id(
+            &(&state).into(),
             &dispute.payment_id,
             &merchant_account.merchant_id,
             &key_store,
diff --git a/crates/router/src/core/encryption.rs b/crates/router/src/core/encryption.rs
index 7f7945bfd1c..efd7d3bfeaa 100644
--- a/crates/router/src/core/encryption.rs
+++ b/crates/router/src/core/encryption.rs
@@ -14,7 +14,7 @@ pub async fn transfer_encryption_key(
 ) -> errors::CustomResult<usize, errors::ApiErrorResponse> {
     let db = &*state.store;
     let key_stores = db
-        .get_all_key_stores(&db.get_master_key().to_vec().into())
+        .get_all_key_stores(&state.into(), &db.get_master_key().to_vec().into())
         .await
         .change_context(errors::ApiErrorResponse::InternalServerError)?;
     send_request_to_key_service_for_merchant(state, key_stores).await
diff --git a/crates/router/src/core/files/helpers.rs b/crates/router/src/core/files/helpers.rs
index 3a565865603..ed95e7790e7 100644
--- a/crates/router/src/core/files/helpers.rs
+++ b/crates/router/src/core/files/helpers.rs
@@ -261,6 +261,7 @@ pub async fn upload_and_get_provider_provider_file_id_profile_id(
                 let payment_intent = state
                     .store
                     .find_payment_intent_by_payment_id_merchant_id(
+                        &state.into(),
                         &dispute.payment_id,
                         &merchant_account.merchant_id,
                         key_store,
diff --git a/crates/router/src/core/fraud_check.rs b/crates/router/src/core/fraud_check.rs
index 331eb430211..8ddd0b7aa24 100644
--- a/crates/router/src/core/fraud_check.rs
+++ b/crates/router/src/core/fraud_check.rs
@@ -123,7 +123,7 @@ where
 pub async fn should_call_frm<F>(
     merchant_account: &domain::MerchantAccount,
     payment_data: &payments::PaymentData<F>,
-    db: &dyn StorageInterface,
+    state: &SessionState,
     key_store: domain::MerchantKeyStore,
 ) -> RouterResult<(
     bool,
@@ -136,6 +136,7 @@ where
 {
     match merchant_account.frm_routing_algorithm.clone() {
         Some(frm_routing_algorithm_value) => {
+            let db = &*state.store;
             let frm_routing_algorithm_struct: FrmRoutingAlgorithm = frm_routing_algorithm_value
                 .clone()
                 .parse_value("FrmRoutingAlgorithm")
@@ -157,6 +158,7 @@ where
 
             let merchant_connector_account_from_db_option = db
                 .find_merchant_connector_account_by_profile_id_connector_name(
+                    &state.into(),
                     &profile_id,
                     &frm_routing_algorithm_struct.data,
                     &key_store,
@@ -417,7 +419,7 @@ where
                 let frm_data_updated = fraud_check_operation
                     .to_update_tracker()?
                     .update_tracker(
-                        &*state.store,
+                        state,
                         &key_store,
                         frm_data.clone(),
                         payment_data,
@@ -492,7 +494,7 @@ where
                 let mut frm_data = fraud_check_operation
                     .to_update_tracker()?
                     .update_tracker(
-                        &*state.store,
+                        state,
                         &key_store,
                         frm_data.to_owned(),
                         payment_data,
@@ -527,7 +529,7 @@ where
                 let updated_frm_data = fraud_check_operation
                     .to_update_tracker()?
                     .update_tracker(
-                        &*state.store,
+                        state,
                         &key_store,
                         frm_data.to_owned(),
                         payment_data,
@@ -547,7 +549,6 @@ where
 
 #[allow(clippy::too_many_arguments)]
 pub async fn call_frm_before_connector_call<'a, F, Req>(
-    db: &dyn StorageInterface,
     operation: &BoxedOperation<'_, F, Req>,
     merchant_account: &domain::MerchantAccount,
     payment_data: &mut payments::PaymentData<F>,
@@ -562,13 +563,13 @@ where
     F: Send + Clone,
 {
     let (is_frm_enabled, frm_routing_algorithm, frm_connector_label, frm_configs) =
-        should_call_frm(merchant_account, payment_data, db, key_store.clone()).await?;
+        should_call_frm(merchant_account, payment_data, state, key_store.clone()).await?;
     if let Some((frm_routing_algorithm_val, profile_id)) =
         frm_routing_algorithm.zip(frm_connector_label)
     {
         if let Some(frm_configs) = frm_configs.clone() {
             let mut updated_frm_info = Box::pin(make_frm_data_and_fraud_check_operation(
-                db,
+                &*state.store,
                 state,
                 merchant_account,
                 payment_data.to_owned(),
@@ -655,6 +656,7 @@ pub async fn frm_fulfillment_core(
     let db = &*state.clone().store;
     let payment_intent = db
         .find_payment_intent_by_payment_id_merchant_id(
+            &(&state).into(),
             &req.payment_id.clone(),
             &merchant_account.merchant_id,
             &key_store,
diff --git a/crates/router/src/core/fraud_check/operation.rs b/crates/router/src/core/fraud_check/operation.rs
index 8c6f8b7bf52..2d159d2e220 100644
--- a/crates/router/src/core/fraud_check/operation.rs
+++ b/crates/router/src/core/fraud_check/operation.rs
@@ -14,7 +14,6 @@ use crate::{
         errors::{self, RouterResult},
         payments,
     },
-    db::StorageInterface,
     routes::{app::ReqState, SessionState},
     types::{domain, fraud_check::FrmRouterData},
 };
@@ -101,7 +100,7 @@ pub trait Domain<F>: Send + Sync {
 pub trait UpdateTracker<D, F: Clone>: Send {
     async fn update_tracker<'b>(
         &'b self,
-        db: &dyn StorageInterface,
+        state: &SessionState,
         key_store: &domain::MerchantKeyStore,
         frm_data: D,
         payment_data: &mut payments::PaymentData<F>,
diff --git a/crates/router/src/core/fraud_check/operation/fraud_check_post.rs b/crates/router/src/core/fraud_check/operation/fraud_check_post.rs
index 7c97eee8b49..698eb43385e 100644
--- a/crates/router/src/core/fraud_check/operation/fraud_check_post.rs
+++ b/crates/router/src/core/fraud_check/operation/fraud_check_post.rs
@@ -19,7 +19,6 @@ use crate::{
         },
         payments,
     },
-    db::StorageInterface,
     errors,
     routes::app::ReqState,
     services::{self, api},
@@ -329,13 +328,14 @@ impl<F: Send + Clone> Domain<F> for FraudCheckPost {
 impl<F: Clone + Send> UpdateTracker<FrmData, F> for FraudCheckPost {
     async fn update_tracker<'b>(
         &'b self,
-        db: &dyn StorageInterface,
+        state: &SessionState,
         key_store: &domain::MerchantKeyStore,
         mut frm_data: FrmData,
         payment_data: &mut payments::PaymentData<F>,
         frm_suggestion: Option<FrmSuggestion>,
         frm_router_data: FrmRouterData,
     ) -> RouterResult<FrmData> {
+        let db = &*state.store;
         let frm_check_update = match frm_router_data.response {
             FrmResponse::Sale(response) => match response {
                 Err(err) => Some(FraudCheckUpdate::ErrorUpdate {
@@ -515,6 +515,7 @@ impl<F: Clone + Send> UpdateTracker<FrmData, F> for FraudCheckPost {
 
             payment_data.payment_intent = db
                 .update_payment_intent(
+                    &state.into(),
                     payment_data.payment_intent.clone(),
                     PaymentIntentUpdate::RejectUpdate {
                         status: payment_intent_status,
diff --git a/crates/router/src/core/fraud_check/operation/fraud_check_pre.rs b/crates/router/src/core/fraud_check/operation/fraud_check_pre.rs
index c153acc7544..6a0bd78130d 100644
--- a/crates/router/src/core/fraud_check/operation/fraud_check_pre.rs
+++ b/crates/router/src/core/fraud_check/operation/fraud_check_pre.rs
@@ -16,7 +16,6 @@ use crate::{
         },
         payments,
     },
-    db::StorageInterface,
     errors,
     routes::app::ReqState,
     types::{
@@ -218,7 +217,7 @@ impl<F: Send + Clone> Domain<F> for FraudCheckPre {
 impl<F: Clone + Send> UpdateTracker<FrmData, F> for FraudCheckPre {
     async fn update_tracker<'b>(
         &'b self,
-        db: &dyn StorageInterface,
+        state: &SessionState,
         _key_store: &domain::MerchantKeyStore,
         mut frm_data: FrmData,
         payment_data: &mut payments::PaymentData<F>,
@@ -337,6 +336,7 @@ impl<F: Clone + Send> UpdateTracker<FrmData, F> for FraudCheckPre {
             }),
         };
 
+        let db = &*state.store;
         frm_data.fraud_check = match frm_check_update {
             Some(fraud_check_update) => db
                 .update_fraud_check_response_with_attempt_id(
diff --git a/crates/router/src/core/locker_migration.rs b/crates/router/src/core/locker_migration.rs
index 24ba06bcf36..22b3b29e03b 100644
--- a/crates/router/src/core/locker_migration.rs
+++ b/crates/router/src/core/locker_migration.rs
@@ -17,10 +17,11 @@ pub async fn rust_locker_migration(
     merchant_id: &str,
 ) -> CustomResult<services::ApplicationResponse<MigrateCardResponse>, errors::ApiErrorResponse> {
     let db = state.store.as_ref();
-
+    let key_manager_state = &(&state).into();
     let key_store = state
         .store
         .get_merchant_key_store_by_merchant_id(
+            key_manager_state,
             merchant_id,
             &state.store.get_master_key().to_vec().into(),
         )
@@ -28,13 +29,13 @@ pub async fn rust_locker_migration(
         .change_context(errors::ApiErrorResponse::InternalServerError)?;
 
     let merchant_account = db
-        .find_merchant_account_by_merchant_id(merchant_id, &key_store)
+        .find_merchant_account_by_merchant_id(key_manager_state, merchant_id, &key_store)
         .await
         .to_not_found_response(errors::ApiErrorResponse::MerchantAccountNotFound)
         .change_context(errors::ApiErrorResponse::InternalServerError)?;
 
     let domain_customers = db
-        .list_customers_by_merchant_id(merchant_id, &key_store)
+        .list_customers_by_merchant_id(key_manager_state, merchant_id, &key_store)
         .await
         .change_context(errors::ApiErrorResponse::InternalServerError)?;
 
diff --git a/crates/router/src/core/mandate/helpers.rs b/crates/router/src/core/mandate/helpers.rs
index 2bb981d03e8..a4eb18371f0 100644
--- a/crates/router/src/core/mandate/helpers.rs
+++ b/crates/router/src/core/mandate/helpers.rs
@@ -21,6 +21,7 @@ pub async fn get_profile_id_for_mandate(
         let pi = state
             .store
             .find_payment_intent_by_payment_id_merchant_id(
+                &state.into(),
                 payment_id,
                 &merchant_account.merchant_id,
                 key_store,
diff --git a/crates/router/src/core/payment_link.rs b/crates/router/src/core/payment_link.rs
index 49e4885dc93..bf50405ba81 100644
--- a/crates/router/src/core/payment_link.rs
+++ b/crates/router/src/core/payment_link.rs
@@ -59,6 +59,7 @@ pub async fn initiate_payment_link_flow(
     let db = &*state.store;
     let payment_intent = db
         .find_payment_intent_by_payment_id_merchant_id(
+            &(&state).into(),
             &payment_id,
             &merchant_id,
             &key_store,
@@ -497,6 +498,7 @@ pub async fn get_payment_link_status(
     let db = &*state.store;
     let payment_intent = db
         .find_payment_intent_by_payment_id_merchant_id(
+            &(&state).into(),
             &payment_id,
             &merchant_id,
             &key_store,
diff --git a/crates/router/src/core/payment_methods.rs b/crates/router/src/core/payment_methods.rs
index b9e21b616c0..86cb1fc1b1e 100644
--- a/crates/router/src/core/payment_methods.rs
+++ b/crates/router/src/core/payment_methods.rs
@@ -266,6 +266,7 @@ pub async fn render_pm_collect_link(
                 // Fetch customer
                 let customer = db
                     .find_customer_by_customer_id_merchant_id(
+                        &(&state).into(),
                         &customer_id,
                         &req.merchant_id,
                         &key_store,
diff --git a/crates/router/src/core/payment_methods/cards.rs b/crates/router/src/core/payment_methods/cards.rs
index 468bc0dbfc3..431826fbdb0 100644
--- a/crates/router/src/core/payment_methods/cards.rs
+++ b/crates/router/src/core/payment_methods/cards.rs
@@ -23,11 +23,15 @@ use common_enums::enums::MerchantStorageScheme;
 use common_utils::{
     consts,
     crypto::Encryptable,
+    encryption::Encryption,
     ext_traits::{AsyncExt, Encode, StringExt, ValueExt},
     generate_id, id_type,
-    types::MinorUnit,
+    types::{
+        keymanager::{Identifier, KeyManagerState},
+        MinorUnit,
+    },
 };
-use diesel_models::{business_profile::BusinessProfile, encryption::Encryption, payment_method};
+use diesel_models::{business_profile::BusinessProfile, payment_method};
 use domain::CustomerUpdate;
 use error_stack::{report, ResultExt};
 use euclid::{
@@ -77,7 +81,7 @@ use crate::{
 #[instrument(skip_all)]
 #[allow(clippy::too_many_arguments)]
 pub async fn create_payment_method(
-    db: &dyn db::StorageInterface,
+    state: &routes::SessionState,
     req: &api::PaymentMethodCreate,
     customer_id: &id_type::CustomerId,
     payment_method_id: &str,
@@ -94,8 +98,10 @@ pub async fn create_payment_method(
     payment_method_billing_address: Option<Encryption>,
     card_scheme: Option<String>,
 ) -> errors::CustomResult<storage::PaymentMethod, errors::ApiErrorResponse> {
+    let db = &*state.store;
     let customer = db
         .find_customer_by_customer_id_merchant_id(
+            &state.into(),
             customer_id,
             merchant_id,
             key_store,
@@ -153,7 +159,7 @@ pub async fn create_payment_method(
 
     if customer.default_payment_method_id.is_none() && req.payment_method.is_some() {
         let _ = set_default_payment_method(
-            db,
+            state,
             merchant_id.to_string(),
             key_store.clone(),
             customer_id,
@@ -197,7 +203,7 @@ pub fn store_default_payment_method(
 }
 #[instrument(skip_all)]
 pub async fn get_or_insert_payment_method(
-    db: &dyn db::StorageInterface,
+    state: &routes::SessionState,
     req: api::PaymentMethodCreate,
     resp: &mut api::PaymentMethodResponse,
     merchant_account: &domain::MerchantAccount,
@@ -206,6 +212,7 @@ pub async fn get_or_insert_payment_method(
 ) -> errors::RouterResult<diesel_models::PaymentMethod> {
     let mut payment_method_id = resp.payment_method_id.clone();
     let mut locker_id = None;
+    let db = &*state.store;
     let payment_method = {
         let existing_pm_by_pmid = db
             .find_payment_method(&payment_method_id, merchant_account.storage_scheme)
@@ -240,7 +247,7 @@ pub async fn get_or_insert_payment_method(
         Err(err) => {
             if err.current_context().is_db_not_found() {
                 insert_payment_method(
-                    db,
+                    state,
                     resp,
                     &req,
                     key_store,
@@ -278,7 +285,7 @@ pub async fn migrate_payment_method(
 
     if let Some(connector_mandate_details) = &req.connector_mandate_details {
         helpers::validate_merchant_connector_ids_in_connector_mandate_details(
-            &*state.store,
+            &state,
             key_store,
             connector_mandate_details,
             merchant_id,
@@ -294,7 +301,7 @@ pub async fn migrate_payment_method(
                     &req,
                 );
             get_client_secret_or_add_payment_method(
-                state,
+                &state,
                 payment_method_create_request,
                 merchant_account,
                 key_store,
@@ -338,7 +345,7 @@ pub async fn skip_locker_call_and_migrate_payment_method(
     let payment_method_billing_address: Option<Encryptable<Secret<serde_json::Value>>> = req
         .billing
         .clone()
-        .async_map(|billing| create_encrypted_data(key_store, billing))
+        .async_map(|billing| create_encrypted_data(&state, key_store, billing))
         .await
         .transpose()
         .change_context(errors::ApiErrorResponse::InternalServerError)
@@ -346,6 +353,7 @@ pub async fn skip_locker_call_and_migrate_payment_method(
 
     let customer = db
         .find_customer_by_customer_id_merchant_id(
+            &(&state).into(),
             &customer_id,
             &merchant_id,
             key_store,
@@ -475,7 +483,7 @@ pub async fn skip_locker_call_and_migrate_payment_method(
 
     let payment_method_data_encrypted: Option<Encryptable<Secret<serde_json::Value>>> =
         payment_method_card_details
-            .async_map(|card_details| create_encrypted_data(key_store, card_details))
+            .async_map(|card_details| create_encrypted_data(&state, key_store, card_details))
             .await
             .transpose()
             .change_context(errors::ApiErrorResponse::InternalServerError)
@@ -535,7 +543,7 @@ pub async fn skip_locker_call_and_migrate_payment_method(
 
     if customer.default_payment_method_id.is_none() && req.payment_method.is_some() {
         let _ = set_default_payment_method(
-            &*state.store,
+            &state,
             merchant_id.to_string(),
             key_store.clone(),
             &customer_id,
@@ -572,12 +580,11 @@ pub fn get_card_bin_and_last4_digits_for_masked_card(
 
 #[instrument(skip_all)]
 pub async fn get_client_secret_or_add_payment_method(
-    state: routes::SessionState,
+    state: &routes::SessionState,
     req: api::PaymentMethodCreate,
     merchant_account: &domain::MerchantAccount,
     key_store: &domain::MerchantKeyStore,
 ) -> errors::RouterResponse<api::PaymentMethodResponse> {
-    let db = &*state.store;
     let merchant_id = &merchant_account.merchant_id;
     let customer_id = req.customer_id.clone().get_required_value("customer_id")?;
 
@@ -589,7 +596,7 @@ pub async fn get_client_secret_or_add_payment_method(
     let payment_method_billing_address: Option<Encryptable<Secret<serde_json::Value>>> = req
         .billing
         .clone()
-        .async_map(|billing| create_encrypted_data(key_store, billing))
+        .async_map(|billing| create_encrypted_data(state, key_store, billing))
         .await
         .transpose()
         .change_context(errors::ApiErrorResponse::InternalServerError)
@@ -608,7 +615,7 @@ pub async fn get_client_secret_or_add_payment_method(
         let payment_method_id = generate_id(consts::ID_LENGTH, "pm");
 
         let res = create_payment_method(
-            db,
+            state,
             &req,
             &customer_id,
             payment_method_id.as_str(),
@@ -629,7 +636,7 @@ pub async fn get_client_secret_or_add_payment_method(
 
         if res.status == enums::PaymentMethodStatus::AwaitingData {
             add_payment_method_status_update_task(
-                db,
+                &*state.store,
                 &res,
                 enums::PaymentMethodStatus::AwaitingData,
                 enums::PaymentMethodStatus::Inactive,
@@ -708,6 +715,7 @@ pub async fn add_payment_method_data(
     let customer_id = payment_method.customer_id.clone();
     let customer = db
         .find_customer_by_customer_id_merchant_id(
+            &(&state).into(),
             &customer_id,
             &merchant_account.merchant_id,
             &key_store,
@@ -754,7 +762,7 @@ pub async fn add_payment_method_data(
                         .attach_printable("Failed to add payment method in db")?;
 
                         get_or_insert_payment_method(
-                            db,
+                            &state,
                             req.clone(),
                             &mut pm_resp,
                             &merchant_account,
@@ -795,6 +803,7 @@ pub async fn add_payment_method_data(
 
                         let pm_data_encrypted: Encryptable<Secret<serde_json::Value>> =
                             create_encrypted_data(
+                                &state,
                                 &key_store,
                                 PaymentMethodsData::Card(updated_card),
                             )
@@ -822,7 +831,7 @@ pub async fn add_payment_method_data(
 
                         if customer.default_payment_method_id.is_none() {
                             let _ = set_default_payment_method(
-                                db,
+                                &state,
                                 merchant_account.merchant_id.clone(),
                                 key_store.clone(),
                                 &customer_id,
@@ -864,7 +873,7 @@ pub async fn add_payment_method_data(
 
 #[instrument(skip_all)]
 pub async fn add_payment_method(
-    state: routes::SessionState,
+    state: &routes::SessionState,
     req: api::PaymentMethodCreate,
     merchant_account: &domain::MerchantAccount,
     key_store: &domain::MerchantKeyStore,
@@ -877,7 +886,7 @@ pub async fn add_payment_method(
     let payment_method_billing_address: Option<Encryptable<Secret<serde_json::Value>>> = req
         .billing
         .clone()
-        .async_map(|billing| create_encrypted_data(key_store, billing))
+        .async_map(|billing| create_encrypted_data(state, key_store, billing))
         .await
         .transpose()
         .change_context(errors::ApiErrorResponse::InternalServerError)
@@ -894,7 +903,7 @@ pub async fn add_payment_method(
         #[cfg(feature = "payouts")]
         api_enums::PaymentMethod::BankTransfer => match req.bank_transfer.clone() {
             Some(bank) => add_bank_to_locker(
-                &state,
+                state,
                 req.clone(),
                 merchant_account,
                 key_store,
@@ -923,7 +932,7 @@ pub async fn add_payment_method(
                     &card_details.card_exp_year,
                 )?;
                 Box::pin(add_card_to_locker(
-                    &state,
+                    state,
                     req.clone(),
                     &card_details,
                     &customer_id,
@@ -953,7 +962,7 @@ pub async fn add_payment_method(
         Some(duplication_check) => match duplication_check {
             payment_methods::DataDuplicationCheck::Duplicated => {
                 let existing_pm = get_or_insert_payment_method(
-                    db,
+                    state,
                     req.clone(),
                     &mut resp,
                     merchant_account,
@@ -967,7 +976,7 @@ pub async fn add_payment_method(
             payment_methods::DataDuplicationCheck::MetaDataChanged => {
                 if let Some(card) = req.card.clone() {
                     let existing_pm = get_or_insert_payment_method(
-                        db,
+                        state,
                         req.clone(),
                         &mut resp,
                         merchant_account,
@@ -979,7 +988,7 @@ pub async fn add_payment_method(
                     let client_secret = existing_pm.client_secret.clone();
 
                     delete_card_from_locker(
-                        &state,
+                        state,
                         &customer_id,
                         merchant_id,
                         existing_pm
@@ -990,7 +999,7 @@ pub async fn add_payment_method(
                     .await?;
 
                     let add_card_resp = add_card_hs(
-                        &state,
+                        state,
                         req.clone(),
                         &card,
                         &customer_id,
@@ -1018,12 +1027,9 @@ pub async fn add_payment_method(
                             .attach_printable("Failed while updating card metadata changes"))?
                     };
 
-                    let existing_pm_data = get_card_details_without_locker_fallback(
-                        &existing_pm,
-                        key_store.key.peek(),
-                        &state,
-                    )
-                    .await?;
+                    let existing_pm_data =
+                        get_card_details_without_locker_fallback(&existing_pm, state, key_store)
+                            .await?;
 
                     let updated_card = Some(api::CardDetailFromLocker {
                         scheme: existing_pm.scheme.clone(),
@@ -1052,7 +1058,9 @@ pub async fn add_payment_method(
                     });
                     let pm_data_encrypted: Option<Encryptable<Secret<serde_json::Value>>> =
                         updated_pmd
-                            .async_map(|updated_pmd| create_encrypted_data(key_store, updated_pmd))
+                            .async_map(|updated_pmd| {
+                                create_encrypted_data(state, key_store, updated_pmd)
+                            })
                             .await
                             .transpose()
                             .change_context(errors::ApiErrorResponse::InternalServerError)
@@ -1087,7 +1095,7 @@ pub async fn add_payment_method(
             };
             resp.payment_method_id = generate_id(consts::ID_LENGTH, "pm");
             let pm = insert_payment_method(
-                db,
+                state,
                 &resp,
                 &req,
                 key_store,
@@ -1112,7 +1120,7 @@ pub async fn add_payment_method(
 
 #[allow(clippy::too_many_arguments)]
 pub async fn insert_payment_method(
-    db: &dyn db::StorageInterface,
+    state: &routes::SessionState,
     resp: &api::PaymentMethodResponse,
     req: &api::PaymentMethodCreate,
     key_store: &domain::MerchantKeyStore,
@@ -1133,14 +1141,14 @@ pub async fn insert_payment_method(
 
     let pm_data_encrypted: Option<Encryptable<Secret<serde_json::Value>>> = pm_card_details
         .clone()
-        .async_map(|pm_card| create_encrypted_data(key_store, pm_card))
+        .async_map(|pm_card| create_encrypted_data(state, key_store, pm_card))
         .await
         .transpose()
         .change_context(errors::ApiErrorResponse::InternalServerError)
         .attach_printable("Unable to encrypt payment method data")?;
 
     create_payment_method(
-        db,
+        state,
         req,
         customer_id,
         &resp.payment_method_id,
@@ -1202,7 +1210,9 @@ pub async fn update_customer_payment_method(
 
         // Fetch the existing payment method data from db
         let existing_card_data = decrypt::<serde_json::Value, masking::WithType>(
+            &(&state).into(),
             pm.payment_method_data.clone(),
+            Identifier::Merchant(key_store.merchant_id.clone()),
             key_store.key.get_inner().peek(),
         )
         .await
@@ -1327,7 +1337,7 @@ pub async fn update_customer_payment_method(
                 .map(|card| PaymentMethodsData::Card(CardDetailsPaymentMethod::from(card.clone())));
 
             let pm_data_encrypted: Option<Encryptable<Secret<serde_json::Value>>> = updated_pmd
-                .async_map(|updated_pmd| create_encrypted_data(&key_store, updated_pmd))
+                .async_map(|updated_pmd| create_encrypted_data(&state, &key_store, updated_pmd))
                 .await
                 .transpose()
                 .change_context(errors::ApiErrorResponse::InternalServerError)
@@ -1445,6 +1455,7 @@ pub async fn add_bank_to_locker(
 > {
     let key = key_store.key.get_inner().peek();
     let payout_method_data = api::PayoutMethodData::Bank(bank.clone());
+    let key_manager_state: KeyManagerState = state.into();
     let enc_data = async {
         serde_json::to_value(payout_method_data.to_owned())
             .map_err(|err| {
@@ -1458,7 +1469,14 @@ pub async fn add_bank_to_locker(
                 let secret: Secret<String> = Secret::new(v.to_string());
                 secret
             })
-            .async_lift(|inner| domain::types::encrypt_optional(inner, key))
+            .async_lift(|inner| {
+                domain::types::encrypt_optional(
+                    &key_manager_state,
+                    inner,
+                    Identifier::Merchant(key_store.merchant_id.clone()),
+                    key,
+                )
+            })
             .await
     }
     .await
@@ -1654,6 +1672,7 @@ pub async fn add_card_hs(
 
 #[instrument(skip_all)]
 pub async fn decode_and_decrypt_locker_data(
+    state: &routes::SessionState,
     key_store: &domain::MerchantKeyStore,
     enc_card_data: String,
 ) -> errors::CustomResult<Secret<String>, errors::VaultError> {
@@ -1664,13 +1683,18 @@ pub async fn decode_and_decrypt_locker_data(
         .change_context(errors::VaultError::ResponseDeserializationFailed)
         .attach_printable("Failed to decode hex string into bytes")?;
     // Decrypt
-    decrypt(Some(Encryption::new(decoded_bytes.into())), key)
-        .await
-        .change_context(errors::VaultError::FetchPaymentMethodFailed)?
-        .map_or(
-            Err(report!(errors::VaultError::FetchPaymentMethodFailed)),
-            |d| Ok(d.into_inner()),
-        )
+    decrypt(
+        &state.into(),
+        Some(Encryption::new(decoded_bytes.into())),
+        Identifier::Merchant(key_store.merchant_id.clone()),
+        key,
+    )
+    .await
+    .change_context(errors::VaultError::FetchPaymentMethodFailed)?
+    .map_or(
+        Err(report!(errors::VaultError::FetchPaymentMethodFailed)),
+        |d| Ok(d.into_inner()),
+    )
 }
 
 #[instrument(skip_all)]
@@ -1729,9 +1753,9 @@ pub async fn get_payment_method_from_hs_locker<'a>(
             .attach_printable(
                 "Failed to retrieve field - enc_card_data from RetrieveCardRespPayload",
             )?;
-        decode_and_decrypt_locker_data(key_store, enc_card_data.peek().to_string()).await?
+        decode_and_decrypt_locker_data(state, key_store, enc_card_data.peek().to_string()).await?
     } else {
-        mock_get_payment_method(&*state.store, key_store, payment_method_reference)
+        mock_get_payment_method(state, key_store, payment_method_reference)
             .await?
             .payment_method
             .payment_method_data
@@ -2036,16 +2060,17 @@ pub async fn mock_get_card<'a>(
 
 #[instrument(skip_all)]
 pub async fn mock_get_payment_method<'a>(
-    db: &dyn db::StorageInterface,
+    state: &routes::SessionState,
     key_store: &domain::MerchantKeyStore,
     card_id: &'a str,
 ) -> errors::CustomResult<payment_methods::GetPaymentMethodResponse, errors::VaultError> {
+    let db = &*state.store;
     let locker_mock_up = db
         .find_locker_by_card_id(card_id)
         .await
         .change_context(errors::VaultError::FetchPaymentMethodFailed)?;
     let dec_data = if let Some(e) = locker_mock_up.enc_card_data {
-        decode_and_decrypt_locker_data(key_store, e).await
+        decode_and_decrypt_locker_data(state, key_store, e).await
     } else {
         Err(report!(errors::VaultError::FetchPaymentMethodFailed))
     }?;
@@ -2187,14 +2212,14 @@ pub async fn list_payment_methods(
 ) -> errors::RouterResponse<api::PaymentMethodListResponse> {
     let db = &*state.store;
     let pm_config_mapping = &state.conf.pm_filters;
-
+    let key_manager_state = &(&state).into();
     let payment_intent = if let Some(cs) = &req.client_secret {
         if cs.starts_with("pm_") {
             validate_payment_method_and_client_secret(cs, db, &merchant_account).await?;
             None
         } else {
             helpers::verify_payment_intent_time_and_client_secret(
-                db,
+                &state,
                 &merchant_account,
                 &key_store,
                 req.client_secret.clone(),
@@ -2209,7 +2234,7 @@ pub async fn list_payment_methods(
         .as_ref()
         .async_map(|pi| async {
             helpers::get_address_by_id(
-                db,
+                &state,
                 pi.shipping_address_id.clone(),
                 &key_store,
                 &pi.payment_id,
@@ -2226,7 +2251,7 @@ pub async fn list_payment_methods(
         .as_ref()
         .async_map(|pi| async {
             helpers::get_address_by_id(
-                db,
+                &state,
                 pi.billing_address_id.clone(),
                 &key_store,
                 &pi.payment_id,
@@ -2246,6 +2271,7 @@ pub async fn list_payment_methods(
                 .as_ref()
                 .async_and_then(|cust| async {
                     db.find_customer_by_customer_id_merchant_id(
+                        key_manager_state,
                         cust,
                         &pi.merchant_id,
                         &key_store,
@@ -2293,6 +2319,7 @@ pub async fn list_payment_methods(
 
     let all_mcas = db
         .find_merchant_connector_account_by_merchant_id_and_disabled_list(
+            key_manager_state,
             &merchant_account.merchant_id,
             false,
             &key_store,
@@ -3273,6 +3300,7 @@ pub async fn call_surcharge_decision_management(
         let _ = state
             .store
             .update_payment_intent(
+                &(&state).into(),
                 payment_intent,
                 storage::PaymentIntentUpdate::SurchargeApplicableUpdate {
                     surcharge_applicable: true,
@@ -3322,6 +3350,7 @@ pub async fn call_surcharge_decision_management_for_saved_card(
         let _ = state
             .store
             .update_payment_intent(
+                &state.into(),
                 payment_intent,
                 storage::PaymentIntentUpdate::SurchargeApplicableUpdate {
                     surcharge_applicable: true,
@@ -3586,7 +3615,6 @@ pub async fn do_list_customer_pm_fetch_customer_if_not_passed(
     customer_id: Option<&id_type::CustomerId>,
     ephemeral_api_key: Option<&str>,
 ) -> errors::RouterResponse<api::CustomerPaymentMethodsListResponse> {
-    let db = state.store.as_ref();
     let limit = req.clone().and_then(|pml_req| pml_req.limit);
 
     let auth_cust = if let Some(key) = ephemeral_api_key {
@@ -3617,7 +3645,7 @@ pub async fn do_list_customer_pm_fetch_customer_if_not_passed(
         let cloned_secret = req.and_then(|r| r.client_secret.as_ref().cloned());
         let payment_intent: Option<hyperswitch_domain_models::payments::PaymentIntent> =
             helpers::verify_payment_intent_time_and_client_secret(
-                db,
+                &state,
                 &merchant_account,
                 &key_store,
                 cloned_secret,
@@ -3671,6 +3699,7 @@ pub async fn list_customer_payment_method(
 
     let customer = db
         .find_customer_by_customer_id_merchant_id(
+            &state.into(),
             customer_id,
             &merchant_account.merchant_id,
             &key_store,
@@ -3679,8 +3708,6 @@ pub async fn list_customer_payment_method(
         .await
         .to_not_found_response(errors::ApiErrorResponse::CustomerNotFound)?;
 
-    let key = key_store.key.get_inner().peek();
-
     let is_requires_cvv = db
         .find_config_by_key_unwrap_or(
             format!("{}_requires_cvv", merchant_account.merchant_id).as_str(),
@@ -3741,7 +3768,8 @@ pub async fn list_customer_payment_method(
 
         let payment_method_retrieval_context = match payment_method {
             enums::PaymentMethod::Card => {
-                let card_details = get_card_details_with_locker_fallback(&pm, key, state).await?;
+                let card_details =
+                    get_card_details_with_locker_fallback(&pm, state, &key_store).await?;
 
                 if card_details.is_some() {
                     PaymentMethodListContext {
@@ -3761,12 +3789,13 @@ pub async fn list_customer_payment_method(
 
             enums::PaymentMethod::BankDebit => {
                 // Retrieve the pm_auth connector details so that it can be tokenized
-                let bank_account_token_data = get_bank_account_connector_details(&pm, key)
-                    .await
-                    .unwrap_or_else(|error| {
-                        logger::error!(?error);
-                        None
-                    });
+                let bank_account_token_data =
+                    get_bank_account_connector_details(state, &pm, &key_store)
+                        .await
+                        .unwrap_or_else(|error| {
+                            logger::error!(?error);
+                            None
+                        });
                 if let Some(data) = bank_account_token_data {
                     let token_data = PaymentTokenData::AuthBankDebit(data);
 
@@ -3822,7 +3851,7 @@ pub async fn list_customer_payment_method(
 
         // Retrieve the masked bank details to be sent as a response
         let bank_details = if payment_method == enums::PaymentMethod::BankDebit {
-            get_masked_bank_details(&pm, key)
+            get_masked_bank_details(state, &pm, &key_store)
                 .await
                 .unwrap_or_else(|error| {
                     logger::error!(?error);
@@ -3833,8 +3862,9 @@ pub async fn list_customer_payment_method(
         };
 
         let payment_method_billing = decrypt_generic_data::<api_models::payments::Address>(
+            state,
             pm.payment_method_billing_address,
-            key,
+            &key_store,
         )
         .await
         .attach_printable("unable to decrypt payment method billing address details")?;
@@ -3993,6 +4023,7 @@ pub async fn get_mca_status(
         let mcas = state
             .store
             .find_merchant_connector_account_by_merchant_id_and_disabled_list(
+                &state.into(),
                 merchant_id,
                 true,
                 key_store,
@@ -4021,17 +4052,21 @@ pub async fn get_mca_status(
     Ok(false)
 }
 pub async fn decrypt_generic_data<T>(
+    state: &routes::SessionState,
     data: Option<Encryption>,
-    key: &[u8],
+    key_store: &domain::MerchantKeyStore,
 ) -> errors::RouterResult<Option<T>>
 where
     T: serde::de::DeserializeOwned,
 {
-    let decrypted_data = decrypt::<serde_json::Value, masking::WithType>(data, key)
-        .await
-        .change_context(errors::StorageError::DecryptionError)
-        .change_context(errors::ApiErrorResponse::InternalServerError)
-        .attach_printable("unable to decrypt data")?;
+    let key = key_store.key.get_inner().peek();
+    let identifier = Identifier::Merchant(key_store.merchant_id.clone());
+    let decrypted_data =
+        decrypt::<serde_json::Value, masking::WithType>(&state.into(), data, identifier, key)
+            .await
+            .change_context(errors::StorageError::DecryptionError)
+            .change_context(errors::ApiErrorResponse::InternalServerError)
+            .attach_printable("unable to decrypt data")?;
 
     decrypted_data
         .map(|decrypted_data| decrypted_data.into_inner().expose())
@@ -4043,22 +4078,28 @@ where
 
 pub async fn get_card_details_with_locker_fallback(
     pm: &payment_method::PaymentMethod,
-    key: &[u8],
     state: &routes::SessionState,
+    key_store: &domain::MerchantKeyStore,
 ) -> errors::RouterResult<Option<api::CardDetailFromLocker>> {
-    let card_decrypted =
-        decrypt::<serde_json::Value, masking::WithType>(pm.payment_method_data.clone(), key)
-            .await
-            .change_context(errors::StorageError::DecryptionError)
-            .attach_printable("unable to decrypt card details")
-            .ok()
-            .flatten()
-            .map(|x| x.into_inner().expose())
-            .and_then(|v| serde_json::from_value::<PaymentMethodsData>(v).ok())
-            .and_then(|pmd| match pmd {
-                PaymentMethodsData::Card(crd) => Some(api::CardDetailFromLocker::from(crd)),
-                _ => None,
-            });
+    let key = key_store.key.get_inner().peek();
+    let identifier = Identifier::Merchant(key_store.merchant_id.clone());
+    let card_decrypted = decrypt::<serde_json::Value, masking::WithType>(
+        &state.into(),
+        pm.payment_method_data.clone(),
+        identifier,
+        key,
+    )
+    .await
+    .change_context(errors::StorageError::DecryptionError)
+    .attach_printable("unable to decrypt card details")
+    .ok()
+    .flatten()
+    .map(|x| x.into_inner().expose())
+    .and_then(|v| serde_json::from_value::<PaymentMethodsData>(v).ok())
+    .and_then(|pmd| match pmd {
+        PaymentMethodsData::Card(crd) => Some(api::CardDetailFromLocker::from(crd)),
+        _ => None,
+    });
 
     Ok(if let Some(mut crd) = card_decrypted {
         crd.scheme.clone_from(&pm.scheme);
@@ -4073,22 +4114,28 @@ pub async fn get_card_details_with_locker_fallback(
 
 pub async fn get_card_details_without_locker_fallback(
     pm: &payment_method::PaymentMethod,
-    key: &[u8],
     state: &routes::SessionState,
+    key_store: &domain::MerchantKeyStore,
 ) -> errors::RouterResult<api::CardDetailFromLocker> {
-    let card_decrypted =
-        decrypt::<serde_json::Value, masking::WithType>(pm.payment_method_data.clone(), key)
-            .await
-            .change_context(errors::StorageError::DecryptionError)
-            .attach_printable("unable to decrypt card details")
-            .ok()
-            .flatten()
-            .map(|x| x.into_inner().expose())
-            .and_then(|v| serde_json::from_value::<PaymentMethodsData>(v).ok())
-            .and_then(|pmd| match pmd {
-                PaymentMethodsData::Card(crd) => Some(api::CardDetailFromLocker::from(crd)),
-                _ => None,
-            });
+    let key = key_store.key.get_inner().peek();
+    let identifier = Identifier::Merchant(key_store.merchant_id.clone());
+    let card_decrypted = decrypt::<serde_json::Value, masking::WithType>(
+        &state.into(),
+        pm.payment_method_data.clone(),
+        identifier,
+        key,
+    )
+    .await
+    .change_context(errors::StorageError::DecryptionError)
+    .attach_printable("unable to decrypt card details")
+    .ok()
+    .flatten()
+    .map(|x| x.into_inner().expose())
+    .and_then(|v| serde_json::from_value::<PaymentMethodsData>(v).ok())
+    .and_then(|pmd| match pmd {
+        PaymentMethodsData::Card(crd) => Some(api::CardDetailFromLocker::from(crd)),
+        _ => None,
+    });
 
     Ok(if let Some(mut crd) = card_decrypted {
         crd.scheme.clone_from(&pm.scheme);
@@ -4141,25 +4188,32 @@ pub async fn get_lookup_key_from_locker(
 }
 
 async fn get_masked_bank_details(
+    state: &routes::SessionState,
     pm: &payment_method::PaymentMethod,
-    key: &[u8],
+    key_store: &domain::MerchantKeyStore,
 ) -> errors::RouterResult<Option<MaskedBankDetails>> {
-    let payment_method_data =
-        decrypt::<serde_json::Value, masking::WithType>(pm.payment_method_data.clone(), key)
-            .await
-            .change_context(errors::StorageError::DecryptionError)
-            .change_context(errors::ApiErrorResponse::InternalServerError)
-            .attach_printable("unable to decrypt bank details")?
-            .map(|x| x.into_inner().expose())
-            .map(
-                |v| -> Result<PaymentMethodsData, error_stack::Report<errors::ApiErrorResponse>> {
-                    v.parse_value::<PaymentMethodsData>("PaymentMethodsData")
-                        .change_context(errors::StorageError::DeserializationFailed)
-                        .change_context(errors::ApiErrorResponse::InternalServerError)
-                        .attach_printable("Failed to deserialize Payment Method Auth config")
-                },
-            )
-            .transpose()?;
+    let key = key_store.key.get_inner().peek();
+    let identifier = Identifier::Merchant(key_store.merchant_id.clone());
+    let payment_method_data = decrypt::<serde_json::Value, masking::WithType>(
+        &state.into(),
+        pm.payment_method_data.clone(),
+        identifier,
+        key,
+    )
+    .await
+    .change_context(errors::StorageError::DecryptionError)
+    .change_context(errors::ApiErrorResponse::InternalServerError)
+    .attach_printable("unable to decrypt bank details")?
+    .map(|x| x.into_inner().expose())
+    .map(
+        |v| -> Result<PaymentMethodsData, error_stack::Report<errors::ApiErrorResponse>> {
+            v.parse_value::<PaymentMethodsData>("PaymentMethodsData")
+                .change_context(errors::StorageError::DeserializationFailed)
+                .change_context(errors::ApiErrorResponse::InternalServerError)
+                .attach_printable("Failed to deserialize Payment Method Auth config")
+        },
+    )
+    .transpose()?;
 
     match payment_method_data {
         Some(pmd) => match pmd {
@@ -4174,25 +4228,32 @@ async fn get_masked_bank_details(
 }
 
 async fn get_bank_account_connector_details(
+    state: &routes::SessionState,
     pm: &payment_method::PaymentMethod,
-    key: &[u8],
+    key_store: &domain::MerchantKeyStore,
 ) -> errors::RouterResult<Option<BankAccountTokenData>> {
-    let payment_method_data =
-        decrypt::<serde_json::Value, masking::WithType>(pm.payment_method_data.clone(), key)
-            .await
-            .change_context(errors::StorageError::DecryptionError)
-            .change_context(errors::ApiErrorResponse::InternalServerError)
-            .attach_printable("unable to decrypt bank details")?
-            .map(|x| x.into_inner().expose())
-            .map(
-                |v| -> Result<PaymentMethodsData, error_stack::Report<errors::ApiErrorResponse>> {
-                    v.parse_value::<PaymentMethodsData>("PaymentMethodsData")
-                        .change_context(errors::StorageError::DeserializationFailed)
-                        .change_context(errors::ApiErrorResponse::InternalServerError)
-                        .attach_printable("Failed to deserialize Payment Method Auth config")
-                },
-            )
-            .transpose()?;
+    let key = key_store.key.get_inner().peek();
+    let identifier = Identifier::Merchant(key_store.merchant_id.clone());
+    let payment_method_data = decrypt::<serde_json::Value, masking::WithType>(
+        &state.into(),
+        pm.payment_method_data.clone(),
+        identifier,
+        key,
+    )
+    .await
+    .change_context(errors::StorageError::DecryptionError)
+    .change_context(errors::ApiErrorResponse::InternalServerError)
+    .attach_printable("unable to decrypt bank details")?
+    .map(|x| x.into_inner().expose())
+    .map(
+        |v| -> Result<PaymentMethodsData, error_stack::Report<errors::ApiErrorResponse>> {
+            v.parse_value::<PaymentMethodsData>("PaymentMethodsData")
+                .change_context(errors::StorageError::DeserializationFailed)
+                .change_context(errors::ApiErrorResponse::InternalServerError)
+                .attach_printable("Failed to deserialize Payment Method Auth config")
+        },
+    )
+    .transpose()?;
 
     match payment_method_data {
         Some(pmd) => match pmd {
@@ -4229,17 +4290,20 @@ async fn get_bank_account_connector_details(
     }
 }
 pub async fn set_default_payment_method(
-    db: &dyn db::StorageInterface,
+    state: &routes::SessionState,
     merchant_id: String,
     key_store: domain::MerchantKeyStore,
     customer_id: &id_type::CustomerId,
     payment_method_id: String,
     storage_scheme: MerchantStorageScheme,
 ) -> errors::RouterResponse<CustomerDefaultPaymentMethodResponse> {
+    let db = &*state.store;
+    let key_manager_state = &state.into();
     // check for the customer
     // TODO: customer need not be checked again here, this function can take an optional customer and check for existence of customer based on the optional value
     let customer = db
         .find_customer_by_customer_id_merchant_id(
+            key_manager_state,
             customer_id,
             &merchant_id,
             &key_store,
@@ -4283,6 +4347,7 @@ pub async fn set_default_payment_method(
     // update the db with the default payment method id
     let updated_customer_details = db
         .update_customer_by_customer_id_merchant_id(
+            key_manager_state,
             customer_id.to_owned(),
             merchant_id.to_owned(),
             customer,
@@ -4470,7 +4535,6 @@ pub async fn retrieve_payment_method(
         .await
         .to_not_found_response(errors::ApiErrorResponse::PaymentMethodNotFound)?;
 
-    let key = key_store.key.peek();
     let card = if pm.payment_method == Some(enums::PaymentMethod::Card) {
         let card_detail = if state.conf.locker.locker_enabled {
             let card = get_card_from_locker(
@@ -4486,7 +4550,7 @@ pub async fn retrieve_payment_method(
                 .change_context(errors::ApiErrorResponse::InternalServerError)
                 .attach_printable("Failed while getting card details from locker")?
         } else {
-            get_card_details_without_locker_fallback(&pm, key, &state).await?
+            get_card_details_without_locker_fallback(&pm, &state, &key_store).await?
         };
         Some(card_detail)
     } else {
@@ -4521,6 +4585,7 @@ pub async fn delete_payment_method(
     key_store: domain::MerchantKeyStore,
 ) -> errors::RouterResponse<api::PaymentMethodDeleteResponse> {
     let db = state.store.as_ref();
+    let key_manager_state = &(&state).into();
     let key = db
         .find_payment_method(
             pm_id.payment_method_id.as_str(),
@@ -4531,6 +4596,7 @@ pub async fn delete_payment_method(
 
     let customer = db
         .find_customer_by_customer_id_merchant_id(
+            key_manager_state,
             &key.customer_id,
             &merchant_account.merchant_id,
             &key_store,
@@ -4570,6 +4636,7 @@ pub async fn delete_payment_method(
         };
 
         db.update_customer_by_customer_id_merchant_id(
+            key_manager_state,
             key.customer_id,
             key.merchant_id,
             customer,
@@ -4591,6 +4658,7 @@ pub async fn delete_payment_method(
 }
 
 pub async fn create_encrypted_data<T>(
+    state: &routes::SessionState,
     key_store: &domain::MerchantKeyStore,
     data: T,
 ) -> Result<Encryptable<Secret<serde_json::Value>>, error_stack::Report<errors::StorageError>>
@@ -4598,6 +4666,8 @@ where
     T: Debug + serde::Serialize,
 {
     let key = key_store.key.get_inner().peek();
+    let identifier = Identifier::Merchant(key_store.merchant_id.clone());
+    let key_manager_state: KeyManagerState = state.into();
 
     let encoded_data = Encode::encode_to_value(&data)
         .change_context(errors::StorageError::SerializationFailed)
@@ -4605,10 +4675,11 @@ where
 
     let secret_data = Secret::<_, masking::WithType>::new(encoded_data);
 
-    let encrypted_data = domain::types::encrypt(secret_data, key)
-        .await
-        .change_context(errors::StorageError::EncryptionError)
-        .attach_printable("Unable to encrypt data")?;
+    let encrypted_data =
+        domain::types::encrypt(&key_manager_state, secret_data, identifier.clone(), key)
+            .await
+            .change_context(errors::StorageError::EncryptionError)
+            .attach_printable("Unable to encrypt data")?;
 
     Ok(encrypted_data)
 }
diff --git a/crates/router/src/core/payment_methods/validator.rs b/crates/router/src/core/payment_methods/validator.rs
index be34d3db38c..23470fb3ef1 100644
--- a/crates/router/src/core/payment_methods/validator.rs
+++ b/crates/router/src/core/payment_methods/validator.rs
@@ -27,6 +27,7 @@ pub async fn validate_request_and_initiate_payment_method_collect_link(
     let merchant_id = merchant_account.merchant_id.clone();
     match db
         .find_customer_by_customer_id_merchant_id(
+            &state.into(),
             &customer_id,
             &merchant_id,
             key_store,
diff --git a/crates/router/src/core/payments.rs b/crates/router/src/core/payments.rs
index 5cad096bd39..9c420c1e44d 100644
--- a/crates/router/src/core/payments.rs
+++ b/crates/router/src/core/payments.rs
@@ -164,7 +164,7 @@ where
     let (operation, customer) = operation
         .to_domain()?
         .get_or_create_customer_details(
-            &*state.store,
+            state,
             &mut payment_data,
             customer_details,
             &key_store,
@@ -208,8 +208,6 @@ where
         // Fetch and check FRM configs
         #[cfg(feature = "frm")]
         let mut frm_info = None;
-        #[cfg(feature = "frm")]
-        let db = &*state.store;
         #[allow(unused_variables, unused_mut)]
         let mut should_continue_transaction: bool = true;
         #[cfg(feature = "frm")]
@@ -217,7 +215,6 @@ where
         #[cfg(feature = "frm")]
         let frm_configs = if state.conf.frm.enabled {
             Box::pin(frm_core::call_frm_before_connector_call(
-                db,
                 &operation,
                 &merchant_account,
                 &mut payment_data,
@@ -1203,6 +1200,7 @@ impl PaymentRedirectFlow for PaymentAuthenticateCompleteAuthorize {
         let payment_intent = state
             .store
             .find_payment_intent_by_payment_id_merchant_id(
+                &state.into(),
                 &payment_id,
                 &merchant_id,
                 &merchant_key_store,
@@ -2883,7 +2881,7 @@ pub async fn list_payments(
     let merchant_id = &merchant.merchant_id;
     let db = state.store.as_ref();
     let payment_intents = helpers::filter_by_constraints(
-        db,
+        &state,
         &constraints,
         merchant_id,
         &key_store,
@@ -2955,6 +2953,7 @@ pub async fn apply_filters_on_payments(
     let db = state.store.as_ref();
     let list: Vec<(storage::PaymentIntent, storage::PaymentAttempt)> = db
         .get_filtered_payment_intents_attempt(
+            &(&state).into(),
             &merchant.merchant_id,
             &constraints.clone().into(),
             &merchant_key_store,
@@ -3008,6 +3007,7 @@ pub async fn get_filters_for_payments(
     let db = state.store.as_ref();
     let pi = db
         .filter_payment_intents_by_time_range_constraints(
+            &(&state).into(),
             &merchant.merchant_id,
             &time_range,
             &merchant_key_store,
@@ -4021,6 +4021,7 @@ pub async fn payment_external_authentication(
     let payment_id = req.payment_id;
     let payment_intent = db
         .find_payment_intent_by_payment_id_merchant_id(
+            &(&state).into(),
             &payment_id,
             merchant_id,
             &key_store,
@@ -4054,6 +4055,7 @@ pub async fn payment_external_authentication(
             state
                 .store
                 .find_customer_by_customer_id_merchant_id(
+                    &(&state).into(),
                     customer_id,
                     &merchant_account.merchant_id,
                     &key_store,
@@ -4076,7 +4078,7 @@ pub async fn payment_external_authentication(
     let currency = payment_attempt.currency.get_required_value("currency")?;
     let amount = payment_attempt.get_total_amount();
     let shipping_address = helpers::create_or_find_address_for_payment_by_request(
-        db,
+        &state,
         None,
         payment_intent.shipping_address_id.as_deref(),
         merchant_id,
@@ -4087,7 +4089,7 @@ pub async fn payment_external_authentication(
     )
     .await?;
     let billing_address = helpers::create_or_find_address_for_payment_by_request(
-        db,
+        &state,
         None,
         payment_intent.billing_address_id.as_deref(),
         merchant_id,
@@ -4259,9 +4261,11 @@ pub async fn payments_manual_update(
         error_message,
         error_reason,
     } = req;
+    let key_manager_state = &(&state).into();
     let key_store = state
         .store
         .get_merchant_key_store_by_merchant_id(
+            key_manager_state,
             &merchant_id,
             &state.store.get_master_key().to_vec().into(),
         )
@@ -4270,7 +4274,7 @@ pub async fn payments_manual_update(
         .attach_printable("Error while fetching the key store by merchant_id")?;
     let merchant_account = state
         .store
-        .find_merchant_account_by_merchant_id(&merchant_id, &key_store)
+        .find_merchant_account_by_merchant_id(key_manager_state, &merchant_id, &key_store)
         .await
         .to_not_found_response(errors::ApiErrorResponse::MerchantAccountNotFound)
         .attach_printable("Error while fetching the merchant_account by merchant_id")?;
@@ -4290,6 +4294,7 @@ pub async fn payments_manual_update(
     let payment_intent = state
         .store
         .find_payment_intent_by_payment_id_merchant_id(
+            &(&state).into(),
             &payment_id,
             &merchant_account.merchant_id,
             &key_store,
@@ -4345,6 +4350,7 @@ pub async fn payments_manual_update(
         state
             .store
             .update_payment_intent(
+                &(&state).into(),
                 payment_intent,
                 payment_intent_update,
                 &key_store,
diff --git a/crates/router/src/core/payments/helpers.rs b/crates/router/src/core/payments/helpers.rs
index 3629457d5ab..ecf8ff0c40d 100644
--- a/crates/router/src/core/payments/helpers.rs
+++ b/crates/router/src/core/payments/helpers.rs
@@ -1,8 +1,9 @@
 use std::{borrow::Cow, str::FromStr};
 
 use api_models::{
+    customers::CustomerRequestWithEmail,
     mandates::RecurringDetails,
-    payments::{CardToken, GetPaymentMethodType, RequestSurchargeDetails},
+    payments::{AddressDetailsWithPhone, CardToken, GetPaymentMethodType, RequestSurchargeDetails},
 };
 use base64::Engine;
 use common_enums::ConnectorType;
@@ -10,7 +11,10 @@ use common_utils::{
     crypto::Encryptable,
     ext_traits::{AsyncExt, ByteSliceExt, Encode, ValueExt},
     fp_utils, generate_id, id_type, pii,
-    types::MinorUnit,
+    types::{
+        keymanager::{Identifier, KeyManagerState, ToEncryptable},
+        MinorUnit,
+    },
 };
 use diesel_models::enums::{self};
 // TODO : Evaluate all the helper functions ()
@@ -139,7 +143,7 @@ pub fn filter_mca_based_on_connector_type(
 #[instrument(skip_all)]
 #[allow(clippy::too_many_arguments)]
 pub async fn create_or_update_address_for_payment_by_request(
-    db: &dyn StorageInterface,
+    session_state: &SessionState,
     req_address: Option<&api::Address>,
     address_id: Option<&str>,
     merchant_id: &str,
@@ -149,87 +153,54 @@ pub async fn create_or_update_address_for_payment_by_request(
     storage_scheme: storage_enums::MerchantStorageScheme,
 ) -> CustomResult<Option<domain::Address>, errors::ApiErrorResponse> {
     let key = merchant_key_store.key.get_inner().peek();
-
+    let db = &session_state.store;
+    let key_manager_state = &session_state.into();
     Ok(match address_id {
         Some(id) => match req_address {
             Some(address) => {
-                let address_update = async {
-                    Ok::<_, error_stack::Report<common_utils::errors::CryptoError>>(
-                        storage::AddressUpdate::Update {
-                            city: address
-                                .address
-                                .as_ref()
-                                .and_then(|value| value.city.clone()),
-                            country: address.address.as_ref().and_then(|value| value.country),
-                            line1: address
-                                .address
-                                .as_ref()
-                                .and_then(|value| value.line1.clone())
-                                .async_lift(|inner| types::encrypt_optional(inner, key))
-                                .await?,
-                            line2: address
-                                .address
-                                .as_ref()
-                                .and_then(|value| value.line2.clone())
-                                .async_lift(|inner| types::encrypt_optional(inner, key))
-                                .await?,
-                            line3: address
-                                .address
-                                .as_ref()
-                                .and_then(|value| value.line3.clone())
-                                .async_lift(|inner| types::encrypt_optional(inner, key))
-                                .await?,
-                            state: address
-                                .address
-                                .as_ref()
-                                .and_then(|value| value.state.clone())
-                                .async_lift(|inner| types::encrypt_optional(inner, key))
-                                .await?,
-                            zip: address
-                                .address
-                                .as_ref()
-                                .and_then(|value| value.zip.clone())
-                                .async_lift(|inner| types::encrypt_optional(inner, key))
-                                .await?,
-                            first_name: address
-                                .address
-                                .as_ref()
-                                .and_then(|value| value.first_name.clone())
-                                .async_lift(|inner| types::encrypt_optional(inner, key))
-                                .await?,
-                            last_name: address
-                                .address
-                                .as_ref()
-                                .and_then(|value| value.last_name.clone())
-                                .async_lift(|inner| types::encrypt_optional(inner, key))
-                                .await?,
-                            phone_number: address
-                                .phone
-                                .as_ref()
-                                .and_then(|value| value.number.clone())
-                                .async_lift(|inner| types::encrypt_optional(inner, key))
-                                .await?,
-                            country_code: address
-                                .phone
-                                .as_ref()
-                                .and_then(|value| value.country_code.clone()),
-                            updated_by: storage_scheme.to_string(),
-                            email: address
-                                .email
-                                .as_ref()
-                                .cloned()
-                                .async_lift(|inner| {
-                                    types::encrypt_optional(inner.map(|inner| inner.expose()), key)
-                                })
-                                .await?,
-                        },
-                    )
-                }
+                let encrypted_data = types::batch_encrypt(
+                    &session_state.into(),
+                    AddressDetailsWithPhone::to_encryptable(AddressDetailsWithPhone {
+                        address: address.address.clone(),
+                        phone_number: address
+                            .phone
+                            .as_ref()
+                            .and_then(|phone| phone.number.clone()),
+                        email: address.email.clone(),
+                    }),
+                    Identifier::Merchant(merchant_key_store.merchant_id.clone()),
+                    key,
+                )
                 .await
                 .change_context(errors::ApiErrorResponse::InternalServerError)
                 .attach_printable("Failed while encrypting address")?;
+                let encryptable_address = AddressDetailsWithPhone::from_encryptable(encrypted_data)
+                    .change_context(errors::ApiErrorResponse::InternalServerError)
+                    .attach_printable("Failed while encrypting address")?;
+                let address_update = storage::AddressUpdate::Update {
+                    city: address
+                        .address
+                        .as_ref()
+                        .and_then(|value| value.city.clone()),
+                    country: address.address.as_ref().and_then(|value| value.country),
+                    line1: encryptable_address.line1,
+                    line2: encryptable_address.line2,
+                    line3: encryptable_address.line3,
+                    state: encryptable_address.state,
+                    zip: encryptable_address.zip,
+                    first_name: encryptable_address.first_name,
+                    last_name: encryptable_address.last_name,
+                    phone_number: encryptable_address.phone_number,
+                    country_code: address
+                        .phone
+                        .as_ref()
+                        .and_then(|value| value.country_code.clone()),
+                    updated_by: storage_scheme.to_string(),
+                    email: encryptable_address.email,
+                };
                 let address = db
                     .find_address_by_merchant_id_payment_id_address_id(
+                        key_manager_state,
                         merchant_id,
                         payment_id,
                         id,
@@ -241,6 +212,7 @@ pub async fn create_or_update_address_for_payment_by_request(
                     .attach_printable("Error while fetching address")?;
                 Some(
                     db.update_address_for_payments(
+                        key_manager_state,
                         address,
                         address_update,
                         payment_id.to_string(),
@@ -254,6 +226,7 @@ pub async fn create_or_update_address_for_payment_by_request(
             }
             None => Some(
                 db.find_address_by_merchant_id_payment_id_address_id(
+                    key_manager_state,
                     merchant_id,
                     payment_id,
                     id,
@@ -268,10 +241,11 @@ pub async fn create_or_update_address_for_payment_by_request(
         },
         None => match req_address {
             Some(address) => {
-                let address = get_domain_address(address, merchant_id, key, storage_scheme)
-                    .await
-                    .change_context(errors::ApiErrorResponse::InternalServerError)
-                    .attach_printable("Failed while encrypting address while insert")?;
+                let address =
+                    get_domain_address(session_state, address, merchant_id, key, storage_scheme)
+                        .await
+                        .change_context(errors::ApiErrorResponse::InternalServerError)
+                        .attach_printable("Failed while encrypting address while insert")?;
 
                 let payment_address = domain::PaymentAddress {
                     address,
@@ -281,6 +255,7 @@ pub async fn create_or_update_address_for_payment_by_request(
 
                 Some(
                     db.insert_address_for_payments(
+                        key_manager_state,
                         payment_id,
                         payment_address,
                         merchant_key_store,
@@ -301,7 +276,7 @@ pub async fn create_or_update_address_for_payment_by_request(
 #[instrument(skip_all)]
 #[allow(clippy::too_many_arguments)]
 pub async fn create_or_find_address_for_payment_by_request(
-    db: &dyn StorageInterface,
+    state: &SessionState,
     req_address: Option<&api::Address>,
     address_id: Option<&str>,
     merchant_id: &str,
@@ -311,10 +286,12 @@ pub async fn create_or_find_address_for_payment_by_request(
     storage_scheme: storage_enums::MerchantStorageScheme,
 ) -> CustomResult<Option<domain::Address>, errors::ApiErrorResponse> {
     let key = merchant_key_store.key.get_inner().peek();
-
+    let db = &state.store;
+    let key_manager_state = &state.into();
     Ok(match address_id {
         Some(id) => Some(
             db.find_address_by_merchant_id_payment_id_address_id(
+                key_manager_state,
                 merchant_id,
                 payment_id,
                 id,
@@ -329,7 +306,7 @@ pub async fn create_or_find_address_for_payment_by_request(
         None => match req_address {
             Some(address) => {
                 // generate a new address here
-                let address = get_domain_address(address, merchant_id, key, storage_scheme)
+                let address = get_domain_address(state, address, merchant_id, key, storage_scheme)
                     .await
                     .change_context(errors::ApiErrorResponse::InternalServerError)
                     .attach_printable("Failed while encrypting address while insert")?;
@@ -342,6 +319,7 @@ pub async fn create_or_find_address_for_payment_by_request(
 
                 Some(
                     db.insert_address_for_payments(
+                        key_manager_state,
                         payment_id,
                         payment_address,
                         merchant_key_store,
@@ -359,70 +337,56 @@ pub async fn create_or_find_address_for_payment_by_request(
 }
 
 pub async fn get_domain_address(
+    session_state: &SessionState,
     address: &api_models::payments::Address,
     merchant_id: &str,
     key: &[u8],
     storage_scheme: enums::MerchantStorageScheme,
 ) -> CustomResult<domain::Address, common_utils::errors::CryptoError> {
     async {
-        let address_details = address.address.as_ref();
+        let address_details = &address.address.as_ref();
+        let encrypted_data = types::batch_encrypt(
+            &session_state.into(),
+            AddressDetailsWithPhone::to_encryptable(AddressDetailsWithPhone {
+                address: address_details.cloned(),
+                phone_number: address
+                    .phone
+                    .as_ref()
+                    .and_then(|phone| phone.number.clone()),
+                email: address.email.clone(),
+            }),
+            Identifier::Merchant(merchant_id.to_string()),
+            key,
+        )
+        .await?;
+        let encryptable_address = AddressDetailsWithPhone::from_encryptable(encrypted_data)
+            .change_context(common_utils::errors::CryptoError::EncodingFailed)?;
         Ok(domain::Address {
             id: None,
-            phone_number: address
-                .phone
-                .as_ref()
-                .and_then(|a| a.number.clone())
-                .async_lift(|inner| types::encrypt_optional(inner, key))
-                .await?,
+            phone_number: encryptable_address.phone_number,
             country_code: address.phone.as_ref().and_then(|a| a.country_code.clone()),
             merchant_id: merchant_id.to_string(),
             address_id: generate_id(consts::ID_LENGTH, "add"),
             city: address_details.and_then(|address_details| address_details.city.clone()),
             country: address_details.and_then(|address_details| address_details.country),
-            line1: address_details
-                .and_then(|address_details| address_details.line1.clone())
-                .async_lift(|inner| types::encrypt_optional(inner, key))
-                .await?,
-            line2: address_details
-                .and_then(|address_details| address_details.line2.clone())
-                .async_lift(|inner| types::encrypt_optional(inner, key))
-                .await?,
-            line3: address_details
-                .and_then(|address_details| address_details.line3.clone())
-                .async_lift(|inner| types::encrypt_optional(inner, key))
-                .await?,
-            state: address_details
-                .and_then(|address_details| address_details.state.clone())
-                .async_lift(|inner| types::encrypt_optional(inner, key))
-                .await?,
+            line1: encryptable_address.line1,
+            line2: encryptable_address.line2,
+            line3: encryptable_address.line3,
+            state: encryptable_address.state,
             created_at: common_utils::date_time::now(),
-            first_name: address_details
-                .and_then(|address_details| address_details.first_name.clone())
-                .async_lift(|inner| types::encrypt_optional(inner, key))
-                .await?,
-            last_name: address_details
-                .and_then(|address_details| address_details.last_name.clone())
-                .async_lift(|inner| types::encrypt_optional(inner, key))
-                .await?,
+            first_name: encryptable_address.first_name,
+            last_name: encryptable_address.last_name,
             modified_at: common_utils::date_time::now(),
-            zip: address_details
-                .and_then(|address_details| address_details.zip.clone())
-                .async_lift(|inner| types::encrypt_optional(inner, key))
-                .await?,
+            zip: encryptable_address.zip,
             updated_by: storage_scheme.to_string(),
-            email: address
-                .email
-                .as_ref()
-                .cloned()
-                .async_lift(|inner| types::encrypt_optional(inner.map(|inner| inner.expose()), key))
-                .await?,
+            email: encryptable_address.email,
         })
     }
     .await
 }
 
 pub async fn get_address_by_id(
-    db: &dyn StorageInterface,
+    state: &SessionState,
     address_id: Option<String>,
     merchant_key_store: &domain::MerchantKeyStore,
     payment_id: &str,
@@ -431,17 +395,21 @@ pub async fn get_address_by_id(
 ) -> CustomResult<Option<domain::Address>, errors::ApiErrorResponse> {
     match address_id {
         None => Ok(None),
-        Some(address_id) => Ok(db
-            .find_address_by_merchant_id_payment_id_address_id(
-                merchant_id,
-                payment_id,
-                &address_id,
-                merchant_key_store,
-                storage_scheme,
-            )
-            .await
-            .map(|payment_address| payment_address.address)
-            .ok()),
+        Some(address_id) => {
+            let db = &*state.store;
+            Ok(db
+                .find_address_by_merchant_id_payment_id_address_id(
+                    &state.into(),
+                    merchant_id,
+                    payment_id,
+                    &address_id,
+                    merchant_key_store,
+                    storage_scheme,
+                )
+                .await
+                .map(|payment_address| payment_address.address)
+                .ok())
+        }
     }
 }
 
@@ -688,12 +656,13 @@ pub async fn get_token_for_recurring_mandate(
         )
         .await
         .to_not_found_response(errors::ApiErrorResponse::MandateNotFound)?;
-
+    let key_manager_state: KeyManagerState = state.into();
     let original_payment_intent = mandate
         .original_payment_id
         .as_ref()
         .async_map(|payment_id| async {
             db.find_payment_intent_by_payment_id_merchant_id(
+                &key_manager_state,
                 payment_id,
                 &mandate.merchant_id,
                 merchant_key_store,
@@ -1429,7 +1398,7 @@ pub(crate) async fn get_payment_method_create_request(
 }
 
 pub async fn get_customer_from_details<F: Clone>(
-    db: &dyn StorageInterface,
+    state: &SessionState,
     customer_id: Option<id_type::CustomerId>,
     merchant_id: &str,
     payment_data: &mut PaymentData<F>,
@@ -1439,8 +1408,10 @@ pub async fn get_customer_from_details<F: Clone>(
     match customer_id {
         None => Ok(None),
         Some(customer_id) => {
+            let db = &*state.store;
             let customer = db
                 .find_customer_optional_by_customer_id_merchant_id(
+                    &state.into(),
                     &customer_id,
                     merchant_id,
                     merchant_key_store,
@@ -1549,8 +1520,8 @@ pub async fn get_connector_default(
 #[instrument(skip_all)]
 #[allow(clippy::type_complexity)]
 pub async fn create_customer_if_not_exist<'a, F: Clone, R>(
+    state: &SessionState,
     operation: BoxedOperation<'a, F, R>,
-    db: &dyn StorageInterface,
     payment_data: &mut PaymentData<F>,
     req: Option<CustomerDetails>,
     merchant_id: &str,
@@ -1613,7 +1584,7 @@ pub async fn create_customer_if_not_exist<'a, F: Clone, R>(
 
     payment_data.payment_intent.customer_details = raw_customer_details
         .clone()
-        .async_map(|customer_details| create_encrypted_data(key_store, customer_details))
+        .async_map(|customer_details| create_encrypted_data(state, key_store, customer_details))
         .await
         .transpose()
         .change_context(errors::StorageError::EncryptionError)
@@ -1622,18 +1593,36 @@ pub async fn create_customer_if_not_exist<'a, F: Clone, R>(
     let customer_id = request_customer_details
         .customer_id
         .or(payment_data.payment_intent.customer_id.clone());
-
+    let db = &*state.store;
+    let key_manager_state = &state.into();
     let optional_customer = match customer_id {
         Some(customer_id) => {
             let customer_data = db
                 .find_customer_optional_by_customer_id_merchant_id(
+                    key_manager_state,
                     &customer_id,
                     merchant_id,
                     key_store,
                     storage_scheme,
                 )
                 .await?;
-
+            let key = key_store.key.get_inner().peek();
+            let encrypted_data = types::batch_encrypt(
+                key_manager_state,
+                CustomerRequestWithEmail::to_encryptable(CustomerRequestWithEmail {
+                    name: request_customer_details.name.clone(),
+                    email: request_customer_details.email.clone(),
+                    phone: request_customer_details.phone.clone(),
+                }),
+                Identifier::Merchant(key_store.merchant_id.clone()),
+                key,
+            )
+            .await
+            .change_context(errors::StorageError::SerializationFailed)
+            .attach_printable("Failed while encrypting Customer while Update")?;
+            let encryptable_customer = CustomerRequestWithEmail::from_encryptable(encrypted_data)
+                .change_context(errors::StorageError::SerializationFailed)
+                .attach_printable("Failed while encrypting Customer while Update")?;
             Some(match customer_data {
                 Some(c) => {
                     // Update the customer data if new data is passed in the request
@@ -1642,44 +1631,19 @@ pub async fn create_customer_if_not_exist<'a, F: Clone, R>(
                         | request_customer_details.phone.is_some()
                         | request_customer_details.phone_country_code.is_some()
                     {
-                        let key = key_store.key.get_inner().peek();
-                        let customer_update = async {
-                            Ok::<_, error_stack::Report<common_utils::errors::CryptoError>>(
-                                Update {
-                                    name: request_customer_details
-                                        .name
-                                        .async_lift(|inner| types::encrypt_optional(inner, key))
-                                        .await?,
-                                    email: request_customer_details
-                                        .email
-                                        .clone()
-                                        .async_lift(|inner| {
-                                            types::encrypt_optional(
-                                                inner.map(|inner| inner.expose()),
-                                                key,
-                                            )
-                                        })
-                                        .await?,
-                                    phone: Box::new(
-                                        request_customer_details
-                                            .phone
-                                            .clone()
-                                            .async_lift(|inner| types::encrypt_optional(inner, key))
-                                            .await?,
-                                    ),
-                                    phone_country_code: request_customer_details.phone_country_code,
-                                    description: None,
-                                    connector_customer: None,
-                                    metadata: None,
-                                    address_id: None,
-                                },
-                            )
-                        }
-                        .await
-                        .change_context(errors::StorageError::SerializationFailed)
-                        .attach_printable("Failed while encrypting Customer while Update")?;
+                        let customer_update = Update {
+                            name: encryptable_customer.name,
+                            email: encryptable_customer.email,
+                            phone: Box::new(encryptable_customer.phone),
+                            phone_country_code: request_customer_details.phone_country_code,
+                            description: None,
+                            connector_customer: None,
+                            metadata: None,
+                            address_id: None,
+                        };
 
                         db.update_customer_by_customer_id_merchant_id(
+                            key_manager_state,
                             customer_id,
                             merchant_id.to_string(),
                             c,
@@ -1693,51 +1657,25 @@ pub async fn create_customer_if_not_exist<'a, F: Clone, R>(
                     }
                 }
                 None => {
-                    let new_customer = async {
-                        let key = key_store.key.get_inner().peek();
-                        Ok::<_, error_stack::Report<common_utils::errors::CryptoError>>(
-                            domain::Customer {
-                                customer_id,
-                                merchant_id: merchant_id.to_string(),
-                                name: request_customer_details
-                                    .name
-                                    .async_lift(|inner| types::encrypt_optional(inner, key))
-                                    .await?,
-                                email: request_customer_details
-                                    .email
-                                    .clone()
-                                    .async_lift(|inner| {
-                                        types::encrypt_optional(
-                                            inner.map(|inner| inner.expose()),
-                                            key,
-                                        )
-                                    })
-                                    .await?,
-                                phone: request_customer_details
-                                    .phone
-                                    .clone()
-                                    .async_lift(|inner| types::encrypt_optional(inner, key))
-                                    .await?,
-                                phone_country_code: request_customer_details
-                                    .phone_country_code
-                                    .clone(),
-                                description: None,
-                                created_at: common_utils::date_time::now(),
-                                id: None,
-                                metadata: None,
-                                modified_at: common_utils::date_time::now(),
-                                connector_customer: None,
-                                address_id: None,
-                                default_payment_method_id: None,
-                                updated_by: None,
-                            },
-                        )
-                    }
-                    .await
-                    .change_context(errors::StorageError::SerializationFailed)
-                    .attach_printable("Failed while encrypting Customer while insert")?;
+                    let new_customer = domain::Customer {
+                        customer_id,
+                        merchant_id: merchant_id.to_string(),
+                        name: encryptable_customer.name,
+                        email: encryptable_customer.email,
+                        phone: encryptable_customer.phone,
+                        phone_country_code: request_customer_details.phone_country_code.clone(),
+                        description: None,
+                        created_at: common_utils::date_time::now(),
+                        id: None,
+                        metadata: None,
+                        modified_at: common_utils::date_time::now(),
+                        connector_customer: None,
+                        address_id: None,
+                        default_payment_method_id: None,
+                        updated_by: None,
+                    };
                     metrics::CUSTOMER_CREATED.add(&metrics::CONTEXT, 1, &[]);
-                    db.insert_customer(new_customer, key_store, storage_scheme)
+                    db.insert_customer(key_manager_state, new_customer, key_store, storage_scheme)
                         .await
                 }
             })
@@ -1746,6 +1684,7 @@ pub async fn create_customer_if_not_exist<'a, F: Clone, R>(
             None => None,
             Some(customer_id) => db
                 .find_customer_optional_by_customer_id_merchant_id(
+                    key_manager_state,
                     customer_id,
                     merchant_id,
                     key_store,
@@ -2533,14 +2472,16 @@ where
 
 #[cfg(feature = "olap")]
 pub(super) async fn filter_by_constraints(
-    db: &dyn StorageInterface,
+    state: &SessionState,
     constraints: &api::PaymentListConstraints,
     merchant_id: &str,
     key_store: &domain::MerchantKeyStore,
     storage_scheme: storage_enums::MerchantStorageScheme,
 ) -> CustomResult<Vec<PaymentIntent>, errors::DataStorageError> {
+    let db = &*state.store;
     let result = db
         .filter_payment_intent_by_constraints(
+            &(state).into(),
             merchant_id,
             &constraints.clone().into(),
             key_store,
@@ -2957,17 +2898,19 @@ pub(crate) fn validate_pm_or_token_given(
 
 // A function to perform database lookup and then verify the client secret
 pub async fn verify_payment_intent_time_and_client_secret(
-    db: &dyn StorageInterface,
+    state: &SessionState,
     merchant_account: &domain::MerchantAccount,
     key_store: &domain::MerchantKeyStore,
     client_secret: Option<String>,
 ) -> error_stack::Result<Option<PaymentIntent>, errors::ApiErrorResponse> {
+    let db = &*state.store;
     client_secret
         .async_map(|cs| async move {
             let payment_id = get_payment_id_from_client_secret(&cs)?;
 
             let payment_intent = db
                 .find_payment_intent_by_payment_id_merchant_id(
+                    &state.into(),
                     &payment_id,
                     &merchant_account.merchant_id,
                     key_store,
@@ -3371,6 +3314,7 @@ pub async fn get_merchant_connector_account(
     merchant_connector_id: Option<&String>,
 ) -> RouterResult<MerchantConnectorAccountType> {
     let db = &*state.store;
+    let key_manager_state = &state.into();
     match creds_identifier {
         Some(creds_identifier) => {
             let key = format!("mcd_{merchant_id}_{creds_identifier}");
@@ -3445,6 +3389,7 @@ pub async fn get_merchant_connector_account(
         None => {
             if let Some(merchant_connector_id) = merchant_connector_id {
                 db.find_by_merchant_connector_account_merchant_id_merchant_connector_id(
+                    key_manager_state,
                     merchant_id,
                     merchant_connector_id,
                     key_store,
@@ -3457,6 +3402,7 @@ pub async fn get_merchant_connector_account(
                 )
             } else {
                 db.find_merchant_connector_account_by_profile_id_connector_name(
+                    key_manager_state,
                     profile_id,
                     connector_name,
                     key_store,
@@ -3737,13 +3683,14 @@ impl AttemptType {
         request: &api::PaymentsRequest,
         fetched_payment_intent: PaymentIntent,
         fetched_payment_attempt: PaymentAttempt,
-        db: &dyn StorageInterface,
+        state: &SessionState,
         key_store: &domain::MerchantKeyStore,
         storage_scheme: storage::enums::MerchantStorageScheme,
     ) -> RouterResult<(PaymentIntent, PaymentAttempt)> {
         match self {
             Self::SameOld => Ok((fetched_payment_intent, fetched_payment_attempt)),
             Self::New => {
+                let db = &*state.store;
                 let new_attempt_count = fetched_payment_intent.attempt_count + 1;
                 let new_payment_attempt = db
                     .insert_payment_attempt(
@@ -3766,6 +3713,7 @@ impl AttemptType {
 
                 let updated_payment_intent = db
                     .update_payment_intent(
+                        &state.into(),
                         fetched_payment_intent,
                         storage::PaymentIntentUpdate::StatusAndAttemptUpdate {
                             status: payment_intent_status_fsm(
@@ -4159,6 +4107,7 @@ pub fn is_apple_pay_simplified_flow(
 }
 
 pub async fn get_encrypted_apple_pay_connector_wallets_details(
+    state: &SessionState,
     key_store: &domain::MerchantKeyStore,
     connector_metadata: &Option<masking::Secret<tera::Value>>,
 ) -> RouterResult<Option<Encryptable<masking::Secret<serde_json::Value>>>> {
@@ -4179,10 +4128,15 @@ pub async fn get_encrypted_apple_pay_connector_wallets_details(
         })
         .transpose()?
         .map(masking::Secret::new);
-
+    let key_manager_state: KeyManagerState = state.into();
     let encrypted_connector_apple_pay_details = connector_apple_pay_details
         .async_lift(|wallets_details| {
-            types::encrypt_optional(wallets_details, key_store.key.get_inner().peek())
+            types::encrypt_optional(
+                &key_manager_state,
+                wallets_details,
+                Identifier::Merchant(key_store.merchant_id.clone()),
+                key_store.key.get_inner().peek(),
+            )
         })
         .await
         .change_context(errors::ApiErrorResponse::InternalServerError)
@@ -4266,6 +4220,7 @@ where
         let merchant_connector_account_list = state
             .store
             .find_merchant_connector_account_by_merchant_id_and_disabled_list(
+                &state.into(),
                 merchant_account.merchant_id.as_str(),
                 false,
                 key_store,
@@ -5126,13 +5081,15 @@ pub async fn override_setup_future_usage_to_on_session<F: Clone>(
 }
 
 pub async fn validate_merchant_connector_ids_in_connector_mandate_details(
-    db: &dyn StorageInterface,
+    state: &SessionState,
     key_store: &domain::MerchantKeyStore,
     connector_mandate_details: &api_models::payment_methods::PaymentsMandateReference,
     merchant_id: &str,
 ) -> CustomResult<(), errors::ApiErrorResponse> {
+    let db = &*state.store;
     let merchant_connector_account_list = db
         .find_merchant_connector_account_by_merchant_id_and_disabled_list(
+            &state.into(),
             merchant_id,
             true,
             key_store,
diff --git a/crates/router/src/core/payments/operations.rs b/crates/router/src/core/payments/operations.rs
index be54ead0ac1..70cc77aa536 100644
--- a/crates/router/src/core/payments/operations.rs
+++ b/crates/router/src/core/payments/operations.rs
@@ -28,7 +28,6 @@ pub use self::{
 use super::{helpers, CustomerDetails, PaymentData};
 use crate::{
     core::errors::{self, CustomResult, RouterResult},
-    db::StorageInterface,
     routes::{app::ReqState, SessionState},
     services,
     types::{
@@ -117,7 +116,7 @@ pub trait Domain<F: Clone, R>: Send + Sync {
     /// This will fetch customer details, (this operation is flow specific)
     async fn get_or_create_customer_details<'a>(
         &'a self,
-        db: &dyn StorageInterface,
+        state: &SessionState,
         payment_data: &mut PaymentData<F>,
         request: Option<CustomerDetails>,
         merchant_key_store: &domain::MerchantKeyStore,
@@ -259,7 +258,7 @@ where
     #[instrument(skip_all)]
     async fn get_or_create_customer_details<'a>(
         &'a self,
-        db: &dyn StorageInterface,
+        state: &SessionState,
         payment_data: &mut PaymentData<F>,
         _request: Option<CustomerDetails>,
         merchant_key_store: &domain::MerchantKeyStore,
@@ -274,7 +273,7 @@ where
         Ok((
             Box::new(self),
             helpers::get_customer_from_details(
-                db,
+                state,
                 payment_data.payment_intent.customer_id.clone(),
                 &merchant_key_store.merchant_id,
                 payment_data,
@@ -334,7 +333,7 @@ where
     #[instrument(skip_all)]
     async fn get_or_create_customer_details<'a>(
         &'a self,
-        db: &dyn StorageInterface,
+        state: &SessionState,
         payment_data: &mut PaymentData<F>,
         _request: Option<CustomerDetails>,
         merchant_key_store: &domain::MerchantKeyStore,
@@ -349,7 +348,7 @@ where
         Ok((
             Box::new(self),
             helpers::get_customer_from_details(
-                db,
+                state,
                 payment_data.payment_intent.customer_id.clone(),
                 &merchant_key_store.merchant_id,
                 payment_data,
@@ -408,7 +407,7 @@ where
     #[instrument(skip_all)]
     async fn get_or_create_customer_details<'a>(
         &'a self,
-        db: &dyn StorageInterface,
+        state: &SessionState,
         payment_data: &mut PaymentData<F>,
         _request: Option<CustomerDetails>,
         merchant_key_store: &domain::MerchantKeyStore,
@@ -423,7 +422,7 @@ where
         Ok((
             Box::new(self),
             helpers::get_customer_from_details(
-                db,
+                state,
                 payment_data.payment_intent.customer_id.clone(),
                 &merchant_key_store.merchant_id,
                 payment_data,
@@ -483,7 +482,7 @@ where
     #[instrument(skip_all)]
     async fn get_or_create_customer_details<'a>(
         &'a self,
-        _db: &dyn StorageInterface,
+        _state: &SessionState,
         _payment_data: &mut PaymentData<F>,
         _request: Option<CustomerDetails>,
         _merchant_key_store: &domain::MerchantKeyStore,
diff --git a/crates/router/src/core/payments/operations/payment_approve.rs b/crates/router/src/core/payments/operations/payment_approve.rs
index 172c5943c0c..5b18512fe20 100644
--- a/crates/router/src/core/payments/operations/payment_approve.rs
+++ b/crates/router/src/core/payments/operations/payment_approve.rs
@@ -53,6 +53,7 @@ impl<F: Send + Clone> GetTracker<F, PaymentData<F>, api::PaymentsCaptureRequest>
 
         payment_intent = db
             .find_payment_intent_by_payment_id_merchant_id(
+                &state.into(),
                 &payment_id,
                 merchant_id,
                 key_store,
@@ -97,7 +98,7 @@ impl<F: Send + Clone> GetTracker<F, PaymentData<F>, api::PaymentsCaptureRequest>
         amount = payment_attempt.get_total_amount().into();
 
         let shipping_address = helpers::get_address_by_id(
-            db,
+            state,
             payment_intent.shipping_address_id.clone(),
             key_store,
             &payment_intent.payment_id,
@@ -107,7 +108,7 @@ impl<F: Send + Clone> GetTracker<F, PaymentData<F>, api::PaymentsCaptureRequest>
         .await?;
 
         let billing_address = helpers::get_address_by_id(
-            db,
+            state,
             payment_intent.billing_address_id.clone(),
             key_store,
             &payment_intent.payment_id,
@@ -117,7 +118,7 @@ impl<F: Send + Clone> GetTracker<F, PaymentData<F>, api::PaymentsCaptureRequest>
         .await?;
 
         let payment_method_billing = helpers::get_address_by_id(
-            db,
+            state,
             payment_attempt.payment_method_billing_address_id.clone(),
             key_store,
             &payment_intent.payment_id,
@@ -199,7 +200,7 @@ impl<F: Clone> UpdateTracker<F, PaymentData<F>, api::PaymentsCaptureRequest> for
     #[instrument(skip_all)]
     async fn update_trackers<'b>(
         &'b self,
-        db: &'b SessionState,
+        state: &'b SessionState,
         _req_state: ReqState,
         mut payment_data: PaymentData<F>,
         _customer: Option<domain::Customer>,
@@ -224,9 +225,10 @@ impl<F: Clone> UpdateTracker<F, PaymentData<F>, api::PaymentsCaptureRequest> for
             merchant_decision: Some(api_models::enums::MerchantDecision::Approved.to_string()),
             updated_by: storage_scheme.to_string(),
         };
-        payment_data.payment_intent = db
+        payment_data.payment_intent = state
             .store
             .update_payment_intent(
+                &state.into(),
                 payment_data.payment_intent,
                 intent_status_update,
                 key_store,
@@ -234,7 +236,8 @@ impl<F: Clone> UpdateTracker<F, PaymentData<F>, api::PaymentsCaptureRequest> for
             )
             .await
             .to_not_found_response(errors::ApiErrorResponse::PaymentNotFound)?;
-        db.store
+        state
+            .store
             .update_payment_attempt_with_attempt_id(
                 payment_data.payment_attempt.clone(),
                 storage::PaymentAttemptUpdate::StatusUpdate {
diff --git a/crates/router/src/core/payments/operations/payment_cancel.rs b/crates/router/src/core/payments/operations/payment_cancel.rs
index 94591d44e4b..a8a2756a58d 100644
--- a/crates/router/src/core/payments/operations/payment_cancel.rs
+++ b/crates/router/src/core/payments/operations/payment_cancel.rs
@@ -51,6 +51,7 @@ impl<F: Send + Clone> GetTracker<F, PaymentData<F>, api::PaymentsCancelRequest>
 
         let payment_intent = db
             .find_payment_intent_by_payment_id_merchant_id(
+                &state.into(),
                 &payment_id,
                 merchant_id,
                 key_store,
@@ -82,7 +83,7 @@ impl<F: Send + Clone> GetTracker<F, PaymentData<F>, api::PaymentsCancelRequest>
             .to_not_found_response(errors::ApiErrorResponse::PaymentNotFound)?;
 
         let shipping_address = helpers::get_address_by_id(
-            db,
+            state,
             payment_intent.shipping_address_id.clone(),
             key_store,
             &payment_intent.payment_id,
@@ -92,7 +93,7 @@ impl<F: Send + Clone> GetTracker<F, PaymentData<F>, api::PaymentsCancelRequest>
         .await?;
 
         let billing_address = helpers::get_address_by_id(
-            db,
+            state,
             payment_intent.billing_address_id.clone(),
             key_store,
             &payment_intent.payment_id,
@@ -102,7 +103,7 @@ impl<F: Send + Clone> GetTracker<F, PaymentData<F>, api::PaymentsCancelRequest>
         .await?;
 
         let payment_method_billing = helpers::get_address_by_id(
-            db,
+            state,
             payment_attempt.payment_method_billing_address_id.clone(),
             key_store,
             &payment_intent.payment_id,
@@ -212,7 +213,7 @@ impl<F: Clone> UpdateTracker<F, PaymentData<F>, api::PaymentsCancelRequest> for
     #[instrument(skip_all)]
     async fn update_trackers<'b>(
         &'b self,
-        db: &'b SessionState,
+        state: &'b SessionState,
         req_state: ReqState,
         mut payment_data: PaymentData<F>,
         _customer: Option<domain::Customer>,
@@ -242,9 +243,10 @@ impl<F: Clone> UpdateTracker<F, PaymentData<F>, api::PaymentsCancelRequest> for
             };
 
         if let Some(payment_intent_update) = intent_status_update {
-            payment_data.payment_intent = db
+            payment_data.payment_intent = state
                 .store
                 .update_payment_intent(
+                    &state.into(),
                     payment_data.payment_intent,
                     payment_intent_update,
                     key_store,
@@ -254,7 +256,8 @@ impl<F: Clone> UpdateTracker<F, PaymentData<F>, api::PaymentsCancelRequest> for
                 .to_not_found_response(errors::ApiErrorResponse::PaymentNotFound)?;
         }
 
-        db.store
+        state
+            .store
             .update_payment_attempt_with_attempt_id(
                 payment_data.payment_attempt.clone(),
                 storage::PaymentAttemptUpdate::VoidUpdate {
diff --git a/crates/router/src/core/payments/operations/payment_capture.rs b/crates/router/src/core/payments/operations/payment_capture.rs
index f6e6dee14a5..03a3d031e1a 100644
--- a/crates/router/src/core/payments/operations/payment_capture.rs
+++ b/crates/router/src/core/payments/operations/payment_capture.rs
@@ -54,6 +54,7 @@ impl<F: Send + Clone> GetTracker<F, payments::PaymentData<F>, api::PaymentsCaptu
 
         payment_intent = db
             .find_payment_intent_by_payment_id_merchant_id(
+                &state.into(),
                 &payment_id,
                 merchant_id,
                 key_store,
@@ -135,7 +136,7 @@ impl<F: Send + Clone> GetTracker<F, payments::PaymentData<F>, api::PaymentsCaptu
         amount = payment_attempt.get_total_amount().into();
 
         let shipping_address = helpers::get_address_by_id(
-            db,
+            state,
             payment_intent.shipping_address_id.clone(),
             key_store,
             &payment_intent.payment_id,
@@ -145,7 +146,7 @@ impl<F: Send + Clone> GetTracker<F, payments::PaymentData<F>, api::PaymentsCaptu
         .await?;
 
         let billing_address = helpers::get_address_by_id(
-            db,
+            state,
             payment_intent.billing_address_id.clone(),
             key_store,
             &payment_intent.payment_id,
@@ -155,7 +156,7 @@ impl<F: Send + Clone> GetTracker<F, payments::PaymentData<F>, api::PaymentsCaptu
         .await?;
 
         let payment_method_billing = helpers::get_address_by_id(
-            db,
+            state,
             payment_attempt.payment_method_billing_address_id.clone(),
             key_store,
             &payment_intent.payment_id,
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 9c48df1dd53..c6875392750 100644
--- a/crates/router/src/core/payments/operations/payment_complete_authorize.rs
+++ b/crates/router/src/core/payments/operations/payment_complete_authorize.rs
@@ -17,7 +17,6 @@ use crate::{
         },
         utils as core_utils,
     },
-    db::StorageInterface,
     routes::{app::ReqState, SessionState},
     services,
     types::{
@@ -56,6 +55,7 @@ impl<F: Send + Clone> GetTracker<F, PaymentData<F>, api::PaymentsRequest> for Co
 
         payment_intent = db
             .find_payment_intent_by_payment_id_merchant_id(
+                &state.into(),
                 &payment_id,
                 merchant_id,
                 key_store,
@@ -200,7 +200,7 @@ impl<F: Send + Clone> GetTracker<F, PaymentData<F>, api::PaymentsRequest> for Co
         )?;
 
         let shipping_address = helpers::create_or_update_address_for_payment_by_request(
-            db,
+            state,
             request.shipping.as_ref(),
             payment_intent.shipping_address_id.clone().as_deref(),
             merchant_id.as_ref(),
@@ -216,7 +216,7 @@ impl<F: Send + Clone> GetTracker<F, PaymentData<F>, api::PaymentsRequest> for Co
             .map(|shipping_address| shipping_address.address_id.clone());
 
         let billing_address = helpers::get_address_by_id(
-            db,
+            state,
             payment_intent.billing_address_id.clone(),
             key_store,
             &payment_intent.payment_id,
@@ -226,7 +226,7 @@ impl<F: Send + Clone> GetTracker<F, PaymentData<F>, api::PaymentsRequest> for Co
         .await?;
 
         let payment_method_billing = helpers::get_address_by_id(
-            db,
+            state,
             payment_attempt.payment_method_billing_address_id.clone(),
             key_store,
             &payment_intent.payment_id,
@@ -364,7 +364,7 @@ impl<F: Clone + Send> Domain<F, api::PaymentsRequest> for CompleteAuthorize {
     #[instrument(skip_all)]
     async fn get_or_create_customer_details<'a>(
         &'a self,
-        db: &dyn StorageInterface,
+        state: &SessionState,
         payment_data: &mut PaymentData<F>,
         request: Option<CustomerDetails>,
         key_store: &domain::MerchantKeyStore,
@@ -377,8 +377,8 @@ impl<F: Clone + Send> Domain<F, api::PaymentsRequest> for CompleteAuthorize {
         errors::StorageError,
     > {
         helpers::create_customer_if_not_exist(
+            state,
             Box::new(self),
-            db,
             payment_data,
             request,
             &key_store.merchant_id,
@@ -478,6 +478,7 @@ impl<F: Clone> UpdateTracker<F, PaymentData<F>, api::PaymentsRequest> for Comple
 
         let updated_payment_intent = db
             .update_payment_intent(
+                &state.into(),
                 payment_intent,
                 payment_intent_update,
                 key_store,
diff --git a/crates/router/src/core/payments/operations/payment_confirm.rs b/crates/router/src/core/payments/operations/payment_confirm.rs
index 2955b0c3850..addd2f30670 100644
--- a/crates/router/src/core/payments/operations/payment_confirm.rs
+++ b/crates/router/src/core/payments/operations/payment_confirm.rs
@@ -7,7 +7,10 @@ use api_models::{
     payments::{AdditionalPaymentData, ExtendedCardInfo},
 };
 use async_trait::async_trait;
-use common_utils::ext_traits::{AsyncExt, Encode, StringExt, ValueExt};
+use common_utils::{
+    ext_traits::{AsyncExt, Encode, StringExt, ValueExt},
+    types::keymanager::Identifier,
+};
 use error_stack::{report, ResultExt};
 use futures::FutureExt;
 use hyperswitch_domain_models::payments::payment_intent::PaymentIntentUpdateFields;
@@ -30,7 +33,6 @@ use crate::{
         },
         utils as core_utils,
     },
-    db::StorageInterface,
     events::audit_events::{AuditEvent, AuditEventType},
     routes::{app::ReqState, SessionState},
     services,
@@ -74,6 +76,7 @@ impl<F: Send + Clone> GetTracker<F, PaymentData<F>, api::PaymentsRequest> for Pa
         // Parallel calls - level 0
         let mut payment_intent = store
             .find_payment_intent_by_payment_id_merchant_id(
+                &state.into(),
                 &payment_id,
                 m_merchant_id.as_str(),
                 key_store,
@@ -181,13 +184,13 @@ impl<F: Send + Clone> GetTracker<F, PaymentData<F>, api::PaymentsRequest> for Pa
         let m_payment_intent_payment_id = payment_intent.payment_id.clone();
         let m_customer_details_customer_id = customer_details.customer_id.clone();
         let m_payment_intent_customer_id = payment_intent.customer_id.clone();
-        let store = state.clone().store;
         let m_key_store = key_store.clone();
+        let session_state = state.clone();
 
         let shipping_address_fut = tokio::spawn(
             async move {
                 helpers::create_or_update_address_for_payment_by_request(
-                    store.as_ref(),
+                    &session_state,
                     m_request_shipping.as_ref(),
                     m_payment_intent_shipping_address_id.as_deref(),
                     m_merchant_id.as_str(),
@@ -209,13 +212,13 @@ impl<F: Send + Clone> GetTracker<F, PaymentData<F>, api::PaymentsRequest> for Pa
         let m_payment_intent_customer_id = payment_intent.customer_id.clone();
         let m_payment_intent_billing_address_id = payment_intent.billing_address_id.clone();
         let m_payment_intent_payment_id = payment_intent.payment_id.clone();
-        let store = state.clone().store;
         let m_key_store = key_store.clone();
+        let session_state = state.clone();
 
         let billing_address_fut = tokio::spawn(
             async move {
                 helpers::create_or_update_address_for_payment_by_request(
-                    store.as_ref(),
+                    &session_state,
                     m_request_billing.as_ref(),
                     m_payment_intent_billing_address_id.as_deref(),
                     m_merchant_id.as_ref(),
@@ -306,7 +309,7 @@ impl<F: Send + Clone> GetTracker<F, PaymentData<F>, api::PaymentsRequest> for Pa
                             request,
                             payment_intent,
                             payment_attempt,
-                            &*state.store,
+                            state,
                             key_store,
                             storage_scheme,
                         )
@@ -467,8 +470,6 @@ impl<F: Send + Clone> GetTracker<F, PaymentData<F>, api::PaymentsRequest> for Pa
             .in_current_span(),
         );
 
-        let store = state.clone().store;
-
         let n_payment_method_billing_address_id =
             payment_attempt.payment_method_billing_address_id.clone();
         let n_request_payment_method_billing_address = request
@@ -480,11 +481,12 @@ impl<F: Send + Clone> GetTracker<F, PaymentData<F>, api::PaymentsRequest> for Pa
         let m_key_store = key_store.clone();
         let m_customer_details_customer_id = customer_details.customer_id.clone();
         let m_merchant_id = merchant_id.clone();
+        let session_state = state.clone();
 
         let payment_method_billing_future = tokio::spawn(
             async move {
                 helpers::create_or_update_address_for_payment_by_request(
-                    store.as_ref(),
+                    &session_state,
                     n_request_payment_method_billing_address.as_ref(),
                     n_payment_method_billing_address_id.as_deref(),
                     m_merchant_id.as_str(),
@@ -688,7 +690,7 @@ impl<F: Clone + Send> Domain<F, api::PaymentsRequest> for PaymentConfirm {
     #[instrument(skip_all)]
     async fn get_or_create_customer_details<'a>(
         &'a self,
-        db: &dyn StorageInterface,
+        state: &SessionState,
         payment_data: &mut PaymentData<F>,
         request: Option<CustomerDetails>,
         key_store: &domain::MerchantKeyStore,
@@ -701,8 +703,8 @@ impl<F: Clone + Send> Domain<F, api::PaymentsRequest> for PaymentConfirm {
         errors::StorageError,
     > {
         helpers::create_customer_if_not_exist(
+            state,
             Box::new(self),
-            db,
             payment_data,
             request,
             &key_store.merchant_id,
@@ -1077,12 +1079,15 @@ impl<F: Clone> UpdateTracker<F, PaymentData<F>, api::PaymentsRequest> for Paymen
             .transpose()
             .change_context(errors::ApiErrorResponse::InternalServerError)
             .attach_printable("Failed to encode additional pm data")?;
+        let key_manager_state = &state.into();
         let encode_additional_pm_to_value = if let Some(ref pm) = payment_data.payment_method_info {
             let key = key_store.key.get_inner().peek();
 
             let card_detail_from_locker: Option<api::CardDetailFromLocker> =
                 decrypt::<serde_json::Value, masking::WithType>(
+                    key_manager_state,
                     pm.payment_method_data.clone(),
+                    Identifier::Merchant(key_store.merchant_id.clone()),
                     key,
                 )
                 .await
@@ -1243,7 +1248,7 @@ impl<F: Clone> UpdateTracker<F, PaymentData<F>, api::PaymentsRequest> for Paymen
 
         let billing_address = payment_data.address.get_payment_billing();
         let billing_details = billing_address
-            .async_map(|billing_details| create_encrypted_data(key_store, billing_details))
+            .async_map(|billing_details| create_encrypted_data(state, key_store, billing_details))
             .await
             .transpose()
             .change_context(errors::ApiErrorResponse::InternalServerError)
@@ -1251,7 +1256,7 @@ impl<F: Clone> UpdateTracker<F, PaymentData<F>, api::PaymentsRequest> for Paymen
 
         let shipping_address = payment_data.address.get_shipping();
         let shipping_details = shipping_address
-            .async_map(|shipping_details| create_encrypted_data(key_store, shipping_details))
+            .async_map(|shipping_details| create_encrypted_data(state, key_store, shipping_details))
             .await
             .transpose()
             .change_context(errors::ApiErrorResponse::InternalServerError)
@@ -1273,10 +1278,12 @@ impl<F: Clone> UpdateTracker<F, PaymentData<F>, api::PaymentsRequest> for Paymen
         let m_storage_scheme = storage_scheme.to_string();
         let session_expiry = m_payment_data_payment_intent.session_expiry;
         let m_key_store = key_store.clone();
+        let key_manager_state = state.into();
 
         let payment_intent_fut = tokio::spawn(
             async move {
                 m_db.update_payment_intent(
+                    &key_manager_state,
                     m_payment_data_payment_intent,
                     storage::PaymentIntentUpdate::Update(Box::new(PaymentIntentUpdateFields {
                         amount: payment_data.payment_intent.amount,
@@ -1320,10 +1327,13 @@ impl<F: Clone> UpdateTracker<F, PaymentData<F>, api::PaymentsRequest> for Paymen
                 let m_customer_merchant_id = customer.merchant_id.to_owned();
                 let m_key_store = key_store.clone();
                 let m_updated_customer = updated_customer.clone();
-                let m_db = state.clone().store;
+                let session_state = state.clone();
+                let m_db = session_state.store.clone();
+                let key_manager_state = state.into();
                 tokio::spawn(
                     async move {
                         m_db.update_customer_by_customer_id_merchant_id(
+                            &key_manager_state,
                             m_customer_customer_id,
                             m_customer_merchant_id,
                             customer,
diff --git a/crates/router/src/core/payments/operations/payment_create.rs b/crates/router/src/core/payments/operations/payment_create.rs
index 18dc2c5f39a..929f404eae9 100644
--- a/crates/router/src/core/payments/operations/payment_create.rs
+++ b/crates/router/src/core/payments/operations/payment_create.rs
@@ -6,7 +6,7 @@ use api_models::{
 use async_trait::async_trait;
 use common_utils::{
     ext_traits::{AsyncExt, Encode, ValueExt},
-    types::MinorUnit,
+    types::{keymanager::Identifier, MinorUnit},
 };
 use diesel_models::{ephemeral_key, PaymentMethod};
 use error_stack::{self, ResultExt};
@@ -32,7 +32,10 @@ use crate::{
         utils as core_utils,
     },
     db::StorageInterface,
-    routes::{app::ReqState, SessionState},
+    routes::{
+        app::{ReqState, SessionStateInfo},
+        SessionState,
+    },
     services,
     types::{
         api::{self, PaymentIdTypeExt},
@@ -143,7 +146,7 @@ impl<F: Send + Clone> GetTracker<F, PaymentData<F>, api::PaymentsRequest> for Pa
         let customer_details = helpers::get_customer_details_from_request(request);
 
         let shipping_address = helpers::create_or_find_address_for_payment_by_request(
-            db,
+            state,
             request.shipping.as_ref(),
             None,
             merchant_id,
@@ -155,7 +158,7 @@ impl<F: Send + Clone> GetTracker<F, PaymentData<F>, api::PaymentsRequest> for Pa
         .await?;
 
         let billing_address = helpers::create_or_find_address_for_payment_by_request(
-            db,
+            state,
             request.billing.as_ref(),
             None,
             merchant_id,
@@ -168,7 +171,7 @@ impl<F: Send + Clone> GetTracker<F, PaymentData<F>, api::PaymentsRequest> for Pa
 
         let payment_method_billing_address =
             helpers::create_or_find_address_for_payment_by_request(
-                db,
+                state,
                 request
                     .payment_method_data
                     .as_ref()
@@ -286,7 +289,12 @@ impl<F: Send + Clone> GetTracker<F, PaymentData<F>, api::PaymentsRequest> for Pa
         .await?;
 
         payment_intent = db
-            .insert_payment_intent(payment_intent_new, merchant_key_store, storage_scheme)
+            .insert_payment_intent(
+                &state.into(),
+                payment_intent_new,
+                merchant_key_store,
+                storage_scheme,
+            )
             .await
             .to_duplicate_response(errors::ApiErrorResponse::DuplicatePayment {
                 payment_id: payment_id.clone(),
@@ -475,7 +483,7 @@ impl<F: Clone + Send> Domain<F, api::PaymentsRequest> for PaymentCreate {
     #[instrument(skip_all)]
     async fn get_or_create_customer_details<'a>(
         &'a self,
-        db: &dyn StorageInterface,
+        state: &SessionState,
         payment_data: &mut PaymentData<F>,
         request: Option<CustomerDetails>,
         key_store: &domain::MerchantKeyStore,
@@ -488,8 +496,8 @@ impl<F: Clone + Send> Domain<F, api::PaymentsRequest> for PaymentCreate {
         errors::StorageError,
     > {
         helpers::create_customer_if_not_exist(
+            state,
             Box::new(self),
-            db,
             payment_data,
             request,
             &key_store.merchant_id,
@@ -638,12 +646,15 @@ impl<F: Clone> UpdateTracker<F, PaymentData<F>, api::PaymentsRequest> for Paymen
         let raw_customer_details = customer
             .map(|customer| CustomerData::try_from(customer.clone()))
             .transpose()?;
+        let session_state = state.session_state();
 
         // Updation of Customer Details for the cases where both customer_id and specific customer
         // details are provided in Payment Create Request
         let customer_details = raw_customer_details
             .clone()
-            .async_map(|customer_details| create_encrypted_data(key_store, customer_details))
+            .async_map(|customer_details| {
+                create_encrypted_data(&session_state, key_store, customer_details)
+            })
             .await
             .transpose()
             .change_context(errors::ApiErrorResponse::InternalServerError)
@@ -652,6 +663,7 @@ impl<F: Clone> UpdateTracker<F, PaymentData<F>, api::PaymentsRequest> for Paymen
         payment_data.payment_intent = state
             .store
             .update_payment_intent(
+                &state.into(),
                 payment_data.payment_intent,
                 storage::PaymentIntentUpdate::PaymentCreateUpdate {
                     return_url: None,
@@ -836,7 +848,9 @@ impl PaymentCreate {
                 .as_ref()
                 .async_map(|pm_info| async {
                     decrypt::<serde_json::Value, masking::WithType>(
+                        &state.into(),
                         pm_info.payment_method_data.clone(),
+                        Identifier::Merchant(key_store.merchant_id.clone()),
                         key_store.key.get_inner().peek(),
                     )
                     .await
@@ -983,7 +997,7 @@ impl PaymentCreate {
     #[instrument(skip_all)]
     #[allow(clippy::too_many_arguments)]
     async fn make_payment_intent(
-        _state: &SessionState,
+        state: &SessionState,
         payment_id: &str,
         merchant_account: &domain::MerchantAccount,
         key_store: &domain::MerchantKeyStore,
@@ -1057,7 +1071,7 @@ impl PaymentCreate {
         let billing_details = request
             .billing
             .clone()
-            .async_map(|billing_details| create_encrypted_data(key_store, billing_details))
+            .async_map(|billing_details| create_encrypted_data(state, key_store, billing_details))
             .await
             .transpose()
             .change_context(errors::ApiErrorResponse::InternalServerError)
@@ -1068,7 +1082,7 @@ impl PaymentCreate {
         let shipping_details = request
             .shipping
             .clone()
-            .async_map(|shipping_details| create_encrypted_data(key_store, shipping_details))
+            .async_map(|shipping_details| create_encrypted_data(state, key_store, shipping_details))
             .await
             .transpose()
             .change_context(errors::ApiErrorResponse::InternalServerError)
@@ -1093,7 +1107,7 @@ impl PaymentCreate {
 
         // Encrypting our Customer Details to be stored in Payment Intent
         let customer_details = raw_customer_details
-            .async_map(|customer_details| create_encrypted_data(key_store, customer_details))
+            .async_map(|customer_details| create_encrypted_data(state, key_store, customer_details))
             .await
             .transpose()
             .change_context(errors::ApiErrorResponse::InternalServerError)
diff --git a/crates/router/src/core/payments/operations/payment_reject.rs b/crates/router/src/core/payments/operations/payment_reject.rs
index a3a8130a9f6..a83079a6a43 100644
--- a/crates/router/src/core/payments/operations/payment_reject.rs
+++ b/crates/router/src/core/payments/operations/payment_reject.rs
@@ -48,6 +48,7 @@ impl<F: Send + Clone> GetTracker<F, PaymentData<F>, PaymentsCancelRequest> for P
 
         let payment_intent = db
             .find_payment_intent_by_payment_id_merchant_id(
+                &state.into(),
                 &payment_id,
                 merchant_id,
                 key_store,
@@ -79,7 +80,7 @@ impl<F: Send + Clone> GetTracker<F, PaymentData<F>, PaymentsCancelRequest> for P
             .to_not_found_response(errors::ApiErrorResponse::PaymentNotFound)?;
 
         let shipping_address = helpers::get_address_by_id(
-            db,
+            state,
             payment_intent.shipping_address_id.clone(),
             key_store,
             &payment_intent.payment_id,
@@ -89,7 +90,7 @@ impl<F: Send + Clone> GetTracker<F, PaymentData<F>, PaymentsCancelRequest> for P
         .await?;
 
         let billing_address = helpers::get_address_by_id(
-            db,
+            state,
             payment_intent.billing_address_id.clone(),
             key_store,
             &payment_intent.payment_id,
@@ -99,7 +100,7 @@ impl<F: Send + Clone> GetTracker<F, PaymentData<F>, PaymentsCancelRequest> for P
         .await?;
 
         let payment_method_billing = helpers::get_address_by_id(
-            db,
+            state,
             payment_attempt.payment_method_billing_address_id.clone(),
             key_store,
             &payment_intent.payment_id,
@@ -234,6 +235,7 @@ impl<F: Clone> UpdateTracker<F, PaymentData<F>, PaymentsCancelRequest> for Payme
         payment_data.payment_intent = state
             .store
             .update_payment_intent(
+                &state.into(),
                 payment_data.payment_intent,
                 intent_status_update,
                 key_store,
diff --git a/crates/router/src/core/payments/operations/payment_response.rs b/crates/router/src/core/payments/operations/payment_response.rs
index fc075f29799..808b2ae6181 100644
--- a/crates/router/src/core/payments/operations/payment_response.rs
+++ b/crates/router/src/core/payments/operations/payment_response.rs
@@ -2,7 +2,10 @@ use std::collections::HashMap;
 
 use async_trait::async_trait;
 use common_enums::AuthorizationStatus;
-use common_utils::{ext_traits::Encode, types::MinorUnit};
+use common_utils::{
+    ext_traits::Encode,
+    types::{keymanager::KeyManagerState, MinorUnit},
+};
 use error_stack::{report, ResultExt};
 use futures::FutureExt;
 use hyperswitch_domain_models::payments::payment_attempt::PaymentAttempt;
@@ -265,7 +268,7 @@ impl<F: Clone> PostUpdateTracker<F, PaymentData<F>, types::PaymentsIncrementalAu
 {
     async fn update_tracker<'b>(
         &'b self,
-        db: &'b SessionState,
+        state: &'b SessionState,
         _payment_id: &api::PaymentIdType,
         mut payment_data: PaymentData<F>,
         router_data: types::RouterData<
@@ -317,7 +320,7 @@ impl<F: Clone> PostUpdateTracker<F, PaymentData<F>, types::PaymentsIncrementalAu
             };
         //payment_attempt update
         if let Some(payment_attempt_update) = option_payment_attempt_update {
-            payment_data.payment_attempt = db
+            payment_data.payment_attempt = state
                 .store
                 .update_payment_attempt_with_attempt_id(
                     payment_data.payment_attempt.clone(),
@@ -329,9 +332,10 @@ impl<F: Clone> PostUpdateTracker<F, PaymentData<F>, types::PaymentsIncrementalAu
         }
         // payment_intent update
         if let Some(payment_intent_update) = option_payment_intent_update {
-            payment_data.payment_intent = db
+            payment_data.payment_intent = state
                 .store
                 .update_payment_intent(
+                    &state.into(),
                     payment_data.payment_intent.clone(),
                     payment_intent_update,
                     key_store,
@@ -370,7 +374,8 @@ impl<F: Clone> PostUpdateTracker<F, PaymentData<F>, types::PaymentsIncrementalAu
                     "missing authorization_id in incremental_authorization_details in payment_data",
                 ),
             )?;
-        db.store
+        state
+            .store
             .update_authorization_by_merchant_id_authorization_id(
                 router_data.merchant_id.clone(),
                 authorization_id,
@@ -380,7 +385,7 @@ impl<F: Clone> PostUpdateTracker<F, PaymentData<F>, types::PaymentsIncrementalAu
             .to_not_found_response(errors::ApiErrorResponse::InternalServerError)
             .attach_printable("failed while updating authorization")?;
         //Fetch all the authorizations of the payment and send in incremental authorization response
-        let authorizations = db
+        let authorizations = state
             .store
             .find_all_authorizations_by_merchant_id_payment_id(
                 &router_data.merchant_id,
@@ -1255,9 +1260,11 @@ async fn payment_response_update_tracker<F: Clone, T: types::Capturable>(
     let m_key_store = key_store.clone();
     let m_payment_data_payment_intent = payment_data.payment_intent.clone();
     let m_payment_intent_update = payment_intent_update.clone();
+    let key_manager_state: KeyManagerState = state.into();
     let payment_intent_fut = tokio::spawn(
         async move {
             m_db.update_payment_intent(
+                &key_manager_state,
                 m_payment_data_payment_intent,
                 m_payment_intent_update,
                 &m_key_store,
diff --git a/crates/router/src/core/payments/operations/payment_session.rs b/crates/router/src/core/payments/operations/payment_session.rs
index 503a5c5f2bb..00f599d4095 100644
--- a/crates/router/src/core/payments/operations/payment_session.rs
+++ b/crates/router/src/core/payments/operations/payment_session.rs
@@ -13,7 +13,6 @@ use crate::{
         errors::{self, RouterResult, StorageErrorExt},
         payments::{self, helpers, operations, PaymentData},
     },
-    db::StorageInterface,
     routes::{app::ReqState, SessionState},
     services,
     types::{
@@ -53,6 +52,7 @@ impl<F: Send + Clone> GetTracker<F, PaymentData<F>, api::PaymentsSessionRequest>
 
         let mut payment_intent = db
             .find_payment_intent_by_payment_id_merchant_id(
+                &state.into(),
                 &payment_id,
                 merchant_id,
                 key_store,
@@ -89,7 +89,7 @@ impl<F: Send + Clone> GetTracker<F, PaymentData<F>, api::PaymentsSessionRequest>
         let amount = payment_attempt.get_total_amount().into();
 
         let shipping_address = helpers::get_address_by_id(
-            db,
+            state,
             payment_intent.shipping_address_id.clone(),
             key_store,
             &payment_intent.payment_id,
@@ -99,7 +99,7 @@ impl<F: Send + Clone> GetTracker<F, PaymentData<F>, api::PaymentsSessionRequest>
         .await?;
 
         let billing_address = helpers::get_address_by_id(
-            db,
+            state,
             payment_intent.billing_address_id.clone(),
             key_store,
             &payment_intent.payment_id,
@@ -109,7 +109,7 @@ impl<F: Send + Clone> GetTracker<F, PaymentData<F>, api::PaymentsSessionRequest>
         .await?;
 
         let payment_method_billing = helpers::get_address_by_id(
-            db,
+            state,
             payment_attempt.payment_method_billing_address_id.clone(),
             key_store,
             &payment_intent.payment_id,
@@ -244,6 +244,7 @@ impl<F: Clone> UpdateTracker<F, PaymentData<F>, api::PaymentsSessionRequest> for
             Some(metadata) => state
                 .store
                 .update_payment_intent(
+                    &state.into(),
                     payment_data.payment_intent,
                     storage::PaymentIntentUpdate::MetadataUpdate {
                         metadata,
@@ -295,7 +296,7 @@ where
     #[instrument(skip_all)]
     async fn get_or_create_customer_details<'a>(
         &'a self,
-        db: &dyn StorageInterface,
+        state: &SessionState,
         payment_data: &mut PaymentData<F>,
         request: Option<payments::CustomerDetails>,
         key_store: &domain::MerchantKeyStore,
@@ -308,8 +309,8 @@ where
         errors::StorageError,
     > {
         helpers::create_customer_if_not_exist(
+            state,
             Box::new(self),
-            db,
             payment_data,
             request,
             &key_store.merchant_id,
@@ -358,6 +359,7 @@ where
 
         let all_connector_accounts = db
             .find_merchant_connector_account_by_merchant_id_and_disabled_list(
+                &state.into(),
                 &merchant_account.merchant_id,
                 false,
                 key_store,
diff --git a/crates/router/src/core/payments/operations/payment_start.rs b/crates/router/src/core/payments/operations/payment_start.rs
index c4096c6ea5a..98befe122cc 100644
--- a/crates/router/src/core/payments/operations/payment_start.rs
+++ b/crates/router/src/core/payments/operations/payment_start.rs
@@ -12,7 +12,6 @@ use crate::{
         errors::{self, CustomResult, RouterResult, StorageErrorExt},
         payments::{helpers, operations, CustomerDetails, PaymentAddress, PaymentData},
     },
-    db::StorageInterface,
     routes::{app::ReqState, SessionState},
     services,
     types::{
@@ -51,6 +50,7 @@ impl<F: Send + Clone> GetTracker<F, PaymentData<F>, api::PaymentsStartRequest> f
 
         payment_intent = db
             .find_payment_intent_by_payment_id_merchant_id(
+                &state.into(),
                 &payment_id,
                 merchant_id,
                 key_store,
@@ -86,7 +86,7 @@ impl<F: Send + Clone> GetTracker<F, PaymentData<F>, api::PaymentsStartRequest> f
         amount = payment_attempt.get_total_amount().into();
 
         let shipping_address = helpers::get_address_by_id(
-            db,
+            state,
             payment_intent.shipping_address_id.clone(),
             key_store,
             &payment_intent.payment_id,
@@ -96,7 +96,7 @@ impl<F: Send + Clone> GetTracker<F, PaymentData<F>, api::PaymentsStartRequest> f
         .await?;
 
         let billing_address = helpers::get_address_by_id(
-            db,
+            state,
             payment_intent.billing_address_id.clone(),
             key_store,
             &payment_intent.payment_id,
@@ -106,7 +106,7 @@ impl<F: Send + Clone> GetTracker<F, PaymentData<F>, api::PaymentsStartRequest> f
         .await?;
 
         let payment_method_billing = helpers::get_address_by_id(
-            db,
+            state,
             payment_attempt.payment_method_billing_address_id.clone(),
             key_store,
             &payment_intent.payment_id,
@@ -268,7 +268,7 @@ where
     #[instrument(skip_all)]
     async fn get_or_create_customer_details<'a>(
         &'a self,
-        db: &dyn StorageInterface,
+        state: &SessionState,
         payment_data: &mut PaymentData<F>,
         request: Option<CustomerDetails>,
         key_store: &domain::MerchantKeyStore,
@@ -281,8 +281,8 @@ where
         errors::StorageError,
     > {
         helpers::create_customer_if_not_exist(
+            state,
             Box::new(self),
-            db,
             payment_data,
             request,
             &key_store.merchant_id,
diff --git a/crates/router/src/core/payments/operations/payment_status.rs b/crates/router/src/core/payments/operations/payment_status.rs
index 5f20ccdf277..fff096d9b4c 100644
--- a/crates/router/src/core/payments/operations/payment_status.rs
+++ b/crates/router/src/core/payments/operations/payment_status.rs
@@ -2,7 +2,7 @@ use std::marker::PhantomData;
 
 use api_models::enums::FrmSuggestion;
 use async_trait::async_trait;
-use common_utils::ext_traits::AsyncExt;
+use common_utils::{ext_traits::AsyncExt, types::keymanager::KeyManagerState};
 use error_stack::ResultExt;
 use router_derive::PaymentOperation;
 use router_env::{instrument, logger, tracing};
@@ -16,7 +16,6 @@ use crate::{
             PaymentData,
         },
     },
-    db::StorageInterface,
     routes::{app::ReqState, SessionState},
     services,
     types::{
@@ -58,7 +57,7 @@ impl<F: Clone + Send> Domain<F, api::PaymentsRequest> for PaymentStatus {
     #[instrument(skip_all)]
     async fn get_or_create_customer_details<'a>(
         &'a self,
-        db: &dyn StorageInterface,
+        state: &SessionState,
         payment_data: &mut PaymentData<F>,
         request: Option<CustomerDetails>,
         key_store: &domain::MerchantKeyStore,
@@ -71,8 +70,8 @@ impl<F: Clone + Send> Domain<F, api::PaymentsRequest> for PaymentStatus {
         errors::StorageError,
     > {
         helpers::create_customer_if_not_exist(
+            state,
             Box::new(self),
-            db,
             payment_data,
             request,
             &key_store.merchant_id,
@@ -197,7 +196,7 @@ impl<F: Send + Clone> GetTracker<F, PaymentData<F>, api::PaymentsRetrieveRequest
             payment_id,
             merchant_account,
             key_store,
-            &*state.store,
+            state,
             request,
             self,
             merchant_account.storage_scheme,
@@ -214,7 +213,7 @@ async fn get_tracker_for_sync<
     payment_id: &api::PaymentIdType,
     merchant_account: &domain::MerchantAccount,
     key_store: &domain::MerchantKeyStore,
-    db: &dyn StorageInterface,
+    state: &SessionState,
     request: &api::PaymentsRetrieveRequest,
     operation: Op,
     storage_scheme: enums::MerchantStorageScheme,
@@ -222,7 +221,7 @@ async fn get_tracker_for_sync<
     let (payment_intent, mut payment_attempt, currency, amount);
 
     (payment_intent, payment_attempt) = get_payment_intent_payment_attempt(
-        db,
+        state,
         payment_id,
         &merchant_account.merchant_id,
         key_store,
@@ -238,7 +237,7 @@ async fn get_tracker_for_sync<
     amount = payment_attempt.get_total_amount().into();
 
     let shipping_address = helpers::get_address_by_id(
-        db,
+        state,
         payment_intent.shipping_address_id.clone(),
         key_store,
         &payment_intent.payment_id.clone(),
@@ -247,7 +246,7 @@ async fn get_tracker_for_sync<
     )
     .await?;
     let billing_address = helpers::get_address_by_id(
-        db,
+        state,
         payment_intent.billing_address_id.clone(),
         key_store,
         &payment_intent.payment_id.clone(),
@@ -257,7 +256,7 @@ async fn get_tracker_for_sync<
     .await?;
 
     let payment_method_billing = helpers::get_address_by_id(
-        db,
+        state,
         payment_attempt.payment_method_billing_address_id.clone(),
         key_store,
         &payment_intent.payment_id.clone(),
@@ -267,7 +266,7 @@ async fn get_tracker_for_sync<
     .await?;
 
     payment_attempt.encoded_data.clone_from(&request.param);
-
+    let db = &*state.store;
     let attempts = match request.expand_attempts {
         Some(true) => {
             Some(db
@@ -510,18 +509,21 @@ impl<F: Send + Clone> ValidateRequest<F, api::PaymentsRetrieveRequest> for Payme
 }
 
 pub async fn get_payment_intent_payment_attempt(
-    db: &dyn StorageInterface,
+    state: &SessionState,
     payment_id: &api::PaymentIdType,
     merchant_id: &str,
     key_store: &domain::MerchantKeyStore,
     storage_scheme: enums::MerchantStorageScheme,
 ) -> RouterResult<(storage::PaymentIntent, storage::PaymentAttempt)> {
+    let key_manager_state: KeyManagerState = state.into();
+    let db = &*state.store;
     let get_pi_pa = || async {
         let (pi, pa);
         match payment_id {
             api_models::payments::PaymentIdType::PaymentIntentId(ref id) => {
                 pi = db
                     .find_payment_intent_by_payment_id_merchant_id(
+                        &key_manager_state,
                         id,
                         merchant_id,
                         key_store,
@@ -547,6 +549,7 @@ pub async fn get_payment_intent_payment_attempt(
                     .await?;
                 pi = db
                     .find_payment_intent_by_payment_id_merchant_id(
+                        &key_manager_state,
                         pa.payment_id.as_str(),
                         merchant_id,
                         key_store,
@@ -560,6 +563,7 @@ pub async fn get_payment_intent_payment_attempt(
                     .await?;
                 pi = db
                     .find_payment_intent_by_payment_id_merchant_id(
+                        &key_manager_state,
                         pa.payment_id.as_str(),
                         merchant_id,
                         key_store,
@@ -578,6 +582,7 @@ pub async fn get_payment_intent_payment_attempt(
 
                 pi = db
                     .find_payment_intent_by_payment_id_merchant_id(
+                        &key_manager_state,
                         pa.payment_id.as_str(),
                         merchant_id,
                         key_store,
diff --git a/crates/router/src/core/payments/operations/payment_update.rs b/crates/router/src/core/payments/operations/payment_update.rs
index 98006e574ca..f95ec0d0143 100644
--- a/crates/router/src/core/payments/operations/payment_update.rs
+++ b/crates/router/src/core/payments/operations/payment_update.rs
@@ -24,7 +24,6 @@ use crate::{
         payments::{self, helpers, operations, CustomerDetails, PaymentAddress, PaymentData},
         utils as core_utils,
     },
-    db::StorageInterface,
     routes::{app::ReqState, SessionState},
     services,
     types::{
@@ -64,6 +63,7 @@ impl<F: Send + Clone> GetTracker<F, PaymentData<F>, api::PaymentsRequest> for Pa
 
         payment_intent = db
             .find_payment_intent_by_payment_id_merchant_id(
+                &state.into(),
                 &payment_id,
                 merchant_id,
                 key_store,
@@ -193,7 +193,7 @@ impl<F: Send + Clone> GetTracker<F, PaymentData<F>, api::PaymentsRequest> for Pa
         }
 
         let shipping_address = helpers::create_or_update_address_for_payment_by_request(
-            db,
+            state,
             request.shipping.as_ref(),
             payment_intent.shipping_address_id.as_deref(),
             merchant_id,
@@ -207,7 +207,7 @@ impl<F: Send + Clone> GetTracker<F, PaymentData<F>, api::PaymentsRequest> for Pa
         )
         .await?;
         let billing_address = helpers::create_or_update_address_for_payment_by_request(
-            db,
+            state,
             request.billing.as_ref(),
             payment_intent.billing_address_id.as_deref(),
             merchant_id,
@@ -222,7 +222,7 @@ impl<F: Send + Clone> GetTracker<F, PaymentData<F>, api::PaymentsRequest> for Pa
         .await?;
 
         let payment_method_billing = helpers::create_or_update_address_for_payment_by_request(
-            db,
+            state,
             request
                 .payment_method_data
                 .as_ref()
@@ -491,7 +491,7 @@ impl<F: Clone + Send> Domain<F, api::PaymentsRequest> for PaymentUpdate {
     #[instrument(skip_all)]
     async fn get_or_create_customer_details<'a>(
         &'a self,
-        db: &dyn StorageInterface,
+        state: &SessionState,
         payment_data: &mut PaymentData<F>,
         request: Option<CustomerDetails>,
         key_store: &domain::MerchantKeyStore,
@@ -504,8 +504,8 @@ impl<F: Clone + Send> Domain<F, api::PaymentsRequest> for PaymentUpdate {
         errors::StorageError,
     > {
         helpers::create_customer_if_not_exist(
+            state,
             Box::new(self),
-            db,
             payment_data,
             request,
             &key_store.merchant_id,
@@ -715,7 +715,7 @@ impl<F: Clone> UpdateTracker<F, PaymentData<F>, api::PaymentsRequest> for Paymen
         let billing_details = payment_data
             .address
             .get_payment_billing()
-            .async_map(|billing_details| create_encrypted_data(key_store, billing_details))
+            .async_map(|billing_details| create_encrypted_data(state, key_store, billing_details))
             .await
             .transpose()
             .change_context(errors::ApiErrorResponse::InternalServerError)
@@ -724,7 +724,7 @@ impl<F: Clone> UpdateTracker<F, PaymentData<F>, api::PaymentsRequest> for Paymen
         let shipping_details = payment_data
             .address
             .get_shipping()
-            .async_map(|shipping_details| create_encrypted_data(key_store, shipping_details))
+            .async_map(|shipping_details| create_encrypted_data(state, key_store, shipping_details))
             .await
             .transpose()
             .change_context(errors::ApiErrorResponse::InternalServerError)
@@ -741,6 +741,7 @@ impl<F: Clone> UpdateTracker<F, PaymentData<F>, api::PaymentsRequest> for Paymen
         payment_data.payment_intent = state
             .store
             .update_payment_intent(
+                &state.into(),
                 payment_data.payment_intent.clone(),
                 storage::PaymentIntentUpdate::Update(Box::new(PaymentIntentUpdateFields {
                     amount: payment_data.amount.into(),
diff --git a/crates/router/src/core/payments/operations/payments_incremental_authorization.rs b/crates/router/src/core/payments/operations/payments_incremental_authorization.rs
index 61a629df622..20c2e051b61 100644
--- a/crates/router/src/core/payments/operations/payments_incremental_authorization.rs
+++ b/crates/router/src/core/payments/operations/payments_incremental_authorization.rs
@@ -16,10 +16,7 @@ use crate::{
             PaymentAddress,
         },
     },
-    routes::{
-        app::{ReqState, StorageInterface},
-        SessionState,
-    },
+    routes::{app::ReqState, SessionState},
     services,
     types::{
         api::{self, PaymentIdTypeExt},
@@ -59,6 +56,7 @@ impl<F: Send + Clone>
 
         let payment_intent = db
             .find_payment_intent_by_payment_id_merchant_id(
+                &state.into(),
                 &payment_id,
                 merchant_id,
                 key_store,
@@ -179,7 +177,7 @@ impl<F: Clone> UpdateTracker<F, payments::PaymentData<F>, PaymentsIncrementalAut
     #[instrument(skip_all)]
     async fn update_trackers<'b>(
         &'b self,
-        db: &'b SessionState,
+        state: &'b SessionState,
         _req_state: ReqState,
         mut payment_data: payments::PaymentData<F>,
         _customer: Option<domain::Customer>,
@@ -224,7 +222,7 @@ impl<F: Clone> UpdateTracker<F, payments::PaymentData<F>, PaymentsIncrementalAut
             connector_authorization_id: None,
             previously_authorized_amount: payment_data.payment_intent.amount,
         };
-        let authorization = db
+        let authorization = state
             .store
             .insert_authorization(authorization_new.clone())
             .await
@@ -236,9 +234,10 @@ impl<F: Clone> UpdateTracker<F, payments::PaymentData<F>, PaymentsIncrementalAut
             })
             .attach_printable("failed while inserting new authorization")?;
         // Update authorization_count in payment_intent
-        payment_data.payment_intent = db
+        payment_data.payment_intent = state
             .store
             .update_payment_intent(
+                &state.into(),
                 payment_data.payment_intent.clone(),
                 storage::PaymentIntentUpdate::AuthorizationCountUpdate {
                     authorization_count: new_authorization_count,
@@ -295,7 +294,7 @@ impl<F: Clone + Send> Domain<F, PaymentsIncrementalAuthorizationRequest>
     #[instrument(skip_all)]
     async fn get_or_create_customer_details<'a>(
         &'a self,
-        _db: &dyn StorageInterface,
+        _state: &SessionState,
         _payment_data: &mut payments::PaymentData<F>,
         _request: Option<CustomerDetails>,
         _merchant_key_store: &domain::MerchantKeyStore,
diff --git a/crates/router/src/core/payments/retry.rs b/crates/router/src/core/payments/retry.rs
index bf5ae5aa635..99cb6aaec68 100644
--- a/crates/router/src/core/payments/retry.rs
+++ b/crates/router/src/core/payments/retry.rs
@@ -469,6 +469,7 @@ where
 
     payment_data.payment_intent = db
         .update_payment_intent(
+            &state.into(),
             payment_data.payment_intent.clone(),
             storage::PaymentIntentUpdate::PaymentAttemptAndAttemptCountUpdate {
                 active_attempt_id: payment_data.payment_attempt.attempt_id.clone(),
diff --git a/crates/router/src/core/payments/routing.rs b/crates/router/src/core/payments/routing.rs
index 0ff53c63b48..ff9f6ddbf3a 100644
--- a/crates/router/src/core/payments/routing.rs
+++ b/crates/router/src/core/payments/routing.rs
@@ -528,6 +528,7 @@ pub async fn refresh_cgraph_cache<'a>(
     let mut merchant_connector_accounts = state
         .store
         .find_merchant_connector_account_by_merchant_id_and_disabled_list(
+            &state.into(),
             &key_store.merchant_id,
             false,
             key_store,
diff --git a/crates/router/src/core/payments/tokenization.rs b/crates/router/src/core/payments/tokenization.rs
index b77bdb7515e..40163367139 100644
--- a/crates/router/src/core/payments/tokenization.rs
+++ b/crates/router/src/core/payments/tokenization.rs
@@ -8,7 +8,7 @@ use common_utils::{
     id_type, pii,
 };
 use error_stack::{report, ResultExt};
-use masking::{ExposeInterface, PeekInterface, Secret};
+use masking::{ExposeInterface, Secret};
 use router_env::{instrument, metrics::add_attributes, tracing};
 
 use super::helpers;
@@ -214,7 +214,7 @@ where
 
                 let pm_data_encrypted: Option<Encryptable<Secret<serde_json::Value>>> =
                     pm_card_details
-                        .async_map(|pm_card| create_encrypted_data(key_store, pm_card))
+                        .async_map(|pm_card| create_encrypted_data(state, key_store, pm_card))
                         .await
                         .transpose()
                         .change_context(errors::ApiErrorResponse::InternalServerError)
@@ -223,7 +223,7 @@ where
                 let encrypted_payment_method_billing_address: Option<
                     Encryptable<Secret<serde_json::Value>>,
                 > = payment_method_billing_address
-                    .async_map(|address| create_encrypted_data(key_store, address.clone()))
+                    .async_map(|address| create_encrypted_data(state, key_store, address.clone()))
                     .await
                     .transpose()
                     .change_context(errors::ApiErrorResponse::InternalServerError)
@@ -310,7 +310,7 @@ where
                                         let pm_metadata =
                                             create_payment_method_metadata(None, connector_token)?;
                                         payment_methods::cards::create_payment_method(
-                                            db,
+                                            state,
                                             &payment_method_create_request,
                                             &customer_id,
                                             &resp.payment_method_id,
@@ -407,7 +407,7 @@ where
                                     Err(err) => {
                                         if err.current_context().is_db_not_found() {
                                             payment_methods::cards::insert_payment_method(
-                                                db,
+                                                state,
                                                 &resp,
                                                 &payment_method_create_request.clone(),
                                                 key_store,
@@ -479,10 +479,8 @@ where
                                         ))?
                                 };
 
-                                let existing_pm_data = payment_methods::cards::get_card_details_without_locker_fallback(
-                                    &existing_pm,
-                                    key_store.key.peek(),
-                                    state,
+                                let existing_pm_data = payment_methods::cards::get_card_details_without_locker_fallback(&existing_pm,state,
+                                    key_store,
                                 )
                                 .await?;
 
@@ -518,7 +516,7 @@ where
                                 let pm_data_encrypted: Option<
                                     Encryptable<Secret<serde_json::Value>>,
                                 > = updated_pmd
-                                    .async_map(|pmd| create_encrypted_data(key_store, pmd))
+                                    .async_map(|pmd| create_encrypted_data(state, key_store, pmd))
                                     .await
                                     .transpose()
                                     .change_context(errors::ApiErrorResponse::InternalServerError)
@@ -601,7 +599,7 @@ where
 
                             resp.payment_method_id = generate_id(consts::ID_LENGTH, "pm");
                             payment_methods::cards::create_payment_method(
-                                db,
+                                state,
                                 &payment_method_create_request,
                                 &customer_id,
                                 &resp.payment_method_id,
diff --git a/crates/router/src/core/payout_link.rs b/crates/router/src/core/payout_link.rs
index 3de8e505499..78ff9900f66 100644
--- a/crates/router/src/core/payout_link.rs
+++ b/crates/router/src/core/payout_link.rs
@@ -122,6 +122,7 @@ pub async fn initiate_payout_link(
             // Fetch customer
             let customer = db
                 .find_customer_by_customer_id_merchant_id(
+                    &(&state).into(),
                     &customer_id,
                     &req.merchant_id,
                     &key_store,
@@ -263,10 +264,12 @@ pub async fn filter_payout_methods(
     key_store: &domain::MerchantKeyStore,
     payout: &hyperswitch_domain_models::payouts::payouts::Payouts,
 ) -> errors::RouterResult<Vec<link_utils::EnabledPaymentMethod>> {
-    let db: &dyn StorageInterface = &*state.store;
+    let db = &*state.store;
+    let key_manager_state = &state.into();
     //Fetch all merchant connector accounts
     let all_mcas = db
         .find_merchant_connector_account_by_merchant_id_and_disabled_list(
+            key_manager_state,
             &merchant_account.merchant_id,
             false,
             key_store,
@@ -282,7 +285,7 @@ pub async fn filter_payout_methods(
         common_enums::ConnectorType::PayoutProcessor,
     );
     let address = db
-        .find_address_by_address_id(&payout.address_id.clone(), key_store)
+        .find_address_by_address_id(key_manager_state, &payout.address_id.clone(), key_store)
         .await
         .change_context(errors::ApiErrorResponse::InternalServerError)
         .attach_printable_lazy(|| {
diff --git a/crates/router/src/core/payouts.rs b/crates/router/src/core/payouts.rs
index 4365519aecc..0ec3960b07d 100644
--- a/crates/router/src/core/payouts.rs
+++ b/crates/router/src/core/payouts.rs
@@ -732,6 +732,7 @@ pub async fn payouts_list_core(
             Ok(payout_attempt) => {
                 match db
                     .find_customer_by_customer_id_merchant_id(
+                        &(&state).into(),
                         &payouts.customer_id,
                         merchant_id,
                         &key_store,
@@ -822,7 +823,14 @@ pub async fn payouts_filtered_list_core(
         .to_not_found_response(errors::ApiErrorResponse::PayoutNotFound)?;
 
     let data: Vec<api::PayoutCreateResponse> = join_all(list.into_iter().map(|(p, pa, c)| async {
-        match domain::Customer::convert_back(c, &key_store.key).await {
+        match domain::Customer::convert_back(
+            &(&state).into(),
+            c,
+            &key_store.key,
+            key_store.merchant_id.clone(),
+        )
+        .await
+        {
             Ok(domain_cust) => Some((p, pa, domain_cust)),
             Err(err) => {
                 logger::warn!(
@@ -1084,6 +1092,7 @@ pub async fn create_recipient(
                     {
                         payout_data.customer_details = Some(
                             db.update_customer_by_customer_id_merchant_id(
+                                &state.into(),
                                 customer_id,
                                 merchant_id,
                                 customer,
@@ -2184,7 +2193,7 @@ pub async fn payout_create_db_entries(
 
     // Get or create address
     let billing_address = payment_helpers::create_or_find_address_for_payment_by_request(
-        db,
+        state,
         req.billing.as_ref(),
         None,
         merchant_id,
@@ -2345,7 +2354,7 @@ pub async fn make_payout_data(
         .to_not_found_response(errors::ApiErrorResponse::PayoutNotFound)?;
 
     let billing_address = payment_helpers::create_or_find_address_for_payment_by_request(
-        db,
+        state,
         None,
         Some(&payouts.address_id.to_owned()),
         merchant_id,
@@ -2358,6 +2367,7 @@ pub async fn make_payout_data(
 
     let customer_details = db
         .find_customer_optional_by_customer_id_merchant_id(
+            &state.into(),
             &payouts.customer_id.to_owned(),
             merchant_id,
             key_store,
diff --git a/crates/router/src/core/payouts/helpers.rs b/crates/router/src/core/payouts/helpers.rs
index 3ab17143202..6cda7b28433 100644
--- a/crates/router/src/core/payouts/helpers.rs
+++ b/crates/router/src/core/payouts/helpers.rs
@@ -1,13 +1,17 @@
-use api_models::{enums, payment_methods::Card, payouts};
+use api_models::{customers::CustomerRequestWithEmail, enums, payment_methods::Card, payouts};
 use common_utils::{
+    encryption::Encryption,
     errors::CustomResult,
     ext_traits::{AsyncExt, StringExt},
     fp_utils, generate_customer_id_of_default_length, id_type,
-    types::MinorUnit,
+    types::{
+        keymanager::{Identifier, KeyManagerState, ToEncryptable},
+        MinorUnit,
+    },
 };
-use diesel_models::encryption::Encryption;
 use error_stack::{report, ResultExt};
-use masking::{ExposeInterface, PeekInterface, Secret};
+use hyperswitch_domain_models::type_encryption::batch_encrypt;
+use masking::{PeekInterface, Secret};
 use router_env::logger;
 
 use super::PayoutData;
@@ -233,6 +237,7 @@ pub async fn save_payout_data_to_locker(
             }
             _ => {
                 let key = key_store.key.get_inner().peek();
+                let key_manager_state: KeyManagerState = state.into();
                 let enc_data = async {
                     serde_json::to_value(payout_method_data.to_owned())
                         .change_context(errors::ApiErrorResponse::InternalServerError)
@@ -242,7 +247,14 @@ pub async fn save_payout_data_to_locker(
                             let secret: Secret<String> = Secret::new(v.to_string());
                             secret
                         })
-                        .async_lift(|inner| domain_types::encrypt_optional(inner, key))
+                        .async_lift(|inner| {
+                            domain_types::encrypt_optional(
+                                &key_manager_state,
+                                inner,
+                                Identifier::Merchant(key_store.merchant_id.clone()),
+                                key,
+                            )
+                        })
                         .await
                 }
                 .await
@@ -453,7 +465,7 @@ pub async fn save_payout_data_to_locker(
                 });
             (
                 Some(
-                    cards::create_encrypted_data(key_store, pm_data)
+                    cards::create_encrypted_data(state, key_store, pm_data)
                         .await
                         .change_context(errors::ApiErrorResponse::InternalServerError)
                         .attach_printable("Unable to encrypt customer details")?,
@@ -489,7 +501,7 @@ pub async fn save_payout_data_to_locker(
     if should_insert_in_pm_table {
         let payment_method_id = common_utils::generate_id(crate::consts::ID_LENGTH, "pm");
         cards::create_payment_method(
-            db,
+            state,
             &new_payment_method,
             &payout_attempt.customer_id,
             &payment_method_id,
@@ -601,9 +613,11 @@ pub async fn get_or_create_customer_details(
 
     let merchant_id = &merchant_account.merchant_id;
     let key = key_store.key.get_inner().peek();
+    let key_manager_state = &state.into();
 
     match db
         .find_customer_optional_by_customer_id_merchant_id(
+            key_manager_state,
             &customer_id,
             merchant_id,
             key_store,
@@ -614,21 +628,28 @@ pub async fn get_or_create_customer_details(
     {
         Some(customer) => Ok(Some(customer)),
         None => {
+            let encrypted_data = batch_encrypt(
+                &state.into(),
+                CustomerRequestWithEmail::to_encryptable(CustomerRequestWithEmail {
+                    name: customer_details.name.clone(),
+                    email: customer_details.email.clone(),
+                    phone: customer_details.phone.clone(),
+                }),
+                Identifier::Merchant(key_store.merchant_id.clone()),
+                key,
+            )
+            .await
+            .change_context(errors::ApiErrorResponse::InternalServerError)?;
+            let encryptable_customer =
+                CustomerRequestWithEmail::from_encryptable(encrypted_data)
+                    .change_context(errors::ApiErrorResponse::InternalServerError)?;
+
             let customer = domain::Customer {
                 customer_id,
                 merchant_id: merchant_id.to_string(),
-                name: domain_types::encrypt_optional(customer_details.name.to_owned(), key)
-                    .await
-                    .change_context(errors::ApiErrorResponse::InternalServerError)?,
-                email: domain_types::encrypt_optional(
-                    customer_details.email.to_owned().map(|e| e.expose()),
-                    key,
-                )
-                .await
-                .change_context(errors::ApiErrorResponse::InternalServerError)?,
-                phone: domain_types::encrypt_optional(customer_details.phone.to_owned(), key)
-                    .await
-                    .change_context(errors::ApiErrorResponse::InternalServerError)?,
+                name: encryptable_customer.name,
+                email: encryptable_customer.email,
+                phone: encryptable_customer.phone,
                 description: None,
                 phone_country_code: customer_details.phone_country_code.to_owned(),
                 metadata: None,
@@ -642,9 +663,14 @@ pub async fn get_or_create_customer_details(
             };
 
             Ok(Some(
-                db.insert_customer(customer, key_store, merchant_account.storage_scheme)
-                    .await
-                    .change_context(errors::ApiErrorResponse::InternalServerError)?,
+                db.insert_customer(
+                    key_manager_state,
+                    customer,
+                    key_store,
+                    merchant_account.storage_scheme,
+                )
+                .await
+                .change_context(errors::ApiErrorResponse::InternalServerError)?,
             ))
         }
     }
diff --git a/crates/router/src/core/pm_auth.rs b/crates/router/src/core/pm_auth.rs
index 3434ac3e9c7..32e5ef308cf 100644
--- a/crates/router/src/core/pm_auth.rs
+++ b/crates/router/src/core/pm_auth.rs
@@ -15,7 +15,7 @@ use common_utils::{
     crypto::{HmacSha256, SignMessage},
     ext_traits::AsyncExt,
     generate_id,
-    types::{self as util_types, AmountConvertor},
+    types::{self as util_types, keymanager::Identifier, AmountConvertor},
 };
 use error_stack::ResultExt;
 use helpers::PaymentAuthConnectorDataExt;
@@ -110,7 +110,7 @@ pub async fn create_link_token(
     > = connector.connector.get_connector_integration();
 
     let payment_intent = oss_helpers::verify_payment_intent_time_and_client_secret(
-        &*state.store,
+        &state,
         &merchant_account,
         &key_store,
         payload.client_secret,
@@ -121,7 +121,7 @@ pub async fn create_link_token(
         .as_ref()
         .async_map(|pi| async {
             oss_helpers::get_address_by_id(
-                &*state.store,
+                &state,
                 pi.billing_address_id.clone(),
                 &key_store,
                 &pi.payment_id,
@@ -139,6 +139,7 @@ pub async fn create_link_token(
     let merchant_connector_account = state
         .store
         .find_by_merchant_connector_account_merchant_id_merchant_connector_id(
+            &(&state).into(),
             merchant_account.merchant_id.as_str(),
             &selected_config.mca_id,
             &key_store,
@@ -234,6 +235,7 @@ pub async fn exchange_token_core(
     let merchant_connector_account = state
         .store
         .find_by_merchant_connector_account_merchant_id_merchant_connector_id(
+            &(&state).into(),
             merchant_account.merchant_id.as_str(),
             &config.mca_id,
             &key_store,
@@ -294,6 +296,7 @@ async fn store_bank_details_in_payment_methods(
 
     let payment_intent = db
         .find_payment_intent_by_payment_id_merchant_id(
+            &(&state).into(),
             &payload.payment_id,
             &merchant_account.merchant_id,
             &key_store,
@@ -326,7 +329,9 @@ async fn store_bank_details_in_payment_methods(
     for pm in payment_methods {
         if pm.payment_method == Some(enums::PaymentMethod::BankDebit) {
             let bank_details_pm_data = decrypt::<serde_json::Value, masking::WithType>(
+                &(&state).into(),
                 pm.payment_method_data.clone(),
+                Identifier::Merchant(key_store.merchant_id.clone()),
                 key,
             )
             .await
@@ -433,10 +438,11 @@ async fn store_bank_details_in_payment_methods(
             );
 
             let payment_method_data = payment_methods::PaymentMethodsData::BankDetails(pmd);
-            let encrypted_data = cards::create_encrypted_data(&key_store, payment_method_data)
-                .await
-                .change_context(ApiErrorResponse::InternalServerError)
-                .attach_printable("Unable to encrypt customer details")?;
+            let encrypted_data =
+                cards::create_encrypted_data(&state, &key_store, payment_method_data)
+                    .await
+                    .change_context(ApiErrorResponse::InternalServerError)
+                    .attach_printable("Unable to encrypt customer details")?;
 
             let pm_update = storage::PaymentMethodUpdate::PaymentMethodDataUpdate {
                 payment_method_data: Some(encrypted_data.into()),
@@ -446,7 +452,7 @@ async fn store_bank_details_in_payment_methods(
         } else {
             let payment_method_data = payment_methods::PaymentMethodsData::BankDetails(pmd);
             let encrypted_data =
-                cards::create_encrypted_data(&key_store, Some(payment_method_data))
+                cards::create_encrypted_data(&state, &key_store, Some(payment_method_data))
                     .await
                     .change_context(ApiErrorResponse::InternalServerError)
                     .attach_printable("Unable to encrypt customer details")?;
@@ -701,14 +707,19 @@ pub async fn retrieve_payment_method_from_auth_service(
     let connector = PaymentAuthConnectorData::get_connector_by_name(
         auth_token.connector_details.connector.as_str(),
     )?;
-
+    let key_manager_state = &state.into();
     let merchant_account = db
-        .find_merchant_account_by_merchant_id(&payment_intent.merchant_id, key_store)
+        .find_merchant_account_by_merchant_id(
+            key_manager_state,
+            &payment_intent.merchant_id,
+            key_store,
+        )
         .await
         .to_not_found_response(ApiErrorResponse::MerchantAccountNotFound)?;
 
     let mca = db
         .find_by_merchant_connector_account_merchant_id_merchant_connector_id(
+            key_manager_state,
             &payment_intent.merchant_id,
             &auth_token.connector_details.mca_id,
             key_store,
@@ -770,7 +781,7 @@ pub async fn retrieve_payment_method_from_auth_service(
     }
 
     let address = oss_helpers::get_address_by_id(
-        &*state.store,
+        state,
         payment_intent.billing_address_id.clone(),
         key_store,
         &payment_intent.payment_id,
diff --git a/crates/router/src/core/refunds.rs b/crates/router/src/core/refunds.rs
index 5b74eefb9a4..374c37dc217 100644
--- a/crates/router/src/core/refunds.rs
+++ b/crates/router/src/core/refunds.rs
@@ -57,6 +57,7 @@ pub async fn refund_create_core(
 
     payment_intent = db
         .find_payment_intent_by_payment_id_merchant_id(
+            &(&state).into(),
             &req.payment_id,
             merchant_id,
             &key_store,
@@ -415,6 +416,7 @@ pub async fn refund_retrieve_core(
     let payment_id = refund.payment_id.as_str();
     payment_intent = db
         .find_payment_intent_by_payment_id_merchant_id(
+            &(&state).into(),
             payment_id,
             merchant_id,
             &key_store,
@@ -924,9 +926,11 @@ pub async fn refund_manual_update(
     state: SessionState,
     req: api_models::refunds::RefundManualUpdateRequest,
 ) -> RouterResponse<serde_json::Value> {
+    let key_manager_state = &(&state).into();
     let key_store = state
         .store
         .get_merchant_key_store_by_merchant_id(
+            key_manager_state,
             &req.merchant_id,
             &state.store.get_master_key().to_vec().into(),
         )
@@ -935,7 +939,7 @@ pub async fn refund_manual_update(
         .attach_printable("Error while fetching the key store by merchant_id")?;
     let merchant_account = state
         .store
-        .find_merchant_account_by_merchant_id(&req.merchant_id, &key_store)
+        .find_merchant_account_by_merchant_id(key_manager_state, &req.merchant_id, &key_store)
         .await
         .to_not_found_response(errors::ApiErrorResponse::MerchantAccountNotFound)
         .attach_printable("Error while fetching the merchant_account by merchant_id")?;
@@ -1125,6 +1129,7 @@ pub async fn sync_refund_with_gateway_workflow(
     state: &SessionState,
     refund_tracker: &storage::ProcessTracker,
 ) -> Result<(), errors::ProcessTrackerError> {
+    let key_manager_state = &state.into();
     let refund_core =
         serde_json::from_value::<storage::RefundCoreWorkflow>(refund_tracker.tracking_data.clone())
             .change_context(errors::ApiErrorResponse::InternalServerError)
@@ -1138,6 +1143,7 @@ pub async fn sync_refund_with_gateway_workflow(
     let key_store = state
         .store
         .get_merchant_key_store_by_merchant_id(
+            key_manager_state,
             &refund_core.merchant_id,
             &state.store.get_master_key().to_vec().into(),
         )
@@ -1145,7 +1151,11 @@ pub async fn sync_refund_with_gateway_workflow(
 
     let merchant_account = state
         .store
-        .find_merchant_account_by_merchant_id(&refund_core.merchant_id, &key_store)
+        .find_merchant_account_by_merchant_id(
+            key_manager_state,
+            &refund_core.merchant_id,
+            &key_store,
+        )
         .await?;
 
     let response = Box::pin(refund_retrieve_core(
@@ -1220,17 +1230,22 @@ pub async fn trigger_refund_execute_workflow(
                     refund_tracker.tracking_data
                 )
             })?;
-
+    let key_manager_state = &state.into();
     let key_store = state
         .store
         .get_merchant_key_store_by_merchant_id(
+            key_manager_state,
             &refund_core.merchant_id,
             &state.store.get_master_key().to_vec().into(),
         )
         .await?;
 
     let merchant_account = db
-        .find_merchant_account_by_merchant_id(&refund_core.merchant_id, &key_store)
+        .find_merchant_account_by_merchant_id(
+            key_manager_state,
+            &refund_core.merchant_id,
+            &key_store,
+        )
         .await
         .to_not_found_response(errors::ApiErrorResponse::MerchantAccountNotFound)?;
 
@@ -1245,7 +1260,11 @@ pub async fn trigger_refund_execute_workflow(
     match (&refund.sent_to_gateway, &refund.refund_status) {
         (false, enums::RefundStatus::Pending) => {
             let merchant_account = db
-                .find_merchant_account_by_merchant_id(&refund.merchant_id, &key_store)
+                .find_merchant_account_by_merchant_id(
+                    key_manager_state,
+                    &refund.merchant_id,
+                    &key_store,
+                )
                 .await
                 .to_not_found_response(errors::ApiErrorResponse::MerchantAccountNotFound)?;
 
@@ -1261,6 +1280,7 @@ pub async fn trigger_refund_execute_workflow(
 
             let payment_intent = db
                 .find_payment_intent_by_payment_id_merchant_id(
+                    &(state.into()),
                     &payment_attempt.payment_id,
                     &refund.merchant_id,
                     &key_store,
diff --git a/crates/router/src/core/routing.rs b/crates/router/src/core/routing.rs
index 5f10de56e47..b17217737be 100644
--- a/crates/router/src/core/routing.rs
+++ b/crates/router/src/core/routing.rs
@@ -120,7 +120,7 @@ pub async fn create_routing_config(
     .await?;
 
     helpers::validate_connectors_in_routing_config(
-        db,
+        &state,
         &key_store,
         &merchant_account.merchant_id,
         &profile_id,
diff --git a/crates/router/src/core/routing/helpers.rs b/crates/router/src/core/routing/helpers.rs
index d99177aa555..707ed41d95a 100644
--- a/crates/router/src/core/routing/helpers.rs
+++ b/crates/router/src/core/routing/helpers.rs
@@ -15,6 +15,7 @@ use storage_impl::redis::cache;
 use crate::{
     core::errors::{self, RouterResult},
     db::StorageInterface,
+    routes::SessionState,
     types::{domain, storage},
     utils::StringExt,
 };
@@ -186,7 +187,7 @@ pub async fn update_routing_algorithm(
 /// This will help make one of all configured algorithms to be in active state for a particular
 /// merchant
 pub async fn update_merchant_active_algorithm_ref(
-    db: &dyn StorageInterface,
+    state: &SessionState,
     key_store: &domain::MerchantKeyStore,
     config_key: cache::CacheKind<'_>,
     algorithm_id: routing_types::RoutingAlgorithmRef,
@@ -218,8 +219,9 @@ pub async fn update_merchant_active_algorithm_ref(
         payment_link_config: None,
         pm_collect_link_config: None,
     };
-
+    let db = &*state.store;
     db.update_specific_fields_in_merchant(
+        &state.into(),
         &key_store.merchant_id,
         merchant_account_update,
         key_store,
@@ -300,14 +302,16 @@ pub async fn update_business_profile_active_algorithm_ref(
 }
 
 pub async fn validate_connectors_in_routing_config(
-    db: &dyn StorageInterface,
+    state: &SessionState,
     key_store: &domain::MerchantKeyStore,
     merchant_id: &str,
     profile_id: &str,
     routing_algorithm: &routing_types::RoutingAlgorithm,
 ) -> RouterResult<()> {
-    let all_mcas = db
+    let all_mcas = &*state
+        .store
         .find_merchant_connector_account_by_merchant_id_and_disabled_list(
+            &state.into(),
             merchant_id,
             true,
             key_store,
diff --git a/crates/router/src/core/surcharge_decision_config.rs b/crates/router/src/core/surcharge_decision_config.rs
index b35d7c5ad28..55ea4ba16f8 100644
--- a/crates/router/src/core/surcharge_decision_config.rs
+++ b/crates/router/src/core/surcharge_decision_config.rs
@@ -91,7 +91,7 @@ pub async fn upsert_surcharge_decision_config(
 
             algo_id.update_surcharge_config_id(key.clone());
             let config_key = cache::CacheKind::Surcharge(key.into());
-            update_merchant_active_algorithm_ref(db, &key_store, config_key, algo_id)
+            update_merchant_active_algorithm_ref(&state, &key_store, config_key, algo_id)
                 .await
                 .change_context(errors::ApiErrorResponse::InternalServerError)
                 .attach_printable("Failed to update routing algorithm ref")?;
@@ -128,7 +128,7 @@ pub async fn upsert_surcharge_decision_config(
 
             algo_id.update_surcharge_config_id(key.clone());
             let config_key = cache::CacheKind::Surcharge(key.clone().into());
-            update_merchant_active_algorithm_ref(db, &key_store, config_key, algo_id)
+            update_merchant_active_algorithm_ref(&state, &key_store, config_key, algo_id)
                 .await
                 .change_context(errors::ApiErrorResponse::InternalServerError)
                 .attach_printable("Failed to update routing algorithm ref")?;
@@ -158,7 +158,7 @@ pub async fn delete_surcharge_decision_config(
         .unwrap_or_default();
     algo_id.surcharge_config_algo_id = None;
     let config_key = cache::CacheKind::Surcharge(key.clone().into());
-    update_merchant_active_algorithm_ref(db, &key_store, config_key, algo_id)
+    update_merchant_active_algorithm_ref(&state, &key_store, config_key, algo_id)
         .await
         .change_context(errors::ApiErrorResponse::InternalServerError)
         .attach_printable("Failed to update deleted algorithm ref")?;
diff --git a/crates/router/src/core/user.rs b/crates/router/src/core/user.rs
index 461ac855364..be33ccc69e1 100644
--- a/crates/router/src/core/user.rs
+++ b/crates/router/src/core/user.rs
@@ -4,6 +4,7 @@ use api_models::{
     payments::RedirectionResponse,
     user::{self as user_api, InviteMultipleUserResponse},
 };
+use common_utils::types::keymanager::Identifier;
 #[cfg(feature = "email")]
 use diesel_models::user_role::UserRoleUpdate;
 use diesel_models::{
@@ -1104,9 +1105,11 @@ pub async fn create_internal_user(
     state: SessionState,
     request: user_api::CreateInternalUserRequest,
 ) -> UserResponse<()> {
+    let key_manager_state = &(&state).into();
     let key_store = state
         .store
         .get_merchant_key_store_by_merchant_id(
+            key_manager_state,
             consts::user_role::INTERNAL_USER_MERCHANT_ID,
             &state.store.get_master_key().to_vec().into(),
         )
@@ -1122,6 +1125,7 @@ pub async fn create_internal_user(
     let internal_merchant = state
         .store
         .find_merchant_account_by_merchant_id(
+            key_manager_state,
             consts::user_role::INTERNAL_USER_MERCHANT_ID,
             &key_store,
         )
@@ -1176,7 +1180,7 @@ pub async fn switch_merchant_id(
     }
 
     let user = user_from_token.get_user_from_db(&state).await?;
-
+    let key_manager_state = &(&state).into();
     let role_info = roles::RoleInfo::from_role_id(
         &state,
         &user_from_token.role_id,
@@ -1190,6 +1194,7 @@ pub async fn switch_merchant_id(
         let key_store = state
             .store
             .get_merchant_key_store_by_merchant_id(
+                key_manager_state,
                 request.merchant_id.as_str(),
                 &state.store.get_master_key().to_vec().into(),
             )
@@ -1204,7 +1209,11 @@ pub async fn switch_merchant_id(
 
         let org_id = state
             .store
-            .find_merchant_account_by_merchant_id(request.merchant_id.as_str(), &key_store)
+            .find_merchant_account_by_merchant_id(
+                key_manager_state,
+                request.merchant_id.as_str(),
+                &key_store,
+            )
             .await
             .map_err(|e| {
                 if e.current_context().is_db_not_found() {
@@ -1306,6 +1315,7 @@ pub async fn list_merchants_for_user(
     let merchant_accounts = state
         .store
         .list_multiple_merchant_accounts(
+            &(&state).into(),
             user_roles
                 .iter()
                 .map(|role| role.merchant_id.clone())
@@ -1852,7 +1862,9 @@ pub async fn update_totp(
                 totp_secret: Some(
                     // TODO: Impl conversion trait for User and move this there
                     domain::types::encrypt::<String, masking::WithType>(
+                        &(&state).into(),
                         totp.get_secret_base32().into(),
+                        Identifier::User(key_store.user_id.clone()),
                         key_store.key.peek(),
                     )
                     .await
@@ -1918,7 +1930,10 @@ pub async fn transfer_user_key_store_keymanager(
     let db = &state.global_store;
 
     let key_stores = db
-        .get_all_user_key_store(&state.store.get_master_key().to_vec().into())
+        .get_all_user_key_store(
+            &(&state).into(),
+            &state.store.get_master_key().to_vec().into(),
+        )
         .await
         .change_context(UserErrors::InternalServerError)?;
 
@@ -2056,10 +2071,12 @@ pub async fn create_user_authentication_method(
     )
     .change_context(UserErrors::InternalServerError)
     .attach_printable("Failed to decode DEK")?;
-
+    let id = uuid::Uuid::new_v4().to_string();
     let (private_config, public_config) = utils::user::construct_public_and_private_db_configs(
+        &state,
         &req.auth_method,
         &user_auth_encryption_key,
+        id.clone(),
     )
     .await?;
 
@@ -2103,7 +2120,7 @@ pub async fn create_user_authentication_method(
     state
         .store
         .insert_user_authentication_method(UserAuthenticationMethodNew {
-            id: uuid::Uuid::new_v4().to_string(),
+            id,
             auth_id,
             owner_id: req.owner_id,
             owner_type: req.owner_type,
@@ -2137,8 +2154,10 @@ pub async fn update_user_authentication_method(
     .attach_printable("Failed to decode DEK")?;
 
     let (private_config, public_config) = utils::user::construct_public_and_private_db_configs(
+        &state,
         &req.auth_method,
         &user_auth_encryption_key,
+        req.id.clone(),
     )
     .await?;
 
@@ -2212,9 +2231,12 @@ pub async fn get_sso_auth_url(
         .await
         .to_not_found_response(UserErrors::InvalidUserAuthMethodOperation)?;
 
-    let open_id_private_config =
-        utils::user::decrypt_oidc_private_config(&state, user_authentication_method.private_config)
-            .await?;
+    let open_id_private_config = utils::user::decrypt_oidc_private_config(
+        &state,
+        user_authentication_method.private_config,
+        request.id.clone(),
+    )
+    .await?;
 
     let open_id_public_config = serde_json::from_value::<user_api::OpenIdConnectPublicConfig>(
         user_authentication_method
@@ -2264,9 +2286,12 @@ pub async fn sso_sign(
         .await
         .change_context(UserErrors::InternalServerError)?;
 
-    let open_id_private_config =
-        utils::user::decrypt_oidc_private_config(&state, user_authentication_method.private_config)
-            .await?;
+    let open_id_private_config = utils::user::decrypt_oidc_private_config(
+        &state,
+        user_authentication_method.private_config,
+        authentication_method_id,
+    )
+    .await?;
 
     let open_id_public_config = serde_json::from_value::<user_api::OpenIdConnectPublicConfig>(
         user_authentication_method
diff --git a/crates/router/src/core/user/dashboard_metadata.rs b/crates/router/src/core/user/dashboard_metadata.rs
index 36489846294..b279d852d40 100644
--- a/crates/router/src/core/user/dashboard_metadata.rs
+++ b/crates/router/src/core/user/dashboard_metadata.rs
@@ -613,6 +613,7 @@ pub async fn backfill_metadata(
     let key_store = state
         .store
         .get_merchant_key_store_by_merchant_id(
+            &state.into(),
             &user.merchant_id,
             &state.store.get_master_key().to_vec().into(),
         )
@@ -713,6 +714,7 @@ pub async fn get_merchant_connector_account_by_name(
     state
         .store
         .find_merchant_connector_account_by_merchant_id_connector_name(
+            &state.into(),
             merchant_id,
             connector_name,
             key_store,
diff --git a/crates/router/src/core/user/sample_data.rs b/crates/router/src/core/user/sample_data.rs
index e1ccb3b0335..b679753b56c 100644
--- a/crates/router/src/core/user/sample_data.rs
+++ b/crates/router/src/core/user/sample_data.rs
@@ -25,6 +25,7 @@ pub async fn generate_sample_data_for_user(
     let key_store = state
         .store
         .get_merchant_key_store_by_merchant_id(
+            &(&state).into(),
             &user_from_token.merchant_id,
             &state.store.get_master_key().to_vec().into(),
         )
@@ -50,7 +51,7 @@ pub async fn generate_sample_data_for_user(
 
     state
         .store
-        .insert_payment_intents_batch_for_sample_data(payment_intents, &key_store)
+        .insert_payment_intents_batch_for_sample_data(&(&state).into(), payment_intents, &key_store)
         .await
         .switch()?;
     state
@@ -74,10 +75,11 @@ pub async fn delete_sample_data_for_user(
     _req_state: ReqState,
 ) -> SampleDataApiResponse<()> {
     let merchant_id_del = user_from_token.merchant_id.as_str();
-
+    let key_manager_state = &(&state).into();
     let key_store = state
         .store
         .get_merchant_key_store_by_merchant_id(
+            key_manager_state,
             &user_from_token.merchant_id,
             &state.store.get_master_key().to_vec().into(),
         )
@@ -87,7 +89,7 @@ pub async fn delete_sample_data_for_user(
 
     state
         .store
-        .delete_payment_intents_for_sample_data(merchant_id_del, &key_store)
+        .delete_payment_intents_for_sample_data(key_manager_state, merchant_id_del, &key_store)
         .await
         .switch()?;
     state
diff --git a/crates/router/src/core/verification.rs b/crates/router/src/core/verification.rs
index b6e71b2828f..65ac5688325 100644
--- a/crates/router/src/core/verification.rs
+++ b/crates/router/src/core/verification.rs
@@ -91,13 +91,19 @@ pub async fn get_verified_apple_domains_with_mid_mca_id(
     errors::ApiErrorResponse,
 > {
     let db = state.store.as_ref();
+    let key_manager_state = &(&state).into();
     let key_store = db
-        .get_merchant_key_store_by_merchant_id(&merchant_id, &db.get_master_key().to_vec().into())
+        .get_merchant_key_store_by_merchant_id(
+            key_manager_state,
+            &merchant_id,
+            &db.get_master_key().to_vec().into(),
+        )
         .await
         .change_context(errors::ApiErrorResponse::MerchantAccountNotFound)?;
 
     let verified_domains = db
         .find_by_merchant_connector_account_merchant_id_merchant_connector_id(
+            key_manager_state,
             merchant_id.as_str(),
             merchant_connector_id.as_str(),
             &key_store,
diff --git a/crates/router/src/core/verification/utils.rs b/crates/router/src/core/verification/utils.rs
index bfbc1cb8b44..a59789b2802 100644
--- a/crates/router/src/core/verification/utils.rs
+++ b/crates/router/src/core/verification/utils.rs
@@ -15,9 +15,11 @@ pub async fn check_existence_and_add_domain_to_db(
     merchant_connector_id: String,
     domain_from_req: Vec<String>,
 ) -> CustomResult<Vec<String>, errors::ApiErrorResponse> {
+    let key_manager_state = &state.into();
     let key_store = state
         .store
         .get_merchant_key_store_by_merchant_id(
+            key_manager_state,
             &merchant_id,
             &state.store.get_master_key().to_vec().into(),
         )
@@ -27,6 +29,7 @@ pub async fn check_existence_and_add_domain_to_db(
     let merchant_connector_account = state
         .store
         .find_by_merchant_connector_account_merchant_id_merchant_connector_id(
+            key_manager_state,
             &merchant_id,
             &merchant_connector_id,
             &key_store,
@@ -66,6 +69,7 @@ pub async fn check_existence_and_add_domain_to_db(
     state
         .store
         .update_merchant_connector_account(
+            key_manager_state,
             merchant_connector_account,
             updated_mca.into(),
             &key_store,
diff --git a/crates/router/src/core/webhooks/incoming.rs b/crates/router/src/core/webhooks/incoming.rs
index 9eb74dc2df4..5c5346ce134 100644
--- a/crates/router/src/core/webhooks/incoming.rs
+++ b/crates/router/src/core/webhooks/incoming.rs
@@ -258,7 +258,7 @@ async fn incoming_webhooks_core<W: types::OutgoingWebhookType>(
             Some(merchant_connector_account) => merchant_connector_account,
             None => {
                 helper_utils::get_mca_from_object_reference_id(
-                    &*state.clone().store,
+                    &state,
                     object_ref_id.clone(),
                     &merchant_account,
                     &connector_name,
@@ -1675,6 +1675,7 @@ async fn fetch_optional_mca_and_connector(
     if connector_name_or_mca_id.starts_with("mca_") {
         let mca = db
             .find_by_merchant_connector_account_merchant_id_merchant_connector_id(
+                &state.into(),
                 &merchant_account.merchant_id,
                 connector_name_or_mca_id,
                 key_store,
diff --git a/crates/router/src/core/webhooks/outgoing.rs b/crates/router/src/core/webhooks/outgoing.rs
index c40b4ae8869..ed2b41dc64d 100644
--- a/crates/router/src/core/webhooks/outgoing.rs
+++ b/crates/router/src/core/webhooks/outgoing.rs
@@ -4,7 +4,7 @@ use api_models::{
     webhook_events::{OutgoingWebhookRequestContent, OutgoingWebhookResponseContent},
     webhooks,
 };
-use common_utils::{ext_traits::Encode, request::RequestContent};
+use common_utils::{ext_traits::Encode, request::RequestContent, types::keymanager::Identifier};
 use diesel_models::process_tracker::business_status;
 use error_stack::{report, ResultExt};
 use hyperswitch_domain_models::type_encryption::decrypt;
@@ -87,6 +87,7 @@ pub(crate) async fn create_event_and_trigger_outgoing_webhook(
     };
 
     let request_content = get_outgoing_webhook_request(
+        &state,
         &merchant_account,
         outgoing_webhook,
         &business_profile,
@@ -97,7 +98,7 @@ pub(crate) async fn create_event_and_trigger_outgoing_webhook(
     .attach_printable("Failed to construct outgoing webhook request content")?;
 
     let event_metadata = storage::EventMetadata::foreign_from((&content, &primary_object_id));
-
+    let key_manager_state = &(&state).into();
     let new_event = domain::Event {
         event_id: event_id.clone(),
         event_type,
@@ -113,11 +114,13 @@ pub(crate) async fn create_event_and_trigger_outgoing_webhook(
         initial_attempt_id: Some(event_id.clone()),
         request: Some(
             domain_types::encrypt(
+                key_manager_state,
                 request_content
                     .encode_to_string_of_json()
                     .change_context(errors::ApiErrorResponse::WebhookProcessingFailure)
                     .attach_printable("Failed to encode outgoing webhook request content")
                     .map(Secret::new)?,
+                Identifier::Merchant(merchant_key_store.merchant_id.clone()),
                 merchant_key_store.key.get_inner().peek(),
             )
             .await
@@ -131,7 +134,7 @@ pub(crate) async fn create_event_and_trigger_outgoing_webhook(
 
     let event_insert_result = state
         .store
-        .insert_event(new_event, merchant_key_store)
+        .insert_event(key_manager_state, new_event, merchant_key_store)
         .await;
 
     let event = match event_insert_result {
@@ -552,6 +555,7 @@ fn get_webhook_url_from_business_profile(
 }
 
 pub(crate) async fn get_outgoing_webhook_request(
+    state: &SessionState,
     merchant_account: &domain::MerchantAccount,
     outgoing_webhook: api::OutgoingWebhook,
     business_profile: &diesel_models::business_profile::BusinessProfile,
@@ -559,6 +563,7 @@ pub(crate) async fn get_outgoing_webhook_request(
 ) -> CustomResult<OutgoingWebhookRequestContent, errors::WebhooksFlowError> {
     #[inline]
     async fn get_outgoing_webhook_request_inner<WebhookType: types::OutgoingWebhookType>(
+        state: &SessionState,
         outgoing_webhook: api::OutgoingWebhook,
         business_profile: &diesel_models::business_profile::BusinessProfile,
         key_store: &domain::MerchantKeyStore,
@@ -571,9 +576,11 @@ pub(crate) async fn get_outgoing_webhook_request(
         let transformed_outgoing_webhook = WebhookType::from(outgoing_webhook);
         let payment_response_hash_key = business_profile.payment_response_hash_key.clone();
         let custom_headers = decrypt::<serde_json::Value, masking::WithType>(
+            &state.into(),
             business_profile
                 .outgoing_webhook_custom_http_headers
                 .clone(),
+            Identifier::Merchant(key_store.merchant_id.clone()),
             key_store.key.get_inner().peek(),
         )
         .await
@@ -614,6 +621,7 @@ pub(crate) async fn get_outgoing_webhook_request(
         #[cfg(feature = "stripe")]
         Some(api_models::enums::Connector::Stripe) => {
             get_outgoing_webhook_request_inner::<stripe_webhooks::StripeOutgoingWebhook>(
+                state,
                 outgoing_webhook,
                 business_profile,
                 key_store,
@@ -622,6 +630,7 @@ pub(crate) async fn get_outgoing_webhook_request(
         }
         _ => {
             get_outgoing_webhook_request_inner::<webhooks::OutgoingWebhook>(
+                state,
                 outgoing_webhook,
                 business_profile,
                 key_store,
@@ -645,7 +654,7 @@ async fn update_event_if_client_error(
     error_message: String,
 ) -> CustomResult<domain::Event, errors::WebhooksFlowError> {
     let is_webhook_notified = false;
-
+    let key_manager_state = &(&state).into();
     let response_to_store = OutgoingWebhookResponseContent {
         body: None,
         headers: None,
@@ -657,12 +666,14 @@ async fn update_event_if_client_error(
         is_webhook_notified,
         response: Some(
             domain_types::encrypt(
+                key_manager_state,
                 response_to_store
                     .encode_to_string_of_json()
                     .change_context(
                         errors::WebhooksFlowError::OutgoingWebhookResponseEncodingFailed,
                     )
                     .map(Secret::new)?,
+                Identifier::Merchant(merchant_key_store.merchant_id.clone()),
                 merchant_key_store.key.get_inner().peek(),
             )
             .await
@@ -674,6 +685,7 @@ async fn update_event_if_client_error(
     state
         .store
         .update_event_by_merchant_id_event_id(
+            key_manager_state,
             merchant_id,
             event_id,
             event_update,
@@ -733,7 +745,7 @@ async fn update_event_in_storage(
 ) -> CustomResult<domain::Event, errors::WebhooksFlowError> {
     let status_code = response.status();
     let is_webhook_notified = status_code.is_success();
-
+    let key_manager_state = &(&state).into();
     let response_headers = response
         .headers()
         .iter()
@@ -772,12 +784,14 @@ async fn update_event_in_storage(
         is_webhook_notified,
         response: Some(
             domain_types::encrypt(
+                key_manager_state,
                 response_to_store
                     .encode_to_string_of_json()
                     .change_context(
                         errors::WebhooksFlowError::OutgoingWebhookResponseEncodingFailed,
                     )
                     .map(Secret::new)?,
+                Identifier::Merchant(merchant_key_store.merchant_id.clone()),
                 merchant_key_store.key.get_inner().peek(),
             )
             .await
@@ -788,6 +802,7 @@ async fn update_event_in_storage(
     state
         .store
         .update_event_by_merchant_id_event_id(
+            key_manager_state,
             merchant_id,
             event_id,
             event_update,
diff --git a/crates/router/src/core/webhooks/webhook_events.rs b/crates/router/src/core/webhooks/webhook_events.rs
index 2a16ccce0b4..19118ad639a 100644
--- a/crates/router/src/core/webhooks/webhook_events.rs
+++ b/crates/router/src/core/webhooks/webhook_events.rs
@@ -28,7 +28,7 @@ pub async fn list_initial_delivery_attempts(
         api::webhook_events::EventListConstraintsInternal::foreign_try_from(constraints)?;
 
     let store = state.store.as_ref();
-
+    let key_manager_state = &(&state).into();
     let (account, key_store) =
         determine_identifier_and_get_key_store(state.clone(), merchant_id_or_profile_id).await?;
 
@@ -36,14 +36,14 @@ pub async fn list_initial_delivery_attempts(
         api_models::webhook_events::EventListConstraintsInternal::ObjectIdFilter { object_id } => {
             match account {
                 MerchantAccountOrBusinessProfile::MerchantAccount(merchant_account) => store
-                .list_initial_events_by_merchant_id_primary_object_id(
+                .list_initial_events_by_merchant_id_primary_object_id(key_manager_state,
                     &merchant_account.merchant_id,
                     &object_id,
                     &key_store,
                 )
                 .await,
                 MerchantAccountOrBusinessProfile::BusinessProfile(business_profile) => store
-                .list_initial_events_by_profile_id_primary_object_id(
+                .list_initial_events_by_profile_id_primary_object_id(key_manager_state,
                     &business_profile.profile_id,
                     &object_id,
                     &key_store,
@@ -73,7 +73,7 @@ pub async fn list_initial_delivery_attempts(
 
             match account {
                 MerchantAccountOrBusinessProfile::MerchantAccount(merchant_account) => store
-                .list_initial_events_by_merchant_id_constraints(
+                .list_initial_events_by_merchant_id_constraints(key_manager_state,
                     &merchant_account.merchant_id,
                     created_after,
                     created_before,
@@ -83,7 +83,7 @@ pub async fn list_initial_delivery_attempts(
                 )
                 .await,
                 MerchantAccountOrBusinessProfile::BusinessProfile(business_profile) => store
-                .list_initial_events_by_profile_id_constraints(
+                .list_initial_events_by_profile_id_constraints(key_manager_state,
                     &business_profile.profile_id,
                     created_after,
                     created_before,
@@ -116,11 +116,12 @@ pub async fn list_delivery_attempts(
 
     let (account, key_store) =
         determine_identifier_and_get_key_store(state.clone(), merchant_id_or_profile_id).await?;
-
+    let key_manager_state = &(&state).into();
     let events = match account {
         MerchantAccountOrBusinessProfile::MerchantAccount(merchant_account) => {
             store
                 .list_events_by_merchant_id_initial_attempt_id(
+                    key_manager_state,
                     &merchant_account.merchant_id,
                     &initial_attempt_id,
                     &key_store,
@@ -130,6 +131,7 @@ pub async fn list_delivery_attempts(
         MerchantAccountOrBusinessProfile::BusinessProfile(business_profile) => {
             store
                 .list_events_by_profile_id_initial_attempt_id(
+                    key_manager_state,
                     &business_profile.profile_id,
                     &initial_attempt_id,
                     &key_store,
@@ -162,12 +164,17 @@ pub async fn retry_delivery_attempt(
     event_id: String,
 ) -> RouterResponse<api::webhook_events::EventRetrieveResponse> {
     let store = state.store.as_ref();
-
+    let key_manager_state = &(&state).into();
     let (account, key_store) =
         determine_identifier_and_get_key_store(state.clone(), merchant_id_or_profile_id).await?;
 
     let event_to_retry = store
-        .find_event_by_merchant_id_event_id(&key_store.merchant_id, &event_id, &key_store)
+        .find_event_by_merchant_id_event_id(
+            key_manager_state,
+            &key_store.merchant_id,
+            &event_id,
+            &key_store,
+        )
         .await
         .to_not_found_response(errors::ApiErrorResponse::EventNotFound)?;
 
@@ -216,7 +223,7 @@ pub async fn retry_delivery_attempt(
     };
 
     let event = store
-        .insert_event(new_event, &key_store)
+        .insert_event(key_manager_state, new_event, &key_store)
         .await
         .change_context(errors::ApiErrorResponse::InternalServerError)
         .attach_printable("Failed to insert event")?;
@@ -245,7 +252,12 @@ pub async fn retry_delivery_attempt(
     .await;
 
     let updated_event = store
-        .find_event_by_merchant_id_event_id(&key_store.merchant_id, &new_event_id, &key_store)
+        .find_event_by_merchant_id_event_id(
+            key_manager_state,
+            &key_store.merchant_id,
+            &new_event_id,
+            &key_store,
+        )
         .await
         .to_not_found_response(errors::ApiErrorResponse::EventNotFound)?;
 
@@ -259,8 +271,10 @@ async fn determine_identifier_and_get_key_store(
     merchant_id_or_profile_id: String,
 ) -> errors::RouterResult<(MerchantAccountOrBusinessProfile, domain::MerchantKeyStore)> {
     let store = state.store.as_ref();
+    let key_manager_state = &(&state).into();
     match store
         .get_merchant_key_store_by_merchant_id(
+            key_manager_state,
             &merchant_id_or_profile_id,
             &store.get_master_key().to_vec().into(),
         )
@@ -271,7 +285,11 @@ async fn determine_identifier_and_get_key_store(
         // Find a merchant account having `merchant_id` = `merchant_id_or_profile_id`.
         Ok(key_store) => {
             let merchant_account = store
-                .find_merchant_account_by_merchant_id(&merchant_id_or_profile_id, &key_store)
+                .find_merchant_account_by_merchant_id(
+                    key_manager_state,
+                    &merchant_id_or_profile_id,
+                    &key_store,
+                )
                 .await
                 .to_not_found_response(errors::ApiErrorResponse::MerchantAccountNotFound)?;
 
@@ -301,6 +319,7 @@ async fn determine_identifier_and_get_key_store(
 
             let key_store = store
                 .get_merchant_key_store_by_merchant_id(
+                    key_manager_state,
                     &business_profile.merchant_id,
                     &store.get_master_key().to_vec().into(),
                 )
diff --git a/crates/router/src/db/address.rs b/crates/router/src/db/address.rs
index f210019b4da..04a8f673a94 100644
--- a/crates/router/src/db/address.rs
+++ b/crates/router/src/db/address.rs
@@ -1,4 +1,4 @@
-use common_utils::id_type;
+use common_utils::{id_type, types::keymanager::KeyManagerState};
 use diesel_models::{address::AddressUpdateInternal, enums::MerchantStorageScheme};
 use error_stack::ResultExt;
 
@@ -22,6 +22,7 @@ where
 {
     async fn update_address(
         &self,
+        state: &KeyManagerState,
         address_id: String,
         address: storage_types::AddressUpdate,
         key_store: &domain::MerchantKeyStore,
@@ -29,6 +30,7 @@ where
 
     async fn update_address_for_payments(
         &self,
+        state: &KeyManagerState,
         this: domain::PaymentAddress,
         address: domain::AddressUpdate,
         payment_id: String,
@@ -38,12 +40,14 @@ where
 
     async fn find_address_by_address_id(
         &self,
+        state: &KeyManagerState,
         address_id: &str,
         key_store: &domain::MerchantKeyStore,
     ) -> CustomResult<domain::Address, errors::StorageError>;
 
     async fn insert_address_for_payments(
         &self,
+        state: &KeyManagerState,
         payment_id: &str,
         address: domain::PaymentAddress,
         key_store: &domain::MerchantKeyStore,
@@ -52,12 +56,14 @@ where
 
     async fn insert_address_for_customers(
         &self,
+        state: &KeyManagerState,
         address: domain::CustomerAddress,
         key_store: &domain::MerchantKeyStore,
     ) -> CustomResult<domain::Address, errors::StorageError>;
 
     async fn find_address_by_merchant_id_payment_id_address_id(
         &self,
+        state: &KeyManagerState,
         merchant_id: &str,
         payment_id: &str,
         address_id: &str,
@@ -67,6 +73,7 @@ where
 
     async fn update_address_by_merchant_id_customer_id(
         &self,
+        state: &KeyManagerState,
         customer_id: &id_type::CustomerId,
         merchant_id: &str,
         address: storage_types::AddressUpdate,
@@ -76,7 +83,7 @@ where
 
 #[cfg(not(feature = "kv_store"))]
 mod storage {
-    use common_utils::{ext_traits::AsyncExt, id_type};
+    use common_utils::{ext_traits::AsyncExt, id_type, types::keymanager::KeyManagerState};
     use error_stack::{report, ResultExt};
     use router_env::{instrument, tracing};
 
@@ -98,6 +105,7 @@ mod storage {
         #[instrument(skip_all)]
         async fn find_address_by_address_id(
             &self,
+            state: &KeyManagerState,
             address_id: &str,
             key_store: &domain::MerchantKeyStore,
         ) -> CustomResult<domain::Address, errors::StorageError> {
@@ -107,7 +115,11 @@ mod storage {
                 .map_err(|error| report!(errors::StorageError::from(error)))
                 .async_and_then(|address| async {
                     address
-                        .convert(key_store.key.get_inner())
+                        .convert(
+                            state,
+                            key_store.key.get_inner(),
+                            key_store.merchant_id.clone(),
+                        )
                         .await
                         .change_context(errors::StorageError::DecryptionError)
                 })
@@ -117,6 +129,7 @@ mod storage {
         #[instrument(skip_all)]
         async fn find_address_by_merchant_id_payment_id_address_id(
             &self,
+            state: &KeyManagerState,
             merchant_id: &str,
             payment_id: &str,
             address_id: &str,
@@ -134,7 +147,7 @@ mod storage {
             .map_err(|error| report!(errors::StorageError::from(error)))
             .async_and_then(|address| async {
                 address
-                    .convert(key_store.key.get_inner())
+                    .convert(state, key_store.key.get_inner(), merchant_id.to_string())
                     .await
                     .change_context(errors::StorageError::DecryptionError)
             })
@@ -144,6 +157,7 @@ mod storage {
         #[instrument(skip_all)]
         async fn update_address(
             &self,
+            state: &KeyManagerState,
             address_id: String,
             address: storage_types::AddressUpdate,
             key_store: &domain::MerchantKeyStore,
@@ -154,7 +168,11 @@ mod storage {
                 .map_err(|error| report!(errors::StorageError::from(error)))
                 .async_and_then(|address| async {
                     address
-                        .convert(key_store.key.get_inner())
+                        .convert(
+                            state,
+                            key_store.key.get_inner(),
+                            key_store.merchant_id.clone(),
+                        )
                         .await
                         .change_context(errors::StorageError::DecryptionError)
                 })
@@ -164,6 +182,7 @@ mod storage {
         #[instrument(skip_all)]
         async fn update_address_for_payments(
             &self,
+            state: &KeyManagerState,
             this: domain::PaymentAddress,
             address_update: domain::AddressUpdate,
             _payment_id: String,
@@ -180,7 +199,11 @@ mod storage {
                 .map_err(|error| report!(errors::StorageError::from(error)))
                 .async_and_then(|address| async {
                     address
-                        .convert(key_store.key.get_inner())
+                        .convert(
+                            state,
+                            key_store.key.get_inner(),
+                            key_store.merchant_id.clone(),
+                        )
                         .await
                         .change_context(errors::StorageError::DecryptionError)
                 })
@@ -190,6 +213,7 @@ mod storage {
         #[instrument(skip_all)]
         async fn insert_address_for_payments(
             &self,
+            state: &KeyManagerState,
             _payment_id: &str,
             address: domain::PaymentAddress,
             key_store: &domain::MerchantKeyStore,
@@ -205,7 +229,11 @@ mod storage {
                 .map_err(|error| report!(errors::StorageError::from(error)))
                 .async_and_then(|address| async {
                     address
-                        .convert(key_store.key.get_inner())
+                        .convert(
+                            state,
+                            key_store.key.get_inner(),
+                            key_store.merchant_id.clone(),
+                        )
                         .await
                         .change_context(errors::StorageError::DecryptionError)
                 })
@@ -215,6 +243,7 @@ mod storage {
         #[instrument(skip_all)]
         async fn insert_address_for_customers(
             &self,
+            state: &KeyManagerState,
             address: domain::CustomerAddress,
             key_store: &domain::MerchantKeyStore,
         ) -> CustomResult<domain::Address, errors::StorageError> {
@@ -228,7 +257,11 @@ mod storage {
                 .map_err(|error| report!(errors::StorageError::from(error)))
                 .async_and_then(|address| async {
                     address
-                        .convert(key_store.key.get_inner())
+                        .convert(
+                            state,
+                            key_store.key.get_inner(),
+                            key_store.merchant_id.clone(),
+                        )
                         .await
                         .change_context(errors::StorageError::DecryptionError)
                 })
@@ -238,6 +271,7 @@ mod storage {
         #[instrument(skip_all)]
         async fn update_address_by_merchant_id_customer_id(
             &self,
+            state: &KeyManagerState,
             customer_id: &id_type::CustomerId,
             merchant_id: &str,
             address: storage_types::AddressUpdate,
@@ -257,7 +291,7 @@ mod storage {
                 for address in addresses.into_iter() {
                     output.push(
                         address
-                            .convert(key_store.key.get_inner())
+                            .convert(state, key_store.key.get_inner(), merchant_id.to_string())
                             .await
                             .change_context(errors::StorageError::DecryptionError)?,
                     )
@@ -271,7 +305,7 @@ mod storage {
 
 #[cfg(feature = "kv_store")]
 mod storage {
-    use common_utils::{ext_traits::AsyncExt, id_type};
+    use common_utils::{ext_traits::AsyncExt, id_type, types::keymanager::KeyManagerState};
     use diesel_models::{enums::MerchantStorageScheme, AddressUpdateInternal};
     use error_stack::{report, ResultExt};
     use redis_interface::HsetnxReply;
@@ -299,6 +333,7 @@ mod storage {
         #[instrument(skip_all)]
         async fn find_address_by_address_id(
             &self,
+            state: &KeyManagerState,
             address_id: &str,
             key_store: &domain::MerchantKeyStore,
         ) -> CustomResult<domain::Address, errors::StorageError> {
@@ -308,7 +343,11 @@ mod storage {
                 .map_err(|error| report!(errors::StorageError::from(error)))
                 .async_and_then(|address| async {
                     address
-                        .convert(key_store.key.get_inner())
+                        .convert(
+                            state,
+                            key_store.key.get_inner(),
+                            key_store.merchant_id.clone(),
+                        )
                         .await
                         .change_context(errors::StorageError::DecryptionError)
                 })
@@ -318,6 +357,7 @@ mod storage {
         #[instrument(skip_all)]
         async fn find_address_by_merchant_id_payment_id_address_id(
             &self,
+            state: &KeyManagerState,
             merchant_id: &str,
             payment_id: &str,
             address_id: &str,
@@ -362,7 +402,11 @@ mod storage {
                 }
             }?;
             address
-                .convert(key_store.key.get_inner())
+                .convert(
+                    state,
+                    key_store.key.get_inner(),
+                    key_store.merchant_id.clone(),
+                )
                 .await
                 .change_context(errors::StorageError::DecryptionError)
         }
@@ -370,6 +414,7 @@ mod storage {
         #[instrument(skip_all)]
         async fn update_address(
             &self,
+            state: &KeyManagerState,
             address_id: String,
             address: storage_types::AddressUpdate,
             key_store: &domain::MerchantKeyStore,
@@ -380,7 +425,11 @@ mod storage {
                 .map_err(|error| report!(errors::StorageError::from(error)))
                 .async_and_then(|address| async {
                     address
-                        .convert(key_store.key.get_inner())
+                        .convert(
+                            state,
+                            key_store.key.get_inner(),
+                            key_store.merchant_id.clone(),
+                        )
                         .await
                         .change_context(errors::StorageError::DecryptionError)
                 })
@@ -390,6 +439,7 @@ mod storage {
         #[instrument(skip_all)]
         async fn update_address_for_payments(
             &self,
+            state: &KeyManagerState,
             this: domain::PaymentAddress,
             address_update: domain::AddressUpdate,
             payment_id: String,
@@ -420,7 +470,11 @@ mod storage {
                         .map_err(|error| report!(errors::StorageError::from(error)))
                         .async_and_then(|address| async {
                             address
-                                .convert(key_store.key.get_inner())
+                                .convert(
+                                    state,
+                                    key_store.key.get_inner(),
+                                    key_store.merchant_id.clone(),
+                                )
                                 .await
                                 .change_context(errors::StorageError::DecryptionError)
                         })
@@ -457,7 +511,11 @@ mod storage {
                     .change_context(errors::StorageError::KVError)?;
 
                     updated_address
-                        .convert(key_store.key.get_inner())
+                        .convert(
+                            state,
+                            key_store.key.get_inner(),
+                            key_store.merchant_id.clone(),
+                        )
                         .await
                         .change_context(errors::StorageError::DecryptionError)
                 }
@@ -467,6 +525,7 @@ mod storage {
         #[instrument(skip_all)]
         async fn insert_address_for_payments(
             &self,
+            state: &KeyManagerState,
             payment_id: &str,
             address: domain::PaymentAddress,
             key_store: &domain::MerchantKeyStore,
@@ -493,7 +552,11 @@ mod storage {
                         .map_err(|error| report!(errors::StorageError::from(error)))
                         .async_and_then(|address| async {
                             address
-                                .convert(key_store.key.get_inner())
+                                .convert(
+                                    state,
+                                    key_store.key.get_inner(),
+                                    key_store.merchant_id.clone(),
+                                )
                                 .await
                                 .change_context(errors::StorageError::DecryptionError)
                         })
@@ -553,7 +616,11 @@ mod storage {
                         }
                         .into()),
                         Ok(HsetnxReply::KeySet) => Ok(created_address
-                            .convert(key_store.key.get_inner())
+                            .convert(
+                                state,
+                                key_store.key.get_inner(),
+                                key_store.merchant_id.clone(),
+                            )
                             .await
                             .change_context(errors::StorageError::DecryptionError)?),
                         Err(er) => Err(er).change_context(errors::StorageError::KVError),
@@ -565,6 +632,7 @@ mod storage {
         #[instrument(skip_all)]
         async fn insert_address_for_customers(
             &self,
+            state: &KeyManagerState,
             address: domain::CustomerAddress,
             key_store: &domain::MerchantKeyStore,
         ) -> CustomResult<domain::Address, errors::StorageError> {
@@ -578,7 +646,11 @@ mod storage {
                 .map_err(|error| report!(errors::StorageError::from(error)))
                 .async_and_then(|address| async {
                     address
-                        .convert(key_store.key.get_inner())
+                        .convert(
+                            state,
+                            key_store.key.get_inner(),
+                            key_store.merchant_id.clone(),
+                        )
                         .await
                         .change_context(errors::StorageError::DecryptionError)
                 })
@@ -588,6 +660,7 @@ mod storage {
         #[instrument(skip_all)]
         async fn update_address_by_merchant_id_customer_id(
             &self,
+            state: &KeyManagerState,
             customer_id: &id_type::CustomerId,
             merchant_id: &str,
             address: storage_types::AddressUpdate,
@@ -607,7 +680,11 @@ mod storage {
                 for address in addresses.into_iter() {
                     output.push(
                         address
-                            .convert(key_store.key.get_inner())
+                            .convert(
+                                state,
+                                key_store.key.get_inner(),
+                                key_store.merchant_id.clone(),
+                            )
                             .await
                             .change_context(errors::StorageError::DecryptionError)?,
                     )
@@ -623,6 +700,7 @@ mod storage {
 impl AddressInterface for MockDb {
     async fn find_address_by_address_id(
         &self,
+        state: &KeyManagerState,
         address_id: &str,
         key_store: &domain::MerchantKeyStore,
     ) -> CustomResult<domain::Address, errors::StorageError> {
@@ -635,7 +713,11 @@ impl AddressInterface for MockDb {
         {
             Some(address) => address
                 .clone()
-                .convert(key_store.key.get_inner())
+                .convert(
+                    state,
+                    key_store.key.get_inner(),
+                    key_store.merchant_id.clone(),
+                )
                 .await
                 .change_context(errors::StorageError::DecryptionError),
             None => {
@@ -648,6 +730,7 @@ impl AddressInterface for MockDb {
 
     async fn find_address_by_merchant_id_payment_id_address_id(
         &self,
+        state: &KeyManagerState,
         _merchant_id: &str,
         _payment_id: &str,
         address_id: &str,
@@ -663,7 +746,11 @@ impl AddressInterface for MockDb {
         {
             Some(address) => address
                 .clone()
-                .convert(key_store.key.get_inner())
+                .convert(
+                    state,
+                    key_store.key.get_inner(),
+                    key_store.merchant_id.clone(),
+                )
                 .await
                 .change_context(errors::StorageError::DecryptionError),
             None => {
@@ -676,6 +763,7 @@ impl AddressInterface for MockDb {
 
     async fn update_address(
         &self,
+        state: &KeyManagerState,
         address_id: String,
         address_update: storage_types::AddressUpdate,
         key_store: &domain::MerchantKeyStore,
@@ -694,7 +782,11 @@ impl AddressInterface for MockDb {
             });
         match updated_addr {
             Some(address_updated) => address_updated
-                .convert(key_store.key.get_inner())
+                .convert(
+                    state,
+                    key_store.key.get_inner(),
+                    key_store.merchant_id.clone(),
+                )
                 .await
                 .change_context(errors::StorageError::DecryptionError),
             None => Err(errors::StorageError::ValueNotFound(
@@ -706,6 +798,7 @@ impl AddressInterface for MockDb {
 
     async fn update_address_for_payments(
         &self,
+        state: &KeyManagerState,
         this: domain::PaymentAddress,
         address_update: domain::AddressUpdate,
         _payment_id: String,
@@ -726,7 +819,11 @@ impl AddressInterface for MockDb {
             });
         match updated_addr {
             Some(address_updated) => address_updated
-                .convert(key_store.key.get_inner())
+                .convert(
+                    state,
+                    key_store.key.get_inner(),
+                    key_store.merchant_id.clone(),
+                )
                 .await
                 .change_context(errors::StorageError::DecryptionError),
             None => Err(errors::StorageError::ValueNotFound(
@@ -738,6 +835,7 @@ impl AddressInterface for MockDb {
 
     async fn insert_address_for_payments(
         &self,
+        state: &KeyManagerState,
         _payment_id: &str,
         address_new: domain::PaymentAddress,
         key_store: &domain::MerchantKeyStore,
@@ -752,13 +850,18 @@ impl AddressInterface for MockDb {
         addresses.push(address.clone());
 
         address
-            .convert(key_store.key.get_inner())
+            .convert(
+                state,
+                key_store.key.get_inner(),
+                key_store.merchant_id.clone(),
+            )
             .await
             .change_context(errors::StorageError::DecryptionError)
     }
 
     async fn insert_address_for_customers(
         &self,
+        state: &KeyManagerState,
         address_new: domain::CustomerAddress,
         key_store: &domain::MerchantKeyStore,
     ) -> CustomResult<domain::Address, errors::StorageError> {
@@ -771,13 +874,18 @@ impl AddressInterface for MockDb {
         addresses.push(address.clone());
 
         address
-            .convert(key_store.key.get_inner())
+            .convert(
+                state,
+                key_store.key.get_inner(),
+                key_store.merchant_id.clone(),
+            )
             .await
             .change_context(errors::StorageError::DecryptionError)
     }
 
     async fn update_address_by_merchant_id_customer_id(
         &self,
+        state: &KeyManagerState,
         customer_id: &id_type::CustomerId,
         merchant_id: &str,
         address_update: storage_types::AddressUpdate,
@@ -801,7 +909,11 @@ impl AddressInterface for MockDb {
         match updated_addr {
             Some(address) => {
                 let address: domain::Address = address
-                    .convert(key_store.key.get_inner())
+                    .convert(
+                        state,
+                        key_store.key.get_inner(),
+                        key_store.merchant_id.clone(),
+                    )
                     .await
                     .change_context(errors::StorageError::DecryptionError)?;
                 Ok(vec![address])
diff --git a/crates/router/src/db/customers.rs b/crates/router/src/db/customers.rs
index cad3d2969fe..1bfda658521 100644
--- a/crates/router/src/db/customers.rs
+++ b/crates/router/src/db/customers.rs
@@ -1,4 +1,4 @@
-use common_utils::{ext_traits::AsyncExt, id_type};
+use common_utils::{ext_traits::AsyncExt, id_type, types::keymanager::KeyManagerState};
 use error_stack::ResultExt;
 use futures::future::try_join_all;
 use router_env::{instrument, tracing};
@@ -29,14 +29,17 @@ where
 
     async fn find_customer_optional_by_customer_id_merchant_id(
         &self,
+        state: &KeyManagerState,
         customer_id: &id_type::CustomerId,
         merchant_id: &str,
         key_store: &domain::MerchantKeyStore,
         storage_scheme: MerchantStorageScheme,
     ) -> CustomResult<Option<domain::Customer>, errors::StorageError>;
 
+    #[allow(clippy::too_many_arguments)]
     async fn update_customer_by_customer_id_merchant_id(
         &self,
+        state: &KeyManagerState,
         customer_id: id_type::CustomerId,
         merchant_id: String,
         customer: domain::Customer,
@@ -47,6 +50,7 @@ where
 
     async fn find_customer_by_customer_id_merchant_id(
         &self,
+        state: &KeyManagerState,
         customer_id: &id_type::CustomerId,
         merchant_id: &str,
         key_store: &domain::MerchantKeyStore,
@@ -55,12 +59,14 @@ where
 
     async fn list_customers_by_merchant_id(
         &self,
+        state: &KeyManagerState,
         merchant_id: &str,
         key_store: &domain::MerchantKeyStore,
     ) -> CustomResult<Vec<domain::Customer>, errors::StorageError>;
 
     async fn insert_customer(
         &self,
+        state: &KeyManagerState,
         customer_data: domain::Customer,
         key_store: &domain::MerchantKeyStore,
         storage_scheme: MerchantStorageScheme,
@@ -69,7 +75,7 @@ where
 
 #[cfg(feature = "kv_store")]
 mod storage {
-    use common_utils::{ext_traits::AsyncExt, id_type};
+    use common_utils::{ext_traits::AsyncExt, id_type, types::keymanager::KeyManagerState};
     use diesel_models::kv;
     use error_stack::{report, ResultExt};
     use futures::future::try_join_all;
@@ -103,6 +109,7 @@ mod storage {
         // check customer not found in kv and fallback to db
         async fn find_customer_optional_by_customer_id_merchant_id(
             &self,
+            state: &KeyManagerState,
             customer_id: &id_type::CustomerId,
             merchant_id: &str,
             key_store: &domain::MerchantKeyStore,
@@ -149,9 +156,13 @@ mod storage {
 
             let maybe_result = maybe_customer
                 .async_map(|c| async {
-                    c.convert(key_store.key.get_inner())
-                        .await
-                        .change_context(errors::StorageError::DecryptionError)
+                    c.convert(
+                        state,
+                        key_store.key.get_inner(),
+                        key_store.merchant_id.clone(),
+                    )
+                    .await
+                    .change_context(errors::StorageError::DecryptionError)
                 })
                 .await
                 .transpose()?;
@@ -167,6 +178,7 @@ mod storage {
         #[instrument(skip_all)]
         async fn update_customer_by_customer_id_merchant_id(
             &self,
+            state: &KeyManagerState,
             customer_id: id_type::CustomerId,
             merchant_id: String,
             customer: domain::Customer,
@@ -236,7 +248,11 @@ mod storage {
             };
 
             updated_object?
-                .convert(key_store.key.get_inner())
+                .convert(
+                    state,
+                    key_store.key.get_inner(),
+                    key_store.merchant_id.clone(),
+                )
                 .await
                 .change_context(errors::StorageError::DecryptionError)
         }
@@ -244,6 +260,7 @@ mod storage {
         #[instrument(skip_all)]
         async fn find_customer_by_customer_id_merchant_id(
             &self,
+            state: &KeyManagerState,
             customer_id: &id_type::CustomerId,
             merchant_id: &str,
             key_store: &domain::MerchantKeyStore,
@@ -287,7 +304,11 @@ mod storage {
             }?;
 
             let result: domain::Customer = customer
-                .convert(key_store.key.get_inner())
+                .convert(
+                    state,
+                    key_store.key.get_inner(),
+                    key_store.merchant_id.clone(),
+                )
                 .await
                 .change_context(errors::StorageError::DecryptionError)?;
             //.await
@@ -303,6 +324,7 @@ mod storage {
         #[instrument(skip_all)]
         async fn list_customers_by_merchant_id(
             &self,
+            state: &KeyManagerState,
             merchant_id: &str,
             key_store: &domain::MerchantKeyStore,
         ) -> CustomResult<Vec<domain::Customer>, errors::StorageError> {
@@ -316,7 +338,11 @@ mod storage {
             let customers = try_join_all(encrypted_customers.into_iter().map(
                 |encrypted_customer| async {
                     encrypted_customer
-                        .convert(key_store.key.get_inner())
+                        .convert(
+                            state,
+                            key_store.key.get_inner(),
+                            key_store.merchant_id.clone(),
+                        )
                         .await
                         .change_context(errors::StorageError::DecryptionError)
                 },
@@ -329,6 +355,7 @@ mod storage {
         #[instrument(skip_all)]
         async fn insert_customer(
             &self,
+            state: &KeyManagerState,
             customer_data: domain::Customer,
             key_store: &domain::MerchantKeyStore,
             storage_scheme: MerchantStorageScheme,
@@ -394,7 +421,11 @@ mod storage {
             }?;
 
             create_customer
-                .convert(key_store.key.get_inner())
+                .convert(
+                    state,
+                    key_store.key.get_inner(),
+                    key_store.merchant_id.clone(),
+                )
                 .await
                 .change_context(errors::StorageError::DecryptionError)
         }
@@ -419,7 +450,7 @@ mod storage {
 
 #[cfg(not(feature = "kv_store"))]
 mod storage {
-    use common_utils::{ext_traits::AsyncExt, id_type};
+    use common_utils::{ext_traits::AsyncExt, id_type, types::keymanager::KeyManagerState};
     use error_stack::{report, ResultExt};
     use futures::future::try_join_all;
     use masking::PeekInterface;
@@ -447,6 +478,7 @@ mod storage {
         #[instrument(skip_all)]
         async fn find_customer_optional_by_customer_id_merchant_id(
             &self,
+            state: &KeyManagerState,
             customer_id: &id_type::CustomerId,
             merchant_id: &str,
             key_store: &domain::MerchantKeyStore,
@@ -462,7 +494,7 @@ mod storage {
                 .await
                 .map_err(|error| report!(errors::StorageError::from(error)))?
                 .async_map(|c| async {
-                    c.convert(key_store.key.get_inner())
+                    c.convert(state, key_store.key.get_inner(), merchant_id.to_string())
                         .await
                         .change_context(errors::StorageError::DecryptionError)
                 })
@@ -483,6 +515,7 @@ mod storage {
         #[instrument(skip_all)]
         async fn update_customer_by_customer_id_merchant_id(
             &self,
+            state: &KeyManagerState,
             customer_id: id_type::CustomerId,
             merchant_id: String,
             _customer: domain::Customer,
@@ -494,13 +527,13 @@ mod storage {
             storage_types::Customer::update_by_customer_id_merchant_id(
                 &conn,
                 customer_id,
-                merchant_id,
+                merchant_id.clone(),
                 customer_update.into(),
             )
             .await
             .map_err(|error| report!(errors::StorageError::from(error)))
             .async_and_then(|c| async {
-                c.convert(key_store.key.get_inner())
+                c.convert(state, key_store.key.get_inner(), merchant_id)
                     .await
                     .change_context(errors::StorageError::DecryptionError)
             })
@@ -510,6 +543,7 @@ mod storage {
         #[instrument(skip_all)]
         async fn find_customer_by_customer_id_merchant_id(
             &self,
+            state: &KeyManagerState,
             customer_id: &id_type::CustomerId,
             merchant_id: &str,
             key_store: &domain::MerchantKeyStore,
@@ -525,7 +559,7 @@ mod storage {
                 .await
                 .map_err(|error| report!(errors::StorageError::from(error)))
                 .async_and_then(|c| async {
-                    c.convert(key_store.key.get_inner())
+                    c.convert(state, key_store.key.get_inner(), merchant_id.to_string())
                         .await
                         .change_context(errors::StorageError::DecryptionError)
                 })
@@ -541,6 +575,7 @@ mod storage {
         #[instrument(skip_all)]
         async fn list_customers_by_merchant_id(
             &self,
+            state: &KeyManagerState,
             merchant_id: &str,
             key_store: &domain::MerchantKeyStore,
         ) -> CustomResult<Vec<domain::Customer>, errors::StorageError> {
@@ -554,7 +589,7 @@ mod storage {
             let customers = try_join_all(encrypted_customers.into_iter().map(
                 |encrypted_customer| async {
                     encrypted_customer
-                        .convert(key_store.key.get_inner())
+                        .convert(state, key_store.key.get_inner(), merchant_id.to_string())
                         .await
                         .change_context(errors::StorageError::DecryptionError)
                 },
@@ -567,6 +602,7 @@ mod storage {
         #[instrument(skip_all)]
         async fn insert_customer(
             &self,
+            state: &KeyManagerState,
             customer_data: domain::Customer,
             key_store: &domain::MerchantKeyStore,
             _storage_scheme: MerchantStorageScheme,
@@ -580,9 +616,13 @@ mod storage {
                 .await
                 .map_err(|error| report!(errors::StorageError::from(error)))
                 .async_and_then(|c| async {
-                    c.convert(key_store.key.get_inner())
-                        .await
-                        .change_context(errors::StorageError::DecryptionError)
+                    c.convert(
+                        state,
+                        key_store.key.get_inner(),
+                        key_store.merchant_id.clone(),
+                    )
+                    .await
+                    .change_context(errors::StorageError::DecryptionError)
                 })
                 .await
         }
@@ -610,6 +650,7 @@ impl CustomerInterface for MockDb {
     #[allow(clippy::panic)]
     async fn find_customer_optional_by_customer_id_merchant_id(
         &self,
+        state: &KeyManagerState,
         customer_id: &id_type::CustomerId,
         merchant_id: &str,
         key_store: &domain::MerchantKeyStore,
@@ -624,9 +665,13 @@ impl CustomerInterface for MockDb {
             .cloned();
         customer
             .async_map(|c| async {
-                c.convert(key_store.key.get_inner())
-                    .await
-                    .change_context(errors::StorageError::DecryptionError)
+                c.convert(
+                    state,
+                    key_store.key.get_inner(),
+                    key_store.merchant_id.clone(),
+                )
+                .await
+                .change_context(errors::StorageError::DecryptionError)
             })
             .await
             .transpose()
@@ -634,6 +679,7 @@ impl CustomerInterface for MockDb {
 
     async fn list_customers_by_merchant_id(
         &self,
+        state: &KeyManagerState,
         merchant_id: &str,
         key_store: &domain::MerchantKeyStore,
     ) -> CustomResult<Vec<domain::Customer>, errors::StorageError> {
@@ -646,7 +692,11 @@ impl CustomerInterface for MockDb {
                 .map(|customer| async {
                     customer
                         .to_owned()
-                        .convert(key_store.key.get_inner())
+                        .convert(
+                            state,
+                            key_store.key.get_inner(),
+                            key_store.merchant_id.clone(),
+                        )
                         .await
                         .change_context(errors::StorageError::DecryptionError)
                 }),
@@ -659,6 +709,7 @@ impl CustomerInterface for MockDb {
     #[instrument(skip_all)]
     async fn update_customer_by_customer_id_merchant_id(
         &self,
+        _state: &KeyManagerState,
         _customer_id: id_type::CustomerId,
         _merchant_id: String,
         _customer: domain::Customer,
@@ -672,6 +723,7 @@ impl CustomerInterface for MockDb {
 
     async fn find_customer_by_customer_id_merchant_id(
         &self,
+        _state: &KeyManagerState,
         _customer_id: &id_type::CustomerId,
         _merchant_id: &str,
         _key_store: &domain::MerchantKeyStore,
@@ -684,6 +736,7 @@ impl CustomerInterface for MockDb {
     #[allow(clippy::panic)]
     async fn insert_customer(
         &self,
+        state: &KeyManagerState,
         customer_data: domain::Customer,
         key_store: &domain::MerchantKeyStore,
         _storage_scheme: MerchantStorageScheme,
@@ -697,7 +750,11 @@ impl CustomerInterface for MockDb {
         customers.push(customer.clone());
 
         customer
-            .convert(key_store.key.get_inner())
+            .convert(
+                state,
+                key_store.key.get_inner(),
+                key_store.merchant_id.clone(),
+            )
             .await
             .change_context(errors::StorageError::DecryptionError)
     }
diff --git a/crates/router/src/db/events.rs b/crates/router/src/db/events.rs
index aba11f95988..2fd8a09f173 100644
--- a/crates/router/src/db/events.rs
+++ b/crates/router/src/db/events.rs
@@ -1,4 +1,4 @@
-use common_utils::ext_traits::AsyncExt;
+use common_utils::{ext_traits::AsyncExt, types::keymanager::KeyManagerState};
 use error_stack::{report, ResultExt};
 use router_env::{instrument, tracing};
 
@@ -23,12 +23,14 @@ where
 {
     async fn insert_event(
         &self,
+        state: &KeyManagerState,
         event: domain::Event,
         merchant_key_store: &domain::MerchantKeyStore,
     ) -> CustomResult<domain::Event, errors::StorageError>;
 
     async fn find_event_by_merchant_id_event_id(
         &self,
+        state: &KeyManagerState,
         merchant_id: &str,
         event_id: &str,
         merchant_key_store: &domain::MerchantKeyStore,
@@ -36,13 +38,16 @@ where
 
     async fn list_initial_events_by_merchant_id_primary_object_id(
         &self,
+        state: &KeyManagerState,
         merchant_id: &str,
         primary_object_id: &str,
         merchant_key_store: &domain::MerchantKeyStore,
     ) -> CustomResult<Vec<domain::Event>, errors::StorageError>;
 
+    #[allow(clippy::too_many_arguments)]
     async fn list_initial_events_by_merchant_id_constraints(
         &self,
+        state: &KeyManagerState,
         merchant_id: &str,
         created_after: Option<time::PrimitiveDateTime>,
         created_before: Option<time::PrimitiveDateTime>,
@@ -53,6 +58,7 @@ where
 
     async fn list_events_by_merchant_id_initial_attempt_id(
         &self,
+        state: &KeyManagerState,
         merchant_id: &str,
         initial_attempt_id: &str,
         merchant_key_store: &domain::MerchantKeyStore,
@@ -60,13 +66,16 @@ where
 
     async fn list_initial_events_by_profile_id_primary_object_id(
         &self,
+        state: &KeyManagerState,
         profile_id: &str,
         primary_object_id: &str,
         merchant_key_store: &domain::MerchantKeyStore,
     ) -> CustomResult<Vec<domain::Event>, errors::StorageError>;
 
+    #[allow(clippy::too_many_arguments)]
     async fn list_initial_events_by_profile_id_constraints(
         &self,
+        state: &KeyManagerState,
         profile_id: &str,
         created_after: Option<time::PrimitiveDateTime>,
         created_before: Option<time::PrimitiveDateTime>,
@@ -77,6 +86,7 @@ where
 
     async fn list_events_by_profile_id_initial_attempt_id(
         &self,
+        state: &KeyManagerState,
         profile_id: &str,
         initial_attempt_id: &str,
         merchant_key_store: &domain::MerchantKeyStore,
@@ -84,6 +94,7 @@ where
 
     async fn update_event_by_merchant_id_event_id(
         &self,
+        state: &KeyManagerState,
         merchant_id: &str,
         event_id: &str,
         event: domain::EventUpdate,
@@ -96,6 +107,7 @@ impl EventInterface for Store {
     #[instrument(skip_all)]
     async fn insert_event(
         &self,
+        state: &KeyManagerState,
         event: domain::Event,
         merchant_key_store: &domain::MerchantKeyStore,
     ) -> CustomResult<domain::Event, errors::StorageError> {
@@ -107,7 +119,11 @@ impl EventInterface for Store {
             .insert(&conn)
             .await
             .map_err(|error| report!(errors::StorageError::from(error)))?
-            .convert(merchant_key_store.key.get_inner())
+            .convert(
+                state,
+                merchant_key_store.key.get_inner(),
+                merchant_key_store.merchant_id.clone(),
+            )
             .await
             .change_context(errors::StorageError::DecryptionError)
     }
@@ -115,6 +131,7 @@ impl EventInterface for Store {
     #[instrument(skip_all)]
     async fn find_event_by_merchant_id_event_id(
         &self,
+        state: &KeyManagerState,
         merchant_id: &str,
         event_id: &str,
         merchant_key_store: &domain::MerchantKeyStore,
@@ -123,7 +140,11 @@ impl EventInterface for Store {
         storage::Event::find_by_merchant_id_event_id(&conn, merchant_id, event_id)
             .await
             .map_err(|error| report!(errors::StorageError::from(error)))?
-            .convert(merchant_key_store.key.get_inner())
+            .convert(
+                state,
+                merchant_key_store.key.get_inner(),
+                merchant_key_store.merchant_id.clone(),
+            )
             .await
             .change_context(errors::StorageError::DecryptionError)
     }
@@ -131,6 +152,7 @@ impl EventInterface for Store {
     #[instrument(skip_all)]
     async fn list_initial_events_by_merchant_id_primary_object_id(
         &self,
+        state: &KeyManagerState,
         merchant_id: &str,
         primary_object_id: &str,
         merchant_key_store: &domain::MerchantKeyStore,
@@ -148,7 +170,11 @@ impl EventInterface for Store {
             for event in events.into_iter() {
                 domain_events.push(
                     event
-                        .convert(merchant_key_store.key.get_inner())
+                        .convert(
+                            state,
+                            merchant_key_store.key.get_inner(),
+                            merchant_key_store.merchant_id.clone(),
+                        )
                         .await
                         .change_context(errors::StorageError::DecryptionError)?,
                 );
@@ -161,6 +187,7 @@ impl EventInterface for Store {
     #[instrument(skip_all)]
     async fn list_initial_events_by_merchant_id_constraints(
         &self,
+        state: &KeyManagerState,
         merchant_id: &str,
         created_after: Option<time::PrimitiveDateTime>,
         created_before: Option<time::PrimitiveDateTime>,
@@ -184,7 +211,11 @@ impl EventInterface for Store {
             for event in events.into_iter() {
                 domain_events.push(
                     event
-                        .convert(merchant_key_store.key.get_inner())
+                        .convert(
+                            state,
+                            merchant_key_store.key.get_inner(),
+                            merchant_key_store.merchant_id.clone(),
+                        )
                         .await
                         .change_context(errors::StorageError::DecryptionError)?,
                 );
@@ -197,6 +228,7 @@ impl EventInterface for Store {
     #[instrument(skip_all)]
     async fn list_events_by_merchant_id_initial_attempt_id(
         &self,
+        state: &KeyManagerState,
         merchant_id: &str,
         initial_attempt_id: &str,
         merchant_key_store: &domain::MerchantKeyStore,
@@ -214,7 +246,11 @@ impl EventInterface for Store {
             for event in events.into_iter() {
                 domain_events.push(
                     event
-                        .convert(merchant_key_store.key.get_inner())
+                        .convert(
+                            state,
+                            merchant_key_store.key.get_inner(),
+                            merchant_key_store.merchant_id.clone(),
+                        )
                         .await
                         .change_context(errors::StorageError::DecryptionError)?,
                 );
@@ -227,6 +263,7 @@ impl EventInterface for Store {
     #[instrument(skip_all)]
     async fn list_initial_events_by_profile_id_primary_object_id(
         &self,
+        state: &KeyManagerState,
         profile_id: &str,
         primary_object_id: &str,
         merchant_key_store: &domain::MerchantKeyStore,
@@ -244,7 +281,11 @@ impl EventInterface for Store {
             for event in events.into_iter() {
                 domain_events.push(
                     event
-                        .convert(merchant_key_store.key.get_inner())
+                        .convert(
+                            state,
+                            merchant_key_store.key.get_inner(),
+                            merchant_key_store.merchant_id.clone(),
+                        )
                         .await
                         .change_context(errors::StorageError::DecryptionError)?,
                 );
@@ -257,6 +298,7 @@ impl EventInterface for Store {
     #[instrument(skip_all)]
     async fn list_initial_events_by_profile_id_constraints(
         &self,
+        state: &KeyManagerState,
         profile_id: &str,
         created_after: Option<time::PrimitiveDateTime>,
         created_before: Option<time::PrimitiveDateTime>,
@@ -280,7 +322,11 @@ impl EventInterface for Store {
             for event in events.into_iter() {
                 domain_events.push(
                     event
-                        .convert(merchant_key_store.key.get_inner())
+                        .convert(
+                            state,
+                            merchant_key_store.key.get_inner(),
+                            merchant_key_store.merchant_id.clone(),
+                        )
                         .await
                         .change_context(errors::StorageError::DecryptionError)?,
                 );
@@ -293,6 +339,7 @@ impl EventInterface for Store {
     #[instrument(skip_all)]
     async fn list_events_by_profile_id_initial_attempt_id(
         &self,
+        state: &KeyManagerState,
         profile_id: &str,
         initial_attempt_id: &str,
         merchant_key_store: &domain::MerchantKeyStore,
@@ -306,7 +353,11 @@ impl EventInterface for Store {
                 for event in events.into_iter() {
                     domain_events.push(
                         event
-                            .convert(merchant_key_store.key.get_inner())
+                            .convert(
+                                state,
+                                merchant_key_store.key.get_inner(),
+                                merchant_key_store.merchant_id.clone(),
+                            )
                             .await
                             .change_context(errors::StorageError::DecryptionError)?,
                     );
@@ -319,6 +370,7 @@ impl EventInterface for Store {
     #[instrument(skip_all)]
     async fn update_event_by_merchant_id_event_id(
         &self,
+        state: &KeyManagerState,
         merchant_id: &str,
         event_id: &str,
         event: domain::EventUpdate,
@@ -328,7 +380,11 @@ impl EventInterface for Store {
         storage::Event::update_by_merchant_id_event_id(&conn, merchant_id, event_id, event.into())
             .await
             .map_err(|error| report!(errors::StorageError::from(error)))?
-            .convert(merchant_key_store.key.get_inner())
+            .convert(
+                state,
+                merchant_key_store.key.get_inner(),
+                merchant_key_store.merchant_id.clone(),
+            )
             .await
             .change_context(errors::StorageError::DecryptionError)
     }
@@ -338,6 +394,7 @@ impl EventInterface for Store {
 impl EventInterface for MockDb {
     async fn insert_event(
         &self,
+        state: &KeyManagerState,
         event: domain::Event,
         merchant_key_store: &domain::MerchantKeyStore,
     ) -> CustomResult<domain::Event, errors::StorageError> {
@@ -350,13 +407,18 @@ impl EventInterface for MockDb {
         locked_events.push(stored_event.clone());
 
         stored_event
-            .convert(merchant_key_store.key.get_inner())
+            .convert(
+                state,
+                merchant_key_store.key.get_inner(),
+                merchant_key_store.merchant_id.clone(),
+            )
             .await
             .change_context(errors::StorageError::DecryptionError)
     }
 
     async fn find_event_by_merchant_id_event_id(
         &self,
+        state: &KeyManagerState,
         merchant_id: &str,
         event_id: &str,
         merchant_key_store: &domain::MerchantKeyStore,
@@ -370,7 +432,11 @@ impl EventInterface for MockDb {
             .cloned()
             .async_map(|event| async {
                 event
-                    .convert(merchant_key_store.key.get_inner())
+                    .convert(
+                        state,
+                        merchant_key_store.key.get_inner(),
+                        merchant_key_store.merchant_id.clone(),
+                    )
                     .await
                     .change_context(errors::StorageError::DecryptionError)
             })
@@ -386,6 +452,7 @@ impl EventInterface for MockDb {
 
     async fn list_initial_events_by_merchant_id_primary_object_id(
         &self,
+        state: &KeyManagerState,
         merchant_id: &str,
         primary_object_id: &str,
         merchant_key_store: &domain::MerchantKeyStore,
@@ -405,7 +472,11 @@ impl EventInterface for MockDb {
 
         for event in events {
             let domain_event = event
-                .convert(merchant_key_store.key.get_inner())
+                .convert(
+                    state,
+                    merchant_key_store.key.get_inner(),
+                    merchant_key_store.merchant_id.clone(),
+                )
                 .await
                 .change_context(errors::StorageError::DecryptionError)?;
             domain_events.push(domain_event);
@@ -416,6 +487,7 @@ impl EventInterface for MockDb {
 
     async fn list_initial_events_by_merchant_id_constraints(
         &self,
+        state: &KeyManagerState,
         merchant_id: &str,
         created_after: Option<time::PrimitiveDateTime>,
         created_before: Option<time::PrimitiveDateTime>,
@@ -470,7 +542,11 @@ impl EventInterface for MockDb {
 
         for event in events {
             let domain_event = event
-                .convert(merchant_key_store.key.get_inner())
+                .convert(
+                    state,
+                    merchant_key_store.key.get_inner(),
+                    merchant_key_store.merchant_id.clone(),
+                )
                 .await
                 .change_context(errors::StorageError::DecryptionError)?;
             domain_events.push(domain_event);
@@ -481,6 +557,7 @@ impl EventInterface for MockDb {
 
     async fn list_events_by_merchant_id_initial_attempt_id(
         &self,
+        state: &KeyManagerState,
         merchant_id: &str,
         initial_attempt_id: &str,
         merchant_key_store: &domain::MerchantKeyStore,
@@ -498,7 +575,11 @@ impl EventInterface for MockDb {
 
         for event in events {
             let domain_event = event
-                .convert(merchant_key_store.key.get_inner())
+                .convert(
+                    state,
+                    merchant_key_store.key.get_inner(),
+                    merchant_key_store.merchant_id.clone(),
+                )
                 .await
                 .change_context(errors::StorageError::DecryptionError)?;
             domain_events.push(domain_event);
@@ -509,6 +590,7 @@ impl EventInterface for MockDb {
 
     async fn list_initial_events_by_profile_id_primary_object_id(
         &self,
+        state: &KeyManagerState,
         profile_id: &str,
         primary_object_id: &str,
         merchant_key_store: &domain::MerchantKeyStore,
@@ -528,7 +610,11 @@ impl EventInterface for MockDb {
 
         for event in events {
             let domain_event = event
-                .convert(merchant_key_store.key.get_inner())
+                .convert(
+                    state,
+                    merchant_key_store.key.get_inner(),
+                    merchant_key_store.merchant_id.clone(),
+                )
                 .await
                 .change_context(errors::StorageError::DecryptionError)?;
             domain_events.push(domain_event);
@@ -539,6 +625,7 @@ impl EventInterface for MockDb {
 
     async fn list_initial_events_by_profile_id_constraints(
         &self,
+        state: &KeyManagerState,
         profile_id: &str,
         created_after: Option<time::PrimitiveDateTime>,
         created_before: Option<time::PrimitiveDateTime>,
@@ -593,7 +680,11 @@ impl EventInterface for MockDb {
 
         for event in events {
             let domain_event = event
-                .convert(merchant_key_store.key.get_inner())
+                .convert(
+                    state,
+                    merchant_key_store.key.get_inner(),
+                    merchant_key_store.merchant_id.clone(),
+                )
                 .await
                 .change_context(errors::StorageError::DecryptionError)?;
             domain_events.push(domain_event);
@@ -604,6 +695,7 @@ impl EventInterface for MockDb {
 
     async fn list_events_by_profile_id_initial_attempt_id(
         &self,
+        state: &KeyManagerState,
         profile_id: &str,
         initial_attempt_id: &str,
         merchant_key_store: &domain::MerchantKeyStore,
@@ -621,7 +713,11 @@ impl EventInterface for MockDb {
 
         for event in events {
             let domain_event = event
-                .convert(merchant_key_store.key.get_inner())
+                .convert(
+                    state,
+                    merchant_key_store.key.get_inner(),
+                    merchant_key_store.merchant_id.clone(),
+                )
                 .await
                 .change_context(errors::StorageError::DecryptionError)?;
             domain_events.push(domain_event);
@@ -632,6 +728,7 @@ impl EventInterface for MockDb {
 
     async fn update_event_by_merchant_id_event_id(
         &self,
+        state: &KeyManagerState,
         merchant_id: &str,
         event_id: &str,
         event: domain::EventUpdate,
@@ -657,7 +754,11 @@ impl EventInterface for MockDb {
 
         event_to_update
             .clone()
-            .convert(merchant_key_store.key.get_inner())
+            .convert(
+                state,
+                merchant_key_store.key.get_inner(),
+                merchant_key_store.merchant_id.clone(),
+            )
             .await
             .change_context(errors::StorageError::DecryptionError)
     }
@@ -665,6 +766,9 @@ impl EventInterface for MockDb {
 
 #[cfg(test)]
 mod tests {
+    use std::sync::Arc;
+
+    use common_utils::types::keymanager::Identifier;
     use diesel_models::{enums, events::EventMetadata};
     use time::macros::datetime;
 
@@ -673,6 +777,10 @@ mod tests {
             events::EventInterface, merchant_key_store::MerchantKeyStoreInterface,
             MasterKeyInterface, MockDb,
         },
+        routes::{
+            self,
+            app::{settings::Settings, StorageImpl},
+        },
         services,
         types::domain,
     };
@@ -685,17 +793,31 @@ mod tests {
             .await
             .expect("Failed to create Mock store");
         let event_id = "test_event_id";
+        let (tx, _) = tokio::sync::oneshot::channel();
+        let app_state = Box::pin(routes::AppState::with_storage(
+            Settings::default(),
+            StorageImpl::PostgresqlTest,
+            tx,
+            Box::new(services::MockApiClient),
+        ))
+        .await;
+        let state = &Arc::new(app_state)
+            .get_session_state("public", || {})
+            .unwrap();
         let merchant_id = "merchant1";
         let business_profile_id = "profile1";
         let payment_id = "test_payment_id";
-
+        let key_manager_state = &state.into();
         let master_key = mockdb.get_master_key();
         mockdb
             .insert_merchant_key_store(
+                key_manager_state,
                 domain::MerchantKeyStore {
                     merchant_id: merchant_id.into(),
                     key: domain::types::encrypt(
+                        key_manager_state,
                         services::generate_aes256_key().unwrap().to_vec().into(),
+                        Identifier::Merchant(merchant_id.to_string()),
                         master_key,
                     )
                     .await
@@ -707,12 +829,17 @@ mod tests {
             .await
             .unwrap();
         let merchant_key_store = mockdb
-            .get_merchant_key_store_by_merchant_id(merchant_id, &master_key.to_vec().into())
+            .get_merchant_key_store_by_merchant_id(
+                key_manager_state,
+                merchant_id,
+                &master_key.to_vec().into(),
+            )
             .await
             .unwrap();
 
         let event1 = mockdb
             .insert_event(
+                key_manager_state,
                 domain::Event {
                     event_id: event_id.into(),
                     event_type: enums::EventType::PaymentSucceeded,
@@ -742,6 +869,7 @@ mod tests {
 
         let updated_event = mockdb
             .update_event_by_merchant_id_event_id(
+                key_manager_state,
                 merchant_id,
                 event_id,
                 domain::EventUpdate::UpdateResponse {
diff --git a/crates/router/src/db/kafka_store.rs b/crates/router/src/db/kafka_store.rs
index ce0821c6322..ed2357c1a1c 100644
--- a/crates/router/src/db/kafka_store.rs
+++ b/crates/router/src/db/kafka_store.rs
@@ -1,7 +1,7 @@
 use std::sync::Arc;
 
 use common_enums::enums::MerchantStorageScheme;
-use common_utils::{errors::CustomResult, id_type, pii};
+use common_utils::{errors::CustomResult, id_type, pii, types::keymanager::KeyManagerState};
 use diesel_models::{
     enums,
     enums::ProcessTrackerStatus,
@@ -102,27 +102,30 @@ impl KafkaStore {
 impl AddressInterface for KafkaStore {
     async fn find_address_by_address_id(
         &self,
+        state: &KeyManagerState,
         address_id: &str,
         key_store: &domain::MerchantKeyStore,
     ) -> CustomResult<domain::Address, errors::StorageError> {
         self.diesel_store
-            .find_address_by_address_id(address_id, key_store)
+            .find_address_by_address_id(state, address_id, key_store)
             .await
     }
 
     async fn update_address(
         &self,
+        state: &KeyManagerState,
         address_id: String,
         address: storage::AddressUpdate,
         key_store: &domain::MerchantKeyStore,
     ) -> CustomResult<domain::Address, errors::StorageError> {
         self.diesel_store
-            .update_address(address_id, address, key_store)
+            .update_address(state, address_id, address, key_store)
             .await
     }
 
     async fn update_address_for_payments(
         &self,
+        state: &KeyManagerState,
         this: domain::PaymentAddress,
         address: domain::AddressUpdate,
         payment_id: String,
@@ -130,24 +133,33 @@ impl AddressInterface for KafkaStore {
         storage_scheme: MerchantStorageScheme,
     ) -> CustomResult<domain::PaymentAddress, errors::StorageError> {
         self.diesel_store
-            .update_address_for_payments(this, address, payment_id, key_store, storage_scheme)
+            .update_address_for_payments(
+                state,
+                this,
+                address,
+                payment_id,
+                key_store,
+                storage_scheme,
+            )
             .await
     }
 
     async fn insert_address_for_payments(
         &self,
+        state: &KeyManagerState,
         payment_id: &str,
         address: domain::PaymentAddress,
         key_store: &domain::MerchantKeyStore,
         storage_scheme: MerchantStorageScheme,
     ) -> CustomResult<domain::PaymentAddress, errors::StorageError> {
         self.diesel_store
-            .insert_address_for_payments(payment_id, address, key_store, storage_scheme)
+            .insert_address_for_payments(state, payment_id, address, key_store, storage_scheme)
             .await
     }
 
     async fn find_address_by_merchant_id_payment_id_address_id(
         &self,
+        state: &KeyManagerState,
         merchant_id: &str,
         payment_id: &str,
         address_id: &str,
@@ -156,6 +168,7 @@ impl AddressInterface for KafkaStore {
     ) -> CustomResult<domain::PaymentAddress, errors::StorageError> {
         self.diesel_store
             .find_address_by_merchant_id_payment_id_address_id(
+                state,
                 merchant_id,
                 payment_id,
                 address_id,
@@ -167,23 +180,31 @@ impl AddressInterface for KafkaStore {
 
     async fn insert_address_for_customers(
         &self,
+        state: &KeyManagerState,
         address: domain::CustomerAddress,
         key_store: &domain::MerchantKeyStore,
     ) -> CustomResult<domain::Address, errors::StorageError> {
         self.diesel_store
-            .insert_address_for_customers(address, key_store)
+            .insert_address_for_customers(state, address, key_store)
             .await
     }
 
     async fn update_address_by_merchant_id_customer_id(
         &self,
+        state: &KeyManagerState,
         customer_id: &id_type::CustomerId,
         merchant_id: &str,
         address: storage::AddressUpdate,
         key_store: &domain::MerchantKeyStore,
     ) -> CustomResult<Vec<domain::Address>, errors::StorageError> {
         self.diesel_store
-            .update_address_by_merchant_id_customer_id(customer_id, merchant_id, address, key_store)
+            .update_address_by_merchant_id_customer_id(
+                state,
+                customer_id,
+                merchant_id,
+                address,
+                key_store,
+            )
             .await
     }
 }
@@ -332,6 +353,7 @@ impl CustomerInterface for KafkaStore {
 
     async fn find_customer_optional_by_customer_id_merchant_id(
         &self,
+        state: &KeyManagerState,
         customer_id: &id_type::CustomerId,
         merchant_id: &str,
         key_store: &domain::MerchantKeyStore,
@@ -339,6 +361,7 @@ impl CustomerInterface for KafkaStore {
     ) -> CustomResult<Option<domain::Customer>, errors::StorageError> {
         self.diesel_store
             .find_customer_optional_by_customer_id_merchant_id(
+                state,
                 customer_id,
                 merchant_id,
                 key_store,
@@ -349,6 +372,7 @@ impl CustomerInterface for KafkaStore {
 
     async fn update_customer_by_customer_id_merchant_id(
         &self,
+        state: &KeyManagerState,
         customer_id: id_type::CustomerId,
         merchant_id: String,
         customer: domain::Customer,
@@ -358,6 +382,7 @@ impl CustomerInterface for KafkaStore {
     ) -> CustomResult<domain::Customer, errors::StorageError> {
         self.diesel_store
             .update_customer_by_customer_id_merchant_id(
+                state,
                 customer_id,
                 merchant_id,
                 customer,
@@ -370,16 +395,18 @@ impl CustomerInterface for KafkaStore {
 
     async fn list_customers_by_merchant_id(
         &self,
+        state: &KeyManagerState,
         merchant_id: &str,
         key_store: &domain::MerchantKeyStore,
     ) -> CustomResult<Vec<domain::Customer>, errors::StorageError> {
         self.diesel_store
-            .list_customers_by_merchant_id(merchant_id, key_store)
+            .list_customers_by_merchant_id(state, merchant_id, key_store)
             .await
     }
 
     async fn find_customer_by_customer_id_merchant_id(
         &self,
+        state: &KeyManagerState,
         customer_id: &id_type::CustomerId,
         merchant_id: &str,
         key_store: &domain::MerchantKeyStore,
@@ -387,6 +414,7 @@ impl CustomerInterface for KafkaStore {
     ) -> CustomResult<domain::Customer, errors::StorageError> {
         self.diesel_store
             .find_customer_by_customer_id_merchant_id(
+                state,
                 customer_id,
                 merchant_id,
                 key_store,
@@ -397,12 +425,13 @@ impl CustomerInterface for KafkaStore {
 
     async fn insert_customer(
         &self,
+        state: &KeyManagerState,
         customer_data: domain::Customer,
         key_store: &domain::MerchantKeyStore,
         storage_scheme: MerchantStorageScheme,
     ) -> CustomResult<domain::Customer, errors::StorageError> {
         self.diesel_store
-            .insert_customer(customer_data, key_store, storage_scheme)
+            .insert_customer(state, customer_data, key_store, storage_scheme)
             .await
     }
 }
@@ -519,33 +548,37 @@ impl EphemeralKeyInterface for KafkaStore {
 impl EventInterface for KafkaStore {
     async fn insert_event(
         &self,
+        state: &KeyManagerState,
         event: domain::Event,
         merchant_key_store: &domain::MerchantKeyStore,
     ) -> CustomResult<domain::Event, errors::StorageError> {
         self.diesel_store
-            .insert_event(event, merchant_key_store)
+            .insert_event(state, event, merchant_key_store)
             .await
     }
 
     async fn find_event_by_merchant_id_event_id(
         &self,
+        state: &KeyManagerState,
         merchant_id: &str,
         event_id: &str,
         merchant_key_store: &domain::MerchantKeyStore,
     ) -> CustomResult<domain::Event, errors::StorageError> {
         self.diesel_store
-            .find_event_by_merchant_id_event_id(merchant_id, event_id, merchant_key_store)
+            .find_event_by_merchant_id_event_id(state, merchant_id, event_id, merchant_key_store)
             .await
     }
 
     async fn list_initial_events_by_merchant_id_primary_object_id(
         &self,
+        state: &KeyManagerState,
         merchant_id: &str,
         primary_object_id: &str,
         merchant_key_store: &domain::MerchantKeyStore,
     ) -> CustomResult<Vec<domain::Event>, errors::StorageError> {
         self.diesel_store
             .list_initial_events_by_merchant_id_primary_object_id(
+                state,
                 merchant_id,
                 primary_object_id,
                 merchant_key_store,
@@ -555,6 +588,7 @@ impl EventInterface for KafkaStore {
 
     async fn list_initial_events_by_merchant_id_constraints(
         &self,
+        state: &KeyManagerState,
         merchant_id: &str,
         created_after: Option<PrimitiveDateTime>,
         created_before: Option<PrimitiveDateTime>,
@@ -564,6 +598,7 @@ impl EventInterface for KafkaStore {
     ) -> CustomResult<Vec<domain::Event>, errors::StorageError> {
         self.diesel_store
             .list_initial_events_by_merchant_id_constraints(
+                state,
                 merchant_id,
                 created_after,
                 created_before,
@@ -576,12 +611,14 @@ impl EventInterface for KafkaStore {
 
     async fn list_events_by_merchant_id_initial_attempt_id(
         &self,
+        state: &KeyManagerState,
         merchant_id: &str,
         initial_attempt_id: &str,
         merchant_key_store: &domain::MerchantKeyStore,
     ) -> CustomResult<Vec<domain::Event>, errors::StorageError> {
         self.diesel_store
             .list_events_by_merchant_id_initial_attempt_id(
+                state,
                 merchant_id,
                 initial_attempt_id,
                 merchant_key_store,
@@ -591,12 +628,14 @@ impl EventInterface for KafkaStore {
 
     async fn list_initial_events_by_profile_id_primary_object_id(
         &self,
+        state: &KeyManagerState,
         profile_id: &str,
         primary_object_id: &str,
         merchant_key_store: &domain::MerchantKeyStore,
     ) -> CustomResult<Vec<domain::Event>, errors::StorageError> {
         self.diesel_store
             .list_initial_events_by_profile_id_primary_object_id(
+                state,
                 profile_id,
                 primary_object_id,
                 merchant_key_store,
@@ -606,6 +645,7 @@ impl EventInterface for KafkaStore {
 
     async fn list_initial_events_by_profile_id_constraints(
         &self,
+        state: &KeyManagerState,
         profile_id: &str,
         created_after: Option<PrimitiveDateTime>,
         created_before: Option<PrimitiveDateTime>,
@@ -615,6 +655,7 @@ impl EventInterface for KafkaStore {
     ) -> CustomResult<Vec<domain::Event>, errors::StorageError> {
         self.diesel_store
             .list_initial_events_by_profile_id_constraints(
+                state,
                 profile_id,
                 created_after,
                 created_before,
@@ -627,12 +668,14 @@ impl EventInterface for KafkaStore {
 
     async fn list_events_by_profile_id_initial_attempt_id(
         &self,
+        state: &KeyManagerState,
         profile_id: &str,
         initial_attempt_id: &str,
         merchant_key_store: &domain::MerchantKeyStore,
     ) -> CustomResult<Vec<domain::Event>, errors::StorageError> {
         self.diesel_store
             .list_events_by_profile_id_initial_attempt_id(
+                state,
                 profile_id,
                 initial_attempt_id,
                 merchant_key_store,
@@ -642,13 +685,20 @@ impl EventInterface for KafkaStore {
 
     async fn update_event_by_merchant_id_event_id(
         &self,
+        state: &KeyManagerState,
         merchant_id: &str,
         event_id: &str,
         event: domain::EventUpdate,
         merchant_key_store: &domain::MerchantKeyStore,
     ) -> CustomResult<domain::Event, errors::StorageError> {
         self.diesel_store
-            .update_event_by_merchant_id_event_id(merchant_id, event_id, event, merchant_key_store)
+            .update_event_by_merchant_id_event_id(
+                state,
+                merchant_id,
+                event_id,
+                event,
+                merchant_key_store,
+            )
             .await
     }
 }
@@ -790,43 +840,47 @@ impl PaymentLinkInterface for KafkaStore {
 impl MerchantAccountInterface for KafkaStore {
     async fn insert_merchant(
         &self,
+        state: &KeyManagerState,
         merchant_account: domain::MerchantAccount,
         key_store: &domain::MerchantKeyStore,
     ) -> CustomResult<domain::MerchantAccount, errors::StorageError> {
         self.diesel_store
-            .insert_merchant(merchant_account, key_store)
+            .insert_merchant(state, merchant_account, key_store)
             .await
     }
 
     async fn find_merchant_account_by_merchant_id(
         &self,
+        state: &KeyManagerState,
         merchant_id: &str,
         key_store: &domain::MerchantKeyStore,
     ) -> CustomResult<domain::MerchantAccount, errors::StorageError> {
         self.diesel_store
-            .find_merchant_account_by_merchant_id(merchant_id, key_store)
+            .find_merchant_account_by_merchant_id(state, merchant_id, key_store)
             .await
     }
 
     async fn update_merchant(
         &self,
+        state: &KeyManagerState,
         this: domain::MerchantAccount,
         merchant_account: storage::MerchantAccountUpdate,
         key_store: &domain::MerchantKeyStore,
     ) -> CustomResult<domain::MerchantAccount, errors::StorageError> {
         self.diesel_store
-            .update_merchant(this, merchant_account, key_store)
+            .update_merchant(state, this, merchant_account, key_store)
             .await
     }
 
     async fn update_specific_fields_in_merchant(
         &self,
+        state: &KeyManagerState,
         merchant_id: &str,
         merchant_account: storage::MerchantAccountUpdate,
         key_store: &domain::MerchantKeyStore,
     ) -> CustomResult<domain::MerchantAccount, errors::StorageError> {
         self.diesel_store
-            .update_specific_fields_in_merchant(merchant_id, merchant_account, key_store)
+            .update_specific_fields_in_merchant(state, merchant_id, merchant_account, key_store)
             .await
     }
 
@@ -841,20 +895,22 @@ impl MerchantAccountInterface for KafkaStore {
 
     async fn find_merchant_account_by_publishable_key(
         &self,
+        state: &KeyManagerState,
         publishable_key: &str,
     ) -> CustomResult<authentication::AuthenticationData, errors::StorageError> {
         self.diesel_store
-            .find_merchant_account_by_publishable_key(publishable_key)
+            .find_merchant_account_by_publishable_key(state, publishable_key)
             .await
     }
 
     #[cfg(feature = "olap")]
     async fn list_merchant_accounts_by_organization_id(
         &self,
+        state: &KeyManagerState,
         organization_id: &str,
     ) -> CustomResult<Vec<domain::MerchantAccount>, errors::StorageError> {
         self.diesel_store
-            .list_merchant_accounts_by_organization_id(organization_id)
+            .list_merchant_accounts_by_organization_id(state, organization_id)
             .await
     }
 
@@ -870,10 +926,11 @@ impl MerchantAccountInterface for KafkaStore {
     #[cfg(feature = "olap")]
     async fn list_multiple_merchant_accounts(
         &self,
+        state: &KeyManagerState,
         merchant_ids: Vec<String>,
     ) -> CustomResult<Vec<domain::MerchantAccount>, errors::StorageError> {
         self.diesel_store
-            .list_multiple_merchant_accounts(merchant_ids)
+            .list_multiple_merchant_accounts(state, merchant_ids)
             .await
     }
 }
@@ -957,12 +1014,14 @@ impl MerchantConnectorAccountInterface for KafkaStore {
     }
     async fn find_merchant_connector_account_by_merchant_id_connector_label(
         &self,
+        state: &KeyManagerState,
         merchant_id: &str,
         connector: &str,
         key_store: &domain::MerchantKeyStore,
     ) -> CustomResult<domain::MerchantConnectorAccount, errors::StorageError> {
         self.diesel_store
             .find_merchant_connector_account_by_merchant_id_connector_label(
+                state,
                 merchant_id,
                 connector,
                 key_store,
@@ -972,12 +1031,14 @@ impl MerchantConnectorAccountInterface for KafkaStore {
 
     async fn find_merchant_connector_account_by_merchant_id_connector_name(
         &self,
+        state: &KeyManagerState,
         merchant_id: &str,
         connector_name: &str,
         key_store: &domain::MerchantKeyStore,
     ) -> CustomResult<Vec<domain::MerchantConnectorAccount>, errors::StorageError> {
         self.diesel_store
             .find_merchant_connector_account_by_merchant_id_connector_name(
+                state,
                 merchant_id,
                 connector_name,
                 key_store,
@@ -987,12 +1048,14 @@ impl MerchantConnectorAccountInterface for KafkaStore {
 
     async fn find_merchant_connector_account_by_profile_id_connector_name(
         &self,
+        state: &KeyManagerState,
         profile_id: &str,
         connector_name: &str,
         key_store: &domain::MerchantKeyStore,
     ) -> CustomResult<domain::MerchantConnectorAccount, errors::StorageError> {
         self.diesel_store
             .find_merchant_connector_account_by_profile_id_connector_name(
+                state,
                 profile_id,
                 connector_name,
                 key_store,
@@ -1002,22 +1065,25 @@ impl MerchantConnectorAccountInterface for KafkaStore {
 
     async fn insert_merchant_connector_account(
         &self,
+        state: &KeyManagerState,
         t: domain::MerchantConnectorAccount,
         key_store: &domain::MerchantKeyStore,
     ) -> CustomResult<domain::MerchantConnectorAccount, errors::StorageError> {
         self.diesel_store
-            .insert_merchant_connector_account(t, key_store)
+            .insert_merchant_connector_account(state, t, key_store)
             .await
     }
 
     async fn find_by_merchant_connector_account_merchant_id_merchant_connector_id(
         &self,
+        state: &KeyManagerState,
         merchant_id: &str,
         merchant_connector_id: &str,
         key_store: &domain::MerchantKeyStore,
     ) -> CustomResult<domain::MerchantConnectorAccount, errors::StorageError> {
         self.diesel_store
             .find_by_merchant_connector_account_merchant_id_merchant_connector_id(
+                state,
                 merchant_id,
                 merchant_connector_id,
                 key_store,
@@ -1027,12 +1093,14 @@ impl MerchantConnectorAccountInterface for KafkaStore {
 
     async fn find_merchant_connector_account_by_merchant_id_and_disabled_list(
         &self,
+        state: &KeyManagerState,
         merchant_id: &str,
         get_disabled: bool,
         key_store: &domain::MerchantKeyStore,
     ) -> CustomResult<Vec<domain::MerchantConnectorAccount>, errors::StorageError> {
         self.diesel_store
             .find_merchant_connector_account_by_merchant_id_and_disabled_list(
+                state,
                 merchant_id,
                 get_disabled,
                 key_store,
@@ -1042,12 +1110,13 @@ impl MerchantConnectorAccountInterface for KafkaStore {
 
     async fn update_merchant_connector_account(
         &self,
+        state: &KeyManagerState,
         this: domain::MerchantConnectorAccount,
         merchant_connector_account: storage::MerchantConnectorAccountUpdateInternal,
         key_store: &domain::MerchantKeyStore,
     ) -> CustomResult<domain::MerchantConnectorAccount, errors::StorageError> {
         self.diesel_store
-            .update_merchant_connector_account(this, merchant_connector_account, key_store)
+            .update_merchant_connector_account(state, this, merchant_connector_account, key_store)
             .await
     }
 
@@ -1326,6 +1395,7 @@ impl PaymentAttemptInterface for KafkaStore {
 impl PaymentIntentInterface for KafkaStore {
     async fn update_payment_intent(
         &self,
+        state: &KeyManagerState,
         this: storage::PaymentIntent,
         payment_intent: storage::PaymentIntentUpdate,
         key_store: &domain::MerchantKeyStore,
@@ -1333,7 +1403,13 @@ impl PaymentIntentInterface for KafkaStore {
     ) -> CustomResult<storage::PaymentIntent, errors::DataStorageError> {
         let intent = self
             .diesel_store
-            .update_payment_intent(this.clone(), payment_intent, key_store, storage_scheme)
+            .update_payment_intent(
+                state,
+                this.clone(),
+                payment_intent,
+                key_store,
+                storage_scheme,
+            )
             .await?;
 
         if let Err(er) = self
@@ -1349,6 +1425,7 @@ impl PaymentIntentInterface for KafkaStore {
 
     async fn insert_payment_intent(
         &self,
+        state: &KeyManagerState,
         new: storage::PaymentIntent,
         key_store: &domain::MerchantKeyStore,
         storage_scheme: MerchantStorageScheme,
@@ -1356,7 +1433,7 @@ impl PaymentIntentInterface for KafkaStore {
         logger::debug!("Inserting PaymentIntent Via KafkaStore");
         let intent = self
             .diesel_store
-            .insert_payment_intent(new, key_store, storage_scheme)
+            .insert_payment_intent(state, new, key_store, storage_scheme)
             .await?;
 
         if let Err(er) = self
@@ -1372,6 +1449,7 @@ impl PaymentIntentInterface for KafkaStore {
 
     async fn find_payment_intent_by_payment_id_merchant_id(
         &self,
+        state: &KeyManagerState,
         payment_id: &str,
         merchant_id: &str,
         key_store: &domain::MerchantKeyStore,
@@ -1379,6 +1457,7 @@ impl PaymentIntentInterface for KafkaStore {
     ) -> CustomResult<storage::PaymentIntent, errors::DataStorageError> {
         self.diesel_store
             .find_payment_intent_by_payment_id_merchant_id(
+                state,
                 payment_id,
                 merchant_id,
                 key_store,
@@ -1390,19 +1469,27 @@ impl PaymentIntentInterface for KafkaStore {
     #[cfg(feature = "olap")]
     async fn filter_payment_intent_by_constraints(
         &self,
+        state: &KeyManagerState,
         merchant_id: &str,
         filters: &hyperswitch_domain_models::payments::payment_intent::PaymentIntentFetchConstraints,
         key_store: &domain::MerchantKeyStore,
         storage_scheme: MerchantStorageScheme,
     ) -> CustomResult<Vec<storage::PaymentIntent>, errors::DataStorageError> {
         self.diesel_store
-            .filter_payment_intent_by_constraints(merchant_id, filters, key_store, storage_scheme)
+            .filter_payment_intent_by_constraints(
+                state,
+                merchant_id,
+                filters,
+                key_store,
+                storage_scheme,
+            )
             .await
     }
 
     #[cfg(feature = "olap")]
     async fn filter_payment_intents_by_time_range_constraints(
         &self,
+        state: &KeyManagerState,
         merchant_id: &str,
         time_range: &api_models::payments::TimeRange,
         key_store: &domain::MerchantKeyStore,
@@ -1410,6 +1497,7 @@ impl PaymentIntentInterface for KafkaStore {
     ) -> CustomResult<Vec<storage::PaymentIntent>, errors::DataStorageError> {
         self.diesel_store
             .filter_payment_intents_by_time_range_constraints(
+                state,
                 merchant_id,
                 time_range,
                 key_store,
@@ -1421,6 +1509,7 @@ impl PaymentIntentInterface for KafkaStore {
     #[cfg(feature = "olap")]
     async fn get_filtered_payment_intents_attempt(
         &self,
+        state: &KeyManagerState,
         merchant_id: &str,
         constraints: &hyperswitch_domain_models::payments::payment_intent::PaymentIntentFetchConstraints,
         key_store: &domain::MerchantKeyStore,
@@ -1434,6 +1523,7 @@ impl PaymentIntentInterface for KafkaStore {
     > {
         self.diesel_store
             .get_filtered_payment_intents_attempt(
+                state,
                 merchant_id,
                 constraints,
                 key_store,
@@ -2059,21 +2149,23 @@ impl RefundInterface for KafkaStore {
 impl MerchantKeyStoreInterface for KafkaStore {
     async fn insert_merchant_key_store(
         &self,
+        state: &KeyManagerState,
         merchant_key_store: domain::MerchantKeyStore,
         key: &Secret<Vec<u8>>,
     ) -> CustomResult<domain::MerchantKeyStore, errors::StorageError> {
         self.diesel_store
-            .insert_merchant_key_store(merchant_key_store, key)
+            .insert_merchant_key_store(state, merchant_key_store, key)
             .await
     }
 
     async fn get_merchant_key_store_by_merchant_id(
         &self,
+        state: &KeyManagerState,
         merchant_id: &str,
         key: &Secret<Vec<u8>>,
     ) -> CustomResult<domain::MerchantKeyStore, errors::StorageError> {
         self.diesel_store
-            .get_merchant_key_store_by_merchant_id(merchant_id, key)
+            .get_merchant_key_store_by_merchant_id(state, merchant_id, key)
             .await
     }
 
@@ -2089,18 +2181,20 @@ impl MerchantKeyStoreInterface for KafkaStore {
     #[cfg(feature = "olap")]
     async fn list_multiple_key_stores(
         &self,
+        state: &KeyManagerState,
         merchant_ids: Vec<String>,
         key: &Secret<Vec<u8>>,
     ) -> CustomResult<Vec<domain::MerchantKeyStore>, errors::StorageError> {
         self.diesel_store
-            .list_multiple_key_stores(merchant_ids, key)
+            .list_multiple_key_stores(state, merchant_ids, key)
             .await
     }
     async fn get_all_key_stores(
         &self,
+        state: &KeyManagerState,
         key: &Secret<Vec<u8>>,
     ) -> CustomResult<Vec<domain::MerchantKeyStore>, errors::StorageError> {
-        self.diesel_store.get_all_key_stores(key).await
+        self.diesel_store.get_all_key_stores(state, key).await
     }
 }
 
@@ -2592,6 +2686,7 @@ impl DashboardMetadataInterface for KafkaStore {
 impl BatchSampleDataInterface for KafkaStore {
     async fn insert_payment_intents_batch_for_sample_data(
         &self,
+        state: &KeyManagerState,
         batch: Vec<hyperswitch_domain_models::payments::PaymentIntent>,
         key_store: &hyperswitch_domain_models::merchant_key_store::MerchantKeyStore,
     ) -> CustomResult<
@@ -2600,7 +2695,7 @@ impl BatchSampleDataInterface for KafkaStore {
     > {
         let payment_intents_list = self
             .diesel_store
-            .insert_payment_intents_batch_for_sample_data(batch, key_store)
+            .insert_payment_intents_batch_for_sample_data(state, batch, key_store)
             .await?;
 
         for payment_intent in payment_intents_list.iter() {
@@ -2654,6 +2749,7 @@ impl BatchSampleDataInterface for KafkaStore {
 
     async fn delete_payment_intents_for_sample_data(
         &self,
+        state: &KeyManagerState,
         merchant_id: &str,
         key_store: &hyperswitch_domain_models::merchant_key_store::MerchantKeyStore,
     ) -> CustomResult<
@@ -2662,7 +2758,7 @@ impl BatchSampleDataInterface for KafkaStore {
     > {
         let payment_intents_list = self
             .diesel_store
-            .delete_payment_intents_for_sample_data(merchant_id, key_store)
+            .delete_payment_intents_for_sample_data(state, merchant_id, key_store)
             .await?;
 
         for payment_intent in payment_intents_list.iter() {
@@ -2947,29 +3043,32 @@ impl GenericLinkInterface for KafkaStore {
 impl UserKeyStoreInterface for KafkaStore {
     async fn insert_user_key_store(
         &self,
+        state: &KeyManagerState,
         user_key_store: domain::UserKeyStore,
         key: &Secret<Vec<u8>>,
     ) -> CustomResult<domain::UserKeyStore, errors::StorageError> {
         self.diesel_store
-            .insert_user_key_store(user_key_store, key)
+            .insert_user_key_store(state, user_key_store, key)
             .await
     }
 
     async fn get_user_key_store_by_user_id(
         &self,
+        state: &KeyManagerState,
         user_id: &str,
         key: &Secret<Vec<u8>>,
     ) -> CustomResult<domain::UserKeyStore, errors::StorageError> {
         self.diesel_store
-            .get_user_key_store_by_user_id(user_id, key)
+            .get_user_key_store_by_user_id(state, user_id, key)
             .await
     }
 
     async fn get_all_user_key_store(
         &self,
+        state: &KeyManagerState,
         key: &Secret<Vec<u8>>,
     ) -> CustomResult<Vec<domain::UserKeyStore>, errors::StorageError> {
-        self.diesel_store.get_all_user_key_store(key).await
+        self.diesel_store.get_all_user_key_store(state, key).await
     }
 }
 
diff --git a/crates/router/src/db/merchant_account.rs b/crates/router/src/db/merchant_account.rs
index ff3830b2381..eadf00c872c 100644
--- a/crates/router/src/db/merchant_account.rs
+++ b/crates/router/src/db/merchant_account.rs
@@ -1,7 +1,7 @@
 #[cfg(feature = "olap")]
 use std::collections::HashMap;
 
-use common_utils::ext_traits::AsyncExt;
+use common_utils::{ext_traits::AsyncExt, types::keymanager::KeyManagerState};
 use diesel_models::MerchantAccountUpdateInternal;
 use error_stack::{report, ResultExt};
 use router_env::{instrument, tracing};
@@ -31,12 +31,14 @@ where
 {
     async fn insert_merchant(
         &self,
+        state: &KeyManagerState,
         merchant_account: domain::MerchantAccount,
         merchant_key_store: &domain::MerchantKeyStore,
     ) -> CustomResult<domain::MerchantAccount, errors::StorageError>;
 
     async fn find_merchant_account_by_merchant_id(
         &self,
+        state: &KeyManagerState,
         merchant_id: &str,
         merchant_key_store: &domain::MerchantKeyStore,
     ) -> CustomResult<domain::MerchantAccount, errors::StorageError>;
@@ -48,6 +50,7 @@ where
 
     async fn update_merchant(
         &self,
+        state: &KeyManagerState,
         this: domain::MerchantAccount,
         merchant_account: storage::MerchantAccountUpdate,
         merchant_key_store: &domain::MerchantKeyStore,
@@ -55,6 +58,7 @@ where
 
     async fn update_specific_fields_in_merchant(
         &self,
+        state: &KeyManagerState,
         merchant_id: &str,
         merchant_account: storage::MerchantAccountUpdate,
         merchant_key_store: &domain::MerchantKeyStore,
@@ -62,12 +66,14 @@ where
 
     async fn find_merchant_account_by_publishable_key(
         &self,
+        state: &KeyManagerState,
         publishable_key: &str,
     ) -> CustomResult<authentication::AuthenticationData, errors::StorageError>;
 
     #[cfg(feature = "olap")]
     async fn list_merchant_accounts_by_organization_id(
         &self,
+        state: &KeyManagerState,
         organization_id: &str,
     ) -> CustomResult<Vec<domain::MerchantAccount>, errors::StorageError>;
 
@@ -79,6 +85,7 @@ where
     #[cfg(feature = "olap")]
     async fn list_multiple_merchant_accounts(
         &self,
+        state: &KeyManagerState,
         merchant_ids: Vec<String>,
     ) -> CustomResult<Vec<domain::MerchantAccount>, errors::StorageError>;
 }
@@ -88,6 +95,7 @@ impl MerchantAccountInterface for Store {
     #[instrument(skip_all)]
     async fn insert_merchant(
         &self,
+        state: &KeyManagerState,
         merchant_account: domain::MerchantAccount,
         merchant_key_store: &domain::MerchantKeyStore,
     ) -> CustomResult<domain::MerchantAccount, errors::StorageError> {
@@ -99,7 +107,11 @@ impl MerchantAccountInterface for Store {
             .insert(&conn)
             .await
             .map_err(|error| report!(errors::StorageError::from(error)))?
-            .convert(merchant_key_store.key.get_inner())
+            .convert(
+                state,
+                merchant_key_store.key.get_inner(),
+                merchant_key_store.merchant_id.clone(),
+            )
             .await
             .change_context(errors::StorageError::DecryptionError)
     }
@@ -107,6 +119,7 @@ impl MerchantAccountInterface for Store {
     #[instrument(skip_all)]
     async fn find_merchant_account_by_merchant_id(
         &self,
+        state: &KeyManagerState,
         merchant_id: &str,
         merchant_key_store: &domain::MerchantKeyStore,
     ) -> CustomResult<domain::MerchantAccount, errors::StorageError> {
@@ -121,7 +134,11 @@ impl MerchantAccountInterface for Store {
         {
             fetch_func()
                 .await?
-                .convert(merchant_key_store.key.get_inner())
+                .convert(
+                    state,
+                    merchant_key_store.key.get_inner(),
+                    merchant_id.to_string(),
+                )
                 .await
                 .change_context(errors::StorageError::DecryptionError)
         }
@@ -130,7 +147,11 @@ impl MerchantAccountInterface for Store {
         {
             cache::get_or_populate_in_memory(self, merchant_id, fetch_func, &ACCOUNTS_CACHE)
                 .await?
-                .convert(merchant_key_store.key.get_inner())
+                .convert(
+                    state,
+                    merchant_key_store.key.get_inner(),
+                    merchant_key_store.merchant_id.clone(),
+                )
                 .await
                 .change_context(errors::StorageError::DecryptionError)
         }
@@ -139,6 +160,7 @@ impl MerchantAccountInterface for Store {
     #[instrument(skip_all)]
     async fn update_merchant(
         &self,
+        state: &KeyManagerState,
         this: domain::MerchantAccount,
         merchant_account: storage::MerchantAccountUpdate,
         merchant_key_store: &domain::MerchantKeyStore,
@@ -157,7 +179,11 @@ impl MerchantAccountInterface for Store {
             publish_and_redact_merchant_account_cache(self, &updated_merchant_account).await?;
         }
         updated_merchant_account
-            .convert(merchant_key_store.key.get_inner())
+            .convert(
+                state,
+                merchant_key_store.key.get_inner(),
+                merchant_key_store.merchant_id.clone(),
+            )
             .await
             .change_context(errors::StorageError::DecryptionError)
     }
@@ -165,6 +191,7 @@ impl MerchantAccountInterface for Store {
     #[instrument(skip_all)]
     async fn update_specific_fields_in_merchant(
         &self,
+        state: &KeyManagerState,
         merchant_id: &str,
         merchant_account: storage::MerchantAccountUpdate,
         merchant_key_store: &domain::MerchantKeyStore,
@@ -183,7 +210,11 @@ impl MerchantAccountInterface for Store {
             publish_and_redact_merchant_account_cache(self, &updated_merchant_account).await?;
         }
         updated_merchant_account
-            .convert(merchant_key_store.key.get_inner())
+            .convert(
+                state,
+                merchant_key_store.key.get_inner(),
+                merchant_key_store.merchant_id.clone(),
+            )
             .await
             .change_context(errors::StorageError::DecryptionError)
     }
@@ -191,6 +222,7 @@ impl MerchantAccountInterface for Store {
     #[instrument(skip_all)]
     async fn find_merchant_account_by_publishable_key(
         &self,
+        state: &KeyManagerState,
         publishable_key: &str,
     ) -> CustomResult<authentication::AuthenticationData, errors::StorageError> {
         let fetch_by_pub_key_func = || async {
@@ -219,6 +251,7 @@ impl MerchantAccountInterface for Store {
         }
         let key_store = self
             .get_merchant_key_store_by_merchant_id(
+                state,
                 &merchant_account.merchant_id,
                 &self.get_master_key().to_vec().into(),
             )
@@ -226,7 +259,11 @@ impl MerchantAccountInterface for Store {
 
         Ok(authentication::AuthenticationData {
             merchant_account: merchant_account
-                .convert(key_store.key.get_inner())
+                .convert(
+                    state,
+                    key_store.key.get_inner(),
+                    key_store.merchant_id.clone(),
+                )
                 .await
                 .change_context(errors::StorageError::DecryptionError)?,
 
@@ -238,6 +275,7 @@ impl MerchantAccountInterface for Store {
     #[instrument(skip_all)]
     async fn list_merchant_accounts_by_organization_id(
         &self,
+        state: &KeyManagerState,
         organization_id: &str,
     ) -> CustomResult<Vec<domain::MerchantAccount>, errors::StorageError> {
         use futures::future::try_join_all;
@@ -253,6 +291,7 @@ impl MerchantAccountInterface for Store {
         let merchant_key_stores =
             try_join_all(encrypted_merchant_accounts.iter().map(|merchant_account| {
                 self.get_merchant_key_store_by_merchant_id(
+                    state,
                     &merchant_account.merchant_id,
                     &db_master_key,
                 )
@@ -265,7 +304,11 @@ impl MerchantAccountInterface for Store {
                 .zip(merchant_key_stores.iter())
                 .map(|(merchant_account, key_store)| async {
                     merchant_account
-                        .convert(key_store.key.get_inner())
+                        .convert(
+                            state,
+                            key_store.key.get_inner(),
+                            key_store.merchant_id.clone(),
+                        )
                         .await
                         .change_context(errors::StorageError::DecryptionError)
                 }),
@@ -314,6 +357,7 @@ impl MerchantAccountInterface for Store {
     #[instrument(skip_all)]
     async fn list_multiple_merchant_accounts(
         &self,
+        state: &KeyManagerState,
         merchant_ids: Vec<String>,
     ) -> CustomResult<Vec<domain::MerchantAccount>, errors::StorageError> {
         let conn = connection::pg_connection_read(self).await?;
@@ -327,6 +371,7 @@ impl MerchantAccountInterface for Store {
 
         let merchant_key_stores = self
             .list_multiple_key_stores(
+                state,
                 encrypted_merchant_accounts
                     .iter()
                     .map(|merchant_account| &merchant_account.merchant_id)
@@ -351,7 +396,11 @@ impl MerchantAccountInterface for Store {
                         )),
                     )?;
                     merchant_account
-                        .convert(key_store.key.get_inner())
+                        .convert(
+                            state,
+                            key_store.key.get_inner(),
+                            key_store.merchant_id.clone(),
+                        )
                         .await
                         .change_context(errors::StorageError::DecryptionError)
                 },
@@ -399,6 +448,7 @@ impl MerchantAccountInterface for MockDb {
     #[allow(clippy::panic)]
     async fn insert_merchant(
         &self,
+        state: &KeyManagerState,
         mut merchant_account: domain::MerchantAccount,
         merchant_key_store: &domain::MerchantKeyStore,
     ) -> CustomResult<domain::MerchantAccount, errors::StorageError> {
@@ -412,7 +462,11 @@ impl MerchantAccountInterface for MockDb {
         accounts.push(account.clone());
 
         account
-            .convert(merchant_key_store.key.get_inner())
+            .convert(
+                state,
+                merchant_key_store.key.get_inner(),
+                merchant_key_store.merchant_id.clone(),
+            )
             .await
             .change_context(errors::StorageError::DecryptionError)
     }
@@ -420,6 +474,7 @@ impl MerchantAccountInterface for MockDb {
     #[allow(clippy::panic)]
     async fn find_merchant_account_by_merchant_id(
         &self,
+        state: &KeyManagerState,
         merchant_id: &str,
         merchant_key_store: &domain::MerchantKeyStore,
     ) -> CustomResult<domain::MerchantAccount, errors::StorageError> {
@@ -429,9 +484,13 @@ impl MerchantAccountInterface for MockDb {
             .find(|account| account.merchant_id == merchant_id)
             .cloned()
             .async_map(|a| async {
-                a.convert(merchant_key_store.key.get_inner())
-                    .await
-                    .change_context(errors::StorageError::DecryptionError)
+                a.convert(
+                    state,
+                    merchant_key_store.key.get_inner(),
+                    merchant_key_store.merchant_id.clone(),
+                )
+                .await
+                .change_context(errors::StorageError::DecryptionError)
             })
             .await
             .transpose()?;
@@ -445,6 +504,7 @@ impl MerchantAccountInterface for MockDb {
 
     async fn update_merchant(
         &self,
+        _state: &KeyManagerState,
         _this: domain::MerchantAccount,
         _merchant_account: storage::MerchantAccountUpdate,
         _merchant_key_store: &domain::MerchantKeyStore,
@@ -455,6 +515,7 @@ impl MerchantAccountInterface for MockDb {
 
     async fn update_specific_fields_in_merchant(
         &self,
+        _state: &KeyManagerState,
         _merchant_id: &str,
         _merchant_account: storage::MerchantAccountUpdate,
         _merchant_key_store: &domain::MerchantKeyStore,
@@ -465,6 +526,7 @@ impl MerchantAccountInterface for MockDb {
 
     async fn find_merchant_account_by_publishable_key(
         &self,
+        _state: &KeyManagerState,
         _publishable_key: &str,
     ) -> CustomResult<authentication::AuthenticationData, errors::StorageError> {
         // [#172]: Implement function for `MockDb`
@@ -489,6 +551,7 @@ impl MerchantAccountInterface for MockDb {
     #[cfg(feature = "olap")]
     async fn list_merchant_accounts_by_organization_id(
         &self,
+        _state: &KeyManagerState,
         _organization_id: &str,
     ) -> CustomResult<Vec<domain::MerchantAccount>, errors::StorageError> {
         Err(errors::StorageError::MockDbError)?
@@ -497,6 +560,7 @@ impl MerchantAccountInterface for MockDb {
     #[cfg(feature = "olap")]
     async fn list_multiple_merchant_accounts(
         &self,
+        _state: &KeyManagerState,
         _merchant_ids: Vec<String>,
     ) -> CustomResult<Vec<domain::MerchantAccount>, errors::StorageError> {
         Err(errors::StorageError::MockDbError)?
diff --git a/crates/router/src/db/merchant_connector_account.rs b/crates/router/src/db/merchant_connector_account.rs
index b9becb90dca..078980f9184 100644
--- a/crates/router/src/db/merchant_connector_account.rs
+++ b/crates/router/src/db/merchant_connector_account.rs
@@ -1,6 +1,9 @@
 use async_bb8_diesel::AsyncConnection;
-use common_utils::ext_traits::{AsyncExt, ByteSliceExt, Encode};
-use diesel_models::encryption::Encryption;
+use common_utils::{
+    encryption::Encryption,
+    ext_traits::{AsyncExt, ByteSliceExt, Encode},
+    types::keymanager::KeyManagerState,
+};
 use error_stack::{report, ResultExt};
 use router_env::{instrument, tracing};
 #[cfg(feature = "accounts_cache")]
@@ -121,6 +124,7 @@ where
 {
     async fn find_merchant_connector_account_by_merchant_id_connector_label(
         &self,
+        state: &KeyManagerState,
         merchant_id: &str,
         connector_label: &str,
         key_store: &domain::MerchantKeyStore,
@@ -128,6 +132,7 @@ where
 
     async fn find_merchant_connector_account_by_profile_id_connector_name(
         &self,
+        state: &KeyManagerState,
         profile_id: &str,
         connector_name: &str,
         key_store: &domain::MerchantKeyStore,
@@ -135,6 +140,7 @@ where
 
     async fn find_merchant_connector_account_by_merchant_id_connector_name(
         &self,
+        state: &KeyManagerState,
         merchant_id: &str,
         connector_name: &str,
         key_store: &domain::MerchantKeyStore,
@@ -142,12 +148,14 @@ where
 
     async fn insert_merchant_connector_account(
         &self,
+        state: &KeyManagerState,
         t: domain::MerchantConnectorAccount,
         key_store: &domain::MerchantKeyStore,
     ) -> CustomResult<domain::MerchantConnectorAccount, errors::StorageError>;
 
     async fn find_by_merchant_connector_account_merchant_id_merchant_connector_id(
         &self,
+        state: &KeyManagerState,
         merchant_id: &str,
         merchant_connector_id: &str,
         key_store: &domain::MerchantKeyStore,
@@ -155,6 +163,7 @@ where
 
     async fn find_merchant_connector_account_by_merchant_id_and_disabled_list(
         &self,
+        state: &KeyManagerState,
         merchant_id: &str,
         get_disabled: bool,
         key_store: &domain::MerchantKeyStore,
@@ -162,6 +171,7 @@ where
 
     async fn update_merchant_connector_account(
         &self,
+        state: &KeyManagerState,
         this: domain::MerchantConnectorAccount,
         merchant_connector_account: storage::MerchantConnectorAccountUpdateInternal,
         key_store: &domain::MerchantKeyStore,
@@ -187,6 +197,7 @@ impl MerchantConnectorAccountInterface for Store {
     #[instrument(skip_all)]
     async fn find_merchant_connector_account_by_merchant_id_connector_label(
         &self,
+        state: &KeyManagerState,
         merchant_id: &str,
         connector_label: &str,
         key_store: &domain::MerchantKeyStore,
@@ -206,7 +217,7 @@ impl MerchantConnectorAccountInterface for Store {
         {
             find_call()
                 .await?
-                .convert(key_store.key.get_inner())
+                .convert(state, key_store.key.get_inner(), merchant_id.to_string())
                 .await
                 .change_context(errors::StorageError::DeserializationFailed)
         }
@@ -221,9 +232,13 @@ impl MerchantConnectorAccountInterface for Store {
             )
             .await
             .async_and_then(|item| async {
-                item.convert(key_store.key.get_inner())
-                    .await
-                    .change_context(errors::StorageError::DecryptionError)
+                item.convert(
+                    state,
+                    key_store.key.get_inner(),
+                    key_store.merchant_id.clone(),
+                )
+                .await
+                .change_context(errors::StorageError::DecryptionError)
             })
             .await
         }
@@ -232,6 +247,7 @@ impl MerchantConnectorAccountInterface for Store {
     #[instrument(skip_all)]
     async fn find_merchant_connector_account_by_profile_id_connector_name(
         &self,
+        state: &KeyManagerState,
         profile_id: &str,
         connector_name: &str,
         key_store: &domain::MerchantKeyStore,
@@ -251,7 +267,11 @@ impl MerchantConnectorAccountInterface for Store {
         {
             find_call()
                 .await?
-                .convert(key_store.key.get_inner())
+                .convert(
+                    state,
+                    key_store.key.get_inner(),
+                    key_store.merchant_id.clone(),
+                )
                 .await
                 .change_context(errors::StorageError::DeserializationFailed)
         }
@@ -266,9 +286,13 @@ impl MerchantConnectorAccountInterface for Store {
             )
             .await
             .async_and_then(|item| async {
-                item.convert(key_store.key.get_inner())
-                    .await
-                    .change_context(errors::StorageError::DecryptionError)
+                item.convert(
+                    state,
+                    key_store.key.get_inner(),
+                    key_store.merchant_id.clone(),
+                )
+                .await
+                .change_context(errors::StorageError::DecryptionError)
             })
             .await
         }
@@ -277,6 +301,7 @@ impl MerchantConnectorAccountInterface for Store {
     #[instrument(skip_all)]
     async fn find_merchant_connector_account_by_merchant_id_connector_name(
         &self,
+        state: &KeyManagerState,
         merchant_id: &str,
         connector_name: &str,
         key_store: &domain::MerchantKeyStore,
@@ -293,9 +318,13 @@ impl MerchantConnectorAccountInterface for Store {
             let mut output = Vec::with_capacity(items.len());
             for item in items.into_iter() {
                 output.push(
-                    item.convert(key_store.key.get_inner())
-                        .await
-                        .change_context(errors::StorageError::DecryptionError)?,
+                    item.convert(
+                        state,
+                        key_store.key.get_inner(),
+                        key_store.merchant_id.clone(),
+                    )
+                    .await
+                    .change_context(errors::StorageError::DecryptionError)?,
                 )
             }
             Ok(output)
@@ -306,6 +335,7 @@ impl MerchantConnectorAccountInterface for Store {
     #[instrument(skip_all)]
     async fn find_by_merchant_connector_account_merchant_id_merchant_connector_id(
         &self,
+        state: &KeyManagerState,
         merchant_id: &str,
         merchant_connector_id: &str,
         key_store: &domain::MerchantKeyStore,
@@ -325,7 +355,11 @@ impl MerchantConnectorAccountInterface for Store {
         {
             find_call()
                 .await?
-                .convert(key_store.key.get_inner())
+                .convert(
+                    state,
+                    key_store.key.get_inner(),
+                    key_store.merchant_id.clone(),
+                )
                 .await
                 .change_context(errors::StorageError::DecryptionError)
         }
@@ -339,7 +373,11 @@ impl MerchantConnectorAccountInterface for Store {
                 &cache::ACCOUNTS_CACHE,
             )
             .await?
-            .convert(key_store.key.get_inner())
+            .convert(
+                state,
+                key_store.key.get_inner(),
+                key_store.merchant_id.clone(),
+            )
             .await
             .change_context(errors::StorageError::DecryptionError)
         }
@@ -348,6 +386,7 @@ impl MerchantConnectorAccountInterface for Store {
     #[instrument(skip_all)]
     async fn insert_merchant_connector_account(
         &self,
+        state: &KeyManagerState,
         t: domain::MerchantConnectorAccount,
         key_store: &domain::MerchantKeyStore,
     ) -> CustomResult<domain::MerchantConnectorAccount, errors::StorageError> {
@@ -359,9 +398,13 @@ impl MerchantConnectorAccountInterface for Store {
             .await
             .map_err(|error| report!(errors::StorageError::from(error)))
             .async_and_then(|item| async {
-                item.convert(key_store.key.get_inner())
-                    .await
-                    .change_context(errors::StorageError::DecryptionError)
+                item.convert(
+                    state,
+                    key_store.key.get_inner(),
+                    key_store.merchant_id.clone(),
+                )
+                .await
+                .change_context(errors::StorageError::DecryptionError)
             })
             .await
     }
@@ -369,6 +412,7 @@ impl MerchantConnectorAccountInterface for Store {
     #[instrument(skip_all)]
     async fn find_merchant_connector_account_by_merchant_id_and_disabled_list(
         &self,
+        state: &KeyManagerState,
         merchant_id: &str,
         get_disabled: bool,
         key_store: &domain::MerchantKeyStore,
@@ -381,9 +425,13 @@ impl MerchantConnectorAccountInterface for Store {
                 let mut output = Vec::with_capacity(items.len());
                 for item in items.into_iter() {
                     output.push(
-                        item.convert(key_store.key.get_inner())
-                            .await
-                            .change_context(errors::StorageError::DecryptionError)?,
+                        item.convert(
+                            state,
+                            key_store.key.get_inner(),
+                            key_store.merchant_id.clone(),
+                        )
+                        .await
+                        .change_context(errors::StorageError::DecryptionError)?,
                     )
                 }
                 Ok(output)
@@ -492,6 +540,7 @@ impl MerchantConnectorAccountInterface for Store {
     #[instrument(skip_all)]
     async fn update_merchant_connector_account(
         &self,
+        state: &KeyManagerState,
         this: domain::MerchantConnectorAccount,
         merchant_connector_account: storage::MerchantConnectorAccountUpdateInternal,
         key_store: &domain::MerchantKeyStore,
@@ -516,9 +565,13 @@ impl MerchantConnectorAccountInterface for Store {
                 .await
                 .map_err(|error| report!(errors::StorageError::from(error)))
                 .async_and_then(|item| async {
-                    item.convert(key_store.key.get_inner())
-                        .await
-                        .change_context(errors::StorageError::DecryptionError)
+                    item.convert(
+                        state,
+                        key_store.key.get_inner(),
+                        key_store.merchant_id.clone(),
+                    )
+                    .await
+                    .change_context(errors::StorageError::DecryptionError)
                 })
                 .await
         };
@@ -629,6 +682,7 @@ impl MerchantConnectorAccountInterface for MockDb {
     }
     async fn find_merchant_connector_account_by_merchant_id_connector_label(
         &self,
+        state: &KeyManagerState,
         merchant_id: &str,
         connector: &str,
         key_store: &domain::MerchantKeyStore,
@@ -645,7 +699,11 @@ impl MerchantConnectorAccountInterface for MockDb {
             .cloned()
             .async_map(|account| async {
                 account
-                    .convert(key_store.key.get_inner())
+                    .convert(
+                        state,
+                        key_store.key.get_inner(),
+                        key_store.merchant_id.clone(),
+                    )
                     .await
                     .change_context(errors::StorageError::DecryptionError)
             })
@@ -663,6 +721,7 @@ impl MerchantConnectorAccountInterface for MockDb {
 
     async fn find_merchant_connector_account_by_merchant_id_connector_name(
         &self,
+        state: &KeyManagerState,
         merchant_id: &str,
         connector_name: &str,
         key_store: &domain::MerchantKeyStore,
@@ -681,7 +740,11 @@ impl MerchantConnectorAccountInterface for MockDb {
         for account in accounts.into_iter() {
             output.push(
                 account
-                    .convert(key_store.key.get_inner())
+                    .convert(
+                        state,
+                        key_store.key.get_inner(),
+                        key_store.merchant_id.clone(),
+                    )
                     .await
                     .change_context(errors::StorageError::DecryptionError)?,
             )
@@ -691,6 +754,7 @@ impl MerchantConnectorAccountInterface for MockDb {
 
     async fn find_merchant_connector_account_by_profile_id_connector_name(
         &self,
+        state: &KeyManagerState,
         profile_id: &str,
         connector_name: &str,
         key_store: &domain::MerchantKeyStore,
@@ -709,7 +773,11 @@ impl MerchantConnectorAccountInterface for MockDb {
         match maybe_mca {
             Some(mca) => mca
                 .to_owned()
-                .convert(key_store.key.get_inner())
+                .convert(
+                    state,
+                    key_store.key.get_inner(),
+                    key_store.merchant_id.clone(),
+                )
                 .await
                 .change_context(errors::StorageError::DecryptionError),
             None => Err(errors::StorageError::ValueNotFound(
@@ -721,6 +789,7 @@ impl MerchantConnectorAccountInterface for MockDb {
 
     async fn find_by_merchant_connector_account_merchant_id_merchant_connector_id(
         &self,
+        state: &KeyManagerState,
         merchant_id: &str,
         merchant_connector_id: &str,
         key_store: &domain::MerchantKeyStore,
@@ -737,7 +806,11 @@ impl MerchantConnectorAccountInterface for MockDb {
             .cloned()
             .async_map(|account| async {
                 account
-                    .convert(key_store.key.get_inner())
+                    .convert(
+                        state,
+                        key_store.key.get_inner(),
+                        key_store.merchant_id.clone(),
+                    )
                     .await
                     .change_context(errors::StorageError::DecryptionError)
             })
@@ -755,6 +828,7 @@ impl MerchantConnectorAccountInterface for MockDb {
 
     async fn insert_merchant_connector_account(
         &self,
+        state: &KeyManagerState,
         t: domain::MerchantConnectorAccount,
         key_store: &domain::MerchantKeyStore,
     ) -> CustomResult<domain::MerchantConnectorAccount, errors::StorageError> {
@@ -788,13 +862,18 @@ impl MerchantConnectorAccountInterface for MockDb {
         };
         accounts.push(account.clone());
         account
-            .convert(key_store.key.get_inner())
+            .convert(
+                state,
+                key_store.key.get_inner(),
+                key_store.merchant_id.clone(),
+            )
             .await
             .change_context(errors::StorageError::DecryptionError)
     }
 
     async fn find_merchant_connector_account_by_merchant_id_and_disabled_list(
         &self,
+        state: &KeyManagerState,
         merchant_id: &str,
         get_disabled: bool,
         key_store: &domain::MerchantKeyStore,
@@ -818,7 +897,11 @@ impl MerchantConnectorAccountInterface for MockDb {
         for account in accounts.into_iter() {
             output.push(
                 account
-                    .convert(key_store.key.get_inner())
+                    .convert(
+                        state,
+                        key_store.key.get_inner(),
+                        key_store.merchant_id.clone(),
+                    )
                     .await
                     .change_context(errors::StorageError::DecryptionError)?,
             )
@@ -828,6 +911,7 @@ impl MerchantConnectorAccountInterface for MockDb {
 
     async fn update_merchant_connector_account(
         &self,
+        state: &KeyManagerState,
         this: domain::MerchantConnectorAccount,
         merchant_connector_account: storage::MerchantConnectorAccountUpdateInternal,
         key_store: &domain::MerchantKeyStore,
@@ -846,7 +930,11 @@ impl MerchantConnectorAccountInterface for MockDb {
             })
             .async_map(|account| async {
                 account
-                    .convert(key_store.key.get_inner())
+                    .convert(
+                        state,
+                        key_store.key.get_inner(),
+                        key_store.merchant_id.clone(),
+                    )
                     .await
                     .change_context(errors::StorageError::DecryptionError)
             })
@@ -890,8 +978,10 @@ impl MerchantConnectorAccountInterface for MockDb {
 #[cfg(feature = "accounts_cache")]
 #[cfg(test)]
 mod merchant_connector_account_cache_tests {
+    use std::sync::Arc;
+
     use api_models::enums::CountryAlpha2;
-    use common_utils::date_time;
+    use common_utils::{date_time, types::keymanager::Identifier};
     use diesel_models::enums::ConnectorType;
     use error_stack::ResultExt;
     use masking::PeekInterface;
@@ -901,6 +991,7 @@ mod merchant_connector_account_cache_tests {
         pub_sub::PubSubInterface,
     };
     use time::macros::datetime;
+    use tokio::sync::oneshot;
 
     use crate::{
         core::errors,
@@ -908,6 +999,10 @@ mod merchant_connector_account_cache_tests {
             merchant_connector_account::MerchantConnectorAccountInterface,
             merchant_key_store::MerchantKeyStoreInterface, MasterKeyInterface, MockDb,
         },
+        routes::{
+            self,
+            app::{settings::Settings, StorageImpl},
+        },
         services,
         types::{
             domain::{self, behaviour::Conversion},
@@ -918,6 +1013,19 @@ mod merchant_connector_account_cache_tests {
     #[allow(clippy::unwrap_used)]
     #[tokio::test]
     async fn test_connector_profile_id_cache() {
+        let conf = Settings::new().unwrap();
+        let tx: oneshot::Sender<()> = oneshot::channel().0;
+
+        let app_state = Box::pin(routes::AppState::with_storage(
+            conf,
+            StorageImpl::PostgresqlTest,
+            tx,
+            Box::new(services::MockApiClient),
+        ))
+        .await;
+        let state = &Arc::new(app_state)
+            .get_session_state("public", || {})
+            .unwrap();
         #[allow(clippy::expect_used)]
         let db = MockDb::new(&redis_interface::RedisSettings::default())
             .await
@@ -934,12 +1042,15 @@ mod merchant_connector_account_cache_tests {
         let connector_label = "stripe_USA";
         let merchant_connector_id = "simple_merchant_connector_id";
         let profile_id = "pro_max_ultra";
-
+        let key_manager_state = &state.into();
         db.insert_merchant_key_store(
+            key_manager_state,
             domain::MerchantKeyStore {
                 merchant_id: merchant_id.into(),
                 key: domain::types::encrypt(
+                    key_manager_state,
                     services::generate_aes256_key().unwrap().to_vec().into(),
+                    Identifier::Merchant(merchant_id.to_string()),
                     master_key,
                 )
                 .await
@@ -952,7 +1063,11 @@ mod merchant_connector_account_cache_tests {
         .unwrap();
 
         let merchant_key = db
-            .get_merchant_key_store_by_merchant_id(merchant_id, &master_key.to_vec().into())
+            .get_merchant_key_store_by_merchant_id(
+                key_manager_state,
+                merchant_id,
+                &master_key.to_vec().into(),
+            )
             .await
             .unwrap();
 
@@ -961,7 +1076,9 @@ mod merchant_connector_account_cache_tests {
             merchant_id: merchant_id.to_string(),
             connector_name: "stripe".to_string(),
             connector_account_details: domain::types::encrypt(
+                key_manager_state,
                 serde_json::Value::default().into(),
+                Identifier::Merchant(merchant_key.merchant_id.clone()),
                 merchant_key.key.get_inner().peek(),
             )
             .await
@@ -986,7 +1103,9 @@ mod merchant_connector_account_cache_tests {
             status: common_enums::ConnectorStatus::Inactive,
             connector_wallets_details: Some(
                 domain::types::encrypt(
+                    key_manager_state,
                     serde_json::Value::default().into(),
+                    Identifier::Merchant(merchant_key.merchant_id.clone()),
                     merchant_key.key.get_inner().peek(),
                 )
                 .await
@@ -995,13 +1114,14 @@ mod merchant_connector_account_cache_tests {
             additional_merchant_data: None,
         };
 
-        db.insert_merchant_connector_account(mca.clone(), &merchant_key)
+        db.insert_merchant_connector_account(key_manager_state, mca.clone(), &merchant_key)
             .await
             .unwrap();
 
         let find_call = || async {
             Conversion::convert(
                 db.find_merchant_connector_account_by_profile_id_connector_name(
+                    key_manager_state,
                     profile_id,
                     &mca.connector_name,
                     &merchant_key,
diff --git a/crates/router/src/db/merchant_key_store.rs b/crates/router/src/db/merchant_key_store.rs
index 42a862e2d3d..1cc12796bc6 100644
--- a/crates/router/src/db/merchant_key_store.rs
+++ b/crates/router/src/db/merchant_key_store.rs
@@ -1,3 +1,4 @@
+use common_utils::types::keymanager::KeyManagerState;
 use error_stack::{report, ResultExt};
 use masking::Secret;
 use router_env::{instrument, tracing};
@@ -19,12 +20,14 @@ use crate::{
 pub trait MerchantKeyStoreInterface {
     async fn insert_merchant_key_store(
         &self,
+        state: &KeyManagerState,
         merchant_key_store: domain::MerchantKeyStore,
         key: &Secret<Vec<u8>>,
     ) -> CustomResult<domain::MerchantKeyStore, errors::StorageError>;
 
     async fn get_merchant_key_store_by_merchant_id(
         &self,
+        state: &KeyManagerState,
         merchant_id: &str,
         key: &Secret<Vec<u8>>,
     ) -> CustomResult<domain::MerchantKeyStore, errors::StorageError>;
@@ -37,12 +40,14 @@ pub trait MerchantKeyStoreInterface {
     #[cfg(feature = "olap")]
     async fn list_multiple_key_stores(
         &self,
+        state: &KeyManagerState,
         merchant_ids: Vec<String>,
         key: &Secret<Vec<u8>>,
     ) -> CustomResult<Vec<domain::MerchantKeyStore>, errors::StorageError>;
 
     async fn get_all_key_stores(
         &self,
+        state: &KeyManagerState,
         key: &Secret<Vec<u8>>,
     ) -> CustomResult<Vec<domain::MerchantKeyStore>, errors::StorageError>;
 }
@@ -52,10 +57,12 @@ impl MerchantKeyStoreInterface for Store {
     #[instrument(skip_all)]
     async fn insert_merchant_key_store(
         &self,
+        state: &KeyManagerState,
         merchant_key_store: domain::MerchantKeyStore,
         key: &Secret<Vec<u8>>,
     ) -> CustomResult<domain::MerchantKeyStore, errors::StorageError> {
         let conn = connection::pg_connection_write(self).await?;
+        let merchant_id = merchant_key_store.merchant_id.clone();
         merchant_key_store
             .construct_new()
             .await
@@ -63,7 +70,7 @@ impl MerchantKeyStoreInterface for Store {
             .insert(&conn)
             .await
             .map_err(|error| report!(errors::StorageError::from(error)))?
-            .convert(key)
+            .convert(state, key, merchant_id)
             .await
             .change_context(errors::StorageError::DecryptionError)
     }
@@ -71,6 +78,7 @@ impl MerchantKeyStoreInterface for Store {
     #[instrument(skip_all)]
     async fn get_merchant_key_store_by_merchant_id(
         &self,
+        state: &KeyManagerState,
         merchant_id: &str,
         key: &Secret<Vec<u8>>,
     ) -> CustomResult<domain::MerchantKeyStore, errors::StorageError> {
@@ -89,7 +97,7 @@ impl MerchantKeyStoreInterface for Store {
         {
             fetch_func()
                 .await?
-                .convert(key)
+                .convert(state, key, merchant_id.to_string())
                 .await
                 .change_context(errors::StorageError::DecryptionError)
         }
@@ -104,7 +112,7 @@ impl MerchantKeyStoreInterface for Store {
                 &ACCOUNTS_CACHE,
             )
             .await?
-            .convert(key)
+            .convert(state, key, merchant_id.to_string())
             .await
             .change_context(errors::StorageError::DecryptionError)
         }
@@ -146,6 +154,7 @@ impl MerchantKeyStoreInterface for Store {
     #[instrument(skip_all)]
     async fn list_multiple_key_stores(
         &self,
+        state: &KeyManagerState,
         merchant_ids: Vec<String>,
         key: &Secret<Vec<u8>>,
     ) -> CustomResult<Vec<domain::MerchantKeyStore>, errors::StorageError> {
@@ -161,8 +170,9 @@ impl MerchantKeyStoreInterface for Store {
         };
 
         futures::future::try_join_all(fetch_func().await?.into_iter().map(|key_store| async {
+            let merchant_id = key_store.merchant_id.clone();
             key_store
-                .convert(key)
+                .convert(state, key, merchant_id)
                 .await
                 .change_context(errors::StorageError::DecryptionError)
         }))
@@ -171,6 +181,7 @@ impl MerchantKeyStoreInterface for Store {
 
     async fn get_all_key_stores(
         &self,
+        state: &KeyManagerState,
         key: &Secret<Vec<u8>>,
     ) -> CustomResult<Vec<domain::MerchantKeyStore>, errors::StorageError> {
         let conn = connection::pg_connection_read(self).await?;
@@ -181,8 +192,9 @@ impl MerchantKeyStoreInterface for Store {
         };
 
         futures::future::try_join_all(fetch_func().await?.into_iter().map(|key_store| async {
+            let merchant_id = key_store.merchant_id.clone();
             key_store
-                .convert(key)
+                .convert(state, key, merchant_id)
                 .await
                 .change_context(errors::StorageError::DecryptionError)
         }))
@@ -194,6 +206,7 @@ impl MerchantKeyStoreInterface for Store {
 impl MerchantKeyStoreInterface for MockDb {
     async fn insert_merchant_key_store(
         &self,
+        state: &KeyManagerState,
         merchant_key_store: domain::MerchantKeyStore,
         key: &Secret<Vec<u8>>,
     ) -> CustomResult<domain::MerchantKeyStore, errors::StorageError> {
@@ -213,15 +226,16 @@ impl MerchantKeyStoreInterface for MockDb {
             .await
             .change_context(errors::StorageError::MockDbError)?;
         locked_merchant_key_store.push(merchant_key.clone());
-
+        let merchant_id = merchant_key.merchant_id.clone();
         merchant_key
-            .convert(key)
+            .convert(state, key, merchant_id)
             .await
             .change_context(errors::StorageError::DecryptionError)
     }
 
     async fn get_merchant_key_store_by_merchant_id(
         &self,
+        state: &KeyManagerState,
         merchant_id: &str,
         key: &Secret<Vec<u8>>,
     ) -> CustomResult<domain::MerchantKeyStore, errors::StorageError> {
@@ -234,7 +248,7 @@ impl MerchantKeyStoreInterface for MockDb {
             .ok_or(errors::StorageError::ValueNotFound(String::from(
                 "merchant_key_store",
             )))?
-            .convert(key)
+            .convert(state, key, merchant_id.to_string())
             .await
             .change_context(errors::StorageError::DecryptionError)
     }
@@ -258,6 +272,7 @@ impl MerchantKeyStoreInterface for MockDb {
     #[cfg(feature = "olap")]
     async fn list_multiple_key_stores(
         &self,
+        state: &KeyManagerState,
         merchant_ids: Vec<String>,
         key: &Secret<Vec<u8>>,
     ) -> CustomResult<Vec<domain::MerchantKeyStore>, errors::StorageError> {
@@ -269,7 +284,7 @@ impl MerchantKeyStoreInterface for MockDb {
                 .map(|merchant_key| async {
                     merchant_key
                         .to_owned()
-                        .convert(key)
+                        .convert(state, key, merchant_key.merchant_id.clone())
                         .await
                         .change_context(errors::StorageError::DecryptionError)
                 }),
@@ -278,6 +293,7 @@ impl MerchantKeyStoreInterface for MockDb {
     }
     async fn get_all_key_stores(
         &self,
+        state: &KeyManagerState,
         key: &Secret<Vec<u8>>,
     ) -> CustomResult<Vec<domain::MerchantKeyStore>, errors::StorageError> {
         let merchant_key_stores = self.merchant_key_store.lock().await;
@@ -285,7 +301,7 @@ impl MerchantKeyStoreInterface for MockDb {
         futures::future::try_join_all(merchant_key_stores.iter().map(|merchant_key| async {
             merchant_key
                 .to_owned()
-                .convert(key)
+                .convert(state, key, merchant_key.merchant_id.clone())
                 .await
                 .change_context(errors::StorageError::DecryptionError)
         }))
@@ -295,30 +311,54 @@ impl MerchantKeyStoreInterface for MockDb {
 
 #[cfg(test)]
 mod tests {
+    use std::sync::Arc;
+
+    use common_utils::types::keymanager::Identifier;
     use time::macros::datetime;
+    use tokio::sync::oneshot;
 
     use crate::{
         db::{merchant_key_store::MerchantKeyStoreInterface, MasterKeyInterface, MockDb},
+        routes::{
+            self,
+            app::{settings::Settings, StorageImpl},
+        },
         services,
-        types::domain::{self},
+        types::domain,
     };
 
-    #[allow(clippy::unwrap_used)]
+    #[allow(clippy::unwrap_used, clippy::expect_used)]
     #[tokio::test]
     async fn test_mock_db_merchant_key_store_interface() {
+        let conf = Settings::new().expect("invalid settings");
+        let tx: oneshot::Sender<()> = oneshot::channel().0;
+        let app_state = Box::pin(routes::AppState::with_storage(
+            conf,
+            StorageImpl::PostgresqlTest,
+            tx,
+            Box::new(services::MockApiClient),
+        ))
+        .await;
+        let state = &Arc::new(app_state)
+            .get_session_state("public", || {})
+            .unwrap();
         #[allow(clippy::expect_used)]
         let mock_db = MockDb::new(&redis_interface::RedisSettings::default())
             .await
             .expect("Failed to create mock DB");
         let master_key = mock_db.get_master_key();
         let merchant_id = "merchant1";
-
+        let identifier = Identifier::Merchant(merchant_id.to_string());
+        let key_manager_state = &state.into();
         let merchant_key1 = mock_db
             .insert_merchant_key_store(
+                key_manager_state,
                 domain::MerchantKeyStore {
                     merchant_id: merchant_id.into(),
                     key: domain::types::encrypt(
+                        key_manager_state,
                         services::generate_aes256_key().unwrap().to_vec().into(),
+                        identifier.clone(),
                         master_key,
                     )
                     .await
@@ -331,7 +371,11 @@ mod tests {
             .unwrap();
 
         let found_merchant_key1 = mock_db
-            .get_merchant_key_store_by_merchant_id(merchant_id, &master_key.to_vec().into())
+            .get_merchant_key_store_by_merchant_id(
+                key_manager_state,
+                merchant_id,
+                &master_key.to_vec().into(),
+            )
             .await
             .unwrap();
 
@@ -340,10 +384,13 @@ mod tests {
 
         let insert_duplicate_merchant_key1_result = mock_db
             .insert_merchant_key_store(
+                key_manager_state,
                 domain::MerchantKeyStore {
                     merchant_id: merchant_id.into(),
                     key: domain::types::encrypt(
+                        key_manager_state,
                         services::generate_aes256_key().unwrap().to_vec().into(),
+                        identifier.clone(),
                         master_key,
                     )
                     .await
@@ -356,12 +403,20 @@ mod tests {
         assert!(insert_duplicate_merchant_key1_result.is_err());
 
         let find_non_existent_merchant_key_result = mock_db
-            .get_merchant_key_store_by_merchant_id("non_existent", &master_key.to_vec().into())
+            .get_merchant_key_store_by_merchant_id(
+                key_manager_state,
+                "non_existent",
+                &master_key.to_vec().into(),
+            )
             .await;
         assert!(find_non_existent_merchant_key_result.is_err());
 
         let find_merchant_key_with_incorrect_master_key_result = mock_db
-            .get_merchant_key_store_by_merchant_id(merchant_id, &vec![0; 32].into())
+            .get_merchant_key_store_by_merchant_id(
+                key_manager_state,
+                merchant_id,
+                &vec![0; 32].into(),
+            )
             .await;
         assert!(find_merchant_key_with_incorrect_master_key_result.is_err());
     }
diff --git a/crates/router/src/db/user/sample_data.rs b/crates/router/src/db/user/sample_data.rs
index 5a23666c7b1..cabf62b850e 100644
--- a/crates/router/src/db/user/sample_data.rs
+++ b/crates/router/src/db/user/sample_data.rs
@@ -1,3 +1,4 @@
+use common_utils::types::keymanager::KeyManagerState;
 use diesel_models::{
     errors::DatabaseError,
     query::user::sample_data as sample_data_queries,
@@ -20,6 +21,7 @@ use crate::{connection::pg_connection_write, core::errors::CustomResult, service
 pub trait BatchSampleDataInterface {
     async fn insert_payment_intents_batch_for_sample_data(
         &self,
+        state: &KeyManagerState,
         batch: Vec<PaymentIntent>,
         key_store: &MerchantKeyStore,
     ) -> CustomResult<Vec<PaymentIntent>, StorageError>;
@@ -36,6 +38,7 @@ pub trait BatchSampleDataInterface {
 
     async fn delete_payment_intents_for_sample_data(
         &self,
+        state: &KeyManagerState,
         merchant_id: &str,
         key_store: &MerchantKeyStore,
     ) -> CustomResult<Vec<PaymentIntent>, StorageError>;
@@ -55,6 +58,7 @@ pub trait BatchSampleDataInterface {
 impl BatchSampleDataInterface for Store {
     async fn insert_payment_intents_batch_for_sample_data(
         &self,
+        state: &KeyManagerState,
         batch: Vec<PaymentIntent>,
         key_store: &MerchantKeyStore,
     ) -> CustomResult<Vec<PaymentIntent>, StorageError> {
@@ -68,13 +72,17 @@ impl BatchSampleDataInterface for Store {
                 .change_context(StorageError::EncryptionError)
         }))
         .await?;
-
         sample_data_queries::insert_payment_intents(&conn, new_intents)
             .await
             .map_err(diesel_error_to_data_error)
             .map(|v| {
                 try_join_all(v.into_iter().map(|payment_intent| {
-                    PaymentIntent::convert_back(payment_intent, key_store.key.get_inner())
+                    PaymentIntent::convert_back(
+                        state,
+                        payment_intent,
+                        key_store.key.get_inner(),
+                        key_store.merchant_id.clone(),
+                    )
                 }))
                 .map(|join_result| join_result.change_context(StorageError::DecryptionError))
             })?
@@ -111,6 +119,7 @@ impl BatchSampleDataInterface for Store {
 
     async fn delete_payment_intents_for_sample_data(
         &self,
+        state: &KeyManagerState,
         merchant_id: &str,
         key_store: &MerchantKeyStore,
     ) -> CustomResult<Vec<PaymentIntent>, StorageError> {
@@ -122,7 +131,12 @@ impl BatchSampleDataInterface for Store {
             .map_err(diesel_error_to_data_error)
             .map(|v| {
                 try_join_all(v.into_iter().map(|payment_intent| {
-                    PaymentIntent::convert_back(payment_intent, key_store.key.get_inner())
+                    PaymentIntent::convert_back(
+                        state,
+                        payment_intent,
+                        key_store.key.get_inner(),
+                        key_store.merchant_id.clone(),
+                    )
                 }))
                 .map(|join_result| join_result.change_context(StorageError::DecryptionError))
             })?
@@ -162,6 +176,7 @@ impl BatchSampleDataInterface for Store {
 impl BatchSampleDataInterface for storage_impl::MockDb {
     async fn insert_payment_intents_batch_for_sample_data(
         &self,
+        _state: &KeyManagerState,
         _batch: Vec<PaymentIntent>,
         _key_store: &MerchantKeyStore,
     ) -> CustomResult<Vec<PaymentIntent>, StorageError> {
@@ -184,6 +199,7 @@ impl BatchSampleDataInterface for storage_impl::MockDb {
 
     async fn delete_payment_intents_for_sample_data(
         &self,
+        _state: &KeyManagerState,
         _merchant_id: &str,
         _key_store: &MerchantKeyStore,
     ) -> CustomResult<Vec<PaymentIntent>, StorageError> {
diff --git a/crates/router/src/db/user_key_store.rs b/crates/router/src/db/user_key_store.rs
index c7e48037e96..e7dbe531c65 100644
--- a/crates/router/src/db/user_key_store.rs
+++ b/crates/router/src/db/user_key_store.rs
@@ -1,4 +1,4 @@
-use common_utils::errors::CustomResult;
+use common_utils::{errors::CustomResult, types::keymanager::KeyManagerState};
 use error_stack::{report, ResultExt};
 use masking::Secret;
 use router_env::{instrument, tracing};
@@ -18,18 +18,21 @@ use crate::{
 pub trait UserKeyStoreInterface {
     async fn insert_user_key_store(
         &self,
+        state: &KeyManagerState,
         user_key_store: domain::UserKeyStore,
         key: &Secret<Vec<u8>>,
     ) -> CustomResult<domain::UserKeyStore, errors::StorageError>;
 
     async fn get_user_key_store_by_user_id(
         &self,
+        state: &KeyManagerState,
         user_id: &str,
         key: &Secret<Vec<u8>>,
     ) -> CustomResult<domain::UserKeyStore, errors::StorageError>;
 
     async fn get_all_user_key_store(
         &self,
+        state: &KeyManagerState,
         key: &Secret<Vec<u8>>,
     ) -> CustomResult<Vec<domain::UserKeyStore>, errors::StorageError>;
 }
@@ -39,10 +42,12 @@ impl UserKeyStoreInterface for Store {
     #[instrument(skip_all)]
     async fn insert_user_key_store(
         &self,
+        state: &KeyManagerState,
         user_key_store: domain::UserKeyStore,
         key: &Secret<Vec<u8>>,
     ) -> CustomResult<domain::UserKeyStore, errors::StorageError> {
         let conn = connection::pg_connection_write(self).await?;
+        let user_id = user_key_store.user_id.clone();
         user_key_store
             .construct_new()
             .await
@@ -50,7 +55,7 @@ impl UserKeyStoreInterface for Store {
             .insert(&conn)
             .await
             .map_err(|error| report!(errors::StorageError::from(error)))?
-            .convert(key)
+            .convert(state, key, user_id)
             .await
             .change_context(errors::StorageError::DecryptionError)
     }
@@ -58,6 +63,7 @@ impl UserKeyStoreInterface for Store {
     #[instrument(skip_all)]
     async fn get_user_key_store_by_user_id(
         &self,
+        state: &KeyManagerState,
         user_id: &str,
         key: &Secret<Vec<u8>>,
     ) -> CustomResult<domain::UserKeyStore, errors::StorageError> {
@@ -66,13 +72,14 @@ impl UserKeyStoreInterface for Store {
         diesel_models::user_key_store::UserKeyStore::find_by_user_id(&conn, user_id)
             .await
             .map_err(|error| report!(errors::StorageError::from(error)))?
-            .convert(key)
+            .convert(state, key, user_id.to_string())
             .await
             .change_context(errors::StorageError::DecryptionError)
     }
 
     async fn get_all_user_key_store(
         &self,
+        state: &KeyManagerState,
         key: &Secret<Vec<u8>>,
     ) -> CustomResult<Vec<domain::UserKeyStore>, errors::StorageError> {
         let conn = connection::pg_connection_read(self).await?;
@@ -84,8 +91,9 @@ impl UserKeyStoreInterface for Store {
         };
 
         futures::future::try_join_all(fetch_func().await?.into_iter().map(|key_store| async {
+            let user_id = key_store.user_id.clone();
             key_store
-                .convert(key)
+                .convert(state, key, user_id)
                 .await
                 .change_context(errors::StorageError::DecryptionError)
         }))
@@ -98,6 +106,7 @@ impl UserKeyStoreInterface for MockDb {
     #[instrument(skip_all)]
     async fn insert_user_key_store(
         &self,
+        state: &KeyManagerState,
         user_key_store: domain::UserKeyStore,
         key: &Secret<Vec<u8>>,
     ) -> CustomResult<domain::UserKeyStore, errors::StorageError> {
@@ -117,23 +126,25 @@ impl UserKeyStoreInterface for MockDb {
             .await
             .change_context(errors::StorageError::MockDbError)?;
         locked_user_key_store.push(user_key_store.clone());
-
+        let user_id = user_key_store.user_id.clone();
         user_key_store
-            .convert(key)
+            .convert(state, key, user_id)
             .await
             .change_context(errors::StorageError::DecryptionError)
     }
 
     async fn get_all_user_key_store(
         &self,
+        state: &KeyManagerState,
         key: &Secret<Vec<u8>>,
     ) -> CustomResult<Vec<domain::UserKeyStore>, errors::StorageError> {
         let user_key_store = self.user_key_store.lock().await;
 
         futures::future::try_join_all(user_key_store.iter().map(|user_key| async {
+            let user_id = user_key.user_id.clone();
             user_key
                 .to_owned()
-                .convert(key)
+                .convert(state, key, user_id)
                 .await
                 .change_context(errors::StorageError::DecryptionError)
         }))
@@ -143,6 +154,7 @@ impl UserKeyStoreInterface for MockDb {
     #[instrument(skip_all)]
     async fn get_user_key_store_by_user_id(
         &self,
+        state: &KeyManagerState,
         user_id: &str,
         key: &Secret<Vec<u8>>,
     ) -> CustomResult<domain::UserKeyStore, errors::StorageError> {
@@ -156,7 +168,7 @@ impl UserKeyStoreInterface for MockDb {
                 "No user_key_store is found for user_id={}",
                 user_id
             )))?
-            .convert(key)
+            .convert(state, key, user_id.to_string())
             .await
             .change_context(errors::StorageError::DecryptionError)
     }
diff --git a/crates/router/src/lib.rs b/crates/router/src/lib.rs
index 38000f7b664..6405a3b8479 100644
--- a/crates/router/src/lib.rs
+++ b/crates/router/src/lib.rs
@@ -193,7 +193,11 @@ pub async fn start_server(conf: settings::Settings<SecuredSecret>) -> Applicatio
     let api_client = Box::new(
         services::ProxyClient::new(
             conf.proxy.clone(),
-            services::proxy_bypass_urls(&conf.locker, &conf.proxy.bypass_proxy_urls),
+            services::proxy_bypass_urls(
+                conf.key_manager.get_inner(),
+                &conf.locker,
+                &conf.proxy.bypass_proxy_urls,
+            ),
         )
         .map_err(|error| {
             errors::ApplicationError::ApiClientError(error.current_context().clone())
diff --git a/crates/router/src/routes/app.rs b/crates/router/src/routes/app.rs
index 0d7d042f7af..b733e76289e 100644
--- a/crates/router/src/routes/app.rs
+++ b/crates/router/src/routes/app.rs
@@ -110,6 +110,7 @@ pub trait SessionStateInfo {
     fn event_handler(&self) -> EventsHandler;
     fn get_request_id(&self) -> Option<String>;
     fn add_request_id(&mut self, request_id: RequestId);
+    fn session_state(&self) -> SessionState;
 }
 
 impl SessionStateInfo for SessionState {
@@ -130,6 +131,9 @@ impl SessionStateInfo for SessionState {
         self.store.add_request_id(request_id.to_string());
         self.request_id.replace(request_id);
     }
+    fn session_state(&self) -> SessionState {
+        self.clone()
+    }
 }
 #[derive(Clone)]
 pub struct AppState {
diff --git a/crates/router/src/routes/payment_methods.rs b/crates/router/src/routes/payment_methods.rs
index 003cd71c00d..25df0ef6434 100644
--- a/crates/router/src/routes/payment_methods.rs
+++ b/crates/router/src/routes/payment_methods.rs
@@ -40,7 +40,7 @@ pub async fn create_payment_method_api(
         json_payload.into_inner(),
         |state, auth, req, _| async move {
             Box::pin(cards::get_client_secret_or_add_payment_method(
-                state,
+                &state,
                 req,
                 &auth.merchant_account,
                 &auth.key_store,
@@ -88,9 +88,11 @@ async fn get_merchant_account(
     state: &SessionState,
     merchant_id: &str,
 ) -> CustomResult<(MerchantKeyStore, domain::MerchantAccount), errors::ApiErrorResponse> {
+    let key_manager_state = &state.into();
     let key_store = state
         .store
         .get_merchant_key_store_by_merchant_id(
+            key_manager_state,
             merchant_id,
             &state.store.get_master_key().to_vec().into(),
         )
@@ -99,7 +101,7 @@ async fn get_merchant_account(
 
     let merchant_account = state
         .store
-        .find_merchant_account_by_merchant_id(merchant_id, &key_store)
+        .find_merchant_account_by_merchant_id(key_manager_state, merchant_id, &key_store)
         .await
         .to_not_found_response(errors::ApiErrorResponse::MerchantAccountNotFound)?;
     Ok((key_store, merchant_account))
@@ -530,7 +532,7 @@ pub async fn default_payment_method_set_api(
         payload,
         |state, auth: auth::AuthenticationData, default_payment_method, _| async move {
             cards::set_default_payment_method(
-                &*state.clone().store,
+                &state,
                 auth.merchant_account.merchant_id,
                 auth.key_store,
                 customer_id,
diff --git a/crates/router/src/routes/recon.rs b/crates/router/src/routes/recon.rs
index aabbd637ae7..d8100e8d341 100644
--- a/crates/router/src/routes/recon.rs
+++ b/crates/router/src/routes/recon.rs
@@ -85,15 +85,17 @@ pub async fn send_recon_request(
         .await
         .to_not_found_response(errors::ApiErrorResponse::MerchantAccountNotFound)?
         .merchant_id;
+    let key_manager_state = &(&state).into();
     let key_store = db
         .get_merchant_key_store_by_merchant_id(
+            key_manager_state,
             merchant_id.as_str(),
             &db.get_master_key().to_vec().into(),
         )
         .await
         .to_not_found_response(errors::ApiErrorResponse::MerchantAccountNotFound)?;
     let merchant_account = db
-        .find_merchant_account_by_merchant_id(merchant_id.as_str(), &key_store)
+        .find_merchant_account_by_merchant_id(key_manager_state, merchant_id.as_str(), &key_store)
         .await
         .to_not_found_response(errors::ApiErrorResponse::MerchantAccountNotFound)?;
 
@@ -130,7 +132,12 @@ pub async fn send_recon_request(
         };
 
         let response = db
-            .update_merchant(merchant_account, updated_merchant_account, &key_store)
+            .update_merchant(
+                key_manager_state,
+                merchant_account,
+                updated_merchant_account,
+                &key_store,
+            )
             .await
             .change_context(errors::ApiErrorResponse::InternalServerError)
             .attach_printable_lazy(|| {
@@ -162,6 +169,7 @@ pub async fn recon_merchant_account_update(
 
     let key_store = db
         .get_merchant_key_store_by_merchant_id(
+            &(&state).into(),
             &req.merchant_id,
             &db.get_master_key().to_vec().into(),
         )
@@ -169,7 +177,7 @@ pub async fn recon_merchant_account_update(
         .to_not_found_response(errors::ApiErrorResponse::MerchantAccountNotFound)?;
 
     let merchant_account = db
-        .find_merchant_account_by_merchant_id(merchant_id, &key_store)
+        .find_merchant_account_by_merchant_id(&(&state).into(), merchant_id, &key_store)
         .await
         .to_not_found_response(errors::ApiErrorResponse::MerchantAccountNotFound)?;
 
@@ -178,7 +186,12 @@ pub async fn recon_merchant_account_update(
     };
 
     let response = db
-        .update_merchant(merchant_account, updated_merchant_account, &key_store)
+        .update_merchant(
+            &(&state).into(),
+            merchant_account,
+            updated_merchant_account,
+            &key_store,
+        )
         .await
         .change_context(errors::ApiErrorResponse::InternalServerError)
         .attach_printable_lazy(|| {
diff --git a/crates/router/src/services/api.rs b/crates/router/src/services/api.rs
index 5dc46d35652..ea9ce177439 100644
--- a/crates/router/src/services/api.rs
+++ b/crates/router/src/services/api.rs
@@ -474,12 +474,19 @@ pub async fn send_request(
     let should_bypass_proxy = url
         .as_str()
         .starts_with(&state.conf.connectors.dummyconnector.base_url)
-        || proxy_bypass_urls(&state.conf.locker, &state.conf.proxy.bypass_proxy_urls)
-            .contains(&url.to_string());
+        || proxy_bypass_urls(
+            state.conf.key_manager.get_inner(),
+            &state.conf.locker,
+            &state.conf.proxy.bypass_proxy_urls,
+        )
+        .contains(&url.to_string());
     #[cfg(not(feature = "dummy_connector"))]
-    let should_bypass_proxy =
-        proxy_bypass_urls(&state.conf.locker, &state.conf.proxy.bypass_proxy_urls)
-            .contains(&url.to_string());
+    let should_bypass_proxy = proxy_bypass_urls(
+        &state.conf.key_manager.get_inner(),
+        &state.conf.locker,
+        &state.conf.proxy.bypass_proxy_urls,
+    )
+    .contains(&url.to_string());
     let client = client::create_client(
         &state.conf.proxy,
         should_bypass_proxy,
diff --git a/crates/router/src/services/api/client.rs b/crates/router/src/services/api/client.rs
index f3cb2f3f314..4dda8eab627 100644
--- a/crates/router/src/services/api/client.rs
+++ b/crates/router/src/services/api/client.rs
@@ -15,7 +15,7 @@ use crate::{
         errors::{ApiClientError, CustomResult},
         payments,
     },
-    routes::SessionState,
+    routes::{app::settings::KeyManagerConfig, SessionState},
 };
 
 static NON_PROXIED_CLIENT: OnceCell<reqwest::Client> = OnceCell::new();
@@ -110,7 +110,12 @@ pub fn create_client(
     }
 }
 
-pub fn proxy_bypass_urls(locker: &Locker, config_whitelist: &[String]) -> Vec<String> {
+pub fn proxy_bypass_urls(
+    key_manager: &KeyManagerConfig,
+    locker: &Locker,
+    config_whitelist: &[String],
+) -> Vec<String> {
+    let key_manager_host = key_manager.url.to_owned();
     let locker_host = locker.host.to_owned();
     let locker_host_rs = locker.host_rs.to_owned();
 
@@ -126,8 +131,11 @@ pub fn proxy_bypass_urls(locker: &Locker, config_whitelist: &[String]) -> Vec<St
         format!("{locker_host}/card/addCard"),
         format!("{locker_host}/card/getCard"),
         format!("{locker_host}/card/deleteCard"),
+        format!("{key_manager_host}/data/encrypt"),
+        format!("{key_manager_host}/data/decrypt"),
+        format!("{key_manager_host}/key/create"),
+        format!("{key_manager_host}/key/rotate"),
     ];
-
     [&proxy_list, config_whitelist].concat().to_vec()
 }
 
diff --git a/crates/router/src/services/authentication.rs b/crates/router/src/services/authentication.rs
index adc23935d9c..22c7f25ff82 100644
--- a/crates/router/src/services/authentication.rs
+++ b/crates/router/src/services/authentication.rs
@@ -319,9 +319,12 @@ where
                 .attach_printable("API key has expired");
         }
 
+        let key_manager_state = &(&state.session_state()).into();
+
         let key_store = state
             .store()
             .get_merchant_key_store_by_merchant_id(
+                key_manager_state,
                 &stored_api_key.merchant_id,
                 &state.store().get_master_key().to_vec().into(),
             )
@@ -331,7 +334,11 @@ where
 
         let merchant = state
             .store()
-            .find_merchant_account_by_merchant_id(&stored_api_key.merchant_id, &key_store)
+            .find_merchant_account_by_merchant_id(
+                key_manager_state,
+                &stored_api_key.merchant_id,
+                &key_store,
+            )
             .await
             .to_not_found_response(errors::ApiErrorResponse::Unauthorized)?;
 
@@ -534,9 +541,11 @@ where
         _request_headers: &HeaderMap,
         state: &A,
     ) -> RouterResult<(AuthenticationData, AuthenticationType)> {
+        let key_manager_state = &(&state.session_state()).into();
         let key_store = state
             .store()
             .get_merchant_key_store_by_merchant_id(
+                key_manager_state,
                 self.0.as_ref(),
                 &state.store().get_master_key().to_vec().into(),
             )
@@ -552,7 +561,7 @@ where
 
         let merchant = state
             .store()
-            .find_merchant_account_by_merchant_id(self.0.as_ref(), &key_store)
+            .find_merchant_account_by_merchant_id(key_manager_state, self.0.as_ref(), &key_store)
             .await
             .map_err(|e| {
                 if e.current_context().is_db_not_found() {
@@ -590,10 +599,10 @@ where
     ) -> RouterResult<(AuthenticationData, AuthenticationType)> {
         let publishable_key =
             get_api_key(request_headers).change_context(errors::ApiErrorResponse::Unauthorized)?;
-
+        let key_manager_state = &(&state.session_state()).into();
         state
             .store()
-            .find_merchant_account_by_publishable_key(publishable_key)
+            .find_merchant_account_by_publishable_key(key_manager_state, publishable_key)
             .await
             .map_err(|e| {
                 if e.current_context().is_db_not_found() {
@@ -818,10 +827,11 @@ where
 
         let permissions = authorization::get_permissions(state, &payload).await?;
         authorization::check_authorization(&self.0, &permissions)?;
-
+        let key_manager_state = &(&state.session_state()).into();
         let key_store = state
             .store()
             .get_merchant_key_store_by_merchant_id(
+                key_manager_state,
                 &payload.merchant_id,
                 &state.store().get_master_key().to_vec().into(),
             )
@@ -831,7 +841,11 @@ where
 
         let merchant = state
             .store()
-            .find_merchant_account_by_merchant_id(&payload.merchant_id, &key_store)
+            .find_merchant_account_by_merchant_id(
+                key_manager_state,
+                &payload.merchant_id,
+                &key_store,
+            )
             .await
             .change_context(errors::ApiErrorResponse::InvalidJwtToken)?;
 
@@ -868,10 +882,11 @@ where
 
         let permissions = authorization::get_permissions(state, &payload).await?;
         authorization::check_authorization(&self.0, &permissions)?;
-
+        let key_manager_state = &(&state.session_state()).into();
         let key_store = state
             .store()
             .get_merchant_key_store_by_merchant_id(
+                key_manager_state,
                 &payload.merchant_id,
                 &state.store().get_master_key().to_vec().into(),
             )
@@ -881,7 +896,11 @@ where
 
         let merchant = state
             .store()
-            .find_merchant_account_by_merchant_id(&payload.merchant_id, &key_store)
+            .find_merchant_account_by_merchant_id(
+                key_manager_state,
+                &payload.merchant_id,
+                &key_store,
+            )
             .await
             .change_context(errors::ApiErrorResponse::InvalidJwtToken)?;
 
@@ -963,10 +982,11 @@ where
         state: &A,
     ) -> RouterResult<(AuthenticationData, AuthenticationType)> {
         let payload = parse_jwt_payload::<A, AuthToken>(request_headers, state).await?;
-
+        let key_manager_state = &(&state.session_state()).into();
         let key_store = state
             .store()
             .get_merchant_key_store_by_merchant_id(
+                key_manager_state,
                 &payload.merchant_id,
                 &state.store().get_master_key().to_vec().into(),
             )
@@ -976,7 +996,11 @@ where
 
         let merchant = state
             .store()
-            .find_merchant_account_by_merchant_id(&payload.merchant_id, &key_store)
+            .find_merchant_account_by_merchant_id(
+                key_manager_state,
+                &payload.merchant_id,
+                &key_store,
+            )
             .await
             .to_not_found_response(errors::ApiErrorResponse::Unauthorized)?;
 
diff --git a/crates/router/src/types/api/admin.rs b/crates/router/src/types/api/admin.rs
index 884e47c6fc4..054888d1dfe 100644
--- a/crates/router/src/types/api/admin.rs
+++ b/crates/router/src/types/api/admin.rs
@@ -8,13 +8,17 @@ pub use api_models::admin::{
     MerchantId, PaymentMethodsEnabled, ToggleAllKVRequest, ToggleAllKVResponse, ToggleKVRequest,
     ToggleKVResponse, WebhookDetails,
 };
-use common_utils::ext_traits::{AsyncExt, Encode, ValueExt};
+use common_utils::{
+    ext_traits::{AsyncExt, Encode, ValueExt},
+    types::keymanager::Identifier,
+};
 use error_stack::{report, ResultExt};
 use hyperswitch_domain_models::{merchant_key_store::MerchantKeyStore, type_encryption::decrypt};
 use masking::{ExposeInterface, PeekInterface, Secret};
 
 use crate::{
     core::{errors, payment_methods::cards::create_encrypted_data},
+    routes::SessionState,
     types::{domain, storage, transformers::ForeignTryFrom},
 };
 
@@ -84,11 +88,14 @@ impl ForeignTryFrom<domain::MerchantAccount> for MerchantAccountResponse {
 }
 
 pub async fn business_profile_response(
+    state: &SessionState,
     item: storage::business_profile::BusinessProfile,
     key_store: &MerchantKeyStore,
 ) -> Result<BusinessProfileResponse, error_stack::Report<errors::ParsingError>> {
     let outgoing_webhook_custom_http_headers = decrypt::<serde_json::Value, masking::WithType>(
+        &state.into(),
         item.outgoing_webhook_custom_http_headers.clone(),
+        Identifier::Merchant(key_store.merchant_id.clone()),
         key_store.key.get_inner().peek(),
     )
     .await
@@ -147,6 +154,7 @@ pub async fn business_profile_response(
 }
 
 pub async fn create_business_profile(
+    state: &SessionState,
     merchant_account: domain::MerchantAccount,
     request: BusinessProfileCreate,
     key_store: &MerchantKeyStore,
@@ -188,7 +196,7 @@ pub async fn create_business_profile(
         .transpose()?;
     let outgoing_webhook_custom_http_headers = request
         .outgoing_webhook_custom_http_headers
-        .async_map(|headers| create_encrypted_data(key_store, headers))
+        .async_map(|headers| create_encrypted_data(state, key_store, headers))
         .await
         .transpose()
         .change_context(errors::ApiErrorResponse::InternalServerError)
diff --git a/crates/router/src/types/api/mandates.rs b/crates/router/src/types/api/mandates.rs
index 71b90ab41c3..686f7f3ce49 100644
--- a/crates/router/src/types/api/mandates.rs
+++ b/crates/router/src/types/api/mandates.rs
@@ -2,7 +2,6 @@ use api_models::mandates;
 pub use api_models::mandates::{MandateId, MandateResponse, MandateRevokedResponse};
 use common_utils::ext_traits::OptionExt;
 use error_stack::ResultExt;
-use masking::PeekInterface;
 use serde::{Deserialize, Serialize};
 
 use crate::{
@@ -73,8 +72,8 @@ impl MandateResponseExt for MandateResponse {
             } else {
                 payment_methods::cards::get_card_details_without_locker_fallback(
                     &payment_method,
-                    key_store.key.get_inner().peek(),
                     state,
+                    &key_store,
                 )
                 .await?
             };
diff --git a/crates/router/src/types/domain/address.rs b/crates/router/src/types/domain/address.rs
index 0ed09a35013..e14ab8ea641 100644
--- a/crates/router/src/types/domain/address.rs
+++ b/crates/router/src/types/domain/address.rs
@@ -1,18 +1,19 @@
 use async_trait::async_trait;
 use common_utils::{
-    crypto, date_time,
+    crypto::{self, Encryptable},
+    date_time,
+    encryption::Encryption,
     errors::{CustomResult, ValidationError},
     id_type,
+    types::keymanager::{Identifier, KeyManagerState, ToEncryptable},
 };
-use diesel_models::{address::AddressUpdateInternal, encryption::Encryption, enums};
+use diesel_models::{address::AddressUpdateInternal, enums};
 use error_stack::ResultExt;
 use masking::{PeekInterface, Secret};
+use rustc_hash::FxHashMap;
 use time::{OffsetDateTime, PrimitiveDateTime};
 
-use super::{
-    behaviour,
-    types::{self, AsyncLift},
-};
+use super::{behaviour, types};
 
 #[derive(Clone, Debug, serde::Serialize)]
 pub struct Address {
@@ -73,8 +74,10 @@ impl behaviour::Conversion for CustomerAddress {
     }
 
     async fn convert_back(
+        state: &KeyManagerState,
         other: Self::DstType,
         key: &Secret<Vec<u8>>,
+        key_store_ref_id: String,
     ) -> CustomResult<Self, ValidationError> {
         let customer_id =
             other
@@ -84,7 +87,7 @@ impl behaviour::Conversion for CustomerAddress {
                     field_name: "customer_id".to_string(),
                 })?;
 
-        let address = Address::convert_back(other, key).await?;
+        let address = Address::convert_back(state, other, key, key_store_ref_id).await?;
 
         Ok(Self {
             address,
@@ -117,8 +120,10 @@ impl behaviour::Conversion for PaymentAddress {
     }
 
     async fn convert_back(
+        state: &KeyManagerState,
         other: Self::DstType,
         key: &Secret<Vec<u8>>,
+        key_store_ref_id: String,
     ) -> CustomResult<Self, ValidationError> {
         let payment_id = other
             .payment_id
@@ -129,7 +134,7 @@ impl behaviour::Conversion for PaymentAddress {
 
         let customer_id = other.customer_id.clone();
 
-        let address = Address::convert_back(other, key).await?;
+        let address = Address::convert_back(state, other, key, key_store_ref_id).await?;
 
         Ok(Self {
             address,
@@ -180,36 +185,45 @@ impl behaviour::Conversion for Address {
     }
 
     async fn convert_back(
+        state: &KeyManagerState,
         other: Self::DstType,
         key: &Secret<Vec<u8>>,
+        _key_store_ref_id: String,
     ) -> CustomResult<Self, ValidationError> {
-        async {
-            let inner_decrypt = |inner| types::decrypt(inner, key.peek());
-            let inner_decrypt_email = |inner| types::decrypt(inner, key.peek());
-            Ok::<Self, error_stack::Report<common_utils::errors::CryptoError>>(Self {
-                id: other.id,
-                address_id: other.address_id,
-                city: other.city,
-                country: other.country,
-                line1: other.line1.async_lift(inner_decrypt).await?,
-                line2: other.line2.async_lift(inner_decrypt).await?,
-                line3: other.line3.async_lift(inner_decrypt).await?,
-                state: other.state.async_lift(inner_decrypt).await?,
-                zip: other.zip.async_lift(inner_decrypt).await?,
-                first_name: other.first_name.async_lift(inner_decrypt).await?,
-                last_name: other.last_name.async_lift(inner_decrypt).await?,
-                phone_number: other.phone_number.async_lift(inner_decrypt).await?,
-                country_code: other.country_code,
-                created_at: other.created_at,
-                modified_at: other.modified_at,
-                updated_by: other.updated_by,
-                merchant_id: other.merchant_id,
-                email: other.email.async_lift(inner_decrypt_email).await?,
-            })
-        }
+        let identifier = Identifier::Merchant(other.merchant_id.clone());
+        let decrypted: FxHashMap<String, Encryptable<Secret<String>>> = types::batch_decrypt(
+            state,
+            diesel_models::Address::to_encryptable(other.clone()),
+            identifier.clone(),
+            key.peek(),
+        )
         .await
         .change_context(ValidationError::InvalidValue {
             message: "Failed while decrypting".to_string(),
+        })?;
+        let encryptable_address = diesel_models::Address::from_encryptable(decrypted)
+            .change_context(ValidationError::InvalidValue {
+                message: "Failed while decrypting".to_string(),
+            })?;
+        Ok(Self {
+            id: other.id,
+            address_id: other.address_id,
+            city: other.city,
+            country: other.country,
+            line1: encryptable_address.line1,
+            line2: encryptable_address.line2,
+            line3: encryptable_address.line3,
+            state: encryptable_address.state,
+            zip: encryptable_address.zip,
+            first_name: encryptable_address.first_name,
+            last_name: encryptable_address.last_name,
+            phone_number: encryptable_address.phone_number,
+            country_code: other.country_code,
+            created_at: other.created_at,
+            modified_at: other.modified_at,
+            updated_by: other.updated_by,
+            merchant_id: other.merchant_id,
+            email: encryptable_address.email,
         })
     }
 
diff --git a/crates/router/src/types/domain/customer.rs b/crates/router/src/types/domain/customer.rs
index c5b0b3701cb..b7ed05e3506 100644
--- a/crates/router/src/types/domain/customer.rs
+++ b/crates/router/src/types/domain/customer.rs
@@ -1,10 +1,16 @@
-use common_utils::{crypto, date_time, id_type, pii};
-use diesel_models::{customers::CustomerUpdateInternal, encryption::Encryption};
+use api_models::customers::CustomerRequestWithEncryption;
+use common_utils::{
+    crypto, date_time,
+    encryption::Encryption,
+    id_type, pii,
+    types::keymanager::{Identifier, KeyManagerState, ToEncryptable},
+};
+use diesel_models::customers::CustomerUpdateInternal;
 use error_stack::ResultExt;
 use masking::{PeekInterface, Secret};
 use time::PrimitiveDateTime;
 
-use super::types::{self, AsyncLift};
+use super::types;
 use crate::errors::{CustomResult, ValidationError};
 
 #[derive(Clone, Debug)]
@@ -53,36 +59,49 @@ impl super::behaviour::Conversion for Customer {
     }
 
     async fn convert_back(
+        state: &KeyManagerState,
         item: Self::DstType,
         key: &Secret<Vec<u8>>,
+        _key_store_ref_id: String,
     ) -> CustomResult<Self, ValidationError>
     where
         Self: Sized,
     {
-        async {
-            let inner_decrypt = |inner| types::decrypt(inner, key.peek());
-            let inner_decrypt_email = |inner| types::decrypt(inner, key.peek());
-            Ok::<Self, error_stack::Report<common_utils::errors::CryptoError>>(Self {
-                id: Some(item.id),
-                customer_id: item.customer_id,
-                merchant_id: item.merchant_id,
-                name: item.name.async_lift(inner_decrypt).await?,
-                email: item.email.async_lift(inner_decrypt_email).await?,
-                phone: item.phone.async_lift(inner_decrypt).await?,
-                phone_country_code: item.phone_country_code,
-                description: item.description,
-                created_at: item.created_at,
-                metadata: item.metadata,
-                modified_at: item.modified_at,
-                connector_customer: item.connector_customer,
-                address_id: item.address_id,
-                default_payment_method_id: item.default_payment_method_id,
-                updated_by: item.updated_by,
-            })
-        }
+        let decrypted = types::batch_decrypt(
+            state,
+            CustomerRequestWithEncryption::to_encryptable(CustomerRequestWithEncryption {
+                name: item.name.clone(),
+                phone: item.phone.clone(),
+                email: item.email.clone(),
+            }),
+            Identifier::Merchant(item.merchant_id.clone()),
+            key.peek(),
+        )
         .await
         .change_context(ValidationError::InvalidValue {
             message: "Failed while decrypting customer data".to_string(),
+        })?;
+        let encryptable_customer = CustomerRequestWithEncryption::from_encryptable(decrypted)
+            .change_context(ValidationError::InvalidValue {
+                message: "Failed while decrypting customer data".to_string(),
+            })?;
+
+        Ok(Self {
+            id: Some(item.id),
+            customer_id: item.customer_id,
+            merchant_id: item.merchant_id,
+            name: encryptable_customer.name,
+            email: encryptable_customer.email,
+            phone: encryptable_customer.phone,
+            phone_country_code: item.phone_country_code,
+            description: item.description,
+            created_at: item.created_at,
+            metadata: item.metadata,
+            modified_at: item.modified_at,
+            connector_customer: item.connector_customer,
+            address_id: item.address_id,
+            default_payment_method_id: item.default_payment_method_id,
+            updated_by: item.updated_by,
         })
     }
 
diff --git a/crates/router/src/types/domain/event.rs b/crates/router/src/types/domain/event.rs
index 74a6cfb47b5..c5eca1ab5ea 100644
--- a/crates/router/src/types/domain/event.rs
+++ b/crates/router/src/types/domain/event.rs
@@ -1,14 +1,18 @@
-use common_utils::crypto::OptionalEncryptableSecretString;
+use common_utils::{
+    crypto::OptionalEncryptableSecretString,
+    types::keymanager::{Identifier, KeyManagerState, ToEncryptable},
+};
 use diesel_models::{
     enums::{EventClass, EventObjectType, EventType, WebhookDeliveryAttempt},
     events::{EventMetadata, EventUpdateInternal},
+    EventWithEncryption,
 };
 use error_stack::ResultExt;
 use masking::{PeekInterface, Secret};
 
 use crate::{
     errors::{CustomResult, ValidationError},
-    types::domain::types::{self, AsyncLift},
+    types::domain::types,
 };
 
 #[derive(Clone, Debug)]
@@ -80,41 +84,49 @@ impl super::behaviour::Conversion for Event {
     }
 
     async fn convert_back(
+        state: &KeyManagerState,
         item: Self::DstType,
         key: &Secret<Vec<u8>>,
+        key_store_ref_id: String,
     ) -> CustomResult<Self, ValidationError>
     where
         Self: Sized,
     {
-        async {
-            Ok::<Self, error_stack::Report<common_utils::errors::CryptoError>>(Self {
-                event_id: item.event_id,
-                event_type: item.event_type,
-                event_class: item.event_class,
-                is_webhook_notified: item.is_webhook_notified,
-                primary_object_id: item.primary_object_id,
-                primary_object_type: item.primary_object_type,
-                created_at: item.created_at,
-                merchant_id: item.merchant_id,
-                business_profile_id: item.business_profile_id,
-                primary_object_created_at: item.primary_object_created_at,
-                idempotent_event_id: item.idempotent_event_id,
-                initial_attempt_id: item.initial_attempt_id,
-                request: item
-                    .request
-                    .async_lift(|inner| types::decrypt(inner, key.peek()))
-                    .await?,
-                response: item
-                    .response
-                    .async_lift(|inner| types::decrypt(inner, key.peek()))
-                    .await?,
-                delivery_attempt: item.delivery_attempt,
-                metadata: item.metadata,
-            })
-        }
+        let decrypted = types::batch_decrypt(
+            state,
+            EventWithEncryption::to_encryptable(EventWithEncryption {
+                request: item.request.clone(),
+                response: item.response.clone(),
+            }),
+            Identifier::Merchant(key_store_ref_id.clone()),
+            key.peek(),
+        )
         .await
         .change_context(ValidationError::InvalidValue {
             message: "Failed while decrypting event data".to_string(),
+        })?;
+        let encryptable_event = EventWithEncryption::from_encryptable(decrypted).change_context(
+            ValidationError::InvalidValue {
+                message: "Failed while decrypting event data".to_string(),
+            },
+        )?;
+        Ok(Self {
+            event_id: item.event_id,
+            event_type: item.event_type,
+            event_class: item.event_class,
+            is_webhook_notified: item.is_webhook_notified,
+            primary_object_id: item.primary_object_id,
+            primary_object_type: item.primary_object_type,
+            created_at: item.created_at,
+            merchant_id: item.merchant_id,
+            business_profile_id: item.business_profile_id,
+            primary_object_created_at: item.primary_object_created_at,
+            idempotent_event_id: item.idempotent_event_id,
+            initial_attempt_id: item.initial_attempt_id,
+            request: encryptable_event.request,
+            response: encryptable_event.response,
+            delivery_attempt: item.delivery_attempt,
+            metadata: item.metadata,
         })
     }
 
diff --git a/crates/router/src/types/domain/merchant_connector_account.rs b/crates/router/src/types/domain/merchant_connector_account.rs
index 2cf091eda12..6f654848f60 100644
--- a/crates/router/src/types/domain/merchant_connector_account.rs
+++ b/crates/router/src/types/domain/merchant_connector_account.rs
@@ -1,13 +1,12 @@
 use common_utils::{
     crypto::{Encryptable, GcmAes256},
     date_time,
+    encryption::Encryption,
     errors::{CustomResult, ValidationError},
     pii,
+    types::keymanager::{Identifier, KeyManagerState},
 };
-use diesel_models::{
-    encryption::Encryption, enums,
-    merchant_connector_account::MerchantConnectorAccountUpdateInternal,
-};
+use diesel_models::{enums, merchant_connector_account::MerchantConnectorAccountUpdateInternal};
 use error_stack::ResultExt;
 use masking::{PeekInterface, Secret};
 
@@ -108,15 +107,20 @@ impl behaviour::Conversion for MerchantConnectorAccount {
     }
 
     async fn convert_back(
+        state: &KeyManagerState,
         other: Self::DstType,
         key: &Secret<Vec<u8>>,
+        _key_store_ref_id: String,
     ) -> CustomResult<Self, ValidationError> {
+        let identifier = Identifier::Merchant(other.merchant_id.clone());
         Ok(Self {
             id: Some(other.id),
             merchant_id: other.merchant_id,
             connector_name: other.connector_name,
-            connector_account_details: Encryptable::decrypt(
+            connector_account_details: Encryptable::decrypt_via_api(
+                state,
                 other.connector_account_details,
+                identifier.clone(),
                 key.peek(),
                 GcmAes256,
             )
@@ -145,7 +149,7 @@ impl behaviour::Conversion for MerchantConnectorAccount {
             status: other.status,
             connector_wallets_details: other
                 .connector_wallets_details
-                .async_lift(|inner| types::decrypt(inner, key.peek()))
+                .async_lift(|inner| types::decrypt(state, inner, identifier.clone(), key.peek()))
                 .await
                 .change_context(ValidationError::InvalidValue {
                     message: "Failed while decrypting connector wallets details".to_string(),
diff --git a/crates/router/src/types/domain/types.rs b/crates/router/src/types/domain/types.rs
index 151ae61f5fe..53239cd27cf 100644
--- a/crates/router/src/types/domain/types.rs
+++ b/crates/router/src/types/domain/types.rs
@@ -1,6 +1,7 @@
 use common_utils::types::keymanager::KeyManagerState;
 pub use hyperswitch_domain_models::type_encryption::{
-    decrypt, encrypt, encrypt_optional, AsyncLift, Lift, TypeEncryption,
+    batch_decrypt, batch_encrypt, decrypt, encrypt, encrypt_optional, AsyncLift, Lift,
+    TypeEncryption,
 };
 
 impl From<&crate::SessionState> for KeyManagerState {
diff --git a/crates/router/src/types/domain/user.rs b/crates/router/src/types/domain/user.rs
index c4c67796d46..ec44103a8f0 100644
--- a/crates/router/src/types/domain/user.rs
+++ b/crates/router/src/types/domain/user.rs
@@ -7,8 +7,11 @@ use common_enums::TokenPurpose;
 #[cfg(not(feature = "v2"))]
 use common_utils::id_type;
 #[cfg(feature = "keymanager_create")]
-use common_utils::types::keymanager::{EncryptionCreateRequest, Identifier};
-use common_utils::{crypto::Encryptable, errors::CustomResult, new_type::MerchantName, pii};
+use common_utils::types::keymanager::EncryptionCreateRequest;
+use common_utils::{
+    crypto::Encryptable, errors::CustomResult, new_type::MerchantName, pii,
+    types::keymanager::Identifier,
+};
 use diesel_models::{
     enums::{TotpStatus, UserStatus},
     organization as diesel_org,
@@ -368,6 +371,7 @@ impl NewUserMerchant {
         if state
             .store
             .get_merchant_key_store_by_merchant_id(
+                &(&state).into(),
                 self.get_merchant_id().as_str(),
                 &state.store.get_master_key().to_vec().into(),
             )
@@ -949,9 +953,14 @@ impl UserFromStorage {
 
     pub async fn get_or_create_key_store(&self, state: &SessionState) -> UserResult<UserKeyStore> {
         let master_key = state.store.get_master_key();
+        let key_manager_state = &state.into();
         let key_store_result = state
             .global_store
-            .get_user_key_store_by_user_id(self.get_user_id(), &master_key.to_vec().into())
+            .get_user_key_store_by_user_id(
+                key_manager_state,
+                self.get_user_id(),
+                &master_key.to_vec().into(),
+            )
             .await;
 
         if let Ok(key_store) = key_store_result {
@@ -968,16 +977,21 @@ impl UserFromStorage {
 
             let key_store = UserKeyStore {
                 user_id: self.get_user_id().to_string(),
-                key: domain_types::encrypt(key.to_vec().into(), master_key)
-                    .await
-                    .change_context(UserErrors::InternalServerError)?,
+                key: domain_types::encrypt(
+                    key_manager_state,
+                    key.to_vec().into(),
+                    Identifier::User(self.get_user_id().to_string()),
+                    master_key,
+                )
+                .await
+                .change_context(UserErrors::InternalServerError)?,
                 created_at: common_utils::date_time::now(),
             };
 
             #[cfg(feature = "keymanager_create")]
             {
                 common_utils::keymanager::create_key_in_key_manager(
-                    &state.into(),
+                    key_manager_state,
                     EncryptionCreateRequest {
                         identifier: Identifier::User(key_store.user_id.clone()),
                     },
@@ -988,7 +1002,7 @@ impl UserFromStorage {
 
             state
                 .global_store
-                .insert_user_key_store(key_store, &master_key.to_vec().into())
+                .insert_user_key_store(key_manager_state, key_store, &master_key.to_vec().into())
                 .await
                 .change_context(UserErrors::InternalServerError)
         } else {
@@ -1014,10 +1028,11 @@ impl UserFromStorage {
         if self.0.totp_secret.is_none() {
             return Ok(None);
         }
-
+        let key_manager_state = &state.into();
         let user_key_store = state
             .global_store
             .get_user_key_store_by_user_id(
+                key_manager_state,
                 self.get_user_id(),
                 &state.store.get_master_key().to_vec().into(),
             )
@@ -1025,7 +1040,9 @@ impl UserFromStorage {
             .change_context(UserErrors::InternalServerError)?;
 
         Ok(domain_types::decrypt::<String, masking::WithType>(
+            key_manager_state,
             self.0.totp_secret.clone(),
+            Identifier::User(user_key_store.user_id.clone()),
             user_key_store.key.peek(),
         )
         .await
@@ -1141,6 +1158,7 @@ impl SignInWithMultipleRolesStrategy {
         let merchant_accounts = state
             .store
             .list_multiple_merchant_accounts(
+                &state.into(),
                 self.user_roles
                     .iter()
                     .map(|role| role.merchant_id.clone())
diff --git a/crates/router/src/types/domain/user_key_store.rs b/crates/router/src/types/domain/user_key_store.rs
index 4c1427d58dc..3a1a9a60e95 100644
--- a/crates/router/src/types/domain/user_key_store.rs
+++ b/crates/router/src/types/domain/user_key_store.rs
@@ -1,6 +1,7 @@
 use common_utils::{
     crypto::{Encryptable, GcmAes256},
     date_time,
+    types::keymanager::{Identifier, KeyManagerState},
 };
 use error_stack::ResultExt;
 use masking::{PeekInterface, Secret};
@@ -32,14 +33,17 @@ impl super::behaviour::Conversion for UserKeyStore {
     }
 
     async fn convert_back(
+        state: &KeyManagerState,
         item: Self::DstType,
         key: &Secret<Vec<u8>>,
+        _key_store_ref_id: String,
     ) -> CustomResult<Self, ValidationError>
     where
         Self: Sized,
     {
+        let identifier = Identifier::User(item.user_id.clone());
         Ok(Self {
-            key: Encryptable::decrypt(item.key, key.peek(), GcmAes256)
+            key: Encryptable::decrypt_via_api(state, item.key, identifier, key.peek(), GcmAes256)
                 .await
                 .change_context(ValidationError::InvalidValue {
                     message: "Failed while decrypting customer data".to_string(),
diff --git a/crates/router/src/utils.rs b/crates/router/src/utils.rs
index 64e2f534b7a..a36aee4593e 100644
--- a/crates/router/src/utils.rs
+++ b/crates/router/src/utils.rs
@@ -14,19 +14,25 @@ pub mod verify_connector;
 
 use std::fmt::Debug;
 
-use api_models::{enums, payments, webhooks};
+use api_models::{
+    enums,
+    payments::{self, AddressDetailsWithPhone},
+    webhooks,
+};
 use base64::Engine;
-use common_utils::id_type;
 pub use common_utils::{
     crypto,
     ext_traits::{ByteSliceExt, BytesExt, Encode, StringExt, ValueExt},
     fp_utils::when,
     validation::validate_email,
 };
+use common_utils::{
+    id_type,
+    types::keymanager::{Identifier, KeyManagerState, ToEncryptable},
+};
 use error_stack::ResultExt;
-use hyperswitch_domain_models::payments::PaymentIntent;
+use hyperswitch_domain_models::{payments::PaymentIntent, type_encryption::batch_encrypt};
 use image::Luma;
-use masking::ExposeInterface;
 use nanoid::nanoid;
 use qrcode;
 use router_env::metrics::add_attributes;
@@ -43,19 +49,10 @@ use crate::{
         errors::{self, CustomResult, RouterResult, StorageErrorExt},
         utils, webhooks as webhooks_core,
     },
-    db::StorageInterface,
     logger,
-    routes::metrics,
+    routes::{metrics, SessionState},
     services,
-    types::{
-        self,
-        domain::{
-            self,
-            types::{encrypt_optional, AsyncLift},
-        },
-        storage,
-        transformers::ForeignFrom,
-    },
+    types::{self, domain, storage, transformers::ForeignFrom},
 };
 
 pub mod error_parser {
@@ -194,14 +191,17 @@ impl QrImage {
 }
 
 pub async fn find_payment_intent_from_payment_id_type(
-    db: &dyn StorageInterface,
+    state: &SessionState,
     payment_id_type: payments::PaymentIdType,
     merchant_account: &domain::MerchantAccount,
     key_store: &domain::MerchantKeyStore,
 ) -> CustomResult<PaymentIntent, errors::ApiErrorResponse> {
+    let key_manager_state: KeyManagerState = state.into();
+    let db = &*state.store;
     match payment_id_type {
         payments::PaymentIdType::PaymentIntentId(payment_id) => db
             .find_payment_intent_by_payment_id_merchant_id(
+                &key_manager_state,
                 &payment_id,
                 &merchant_account.merchant_id,
                 key_store,
@@ -219,6 +219,7 @@ pub async fn find_payment_intent_from_payment_id_type(
                 .await
                 .to_not_found_response(errors::ApiErrorResponse::PaymentNotFound)?;
             db.find_payment_intent_by_payment_id_merchant_id(
+                &key_manager_state,
                 &attempt.payment_id,
                 &merchant_account.merchant_id,
                 key_store,
@@ -237,6 +238,7 @@ pub async fn find_payment_intent_from_payment_id_type(
                 .await
                 .to_not_found_response(errors::ApiErrorResponse::PaymentNotFound)?;
             db.find_payment_intent_by_payment_id_merchant_id(
+                &key_manager_state,
                 &attempt.payment_id,
                 &merchant_account.merchant_id,
                 key_store,
@@ -252,12 +254,13 @@ pub async fn find_payment_intent_from_payment_id_type(
 }
 
 pub async fn find_payment_intent_from_refund_id_type(
-    db: &dyn StorageInterface,
+    state: &SessionState,
     refund_id_type: webhooks::RefundIdType,
     merchant_account: &domain::MerchantAccount,
     key_store: &domain::MerchantKeyStore,
     connector_name: &str,
 ) -> CustomResult<PaymentIntent, errors::ApiErrorResponse> {
+    let db = &*state.store;
     let refund = match refund_id_type {
         webhooks::RefundIdType::RefundId(id) => db
             .find_refund_by_merchant_id_refund_id(
@@ -286,6 +289,7 @@ pub async fn find_payment_intent_from_refund_id_type(
         .await
         .to_not_found_response(errors::ApiErrorResponse::PaymentNotFound)?;
     db.find_payment_intent_by_payment_id_merchant_id(
+        &state.into(),
         &attempt.payment_id,
         &merchant_account.merchant_id,
         key_store,
@@ -296,11 +300,12 @@ pub async fn find_payment_intent_from_refund_id_type(
 }
 
 pub async fn find_payment_intent_from_mandate_id_type(
-    db: &dyn StorageInterface,
+    state: &SessionState,
     mandate_id_type: webhooks::MandateIdType,
     merchant_account: &domain::MerchantAccount,
     key_store: &domain::MerchantKeyStore,
 ) -> CustomResult<PaymentIntent, errors::ApiErrorResponse> {
+    let db = &*state.store;
     let mandate = match mandate_id_type {
         webhooks::MandateIdType::MandateId(mandate_id) => db
             .find_mandate_by_merchant_id_mandate_id(
@@ -320,6 +325,7 @@ pub async fn find_payment_intent_from_mandate_id_type(
             .to_not_found_response(errors::ApiErrorResponse::MandateNotFound)?,
     };
     db.find_payment_intent_by_payment_id_merchant_id(
+        &state.into(),
         &mandate
             .original_payment_id
             .ok_or(errors::ApiErrorResponse::InternalServerError)
@@ -333,11 +339,12 @@ pub async fn find_payment_intent_from_mandate_id_type(
 }
 
 pub async fn find_mca_from_authentication_id_type(
-    db: &dyn StorageInterface,
+    state: &SessionState,
     authentication_id_type: webhooks::AuthenticationIdType,
     merchant_account: &domain::MerchantAccount,
     key_store: &domain::MerchantKeyStore,
 ) -> CustomResult<domain::MerchantConnectorAccount, errors::ApiErrorResponse> {
+    let db = &*state.store;
     let authentication = match authentication_id_type {
         webhooks::AuthenticationIdType::AuthenticationId(authentication_id) => db
             .find_authentication_by_merchant_id_authentication_id(
@@ -356,6 +363,7 @@ pub async fn find_mca_from_authentication_id_type(
         }
     };
     db.find_by_merchant_connector_account_merchant_id_merchant_connector_id(
+        &state.into(),
         &merchant_account.merchant_id,
         &authentication.merchant_connector_id,
         key_store,
@@ -367,12 +375,13 @@ pub async fn find_mca_from_authentication_id_type(
 }
 
 pub async fn get_mca_from_payment_intent(
-    db: &dyn StorageInterface,
+    state: &SessionState,
     merchant_account: &domain::MerchantAccount,
     payment_intent: PaymentIntent,
     key_store: &domain::MerchantKeyStore,
     connector_name: &str,
 ) -> CustomResult<domain::MerchantConnectorAccount, errors::ApiErrorResponse> {
+    let db = &*state.store;
     let payment_attempt = db
         .find_payment_attempt_by_attempt_id_merchant_id(
             &payment_intent.active_attempt.get_id(),
@@ -381,10 +390,11 @@ pub async fn get_mca_from_payment_intent(
         )
         .await
         .to_not_found_response(errors::ApiErrorResponse::PaymentNotFound)?;
-
+    let key_manager_state = &state.into();
     match payment_attempt.merchant_connector_id {
         Some(merchant_connector_id) => db
             .find_by_merchant_connector_account_merchant_id_merchant_connector_id(
+                key_manager_state,
                 &merchant_account.merchant_id,
                 &merchant_connector_id,
                 key_store,
@@ -410,6 +420,7 @@ pub async fn get_mca_from_payment_intent(
             };
 
             db.find_merchant_connector_account_by_profile_id_connector_name(
+                key_manager_state,
                 &profile_id,
                 connector_name,
                 key_store,
@@ -426,12 +437,13 @@ pub async fn get_mca_from_payment_intent(
 
 #[cfg(feature = "payouts")]
 pub async fn get_mca_from_payout_attempt(
-    db: &dyn StorageInterface,
+    state: &SessionState,
     merchant_account: &domain::MerchantAccount,
     payout_id_type: webhooks::PayoutIdType,
     connector_name: &str,
     key_store: &domain::MerchantKeyStore,
 ) -> CustomResult<domain::MerchantConnectorAccount, errors::ApiErrorResponse> {
+    let db = &*state.store;
     let payout = match payout_id_type {
         webhooks::PayoutIdType::PayoutAttemptId(payout_attempt_id) => db
             .find_payout_attempt_by_merchant_id_payout_attempt_id(
@@ -450,10 +462,11 @@ pub async fn get_mca_from_payout_attempt(
             .await
             .to_not_found_response(errors::ApiErrorResponse::PayoutNotFound)?,
     };
-
+    let key_manager_state = &state.into();
     match payout.merchant_connector_id {
         Some(merchant_connector_id) => db
             .find_by_merchant_connector_account_merchant_id_merchant_connector_id(
+                key_manager_state,
                 &merchant_account.merchant_id,
                 &merchant_connector_id,
                 key_store,
@@ -464,6 +477,7 @@ pub async fn get_mca_from_payout_attempt(
             }),
         None => db
             .find_merchant_connector_account_by_profile_id_connector_name(
+                key_manager_state,
                 &payout.profile_id,
                 connector_name,
                 key_store,
@@ -479,15 +493,17 @@ pub async fn get_mca_from_payout_attempt(
 }
 
 pub async fn get_mca_from_object_reference_id(
-    db: &dyn StorageInterface,
+    state: &SessionState,
     object_reference_id: webhooks::ObjectReferenceId,
     merchant_account: &domain::MerchantAccount,
     connector_name: &str,
     key_store: &domain::MerchantKeyStore,
 ) -> CustomResult<domain::MerchantConnectorAccount, errors::ApiErrorResponse> {
+    let db = &*state.store;
     match merchant_account.default_profile.as_ref() {
         Some(profile_id) => db
             .find_merchant_connector_account_by_profile_id_connector_name(
+                &state.into(),
                 profile_id,
                 connector_name,
                 key_store,
@@ -499,10 +515,10 @@ pub async fn get_mca_from_object_reference_id(
         _ => match object_reference_id {
             webhooks::ObjectReferenceId::PaymentId(payment_id_type) => {
                 get_mca_from_payment_intent(
-                    db,
+                    state,
                     merchant_account,
                     find_payment_intent_from_payment_id_type(
-                        db,
+                        state,
                         payment_id_type,
                         merchant_account,
                         key_store,
@@ -515,10 +531,10 @@ pub async fn get_mca_from_object_reference_id(
             }
             webhooks::ObjectReferenceId::RefundId(refund_id_type) => {
                 get_mca_from_payment_intent(
-                    db,
+                    state,
                     merchant_account,
                     find_payment_intent_from_refund_id_type(
-                        db,
+                        state,
                         refund_id_type,
                         merchant_account,
                         key_store,
@@ -532,10 +548,10 @@ pub async fn get_mca_from_object_reference_id(
             }
             webhooks::ObjectReferenceId::MandateId(mandate_id_type) => {
                 get_mca_from_payment_intent(
-                    db,
+                    state,
                     merchant_account,
                     find_payment_intent_from_mandate_id_type(
-                        db,
+                        state,
                         mandate_id_type,
                         merchant_account,
                         key_store,
@@ -548,7 +564,7 @@ pub async fn get_mca_from_object_reference_id(
             }
             webhooks::ObjectReferenceId::ExternalAuthenticationID(authentication_id_type) => {
                 find_mca_from_authentication_id_type(
-                    db,
+                    state,
                     authentication_id_type,
                     merchant_account,
                     key_store,
@@ -558,7 +574,7 @@ pub async fn get_mca_from_object_reference_id(
             #[cfg(feature = "payouts")]
             webhooks::ObjectReferenceId::PayoutId(payout_id_type) => {
                 get_mca_from_payout_attempt(
-                    db,
+                    state,
                     merchant_account,
                     payout_id_type,
                     connector_name,
@@ -649,13 +665,16 @@ pub fn add_connector_http_status_code_metrics(option_status_code: Option<u16>) {
 pub trait CustomerAddress {
     async fn get_address_update(
         &self,
+        state: &SessionState,
         address_details: payments::AddressDetails,
         key: &[u8],
         storage_scheme: storage::enums::MerchantStorageScheme,
+        merchant_id: String,
     ) -> CustomResult<storage::AddressUpdate, common_utils::errors::CryptoError>;
 
     async fn get_domain_address(
         &self,
+        state: &SessionState,
         address_details: payments::AddressDetails,
         merchant_id: &str,
         customer_id: &id_type::CustomerId,
@@ -668,126 +687,89 @@ pub trait CustomerAddress {
 impl CustomerAddress for api_models::customers::CustomerRequest {
     async fn get_address_update(
         &self,
+        state: &SessionState,
         address_details: payments::AddressDetails,
         key: &[u8],
         storage_scheme: storage::enums::MerchantStorageScheme,
+        merchant_id: String,
     ) -> CustomResult<storage::AddressUpdate, common_utils::errors::CryptoError> {
-        async {
-            Ok(storage::AddressUpdate::Update {
-                city: address_details.city,
-                country: address_details.country,
-                line1: address_details
-                    .line1
-                    .async_lift(|inner| encrypt_optional(inner, key))
-                    .await?,
-                line2: address_details
-                    .line2
-                    .async_lift(|inner| encrypt_optional(inner, key))
-                    .await?,
-                line3: address_details
-                    .line3
-                    .async_lift(|inner| encrypt_optional(inner, key))
-                    .await?,
-                zip: address_details
-                    .zip
-                    .async_lift(|inner| encrypt_optional(inner, key))
-                    .await?,
-                state: address_details
-                    .state
-                    .async_lift(|inner| encrypt_optional(inner, key))
-                    .await?,
-                first_name: address_details
-                    .first_name
-                    .async_lift(|inner| encrypt_optional(inner, key))
-                    .await?,
-                last_name: address_details
-                    .last_name
-                    .async_lift(|inner| encrypt_optional(inner, key))
-                    .await?,
-                phone_number: self
-                    .phone
-                    .clone()
-                    .async_lift(|inner| encrypt_optional(inner, key))
-                    .await?,
-                country_code: self.phone_country_code.clone(),
-                updated_by: storage_scheme.to_string(),
-                email: self
-                    .email
-                    .as_ref()
-                    .cloned()
-                    .async_lift(|inner| encrypt_optional(inner.map(|inner| inner.expose()), key))
-                    .await?,
-            })
-        }
-        .await
+        let encrypted_data = batch_encrypt(
+            &state.into(),
+            AddressDetailsWithPhone::to_encryptable(AddressDetailsWithPhone {
+                address: Some(address_details.clone()),
+                phone_number: self.phone.clone(),
+                email: self.email.clone(),
+            }),
+            Identifier::Merchant(merchant_id),
+            key,
+        )
+        .await?;
+        let encryptable_address = AddressDetailsWithPhone::from_encryptable(encrypted_data)
+            .change_context(common_utils::errors::CryptoError::EncodingFailed)?;
+        Ok(storage::AddressUpdate::Update {
+            city: address_details.city,
+            country: address_details.country,
+            line1: encryptable_address.line1,
+            line2: encryptable_address.line2,
+            line3: encryptable_address.line3,
+            zip: encryptable_address.zip,
+            state: encryptable_address.state,
+            first_name: encryptable_address.first_name,
+            last_name: encryptable_address.last_name,
+            phone_number: encryptable_address.phone_number,
+            country_code: self.phone_country_code.clone(),
+            updated_by: storage_scheme.to_string(),
+            email: encryptable_address.email,
+        })
     }
 
     async fn get_domain_address(
         &self,
+        state: &SessionState,
         address_details: payments::AddressDetails,
         merchant_id: &str,
         customer_id: &id_type::CustomerId,
         key: &[u8],
         storage_scheme: storage::enums::MerchantStorageScheme,
     ) -> CustomResult<domain::CustomerAddress, common_utils::errors::CryptoError> {
-        async {
-            let address = domain::Address {
-                id: None,
-                city: address_details.city,
-                country: address_details.country,
-                line1: address_details
-                    .line1
-                    .async_lift(|inner| encrypt_optional(inner, key))
-                    .await?,
-                line2: address_details
-                    .line2
-                    .async_lift(|inner| encrypt_optional(inner, key))
-                    .await?,
-                line3: address_details
-                    .line3
-                    .async_lift(|inner| encrypt_optional(inner, key))
-                    .await?,
-                zip: address_details
-                    .zip
-                    .async_lift(|inner| encrypt_optional(inner, key))
-                    .await?,
-                state: address_details
-                    .state
-                    .async_lift(|inner| encrypt_optional(inner, key))
-                    .await?,
-                first_name: address_details
-                    .first_name
-                    .async_lift(|inner| encrypt_optional(inner, key))
-                    .await?,
-                last_name: address_details
-                    .last_name
-                    .async_lift(|inner| encrypt_optional(inner, key))
-                    .await?,
-                phone_number: self
-                    .phone
-                    .clone()
-                    .async_lift(|inner| encrypt_optional(inner, key))
-                    .await?,
-                country_code: self.phone_country_code.clone(),
-                merchant_id: merchant_id.to_string(),
-                address_id: generate_id(consts::ID_LENGTH, "add"),
-                created_at: common_utils::date_time::now(),
-                modified_at: common_utils::date_time::now(),
-                updated_by: storage_scheme.to_string(),
-                email: self
-                    .email
-                    .as_ref()
-                    .cloned()
-                    .async_lift(|inner| encrypt_optional(inner.map(|inner| inner.expose()), key))
-                    .await?,
-            };
+        let encrypted_data = batch_encrypt(
+            &state.into(),
+            AddressDetailsWithPhone::to_encryptable(AddressDetailsWithPhone {
+                address: Some(address_details.clone()),
+                phone_number: self.phone.clone(),
+                email: self.email.clone(),
+            }),
+            Identifier::Merchant(merchant_id.to_string()),
+            key,
+        )
+        .await?;
+        let encryptable_address = AddressDetailsWithPhone::from_encryptable(encrypted_data)
+            .change_context(common_utils::errors::CryptoError::EncodingFailed)?;
+        let address = domain::Address {
+            id: None,
+            city: address_details.city,
+            country: address_details.country,
+            line1: encryptable_address.line1,
+            line2: encryptable_address.line2,
+            line3: encryptable_address.line3,
+            zip: encryptable_address.zip,
+            state: encryptable_address.state,
+            first_name: encryptable_address.first_name,
+            last_name: encryptable_address.last_name,
+            phone_number: encryptable_address.phone_number,
+            country_code: self.phone_country_code.clone(),
+            merchant_id: merchant_id.to_string(),
+            address_id: generate_id(consts::ID_LENGTH, "add"),
+            created_at: common_utils::date_time::now(),
+            modified_at: common_utils::date_time::now(),
+            updated_by: storage_scheme.to_string(),
+            email: encryptable_address.email,
+        };
 
-            Ok(domain::CustomerAddress {
-                address,
-                customer_id: customer_id.to_owned(),
-            })
-        }
-        .await
+        Ok(domain::CustomerAddress {
+            address,
+            customer_id: customer_id.to_owned(),
+        })
     }
 }
 
@@ -911,7 +893,7 @@ pub async fn trigger_payments_webhook<F, Op>(
     key_store: &domain::MerchantKeyStore,
     payment_data: crate::core::payments::PaymentData<F>,
     customer: Option<domain::Customer>,
-    state: &crate::routes::SessionState,
+    state: &SessionState,
     operation: Op,
 ) -> RouterResult<()>
 where
diff --git a/crates/router/src/utils/connector_onboarding.rs b/crates/router/src/utils/connector_onboarding.rs
index 15ad2eb8954..0bc8e58fcc4 100644
--- a/crates/router/src/utils/connector_onboarding.rs
+++ b/crates/router/src/utils/connector_onboarding.rs
@@ -45,9 +45,11 @@ pub async fn check_if_connector_exists(
     connector_id: &str,
     merchant_id: &str,
 ) -> RouterResult<()> {
+    let key_manager_state = &state.into();
     let key_store = state
         .store
         .get_merchant_key_store_by_merchant_id(
+            key_manager_state,
             merchant_id,
             &state.store.get_master_key().to_vec().into(),
         )
@@ -57,6 +59,7 @@ pub async fn check_if_connector_exists(
     let _connector = state
         .store
         .find_by_merchant_connector_account_merchant_id_merchant_connector_id(
+            key_manager_state,
             merchant_id,
             connector_id,
             &key_store,
diff --git a/crates/router/src/utils/user.rs b/crates/router/src/utils/user.rs
index 3cd35886ffe..9734122a260 100644
--- a/crates/router/src/utils/user.rs
+++ b/crates/router/src/utils/user.rs
@@ -2,8 +2,8 @@ use std::{collections::HashMap, sync::Arc};
 
 use api_models::user as user_api;
 use common_enums::UserAuthType;
-use common_utils::errors::CustomResult;
-use diesel_models::{encryption::Encryption, enums::UserStatus, user_role::UserRole};
+use common_utils::{encryption::Encryption, errors::CustomResult, types::keymanager::Identifier};
+use diesel_models::{enums::UserStatus, user_role::UserRole};
 use error_stack::ResultExt;
 use masking::{ExposeInterface, Secret};
 use redis_interface::RedisConnectionPool;
@@ -33,9 +33,11 @@ impl UserFromToken {
         &self,
         state: SessionState,
     ) -> UserResult<MerchantAccount> {
+        let key_manager_state = &(&state).into();
         let key_store = state
             .store
             .get_merchant_key_store_by_merchant_id(
+                key_manager_state,
                 &self.merchant_id,
                 &state.store.get_master_key().to_vec().into(),
             )
@@ -49,7 +51,7 @@ impl UserFromToken {
             })?;
         let merchant_account = state
             .store
-            .find_merchant_account_by_merchant_id(&self.merchant_id, &key_store)
+            .find_merchant_account_by_merchant_id(key_manager_state, &self.merchant_id, &key_store)
             .await
             .map_err(|e| {
                 if e.current_context().is_db_not_found() {
@@ -218,8 +220,10 @@ impl ForeignFrom<&user_api::AuthConfig> for UserAuthType {
 }
 
 pub async fn construct_public_and_private_db_configs(
+    state: &SessionState,
     auth_config: &user_api::AuthConfig,
     encryption_key: &[u8],
+    id: String,
 ) -> UserResult<(Option<Encryption>, Option<serde_json::Value>)> {
     match auth_config {
         user_api::AuthConfig::OpenIdConnect {
@@ -231,7 +235,9 @@ pub async fn construct_public_and_private_db_configs(
                 .attach_printable("Failed to convert auth config to json")?;
 
             let encrypted_config = domain::types::encrypt::<serde_json::Value, masking::WithType>(
+                &state.into(),
                 private_config_value.into(),
+                Identifier::UserAuth(id),
                 encryption_key,
             )
             .await
@@ -263,6 +269,7 @@ where
 pub async fn decrypt_oidc_private_config(
     state: &SessionState,
     encrypted_config: Option<Encryption>,
+    id: String,
 ) -> UserResult<user_api::OpenIdConnectPrivateConfig> {
     let user_auth_key = hex::decode(
         state
@@ -277,7 +284,9 @@ pub async fn decrypt_oidc_private_config(
     .attach_printable("Failed to decode DEK")?;
 
     let private_config = domain::types::decrypt::<serde_json::Value, masking::WithType>(
+        &state.into(),
         encrypted_config,
+        Identifier::UserAuth(id),
         &user_auth_key,
     )
     .await
diff --git a/crates/router/src/utils/user/sample_data.rs b/crates/router/src/utils/user/sample_data.rs
index b817d3e1cd7..0909f4ffbeb 100644
--- a/crates/router/src/utils/user/sample_data.rs
+++ b/crates/router/src/utils/user/sample_data.rs
@@ -23,7 +23,7 @@ pub async fn generate_sample_data(
 ) -> SampleDataResult<Vec<(PaymentIntent, PaymentAttemptBatchNew, Option<RefundNew>)>> {
     let merchant_id = merchant_id.to_string();
     let sample_data_size: usize = req.record.unwrap_or(100);
-
+    let key_manager_state = &state.into();
     if !(10..=100).contains(&sample_data_size) {
         return Err(SampleDataError::InvalidRange.into());
     }
@@ -31,6 +31,7 @@ pub async fn generate_sample_data(
     let key_store = state
         .store
         .get_merchant_key_store_by_merchant_id(
+            key_manager_state,
             merchant_id.as_str(),
             &state.store.get_master_key().to_vec().into(),
         )
@@ -39,7 +40,7 @@ pub async fn generate_sample_data(
 
     let merchant_from_db = state
         .store
-        .find_merchant_account_by_merchant_id(merchant_id.as_str(), &key_store)
+        .find_merchant_account_by_merchant_id(key_manager_state, merchant_id.as_str(), &key_store)
         .await
         .change_context::<SampleDataError>(SampleDataError::DataDoesNotExist)?;
 
diff --git a/crates/router/src/workflows/api_key_expiry.rs b/crates/router/src/workflows/api_key_expiry.rs
index dc39de8f933..e49a5f86c3c 100644
--- a/crates/router/src/workflows/api_key_expiry.rs
+++ b/crates/router/src/workflows/api_key_expiry.rs
@@ -28,17 +28,22 @@ impl ProcessTrackerWorkflow<SessionState> for ApiKeyExpiryWorkflow {
             .tracking_data
             .clone()
             .parse_value("ApiKeyExpiryTrackingData")?;
-
+        let key_manager_satte = &state.into();
         let key_store = state
             .store
             .get_merchant_key_store_by_merchant_id(
+                key_manager_satte,
                 tracking_data.merchant_id.as_str(),
                 &state.store.get_master_key().to_vec().into(),
             )
             .await?;
 
         let merchant_account = db
-            .find_merchant_account_by_merchant_id(tracking_data.merchant_id.as_str(), &key_store)
+            .find_merchant_account_by_merchant_id(
+                key_manager_satte,
+                tracking_data.merchant_id.as_str(),
+                &key_store,
+            )
             .await?;
 
         let email_id = merchant_account
diff --git a/crates/router/src/workflows/attach_payout_account_workflow.rs b/crates/router/src/workflows/attach_payout_account_workflow.rs
index eb60510ad75..7ff0faefa68 100644
--- a/crates/router/src/workflows/attach_payout_account_workflow.rs
+++ b/crates/router/src/workflows/attach_payout_account_workflow.rs
@@ -31,16 +31,17 @@ impl ProcessTrackerWorkflow<SessionState> for AttachPayoutAccountWorkflow {
             .merchant_id
             .clone()
             .get_required_value("merchant_id")?;
-
+        let key_manager_state = &state.into();
         let key_store = db
             .get_merchant_key_store_by_merchant_id(
+                key_manager_state,
                 merchant_id.as_ref(),
                 &db.get_master_key().to_vec().into(),
             )
             .await?;
 
         let merchant_account = db
-            .find_merchant_account_by_merchant_id(&merchant_id, &key_store)
+            .find_merchant_account_by_merchant_id(key_manager_state, &merchant_id, &key_store)
             .await?;
 
         let request = api::payouts::PayoutRequest::PayoutRetrieveRequest(tracking_data);
diff --git a/crates/router/src/workflows/outgoing_webhook_retry.rs b/crates/router/src/workflows/outgoing_webhook_retry.rs
index a8d5c28b64f..d181aedd18f 100644
--- a/crates/router/src/workflows/outgoing_webhook_retry.rs
+++ b/crates/router/src/workflows/outgoing_webhook_retry.rs
@@ -43,8 +43,10 @@ impl ProcessTrackerWorkflow<SessionState> for OutgoingWebhookRetryWorkflow {
             .parse_value("OutgoingWebhookTrackingData")?;
 
         let db = &*state.store;
+        let key_manager_state = &state.into();
         let key_store = db
             .get_merchant_key_store_by_merchant_id(
+                key_manager_state,
                 &tracking_data.merchant_id,
                 &db.get_master_key().to_vec().into(),
             )
@@ -63,6 +65,7 @@ impl ProcessTrackerWorkflow<SessionState> for OutgoingWebhookRetryWorkflow {
         let initial_event = match &tracking_data.initial_attempt_id {
             Some(initial_attempt_id) => {
                 db.find_event_by_merchant_id_event_id(
+                    key_manager_state,
                     &business_profile.merchant_id,
                     initial_attempt_id,
                     &key_store,
@@ -77,6 +80,7 @@ impl ProcessTrackerWorkflow<SessionState> for OutgoingWebhookRetryWorkflow {
                     tracking_data.primary_object_id, tracking_data.event_type
                 );
                 db.find_event_by_merchant_id_event_id(
+                    key_manager_state,
                     &business_profile.merchant_id,
                     &old_event_id,
                     &key_store,
@@ -106,7 +110,7 @@ impl ProcessTrackerWorkflow<SessionState> for OutgoingWebhookRetryWorkflow {
         };
 
         let event = db
-            .insert_event(new_event, &key_store)
+            .insert_event(key_manager_state, new_event, &key_store)
             .await
             .map_err(|error| {
                 logger::error!(?error, "Failed to insert event in events table");
@@ -137,7 +141,11 @@ impl ProcessTrackerWorkflow<SessionState> for OutgoingWebhookRetryWorkflow {
             // resource
             None => {
                 let merchant_account = db
-                    .find_merchant_account_by_merchant_id(&tracking_data.merchant_id, &key_store)
+                    .find_merchant_account_by_merchant_id(
+                        key_manager_state,
+                        &tracking_data.merchant_id,
+                        &key_store,
+                    )
                     .await?;
 
                 // TODO: Add request state for the PT flows as well
@@ -162,6 +170,7 @@ impl ProcessTrackerWorkflow<SessionState> for OutgoingWebhookRetryWorkflow {
                         };
 
                         let request_content = webhooks_core::get_outgoing_webhook_request(
+                            state,
                             &merchant_account,
                             outgoing_webhook,
                             &business_profile,
diff --git a/crates/router/src/workflows/payment_method_status_update.rs b/crates/router/src/workflows/payment_method_status_update.rs
index b8e57360d90..fa0631cc5c2 100644
--- a/crates/router/src/workflows/payment_method_status_update.rs
+++ b/crates/router/src/workflows/payment_method_status_update.rs
@@ -30,17 +30,18 @@ impl ProcessTrackerWorkflow<SessionState> for PaymentMethodStatusUpdateWorkflow
         let prev_pm_status = tracking_data.prev_status;
         let curr_pm_status = tracking_data.curr_status;
         let merchant_id = tracking_data.merchant_id;
-
+        let key_manager_state = &state.into();
         let key_store = state
             .store
             .get_merchant_key_store_by_merchant_id(
+                key_manager_state,
                 merchant_id.as_str(),
                 &state.store.get_master_key().to_vec().into(),
             )
             .await?;
 
         let merchant_account = db
-            .find_merchant_account_by_merchant_id(&merchant_id, &key_store)
+            .find_merchant_account_by_merchant_id(key_manager_state, &merchant_id, &key_store)
             .await?;
 
         let payment_method = db
diff --git a/crates/router/src/workflows/payment_sync.rs b/crates/router/src/workflows/payment_sync.rs
index ef0fe07e9b7..2bc7b183ec1 100644
--- a/crates/router/src/workflows/payment_sync.rs
+++ b/crates/router/src/workflows/payment_sync.rs
@@ -38,9 +38,10 @@ impl ProcessTrackerWorkflow<SessionState> for PaymentsSyncWorkflow {
             .tracking_data
             .clone()
             .parse_value("PaymentsRetrieveRequest")?;
-
+        let key_manager_state = &state.into();
         let key_store = db
             .get_merchant_key_store_by_merchant_id(
+                key_manager_state,
                 tracking_data
                     .merchant_id
                     .as_ref()
@@ -51,6 +52,7 @@ impl ProcessTrackerWorkflow<SessionState> for PaymentsSyncWorkflow {
 
         let merchant_account = db
             .find_merchant_account_by_merchant_id(
+                key_manager_state,
                 tracking_data
                     .merchant_id
                     .as_ref()
@@ -148,6 +150,7 @@ impl ProcessTrackerWorkflow<SessionState> for PaymentsSyncWorkflow {
 
                     payment_data.payment_intent = db
                         .update_payment_intent(
+                            &state.into(),
                             payment_data.payment_intent,
                             payment_intent_update,
                             &key_store,
diff --git a/crates/router/tests/payments.rs b/crates/router/tests/payments.rs
index ed11f3b8b1c..997ae51cf31 100644
--- a/crates/router/tests/payments.rs
+++ b/crates/router/tests/payments.rs
@@ -288,10 +288,11 @@ async fn payments_create_core() {
     let state = Arc::new(app_state)
         .get_session_state("public", || {})
         .unwrap();
-
+    let key_manager_state = &(&state).into();
     let key_store = state
         .store
         .get_merchant_key_store_by_merchant_id(
+            key_manager_state,
             "juspay_merchant",
             &state.store.get_master_key().to_vec().into(),
         )
@@ -300,7 +301,7 @@ async fn payments_create_core() {
 
     let merchant_account = state
         .store
-        .find_merchant_account_by_merchant_id("juspay_merchant", &key_store)
+        .find_merchant_account_by_merchant_id(key_manager_state, "juspay_merchant", &key_store)
         .await
         .unwrap();
 
@@ -476,10 +477,11 @@ async fn payments_create_core_adyen_no_redirect() {
     let customer_id = format!("cust_{}", Uuid::new_v4());
     let merchant_id = "arunraj".to_string();
     let payment_id = "pay_mbabizu24mvu3mela5njyhpit10".to_string();
-
+    let key_manager_state = &(&state).into();
     let key_store = state
         .store
         .get_merchant_key_store_by_merchant_id(
+            key_manager_state,
             "juspay_merchant",
             &state.store.get_master_key().to_vec().into(),
         )
@@ -488,7 +490,7 @@ async fn payments_create_core_adyen_no_redirect() {
 
     let merchant_account = state
         .store
-        .find_merchant_account_by_merchant_id("juspay_merchant", &key_store)
+        .find_merchant_account_by_merchant_id(key_manager_state, "juspay_merchant", &key_store)
         .await
         .unwrap();
 
diff --git a/crates/router/tests/payments2.rs b/crates/router/tests/payments2.rs
index 4c178e4122b..fcf106a9efc 100644
--- a/crates/router/tests/payments2.rs
+++ b/crates/router/tests/payments2.rs
@@ -48,10 +48,11 @@ async fn payments_create_core() {
     let state = Arc::new(app_state)
         .get_session_state("public", || {})
         .unwrap();
-
+    let key_manager_state = &(&state).into();
     let key_store = state
         .store
         .get_merchant_key_store_by_merchant_id(
+            key_manager_state,
             "juspay_merchant",
             &state.store.get_master_key().to_vec().into(),
         )
@@ -60,7 +61,7 @@ async fn payments_create_core() {
 
     let merchant_account = state
         .store
-        .find_merchant_account_by_merchant_id("juspay_merchant", &key_store)
+        .find_merchant_account_by_merchant_id(key_manager_state, "juspay_merchant", &key_store)
         .await
         .unwrap();
 
@@ -243,10 +244,11 @@ async fn payments_create_core_adyen_no_redirect() {
     let customer_id = format!("cust_{}", Uuid::new_v4());
     let merchant_id = "arunraj".to_string();
     let payment_id = "pay_mbabizu24mvu3mela5njyhpit10".to_string();
-
+    let key_manager_state = &(&state).into();
     let key_store = state
         .store
         .get_merchant_key_store_by_merchant_id(
+            key_manager_state,
             "juspay_merchant",
             &state.store.get_master_key().to_vec().into(),
         )
@@ -255,7 +257,7 @@ async fn payments_create_core_adyen_no_redirect() {
 
     let merchant_account = state
         .store
-        .find_merchant_account_by_merchant_id("juspay_merchant", &key_store)
+        .find_merchant_account_by_merchant_id(key_manager_state, "juspay_merchant", &key_store)
         .await
         .unwrap();
 
diff --git a/crates/storage_impl/src/mock_db/payment_intent.rs b/crates/storage_impl/src/mock_db/payment_intent.rs
index bf3ce0baaab..3e183b94c26 100644
--- a/crates/storage_impl/src/mock_db/payment_intent.rs
+++ b/crates/storage_impl/src/mock_db/payment_intent.rs
@@ -1,4 +1,4 @@
-use common_utils::errors::CustomResult;
+use common_utils::{errors::CustomResult, types::keymanager::KeyManagerState};
 use diesel_models::enums as storage_enums;
 use error_stack::ResultExt;
 use hyperswitch_domain_models::{
@@ -19,6 +19,7 @@ impl PaymentIntentInterface for MockDb {
     #[cfg(feature = "olap")]
     async fn filter_payment_intent_by_constraints(
         &self,
+        _state: &KeyManagerState,
         _merchant_id: &str,
         _filters: &hyperswitch_domain_models::payments::payment_intent::PaymentIntentFetchConstraints,
         _key_store: &MerchantKeyStore,
@@ -30,6 +31,7 @@ impl PaymentIntentInterface for MockDb {
     #[cfg(feature = "olap")]
     async fn filter_payment_intents_by_time_range_constraints(
         &self,
+        _state: &KeyManagerState,
         _merchant_id: &str,
         _time_range: &api_models::payments::TimeRange,
         _key_store: &MerchantKeyStore,
@@ -51,6 +53,7 @@ impl PaymentIntentInterface for MockDb {
     #[cfg(feature = "olap")]
     async fn get_filtered_payment_intents_attempt(
         &self,
+        _state: &KeyManagerState,
         _merchant_id: &str,
         _constraints: &hyperswitch_domain_models::payments::payment_intent::PaymentIntentFetchConstraints,
         _key_store: &MerchantKeyStore,
@@ -63,6 +66,7 @@ impl PaymentIntentInterface for MockDb {
     #[allow(clippy::panic)]
     async fn insert_payment_intent(
         &self,
+        _state: &KeyManagerState,
         new: PaymentIntent,
         _key_store: &MerchantKeyStore,
         _storage_scheme: storage_enums::MerchantStorageScheme,
@@ -76,6 +80,7 @@ impl PaymentIntentInterface for MockDb {
     #[allow(clippy::unwrap_used)]
     async fn update_payment_intent(
         &self,
+        state: &KeyManagerState,
         this: PaymentIntent,
         update: PaymentIntentUpdate,
         key_store: &MerchantKeyStore,
@@ -95,8 +100,10 @@ impl PaymentIntentInterface for MockDb {
             .change_context(StorageError::EncryptionError)?;
 
         *payment_intent = PaymentIntent::convert_back(
+            state,
             diesel_payment_intent_update.apply_changeset(diesel_payment_intent),
             key_store.key.get_inner(),
+            key_store.merchant_id.clone(),
         )
         .await
         .change_context(StorageError::DecryptionError)?;
@@ -108,6 +115,7 @@ impl PaymentIntentInterface for MockDb {
     #[allow(clippy::unwrap_used)]
     async fn find_payment_intent_by_payment_id_merchant_id(
         &self,
+        _state: &KeyManagerState,
         payment_id: &str,
         merchant_id: &str,
         _key_store: &MerchantKeyStore,
diff --git a/crates/storage_impl/src/payments/payment_intent.rs b/crates/storage_impl/src/payments/payment_intent.rs
index 62854cb261a..ced94b5717b 100644
--- a/crates/storage_impl/src/payments/payment_intent.rs
+++ b/crates/storage_impl/src/payments/payment_intent.rs
@@ -4,7 +4,10 @@ use api_models::payments::AmountFilter;
 use async_bb8_diesel::{AsyncConnection, AsyncRunQueryDsl};
 #[cfg(feature = "olap")]
 use common_utils::errors::ReportSwitchExt;
-use common_utils::ext_traits::{AsyncExt, Encode};
+use common_utils::{
+    ext_traits::{AsyncExt, Encode},
+    types::keymanager::KeyManagerState,
+};
 #[cfg(feature = "olap")]
 use diesel::{associations::HasTable, ExpressionMethods, JoinOnDsl, QueryDsl};
 use diesel_models::{
@@ -53,6 +56,7 @@ use crate::{
 impl<T: DatabaseStore> PaymentIntentInterface for KVRouterStore<T> {
     async fn insert_payment_intent(
         &self,
+        state: &KeyManagerState,
         payment_intent: PaymentIntent,
         merchant_key_store: &MerchantKeyStore,
         storage_scheme: MerchantStorageScheme,
@@ -69,7 +73,12 @@ impl<T: DatabaseStore> PaymentIntentInterface for KVRouterStore<T> {
         match storage_scheme {
             MerchantStorageScheme::PostgresOnly => {
                 self.router_store
-                    .insert_payment_intent(payment_intent, merchant_key_store, storage_scheme)
+                    .insert_payment_intent(
+                        state,
+                        payment_intent,
+                        merchant_key_store,
+                        storage_scheme,
+                    )
                     .await
             }
 
@@ -121,6 +130,7 @@ impl<T: DatabaseStore> PaymentIntentInterface for KVRouterStore<T> {
     #[instrument(skip_all)]
     async fn update_payment_intent(
         &self,
+        state: &KeyManagerState,
         this: PaymentIntent,
         payment_intent_update: PaymentIntentUpdate,
         merchant_key_store: &MerchantKeyStore,
@@ -143,6 +153,7 @@ impl<T: DatabaseStore> PaymentIntentInterface for KVRouterStore<T> {
             MerchantStorageScheme::PostgresOnly => {
                 self.router_store
                     .update_payment_intent(
+                        state,
                         this,
                         payment_intent_update,
                         merchant_key_store,
@@ -189,10 +200,14 @@ impl<T: DatabaseStore> PaymentIntentInterface for KVRouterStore<T> {
                 .try_into_hset()
                 .change_context(StorageError::KVError)?;
 
-                let payment_intent =
-                    PaymentIntent::convert_back(diesel_intent, merchant_key_store.key.get_inner())
-                        .await
-                        .change_context(StorageError::DecryptionError)?;
+                let payment_intent = PaymentIntent::convert_back(
+                    state,
+                    diesel_intent,
+                    merchant_key_store.key.get_inner(),
+                    merchant_id,
+                )
+                .await
+                .change_context(StorageError::DecryptionError)?;
 
                 Ok(payment_intent)
             }
@@ -202,6 +217,7 @@ impl<T: DatabaseStore> PaymentIntentInterface for KVRouterStore<T> {
     #[instrument(skip_all)]
     async fn find_payment_intent_by_payment_id_merchant_id(
         &self,
+        state: &KeyManagerState,
         payment_id: &str,
         merchant_id: &str,
         merchant_key_store: &MerchantKeyStore,
@@ -243,9 +259,14 @@ impl<T: DatabaseStore> PaymentIntentInterface for KVRouterStore<T> {
             }
         }?;
 
-        PaymentIntent::convert_back(diesel_payment_intent, merchant_key_store.key.get_inner())
-            .await
-            .change_context(StorageError::DecryptionError)
+        PaymentIntent::convert_back(
+            state,
+            diesel_payment_intent,
+            merchant_key_store.key.get_inner(),
+            merchant_id.to_string(),
+        )
+        .await
+        .change_context(StorageError::DecryptionError)
     }
 
     async fn get_active_payment_attempt(
@@ -278,6 +299,7 @@ impl<T: DatabaseStore> PaymentIntentInterface for KVRouterStore<T> {
     #[cfg(feature = "olap")]
     async fn filter_payment_intent_by_constraints(
         &self,
+        state: &KeyManagerState,
         merchant_id: &str,
         filters: &PaymentIntentFetchConstraints,
         merchant_key_store: &MerchantKeyStore,
@@ -285,6 +307,7 @@ impl<T: DatabaseStore> PaymentIntentInterface for KVRouterStore<T> {
     ) -> error_stack::Result<Vec<PaymentIntent>, StorageError> {
         self.router_store
             .filter_payment_intent_by_constraints(
+                state,
                 merchant_id,
                 filters,
                 merchant_key_store,
@@ -296,6 +319,7 @@ impl<T: DatabaseStore> PaymentIntentInterface for KVRouterStore<T> {
     #[cfg(feature = "olap")]
     async fn filter_payment_intents_by_time_range_constraints(
         &self,
+        state: &KeyManagerState,
         merchant_id: &str,
         time_range: &api_models::payments::TimeRange,
         merchant_key_store: &MerchantKeyStore,
@@ -303,6 +327,7 @@ impl<T: DatabaseStore> PaymentIntentInterface for KVRouterStore<T> {
     ) -> error_stack::Result<Vec<PaymentIntent>, StorageError> {
         self.router_store
             .filter_payment_intents_by_time_range_constraints(
+                state,
                 merchant_id,
                 time_range,
                 merchant_key_store,
@@ -314,6 +339,7 @@ impl<T: DatabaseStore> PaymentIntentInterface for KVRouterStore<T> {
     #[cfg(feature = "olap")]
     async fn get_filtered_payment_intents_attempt(
         &self,
+        state: &KeyManagerState,
         merchant_id: &str,
         filters: &PaymentIntentFetchConstraints,
         merchant_key_store: &MerchantKeyStore,
@@ -321,6 +347,7 @@ impl<T: DatabaseStore> PaymentIntentInterface for KVRouterStore<T> {
     ) -> error_stack::Result<Vec<(PaymentIntent, PaymentAttempt)>, StorageError> {
         self.router_store
             .get_filtered_payment_intents_attempt(
+                state,
                 merchant_id,
                 filters,
                 merchant_key_store,
@@ -351,6 +378,7 @@ impl<T: DatabaseStore> PaymentIntentInterface for crate::RouterStore<T> {
     #[instrument(skip_all)]
     async fn insert_payment_intent(
         &self,
+        state: &KeyManagerState,
         payment_intent: PaymentIntent,
         merchant_key_store: &MerchantKeyStore,
         _storage_scheme: MerchantStorageScheme,
@@ -367,14 +395,20 @@ impl<T: DatabaseStore> PaymentIntentInterface for crate::RouterStore<T> {
                 er.change_context(new_err)
             })?;
 
-        PaymentIntent::convert_back(diesel_payment_intent, merchant_key_store.key.get_inner())
-            .await
-            .change_context(StorageError::DecryptionError)
+        PaymentIntent::convert_back(
+            state,
+            diesel_payment_intent,
+            merchant_key_store.key.get_inner(),
+            merchant_key_store.merchant_id.clone(),
+        )
+        .await
+        .change_context(StorageError::DecryptionError)
     }
 
     #[instrument(skip_all)]
     async fn update_payment_intent(
         &self,
+        state: &KeyManagerState,
         this: PaymentIntent,
         payment_intent: PaymentIntentUpdate,
         merchant_key_store: &MerchantKeyStore,
@@ -394,14 +428,20 @@ impl<T: DatabaseStore> PaymentIntentInterface for crate::RouterStore<T> {
                 er.change_context(new_err)
             })?;
 
-        PaymentIntent::convert_back(diesel_payment_intent, merchant_key_store.key.get_inner())
-            .await
-            .change_context(StorageError::DecryptionError)
+        PaymentIntent::convert_back(
+            state,
+            diesel_payment_intent,
+            merchant_key_store.key.get_inner(),
+            merchant_key_store.merchant_id.clone(),
+        )
+        .await
+        .change_context(StorageError::DecryptionError)
     }
 
     #[instrument(skip_all)]
     async fn find_payment_intent_by_payment_id_merchant_id(
         &self,
+        state: &KeyManagerState,
         payment_id: &str,
         merchant_id: &str,
         merchant_key_store: &MerchantKeyStore,
@@ -417,8 +457,10 @@ impl<T: DatabaseStore> PaymentIntentInterface for crate::RouterStore<T> {
             })
             .async_and_then(|diesel_payment_intent| async {
                 PaymentIntent::convert_back(
+                    state,
                     diesel_payment_intent,
                     merchant_key_store.key.get_inner(),
+                    merchant_key_store.merchant_id.clone(),
                 )
                 .await
                 .change_context(StorageError::DecryptionError)
@@ -458,6 +500,7 @@ impl<T: DatabaseStore> PaymentIntentInterface for crate::RouterStore<T> {
     #[instrument(skip_all)]
     async fn filter_payment_intent_by_constraints(
         &self,
+        state: &KeyManagerState,
         merchant_id: &str,
         filters: &PaymentIntentFetchConstraints,
         merchant_key_store: &MerchantKeyStore,
@@ -498,6 +541,7 @@ impl<T: DatabaseStore> PaymentIntentInterface for crate::RouterStore<T> {
                         // TODO: Fetch partial columns for this query since we only need some columns
                         let starting_at = self
                             .find_payment_intent_by_payment_id_merchant_id(
+                                state,
                                 starting_after_id,
                                 merchant_id,
                                 merchant_key_store,
@@ -516,6 +560,7 @@ impl<T: DatabaseStore> PaymentIntentInterface for crate::RouterStore<T> {
                         // TODO: Fetch partial columns for this query since we only need some columns
                         let ending_at = self
                             .find_payment_intent_by_payment_id_merchant_id(
+                                state,
                                 ending_before_id,
                                 merchant_id,
                                 merchant_key_store,
@@ -560,8 +605,10 @@ impl<T: DatabaseStore> PaymentIntentInterface for crate::RouterStore<T> {
         .map(|payment_intents| {
             try_join_all(payment_intents.into_iter().map(|diesel_payment_intent| {
                 PaymentIntent::convert_back(
+                    state,
                     diesel_payment_intent,
                     merchant_key_store.key.get_inner(),
+                    merchant_key_store.merchant_id.clone(),
                 )
             }))
             .map(|join_result| join_result.change_context(StorageError::DecryptionError))
@@ -579,6 +626,7 @@ impl<T: DatabaseStore> PaymentIntentInterface for crate::RouterStore<T> {
     #[instrument(skip_all)]
     async fn filter_payment_intents_by_time_range_constraints(
         &self,
+        state: &KeyManagerState,
         merchant_id: &str,
         time_range: &api_models::payments::TimeRange,
         merchant_key_store: &MerchantKeyStore,
@@ -587,6 +635,7 @@ impl<T: DatabaseStore> PaymentIntentInterface for crate::RouterStore<T> {
         // TODO: Remove this redundant function
         let payment_filters = (*time_range).into();
         self.filter_payment_intent_by_constraints(
+            state,
             merchant_id,
             &payment_filters,
             merchant_key_store,
@@ -599,6 +648,7 @@ impl<T: DatabaseStore> PaymentIntentInterface for crate::RouterStore<T> {
     #[instrument(skip_all)]
     async fn get_filtered_payment_intents_attempt(
         &self,
+        state: &KeyManagerState,
         merchant_id: &str,
         constraints: &PaymentIntentFetchConstraints,
         merchant_key_store: &MerchantKeyStore,
@@ -640,6 +690,7 @@ impl<T: DatabaseStore> PaymentIntentInterface for crate::RouterStore<T> {
                         // TODO: Fetch partial columns for this query since we only need some columns
                         let starting_at = self
                             .find_payment_intent_by_payment_id_merchant_id(
+                                state,
                                 starting_after_id,
                                 merchant_id,
                                 merchant_key_store,
@@ -658,6 +709,7 @@ impl<T: DatabaseStore> PaymentIntentInterface for crate::RouterStore<T> {
                         // TODO: Fetch partial columns for this query since we only need some columns
                         let ending_at = self
                             .find_payment_intent_by_payment_id_merchant_id(
+                                state,
                                 ending_before_id,
                                 merchant_id,
                                 merchant_key_store,
@@ -745,13 +797,17 @@ impl<T: DatabaseStore> PaymentIntentInterface for crate::RouterStore<T> {
             .await
             .map(|results| {
                 try_join_all(results.into_iter().map(|(pi, pa)| {
-                    PaymentIntent::convert_back(pi, merchant_key_store.key.get_inner()).map(
-                        |payment_intent| {
-                            payment_intent.map(|payment_intent| {
-                                (payment_intent, PaymentAttempt::from_storage_model(pa))
-                            })
-                        },
+                    PaymentIntent::convert_back(
+                        state,
+                        pi,
+                        merchant_key_store.key.get_inner(),
+                        merchant_id.to_string(),
                     )
+                    .map(|payment_intent| {
+                        payment_intent.map(|payment_intent| {
+                            (payment_intent, PaymentAttempt::from_storage_model(pa))
+                        })
+                    })
                 }))
                 .map(|join_result| join_result.change_context(StorageError::DecryptionError))
             })