Skip to content

Commit

Permalink
feat(core): enable surcharge support for all connectors (#3109)
Browse files Browse the repository at this point in the history
Co-authored-by: hyperswitch-bot[bot] <148525504+hyperswitch-bot[bot]@users.noreply.github.com>
  • Loading branch information
hrithikesh026 and hyperswitch-bot[bot] authored Dec 14, 2023
1 parent 4d19d8b commit 57e1ae9
Show file tree
Hide file tree
Showing 25 changed files with 131 additions and 72 deletions.
4 changes: 1 addition & 3 deletions crates/api_models/src/payments.rs
Original file line number Diff line number Diff line change
Expand Up @@ -322,9 +322,7 @@ impl PaymentsRequest {
pub fn get_total_capturable_amount(&self) -> Option<i64> {
let surcharge_amount = self
.surcharge_details
.map(|surcharge_details| {
surcharge_details.surcharge_amount + surcharge_details.tax_amount.unwrap_or(0)
})
.map(|surcharge_details| surcharge_details.get_total_surcharge_amount())
.unwrap_or(0);
self.amount
.map(|amount| i64::from(amount) + surcharge_amount)
Expand Down
10 changes: 10 additions & 0 deletions crates/data_models/src/payments/payment_attempt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,16 @@ pub struct PaymentAttempt {
pub unified_message: Option<String>,
}

impl PaymentAttempt {
pub fn get_total_amount(&self) -> i64 {
self.amount + self.surcharge_amount.unwrap_or(0) + self.tax_amount.unwrap_or(0)
}
pub fn get_total_surcharge_amount(&self) -> Option<i64> {
self.surcharge_amount
.map(|surcharge_amount| surcharge_amount + self.tax_amount.unwrap_or(0))
}
}

#[derive(Clone, Debug, Eq, PartialEq)]
pub struct PaymentListFilters {
pub connector: Vec<String>,
Expand Down
9 changes: 1 addition & 8 deletions crates/router/src/connector/paypal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -265,10 +265,6 @@ impl ConnectorValidation for Paypal {
),
}
}

fn validate_if_surcharge_implemented(&self) -> CustomResult<(), errors::ConnectorError> {
Ok(())
}
}

impl
Expand Down Expand Up @@ -423,10 +419,7 @@ impl ConnectorIntegration<api::Authorize, types::PaymentsAuthorizeData, types::P
let connector_router_data = paypal::PaypalRouterData::try_from((
&self.get_currency_unit(),
req.request.currency,
req.request
.surcharge_details
.as_ref()
.map_or(req.request.amount, |surcharge| surcharge.final_amount),
req.request.amount,
req,
))?;
let connector_req = paypal::PaypalPaymentsRequest::try_from(&connector_router_data)?;
Expand Down
20 changes: 3 additions & 17 deletions crates/router/src/connector/trustpay.rs
Original file line number Diff line number Diff line change
Expand Up @@ -154,11 +154,7 @@ impl ConnectorCommon for Trustpay {
}
}

impl ConnectorValidation for Trustpay {
fn validate_if_surcharge_implemented(&self) -> CustomResult<(), errors::ConnectorError> {
Ok(())
}
}
impl ConnectorValidation for Trustpay {}

impl api::Payment for Trustpay {}

