Issue:
Bug: fix: Ephemeral key throwing internal server error





Pull request description:
## Type of Change
<!-- Put an `x` in the boxes that apply -->

- [x] Bugfix
- [ ] New feature
- [ ] Enhancement
- [ ] Refactoring
- [ ] Dependency updates

## Description
<!-- Describe your changes in detail -->
This fixes the Internal server error while trying to set ephemeral key on sanbox.

### Additional Changes

- [ ] This PR modifies the database schema
- [ ] This PR modifies application configuration/environment variables

<!-- 
Provide links to the files with corresponding changes.

Following are the paths where you can find config files:
1. `config`
2. `crates/router/src/configs`
3. `loadtest/config`
-->


## Motivation and Context
<!--
Why is this change required? What problem does it solve?
If it fixes an open issue, please link to the issue here.

If you don't have an issue, we'd recommend starting with one first so the PR
can focus on the implementation (unless its an obvious bug or documentation fix
that will have little conversation).
-->
So apparently when you are trying to use the `MSET` command in Redis, which is used to set multiple keys to multiple values in a single atomic operation. But on a setup where there are 2 or more redis clusters if the keys are being set on different clusters redis throws error.



## How did you test it?
<!--
Did you write an integration/unit/API test to verify the code changes?
Or did you test this change manually (provide relevant screenshots)?
-->


## Checklist
<!-- Put an `x` in the boxes that apply -->

- [x] I formatted the code `cargo +nightly fmt`
- [x] I addressed lints thrown by `cargo clippy`
- [x] I reviewed submitted code
- [ ] I added unit tests for my changes where possible
- [ ] I added a [CHANGELOG](/CHANGELOG.md) entry if applicable


Testing:

Patch:
diff --git a/crates/redis_interface/src/commands.rs b/crates/redis_interface/src/commands.rs
index 58d61225221..5626fd878b1 100644
--- a/crates/redis_interface/src/commands.rs
+++ b/crates/redis_interface/src/commands.rs
@@ -246,6 +246,25 @@ impl super::RedisConnectionPool {
             .await
     }
 
+    #[instrument(level = "DEBUG", skip(self))]
+    pub async fn serialize_and_set_multiple_hash_field_if_not_exist<V>(
+        &self,
+        kv: &[(&str, V)],
+        field: &str,
+    ) -> CustomResult<Vec<HsetnxReply>, errors::RedisError>
+    where
+        V: serde::Serialize + Debug,
+    {
+        let mut hsetnx: Vec<HsetnxReply> = Vec::with_capacity(kv.len());
+        for (key, val) in kv {
+            hsetnx.push(
+                self.serialize_and_set_hash_field_if_not_exist(key, field, val)
+                    .await?,
+            );
+        }
+        Ok(hsetnx)
+    }
+
     #[instrument(level = "DEBUG", skip(self))]
     pub async fn hscan(
         &self,
diff --git a/crates/router/src/db/ephemeral_key.rs b/crates/router/src/db/ephemeral_key.rs
index 094c74c4036..1768396afc8 100644
--- a/crates/router/src/db/ephemeral_key.rs
+++ b/crates/router/src/db/ephemeral_key.rs
@@ -22,9 +22,9 @@ pub trait EphemeralKeyInterface {
 }
 
 mod storage {
-    use common_utils::{date_time, ext_traits::StringExt};
+    use common_utils::date_time;
     use error_stack::ResultExt;
-    use redis_interface::MsetnxReply;
+    use redis_interface::HsetnxReply;
     use time::ext::NumericalDuration;
 
     use super::EphemeralKeyInterface;
@@ -32,7 +32,6 @@ mod storage {
         core::errors::{self, CustomResult},
         services::Store,
         types::storage::ephemeral_key::{EphemeralKey, EphemeralKeyNew},
-        utils,
     };
 
     #[async_trait::async_trait]
@@ -42,8 +41,8 @@ mod storage {
             new: EphemeralKeyNew,
             validity: i64,
         ) -> CustomResult<EphemeralKey, errors::StorageError> {
-            let secret_key = new.secret.to_string();
-            let id_key = new.id.to_string();
+            let secret_key = format!("epkey_{}", &new.secret);
+            let id_key = format!("epkey_{}", &new.id);
 
             let created_at = date_time::now();
             let expires = created_at.saturating_add(validity.hours());
@@ -55,21 +54,22 @@ mod storage {
                 merchant_id: new.merchant_id,
                 secret: new.secret,
             };
-            let redis_value = utils::Encode::<EphemeralKey>::encode_to_string_of_json(&created_ek)
-                .change_context(errors::StorageError::KVError)
-                .attach_printable("Unable to serialize ephemeral key")?;
 
-            let redis_map = vec![(&secret_key, &redis_value), (&id_key, &redis_value)];
             match self
                 .redis_conn
-                .set_multiple_keys_if_not_exist(redis_map)
+                .serialize_and_set_multiple_hash_field_if_not_exist(
+                    &[(&secret_key, &created_ek), (&id_key, &created_ek)],
+                    "ephkey",
+                )
                 .await
             {
-                Ok(MsetnxReply::KeysNotSet) => Err(errors::StorageError::DuplicateValue(
-                    "Ephemeral key already exists".to_string(),
-                )
-                .into()),
-                Ok(MsetnxReply::KeysSet) => {
+                Ok(v) if v.contains(&HsetnxReply::KeyNotSet) => {
+                    Err(errors::StorageError::DuplicateValue(
+                        "Ephemeral key already exists".to_string(),
+                    )
+                    .into())
+                }
+                Ok(_) => {
                     let expire_at = expires.assume_utc().unix_timestamp();
                     self.redis_conn
                         .set_expire_at(&secret_key, expire_at)
@@ -88,14 +88,10 @@ mod storage {
             &self,
             key: &str,
         ) -> CustomResult<EphemeralKey, errors::StorageError> {
-            let value: String = self
-                .redis_conn
-                .get_key(key)
+            let key = format!("epkey_{}", key);
+            self.redis_conn
+                .get_hash_field_and_deserialize(&key, "ephkey", "EphemeralKey")
                 .await
-                .change_context(errors::StorageError::KVError)?;
-
-            value
-                .parse_struct("EphemeralKey")
                 .change_context(errors::StorageError::KVError)
         }
         async fn delete_ephemeral_key(
@@ -105,12 +101,12 @@ mod storage {
             let ek = self.get_ephemeral_key(id).await?;
 
             self.redis_conn
-                .delete_key(&ek.id)
+                .delete_key(&format!("epkey_{}", &ek.id))
                 .await
                 .change_context(errors::StorageError::KVError)?;
 
             self.redis_conn
-                .delete_key(&ek.secret)
+                .delete_key(&format!("epkey_{}", &ek.secret))
                 .await
                 .change_context(errors::StorageError::KVError)?;
             Ok(ek)