mirror of
https://github.com/juspay/hyperswitch.git
synced 2025-11-01 19:42:27 +08:00
feat(router): modify attempt_id generation logic to accommodate payment_id as prefix (#1596)
This commit is contained in:
committed by
GitHub
parent
6447b04574
commit
82e1bf0d16
@ -1907,6 +1907,7 @@ mod tests {
|
||||
business_label: "no".to_string(),
|
||||
order_details: None,
|
||||
udf: None,
|
||||
attempt_count: 1,
|
||||
};
|
||||
let req_cs = Some("1".to_string());
|
||||
let merchant_fulfillment_time = Some(900);
|
||||
@ -1948,6 +1949,7 @@ mod tests {
|
||||
business_label: "no".to_string(),
|
||||
order_details: None,
|
||||
udf: None,
|
||||
attempt_count: 1,
|
||||
};
|
||||
let req_cs = Some("1".to_string());
|
||||
let merchant_fulfillment_time = Some(10);
|
||||
@ -1989,6 +1991,7 @@ mod tests {
|
||||
business_label: "no".to_string(),
|
||||
order_details: None,
|
||||
udf: None,
|
||||
attempt_count: 1,
|
||||
};
|
||||
let req_cs = Some("1".to_string());
|
||||
let merchant_fulfillment_time = Some(10);
|
||||
@ -2246,13 +2249,17 @@ impl AttemptType {
|
||||
fn make_new_payment_attempt(
|
||||
payment_method_data: &Option<api_models::payments::PaymentMethodData>,
|
||||
old_payment_attempt: storage::PaymentAttempt,
|
||||
new_attempt_count: i16,
|
||||
) -> storage::PaymentAttemptNew {
|
||||
let created_at @ modified_at @ last_synced = Some(common_utils::date_time::now());
|
||||
|
||||
storage::PaymentAttemptNew {
|
||||
attempt_id: utils::get_payment_attempt_id(
|
||||
&old_payment_attempt.payment_id,
|
||||
new_attempt_count,
|
||||
),
|
||||
payment_id: old_payment_attempt.payment_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.
|
||||
status: payment_attempt_status_fsm(payment_method_data, Some(true)),
|
||||
@ -2314,11 +2321,13 @@ impl AttemptType {
|
||||
match self {
|
||||
Self::SameOld => Ok((fetched_payment_intent, fetched_payment_attempt)),
|
||||
Self::New => {
|
||||
let new_attempt_count = fetched_payment_intent.attempt_count + 1;
|
||||
let new_payment_attempt = db
|
||||
.insert_payment_attempt(
|
||||
Self::make_new_payment_attempt(
|
||||
&request.payment_method_data,
|
||||
fetched_payment_attempt,
|
||||
new_attempt_count,
|
||||
),
|
||||
storage_scheme,
|
||||
)
|
||||
@ -2336,6 +2345,7 @@ impl AttemptType {
|
||||
Some(true),
|
||||
),
|
||||
active_attempt_id: new_payment_attempt.attempt_id.to_owned(),
|
||||
attempt_count: new_attempt_count,
|
||||
},
|
||||
storage_scheme,
|
||||
)
|
||||
|
||||
@ -7,7 +7,6 @@ use error_stack::{self, ResultExt};
|
||||
use router_derive::PaymentOperation;
|
||||
use router_env::{instrument, tracing};
|
||||
use storage_models::ephemeral_key;
|
||||
use uuid::Uuid;
|
||||
|
||||
use super::{BoxedOperation, Domain, GetTracker, Operation, UpdateTracker, ValidateRequest};
|
||||
use crate::{
|
||||
@ -30,7 +29,7 @@ use crate::{
|
||||
},
|
||||
transformers::ForeignInto,
|
||||
},
|
||||
utils::OptionExt,
|
||||
utils::{self, OptionExt},
|
||||
};
|
||||
|
||||
#[derive(Debug, Clone, Copy, PaymentOperation)]
|
||||
@ -527,7 +526,7 @@ impl PaymentCreate {
|
||||
Ok(storage::PaymentAttemptNew {
|
||||
payment_id: payment_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,
|
||||
currency,
|
||||
amount: amount.into(),
|
||||
@ -641,6 +640,7 @@ impl PaymentCreate {
|
||||
active_attempt_id,
|
||||
order_details: order_details_outside_value,
|
||||
udf: request.udf.clone(),
|
||||
attempt_count: 1,
|
||||
..storage::PaymentIntentNew::default()
|
||||
})
|
||||
}
|
||||
|
||||
@ -5,7 +5,6 @@ use common_utils::{date_time, errors::CustomResult, ext_traits::AsyncExt};
|
||||
use error_stack::ResultExt;
|
||||
use router_derive::PaymentOperation;
|
||||
use router_env::{instrument, tracing};
|
||||
use uuid::Uuid;
|
||||
|
||||
use super::{BoxedOperation, Domain, GetTracker, PaymentCreate, UpdateTracker, ValidateRequest};
|
||||
use crate::{
|
||||
@ -307,7 +306,7 @@ impl PaymentMethodValidate {
|
||||
storage::PaymentAttemptNew {
|
||||
payment_id: payment_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,
|
||||
// Amount & Currency will be zero in this case
|
||||
amount: 0,
|
||||
@ -347,6 +346,7 @@ impl PaymentMethodValidate {
|
||||
setup_future_usage: request.setup_future_usage.map(ForeignInto::foreign_into),
|
||||
off_session: request.off_session,
|
||||
active_attempt_id,
|
||||
attempt_count: 1,
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
|
||||
@ -97,6 +97,7 @@ mod storage {
|
||||
active_attempt_id: new.active_attempt_id.to_owned(),
|
||||
order_details: new.order_details.clone(),
|
||||
udf: new.udf.clone(),
|
||||
attempt_count: new.attempt_count,
|
||||
};
|
||||
|
||||
match self
|
||||
@ -357,6 +358,7 @@ impl PaymentIntentInterface for MockDb {
|
||||
active_attempt_id: new.active_attempt_id.to_owned(),
|
||||
order_details: new.order_details,
|
||||
udf: new.udf,
|
||||
attempt_count: new.attempt_count,
|
||||
};
|
||||
payment_intents.push(payment_intent.clone());
|
||||
Ok(payment_intent)
|
||||
|
||||
@ -150,3 +150,8 @@ pub fn to_currency_base_unit_asf64(
|
||||
};
|
||||
Ok(amount)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn get_payment_attempt_id(payment_id: impl std::fmt::Display, attempt_count: i16) -> String {
|
||||
format!("{payment_id}_{attempt_count}")
|
||||
}
|
||||
|
||||
@ -39,6 +39,7 @@ pub struct PaymentIntent {
|
||||
#[diesel(deserialize_as = super::OptionalDieselArray<pii::SecretSerdeValue>)]
|
||||
pub order_details: Option<Vec<pii::SecretSerdeValue>>,
|
||||
pub udf: Option<pii::SecretSerdeValue>,
|
||||
pub attempt_count: i16,
|
||||
}
|
||||
|
||||
#[derive(
|
||||
@ -84,6 +85,7 @@ pub struct PaymentIntentNew {
|
||||
#[diesel(deserialize_as = super::OptionalDieselArray<pii::SecretSerdeValue>)]
|
||||
pub order_details: Option<Vec<pii::SecretSerdeValue>>,
|
||||
pub udf: Option<pii::SecretSerdeValue>,
|
||||
pub attempt_count: i16,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
@ -135,6 +137,7 @@ pub enum PaymentIntentUpdate {
|
||||
StatusAndAttemptUpdate {
|
||||
status: storage_enums::IntentStatus,
|
||||
active_attempt_id: String,
|
||||
attempt_count: i16,
|
||||
},
|
||||
}
|
||||
|
||||
@ -164,6 +167,7 @@ pub struct PaymentIntentUpdateInternal {
|
||||
#[diesel(deserialize_as = super::OptionalDieselArray<pii::SecretSerdeValue>)]
|
||||
pub order_details: Option<Vec<pii::SecretSerdeValue>>,
|
||||
pub udf: Option<pii::SecretSerdeValue>,
|
||||
pub attempt_count: Option<i16>,
|
||||
}
|
||||
|
||||
impl PaymentIntentUpdate {
|
||||
@ -302,9 +306,11 @@ impl From<PaymentIntentUpdate> for PaymentIntentUpdateInternal {
|
||||
PaymentIntentUpdate::StatusAndAttemptUpdate {
|
||||
status,
|
||||
active_attempt_id,
|
||||
attempt_count,
|
||||
} => Self {
|
||||
status: Some(status),
|
||||
active_attempt_id: Some(active_attempt_id),
|
||||
attempt_count: Some(attempt_count),
|
||||
..Default::default()
|
||||
},
|
||||
}
|
||||
|
||||
@ -478,6 +478,7 @@ diesel::table! {
|
||||
business_label -> Varchar,
|
||||
order_details -> Nullable<Array<Nullable<Jsonb>>>,
|
||||
udf -> Nullable<Jsonb>,
|
||||
attempt_count -> Int2,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -0,0 +1,2 @@
|
||||
-- This file should undo anything in `up.sql`
|
||||
ALTER TABLE PAYMENT_INTENT DROP COLUMN attempt_count;
|
||||
@ -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;
|
||||
Reference in New Issue
Block a user