mirror of
https://github.com/juspay/hyperswitch.git
synced 2025-11-02 21:07:58 +08:00
Co-authored-by: hyperswitch-bot[bot] <148525504+hyperswitch-bot[bot]@users.noreply.github.com>
299 lines
11 KiB
Rust
299 lines
11 KiB
Rust
use error_stack::ResultExt;
|
|
use serde::{Deserialize, Serialize};
|
|
|
|
#[cfg(feature = "v2")]
|
|
use crate::payment_attempt::PaymentAttemptUpdateInternal;
|
|
#[cfg(feature = "v1")]
|
|
use crate::payment_intent::PaymentIntentUpdate;
|
|
#[cfg(feature = "v2")]
|
|
use crate::payment_intent::PaymentIntentUpdateInternal;
|
|
use crate::{
|
|
address::{Address, AddressNew, AddressUpdateInternal},
|
|
customers::{Customer, CustomerNew, CustomerUpdateInternal},
|
|
errors,
|
|
payment_attempt::{PaymentAttempt, PaymentAttemptNew, PaymentAttemptUpdate},
|
|
payment_intent::PaymentIntentNew,
|
|
payout_attempt::{PayoutAttempt, PayoutAttemptNew, PayoutAttemptUpdate},
|
|
payouts::{Payouts, PayoutsNew, PayoutsUpdate},
|
|
refund::{Refund, RefundNew, RefundUpdate},
|
|
reverse_lookup::{ReverseLookup, ReverseLookupNew},
|
|
Mandate, MandateNew, MandateUpdateInternal, PaymentIntent, PaymentMethod, PaymentMethodNew,
|
|
PaymentMethodUpdateInternal, PgPooledConn,
|
|
};
|
|
|
|
#[derive(Debug, Serialize, Deserialize)]
|
|
#[serde(rename_all = "snake_case", tag = "db_op", content = "data")]
|
|
pub enum DBOperation {
|
|
Insert { insertable: Box<Insertable> },
|
|
Update { updatable: Box<Updateable> },
|
|
}
|
|
|
|
impl DBOperation {
|
|
pub fn operation<'a>(&self) -> &'a str {
|
|
match self {
|
|
Self::Insert { .. } => "insert",
|
|
Self::Update { .. } => "update",
|
|
}
|
|
}
|
|
pub fn table<'a>(&self) -> &'a str {
|
|
match self {
|
|
Self::Insert { insertable } => match **insertable {
|
|
Insertable::PaymentIntent(_) => "payment_intent",
|
|
Insertable::PaymentAttempt(_) => "payment_attempt",
|
|
Insertable::Refund(_) => "refund",
|
|
Insertable::Address(_) => "address",
|
|
Insertable::Payouts(_) => "payouts",
|
|
Insertable::PayoutAttempt(_) => "payout_attempt",
|
|
Insertable::Customer(_) => "customer",
|
|
Insertable::ReverseLookUp(_) => "reverse_lookup",
|
|
Insertable::PaymentMethod(_) => "payment_method",
|
|
Insertable::Mandate(_) => "mandate",
|
|
},
|
|
Self::Update { updatable } => match **updatable {
|
|
Updateable::PaymentIntentUpdate(_) => "payment_intent",
|
|
Updateable::PaymentAttemptUpdate(_) => "payment_attempt",
|
|
Updateable::RefundUpdate(_) => "refund",
|
|
Updateable::CustomerUpdate(_) => "customer",
|
|
Updateable::AddressUpdate(_) => "address",
|
|
Updateable::PayoutsUpdate(_) => "payouts",
|
|
Updateable::PayoutAttemptUpdate(_) => "payout_attempt",
|
|
Updateable::PaymentMethodUpdate(_) => "payment_method",
|
|
Updateable::MandateUpdate(_) => " mandate",
|
|
},
|
|
}
|
|
}
|
|
}
|
|
|
|
#[derive(Debug)]
|
|
pub enum DBResult {
|
|
PaymentIntent(Box<PaymentIntent>),
|
|
PaymentAttempt(Box<PaymentAttempt>),
|
|
Refund(Box<Refund>),
|
|
Address(Box<Address>),
|
|
Customer(Box<Customer>),
|
|
ReverseLookUp(Box<ReverseLookup>),
|
|
Payouts(Box<Payouts>),
|
|
PayoutAttempt(Box<PayoutAttempt>),
|
|
PaymentMethod(Box<PaymentMethod>),
|
|
Mandate(Box<Mandate>),
|
|
}
|
|
|
|
#[derive(Debug, Serialize, Deserialize)]
|
|
pub struct TypedSql {
|
|
#[serde(flatten)]
|
|
pub op: DBOperation,
|
|
}
|
|
|
|
impl DBOperation {
|
|
pub async fn execute(self, conn: &PgPooledConn) -> crate::StorageResult<DBResult> {
|
|
Ok(match self {
|
|
Self::Insert { insertable } => match *insertable {
|
|
Insertable::PaymentIntent(a) => {
|
|
DBResult::PaymentIntent(Box::new(a.insert(conn).await?))
|
|
}
|
|
Insertable::PaymentAttempt(a) => {
|
|
DBResult::PaymentAttempt(Box::new(a.insert(conn).await?))
|
|
}
|
|
Insertable::Refund(a) => DBResult::Refund(Box::new(a.insert(conn).await?)),
|
|
Insertable::Address(addr) => DBResult::Address(Box::new(addr.insert(conn).await?)),
|
|
Insertable::Customer(cust) => {
|
|
DBResult::Customer(Box::new(cust.insert(conn).await?))
|
|
}
|
|
Insertable::ReverseLookUp(rev) => {
|
|
DBResult::ReverseLookUp(Box::new(rev.insert(conn).await?))
|
|
}
|
|
Insertable::Payouts(rev) => DBResult::Payouts(Box::new(rev.insert(conn).await?)),
|
|
Insertable::PayoutAttempt(rev) => {
|
|
DBResult::PayoutAttempt(Box::new(rev.insert(conn).await?))
|
|
}
|
|
Insertable::PaymentMethod(rev) => {
|
|
DBResult::PaymentMethod(Box::new(rev.insert(conn).await?))
|
|
}
|
|
Insertable::Mandate(m) => DBResult::Mandate(Box::new(m.insert(conn).await?)),
|
|
},
|
|
Self::Update { updatable } => match *updatable {
|
|
#[cfg(feature = "v1")]
|
|
Updateable::PaymentIntentUpdate(a) => {
|
|
DBResult::PaymentIntent(Box::new(a.orig.update(conn, a.update_data).await?))
|
|
}
|
|
#[cfg(feature = "v2")]
|
|
Updateable::PaymentIntentUpdate(a) => {
|
|
DBResult::PaymentIntent(Box::new(a.orig.update(conn, a.update_data).await?))
|
|
}
|
|
#[cfg(feature = "v1")]
|
|
Updateable::PaymentAttemptUpdate(a) => DBResult::PaymentAttempt(Box::new(
|
|
a.orig.update_with_attempt_id(conn, a.update_data).await?,
|
|
)),
|
|
#[cfg(feature = "v2")]
|
|
Updateable::PaymentAttemptUpdate(a) => DBResult::PaymentAttempt(Box::new(
|
|
a.orig
|
|
.update_with_attempt_id(
|
|
conn,
|
|
PaymentAttemptUpdateInternal::from(a.update_data),
|
|
)
|
|
.await?,
|
|
)),
|
|
Updateable::RefundUpdate(a) => {
|
|
DBResult::Refund(Box::new(a.orig.update(conn, a.update_data).await?))
|
|
}
|
|
Updateable::AddressUpdate(a) => {
|
|
DBResult::Address(Box::new(a.orig.update(conn, a.update_data).await?))
|
|
}
|
|
Updateable::PayoutsUpdate(a) => {
|
|
DBResult::Payouts(Box::new(a.orig.update(conn, a.update_data).await?))
|
|
}
|
|
Updateable::PayoutAttemptUpdate(a) => DBResult::PayoutAttempt(Box::new(
|
|
a.orig.update_with_attempt_id(conn, a.update_data).await?,
|
|
)),
|
|
#[cfg(all(
|
|
any(feature = "v1", feature = "v2"),
|
|
not(feature = "payment_methods_v2")
|
|
))]
|
|
Updateable::PaymentMethodUpdate(v) => DBResult::PaymentMethod(Box::new(
|
|
v.orig
|
|
.update_with_payment_method_id(conn, v.update_data)
|
|
.await?,
|
|
)),
|
|
#[cfg(all(feature = "v2", feature = "payment_methods_v2"))]
|
|
Updateable::PaymentMethodUpdate(v) => DBResult::PaymentMethod(Box::new(
|
|
v.orig.update_with_id(conn, v.update_data).await?,
|
|
)),
|
|
Updateable::MandateUpdate(m) => DBResult::Mandate(Box::new(
|
|
Mandate::update_by_merchant_id_mandate_id(
|
|
conn,
|
|
&m.orig.merchant_id,
|
|
&m.orig.mandate_id,
|
|
m.update_data,
|
|
)
|
|
.await?,
|
|
)),
|
|
#[cfg(all(any(feature = "v1", feature = "v2"), not(feature = "customer_v2")))]
|
|
Updateable::CustomerUpdate(cust) => DBResult::Customer(Box::new(
|
|
Customer::update_by_customer_id_merchant_id(
|
|
conn,
|
|
cust.orig.customer_id.clone(),
|
|
cust.orig.merchant_id.clone(),
|
|
cust.update_data,
|
|
)
|
|
.await?,
|
|
)),
|
|
#[cfg(all(feature = "v2", feature = "customer_v2"))]
|
|
Updateable::CustomerUpdate(cust) => DBResult::Customer(Box::new(
|
|
Customer::update_by_id(conn, cust.orig.id, cust.update_data).await?,
|
|
)),
|
|
},
|
|
})
|
|
}
|
|
}
|
|
|
|
impl TypedSql {
|
|
pub fn to_field_value_pairs(
|
|
&self,
|
|
request_id: String,
|
|
global_id: String,
|
|
) -> crate::StorageResult<Vec<(&str, String)>> {
|
|
let pushed_at = common_utils::date_time::now_unix_timestamp();
|
|
|
|
Ok(vec![
|
|
(
|
|
"typed_sql",
|
|
serde_json::to_string(self)
|
|
.change_context(errors::DatabaseError::QueryGenerationFailed)?,
|
|
),
|
|
("global_id", global_id),
|
|
("request_id", request_id),
|
|
("pushed_at", pushed_at.to_string()),
|
|
])
|
|
}
|
|
}
|
|
|
|
#[derive(Debug, Serialize, Deserialize)]
|
|
#[serde(rename_all = "snake_case", tag = "table", content = "data")]
|
|
pub enum Insertable {
|
|
PaymentIntent(Box<PaymentIntentNew>),
|
|
PaymentAttempt(Box<PaymentAttemptNew>),
|
|
Refund(RefundNew),
|
|
Address(Box<AddressNew>),
|
|
Customer(CustomerNew),
|
|
ReverseLookUp(ReverseLookupNew),
|
|
Payouts(PayoutsNew),
|
|
PayoutAttempt(PayoutAttemptNew),
|
|
PaymentMethod(PaymentMethodNew),
|
|
Mandate(MandateNew),
|
|
}
|
|
|
|
#[derive(Debug, Serialize, Deserialize)]
|
|
#[serde(rename_all = "snake_case", tag = "table", content = "data")]
|
|
pub enum Updateable {
|
|
PaymentIntentUpdate(Box<PaymentIntentUpdateMems>),
|
|
PaymentAttemptUpdate(Box<PaymentAttemptUpdateMems>),
|
|
RefundUpdate(Box<RefundUpdateMems>),
|
|
CustomerUpdate(CustomerUpdateMems),
|
|
AddressUpdate(Box<AddressUpdateMems>),
|
|
PayoutsUpdate(PayoutsUpdateMems),
|
|
PayoutAttemptUpdate(PayoutAttemptUpdateMems),
|
|
PaymentMethodUpdate(Box<PaymentMethodUpdateMems>),
|
|
MandateUpdate(MandateUpdateMems),
|
|
}
|
|
|
|
#[derive(Debug, Serialize, Deserialize)]
|
|
pub struct CustomerUpdateMems {
|
|
pub orig: Customer,
|
|
pub update_data: CustomerUpdateInternal,
|
|
}
|
|
|
|
#[derive(Debug, Serialize, Deserialize)]
|
|
pub struct AddressUpdateMems {
|
|
pub orig: Address,
|
|
pub update_data: AddressUpdateInternal,
|
|
}
|
|
#[cfg(feature = "v1")]
|
|
#[derive(Debug, Serialize, Deserialize)]
|
|
pub struct PaymentIntentUpdateMems {
|
|
pub orig: PaymentIntent,
|
|
pub update_data: PaymentIntentUpdate,
|
|
}
|
|
|
|
#[cfg(feature = "v2")]
|
|
#[derive(Debug, Serialize, Deserialize)]
|
|
pub struct PaymentIntentUpdateMems {
|
|
pub orig: PaymentIntent,
|
|
pub update_data: PaymentIntentUpdateInternal,
|
|
}
|
|
|
|
#[derive(Debug, Serialize, Deserialize)]
|
|
pub struct PaymentAttemptUpdateMems {
|
|
pub orig: PaymentAttempt,
|
|
pub update_data: PaymentAttemptUpdate,
|
|
}
|
|
|
|
#[derive(Debug, Serialize, Deserialize)]
|
|
pub struct RefundUpdateMems {
|
|
pub orig: Refund,
|
|
pub update_data: RefundUpdate,
|
|
}
|
|
|
|
#[derive(Debug, Serialize, Deserialize)]
|
|
pub struct PayoutsUpdateMems {
|
|
pub orig: Payouts,
|
|
pub update_data: PayoutsUpdate,
|
|
}
|
|
|
|
#[derive(Debug, Serialize, Deserialize)]
|
|
pub struct PayoutAttemptUpdateMems {
|
|
pub orig: PayoutAttempt,
|
|
pub update_data: PayoutAttemptUpdate,
|
|
}
|
|
|
|
#[derive(Debug, Serialize, Deserialize)]
|
|
pub struct PaymentMethodUpdateMems {
|
|
pub orig: PaymentMethod,
|
|
pub update_data: PaymentMethodUpdateInternal,
|
|
}
|
|
|
|
#[derive(Debug, Serialize, Deserialize)]
|
|
pub struct MandateUpdateMems {
|
|
pub orig: Mandate,
|
|
pub update_data: MandateUpdateInternal,
|
|
}
|