Skip to content

Commit eb3cecd

Browse files
akshay-97Akshay Shyperswitch-bot[bot]
authored
feat(payment_methods): added kv support for payment_methods table (#4311)
Co-authored-by: Akshay S <[email protected]> Co-authored-by: hyperswitch-bot[bot] <148525504+hyperswitch-bot[bot]@users.noreply.github.com>
1 parent 9448673 commit eb3cecd

35 files changed

+1016
-314
lines changed

crates/diesel_models/src/kv.rs

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use crate::{
1010
payouts::{Payouts, PayoutsNew, PayoutsUpdate},
1111
refund::{Refund, RefundNew, RefundUpdate},
1212
reverse_lookup::{ReverseLookup, ReverseLookupNew},
13-
PaymentIntent, PgPooledConn,
13+
PaymentIntent, PaymentMethod, PaymentMethodNew, PaymentMethodUpdateInternal, PgPooledConn,
1414
};
1515

1616
#[derive(Debug, Serialize, Deserialize)]
@@ -37,6 +37,7 @@ impl DBOperation {
3737
Insertable::Payouts(_) => "payouts",
3838
Insertable::PayoutAttempt(_) => "payout_attempt",
3939
Insertable::ReverseLookUp(_) => "reverse_lookup",
40+
Insertable::PaymentMethod(_) => "payment_method",
4041
},
4142
Self::Update { updatable } => match updatable {
4243
Updateable::PaymentIntentUpdate(_) => "payment_intent",
@@ -45,6 +46,7 @@ impl DBOperation {
4546
Updateable::AddressUpdate(_) => "address",
4647
Updateable::PayoutsUpdate(_) => "payouts",
4748
Updateable::PayoutAttemptUpdate(_) => "payout_attempt",
49+
Updateable::PaymentMethodUpdate(_) => "payment_method",
4850
},
4951
}
5052
}
@@ -59,6 +61,7 @@ pub enum DBResult {
5961
ReverseLookUp(Box<ReverseLookup>),
6062
Payouts(Box<Payouts>),
6163
PayoutAttempt(Box<PayoutAttempt>),
64+
PaymentMethod(Box<PaymentMethod>),
6265
}
6366

6467
#[derive(Debug, Serialize, Deserialize)]
@@ -86,6 +89,9 @@ impl DBOperation {
8689
Insertable::PayoutAttempt(rev) => {
8790
DBResult::PayoutAttempt(Box::new(rev.insert(conn).await?))
8891
}
92+
Insertable::PaymentMethod(rev) => {
93+
DBResult::PaymentMethod(Box::new(rev.insert(conn).await?))
94+
}
8995
},
9096
Self::Update { updatable } => match updatable {
9197
Updateable::PaymentIntentUpdate(a) => {
@@ -106,6 +112,11 @@ impl DBOperation {
106112
Updateable::PayoutAttemptUpdate(a) => DBResult::PayoutAttempt(Box::new(
107113
a.orig.update_with_attempt_id(conn, a.update_data).await?,
108114
)),
115+
Updateable::PaymentMethodUpdate(v) => DBResult::PaymentMethod(Box::new(
116+
v.orig
117+
.update_with_payment_method_id(conn, v.update_data)
118+
.await?,
119+
)),
109120
},
110121
})
111122
}
@@ -142,6 +153,7 @@ pub enum Insertable {
142153
ReverseLookUp(ReverseLookupNew),
143154
Payouts(PayoutsNew),
144155
PayoutAttempt(PayoutAttemptNew),
156+
PaymentMethod(PaymentMethodNew),
145157
}
146158

147159
#[derive(Debug, Serialize, Deserialize)]
@@ -153,6 +165,7 @@ pub enum Updateable {
153165
AddressUpdate(Box<AddressUpdateMems>),
154166
PayoutsUpdate(PayoutsUpdateMems),
155167
PayoutAttemptUpdate(PayoutAttemptUpdateMems),
168+
PaymentMethodUpdate(PaymentMethodUpdateMems),
156169
}
157170

158171
#[derive(Debug, Serialize, Deserialize)]
@@ -190,3 +203,9 @@ pub struct PayoutAttemptUpdateMems {
190203
pub orig: PayoutAttempt,
191204
pub update_data: PayoutAttemptUpdate,
192205
}
206+
207+
#[derive(Debug, Serialize, Deserialize)]
208+
pub struct PaymentMethodUpdateMems {
209+
pub orig: PaymentMethod,
210+
pub update_data: PaymentMethodUpdateInternal,
211+
}

crates/diesel_models/src/payment_method.rs

Lines changed: 65 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use time::PrimitiveDateTime;
66

