diff --git a/Cargo.lock b/Cargo.lock index 71bdc995ec..b1c77fc7f1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2651,6 +2651,7 @@ dependencies = [ "serde_path_to_error", "serde_qs", "serde_urlencoded", + "storage_models", "structopt", "strum", "thiserror", @@ -2996,6 +2997,22 @@ checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" [[package]] name = "storage_models" version = "0.1.0" +dependencies = [ + "async-bb8-diesel", + "async-trait", + "common_utils", + "diesel", + "error-stack", + "hex", + "masking", + "router_derive", + "router_env", + "serde", + "serde_json", + "strum", + "thiserror", + "time", +] [[package]] name = "strsim" diff --git a/crates/router/Cargo.toml b/crates/router/Cargo.toml index f1c78431c5..cbb245bb24 100644 --- a/crates/router/Cargo.toml +++ b/crates/router/Cargo.toml @@ -69,6 +69,7 @@ masking = { version = "0.1.0", path = "../masking" } redis_interface = { version = "0.1.0", path = "../redis_interface" } router_derive = { version = "0.1.0", path = "../router_derive" } router_env = { version = "0.1.0", path = "../router_env", features = ["log_extra_implicit_fields", "log_custom_entries_to_extra"] } +storage_models = { version = "0.1.0", path = "../storage_models" } [build-dependencies] router_env = { version = "0.1.0", path = "../router_env", default-features = false, features = ["vergen"] } diff --git a/crates/router/src/connector/checkout/transformers.rs b/crates/router/src/connector/checkout/transformers.rs index c777592321..d6e00c3b12 100644 --- a/crates/router/src/connector/checkout/transformers.rs +++ b/crates/router/src/connector/checkout/transformers.rs @@ -6,7 +6,11 @@ use crate::{ core::errors, pii::{self, Secret}, services, - types::{self, api, storage::enums}, + types::{ + self, api, + storage::enums, + transformers::{Foreign, ForeignFrom}, + }, }; #[derive(Debug, Serialize)] @@ -138,8 +142,11 @@ pub enum CheckoutPaymentStatus { Captured, } -impl From<(CheckoutPaymentStatus, Option)> for enums::AttemptStatus { - fn from(item: (CheckoutPaymentStatus, Option)) -> Self { +impl From)>> + for Foreign +{ + fn from(item: Foreign<(CheckoutPaymentStatus, Option)>) -> Self { + let item = item.0; let status = item.0; let capture_method = item.1; match status { @@ -157,6 +164,7 @@ impl From<(CheckoutPaymentStatus, Option)> for enums::Atte CheckoutPaymentStatus::Pending => enums::AttemptStatus::Authorizing, CheckoutPaymentStatus::CardVerified => enums::AttemptStatus::Pending, } + .into() } } @@ -203,7 +211,7 @@ impl TryFrom> ), }); Ok(types::RouterData { - status: enums::AttemptStatus::from(( + status: enums::AttemptStatus::foreign_from(( item.response.status, item.data.request.capture_method, )), @@ -227,7 +235,7 @@ impl TryFrom> item: types::PaymentsSyncResponseRouterData, ) -> Result { Ok(types::RouterData { - status: enums::AttemptStatus::from((item.response.status, None)), + status: enums::AttemptStatus::foreign_from((item.response.status, None)), response: Ok(types::PaymentsResponseData::TransactionResponse { resource_id: types::ResponseId::ConnectorTransactionId(item.response.id), //TODO: Add redirection details here diff --git a/crates/router/src/core/admin.rs b/crates/router/src/core/admin.rs index 951d3c45cc..d14489ba69 100644 --- a/crates/router/src/core/admin.rs +++ b/crates/router/src/core/admin.rs @@ -10,6 +10,7 @@ use crate::{ types::{ self, api, storage::{self, MerchantAccount}, + transformers::ForeignInto, }, utils::{self, OptionExt, ValueExt}, }; @@ -55,7 +56,7 @@ pub async fn create_merchant_account( merchant_details: Some(merchant_details), return_url: req.return_url, webhook_details: Some(webhook_details), - routing_algorithm: req.routing_algorithm.map(Into::into), + routing_algorithm: req.routing_algorithm.map(ForeignInto::foreign_into), custom_routing_rules: Some(custom_routing_rules), sub_merchants_enabled: req.sub_merchants_enabled, parent_merchant_id: get_parent_merchant( @@ -110,7 +111,9 @@ pub async fn get_merchant_account( merchant_details, return_url: merchant_account.return_url, webhook_details, - routing_algorithm: merchant_account.routing_algorithm.map(Into::into), + routing_algorithm: merchant_account + .routing_algorithm + .map(ForeignInto::foreign_into), custom_routing_rules, sub_merchants_enabled: merchant_account.sub_merchants_enabled, parent_merchant_id: merchant_account.parent_merchant_id, @@ -173,7 +176,7 @@ pub async fn merchant_account_update( }, routing_algorithm: req .routing_algorithm - .map(Into::into) + .map(ForeignInto::foreign_into) .or(merchant_account.routing_algorithm), custom_routing_rules: if req.custom_routing_rules.is_some() { Some( @@ -310,7 +313,7 @@ pub async fn create_payment_connector( let merchant_connector_account = storage::MerchantConnectorAccountNew { merchant_id: Some(merchant_id.to_string()), - connector_type: Some(req.connector_type.into()), + connector_type: Some(req.connector_type.foreign_into()), connector_name: Some(req.connector_name), merchant_connector_id: None, connector_account_details: req.connector_account_details, @@ -358,7 +361,7 @@ pub async fn retrieve_payment_connector( None => None, }; let response = api::PaymentConnectorCreate { - connector_type: mca.connector_type.into(), + connector_type: mca.connector_type.foreign_into(), connector_name: mca.connector_name, merchant_connector_id: Some(mca.merchant_connector_id), connector_account_details: Some(Secret::new(mca.connector_account_details)), @@ -409,7 +412,7 @@ pub async fn update_payment_connector( }; let payment_connector = storage::MerchantConnectorAccountUpdate::Update { merchant_id: Some(merchant_id.to_string()), - connector_type: Some(req.connector_type.into()), + connector_type: Some(req.connector_type.foreign_into()), connector_name: Some(req.connector_name), merchant_connector_id: Some(merchant_connector_id), connector_account_details: req @@ -425,7 +428,7 @@ pub async fn update_payment_connector( .await .change_context(errors::ApiErrorResponse::InternalServerError)?; let response = api::PaymentConnectorCreate { - connector_type: updated_mca.connector_type.into(), + connector_type: updated_mca.connector_type.foreign_into(), connector_name: updated_mca.connector_name, merchant_connector_id: Some(updated_mca.merchant_connector_id), connector_account_details: Some(Secret::new(updated_mca.connector_account_details)), diff --git a/crates/router/src/core/customers.rs b/crates/router/src/core/customers.rs index 6a4617be6c..e0981bca4f 100644 --- a/crates/router/src/core/customers.rs +++ b/crates/router/src/core/customers.rs @@ -35,14 +35,17 @@ pub async fn create_customer( let customer = match db.insert_customer(new_customer).await { Ok(customer) => customer, - Err(error) => match error.current_context() { - errors::StorageError::DatabaseError(errors::DatabaseError::UniqueViolation) => db - .find_customer_by_customer_id_merchant_id(&customer_id, &merchant_id) - .await - .change_context(errors::ApiErrorResponse::InternalServerError)?, - _ => Err(error.change_context(errors::ApiErrorResponse::InternalServerError))?, - }, + Err(error) => { + if error.current_context().is_db_unique_violation() { + db.find_customer_by_customer_id_merchant_id(&customer_id, &merchant_id) + .await + .change_context(errors::ApiErrorResponse::InternalServerError)? + } else { + Err(error.change_context(errors::ApiErrorResponse::InternalServerError))? + } + } }; + Ok(services::BachResponse::Json(customer.into())) } diff --git a/crates/router/src/core/errors.rs b/crates/router/src/core/errors.rs index 6b5f79a537..8498613da3 100644 --- a/crates/router/src/core/errors.rs +++ b/crates/router/src/core/errors.rs @@ -10,6 +10,7 @@ use config::ConfigError; use error_stack; pub use redis_interface::errors::RedisError; use router_env::opentelemetry::metrics::MetricsError; +use storage_models::errors as storage_errors; pub use self::api_error_response::ApiErrorResponse; pub(crate) use self::utils::{ApiClientErrorExt, ConnectorErrorExt, StorageErrorExt}; @@ -68,8 +69,7 @@ macro_rules! router_error_error_stack_specific { #[derive(Debug, thiserror::Error)] pub enum StorageError { #[error("DatabaseError: {0}")] - DatabaseError(#[from] DatabaseError), - + DatabaseError(error_stack::Report), #[error("ValueNotFound: {0}")] ValueNotFound(String), #[error("DuplicateValue: {0}")] @@ -78,21 +78,32 @@ pub enum StorageError { KVError, } -#[derive(Debug, thiserror::Error)] -pub enum DatabaseError { - #[error("An error occurred when obtaining database connection")] - DatabaseConnectionError, - #[error("The requested resource was not found in the database")] - NotFound, - #[error("A unique constraint violation occurred")] - UniqueViolation, - #[error("No fields were provided to be updated")] - NoFieldsToUpdate, - #[error("An error occurred when generating raw SQL query")] - QueryGenerationFailed, - // InsertFailed, - #[error("An unknown error occurred")] - Others, +impl From> for StorageError { + fn from(err: error_stack::Report) -> Self { + Self::DatabaseError(err) + } +} + +impl StorageError { + pub fn is_db_not_found(&self) -> bool { + match self { + Self::DatabaseError(err) => matches!( + err.current_context(), + storage_errors::DatabaseError::NotFound + ), + _ => false, + } + } + + pub fn is_db_unique_violation(&self) -> bool { + match self { + Self::DatabaseError(err) => matches!( + err.current_context(), + storage_errors::DatabaseError::UniqueViolation, + ), + _ => false, + } + } } impl_error_type!(AuthenticationError, "Authentication error"); @@ -123,7 +134,7 @@ pub enum BachError { ConfigurationError(ConfigError), #[error("{{ error_description: Database operation failed, error_message: {0} }}")] - EDatabaseError(error_stack::Report), + EDatabaseError(error_stack::Report), #[error("{{ error_description: Encryption module operation failed, error_message: {0} }}")] EEncryptionError(error_stack::Report), @@ -136,7 +147,7 @@ pub enum BachError { } router_error_error_stack_specific!( - error_stack::Report, + error_stack::Report, BachError::EDatabaseError(error_stack::Report) ); router_error_error_stack_specific!( diff --git a/crates/router/src/core/errors/utils.rs b/crates/router/src/core/errors/utils.rs index 3f71f497df..a7bac854fb 100644 --- a/crates/router/src/core/errors/utils.rs +++ b/crates/router/src/core/errors/utils.rs @@ -1,4 +1,3 @@ -use super::DatabaseError; use crate::{core::errors, logger}; pub(crate) trait StorageErrorExt { @@ -18,12 +17,10 @@ impl StorageErrorExt for error_stack::Report { self, not_found_response: errors::ApiErrorResponse, ) -> error_stack::Report { - match self.current_context() { - errors::StorageError::DatabaseError(DatabaseError::NotFound) => { - self.change_context(not_found_response) - } - errors::StorageError::ValueNotFound(_) => self.change_context(not_found_response), - _ => self.change_context(errors::ApiErrorResponse::InternalServerError), + if self.current_context().is_db_not_found() { + self.change_context(not_found_response) + } else { + self.change_context(errors::ApiErrorResponse::InternalServerError) } } @@ -31,11 +28,10 @@ impl StorageErrorExt for error_stack::Report { self, duplicate_response: errors::ApiErrorResponse, ) -> error_stack::Report { - match self.current_context() { - errors::StorageError::DatabaseError(DatabaseError::UniqueViolation) => { - self.change_context(duplicate_response) - } - _ => self.change_context(errors::ApiErrorResponse::InternalServerError), + if self.current_context().is_db_unique_violation() { + self.change_context(duplicate_response) + } else { + self.change_context(errors::ApiErrorResponse::InternalServerError) } } } diff --git a/crates/router/src/core/mandate.rs b/crates/router/src/core/mandate.rs index 6f78f869a3..7e6a680133 100644 --- a/crates/router/src/core/mandate.rs +++ b/crates/router/src/core/mandate.rs @@ -12,6 +12,7 @@ use crate::{ mandates::{self, MandateResponseExt}, }, storage, + transformers::ForeignInto, }, }; @@ -51,7 +52,7 @@ pub async fn revoke_mandate( Ok(services::BachResponse::Json( mandates::MandateRevokedResponse { mandate_id: mandate.mandate_id, - status: mandate.mandate_status.into(), + status: mandate.mandate_status.foreign_into(), }, )) } diff --git a/crates/router/src/core/payment_methods/cards.rs b/crates/router/src/core/payment_methods/cards.rs index d0bc34ba32..582f2a584a 100644 --- a/crates/router/src/core/payment_methods/cards.rs +++ b/crates/router/src/core/payment_methods/cards.rs @@ -18,6 +18,7 @@ use crate::{ types::{ api::{self, CreatePaymentMethodExt}, storage::{self, enums}, + transformers::ForeignInto, }, utils::{self, BytesExt, OptionExt, StringExt, ValueExt}, }; @@ -35,8 +36,8 @@ pub async fn create_payment_method( customer_id, merchant_id: merchant_id.to_string(), payment_method_id, - payment_method: req.payment_method.into(), - payment_method_type: req.payment_method_type.map(Into::into), + payment_method: req.payment_method.foreign_into(), + payment_method_type: req.payment_method_type.map(ForeignInto::foreign_into), payment_method_issuer: req.payment_method_issuer.clone(), ..storage::PaymentMethodNew::default() }) @@ -436,12 +437,14 @@ pub async fn list_customer_payment_method( let pma = api::CustomerPaymentMethod { payment_token: payment_token.to_string(), customer_id: pm.customer_id, - payment_method: pm.payment_method.into(), - payment_method_type: pm.payment_method_type.map(Into::into), + payment_method: pm.payment_method.foreign_into(), + payment_method_type: pm.payment_method_type.map(ForeignInto::foreign_into), payment_method_issuer: pm.payment_method_issuer, card, metadata: None, - payment_method_issuer_code: pm.payment_method_issuer_code.map(Into::into), + payment_method_issuer_code: pm + .payment_method_issuer_code + .map(ForeignInto::foreign_into), recurring_enabled: false, installment_payment_enabled: false, payment_experience: Some(vec!["redirect_to_url".to_string()]), //TODO chnage to enum @@ -611,13 +614,13 @@ pub async fn retrieve_payment_method( }; Ok(services::BachResponse::Json(api::PaymentMethodResponse { payment_method_id: pm.payment_method_id, - payment_method: pm.payment_method.into(), - payment_method_type: pm.payment_method_type.map(Into::into), + payment_method: pm.payment_method.foreign_into(), + payment_method_type: pm.payment_method_type.map(ForeignInto::foreign_into), payment_method_issuer: pm.payment_method_issuer, card, metadata: None, // TODO add in addCard api created: Some(pm.created_at), - payment_method_issuer_code: pm.payment_method_issuer_code.map(Into::into), + payment_method_issuer_code: pm.payment_method_issuer_code.map(ForeignInto::foreign_into), recurring_enabled: false, //TODO installment_payment_enabled: false, //TODO payment_experience: Some(vec!["redirect_to_url".to_string()]), //TODO, diff --git a/crates/router/src/core/payments.rs b/crates/router/src/core/payments.rs index 61a47e4bc2..f51db03acf 100644 --- a/crates/router/src/core/payments.rs +++ b/crates/router/src/core/payments.rs @@ -33,7 +33,8 @@ use crate::{ types::{ self, api::{self, PaymentIdTypeExt, PaymentsResponse, PaymentsRetrieveRequest}, - storage::{self, enums}, + storage::{self, enums, ProcessTrackerExt}, + transformers::ForeignInto, }, utils::{self, OptionExt}, }; @@ -573,7 +574,10 @@ pub async fn list_payments( .await .map_err(|err| err.to_not_found_response(errors::ApiErrorResponse::PaymentNotFound))?; - let data: Vec = payment_intent.into_iter().map(From::from).collect(); + let data: Vec = payment_intent + .into_iter() + .map(ForeignInto::foreign_into) + .collect(); utils::when( data.is_empty(), Err(errors::ApiErrorResponse::PaymentNotFound), diff --git a/crates/router/src/core/payments/helpers.rs b/crates/router/src/core/payments/helpers.rs index b1805c5d1f..5576a172cc 100644 --- a/crates/router/src/core/payments/helpers.rs +++ b/crates/router/src/core/payments/helpers.rs @@ -24,6 +24,7 @@ use crate::{ self, api::{self, enums as api_enums, CustomerAcceptanceExt, MandateValidationFieldsExt}, storage::{self, enums as storage_enums, ephemeral_key}, + transformers::ForeignInto, }, utils::{ self, @@ -44,7 +45,7 @@ pub async fn get_address_for_payment_request( Some(address) => { match address_id { Some(id) => Some( - db.update_address(id.to_owned(), address.into()) + db.update_address(id.to_owned(), address.foreign_into()) .await .map_err(|err| { err.to_not_found_response(errors::ApiErrorResponse::AddressNotFound) @@ -119,7 +120,7 @@ pub async fn get_token_pm_type_mandate_details( .get_required_value("mandate_data")?; Ok(( request.payment_token.to_owned(), - request.payment_method.map(Into::into), + request.payment_method.map(ForeignInto::foreign_into), Some(setup_mandate), )) } @@ -130,7 +131,7 @@ pub async fn get_token_pm_type_mandate_details( } None => Ok(( request.payment_token.to_owned(), - request.payment_method.map(Into::into), + request.payment_method.map(ForeignInto::foreign_into), request.mandate_data.clone(), )), } @@ -184,7 +185,7 @@ pub async fn get_token_for_recurring_mandate( let _ = cards::get_lookup_key_from_locker(state, &token, &payment_method).await?; if let Some(payment_method_from_request) = req.payment_method { - let pm: storage_enums::PaymentMethodType = payment_method_from_request.into(); + let pm: storage_enums::PaymentMethodType = payment_method_from_request.foreign_into(); if pm != payment_method.payment_method { Err(report!(errors::ApiErrorResponse::PreconditionFailed { message: "payment method in request does not match previously provided payment \ @@ -464,7 +465,7 @@ pub(crate) async fn call_payment_method( let customer_id = customer.customer_id.clone(); let payment_method_request = api::CreatePaymentMethod { merchant_id: Some(merchant_id.to_string()), - payment_method: payment_method_type.into(), + payment_method: payment_method_type.foreign_into(), payment_method_type: None, payment_method_issuer: None, payment_method_issuer_code: None, @@ -496,7 +497,7 @@ pub(crate) async fn call_payment_method( _ => { let payment_method_request = api::CreatePaymentMethod { merchant_id: Some(merchant_id.to_string()), - payment_method: payment_method_type.into(), + payment_method: payment_method_type.foreign_into(), payment_method_type: None, payment_method_issuer: None, payment_method_issuer_code: None, @@ -1160,14 +1161,14 @@ pub fn generate_mandate( Some(match data.mandate_type { api::MandateType::SingleUse(data) => new_mandate .set_mandate_amount(Some(data.amount)) - .set_mandate_currency(Some(data.currency.into())) + .set_mandate_currency(Some(data.currency.foreign_into())) .set_mandate_type(storage_enums::MandateType::SingleUse) .to_owned(), api::MandateType::MultiUse(op_data) => match op_data { Some(data) => new_mandate .set_mandate_amount(Some(data.amount)) - .set_mandate_currency(Some(data.currency.into())), + .set_mandate_currency(Some(data.currency.foreign_into())), None => &mut new_mandate, } .set_mandate_type(storage_enums::MandateType::MultiUse) diff --git a/crates/router/src/core/payments/operations/payment_capture.rs b/crates/router/src/core/payments/operations/payment_capture.rs index 95fe0858dc..245b150111 100644 --- a/crates/router/src/core/payments/operations/payment_capture.rs +++ b/crates/router/src/core/payments/operations/payment_capture.rs @@ -15,6 +15,7 @@ use crate::{ types::{ api::{self, PaymentIdTypeExt, PaymentsCaptureRequest}, storage::{self, enums}, + transformers::ForeignInto, }, utils::OptionExt, }; @@ -128,8 +129,8 @@ impl GetTracker, api::PaymentsCaptu setup_mandate: None, token: None, address: payments::PaymentAddress { - shipping: shipping_address.as_ref().map(|a| a.into()), - billing: billing_address.as_ref().map(|a| a.into()), + shipping: shipping_address.as_ref().map(|a| a.foreign_into()), + billing: billing_address.as_ref().map(|a| a.foreign_into()), }, confirm: None, payment_method_data: None, diff --git a/crates/router/src/core/payments/operations/payment_confirm.rs b/crates/router/src/core/payments/operations/payment_confirm.rs index 0e0ada459c..411aa3eaba 100644 --- a/crates/router/src/core/payments/operations/payment_confirm.rs +++ b/crates/router/src/core/payments/operations/payment_confirm.rs @@ -18,6 +18,7 @@ use crate::{ self, api::{self, PaymentIdTypeExt}, storage::{self, enums}, + transformers::ForeignInto, }, utils::{self, OptionExt}, }; @@ -147,8 +148,8 @@ impl GetTracker, api::PaymentsRequest> for Pa setup_mandate, token, address: PaymentAddress { - shipping: shipping_address.as_ref().map(|a| a.into()), - billing: billing_address.as_ref().map(|a| a.into()), + shipping: shipping_address.as_ref().map(|a| a.foreign_into()), + billing: billing_address.as_ref().map(|a| a.foreign_into()), }, confirm: request.confirm, payment_method_data: request.payment_method_data.clone(), diff --git a/crates/router/src/core/payments/operations/payment_create.rs b/crates/router/src/core/payments/operations/payment_create.rs index 9233979645..6f84268c0e 100644 --- a/crates/router/src/core/payments/operations/payment_create.rs +++ b/crates/router/src/core/payments/operations/payment_create.rs @@ -23,6 +23,7 @@ use crate::{ self, enums::{self, IntentStatus}, }, + transformers::ForeignInto, }, utils::OptionExt, }; @@ -107,8 +108,8 @@ impl GetTracker, api::PaymentsRequest> for Pa { Ok(payment_attempt) => Ok(payment_attempt), - Err(err) => match err.current_context() { - errors::StorageError::DatabaseError(errors::DatabaseError::UniqueViolation) => { + Err(err) => { + if err.current_context().is_db_unique_violation() { is_update = true; db.find_payment_attempt_by_payment_id_merchant_id( &payment_id, @@ -119,10 +120,12 @@ impl GetTracker, api::PaymentsRequest> for Pa .map_err(|error| { error.to_not_found_response(errors::ApiErrorResponse::PaymentNotFound) }) + } else { + Err(err).change_context(errors::ApiErrorResponse::InternalServerError) } - _ => Err(err).change_context(errors::ApiErrorResponse::InternalServerError), - }, + } }?; + payment_intent = match db .insert_payment_intent( Self::make_payment_intent( @@ -139,8 +142,8 @@ impl GetTracker, api::PaymentsRequest> for Pa { Ok(payment_intent) => Ok(payment_intent), - Err(err) => match err.current_context() { - errors::StorageError::DatabaseError(errors::DatabaseError::UniqueViolation) => { + Err(err) => { + if err.current_context().is_db_unique_violation() { is_update = true; db.find_payment_intent_by_payment_id_merchant_id( &payment_id, @@ -151,9 +154,10 @@ impl GetTracker, api::PaymentsRequest> for Pa .map_err(|error| { error.to_not_found_response(errors::ApiErrorResponse::PaymentNotFound) }) + } else { + Err(err).change_context(errors::ApiErrorResponse::InternalServerError) } - _ => Err(err).change_context(errors::ApiErrorResponse::InternalServerError), - }, + } }?; connector_response = match db @@ -164,16 +168,17 @@ impl GetTracker, api::PaymentsRequest> for Pa .await { Ok(connector_resp) => Ok(connector_resp), - Err(err) => match err.current_context() { - errors::StorageError::DatabaseError(errors::DatabaseError::UniqueViolation) => { + Err(err) => { + if err.current_context().is_db_unique_violation() { Err(err) .change_context(errors::ApiErrorResponse::InternalServerError) .attach_printable("Duplicate connector response in the database") + } else { + Err(err) + .change_context(errors::ApiErrorResponse::InternalServerError) + .attach_printable("Error occured when inserting connector response") } - _ => Err(err) - .change_context(errors::ApiErrorResponse::InternalServerError) - .attach_printable("Error occured when inserting connector response")?, - }, + } }?; let operation = payments::if_not_create_change_operation::<_, F>( @@ -194,8 +199,8 @@ impl GetTracker, api::PaymentsRequest> for Pa setup_mandate, token, address: PaymentAddress { - shipping: shipping_address.as_ref().map(|a| a.into()), - billing: billing_address.as_ref().map(|a| a.into()), + shipping: shipping_address.as_ref().map(|a| a.foreign_into()), + billing: billing_address.as_ref().map(|a| a.foreign_into()), }, confirm: request.confirm, payment_method_data: request.payment_method_data.clone(), @@ -341,13 +346,13 @@ impl PaymentCreate { amount: amount.into(), currency, payment_method, - capture_method: request.capture_method.map(Into::into), + capture_method: request.capture_method.map(ForeignInto::foreign_into), capture_on: request.capture_on, confirm: request.confirm.unwrap_or(false), created_at, modified_at, last_synced, - authentication_type: request.authentication_type.map(Into::into), + authentication_type: request.authentication_type.map(ForeignInto::foreign_into), browser_info, ..storage::PaymentAttemptNew::default() } @@ -379,7 +384,7 @@ impl PaymentCreate { modified_at, last_synced, client_secret: Some(client_secret), - setup_future_usage: request.setup_future_usage.map(Into::into), + setup_future_usage: request.setup_future_usage.map(ForeignInto::foreign_into), off_session: request.off_session, return_url: request.return_url.clone(), shipping_address_id, diff --git a/crates/router/src/core/payments/operations/payment_method_validate.rs b/crates/router/src/core/payments/operations/payment_method_validate.rs index 3c91337730..cc3f5b8ba2 100644 --- a/crates/router/src/core/payments/operations/payment_method_validate.rs +++ b/crates/router/src/core/payments/operations/payment_method_validate.rs @@ -21,6 +21,7 @@ use crate::{ self, api::{self, enums as api_enums, PaymentIdTypeExt}, storage::{self, enums as storage_enums}, + transformers::ForeignInto, }, utils, }; @@ -284,7 +285,7 @@ impl PaymentMethodValidate { amount: 0, currency: Default::default(), connector: None, - payment_method: payment_method.map(Into::into), + payment_method: payment_method.map(ForeignInto::foreign_into), confirm: true, created_at, modified_at, @@ -314,7 +315,7 @@ impl PaymentMethodValidate { modified_at, last_synced, client_secret: Some(client_secret), - setup_future_usage: request.setup_future_usage.map(Into::into), + setup_future_usage: request.setup_future_usage.map(ForeignInto::foreign_into), off_session: request.off_session, ..Default::default() } diff --git a/crates/router/src/core/payments/operations/payment_response.rs b/crates/router/src/core/payments/operations/payment_response.rs index 61b91bcf31..a2761eb68e 100644 --- a/crates/router/src/core/payments/operations/payment_response.rs +++ b/crates/router/src/core/payments/operations/payment_response.rs @@ -13,6 +13,7 @@ use crate::{ types::{ self, api, storage::{self, enums}, + transformers::ForeignInto, }, utils, }; @@ -259,7 +260,7 @@ async fn payment_response_update_tracker( status: enums::IntentStatus::Failed, }, Ok(_) => storage::PaymentIntentUpdate::ResponseUpdate { - status: router_data.status.into(), + status: router_data.status.foreign_into(), return_url: router_data.return_url, amount_captured: None, }, diff --git a/crates/router/src/core/payments/operations/payment_session.rs b/crates/router/src/core/payments/operations/payment_session.rs index c87b17b205..a629e85a3c 100644 --- a/crates/router/src/core/payments/operations/payment_session.rs +++ b/crates/router/src/core/payments/operations/payment_session.rs @@ -16,6 +16,7 @@ use crate::{ types::{ api::{self, PaymentIdTypeExt}, storage::{self, enums}, + transformers::ForeignInto, }, utils::OptionExt, }; @@ -126,8 +127,8 @@ impl GetTracker, api::PaymentsSessionRequest> token: None, setup_mandate: None, address: payments::PaymentAddress { - shipping: shipping_address.as_ref().map(|a| a.into()), - billing: billing_address.as_ref().map(|a| a.into()), + shipping: shipping_address.as_ref().map(|a| a.foreign_into()), + billing: billing_address.as_ref().map(|a| a.foreign_into()), }, confirm: None, payment_method_data: None, diff --git a/crates/router/src/core/payments/operations/payment_start.rs b/crates/router/src/core/payments/operations/payment_start.rs index c4dcaf29fc..d513c48016 100644 --- a/crates/router/src/core/payments/operations/payment_start.rs +++ b/crates/router/src/core/payments/operations/payment_start.rs @@ -16,6 +16,7 @@ use crate::{ types::{ api::{self, PaymentIdTypeExt}, storage::{self, enums, Customer}, + transformers::ForeignInto, }, utils::OptionExt, }; @@ -131,8 +132,8 @@ impl GetTracker, api::PaymentsStartRequest> f setup_mandate: None, token: None, address: PaymentAddress { - shipping: shipping_address.as_ref().map(|a| a.into()), - billing: billing_address.as_ref().map(|a| a.into()), + shipping: shipping_address.as_ref().map(|a| a.foreign_into()), + billing: billing_address.as_ref().map(|a| a.foreign_into()), }, confirm: Some(payment_attempt.confirm), payment_attempt, diff --git a/crates/router/src/core/payments/operations/payment_status.rs b/crates/router/src/core/payments/operations/payment_status.rs index cd80a11cc4..3215a1945a 100644 --- a/crates/router/src/core/payments/operations/payment_status.rs +++ b/crates/router/src/core/payments/operations/payment_status.rs @@ -16,6 +16,7 @@ use crate::{ types::{ api, storage::{self, enums}, + transformers::ForeignInto, }, utils::{self, OptionExt}, }; @@ -201,8 +202,8 @@ async fn get_tracker_for_sync< setup_mandate: None, token: None, address: PaymentAddress { - shipping: shipping_address.as_ref().map(|a| a.into()), - billing: billing_address.as_ref().map(|a| a.into()), + shipping: shipping_address.as_ref().map(|a| a.foreign_into()), + billing: billing_address.as_ref().map(|a| a.foreign_into()), }, confirm: Some(request.force_sync), payment_method_data: None, diff --git a/crates/router/src/core/payments/operations/payment_update.rs b/crates/router/src/core/payments/operations/payment_update.rs index 21e37d1907..f5e0c62a07 100644 --- a/crates/router/src/core/payments/operations/payment_update.rs +++ b/crates/router/src/core/payments/operations/payment_update.rs @@ -17,6 +17,7 @@ use crate::{ types::{ api::{self, PaymentIdTypeExt}, storage::{self, enums}, + transformers::ForeignInto, }, utils::{OptionExt, StringExt}, }; @@ -147,8 +148,8 @@ impl GetTracker, api::PaymentsRequest> for Pa token, setup_mandate, address: PaymentAddress { - shipping: shipping_address.as_ref().map(|a| a.into()), - billing: billing_address.as_ref().map(|a| a.into()), + shipping: shipping_address.as_ref().map(|a| a.foreign_into()), + billing: billing_address.as_ref().map(|a| a.foreign_into()), }, confirm: request.confirm, payment_method_data: request.payment_method_data.clone(), diff --git a/crates/router/src/core/payments/transformers.rs b/crates/router/src/core/payments/transformers.rs index 2e98a615dd..3daf214769 100644 --- a/crates/router/src/core/payments/transformers.rs +++ b/crates/router/src/core/payments/transformers.rs @@ -16,6 +16,7 @@ use crate::{ self, api::{self, NextAction, PaymentsResponse}, storage::{self, enums}, + transformers::ForeignInto, }, utils::{OptionExt, ValueExt}, }; @@ -196,7 +197,10 @@ where .as_ref() .and_then(|cus| cus.phone.as_ref().map(|s| s.to_owned())), mandate_id: data.mandate_id, - payment_method: data.payment_attempt.payment_method.map(Into::into), + payment_method: data + .payment_attempt + .payment_method + .map(ForeignInto::foreign_into), payment_method_data: data .payment_method_data .map(api::PaymentMethodDataResponse::from), @@ -237,7 +241,7 @@ where let refunds_response = if refunds.is_empty() { None } else { - Some(refunds.into_iter().map(From::from).collect()) + Some(refunds.into_iter().map(ForeignInto::foreign_into).collect()) }; Ok(match payment_request { @@ -265,7 +269,7 @@ where response .set_payment_id(Some(payment_attempt.payment_id)) .set_merchant_id(Some(payment_attempt.merchant_id)) - .set_status(payment_intent.status.into()) + .set_status(payment_intent.status.foreign_into()) .set_amount(payment_attempt.amount) .set_amount_capturable(None) .set_amount_received(payment_intent.amount_captured) @@ -292,7 +296,9 @@ where .set_description(payment_intent.description) .set_refunds(refunds_response) // refunds.iter().map(refund_to_refund_response), .set_payment_method( - payment_attempt.payment_method.map(Into::into), + payment_attempt + .payment_method + .map(ForeignInto::foreign_into), auth_flow == services::AuthFlow::Merchant, ) .set_payment_method_data( @@ -306,12 +312,22 @@ where .set_next_action(next_action_response) .set_return_url(payment_intent.return_url) .set_authentication_type( - payment_attempt.authentication_type.map(Into::into), + payment_attempt + .authentication_type + .map(ForeignInto::foreign_into), ) .set_statement_descriptor_name(payment_intent.statement_descriptor_name) .set_statement_descriptor_suffix(payment_intent.statement_descriptor_suffix) - .set_setup_future_usage(payment_intent.setup_future_usage.map(Into::into)) - .set_capture_method(payment_attempt.capture_method.map(Into::into)) + .set_setup_future_usage( + payment_intent + .setup_future_usage + .map(ForeignInto::foreign_into), + ) + .set_capture_method( + payment_attempt + .capture_method + .map(ForeignInto::foreign_into), + ) .to_owned(), ) } @@ -319,7 +335,7 @@ where None => services::BachResponse::Json(PaymentsResponse { payment_id: Some(payment_attempt.payment_id), merchant_id: Some(payment_attempt.merchant_id), - status: payment_intent.status.into(), + status: payment_intent.status.foreign_into(), amount: payment_attempt.amount, amount_capturable: None, amount_received: payment_intent.amount_captured, @@ -329,8 +345,12 @@ where customer_id: payment_intent.customer_id, description: payment_intent.description, refunds: refunds_response, - payment_method: payment_attempt.payment_method.map(Into::into), - capture_method: payment_attempt.capture_method.map(Into::into), + payment_method: payment_attempt + .payment_method + .map(ForeignInto::foreign_into), + capture_method: payment_attempt + .capture_method + .map(ForeignInto::foreign_into), error_message: payment_attempt.error_message, payment_method_data: payment_method_data.map(api::PaymentMethodDataResponse::from), email: customer diff --git a/crates/router/src/core/refunds.rs b/crates/router/src/core/refunds.rs index fc2e4937ad..f61de78d2a 100644 --- a/crates/router/src/core/refunds.rs +++ b/crates/router/src/core/refunds.rs @@ -16,7 +16,8 @@ use crate::{ types::{ self, api::{self, refunds}, - storage::{self, enums}, + storage::{self, enums, ProcessTrackerExt}, + transformers::{Foreign, ForeignInto}, }, utils::{self, OptionExt}, }; @@ -172,10 +173,10 @@ pub async fn refund_response_wrapper<'a, F, Fut, T>( where F: Fn(&'a AppState, storage::MerchantAccount, String) -> Fut, Fut: futures::Future>, - refunds::RefundResponse: From, + T: ForeignInto, { Ok(services::BachResponse::Json( - f(state, merchant_account, refund_id).await?.into(), + f(state, merchant_account, refund_id).await?.foreign_into(), )) } @@ -327,7 +328,7 @@ pub async fn refund_update_core( .await .change_context(errors::ApiErrorResponse::InternalServerError)?; - Ok(services::BachResponse::Json(response.into())) + Ok(services::BachResponse::Json(response.foreign_into())) } // ********************************************** VALIDATIONS ********************************************** @@ -442,7 +443,8 @@ pub async fn validate_and_create_refund( .await? } }; - Ok(refund.into()) + + Ok(refund.foreign_into()) } // ********************************************** UTILS ********************************************** @@ -493,7 +495,7 @@ impl TryFrom> for refunds::RefundResponse { let response = data.response; let (status, error_message) = match response { - Ok(response) => (response.refund_status.into(), None), + Ok(response) => (response.refund_status.foreign_into(), None), Err(error_response) => (api::RefundStatus::Pending, Some(error_response.message)), }; @@ -510,18 +512,20 @@ impl TryFrom> for refunds::RefundResponse { } } -impl From for api::RefundResponse { - fn from(refund: storage::Refund) -> Self { - Self { +impl From> for Foreign { + fn from(refund: Foreign) -> Self { + let refund = refund.0; + api::RefundResponse { payment_id: refund.payment_id, refund_id: refund.refund_id, amount: refund.refund_amount, currency: refund.currency.to_string(), reason: refund.description, - status: refund.refund_status.into(), + status: refund.refund_status.foreign_into(), metadata: refund.metadata, error_message: refund.refund_error_message, } + .into() } } diff --git a/crates/router/src/core/refunds/validator.rs b/crates/router/src/core/refunds/validator.rs index 056a4ef058..e47591658f 100644 --- a/crates/router/src/core/refunds/validator.rs +++ b/crates/router/src/core/refunds/validator.rs @@ -102,12 +102,16 @@ pub async fn validate_uniqueness_of_refund_id_against_merchant_id( .await; logger::debug!(?refund); match refund { - Err(err) => match err.current_context() { - // Empty vec should be returned by query in case of no results, this check exists just - // to be on the safer side. Fixed this, now vector is not returned but should check the flow in detail later. - errors::StorageError::DatabaseError(errors::DatabaseError::NotFound) => Ok(None), - _ => Err(err.change_context(errors::ApiErrorResponse::InternalServerError)), - }, + Err(err) => { + if err.current_context().is_db_not_found() { + // Empty vec should be returned by query in case of no results, this check exists just + // to be on the safer side. Fixed this, now vector is not returned but should check the flow in detail later. + Ok(None) + } else { + Err(err.change_context(errors::ApiErrorResponse::InternalServerError)) + } + } + Ok(refund) => { if refund.payment_id == payment_id { Ok(Some(refund)) diff --git a/crates/router/src/core/webhooks.rs b/crates/router/src/core/webhooks.rs index 5dff359803..d581b848a1 100644 --- a/crates/router/src/core/webhooks.rs +++ b/crates/router/src/core/webhooks.rs @@ -18,6 +18,7 @@ use crate::{ types::{ api, storage::{self, enums}, + transformers::{ForeignInto, ForeignTryInto}, }, utils::{generate_id, Encode, OptionExt, ValueExt}, }; @@ -66,7 +67,7 @@ async fn payments_incoming_webhook_flow( let event_type: enums::EventType = payments_response .status - .try_into() + .foreign_try_into() .into_report() .change_context(errors::WebhooksFlowError::PaymentsCoreFailed)?; @@ -123,7 +124,7 @@ async fn create_event_and_trigger_outgoing_webhook( let outgoing_webhook = api::OutgoingWebhook { merchant_id: merchant_account.merchant_id.clone(), event_id: event.event_id, - event_type: event.event_type.into(), + event_type: event.event_type.foreign_into(), content, timestamp: event.created_at, }; diff --git a/crates/router/src/db/address.rs b/crates/router/src/db/address.rs index 522ac70a99..bfed05381e 100644 --- a/crates/router/src/db/address.rs +++ b/crates/router/src/db/address.rs @@ -1,3 +1,5 @@ +use error_stack::IntoReport; + use super::MockDb; use crate::{ connection::pg_connection, @@ -24,7 +26,10 @@ pub trait AddressInterface { impl AddressInterface for super::Store { async fn find_address(&self, address_id: &str) -> CustomResult { let conn = pg_connection(&self.master_pool).await; - Address::find_by_address_id(&conn, address_id).await + Address::find_by_address_id(&conn, address_id) + .await + .map_err(Into::into) + .into_report() } async fn update_address( @@ -33,7 +38,10 @@ impl AddressInterface for super::Store { address: AddressUpdate, ) -> CustomResult { let conn = pg_connection(&self.master_pool).await; - Address::update_by_address_id(&conn, address_id, address).await + Address::update_by_address_id(&conn, address_id, address) + .await + .map_err(Into::into) + .into_report() } async fn insert_address( @@ -41,7 +49,11 @@ impl AddressInterface for super::Store { address: AddressNew, ) -> CustomResult { let conn = pg_connection(&self.master_pool).await; - address.insert(&conn).await + address + .insert(&conn) + .await + .map_err(Into::into) + .into_report() } } diff --git a/crates/router/src/db/configs.rs b/crates/router/src/db/configs.rs index 99d95ce0b7..2d94d50846 100644 --- a/crates/router/src/db/configs.rs +++ b/crates/router/src/db/configs.rs @@ -1,3 +1,5 @@ +use error_stack::IntoReport; + use super::MockDb; use crate::{ connection::pg_connection, @@ -20,12 +22,15 @@ pub trait ConfigInterface { impl ConfigInterface for super::Store { async fn insert_config(&self, config: ConfigNew) -> CustomResult { let conn = pg_connection(&self.master_pool).await; - config.insert(&conn).await + config.insert(&conn).await.map_err(Into::into).into_report() } async fn find_config_by_key(&self, key: &str) -> CustomResult { let conn = pg_connection(&self.master_pool).await; - Config::find_by_key(&conn, key).await + Config::find_by_key(&conn, key) + .await + .map_err(Into::into) + .into_report() } async fn update_config_by_key( @@ -34,7 +39,10 @@ impl ConfigInterface for super::Store { config_update: ConfigUpdate, ) -> CustomResult { let conn = pg_connection(&self.master_pool).await; - Config::update_by_key(&conn, key, config_update).await + Config::update_by_key(&conn, key, config_update) + .await + .map_err(Into::into) + .into_report() } } diff --git a/crates/router/src/db/connector_response.rs b/crates/router/src/db/connector_response.rs index cc68e2b9ad..b101c5c3fb 100644 --- a/crates/router/src/db/connector_response.rs +++ b/crates/router/src/db/connector_response.rs @@ -1,3 +1,5 @@ +use error_stack::IntoReport; + use super::MockDb; use crate::{ connection::pg_connection, @@ -37,7 +39,11 @@ impl ConnectorResponseInterface for super::Store { _storage_scheme: enums::MerchantStorageScheme, ) -> CustomResult { let conn = pg_connection(&self.master_pool).await; - connector_response.insert(&conn).await + connector_response + .insert(&conn) + .await + .map_err(Into::into) + .into_report() } async fn find_connector_response_by_payment_id_merchant_id_txn_id( @@ -55,6 +61,8 @@ impl ConnectorResponseInterface for super::Store { txn_id, ) .await + .map_err(Into::into) + .into_report() } async fn update_connector_response( @@ -64,7 +72,10 @@ impl ConnectorResponseInterface for super::Store { _storage_scheme: enums::MerchantStorageScheme, ) -> CustomResult { let conn = pg_connection(&self.master_pool).await; - this.update(&conn, connector_response_update).await + this.update(&conn, connector_response_update) + .await + .map_err(Into::into) + .into_report() } } diff --git a/crates/router/src/db/customers.rs b/crates/router/src/db/customers.rs index 7bcfd969aa..dacabafa48 100644 --- a/crates/router/src/db/customers.rs +++ b/crates/router/src/db/customers.rs @@ -1,3 +1,5 @@ +use error_stack::IntoReport; + use super::MockDb; use crate::{ connection::pg_connection, @@ -46,7 +48,10 @@ impl CustomerInterface for super::Store { merchant_id: &str, ) -> CustomResult, errors::StorageError> { let conn = pg_connection(&self.master_pool).await; - Customer::find_optional_by_customer_id_merchant_id(&conn, customer_id, merchant_id).await + Customer::find_optional_by_customer_id_merchant_id(&conn, customer_id, merchant_id) + .await + .map_err(Into::into) + .into_report() } async fn update_customer_by_customer_id_merchant_id( @@ -56,7 +61,10 @@ impl CustomerInterface for super::Store { customer: CustomerUpdate, ) -> CustomResult { let conn = pg_connection(&self.master_pool).await; - Customer::update_by_customer_id_merchant_id(&conn, customer_id, merchant_id, customer).await + Customer::update_by_customer_id_merchant_id(&conn, customer_id, merchant_id, customer) + .await + .map_err(Into::into) + .into_report() } async fn find_customer_by_customer_id_merchant_id( @@ -65,7 +73,10 @@ impl CustomerInterface for super::Store { merchant_id: &str, ) -> CustomResult { let conn = pg_connection(&self.master_pool).await; - Customer::find_by_customer_id_merchant_id(&conn, customer_id, merchant_id).await + Customer::find_by_customer_id_merchant_id(&conn, customer_id, merchant_id) + .await + .map_err(Into::into) + .into_report() } async fn insert_customer( @@ -73,7 +84,11 @@ impl CustomerInterface for super::Store { customer_data: CustomerNew, ) -> CustomResult { let conn = pg_connection(&self.master_pool).await; - customer_data.insert_diesel(&conn).await + customer_data + .insert_diesel(&conn) + .await + .map_err(Into::into) + .into_report() } async fn delete_customer_by_customer_id_merchant_id( @@ -82,7 +97,10 @@ impl CustomerInterface for super::Store { merchant_id: &str, ) -> CustomResult { let conn = pg_connection(&self.master_pool).await; - Customer::delete_by_customer_id_merchant_id(&conn, customer_id, merchant_id).await + Customer::delete_by_customer_id_merchant_id(&conn, customer_id, merchant_id) + .await + .map_err(Into::into) + .into_report() } } diff --git a/crates/router/src/db/events.rs b/crates/router/src/db/events.rs index f78b6b12db..6ae0e92209 100644 --- a/crates/router/src/db/events.rs +++ b/crates/router/src/db/events.rs @@ -1,3 +1,5 @@ +use error_stack::IntoReport; + use super::MockDb; use crate::{ connection::pg_connection, @@ -14,7 +16,7 @@ pub trait EventInterface { impl EventInterface for super::Store { async fn insert_event(&self, event: EventNew) -> CustomResult { let conn = pg_connection(&self.master_pool).await; - event.insert(&conn).await + event.insert(&conn).await.map_err(Into::into).into_report() } } diff --git a/crates/router/src/db/locker_mock_up.rs b/crates/router/src/db/locker_mock_up.rs index 01fdaf0483..24c2b8d478 100644 --- a/crates/router/src/db/locker_mock_up.rs +++ b/crates/router/src/db/locker_mock_up.rs @@ -1,3 +1,5 @@ +use error_stack::IntoReport; + use super::MockDb; use crate::{ connection::pg_connection, @@ -25,7 +27,10 @@ impl LockerMockUpInterface for super::Store { card_id: &str, ) -> CustomResult { let conn = pg_connection(&self.master_pool).await; - LockerMockUp::find_by_card_id(&conn, card_id).await + LockerMockUp::find_by_card_id(&conn, card_id) + .await + .map_err(Into::into) + .into_report() } async fn insert_locker_mock_up( @@ -33,7 +38,7 @@ impl LockerMockUpInterface for super::Store { new: LockerMockUpNew, ) -> CustomResult { let conn = pg_connection(&self.master_pool).await; - new.insert(&conn).await + new.insert(&conn).await.map_err(Into::into).into_report() } } diff --git a/crates/router/src/db/mandate.rs b/crates/router/src/db/mandate.rs index d5e25b84bb..ee970425d2 100644 --- a/crates/router/src/db/mandate.rs +++ b/crates/router/src/db/mandate.rs @@ -1,3 +1,5 @@ +use error_stack::IntoReport; + use super::MockDb; use crate::{ connection::pg_connection, @@ -40,7 +42,10 @@ impl MandateInterface for super::Store { mandate_id: &str, ) -> CustomResult { let conn = pg_connection(&self.master_pool).await; - Mandate::find_by_merchant_id_mandate_id(&conn, merchant_id, mandate_id).await + Mandate::find_by_merchant_id_mandate_id(&conn, merchant_id, mandate_id) + .await + .map_err(Into::into) + .into_report() } async fn find_mandate_by_merchant_id_customer_id( @@ -49,7 +54,10 @@ impl MandateInterface for super::Store { customer_id: &str, ) -> CustomResult, errors::StorageError> { let conn = pg_connection(&self.master_pool).await; - Mandate::find_by_merchant_id_customer_id(&conn, merchant_id, customer_id).await + Mandate::find_by_merchant_id_customer_id(&conn, merchant_id, customer_id) + .await + .map_err(Into::into) + .into_report() } async fn update_mandate_by_merchant_id_mandate_id( @@ -59,7 +67,10 @@ impl MandateInterface for super::Store { mandate: MandateUpdate, ) -> CustomResult { let conn = pg_connection(&self.master_pool).await; - Mandate::update_by_merchant_id_mandate_id(&conn, merchant_id, mandate_id, mandate).await + Mandate::update_by_merchant_id_mandate_id(&conn, merchant_id, mandate_id, mandate) + .await + .map_err(Into::into) + .into_report() } async fn insert_mandate( @@ -67,7 +78,11 @@ impl MandateInterface for super::Store { mandate: MandateNew, ) -> CustomResult { let conn = pg_connection(&self.master_pool).await; - mandate.insert(&conn).await + mandate + .insert(&conn) + .await + .map_err(Into::into) + .into_report() } } diff --git a/crates/router/src/db/merchant_account.rs b/crates/router/src/db/merchant_account.rs index 435e9e88c3..84b3efeeca 100644 --- a/crates/router/src/db/merchant_account.rs +++ b/crates/router/src/db/merchant_account.rs @@ -1,10 +1,10 @@ -use error_stack::Report; +use error_stack::{IntoReport, Report}; use masking::PeekInterface; use super::MockDb; use crate::{ connection::pg_connection, - core::errors::{self, CustomResult, DatabaseError, StorageError}, + core::errors::{self, CustomResult}, types::storage::{enums, MerchantAccount, MerchantAccountNew, MerchantAccountUpdate}, }; @@ -49,7 +49,11 @@ impl MerchantAccountInterface for super::Store { merchant_account: MerchantAccountNew, ) -> CustomResult { let conn = pg_connection(&self.master_pool).await; - merchant_account.insert_diesel(&conn).await + merchant_account + .insert_diesel(&conn) + .await + .map_err(Into::into) + .into_report() } async fn find_merchant_account_by_merchant_id( @@ -57,7 +61,10 @@ impl MerchantAccountInterface for super::Store { merchant_id: &str, ) -> CustomResult { let conn = pg_connection(&self.master_pool).await; - MerchantAccount::find_by_merchant_id(&conn, merchant_id).await + MerchantAccount::find_by_merchant_id(&conn, merchant_id) + .await + .map_err(Into::into) + .into_report() } async fn update_merchant( @@ -66,7 +73,10 @@ impl MerchantAccountInterface for super::Store { merchant_account: MerchantAccountUpdate, ) -> CustomResult { let conn = pg_connection(&self.master_pool).await; - this.update(&conn, merchant_account).await + this.update(&conn, merchant_account) + .await + .map_err(Into::into) + .into_report() } async fn find_merchant_account_by_api_key( @@ -74,7 +84,10 @@ impl MerchantAccountInterface for super::Store { api_key: &str, ) -> CustomResult { let conn = pg_connection(&self.master_pool).await; - MerchantAccount::find_by_api_key(&conn, api_key).await + MerchantAccount::find_by_api_key(&conn, api_key) + .await + .map_err(Into::into) + .into_report() } async fn find_merchant_account_by_publishable_key( @@ -82,7 +95,10 @@ impl MerchantAccountInterface for super::Store { publishable_key: &str, ) -> CustomResult { let conn = pg_connection(&self.master_pool).await; - MerchantAccount::find_by_publishable_key(&conn, publishable_key).await + MerchantAccount::find_by_publishable_key(&conn, publishable_key) + .await + .map_err(Into::into) + .into_report() } async fn delete_merchant_account_by_merchant_id( @@ -90,7 +106,10 @@ impl MerchantAccountInterface for super::Store { merchant_id: &str, ) -> CustomResult { let conn = pg_connection(&self.master_pool).await; - MerchantAccount::delete_by_merchant_id(&conn, merchant_id).await + MerchantAccount::delete_by_merchant_id(&conn, merchant_id) + .await + .map_err(Into::into) + .into_report() } } @@ -163,7 +182,8 @@ impl MerchantAccountInterface for MockDb { .iter() .find(|account| account.api_key.as_ref().map(|s| s.peek()) == Some(&api_key.into())) .cloned() - .ok_or_else(|| Report::from(StorageError::DatabaseError(DatabaseError::NotFound))) + .ok_or_else(|| Report::from(storage_models::errors::DatabaseError::NotFound).into()) + .into_report() } async fn find_merchant_account_by_publishable_key( diff --git a/crates/router/src/db/merchant_connector_account.rs b/crates/router/src/db/merchant_connector_account.rs index 548f705c62..022bb3107b 100644 --- a/crates/router/src/db/merchant_connector_account.rs +++ b/crates/router/src/db/merchant_connector_account.rs @@ -1,3 +1,4 @@ +use error_stack::IntoReport; use masking::ExposeInterface; use super::MockDb; @@ -54,7 +55,10 @@ impl MerchantConnectorAccountInterface for super::Store { connector: &str, ) -> CustomResult { let conn = pg_connection(&self.master_pool).await; - MerchantConnectorAccount::find_by_merchant_id_connector(&conn, merchant_id, connector).await + MerchantConnectorAccount::find_by_merchant_id_connector(&conn, merchant_id, connector) + .await + .map_err(Into::into) + .into_report() } async fn find_by_merchant_connector_account_merchant_id_merchant_connector_id( @@ -69,6 +73,8 @@ impl MerchantConnectorAccountInterface for super::Store { merchant_connector_id, ) .await + .map_err(Into::into) + .into_report() } async fn insert_merchant_connector_account( @@ -76,7 +82,10 @@ impl MerchantConnectorAccountInterface for super::Store { t: MerchantConnectorAccountNew, ) -> CustomResult { let conn = pg_connection(&self.master_pool).await; - t.insert_diesel(&conn).await + t.insert_diesel(&conn) + .await + .map_err(Into::into) + .into_report() } async fn find_merchant_connector_account_by_merchant_id_list( @@ -84,7 +93,10 @@ impl MerchantConnectorAccountInterface for super::Store { merchant_id: &str, ) -> CustomResult, errors::StorageError> { let conn = pg_connection(&self.master_pool).await; - MerchantConnectorAccount::find_by_merchant_id(&conn, merchant_id).await + MerchantConnectorAccount::find_by_merchant_id(&conn, merchant_id) + .await + .map_err(Into::into) + .into_report() } async fn update_merchant_connector_account( @@ -93,7 +105,10 @@ impl MerchantConnectorAccountInterface for super::Store { merchant_connector_account: MerchantConnectorAccountUpdate, ) -> CustomResult { let conn = pg_connection(&self.master_pool).await; - this.update(&conn, merchant_connector_account).await + this.update(&conn, merchant_connector_account) + .await + .map_err(Into::into) + .into_report() } async fn delete_merchant_connector_account_by_merchant_id_merchant_connector_id( @@ -108,6 +123,8 @@ impl MerchantConnectorAccountInterface for super::Store { merchant_connector_id, ) .await + .map_err(Into::into) + .into_report() } } diff --git a/crates/router/src/db/payment_attempt.rs b/crates/router/src/db/payment_attempt.rs index 7eb1ccc0d8..77af845d07 100644 --- a/crates/router/src/db/payment_attempt.rs +++ b/crates/router/src/db/payment_attempt.rs @@ -58,6 +58,8 @@ pub trait PaymentAttemptInterface { #[cfg(not(feature = "kv_store"))] mod storage { + use error_stack::IntoReport; + use super::PaymentAttemptInterface; use crate::{ connection::pg_connection, @@ -74,7 +76,11 @@ mod storage { _storage_scheme: enums::MerchantStorageScheme, ) -> CustomResult { let conn = pg_connection(&self.master_pool).await; - payment_attempt.insert_diesel(&conn).await + payment_attempt + .insert_diesel(&conn) + .await + .map_err(Into::into) + .into_report() } async fn update_payment_attempt( @@ -84,7 +90,10 @@ mod storage { _storage_scheme: enums::MerchantStorageScheme, ) -> CustomResult { let conn = pg_connection(&self.master_pool).await; - this.update(&conn, payment_attempt).await + this.update(&conn, payment_attempt) + .await + .map_err(Into::into) + .into_report() } async fn find_payment_attempt_by_payment_id_merchant_id( @@ -94,7 +103,10 @@ mod storage { _storage_scheme: enums::MerchantStorageScheme, ) -> CustomResult { let conn = pg_connection(&self.master_pool).await; - PaymentAttempt::find_by_payment_id_merchant_id(&conn, payment_id, merchant_id).await + PaymentAttempt::find_by_payment_id_merchant_id(&conn, payment_id, merchant_id) + .await + .map_err(Into::into) + .into_report() } async fn find_payment_attempt_by_transaction_id_payment_id_merchant_id( @@ -112,6 +124,8 @@ mod storage { merchant_id, ) .await + .map_err(Into::into) + .into_report() } async fn find_payment_attempt_last_successful_attempt_by_payment_id_merchant_id( @@ -127,6 +141,8 @@ mod storage { merchant_id, ) .await + .map_err(Into::into) + .into_report() } async fn find_payment_attempt_by_merchant_id_connector_txn_id( @@ -144,6 +160,8 @@ mod storage { connector_txn_id, ) .await + .map_err(Into::into) + .into_report() } async fn find_payment_attempt_by_merchant_id_txn_id( @@ -154,7 +172,10 @@ mod storage { ) -> CustomResult { let conn = pg_connection(&self.master_pool).await; - PaymentAttempt::find_by_merchant_id_transaction_id(&conn, merchant_id, txn_id).await + PaymentAttempt::find_by_merchant_id_transaction_id(&conn, merchant_id, txn_id) + .await + .map_err(Into::into) + .into_report() } } } @@ -305,7 +326,11 @@ mod storage { match storage_scheme { enums::MerchantStorageScheme::PostgresOnly => { let conn = pg_connection(&self.master_pool).await; - payment_attempt.insert_diesel(&conn).await + payment_attempt + .insert_diesel(&conn) + .await + .map_err(Into::into) + .into_report() } enums::MerchantStorageScheme::RedisKv => { @@ -394,7 +419,10 @@ mod storage { match storage_scheme { enums::MerchantStorageScheme::PostgresOnly => { let conn = pg_connection(&self.master_pool).await; - this.update(&conn, payment_attempt).await + this.update(&conn, payment_attempt) + .await + .map_err(Into::into) + .into_report() } enums::MerchantStorageScheme::RedisKv => { @@ -445,6 +473,8 @@ mod storage { let conn = pg_connection(&self.master_pool).await; PaymentAttempt::find_by_payment_id_merchant_id(&conn, payment_id, merchant_id) .await + .map_err(Into::into) + .into_report() } enums::MerchantStorageScheme::RedisKv => { @@ -534,6 +564,8 @@ mod storage { connector_txn_id, ) .await + .map_err(Into::into) + .into_report() } enums::MerchantStorageScheme::RedisKv => { @@ -553,6 +585,8 @@ mod storage { let conn = pg_connection(&self.master_pool).await; PaymentAttempt::find_by_merchant_id_transaction_id(&conn, merchant_id, txn_id) .await + .map_err(Into::into) + .into_report() } enums::MerchantStorageScheme::RedisKv => { diff --git a/crates/router/src/db/payment_intent.rs b/crates/router/src/db/payment_intent.rs index 3337dc40ab..fe2623b9d8 100644 --- a/crates/router/src/db/payment_intent.rs +++ b/crates/router/src/db/payment_intent.rs @@ -65,7 +65,10 @@ mod storage { match storage_scheme { enums::MerchantStorageScheme::PostgresOnly => { let conn = pg_connection(&self.master_pool).await; - new.insert_diesel(&conn).await + new.insert_diesel(&conn) + .await + .map_err(Into::into) + .into_report() } enums::MerchantStorageScheme::RedisKv => { @@ -142,7 +145,10 @@ mod storage { match storage_scheme { enums::MerchantStorageScheme::PostgresOnly => { let conn = pg_connection(&self.master_pool).await; - this.update(&conn, payment_intent).await + this.update(&conn, payment_intent) + .await + .map_err(Into::into) + .into_report() } enums::MerchantStorageScheme::RedisKv => { @@ -193,6 +199,8 @@ mod storage { let conn = pg_connection(&self.master_pool).await; PaymentIntent::find_by_payment_id_merchant_id(&conn, payment_id, merchant_id) .await + .map_err(Into::into) + .into_report() } enums::MerchantStorageScheme::RedisKv => { @@ -225,7 +233,10 @@ mod storage { match storage_scheme { enums::MerchantStorageScheme::PostgresOnly => { let conn = pg_connection(&self.master_pool).await; - PaymentIntent::filter_by_constraints(&conn, merchant_id, pc).await + PaymentIntent::filter_by_constraints(&conn, merchant_id, pc) + .await + .map_err(Into::into) + .into_report() } enums::MerchantStorageScheme::RedisKv => { @@ -239,6 +250,8 @@ mod storage { #[cfg(not(feature = "kv_store"))] mod storage { + use error_stack::IntoReport; + use super::PaymentIntentInterface; use crate::{ connection::pg_connection, @@ -258,7 +271,10 @@ mod storage { _storage_scheme: enums::MerchantStorageScheme, ) -> CustomResult { let conn = pg_connection(&self.master_pool).await; - new.insert_diesel(&conn).await + new.insert_diesel(&conn) + .await + .map_err(Into::into) + .into_report() } async fn update_payment_intent( @@ -268,7 +284,10 @@ mod storage { _storage_scheme: enums::MerchantStorageScheme, ) -> CustomResult { let conn = pg_connection(&self.master_pool).await; - this.update(&conn, payment_intent).await + this.update(&conn, payment_intent) + .await + .map_err(Into::into) + .into_report() } async fn find_payment_intent_by_payment_id_merchant_id( @@ -278,7 +297,10 @@ mod storage { _storage_scheme: enums::MerchantStorageScheme, ) -> CustomResult { let conn = pg_connection(&self.master_pool).await; - PaymentIntent::find_by_payment_id_merchant_id(&conn, payment_id, merchant_id).await + PaymentIntent::find_by_payment_id_merchant_id(&conn, payment_id, merchant_id) + .await + .map_err(Into::into) + .into_report() } async fn filter_payment_intent_by_constraints( @@ -288,7 +310,10 @@ mod storage { _storage_scheme: enums::MerchantStorageScheme, ) -> CustomResult, errors::StorageError> { let conn = pg_connection(&self.master_pool).await; - PaymentIntent::filter_by_constraints(&conn, merchant_id, pc).await + PaymentIntent::filter_by_constraints(&conn, merchant_id, pc) + .await + .map_err(Into::into) + .into_report() } } } diff --git a/crates/router/src/db/payment_method.rs b/crates/router/src/db/payment_method.rs index 4df25ff707..4752c88f4e 100644 --- a/crates/router/src/db/payment_method.rs +++ b/crates/router/src/db/payment_method.rs @@ -1,3 +1,5 @@ +use error_stack::IntoReport; + use super::MockDb; use crate::{ connection::pg_connection, @@ -37,7 +39,10 @@ impl PaymentMethodInterface for super::Store { payment_method_id: &str, ) -> CustomResult { let conn = pg_connection(&self.master_pool).await; - PaymentMethod::find_by_payment_method_id(&conn, payment_method_id).await + PaymentMethod::find_by_payment_method_id(&conn, payment_method_id) + .await + .map_err(Into::into) + .into_report() } async fn insert_payment_method( @@ -45,7 +50,7 @@ impl PaymentMethodInterface for super::Store { m: PaymentMethodNew, ) -> CustomResult { let conn = pg_connection(&self.master_pool).await; - m.insert(&conn).await + m.insert(&conn).await.map_err(Into::into).into_report() } async fn find_payment_method_by_customer_id_merchant_id_list( @@ -54,7 +59,10 @@ impl PaymentMethodInterface for super::Store { merchant_id: &str, ) -> CustomResult, errors::StorageError> { let conn = pg_connection(&self.master_pool).await; - PaymentMethod::find_by_customer_id_merchant_id(&conn, customer_id, merchant_id).await + PaymentMethod::find_by_customer_id_merchant_id(&conn, customer_id, merchant_id) + .await + .map_err(Into::into) + .into_report() } async fn delete_payment_method_by_merchant_id_payment_method_id( @@ -69,6 +77,8 @@ impl PaymentMethodInterface for super::Store { payment_method_id, ) .await + .map_err(Into::into) + .into_report() } } diff --git a/crates/router/src/db/process_tracker.rs b/crates/router/src/db/process_tracker.rs index cb4cda9064..ae52177db0 100644 --- a/crates/router/src/db/process_tracker.rs +++ b/crates/router/src/db/process_tracker.rs @@ -1,3 +1,4 @@ +use error_stack::IntoReport; use time::PrimitiveDateTime; use super::MockDb; @@ -58,7 +59,10 @@ impl ProcessTrackerInterface for super::Store { id: &str, ) -> CustomResult, errors::StorageError> { let conn = pg_connection(&self.master_pool).await; - ProcessTracker::find_process_by_id(&conn, id).await + ProcessTracker::find_process_by_id(&conn, id) + .await + .map_err(Into::into) + .into_report() } async fn reinitialize_limbo_processes( @@ -67,7 +71,10 @@ impl ProcessTrackerInterface for super::Store { schedule_time: PrimitiveDateTime, ) -> CustomResult { let conn = pg_connection(&self.master_pool).await; - ProcessTracker::reinitialize_limbo_processes(&conn, ids, schedule_time).await + ProcessTracker::reinitialize_limbo_processes(&conn, ids, schedule_time) + .await + .map_err(Into::into) + .into_report() } async fn find_processes_by_time_status( @@ -86,6 +93,8 @@ impl ProcessTrackerInterface for super::Store { limit, ) .await + .map_err(Into::into) + .into_report() } async fn insert_process( @@ -93,7 +102,10 @@ impl ProcessTrackerInterface for super::Store { new: ProcessTrackerNew, ) -> CustomResult { let conn = pg_connection(&self.master_pool).await; - new.insert_process(&conn).await + new.insert_process(&conn) + .await + .map_err(Into::into) + .into_report() } async fn update_process( @@ -102,7 +114,10 @@ impl ProcessTrackerInterface for super::Store { process: ProcessTrackerUpdate, ) -> CustomResult { let conn = pg_connection(&self.master_pool).await; - this.update(&conn, process).await + this.update(&conn, process) + .await + .map_err(Into::into) + .into_report() } async fn update_process_tracker( @@ -111,7 +126,10 @@ impl ProcessTrackerInterface for super::Store { process: ProcessTrackerUpdate, ) -> CustomResult { let conn = pg_connection(&self.master_pool).await; - this.update(&conn, process).await + this.update(&conn, process) + .await + .map_err(Into::into) + .into_report() } async fn process_tracker_update_process_status_by_ids( @@ -120,7 +138,10 @@ impl ProcessTrackerInterface for super::Store { task_update: ProcessTrackerUpdate, ) -> CustomResult, errors::StorageError> { let conn = pg_connection(&self.master_pool).await; - ProcessTracker::update_process_status_by_ids(&conn, task_ids, task_update).await + ProcessTracker::update_process_status_by_ids(&conn, task_ids, task_update) + .await + .map_err(Into::into) + .into_report() } } diff --git a/crates/router/src/db/refund.rs b/crates/router/src/db/refund.rs index d1659caf33..2c34d0744b 100644 --- a/crates/router/src/db/refund.rs +++ b/crates/router/src/db/refund.rs @@ -1,9 +1,10 @@ -use error_stack::Report; +use error_stack::{IntoReport, Report}; +use storage_models::errors::DatabaseError; use super::MockDb; use crate::{ connection::pg_connection, - core::errors::{self, CustomResult, DatabaseError, StorageError}, + core::errors::{self, CustomResult, StorageError}, types::storage::{enums, Refund, RefundNew, RefundUpdate}, }; @@ -69,6 +70,8 @@ impl RefundInterface for super::Store { let conn = pg_connection(&self.master_pool).await; Refund::find_by_internal_reference_id_merchant_id(&conn, internal_reference_id, merchant_id) .await + .map_err(Into::into) + .into_report() } async fn insert_refund( @@ -77,7 +80,7 @@ impl RefundInterface for super::Store { _storage_scheme: enums::MerchantStorageScheme, ) -> CustomResult { let conn = pg_connection(&self.master_pool).await; - new.insert(&conn).await + new.insert(&conn).await.map_err(Into::into).into_report() } async fn find_refund_by_merchant_id_transaction_id( &self, @@ -86,7 +89,10 @@ impl RefundInterface for super::Store { _storage_scheme: enums::MerchantStorageScheme, ) -> CustomResult, errors::StorageError> { let conn = pg_connection(&self.master_pool).await; - Refund::find_by_merchant_id_transaction_id(&conn, merchant_id, txn_id).await + Refund::find_by_merchant_id_transaction_id(&conn, merchant_id, txn_id) + .await + .map_err(Into::into) + .into_report() } async fn update_refund( @@ -96,7 +102,10 @@ impl RefundInterface for super::Store { _storage_scheme: enums::MerchantStorageScheme, ) -> CustomResult { let conn = pg_connection(&self.master_pool).await; - this.update(&conn, refund).await + this.update(&conn, refund) + .await + .map_err(Into::into) + .into_report() } async fn find_refund_by_merchant_id_refund_id( @@ -106,7 +115,10 @@ impl RefundInterface for super::Store { _storage_scheme: enums::MerchantStorageScheme, ) -> CustomResult { let conn = pg_connection(&self.master_pool).await; - Refund::find_by_merchant_id_refund_id(&conn, merchant_id, refund_id).await + Refund::find_by_merchant_id_refund_id(&conn, merchant_id, refund_id) + .await + .map_err(Into::into) + .into_report() } // async fn find_refund_by_payment_id_merchant_id_refund_id( @@ -127,7 +139,10 @@ impl RefundInterface for super::Store { _storage_scheme: enums::MerchantStorageScheme, ) -> CustomResult, errors::StorageError> { let conn = pg_connection(&self.master_pool).await; - Refund::find_by_payment_id_merchant_id(&conn, payment_id, merchant_id).await + Refund::find_by_payment_id_merchant_id(&conn, payment_id, merchant_id) + .await + .map_err(Into::into) + .into_report() } } @@ -214,7 +229,11 @@ impl RefundInterface for MockDb { .iter() .find(|refund| refund.merchant_id == merchant_id && refund.refund_id == refund_id) .cloned() - .ok_or_else(|| Report::from(StorageError::DatabaseError(DatabaseError::NotFound))) + .ok_or_else(|| { + Report::from(StorageError::DatabaseError(Report::from( + DatabaseError::NotFound, + ))) + }) } async fn find_refund_by_payment_id_merchant_id( diff --git a/crates/router/src/db/temp_card.rs b/crates/router/src/db/temp_card.rs index e5e6849a02..b39eadd74b 100644 --- a/crates/router/src/db/temp_card.rs +++ b/crates/router/src/db/temp_card.rs @@ -1,3 +1,5 @@ +use error_stack::IntoReport; + use super::MockDb; use crate::{ connection::pg_connection, @@ -35,7 +37,11 @@ impl TempCardInterface for super::Store { address: TempCardNew, ) -> CustomResult { let conn = pg_connection(&self.master_pool).await; - address.insert_diesel(&conn).await + address + .insert_diesel(&conn) + .await + .map_err(Into::into) + .into_report() } async fn find_tempcard_by_transaction_id( @@ -43,7 +49,10 @@ impl TempCardInterface for super::Store { transaction_id: &str, ) -> CustomResult, errors::StorageError> { let conn = pg_connection(&self.master_pool).await; - TempCard::find_by_transaction_id(&conn, transaction_id).await + TempCard::find_by_transaction_id(&conn, transaction_id) + .await + .map_err(Into::into) + .into_report() } async fn insert_tempcard_with_token( @@ -51,7 +60,10 @@ impl TempCardInterface for super::Store { card: TempCard, ) -> CustomResult { let conn = pg_connection(&self.master_pool).await; - TempCard::insert_with_token(card, &conn).await + TempCard::insert_with_token(card, &conn) + .await + .map_err(Into::into) + .into_report() } async fn find_tempcard_by_token( @@ -59,7 +71,10 @@ impl TempCardInterface for super::Store { token: &i32, ) -> CustomResult { let conn = pg_connection(&self.master_pool).await; - TempCard::find_by_token(&conn, token).await + TempCard::find_by_token(&conn, token) + .await + .map_err(Into::into) + .into_report() } } diff --git a/crates/router/src/lib.rs b/crates/router/src/lib.rs index 06afd4d62e..de83d4e94f 100644 --- a/crates/router/src/lib.rs +++ b/crates/router/src/lib.rs @@ -31,8 +31,6 @@ pub(crate) mod macros; pub mod routes; pub mod scheduler; -#[allow(unused_imports)] // Allow unused imports only for schema module -pub mod schema; pub mod services; pub mod types; pub mod utils; @@ -64,7 +62,7 @@ pub mod headers { pub mod pii { //! Personal Identifiable Information protection. - pub(crate) use common_utils::pii::{CardNumber, Email, IpAddress}; + pub(crate) use common_utils::pii::{CardNumber, Email}; #[doc(inline)] pub use masking::*; } diff --git a/crates/router/src/scheduler/consumer.rs b/crates/router/src/scheduler/consumer.rs index 9db54dae04..92cf572356 100644 --- a/crates/router/src/scheduler/consumer.rs +++ b/crates/router/src/scheduler/consumer.rs @@ -23,7 +23,7 @@ use crate::{ logger::{error, info}, routes::AppState, scheduler::utils as pt_utils, - types::storage::{self, enums}, + types::storage::{self, enums, ProcessTrackerExt}, }; // Valid consumer business statuses diff --git a/crates/router/src/scheduler/workflows/payment_sync.rs b/crates/router/src/scheduler/workflows/payment_sync.rs index 6566e40bb0..df8597797e 100644 --- a/crates/router/src/scheduler/workflows/payment_sync.rs +++ b/crates/router/src/scheduler/workflows/payment_sync.rs @@ -9,7 +9,7 @@ use crate::{ scheduler::{consumer, process_data, utils}, types::{ api, - storage::{self, enums}, + storage::{self, enums, ProcessTrackerExt}, }, utils::{OptionExt, ValueExt}, }; diff --git a/crates/router/src/types/api/mandates.rs b/crates/router/src/types/api/mandates.rs index d2b44126e2..f38b96e06f 100644 --- a/crates/router/src/types/api/mandates.rs +++ b/crates/router/src/types/api/mandates.rs @@ -13,6 +13,7 @@ use crate::{ types::{ api, storage::{self, enums as storage_enums}, + transformers::ForeignInto, }, }; @@ -67,7 +68,7 @@ impl MandateResponseExt for MandateResponse { }), }), card, - status: mandate.mandate_status.into(), + status: mandate.mandate_status.foreign_into(), payment_method: payment_method.payment_method.to_string(), payment_method_id: mandate.payment_method_id, }) diff --git a/crates/router/src/types/api/payments.rs b/crates/router/src/types/api/payments.rs index 4ddc554aca..695c8bb44c 100644 --- a/crates/router/src/types/api/payments.rs +++ b/crates/router/src/types/api/payments.rs @@ -17,7 +17,10 @@ use time::PrimitiveDateTime; use crate::{ core::errors, services::api, - types::{self, api as api_types}, + types::{ + self, api as api_types, storage, + transformers::{Foreign, ForeignInto}, + }, }; pub(crate) trait PaymentsRequestExt { @@ -109,12 +112,13 @@ impl MandateValidationFieldsExt for MandateValidationFields { } } -impl From for PaymentsResponse { - fn from(item: types::storage::PaymentIntent) -> Self { +impl From> for Foreign { + fn from(item: Foreign) -> Self { + let item = item.0; payments::PaymentsResponse { payment_id: Some(item.payment_id), merchant_id: Some(item.merchant_id), - status: item.status.into(), + status: item.status.foreign_into(), amount: item.amount, amount_capturable: item.amount_captured, client_secret: item.client_secret.map(|s| s.into()), @@ -123,8 +127,9 @@ impl From for PaymentsResponse { description: item.description, metadata: item.metadata, customer_id: item.customer_id, - ..Self::default() + ..Default::default() } + .into() } } diff --git a/crates/router/src/types/api/refunds.rs b/crates/router/src/types/api/refunds.rs index 11104cc96d..f1b6dad2ce 100644 --- a/crates/router/src/types/api/refunds.rs +++ b/crates/router/src/types/api/refunds.rs @@ -3,18 +3,19 @@ pub use api_models::refunds::{RefundRequest, RefundResponse, RefundStatus}; use super::ConnectorCommon; use crate::{ services::api, - types::{self, storage::enums as storage_enums}, + types::{self, storage::enums as storage_enums, transformers::Foreign}, }; -impl From for RefundStatus { - fn from(status: storage_enums::RefundStatus) -> Self { - match status { +impl From> for Foreign { + fn from(status: Foreign) -> Self { + match status.0 { storage_enums::RefundStatus::Failure | storage_enums::RefundStatus::TransactionFailure => RefundStatus::Failed, storage_enums::RefundStatus::ManualReview => RefundStatus::Review, storage_enums::RefundStatus::Pending => RefundStatus::Pending, storage_enums::RefundStatus::Success => RefundStatus::Succeeded, } + .into() } } diff --git a/crates/router/src/types/storage.rs b/crates/router/src/types/storage.rs index af125e0390..8f6a4fe4d9 100644 --- a/crates/router/src/types/storage.rs +++ b/crates/router/src/types/storage.rs @@ -18,71 +18,8 @@ mod query; pub mod refund; pub mod temp_card; -use diesel_impl::{DieselArray, OptionalDieselArray}; - pub use self::{ address::*, configs::*, connector_response::*, customers::*, events::*, locker_mock_up::*, mandate::*, merchant_account::*, merchant_connector_account::*, payment_attempt::*, payment_intent::*, payment_method::*, process_tracker::*, refund::*, temp_card::*, }; - -/// The types and implementations provided by this module are required for the schema generated by -/// `diesel_cli` 2.0 to work with the types defined in Rust code. This is because -/// [`diesel`][diesel] 2.0 [changed the nullability of array elements][diesel-2.0-array-nullability], -/// which causes [`diesel`][diesel] to deserialize arrays as `Vec>`. To prevent declaring -/// array elements as `Option`, this module provides types and implementations to deserialize -/// arrays as `Vec`, considering only non-null values (`Some(T)`) among the deserialized -/// `Option` values. -/// -/// [diesel-2.0-array-nullability]: https://diesel.rs/guides/migration_guide.html#2-0-0-nullability-of-array-elements - -#[doc(hidden)] -pub(crate) mod diesel_impl { - use diesel::{ - deserialize::FromSql, - pg::Pg, - sql_types::{Array, Nullable}, - Queryable, - }; - - pub struct DieselArray(Vec>); - - impl From> for Vec { - fn from(array: DieselArray) -> Self { - array.0.into_iter().flatten().collect() - } - } - - impl Queryable>, Pg> for DieselArray - where - T: FromSql, - Vec>: FromSql>, Pg>, - { - type Row = Vec>; - - fn build(row: Self::Row) -> diesel::deserialize::Result { - Ok(DieselArray(row)) - } - } - - pub struct OptionalDieselArray(Option>>); - - impl From> for Option> { - fn from(option_array: OptionalDieselArray) -> Self { - option_array - .0 - .map(|array| array.into_iter().flatten().collect()) - } - } - - impl Queryable>>, Pg> for OptionalDieselArray - where - Option>>: FromSql>>, Pg>, - { - type Row = Option>>; - - fn build(row: Self::Row) -> diesel::deserialize::Result { - Ok(OptionalDieselArray(row)) - } - } -} diff --git a/crates/router/src/types/storage/address.rs b/crates/router/src/types/storage/address.rs index 2eb24884c9..8dd7323715 100644 --- a/crates/router/src/types/storage/address.rs +++ b/crates/router/src/types/storage/address.rs @@ -1,188 +1 @@ -use common_utils::custom_serde; -use diesel::{AsChangeset, Identifiable, Insertable, Queryable}; -use masking::Secret; -use serde::{Deserialize, Serialize}; -use time::{OffsetDateTime, PrimitiveDateTime}; - -use crate::{consts, schema::address, types::api, utils::generate_id}; - -#[derive(Clone, Debug, Deserialize, Serialize, Insertable, router_derive::DebugAsDisplay)] -#[diesel(table_name = address)] -#[serde(deny_unknown_fields)] -pub struct AddressNew { - pub address_id: String, - pub city: Option, - pub country: Option, - pub line1: Option>, - pub line2: Option>, - pub line3: Option>, - pub state: Option>, - pub zip: Option>, - pub first_name: Option>, - pub last_name: Option>, - pub phone_number: Option>, - pub country_code: Option, - pub customer_id: String, - pub merchant_id: String, -} - -#[derive(Clone, Debug, Deserialize, Serialize, Identifiable, Queryable)] -#[diesel(table_name = address)] -pub struct Address { - #[serde(skip_serializing)] - pub id: i32, - #[serde(skip_serializing)] - pub address_id: String, - pub city: Option, - pub country: Option, - pub line1: Option>, - pub line2: Option>, - pub line3: Option>, - pub state: Option>, - pub zip: Option>, - pub first_name: Option>, - pub last_name: Option>, - pub phone_number: Option>, - pub country_code: Option, - #[serde(skip_serializing)] - #[serde(with = "custom_serde::iso8601")] - pub created_at: PrimitiveDateTime, - #[serde(skip_serializing)] - #[serde(with = "custom_serde::iso8601")] - pub modified_at: PrimitiveDateTime, - pub customer_id: String, - pub merchant_id: String, -} - -#[derive(Debug)] -pub enum AddressUpdate { - Update { - city: Option, - country: Option, - line1: Option>, - line2: Option>, - line3: Option>, - state: Option>, - zip: Option>, - first_name: Option>, - last_name: Option>, - phone_number: Option>, - country_code: Option, - }, -} - -#[derive(Clone, Debug, AsChangeset, router_derive::DebugAsDisplay)] -#[diesel(table_name = address)] -pub(super) struct AddressUpdateInternal { - city: Option, - country: Option, - line1: Option>, - line2: Option>, - line3: Option>, - state: Option>, - zip: Option>, - first_name: Option>, - last_name: Option>, - phone_number: Option>, - country_code: Option, - modified_at: PrimitiveDateTime, -} - -impl From for AddressUpdateInternal { - fn from(address_update: AddressUpdate) -> Self { - match address_update { - AddressUpdate::Update { - city, - country, - line1, - line2, - line3, - state, - zip, - first_name, - last_name, - phone_number, - country_code, - } => Self { - city, - country, - line1, - line2, - line3, - state, - zip, - first_name, - last_name, - phone_number, - country_code, - modified_at: convert_to_pdt(OffsetDateTime::now_utc()), - }, - } - } -} - -// TODO: Create utils for this since cane be reused outside address -fn convert_to_pdt(offset_time: OffsetDateTime) -> PrimitiveDateTime { - PrimitiveDateTime::new(offset_time.date(), offset_time.time()) -} - -impl<'a> From<&'a api::Address> for AddressUpdate { - fn from(address: &api::Address) -> Self { - AddressUpdate::Update { - city: address.address.as_ref().and_then(|a| a.city.clone()), - country: address.address.as_ref().and_then(|a| a.country.clone()), - line1: address.address.as_ref().and_then(|a| a.line1.clone()), - line2: address.address.as_ref().and_then(|a| a.line2.clone()), - line3: address.address.as_ref().and_then(|a| a.line3.clone()), - state: address.address.as_ref().and_then(|a| a.state.clone()), - zip: address.address.as_ref().and_then(|a| a.zip.clone()), - first_name: address.address.as_ref().and_then(|a| a.first_name.clone()), - last_name: address.address.as_ref().and_then(|a| a.last_name.clone()), - phone_number: address.phone.as_ref().and_then(|a| a.number.clone()), - country_code: address.phone.as_ref().and_then(|a| a.country_code.clone()), - } - } -} - -impl<'a> From<&'a Address> for api::Address { - fn from(address: &Address) -> Self { - api::Address { - address: Some(api::AddressDetails { - city: address.city.clone(), - country: address.country.clone(), - line1: address.line1.clone(), - line2: address.line2.clone(), - line3: address.line3.clone(), - state: address.state.clone(), - zip: address.zip.clone(), - first_name: address.first_name.clone(), - last_name: address.last_name.clone(), - }), - phone: Some(api::PhoneDetails { - number: address.phone_number.clone(), - country_code: address.country_code.clone(), - }), - } - } -} - -impl Default for AddressNew { - fn default() -> Self { - Self { - address_id: generate_id(consts::ID_LENGTH, "add"), - city: None, - country: None, - line1: None, - line2: None, - line3: None, - state: None, - zip: None, - first_name: None, - last_name: None, - phone_number: None, - country_code: None, - customer_id: String::default(), - merchant_id: String::default(), - } - } -} +pub use storage_models::address::{Address, AddressNew, AddressUpdate, AddressUpdateInternal}; diff --git a/crates/router/src/types/storage/configs.rs b/crates/router/src/types/storage/configs.rs index b6c637f441..0adee5fef1 100644 --- a/crates/router/src/types/storage/configs.rs +++ b/crates/router/src/types/storage/configs.rs @@ -1,43 +1 @@ -use std::convert::From; - -use diesel::{AsChangeset, Identifiable, Insertable, Queryable}; -use serde::{Deserialize, Serialize}; - -use crate::schema::configs; - -#[derive(Default, Clone, Debug, Insertable, Serialize, Deserialize)] -#[diesel(table_name = configs)] - -pub struct ConfigNew { - pub key: String, - pub config: String, -} - -#[derive(Default, Clone, Debug, Identifiable, Queryable, Deserialize, Serialize)] -#[diesel(table_name = configs)] - -pub struct Config { - #[serde(skip_serializing)] - pub id: i32, - pub key: String, - pub config: String, -} - -#[derive(Debug)] -pub enum ConfigUpdate { - Update { config: Option }, -} - -#[derive(Clone, Debug, AsChangeset, Default)] -#[diesel(table_name = configs)] -pub(super) struct ConfigUpdateInternal { - config: Option, -} - -impl From for ConfigUpdateInternal { - fn from(config_update: ConfigUpdate) -> Self { - match config_update { - ConfigUpdate::Update { config } => Self { config }, - } - } -} +pub use storage_models::configs::{Config, ConfigNew, ConfigUpdate, ConfigUpdateInternal}; diff --git a/crates/router/src/types/storage/connector_response.rs b/crates/router/src/types/storage/connector_response.rs index c9978be8ae..eb4e2474c9 100644 --- a/crates/router/src/types/storage/connector_response.rs +++ b/crates/router/src/types/storage/connector_response.rs @@ -1,89 +1,4 @@ -use diesel::{AsChangeset, Identifiable, Insertable, Queryable}; -use serde::{Deserialize, Serialize}; -use time::PrimitiveDateTime; - -use crate::schema::connector_response; - -#[derive(Clone, Debug, Deserialize, Serialize, Insertable, router_derive::DebugAsDisplay)] -#[diesel(table_name = connector_response)] -#[serde(deny_unknown_fields)] -pub struct ConnectorResponseNew { - pub payment_id: String, - pub merchant_id: String, - pub txn_id: String, - pub created_at: PrimitiveDateTime, - pub modified_at: PrimitiveDateTime, - pub connector_name: Option, - pub connector_transaction_id: Option, - pub authentication_data: Option, - pub encoded_data: Option, -} - -#[derive(Clone, Debug, Deserialize, Serialize, Identifiable, Queryable)] -#[diesel(table_name = connector_response)] - -pub struct ConnectorResponse { - #[serde(skip_serializing)] - pub id: i32, - pub payment_id: String, - pub merchant_id: String, - pub txn_id: String, - pub created_at: PrimitiveDateTime, - pub modified_at: PrimitiveDateTime, - pub connector_name: Option, - pub connector_transaction_id: Option, - pub authentication_data: Option, - pub encoded_data: Option, -} - -#[derive(Clone, Debug, Deserialize, AsChangeset, Serialize)] -#[diesel(table_name = connector_response)] -pub struct ConnectorResponseUpdateInternal { - pub connector_transaction_id: Option, - pub authentication_data: Option, - pub modified_at: PrimitiveDateTime, - pub encoded_data: Option, - pub connector_name: Option, -} - -#[derive(Debug)] -pub enum ConnectorResponseUpdate { - ResponseUpdate { - connector_transaction_id: Option, - authentication_data: Option, - encoded_data: Option, - connector_name: Option, - }, -} - -impl ConnectorResponseUpdate { - pub fn apply_changeset(self, source: ConnectorResponse) -> ConnectorResponse { - let connector_response_update: ConnectorResponseUpdateInternal = self.into(); - ConnectorResponse { - modified_at: connector_response_update.modified_at, - connector_transaction_id: connector_response_update.connector_transaction_id, - authentication_data: connector_response_update.authentication_data, - encoded_data: connector_response_update.encoded_data, - ..source - } - } -} - -impl From for ConnectorResponseUpdateInternal { - fn from(connector_response_update: ConnectorResponseUpdate) -> Self { - match connector_response_update { - ConnectorResponseUpdate::ResponseUpdate { - connector_transaction_id, - authentication_data, - encoded_data, - connector_name, - } => Self { - connector_transaction_id, - authentication_data, - encoded_data, - modified_at: common_utils::date_time::now(), - connector_name, - }, - } - } -} +pub use storage_models::connector_response::{ + ConnectorResponse, ConnectorResponseNew, ConnectorResponseUpdate, + ConnectorResponseUpdateInternal, +}; diff --git a/crates/router/src/types/storage/customers.rs b/crates/router/src/types/storage/customers.rs index 58f48a9ed5..abb0569539 100644 --- a/crates/router/src/types/storage/customers.rs +++ b/crates/router/src/types/storage/customers.rs @@ -1,80 +1,3 @@ -use diesel::{AsChangeset, Identifiable, Insertable, Queryable}; -use time::PrimitiveDateTime; - -use crate::{ - pii::{self, Secret}, - schema::customers, +pub use storage_models::customers::{ + Customer, CustomerNew, CustomerUpdate, CustomerUpdateInternal, }; - -#[derive(Default, Clone, Debug, Insertable, router_derive::DebugAsDisplay)] -#[diesel(table_name = customers)] -pub struct CustomerNew { - pub customer_id: String, - pub merchant_id: String, - pub name: Option, - pub email: Option>, - pub phone: Option>, - pub description: Option, - pub phone_country_code: Option, - pub metadata: Option, -} - -#[derive(Clone, Debug, Identifiable, Queryable)] -#[diesel(table_name = customers)] -pub struct Customer { - pub id: i32, - pub customer_id: String, - pub merchant_id: String, - pub name: Option, - pub email: Option>, - pub phone: Option>, - pub phone_country_code: Option, - pub description: Option, - pub created_at: PrimitiveDateTime, - pub metadata: Option, -} - -#[derive(Debug)] -pub enum CustomerUpdate { - Update { - name: Option, - email: Option>, - phone: Option>, - description: Option, - phone_country_code: Option, - metadata: Option, - }, -} - -#[derive(Clone, Debug, Default, AsChangeset, router_derive::DebugAsDisplay)] -#[diesel(table_name = customers)] -pub(super) struct CustomerUpdateInternal { - name: Option, - email: Option>, - phone: Option>, - description: Option, - phone_country_code: Option, - metadata: Option, -} - -impl From for CustomerUpdateInternal { - fn from(customer_update: CustomerUpdate) -> Self { - match customer_update { - CustomerUpdate::Update { - name, - email, - phone, - description, - phone_country_code, - metadata, - } => Self { - name, - email, - phone, - description, - phone_country_code, - metadata, - }, - } - } -} diff --git a/crates/router/src/types/storage/enums.rs b/crates/router/src/types/storage/enums.rs index a44577fe06..4cf03ac8d4 100644 --- a/crates/router/src/types/storage/enums.rs +++ b/crates/router/src/types/storage/enums.rs @@ -1,657 +1 @@ -#[doc(hidden)] -pub mod diesel_exports { - pub use super::{ - DbAttemptStatus as AttemptStatus, DbAuthenticationType as AuthenticationType, - DbCaptureMethod as CaptureMethod, DbConnectorType as ConnectorType, DbCurrency as Currency, - DbEventClass as EventClass, DbEventObjectType as EventObjectType, DbEventType as EventType, - DbFutureUsage as FutureUsage, DbIntentStatus as IntentStatus, - DbMandateStatus as MandateStatus, DbMandateType as MandateType, - DbMerchantStorageScheme as MerchantStorageScheme, DbPaymentFlow as PaymentFlow, - DbPaymentMethodIssuerCode as PaymentMethodIssuerCode, - DbPaymentMethodSubType as PaymentMethodSubType, DbPaymentMethodType as PaymentMethodType, - DbProcessTrackerStatus as ProcessTrackerStatus, DbRefundStatus as RefundStatus, - DbRefundType as RefundType, DbRoutingAlgorithm as RoutingAlgorithm, - }; -} - -#[derive( - Clone, - Copy, - Debug, - Default, - Eq, - PartialEq, - serde::Deserialize, - serde::Serialize, - strum::Display, - strum::EnumString, - router_derive::DieselEnum, -)] -#[router_derive::diesel_enum] -#[serde(rename_all = "snake_case")] -#[strum(serialize_all = "snake_case")] -pub enum AttemptStatus { - Started, - AuthenticationFailed, - JuspayDeclined, - PendingVbv, - VbvSuccessful, - Authorized, - AuthorizationFailed, - Charged, - Authorizing, - CodInitiated, - Voided, - VoidInitiated, - CaptureInitiated, - CaptureFailed, - VoidFailed, - AutoRefunded, - PartialCharged, - #[default] - Pending, - Failure, - PaymentMethodAwaited, - ConfirmationAwaited, -} - -#[derive( - Clone, - Copy, - Debug, - Default, - Eq, - PartialEq, - serde::Deserialize, - serde::Serialize, - strum::Display, - strum::EnumString, - router_derive::DieselEnum, -)] -#[router_derive::diesel_enum] -#[serde(rename_all = "snake_case")] -#[strum(serialize_all = "snake_case")] -pub enum AuthenticationType { - #[default] - ThreeDs, - NoThreeDs, -} - -#[derive( - Clone, - Copy, - Debug, - Default, - Eq, - PartialEq, - serde::Deserialize, - serde::Serialize, - strum::Display, - strum::EnumString, - router_derive::DieselEnum, -)] -#[router_derive::diesel_enum] -#[serde(rename_all = "snake_case")] -#[strum(serialize_all = "snake_case")] -pub enum CaptureMethod { - #[default] - Automatic, - Manual, - ManualMultiple, - Scheduled, -} - -#[derive( - Clone, - Copy, - Debug, - Eq, - PartialEq, - strum::Display, - strum::EnumString, - serde::Deserialize, - serde::Serialize, - router_derive::DieselEnum, -)] -#[router_derive::diesel_enum] -#[strum(serialize_all = "snake_case")] -#[serde(rename_all = "snake_case")] -pub enum ConnectorType { - /// PayFacs, Acquirers, Gateways, BNPL etc - PaymentProcessor, - /// Fraud, Currency Conversion, Crypto etc - PaymentVas, - /// Accounting, Billing, Invoicing, Tax etc - FinOperations, - /// Inventory, ERP, CRM, KYC etc - FizOperations, - /// Payment Networks like Visa, MasterCard etc - Networks, - /// All types of banks including corporate / commercial / personal / neo banks - BankingEntities, - /// All types of non-banking financial institutions including Insurance, Credit / Lending etc - NonBankingFinance, -} - -#[allow(clippy::upper_case_acronyms)] -#[derive( - Clone, - Copy, - Debug, - Default, - Eq, - Hash, - PartialEq, - serde::Deserialize, - serde::Serialize, - strum::Display, - strum::EnumString, - router_derive::DieselEnum, -)] -#[router_derive::diesel_enum] -pub enum Currency { - AED, - ALL, - AMD, - ARS, - AUD, - AWG, - AZN, - BBD, - BDT, - BHD, - BMD, - BND, - BOB, - BRL, - BSD, - BWP, - BZD, - CAD, - CHF, - CNY, - COP, - CRC, - CUP, - CZK, - DKK, - DOP, - DZD, - EGP, - ETB, - EUR, - FJD, - GBP, - GHS, - GIP, - GMD, - GTQ, - GYD, - HKD, - HNL, - HRK, - HTG, - HUF, - IDR, - ILS, - INR, - JMD, - JOD, - JPY, - KES, - KGS, - KHR, - KRW, - KWD, - KYD, - KZT, - LAK, - LBP, - LKR, - LRD, - LSL, - MAD, - MDL, - MKD, - MMK, - MNT, - MOP, - MUR, - MVR, - MWK, - MXN, - MYR, - NAD, - NGN, - NIO, - NOK, - NPR, - NZD, - OMR, - PEN, - PGK, - PHP, - PKR, - PLN, - QAR, - RUB, - SAR, - SCR, - SEK, - SGD, - SLL, - SOS, - SSP, - SVC, - SZL, - THB, - TTD, - TWD, - TZS, - #[default] - USD, - UYU, - UZS, - YER, - ZAR, -} - -#[derive( - Clone, - Copy, - Debug, - Eq, - PartialEq, - serde::Deserialize, - serde::Serialize, - strum::Display, - strum::EnumString, - router_derive::DieselEnum, -)] -#[router_derive::diesel_enum] -#[serde(rename_all = "snake_case")] -#[strum(serialize_all = "snake_case")] -pub enum EventClass { - Payments, -} - -#[derive( - Clone, - Copy, - Debug, - Eq, - PartialEq, - serde::Deserialize, - serde::Serialize, - strum::Display, - strum::EnumString, - router_derive::DieselEnum, -)] -#[router_derive::diesel_enum] -#[serde(rename_all = "snake_case")] -#[strum(serialize_all = "snake_case")] -pub enum EventObjectType { - PaymentDetails, -} - -#[derive( - Clone, - Copy, - Debug, - Eq, - PartialEq, - serde::Deserialize, - serde::Serialize, - strum::Display, - strum::EnumString, - router_derive::DieselEnum, -)] -#[router_derive::diesel_enum] -#[serde(rename_all = "snake_case")] -#[strum(serialize_all = "snake_case")] -pub enum EventType { - PaymentSucceeded, -} - -#[derive( - Clone, - Copy, - Debug, - Default, - Eq, - PartialEq, - serde::Deserialize, - serde::Serialize, - strum::Display, - strum::EnumString, - router_derive::DieselEnum, -)] -#[router_derive::diesel_enum] -#[serde(rename_all = "snake_case")] -#[strum(serialize_all = "snake_case")] -pub enum IntentStatus { - Succeeded, - Failed, - Cancelled, - Processing, - RequiresCustomerAction, - RequiresPaymentMethod, - #[default] - RequiresConfirmation, - RequiresCapture, -} - -#[derive( - Clone, - Copy, - Debug, - Default, - Eq, - PartialEq, - serde::Deserialize, - serde::Serialize, - strum::Display, - strum::EnumString, - router_derive::DieselEnum, -)] -#[router_derive::diesel_enum] -#[serde(rename_all = "snake_case")] -#[strum(serialize_all = "snake_case")] -pub enum FutureUsage { - #[default] - OffSession, - OnSession, -} - -#[derive( - Clone, - Copy, - Debug, - Default, - Eq, - PartialEq, - serde::Deserialize, - serde::Serialize, - strum::Display, - strum::EnumString, - router_derive::DieselEnum, -)] -#[router_derive::diesel_enum] -#[serde(rename_all = "snake_case")] -#[strum(serialize_all = "snake_case")] -pub enum MerchantStorageScheme { - #[default] - PostgresOnly, - RedisKv, -} - -#[derive( - Clone, - Copy, - Debug, - Eq, - PartialEq, - strum::Display, - strum::EnumString, - serde::Serialize, - serde::Deserialize, - router_derive::DieselEnum, -)] -#[router_derive::diesel_enum] -#[strum(serialize_all = "snake_case")] -pub enum PaymentFlow { - Vsc, - Emi, - Otp, - UpiIntent, - UpiCollect, - UpiScanAndPay, - Sdk, -} - -#[derive( - Clone, - Copy, - Debug, - Eq, - Hash, - PartialEq, - serde::Deserialize, - serde::Serialize, - strum::Display, - strum::EnumString, - router_derive::DieselEnum, -)] -#[router_derive::diesel_enum] -#[strum(serialize_all = "snake_case")] -#[serde(rename_all = "snake_case")] -pub enum PaymentMethodIssuerCode { - JpHdfc, - JpIcici, - JpGooglepay, - JpApplepay, - JpPhonepay, - JpWechat, - JpSofort, - JpGiropay, - JpSepa, - JpBacs, -} - -#[derive( - Clone, - Copy, - Debug, - Eq, - Hash, - PartialEq, - serde::Deserialize, - serde::Serialize, - strum::Display, - strum::EnumString, - router_derive::DieselEnum, -)] -#[router_derive::diesel_enum] -#[serde(rename_all = "snake_case")] -#[strum(serialize_all = "snake_case")] -pub enum PaymentMethodSubType { - Credit, - Debit, - UpiIntent, - UpiCollect, - CreditCardInstallments, - PayLaterInstallments, -} - -#[derive( - Clone, - Copy, - Debug, - Default, - Eq, - Hash, - PartialEq, - serde::Deserialize, - serde::Serialize, - strum::Display, - strum::EnumString, - router_derive::DieselEnum, -)] -#[router_derive::diesel_enum] -#[serde(rename_all = "snake_case")] -#[strum(serialize_all = "snake_case")] -pub enum PaymentMethodType { - Card, - PaymentContainer, - #[default] - BankTransfer, - BankDebit, - PayLater, - Netbanking, - Upi, - OpenBanking, - ConsumerFinance, - Wallet, - Klarna, - Paypal, -} - -#[derive( - Clone, - Copy, - Debug, - Eq, - Hash, - PartialEq, - serde::Deserialize, - serde::Serialize, - strum::Display, - strum::EnumString, - router_derive::DieselEnum, -)] -#[router_derive::diesel_enum] -#[serde(rename_all = "lowercase")] -#[strum(serialize_all = "lowercase")] -pub enum WalletIssuer { - GooglePay, - ApplePay, -} - -#[derive( - Clone, - Copy, - Debug, - Eq, - PartialEq, - serde::Deserialize, - serde::Serialize, - strum::Display, - strum::EnumString, - router_derive::DieselEnum, -)] -#[router_derive::diesel_enum] -#[serde(rename_all = "snake_case")] -#[strum(serialize_all = "snake_case")] -pub enum ProcessTrackerStatus { - // Picked by the producer - Processing, - // State when the task is added - New, - // Send to retry - Pending, - // Picked by consumer - ProcessStarted, - // Finished by consumer - Finish, -} - -#[derive( - Clone, - Copy, - Debug, - Default, - Eq, - PartialEq, - strum::Display, - strum::EnumString, - router_derive::DieselEnum, -)] -#[router_derive::diesel_enum] -#[strum(serialize_all = "snake_case")] -pub enum RefundStatus { - Failure, - ManualReview, - #[default] - Pending, - Success, - TransactionFailure, -} - -#[derive( - Clone, - Copy, - Debug, - Default, - Eq, - PartialEq, - strum::Display, - strum::EnumString, - router_derive::DieselEnum, -)] -#[router_derive::diesel_enum] -#[strum(serialize_all = "snake_case")] -pub enum RefundType { - InstantRefund, - #[default] - RegularRefund, - RetryRefund, -} - -#[derive( - Clone, - Copy, - Debug, - Eq, - PartialEq, - serde::Deserialize, - serde::Serialize, - strum::Display, - strum::EnumString, - router_derive::DieselEnum, -)] -#[serde(rename_all = "snake_case")] -#[strum(serialize_all = "snake_case")] -#[router_derive::diesel_enum] -pub enum RoutingAlgorithm { - RoundRobin, - MaxConversion, - MinCost, - Custom, -} - -// Mandate -#[derive( - Clone, - Copy, - Debug, - Eq, - PartialEq, - Default, - serde::Deserialize, - serde::Serialize, - strum::Display, - strum::EnumString, - router_derive::DieselEnum, -)] -#[router_derive::diesel_enum] -#[serde(rename_all = "snake_case")] -#[strum(serialize_all = "snake_case")] -pub enum MandateType { - SingleUse, - #[default] - MultiUse, -} - -#[derive( - Clone, - Copy, - Debug, - Eq, - PartialEq, - Default, - serde::Deserialize, - serde::Serialize, - strum::Display, - strum::EnumString, - router_derive::DieselEnum, -)] -#[router_derive::diesel_enum] -#[serde(rename_all = "snake_case")] -#[strum(serialize_all = "snake_case")] -pub enum MandateStatus { - #[default] - Active, - Inactive, - Pending, - Revoked, -} +pub use storage_models::enums::*; diff --git a/crates/router/src/types/storage/ephemeral_key.rs b/crates/router/src/types/storage/ephemeral_key.rs index 44226d50fd..afbae4eca0 100644 --- a/crates/router/src/types/storage/ephemeral_key.rs +++ b/crates/router/src/types/storage/ephemeral_key.rs @@ -1,16 +1 @@ -pub struct EphemeralKeyNew { - pub id: String, - pub merchant_id: String, - pub customer_id: String, - pub secret: String, -} - -#[derive(Debug, serde::Serialize, serde::Deserialize)] -pub struct EphemeralKey { - pub id: String, - pub merchant_id: String, - pub customer_id: String, - pub created_at: i64, - pub expires: i64, - pub secret: String, -} +pub use storage_models::ephemeral_key::{EphemeralKey, EphemeralKeyNew}; diff --git a/crates/router/src/types/storage/events.rs b/crates/router/src/types/storage/events.rs index 86edcbae39..c56791a8de 100644 --- a/crates/router/src/types/storage/events.rs +++ b/crates/router/src/types/storage/events.rs @@ -1,35 +1 @@ -use common_utils::custom_serde; -use diesel::{Identifiable, Insertable, Queryable}; -use serde::{Deserialize, Serialize}; -use time::PrimitiveDateTime; - -use crate::{schema::events, types::storage::enums as storage_enums}; - -#[derive(Clone, Debug, Deserialize, Insertable, Serialize, router_derive::DebugAsDisplay)] -#[diesel(table_name = events)] -#[serde(deny_unknown_fields)] -pub struct EventNew { - pub event_id: String, - pub event_type: storage_enums::EventType, - pub event_class: storage_enums::EventClass, - pub is_webhook_notified: bool, - pub intent_reference_id: Option, - pub primary_object_id: String, - pub primary_object_type: storage_enums::EventObjectType, -} - -#[derive(Clone, Debug, Deserialize, Serialize, Identifiable, Queryable)] -#[diesel(table_name = events)] -pub struct Event { - #[serde(skip_serializing)] - pub id: i32, - pub event_id: String, - pub event_type: storage_enums::EventType, - pub event_class: storage_enums::EventClass, - pub is_webhook_notified: bool, - pub intent_reference_id: Option, - pub primary_object_id: String, - pub primary_object_type: storage_enums::EventObjectType, - #[serde(with = "custom_serde::iso8601")] - pub created_at: PrimitiveDateTime, -} +pub use storage_models::events::{Event, EventNew}; diff --git a/crates/router/src/types/storage/locker_mock_up.rs b/crates/router/src/types/storage/locker_mock_up.rs index 5df7c60b68..7621ffa539 100644 --- a/crates/router/src/types/storage/locker_mock_up.rs +++ b/crates/router/src/types/storage/locker_mock_up.rs @@ -1,34 +1 @@ -use diesel::{Identifiable, Insertable, Queryable}; - -use crate::schema::locker_mock_up; - -#[derive(Clone, Debug, Eq, Identifiable, Queryable, PartialEq)] -#[diesel(table_name = locker_mock_up)] -pub struct LockerMockUp { - pub id: i32, - pub card_id: String, - pub external_id: String, - pub card_fingerprint: String, - pub card_global_fingerprint: String, - pub merchant_id: String, - pub card_number: String, - pub card_exp_year: String, - pub card_exp_month: String, - pub name_on_card: Option, - pub nickname: Option, - pub customer_id: Option, - pub duplicate: Option, -} - -#[derive(Clone, Debug, Default, Insertable, router_derive::DebugAsDisplay)] -#[diesel(table_name = locker_mock_up)] -pub struct LockerMockUpNew { - pub card_id: String, - pub external_id: String, - pub card_fingerprint: String, - pub card_global_fingerprint: String, - pub merchant_id: String, - pub card_number: String, - pub card_exp_year: String, - pub card_exp_month: String, -} +pub use storage_models::locker_mock_up::{LockerMockUp, LockerMockUpNew}; diff --git a/crates/router/src/types/storage/mandate.rs b/crates/router/src/types/storage/mandate.rs index 17a2203aa0..bafecb42f2 100644 --- a/crates/router/src/types/storage/mandate.rs +++ b/crates/router/src/types/storage/mandate.rs @@ -1,106 +1,3 @@ -use diesel::{AsChangeset, Identifiable, Insertable, Queryable}; -use time::PrimitiveDateTime; - -use crate::schema::mandate; -// use serde::{Deserialize, Serialize}; -use crate::{ - pii::{self, Secret}, - types::storage::enums as storage_enums, +pub use storage_models::mandate::{ + Mandate, MandateNew, MandateUpdate, MandateUpdateInternal, SingleUseMandate, }; - -#[derive(Clone, Debug, Identifiable, Queryable)] -#[diesel(table_name = mandate)] -pub struct Mandate { - pub id: i32, - pub mandate_id: String, - pub customer_id: String, - pub merchant_id: String, - pub payment_method_id: String, - pub mandate_status: storage_enums::MandateStatus, - pub mandate_type: storage_enums::MandateType, - pub customer_accepted_at: Option, - pub customer_ip_address: Option>, - pub customer_user_agent: Option, - pub network_transaction_id: Option, - pub previous_transaction_id: Option, - pub created_at: PrimitiveDateTime, - pub mandate_amount: Option, - pub mandate_currency: Option, - pub amount_captured: Option, - pub connector: String, - pub connector_mandate_id: Option, -} - -#[derive( - router_derive::Setter, Clone, Debug, Default, Insertable, router_derive::DebugAsDisplay, -)] -#[diesel(table_name = mandate)] -pub struct MandateNew { - pub mandate_id: String, - pub customer_id: String, - pub merchant_id: String, - pub payment_method_id: String, - pub mandate_status: storage_enums::MandateStatus, - pub mandate_type: storage_enums::MandateType, - pub customer_accepted_at: Option, - pub customer_ip_address: Option>, - pub customer_user_agent: Option, - pub network_transaction_id: Option, - pub previous_transaction_id: Option, - pub created_at: Option, - pub mandate_amount: Option, - pub mandate_currency: Option, - pub amount_captured: Option, - pub connector: String, - pub connector_mandate_id: Option, -} - -#[derive(Debug)] -pub enum MandateUpdate { - StatusUpdate { - mandate_status: storage_enums::MandateStatus, - }, - CaptureAmountUpdate { - amount_captured: Option, - }, - ConnectorReferenceUpdate { - connector_mandate_id: Option, - }, -} - -#[derive(Clone, Eq, PartialEq, Copy, Debug, Default, serde::Serialize, serde::Deserialize)] -pub struct MandateAmountData { - pub amount: i32, - pub currency: storage_enums::Currency, -} - -#[derive(Clone, Debug, Default, AsChangeset, router_derive::DebugAsDisplay)] -#[diesel(table_name = mandate)] -pub(super) struct MandateUpdateInternal { - mandate_status: Option, - amount_captured: Option, - connector_mandate_id: Option, -} - -impl From for MandateUpdateInternal { - fn from(mandate_update: MandateUpdate) -> Self { - match mandate_update { - MandateUpdate::StatusUpdate { mandate_status } => Self { - mandate_status: Some(mandate_status), - connector_mandate_id: None, - amount_captured: None, - }, - MandateUpdate::CaptureAmountUpdate { amount_captured } => Self { - mandate_status: None, - amount_captured, - connector_mandate_id: None, - }, - MandateUpdate::ConnectorReferenceUpdate { - connector_mandate_id, - } => Self { - connector_mandate_id, - ..Default::default() - }, - } - } -} diff --git a/crates/router/src/types/storage/merchant_account.rs b/crates/router/src/types/storage/merchant_account.rs index 92b32cbaf5..e6bd21d03c 100644 --- a/crates/router/src/types/storage/merchant_account.rs +++ b/crates/router/src/types/storage/merchant_account.rs @@ -1,120 +1,3 @@ -use diesel::{AsChangeset, Identifiable, Insertable, Queryable}; - -use crate::{pii::StrongSecret, schema::merchant_account, types::storage::enums as storage_enums}; - -#[derive(Clone, Debug, Eq, PartialEq, Identifiable, Queryable, router_derive::DebugAsDisplay)] -#[diesel(table_name = merchant_account)] -pub struct MerchantAccount { - pub id: i32, - pub merchant_id: String, - pub api_key: Option>, - pub return_url: Option, - pub enable_payment_response_hash: bool, - pub payment_response_hash_key: Option, - pub redirect_to_merchant_with_http_post: bool, - pub merchant_name: Option, - pub merchant_details: Option, - pub webhook_details: Option, - pub routing_algorithm: Option, - pub custom_routing_rules: Option, - pub sub_merchants_enabled: Option, - pub parent_merchant_id: Option, - pub publishable_key: Option, - pub storage_scheme: storage_enums::MerchantStorageScheme, -} - -#[derive(Clone, Debug, Default, Insertable, router_derive::DebugAsDisplay)] -#[diesel(table_name = merchant_account)] -pub struct MerchantAccountNew { - pub merchant_id: String, - pub merchant_name: Option, - pub api_key: Option>, - pub merchant_details: Option, - pub return_url: Option, - pub webhook_details: Option, - pub routing_algorithm: Option, - pub custom_routing_rules: Option, - pub sub_merchants_enabled: Option, - pub parent_merchant_id: Option, - pub enable_payment_response_hash: Option, - pub payment_response_hash_key: Option, - pub redirect_to_merchant_with_http_post: Option, - pub(crate) publishable_key: Option, -} - -#[derive(Debug)] -pub enum MerchantAccountUpdate { - Update { - merchant_id: String, - merchant_name: Option, - api_key: Option>, - merchant_details: Option, - return_url: Option, - webhook_details: Option, - routing_algorithm: Option, - custom_routing_rules: Option, - sub_merchants_enabled: Option, - parent_merchant_id: Option, - enable_payment_response_hash: Option, - payment_response_hash_key: Option, - redirect_to_merchant_with_http_post: Option, - publishable_key: Option, - }, -} - -#[derive(Clone, Debug, Default, AsChangeset, router_derive::DebugAsDisplay)] -#[diesel(table_name = merchant_account)] -pub(super) struct MerchantAccountUpdateInternal { - merchant_id: Option, - merchant_name: Option, - api_key: Option>, - merchant_details: Option, - return_url: Option, - webhook_details: Option, - routing_algorithm: Option, - custom_routing_rules: Option, - sub_merchants_enabled: Option, - parent_merchant_id: Option, - enable_payment_response_hash: Option, - payment_response_hash_key: Option, - redirect_to_merchant_with_http_post: Option, - publishable_key: Option, -} - -impl From for MerchantAccountUpdateInternal { - fn from(merchant_account_update: MerchantAccountUpdate) -> Self { - match merchant_account_update { - MerchantAccountUpdate::Update { - merchant_id, - merchant_name, - api_key, - merchant_details, - return_url, - webhook_details, - routing_algorithm, - custom_routing_rules, - sub_merchants_enabled, - parent_merchant_id, - enable_payment_response_hash, - payment_response_hash_key, - redirect_to_merchant_with_http_post, - publishable_key, - } => Self { - merchant_id: Some(merchant_id), - merchant_name, - api_key, - merchant_details, - return_url, - webhook_details, - routing_algorithm, - custom_routing_rules, - sub_merchants_enabled, - parent_merchant_id, - enable_payment_response_hash, - payment_response_hash_key, - redirect_to_merchant_with_http_post, - publishable_key, - }, - } - } -} +pub use storage_models::merchant_account::{ + MerchantAccount, MerchantAccountNew, MerchantAccountUpdate, MerchantAccountUpdateInternal, +}; diff --git a/crates/router/src/types/storage/merchant_connector_account.rs b/crates/router/src/types/storage/merchant_connector_account.rs index 1d7ceedc81..249538f582 100644 --- a/crates/router/src/types/storage/merchant_connector_account.rs +++ b/crates/router/src/types/storage/merchant_connector_account.rs @@ -1,85 +1,4 @@ -use diesel::{AsChangeset, Identifiable, Insertable, Queryable}; - -use crate::{ - pii::Secret, schema::merchant_connector_account, types::storage::enums as storage_enums, +pub use storage_models::merchant_connector_account::{ + MerchantConnectorAccount, MerchantConnectorAccountNew, MerchantConnectorAccountUpdate, + MerchantConnectorAccountUpdateInternal, }; - -#[derive(Clone, Debug, Eq, PartialEq, Identifiable, Queryable, router_derive::DebugAsDisplay)] -#[diesel(table_name = merchant_connector_account)] -pub struct MerchantConnectorAccount { - pub id: i32, - pub merchant_id: String, - pub connector_name: String, - pub connector_account_details: serde_json::Value, - pub test_mode: Option, - pub disabled: Option, - pub merchant_connector_id: i32, - #[diesel(deserialize_as = super::OptionalDieselArray)] - pub payment_methods_enabled: Option>, - pub connector_type: storage_enums::ConnectorType, -} - -#[derive(Clone, Debug, Default, Insertable, router_derive::DebugAsDisplay)] -#[diesel(table_name = merchant_connector_account)] -pub struct MerchantConnectorAccountNew { - pub merchant_id: Option, - pub connector_type: Option, - pub connector_name: Option, - pub connector_account_details: Option>, - pub test_mode: Option, - pub disabled: Option, - pub merchant_connector_id: Option, - pub payment_methods_enabled: Option>, -} - -#[derive(Debug)] -pub enum MerchantConnectorAccountUpdate { - Update { - merchant_id: Option, - connector_type: Option, - connector_name: Option, - connector_account_details: Option>, - test_mode: Option, - disabled: Option, - merchant_connector_id: Option, - payment_methods_enabled: Option>, - }, -} -#[derive(Clone, Debug, Default, AsChangeset, router_derive::DebugAsDisplay)] -#[diesel(table_name = merchant_connector_account)] -pub(super) struct MerchantConnectorAccountUpdateInternal { - merchant_id: Option, - connector_type: Option, - connector_name: Option, - connector_account_details: Option>, - test_mode: Option, - disabled: Option, - merchant_connector_id: Option, - payment_methods_enabled: Option>, -} - -impl From for MerchantConnectorAccountUpdateInternal { - fn from(merchant_connector_account_update: MerchantConnectorAccountUpdate) -> Self { - match merchant_connector_account_update { - MerchantConnectorAccountUpdate::Update { - merchant_id, - connector_type, - connector_name, - connector_account_details, - test_mode, - disabled, - merchant_connector_id, - payment_methods_enabled, - } => Self { - merchant_id, - connector_type, - connector_name, - connector_account_details, - test_mode, - disabled, - merchant_connector_id, - payment_methods_enabled, - }, - } - } -} diff --git a/crates/router/src/types/storage/payment_attempt.rs b/crates/router/src/types/storage/payment_attempt.rs index 3f18d125db..40cd181d76 100644 --- a/crates/router/src/types/storage/payment_attempt.rs +++ b/crates/router/src/types/storage/payment_attempt.rs @@ -1,239 +1,9 @@ -use diesel::{AsChangeset, Identifiable, Insertable, Queryable}; -use serde::{Deserialize, Serialize}; -use time::PrimitiveDateTime; +pub use storage_models::payment_attempt::{ + PaymentAttempt, PaymentAttemptNew, PaymentAttemptUpdate, PaymentAttemptUpdateInternal, +}; -use crate::{schema::payment_attempt, types::storage::enums as storage_enums}; - -#[derive(Clone, Debug, Eq, PartialEq, Identifiable, Queryable, Serialize, Deserialize)] -#[diesel(table_name = payment_attempt)] -pub struct PaymentAttempt { - pub id: i32, - pub payment_id: String, - pub merchant_id: String, - pub txn_id: String, - pub status: storage_enums::AttemptStatus, - pub amount: i32, - pub currency: Option, - pub save_to_locker: Option, - pub connector: Option, - pub error_message: Option, - pub offer_amount: Option, - pub surcharge_amount: Option, - pub tax_amount: Option, - pub payment_method_id: Option, - pub payment_method: Option, - pub payment_flow: Option, - pub redirect: Option, - pub connector_transaction_id: Option, - pub capture_method: Option, - pub capture_on: Option, - pub confirm: bool, - pub authentication_type: Option, - pub created_at: PrimitiveDateTime, - pub modified_at: PrimitiveDateTime, - pub last_synced: Option, - pub cancellation_reason: Option, - pub amount_to_capture: Option, - pub mandate_id: Option, - pub browser_info: Option, -} - -#[derive(Clone, Debug, Default, Insertable, router_derive::DebugAsDisplay)] -#[diesel(table_name = payment_attempt)] -pub struct PaymentAttemptNew { - pub payment_id: String, - pub merchant_id: String, - pub txn_id: String, - pub status: storage_enums::AttemptStatus, - pub amount: i32, - pub currency: Option, - // pub auto_capture: Option, - pub save_to_locker: Option, - pub connector: Option, - pub error_message: Option, - pub offer_amount: Option, - pub surcharge_amount: Option, - pub tax_amount: Option, - pub payment_method_id: Option, - pub payment_method: Option, - pub payment_flow: Option, - pub redirect: Option, - pub connector_transaction_id: Option, - pub capture_method: Option, - pub capture_on: Option, - pub confirm: bool, - pub authentication_type: Option, - pub created_at: Option, - pub modified_at: Option, - pub last_synced: Option, - pub cancellation_reason: Option, - pub amount_to_capture: Option, - pub mandate_id: Option, - pub browser_info: Option, -} - -#[derive(Debug, Clone)] -pub enum PaymentAttemptUpdate { - Update { - amount: i32, - currency: storage_enums::Currency, - status: storage_enums::AttemptStatus, - authentication_type: Option, - payment_method: Option, - }, - AuthenticationTypeUpdate { - authentication_type: storage_enums::AuthenticationType, - }, - ConfirmUpdate { - status: storage_enums::AttemptStatus, - payment_method: Option, - browser_info: Option, - connector: Option, - }, - VoidUpdate { - status: storage_enums::AttemptStatus, - cancellation_reason: Option, - }, - ResponseUpdate { - status: storage_enums::AttemptStatus, - connector_transaction_id: Option, - authentication_type: Option, - payment_method_id: Option>, - redirect: Option, - mandate_id: Option, - }, - StatusUpdate { - status: storage_enums::AttemptStatus, - }, - ErrorUpdate { - status: storage_enums::AttemptStatus, - error_message: Option, - }, -} - -#[derive(Clone, Debug, Default, AsChangeset, router_derive::DebugAsDisplay)] -#[diesel(table_name = payment_attempt)] -pub(super) struct PaymentAttemptUpdateInternal { - amount: Option, - currency: Option, - status: Option, - connector_transaction_id: Option, - connector: Option, - authentication_type: Option, - payment_method: Option, - error_message: Option, - payment_method_id: Option>, - cancellation_reason: Option, - modified_at: Option, - redirect: Option, - mandate_id: Option, - browser_info: Option, -} - -impl PaymentAttemptUpdate { - pub fn apply_changeset(self, source: PaymentAttempt) -> PaymentAttempt { - let pa_update: PaymentAttemptUpdateInternal = self.into(); - PaymentAttempt { - amount: pa_update.amount.unwrap_or(source.amount), - currency: pa_update.currency.or(source.currency), - status: pa_update.status.unwrap_or(source.status), - connector_transaction_id: pa_update - .connector_transaction_id - .or(source.connector_transaction_id), - authentication_type: pa_update.authentication_type.or(source.authentication_type), - payment_method: pa_update.payment_method.or(source.payment_method), - error_message: pa_update.error_message.or(source.error_message), - payment_method_id: pa_update - .payment_method_id - .unwrap_or(source.payment_method_id), - browser_info: pa_update.browser_info, - modified_at: common_utils::date_time::now(), - ..source - } - } -} - -impl From for PaymentAttemptUpdateInternal { - fn from(payment_attempt_update: PaymentAttemptUpdate) -> Self { - match payment_attempt_update { - PaymentAttemptUpdate::Update { - amount, - currency, - status, - // connector_transaction_id, - authentication_type, - payment_method, - } => Self { - amount: Some(amount), - currency: Some(currency), - status: Some(status), - // connector_transaction_id, - authentication_type, - payment_method, - modified_at: Some(common_utils::date_time::now()), - ..Default::default() - }, - PaymentAttemptUpdate::AuthenticationTypeUpdate { - authentication_type, - } => Self { - authentication_type: Some(authentication_type), - modified_at: Some(common_utils::date_time::now()), - ..Default::default() - }, - PaymentAttemptUpdate::ConfirmUpdate { - status, - payment_method, - browser_info, - connector, - } => Self { - status: Some(status), - payment_method, - modified_at: Some(common_utils::date_time::now()), - browser_info, - connector, - ..Default::default() - }, - PaymentAttemptUpdate::VoidUpdate { - status, - cancellation_reason, - } => Self { - status: Some(status), - cancellation_reason, - ..Default::default() - }, - PaymentAttemptUpdate::ResponseUpdate { - status, - connector_transaction_id, - authentication_type, - payment_method_id, - redirect, - mandate_id, - } => Self { - status: Some(status), - connector_transaction_id, - authentication_type, - payment_method_id, - modified_at: Some(common_utils::date_time::now()), - redirect, - mandate_id, - ..Default::default() - }, - PaymentAttemptUpdate::ErrorUpdate { - status, - error_message, - } => Self { - status: Some(status), - error_message, - modified_at: Some(common_utils::date_time::now()), - ..Default::default() - }, - PaymentAttemptUpdate::StatusUpdate { status } => Self { - status: Some(status), - ..Default::default() - }, - } - } -} +#[cfg(feature = "kv_store")] +impl crate::utils::storage_partitioning::KvStorePartition for PaymentAttempt {} #[cfg(test)] mod tests { diff --git a/crates/router/src/types/storage/payment_intent.rs b/crates/router/src/types/storage/payment_intent.rs index a153fa4c64..3a24b787f6 100644 --- a/crates/router/src/types/storage/payment_intent.rs +++ b/crates/router/src/types/storage/payment_intent.rs @@ -1,233 +1,89 @@ -use diesel::{AsChangeset, Identifiable, Insertable, Queryable}; -use serde::{Deserialize, Serialize}; -use time::PrimitiveDateTime; +use async_bb8_diesel::AsyncRunQueryDsl; +use diesel::{associations::HasTable, ExpressionMethods, QueryDsl}; +use error_stack::{IntoReport, ResultExt}; +use router_env::tracing::{self, instrument}; +pub use storage_models::{ + errors, + payment_intent::{ + PaymentIntent, PaymentIntentNew, PaymentIntentUpdate, PaymentIntentUpdateInternal, + }, + schema::payment_intent::dsl, +}; -use crate::{schema::payment_intent, types::storage::enums as storage_enums}; +use crate::{connection::PgPooledConn, core::errors::CustomResult, types::api}; -#[derive(Clone, Debug, Eq, PartialEq, Identifiable, Queryable, Serialize, Deserialize)] -#[diesel(table_name = payment_intent)] -pub struct PaymentIntent { - pub id: i32, - pub payment_id: String, - pub merchant_id: String, - pub status: storage_enums::IntentStatus, - pub amount: i32, - pub currency: Option, - pub amount_captured: Option, - pub customer_id: Option, - pub description: Option, - pub return_url: Option, - pub metadata: Option, - pub connector_id: Option, - pub shipping_address_id: Option, - pub billing_address_id: Option, - pub statement_descriptor_name: Option, - pub statement_descriptor_suffix: Option, - pub created_at: PrimitiveDateTime, - pub modified_at: PrimitiveDateTime, - pub last_synced: Option, // FIXME: this is optional - pub setup_future_usage: Option, - pub off_session: Option, - pub client_secret: Option, +#[cfg(feature = "kv_store")] +impl crate::utils::storage_partitioning::KvStorePartition for PaymentIntent {} + +#[async_trait::async_trait] +pub trait PaymentIntentDbExt: Sized { + async fn filter_by_constraints( + conn: &PgPooledConn, + merchant_id: &str, + pc: &api::PaymentListConstraints, + ) -> CustomResult, errors::DatabaseError>; } -#[derive(Clone, Debug, Default, Eq, PartialEq, Insertable, router_derive::DebugAsDisplay)] -#[diesel(table_name = payment_intent)] -pub struct PaymentIntentNew { - pub payment_id: String, - pub merchant_id: String, - pub status: storage_enums::IntentStatus, - pub amount: i32, - pub currency: Option, - pub amount_captured: Option, - pub customer_id: Option, - pub description: Option, - pub return_url: Option, - pub metadata: Option, - pub connector_id: Option, - pub shipping_address_id: Option, - pub billing_address_id: Option, - pub statement_descriptor_name: Option, - pub statement_descriptor_suffix: Option, - pub created_at: Option, - pub modified_at: Option, - pub last_synced: Option, - pub client_secret: Option, - pub setup_future_usage: Option, - pub off_session: Option, -} +#[async_trait::async_trait] +impl PaymentIntentDbExt for PaymentIntent { + #[instrument(skip(conn))] + async fn filter_by_constraints( + conn: &PgPooledConn, + merchant_id: &str, + pc: &api::PaymentListConstraints, + ) -> CustomResult, errors::DatabaseError> { + let customer_id = &pc.customer_id; + let starting_after = &pc.starting_after; + let ending_before = &pc.ending_before; -#[derive(Debug, Clone)] -pub enum PaymentIntentUpdate { - ResponseUpdate { - status: storage_enums::IntentStatus, - amount_captured: Option, - return_url: Option, - }, - MetadataUpdate { - metadata: serde_json::Value, - }, - ReturnUrlUpdate { - return_url: Option, - status: Option, - customer_id: Option, - shipping_address_id: Option, - billing_address_id: Option, - }, - MerchantStatusUpdate { - status: storage_enums::IntentStatus, - shipping_address_id: Option, - billing_address_id: Option, - }, - PGStatusUpdate { - status: storage_enums::IntentStatus, - }, - Update { - amount: i32, - currency: storage_enums::Currency, - status: storage_enums::IntentStatus, - customer_id: Option, - shipping_address_id: Option, - billing_address_id: Option, - }, -} + //TODO: Replace this with Boxable Expression and pass it into generic filter + // when https://github.com/rust-lang/rust/issues/52662 becomes stable -#[derive(Clone, Debug, Default, AsChangeset, router_derive::DebugAsDisplay)] -#[diesel(table_name = payment_intent)] + let mut filter = ::table() + .filter(dsl::merchant_id.eq(merchant_id.to_owned())) + .order_by(dsl::id) + .into_boxed(); -pub struct PaymentIntentUpdateInternal { - pub amount: Option, - pub currency: Option, - pub status: Option, - pub amount_captured: Option, - pub customer_id: Option, - pub return_url: Option, - pub setup_future_usage: Option, - pub off_session: Option, - pub metadata: Option, - pub client_secret: Option>, - pub billing_address_id: Option, - pub shipping_address_id: Option, - pub modified_at: Option, -} - -impl PaymentIntentUpdate { - pub fn apply_changeset(self, source: PaymentIntent) -> PaymentIntent { - let internal_update: PaymentIntentUpdateInternal = self.into(); - PaymentIntent { - amount: internal_update.amount.unwrap_or(source.amount), - currency: internal_update.currency.or(source.currency), - status: internal_update.status.unwrap_or(source.status), - amount_captured: internal_update.amount_captured.or(source.amount_captured), - customer_id: internal_update.customer_id.or(source.customer_id), - return_url: internal_update.return_url.or(source.return_url), - setup_future_usage: internal_update - .setup_future_usage - .or(source.setup_future_usage), - off_session: internal_update.off_session.or(source.off_session), - metadata: internal_update.metadata.or(source.metadata), - client_secret: internal_update - .client_secret - .unwrap_or(source.client_secret), - billing_address_id: internal_update - .billing_address_id - .or(source.billing_address_id), - shipping_address_id: internal_update - .shipping_address_id - .or(source.shipping_address_id), - modified_at: common_utils::date_time::now(), - ..source + if let Some(customer_id) = customer_id { + filter = filter.filter(dsl::customer_id.eq(customer_id.to_owned())); } - } -} - -impl From for PaymentIntentUpdateInternal { - fn from(payment_intent_update: PaymentIntentUpdate) -> Self { - match payment_intent_update { - PaymentIntentUpdate::Update { - amount, - currency, - status, - customer_id, - shipping_address_id, - billing_address_id, - } => Self { - amount: Some(amount), - currency: Some(currency), - status: Some(status), - customer_id, - client_secret: make_client_secret_null_if_success(Some(status)), - shipping_address_id, - billing_address_id, - modified_at: Some(common_utils::date_time::now()), - ..Default::default() - }, - PaymentIntentUpdate::MetadataUpdate { metadata } => Self { - metadata: Some(metadata), - modified_at: Some(common_utils::date_time::now()), - ..Default::default() - }, - PaymentIntentUpdate::ReturnUrlUpdate { - return_url, - status, - customer_id, - shipping_address_id, - billing_address_id, - } => Self { - return_url, - status, - client_secret: make_client_secret_null_if_success(status), - customer_id, - shipping_address_id, - billing_address_id, - modified_at: Some(common_utils::date_time::now()), - ..Default::default() - }, - PaymentIntentUpdate::PGStatusUpdate { status } => Self { - status: Some(status), - modified_at: Some(common_utils::date_time::now()), - ..Default::default() - }, - PaymentIntentUpdate::MerchantStatusUpdate { - status, - shipping_address_id, - billing_address_id, - } => Self { - status: Some(status), - client_secret: make_client_secret_null_if_success(Some(status)), - shipping_address_id, - billing_address_id, - modified_at: Some(common_utils::date_time::now()), - ..Default::default() - }, - PaymentIntentUpdate::ResponseUpdate { - // amount, - // currency, - status, - amount_captured, - // customer_id, - return_url, - } => Self { - // amount, - // currency: Some(currency), - status: Some(status), - amount_captured, - // customer_id, - return_url, - client_secret: make_client_secret_null_if_success(Some(status)), - modified_at: Some(common_utils::date_time::now()), - ..Default::default() - }, + if let Some(created) = pc.created { + filter = filter.filter(dsl::created_at.eq(created)); + } + if let Some(created_lt) = pc.created_lt { + filter = filter.filter(dsl::created_at.lt(created_lt)); + } + if let Some(created_gt) = pc.created_gt { + filter = filter.filter(dsl::created_at.gt(created_gt)); + } + if let Some(created_lte) = pc.created_lte { + filter = filter.filter(dsl::created_at.le(created_lte)); + } + if let Some(created_gte) = pc.created_gte { + filter = filter.filter(dsl::created_at.gt(created_gte)); + } + if let Some(starting_after) = starting_after { + let id = Self::find_by_payment_id_merchant_id(conn, starting_after, merchant_id) + .await? + .id; + filter = filter.filter(dsl::id.gt(id)); + } + if let Some(ending_before) = ending_before { + let id = Self::find_by_payment_id_merchant_id(conn, ending_before, merchant_id) + .await? + .id; + filter = filter.filter(dsl::id.lt(id.to_owned())); } - } -} -fn make_client_secret_null_if_success( - status: Option, -) -> Option> { - if status == Some(storage_enums::IntentStatus::Succeeded) { - Option::>::Some(None) - } else { - None + filter = filter.limit(pc.limit); + + crate::logger::debug!(query = %diesel::debug_query::(&filter).to_string()); + + filter + .get_results_async(conn) + .await + .into_report() + .change_context(errors::DatabaseError::NotFound) + .attach_printable_lazy(|| "Error filtering records by predicate") } } diff --git a/crates/router/src/types/storage/payment_method.rs b/crates/router/src/types/storage/payment_method.rs index 58365f9f69..e66b2cd2ef 100644 --- a/crates/router/src/types/storage/payment_method.rs +++ b/crates/router/src/types/storage/payment_method.rs @@ -1,86 +1 @@ -use diesel::{Identifiable, Insertable, Queryable}; -use time::PrimitiveDateTime; - -use crate::{pii::Secret, schema::payment_methods, types::storage::enums as storage_enums}; - -#[derive(Clone, Debug, Eq, PartialEq, Identifiable, Queryable)] -#[diesel(table_name = payment_methods)] -pub struct PaymentMethod { - pub id: i32, - pub customer_id: String, - pub merchant_id: String, - pub payment_method_id: String, - #[diesel(deserialize_as = super::OptionalDieselArray)] - pub accepted_currency: Option>, - pub scheme: Option, - pub token: Option, - pub cardholder_name: Option>, - pub issuer_name: Option, - pub issuer_country: Option, - #[diesel(deserialize_as = super::OptionalDieselArray)] - pub payer_country: Option>, - pub is_stored: Option, - pub swift_code: Option, - pub direct_debit_token: Option, - pub network_transaction_id: Option, - pub created_at: PrimitiveDateTime, - pub last_modified: PrimitiveDateTime, - pub payment_method: storage_enums::PaymentMethodType, - pub payment_method_type: Option, - pub payment_method_issuer: Option, - pub payment_method_issuer_code: Option, -} - -#[derive(Clone, Debug, Eq, PartialEq, Insertable, Queryable, router_derive::DebugAsDisplay)] -#[diesel(table_name = payment_methods)] -pub struct PaymentMethodNew { - pub customer_id: String, - pub merchant_id: String, - pub payment_method_id: String, - pub payment_method: storage_enums::PaymentMethodType, - pub payment_method_type: Option, - pub payment_method_issuer: Option, - pub payment_method_issuer_code: Option, - pub accepted_currency: Option>, - pub scheme: Option, - pub token: Option, - pub cardholder_name: Option>, - pub issuer_name: Option, - pub issuer_country: Option, - pub payer_country: Option>, - pub is_stored: Option, - pub swift_code: Option, - pub direct_debit_token: Option, - pub network_transaction_id: Option, - pub created_at: PrimitiveDateTime, - pub last_modified: PrimitiveDateTime, -} - -impl Default for PaymentMethodNew { - fn default() -> Self { - let now = common_utils::date_time::now(); - - Self { - customer_id: String::default(), - merchant_id: String::default(), - payment_method_id: String::default(), - payment_method: storage_enums::PaymentMethodType::default(), - payment_method_type: Option::default(), - payment_method_issuer: Option::default(), - payment_method_issuer_code: Option::default(), - accepted_currency: Option::default(), - scheme: Option::default(), - token: Option::default(), - cardholder_name: Option::default(), - issuer_name: Option::default(), - issuer_country: Option::default(), - payer_country: Option::default(), - is_stored: Option::default(), - swift_code: Option::default(), - direct_debit_token: Option::default(), - network_transaction_id: Option::default(), - created_at: now, - last_modified: now, - } - } -} +pub use storage_models::payment_method::{PaymentMethod, PaymentMethodNew}; diff --git a/crates/router/src/types/storage/process_tracker.rs b/crates/router/src/types/storage/process_tracker.rs index 42c0b41061..883c69d69c 100644 --- a/crates/router/src/types/storage/process_tracker.rs +++ b/crates/router/src/types/storage/process_tracker.rs @@ -1,48 +1,49 @@ -use diesel::{AsChangeset, Identifiable, Insertable, Queryable}; use error_stack::ResultExt; -use serde::{Deserialize, Serialize}; +use serde::Serialize; +pub use storage_models::process_tracker::{ + Milliseconds, ProcessData, ProcessTracker, ProcessTrackerNew, ProcessTrackerUpdate, + ProcessTrackerUpdateInternal, SchedulerOptions, +}; use time::PrimitiveDateTime; use crate::{ - core::errors, db::StorageInterface, scheduler::metrics, schema::process_tracker, - types::storage::enums as storage_enums, + core::errors, db::StorageInterface, scheduler::metrics, types::storage::enums as storage_enums, }; -#[derive( - Clone, - Debug, - Eq, - PartialEq, - Deserialize, - Identifiable, - Queryable, - Serialize, - router_derive::DebugAsDisplay, -)] -#[diesel(table_name = process_tracker)] -pub struct ProcessTracker { - pub id: String, - pub name: Option, - #[diesel(deserialize_as = super::DieselArray)] - pub tag: Vec, - pub runner: Option, - pub retry_count: i32, - pub schedule_time: Option, - pub rule: String, - pub tracking_data: serde_json::Value, - pub business_status: String, - pub status: storage_enums::ProcessTrackerStatus, - #[diesel(deserialize_as = super::DieselArray)] - pub event: Vec, - pub created_at: PrimitiveDateTime, - pub updated_at: PrimitiveDateTime, +#[async_trait::async_trait] +pub trait ProcessTrackerExt { + fn is_valid_business_status(&self, valid_statuses: &[&str]) -> bool; + + fn make_process_tracker_new<'a, T>( + process_tracker_id: String, + task: &'a str, + runner: &'a str, + tracking_data: T, + schedule_time: PrimitiveDateTime, + ) -> Result + where + T: Serialize; + + async fn retry( + self, + db: &dyn StorageInterface, + schedule_time: PrimitiveDateTime, + ) -> Result<(), errors::ProcessTrackerError>; + + async fn finish_with_status( + self, + db: &dyn StorageInterface, + status: String, + ) -> Result<(), errors::ProcessTrackerError>; } -impl ProcessTracker { - pub fn is_valid_business_status(&self, valid_statuses: &[&str]) -> bool { +#[async_trait::async_trait] +impl ProcessTrackerExt for ProcessTracker { + fn is_valid_business_status(&self, valid_statuses: &[&str]) -> bool { valid_statuses.iter().any(|x| x == &self.business_status) } - pub fn make_process_tracker_new<'a, T>( + + fn make_process_tracker_new<'a, T>( process_tracker_id: String, task: &'a str, runner: &'a str, @@ -71,7 +72,7 @@ impl ProcessTracker { }) } - pub async fn retry( + async fn retry( self, db: &dyn StorageInterface, schedule_time: PrimitiveDateTime, @@ -89,7 +90,7 @@ impl ProcessTracker { Ok(()) } - pub async fn finish_with_status( + async fn finish_with_status( self, db: &dyn StorageInterface, status: String, @@ -107,135 +108,3 @@ impl ProcessTracker { Ok(()) } } - -#[derive(Clone, Debug, Insertable, router_derive::DebugAsDisplay)] -#[diesel(table_name = process_tracker)] -pub struct ProcessTrackerNew { - pub id: String, - pub name: Option, - pub tag: Vec, - pub runner: Option, - pub retry_count: i32, - pub schedule_time: Option, - pub rule: String, - pub tracking_data: serde_json::Value, - pub business_status: String, - pub status: storage_enums::ProcessTrackerStatus, - pub event: Vec, - pub created_at: PrimitiveDateTime, - pub updated_at: PrimitiveDateTime, -} - -#[derive(Debug)] -pub enum ProcessTrackerUpdate { - Update { - name: Option, - retry_count: Option, - schedule_time: Option, - tracking_data: Option, - business_status: Option, - status: Option, - updated_at: Option, - }, - StatusUpdate { - status: storage_enums::ProcessTrackerStatus, - business_status: Option, - }, - StatusRetryUpdate { - status: storage_enums::ProcessTrackerStatus, - retry_count: i32, - schedule_time: PrimitiveDateTime, - }, -} - -#[derive(Debug, Clone, AsChangeset, router_derive::DebugAsDisplay)] -#[diesel(table_name = process_tracker)] -pub(super) struct ProcessTrackerUpdateInternal { - name: Option, - retry_count: Option, - schedule_time: Option, - tracking_data: Option, - business_status: Option, - status: Option, - updated_at: Option, -} - -impl Default for ProcessTrackerUpdateInternal { - fn default() -> Self { - Self { - name: Option::default(), - retry_count: Option::default(), - schedule_time: Option::default(), - tracking_data: Option::default(), - business_status: Option::default(), - status: Option::default(), - updated_at: Some(common_utils::date_time::now()), - } - } -} - -impl From for ProcessTrackerUpdateInternal { - fn from(process_tracker_update: ProcessTrackerUpdate) -> Self { - match process_tracker_update { - ProcessTrackerUpdate::Update { - name, - retry_count, - schedule_time, - tracking_data, - business_status, - status, - updated_at, - } => Self { - name, - retry_count, - schedule_time, - tracking_data, - business_status, - status, - updated_at, - }, - ProcessTrackerUpdate::StatusUpdate { - status, - business_status, - } => Self { - status: Some(status), - business_status, - ..Default::default() - }, - ProcessTrackerUpdate::StatusRetryUpdate { - status, - retry_count, - schedule_time, - } => Self { - status: Some(status), - retry_count: Some(retry_count), - schedule_time: Some(schedule_time), - ..Default::default() - }, - } - } -} - -// TODO: Move this to a utility module? -pub struct Milliseconds(i32); - -#[allow(dead_code)] -pub struct SchedulerOptions { - looper_interval: Milliseconds, - db_name: String, - cache_name: String, - schema_name: String, - cache_expiry: i32, - runners: Vec, - fetch_limit: i32, - fetch_limit_product_factor: i32, - query_order: String, -} - -#[derive(Debug, Clone)] -#[allow(dead_code)] -pub struct ProcessData { - db_name: String, - cache_name: String, - process_tracker: ProcessTracker, -} diff --git a/crates/router/src/types/storage/query.rs b/crates/router/src/types/storage/query.rs index d28e004d2d..0dd8b43b5d 100644 --- a/crates/router/src/types/storage/query.rs +++ b/crates/router/src/types/storage/query.rs @@ -1,16 +1 @@ -mod address; -mod configs; -mod connector_response; -mod customers; -mod events; -mod generics; -mod locker_mock_up; -mod mandate; -mod merchant_account; -mod merchant_connector_account; -mod payment_attempt; -mod payment_intent; -mod payment_method; -mod process_tracker; -mod refund; -mod temp_card; +pub use storage_models::query::*; diff --git a/crates/router/src/types/storage/query/payment_intent.rs b/crates/router/src/types/storage/query/payment_intent.rs deleted file mode 100644 index c6e17a0b11..0000000000 --- a/crates/router/src/types/storage/query/payment_intent.rs +++ /dev/null @@ -1,177 +0,0 @@ -use async_bb8_diesel::AsyncRunQueryDsl; -use diesel::{associations::HasTable, BoolExpressionMethods, ExpressionMethods, QueryDsl}; -use error_stack::{IntoReport, ResultExt}; -use router_env::tracing::{self, instrument}; - -#[cfg(not(feature = "kv_store"))] -use super::generics::{self, ExecuteQuery}; -#[cfg(feature = "kv_store")] -use super::generics::{self, ExecuteQuery, RawQuery, RawSqlQuery}; -use crate::{ - connection::PgPooledConn, - core::errors::{self, CustomResult}, - schema::payment_intent::dsl, - types::{ - api, - storage::{ - PaymentIntent, PaymentIntentNew, PaymentIntentUpdate, PaymentIntentUpdateInternal, - }, - }, -}; - -impl PaymentIntentNew { - #[instrument(skip(conn))] - pub async fn insert_diesel( - self, - conn: &PgPooledConn, - ) -> CustomResult { - generics::generic_insert::<_, _, PaymentIntent, _>(conn, self, ExecuteQuery::new()).await - } - - #[cfg(feature = "kv_store")] - #[instrument(skip(conn))] - pub async fn insert_diesel_query( - self, - conn: &PgPooledConn, - ) -> CustomResult { - generics::generic_insert::<_, _, PaymentIntent, _>(conn, self, RawQuery).await - } -} - -impl PaymentIntent { - #[instrument(skip(conn))] - pub async fn update( - self, - conn: &PgPooledConn, - payment_intent: PaymentIntentUpdate, - ) -> CustomResult { - match generics::generic_update_by_id::<::Table, _, _, Self, _>( - conn, - self.id, - PaymentIntentUpdateInternal::from(payment_intent), - ExecuteQuery::new(), - ) - .await - { - Err(error) => match error.current_context() { - errors::StorageError::DatabaseError(errors::DatabaseError::NoFieldsToUpdate) => { - Ok(self) - } - _ => Err(error), - }, - result => result, - } - } - - #[cfg(feature = "kv_store")] - #[instrument(skip(conn))] - pub async fn update_query( - self, - conn: &PgPooledConn, - payment_intent: PaymentIntentUpdate, - ) -> CustomResult { - generics::generic_update_by_id::<::Table, _, _, Self, _>( - conn, - self.id, - PaymentIntentUpdateInternal::from(payment_intent), - RawQuery, - ) - .await - } - - #[instrument(skip(conn))] - pub async fn find_by_payment_id_merchant_id( - conn: &PgPooledConn, - payment_id: &str, - merchant_id: &str, - ) -> CustomResult { - generics::generic_find_one::<::Table, _, _>( - conn, - dsl::merchant_id - .eq(merchant_id.to_owned()) - .and(dsl::payment_id.eq(payment_id.to_owned())), - ) - .await - } - - #[instrument(skip(conn))] - pub async fn find_optional_by_payment_id_merchant_id( - conn: &PgPooledConn, - payment_id: &str, - merchant_id: &str, - ) -> CustomResult, errors::StorageError> { - generics::generic_find_one_optional::<::Table, _, _>( - conn, - dsl::merchant_id - .eq(merchant_id.to_owned()) - .and(dsl::payment_id.eq(payment_id.to_owned())), - ) - .await - } - - #[instrument(skip(conn))] - pub async fn filter_by_constraints( - conn: &PgPooledConn, - merchant_id: &str, - pc: &api::PaymentListConstraints, - ) -> CustomResult, errors::StorageError> { - let customer_id = &pc.customer_id; - let starting_after = &pc.starting_after; - let ending_before = &pc.ending_before; - - //TODO: Replace this with Boxable Expression and pass it into generic filter - // when https://github.com/rust-lang/rust/issues/52662 becomes stable - - let mut filter = ::table() - .filter(dsl::merchant_id.eq(merchant_id.to_owned())) - .order_by(dsl::id) - .into_boxed(); - - if let Some(customer_id) = customer_id { - filter = filter.filter(dsl::customer_id.eq(customer_id.to_owned())); - } - if let Some(created) = pc.created { - filter = filter.filter(dsl::created_at.eq(created)); - } - if let Some(created_lt) = pc.created_lt { - filter = filter.filter(dsl::created_at.lt(created_lt)); - } - if let Some(created_gt) = pc.created_gt { - filter = filter.filter(dsl::created_at.gt(created_gt)); - } - if let Some(created_lte) = pc.created_lte { - filter = filter.filter(dsl::created_at.le(created_lte)); - } - if let Some(created_gte) = pc.created_gte { - filter = filter.filter(dsl::created_at.gt(created_gte)); - } - if let Some(starting_after) = starting_after { - let id = Self::find_by_payment_id_merchant_id(conn, starting_after, merchant_id) - .await? - .id; - filter = filter.filter(dsl::id.gt(id)); - } - if let Some(ending_before) = ending_before { - let id = Self::find_by_payment_id_merchant_id(conn, ending_before, merchant_id) - .await? - .id; - filter = filter.filter(dsl::id.lt(id.to_owned())); - } - - filter = filter.limit(pc.limit); - - crate::logger::debug!(query = %diesel::debug_query::(&filter).to_string()); - - filter - .get_results_async(conn) - .await - .into_report() - .change_context(errors::StorageError::DatabaseError( - errors::DatabaseError::NotFound, - )) - .attach_printable_lazy(|| "Error filtering records by predicate") - } -} - -#[cfg(feature = "kv_store")] -impl crate::utils::storage_partitioning::KvStorePartition for PaymentIntent {} diff --git a/crates/router/src/types/storage/refund.rs b/crates/router/src/types/storage/refund.rs index bd01d97560..26992d18e4 100644 --- a/crates/router/src/types/storage/refund.rs +++ b/crates/router/src/types/storage/refund.rs @@ -1,141 +1,3 @@ -use diesel::{AsChangeset, Identifiable, Insertable, Queryable}; -use serde::{Deserialize, Serialize}; -use time::PrimitiveDateTime; - -use crate::{schema::refund, types::storage::enums as storage_enums}; - -#[derive(Clone, Debug, Eq, Identifiable, Queryable, PartialEq)] -#[diesel(table_name = refund)] -pub struct Refund { - pub id: i32, - pub internal_reference_id: String, - pub refund_id: String, //merchant_reference id - pub payment_id: String, - pub merchant_id: String, - pub transaction_id: String, - pub connector: String, - pub pg_refund_id: Option, - pub external_reference_id: Option, - pub refund_type: storage_enums::RefundType, - pub total_amount: i32, - pub currency: storage_enums::Currency, - pub refund_amount: i32, - pub refund_status: storage_enums::RefundStatus, - pub sent_to_gateway: bool, - pub refund_error_message: Option, - pub metadata: Option, - pub refund_arn: Option, - pub created_at: PrimitiveDateTime, - pub updated_at: PrimitiveDateTime, - pub description: Option, -} - -#[derive(Clone, Debug, Default, Eq, PartialEq, Insertable, router_derive::DebugAsDisplay)] -#[diesel(table_name = refund)] -pub struct RefundNew { - pub refund_id: String, - pub payment_id: String, - pub merchant_id: String, - pub internal_reference_id: String, - pub external_reference_id: Option, - pub transaction_id: String, - pub connector: String, - pub pg_refund_id: Option, - pub refund_type: storage_enums::RefundType, - pub total_amount: i32, - pub currency: storage_enums::Currency, - pub refund_amount: i32, - pub refund_status: storage_enums::RefundStatus, - pub sent_to_gateway: bool, - pub refund_error_message: Option, - pub metadata: Option, - pub refund_arn: Option, - pub created_at: Option, - pub modified_at: Option, - pub description: Option, -} - -#[derive(Debug)] -pub enum RefundUpdate { - Update { - pg_refund_id: String, - refund_status: storage_enums::RefundStatus, - sent_to_gateway: bool, - refund_error_message: Option, - refund_arn: String, - }, - MetadataUpdate { - metadata: Option, - }, - StatusUpdate { - pg_refund_id: Option, - sent_to_gateway: bool, - refund_status: storage_enums::RefundStatus, - }, - ErrorUpdate { - refund_status: Option, - refund_error_message: Option, - }, -} - -#[derive(Clone, Debug, Default, AsChangeset, router_derive::DebugAsDisplay)] -#[diesel(table_name = refund)] -pub(super) struct RefundUpdateInternal { - pg_refund_id: Option, - refund_status: Option, - sent_to_gateway: Option, - refund_error_message: Option, - refund_arn: Option, - metadata: Option, -} - -impl From for RefundUpdateInternal { - fn from(refund_update: RefundUpdate) -> Self { - match refund_update { - RefundUpdate::Update { - pg_refund_id, - refund_status, - sent_to_gateway, - refund_error_message, - refund_arn, - } => Self { - pg_refund_id: Some(pg_refund_id), - refund_status: Some(refund_status), - sent_to_gateway: Some(sent_to_gateway), - refund_error_message, - refund_arn: Some(refund_arn), - ..Default::default() - }, - RefundUpdate::MetadataUpdate { metadata } => Self { - metadata, - ..Default::default() - }, - RefundUpdate::StatusUpdate { - pg_refund_id, - sent_to_gateway, - refund_status, - } => Self { - pg_refund_id, - sent_to_gateway: Some(sent_to_gateway), - refund_status: Some(refund_status), - ..Default::default() - }, - RefundUpdate::ErrorUpdate { - refund_status, - refund_error_message, - } => Self { - refund_status, - refund_error_message, - ..Default::default() - }, - } - } -} - -#[derive(Debug, Eq, PartialEq, Deserialize, Serialize)] -pub struct RefundCoreWorkflow { - pub refund_internal_reference_id: String, - pub transaction_id: String, - pub merchant_id: String, - pub payment_id: String, -} +pub use storage_models::refund::{ + Refund, RefundCoreWorkflow, RefundNew, RefundUpdate, RefundUpdateInternal, +}; diff --git a/crates/router/src/types/storage/temp_card.rs b/crates/router/src/types/storage/temp_card.rs index 6b036ef8d9..fba5d4b518 100644 --- a/crates/router/src/types/storage/temp_card.rs +++ b/crates/router/src/types/storage/temp_card.rs @@ -1,23 +1 @@ -use diesel::{Identifiable, Insertable, Queryable}; -use serde_json::Value; -use time::PrimitiveDateTime; - -use crate::schema::temp_card; - -#[derive(Clone, Debug, router_derive::DebugAsDisplay, Queryable, Identifiable, Insertable)] -#[diesel(table_name = temp_card)] -pub struct TempCard { - pub id: i32, - pub date_created: PrimitiveDateTime, - pub txn_id: Option, - pub card_info: Option, -} - -#[derive(Clone, Debug, Insertable, router_derive::DebugAsDisplay)] -#[diesel(table_name = temp_card)] -pub struct TempCardNew { - pub id: Option, - pub card_info: Option, - pub date_created: PrimitiveDateTime, - pub txn_id: Option, -} +pub use storage_models::temp_card::{TempCard, TempCardNew}; diff --git a/crates/router/src/types/transformers.rs b/crates/router/src/types/transformers.rs index 60b62867c1..9b6bad04ba 100644 --- a/crates/router/src/types/transformers.rs +++ b/crates/router/src/types/transformers.rs @@ -1,184 +1,366 @@ +use std::convert::TryInto; + use api_models::enums as api_enums; +use storage_models::enums as storage_enums; -use crate::{core::errors, types::storage::enums as storage_enums}; +use crate::{ + core::errors, + types::{api as api_types, storage}, +}; -impl From for storage_enums::RoutingAlgorithm { - fn from(algo: api_enums::RoutingAlgorithm) -> Self { - match algo { - api_enums::RoutingAlgorithm::RoundRobin => Self::RoundRobin, - api_enums::RoutingAlgorithm::MaxConversion => Self::MaxConversion, - api_enums::RoutingAlgorithm::MinCost => Self::MinCost, - api_enums::RoutingAlgorithm::Custom => Self::Custom, - } +pub struct Foreign(pub T); + +type F = Foreign; + +impl From for Foreign { + fn from(val: T) -> Self { + Self(val) } } -impl From for api_enums::RoutingAlgorithm { - fn from(algo: storage_enums::RoutingAlgorithm) -> Self { - match algo { - storage_enums::RoutingAlgorithm::RoundRobin => Self::RoundRobin, - storage_enums::RoutingAlgorithm::MaxConversion => Self::MaxConversion, - storage_enums::RoutingAlgorithm::MinCost => Self::MinCost, - storage_enums::RoutingAlgorithm::Custom => Self::Custom, - } +pub trait ForeignInto { + fn foreign_into(self) -> T; +} + +pub trait ForeignTryInto { + type Error; + + fn foreign_try_into(self) -> Result; +} + +pub trait ForeignFrom { + fn foreign_from(from: F) -> Self; +} + +pub trait ForeignTryFrom: Sized { + type Error; + + fn foreign_try_from(from: F) -> Result; +} + +impl ForeignInto for F +where + Foreign: Into>, +{ + fn foreign_into(self) -> T { + let f_from = Foreign(self); + let f_to: Foreign = f_from.into(); + f_to.0 } } -impl From for storage_enums::ConnectorType { - fn from(conn: api_enums::ConnectorType) -> Self { - match conn { - api_enums::ConnectorType::PaymentProcessor => Self::PaymentProcessor, - api_enums::ConnectorType::PaymentVas => Self::PaymentVas, - api_enums::ConnectorType::FinOperations => Self::FinOperations, - api_enums::ConnectorType::FizOperations => Self::FizOperations, - api_enums::ConnectorType::Networks => Self::Networks, - api_enums::ConnectorType::BankingEntities => Self::BankingEntities, - api_enums::ConnectorType::NonBankingFinance => Self::NonBankingFinance, - } +impl ForeignTryInto for F +where + Foreign: TryInto>, +{ + type Error = as TryInto>>::Error; + + fn foreign_try_into(self) -> Result { + let f_from = Foreign(self); + let f_to: Result, Self::Error> = f_from.try_into(); + f_to.map(|f| f.0) } } -impl From for api_enums::ConnectorType { - fn from(conn: storage_enums::ConnectorType) -> Self { - match conn { - storage_enums::ConnectorType::PaymentProcessor => Self::PaymentProcessor, - storage_enums::ConnectorType::PaymentVas => Self::PaymentVas, - storage_enums::ConnectorType::FinOperations => Self::FinOperations, - storage_enums::ConnectorType::FizOperations => Self::FizOperations, - storage_enums::ConnectorType::Networks => Self::Networks, - storage_enums::ConnectorType::BankingEntities => Self::BankingEntities, - storage_enums::ConnectorType::NonBankingFinance => Self::NonBankingFinance, - } +impl ForeignFrom for T +where + Foreign: From>, +{ + fn foreign_from(from: F) -> Self { + let f_from = Foreign(from); + let f_to: Foreign = f_from.into(); + f_to.0 } } -impl From for api_enums::MandateStatus { - fn from(status: storage_enums::MandateStatus) -> Self { - match status { - storage_enums::MandateStatus::Active => Self::Active, - storage_enums::MandateStatus::Inactive => Self::Inactive, - storage_enums::MandateStatus::Pending => Self::Pending, - storage_enums::MandateStatus::Revoked => Self::Revoked, - } +impl ForeignTryFrom for T +where + Foreign: TryFrom>, +{ + type Error = as TryFrom>>::Error; + + fn foreign_try_from(from: F) -> Result { + let f_from = Foreign(from); + let f_to: Result, Self::Error> = f_from.try_into(); + f_to.map(|f| f.0) } } -impl From for storage_enums::PaymentMethodType { - fn from(pm_type: api_enums::PaymentMethodType) -> Self { - match pm_type { - api_enums::PaymentMethodType::Card => Self::Card, - api_enums::PaymentMethodType::PaymentContainer => Self::PaymentContainer, - api_enums::PaymentMethodType::BankTransfer => Self::BankTransfer, - api_enums::PaymentMethodType::BankDebit => Self::BankDebit, - api_enums::PaymentMethodType::PayLater => Self::PayLater, - api_enums::PaymentMethodType::Netbanking => Self::Netbanking, - api_enums::PaymentMethodType::Upi => Self::Upi, - api_enums::PaymentMethodType::OpenBanking => Self::OpenBanking, - api_enums::PaymentMethodType::ConsumerFinance => Self::ConsumerFinance, - api_enums::PaymentMethodType::Wallet => Self::Wallet, - api_enums::PaymentMethodType::Klarna => Self::Klarna, - api_enums::PaymentMethodType::Paypal => Self::Paypal, - } - } -} - -impl From for api_enums::PaymentMethodType { - fn from(pm_type: storage_enums::PaymentMethodType) -> Self { - match pm_type { - storage_enums::PaymentMethodType::Card => Self::Card, - storage_enums::PaymentMethodType::PaymentContainer => Self::PaymentContainer, - storage_enums::PaymentMethodType::BankTransfer => Self::BankTransfer, - storage_enums::PaymentMethodType::BankDebit => Self::BankDebit, - storage_enums::PaymentMethodType::PayLater => Self::PayLater, - storage_enums::PaymentMethodType::Netbanking => Self::Netbanking, - storage_enums::PaymentMethodType::Upi => Self::Upi, - storage_enums::PaymentMethodType::OpenBanking => Self::OpenBanking, - storage_enums::PaymentMethodType::ConsumerFinance => Self::ConsumerFinance, - storage_enums::PaymentMethodType::Wallet => Self::Wallet, - storage_enums::PaymentMethodType::Klarna => Self::Klarna, - storage_enums::PaymentMethodType::Paypal => Self::Paypal, - } - } -} - -impl From for storage_enums::PaymentMethodSubType { - fn from(pm_subtype: api_enums::PaymentMethodSubType) -> Self { - match pm_subtype { - api_enums::PaymentMethodSubType::Credit => Self::Credit, - api_enums::PaymentMethodSubType::Debit => Self::Debit, - api_enums::PaymentMethodSubType::UpiIntent => Self::UpiIntent, - api_enums::PaymentMethodSubType::UpiCollect => Self::UpiCollect, - api_enums::PaymentMethodSubType::CreditCardInstallments => Self::CreditCardInstallments, - api_enums::PaymentMethodSubType::PayLaterInstallments => Self::PayLaterInstallments, - } - } -} - -impl From for api_enums::PaymentMethodSubType { - fn from(pm_subtype: storage_enums::PaymentMethodSubType) -> Self { - match pm_subtype { - storage_enums::PaymentMethodSubType::Credit => Self::Credit, - storage_enums::PaymentMethodSubType::Debit => Self::Debit, - storage_enums::PaymentMethodSubType::UpiIntent => Self::UpiIntent, - storage_enums::PaymentMethodSubType::UpiCollect => Self::UpiCollect, - storage_enums::PaymentMethodSubType::CreditCardInstallments => { - Self::CreditCardInstallments +impl From> for F { + fn from(algo: F) -> Self { + match algo.0 { + api_enums::RoutingAlgorithm::RoundRobin => storage_enums::RoutingAlgorithm::RoundRobin, + api_enums::RoutingAlgorithm::MaxConversion => { + storage_enums::RoutingAlgorithm::MaxConversion } - storage_enums::PaymentMethodSubType::PayLaterInstallments => Self::PayLaterInstallments, + api_enums::RoutingAlgorithm::MinCost => storage_enums::RoutingAlgorithm::MinCost, + api_enums::RoutingAlgorithm::Custom => storage_enums::RoutingAlgorithm::Custom, } + .into() } } -impl From for api_enums::PaymentMethodIssuerCode { - fn from(issuer_code: storage_enums::PaymentMethodIssuerCode) -> Self { - match issuer_code { - storage_enums::PaymentMethodIssuerCode::JpHdfc => Self::JpHdfc, - storage_enums::PaymentMethodIssuerCode::JpIcici => Self::JpIcici, - storage_enums::PaymentMethodIssuerCode::JpGooglepay => Self::JpGooglepay, - storage_enums::PaymentMethodIssuerCode::JpApplepay => Self::JpApplepay, - storage_enums::PaymentMethodIssuerCode::JpPhonepay => Self::JpPhonepay, - storage_enums::PaymentMethodIssuerCode::JpWechat => Self::JpWechat, - storage_enums::PaymentMethodIssuerCode::JpSofort => Self::JpSofort, - storage_enums::PaymentMethodIssuerCode::JpGiropay => Self::JpGiropay, - storage_enums::PaymentMethodIssuerCode::JpSepa => Self::JpSepa, - storage_enums::PaymentMethodIssuerCode::JpBacs => Self::JpBacs, +impl From> for F { + fn from(algo: F) -> Self { + match algo.0 { + storage_enums::RoutingAlgorithm::RoundRobin => api_enums::RoutingAlgorithm::RoundRobin, + storage_enums::RoutingAlgorithm::MaxConversion => { + api_enums::RoutingAlgorithm::MaxConversion + } + storage_enums::RoutingAlgorithm::MinCost => api_enums::RoutingAlgorithm::MinCost, + storage_enums::RoutingAlgorithm::Custom => api_enums::RoutingAlgorithm::Custom, } + .into() } } -impl From for api_enums::IntentStatus { - fn from(status: storage_enums::IntentStatus) -> Self { - match status { - storage_enums::IntentStatus::Succeeded => Self::Succeeded, - storage_enums::IntentStatus::Failed => Self::Failed, - storage_enums::IntentStatus::Cancelled => Self::Cancelled, - storage_enums::IntentStatus::Processing => Self::Processing, - storage_enums::IntentStatus::RequiresCustomerAction => Self::RequiresCustomerAction, - storage_enums::IntentStatus::RequiresPaymentMethod => Self::RequiresPaymentMethod, - storage_enums::IntentStatus::RequiresConfirmation => Self::RequiresConfirmation, - storage_enums::IntentStatus::RequiresCapture => Self::RequiresCapture, +impl From> for F { + fn from(conn: F) -> Self { + match conn.0 { + api_enums::ConnectorType::PaymentProcessor => { + storage_enums::ConnectorType::PaymentProcessor + } + api_enums::ConnectorType::PaymentVas => storage_enums::ConnectorType::PaymentVas, + api_enums::ConnectorType::FinOperations => storage_enums::ConnectorType::FinOperations, + api_enums::ConnectorType::FizOperations => storage_enums::ConnectorType::FizOperations, + api_enums::ConnectorType::Networks => storage_enums::ConnectorType::Networks, + api_enums::ConnectorType::BankingEntities => { + storage_enums::ConnectorType::BankingEntities + } + api_enums::ConnectorType::NonBankingFinance => { + storage_enums::ConnectorType::NonBankingFinance + } } + .into() } } -impl From for storage_enums::IntentStatus { - fn from(status: api_enums::IntentStatus) -> Self { - match status { - api_enums::IntentStatus::Succeeded => Self::Succeeded, - api_enums::IntentStatus::Failed => Self::Failed, - api_enums::IntentStatus::Cancelled => Self::Cancelled, - api_enums::IntentStatus::Processing => Self::Processing, - api_enums::IntentStatus::RequiresCustomerAction => Self::RequiresCustomerAction, - api_enums::IntentStatus::RequiresPaymentMethod => Self::RequiresPaymentMethod, - api_enums::IntentStatus::RequiresConfirmation => Self::RequiresConfirmation, - api_enums::IntentStatus::RequiresCapture => Self::RequiresCapture, +impl From> for F { + fn from(conn: F) -> Self { + match conn.0 { + storage_enums::ConnectorType::PaymentProcessor => { + api_enums::ConnectorType::PaymentProcessor + } + storage_enums::ConnectorType::PaymentVas => api_enums::ConnectorType::PaymentVas, + storage_enums::ConnectorType::FinOperations => api_enums::ConnectorType::FinOperations, + storage_enums::ConnectorType::FizOperations => api_enums::ConnectorType::FizOperations, + storage_enums::ConnectorType::Networks => api_enums::ConnectorType::Networks, + storage_enums::ConnectorType::BankingEntities => { + api_enums::ConnectorType::BankingEntities + } + storage_enums::ConnectorType::NonBankingFinance => { + api_enums::ConnectorType::NonBankingFinance + } } + .into() } } -impl From for storage_enums::IntentStatus { - fn from(s: storage_enums::AttemptStatus) -> Self { - match s { +impl From> for F { + fn from(status: F) -> Self { + match status.0 { + storage_enums::MandateStatus::Active => api_enums::MandateStatus::Active, + storage_enums::MandateStatus::Inactive => api_enums::MandateStatus::Inactive, + storage_enums::MandateStatus::Pending => api_enums::MandateStatus::Pending, + storage_enums::MandateStatus::Revoked => api_enums::MandateStatus::Revoked, + } + .into() + } +} + +impl From> for F { + fn from(pm_type: F) -> Self { + match pm_type.0 { + api_enums::PaymentMethodType::Card => storage_enums::PaymentMethodType::Card, + api_enums::PaymentMethodType::PaymentContainer => { + storage_enums::PaymentMethodType::PaymentContainer + } + api_enums::PaymentMethodType::BankTransfer => { + storage_enums::PaymentMethodType::BankTransfer + } + api_enums::PaymentMethodType::BankDebit => storage_enums::PaymentMethodType::BankDebit, + api_enums::PaymentMethodType::PayLater => storage_enums::PaymentMethodType::PayLater, + api_enums::PaymentMethodType::Netbanking => { + storage_enums::PaymentMethodType::Netbanking + } + api_enums::PaymentMethodType::Upi => storage_enums::PaymentMethodType::Upi, + api_enums::PaymentMethodType::OpenBanking => { + storage_enums::PaymentMethodType::OpenBanking + } + api_enums::PaymentMethodType::ConsumerFinance => { + storage_enums::PaymentMethodType::ConsumerFinance + } + api_enums::PaymentMethodType::Wallet => storage_enums::PaymentMethodType::Wallet, + api_enums::PaymentMethodType::Klarna => storage_enums::PaymentMethodType::Klarna, + api_enums::PaymentMethodType::Paypal => storage_enums::PaymentMethodType::Paypal, + } + .into() + } +} + +impl From> for F { + fn from(pm_type: F) -> Self { + match pm_type.0 { + storage_enums::PaymentMethodType::Card => api_enums::PaymentMethodType::Card, + storage_enums::PaymentMethodType::PaymentContainer => { + api_enums::PaymentMethodType::PaymentContainer + } + storage_enums::PaymentMethodType::BankTransfer => { + api_enums::PaymentMethodType::BankTransfer + } + storage_enums::PaymentMethodType::BankDebit => api_enums::PaymentMethodType::BankDebit, + storage_enums::PaymentMethodType::PayLater => api_enums::PaymentMethodType::PayLater, + storage_enums::PaymentMethodType::Netbanking => { + api_enums::PaymentMethodType::Netbanking + } + storage_enums::PaymentMethodType::Upi => api_enums::PaymentMethodType::Upi, + storage_enums::PaymentMethodType::OpenBanking => { + api_enums::PaymentMethodType::OpenBanking + } + storage_enums::PaymentMethodType::ConsumerFinance => { + api_enums::PaymentMethodType::ConsumerFinance + } + storage_enums::PaymentMethodType::Wallet => api_enums::PaymentMethodType::Wallet, + storage_enums::PaymentMethodType::Klarna => api_enums::PaymentMethodType::Klarna, + storage_enums::PaymentMethodType::Paypal => api_enums::PaymentMethodType::Paypal, + } + .into() + } +} + +impl From> for F { + fn from(pm_subtype: F) -> Self { + match pm_subtype.0 { + api_enums::PaymentMethodSubType::Credit => storage_enums::PaymentMethodSubType::Credit, + api_enums::PaymentMethodSubType::Debit => storage_enums::PaymentMethodSubType::Debit, + api_enums::PaymentMethodSubType::UpiIntent => { + storage_enums::PaymentMethodSubType::UpiIntent + } + api_enums::PaymentMethodSubType::UpiCollect => { + storage_enums::PaymentMethodSubType::UpiCollect + } + api_enums::PaymentMethodSubType::CreditCardInstallments => { + storage_enums::PaymentMethodSubType::CreditCardInstallments + } + api_enums::PaymentMethodSubType::PayLaterInstallments => { + storage_enums::PaymentMethodSubType::PayLaterInstallments + } + } + .into() + } +} + +impl From> for F { + fn from(pm_subtype: F) -> Self { + match pm_subtype.0 { + storage_enums::PaymentMethodSubType::Credit => api_enums::PaymentMethodSubType::Credit, + storage_enums::PaymentMethodSubType::Debit => api_enums::PaymentMethodSubType::Debit, + storage_enums::PaymentMethodSubType::UpiIntent => { + api_enums::PaymentMethodSubType::UpiIntent + } + storage_enums::PaymentMethodSubType::UpiCollect => { + api_enums::PaymentMethodSubType::UpiCollect + } + storage_enums::PaymentMethodSubType::CreditCardInstallments => { + api_enums::PaymentMethodSubType::CreditCardInstallments + } + storage_enums::PaymentMethodSubType::PayLaterInstallments => { + api_enums::PaymentMethodSubType::PayLaterInstallments + } + } + .into() + } +} + +impl From> for F { + fn from(issuer_code: F) -> Self { + match issuer_code.0 { + storage_enums::PaymentMethodIssuerCode::JpHdfc => { + api_enums::PaymentMethodIssuerCode::JpHdfc + } + storage_enums::PaymentMethodIssuerCode::JpIcici => { + api_enums::PaymentMethodIssuerCode::JpIcici + } + storage_enums::PaymentMethodIssuerCode::JpGooglepay => { + api_enums::PaymentMethodIssuerCode::JpGooglepay + } + storage_enums::PaymentMethodIssuerCode::JpApplepay => { + api_enums::PaymentMethodIssuerCode::JpApplepay + } + storage_enums::PaymentMethodIssuerCode::JpPhonepay => { + api_enums::PaymentMethodIssuerCode::JpPhonepay + } + storage_enums::PaymentMethodIssuerCode::JpWechat => { + api_enums::PaymentMethodIssuerCode::JpWechat + } + storage_enums::PaymentMethodIssuerCode::JpSofort => { + api_enums::PaymentMethodIssuerCode::JpSofort + } + storage_enums::PaymentMethodIssuerCode::JpGiropay => { + api_enums::PaymentMethodIssuerCode::JpGiropay + } + storage_enums::PaymentMethodIssuerCode::JpSepa => { + api_enums::PaymentMethodIssuerCode::JpSepa + } + storage_enums::PaymentMethodIssuerCode::JpBacs => { + api_enums::PaymentMethodIssuerCode::JpBacs + } + } + .into() + } +} + +impl From> for F { + fn from(status: F) -> Self { + match status.0 { + storage_enums::IntentStatus::Succeeded => api_enums::IntentStatus::Succeeded, + storage_enums::IntentStatus::Failed => api_enums::IntentStatus::Failed, + storage_enums::IntentStatus::Cancelled => api_enums::IntentStatus::Cancelled, + storage_enums::IntentStatus::Processing => api_enums::IntentStatus::Processing, + storage_enums::IntentStatus::RequiresCustomerAction => { + api_enums::IntentStatus::RequiresCustomerAction + } + storage_enums::IntentStatus::RequiresPaymentMethod => { + api_enums::IntentStatus::RequiresPaymentMethod + } + storage_enums::IntentStatus::RequiresConfirmation => { + api_enums::IntentStatus::RequiresConfirmation + } + storage_enums::IntentStatus::RequiresCapture => { + api_enums::IntentStatus::RequiresCapture + } + } + .into() + } +} + +impl From> for F { + fn from(status: F) -> Self { + match status.0 { + api_enums::IntentStatus::Succeeded => storage_enums::IntentStatus::Succeeded, + api_enums::IntentStatus::Failed => storage_enums::IntentStatus::Failed, + api_enums::IntentStatus::Cancelled => storage_enums::IntentStatus::Cancelled, + api_enums::IntentStatus::Processing => storage_enums::IntentStatus::Processing, + api_enums::IntentStatus::RequiresCustomerAction => { + storage_enums::IntentStatus::RequiresCustomerAction + } + api_enums::IntentStatus::RequiresPaymentMethod => { + storage_enums::IntentStatus::RequiresPaymentMethod + } + api_enums::IntentStatus::RequiresConfirmation => { + storage_enums::IntentStatus::RequiresConfirmation + } + api_enums::IntentStatus::RequiresCapture => { + storage_enums::IntentStatus::RequiresCapture + } + } + .into() + } +} + +impl From> for F { + fn from(s: F) -> Self { + match s.0 { storage_enums::AttemptStatus::Charged | storage_enums::AttemptStatus::AutoRefunded => { storage_enums::IntentStatus::Succeeded } @@ -214,206 +396,271 @@ impl From for storage_enums::IntentStatus { | storage_enums::AttemptStatus::Failure => storage_enums::IntentStatus::Failed, storage_enums::AttemptStatus::Voided => storage_enums::IntentStatus::Cancelled, } + .into() } } -impl TryFrom for storage_enums::EventType { +impl TryFrom> for F { type Error = errors::ValidationError; - fn try_from(value: api_enums::IntentStatus) -> Result { - match value { - api_enums::IntentStatus::Succeeded => Ok(Self::PaymentSucceeded), + fn try_from(value: F) -> Result { + match value.0 { + api_enums::IntentStatus::Succeeded => Ok(storage_enums::EventType::PaymentSucceeded), _ => Err(errors::ValidationError::IncorrectValueProvided { field_name: "intent_status", }), } + .map(Into::into) } } -impl From for api_enums::EventType { - fn from(event_type: storage_enums::EventType) -> Self { - match event_type { +impl From> for F { + fn from(event_type: F) -> Self { + match event_type.0 { storage_enums::EventType::PaymentSucceeded => api_enums::EventType::PaymentSucceeded, } + .into() } } -impl From for storage_enums::FutureUsage { - fn from(future_usage: api_enums::FutureUsage) -> Self { - match future_usage { - api_enums::FutureUsage::OnSession => Self::OnSession, - api_enums::FutureUsage::OffSession => Self::OffSession, +impl From> for F { + fn from(future_usage: F) -> Self { + match future_usage.0 { + api_enums::FutureUsage::OnSession => storage_enums::FutureUsage::OnSession, + api_enums::FutureUsage::OffSession => storage_enums::FutureUsage::OffSession, } + .into() } } -impl From for api_enums::FutureUsage { - fn from(future_usage: storage_enums::FutureUsage) -> Self { - match future_usage { - storage_enums::FutureUsage::OnSession => Self::OnSession, - storage_enums::FutureUsage::OffSession => Self::OffSession, +impl From> for F { + fn from(future_usage: F) -> Self { + match future_usage.0 { + storage_enums::FutureUsage::OnSession => api_enums::FutureUsage::OnSession, + storage_enums::FutureUsage::OffSession => api_enums::FutureUsage::OffSession, } + .into() } } -impl From for api_enums::RefundStatus { - fn from(status: storage_enums::RefundStatus) -> Self { - match status { - storage_enums::RefundStatus::Failure => Self::Failure, - storage_enums::RefundStatus::ManualReview => Self::ManualReview, - storage_enums::RefundStatus::Pending => Self::Pending, - storage_enums::RefundStatus::Success => Self::Success, - storage_enums::RefundStatus::TransactionFailure => Self::TransactionFailure, +impl From> for F { + fn from(status: F) -> Self { + match status.0 { + storage_enums::RefundStatus::Failure => api_enums::RefundStatus::Failure, + storage_enums::RefundStatus::ManualReview => api_enums::RefundStatus::ManualReview, + storage_enums::RefundStatus::Pending => api_enums::RefundStatus::Pending, + storage_enums::RefundStatus::Success => api_enums::RefundStatus::Success, + storage_enums::RefundStatus::TransactionFailure => { + api_enums::RefundStatus::TransactionFailure + } } + .into() } } -impl From for storage_enums::CaptureMethod { - fn from(capture_method: api_enums::CaptureMethod) -> Self { - match capture_method { - api_enums::CaptureMethod::Automatic => Self::Automatic, - api_enums::CaptureMethod::Manual => Self::Manual, - api_enums::CaptureMethod::ManualMultiple => Self::ManualMultiple, - api_enums::CaptureMethod::Scheduled => Self::Scheduled, +impl From> for F { + fn from(capture_method: F) -> Self { + match capture_method.0 { + api_enums::CaptureMethod::Automatic => storage_enums::CaptureMethod::Automatic, + api_enums::CaptureMethod::Manual => storage_enums::CaptureMethod::Manual, + api_enums::CaptureMethod::ManualMultiple => { + storage_enums::CaptureMethod::ManualMultiple + } + api_enums::CaptureMethod::Scheduled => storage_enums::CaptureMethod::Scheduled, } + .into() } } -impl From for api_enums::CaptureMethod { - fn from(capture_method: storage_enums::CaptureMethod) -> Self { - match capture_method { - storage_enums::CaptureMethod::Automatic => Self::Automatic, - storage_enums::CaptureMethod::Manual => Self::Manual, - storage_enums::CaptureMethod::ManualMultiple => Self::ManualMultiple, - storage_enums::CaptureMethod::Scheduled => Self::Scheduled, +impl From> for F { + fn from(capture_method: F) -> Self { + match capture_method.0 { + storage_enums::CaptureMethod::Automatic => api_enums::CaptureMethod::Automatic, + storage_enums::CaptureMethod::Manual => api_enums::CaptureMethod::Manual, + storage_enums::CaptureMethod::ManualMultiple => { + api_enums::CaptureMethod::ManualMultiple + } + storage_enums::CaptureMethod::Scheduled => api_enums::CaptureMethod::Scheduled, } + .into() } } -impl From for storage_enums::AuthenticationType { - fn from(auth_type: api_enums::AuthenticationType) -> Self { - match auth_type { - api_enums::AuthenticationType::ThreeDs => Self::ThreeDs, - api_enums::AuthenticationType::NoThreeDs => Self::NoThreeDs, +impl From> for F { + fn from(auth_type: F) -> Self { + match auth_type.0 { + api_enums::AuthenticationType::ThreeDs => storage_enums::AuthenticationType::ThreeDs, + api_enums::AuthenticationType::NoThreeDs => { + storage_enums::AuthenticationType::NoThreeDs + } } + .into() } } -impl From for api_enums::AuthenticationType { - fn from(auth_type: storage_enums::AuthenticationType) -> Self { - match auth_type { - storage_enums::AuthenticationType::ThreeDs => Self::ThreeDs, - storage_enums::AuthenticationType::NoThreeDs => Self::NoThreeDs, +impl From> for F { + fn from(auth_type: F) -> Self { + match auth_type.0 { + storage_enums::AuthenticationType::ThreeDs => api_enums::AuthenticationType::ThreeDs, + storage_enums::AuthenticationType::NoThreeDs => { + api_enums::AuthenticationType::NoThreeDs + } } + .into() } } -impl From for storage_enums::Currency { - fn from(currency: api_enums::Currency) -> Self { - match currency { - api_enums::Currency::AED => Self::AED, - api_enums::Currency::ALL => Self::ALL, - api_enums::Currency::AMD => Self::AMD, - api_enums::Currency::ARS => Self::ARS, - api_enums::Currency::AUD => Self::AUD, - api_enums::Currency::AWG => Self::AWG, - api_enums::Currency::AZN => Self::AZN, - api_enums::Currency::BBD => Self::BBD, - api_enums::Currency::BDT => Self::BDT, - api_enums::Currency::BHD => Self::BHD, - api_enums::Currency::BMD => Self::BMD, - api_enums::Currency::BND => Self::BND, - api_enums::Currency::BOB => Self::BOB, - api_enums::Currency::BRL => Self::BRL, - api_enums::Currency::BSD => Self::BSD, - api_enums::Currency::BWP => Self::BWP, - api_enums::Currency::BZD => Self::BZD, - api_enums::Currency::CAD => Self::CAD, - api_enums::Currency::CHF => Self::CHF, - api_enums::Currency::CNY => Self::CNY, - api_enums::Currency::COP => Self::COP, - api_enums::Currency::CRC => Self::CRC, - api_enums::Currency::CUP => Self::CUP, - api_enums::Currency::CZK => Self::CZK, - api_enums::Currency::DKK => Self::DKK, - api_enums::Currency::DOP => Self::DOP, - api_enums::Currency::DZD => Self::DZD, - api_enums::Currency::EGP => Self::EGP, - api_enums::Currency::ETB => Self::ETB, - api_enums::Currency::EUR => Self::EUR, - api_enums::Currency::FJD => Self::FJD, - api_enums::Currency::GBP => Self::GBP, - api_enums::Currency::GHS => Self::GHS, - api_enums::Currency::GIP => Self::GIP, - api_enums::Currency::GMD => Self::GMD, - api_enums::Currency::GTQ => Self::GTQ, - api_enums::Currency::GYD => Self::GYD, - api_enums::Currency::HKD => Self::HKD, - api_enums::Currency::HNL => Self::HNL, - api_enums::Currency::HRK => Self::HRK, - api_enums::Currency::HTG => Self::HTG, - api_enums::Currency::HUF => Self::HUF, - api_enums::Currency::IDR => Self::IDR, - api_enums::Currency::ILS => Self::ILS, - api_enums::Currency::INR => Self::INR, - api_enums::Currency::JMD => Self::JMD, - api_enums::Currency::JOD => Self::JOD, - api_enums::Currency::JPY => Self::JPY, - api_enums::Currency::KES => Self::KES, - api_enums::Currency::KGS => Self::KGS, - api_enums::Currency::KHR => Self::KHR, - api_enums::Currency::KRW => Self::KRW, - api_enums::Currency::KWD => Self::KWD, - api_enums::Currency::KYD => Self::KYD, - api_enums::Currency::KZT => Self::KZT, - api_enums::Currency::LAK => Self::LAK, - api_enums::Currency::LBP => Self::LBP, - api_enums::Currency::LKR => Self::LKR, - api_enums::Currency::LRD => Self::LRD, - api_enums::Currency::LSL => Self::LSL, - api_enums::Currency::MAD => Self::MAD, - api_enums::Currency::MDL => Self::MDL, - api_enums::Currency::MKD => Self::MKD, - api_enums::Currency::MMK => Self::MMK, - api_enums::Currency::MNT => Self::MNT, - api_enums::Currency::MOP => Self::MOP, - api_enums::Currency::MUR => Self::MUR, - api_enums::Currency::MVR => Self::MVR, - api_enums::Currency::MWK => Self::MWK, - api_enums::Currency::MXN => Self::MXN, - api_enums::Currency::MYR => Self::MYR, - api_enums::Currency::NAD => Self::NAD, - api_enums::Currency::NGN => Self::NGN, - api_enums::Currency::NIO => Self::NIO, - api_enums::Currency::NOK => Self::NOK, - api_enums::Currency::NPR => Self::NPR, - api_enums::Currency::NZD => Self::NZD, - api_enums::Currency::OMR => Self::OMR, - api_enums::Currency::PEN => Self::PEN, - api_enums::Currency::PGK => Self::PGK, - api_enums::Currency::PHP => Self::PHP, - api_enums::Currency::PKR => Self::PKR, - api_enums::Currency::PLN => Self::PLN, - api_enums::Currency::QAR => Self::QAR, - api_enums::Currency::RUB => Self::RUB, - api_enums::Currency::SAR => Self::SAR, - api_enums::Currency::SCR => Self::SCR, - api_enums::Currency::SEK => Self::SEK, - api_enums::Currency::SGD => Self::SGD, - api_enums::Currency::SLL => Self::SLL, - api_enums::Currency::SOS => Self::SOS, - api_enums::Currency::SSP => Self::SSP, - api_enums::Currency::SVC => Self::SVC, - api_enums::Currency::SZL => Self::SZL, - api_enums::Currency::THB => Self::THB, - api_enums::Currency::TTD => Self::TTD, - api_enums::Currency::TWD => Self::TWD, - api_enums::Currency::TZS => Self::TZS, - api_enums::Currency::USD => Self::USD, - api_enums::Currency::UYU => Self::UYU, - api_enums::Currency::UZS => Self::UZS, - api_enums::Currency::YER => Self::YER, - api_enums::Currency::ZAR => Self::ZAR, +impl From> for F { + fn from(currency: F) -> Self { + match currency.0 { + api_enums::Currency::AED => storage_enums::Currency::AED, + api_enums::Currency::ALL => storage_enums::Currency::ALL, + api_enums::Currency::AMD => storage_enums::Currency::AMD, + api_enums::Currency::ARS => storage_enums::Currency::ARS, + api_enums::Currency::AUD => storage_enums::Currency::AUD, + api_enums::Currency::AWG => storage_enums::Currency::AWG, + api_enums::Currency::AZN => storage_enums::Currency::AZN, + api_enums::Currency::BBD => storage_enums::Currency::BBD, + api_enums::Currency::BDT => storage_enums::Currency::BDT, + api_enums::Currency::BHD => storage_enums::Currency::BHD, + api_enums::Currency::BMD => storage_enums::Currency::BMD, + api_enums::Currency::BND => storage_enums::Currency::BND, + api_enums::Currency::BOB => storage_enums::Currency::BOB, + api_enums::Currency::BRL => storage_enums::Currency::BRL, + api_enums::Currency::BSD => storage_enums::Currency::BSD, + api_enums::Currency::BWP => storage_enums::Currency::BWP, + api_enums::Currency::BZD => storage_enums::Currency::BZD, + api_enums::Currency::CAD => storage_enums::Currency::CAD, + api_enums::Currency::CHF => storage_enums::Currency::CHF, + api_enums::Currency::CNY => storage_enums::Currency::CNY, + api_enums::Currency::COP => storage_enums::Currency::COP, + api_enums::Currency::CRC => storage_enums::Currency::CRC, + api_enums::Currency::CUP => storage_enums::Currency::CUP, + api_enums::Currency::CZK => storage_enums::Currency::CZK, + api_enums::Currency::DKK => storage_enums::Currency::DKK, + api_enums::Currency::DOP => storage_enums::Currency::DOP, + api_enums::Currency::DZD => storage_enums::Currency::DZD, + api_enums::Currency::EGP => storage_enums::Currency::EGP, + api_enums::Currency::ETB => storage_enums::Currency::ETB, + api_enums::Currency::EUR => storage_enums::Currency::EUR, + api_enums::Currency::FJD => storage_enums::Currency::FJD, + api_enums::Currency::GBP => storage_enums::Currency::GBP, + api_enums::Currency::GHS => storage_enums::Currency::GHS, + api_enums::Currency::GIP => storage_enums::Currency::GIP, + api_enums::Currency::GMD => storage_enums::Currency::GMD, + api_enums::Currency::GTQ => storage_enums::Currency::GTQ, + api_enums::Currency::GYD => storage_enums::Currency::GYD, + api_enums::Currency::HKD => storage_enums::Currency::HKD, + api_enums::Currency::HNL => storage_enums::Currency::HNL, + api_enums::Currency::HRK => storage_enums::Currency::HRK, + api_enums::Currency::HTG => storage_enums::Currency::HTG, + api_enums::Currency::HUF => storage_enums::Currency::HUF, + api_enums::Currency::IDR => storage_enums::Currency::IDR, + api_enums::Currency::ILS => storage_enums::Currency::ILS, + api_enums::Currency::INR => storage_enums::Currency::INR, + api_enums::Currency::JMD => storage_enums::Currency::JMD, + api_enums::Currency::JOD => storage_enums::Currency::JOD, + api_enums::Currency::JPY => storage_enums::Currency::JPY, + api_enums::Currency::KES => storage_enums::Currency::KES, + api_enums::Currency::KGS => storage_enums::Currency::KGS, + api_enums::Currency::KHR => storage_enums::Currency::KHR, + api_enums::Currency::KRW => storage_enums::Currency::KRW, + api_enums::Currency::KWD => storage_enums::Currency::KWD, + api_enums::Currency::KYD => storage_enums::Currency::KYD, + api_enums::Currency::KZT => storage_enums::Currency::KZT, + api_enums::Currency::LAK => storage_enums::Currency::LAK, + api_enums::Currency::LBP => storage_enums::Currency::LBP, + api_enums::Currency::LKR => storage_enums::Currency::LKR, + api_enums::Currency::LRD => storage_enums::Currency::LRD, + api_enums::Currency::LSL => storage_enums::Currency::LSL, + api_enums::Currency::MAD => storage_enums::Currency::MAD, + api_enums::Currency::MDL => storage_enums::Currency::MDL, + api_enums::Currency::MKD => storage_enums::Currency::MKD, + api_enums::Currency::MMK => storage_enums::Currency::MMK, + api_enums::Currency::MNT => storage_enums::Currency::MNT, + api_enums::Currency::MOP => storage_enums::Currency::MOP, + api_enums::Currency::MUR => storage_enums::Currency::MUR, + api_enums::Currency::MVR => storage_enums::Currency::MVR, + api_enums::Currency::MWK => storage_enums::Currency::MWK, + api_enums::Currency::MXN => storage_enums::Currency::MXN, + api_enums::Currency::MYR => storage_enums::Currency::MYR, + api_enums::Currency::NAD => storage_enums::Currency::NAD, + api_enums::Currency::NGN => storage_enums::Currency::NGN, + api_enums::Currency::NIO => storage_enums::Currency::NIO, + api_enums::Currency::NOK => storage_enums::Currency::NOK, + api_enums::Currency::NPR => storage_enums::Currency::NPR, + api_enums::Currency::NZD => storage_enums::Currency::NZD, + api_enums::Currency::OMR => storage_enums::Currency::OMR, + api_enums::Currency::PEN => storage_enums::Currency::PEN, + api_enums::Currency::PGK => storage_enums::Currency::PGK, + api_enums::Currency::PHP => storage_enums::Currency::PHP, + api_enums::Currency::PKR => storage_enums::Currency::PKR, + api_enums::Currency::PLN => storage_enums::Currency::PLN, + api_enums::Currency::QAR => storage_enums::Currency::QAR, + api_enums::Currency::RUB => storage_enums::Currency::RUB, + api_enums::Currency::SAR => storage_enums::Currency::SAR, + api_enums::Currency::SCR => storage_enums::Currency::SCR, + api_enums::Currency::SEK => storage_enums::Currency::SEK, + api_enums::Currency::SGD => storage_enums::Currency::SGD, + api_enums::Currency::SLL => storage_enums::Currency::SLL, + api_enums::Currency::SOS => storage_enums::Currency::SOS, + api_enums::Currency::SSP => storage_enums::Currency::SSP, + api_enums::Currency::SVC => storage_enums::Currency::SVC, + api_enums::Currency::SZL => storage_enums::Currency::SZL, + api_enums::Currency::THB => storage_enums::Currency::THB, + api_enums::Currency::TTD => storage_enums::Currency::TTD, + api_enums::Currency::TWD => storage_enums::Currency::TWD, + api_enums::Currency::TZS => storage_enums::Currency::TZS, + api_enums::Currency::USD => storage_enums::Currency::USD, + api_enums::Currency::UYU => storage_enums::Currency::UYU, + api_enums::Currency::UZS => storage_enums::Currency::UZS, + api_enums::Currency::YER => storage_enums::Currency::YER, + api_enums::Currency::ZAR => storage_enums::Currency::ZAR, } + .into() + } +} + +impl<'a> From> for F { + fn from(address: F<&api_types::Address>) -> Self { + let address = address.0; + storage::AddressUpdate::Update { + city: address.address.as_ref().and_then(|a| a.city.clone()), + country: address.address.as_ref().and_then(|a| a.country.clone()), + line1: address.address.as_ref().and_then(|a| a.line1.clone()), + line2: address.address.as_ref().and_then(|a| a.line2.clone()), + line3: address.address.as_ref().and_then(|a| a.line3.clone()), + state: address.address.as_ref().and_then(|a| a.state.clone()), + zip: address.address.as_ref().and_then(|a| a.zip.clone()), + first_name: address.address.as_ref().and_then(|a| a.first_name.clone()), + last_name: address.address.as_ref().and_then(|a| a.last_name.clone()), + phone_number: address.phone.as_ref().and_then(|a| a.number.clone()), + country_code: address.phone.as_ref().and_then(|a| a.country_code.clone()), + } + .into() + } +} + +impl<'a> From> for F { + fn from(address: F<&storage::Address>) -> Self { + let address = address.0; + api_types::Address { + address: Some(api_types::AddressDetails { + city: address.city.clone(), + country: address.country.clone(), + line1: address.line1.clone(), + line2: address.line2.clone(), + line3: address.line3.clone(), + state: address.state.clone(), + zip: address.zip.clone(), + first_name: address.first_name.clone(), + last_name: address.last_name.clone(), + }), + phone: Some(api_types::PhoneDetails { + number: address.phone_number.clone(), + country_code: address.country_code.clone(), + }), + } + .into() } } diff --git a/crates/storage_models/Cargo.toml b/crates/storage_models/Cargo.toml index 89a7c3882c..620b084f68 100644 --- a/crates/storage_models/Cargo.toml +++ b/crates/storage_models/Cargo.toml @@ -6,3 +6,19 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] +async-bb8-diesel = { git = "https://github.com/juspay/async-bb8-diesel", rev = "412663e16802dbc58a1b98bfcbe78fa0090311eb" } +async-trait = "0.1.57" +diesel = { git = "https://github.com/juspay/diesel", features = ["postgres", "serde_json", "time"], rev = "22f3f59f1db8a3f61623e4d6b375d64cd7bd3d02" } +error-stack = "0.2.1" +hex = "0.4.3" +serde = { version = "1.0.145", features = ["derive"] } +serde_json = "1.0.85" +strum = { version = "0.24.1", features = ["derive"] } +thiserror = "1.0.37" +time = { version = "0.3.14", features = ["serde", "serde-well-known", "std"] } + +# First party crates +common_utils = { version = "0.1.0", path = "../common_utils" } +masking = { version = "0.1.0", path = "../masking" } +router_derive = { version = "0.1.0", path = "../router_derive" } +router_env = { version = "0.1.0", path = "../router_env", features = ["log_extra_implicit_fields", "log_custom_entries_to_extra"] } diff --git a/crates/storage_models/src/address.rs b/crates/storage_models/src/address.rs new file mode 100644 index 0000000000..af0a5f186b --- /dev/null +++ b/crates/storage_models/src/address.rs @@ -0,0 +1,148 @@ +use common_utils::{consts, custom_serde, generate_id}; +use diesel::{AsChangeset, Identifiable, Insertable, Queryable}; +use masking::Secret; +use serde::{Deserialize, Serialize}; +use time::{OffsetDateTime, PrimitiveDateTime}; + +use crate::schema::address; + +#[derive(Clone, Debug, Deserialize, Serialize, Insertable, router_derive::DebugAsDisplay)] +#[diesel(table_name = address)] +#[serde(deny_unknown_fields)] +pub struct AddressNew { + pub address_id: String, + pub city: Option, + pub country: Option, + pub line1: Option>, + pub line2: Option>, + pub line3: Option>, + pub state: Option>, + pub zip: Option>, + pub first_name: Option>, + pub last_name: Option>, + pub phone_number: Option>, + pub country_code: Option, + pub customer_id: String, + pub merchant_id: String, +} + +#[derive(Clone, Debug, Deserialize, Serialize, Identifiable, Queryable)] +#[diesel(table_name = address)] +pub struct Address { + #[serde(skip_serializing)] + pub id: i32, + #[serde(skip_serializing)] + pub address_id: String, + pub city: Option, + pub country: Option, + pub line1: Option>, + pub line2: Option>, + pub line3: Option>, + pub state: Option>, + pub zip: Option>, + pub first_name: Option>, + pub last_name: Option>, + pub phone_number: Option>, + pub country_code: Option, + #[serde(skip_serializing)] + #[serde(with = "custom_serde::iso8601")] + pub created_at: PrimitiveDateTime, + #[serde(skip_serializing)] + #[serde(with = "custom_serde::iso8601")] + pub modified_at: PrimitiveDateTime, + pub customer_id: String, + pub merchant_id: String, +} + +#[derive(Debug)] +pub enum AddressUpdate { + Update { + city: Option, + country: Option, + line1: Option>, + line2: Option>, + line3: Option>, + state: Option>, + zip: Option>, + first_name: Option>, + last_name: Option>, + phone_number: Option>, + country_code: Option, + }, +} + +#[derive(Clone, Debug, AsChangeset, router_derive::DebugAsDisplay)] +#[diesel(table_name = address)] +pub struct AddressUpdateInternal { + city: Option, + country: Option, + line1: Option>, + line2: Option>, + line3: Option>, + state: Option>, + zip: Option>, + first_name: Option>, + last_name: Option>, + phone_number: Option>, + country_code: Option, + modified_at: PrimitiveDateTime, +} + +impl From for AddressUpdateInternal { + fn from(address_update: AddressUpdate) -> Self { + match address_update { + AddressUpdate::Update { + city, + country, + line1, + line2, + line3, + state, + zip, + first_name, + last_name, + phone_number, + country_code, + } => Self { + city, + country, + line1, + line2, + line3, + state, + zip, + first_name, + last_name, + phone_number, + country_code, + modified_at: convert_to_pdt(OffsetDateTime::now_utc()), + }, + } + } +} + +// TODO: Create utils for this since cane be reused outside address +fn convert_to_pdt(offset_time: OffsetDateTime) -> PrimitiveDateTime { + PrimitiveDateTime::new(offset_time.date(), offset_time.time()) +} + +impl Default for AddressNew { + fn default() -> Self { + Self { + address_id: generate_id(consts::ID_LENGTH, "add"), + city: None, + country: None, + line1: None, + line2: None, + line3: None, + state: None, + zip: None, + first_name: None, + last_name: None, + phone_number: None, + country_code: None, + customer_id: String::default(), + merchant_id: String::default(), + } + } +} diff --git a/crates/storage_models/src/configs.rs b/crates/storage_models/src/configs.rs new file mode 100644 index 0000000000..c5564b3be3 --- /dev/null +++ b/crates/storage_models/src/configs.rs @@ -0,0 +1,43 @@ +use std::convert::From; + +use diesel::{AsChangeset, Identifiable, Insertable, Queryable}; +use serde::{Deserialize, Serialize}; + +use crate::schema::configs; + +#[derive(Default, Clone, Debug, Insertable, Serialize, Deserialize)] +#[diesel(table_name = configs)] + +pub struct ConfigNew { + pub key: String, + pub config: String, +} + +#[derive(Default, Clone, Debug, Identifiable, Queryable, Deserialize, Serialize)] +#[diesel(table_name = configs)] + +pub struct Config { + #[serde(skip_serializing)] + pub id: i32, + pub key: String, + pub config: String, +} + +#[derive(Debug)] +pub enum ConfigUpdate { + Update { config: Option }, +} + +#[derive(Clone, Debug, AsChangeset, Default)] +#[diesel(table_name = configs)] +pub struct ConfigUpdateInternal { + config: Option, +} + +impl From for ConfigUpdateInternal { + fn from(config_update: ConfigUpdate) -> Self { + match config_update { + ConfigUpdate::Update { config } => Self { config }, + } + } +} diff --git a/crates/storage_models/src/connector_response.rs b/crates/storage_models/src/connector_response.rs new file mode 100644 index 0000000000..01d35d7b23 --- /dev/null +++ b/crates/storage_models/src/connector_response.rs @@ -0,0 +1,88 @@ +use diesel::{AsChangeset, Identifiable, Insertable, Queryable}; +use serde::{Deserialize, Serialize}; +use time::PrimitiveDateTime; + +use crate::schema::connector_response; + +#[derive(Clone, Debug, Deserialize, Serialize, Insertable, router_derive::DebugAsDisplay)] +#[diesel(table_name = connector_response)] +#[serde(deny_unknown_fields)] +pub struct ConnectorResponseNew { + pub payment_id: String, + pub merchant_id: String, + pub txn_id: String, + pub created_at: PrimitiveDateTime, + pub modified_at: PrimitiveDateTime, + pub connector_name: Option, + pub connector_transaction_id: Option, + pub authentication_data: Option, + pub encoded_data: Option, +} + +#[derive(Clone, Debug, Deserialize, Serialize, Identifiable, Queryable)] +#[diesel(table_name = connector_response)] +pub struct ConnectorResponse { + #[serde(skip_serializing)] + pub id: i32, + pub payment_id: String, + pub merchant_id: String, + pub txn_id: String, + pub created_at: PrimitiveDateTime, + pub modified_at: PrimitiveDateTime, + pub connector_name: Option, + pub connector_transaction_id: Option, + pub authentication_data: Option, + pub encoded_data: Option, +} + +#[derive(Clone, Debug, Deserialize, AsChangeset, Serialize)] +#[diesel(table_name = connector_response)] +pub struct ConnectorResponseUpdateInternal { + pub connector_transaction_id: Option, + pub authentication_data: Option, + pub modified_at: PrimitiveDateTime, + pub encoded_data: Option, + pub connector_name: Option, +} + +#[derive(Debug)] +pub enum ConnectorResponseUpdate { + ResponseUpdate { + connector_transaction_id: Option, + authentication_data: Option, + encoded_data: Option, + connector_name: Option, + }, +} + +impl ConnectorResponseUpdate { + pub fn apply_changeset(self, source: ConnectorResponse) -> ConnectorResponse { + let connector_response_update: ConnectorResponseUpdateInternal = self.into(); + ConnectorResponse { + modified_at: connector_response_update.modified_at, + connector_transaction_id: connector_response_update.connector_transaction_id, + authentication_data: connector_response_update.authentication_data, + encoded_data: connector_response_update.encoded_data, + ..source + } + } +} + +impl From for ConnectorResponseUpdateInternal { + fn from(connector_response_update: ConnectorResponseUpdate) -> Self { + match connector_response_update { + ConnectorResponseUpdate::ResponseUpdate { + connector_transaction_id, + authentication_data, + encoded_data, + connector_name, + } => Self { + connector_transaction_id, + authentication_data, + encoded_data, + modified_at: common_utils::date_time::now(), + connector_name, + }, + } + } +} diff --git a/crates/storage_models/src/customers.rs b/crates/storage_models/src/customers.rs new file mode 100644 index 0000000000..4ae3c16213 --- /dev/null +++ b/crates/storage_models/src/customers.rs @@ -0,0 +1,79 @@ +use common_utils::pii; +use diesel::{AsChangeset, Identifiable, Insertable, Queryable}; +use masking::Secret; +use time::PrimitiveDateTime; + +use crate::schema::customers; + +#[derive(Default, Clone, Debug, Insertable, router_derive::DebugAsDisplay)] +#[diesel(table_name = customers)] +pub struct CustomerNew { + pub customer_id: String, + pub merchant_id: String, + pub name: Option, + pub email: Option>, + pub phone: Option>, + pub description: Option, + pub phone_country_code: Option, + pub metadata: Option, +} + +#[derive(Clone, Debug, Identifiable, Queryable)] +#[diesel(table_name = customers)] +pub struct Customer { + pub id: i32, + pub customer_id: String, + pub merchant_id: String, + pub name: Option, + pub email: Option>, + pub phone: Option>, + pub phone_country_code: Option, + pub description: Option, + pub created_at: PrimitiveDateTime, + pub metadata: Option, +} + +#[derive(Debug)] +pub enum CustomerUpdate { + Update { + name: Option, + email: Option>, + phone: Option>, + description: Option, + phone_country_code: Option, + metadata: Option, + }, +} + +#[derive(Clone, Debug, Default, AsChangeset, router_derive::DebugAsDisplay)] +#[diesel(table_name = customers)] +pub struct CustomerUpdateInternal { + name: Option, + email: Option>, + phone: Option>, + description: Option, + phone_country_code: Option, + metadata: Option, +} + +impl From for CustomerUpdateInternal { + fn from(customer_update: CustomerUpdate) -> Self { + match customer_update { + CustomerUpdate::Update { + name, + email, + phone, + description, + phone_country_code, + metadata, + } => Self { + name, + email, + phone, + description, + phone_country_code, + metadata, + }, + } + } +} diff --git a/crates/storage_models/src/dispute.rs b/crates/storage_models/src/dispute.rs new file mode 100644 index 0000000000..8b13789179 --- /dev/null +++ b/crates/storage_models/src/dispute.rs @@ -0,0 +1 @@ + diff --git a/crates/storage_models/src/enums.rs b/crates/storage_models/src/enums.rs new file mode 100644 index 0000000000..a44577fe06 --- /dev/null +++ b/crates/storage_models/src/enums.rs @@ -0,0 +1,657 @@ +#[doc(hidden)] +pub mod diesel_exports { + pub use super::{ + DbAttemptStatus as AttemptStatus, DbAuthenticationType as AuthenticationType, + DbCaptureMethod as CaptureMethod, DbConnectorType as ConnectorType, DbCurrency as Currency, + DbEventClass as EventClass, DbEventObjectType as EventObjectType, DbEventType as EventType, + DbFutureUsage as FutureUsage, DbIntentStatus as IntentStatus, + DbMandateStatus as MandateStatus, DbMandateType as MandateType, + DbMerchantStorageScheme as MerchantStorageScheme, DbPaymentFlow as PaymentFlow, + DbPaymentMethodIssuerCode as PaymentMethodIssuerCode, + DbPaymentMethodSubType as PaymentMethodSubType, DbPaymentMethodType as PaymentMethodType, + DbProcessTrackerStatus as ProcessTrackerStatus, DbRefundStatus as RefundStatus, + DbRefundType as RefundType, DbRoutingAlgorithm as RoutingAlgorithm, + }; +} + +#[derive( + Clone, + Copy, + Debug, + Default, + Eq, + PartialEq, + serde::Deserialize, + serde::Serialize, + strum::Display, + strum::EnumString, + router_derive::DieselEnum, +)] +#[router_derive::diesel_enum] +#[serde(rename_all = "snake_case")] +#[strum(serialize_all = "snake_case")] +pub enum AttemptStatus { + Started, + AuthenticationFailed, + JuspayDeclined, + PendingVbv, + VbvSuccessful, + Authorized, + AuthorizationFailed, + Charged, + Authorizing, + CodInitiated, + Voided, + VoidInitiated, + CaptureInitiated, + CaptureFailed, + VoidFailed, + AutoRefunded, + PartialCharged, + #[default] + Pending, + Failure, + PaymentMethodAwaited, + ConfirmationAwaited, +} + +#[derive( + Clone, + Copy, + Debug, + Default, + Eq, + PartialEq, + serde::Deserialize, + serde::Serialize, + strum::Display, + strum::EnumString, + router_derive::DieselEnum, +)] +#[router_derive::diesel_enum] +#[serde(rename_all = "snake_case")] +#[strum(serialize_all = "snake_case")] +pub enum AuthenticationType { + #[default] + ThreeDs, + NoThreeDs, +} + +#[derive( + Clone, + Copy, + Debug, + Default, + Eq, + PartialEq, + serde::Deserialize, + serde::Serialize, + strum::Display, + strum::EnumString, + router_derive::DieselEnum, +)] +#[router_derive::diesel_enum] +#[serde(rename_all = "snake_case")] +#[strum(serialize_all = "snake_case")] +pub enum CaptureMethod { + #[default] + Automatic, + Manual, + ManualMultiple, + Scheduled, +} + +#[derive( + Clone, + Copy, + Debug, + Eq, + PartialEq, + strum::Display, + strum::EnumString, + serde::Deserialize, + serde::Serialize, + router_derive::DieselEnum, +)] +#[router_derive::diesel_enum] +#[strum(serialize_all = "snake_case")] +#[serde(rename_all = "snake_case")] +pub enum ConnectorType { + /// PayFacs, Acquirers, Gateways, BNPL etc + PaymentProcessor, + /// Fraud, Currency Conversion, Crypto etc + PaymentVas, + /// Accounting, Billing, Invoicing, Tax etc + FinOperations, + /// Inventory, ERP, CRM, KYC etc + FizOperations, + /// Payment Networks like Visa, MasterCard etc + Networks, + /// All types of banks including corporate / commercial / personal / neo banks + BankingEntities, + /// All types of non-banking financial institutions including Insurance, Credit / Lending etc + NonBankingFinance, +} + +#[allow(clippy::upper_case_acronyms)] +#[derive( + Clone, + Copy, + Debug, + Default, + Eq, + Hash, + PartialEq, + serde::Deserialize, + serde::Serialize, + strum::Display, + strum::EnumString, + router_derive::DieselEnum, +)] +#[router_derive::diesel_enum] +pub enum Currency { + AED, + ALL, + AMD, + ARS, + AUD, + AWG, + AZN, + BBD, + BDT, + BHD, + BMD, + BND, + BOB, + BRL, + BSD, + BWP, + BZD, + CAD, + CHF, + CNY, + COP, + CRC, + CUP, + CZK, + DKK, + DOP, + DZD, + EGP, + ETB, + EUR, + FJD, + GBP, + GHS, + GIP, + GMD, + GTQ, + GYD, + HKD, + HNL, + HRK, + HTG, + HUF, + IDR, + ILS, + INR, + JMD, + JOD, + JPY, + KES, + KGS, + KHR, + KRW, + KWD, + KYD, + KZT, + LAK, + LBP, + LKR, + LRD, + LSL, + MAD, + MDL, + MKD, + MMK, + MNT, + MOP, + MUR, + MVR, + MWK, + MXN, + MYR, + NAD, + NGN, + NIO, + NOK, + NPR, + NZD, + OMR, + PEN, + PGK, + PHP, + PKR, + PLN, + QAR, + RUB, + SAR, + SCR, + SEK, + SGD, + SLL, + SOS, + SSP, + SVC, + SZL, + THB, + TTD, + TWD, + TZS, + #[default] + USD, + UYU, + UZS, + YER, + ZAR, +} + +#[derive( + Clone, + Copy, + Debug, + Eq, + PartialEq, + serde::Deserialize, + serde::Serialize, + strum::Display, + strum::EnumString, + router_derive::DieselEnum, +)] +#[router_derive::diesel_enum] +#[serde(rename_all = "snake_case")] +#[strum(serialize_all = "snake_case")] +pub enum EventClass { + Payments, +} + +#[derive( + Clone, + Copy, + Debug, + Eq, + PartialEq, + serde::Deserialize, + serde::Serialize, + strum::Display, + strum::EnumString, + router_derive::DieselEnum, +)] +#[router_derive::diesel_enum] +#[serde(rename_all = "snake_case")] +#[strum(serialize_all = "snake_case")] +pub enum EventObjectType { + PaymentDetails, +} + +#[derive( + Clone, + Copy, + Debug, + Eq, + PartialEq, + serde::Deserialize, + serde::Serialize, + strum::Display, + strum::EnumString, + router_derive::DieselEnum, +)] +#[router_derive::diesel_enum] +#[serde(rename_all = "snake_case")] +#[strum(serialize_all = "snake_case")] +pub enum EventType { + PaymentSucceeded, +} + +#[derive( + Clone, + Copy, + Debug, + Default, + Eq, + PartialEq, + serde::Deserialize, + serde::Serialize, + strum::Display, + strum::EnumString, + router_derive::DieselEnum, +)] +#[router_derive::diesel_enum] +#[serde(rename_all = "snake_case")] +#[strum(serialize_all = "snake_case")] +pub enum IntentStatus { + Succeeded, + Failed, + Cancelled, + Processing, + RequiresCustomerAction, + RequiresPaymentMethod, + #[default] + RequiresConfirmation, + RequiresCapture, +} + +#[derive( + Clone, + Copy, + Debug, + Default, + Eq, + PartialEq, + serde::Deserialize, + serde::Serialize, + strum::Display, + strum::EnumString, + router_derive::DieselEnum, +)] +#[router_derive::diesel_enum] +#[serde(rename_all = "snake_case")] +#[strum(serialize_all = "snake_case")] +pub enum FutureUsage { + #[default] + OffSession, + OnSession, +} + +#[derive( + Clone, + Copy, + Debug, + Default, + Eq, + PartialEq, + serde::Deserialize, + serde::Serialize, + strum::Display, + strum::EnumString, + router_derive::DieselEnum, +)] +#[router_derive::diesel_enum] +#[serde(rename_all = "snake_case")] +#[strum(serialize_all = "snake_case")] +pub enum MerchantStorageScheme { + #[default] + PostgresOnly, + RedisKv, +} + +#[derive( + Clone, + Copy, + Debug, + Eq, + PartialEq, + strum::Display, + strum::EnumString, + serde::Serialize, + serde::Deserialize, + router_derive::DieselEnum, +)] +#[router_derive::diesel_enum] +#[strum(serialize_all = "snake_case")] +pub enum PaymentFlow { + Vsc, + Emi, + Otp, + UpiIntent, + UpiCollect, + UpiScanAndPay, + Sdk, +} + +#[derive( + Clone, + Copy, + Debug, + Eq, + Hash, + PartialEq, + serde::Deserialize, + serde::Serialize, + strum::Display, + strum::EnumString, + router_derive::DieselEnum, +)] +#[router_derive::diesel_enum] +#[strum(serialize_all = "snake_case")] +#[serde(rename_all = "snake_case")] +pub enum PaymentMethodIssuerCode { + JpHdfc, + JpIcici, + JpGooglepay, + JpApplepay, + JpPhonepay, + JpWechat, + JpSofort, + JpGiropay, + JpSepa, + JpBacs, +} + +#[derive( + Clone, + Copy, + Debug, + Eq, + Hash, + PartialEq, + serde::Deserialize, + serde::Serialize, + strum::Display, + strum::EnumString, + router_derive::DieselEnum, +)] +#[router_derive::diesel_enum] +#[serde(rename_all = "snake_case")] +#[strum(serialize_all = "snake_case")] +pub enum PaymentMethodSubType { + Credit, + Debit, + UpiIntent, + UpiCollect, + CreditCardInstallments, + PayLaterInstallments, +} + +#[derive( + Clone, + Copy, + Debug, + Default, + Eq, + Hash, + PartialEq, + serde::Deserialize, + serde::Serialize, + strum::Display, + strum::EnumString, + router_derive::DieselEnum, +)] +#[router_derive::diesel_enum] +#[serde(rename_all = "snake_case")] +#[strum(serialize_all = "snake_case")] +pub enum PaymentMethodType { + Card, + PaymentContainer, + #[default] + BankTransfer, + BankDebit, + PayLater, + Netbanking, + Upi, + OpenBanking, + ConsumerFinance, + Wallet, + Klarna, + Paypal, +} + +#[derive( + Clone, + Copy, + Debug, + Eq, + Hash, + PartialEq, + serde::Deserialize, + serde::Serialize, + strum::Display, + strum::EnumString, + router_derive::DieselEnum, +)] +#[router_derive::diesel_enum] +#[serde(rename_all = "lowercase")] +#[strum(serialize_all = "lowercase")] +pub enum WalletIssuer { + GooglePay, + ApplePay, +} + +#[derive( + Clone, + Copy, + Debug, + Eq, + PartialEq, + serde::Deserialize, + serde::Serialize, + strum::Display, + strum::EnumString, + router_derive::DieselEnum, +)] +#[router_derive::diesel_enum] +#[serde(rename_all = "snake_case")] +#[strum(serialize_all = "snake_case")] +pub enum ProcessTrackerStatus { + // Picked by the producer + Processing, + // State when the task is added + New, + // Send to retry + Pending, + // Picked by consumer + ProcessStarted, + // Finished by consumer + Finish, +} + +#[derive( + Clone, + Copy, + Debug, + Default, + Eq, + PartialEq, + strum::Display, + strum::EnumString, + router_derive::DieselEnum, +)] +#[router_derive::diesel_enum] +#[strum(serialize_all = "snake_case")] +pub enum RefundStatus { + Failure, + ManualReview, + #[default] + Pending, + Success, + TransactionFailure, +} + +#[derive( + Clone, + Copy, + Debug, + Default, + Eq, + PartialEq, + strum::Display, + strum::EnumString, + router_derive::DieselEnum, +)] +#[router_derive::diesel_enum] +#[strum(serialize_all = "snake_case")] +pub enum RefundType { + InstantRefund, + #[default] + RegularRefund, + RetryRefund, +} + +#[derive( + Clone, + Copy, + Debug, + Eq, + PartialEq, + serde::Deserialize, + serde::Serialize, + strum::Display, + strum::EnumString, + router_derive::DieselEnum, +)] +#[serde(rename_all = "snake_case")] +#[strum(serialize_all = "snake_case")] +#[router_derive::diesel_enum] +pub enum RoutingAlgorithm { + RoundRobin, + MaxConversion, + MinCost, + Custom, +} + +// Mandate +#[derive( + Clone, + Copy, + Debug, + Eq, + PartialEq, + Default, + serde::Deserialize, + serde::Serialize, + strum::Display, + strum::EnumString, + router_derive::DieselEnum, +)] +#[router_derive::diesel_enum] +#[serde(rename_all = "snake_case")] +#[strum(serialize_all = "snake_case")] +pub enum MandateType { + SingleUse, + #[default] + MultiUse, +} + +#[derive( + Clone, + Copy, + Debug, + Eq, + PartialEq, + Default, + serde::Deserialize, + serde::Serialize, + strum::Display, + strum::EnumString, + router_derive::DieselEnum, +)] +#[router_derive::diesel_enum] +#[serde(rename_all = "snake_case")] +#[strum(serialize_all = "snake_case")] +pub enum MandateStatus { + #[default] + Active, + Inactive, + Pending, + Revoked, +} diff --git a/crates/storage_models/src/ephemeral_key.rs b/crates/storage_models/src/ephemeral_key.rs new file mode 100644 index 0000000000..44226d50fd --- /dev/null +++ b/crates/storage_models/src/ephemeral_key.rs @@ -0,0 +1,16 @@ +pub struct EphemeralKeyNew { + pub id: String, + pub merchant_id: String, + pub customer_id: String, + pub secret: String, +} + +#[derive(Debug, serde::Serialize, serde::Deserialize)] +pub struct EphemeralKey { + pub id: String, + pub merchant_id: String, + pub customer_id: String, + pub created_at: i64, + pub expires: i64, + pub secret: String, +} diff --git a/crates/storage_models/src/errors.rs b/crates/storage_models/src/errors.rs new file mode 100644 index 0000000000..ded9155f3f --- /dev/null +++ b/crates/storage_models/src/errors.rs @@ -0,0 +1,16 @@ +#[derive(Debug, thiserror::Error)] +pub enum DatabaseError { + #[error("An error occurred when obtaining database connection")] + DatabaseConnectionError, + #[error("The requested resource was not found in the database")] + NotFound, + #[error("A unique constraint violation occurred")] + UniqueViolation, + #[error("No fields were provided to be updated")] + NoFieldsToUpdate, + #[error("An error occurred when generating raw SQL query")] + QueryGenerationFailed, + // InsertFailed, + #[error("An unknown error occurred")] + Others, +} diff --git a/crates/storage_models/src/events.rs b/crates/storage_models/src/events.rs new file mode 100644 index 0000000000..6b1306bfa2 --- /dev/null +++ b/crates/storage_models/src/events.rs @@ -0,0 +1,35 @@ +use common_utils::custom_serde; +use diesel::{Identifiable, Insertable, Queryable}; +use serde::{Deserialize, Serialize}; +use time::PrimitiveDateTime; + +use crate::{enums as storage_enums, schema::events}; + +#[derive(Clone, Debug, Deserialize, Insertable, Serialize, router_derive::DebugAsDisplay)] +#[diesel(table_name = events)] +#[serde(deny_unknown_fields)] +pub struct EventNew { + pub event_id: String, + pub event_type: storage_enums::EventType, + pub event_class: storage_enums::EventClass, + pub is_webhook_notified: bool, + pub intent_reference_id: Option, + pub primary_object_id: String, + pub primary_object_type: storage_enums::EventObjectType, +} + +#[derive(Clone, Debug, Deserialize, Serialize, Identifiable, Queryable)] +#[diesel(table_name = events)] +pub struct Event { + #[serde(skip_serializing)] + pub id: i32, + pub event_id: String, + pub event_type: storage_enums::EventType, + pub event_class: storage_enums::EventClass, + pub is_webhook_notified: bool, + pub intent_reference_id: Option, + pub primary_object_id: String, + pub primary_object_type: storage_enums::EventObjectType, + #[serde(with = "custom_serde::iso8601")] + pub created_at: PrimitiveDateTime, +} diff --git a/crates/storage_models/src/lib.rs b/crates/storage_models/src/lib.rs index 8b13789179..37c637fccc 100644 --- a/crates/storage_models/src/lib.rs +++ b/crates/storage_models/src/lib.rs @@ -1 +1,87 @@ +pub mod address; +pub mod configs; +pub mod connector_response; +pub mod customers; +pub mod dispute; +pub mod enums; +pub mod ephemeral_key; +pub mod errors; +pub mod events; +pub mod locker_mock_up; +pub mod mandate; +pub mod merchant_account; +pub mod merchant_connector_account; +pub mod payment_attempt; +pub mod payment_intent; +pub mod payment_method; +pub mod process_tracker; +pub mod query; +pub mod refund; +pub mod schema; +pub mod temp_card; +use diesel_impl::{DieselArray, OptionalDieselArray}; + +pub type CustomResult = error_stack::Result; +pub type PgPooledConn = async_bb8_diesel::Connection; + +/// The types and implementations provided by this module are required for the schema generated by +/// `diesel_cli` 2.0 to work with the types defined in Rust code. This is because +/// [`diesel`][diesel] 2.0 [changed the nullability of array elements][diesel-2.0-array-nullability], +/// which causes [`diesel`][diesel] to deserialize arrays as `Vec>`. To prevent declaring +/// array elements as `Option`, this module provides types and implementations to deserialize +/// arrays as `Vec`, considering only non-null values (`Some(T)`) among the deserialized +/// `Option` values. +/// +/// [diesel-2.0-array-nullability]: https://diesel.rs/guides/migration_guide.html#2-0-0-nullability-of-array-elements + +#[doc(hidden)] +pub(crate) mod diesel_impl { + use diesel::{ + deserialize::FromSql, + pg::Pg, + sql_types::{Array, Nullable}, + Queryable, + }; + + pub struct DieselArray(Vec>); + + impl From> for Vec { + fn from(array: DieselArray) -> Self { + array.0.into_iter().flatten().collect() + } + } + + impl Queryable>, Pg> for DieselArray + where + T: FromSql, + Vec>: FromSql>, Pg>, + { + type Row = Vec>; + + fn build(row: Self::Row) -> diesel::deserialize::Result { + Ok(DieselArray(row)) + } + } + + pub struct OptionalDieselArray(Option>>); + + impl From> for Option> { + fn from(option_array: OptionalDieselArray) -> Self { + option_array + .0 + .map(|array| array.into_iter().flatten().collect()) + } + } + + impl Queryable>>, Pg> for OptionalDieselArray + where + Option>>: FromSql>>, Pg>, + { + type Row = Option>>; + + fn build(row: Self::Row) -> diesel::deserialize::Result { + Ok(OptionalDieselArray(row)) + } + } +} diff --git a/crates/storage_models/src/locker_mock_up.rs b/crates/storage_models/src/locker_mock_up.rs new file mode 100644 index 0000000000..5df7c60b68 --- /dev/null +++ b/crates/storage_models/src/locker_mock_up.rs @@ -0,0 +1,34 @@ +use diesel::{Identifiable, Insertable, Queryable}; + +use crate::schema::locker_mock_up; + +#[derive(Clone, Debug, Eq, Identifiable, Queryable, PartialEq)] +#[diesel(table_name = locker_mock_up)] +pub struct LockerMockUp { + pub id: i32, + pub card_id: String, + pub external_id: String, + pub card_fingerprint: String, + pub card_global_fingerprint: String, + pub merchant_id: String, + pub card_number: String, + pub card_exp_year: String, + pub card_exp_month: String, + pub name_on_card: Option, + pub nickname: Option, + pub customer_id: Option, + pub duplicate: Option, +} + +#[derive(Clone, Debug, Default, Insertable, router_derive::DebugAsDisplay)] +#[diesel(table_name = locker_mock_up)] +pub struct LockerMockUpNew { + pub card_id: String, + pub external_id: String, + pub card_fingerprint: String, + pub card_global_fingerprint: String, + pub merchant_id: String, + pub card_number: String, + pub card_exp_year: String, + pub card_exp_month: String, +} diff --git a/crates/storage_models/src/mandate.rs b/crates/storage_models/src/mandate.rs new file mode 100644 index 0000000000..62f6101184 --- /dev/null +++ b/crates/storage_models/src/mandate.rs @@ -0,0 +1,103 @@ +use common_utils::pii; +use diesel::{AsChangeset, Identifiable, Insertable, Queryable}; +use masking::Secret; +use time::PrimitiveDateTime; + +use crate::{enums as storage_enums, schema::mandate}; + +#[derive(Clone, Debug, Identifiable, Queryable)] +#[diesel(table_name = mandate)] +pub struct Mandate { + pub id: i32, + pub mandate_id: String, + pub customer_id: String, + pub merchant_id: String, + pub payment_method_id: String, + pub mandate_status: storage_enums::MandateStatus, + pub mandate_type: storage_enums::MandateType, + pub customer_accepted_at: Option, + pub customer_ip_address: Option>, + pub customer_user_agent: Option, + pub network_transaction_id: Option, + pub previous_transaction_id: Option, + pub created_at: PrimitiveDateTime, + pub mandate_amount: Option, + pub mandate_currency: Option, + pub amount_captured: Option, + pub connector: String, + pub connector_mandate_id: Option, +} + +#[derive( + router_derive::Setter, Clone, Debug, Default, Insertable, router_derive::DebugAsDisplay, +)] +#[diesel(table_name = mandate)] +pub struct MandateNew { + pub mandate_id: String, + pub customer_id: String, + pub merchant_id: String, + pub payment_method_id: String, + pub mandate_status: storage_enums::MandateStatus, + pub mandate_type: storage_enums::MandateType, + pub customer_accepted_at: Option, + pub customer_ip_address: Option>, + pub customer_user_agent: Option, + pub network_transaction_id: Option, + pub previous_transaction_id: Option, + pub created_at: Option, + pub mandate_amount: Option, + pub mandate_currency: Option, + pub amount_captured: Option, + pub connector: String, + pub connector_mandate_id: Option, +} + +#[derive(Debug)] +pub enum MandateUpdate { + StatusUpdate { + mandate_status: storage_enums::MandateStatus, + }, + CaptureAmountUpdate { + amount_captured: Option, + }, + ConnectorReferenceUpdate { + connector_mandate_id: Option, + }, +} + +#[derive(Clone, Eq, PartialEq, Copy, Debug, Default, serde::Serialize, serde::Deserialize)] +pub struct SingleUseMandate { + pub amount: i32, + pub currency: storage_enums::Currency, +} + +#[derive(Clone, Debug, Default, AsChangeset, router_derive::DebugAsDisplay)] +#[diesel(table_name = mandate)] +pub struct MandateUpdateInternal { + mandate_status: Option, + amount_captured: Option, + connector_mandate_id: Option, +} + +impl From for MandateUpdateInternal { + fn from(mandate_update: MandateUpdate) -> Self { + match mandate_update { + MandateUpdate::StatusUpdate { mandate_status } => Self { + mandate_status: Some(mandate_status), + connector_mandate_id: None, + amount_captured: None, + }, + MandateUpdate::CaptureAmountUpdate { amount_captured } => Self { + mandate_status: None, + amount_captured, + connector_mandate_id: None, + }, + MandateUpdate::ConnectorReferenceUpdate { + connector_mandate_id, + } => Self { + connector_mandate_id, + ..Default::default() + }, + } + } +} diff --git a/crates/storage_models/src/merchant_account.rs b/crates/storage_models/src/merchant_account.rs new file mode 100644 index 0000000000..3f72800dcf --- /dev/null +++ b/crates/storage_models/src/merchant_account.rs @@ -0,0 +1,121 @@ +use diesel::{AsChangeset, Identifiable, Insertable, Queryable}; +use masking::StrongSecret; + +use crate::{enums as storage_enums, schema::merchant_account}; + +#[derive(Clone, Debug, Eq, PartialEq, Identifiable, Queryable, router_derive::DebugAsDisplay)] +#[diesel(table_name = merchant_account)] +pub struct MerchantAccount { + pub id: i32, + pub merchant_id: String, + pub api_key: Option>, + pub return_url: Option, + pub enable_payment_response_hash: bool, + pub payment_response_hash_key: Option, + pub redirect_to_merchant_with_http_post: bool, + pub merchant_name: Option, + pub merchant_details: Option, + pub webhook_details: Option, + pub routing_algorithm: Option, + pub custom_routing_rules: Option, + pub sub_merchants_enabled: Option, + pub parent_merchant_id: Option, + pub publishable_key: Option, + pub storage_scheme: storage_enums::MerchantStorageScheme, +} + +#[derive(Clone, Debug, Default, Insertable, router_derive::DebugAsDisplay)] +#[diesel(table_name = merchant_account)] +pub struct MerchantAccountNew { + pub merchant_id: String, + pub merchant_name: Option, + pub api_key: Option>, + pub merchant_details: Option, + pub return_url: Option, + pub webhook_details: Option, + pub routing_algorithm: Option, + pub custom_routing_rules: Option, + pub sub_merchants_enabled: Option, + pub parent_merchant_id: Option, + pub enable_payment_response_hash: Option, + pub payment_response_hash_key: Option, + pub redirect_to_merchant_with_http_post: Option, + pub publishable_key: Option, +} + +#[derive(Debug)] +pub enum MerchantAccountUpdate { + Update { + merchant_id: String, + merchant_name: Option, + api_key: Option>, + merchant_details: Option, + return_url: Option, + webhook_details: Option, + routing_algorithm: Option, + custom_routing_rules: Option, + sub_merchants_enabled: Option, + parent_merchant_id: Option, + enable_payment_response_hash: Option, + payment_response_hash_key: Option, + redirect_to_merchant_with_http_post: Option, + publishable_key: Option, + }, +} + +#[derive(Clone, Debug, Default, AsChangeset, router_derive::DebugAsDisplay)] +#[diesel(table_name = merchant_account)] +pub struct MerchantAccountUpdateInternal { + merchant_id: Option, + merchant_name: Option, + api_key: Option>, + merchant_details: Option, + return_url: Option, + webhook_details: Option, + routing_algorithm: Option, + custom_routing_rules: Option, + sub_merchants_enabled: Option, + parent_merchant_id: Option, + enable_payment_response_hash: Option, + payment_response_hash_key: Option, + redirect_to_merchant_with_http_post: Option, + publishable_key: Option, +} + +impl From for MerchantAccountUpdateInternal { + fn from(merchant_account_update: MerchantAccountUpdate) -> Self { + match merchant_account_update { + MerchantAccountUpdate::Update { + merchant_id, + merchant_name, + api_key, + merchant_details, + return_url, + webhook_details, + routing_algorithm, + custom_routing_rules, + sub_merchants_enabled, + parent_merchant_id, + enable_payment_response_hash, + payment_response_hash_key, + redirect_to_merchant_with_http_post, + publishable_key, + } => Self { + merchant_id: Some(merchant_id), + merchant_name, + api_key, + merchant_details, + return_url, + webhook_details, + routing_algorithm, + custom_routing_rules, + sub_merchants_enabled, + parent_merchant_id, + enable_payment_response_hash, + payment_response_hash_key, + redirect_to_merchant_with_http_post, + publishable_key, + }, + } + } +} diff --git a/crates/storage_models/src/merchant_connector_account.rs b/crates/storage_models/src/merchant_connector_account.rs new file mode 100644 index 0000000000..963e44749e --- /dev/null +++ b/crates/storage_models/src/merchant_connector_account.rs @@ -0,0 +1,84 @@ +use diesel::{AsChangeset, Identifiable, Insertable, Queryable}; +use masking::Secret; + +use crate::{enums as storage_enums, schema::merchant_connector_account}; + +#[derive(Clone, Debug, Eq, PartialEq, Identifiable, Queryable, router_derive::DebugAsDisplay)] +#[diesel(table_name = merchant_connector_account)] +pub struct MerchantConnectorAccount { + pub id: i32, + pub merchant_id: String, + pub connector_name: String, + pub connector_account_details: serde_json::Value, + pub test_mode: Option, + pub disabled: Option, + pub merchant_connector_id: i32, + #[diesel(deserialize_as = super::OptionalDieselArray)] + pub payment_methods_enabled: Option>, + pub connector_type: storage_enums::ConnectorType, +} + +#[derive(Clone, Debug, Default, Insertable, router_derive::DebugAsDisplay)] +#[diesel(table_name = merchant_connector_account)] +pub struct MerchantConnectorAccountNew { + pub merchant_id: Option, + pub connector_type: Option, + pub connector_name: Option, + pub connector_account_details: Option>, + pub test_mode: Option, + pub disabled: Option, + pub merchant_connector_id: Option, + pub payment_methods_enabled: Option>, +} + +#[derive(Debug)] +pub enum MerchantConnectorAccountUpdate { + Update { + merchant_id: Option, + connector_type: Option, + connector_name: Option, + connector_account_details: Option>, + test_mode: Option, + disabled: Option, + merchant_connector_id: Option, + payment_methods_enabled: Option>, + }, +} +#[derive(Clone, Debug, Default, AsChangeset, router_derive::DebugAsDisplay)] +#[diesel(table_name = merchant_connector_account)] +pub struct MerchantConnectorAccountUpdateInternal { + merchant_id: Option, + connector_type: Option, + connector_name: Option, + connector_account_details: Option>, + test_mode: Option, + disabled: Option, + merchant_connector_id: Option, + payment_methods_enabled: Option>, +} + +impl From for MerchantConnectorAccountUpdateInternal { + fn from(merchant_connector_account_update: MerchantConnectorAccountUpdate) -> Self { + match merchant_connector_account_update { + MerchantConnectorAccountUpdate::Update { + merchant_id, + connector_type, + connector_name, + connector_account_details, + test_mode, + disabled, + merchant_connector_id, + payment_methods_enabled, + } => Self { + merchant_id, + connector_type, + connector_name, + connector_account_details, + test_mode, + disabled, + merchant_connector_id, + payment_methods_enabled, + }, + } + } +} diff --git a/crates/storage_models/src/payment_attempt.rs b/crates/storage_models/src/payment_attempt.rs new file mode 100644 index 0000000000..a779d7a10e --- /dev/null +++ b/crates/storage_models/src/payment_attempt.rs @@ -0,0 +1,236 @@ +use diesel::{AsChangeset, Identifiable, Insertable, Queryable}; +use serde::{Deserialize, Serialize}; +use time::PrimitiveDateTime; + +use crate::{enums as storage_enums, schema::payment_attempt}; + +#[derive(Clone, Debug, Eq, PartialEq, Identifiable, Queryable, Serialize, Deserialize)] +#[diesel(table_name = payment_attempt)] +pub struct PaymentAttempt { + pub id: i32, + pub payment_id: String, + pub merchant_id: String, + pub txn_id: String, + pub status: storage_enums::AttemptStatus, + pub amount: i32, + pub currency: Option, + pub save_to_locker: Option, + pub connector: Option, + pub error_message: Option, + pub offer_amount: Option, + pub surcharge_amount: Option, + pub tax_amount: Option, + pub payment_method_id: Option, + pub payment_method: Option, + pub payment_flow: Option, + pub redirect: Option, + pub connector_transaction_id: Option, + pub capture_method: Option, + pub capture_on: Option, + pub confirm: bool, + pub authentication_type: Option, + pub created_at: PrimitiveDateTime, + pub modified_at: PrimitiveDateTime, + pub last_synced: Option, + pub cancellation_reason: Option, + pub amount_to_capture: Option, + pub mandate_id: Option, + pub browser_info: Option, +} + +#[derive(Clone, Debug, Default, Insertable, router_derive::DebugAsDisplay)] +#[diesel(table_name = payment_attempt)] +pub struct PaymentAttemptNew { + pub payment_id: String, + pub merchant_id: String, + pub txn_id: String, + pub status: storage_enums::AttemptStatus, + pub amount: i32, + pub currency: Option, + // pub auto_capture: Option, + pub save_to_locker: Option, + pub connector: Option, + pub error_message: Option, + pub offer_amount: Option, + pub surcharge_amount: Option, + pub tax_amount: Option, + pub payment_method_id: Option, + pub payment_method: Option, + pub payment_flow: Option, + pub redirect: Option, + pub connector_transaction_id: Option, + pub capture_method: Option, + pub capture_on: Option, + pub confirm: bool, + pub authentication_type: Option, + pub created_at: Option, + pub modified_at: Option, + pub last_synced: Option, + pub cancellation_reason: Option, + pub amount_to_capture: Option, + pub mandate_id: Option, + pub browser_info: Option, +} + +#[derive(Debug, Clone)] +pub enum PaymentAttemptUpdate { + Update { + amount: i32, + currency: storage_enums::Currency, + status: storage_enums::AttemptStatus, + authentication_type: Option, + payment_method: Option, + }, + AuthenticationTypeUpdate { + authentication_type: storage_enums::AuthenticationType, + }, + ConfirmUpdate { + status: storage_enums::AttemptStatus, + payment_method: Option, + browser_info: Option, + connector: Option, + }, + VoidUpdate { + status: storage_enums::AttemptStatus, + cancellation_reason: Option, + }, + ResponseUpdate { + status: storage_enums::AttemptStatus, + connector_transaction_id: Option, + authentication_type: Option, + payment_method_id: Option>, + redirect: Option, + mandate_id: Option, + }, + StatusUpdate { + status: storage_enums::AttemptStatus, + }, + ErrorUpdate { + status: storage_enums::AttemptStatus, + error_message: Option, + }, +} + +#[derive(Clone, Debug, Default, AsChangeset, router_derive::DebugAsDisplay)] +#[diesel(table_name = payment_attempt)] +pub struct PaymentAttemptUpdateInternal { + amount: Option, + currency: Option, + status: Option, + connector_transaction_id: Option, + connector: Option, + authentication_type: Option, + payment_method: Option, + error_message: Option, + payment_method_id: Option>, + cancellation_reason: Option, + modified_at: Option, + redirect: Option, + mandate_id: Option, + browser_info: Option, +} + +impl PaymentAttemptUpdate { + pub fn apply_changeset(self, source: PaymentAttempt) -> PaymentAttempt { + let pa_update: PaymentAttemptUpdateInternal = self.into(); + PaymentAttempt { + amount: pa_update.amount.unwrap_or(source.amount), + currency: pa_update.currency.or(source.currency), + status: pa_update.status.unwrap_or(source.status), + connector_transaction_id: pa_update + .connector_transaction_id + .or(source.connector_transaction_id), + authentication_type: pa_update.authentication_type.or(source.authentication_type), + payment_method: pa_update.payment_method.or(source.payment_method), + error_message: pa_update.error_message.or(source.error_message), + payment_method_id: pa_update + .payment_method_id + .unwrap_or(source.payment_method_id), + browser_info: pa_update.browser_info, + modified_at: common_utils::date_time::now(), + ..source + } + } +} + +impl From for PaymentAttemptUpdateInternal { + fn from(payment_attempt_update: PaymentAttemptUpdate) -> Self { + match payment_attempt_update { + PaymentAttemptUpdate::Update { + amount, + currency, + status, + // connector_transaction_id, + authentication_type, + payment_method, + } => Self { + amount: Some(amount), + currency: Some(currency), + status: Some(status), + // connector_transaction_id, + authentication_type, + payment_method, + modified_at: Some(common_utils::date_time::now()), + ..Default::default() + }, + PaymentAttemptUpdate::AuthenticationTypeUpdate { + authentication_type, + } => Self { + authentication_type: Some(authentication_type), + modified_at: Some(common_utils::date_time::now()), + ..Default::default() + }, + PaymentAttemptUpdate::ConfirmUpdate { + status, + payment_method, + browser_info, + connector, + } => Self { + status: Some(status), + payment_method, + modified_at: Some(common_utils::date_time::now()), + browser_info, + connector, + ..Default::default() + }, + PaymentAttemptUpdate::VoidUpdate { + status, + cancellation_reason, + } => Self { + status: Some(status), + cancellation_reason, + ..Default::default() + }, + PaymentAttemptUpdate::ResponseUpdate { + status, + connector_transaction_id, + authentication_type, + payment_method_id, + redirect, + mandate_id, + } => Self { + status: Some(status), + connector_transaction_id, + authentication_type, + payment_method_id, + modified_at: Some(common_utils::date_time::now()), + redirect, + mandate_id, + ..Default::default() + }, + PaymentAttemptUpdate::ErrorUpdate { + status, + error_message, + } => Self { + status: Some(status), + error_message, + modified_at: Some(common_utils::date_time::now()), + ..Default::default() + }, + PaymentAttemptUpdate::StatusUpdate { status } => Self { + status: Some(status), + ..Default::default() + }, + } + } +} diff --git a/crates/storage_models/src/payment_intent.rs b/crates/storage_models/src/payment_intent.rs new file mode 100644 index 0000000000..14b2b53a49 --- /dev/null +++ b/crates/storage_models/src/payment_intent.rs @@ -0,0 +1,233 @@ +use diesel::{AsChangeset, Identifiable, Insertable, Queryable}; +use serde::{Deserialize, Serialize}; +use time::PrimitiveDateTime; + +use crate::{enums as storage_enums, schema::payment_intent}; + +#[derive(Clone, Debug, Eq, PartialEq, Identifiable, Queryable, Serialize, Deserialize)] +#[diesel(table_name = payment_intent)] +pub struct PaymentIntent { + pub id: i32, + pub payment_id: String, + pub merchant_id: String, + pub status: storage_enums::IntentStatus, + pub amount: i32, + pub currency: Option, + pub amount_captured: Option, + pub customer_id: Option, + pub description: Option, + pub return_url: Option, + pub metadata: Option, + pub connector_id: Option, + pub shipping_address_id: Option, + pub billing_address_id: Option, + pub statement_descriptor_name: Option, + pub statement_descriptor_suffix: Option, + pub created_at: PrimitiveDateTime, + pub modified_at: PrimitiveDateTime, + pub last_synced: Option, // FIXME: this is optional + pub setup_future_usage: Option, + pub off_session: Option, + pub client_secret: Option, +} + +#[derive(Clone, Debug, Default, Eq, PartialEq, Insertable, router_derive::DebugAsDisplay)] +#[diesel(table_name = payment_intent)] +pub struct PaymentIntentNew { + pub payment_id: String, + pub merchant_id: String, + pub status: storage_enums::IntentStatus, + pub amount: i32, + pub currency: Option, + pub amount_captured: Option, + pub customer_id: Option, + pub description: Option, + pub return_url: Option, + pub metadata: Option, + pub connector_id: Option, + pub shipping_address_id: Option, + pub billing_address_id: Option, + pub statement_descriptor_name: Option, + pub statement_descriptor_suffix: Option, + pub created_at: Option, + pub modified_at: Option, + pub last_synced: Option, + pub client_secret: Option, + pub setup_future_usage: Option, + pub off_session: Option, +} + +#[derive(Debug, Clone)] +pub enum PaymentIntentUpdate { + ResponseUpdate { + status: storage_enums::IntentStatus, + amount_captured: Option, + return_url: Option, + }, + MetadataUpdate { + metadata: serde_json::Value, + }, + ReturnUrlUpdate { + return_url: Option, + status: Option, + customer_id: Option, + shipping_address_id: Option, + billing_address_id: Option, + }, + MerchantStatusUpdate { + status: storage_enums::IntentStatus, + shipping_address_id: Option, + billing_address_id: Option, + }, + PGStatusUpdate { + status: storage_enums::IntentStatus, + }, + Update { + amount: i32, + currency: storage_enums::Currency, + status: storage_enums::IntentStatus, + customer_id: Option, + shipping_address_id: Option, + billing_address_id: Option, + }, +} + +#[derive(Clone, Debug, Default, AsChangeset, router_derive::DebugAsDisplay)] +#[diesel(table_name = payment_intent)] + +pub struct PaymentIntentUpdateInternal { + pub amount: Option, + pub currency: Option, + pub status: Option, + pub amount_captured: Option, + pub customer_id: Option, + pub return_url: Option, + pub setup_future_usage: Option, + pub off_session: Option, + pub metadata: Option, + pub client_secret: Option>, + pub billing_address_id: Option, + pub shipping_address_id: Option, + pub modified_at: Option, +} + +impl PaymentIntentUpdate { + pub fn apply_changeset(self, source: PaymentIntent) -> PaymentIntent { + let internal_update: PaymentIntentUpdateInternal = self.into(); + PaymentIntent { + amount: internal_update.amount.unwrap_or(source.amount), + currency: internal_update.currency.or(source.currency), + status: internal_update.status.unwrap_or(source.status), + amount_captured: internal_update.amount_captured.or(source.amount_captured), + customer_id: internal_update.customer_id.or(source.customer_id), + return_url: internal_update.return_url.or(source.return_url), + setup_future_usage: internal_update + .setup_future_usage + .or(source.setup_future_usage), + off_session: internal_update.off_session.or(source.off_session), + metadata: internal_update.metadata.or(source.metadata), + client_secret: internal_update + .client_secret + .unwrap_or(source.client_secret), + billing_address_id: internal_update + .billing_address_id + .or(source.billing_address_id), + shipping_address_id: internal_update + .shipping_address_id + .or(source.shipping_address_id), + modified_at: common_utils::date_time::now(), + ..source + } + } +} + +impl From for PaymentIntentUpdateInternal { + fn from(payment_intent_update: PaymentIntentUpdate) -> Self { + match payment_intent_update { + PaymentIntentUpdate::Update { + amount, + currency, + status, + customer_id, + shipping_address_id, + billing_address_id, + } => Self { + amount: Some(amount), + currency: Some(currency), + status: Some(status), + customer_id, + client_secret: make_client_secret_null_if_success(Some(status)), + shipping_address_id, + billing_address_id, + modified_at: Some(common_utils::date_time::now()), + ..Default::default() + }, + PaymentIntentUpdate::MetadataUpdate { metadata } => Self { + metadata: Some(metadata), + modified_at: Some(common_utils::date_time::now()), + ..Default::default() + }, + PaymentIntentUpdate::ReturnUrlUpdate { + return_url, + status, + customer_id, + shipping_address_id, + billing_address_id, + } => Self { + return_url, + status, + client_secret: make_client_secret_null_if_success(status), + customer_id, + shipping_address_id, + billing_address_id, + modified_at: Some(common_utils::date_time::now()), + ..Default::default() + }, + PaymentIntentUpdate::PGStatusUpdate { status } => Self { + status: Some(status), + modified_at: Some(common_utils::date_time::now()), + ..Default::default() + }, + PaymentIntentUpdate::MerchantStatusUpdate { + status, + shipping_address_id, + billing_address_id, + } => Self { + status: Some(status), + client_secret: make_client_secret_null_if_success(Some(status)), + shipping_address_id, + billing_address_id, + modified_at: Some(common_utils::date_time::now()), + ..Default::default() + }, + PaymentIntentUpdate::ResponseUpdate { + // amount, + // currency, + status, + amount_captured, + // customer_id, + return_url, + } => Self { + // amount, + // currency: Some(currency), + status: Some(status), + amount_captured, + // customer_id, + return_url, + client_secret: make_client_secret_null_if_success(Some(status)), + modified_at: Some(common_utils::date_time::now()), + ..Default::default() + }, + } + } +} + +fn make_client_secret_null_if_success( + status: Option, +) -> Option> { + if status == Some(storage_enums::IntentStatus::Succeeded) { + Option::>::Some(None) + } else { + None + } +} diff --git a/crates/storage_models/src/payment_method.rs b/crates/storage_models/src/payment_method.rs new file mode 100644 index 0000000000..2e02a727c5 --- /dev/null +++ b/crates/storage_models/src/payment_method.rs @@ -0,0 +1,87 @@ +use diesel::{Identifiable, Insertable, Queryable}; +use masking::Secret; +use time::PrimitiveDateTime; + +use crate::{enums as storage_enums, schema::payment_methods}; + +#[derive(Clone, Debug, Eq, PartialEq, Identifiable, Queryable)] +#[diesel(table_name = payment_methods)] +pub struct PaymentMethod { + pub id: i32, + pub customer_id: String, + pub merchant_id: String, + pub payment_method_id: String, + #[diesel(deserialize_as = super::OptionalDieselArray)] + pub accepted_currency: Option>, + pub scheme: Option, + pub token: Option, + pub cardholder_name: Option>, + pub issuer_name: Option, + pub issuer_country: Option, + #[diesel(deserialize_as = super::OptionalDieselArray)] + pub payer_country: Option>, + pub is_stored: Option, + pub swift_code: Option, + pub direct_debit_token: Option, + pub network_transaction_id: Option, + pub created_at: PrimitiveDateTime, + pub last_modified: PrimitiveDateTime, + pub payment_method: storage_enums::PaymentMethodType, + pub payment_method_type: Option, + pub payment_method_issuer: Option, + pub payment_method_issuer_code: Option, +} + +#[derive(Clone, Debug, Eq, PartialEq, Insertable, Queryable, router_derive::DebugAsDisplay)] +#[diesel(table_name = payment_methods)] +pub struct PaymentMethodNew { + pub customer_id: String, + pub merchant_id: String, + pub payment_method_id: String, + pub payment_method: storage_enums::PaymentMethodType, + pub payment_method_type: Option, + pub payment_method_issuer: Option, + pub payment_method_issuer_code: Option, + pub accepted_currency: Option>, + pub scheme: Option, + pub token: Option, + pub cardholder_name: Option>, + pub issuer_name: Option, + pub issuer_country: Option, + pub payer_country: Option>, + pub is_stored: Option, + pub swift_code: Option, + pub direct_debit_token: Option, + pub network_transaction_id: Option, + pub created_at: PrimitiveDateTime, + pub last_modified: PrimitiveDateTime, +} + +impl Default for PaymentMethodNew { + fn default() -> Self { + let now = common_utils::date_time::now(); + + Self { + customer_id: String::default(), + merchant_id: String::default(), + payment_method_id: String::default(), + payment_method: storage_enums::PaymentMethodType::default(), + payment_method_type: Option::default(), + payment_method_issuer: Option::default(), + payment_method_issuer_code: Option::default(), + accepted_currency: Option::default(), + scheme: Option::default(), + token: Option::default(), + cardholder_name: Option::default(), + issuer_name: Option::default(), + issuer_country: Option::default(), + payer_country: Option::default(), + is_stored: Option::default(), + swift_code: Option::default(), + direct_debit_token: Option::default(), + network_transaction_id: Option::default(), + created_at: now, + last_modified: now, + } + } +} diff --git a/crates/storage_models/src/process_tracker.rs b/crates/storage_models/src/process_tracker.rs new file mode 100644 index 0000000000..40c5d402b1 --- /dev/null +++ b/crates/storage_models/src/process_tracker.rs @@ -0,0 +1,167 @@ +use diesel::{AsChangeset, Identifiable, Insertable, Queryable}; +use serde::{Deserialize, Serialize}; +use time::PrimitiveDateTime; + +use crate::{enums as storage_enums, schema::process_tracker}; + +#[derive( + Clone, + Debug, + Eq, + PartialEq, + Deserialize, + Identifiable, + Queryable, + Serialize, + router_derive::DebugAsDisplay, +)] +#[diesel(table_name = process_tracker)] +pub struct ProcessTracker { + pub id: String, + pub name: Option, + #[diesel(deserialize_as = super::DieselArray)] + pub tag: Vec, + pub runner: Option, + pub retry_count: i32, + pub schedule_time: Option, + pub rule: String, + pub tracking_data: serde_json::Value, + pub business_status: String, + pub status: storage_enums::ProcessTrackerStatus, + #[diesel(deserialize_as = super::DieselArray)] + pub event: Vec, + pub created_at: PrimitiveDateTime, + pub updated_at: PrimitiveDateTime, +} + +#[derive(Clone, Debug, Insertable, router_derive::DebugAsDisplay)] +#[diesel(table_name = process_tracker)] +pub struct ProcessTrackerNew { + pub id: String, + pub name: Option, + pub tag: Vec, + pub runner: Option, + pub retry_count: i32, + pub schedule_time: Option, + pub rule: String, + pub tracking_data: serde_json::Value, + pub business_status: String, + pub status: storage_enums::ProcessTrackerStatus, + pub event: Vec, + pub created_at: PrimitiveDateTime, + pub updated_at: PrimitiveDateTime, +} + +#[derive(Debug)] +pub enum ProcessTrackerUpdate { + Update { + name: Option, + retry_count: Option, + schedule_time: Option, + tracking_data: Option, + business_status: Option, + status: Option, + updated_at: Option, + }, + StatusUpdate { + status: storage_enums::ProcessTrackerStatus, + business_status: Option, + }, + StatusRetryUpdate { + status: storage_enums::ProcessTrackerStatus, + retry_count: i32, + schedule_time: PrimitiveDateTime, + }, +} + +#[derive(Debug, Clone, AsChangeset, router_derive::DebugAsDisplay)] +#[diesel(table_name = process_tracker)] +pub struct ProcessTrackerUpdateInternal { + name: Option, + retry_count: Option, + schedule_time: Option, + tracking_data: Option, + business_status: Option, + status: Option, + updated_at: Option, +} + +impl Default for ProcessTrackerUpdateInternal { + fn default() -> Self { + Self { + name: Option::default(), + retry_count: Option::default(), + schedule_time: Option::default(), + tracking_data: Option::default(), + business_status: Option::default(), + status: Option::default(), + updated_at: Some(common_utils::date_time::now()), + } + } +} + +impl From for ProcessTrackerUpdateInternal { + fn from(process_tracker_update: ProcessTrackerUpdate) -> Self { + match process_tracker_update { + ProcessTrackerUpdate::Update { + name, + retry_count, + schedule_time, + tracking_data, + business_status, + status, + updated_at, + } => Self { + name, + retry_count, + schedule_time, + tracking_data, + business_status, + status, + updated_at, + }, + ProcessTrackerUpdate::StatusUpdate { + status, + business_status, + } => Self { + status: Some(status), + business_status, + ..Default::default() + }, + ProcessTrackerUpdate::StatusRetryUpdate { + status, + retry_count, + schedule_time, + } => Self { + status: Some(status), + retry_count: Some(retry_count), + schedule_time: Some(schedule_time), + ..Default::default() + }, + } + } +} + +// TODO: Move this to a utility module? +pub struct Milliseconds(i32); + +#[allow(dead_code)] +pub struct SchedulerOptions { + looper_interval: Milliseconds, + db_name: String, + cache_name: String, + schema_name: String, + cache_expiry: i32, + runners: Vec, + fetch_limit: i32, + fetch_limit_product_factor: i32, + query_order: String, +} + +#[derive(Debug, Clone)] +#[allow(dead_code)] +pub struct ProcessData { + db_name: String, + cache_name: String, + process_tracker: ProcessTracker, +} diff --git a/crates/storage_models/src/query.rs b/crates/storage_models/src/query.rs new file mode 100644 index 0000000000..196cc16943 --- /dev/null +++ b/crates/storage_models/src/query.rs @@ -0,0 +1,16 @@ +pub mod address; +pub mod configs; +pub mod connector_response; +pub mod customers; +pub mod events; +pub mod generics; +pub mod locker_mock_up; +pub mod mandate; +pub mod merchant_account; +pub mod merchant_connector_account; +pub mod payment_attempt; +pub mod payment_intent; +pub mod payment_method; +pub mod process_tracker; +pub mod refund; +pub mod temp_card; diff --git a/crates/router/src/types/storage/query/address.rs b/crates/storage_models/src/query/address.rs similarity index 78% rename from crates/router/src/types/storage/query/address.rs rename to crates/storage_models/src/query/address.rs index fbfc894d08..4b9b74cc9f 100644 --- a/crates/router/src/types/storage/query/address.rs +++ b/crates/storage_models/src/query/address.rs @@ -3,15 +3,15 @@ use router_env::{tracing, tracing::instrument}; use super::generics::{self, ExecuteQuery}; use crate::{ - connection::PgPooledConn, - core::errors::{self, CustomResult, DatabaseError}, + address::{Address, AddressNew, AddressUpdate, AddressUpdateInternal}, + errors, schema::address::dsl, - types::storage::{Address, AddressNew, AddressUpdate, AddressUpdateInternal}, + CustomResult, PgPooledConn, }; impl AddressNew { #[instrument(skip(conn))] - pub async fn insert(self, conn: &PgPooledConn) -> CustomResult { + pub async fn insert(self, conn: &PgPooledConn) -> CustomResult { generics::generic_insert::<_, _, Address, _>(conn, self, ExecuteQuery::new()).await } } @@ -22,7 +22,7 @@ impl Address { conn: &PgPooledConn, address_id: String, address: AddressUpdate, - ) -> CustomResult { + ) -> CustomResult { match generics::generic_update_by_id::<::Table, _, _, Self, _>( conn, address_id.clone(), @@ -32,10 +32,10 @@ impl Address { .await { Err(error) => match error.current_context() { - errors::StorageError::DatabaseError(DatabaseError::NotFound) => { + errors::DatabaseError::NotFound => { Err(error.attach_printable("Address with the given ID doesn't exist")) } - errors::StorageError::DatabaseError(errors::DatabaseError::NoFieldsToUpdate) => { + errors::DatabaseError::NoFieldsToUpdate => { generics::generic_find_by_id::<::Table, _, _>( conn, address_id.clone(), @@ -52,7 +52,7 @@ impl Address { pub async fn delete_by_address_id( conn: &PgPooledConn, address_id: &str, - ) -> CustomResult { + ) -> CustomResult { generics::generic_delete::<::Table, _, _>( conn, dsl::address_id.eq(address_id.to_owned()), @@ -65,7 +65,7 @@ impl Address { pub async fn find_by_address_id<'a>( conn: &PgPooledConn, address_id: &str, - ) -> CustomResult { + ) -> CustomResult { generics::generic_find_by_id::<::Table, _, _>(conn, address_id.to_owned()) .await } @@ -74,7 +74,7 @@ impl Address { pub async fn find_optional_by_address_id<'a>( conn: &PgPooledConn, address_id: &str, - ) -> CustomResult, errors::StorageError> { + ) -> CustomResult, errors::DatabaseError> { generics::generic_find_by_id_optional::<::Table, _, _>( conn, address_id.to_owned(), diff --git a/crates/router/src/types/storage/query/configs.rs b/crates/storage_models/src/query/configs.rs similarity index 78% rename from crates/router/src/types/storage/query/configs.rs rename to crates/storage_models/src/query/configs.rs index ce6c1a4225..d86e4f08de 100644 --- a/crates/router/src/types/storage/query/configs.rs +++ b/crates/storage_models/src/query/configs.rs @@ -3,14 +3,13 @@ use router_env::tracing::{self, instrument}; use super::generics::{self, ExecuteQuery}; use crate::{ - connection::PgPooledConn, - core::errors::{self, CustomResult}, - types::storage::{Config, ConfigNew, ConfigUpdate, ConfigUpdateInternal}, + configs::{Config, ConfigNew, ConfigUpdate, ConfigUpdateInternal}, + errors, CustomResult, PgPooledConn, }; impl ConfigNew { #[instrument(skip(conn))] - pub async fn insert(self, conn: &PgPooledConn) -> CustomResult { + pub async fn insert(self, conn: &PgPooledConn) -> CustomResult { generics::generic_insert::<_, _, Config, _>(conn, self, ExecuteQuery::new()).await } } @@ -20,7 +19,7 @@ impl Config { pub async fn find_by_key( conn: &PgPooledConn, key: &str, - ) -> CustomResult { + ) -> CustomResult { generics::generic_find_by_id::<::Table, _, _>(conn, key.to_owned()).await } @@ -29,7 +28,7 @@ impl Config { conn: &PgPooledConn, key: &str, config_update: ConfigUpdate, - ) -> CustomResult { + ) -> CustomResult { match generics::generic_update_by_id::<::Table, _, _, Self, _>( conn, key.to_owned(), @@ -39,7 +38,7 @@ impl Config { .await { Err(error) => match error.current_context() { - errors::StorageError::DatabaseError(errors::DatabaseError::NoFieldsToUpdate) => { + errors::DatabaseError::NoFieldsToUpdate => { generics::generic_find_by_id::<::Table, _, _>( conn, key.to_owned(), diff --git a/crates/router/src/types/storage/query/connector_response.rs b/crates/storage_models/src/query/connector_response.rs similarity index 80% rename from crates/router/src/types/storage/query/connector_response.rs rename to crates/storage_models/src/query/connector_response.rs index cdd20cf1ae..38febb82fa 100644 --- a/crates/router/src/types/storage/query/connector_response.rs +++ b/crates/storage_models/src/query/connector_response.rs @@ -3,13 +3,13 @@ use router_env::{tracing, tracing::instrument}; use super::generics::{self, ExecuteQuery}; use crate::{ - connection::PgPooledConn, - core::errors::{self, CustomResult}, - schema::connector_response::dsl, - types::storage::{ + connector_response::{ ConnectorResponse, ConnectorResponseNew, ConnectorResponseUpdate, ConnectorResponseUpdateInternal, }, + errors, + schema::connector_response::dsl, + CustomResult, PgPooledConn, }; impl ConnectorResponseNew { @@ -17,7 +17,7 @@ impl ConnectorResponseNew { pub async fn insert( self, conn: &PgPooledConn, - ) -> CustomResult { + ) -> CustomResult { generics::generic_insert::<_, _, ConnectorResponse, _>(conn, self, ExecuteQuery::new()) .await } @@ -29,7 +29,7 @@ impl ConnectorResponse { self, conn: &PgPooledConn, connector_response: ConnectorResponseUpdate, - ) -> CustomResult { + ) -> CustomResult { match generics::generic_update_by_id::<::Table, _, _, Self, _>( conn, self.id, @@ -39,9 +39,7 @@ impl ConnectorResponse { .await { Err(error) => match error.current_context() { - errors::StorageError::DatabaseError(errors::DatabaseError::NoFieldsToUpdate) => { - Ok(self) - } + errors::DatabaseError::NoFieldsToUpdate => Ok(self), _ => Err(error), }, result => result, @@ -54,7 +52,7 @@ impl ConnectorResponse { payment_id: &str, merchant_id: &str, transaction_id: &str, - ) -> CustomResult { + ) -> CustomResult { generics::generic_find_one::<::Table, _, _>( conn, dsl::merchant_id.eq(merchant_id.to_owned()).and( diff --git a/crates/router/src/types/storage/query/customers.rs b/crates/storage_models/src/query/customers.rs similarity index 82% rename from crates/router/src/types/storage/query/customers.rs rename to crates/storage_models/src/query/customers.rs index 405781c5f0..61c29e079e 100644 --- a/crates/router/src/types/storage/query/customers.rs +++ b/crates/storage_models/src/query/customers.rs @@ -3,10 +3,10 @@ use router_env::{tracing, tracing::instrument}; use super::generics::{self, ExecuteQuery}; use crate::{ - connection::PgPooledConn, - core::errors::{self, CustomResult}, + customers::{Customer, CustomerNew, CustomerUpdate, CustomerUpdateInternal}, + errors, schema::customers::dsl, - types::storage::{Customer, CustomerNew, CustomerUpdate, CustomerUpdateInternal}, + CustomResult, PgPooledConn, }; impl CustomerNew { @@ -14,7 +14,7 @@ impl CustomerNew { pub async fn insert_diesel( self, conn: &PgPooledConn, - ) -> CustomResult { + ) -> CustomResult { generics::generic_insert::<_, _, Customer, _>(conn, self, ExecuteQuery::new()).await } } @@ -26,7 +26,7 @@ impl Customer { customer_id: String, merchant_id: String, customer: CustomerUpdate, - ) -> CustomResult { + ) -> CustomResult { match generics::generic_update_by_id::<::Table, _, _, Self, _>( conn, (customer_id.clone(), merchant_id.clone()), @@ -36,7 +36,7 @@ impl Customer { .await { Err(error) => match error.current_context() { - errors::StorageError::DatabaseError(errors::DatabaseError::NoFieldsToUpdate) => { + errors::DatabaseError::NoFieldsToUpdate => { generics::generic_find_by_id::<::Table, _, _>( conn, (customer_id, merchant_id), @@ -54,7 +54,7 @@ impl Customer { conn: &PgPooledConn, customer_id: &str, merchant_id: &str, - ) -> CustomResult { + ) -> CustomResult { generics::generic_delete::<::Table, _, _>( conn, dsl::customer_id @@ -70,7 +70,7 @@ impl Customer { conn: &PgPooledConn, customer_id: &str, merchant_id: &str, - ) -> CustomResult { + ) -> CustomResult { generics::generic_find_by_id::<::Table, _, _>( conn, (customer_id.to_owned(), merchant_id.to_owned()), @@ -83,7 +83,7 @@ impl Customer { conn: &PgPooledConn, customer_id: &str, merchant_id: &str, - ) -> CustomResult, errors::StorageError> { + ) -> CustomResult, errors::DatabaseError> { generics::generic_find_by_id_optional::<::Table, _, _>( conn, (customer_id.to_owned(), merchant_id.to_owned()), diff --git a/crates/router/src/types/storage/query/events.rs b/crates/storage_models/src/query/events.rs similarity index 68% rename from crates/router/src/types/storage/query/events.rs rename to crates/storage_models/src/query/events.rs index 777f009af8..341d029d2d 100644 --- a/crates/router/src/types/storage/query/events.rs +++ b/crates/storage_models/src/query/events.rs @@ -2,14 +2,14 @@ use router_env::tracing::{self, instrument}; use super::generics::{self, ExecuteQuery}; use crate::{ - connection::PgPooledConn, - core::errors::{self, CustomResult}, - types::storage::{Event, EventNew}, + errors, + events::{Event, EventNew}, + CustomResult, PgPooledConn, }; impl EventNew { #[instrument(skip(conn))] - pub async fn insert(self, conn: &PgPooledConn) -> CustomResult { + pub async fn insert(self, conn: &PgPooledConn) -> CustomResult { generics::generic_insert::<_, _, Event, _>(conn, self, ExecuteQuery::new()).await } } diff --git a/crates/router/src/types/storage/query/generics.rs b/crates/storage_models/src/query/generics.rs similarity index 79% rename from crates/router/src/types/storage/query/generics.rs rename to crates/storage_models/src/query/generics.rs index 1695115c66..df72cf3d7b 100644 --- a/crates/router/src/types/storage/query/generics.rs +++ b/crates/storage_models/src/query/generics.rs @@ -20,25 +20,19 @@ use diesel::{ Insertable, QuerySource, Table, }; use error_stack::{report, IntoReport, ResultExt}; -use router_env::{tracing, tracing::instrument}; +use router_env::{logger, tracing, tracing::instrument}; -use crate::{ - connection::PgPooledConn, - core::errors::{self, CustomResult}, - logger, -}; +use crate::{errors, CustomResult, PgPooledConn}; -#[cfg(feature = "kv_store")] #[derive(Debug)] pub struct RawSqlQuery { - pub(crate) sql: String, + pub sql: String, // The inner `Vec` can be considered to be byte array - pub(crate) binds: Vec>>, + pub binds: Vec>>, } -#[cfg(feature = "kv_store")] impl RawSqlQuery { - pub(crate) fn to_field_value_pairs(&self) -> Vec<(&str, String)> { + pub fn to_field_value_pairs(&self) -> Vec<(&str, String)> { vec![ ("sql", self.sql.clone()), ( @@ -56,19 +50,24 @@ impl RawSqlQuery { } } -pub(super) struct ExecuteQuery(PhantomData); +pub struct ExecuteQuery(PhantomData); impl ExecuteQuery { - pub(super) fn new() -> Self { + pub fn new() -> Self { Self(PhantomData) } } -#[cfg(feature = "kv_store")] -pub(super) struct RawQuery; +impl Default for ExecuteQuery { + fn default() -> Self { + Self::new() + } +} + +pub struct RawQuery; #[async_trait] -pub(super) trait QueryExecutionMode +pub trait QueryExecutionMode where Q: QueryFragment + Send + 'static, { @@ -85,7 +84,7 @@ where conn: &PgPooledConn, query: Q, debug_values: String, - ) -> CustomResult + ) -> CustomResult where Q: AsQuery + QueryFragment + RunQueryDsl; @@ -94,7 +93,7 @@ where conn: &PgPooledConn, query: Q, debug_values: String, - ) -> CustomResult + ) -> CustomResult where Q: QueryId; @@ -103,14 +102,14 @@ where conn: &PgPooledConn, query: Q, debug_values: String, - ) -> CustomResult; + ) -> CustomResult; async fn update_by_id( &self, conn: &PgPooledConn, query: Q, debug_values: String, - ) -> CustomResult + ) -> CustomResult where Q: Clone; @@ -118,7 +117,7 @@ where &self, conn: &PgPooledConn, query: Q, - ) -> CustomResult + ) -> CustomResult where Q: QueryId; @@ -126,13 +125,13 @@ where &self, conn: &PgPooledConn, query: Q, - ) -> CustomResult; + ) -> CustomResult; async fn delete_one_with_result( &self, conn: &PgPooledConn, query: Q, - ) -> CustomResult; + ) -> CustomResult; } #[async_trait] @@ -154,7 +153,7 @@ where conn: &PgPooledConn, query: Q, debug_values: String, - ) -> CustomResult + ) -> CustomResult where Q: AsQuery + QueryFragment + RunQueryDsl, { @@ -164,9 +163,8 @@ where ConnectionError::Query(DieselError::DatabaseError( diesel::result::DatabaseErrorKind::UniqueViolation, _, - )) => Err(report!(error)) - .change_context(errors::DatabaseError::UniqueViolation.into()), - _ => Err(report!(error)).change_context(errors::DatabaseError::Others.into()), + )) => Err(report!(error)).change_context(errors::DatabaseError::UniqueViolation), + _ => Err(report!(error)).change_context(errors::DatabaseError::Others), } .attach_printable_lazy(|| format!("Error while inserting {}", debug_values)), } @@ -177,7 +175,7 @@ where conn: &PgPooledConn, query: Q, debug_values: String, - ) -> CustomResult + ) -> CustomResult where Q: QueryId, { @@ -185,7 +183,7 @@ where .execute_async(conn) .await .into_report() - .change_context(errors::DatabaseError::Others.into()) + .change_context(errors::DatabaseError::Others) .attach_printable_lazy(|| format!("Error while updating {}", debug_values)) } @@ -194,12 +192,12 @@ where conn: &PgPooledConn, query: Q, debug_values: String, - ) -> CustomResult { + ) -> CustomResult { query .get_results_async(conn) .await .into_report() - .change_context(errors::DatabaseError::Others.into()) + .change_context(errors::DatabaseError::Others) .attach_printable_lazy(|| format!("Error while updating {}", debug_values)) } @@ -208,7 +206,7 @@ where conn: &PgPooledConn, query: Q, debug_values: String, - ) -> CustomResult + ) -> CustomResult where Q: Clone, { @@ -220,12 +218,13 @@ where } Err(error) => match error { // Failed to generate query, no fields were provided to be updated - ConnectionError::Query(DieselError::QueryBuilderError(_)) => Err(report!(error)) - .change_context(errors::DatabaseError::NoFieldsToUpdate.into()), - ConnectionError::Query(DieselError::NotFound) => { - Err(report!(error)).change_context(errors::DatabaseError::NotFound.into()) + ConnectionError::Query(DieselError::QueryBuilderError(_)) => { + Err(report!(error)).change_context(errors::DatabaseError::NoFieldsToUpdate) } - _ => Err(report!(error)).change_context(errors::DatabaseError::Others.into()), + ConnectionError::Query(DieselError::NotFound) => { + Err(report!(error)).change_context(errors::DatabaseError::NotFound) + } + _ => Err(report!(error)).change_context(errors::DatabaseError::Others), } .attach_printable_lazy(|| format!("Error while updating by ID {}", debug_values)), } @@ -235,7 +234,7 @@ where &self, conn: &PgPooledConn, query: Q, - ) -> CustomResult + ) -> CustomResult where Q: QueryId, { @@ -243,17 +242,17 @@ where .execute_async(conn) .await .into_report() - .change_context(errors::DatabaseError::Others.into()) + .change_context(errors::DatabaseError::Others) .attach_printable("Error while deleting") .and_then(|result| match result { n if n > 0 => { logger::debug!("{n} records deleted"); Ok(true) } - 0 => Err(report!(errors::StorageError::DatabaseError( - errors::DatabaseError::NotFound - )) - .attach_printable("No records deleted")), + 0 => { + Err(report!(errors::DatabaseError::NotFound) + .attach_printable("No records deleted")) + } _ => Ok(true), // n is usize, rustc requires this for exhaustive check }) } @@ -262,12 +261,12 @@ where &self, conn: &PgPooledConn, query: Q, - ) -> CustomResult { + ) -> CustomResult { query .get_results_async(conn) .await .into_report() - .change_context(errors::DatabaseError::Others.into()) + .change_context(errors::DatabaseError::Others) .attach_printable("Error while deleting") } @@ -275,21 +274,20 @@ where &self, conn: &PgPooledConn, query: Q, - ) -> CustomResult { + ) -> CustomResult { match query.get_result_async(conn).await { Ok(value) => Ok(value), Err(error) => match error { ConnectionError::Query(DieselError::NotFound) => { - Err(report!(error)).change_context(errors::DatabaseError::NotFound.into()) + Err(report!(error)).change_context(errors::DatabaseError::NotFound) } - _ => Err(report!(error)).change_context(errors::DatabaseError::Others.into()), + _ => Err(report!(error)).change_context(errors::DatabaseError::Others), } .attach_printable("Error while deleting"), } } } -#[cfg(feature = "kv_store")] #[async_trait] impl QueryExecutionMode for RawQuery where @@ -308,7 +306,7 @@ where _conn: &PgPooledConn, query: Q, _debug_values: String, - ) -> CustomResult + ) -> CustomResult where Q: AsQuery + QueryFragment + RunQueryDsl, { @@ -320,7 +318,7 @@ where _conn: &PgPooledConn, query: Q, _debug_values: String, - ) -> CustomResult + ) -> CustomResult where Q: QueryId, { @@ -332,7 +330,7 @@ where _conn: &PgPooledConn, query: Q, _debug_values: String, - ) -> CustomResult { + ) -> CustomResult { generate_raw_query(query) } @@ -341,7 +339,7 @@ where _conn: &PgPooledConn, query: Q, _debug_values: String, - ) -> CustomResult + ) -> CustomResult where Q: Clone, { @@ -352,7 +350,7 @@ where &self, _conn: &PgPooledConn, query: Q, - ) -> CustomResult + ) -> CustomResult where Q: QueryId, { @@ -363,7 +361,7 @@ where &self, _conn: &PgPooledConn, query: Q, - ) -> CustomResult { + ) -> CustomResult { generate_raw_query(query) } @@ -371,19 +369,18 @@ where &self, _conn: &PgPooledConn, query: Q, - ) -> CustomResult { + ) -> CustomResult { generate_raw_query(query) } } -#[cfg(feature = "kv_store")] -fn generate_raw_query(query: Q) -> CustomResult +pub fn generate_raw_query(query: Q) -> CustomResult where Q: QueryFragment, { let raw_query = diesel::query_builder::raw_query(&query) .into_report() - .change_context(errors::DatabaseError::QueryGenerationFailed.into())?; + .change_context(errors::DatabaseError::QueryGenerationFailed)?; Ok(RawSqlQuery { sql: raw_query.raw_sql, @@ -392,11 +389,11 @@ where } #[instrument(level = "DEBUG", skip_all)] -pub(super) async fn generic_insert( +pub async fn generic_insert( conn: &PgPooledConn, values: V, execution_mode: Q, -) -> CustomResult +) -> CustomResult where T: HasTable + Table + 'static, V: Debug + Insertable, @@ -417,12 +414,12 @@ where } #[instrument(level = "DEBUG", skip_all)] -pub(super) async fn generic_update( +pub async fn generic_update( conn: &PgPooledConn, predicate: P, values: V, execution_mode: Q, -) -> CustomResult +) -> CustomResult where T: FilterDsl

+ HasTable

+ Table + 'static, V: AsChangeset>::Output as HasTable>::Table> + Debug, @@ -450,12 +447,12 @@ where } #[instrument(level = "DEBUG", skip_all)] -pub(super) async fn generic_update_with_results( +pub async fn generic_update_with_results( conn: &PgPooledConn, predicate: P, values: V, execution_mode: Q, -) -> CustomResult +) -> CustomResult where T: FilterDsl

+ HasTable

+ Table + 'static, V: AsChangeset>::Output as HasTable>::Table> + Debug + 'static, @@ -486,12 +483,12 @@ where } #[instrument(level = "DEBUG", skip_all)] -pub(super) async fn generic_update_by_id( +pub async fn generic_update_by_id( conn: &PgPooledConn, id: Pk, values: V, execution_mode: Q, -) -> CustomResult +) -> CustomResult where T: FindDsl + HasTable
+ LimitDsl + Table + 'static, V: AsChangeset>::Output as HasTable>::Table> + Debug, @@ -529,11 +526,11 @@ where } #[instrument(level = "DEBUG", skip_all)] -pub(super) async fn generic_delete( +pub async fn generic_delete( conn: &PgPooledConn, predicate: P, execution_mode: Q, -) -> CustomResult +) -> CustomResult where T: FilterDsl

+ HasTable

+ Table + 'static, >::Output: IntoUpdateTarget, @@ -557,11 +554,11 @@ where #[allow(dead_code)] #[instrument(level = "DEBUG", skip_all)] -pub(super) async fn generic_delete_with_results( +pub async fn generic_delete_with_results( conn: &PgPooledConn, predicate: P, execution_mode: Q, -) -> CustomResult +) -> CustomResult where T: FilterDsl

+ HasTable

+ Table + 'static, >::Output: IntoUpdateTarget, @@ -585,11 +582,11 @@ where } #[instrument(level = "DEBUG", skip_all)] -pub(super) async fn generic_delete_one_with_result( +pub async fn generic_delete_one_with_result( conn: &PgPooledConn, predicate: P, execution_mode: Q, -) -> CustomResult +) -> CustomResult where T: FilterDsl

+ HasTable

+ Table + 'static, >::Output: IntoUpdateTarget, @@ -616,7 +613,7 @@ where async fn generic_find_by_id_core( conn: &PgPooledConn, id: Pk, -) -> CustomResult +) -> CustomResult where T: FindDsl + HasTable
+ LimitDsl + Table + 'static, >::Output: QueryFragment + RunQueryDsl + Send + 'static, @@ -631,22 +628,20 @@ where match query.first_async(conn).await.into_report() { Ok(value) => Ok(value), Err(err) => match err.current_context() { - ConnectionError::Query(DieselError::NotFound) => Err(err).change_context( - errors::StorageError::DatabaseError(errors::DatabaseError::NotFound), - ), - _ => Err(err).change_context(errors::StorageError::DatabaseError( - errors::DatabaseError::Others, - )), + ConnectionError::Query(DieselError::NotFound) => { + Err(err).change_context(errors::DatabaseError::NotFound) + } + _ => Err(err).change_context(errors::DatabaseError::Others), }, } .attach_printable_lazy(|| format!("Error finding record by primary key: {:?}", id)) } #[instrument(level = "DEBUG", skip_all)] -pub(super) async fn generic_find_by_id( +pub async fn generic_find_by_id( conn: &PgPooledConn, id: Pk, -) -> CustomResult +) -> CustomResult where T: FindDsl + HasTable
+ LimitDsl + Table + 'static, >::Output: QueryFragment + RunQueryDsl + Send + 'static, @@ -659,10 +654,10 @@ where } #[instrument(level = "DEBUG", skip_all)] -pub(super) async fn generic_find_by_id_optional( +pub async fn generic_find_by_id_optional( conn: &PgPooledConn, id: Pk, -) -> CustomResult, errors::StorageError> +) -> CustomResult, errors::DatabaseError> where T: FindDsl + HasTable
+ LimitDsl + Table + 'static, ::Table: FindDsl, @@ -680,7 +675,7 @@ where async fn generic_find_one_core( conn: &PgPooledConn, predicate: P, -) -> CustomResult +) -> CustomResult where T: FilterDsl

+ HasTable

+ Table + 'static, >::Output: @@ -695,21 +690,19 @@ where .await .into_report() .map_err(|err| match err.current_context() { - ConnectionError::Query(DieselError::NotFound) => err.change_context( - errors::StorageError::DatabaseError(errors::DatabaseError::NotFound), - ), - _ => err.change_context(errors::StorageError::DatabaseError( - errors::DatabaseError::Others, - )), + ConnectionError::Query(DieselError::NotFound) => { + err.change_context(errors::DatabaseError::NotFound) + } + _ => err.change_context(errors::DatabaseError::Others), }) .attach_printable_lazy(|| "Error finding record by predicate") } #[instrument(level = "DEBUG", skip_all)] -pub(super) async fn generic_find_one( +pub async fn generic_find_one( conn: &PgPooledConn, predicate: P, -) -> CustomResult +) -> CustomResult where T: FilterDsl

+ HasTable

+ Table + 'static, >::Output: @@ -720,10 +713,10 @@ where } #[instrument(level = "DEBUG", skip_all)] -pub(super) async fn generic_find_one_optional( +pub async fn generic_find_one_optional( conn: &PgPooledConn, predicate: P, -) -> CustomResult, errors::StorageError> +) -> CustomResult, errors::DatabaseError> where T: FilterDsl

+ HasTable

+ Table + 'static, >::Output: @@ -734,11 +727,11 @@ where } #[instrument(level = "DEBUG", skip_all)] -pub(super) async fn generic_filter( +pub async fn generic_filter( conn: &PgPooledConn, predicate: P, limit: Option, -) -> CustomResult, errors::StorageError> +) -> CustomResult, errors::DatabaseError> where T: FilterDsl

+ HasTable

+ Table + 'static, >::Output: LoadQuery<'static, PgConnection, R> + QueryFragment, @@ -762,19 +755,17 @@ where } .await .into_report() - .change_context(errors::StorageError::DatabaseError( - errors::DatabaseError::NotFound, - )) + .change_context(errors::DatabaseError::NotFound) .attach_printable_lazy(|| "Error filtering records by predicate") } -fn to_optional( - arg: CustomResult, -) -> CustomResult, errors::StorageError> { +pub fn to_optional( + arg: CustomResult, +) -> CustomResult, errors::DatabaseError> { match arg { Ok(value) => Ok(Some(value)), Err(err) => match err.current_context() { - errors::StorageError::DatabaseError(errors::DatabaseError::NotFound) => Ok(None), + errors::DatabaseError::NotFound => Ok(None), _ => Err(err), }, } diff --git a/crates/router/src/types/storage/query/locker_mock_up.rs b/crates/storage_models/src/query/locker_mock_up.rs similarity index 75% rename from crates/router/src/types/storage/query/locker_mock_up.rs rename to crates/storage_models/src/query/locker_mock_up.rs index 8e59dea04b..af0cf1d46b 100644 --- a/crates/router/src/types/storage/query/locker_mock_up.rs +++ b/crates/storage_models/src/query/locker_mock_up.rs @@ -3,10 +3,10 @@ use router_env::{tracing, tracing::instrument}; use super::generics::{self, ExecuteQuery}; use crate::{ - connection::PgPooledConn, - core::errors::{self, CustomResult}, + errors, + locker_mock_up::{LockerMockUp, LockerMockUpNew}, schema::locker_mock_up::dsl, - types::storage::{LockerMockUp, LockerMockUpNew}, + CustomResult, PgPooledConn, }; impl LockerMockUpNew { @@ -14,7 +14,7 @@ impl LockerMockUpNew { pub async fn insert( self, conn: &PgPooledConn, - ) -> CustomResult { + ) -> CustomResult { generics::generic_insert::<_, _, LockerMockUp, _>(conn, self, ExecuteQuery::new()).await } } @@ -24,7 +24,7 @@ impl LockerMockUp { pub async fn find_by_card_id( conn: &PgPooledConn, card_id: &str, - ) -> CustomResult { + ) -> CustomResult { generics::generic_find_one::<::Table, _, _>( conn, dsl::card_id.eq(card_id.to_owned()), diff --git a/crates/router/src/types/storage/query/mandate.rs b/crates/storage_models/src/query/mandate.rs similarity index 69% rename from crates/router/src/types/storage/query/mandate.rs rename to crates/storage_models/src/query/mandate.rs index 7dda03cf96..868e5644bd 100644 --- a/crates/router/src/types/storage/query/mandate.rs +++ b/crates/storage_models/src/query/mandate.rs @@ -3,20 +3,12 @@ use error_stack::report; use router_env::tracing::{self, instrument}; use super::generics::{self, ExecuteQuery}; -use crate::{ - connection::PgPooledConn, - core::errors::{self, CustomResult}, - schema::mandate::dsl, - types::storage::{self, mandate::*}, -}; +use crate::{errors, mandate::*, schema::mandate::dsl, CustomResult, PgPooledConn}; impl MandateNew { #[instrument(skip(conn))] - pub async fn insert( - self, - conn: &PgPooledConn, - ) -> CustomResult { - generics::generic_insert::<_, _, storage::Mandate, _>(conn, self, ExecuteQuery::new()).await + pub async fn insert(self, conn: &PgPooledConn) -> CustomResult { + generics::generic_insert::<_, _, Mandate, _>(conn, self, ExecuteQuery::new()).await } } @@ -25,7 +17,7 @@ impl Mandate { conn: &PgPooledConn, merchant_id: &str, mandate_id: &str, - ) -> CustomResult { + ) -> CustomResult { generics::generic_find_one::<::Table, _, _>( conn, dsl::merchant_id @@ -39,7 +31,7 @@ impl Mandate { conn: &PgPooledConn, merchant_id: &str, customer_id: &str, - ) -> CustomResult, errors::StorageError> { + ) -> CustomResult, errors::DatabaseError> { generics::generic_filter::<::Table, _, _>( conn, dsl::merchant_id @@ -55,7 +47,7 @@ impl Mandate { merchant_id: &str, mandate_id: &str, mandate: MandateUpdate, - ) -> CustomResult { + ) -> CustomResult { generics::generic_update_with_results::<::Table, _, _, Self, _>( conn, dsl::merchant_id @@ -68,10 +60,8 @@ impl Mandate { .first() .cloned() .ok_or_else(|| { - report!(errors::StorageError::DatabaseError( - errors::DatabaseError::NotFound - )) - .attach_printable("Error while updating mandate") + report!(errors::DatabaseError::NotFound) + .attach_printable("Error while updating mandate") }) } } diff --git a/crates/router/src/types/storage/query/merchant_account.rs b/crates/storage_models/src/query/merchant_account.rs similarity index 80% rename from crates/router/src/types/storage/query/merchant_account.rs rename to crates/storage_models/src/query/merchant_account.rs index 3a4b3c72bd..0c0a07bab3 100644 --- a/crates/router/src/types/storage/query/merchant_account.rs +++ b/crates/storage_models/src/query/merchant_account.rs @@ -3,12 +3,12 @@ use router_env::tracing::{self, instrument}; use super::generics::{self, ExecuteQuery}; use crate::{ - connection::PgPooledConn, - core::errors::{self, CustomResult}, - schema::merchant_account::dsl, - types::storage::{ + errors, + merchant_account::{ MerchantAccount, MerchantAccountNew, MerchantAccountUpdate, MerchantAccountUpdateInternal, }, + schema::merchant_account::dsl, + CustomResult, PgPooledConn, }; impl MerchantAccountNew { @@ -16,7 +16,7 @@ impl MerchantAccountNew { pub async fn insert_diesel( self, conn: &PgPooledConn, - ) -> CustomResult { + ) -> CustomResult { generics::generic_insert::<_, _, MerchantAccount, _>(conn, self, ExecuteQuery::new()).await } } @@ -27,7 +27,7 @@ impl MerchantAccount { self, conn: &PgPooledConn, merchant_account: MerchantAccountUpdate, - ) -> CustomResult { + ) -> CustomResult { match generics::generic_update_by_id::<::Table, _, _, Self, _>( conn, self.id, @@ -37,9 +37,7 @@ impl MerchantAccount { .await { Err(error) => match error.current_context() { - errors::StorageError::DatabaseError(errors::DatabaseError::NoFieldsToUpdate) => { - Ok(self) - } + errors::DatabaseError::NoFieldsToUpdate => Ok(self), _ => Err(error), }, result => result, @@ -49,7 +47,7 @@ impl MerchantAccount { pub async fn delete_by_merchant_id( conn: &PgPooledConn, merchant_id: &str, - ) -> CustomResult { + ) -> CustomResult { generics::generic_delete::<::Table, _, _>( conn, dsl::merchant_id.eq(merchant_id.to_owned()), @@ -62,7 +60,7 @@ impl MerchantAccount { pub async fn find_by_merchant_id( conn: &PgPooledConn, merchant_id: &str, - ) -> CustomResult { + ) -> CustomResult { generics::generic_find_one::<::Table, _, _>( conn, dsl::merchant_id.eq(merchant_id.to_owned()), @@ -74,7 +72,7 @@ impl MerchantAccount { pub async fn find_by_api_key( conn: &PgPooledConn, api_key: &str, - ) -> CustomResult { + ) -> CustomResult { generics::generic_find_one::<::Table, _, _>( conn, dsl::api_key.eq(api_key.to_owned()), @@ -86,7 +84,7 @@ impl MerchantAccount { pub async fn find_by_publishable_key( conn: &PgPooledConn, publishable_key: &str, - ) -> CustomResult { + ) -> CustomResult { generics::generic_find_one::<::Table, _, _>( conn, dsl::publishable_key.eq(publishable_key.to_owned()), diff --git a/crates/router/src/types/storage/query/merchant_connector_account.rs b/crates/storage_models/src/query/merchant_connector_account.rs similarity index 83% rename from crates/router/src/types/storage/query/merchant_connector_account.rs rename to crates/storage_models/src/query/merchant_connector_account.rs index 5c967cd359..7767f26f92 100644 --- a/crates/router/src/types/storage/query/merchant_connector_account.rs +++ b/crates/storage_models/src/query/merchant_connector_account.rs @@ -3,13 +3,13 @@ use router_env::tracing::{self, instrument}; use super::generics::{self, ExecuteQuery}; use crate::{ - connection::PgPooledConn, - core::errors::{self, CustomResult}, - schema::merchant_connector_account::dsl, - types::storage::{ + errors, + merchant_connector_account::{ MerchantConnectorAccount, MerchantConnectorAccountNew, MerchantConnectorAccountUpdate, MerchantConnectorAccountUpdateInternal, }, + schema::merchant_connector_account::dsl, + CustomResult, PgPooledConn, }; impl MerchantConnectorAccountNew { @@ -17,7 +17,7 @@ impl MerchantConnectorAccountNew { pub async fn insert_diesel( self, conn: &PgPooledConn, - ) -> CustomResult { + ) -> CustomResult { generics::generic_insert::<_, _, MerchantConnectorAccount, _>( conn, self, @@ -33,7 +33,7 @@ impl MerchantConnectorAccount { self, conn: &PgPooledConn, merchant_connector_account: MerchantConnectorAccountUpdate, - ) -> CustomResult { + ) -> CustomResult { match generics::generic_update_by_id::<::Table, _, _, Self, _>( conn, self.id, @@ -43,9 +43,7 @@ impl MerchantConnectorAccount { .await { Err(error) => match error.current_context() { - errors::StorageError::DatabaseError(errors::DatabaseError::NoFieldsToUpdate) => { - Ok(self) - } + errors::DatabaseError::NoFieldsToUpdate => Ok(self), _ => Err(error), }, result => result, @@ -56,7 +54,7 @@ impl MerchantConnectorAccount { conn: &PgPooledConn, merchant_id: &str, merchant_connector_id: &i32, - ) -> CustomResult { + ) -> CustomResult { generics::generic_delete::<::Table, _, _>( conn, dsl::merchant_id @@ -72,7 +70,7 @@ impl MerchantConnectorAccount { conn: &PgPooledConn, merchant_id: &str, connector: &str, - ) -> CustomResult { + ) -> CustomResult { generics::generic_find_one::<::Table, _, _>( conn, dsl::merchant_id @@ -87,7 +85,7 @@ impl MerchantConnectorAccount { conn: &PgPooledConn, merchant_id: &str, merchant_connector_id: &i32, - ) -> CustomResult { + ) -> CustomResult { generics::generic_find_one::<::Table, _, _>( conn, dsl::merchant_id @@ -101,7 +99,7 @@ impl MerchantConnectorAccount { pub async fn find_by_merchant_id( conn: &PgPooledConn, merchant_id: &str, - ) -> CustomResult, errors::StorageError> { + ) -> CustomResult, errors::DatabaseError> { generics::generic_filter::<::Table, _, _>( conn, dsl::merchant_id.eq(merchant_id.to_owned()), diff --git a/crates/router/src/types/storage/query/payment_attempt.rs b/crates/storage_models/src/query/payment_attempt.rs similarity index 78% rename from crates/router/src/types/storage/query/payment_attempt.rs rename to crates/storage_models/src/query/payment_attempt.rs index e7d17d0b31..e3a44deb00 100644 --- a/crates/router/src/types/storage/query/payment_attempt.rs +++ b/crates/storage_models/src/query/payment_attempt.rs @@ -3,21 +3,19 @@ use diesel::{ associations::HasTable, debug_query, pg::Pg, BoolExpressionMethods, ExpressionMethods, QueryDsl, }; use error_stack::{IntoReport, ResultExt}; -use router_env::tracing::{self, instrument}; +use router_env::{ + logger::debug, + tracing::{self, instrument}, +}; -#[cfg(not(feature = "kv_store"))] -use super::generics::{self, ExecuteQuery}; -#[cfg(feature = "kv_store")] use super::generics::{self, ExecuteQuery, RawQuery, RawSqlQuery}; use crate::{ - connection::PgPooledConn, - core::errors::{self, CustomResult}, - logger::debug, - schema::payment_attempt::dsl, - types::storage::{ - enums, PaymentAttempt, PaymentAttemptNew, PaymentAttemptUpdate, - PaymentAttemptUpdateInternal, + enums, errors, + payment_attempt::{ + PaymentAttempt, PaymentAttemptNew, PaymentAttemptUpdate, PaymentAttemptUpdateInternal, }, + schema::payment_attempt::dsl, + CustomResult, PgPooledConn, }; impl PaymentAttemptNew { @@ -25,16 +23,15 @@ impl PaymentAttemptNew { pub async fn insert_diesel( self, conn: &PgPooledConn, - ) -> CustomResult { + ) -> CustomResult { generics::generic_insert::<_, _, PaymentAttempt, _>(conn, self, ExecuteQuery::new()).await } - #[cfg(feature = "kv_store")] #[instrument(skip(conn))] pub async fn insert_diesel_query( self, conn: &PgPooledConn, - ) -> CustomResult { + ) -> CustomResult { generics::generic_insert::<_, _, PaymentAttempt, _>(conn, self, RawQuery).await } } @@ -45,7 +42,7 @@ impl PaymentAttempt { self, conn: &PgPooledConn, payment_attempt: PaymentAttemptUpdate, - ) -> CustomResult { + ) -> CustomResult { match generics::generic_update_by_id::<::Table, _, _, Self, _>( conn, self.id, @@ -55,22 +52,19 @@ impl PaymentAttempt { .await { Err(error) => match error.current_context() { - errors::StorageError::DatabaseError(errors::DatabaseError::NoFieldsToUpdate) => { - Ok(self) - } + errors::DatabaseError::NoFieldsToUpdate => Ok(self), _ => Err(error), }, result => result, } } - #[cfg(feature = "kv_store")] #[instrument(skip(conn))] pub async fn update_query( self, conn: &PgPooledConn, payment_attempt: PaymentAttemptUpdate, - ) -> CustomResult { + ) -> CustomResult { generics::generic_update_by_id::<::Table, _, _, Self, _>( conn, self.id, @@ -85,7 +79,7 @@ impl PaymentAttempt { conn: &PgPooledConn, payment_id: &str, merchant_id: &str, - ) -> CustomResult { + ) -> CustomResult { generics::generic_find_one::<::Table, _, _>( conn, dsl::merchant_id @@ -100,7 +94,7 @@ impl PaymentAttempt { conn: &PgPooledConn, payment_id: &str, merchant_id: &str, - ) -> CustomResult, errors::StorageError> { + ) -> CustomResult, errors::DatabaseError> { generics::generic_find_one_optional::<::Table, _, _>( conn, dsl::merchant_id @@ -116,7 +110,7 @@ impl PaymentAttempt { transaction_id: &str, payment_id: &str, merchant_id: &str, - ) -> CustomResult { + ) -> CustomResult { generics::generic_find_one::<::Table, _, _>( conn, dsl::connector_transaction_id @@ -133,7 +127,7 @@ impl PaymentAttempt { conn: &PgPooledConn, payment_id: &str, merchant_id: &str, - ) -> CustomResult { + ) -> CustomResult { let query = Self::table() .filter( dsl::payment_id @@ -148,9 +142,7 @@ impl PaymentAttempt { .get_result_async(conn) .await .into_report() - .change_context(errors::StorageError::DatabaseError( - errors::DatabaseError::NotFound, - )) + .change_context(errors::DatabaseError::NotFound) .attach_printable("Error while finding last successful payment attempt") } @@ -159,7 +151,7 @@ impl PaymentAttempt { conn: &PgPooledConn, merchant_id: &str, connector_txn_id: &str, - ) -> CustomResult { + ) -> CustomResult { generics::generic_find_one::<::Table, _, _>( conn, dsl::merchant_id @@ -174,7 +166,7 @@ impl PaymentAttempt { conn: &PgPooledConn, merchant_id: &str, txn_id: &str, - ) -> CustomResult { + ) -> CustomResult { generics::generic_find_one::<::Table, _, _>( conn, dsl::merchant_id @@ -184,6 +176,3 @@ impl PaymentAttempt { .await } } - -#[cfg(feature = "kv_store")] -impl crate::utils::storage_partitioning::KvStorePartition for PaymentAttempt {} diff --git a/crates/storage_models/src/query/payment_intent.rs b/crates/storage_models/src/query/payment_intent.rs new file mode 100644 index 0000000000..fab006e06b --- /dev/null +++ b/crates/storage_models/src/query/payment_intent.rs @@ -0,0 +1,99 @@ +use diesel::{associations::HasTable, BoolExpressionMethods, ExpressionMethods}; +use router_env::tracing::{self, instrument}; + +use super::generics::{self, ExecuteQuery, RawQuery, RawSqlQuery}; +use crate::{ + errors, + payment_intent::{ + PaymentIntent, PaymentIntentNew, PaymentIntentUpdate, PaymentIntentUpdateInternal, + }, + schema::payment_intent::dsl, + CustomResult, PgPooledConn, +}; + +impl PaymentIntentNew { + #[instrument(skip(conn))] + pub async fn insert_diesel( + self, + conn: &PgPooledConn, + ) -> CustomResult { + generics::generic_insert::<_, _, PaymentIntent, _>(conn, self, ExecuteQuery::new()).await + } + + #[instrument(skip(conn))] + pub async fn insert_diesel_query( + self, + conn: &PgPooledConn, + ) -> CustomResult { + generics::generic_insert::<_, _, PaymentIntent, _>(conn, self, RawQuery).await + } +} + +impl PaymentIntent { + #[instrument(skip(conn))] + pub async fn update( + self, + conn: &PgPooledConn, + payment_intent: PaymentIntentUpdate, + ) -> CustomResult { + match generics::generic_update_by_id::<::Table, _, _, Self, _>( + conn, + self.id, + PaymentIntentUpdateInternal::from(payment_intent), + ExecuteQuery::new(), + ) + .await + { + Err(error) => match error.current_context() { + errors::DatabaseError::NoFieldsToUpdate => Ok(self), + _ => Err(error), + }, + result => result, + } + } + + #[instrument(skip(conn))] + pub async fn update_query( + self, + conn: &PgPooledConn, + payment_intent: PaymentIntentUpdate, + ) -> CustomResult { + generics::generic_update_by_id::<::Table, _, _, Self, _>( + conn, + self.id, + PaymentIntentUpdateInternal::from(payment_intent), + RawQuery, + ) + .await + } + + #[instrument(skip(conn))] + pub async fn find_by_payment_id_merchant_id( + conn: &PgPooledConn, + payment_id: &str, + merchant_id: &str, + ) -> CustomResult { + generics::generic_find_one::<::Table, _, _>( + conn, + dsl::merchant_id + .eq(merchant_id.to_owned()) + .and(dsl::payment_id.eq(payment_id.to_owned())), + ) + .await + } + + #[instrument(skip(conn))] + pub async fn find_optional_by_payment_id_merchant_id( + conn: &PgPooledConn, + payment_id: &str, + merchant_id: &str, + ) -> CustomResult, errors::DatabaseError> { + generics::generic_find_one_optional::<::Table, _, _>( + conn, + dsl::merchant_id + .eq(merchant_id.to_owned()) + .and(dsl::payment_id.eq(payment_id.to_owned())), + ) + .await + } +} diff --git a/crates/router/src/types/storage/query/payment_method.rs b/crates/storage_models/src/query/payment_method.rs similarity index 84% rename from crates/router/src/types/storage/query/payment_method.rs rename to crates/storage_models/src/query/payment_method.rs index 7ff79efd5a..f14be34421 100644 --- a/crates/router/src/types/storage/query/payment_method.rs +++ b/crates/storage_models/src/query/payment_method.rs @@ -4,10 +4,10 @@ use router_env::tracing::{self, instrument}; use super::generics::{self, ExecuteQuery}; use crate::{ - connection::PgPooledConn, - core::errors::{self, CustomResult}, + errors, + payment_method::{PaymentMethod, PaymentMethodNew}, schema::payment_methods::dsl, - types::storage::payment_method::{PaymentMethod, PaymentMethodNew}, + CustomResult, PgPooledConn, }; impl PaymentMethodNew { @@ -15,7 +15,7 @@ impl PaymentMethodNew { pub async fn insert( self, conn: &PgPooledConn, - ) -> CustomResult { + ) -> CustomResult { generics::generic_insert::<_, _, PaymentMethod, _>(conn, self, ExecuteQuery::new()).await } } @@ -25,7 +25,7 @@ impl PaymentMethod { pub async fn delete_by_payment_method_id( conn: &PgPooledConn, payment_method_id: String, - ) -> CustomResult { + ) -> CustomResult { let result = generics::generic_delete_one_with_result::<::Table, _, Self, _>( conn, @@ -42,7 +42,7 @@ impl PaymentMethod { conn: &PgPooledConn, merchant_id: &str, payment_method_id: &str, - ) -> CustomResult { + ) -> CustomResult { let result = generics::generic_delete_one_with_result::<::Table, _, Self, _>( conn, @@ -60,7 +60,7 @@ impl PaymentMethod { pub async fn find_by_payment_method_id( conn: &PgPooledConn, payment_method_id: &str, - ) -> CustomResult { + ) -> CustomResult { generics::generic_find_one::<::Table, _, _>( conn, dsl::payment_method_id.eq(payment_method_id.to_owned()), @@ -72,7 +72,7 @@ impl PaymentMethod { pub async fn find_by_merchant_id( conn: &PgPooledConn, merchant_id: &str, - ) -> CustomResult, errors::StorageError> { + ) -> CustomResult, errors::DatabaseError> { generics::generic_filter::<::Table, _, _>( conn, dsl::merchant_id.eq(merchant_id.to_owned()), @@ -86,7 +86,7 @@ impl PaymentMethod { conn: &PgPooledConn, customer_id: &str, merchant_id: &str, - ) -> CustomResult, errors::StorageError> { + ) -> CustomResult, errors::DatabaseError> { generics::generic_filter::<::Table, _, _>( conn, dsl::customer_id diff --git a/crates/router/src/types/storage/query/process_tracker.rs b/crates/storage_models/src/query/process_tracker.rs similarity index 80% rename from crates/router/src/types/storage/query/process_tracker.rs rename to crates/storage_models/src/query/process_tracker.rs index c8de65d221..4962f45db6 100644 --- a/crates/router/src/types/storage/query/process_tracker.rs +++ b/crates/storage_models/src/query/process_tracker.rs @@ -3,19 +3,20 @@ use diesel::{ associations::HasTable, debug_query, pg::Pg, BoolExpressionMethods, ExpressionMethods, QueryDsl, }; use error_stack::{IntoReport, ResultExt}; -use router_env::tracing::{self, instrument}; +use router_env::{ + logger::debug, + tracing::{self, instrument}, +}; use time::PrimitiveDateTime; use super::generics::{self, ExecuteQuery}; use crate::{ - connection::{PgPool, PgPooledConn}, - core::errors::{self, CustomResult}, - logger::debug, - schema::process_tracker::dsl, - types::storage::{ - enums, ProcessTracker, ProcessTrackerNew, ProcessTrackerUpdate, - ProcessTrackerUpdateInternal, + enums, errors, + process_tracker::{ + ProcessTracker, ProcessTrackerNew, ProcessTrackerUpdate, ProcessTrackerUpdateInternal, }, + schema::process_tracker::dsl, + CustomResult, PgPooledConn, }; impl ProcessTrackerNew { @@ -23,7 +24,7 @@ impl ProcessTrackerNew { pub async fn insert_process( self, conn: &PgPooledConn, - ) -> CustomResult { + ) -> CustomResult { generics::generic_insert::<_, _, ProcessTracker, _>(conn, self, ExecuteQuery::new()).await } } @@ -34,7 +35,7 @@ impl ProcessTracker { self, conn: &PgPooledConn, process: ProcessTrackerUpdate, - ) -> CustomResult { + ) -> CustomResult { match generics::generic_update_by_id::<::Table, _, _, Self, _>( conn, self.id.clone(), @@ -44,9 +45,7 @@ impl ProcessTracker { .await { Err(error) => match error.current_context() { - errors::StorageError::DatabaseError(errors::DatabaseError::NoFieldsToUpdate) => { - Ok(self) - } + errors::DatabaseError::NoFieldsToUpdate => Ok(self), _ => Err(error), }, result => result, @@ -58,7 +57,7 @@ impl ProcessTracker { conn: &PgPooledConn, task_ids: Vec, task_update: ProcessTrackerUpdate, - ) -> CustomResult, errors::StorageError> { + ) -> CustomResult, errors::DatabaseError> { // TODO: Possible optimization: Instead of returning updated values from database, update // the values in code and return them, if database query executed successfully. generics::generic_update_with_results::<::Table, _, _, Self, _>( @@ -74,7 +73,7 @@ impl ProcessTracker { pub async fn find_process_by_id( conn: &PgPooledConn, id: &str, - ) -> CustomResult, errors::StorageError> { + ) -> CustomResult, errors::DatabaseError> { generics::generic_find_by_id_optional::<::Table, _, _>( conn, id.to_owned(), @@ -89,7 +88,7 @@ impl ProcessTracker { time_upper_limit: PrimitiveDateTime, status: enums::ProcessTrackerStatus, limit: Option, - ) -> CustomResult, errors::StorageError> { + ) -> CustomResult, errors::DatabaseError> { generics::generic_filter::<::Table, _, _>( conn, dsl::schedule_time @@ -103,12 +102,12 @@ impl ProcessTracker { // FIXME with generics #[instrument(skip(pool))] pub async fn find_processes_to_clean( - pool: &PgPool, + pool: &PgPooledConn, time_lower_limit: PrimitiveDateTime, time_upper_limit: PrimitiveDateTime, runner: &str, limit: i64, - ) -> CustomResult, errors::StorageError> { + ) -> CustomResult, errors::DatabaseError> { let query = Self::table() .filter(dsl::schedule_time.between(time_lower_limit, time_upper_limit)) .filter(dsl::status.eq(enums::ProcessTrackerStatus::ProcessStarted)) @@ -121,9 +120,7 @@ impl ProcessTracker { .get_results_async(pool) .await .into_report() - .change_context(errors::StorageError::DatabaseError( - errors::DatabaseError::NotFound, - )) + .change_context(errors::DatabaseError::NotFound) .attach_printable_lazy(|| "Error finding processes to clean") } @@ -132,7 +129,7 @@ impl ProcessTracker { conn: &PgPooledConn, ids: Vec, schedule_time: PrimitiveDateTime, - ) -> CustomResult { + ) -> CustomResult { generics::generic_update::<::Table, _, _, _>( conn, dsl::status diff --git a/crates/router/src/types/storage/query/refund.rs b/crates/storage_models/src/query/refund.rs similarity index 82% rename from crates/router/src/types/storage/query/refund.rs rename to crates/storage_models/src/query/refund.rs index 0e9f50d5f7..2ab12e637b 100644 --- a/crates/router/src/types/storage/query/refund.rs +++ b/crates/storage_models/src/query/refund.rs @@ -3,17 +3,17 @@ use router_env::{tracing, tracing::instrument}; use super::generics::{self, ExecuteQuery}; use crate::{ - connection::PgPooledConn, - core::errors::{self, CustomResult}, + errors, + refund::{Refund, RefundNew, RefundUpdate, RefundUpdateInternal}, schema::refund::dsl, - types::storage::{Refund, RefundNew, RefundUpdate, RefundUpdateInternal}, + CustomResult, PgPooledConn, }; // FIXME: Find by partition key impl RefundNew { #[instrument(skip(conn))] - pub async fn insert(self, conn: &PgPooledConn) -> CustomResult { + pub async fn insert(self, conn: &PgPooledConn) -> CustomResult { generics::generic_insert::<_, _, Refund, _>(conn, self, ExecuteQuery::new()).await } } @@ -24,7 +24,7 @@ impl Refund { self, conn: &PgPooledConn, refund: RefundUpdate, - ) -> CustomResult { + ) -> CustomResult { match generics::generic_update_by_id::<::Table, _, _, Self, _>( conn, self.id, @@ -34,9 +34,7 @@ impl Refund { .await { Err(error) => match error.current_context() { - errors::StorageError::DatabaseError(errors::DatabaseError::NoFieldsToUpdate) => { - Ok(self) - } + errors::DatabaseError::NoFieldsToUpdate => Ok(self), _ => Err(error), }, result => result, @@ -49,7 +47,7 @@ impl Refund { conn: &PgPooledConn, merchant_id: &str, refund_id: &str, - ) -> CustomResult { + ) -> CustomResult { generics::generic_find_one::<::Table, _, _>( conn, dsl::merchant_id @@ -64,7 +62,7 @@ impl Refund { conn: &PgPooledConn, internal_reference_id: &str, merchant_id: &str, - ) -> CustomResult { + ) -> CustomResult { generics::generic_find_one::<::Table, _, _>( conn, dsl::merchant_id @@ -79,7 +77,7 @@ impl Refund { conn: &PgPooledConn, merchant_id: &str, txn_id: &str, - ) -> CustomResult, errors::StorageError> { + ) -> CustomResult, errors::DatabaseError> { generics::generic_filter::<::Table, _, _>( conn, dsl::merchant_id @@ -95,7 +93,7 @@ impl Refund { conn: &PgPooledConn, payment_id: &str, merchant_id: &str, - ) -> CustomResult, errors::StorageError> { + ) -> CustomResult, errors::DatabaseError> { generics::generic_filter::<::Table, _, _>( conn, dsl::merchant_id diff --git a/crates/router/src/types/storage/query/temp_card.rs b/crates/storage_models/src/query/temp_card.rs similarity index 78% rename from crates/router/src/types/storage/query/temp_card.rs rename to crates/storage_models/src/query/temp_card.rs index 33b1643fa8..1d5335254f 100644 --- a/crates/router/src/types/storage/query/temp_card.rs +++ b/crates/storage_models/src/query/temp_card.rs @@ -3,10 +3,10 @@ use router_env::tracing::{self, instrument}; use super::generics::{self, ExecuteQuery}; use crate::{ - connection::PgPooledConn, - core::errors::{self, CustomResult}, + errors, schema::temp_card::dsl, - types::storage::{TempCard, TempCardNew}, + temp_card::{TempCard, TempCardNew}, + CustomResult, PgPooledConn, }; impl TempCardNew { @@ -14,7 +14,7 @@ impl TempCardNew { pub async fn insert_diesel( self, conn: &PgPooledConn, - ) -> CustomResult { + ) -> CustomResult { generics::generic_insert::<_, _, TempCard, _>(conn, self, ExecuteQuery::new()).await } } @@ -24,7 +24,7 @@ impl TempCard { pub async fn insert_with_token( self, conn: &PgPooledConn, - ) -> CustomResult { + ) -> CustomResult { generics::generic_insert::<_, _, TempCard, _>(conn, self, ExecuteQuery::new()).await } @@ -32,7 +32,7 @@ impl TempCard { pub async fn find_by_transaction_id( conn: &PgPooledConn, transaction_id: &str, - ) -> CustomResult, errors::StorageError> { + ) -> CustomResult, errors::DatabaseError> { generics::generic_find_one_optional::<::Table, _, _>( conn, dsl::txn_id.eq(transaction_id.to_owned()), @@ -44,7 +44,7 @@ impl TempCard { pub async fn find_by_token( conn: &PgPooledConn, token: &i32, - ) -> CustomResult { + ) -> CustomResult { generics::generic_find_one::<::Table, _, _>( conn, dsl::id.eq(token.to_owned()), diff --git a/crates/storage_models/src/refund.rs b/crates/storage_models/src/refund.rs new file mode 100644 index 0000000000..adf189665a --- /dev/null +++ b/crates/storage_models/src/refund.rs @@ -0,0 +1,141 @@ +use diesel::{AsChangeset, Identifiable, Insertable, Queryable}; +use serde::{Deserialize, Serialize}; +use time::PrimitiveDateTime; + +use crate::{enums as storage_enums, schema::refund}; + +#[derive(Clone, Debug, Eq, Identifiable, Queryable, PartialEq)] +#[diesel(table_name = refund)] +pub struct Refund { + pub id: i32, + pub internal_reference_id: String, + pub refund_id: String, //merchant_reference id + pub payment_id: String, + pub merchant_id: String, + pub transaction_id: String, + pub connector: String, + pub pg_refund_id: Option, + pub external_reference_id: Option, + pub refund_type: storage_enums::RefundType, + pub total_amount: i32, + pub currency: storage_enums::Currency, + pub refund_amount: i32, + pub refund_status: storage_enums::RefundStatus, + pub sent_to_gateway: bool, + pub refund_error_message: Option, + pub metadata: Option, + pub refund_arn: Option, + pub created_at: PrimitiveDateTime, + pub updated_at: PrimitiveDateTime, + pub description: Option, +} + +#[derive(Clone, Debug, Default, Eq, PartialEq, Insertable, router_derive::DebugAsDisplay)] +#[diesel(table_name = refund)] +pub struct RefundNew { + pub refund_id: String, + pub payment_id: String, + pub merchant_id: String, + pub internal_reference_id: String, + pub external_reference_id: Option, + pub transaction_id: String, + pub connector: String, + pub pg_refund_id: Option, + pub refund_type: storage_enums::RefundType, + pub total_amount: i32, + pub currency: storage_enums::Currency, + pub refund_amount: i32, + pub refund_status: storage_enums::RefundStatus, + pub sent_to_gateway: bool, + pub refund_error_message: Option, + pub metadata: Option, + pub refund_arn: Option, + pub created_at: Option, + pub modified_at: Option, + pub description: Option, +} + +#[derive(Debug)] +pub enum RefundUpdate { + Update { + pg_refund_id: String, + refund_status: storage_enums::RefundStatus, + sent_to_gateway: bool, + refund_error_message: Option, + refund_arn: String, + }, + MetadataUpdate { + metadata: Option, + }, + StatusUpdate { + pg_refund_id: Option, + sent_to_gateway: bool, + refund_status: storage_enums::RefundStatus, + }, + ErrorUpdate { + refund_status: Option, + refund_error_message: Option, + }, +} + +#[derive(Clone, Debug, Default, AsChangeset, router_derive::DebugAsDisplay)] +#[diesel(table_name = refund)] +pub struct RefundUpdateInternal { + pg_refund_id: Option, + refund_status: Option, + sent_to_gateway: Option, + refund_error_message: Option, + refund_arn: Option, + metadata: Option, +} + +impl From for RefundUpdateInternal { + fn from(refund_update: RefundUpdate) -> Self { + match refund_update { + RefundUpdate::Update { + pg_refund_id, + refund_status, + sent_to_gateway, + refund_error_message, + refund_arn, + } => Self { + pg_refund_id: Some(pg_refund_id), + refund_status: Some(refund_status), + sent_to_gateway: Some(sent_to_gateway), + refund_error_message, + refund_arn: Some(refund_arn), + ..Default::default() + }, + RefundUpdate::MetadataUpdate { metadata } => Self { + metadata, + ..Default::default() + }, + RefundUpdate::StatusUpdate { + pg_refund_id, + sent_to_gateway, + refund_status, + } => Self { + pg_refund_id, + sent_to_gateway: Some(sent_to_gateway), + refund_status: Some(refund_status), + ..Default::default() + }, + RefundUpdate::ErrorUpdate { + refund_status, + refund_error_message, + } => Self { + refund_status, + refund_error_message, + ..Default::default() + }, + } + } +} + +#[derive(Debug, Eq, PartialEq, Deserialize, Serialize)] +pub struct RefundCoreWorkflow { + pub refund_internal_reference_id: String, + pub transaction_id: String, + pub merchant_id: String, + pub payment_id: String, +} diff --git a/crates/router/src/schema.rs b/crates/storage_models/src/schema.rs similarity index 92% rename from crates/router/src/schema.rs rename to crates/storage_models/src/schema.rs index 218c2305bc..85b5be3ee5 100644 --- a/crates/router/src/schema.rs +++ b/crates/storage_models/src/schema.rs @@ -2,7 +2,7 @@ diesel::table! { use diesel::sql_types::*; - use crate::types::storage::enums::diesel_exports::*; + use crate::enums::diesel_exports::*; address (address_id) { id -> Int4, @@ -27,7 +27,7 @@ diesel::table! { diesel::table! { use diesel::sql_types::*; - use crate::types::storage::enums::diesel_exports::*; + use crate::enums::diesel_exports::*; configs (key) { id -> Int4, @@ -38,7 +38,7 @@ diesel::table! { diesel::table! { use diesel::sql_types::*; - use crate::types::storage::enums::diesel_exports::*; + use crate::enums::diesel_exports::*; connector_response (id) { id -> Int4, @@ -56,7 +56,7 @@ diesel::table! { diesel::table! { use diesel::sql_types::*; - use crate::types::storage::enums::diesel_exports::*; + use crate::enums::diesel_exports::*; customers (customer_id, merchant_id) { id -> Int4, @@ -74,7 +74,7 @@ diesel::table! { diesel::table! { use diesel::sql_types::*; - use crate::types::storage::enums::diesel_exports::*; + use crate::enums::diesel_exports::*; events (id) { id -> Int4, @@ -91,7 +91,7 @@ diesel::table! { diesel::table! { use diesel::sql_types::*; - use crate::types::storage::enums::diesel_exports::*; + use crate::enums::diesel_exports::*; locker_mock_up (id) { id -> Int4, @@ -112,7 +112,7 @@ diesel::table! { diesel::table! { use diesel::sql_types::*; - use crate::types::storage::enums::diesel_exports::*; + use crate::enums::diesel_exports::*; mandate (id) { id -> Int4, @@ -138,7 +138,7 @@ diesel::table! { diesel::table! { use diesel::sql_types::*; - use crate::types::storage::enums::diesel_exports::*; + use crate::enums::diesel_exports::*; merchant_account (id) { id -> Int4, @@ -162,7 +162,7 @@ diesel::table! { diesel::table! { use diesel::sql_types::*; - use crate::types::storage::enums::diesel_exports::*; + use crate::enums::diesel_exports::*; merchant_connector_account (id) { id -> Int4, @@ -179,7 +179,7 @@ diesel::table! { diesel::table! { use diesel::sql_types::*; - use crate::types::storage::enums::diesel_exports::*; + use crate::enums::diesel_exports::*; payment_attempt (id) { id -> Int4, @@ -216,7 +216,7 @@ diesel::table! { diesel::table! { use diesel::sql_types::*; - use crate::types::storage::enums::diesel_exports::*; + use crate::enums::diesel_exports::*; payment_intent (id) { id -> Int4, @@ -246,7 +246,7 @@ diesel::table! { diesel::table! { use diesel::sql_types::*; - use crate::types::storage::enums::diesel_exports::*; + use crate::enums::diesel_exports::*; payment_methods (id) { id -> Int4, @@ -275,7 +275,7 @@ diesel::table! { diesel::table! { use diesel::sql_types::*; - use crate::types::storage::enums::diesel_exports::*; + use crate::enums::diesel_exports::*; process_tracker (id) { id -> Varchar, @@ -296,7 +296,7 @@ diesel::table! { diesel::table! { use diesel::sql_types::*; - use crate::types::storage::enums::diesel_exports::*; + use crate::enums::diesel_exports::*; refund (id) { id -> Int4, @@ -325,7 +325,7 @@ diesel::table! { diesel::table! { use diesel::sql_types::*; - use crate::types::storage::enums::diesel_exports::*; + use crate::enums::diesel_exports::*; temp_card (id) { id -> Int4, diff --git a/crates/storage_models/src/temp_card.rs b/crates/storage_models/src/temp_card.rs new file mode 100644 index 0000000000..6b036ef8d9 --- /dev/null +++ b/crates/storage_models/src/temp_card.rs @@ -0,0 +1,23 @@ +use diesel::{Identifiable, Insertable, Queryable}; +use serde_json::Value; +use time::PrimitiveDateTime; + +use crate::schema::temp_card; + +#[derive(Clone, Debug, router_derive::DebugAsDisplay, Queryable, Identifiable, Insertable)] +#[diesel(table_name = temp_card)] +pub struct TempCard { + pub id: i32, + pub date_created: PrimitiveDateTime, + pub txn_id: Option, + pub card_info: Option, +} + +#[derive(Clone, Debug, Insertable, router_derive::DebugAsDisplay)] +#[diesel(table_name = temp_card)] +pub struct TempCardNew { + pub id: Option, + pub card_info: Option, + pub date_created: PrimitiveDateTime, + pub txn_id: Option, +} diff --git a/diesel.toml b/diesel.toml index e0e69483d5..61cc07378a 100644 --- a/diesel.toml +++ b/diesel.toml @@ -2,6 +2,6 @@ # see diesel.rs/guides/configuring-diesel-cli [print_schema] -file = "crates/router/src/schema.rs" -import_types = ["diesel::sql_types::*", "crate::types::storage::enums::diesel_exports::*"] +file = "crates/storage_models/src/schema.rs" +import_types = ["diesel::sql_types::*", "crate::enums::diesel_exports::*"] generate_missing_sql_type_definitions = false