feat(router): modify attempt_id generation logic to accommodate payment_id as prefix (#1596)

This commit is contained in:
Sai Harsha Vardhan
2023-07-04 19:12:52 +05:30
committed by GitHub
parent 6447b04574
commit 82e1bf0d16
9 changed files with 38 additions and 6 deletions

View File

@ -1907,6 +1907,7 @@ mod tests {
business_label: "no".to_string(), business_label: "no".to_string(),
order_details: None, order_details: None,
udf: None, udf: None,
attempt_count: 1,
}; };
let req_cs = Some("1".to_string()); let req_cs = Some("1".to_string());
let merchant_fulfillment_time = Some(900); let merchant_fulfillment_time = Some(900);
@ -1948,6 +1949,7 @@ mod tests {
business_label: "no".to_string(), business_label: "no".to_string(),
order_details: None, order_details: None,
udf: None, udf: None,
attempt_count: 1,
}; };
let req_cs = Some("1".to_string()); let req_cs = Some("1".to_string());
let merchant_fulfillment_time = Some(10); let merchant_fulfillment_time = Some(10);
@ -1989,6 +1991,7 @@ mod tests {
business_label: "no".to_string(), business_label: "no".to_string(),
order_details: None, order_details: None,
udf: None, udf: None,
attempt_count: 1,
}; };
let req_cs = Some("1".to_string()); let req_cs = Some("1".to_string());
let merchant_fulfillment_time = Some(10); let merchant_fulfillment_time = Some(10);
@ -2246,13 +2249,17 @@ impl AttemptType {
fn make_new_payment_attempt( fn make_new_payment_attempt(
payment_method_data: &Option<api_models::payments::PaymentMethodData>, payment_method_data: &Option<api_models::payments::PaymentMethodData>,
old_payment_attempt: storage::PaymentAttempt, old_payment_attempt: storage::PaymentAttempt,
new_attempt_count: i16,
) -> storage::PaymentAttemptNew { ) -> storage::PaymentAttemptNew {
let created_at @ modified_at @ last_synced = Some(common_utils::date_time::now()); let created_at @ modified_at @ last_synced = Some(common_utils::date_time::now());
storage::PaymentAttemptNew { storage::PaymentAttemptNew {
attempt_id: utils::get_payment_attempt_id(
&old_payment_attempt.payment_id,
new_attempt_count,
),
payment_id: old_payment_attempt.payment_id, payment_id: old_payment_attempt.payment_id,
merchant_id: old_payment_attempt.merchant_id, merchant_id: old_payment_attempt.merchant_id,
attempt_id: uuid::Uuid::new_v4().simple().to_string(),
// A new payment attempt is getting created so, used the same function which is used to populate status in PaymentCreate Flow. // A new payment attempt is getting created so, used the same function which is used to populate status in PaymentCreate Flow.
status: payment_attempt_status_fsm(payment_method_data, Some(true)), status: payment_attempt_status_fsm(payment_method_data, Some(true)),
@ -2314,11 +2321,13 @@ impl AttemptType {
match self { match self {
Self::SameOld => Ok((fetched_payment_intent, fetched_payment_attempt)), Self::SameOld => Ok((fetched_payment_intent, fetched_payment_attempt)),
Self::New => { Self::New => {
let new_attempt_count = fetched_payment_intent.attempt_count + 1;
let new_payment_attempt = db let new_payment_attempt = db
.insert_payment_attempt( .insert_payment_attempt(
Self::make_new_payment_attempt( Self::make_new_payment_attempt(
&request.payment_method_data, &request.payment_method_data,
fetched_payment_attempt, fetched_payment_attempt,
new_attempt_count,
), ),
storage_scheme, storage_scheme,
) )
@ -2336,6 +2345,7 @@ impl AttemptType {
Some(true), Some(true),
), ),
active_attempt_id: new_payment_attempt.attempt_id.to_owned(), active_attempt_id: new_payment_attempt.attempt_id.to_owned(),
attempt_count: new_attempt_count,
}, },
storage_scheme, storage_scheme,
) )

View File

@ -7,7 +7,6 @@ use error_stack::{self, ResultExt};
use router_derive::PaymentOperation; use router_derive::PaymentOperation;
use router_env::{instrument, tracing}; use router_env::{instrument, tracing};
use storage_models::ephemeral_key; use storage_models::ephemeral_key;
use uuid::Uuid;
use super::{BoxedOperation, Domain, GetTracker, Operation, UpdateTracker, ValidateRequest}; use super::{BoxedOperation, Domain, GetTracker, Operation, UpdateTracker, ValidateRequest};
use crate::{ use crate::{
@ -30,7 +29,7 @@ use crate::{
}, },
transformers::ForeignInto, transformers::ForeignInto,
}, },
utils::OptionExt, utils::{self, OptionExt},
}; };
#[derive(Debug, Clone, Copy, PaymentOperation)] #[derive(Debug, Clone, Copy, PaymentOperation)]
@ -527,7 +526,7 @@ impl PaymentCreate {
Ok(storage::PaymentAttemptNew { Ok(storage::PaymentAttemptNew {
payment_id: payment_id.to_string(), payment_id: payment_id.to_string(),
merchant_id: merchant_id.to_string(), merchant_id: merchant_id.to_string(),
attempt_id: Uuid::new_v4().simple().to_string(), attempt_id: utils::get_payment_attempt_id(payment_id, 1),
status, status,
currency, currency,
amount: amount.into(), amount: amount.into(),
@ -641,6 +640,7 @@ impl PaymentCreate {
active_attempt_id, active_attempt_id,
order_details: order_details_outside_value, order_details: order_details_outside_value,
udf: request.udf.clone(), udf: request.udf.clone(),
attempt_count: 1,
..storage::PaymentIntentNew::default() ..storage::PaymentIntentNew::default()
}) })
} }

View File

@ -5,7 +5,6 @@ use common_utils::{date_time, errors::CustomResult, ext_traits::AsyncExt};
use error_stack::ResultExt; use error_stack::ResultExt;
use router_derive::PaymentOperation; use router_derive::PaymentOperation;
use router_env::{instrument, tracing}; use router_env::{instrument, tracing};
use uuid::Uuid;
use super::{BoxedOperation, Domain, GetTracker, PaymentCreate, UpdateTracker, ValidateRequest}; use super::{BoxedOperation, Domain, GetTracker, PaymentCreate, UpdateTracker, ValidateRequest};
use crate::{ use crate::{
@ -307,7 +306,7 @@ impl PaymentMethodValidate {
storage::PaymentAttemptNew { storage::PaymentAttemptNew {
payment_id: payment_id.to_string(), payment_id: payment_id.to_string(),
merchant_id: merchant_id.to_string(), merchant_id: merchant_id.to_string(),
attempt_id: Uuid::new_v4().simple().to_string(), attempt_id: utils::get_payment_attempt_id(payment_id, 1),
status, status,
// Amount & Currency will be zero in this case // Amount & Currency will be zero in this case
amount: 0, amount: 0,
@ -347,6 +346,7 @@ impl PaymentMethodValidate {
setup_future_usage: request.setup_future_usage.map(ForeignInto::foreign_into), setup_future_usage: request.setup_future_usage.map(ForeignInto::foreign_into),
off_session: request.off_session, off_session: request.off_session,
active_attempt_id, active_attempt_id,
attempt_count: 1,
..Default::default() ..Default::default()
} }
} }

View File

@ -97,6 +97,7 @@ mod storage {
active_attempt_id: new.active_attempt_id.to_owned(), active_attempt_id: new.active_attempt_id.to_owned(),
order_details: new.order_details.clone(), order_details: new.order_details.clone(),
udf: new.udf.clone(), udf: new.udf.clone(),
attempt_count: new.attempt_count,
}; };
match self match self
@ -357,6 +358,7 @@ impl PaymentIntentInterface for MockDb {
active_attempt_id: new.active_attempt_id.to_owned(), active_attempt_id: new.active_attempt_id.to_owned(),
order_details: new.order_details, order_details: new.order_details,
udf: new.udf, udf: new.udf,
attempt_count: new.attempt_count,
}; };
payment_intents.push(payment_intent.clone()); payment_intents.push(payment_intent.clone());
Ok(payment_intent) Ok(payment_intent)

View File

@ -150,3 +150,8 @@ pub fn to_currency_base_unit_asf64(
}; };
Ok(amount) Ok(amount)
} }
#[inline]
pub fn get_payment_attempt_id(payment_id: impl std::fmt::Display, attempt_count: i16) -> String {
format!("{payment_id}_{attempt_count}")
}