77
use crate::{encryption::Encryption, enums as storage_enums, schema::payment_methods};
88

9-
#[derive(Clone, Debug, Eq, PartialEq, Identifiable, Queryable)]
9+
#[derive(Clone, Debug, Eq, PartialEq, Identifiable, Queryable, Serialize, Deserialize)]
1010
#[diesel(table_name = payment_methods)]
1111
pub struct PaymentMethod {
1212
pub id: i32,
@@ -41,7 +41,9 @@ pub struct PaymentMethod {
4141
pub network_transaction_id: Option<String>,
4242
}
4343

44-
#[derive(Clone, Debug, Eq, PartialEq, Insertable, router_derive::DebugAsDisplay)]
44+
#[derive(
45+
Clone, Debug, Eq, PartialEq, Insertable, router_derive::DebugAsDisplay, Serialize, Deserialize,
46+
)]
4547
#[diesel(table_name = payment_methods)]
4648
pub struct PaymentMethodNew {
4749
pub customer_id: String,
@@ -138,7 +140,9 @@ pub enum PaymentMethodUpdate {
138140
},
139141
}
140142

141-
#[derive(Clone, Debug, Default, AsChangeset, router_derive::DebugAsDisplay)]
143+
#[derive(
144+
Clone, Debug, Default, AsChangeset, router_derive::DebugAsDisplay, Serialize, Deserialize,
145+
)]
142146
#[diesel(table_name = payment_methods)]
143147
pub struct PaymentMethodUpdateInternal {
144148
metadata: Option<serde_json::Value>,
@@ -155,6 +159,29 @@ impl PaymentMethodUpdateInternal {
155159

156160
PaymentMethod { metadata, ..source }
157161
}
162+
163+
pub fn apply_changeset(self, source: PaymentMethod) -> PaymentMethod {
164+
let Self {
165+
metadata,
166+
payment_method_data,
167+
last_used_at,
168+
network_transaction_id,
169+
status,
170+
connector_mandate_details,
171+
} = self;
172+
173+
PaymentMethod {
174+
metadata: metadata.map_or(source.metadata, |v| Some(v.into())),
175+
payment_method_data: payment_method_data.map_or(source.payment_method_data, Some),
176+
last_used_at: last_used_at.unwrap_or(source.last_used_at),
177+
network_transaction_id: network_transaction_id
178+
.map_or(source.network_transaction_id, Some),
179+
status: status.unwrap_or(source.status),
180+
connector_mandate_details: connector_mandate_details
181+
.map_or(source.connector_mandate_details, Some),
182+
..source
183+
}
184+
}
158185
}
159186

160187
impl From<PaymentMethodUpdate> for PaymentMethodUpdateInternal {
@@ -218,3 +245,38 @@ impl From<PaymentMethodUpdate> for PaymentMethodUpdateInternal {
218245
}
219246
}
220247
}
248+
249+
impl From<&PaymentMethodNew> for PaymentMethod {
250+
fn from(payment_method_new: &PaymentMethodNew) -> Self {
251+
Self {
252+
id: 0i32,
253+
customer_id: payment_method_new.customer_id.clone(),
254+
merchant_id: payment_method_new.merchant_id.clone(),
255+
payment_method_id: payment_method_new.payment_method_id.clone(),
256+
locker_id: payment_method_new.locker_id.clone(),
257+
accepted_currency: payment_method_new.accepted_currency.clone(),
258+
scheme: payment_method_new.scheme.clone(),
259+
token: payment_method_new.token.clone(),
260+
cardholder_name: payment_method_new.cardholder_name.clone(),
261+
issuer_name: payment_method_new.issuer_name.clone(),
262+
issuer_country: payment_method_new.issuer_country.clone(),
263+
payer_country: payment_method_new.payer_country.clone(),
264+
is_stored: payment_method_new.is_stored,
265+
swift_code: payment_method_new.swift_code.clone(),
266+
direct_debit_token: payment_method_new.direct_debit_token.clone(),
267+
created_at: payment_method_new.created_at,
268+
last_modified: payment_method_new.last_modified,
269+
payment_method: payment_method_new.payment_method,
270+
payment_method_type: payment_method_new.payment_method_type,
271+
payment_method_issuer: payment_method_new.payment_method_issuer.clone(),
272+
payment_method_issuer_code: payment_method_new.payment_method_issuer_code,
273+
metadata: payment_method_new.metadata.clone(),
274+
payment_method_data: payment_method_new.payment_method_data.clone(),
275+
last_used_at: payment_method_new.last_used_at,
276+
connector_mandate_details: payment_method_new.connector_mandate_details.clone(),
277+
customer_acceptance: payment_method_new.customer_acceptance.clone(),
278+
status: payment_method_new.status,
279+
network_transaction_id: payment_method_new.network_transaction_id.clone(),
280+
}
281+
}
282+
}

