Skip to content

Commit cafea45

Browse files
fix: handle session and confirm flow discrepancy in surcharge details (#2696)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
1 parent 856c7af commit cafea45

File tree

20 files changed

+477
-77
lines changed

20 files changed

+477
-77
lines changed

Cargo.lock

Lines changed: 2 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/api_models/Cargo.toml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@ mime = "0.3.17"
2525
reqwest = { version = "0.11.18", optional = true }
2626
serde = { version = "1.0.163", features = ["derive"] }
2727
serde_json = "1.0.96"
28-
serde_with = "3.0.0"
2928
strum = { version = "0.24.1", features = ["derive"] }
3029
time = { version = "0.3.21", features = ["serde", "serde-well-known", "std"] }
3130
url = { version = "2.4.0", features = ["serde"] }

crates/api_models/src/payment_methods.rs

Lines changed: 76 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ use common_utils::{
66
types::Percentage,
77
};
88
use serde::de;
9-
use serde_with::serde_as;
109
use utoipa::ToSchema;
1110

1211
#[cfg(feature = "payouts")]
@@ -15,7 +14,7 @@ use crate::{
1514
admin,
1615
customers::CustomerId,
1716
enums as api_enums,
18-
payments::{self, BankCodeResponse},
17+
payments::{self, BankCodeResponse, RequestSurchargeDetails},
1918
};
2019

2120
#[derive(Debug, serde::Deserialize, serde::Serialize, Clone, ToSchema)]
@@ -342,15 +341,85 @@ pub struct SurchargeDetailsResponse {
342341
pub final_amount: i64,
343342
}
344343

345-
#[serde_as]
346-
#[derive(Clone, Debug, PartialEq, serde::Serialize, serde::Deserialize)]
344+
impl SurchargeDetailsResponse {
345+
pub fn is_request_surcharge_matching(
346+
&self,
347+
request_surcharge_details: RequestSurchargeDetails,
348+
) -> bool {
349+
request_surcharge_details.surcharge_amount == self.surcharge_amount
350+
&& request_surcharge_details.tax_amount.unwrap_or(0) == self.tax_on_surcharge_amount
351+
}
352+
}
353+
354+
#[derive(Clone, Debug)]
347355
pub struct SurchargeMetadata {
348-
#[serde_as(as = "HashMap<_, _>")]
349-
pub surcharge_results: HashMap<String, SurchargeDetailsResponse>,
356+
surcharge_results: HashMap<
357+
(
358+
common_enums::PaymentMethod,
359+
common_enums::PaymentMethodType,
360+
Option<common_enums::CardNetwork>,
361+
),
362+
SurchargeDetailsResponse,
363+
>,
364+
pub payment_attempt_id: String,
350365
}
351366

352367
impl SurchargeMetadata {
353-
pub fn get_key_for_surcharge_details_hash_map(
368+
pub fn new(payment_attempt_id: String) -> Self {
369+
Self {
370+
surcharge_results: HashMap::new(),
371+
payment_attempt_id,
372+
}
373+
}
374+
pub fn is_empty_result(&self) -> bool {
375+
self.surcharge_results.is_empty()
376+
}
377+
pub fn get_surcharge_results_size(&self) -> usize {
378+
self.surcharge_results.len()
379+
}
380+
pub fn insert_surcharge_details(
381+
&mut self,
382+
payment_method: &common_enums::PaymentMethod,
383+
payment_method_type: &common_enums::PaymentMethodType,
384+
card_network: Option<&common_enums::CardNetwork>,
385+
surcharge_details: SurchargeDetailsResponse,
386+
) {
387+
let key = (
388+
payment_method.to_owned(),
389+
payment_method_type.to_owned(),
390+
card_network.cloned(),
391+
);
392+
self.surcharge_results.insert(key, surcharge_details);
393+
}
394+
pub fn get_surcharge_details(
395+
&self,
396+
payment_method: &common_enums::PaymentMethod,
397+
payment_method_type: &common_enums::PaymentMethodType,
398+
card_network: Option<&common_enums::CardNetwork>,
399+
) -> Option<&SurchargeDetailsResponse> {
400+
let key = &(
401+
payment_method.to_owned(),
402+
payment_method_type.to_owned(),
403+
card_network.cloned(),
404+
);
405+
self.surcharge_results.get(key)
406+
}
407+
pub fn get_surcharge_metadata_redis_key(payment_attempt_id: &str) -> String {
408+
format!("surcharge_metadata_{}", payment_attempt_id)
409+
}
410+
pub fn get_individual_surcharge_key_value_pairs(
411+
&self,
412+
) -> Vec<(String, SurchargeDetailsResponse)> {
413+
self.surcharge_results
414+
.iter()
415+
.map(|((pm, pmt, card_network), surcharge_details)| {
416+
let key =
417+
Self::get_surcharge_details_redis_hashset_key(pm, pmt, card_network.as_ref());
418+
(key, surcharge_details.to_owned())
419+
})
420+
.collect()
421+
}
422+
pub fn get_surcharge_details_redis_hashset_key(
354423
payment_method: &common_enums::PaymentMethod,
355424
payment_method_type: &common_enums::PaymentMethodType,
356425
card_network: Option<&common_enums::CardNetwork>,

crates/api_models/src/payments.rs

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ use crate::{
1616
admin, disputes,
1717
enums::{self as api_enums},
1818
ephemeral_key::EphemeralKeyCreateResponse,
19+
payment_methods::{Surcharge, SurchargeDetailsResponse},
1920
refunds,
2021
};
2122

@@ -319,6 +320,23 @@ pub struct RequestSurchargeDetails {
319320
pub tax_amount: Option<i64>,
320321
}
321322

323+
impl RequestSurchargeDetails {
324+
pub fn is_surcharge_zero(&self) -> bool {
325+
self.surcharge_amount == 0 && self.tax_amount.unwrap_or(0) == 0
326+
}
327+
pub fn get_surcharge_details_object(&self, original_amount: i64) -> SurchargeDetailsResponse {
328+
let surcharge_amount = self.surcharge_amount;
329+
let tax_on_surcharge_amount = self.tax_amount.unwrap_or(0);
330+
SurchargeDetailsResponse {
331+
surcharge: Surcharge::Fixed(self.surcharge_amount),
332+
tax_on_surcharge: None,
333+
surcharge_amount,
334+
tax_on_surcharge_amount,
335+
final_amount: original_amount + surcharge_amount + tax_on_surcharge_amount,
336+
}
337+
}
338+
}
339+
322340
#[derive(Default, Debug, Clone, Copy)]
323341
pub struct HeaderPayload {
324342
pub payment_confirm_source: Option<api_enums::PaymentSource>,
@@ -810,6 +828,36 @@ pub enum PaymentMethodData {
810828
GiftCard(Box<GiftCardData>),
811829
}
812830

831+
impl PaymentMethodData {
832+
pub fn get_payment_method_type_if_session_token_type(
833+
&self,
834+
) -> Option<api_enums::PaymentMethodType> {
835+
match self {
836+
Self::Wallet(wallet) => match wallet {
837+
WalletData::ApplePay(_) => Some(api_enums::PaymentMethodType::ApplePay),
838+
WalletData::GooglePay(_) => Some(api_enums::PaymentMethodType::GooglePay),
839+
WalletData::PaypalSdk(_) => Some(api_enums::PaymentMethodType::Paypal),
840+
_ => None,
841+
},
842+
Self::PayLater(pay_later) => match pay_later {
843+
PayLaterData::KlarnaSdk { .. } => Some(api_enums::PaymentMethodType::Klarna),
844+
_ => None,
845+
},
846+
Self::Card(_)
847+
| Self::CardRedirect(_)
848+
| Self::BankRedirect(_)
849+
| Self::BankDebit(_)
850+
| Self::BankTransfer(_)
851+
| Self::Crypto(_)
852+
| Self::MandatePayment
853+
| Self::Reward
854+
| Self::Upi(_)
855+
| Self::Voucher(_)
856+
| Self::GiftCard(_) => None,
857+
}
858+
}
859+
}
860+
813861
pub trait GetPaymentMethodType {
814862
fn get_payment_method_type(&self) -> api_enums::PaymentMethodType;
815863
}

crates/data_models/src/payments/payment_attempt.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -224,13 +224,17 @@ pub enum PaymentAttemptUpdate {
224224
business_sub_label: Option<String>,
225225
amount_to_capture: Option<i64>,
226226
capture_method: Option<storage_enums::CaptureMethod>,
227+
surcharge_amount: Option<i64>,
228+
tax_amount: Option<i64>,
227229
updated_by: String,
228230
},
229231
UpdateTrackers {
230232
payment_token: Option<String>,
231233
connector: Option<String>,
232234
straight_through_algorithm: Option<serde_json::Value>,
233235
amount_capturable: Option<i64>,
236+
surcharge_amount: Option<i64>,
237+
tax_amount: Option<i64>,
234238
updated_by: String,
235239
merchant_connector_id: Option<String>,
236240
},
@@ -255,8 +259,6 @@ pub enum PaymentAttemptUpdate {
255259
error_code: Option<Option<String>>,
256260
error_message: Option<Option<String>>,
257261
amount_capturable: Option<i64>,
258-
surcharge_amount: Option<i64>,
259-
tax_amount: Option<i64>,
260262
updated_by: String,
261263
merchant_connector_id: Option<String>,
262264
},
@@ -285,6 +287,8 @@ pub enum PaymentAttemptUpdate {
285287
error_reason: Option<Option<String>>,
286288
connector_response_reference_id: Option<String>,
287289
amount_capturable: Option<i64>,
290+
surcharge_amount: Option<i64>,
291+
tax_amount: Option<i64>,
288292
updated_by: String,
289293
authentication_data: Option<serde_json::Value>,
290294
encoded_data: Option<String>,

crates/diesel_models/src/payment_attempt.rs

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -141,13 +141,17 @@ pub enum PaymentAttemptUpdate {
141141
business_sub_label: Option<String>,
142142
amount_to_capture: Option<i64>,
143143
capture_method: Option<storage_enums::CaptureMethod>,
144+
surcharge_amount: Option<i64>,
145+
tax_amount: Option<i64>,
144146
updated_by: String,
145147
},
146148
UpdateTrackers {
147149
payment_token: Option<String>,
148150
connector: Option<String>,
149151
straight_through_algorithm: Option<serde_json::Value>,
150152
amount_capturable: Option<i64>,
153+
surcharge_amount: Option<i64>,
154+
tax_amount: Option<i64>,
151155
updated_by: String,
152156
merchant_connector_id: Option<String>,
153157
},
@@ -172,8 +176,6 @@ pub enum PaymentAttemptUpdate {
172176
error_code: Option<Option<String>>,
173177
error_message: Option<Option<String>>,
174178
amount_capturable: Option<i64>,
175-
surcharge_amount: Option<i64>,
176-
tax_amount: Option<i64>,
177179
updated_by: String,
178180
merchant_connector_id: Option<String>,
179181
},
@@ -202,6 +204,8 @@ pub enum PaymentAttemptUpdate {
202204
error_reason: Option<Option<String>>,
203205
connector_response_reference_id: Option<String>,
204206
amount_capturable: Option<i64>,
207+
surcharge_amount: Option<i64>,
208+
tax_amount: Option<i64>,
205209
updated_by: String,
206210
authentication_data: Option<serde_json::Value>,
207211
encoded_data: Option<String>,
@@ -370,6 +374,8 @@ impl From<PaymentAttemptUpdate> for PaymentAttemptUpdateInternal {
370374
business_sub_label,
371375
amount_to_capture,
372376
capture_method,
377+
surcharge_amount,
378+
tax_amount,
373379
updated_by,
374380
} => Self {
375381
amount: Some(amount),
@@ -386,6 +392,8 @@ impl From<PaymentAttemptUpdate> for PaymentAttemptUpdateInternal {
386392
business_sub_label,
387393
amount_to_capture,
388394
capture_method,
395+
surcharge_amount,
396+
tax_amount,
389397
updated_by,
390398
..Default::default()
391399
},
@@ -415,8 +423,6 @@ impl From<PaymentAttemptUpdate> for PaymentAttemptUpdateInternal {
415423
error_code,
416424
error_message,
417425
amount_capturable,
418-
surcharge_amount,
419-
tax_amount,
420426
updated_by,
421427
merchant_connector_id,
422428
} => Self {
@@ -437,8 +443,6 @@ impl From<PaymentAttemptUpdate> for PaymentAttemptUpdateInternal {
437443
error_code,
438444
error_message,
439445
amount_capturable,
440-
surcharge_amount,
441-
tax_amount,
442446
updated_by,
443447
merchant_connector_id,
444448
..Default::default()
@@ -479,6 +483,8 @@ impl From<PaymentAttemptUpdate> for PaymentAttemptUpdateInternal {
479483
error_reason,
480484
connector_response_reference_id,
481485
amount_capturable,
486+
surcharge_amount,
487+
tax_amount,
482488
updated_by,
483489
authentication_data,
484490
encoded_data,
@@ -498,6 +504,8 @@ impl From<PaymentAttemptUpdate> for PaymentAttemptUpdateInternal {
498504
connector_response_reference_id,
499505
amount_capturable,
500506
updated_by,
507+
surcharge_amount,
508+
tax_amount,
501509
authentication_data,
502510
encoded_data,
503511
..Default::default()
@@ -531,13 +539,17 @@ impl From<PaymentAttemptUpdate> for PaymentAttemptUpdateInternal {
531539
connector,
532540
straight_through_algorithm,
533541
amount_capturable,
542+
surcharge_amount,
543+
tax_amount,
534544
updated_by,
535545
merchant_connector_id,
536546
} => Self {
537547
payment_token,
538548
connector,
539549
straight_through_algorithm,
540550
amount_capturable,
551+
surcharge_amount,
552+
tax_amount,
541553
updated_by,
542554
merchant_connector_id,
543555
..Default::default()

crates/redis_interface/src/commands.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -248,7 +248,7 @@ impl super::RedisConnectionPool {
248248
&self,
249249
key: &str,
250250
values: V,
251-
ttl: Option<u32>,
251+
ttl: Option<i64>,
252252
) -> CustomResult<(), errors::RedisError>
253253
where
254254
V: TryInto<RedisMap> + Debug + Send + Sync,
@@ -260,11 +260,10 @@ impl super::RedisConnectionPool {
260260
.await
261261
.into_report()
262262
.change_context(errors::RedisError::SetHashFailed);
263-
264263
// setting expiry for the key
265264
output
266265
.async_and_then(|_| {
267-
self.set_expiry(key, ttl.unwrap_or(self.config.default_hash_ttl).into())
266+
self.set_expiry(key, ttl.unwrap_or(self.config.default_hash_ttl.into()))
268267
})
269268
.await
270269
}

crates/router/src/core/payment_methods/cards.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1052,6 +1052,8 @@ pub async fn list_payment_methods(
10521052
amount_capturable: None,
10531053
updated_by: merchant_account.storage_scheme.to_string(),
10541054
merchant_connector_id: None,
1055+
surcharge_amount: None,
1056+
tax_amount: None,
10551057
};
10561058

10571059
state

0 commit comments

Comments
 (0)