Issue:
Bug: [FIX] empty list of payment attempt on payments retrieve



When you do a `PaymentsRetrieve` with a KV enabled merchant the `PaymentAttempts` list will be empty which is not expected

Pull request description:
## Type of Change
<!-- Put an `x` in the boxes that apply -->
- [x] Bugfix

## Description
<!-- Describe your changes in detail -->
This fixes payments attempts being empty on `PaymentsRetrieve`

## Motivation and Context
<!--
Why is this change required? What problem does it solve?
If it fixes an open issue, please link to the issue here.

If you don't have an issue, we'd recommend starting with one first so the PR
can focus on the implementation (unless it is an obvious bug or documentation fix
that will have little conversation).
-->
This fixes PaymentAttempts being empty on a case where data is directly inserted into the DB or the TTL has expired on Redis.

## 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)?
-->
- Make a payment.
- Do `PaymentsRetrieve` with `expand_attempts=true`
```bash
curl --location 'http://localhost:8080/payments/pay_QJ9r33h2IiJz15brygDm?expand_attempts=true' \
--header 'Accept: application/json' \
--header 'api-key: dev_6GYF6ws2zde4cDNPtKRKdLbYaY1Ekz3MtH2S9B8Zkb0aZIuXh4NlWICzdw5kTmHY'**
```


## 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

Testing:

- Make a payment.
- Do `PaymentsRetrieve` with `expand_attempts=true`
```bash
curl --location 'http://localhost:8080/payments/pay_QJ9r33h2IiJz15brygDm?expand_attempts=true' \
--header 'Accept: application/json' \
--header 'api-key: dev_6GYF6ws2zde4cDNPtKRKdLbYaY1Ekz3MtH2S9B8Zkb0aZIuXh4NlWICzdw5kTmHY'**
```

Patch:
diff --git a/crates/storage_impl/src/payments/payment_attempt.rs b/crates/storage_impl/src/payments/payment_attempt.rs
index f8f752c6bc8..ce2c46bfe1d 100644
--- a/crates/storage_impl/src/payments/payment_attempt.rs
+++ b/crates/storage_impl/src/payments/payment_attempt.rs
@@ -931,12 +931,23 @@ impl<T: DatabaseStore> PaymentAttemptInterface for KVRouterStore<T> {
             }
             MerchantStorageScheme::RedisKv => {
                 let key = format!("mid_{merchant_id}_pid_{payment_id}");
-
-                kv_wrapper(self, KvOperation::<DieselPaymentAttempt>::Scan("pa_*"), key)
-                    .await
-                    .change_context(errors::StorageError::KVError)?
-                    .try_into_scan()
-                    .change_context(errors::StorageError::KVError)
+                Box::pin(try_redis_get_else_try_database_get(
+                    async {
+                        kv_wrapper(self, KvOperation::<DieselPaymentAttempt>::Scan("pa_*"), key)
+                            .await?
+                            .try_into_scan()
+                    },
+                    || async {
+                        self.router_store
+                            .find_attempts_by_merchant_id_payment_id(
+                                merchant_id,
+                                payment_id,
+                                storage_scheme,
+                            )
+                            .await
+                    },
+                ))
+                .await
             }
         }
     }
diff --git a/crates/storage_impl/src/redis/kv_store.rs b/crates/storage_impl/src/redis/kv_store.rs
index 9339b11a9b9..ad57ad403d4 100644
--- a/crates/storage_impl/src/redis/kv_store.rs
+++ b/crates/storage_impl/src/redis/kv_store.rs
@@ -131,7 +131,16 @@ where
             }
 
             KvOperation::Scan(pattern) => {
-                let result: Vec<T> = redis_conn.hscan_and_deserialize(key, pattern, None).await?;
+                let result: Vec<T> = redis_conn
+                    .hscan_and_deserialize(key, pattern, None)
+                    .await
+                    .and_then(|result| {
+                        if result.is_empty() {
+                            Err(RedisError::NotFound).into_report()
+                        } else {
+                            Ok(result)
+                        }
+                    })?;
                 Ok(KvResult::Scan(result))
             }