crates/diesel_models/src/query/payment_method.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,7 @@ impl PaymentMethod {
151151
pub async fn update_with_payment_method_id(
152152
self,
153153
conn: &PgPooledConn,
154-
payment_method: payment_method::PaymentMethodUpdate,
154+
payment_method: payment_method::PaymentMethodUpdateInternal,
155155
) -> StorageResult<Self> {
156156
match generics::generic_update_with_unique_predicate_get_result::<
157157
<Self as HasTable>::Table,
@@ -161,7 +161,7 @@ impl PaymentMethod {
161161
>(
162162
conn,
163163
dsl::payment_method_id.eq(self.payment_method_id.to_owned()),
164-
payment_method::PaymentMethodUpdateInternal::from(payment_method),
164+
payment_method,
165165
)
166166
.await
167167
{

crates/router/src/core/mandate.rs

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,13 @@ pub async fn get_mandate(
4343
.await
4444
.to_not_found_response(errors::ApiErrorResponse::MandateNotFound)?;
4545
Ok(services::ApplicationResponse::Json(
46-
mandates::MandateResponse::from_db_mandate(&state, key_store, mandate).await?,
46+
mandates::MandateResponse::from_db_mandate(
47+
&state,
48+
key_store,
49+
mandate,
50+
merchant_account.storage_scheme,
51+
)
52+
.await?,
4753
))
4854
}
4955

@@ -226,8 +232,13 @@ pub async fn get_customer_mandates(
226232
let mut response_vec = Vec::with_capacity(mandates.len());
227233
for mandate in mandates {
228234
response_vec.push(
229-
mandates::MandateResponse::from_db_mandate(&state, key_store.clone(), mandate)
230-
.await?,
235+
mandates::MandateResponse::from_db_mandate(
236+
&state,
237+
key_store.clone(),
238+
mandate,
239+
merchant_account.storage_scheme,
240+
)
241+
.await?,
231242
);
232243
}
233244
Ok(services::ApplicationResponse::Json(response_vec))
@@ -471,7 +482,12 @@ pub async fn retrieve_mandates_list(
471482
.change_context(errors::ApiErrorResponse::InternalServerError)
472483
.attach_printable("Unable to retrieve mandates")?;
473484
let mandates_list = future::try_join_all(mandates.into_iter().map(|mandate| {
474-
mandates::MandateResponse::from_db_mandate(&state, key_store.clone(), mandate)
485+
mandates::MandateResponse::from_db_mandate(
486+
&state,
487+
key_store.clone(),
488+
mandate,
489+
merchant_account.storage_scheme,
490+
)
475491
}))
476492
.await?;
477493
Ok(services::ApplicationResponse::Json(mandates_list))

crates/router/src/core/payment_methods.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ pub trait PaymentMethodRetrieve {
3838
payment_intent: &PaymentIntent,
3939
card_token_data: Option<&CardToken>,
4040
customer: &Option<domain::Customer>,
41+
storage_scheme: common_enums::enums::MerchantStorageScheme,
4142
) -> RouterResult<storage::PaymentMethodDataWithId>;
4243
}
4344

@@ -122,6 +123,7 @@ impl PaymentMethodRetrieve for Oss {
122123
payment_intent: &PaymentIntent,
123124
card_token_data: Option<&CardToken>,
124125
customer: &Option<domain::Customer>,
126+
storage_scheme: common_enums::enums::MerchantStorageScheme,
125127
) -> RouterResult<storage::PaymentMethodDataWithId> {
126128
let token = match token_data {
127129
storage::PaymentTokenData::TemporaryGeneric(generic_token) => {
@@ -172,6 +174,8 @@ impl PaymentMethodRetrieve for Oss {
172174
.unwrap_or(&card_token.token),
173175
payment_intent,
174176
card_token_data,
177+
merchant_key_store,
178+
storage_scheme,
175179
)
176180
.await
177181
.map(|card| Some((card, enums::PaymentMethod::Card)))?
@@ -201,6 +205,8 @@ impl PaymentMethodRetrieve for Oss {
201205
.unwrap_or(&card_token.token),
202206
payment_intent,
203207
card_token_data,
208+
merchant_key_store,
209+
storage_scheme,
204210
)
205211
.await
206212
.map(|card| Some((card, enums::PaymentMethod::Card)))?

0 commit comments

Comments
 (0)