feat(refunds): Add refunds diesel model support in V2 API (#7503)

Co-authored-by: hyperswitch-bot[bot] <148525504+hyperswitch-bot[bot]@users.noreply.github.com>
Co-authored-by: Hrithikesh <61539176+hrithikesh026@users.noreply.github.com>
This commit is contained in:
Amey Wale
2025-03-24 16:13:18 +05:30
committed by GitHub
parent 451d193137
commit bc8b940918
24 changed files with 915 additions and 41 deletions

View File

@ -33,12 +33,13 @@ payouts = ["api_models/payouts", "common_enums/payouts", "hyperswitch_connectors
payout_retry = ["payouts"]
recon = ["email", "api_models/recon"]
retry = []
v2 = ["customer_v2", "payment_methods_v2", "common_default", "api_models/v2", "diesel_models/v2", "hyperswitch_domain_models/v2", "storage_impl/v2", "kgraph_utils/v2", "common_utils/v2", "hyperswitch_connectors/v2","hyperswitch_interfaces/v2", "common_types/v2","revenue_recovery","scheduler/v2"]
v2 = ["customer_v2", "payment_methods_v2", "common_default", "api_models/v2", "diesel_models/v2", "hyperswitch_domain_models/v2", "storage_impl/v2", "kgraph_utils/v2", "common_utils/v2", "hyperswitch_connectors/v2","hyperswitch_interfaces/v2", "common_types/v2","revenue_recovery","refunds_v2","scheduler/v2"]
v1 = ["common_default", "api_models/v1", "diesel_models/v1", "hyperswitch_domain_models/v1", "storage_impl/v1", "hyperswitch_interfaces/v1", "kgraph_utils/v1", "common_utils/v1", "hyperswitch_connectors/v1", "common_types/v1","scheduler/v1"]
customer_v2 = ["api_models/customer_v2", "diesel_models/customer_v2", "hyperswitch_domain_models/customer_v2", "storage_impl/customer_v2"]
payment_methods_v2 = ["api_models/payment_methods_v2", "diesel_models/payment_methods_v2", "hyperswitch_domain_models/payment_methods_v2", "storage_impl/payment_methods_v2", "common_utils/payment_methods_v2"]
dynamic_routing = ["external_services/dynamic_routing", "storage_impl/dynamic_routing", "api_models/dynamic_routing"]
revenue_recovery =["api_models/revenue_recovery","hyperswitch_interfaces/revenue_recovery","hyperswitch_domain_models/revenue_recovery","hyperswitch_connectors/revenue_recovery"]
refunds_v2 = ["diesel_models/refunds_v2", "storage_impl/refunds_v2"]
# Partial Auth
# The feature reduces the overhead of the router authenticating the merchant for every request, and trusts on `x-merchant-id` header to be present in the request.

View File

@ -2667,6 +2667,7 @@ impl CaptureInterface for KafkaStore {
#[async_trait::async_trait]
impl RefundInterface for KafkaStore {
#[cfg(all(any(feature = "v1", feature = "v2"), not(feature = "refunds_v2")))]
async fn find_refund_by_internal_reference_id_merchant_id(
&self,
internal_reference_id: &str,
@ -2682,6 +2683,7 @@ impl RefundInterface for KafkaStore {
.await
}
#[cfg(all(any(feature = "v1", feature = "v2"), not(feature = "refunds_v2")))]
async fn find_refund_by_payment_id_merchant_id(
&self,
payment_id: &id_type::PaymentId,
@ -2693,6 +2695,7 @@ impl RefundInterface for KafkaStore {
.await
}
#[cfg(all(any(feature = "v1", feature = "v2"), not(feature = "refunds_v2")))]
async fn find_refund_by_merchant_id_refund_id(
&self,
merchant_id: &id_type::MerchantId,
@ -2704,6 +2707,7 @@ impl RefundInterface for KafkaStore {
.await
}
#[cfg(all(any(feature = "v1", feature = "v2"), not(feature = "refunds_v2")))]
async fn find_refund_by_merchant_id_connector_refund_id_connector(
&self,
merchant_id: &id_type::MerchantId,
@ -2742,6 +2746,7 @@ impl RefundInterface for KafkaStore {
Ok(refund)
}
#[cfg(all(any(feature = "v1", feature = "v2"), not(feature = "refunds_v2")))]
async fn find_refund_by_merchant_id_connector_transaction_id(
&self,
merchant_id: &id_type::MerchantId,
@ -2757,6 +2762,17 @@ impl RefundInterface for KafkaStore {
.await
}
#[cfg(all(feature = "v2", feature = "refunds_v2"))]
async fn find_refund_by_id(
&self,
id: &id_type::GlobalRefundId,
storage_scheme: MerchantStorageScheme,
) -> CustomResult<storage::Refund, errors::StorageError> {
self.diesel_store
.find_refund_by_id(id, storage_scheme)
.await
}
async fn insert_refund(
&self,
new: storage::RefundNew,
@ -2774,7 +2790,11 @@ impl RefundInterface for KafkaStore {
Ok(refund)
}
#[cfg(feature = "olap")]
#[cfg(all(
any(feature = "v1", feature = "v2"),
not(feature = "refunds_v2"),
feature = "olap"
))]
async fn filter_refund_by_constraints(
&self,
merchant_id: &id_type::MerchantId,
@ -2794,7 +2814,11 @@ impl RefundInterface for KafkaStore {
.await
}
#[cfg(feature = "olap")]
#[cfg(all(
any(feature = "v1", feature = "v2"),
not(feature = "refunds_v2"),
feature = "olap"
))]
async fn filter_refund_by_meta_constraints(
&self,
merchant_id: &id_type::MerchantId,
@ -2806,7 +2830,11 @@ impl RefundInterface for KafkaStore {
.await
}
#[cfg(feature = "olap")]
#[cfg(all(
any(feature = "v1", feature = "v2"),
not(feature = "refunds_v2"),
feature = "olap"
))]
async fn get_refund_status_with_count(
&self,
merchant_id: &id_type::MerchantId,
@ -2819,7 +2847,11 @@ impl RefundInterface for KafkaStore {
.await
}
#[cfg(feature = "olap")]
#[cfg(all(
any(feature = "v1", feature = "v2"),
not(feature = "refunds_v2"),
feature = "olap"
))]
async fn get_total_count_of_refunds(
&self,
merchant_id: &id_type::MerchantId,

View File

@ -17,6 +17,7 @@ const MAX_LIMIT: usize = 100;
#[async_trait::async_trait]
pub trait RefundInterface {
#[cfg(all(any(feature = "v1", feature = "v2"), not(feature = "refunds_v2")))]
async fn find_refund_by_internal_reference_id_merchant_id(
&self,
internal_reference_id: &str,
@ -24,6 +25,7 @@ pub trait RefundInterface {
storage_scheme: enums::MerchantStorageScheme,
) -> CustomResult<storage_types::Refund, errors::StorageError>;
#[cfg(all(any(feature = "v1", feature = "v2"), not(feature = "refunds_v2")))]
async fn find_refund_by_payment_id_merchant_id(
&self,
payment_id: &common_utils::id_type::PaymentId,
@ -31,6 +33,7 @@ pub trait RefundInterface {
storage_scheme: enums::MerchantStorageScheme,
) -> CustomResult<Vec<storage_types::Refund>, errors::StorageError>;
#[cfg(all(any(feature = "v1", feature = "v2"), not(feature = "refunds_v2")))]
async fn find_refund_by_merchant_id_refund_id(
&self,
merchant_id: &common_utils::id_type::MerchantId,
@ -38,6 +41,7 @@ pub trait RefundInterface {
storage_scheme: enums::MerchantStorageScheme,
) -> CustomResult<storage_types::Refund, errors::StorageError>;
#[cfg(all(any(feature = "v1", feature = "v2"), not(feature = "refunds_v2")))]
async fn find_refund_by_merchant_id_connector_refund_id_connector(
&self,
merchant_id: &common_utils::id_type::MerchantId,
@ -53,6 +57,7 @@ pub trait RefundInterface {
storage_scheme: enums::MerchantStorageScheme,
) -> CustomResult<storage_types::Refund, errors::StorageError>;
#[cfg(all(any(feature = "v1", feature = "v2"), not(feature = "refunds_v2")))]
async fn find_refund_by_merchant_id_connector_transaction_id(
&self,
merchant_id: &common_utils::id_type::MerchantId,
@ -60,13 +65,24 @@ pub trait RefundInterface {
storage_scheme: enums::MerchantStorageScheme,
) -> CustomResult<Vec<storage_types::Refund>, errors::StorageError>;
#[cfg(all(feature = "v2", feature = "refunds_v2"))]
async fn find_refund_by_id(
&self,
id: &common_utils::id_type::GlobalRefundId,
storage_scheme: enums::MerchantStorageScheme,
) -> CustomResult<storage_types::Refund, errors::StorageError>;
async fn insert_refund(
&self,
new: storage_types::RefundNew,
storage_scheme: enums::MerchantStorageScheme,
) -> CustomResult<storage_types::Refund, errors::StorageError>;
#[cfg(feature = "olap")]
#[cfg(all(
any(feature = "v1", feature = "v2"),
not(feature = "refunds_v2"),
feature = "olap"
))]
async fn filter_refund_by_constraints(
&self,
merchant_id: &common_utils::id_type::MerchantId,
@ -76,7 +92,11 @@ pub trait RefundInterface {
offset: i64,
) -> CustomResult<Vec<diesel_models::refund::Refund>, errors::StorageError>;
#[cfg(feature = "olap")]
#[cfg(all(
any(feature = "v1", feature = "v2"),
not(feature = "refunds_v2"),
feature = "olap"
))]
async fn filter_refund_by_meta_constraints(
&self,
merchant_id: &common_utils::id_type::MerchantId,
@ -84,7 +104,11 @@ pub trait RefundInterface {
storage_scheme: enums::MerchantStorageScheme,
) -> CustomResult<api_models::refunds::RefundListMetaData, errors::StorageError>;
#[cfg(feature = "olap")]
#[cfg(all(
any(feature = "v1", feature = "v2"),
not(feature = "refunds_v2"),
feature = "olap"
))]
async fn get_refund_status_with_count(
&self,
merchant_id: &common_utils::id_type::MerchantId,
@ -93,7 +117,11 @@ pub trait RefundInterface {
storage_scheme: enums::MerchantStorageScheme,
) -> CustomResult<Vec<(common_enums::RefundStatus, i64)>, errors::StorageError>;
#[cfg(feature = "olap")]
#[cfg(all(
any(feature = "v1", feature = "v2"),
not(feature = "refunds_v2"),
feature = "olap"
))]
async fn get_total_count_of_refunds(
&self,
merchant_id: &common_utils::id_type::MerchantId,
@ -320,6 +348,7 @@ mod storage {
};
#[async_trait::async_trait]
impl RefundInterface for Store {
#[cfg(all(any(feature = "v1", feature = "v2"), not(feature = "refunds_v2")))]
#[instrument(skip_all)]
async fn find_refund_by_internal_reference_id_merchant_id(
&self,
@ -376,6 +405,7 @@ mod storage {
}
}
#[cfg(all(any(feature = "v1", feature = "v2"), not(feature = "refunds_v2")))]
#[instrument(skip_all)]
async fn insert_refund(
&self,
@ -529,6 +559,20 @@ mod storage {
}
}
#[cfg(all(feature = "v2", feature = "refunds_v2"))]
#[instrument(skip_all)]
async fn insert_refund(
&self,
new: storage_types::RefundNew,
_storage_scheme: enums::MerchantStorageScheme,
) -> CustomResult<storage_types::Refund, errors::StorageError> {
let conn = connection::pg_connection_write(self).await?;
new.insert(&conn)
.await
.map_err(|error| report!(errors::StorageError::from(error)))
}
#[cfg(all(any(feature = "v1", feature = "v2"), not(feature = "refunds_v2")))]
#[instrument(skip_all)]
async fn find_refund_by_merchant_id_connector_transaction_id(
&self,
@ -588,6 +632,7 @@ mod storage {
}
}
#[cfg(all(any(feature = "v1", feature = "v2"), not(feature = "refunds_v2")))]
#[instrument(skip_all)]
async fn update_refund(
&self,
@ -652,6 +697,21 @@ mod storage {
}
}
#[cfg(all(feature = "v2", feature = "refunds_v2"))]
#[instrument(skip_all)]
async fn update_refund(
&self,
this: storage_types::Refund,
refund: storage_types::RefundUpdate,
_storage_scheme: enums::MerchantStorageScheme,
) -> CustomResult<storage_types::Refund, errors::StorageError> {
let conn = connection::pg_connection_write(self).await?;
this.update_with_id(&conn, refund)
.await
.map_err(|error| report!(errors::StorageError::from(error)))
}
#[cfg(all(any(feature = "v1", feature = "v2"), not(feature = "refunds_v2")))]
#[instrument(skip_all)]
async fn find_refund_by_merchant_id_refund_id(
&self,
@ -702,6 +762,7 @@ mod storage {
}
}
#[cfg(all(any(feature = "v1", feature = "v2"), not(feature = "refunds_v2")))]
#[instrument(skip_all)]
async fn find_refund_by_merchant_id_connector_refund_id_connector(
&self,
@ -760,6 +821,7 @@ mod storage {
}
}
#[cfg(all(any(feature = "v1", feature = "v2"), not(feature = "refunds_v2")))]
#[instrument(skip_all)]
async fn find_refund_by_payment_id_merchant_id(
&self,
@ -807,7 +869,24 @@ mod storage {
}
}
#[cfg(feature = "olap")]
#[cfg(all(feature = "v2", feature = "refunds_v2"))]
#[instrument(skip_all)]
async fn find_refund_by_id(
&self,
id: &common_utils::id_type::GlobalRefundId,
_storage_scheme: enums::MerchantStorageScheme,
) -> CustomResult<storage_types::Refund, errors::StorageError> {
let conn = connection::pg_connection_read(self).await?;
storage_types::Refund::find_by_global_id(&conn, id)
.await
.map_err(|error| report!(errors::StorageError::from(error)))
}
#[cfg(all(
any(feature = "v1", feature = "v2"),
not(feature = "refunds_v2"),
feature = "olap"
))]
#[instrument(skip_all)]
async fn filter_refund_by_constraints(
&self,
@ -829,7 +908,11 @@ mod storage {
.map_err(|error| report!(errors::StorageError::from(error)))
}
#[cfg(feature = "olap")]
#[cfg(all(
any(feature = "v1", feature = "v2"),
not(feature = "refunds_v2"),
feature = "olap"
))]
#[instrument(skip_all)]
async fn filter_refund_by_meta_constraints(
&self,
@ -843,7 +926,11 @@ mod storage {
.map_err(|error|report!(errors::StorageError::from(error)))
}
#[cfg(feature = "olap")]
#[cfg(all(
any(feature = "v1", feature = "v2"),
not(feature = "refunds_v2"),
feature = "olap"
))]
#[instrument(skip_all)]
async fn get_refund_status_with_count(
&self,
@ -858,7 +945,11 @@ mod storage {
.map_err(|error| report!(errors::StorageError::from(error)))
}
#[cfg(feature = "olap")]
#[cfg(all(
any(feature = "v1", feature = "v2"),
not(feature = "refunds_v2"),
feature = "olap"
))]
#[instrument(skip_all)]
async fn get_total_count_of_refunds(
&self,
@ -880,6 +971,7 @@ mod storage {
#[async_trait::async_trait]
impl RefundInterface for MockDb {
#[cfg(all(any(feature = "v1", feature = "v2"), not(feature = "refunds_v2")))]
async fn find_refund_by_internal_reference_id_merchant_id(
&self,
internal_reference_id: &str,
@ -899,6 +991,7 @@ impl RefundInterface for MockDb {
})
}
#[cfg(all(any(feature = "v1", feature = "v2"), not(feature = "refunds_v2")))]
async fn insert_refund(
&self,
new: storage_types::RefundNew,
@ -950,6 +1043,56 @@ impl RefundInterface for MockDb {
refunds.push(refund.clone());
Ok(refund)
}
#[cfg(all(feature = "v2", feature = "refunds_v2"))]
async fn insert_refund(
&self,
new: storage_types::RefundNew,
_storage_scheme: enums::MerchantStorageScheme,
) -> CustomResult<storage_types::Refund, errors::StorageError> {
let mut refunds = self.refunds.lock().await;
let current_time = common_utils::date_time::now();
let refund = storage_types::Refund {
id: new.id,
merchant_reference_id: new.merchant_reference_id,
payment_id: new.payment_id,
merchant_id: new.merchant_id,
attempt_id: new.attempt_id,
connector_transaction_id: new.connector_transaction_id,
connector: new.connector,
connector_refund_id: new.connector_refund_id,
external_reference_id: new.external_reference_id,
refund_type: new.refund_type,
total_amount: new.total_amount,
currency: new.currency,
refund_amount: new.refund_amount,
refund_status: new.refund_status,
sent_to_gateway: new.sent_to_gateway,
refund_error_message: None,
refund_error_code: None,
metadata: new.metadata,
refund_arn: new.refund_arn.clone(),
created_at: new.created_at,
modified_at: current_time,
description: new.description,
refund_reason: new.refund_reason.clone(),
profile_id: new.profile_id,
updated_by: new.updated_by,
connector_id: new.connector_id,
charges: new.charges,
split_refunds: new.split_refunds,
organization_id: new.organization_id,
unified_code: None,
unified_message: None,
processor_refund_data: new.processor_refund_data.clone(),
processor_transaction_data: new.processor_transaction_data.clone(),
};
refunds.push(refund.clone());
Ok(refund)
}
#[cfg(all(any(feature = "v1", feature = "v2"), not(feature = "refunds_v2")))]
async fn find_refund_by_merchant_id_connector_transaction_id(
&self,
merchant_id: &common_utils::id_type::MerchantId,
@ -968,6 +1111,7 @@ impl RefundInterface for MockDb {
.collect::<Vec<_>>())
}
#[cfg(all(any(feature = "v1", feature = "v2"), not(feature = "refunds_v2")))]
async fn update_refund(
&self,
this: storage_types::Refund,
@ -990,6 +1134,30 @@ impl RefundInterface for MockDb {
})
}
#[cfg(all(feature = "v2", feature = "refunds_v2"))]
async fn update_refund(
&self,
this: storage_types::Refund,
refund: storage_types::RefundUpdate,
_storage_scheme: enums::MerchantStorageScheme,
) -> CustomResult<storage_types::Refund, errors::StorageError> {
self.refunds
.lock()
.await
.iter_mut()
.find(|refund| this.merchant_reference_id == refund.merchant_reference_id)
.map(|r| {
let refund_updated = RefundUpdateInternal::from(refund).create_refund(r.clone());
*r = refund_updated.clone();
refund_updated
})
.ok_or_else(|| {
errors::StorageError::ValueNotFound("cannot find refund to update".to_string())
.into()
})
}
#[cfg(all(any(feature = "v1", feature = "v2"), not(feature = "refunds_v2")))]
async fn find_refund_by_merchant_id_refund_id(
&self,
merchant_id: &common_utils::id_type::MerchantId,
@ -1007,6 +1175,7 @@ impl RefundInterface for MockDb {
})
}
#[cfg(all(any(feature = "v1", feature = "v2"), not(feature = "refunds_v2")))]
async fn find_refund_by_merchant_id_connector_refund_id_connector(
&self,
merchant_id: &common_utils::id_type::MerchantId,
@ -1032,6 +1201,7 @@ impl RefundInterface for MockDb {
})
}
#[cfg(all(any(feature = "v1", feature = "v2"), not(feature = "refunds_v2")))]
async fn find_refund_by_payment_id_merchant_id(
&self,
payment_id: &common_utils::id_type::PaymentId,
@ -1047,7 +1217,28 @@ impl RefundInterface for MockDb {
.collect::<Vec<_>>())
}
#[cfg(feature = "olap")]
#[cfg(all(feature = "v2", feature = "refunds_v2"))]
async fn find_refund_by_id(
&self,
id: &common_utils::id_type::GlobalRefundId,
_storage_scheme: enums::MerchantStorageScheme,
) -> CustomResult<storage_types::Refund, errors::StorageError> {
let refunds = self.refunds.lock().await;
refunds
.iter()
.find(|refund| refund.id == *id)
.cloned()
.ok_or_else(|| {
errors::StorageError::DatabaseError(DatabaseError::NotFound.into()).into()
})
}
#[cfg(all(
any(feature = "v1", feature = "v2"),
not(feature = "refunds_v2"),
feature = "olap"
))]
async fn filter_refund_by_constraints(
&self,
merchant_id: &common_utils::id_type::MerchantId,
@ -1162,7 +1353,11 @@ impl RefundInterface for MockDb {
Ok(filtered_refunds)
}
#[cfg(feature = "olap")]
#[cfg(all(
any(feature = "v1", feature = "v2"),
not(feature = "refunds_v2"),
feature = "olap"
))]
async fn filter_refund_by_meta_constraints(
&self,
_merchant_id: &common_utils::id_type::MerchantId,
@ -1209,7 +1404,11 @@ impl RefundInterface for MockDb {
Ok(refund_meta_data)
}
#[cfg(feature = "olap")]
#[cfg(all(
any(feature = "v1", feature = "v2"),
not(feature = "refunds_v2"),
feature = "olap"
))]
async fn get_refund_status_with_count(
&self,
_merchant_id: &common_utils::id_type::MerchantId,
@ -1255,7 +1454,11 @@ impl RefundInterface for MockDb {
Ok(result)
}
#[cfg(feature = "olap")]
#[cfg(all(
any(feature = "v1", feature = "v2"),
not(feature = "refunds_v2"),
feature = "olap"
))]
async fn get_total_count_of_refunds(
&self,
merchant_id: &common_utils::id_type::MerchantId,

View File

@ -5,6 +5,9 @@ use common_utils::{
use diesel_models::{enums as storage_enums, refund::Refund};
use time::OffsetDateTime;
use crate::events;
#[cfg(feature = "v1")]
#[derive(serde::Serialize, Debug)]
pub struct KafkaRefund<'a> {
pub internal_reference_id: &'a String,
@ -35,6 +38,7 @@ pub struct KafkaRefund<'a> {
pub organization_id: &'a id_type::OrganizationId,
}
#[cfg(feature = "v1")]
impl<'a> KafkaRefund<'a> {
pub fn from_storage(refund: &'a Refund) -> Self {
Self {
@ -66,6 +70,70 @@ impl<'a> KafkaRefund<'a> {
}
}
#[cfg(feature = "v2")]
#[derive(serde::Serialize, Debug)]
pub struct KafkaRefund<'a> {
pub id: &'a id_type::GlobalRefundId,
pub merchant_reference_id: &'a id_type::RefundReferenceId,
pub payment_id: &'a id_type::GlobalPaymentId,
pub merchant_id: &'a id_type::MerchantId,
pub connector_transaction_id: &'a String,
pub connector: &'a String,
pub connector_refund_id: Option<&'a String>,
pub external_reference_id: Option<&'a String>,
pub refund_type: &'a storage_enums::RefundType,
pub total_amount: &'a MinorUnit,
pub currency: &'a storage_enums::Currency,
pub refund_amount: &'a MinorUnit,
pub refund_status: &'a storage_enums::RefundStatus,
pub sent_to_gateway: &'a bool,
pub refund_error_message: Option<&'a String>,
pub refund_arn: Option<&'a String>,
#[serde(default, with = "time::serde::timestamp")]
pub created_at: OffsetDateTime,
#[serde(default, with = "time::serde::timestamp")]
pub modified_at: OffsetDateTime,
pub description: Option<&'a String>,
pub attempt_id: &'a id_type::GlobalAttemptId,
pub refund_reason: Option<&'a String>,
pub refund_error_code: Option<&'a String>,
pub profile_id: Option<&'a id_type::ProfileId>,
pub organization_id: &'a id_type::OrganizationId,
}
#[cfg(feature = "v2")]
impl<'a> KafkaRefund<'a> {
pub fn from_storage(refund: &'a Refund) -> Self {
Self {
id: &refund.id,
merchant_reference_id: &refund.merchant_reference_id,
payment_id: &refund.payment_id,
merchant_id: &refund.merchant_id,
connector_transaction_id: refund.get_connector_transaction_id(),
connector: &refund.connector,
connector_refund_id: refund.get_optional_connector_refund_id(),
external_reference_id: refund.external_reference_id.as_ref(),
refund_type: &refund.refund_type,
total_amount: &refund.total_amount,
currency: &refund.currency,
refund_amount: &refund.refund_amount,
refund_status: &refund.refund_status,
sent_to_gateway: &refund.sent_to_gateway,
refund_error_message: refund.refund_error_message.as_ref(),
refund_arn: refund.refund_arn.as_ref(),
created_at: refund.created_at.assume_utc(),
modified_at: refund.modified_at.assume_utc(),
description: refund.description.as_ref(),
attempt_id: &refund.attempt_id,
refund_reason: refund.refund_reason.as_ref(),
refund_error_code: refund.refund_error_code.as_ref(),
profile_id: refund.profile_id.as_ref(),
organization_id: &refund.organization_id,
}
}
}
#[cfg(feature = "v1")]
impl super::KafkaMessage for KafkaRefund<'_> {
fn key(&self) -> String {
format!(
@ -77,7 +145,24 @@ impl super::KafkaMessage for KafkaRefund<'_> {
)
}
fn event_type(&self) -> crate::events::EventType {
crate::events::EventType::Refund
fn event_type(&self) -> events::EventType {
events::EventType::Refund
}
}
#[cfg(feature = "v2")]
impl super::KafkaMessage for KafkaRefund<'_> {
fn key(&self) -> String {
format!(
"{}_{}_{}_{}",
self.merchant_id.get_string_repr(),
self.payment_id.get_string_repr(),
self.attempt_id.get_string_repr(),
self.merchant_reference_id.get_string_repr()
)
}
fn event_type(&self) -> events::EventType {
events::EventType::Refund
}
}

View File

@ -5,6 +5,9 @@ use common_utils::{
use diesel_models::{enums as storage_enums, refund::Refund};
use time::OffsetDateTime;
use crate::events;
#[cfg(feature = "v1")]
#[serde_with::skip_serializing_none]
#[derive(serde::Serialize, Debug)]
pub struct KafkaRefundEvent<'a> {
@ -36,6 +39,7 @@ pub struct KafkaRefundEvent<'a> {
pub organization_id: &'a id_type::OrganizationId,
}
#[cfg(feature = "v1")]
impl<'a> KafkaRefundEvent<'a> {
pub fn from_storage(refund: &'a Refund) -> Self {
Self {
@ -67,6 +71,71 @@ impl<'a> KafkaRefundEvent<'a> {
}
}
#[cfg(feature = "v2")]
#[serde_with::skip_serializing_none]
#[derive(serde::Serialize, Debug)]
pub struct KafkaRefundEvent<'a> {
pub id: &'a id_type::GlobalRefundId,
pub merchant_reference_id: &'a id_type::RefundReferenceId,
pub payment_id: &'a id_type::GlobalPaymentId,
pub merchant_id: &'a id_type::MerchantId,
pub connector_transaction_id: &'a String,
pub connector: &'a String,
pub connector_refund_id: Option<&'a String>,
pub external_reference_id: Option<&'a String>,
pub refund_type: &'a storage_enums::RefundType,
pub total_amount: &'a MinorUnit,
pub currency: &'a storage_enums::Currency,
pub refund_amount: &'a MinorUnit,
pub refund_status: &'a storage_enums::RefundStatus,
pub sent_to_gateway: &'a bool,
pub refund_error_message: Option<&'a String>,
pub refund_arn: Option<&'a String>,
#[serde(default, with = "time::serde::timestamp::nanoseconds")]
pub created_at: OffsetDateTime,
#[serde(default, with = "time::serde::timestamp::nanoseconds")]
pub modified_at: OffsetDateTime,
pub description: Option<&'a String>,
pub attempt_id: &'a id_type::GlobalAttemptId,
pub refund_reason: Option<&'a String>,
pub refund_error_code: Option<&'a String>,
pub profile_id: Option<&'a id_type::ProfileId>,
pub organization_id: &'a id_type::OrganizationId,
}
#[cfg(feature = "v2")]
impl<'a> KafkaRefundEvent<'a> {
pub fn from_storage(refund: &'a Refund) -> Self {
Self {
id: &refund.id,
merchant_reference_id: &refund.merchant_reference_id,
payment_id: &refund.payment_id,
merchant_id: &refund.merchant_id,
connector_transaction_id: refund.get_connector_transaction_id(),
connector: &refund.connector,
connector_refund_id: refund.get_optional_connector_refund_id(),
external_reference_id: refund.external_reference_id.as_ref(),
refund_type: &refund.refund_type,
total_amount: &refund.total_amount,
currency: &refund.currency,
refund_amount: &refund.refund_amount,
refund_status: &refund.refund_status,
sent_to_gateway: &refund.sent_to_gateway,
refund_error_message: refund.refund_error_message.as_ref(),
refund_arn: refund.refund_arn.as_ref(),
created_at: refund.created_at.assume_utc(),
modified_at: refund.modified_at.assume_utc(),
description: refund.description.as_ref(),
attempt_id: &refund.attempt_id,
refund_reason: refund.refund_reason.as_ref(),
refund_error_code: refund.refund_error_code.as_ref(),
profile_id: refund.profile_id.as_ref(),
organization_id: &refund.organization_id,
}
}
}
#[cfg(feature = "v1")]
impl super::KafkaMessage for KafkaRefundEvent<'_> {
fn key(&self) -> String {
format!(
@ -77,8 +146,23 @@ impl super::KafkaMessage for KafkaRefundEvent<'_> {
self.refund_id
)
}
fn event_type(&self) -> crate::events::EventType {
crate::events::EventType::Refund
fn event_type(&self) -> events::EventType {
events::EventType::Refund
}
}
#[cfg(feature = "v2")]
impl super::KafkaMessage for KafkaRefundEvent<'_> {
fn key(&self) -> String {
format!(
"{}_{}_{}_{}",
self.merchant_id.get_string_repr(),
self.payment_id.get_string_repr(),
self.attempt_id.get_string_repr(),
self.merchant_reference_id.get_string_repr()
)
}
fn event_type(&self) -> events::EventType {
events::EventType::Refund
}
}

View File

@ -18,6 +18,7 @@ use crate::{connection::PgPooledConn, logger};
#[async_trait::async_trait]
pub trait RefundDbExt: Sized {
#[cfg(all(any(feature = "v1", feature = "v2"), not(feature = "refunds_v2")))]
async fn filter_by_constraints(
conn: &PgPooledConn,
merchant_id: &common_utils::id_type::MerchantId,
@ -26,18 +27,21 @@ pub trait RefundDbExt: Sized {
offset: i64,
) -> CustomResult<Vec<Self>, errors::DatabaseError>;
#[cfg(all(any(feature = "v1", feature = "v2"), not(feature = "refunds_v2")))]
async fn filter_by_meta_constraints(
conn: &PgPooledConn,
merchant_id: &common_utils::id_type::MerchantId,
refund_list_details: &common_utils::types::TimeRange,
) -> CustomResult<api_models::refunds::RefundListMetaData, errors::DatabaseError>;
#[cfg(all(any(feature = "v1", feature = "v2"), not(feature = "refunds_v2")))]
async fn get_refunds_count(
conn: &PgPooledConn,
merchant_id: &common_utils::id_type::MerchantId,
refund_list_details: &refunds::RefundListConstraints,
) -> CustomResult<i64, errors::DatabaseError>;
#[cfg(all(any(feature = "v1", feature = "v2"), not(feature = "refunds_v2")))]
async fn get_refund_status_with_count(
conn: &PgPooledConn,
merchant_id: &common_utils::id_type::MerchantId,
@ -48,6 +52,7 @@ pub trait RefundDbExt: Sized {
#[async_trait::async_trait]
impl RefundDbExt for Refund {
#[cfg(all(any(feature = "v1", feature = "v2"), not(feature = "refunds_v2")))]
async fn filter_by_constraints(
conn: &PgPooledConn,
merchant_id: &common_utils::id_type::MerchantId,
@ -159,6 +164,7 @@ impl RefundDbExt for Refund {
.attach_printable_lazy(|| "Error filtering records by predicate")
}
#[cfg(all(any(feature = "v1", feature = "v2"), not(feature = "refunds_v2")))]
async fn filter_by_meta_constraints(
conn: &PgPooledConn,
merchant_id: &common_utils::id_type::MerchantId,
@ -214,6 +220,7 @@ impl RefundDbExt for Refund {
Ok(meta)
}
#[cfg(all(any(feature = "v1", feature = "v2"), not(feature = "refunds_v2")))]
async fn get_refunds_count(
conn: &PgPooledConn,
merchant_id: &common_utils::id_type::MerchantId,
@ -302,6 +309,7 @@ impl RefundDbExt for Refund {
.attach_printable_lazy(|| "Error filtering count of refunds")
}
#[cfg(all(any(feature = "v1", feature = "v2"), not(feature = "refunds_v2")))]
async fn get_refund_status_with_count(
conn: &PgPooledConn,
merchant_id: &common_utils::id_type::MerchantId,