View File

@ -39,6 +39,7 @@ pub struct PaymentIntent {
#[diesel(deserialize_as = super::OptionalDieselArray<pii::SecretSerdeValue>)] #[diesel(deserialize_as = super::OptionalDieselArray<pii::SecretSerdeValue>)]
pub order_details: Option<Vec<pii::SecretSerdeValue>>, pub order_details: Option<Vec<pii::SecretSerdeValue>>,
pub udf: Option<pii::SecretSerdeValue>, pub udf: Option<pii::SecretSerdeValue>,
pub attempt_count: i16,
} }
#[derive( #[derive(
@ -84,6 +85,7 @@ pub struct PaymentIntentNew {
#[diesel(deserialize_as = super::OptionalDieselArray<pii::SecretSerdeValue>)] #[diesel(deserialize_as = super::OptionalDieselArray<pii::SecretSerdeValue>)]
pub order_details: Option<Vec<pii::SecretSerdeValue>>, pub order_details: Option<Vec<pii::SecretSerdeValue>>,
pub udf: Option<pii::SecretSerdeValue>, pub udf: Option<pii::SecretSerdeValue>,
pub attempt_count: i16,
} }
#[derive(Debug, Clone, Serialize, Deserialize)] #[derive(Debug, Clone, Serialize, Deserialize)]
@ -135,6 +137,7 @@ pub enum PaymentIntentUpdate {
StatusAndAttemptUpdate { StatusAndAttemptUpdate {
status: storage_enums::IntentStatus, status: storage_enums::IntentStatus,
active_attempt_id: String, active_attempt_id: String,
attempt_count: i16,
}, },
} }
@ -164,6 +167,7 @@ pub struct PaymentIntentUpdateInternal {
#[diesel(deserialize_as = super::OptionalDieselArray<pii::SecretSerdeValue>)] #[diesel(deserialize_as = super::OptionalDieselArray<pii::SecretSerdeValue>)]
pub order_details: Option<Vec<pii::SecretSerdeValue>>, pub order_details: Option<Vec<pii::SecretSerdeValue>>,
pub udf: Option<pii::SecretSerdeValue>, pub udf: Option<pii::SecretSerdeValue>,
pub attempt_count: Option<i16>,
} }
impl PaymentIntentUpdate { impl PaymentIntentUpdate {
@ -302,9 +306,11 @@ impl From<PaymentIntentUpdate> for PaymentIntentUpdateInternal {
PaymentIntentUpdate::StatusAndAttemptUpdate { PaymentIntentUpdate::StatusAndAttemptUpdate {
status, status,
active_attempt_id, active_attempt_id,
attempt_count,
} => Self { } => Self {
status: Some(status), status: Some(status),
active_attempt_id: Some(active_attempt_id), active_attempt_id: Some(active_attempt_id),
attempt_count: Some(attempt_count),
..Default::default() ..Default::default()
}, },
} }

View File

@ -478,6 +478,7 @@ diesel::table! {
business_label -> Varchar, business_label -> Varchar,
order_details -> Nullable<Array<Nullable<Jsonb>>>, order_details -> Nullable<Array<Nullable<Jsonb>>>,
udf -> Nullable<Jsonb>, udf -> Nullable<Jsonb>,
attempt_count -> Int2,
} }
} }

View File

@ -0,0 +1,2 @@
-- This file should undo anything in `up.sql`
ALTER TABLE PAYMENT_INTENT DROP COLUMN attempt_count;

View File

@ -0,0 +1,6 @@
ALTER TABLE payment_intent ADD COLUMN attempt_count SMALLINT NOT NULL DEFAULT 1;
UPDATE payment_intent
SET attempt_count = payment_id_count.count
FROM (SELECT payment_id, count(payment_id) FROM payment_attempt GROUP BY payment_id) as payment_id_count
WHERE payment_intent.payment_id = payment_id_count.payment_id;