Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 0 additions & 8 deletions crates/data_models/src/mandates.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ use time::PrimitiveDateTime;
#[serde(rename_all = "snake_case")]
pub struct MandateDetails {
pub update_mandate_id: Option<String>,
pub mandate_type: Option<MandateDataType>,
}

#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
Expand All @@ -23,13 +22,6 @@ pub enum MandateDataType {
MultiUse(Option<MandateAmountData>),
}

#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
#[serde(rename_all = "snake_case")]
#[serde(untagged)]
pub enum MandateTypeDetails {
MandateType(MandateDataType),
MandateDetails(MandateDetails),
}
#[derive(Clone, Debug, serde::Serialize, serde::Deserialize, PartialEq, Eq)]
pub struct MandateAmountData {
pub amount: i64,
Expand Down
12 changes: 9 additions & 3 deletions crates/data_models/src/payments/payment_attempt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,11 @@ use serde::{Deserialize, Serialize};
use time::PrimitiveDateTime;

use super::PaymentIntent;
use crate::{errors, mandates::MandateTypeDetails, ForeignIDRef};
use crate::{
errors,
mandates::{MandateDataType, MandateDetails},
ForeignIDRef,
};

#[async_trait::async_trait]
pub trait PaymentAttemptInterface {
Expand Down Expand Up @@ -143,7 +147,7 @@ pub struct PaymentAttempt {
pub straight_through_algorithm: Option<serde_json::Value>,
pub preprocessing_step_id: Option<String>,
// providing a location to store mandate details intermediately for transaction
pub mandate_details: Option<MandateTypeDetails>,
pub mandate_details: Option<MandateDataType>,
pub error_reason: Option<String>,
pub multiple_capture_count: Option<i16>,
// reference to the payment at connector side
Expand All @@ -155,6 +159,7 @@ pub struct PaymentAttempt {
pub merchant_connector_id: Option<String>,
pub unified_code: Option<String>,
pub unified_message: Option<String>,
pub mandate_data: Option<MandateDetails>,
}

impl PaymentAttempt {
Expand Down Expand Up @@ -221,7 +226,7 @@ pub struct PaymentAttemptNew {
pub business_sub_label: Option<String>,
pub straight_through_algorithm: Option<serde_json::Value>,
pub preprocessing_step_id: Option<String>,
pub mandate_details: Option<MandateTypeDetails>,
pub mandate_details: Option<MandateDataType>,
pub error_reason: Option<String>,
pub connector_response_reference_id: Option<String>,
pub multiple_capture_count: Option<i16>,
Expand All @@ -232,6 +237,7 @@ pub struct PaymentAttemptNew {
pub merchant_connector_id: Option<String>,
pub unified_code: Option<String>,
pub unified_message: Option<String>,
pub mandate_data: Option<MandateDetails>,
}

impl PaymentAttemptNew {
Expand Down
29 changes: 8 additions & 21 deletions crates/diesel_models/src/enums.rs
Original file line number Diff line number Diff line change
Expand Up @@ -174,20 +174,8 @@ use diesel::{
#[serde(rename_all = "snake_case")]
pub struct MandateDetails {
pub update_mandate_id: Option<String>,
pub mandate_type: Option<MandateDataType>,
}

#[derive(
serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq, FromSqlRow, AsExpression,
)]
#[diesel(sql_type = Jsonb)]
#[serde(rename_all = "snake_case")]
pub enum MandateDataType {
SingleUse(MandateAmountData),
MultiUse(Option<MandateAmountData>),
}

impl<DB: Backend> FromSql<Jsonb, DB> for MandateDataType
impl<DB: Backend> FromSql<Jsonb, DB> for MandateDetails
where
serde_json::Value: FromSql<Jsonb, DB>,
{
Expand All @@ -197,7 +185,7 @@ where
}
}

impl ToSql<Jsonb, diesel::pg::Pg> for MandateDataType
impl ToSql<Jsonb, diesel::pg::Pg> for MandateDetails
where
serde_json::Value: ToSql<Jsonb, diesel::pg::Pg>,
{
Expand All @@ -210,19 +198,17 @@ where
<serde_json::Value as ToSql<Jsonb, diesel::pg::Pg>>::to_sql(&value, &mut out.reborrow())
}
}

#[derive(
serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq, FromSqlRow, AsExpression,
)]
#[diesel(sql_type = Jsonb)]
#[serde(untagged)]
#[serde(rename_all = "snake_case")]
pub enum MandateTypeDetails {
MandateType(MandateDataType),
MandateDetails(MandateDetails),
pub enum MandateDataType {
SingleUse(MandateAmountData),
MultiUse(Option<MandateAmountData>),
}

impl<DB: Backend> FromSql<Jsonb, DB> for MandateTypeDetails
impl<DB: Backend> FromSql<Jsonb, DB> for MandateDataType
where
serde_json::Value: FromSql<Jsonb, DB>,
{
Expand All @@ -231,7 +217,8 @@ where
Ok(serde_json::from_value(value)?)
}
}
impl ToSql<Jsonb, diesel::pg::Pg> for MandateTypeDetails

impl ToSql<Jsonb, diesel::pg::Pg> for MandateDataType
where
serde_json::Value: ToSql<Jsonb, diesel::pg::Pg>,
{
Expand Down
6 changes: 4 additions & 2 deletions crates/diesel_models/src/payment_attempt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ pub struct PaymentAttempt {
pub straight_through_algorithm: Option<serde_json::Value>,
pub preprocessing_step_id: Option<String>,
// providing a location to store mandate details intermediately for transaction
pub mandate_details: Option<storage_enums::MandateTypeDetails>,
pub mandate_details: Option<storage_enums::MandateDataType>,
pub error_reason: Option<String>,
pub multiple_capture_count: Option<i16>,
// reference to the payment at connector side
Expand All @@ -64,6 +64,7 @@ pub struct PaymentAttempt {
pub unified_code: Option<String>,
pub unified_message: Option<String>,
pub net_amount: Option<i64>,
pub mandate_data: Option<storage_enums::MandateDetails>,
}

impl PaymentAttempt {
Expand Down Expand Up @@ -126,7 +127,7 @@ pub struct PaymentAttemptNew {
pub business_sub_label: Option<String>,
pub straight_through_algorithm: Option<serde_json::Value>,
pub preprocessing_step_id: Option<String>,
pub mandate_details: Option<storage_enums::MandateTypeDetails>,
pub mandate_details: Option<storage_enums::MandateDataType>,
pub error_reason: Option<String>,
pub connector_response_reference_id: Option<String>,
pub multiple_capture_count: Option<i16>,
Expand All @@ -138,6 +139,7 @@ pub struct PaymentAttemptNew {
pub unified_code: Option<String>,
pub unified_message: Option<String>,
pub net_amount: Option<i64>,
pub mandate_data: Option<storage_enums::MandateDetails>,
}

impl PaymentAttemptNew {
Expand Down
1 change: 1 addition & 0 deletions crates/diesel_models/src/schema.rs
Original file line number Diff line number Diff line change
Expand Up @@ -688,6 +688,7 @@ diesel::table! {
#[max_length = 1024]
unified_message -> Nullable<Varchar>,
net_amount -> Nullable<Int8>,
mandate_data -> Nullable<Jsonb>,
}
}

Expand Down
10 changes: 8 additions & 2 deletions crates/diesel_models/src/user/sample_data.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,11 @@ use common_enums::{
use serde::{Deserialize, Serialize};
use time::PrimitiveDateTime;

use crate::{enums::MandateTypeDetails, schema::payment_attempt, PaymentAttemptNew};
use crate::{
enums::{MandateDataType, MandateDetails},
schema::payment_attempt,
PaymentAttemptNew,
};

#[derive(
Clone, Debug, Default, diesel::Insertable, router_derive::DebugAsDisplay, Serialize, Deserialize,
Expand Down Expand Up @@ -50,7 +54,7 @@ pub struct PaymentAttemptBatchNew {
pub business_sub_label: Option<String>,
pub straight_through_algorithm: Option<serde_json::Value>,
pub preprocessing_step_id: Option<String>,
pub mandate_details: Option<MandateTypeDetails>,
pub mandate_details: Option<MandateDataType>,
pub error_reason: Option<String>,
pub connector_response_reference_id: Option<String>,
pub connector_transaction_id: Option<String>,
Expand All @@ -63,6 +67,7 @@ pub struct PaymentAttemptBatchNew {
pub unified_code: Option<String>,
pub unified_message: Option<String>,
pub net_amount: Option<i64>,
pub mandate_data: Option<MandateDetails>,
}

#[allow(dead_code)]
Expand Down Expand Up @@ -116,6 +121,7 @@ impl PaymentAttemptBatchNew {
unified_code: self.unified_code,
unified_message: self.unified_message,
net_amount: self.net_amount,
mandate_data: self.mandate_data,
}
}
}
62 changes: 27 additions & 35 deletions crates/router/src/core/payment_methods/cards.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1837,17 +1837,8 @@ pub async fn list_payment_methods(
merchant_name: merchant_account.merchant_name,
payment_type,
payment_methods: payment_method_responses,
mandate_payment: payment_attempt
.and_then(|inner| inner.mandate_details)
.and_then(|man_type_details| match man_type_details {
data_models::mandates::MandateTypeDetails::MandateType(mandate_type) => {
Some(mandate_type)
}
data_models::mandates::MandateTypeDetails::MandateDetails(mandate_details) => {
mandate_details.mandate_type
}
})
.map(|d| match d {
mandate_payment: payment_attempt.and_then(|inner| inner.mandate_details).map(
|d| match d {
data_models::mandates::MandateDataType::SingleUse(i) => {
api::MandateType::SingleUse(api::MandateAmountData {
amount: i.amount,
Expand All @@ -1869,7 +1860,8 @@ pub async fn list_payment_methods(
data_models::mandates::MandateDataType::MultiUse(None) => {
api::MandateType::MultiUse(None)
}
}),
},
),
show_surcharge_breakup_screen: merchant_surcharge_configs
.show_surcharge_breakup_screen
.unwrap_or_default(),
Expand Down Expand Up @@ -2079,28 +2071,20 @@ pub async fn filter_payment_methods(
})?;
let filter7 = payment_attempt
.and_then(|attempt| attempt.mandate_details.as_ref())
.map(|mandate_details| {
let (mandate_type_present, update_mandate_id_present) =
match mandate_details {
data_models::mandates::MandateTypeDetails::MandateType(_) => {
(true, false)
}
data_models::mandates::MandateTypeDetails::MandateDetails(
mand_details,
) => (
mand_details.mandate_type.is_some(),
mand_details.update_mandate_id.is_some(),
),
};

if mandate_type_present {
filter_pm_based_on_supported_payments_for_mandate(
supported_payment_methods_for_mandate,
&payment_method,
&payment_method_object.payment_method_type,
connector_variant,
)
} else if update_mandate_id_present {
.map(|_mandate_details| {
filter_pm_based_on_supported_payments_for_mandate(
supported_payment_methods_for_mandate,
&payment_method,
&payment_method_object.payment_method_type,
connector_variant,
)
})
.unwrap_or(true);

let filter8 = payment_attempt
.and_then(|attempt| attempt.mandate_data.as_ref())
.map(|mandate_detail| {
if mandate_detail.update_mandate_id.is_some() {
filter_pm_based_on_update_mandate_support_for_connector(
supported_payment_methods_for_update_mandate,
&payment_method,
Expand All @@ -2121,7 +2105,15 @@ pub async fn filter_payment_methods(
payment_method,
);

if filter && filter2 && filter3 && filter4 && filter5 && filter6 && filter7 {
if filter
&& filter2
&& filter3
&& filter4
&& filter5
&& filter6
&& filter7
&& filter8
{
resp.push(response_pm_type);
}
}
Expand Down
1 change: 1 addition & 0 deletions crates/router/src/core/payments/helpers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3201,6 +3201,7 @@ impl AttemptType {
unified_code: None,
unified_message: None,
net_amount: old_payment_attempt.amount,
mandate_data: old_payment_attempt.mandate_data,
}
}

Expand Down
23 changes: 3 additions & 20 deletions crates/router/src/core/payments/operations/payment_confirm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -441,28 +441,11 @@ impl<F: Send + Clone, Ctx: PaymentMethodRetrieve>

// The operation merges mandate data from both request and payment_attempt
setup_mandate = setup_mandate.map(|mut sm| {
sm.mandate_type = payment_attempt
.mandate_details
.clone()
.and_then(|mandate| match mandate {
data_models::mandates::MandateTypeDetails::MandateType(mandate_type) => {
Some(mandate_type)
}
data_models::mandates::MandateTypeDetails::MandateDetails(mandate_details) => {
mandate_details.mandate_type
}
})
.or(sm.mandate_type);
sm.mandate_type = payment_attempt.mandate_details.clone().or(sm.mandate_type);
sm.update_mandate_id = payment_attempt
.mandate_details
.mandate_data
.clone()
.and_then(|mandate| match mandate {
data_models::mandates::MandateTypeDetails::MandateType(_) => None,
data_models::mandates::MandateTypeDetails::MandateDetails(update_id) => {
Some(update_id.update_mandate_id)
}
})
.flatten()
.and_then(|mandate| mandate.update_mandate_id)
.or(sm.update_mandate_id);
sm
});
Expand Down
26 changes: 10 additions & 16 deletions crates/router/src/core/payments/operations/payment_create.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use api_models::enums::FrmSuggestion;
use async_trait::async_trait;
use common_utils::ext_traits::{AsyncExt, Encode, ValueExt};
use data_models::{
mandates::{MandateData, MandateDetails, MandateTypeDetails},
mandates::{MandateData, MandateDetails},
payments::payment_attempt::PaymentAttempt,
};
use diesel_models::ephemeral_key;
Expand Down Expand Up @@ -733,27 +733,17 @@ impl PaymentCreate {
Err(errors::ApiErrorResponse::InvalidRequestData {message:"Only one field out of 'mandate_type' and 'update_mandate_id' was expected, found both".to_string()})?
}

let mandate_details = if request.mandate_data.is_none() {
None
} else if let Some(update_id) = request
let mandate_data = if let Some(update_id) = request
.mandate_data
.as_ref()
.and_then(|inner| inner.update_mandate_id.clone())
{
let mandate_data = MandateDetails {
let mandate_details = MandateDetails {
update_mandate_id: Some(update_id),
mandate_type: None,
};
Some(MandateTypeDetails::MandateDetails(mandate_data))
Some(mandate_details)
} else {
let mandate_data = MandateDetails {
update_mandate_id: None,
mandate_type: request
.mandate_data
.as_ref()
.and_then(|inner| inner.mandate_type.clone().map(Into::into)),
};
Some(MandateTypeDetails::MandateDetails(mandate_data))
None
};

Ok((
Expand Down Expand Up @@ -782,7 +772,11 @@ impl PaymentCreate {
business_sub_label: request.business_sub_label.clone(),
surcharge_amount,
tax_amount,
mandate_details,
mandate_details: request
.mandate_data
.as_ref()
.and_then(|inner| inner.mandate_type.clone().map(Into::into)),
mandate_data,
..storage::PaymentAttemptNew::default()
},
additional_pm_data,
Expand Down
Loading