Skip to content

Commit 37c113d

Browse files
committed
refactor: resolve comments
1 parent e3f9c19 commit 37c113d

File tree

4 files changed

+407
-343
lines changed

4 files changed

+407
-343
lines changed

crates/router/src/core/payments.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ pub mod session_operation;
1313
pub mod tokenization;
1414
pub mod transformers;
1515
pub mod types;
16+
#[cfg(feature = "v2")]
17+
pub mod vault_session;
1618
#[cfg(feature = "olap")]
1719
use std::collections::HashMap;
1820
use std::{

crates/router/src/core/payments/operations/payment_session_intent.rs

Lines changed: 0 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -179,9 +179,6 @@ impl<F: Clone + Sync> UpdateTracker<F, payments::PaymentIntentData<F>, PaymentsS
179179
where
180180
F: 'b + Send,
181181
{
182-
let db = &*state.store;
183-
let key_manager_state = &state.into();
184-
185182
let prerouting_algorithm = payment_data.payment_intent.prerouting_algorithm.clone();
186183
payment_data.payment_intent = match prerouting_algorithm {
187184
Some(prerouting_algorithm) => state
@@ -201,25 +198,6 @@ impl<F: Clone + Sync> UpdateTracker<F, payments::PaymentIntentData<F>, PaymentsS
201198
None => payment_data.payment_intent,
202199
};
203200

204-
if let Some((customer, updated_customer)) = customer.zip(updated_customer) {
205-
let customer_id = customer.get_id().clone();
206-
let customer_merchant_id = customer.merchant_id.clone();
207-
208-
let _updated_customer = db
209-
.update_customer_by_global_id(
210-
key_manager_state,
211-
&customer_id,
212-
customer,
213-
&customer_merchant_id,
214-
updated_customer,
215-
key_store,
216-
storage_scheme,
217-
)
218-
.await
219-
.change_context(errors::ApiErrorResponse::InternalServerError)
220-
.attach_printable("Failed to update customer during `update_trackers`")?;
221-
}
222-
223201
Ok((Box::new(self), payment_data))
224202
}
225203
}

crates/router/src/core/payments/session_operation.rs

