diff --git a/crates/router/src/core/payments.rs b/crates/router/src/core/payments.rs index 50dfca86ca..0f81ac30f5 100644 --- a/crates/router/src/core/payments.rs +++ b/crates/router/src/core/payments.rs @@ -684,9 +684,13 @@ pub async fn list_payments( merchant: storage::MerchantAccount, constraints: api::PaymentListConstraints, ) -> RouterResponse { + use futures::stream::StreamExt; + + use crate::types::transformers::ForeignFrom; + helpers::validate_payment_list_request(&constraints)?; let merchant_id = &merchant.merchant_id; - let payment_intent = + let payment_intents = helpers::filter_by_constraints(db, &constraints, merchant_id, merchant.storage_scheme) .await .map_err(|err| { @@ -696,10 +700,24 @@ pub async fn list_payments( ) })?; - let data: Vec = payment_intent - .into_iter() - .map(types::transformers::ForeignInto::foreign_into) - .collect(); + let pi = futures::stream::iter(payment_intents) + .filter_map(|pi| async { + let pa = db + .find_payment_attempt_by_payment_id_merchant_id( + &pi.payment_id, + merchant_id, + // since OLAP doesn't have KV. Force to get the data from PSQL. + storage_enums::MerchantStorageScheme::PostgresOnly, + ) + .await + .ok()?; + Some((pi, pa)) + }) + .collect::>() + .await; + + let data: Vec = pi.into_iter().map(ForeignFrom::foreign_from).collect(); + Ok(services::ApplicationResponse::Json( api::PaymentListResponse { size: data.len(), diff --git a/crates/router/src/core/payments/transformers.rs b/crates/router/src/core/payments/transformers.rs index 1889ecabe8..2c23c0fbe0 100644 --- a/crates/router/src/core/payments/transformers.rs +++ b/crates/router/src/core/payments/transformers.rs @@ -15,7 +15,7 @@ use crate::{ types::{ self, api, storage::{self, enums}, - transformers::ForeignInto, + transformers::{ForeignFrom, ForeignInto}, }, utils::{OptionExt, ValueExt}, }; @@ -399,6 +399,30 @@ where }) } +impl ForeignFrom<(storage::PaymentIntent, storage::PaymentAttempt)> for api::PaymentsResponse { + fn foreign_from(item: (storage::PaymentIntent, storage::PaymentAttempt)) -> Self { + let pi = item.0; + let pa = item.1; + Self { + payment_id: Some(pi.payment_id), + merchant_id: Some(pi.merchant_id), + status: pi.status.foreign_into(), + amount: pi.amount, + amount_capturable: pi.amount_captured, + client_secret: pi.client_secret.map(|s| s.into()), + created: Some(pi.created_at), + currency: pi.currency.map(|c| c.to_string()).unwrap_or_default(), + description: pi.description, + metadata: pi.metadata, + customer_id: pi.customer_id, + connector: pa.connector, + payment_method: pa.payment_method.map(ForeignInto::foreign_into), + payment_method_type: pa.payment_method_type.map(ForeignInto::foreign_into), + ..Default::default() + } + } +} + impl TryFrom> for types::PaymentsAuthorizeData { type Error = error_stack::Report; diff --git a/crates/router/src/types/api/payments.rs b/crates/router/src/types/api/payments.rs index 047c9519c8..0f9216a96a 100644 --- a/crates/router/src/types/api/payments.rs +++ b/crates/router/src/types/api/payments.rs @@ -16,10 +16,7 @@ use time::PrimitiveDateTime; use crate::{ core::errors, services::api, - types::{ - self, api as api_types, storage, - transformers::{ForeignFrom, ForeignInto}, - }, + types::{self, api as api_types}, }; pub(crate) trait PaymentsRequestExt { @@ -119,26 +116,6 @@ impl MandateValidationFieldsExt for MandateValidationFields { } } -impl ForeignFrom for PaymentsResponse { - fn foreign_from(item: storage::PaymentIntent) -> Self { - let item = item; - Self { - payment_id: Some(item.payment_id), - merchant_id: Some(item.merchant_id), - status: item.status.foreign_into(), - amount: item.amount, - amount_capturable: item.amount_captured, - client_secret: item.client_secret.map(|s| s.into()), - created: Some(item.created_at), - currency: item.currency.map(|c| c.to_string()).unwrap_or_default(), - description: item.description, - metadata: item.metadata, - customer_id: item.customer_id, - ..Default::default() - } - } -} - // Extract only the last 4 digits of card pub trait PaymentAuthorize: