Files
hyperswitch/crates/storage_models/src/payment_intent.rs

308 lines
11 KiB
Rust

use common_utils::pii;
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: i64,
pub currency: Option<storage_enums::Currency>,
pub amount_captured: Option<i64>,
pub customer_id: Option<String>,
pub description: Option<String>,
pub return_url: Option<String>,
pub metadata: Option<pii::SecretSerdeValue>,
pub connector_id: Option<String>,
pub shipping_address_id: Option<String>,
pub billing_address_id: Option<String>,
pub statement_descriptor_name: Option<String>,
pub statement_descriptor_suffix: Option<String>,
#[serde(with = "common_utils::custom_serde::iso8601")]
pub created_at: PrimitiveDateTime,
#[serde(with = "common_utils::custom_serde::iso8601")]
pub modified_at: PrimitiveDateTime,
#[serde(default, with = "common_utils::custom_serde::iso8601::option")]
pub last_synced: Option<PrimitiveDateTime>,
pub setup_future_usage: Option<storage_enums::FutureUsage>,
pub off_session: Option<bool>,
pub client_secret: Option<String>,
pub active_attempt_id: String,
pub business_country: storage_enums::CountryAlpha2,
pub business_label: String,
pub meta_data: Option<pii::SecretSerdeValue>,
}
#[derive(
Clone,
Debug,
Default,
Eq,
PartialEq,
Insertable,
router_derive::DebugAsDisplay,
Serialize,
Deserialize,
)]
#[diesel(table_name = payment_intent)]
pub struct PaymentIntentNew {
pub payment_id: String,
pub merchant_id: String,
pub status: storage_enums::IntentStatus,
pub amount: i64,
pub currency: Option<storage_enums::Currency>,
pub amount_captured: Option<i64>,
pub customer_id: Option<String>,
pub description: Option<String>,
pub return_url: Option<String>,
pub metadata: Option<pii::SecretSerdeValue>,
pub connector_id: Option<String>,
pub shipping_address_id: Option<String>,
pub billing_address_id: Option<String>,
pub statement_descriptor_name: Option<String>,
pub statement_descriptor_suffix: Option<String>,
#[serde(default, with = "common_utils::custom_serde::iso8601::option")]
pub created_at: Option<PrimitiveDateTime>,
#[serde(default, with = "common_utils::custom_serde::iso8601::option")]
pub modified_at: Option<PrimitiveDateTime>,
#[serde(default, with = "common_utils::custom_serde::iso8601::option")]
pub last_synced: Option<PrimitiveDateTime>,
pub setup_future_usage: Option<storage_enums::FutureUsage>,
pub off_session: Option<bool>,
pub client_secret: Option<String>,
pub active_attempt_id: String,
pub business_country: storage_enums::CountryAlpha2,
pub business_label: String,
pub meta_data: Option<pii::SecretSerdeValue>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum PaymentIntentUpdate {
ResponseUpdate {
status: storage_enums::IntentStatus,
amount_captured: Option<i64>,
return_url: Option<String>,
},
MetadataUpdate {
metadata: pii::SecretSerdeValue,
meta_data: pii::SecretSerdeValue,
},
ReturnUrlUpdate {
return_url: Option<String>,
status: Option<storage_enums::IntentStatus>,
customer_id: Option<String>,
shipping_address_id: Option<String>,
billing_address_id: Option<String>,
},
MerchantStatusUpdate {
status: storage_enums::IntentStatus,
shipping_address_id: Option<String>,
billing_address_id: Option<String>,
},
PGStatusUpdate {
status: storage_enums::IntentStatus,
},
Update {
amount: i64,
currency: storage_enums::Currency,
setup_future_usage: Option<storage_enums::FutureUsage>,
status: storage_enums::IntentStatus,
customer_id: Option<String>,
shipping_address_id: Option<String>,
billing_address_id: Option<String>,
return_url: Option<String>,
business_country: Option<storage_enums::CountryAlpha2>,
business_label: Option<String>,
},
PaymentAttemptUpdate {
active_attempt_id: String,
},
StatusAndAttemptUpdate {
status: storage_enums::IntentStatus,
active_attempt_id: String,
},
}
#[derive(Clone, Debug, Default, AsChangeset, router_derive::DebugAsDisplay)]
#[diesel(table_name = payment_intent)]
pub struct PaymentIntentUpdateInternal {
pub amount: Option<i64>,
pub currency: Option<storage_enums::Currency>,
pub status: Option<storage_enums::IntentStatus>,
pub amount_captured: Option<i64>,
pub customer_id: Option<String>,
pub return_url: Option<String>,
pub setup_future_usage: Option<storage_enums::FutureUsage>,
pub off_session: Option<bool>,
pub metadata: Option<pii::SecretSerdeValue>,
pub client_secret: Option<Option<String>>,
pub billing_address_id: Option<String>,
pub shipping_address_id: Option<String>,
pub modified_at: Option<PrimitiveDateTime>,
pub active_attempt_id: Option<String>,
pub business_country: Option<storage_enums::CountryAlpha2>,
pub business_label: Option<String>,
pub meta_data: Option<pii::SecretSerdeValue>,
}
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(),
meta_data: internal_update.meta_data.or(source.meta_data),
..source
}
}
}
impl From<PaymentIntentUpdate> for PaymentIntentUpdateInternal {
fn from(payment_intent_update: PaymentIntentUpdate) -> Self {
match payment_intent_update {
PaymentIntentUpdate::Update {
amount,
currency,
setup_future_usage,
status,
customer_id,
shipping_address_id,
billing_address_id,
return_url,
business_country,
business_label,
} => Self {
amount: Some(amount),
currency: Some(currency),
status: Some(status),
setup_future_usage,
customer_id,
client_secret: make_client_secret_null_based_on_status(status),
shipping_address_id,
billing_address_id,
modified_at: Some(common_utils::date_time::now()),
return_url,
business_country,
business_label,
..Default::default()
},
PaymentIntentUpdate::MetadataUpdate {
metadata,
meta_data,
} => Self {
metadata: Some(metadata),
meta_data: Some(meta_data),
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: status.and_then(make_client_secret_null_based_on_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()),
client_secret: make_client_secret_null_based_on_status(status),
..Default::default()
},
PaymentIntentUpdate::MerchantStatusUpdate {
status,
shipping_address_id,
billing_address_id,
} => Self {
status: Some(status),
client_secret: make_client_secret_null_based_on_status(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_based_on_status(status),
modified_at: Some(common_utils::date_time::now()),
..Default::default()
},
PaymentIntentUpdate::PaymentAttemptUpdate { active_attempt_id } => Self {
active_attempt_id: Some(active_attempt_id),
..Default::default()
},
PaymentIntentUpdate::StatusAndAttemptUpdate {
status,
active_attempt_id,
} => Self {
status: Some(status),
active_attempt_id: Some(active_attempt_id),
..Default::default()
},
}
}
}
fn make_client_secret_null_based_on_status(
status: storage_enums::IntentStatus,
) -> Option<Option<String>> {
match status {
storage_enums::IntentStatus::Succeeded | storage_enums::IntentStatus::Cancelled => {
Some(None)
}
storage_enums::IntentStatus::Processing
| storage_enums::IntentStatus::RequiresCustomerAction
| storage_enums::IntentStatus::RequiresMerchantAction
| storage_enums::IntentStatus::RequiresPaymentMethod
| storage_enums::IntentStatus::RequiresConfirmation
| storage_enums::IntentStatus::RequiresCapture
| storage_enums::IntentStatus::Failed => None,
}
}