Expand Down Expand Up @@ -432,12 +428,7 @@ impl
_connectors: &settings::Connectors,
) -> CustomResult<RequestContent, errors::ConnectorError> {
let currency = req.request.get_currency()?;
let amount = req
.request
.surcharge_details
.as_ref()
.map(|surcharge_details| surcharge_details.final_amount)
.unwrap_or(req.request.get_amount()?);
let amount = req.request.get_amount()?;
let connector_router_data = trustpay::TrustpayRouterData::try_from((
&self.get_currency_unit(),
currency,
Expand Down Expand Up @@ -544,12 +535,7 @@ impl ConnectorIntegration<api::Authorize, types::PaymentsAuthorizeData, types::P
req: &types::PaymentsAuthorizeRouterData,
_connectors: &settings::Connectors,
) -> CustomResult<RequestContent, errors::ConnectorError> {
let amount = req
.request
.surcharge_details
.as_ref()
.map(|surcharge_details| surcharge_details.final_amount)
.unwrap_or(req.request.amount);
let amount = req.request.amount;
let connector_router_data = trustpay::TrustpayRouterData::try_from((
&self.get_currency_unit(),
req.request.currency,
Expand Down
29 changes: 27 additions & 2 deletions crates/router/src/connector/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@ use crate::{
},
pii::PeekInterface,
types::{
self, api, storage::payment_attempt::PaymentAttemptExt, transformers::ForeignTryFrom,
ApplePayPredecryptData, BrowserInformation, PaymentsCancelData, ResponseId,
self, api, transformers::ForeignTryFrom, ApplePayPredecryptData, BrowserInformation,
PaymentsCancelData, ResponseId,
},
utils::{OptionExt, ValueExt},
};
Expand Down Expand Up @@ -367,6 +367,10 @@ pub trait PaymentsAuthorizeRequestData {
fn get_connector_mandate_id(&self) -> Result<String, Error>;
fn get_complete_authorize_url(&self) -> Result<String, Error>;
fn get_ip_address_as_optional(&self) -> Option<Secret<String, IpAddress>>;
fn get_original_amount(&self) -> i64;
fn get_surcharge_amount(&self) -> Option<i64>;
fn get_tax_on_surcharge_amount(&self) -> Option<i64>;
fn get_total_surcharge_amount(&self) -> Option<i64>;
}

pub trait PaymentMethodTokenizationRequestData {
Expand Down Expand Up @@ -473,6 +477,27 @@ impl PaymentsAuthorizeRequestData for types::PaymentsAuthorizeData {
.map(|ip| Secret::new(ip.to_string()))
})
}
fn get_original_amount(&self) -> i64 {
self.surcharge_details
.as_ref()
.map(|surcharge_details| surcharge_details.original_amount)
.unwrap_or(self.amount)
}
fn get_surcharge_amount(&self) -> Option<i64> {
self.surcharge_details
.as_ref()
.map(|surcharge_details| surcharge_details.surcharge_amount)
}
fn get_tax_on_surcharge_amount(&self) -> Option<i64> {
self.surcharge_details
.as_ref()
.map(|surcharge_details| surcharge_details.tax_on_surcharge_amount)
}
fn get_total_surcharge_amount(&self) -> Option<i64> {
self.surcharge_details
.as_ref()
.map(|surcharge_details| surcharge_details.get_total_surcharge_amount())
}
}

pub trait ConnectorCustomerData {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -310,6 +310,7 @@ fn get_surcharge_details_from_surcharge_output(
.transpose()?
.unwrap_or(0);
Ok(types::SurchargeDetails {
original_amount: payment_attempt.amount,
surcharge: match surcharge_details.surcharge {
surcharge_decision_configs::SurchargeOutput::Fixed { amount } => {
common_utils_types::Surcharge::Fixed(amount)
Expand Down
12 changes: 8 additions & 4 deletions crates/router/src/core/payments.rs
Original file line number Diff line number Diff line change
Expand Up @@ -204,10 +204,6 @@ where
);

if should_continue_transaction {
operation
.to_domain()?
.populate_payment_data(state, &mut payment_data, &merchant_account)
.await?;
payment_data = match connector_details {
api::ConnectorCallType::PreDetermined(connector) => {
let schedule_time = if should_add_task_to_process_tracker {
Expand Down Expand Up @@ -484,6 +480,13 @@ where
.surcharge_applicable
.unwrap_or(false)
{
if let Some(surcharge_details) = payment_data.payment_attempt.get_surcharge_details() {
// if retry payment, surcharge would have been populated from the previous attempt. Use the same surcharge
let surcharge_details =
types::SurchargeDetails::from((&surcharge_details, &payment_data.payment_attempt));
payment_data.surcharge_details = Some(surcharge_details);
return Ok(());
}
let raw_card_key = payment_data
.payment_method_data
.as_ref()
Expand Down Expand Up @@ -562,6 +565,7 @@ where
payment_data.payment_attempt.amount + surcharge_amount + tax_on_surcharge_amount;
Ok(Some(api::SessionSurchargeDetails::PreDetermined(
types::SurchargeDetails {
original_amount: payment_data.payment_attempt.amount,
surcharge: Surcharge::Fixed(surcharge_amount),
tax_on_surcharge: None,
surcharge_amount,
Expand Down
6 changes: 0 additions & 6 deletions crates/router/src/core/payments/flows/authorize_flow.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,12 +76,6 @@ impl Feature<api::Authorize, types::PaymentsAuthorizeData> for types::PaymentsAu
.connector
.validate_capture_method(self.request.capture_method)
.to_payment_failed_response()?;
if self.request.surcharge_details.is_some() {
connector
.connector
.validate_if_surcharge_implemented()
.to_payment_failed_response()?;
}

if self.should_proceed_with_authorize() {
self.decide_authentication_type();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ impl<F: Send + Clone, Ctx: PaymentMethodRetrieve>
payment_method_type.or(payment_attempt.payment_method_type);
payment_attempt.payment_experience = request.payment_experience;
currency = payment_attempt.currency.get_required_value("currency")?;
amount = payment_attempt.amount.into();
amount = payment_attempt.get_total_amount().into();

helpers::validate_customer_id_mandatory_cases(
request.setup_future_usage.is_some(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ impl<F: Send + Clone, Ctx: PaymentMethodRetrieve>
.await?;

let currency = payment_attempt.currency.get_required_value("currency")?;
let amount = payment_attempt.amount.into();
let amount = payment_attempt.get_total_amount().into();

payment_attempt.cancellation_reason = request.cancellation_reason.clone();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ impl<F: Send + Clone, Ctx: PaymentMethodRetrieve>

currency = payment_attempt.currency.get_required_value("currency")?;

amount = payment_attempt.amount.into();
amount = payment_attempt.get_total_amount().into();

let shipping_address = helpers::create_or_find_address_for_payment_by_request(
db,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ impl<F: Send + Clone, Ctx: PaymentMethodRetrieve>
.payment_experience
.or(payment_attempt.payment_experience);
currency = payment_attempt.currency.get_required_value("currency")?;
amount = payment_attempt.amount.into();
amount = payment_attempt.get_total_amount().into();

helpers::validate_customer_id_mandatory_cases(
request.setup_future_usage.is_some(),
Expand Down
6 changes: 3 additions & 3 deletions crates/router/src/core/payments/operations/payment_confirm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -377,7 +377,7 @@ impl<F: Send + Clone, Ctx: PaymentMethodRetrieve>
payment_attempt.capture_method = request.capture_method.or(payment_attempt.capture_method);

currency = payment_attempt.currency.get_required_value("currency")?;
amount = payment_attempt.amount.into();
amount = payment_attempt.get_total_amount().into();

helpers::validate_customer_id_mandatory_cases(
request.setup_future_usage.is_some(),
Expand Down Expand Up @@ -732,7 +732,7 @@ impl<F: Clone, Ctx: PaymentMethodRetrieve>
m_db.update_payment_attempt_with_attempt_id(
m_payment_data_payment_attempt,
storage::PaymentAttemptUpdate::ConfirmUpdate {
amount: payment_data.amount.into(),
amount: payment_data.payment_attempt.amount,
currency: payment_data.currency,
status: attempt_status,
payment_method,
Expand Down Expand Up @@ -780,7 +780,7 @@ impl<F: Clone, Ctx: PaymentMethodRetrieve>
m_db.update_payment_intent(
m_payment_data_payment_intent,
storage::PaymentIntentUpdate::Update {
amount: payment_data.amount.into(),
amount: payment_data.payment_intent.amount,
currency: payment_data.currency,
setup_future_usage,
status: intent_status,
Expand Down
10 changes: 9 additions & 1 deletion crates/router/src/core/payments/operations/payment_create.rs
Original file line number Diff line number Diff line change
Expand Up @@ -297,7 +297,7 @@ impl<F: Send + Clone, Ctx: PaymentMethodRetrieve>
.map(|(payment_method_data, additional_payment_data)| {
payment_method_data.apply_additional_payment_data(additional_payment_data)
});

let amount = payment_attempt.get_total_amount().into();
let payment_data = PaymentData {
flow: PhantomData,
payment_intent,
Expand Down Expand Up @@ -643,6 +643,12 @@ impl PaymentCreate {
} else {
utils::get_payment_attempt_id(payment_id, 1)
};
let surcharge_amount = request
.surcharge_details
.map(|surcharge_details| surcharge_details.surcharge_amount);
let tax_amount = request
.surcharge_details
.and_then(|surcharge_details| surcharge_details.tax_amount);

Ok((
storage::PaymentAttemptNew {
Expand All @@ -668,6 +674,8 @@ impl PaymentCreate {
payment_token: request.payment_token.clone(),
mandate_id: request.mandate_id.clone(),
business_sub_label: request.business_sub_label.clone(),
surcharge_amount,
tax_amount,
mandate_details: request
.mandate_data
.as_ref()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ impl<F: Send + Clone, Ctx: PaymentMethodRetrieve>
.await?;

let currency = payment_attempt.currency.get_required_value("currency")?;
let amount = payment_attempt.amount.into();
let amount = payment_attempt.get_total_amount().into();

let frm_response = db
.find_fraud_check_by_payment_id(payment_intent.payment_id.clone(), merchant_account.merchant_id.clone())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,7 @@ use crate::{
services::RedirectForm,
types::{
self, api,
storage::{
self, enums,
payment_attempt::{AttemptStatusExt, PaymentAttemptExt},
},
storage::{self, enums, payment_attempt::AttemptStatusExt},
transformers::{ForeignFrom, ForeignTryFrom},
CaptureSyncResponse,
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ impl<F: Send + Clone, Ctx: PaymentMethodRetrieve>

payment_attempt.payment_method = Some(storage_enums::PaymentMethod::Wallet);

let amount = payment_intent.amount.into();
let amount = payment_attempt.get_total_amount().into();

let shipping_address = helpers::create_or_find_address_for_payment_by_request(
db,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ impl<F: Send + Clone, Ctx: PaymentMethodRetrieve>
.to_not_found_response(errors::ApiErrorResponse::PaymentNotFound)?;

currency = payment_attempt.currency.get_required_value("currency")?;
amount = payment_attempt.amount.into();
amount = payment_attempt.get_total_amount().into();

let shipping_address = helpers::create_or_find_address_for_payment_by_request(
db,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -244,7 +244,7 @@ async fn get_tracker_for_sync<
let payment_id_str = payment_attempt.payment_id.clone();

currency = payment_attempt.currency.get_required_value("currency")?;
amount = payment_attempt.amount.into();
amount = payment_attempt.get_total_amount().into();

let shipping_address = helpers::get_address_by_id(
db,
Expand Down
22 changes: 18 additions & 4 deletions crates/router/src/core/payments/operations/payment_update.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use std::marker::PhantomData;

use api_models::enums::FrmSuggestion;
use api_models::{enums::FrmSuggestion, payments::RequestSurchargeDetails};
use async_trait::async_trait;
use common_utils::ext_traits::{AsyncExt, Encode, ValueExt};
use error_stack::{report, IntoReport, ResultExt};
Expand Down Expand Up @@ -281,11 +281,25 @@ impl<F: Send + Clone, Ctx: PaymentMethodRetrieve>
})
.await
.transpose()?;
let next_operation: BoxedOperation<'a, F, api::PaymentsRequest, Ctx> =
let (next_operation, amount): (BoxedOperation<'a, F, api::PaymentsRequest, Ctx>, _) =
if request.confirm.unwrap_or(false) {
Box::new(operations::PaymentConfirm)
let amount = {
let amount = request
.amount
.map(Into::into)
.unwrap_or(payment_attempt.amount);
payment_attempt.amount = amount;
payment_intent.amount = amount;
let surcharge_amount = request
.surcharge_details
.as_ref()
.map(RequestSurchargeDetails::get_total_surcharge_amount)
.or(payment_attempt.get_total_surcharge_amount());
(amount + surcharge_amount.unwrap_or(0)).into()
};
(Box::new(operations::PaymentConfirm), amount)
} else {
Box::new(self)
(Box::new(self), amount)
};

payment_intent.status = match request.payment_method_data.as_ref() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ impl<F: Send + Clone, Ctx: PaymentMethodRetrieve>
.to_not_found_response(errors::ApiErrorResponse::PaymentNotFound)?;

let currency = payment_attempt.currency.get_required_value("currency")?;
let amount = payment_attempt.amount;
let amount = payment_attempt.get_total_amount();

let profile_id = payment_intent
.profile_id
Expand Down
Loading

0 comments on commit 57e1ae9

Please sign in to comment.