Lines changed: 3 additions & 321 deletions
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,11 @@ use crate::{
2424
core::{
2525
errors::{self, utils::StorageErrorExt, RouterResult},
2626
payments::{
27-
self as payments_core, call_multiple_connectors_service, customers,
27+
self as payments_core, call_multiple_connectors_service,
2828
flows::{ConstructFlowSpecificData, Feature},
2929
helpers, helpers as payment_helpers, operations,
3030
operations::{BoxedOperation, Operation},
31-
transformers, OperationSessionGetters, OperationSessionSetters,
31+
transformers, vault_session, OperationSessionGetters, OperationSessionSetters,
3232
},
3333
utils as core_utils,
3434
},
@@ -158,7 +158,7 @@ where
158158
.to_not_found_response(errors::ApiErrorResponse::CustomerNotFound)
159159
.attach_printable("Failed while fetching/creating customer")?;
160160

161-
populate_vault_session_details(
161+
vault_session::populate_vault_session_details(
162162
state,
163163
req_state.clone(),
164164
&customer,
@@ -220,321 +220,3 @@ where
220220

221221
Ok((payment_data, req, customer, None, None))
222222
}
223-
224-
#[cfg(feature = "v2")]
225-
#[allow(clippy::too_many_arguments)]
226-
pub async fn populate_vault_session_details<F, RouterDReq, ApiRequest, D>(
227-
state: &SessionState,
228-
req_state: ReqState,
229-
customer: &Option<domain::Customer>,
230-
merchant_context: &domain::MerchantContext,
231-
operation: &BoxedOperation<'_, F, ApiRequest, D>,
232-
profile: &domain::Profile,
233-
payment_data: &mut D,
234-
header_payload: HeaderPayload,
235-
) -> RouterResult<()>
236-
where
237-
F: Send + Clone + Sync,
238-
RouterDReq: Send + Sync,
239-
240-
// To create connector flow specific interface data
241-
D: OperationSessionGetters<F> + OperationSessionSetters<F> + Send + Sync + Clone,
242-
D: ConstructFlowSpecificData<F, RouterDReq, router_types::PaymentsResponseData>,
243-
RouterData<F, RouterDReq, router_types::PaymentsResponseData>: Feature<F, RouterDReq> + Send,
244-
// To construct connector flow specific api
245-
dyn api::Connector:
246-
services::api::ConnectorIntegration<F, RouterDReq, router_types::PaymentsResponseData>,
247-
{
248-
let is_external_vault_sdk_enabled = profile.is_vault_sdk_enabled();
249-
250-
if is_external_vault_sdk_enabled {
251-
let external_vault_source = profile
252-
.external_vault_connector_details
253-
.as_ref()
254-
.map(|details| &details.vault_connector_id);
255-
256-
let merchant_connector_account = helpers::get_merchant_connector_account(
257-
state,
258-
merchant_context.get_merchant_account().get_id(),
259-
None,
260-
merchant_context.get_merchant_key_store(),
261-
profile.get_id(),
262-
"", // This is a placeholder for the connector name, which is not used in this context
263-
external_vault_source,
264-
)
265-
.await?;
266-
267-
let updated_customer = call_create_connector_customer_if_required(
268-
state,
269-
customer,
270-
merchant_context,
271-
&merchant_connector_account,
272-
payment_data,
273-
)
274-
.await?;
275-
276-
(_, *payment_data) = operation
277-
.to_update_tracker()?
278-
.update_trackers(
279-
state,
280-
req_state,
281-
payment_data.clone(),
282-
customer.clone(),
283-
merchant_context.get_merchant_account().storage_scheme,
284-
updated_customer,
285-
merchant_context.get_merchant_key_store(),
286-
None,
287-
header_payload.clone(),
288-
)
289-
.await?;
290-
291-
let vault_session_details = generate_vault_session_details(
292-
state,
293-
merchant_context,
294-
&merchant_connector_account,
295-
profile,
296-
payment_data.get_connector_customer_id(),
297-
)
298-
.await?;
299-
300-
payment_data.set_vault_session_details(vault_session_details);
301-
}
302-
Ok(())
303-
}
304-
305-
#[cfg(feature = "v2")]
306-
pub async fn call_create_connector_customer_if_required<F, Req, D>(
307-
state: &SessionState,
308-
customer: &Option<domain::Customer>,
309-
merchant_context: &domain::MerchantContext,
310-
merchant_connector_account_type: &payment_helpers::MerchantConnectorAccountType,
311-
payment_data: &mut D,
312-
) -> RouterResult<Option<storage::CustomerUpdate>>
313-
where
314-
F: Send + Clone + Sync,
315-
Req: Send + Sync,
316-
317-
// To create connector flow specific interface data
318-
D: OperationSessionGetters<F> + OperationSessionSetters<F> + Send + Sync + Clone,
319-
D: ConstructFlowSpecificData<F, Req, router_types::PaymentsResponseData>,
320-
RouterData<F, Req, router_types::PaymentsResponseData>: Feature<F, Req> + Send,
321-
322-
// To construct connector flow specific api
323-
dyn api::Connector:
324-
services::api::ConnectorIntegration<F, Req, router_types::PaymentsResponseData>,
325-
{
326-
let db_merchant_connector_account =
327-
merchant_connector_account_type.get_inner_db_merchant_connector_account();
328-
329-
match db_merchant_connector_account {
330-
Some(merchant_connector_account) => {
331-
let connector_name = merchant_connector_account.get_connector_name_as_string();
332-
let merchant_connector_id = merchant_connector_account.get_id();
333-
334-
let connector = api::ConnectorData::get_connector_by_name(
335-
&state.conf.connectors,
336-
&connector_name,
337-
api::GetToken::Connector,
338-
Some(merchant_connector_id.clone()),
339-
)?;
340-
341-
let (should_call_connector, existing_connector_customer_id) =
342-
customers::should_call_connector_create_customer(
343-
state,
344-
&connector,
345-
customer,
346-
&merchant_connector_id,
347-
);
348-
349-
if should_call_connector {
350-
// Create customer at connector and update the customer table to store this data
351-
let router_data = payment_data
352-
.construct_router_data(
353-
state,
354-
connector.connector.id(),
355-
merchant_context,
356-
customer,
357-
merchant_connector_account,
358-
None,
359-
None,
360-
)
361-
.await?;
362-
363-
let connector_customer_id = router_data
364-
.create_connector_customer(state, &connector)
365-
.await?;
366-
367-
let customer_update = customers::update_connector_customer_in_customers(
368-
merchant_connector_id,
369-
customer.as_ref(),
370-
connector_customer_id.clone(),
371-
)
372-
.await;
373-
374-
payment_data.set_connector_customer_id(connector_customer_id);
375-
Ok(customer_update)
376-
} else {
377-
// Customer already created in previous calls use the same value, no need to update
378-
payment_data.set_connector_customer_id(
379-
existing_connector_customer_id.map(ToOwned::to_owned),
380-
);
381-
Ok(None)
382-
}
383-
}
384-
None => {
385-
router_env::logger::warn!(
386-
"merchant_connector_account is missing, skipping customer creation"
387-
);
388-
Ok(None)
389-
}
390-
}
391-
}
392-
393-
#[cfg(feature = "v2")]
394-
pub async fn generate_vault_session_details(
395-
state: &SessionState,
396-
merchant_context: &domain::MerchantContext,
397-
merchant_connector_account_type: &payment_helpers::MerchantConnectorAccountType,
398-
profile: &domain::Profile,
399-
connector_customer_id: Option<String>,
400-
) -> RouterResult<Option<api::VaultSessionDetails>> {
401-
let connector_name = merchant_connector_account_type
402-
.get_connector_name()
403-
.map(|name| name.to_string())
404-
.unwrap_or_default(); // should not panic since we should always have a connector name
405-
let connector = api_enums::VaultConnectors::from_str(&connector_name)
406-
.map_err(|_| errors::ApiErrorResponse::InternalServerError)?;
407-
let connector_auth_type: router_types::ConnectorAuthType = merchant_connector_account_type
408-
.get_connector_account_details()
409-
.parse_value("ConnectorAuthType")
410-
.change_context(errors::ApiErrorResponse::InternalServerError)?;
411-
412-
match (connector, connector_auth_type) {
413-
// create session for vgs vault
414-
(
415-
api_enums::VaultConnectors::Vgs,
416-
router_types::ConnectorAuthType::SignatureKey { api_secret, .. },
417-
) => {
418-
let sdk_env = match state.conf.env {
419-
Env::Sandbox | Env::Development => "sandbox",
420-
Env::Production => "live",
421-
}
422-
.to_string();
423-
Ok(Some(api::VaultSessionDetails::Vgs(
424-
api::VgsSessionDetails {
425-
external_vault_id: api_secret,
426-
sdk_env,
427-
},
428-
)))
429-
}
430-
// create session for hyperswitch vault
431-
(
432-
api_enums::VaultConnectors::HyperswitchVault,
433-
router_types::ConnectorAuthType::SignatureKey {
434-
key1, api_secret, ..
435-
},
436-
) => {
437-
let connector_data: api::ConnectorData = api::ConnectorData::get_connector_by_name(
438-
&state.conf.connectors,
439-
&connector_name,
440-
api::GetToken::Connector,
441-
merchant_connector_account_type.get_mca_id(),
442-
)?;
443-
444-
let connector_response = call_external_vault_create(
445-
state,
446-
merchant_context,
447-
&connector_data,
448-
merchant_connector_account_type,
449-
connector_customer_id,
450-
)
451-
.await?;
452-
453-
match connector_response.response {
454-
Ok(router_types::VaultResponseData::ExternalVaultCreateResponse {
455-
session_id,
456-
client_secret,
457-
}) => Ok(Some(api::VaultSessionDetails::HyperswitchVault(
458-
api::HyperswitchVaultSessionDetails {
459-
payment_method_session_id: session_id,
460-
client_secret,
461-
publishable_key: key1,
462-
profile_id: api_secret,
463-
},
464-
))),
465-
Ok(res) => {
466-
router_env::logger::warn!("Unexpected response from external vault create API");
467-
Ok(None)
468-
}
469-
Err(_) => {
470-
router_env::logger::error!(
471-
"Failed to create external vault session for connector: {}",
472-
connector_name
473-
);
474-
Err(errors::ApiErrorResponse::InternalServerError.into())
475-
}
476-
}
477-
}
478-
_ => {
479-
router_env::logger::warn!(
480-
"External vault session creation is not supported for connector: {}",
481-
connector_name
482-
);
483-
Ok(None)
484-
}
485-
}
486-
}
487-
488-
#[cfg(feature = "v2")]
489-
async fn call_external_vault_create(
490-
state: &SessionState,
491-
merchant_context: &domain::MerchantContext,
492-
connector_data: &api::ConnectorData,
493-
merchant_connector_account_type: &payment_helpers::MerchantConnectorAccountType,
494-
connector_customer_id: Option<String>,
495-
) -> RouterResult<VaultRouterData<ExternalVaultCreateFlow>>
496-
where
497-
dyn ConnectorTrait + Sync: services::api::ConnectorIntegration<
498-
ExternalVaultCreateFlow,
499-
router_types::VaultRequestData,
500-
router_types::VaultResponseData,
501-
>,
502-
dyn ConnectorV2 + Sync: ConnectorIntegrationV2<
503-
ExternalVaultCreateFlow,
504-
VaultConnectorFlowData,
505-
router_types::VaultRequestData,
506-
router_types::VaultResponseData,
507-
>,
508-
{
509-
let mut router_data = core_utils::construct_vault_router_data(
510-
state,
511-
merchant_context.get_merchant_account(),
512-
merchant_connector_account_type,
513-
None,
514-
None,
515-
connector_customer_id,
516-
)
517-
.await?;
518-
519-
let mut old_router_data = VaultConnectorFlowData::to_old_router_data(router_data)
520-
.change_context(errors::ApiErrorResponse::InternalServerError)
521-
.attach_printable(
522-
"Cannot construct router data for making the external vault create api call",
523-
)?;
524-
525-
let connector_integration: services::BoxedVaultConnectorIntegrationInterface<
526-
ExternalVaultCreateFlow,
527-
router_types::VaultRequestData,
528-
router_types::VaultResponseData,
529-
> = connector_data.connector.get_connector_integration();
530-
services::execute_connector_processing_step(
531-
state,
532-
connector_integration,
533-
&old_router_data,
534-
CallConnectorAction::Trigger,
535-
None,
536-
None,
537-
)
538-
.await
539-
.to_vault_failed_response()
540-
}

0 commit comments

Comments
 (0)