mirror of
				https://github.com/juspay/hyperswitch.git
				synced 2025-10-31 18:17:13 +08:00 
			
		
		
		
	refactor(payment_methods): unify locker api function call (#5863)
This commit is contained in:
		| @ -4490,7 +4490,7 @@ async fn locker_recipient_create_call( | |||||||
|         ttl: state.conf.locker.ttl_for_storage_in_secs, |         ttl: state.conf.locker.ttl_for_storage_in_secs, | ||||||
|     }); |     }); | ||||||
|  |  | ||||||
|     let store_resp = cards::call_to_locker_hs( |     let store_resp = cards::add_card_to_hs_locker( | ||||||
|         state, |         state, | ||||||
|         &payload, |         &payload, | ||||||
|         &cust_id, |         &cust_id, | ||||||
|  | |||||||
| @ -124,6 +124,8 @@ pub enum VaultError { | |||||||
|     SaveCardFailed, |     SaveCardFailed, | ||||||
|     #[error("Failed to fetch card details from card vault")] |     #[error("Failed to fetch card details from card vault")] | ||||||
|     FetchCardFailed, |     FetchCardFailed, | ||||||
|  |     #[error("Failed to delete card in card vault")] | ||||||
|  |     DeleteCardFailed, | ||||||
|     #[error("Failed to encode card vault request")] |     #[error("Failed to encode card vault request")] | ||||||
|     RequestEncodingFailed, |     RequestEncodingFailed, | ||||||
|     #[error("Failed to deserialize card vault response")] |     #[error("Failed to deserialize card vault response")] | ||||||
| @ -146,6 +148,8 @@ pub enum VaultError { | |||||||
|     SavePaymentMethodFailed, |     SavePaymentMethodFailed, | ||||||
|     #[error("Failed to generate fingerprint")] |     #[error("Failed to generate fingerprint")] | ||||||
|     GenerateFingerprintFailed, |     GenerateFingerprintFailed, | ||||||
|  |     #[error("Failed while calling locker API")] | ||||||
|  |     ApiError, | ||||||
| } | } | ||||||
|  |  | ||||||
| #[derive(Debug, thiserror::Error)] | #[derive(Debug, thiserror::Error)] | ||||||
|  | |||||||
| @ -28,8 +28,10 @@ use common_utils::{ | |||||||
|     consts, |     consts, | ||||||
|     crypto::{self, Encryptable}, |     crypto::{self, Encryptable}, | ||||||
|     encryption::Encryption, |     encryption::Encryption, | ||||||
|     ext_traits::{AsyncExt, Encode, StringExt, ValueExt}, |     ext_traits::{AsyncExt, BytesExt, Encode, StringExt, ValueExt}, | ||||||
|     generate_id, id_type, type_name, |     generate_id, id_type, | ||||||
|  |     request::Request, | ||||||
|  |     type_name, | ||||||
|     types::{ |     types::{ | ||||||
|         keymanager::{Identifier, KeyManagerState}, |         keymanager::{Identifier, KeyManagerState}, | ||||||
|         MinorUnit, |         MinorUnit, | ||||||
| @ -93,7 +95,7 @@ use crate::{ | |||||||
|         storage::{self, enums, PaymentMethodListContext, PaymentTokenData}, |         storage::{self, enums, PaymentMethodListContext, PaymentTokenData}, | ||||||
|         transformers::ForeignTryFrom, |         transformers::ForeignTryFrom, | ||||||
|     }, |     }, | ||||||
|     utils::{ConnectorResponseExt, OptionExt}, |     utils::OptionExt, | ||||||
| }; | }; | ||||||
| #[cfg(all( | #[cfg(all( | ||||||
|     any(feature = "v1", feature = "v2"), |     any(feature = "v1", feature = "v2"), | ||||||
| @ -1876,7 +1878,7 @@ pub async fn add_bank_to_locker( | |||||||
|             enc_data, |             enc_data, | ||||||
|             ttl: state.conf.locker.ttl_for_storage_in_secs, |             ttl: state.conf.locker.ttl_for_storage_in_secs, | ||||||
|         }); |         }); | ||||||
|     let store_resp = call_to_locker_hs( |     let store_resp = add_card_to_hs_locker( | ||||||
|         state, |         state, | ||||||
|         &payload, |         &payload, | ||||||
|         customer_id, |         customer_id, | ||||||
| @ -1920,7 +1922,7 @@ pub async fn add_card_to_locker( | |||||||
|                 card_reference, |                 card_reference, | ||||||
|             ) |             ) | ||||||
|             .await |             .await | ||||||
|             .inspect_err(|error| { |             .inspect_err(|_| { | ||||||
|                 metrics::CARD_LOCKER_FAILURES.add( |                 metrics::CARD_LOCKER_FAILURES.add( | ||||||
|                     &metrics::CONTEXT, |                     &metrics::CONTEXT, | ||||||
|                     1, |                     1, | ||||||
| @ -1929,7 +1931,6 @@ pub async fn add_card_to_locker( | |||||||
|                         router_env::opentelemetry::KeyValue::new("operation", "add"), |                         router_env::opentelemetry::KeyValue::new("operation", "add"), | ||||||
|                     ], |                     ], | ||||||
|                 ); |                 ); | ||||||
|                 logger::error!(?error, "Failed to add card in locker"); |  | ||||||
|             }) |             }) | ||||||
|         }, |         }, | ||||||
|         &metrics::CARD_ADD_TIME, |         &metrics::CARD_ADD_TIME, | ||||||
| @ -1962,7 +1963,7 @@ pub async fn get_card_from_locker( | |||||||
|             .await |             .await | ||||||
|             .change_context(errors::ApiErrorResponse::InternalServerError) |             .change_context(errors::ApiErrorResponse::InternalServerError) | ||||||
|             .attach_printable("Failed while getting card from hyperswitch card vault") |             .attach_printable("Failed while getting card from hyperswitch card vault") | ||||||
|             .inspect_err(|error| { |             .inspect_err(|_| { | ||||||
|                 metrics::CARD_LOCKER_FAILURES.add( |                 metrics::CARD_LOCKER_FAILURES.add( | ||||||
|                     &metrics::CONTEXT, |                     &metrics::CONTEXT, | ||||||
|                     1, |                     1, | ||||||
| @ -1971,7 +1972,6 @@ pub async fn get_card_from_locker( | |||||||
|                         router_env::opentelemetry::KeyValue::new("operation", "get"), |                         router_env::opentelemetry::KeyValue::new("operation", "get"), | ||||||
|                     ], |                     ], | ||||||
|                 ); |                 ); | ||||||
|                 logger::error!(?error, "Failed to retrieve card from locker"); |  | ||||||
|             }) |             }) | ||||||
|         }, |         }, | ||||||
|         &metrics::CARD_GET_TIME, |         &metrics::CARD_GET_TIME, | ||||||
| @ -1996,9 +1996,15 @@ pub async fn delete_card_from_locker( | |||||||
|         async move { |         async move { | ||||||
|             delete_card_from_hs_locker(state, customer_id, merchant_id, card_reference) |             delete_card_from_hs_locker(state, customer_id, merchant_id, card_reference) | ||||||
|                 .await |                 .await | ||||||
|                 .inspect_err(|error| { |                 .inspect_err(|_| { | ||||||
|                     metrics::CARD_LOCKER_FAILURES.add(&metrics::CONTEXT, 1, &[]); |                     metrics::CARD_LOCKER_FAILURES.add( | ||||||
|                     logger::error!(?error, "Failed to delete card from locker"); |                         &metrics::CONTEXT, | ||||||
|  |                         1, | ||||||
|  |                         &[ | ||||||
|  |                             router_env::opentelemetry::KeyValue::new("locker", "rust"), | ||||||
|  |                             router_env::opentelemetry::KeyValue::new("operation", "delete"), | ||||||
|  |                         ], | ||||||
|  |                     ); | ||||||
|                 }) |                 }) | ||||||
|         }, |         }, | ||||||
|         &metrics::CARD_DELETE_TIME, |         &metrics::CARD_DELETE_TIME, | ||||||
| @ -2006,6 +2012,8 @@ pub async fn delete_card_from_locker( | |||||||
|         &[], |         &[], | ||||||
|     ) |     ) | ||||||
|     .await |     .await | ||||||
|  |     .change_context(errors::ApiErrorResponse::InternalServerError) | ||||||
|  |     .attach_printable("Failed while deleting card from locker") | ||||||
| } | } | ||||||
|  |  | ||||||
| #[cfg(all(feature = "v2", feature = "customer_v2"))] | #[cfg(all(feature = "v2", feature = "customer_v2"))] | ||||||
| @ -2049,7 +2057,8 @@ pub async fn add_card_hs( | |||||||
|         ttl: state.conf.locker.ttl_for_storage_in_secs, |         ttl: state.conf.locker.ttl_for_storage_in_secs, | ||||||
|     }); |     }); | ||||||
|  |  | ||||||
|     let store_card_payload = call_to_locker_hs(state, &payload, customer_id, locker_choice).await?; |     let store_card_payload = | ||||||
|  |         add_card_to_hs_locker(state, &payload, customer_id, locker_choice).await?; | ||||||
|  |  | ||||||
|     let payment_method_resp = payment_methods::mk_add_card_response_hs( |     let payment_method_resp = payment_methods::mk_add_card_response_hs( | ||||||
|         card.clone(), |         card.clone(), | ||||||
| @ -2111,30 +2120,22 @@ pub async fn get_payment_method_from_hs_locker<'a>( | |||||||
|             merchant_id, |             merchant_id, | ||||||
|             payment_method_reference, |             payment_method_reference, | ||||||
|             locker_choice, |             locker_choice, | ||||||
|  |             state.tenant.name.clone(), | ||||||
|  |             state.request_id, | ||||||
|         ) |         ) | ||||||
|         .await |         .await | ||||||
|         .change_context(errors::VaultError::FetchPaymentMethodFailed) |         .change_context(errors::VaultError::FetchPaymentMethodFailed) | ||||||
|         .attach_printable("Making get payment method request failed")?; |         .attach_printable("Making get payment method request failed")?; | ||||||
|         let response = services::call_connector_api(state, request, "add_card_to_locker") |  | ||||||
|             .await |         let get_card_resp = call_locker_api::<payment_methods::RetrieveCardResp>( | ||||||
|             .change_context(errors::VaultError::FetchPaymentMethodFailed) |             state, | ||||||
|             .attach_printable("Failed while executing call_connector_api for get_card"); |             request, | ||||||
|         let jwe_body: services::JweBody = response |             "get_pm_from_locker", | ||||||
|             .get_response_inner("JweBody") |  | ||||||
|             .change_context(errors::VaultError::FetchPaymentMethodFailed)?; |  | ||||||
|         let decrypted_payload = payment_methods::get_decrypted_response_payload( |  | ||||||
|             jwekey, |  | ||||||
|             jwe_body, |  | ||||||
|             locker_choice, |             locker_choice, | ||||||
|             locker.decryption_scheme.clone(), |  | ||||||
|         ) |         ) | ||||||
|         .await |         .await | ||||||
|         .change_context(errors::VaultError::FetchPaymentMethodFailed) |         .change_context(errors::VaultError::FetchPaymentMethodFailed)?; | ||||||
|         .attach_printable("Error getting decrypted response payload for get card")?; |  | ||||||
|         let get_card_resp: payment_methods::RetrieveCardResp = decrypted_payload |  | ||||||
|             .parse_struct("RetrieveCardResp") |  | ||||||
|             .change_context(errors::VaultError::FetchPaymentMethodFailed) |  | ||||||
|             .attach_printable("Failed to parse struct to RetrieveCardResp")?; |  | ||||||
|         let retrieve_card_resp = get_card_resp |         let retrieve_card_resp = get_card_resp | ||||||
|             .payload |             .payload | ||||||
|             .get_required_value("RetrieveCardRespPayload") |             .get_required_value("RetrieveCardRespPayload") | ||||||
| @ -2158,7 +2159,7 @@ pub async fn get_payment_method_from_hs_locker<'a>( | |||||||
| } | } | ||||||
|  |  | ||||||
| #[instrument(skip_all)] | #[instrument(skip_all)] | ||||||
| pub async fn call_to_locker_hs( | pub async fn add_card_to_hs_locker( | ||||||
|     state: &routes::SessionState, |     state: &routes::SessionState, | ||||||
|     payload: &payment_methods::StoreLockerReq, |     payload: &payment_methods::StoreLockerReq, | ||||||
|     customer_id: &id_type::CustomerId, |     customer_id: &id_type::CustomerId, | ||||||
| @ -2168,30 +2169,23 @@ pub async fn call_to_locker_hs( | |||||||
|     let jwekey = state.conf.jwekey.get_inner(); |     let jwekey = state.conf.jwekey.get_inner(); | ||||||
|     let db = &*state.store; |     let db = &*state.store; | ||||||
|     let stored_card_response = if !locker.mock_locker { |     let stored_card_response = if !locker.mock_locker { | ||||||
|         let request = |         let request = payment_methods::mk_add_locker_request_hs( | ||||||
|             payment_methods::mk_add_locker_request_hs(jwekey, locker, payload, locker_choice) |  | ||||||
|                 .await?; |  | ||||||
|         let response = services::call_connector_api(state, request, "add_card_to_hs_locker") |  | ||||||
|             .await |  | ||||||
|             .change_context(errors::VaultError::SaveCardFailed); |  | ||||||
|  |  | ||||||
|         let jwe_body: services::JweBody = response |  | ||||||
|             .get_response_inner("JweBody") |  | ||||||
|             .change_context(errors::VaultError::FetchCardFailed)?; |  | ||||||
|  |  | ||||||
|         let decrypted_payload = payment_methods::get_decrypted_response_payload( |  | ||||||
|             jwekey, |             jwekey, | ||||||
|             jwe_body, |             locker, | ||||||
|  |             payload, | ||||||
|  |             locker_choice, | ||||||
|  |             state.tenant.name.clone(), | ||||||
|  |             state.request_id, | ||||||
|  |         ) | ||||||
|  |         .await?; | ||||||
|  |         call_locker_api::<payment_methods::StoreCardResp>( | ||||||
|  |             state, | ||||||
|  |             request, | ||||||
|  |             "add_card_to_hs_locker", | ||||||
|             Some(locker_choice), |             Some(locker_choice), | ||||||
|             locker.decryption_scheme.clone(), |  | ||||||
|         ) |         ) | ||||||
|         .await |         .await | ||||||
|         .change_context(errors::VaultError::SaveCardFailed) |         .change_context(errors::VaultError::SaveCardFailed)? | ||||||
|         .attach_printable("Error getting decrypted response payload")?; |  | ||||||
|         let stored_card_resp: payment_methods::StoreCardResp = decrypted_payload |  | ||||||
|             .parse_struct("StoreCardResp") |  | ||||||
|             .change_context(errors::VaultError::ResponseDeserializationFailed)?; |  | ||||||
|         stored_card_resp |  | ||||||
|     } else { |     } else { | ||||||
|         let card_id = generate_id(consts::ID_LENGTH, "card"); |         let card_id = generate_id(consts::ID_LENGTH, "card"); | ||||||
|         mock_call_to_locker_hs(db, &card_id, payload, None, None, Some(customer_id)).await? |         mock_call_to_locker_hs(db, &card_id, payload, None, None, Some(customer_id)).await? | ||||||
| @ -2204,6 +2198,61 @@ pub async fn call_to_locker_hs( | |||||||
|     Ok(stored_card) |     Ok(stored_card) | ||||||
| } | } | ||||||
|  |  | ||||||
|  | #[instrument(skip_all)] | ||||||
|  | pub async fn call_locker_api<T>( | ||||||
|  |     state: &routes::SessionState, | ||||||
|  |     request: Request, | ||||||
|  |     flow_name: &str, | ||||||
|  |     locker_choice: Option<api_enums::LockerChoice>, | ||||||
|  | ) -> errors::CustomResult<T, errors::VaultError> | ||||||
|  | where | ||||||
|  |     T: serde::de::DeserializeOwned, | ||||||
|  | { | ||||||
|  |     let locker = &state.conf.locker; | ||||||
|  |     let jwekey = state.conf.jwekey.get_inner(); | ||||||
|  |     let response_type_name = type_name!(T); | ||||||
|  |  | ||||||
|  |     let response = services::call_connector_api(state, request, flow_name) | ||||||
|  |         .await | ||||||
|  |         .change_context(errors::VaultError::ApiError)?; | ||||||
|  |  | ||||||
|  |     let is_locker_call_succeeded = response.is_ok(); | ||||||
|  |  | ||||||
|  |     let jwe_body = response | ||||||
|  |         .unwrap_or_else(|err| err) | ||||||
|  |         .response | ||||||
|  |         .parse_struct::<services::JweBody>("JweBody") | ||||||
|  |         .change_context(errors::VaultError::ResponseDeserializationFailed) | ||||||
|  |         .attach_printable("Failed while parsing locker response into JweBody")?; | ||||||
|  |  | ||||||
|  |     let decrypted_payload = payment_methods::get_decrypted_response_payload( | ||||||
|  |         jwekey, | ||||||
|  |         jwe_body, | ||||||
|  |         locker_choice, | ||||||
|  |         locker.decryption_scheme.clone(), | ||||||
|  |     ) | ||||||
|  |     .await | ||||||
|  |     .change_context(errors::VaultError::ResponseDeserializationFailed) | ||||||
|  |     .attach_printable("Failed while decrypting locker payload response")?; | ||||||
|  |  | ||||||
|  |     // Irrespective of locker's response status, payload is JWE + JWS decrypted. But based on locker's status, | ||||||
|  |     // if Ok, deserialize the decrypted payload into given type T | ||||||
|  |     // if Err, raise an error including locker error message too | ||||||
|  |     if is_locker_call_succeeded { | ||||||
|  |         let stored_card_resp: Result<T, error_stack::Report<errors::VaultError>> = | ||||||
|  |             decrypted_payload | ||||||
|  |                 .parse_struct(response_type_name) | ||||||
|  |                 .change_context(errors::VaultError::ResponseDeserializationFailed) | ||||||
|  |                 .attach_printable_lazy(|| { | ||||||
|  |                     format!("Failed while parsing locker response into {response_type_name}") | ||||||
|  |                 }); | ||||||
|  |         stored_card_resp | ||||||
|  |     } else { | ||||||
|  |         Err::<T, error_stack::Report<errors::VaultError>>((errors::VaultError::ApiError).into()) | ||||||
|  |             .attach_printable_lazy(|| format!("Locker error response: {decrypted_payload:?}")) | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
| #[cfg(all( | #[cfg(all( | ||||||
|     any(feature = "v1", feature = "v2"), |     any(feature = "v1", feature = "v2"), | ||||||
|     not(feature = "payment_methods_v2") |     not(feature = "payment_methods_v2") | ||||||
| @ -2322,29 +2371,21 @@ pub async fn get_card_from_hs_locker<'a>( | |||||||
|             merchant_id, |             merchant_id, | ||||||
|             card_reference, |             card_reference, | ||||||
|             Some(locker_choice), |             Some(locker_choice), | ||||||
|  |             state.tenant.name.clone(), | ||||||
|  |             state.request_id, | ||||||
|         ) |         ) | ||||||
|         .await |         .await | ||||||
|         .change_context(errors::VaultError::FetchCardFailed) |         .change_context(errors::VaultError::FetchCardFailed) | ||||||
|         .attach_printable("Making get card request failed")?; |         .attach_printable("Making get card request failed")?; | ||||||
|         let response = services::call_connector_api(state, request, "get_card_from_locker") |         let get_card_resp = call_locker_api::<payment_methods::RetrieveCardResp>( | ||||||
|             .await |             state, | ||||||
|             .change_context(errors::VaultError::FetchCardFailed) |             request, | ||||||
|             .attach_printable("Failed while executing call_connector_api for get_card"); |             "get_card_from_locker", | ||||||
|         let jwe_body: services::JweBody = response |  | ||||||
|             .get_response_inner("JweBody") |  | ||||||
|             .change_context(errors::VaultError::FetchCardFailed)?; |  | ||||||
|         let decrypted_payload = payment_methods::get_decrypted_response_payload( |  | ||||||
|             jwekey, |  | ||||||
|             jwe_body, |  | ||||||
|             Some(locker_choice), |             Some(locker_choice), | ||||||
|             locker.decryption_scheme.clone(), |  | ||||||
|         ) |         ) | ||||||
|         .await |         .await | ||||||
|         .change_context(errors::VaultError::FetchCardFailed) |         .change_context(errors::VaultError::FetchCardFailed)?; | ||||||
|         .attach_printable("Error getting decrypted response payload for get card")?; |  | ||||||
|         let get_card_resp: payment_methods::RetrieveCardResp = decrypted_payload |  | ||||||
|             .parse_struct("RetrieveCardResp") |  | ||||||
|             .change_context(errors::VaultError::FetchCardFailed)?; |  | ||||||
|         let retrieve_card_resp = get_card_resp |         let retrieve_card_resp = get_card_resp | ||||||
|             .payload |             .payload | ||||||
|             .get_required_value("RetrieveCardRespPayload") |             .get_required_value("RetrieveCardRespPayload") | ||||||
| @ -2366,7 +2407,7 @@ pub async fn delete_card_from_hs_locker<'a>( | |||||||
|     customer_id: &id_type::CustomerId, |     customer_id: &id_type::CustomerId, | ||||||
|     merchant_id: &id_type::MerchantId, |     merchant_id: &id_type::MerchantId, | ||||||
|     card_reference: &'a str, |     card_reference: &'a str, | ||||||
| ) -> errors::RouterResult<payment_methods::DeleteCardResp> { | ) -> errors::CustomResult<payment_methods::DeleteCardResp, errors::VaultError> { | ||||||
|     let locker = &state.conf.locker; |     let locker = &state.conf.locker; | ||||||
|     let jwekey = &state.conf.jwekey.get_inner(); |     let jwekey = &state.conf.jwekey.get_inner(); | ||||||
|  |  | ||||||
| @ -2376,35 +2417,26 @@ pub async fn delete_card_from_hs_locker<'a>( | |||||||
|         customer_id, |         customer_id, | ||||||
|         merchant_id, |         merchant_id, | ||||||
|         card_reference, |         card_reference, | ||||||
|  |         state.tenant.name.clone(), | ||||||
|  |         state.request_id, | ||||||
|     ) |     ) | ||||||
|     .await |     .await | ||||||
|     .change_context(errors::ApiErrorResponse::InternalServerError) |     .change_context(errors::VaultError::DeleteCardFailed) | ||||||
|     .attach_printable("Making delete card request failed")?; |     .attach_printable("Making delete card request failed")?; | ||||||
|  |  | ||||||
|     if !locker.mock_locker { |     if !locker.mock_locker { | ||||||
|         let response = services::call_connector_api(state, request, "delete_card_from_locker") |         call_locker_api::<payment_methods::DeleteCardResp>( | ||||||
|             .await |             state, | ||||||
|             .change_context(errors::ApiErrorResponse::InternalServerError) |             request, | ||||||
|             .attach_printable("Failed while executing call_connector_api for delete card"); |             "delete_card_from_locker", | ||||||
|         let jwe_body: services::JweBody = response.get_response_inner("JweBody")?; |  | ||||||
|         let decrypted_payload = payment_methods::get_decrypted_response_payload( |  | ||||||
|             jwekey, |  | ||||||
|             jwe_body, |  | ||||||
|             Some(api_enums::LockerChoice::HyperswitchCardVault), |             Some(api_enums::LockerChoice::HyperswitchCardVault), | ||||||
|             locker.decryption_scheme.clone(), |  | ||||||
|         ) |         ) | ||||||
|         .await |         .await | ||||||
|         .change_context(errors::ApiErrorResponse::InternalServerError) |         .change_context(errors::VaultError::DeleteCardFailed) | ||||||
|         .attach_printable("Error getting decrypted response payload for delete card")?; |  | ||||||
|         let delete_card_resp: payment_methods::DeleteCardResp = decrypted_payload |  | ||||||
|             .parse_struct("DeleteCardResp") |  | ||||||
|             .change_context(errors::ApiErrorResponse::InternalServerError)?; |  | ||||||
|         Ok(delete_card_resp) |  | ||||||
|     } else { |     } else { | ||||||
|         Ok(mock_delete_card_hs(&*state.store, card_reference) |         Ok(mock_delete_card_hs(&*state.store, card_reference) | ||||||
|             .await |             .await | ||||||
|             .change_context(errors::ApiErrorResponse::InternalServerError) |             .change_context(errors::VaultError::DeleteCardFailed)?) | ||||||
|             .attach_printable("card_delete_failure_message")?) |  | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| @ -4871,6 +4903,10 @@ pub async fn list_customer_payment_method( | |||||||
|  |  | ||||||
|     let mut filtered_saved_payment_methods_ctx = Vec::new(); |     let mut filtered_saved_payment_methods_ctx = Vec::new(); | ||||||
|     for pm in saved_payment_methods.into_iter() { |     for pm in saved_payment_methods.into_iter() { | ||||||
|  |         logger::debug!( | ||||||
|  |             "Fetching payment method from locker for payment_method_id: {}", | ||||||
|  |             pm.id | ||||||
|  |         ); | ||||||
|         let payment_method = pm.payment_method.get_required_value("payment_method")?; |         let payment_method = pm.payment_method.get_required_value("payment_method")?; | ||||||
|         let parent_payment_method_token = |         let parent_payment_method_token = | ||||||
|             is_payment_associated.then(|| generate_id(consts::ID_LENGTH, "token")); |             is_payment_associated.then(|| generate_id(consts::ID_LENGTH, "token")); | ||||||
|  | |||||||
| @ -10,6 +10,7 @@ use common_utils::{ | |||||||
| }; | }; | ||||||
| use error_stack::ResultExt; | use error_stack::ResultExt; | ||||||
| use josekit::jwe; | use josekit::jwe; | ||||||
|  | use router_env::tracing_actix_web::RequestId; | ||||||
| use serde::{Deserialize, Serialize}; | use serde::{Deserialize, Serialize}; | ||||||
|  |  | ||||||
| use crate::{ | use crate::{ | ||||||
| @ -301,6 +302,8 @@ pub async fn mk_add_locker_request_hs( | |||||||
|     locker: &settings::Locker, |     locker: &settings::Locker, | ||||||
|     payload: &StoreLockerReq, |     payload: &StoreLockerReq, | ||||||
|     locker_choice: api_enums::LockerChoice, |     locker_choice: api_enums::LockerChoice, | ||||||
|  |     tenant_id: String, | ||||||
|  |     request_id: Option<RequestId>, | ||||||
| ) -> CustomResult<services::Request, errors::VaultError> { | ) -> CustomResult<services::Request, errors::VaultError> { | ||||||
|     let payload = payload |     let payload = payload | ||||||
|         .encode_to_vec() |         .encode_to_vec() | ||||||
| @ -319,6 +322,13 @@ pub async fn mk_add_locker_request_hs( | |||||||
|     url.push_str("/cards/add"); |     url.push_str("/cards/add"); | ||||||
|     let mut request = services::Request::new(services::Method::Post, &url); |     let mut request = services::Request::new(services::Method::Post, &url); | ||||||
|     request.add_header(headers::CONTENT_TYPE, "application/json".into()); |     request.add_header(headers::CONTENT_TYPE, "application/json".into()); | ||||||
|  |     request.add_header(headers::X_TENANT_ID, tenant_id.into()); | ||||||
|  |     if let Some(req_id) = request_id { | ||||||
|  |         request.add_header( | ||||||
|  |             headers::X_REQUEST_ID, | ||||||
|  |             req_id.as_hyphenated().to_string().into(), | ||||||
|  |         ); | ||||||
|  |     } | ||||||
|     request.set_body(RequestContent::Json(Box::new(jwe_payload))); |     request.set_body(RequestContent::Json(Box::new(jwe_payload))); | ||||||
|     Ok(request) |     Ok(request) | ||||||
| } | } | ||||||
| @ -425,6 +435,7 @@ pub fn mk_add_card_response_hs( | |||||||
|     todo!() |     todo!() | ||||||
| } | } | ||||||
|  |  | ||||||
|  | #[allow(clippy::too_many_arguments)] | ||||||
| pub async fn mk_get_card_request_hs( | pub async fn mk_get_card_request_hs( | ||||||
|     jwekey: &settings::Jwekey, |     jwekey: &settings::Jwekey, | ||||||
|     locker: &settings::Locker, |     locker: &settings::Locker, | ||||||
| @ -432,6 +443,8 @@ pub async fn mk_get_card_request_hs( | |||||||
|     merchant_id: &id_type::MerchantId, |     merchant_id: &id_type::MerchantId, | ||||||
|     card_reference: &str, |     card_reference: &str, | ||||||
|     locker_choice: Option<api_enums::LockerChoice>, |     locker_choice: Option<api_enums::LockerChoice>, | ||||||
|  |     tenant_id: String, | ||||||
|  |     request_id: Option<RequestId>, | ||||||
| ) -> CustomResult<services::Request, errors::VaultError> { | ) -> CustomResult<services::Request, errors::VaultError> { | ||||||
|     let merchant_customer_id = customer_id.to_owned(); |     let merchant_customer_id = customer_id.to_owned(); | ||||||
|     let card_req_body = CardReqBody { |     let card_req_body = CardReqBody { | ||||||
| @ -458,6 +471,14 @@ pub async fn mk_get_card_request_hs( | |||||||
|     url.push_str("/cards/retrieve"); |     url.push_str("/cards/retrieve"); | ||||||
|     let mut request = services::Request::new(services::Method::Post, &url); |     let mut request = services::Request::new(services::Method::Post, &url); | ||||||
|     request.add_header(headers::CONTENT_TYPE, "application/json".into()); |     request.add_header(headers::CONTENT_TYPE, "application/json".into()); | ||||||
|  |     request.add_header(headers::X_TENANT_ID, tenant_id.into()); | ||||||
|  |     if let Some(req_id) = request_id { | ||||||
|  |         request.add_header( | ||||||
|  |             headers::X_REQUEST_ID, | ||||||
|  |             req_id.as_hyphenated().to_string().into(), | ||||||
|  |         ); | ||||||
|  |     } | ||||||
|  |  | ||||||
|     request.set_body(RequestContent::Json(Box::new(jwe_payload))); |     request.set_body(RequestContent::Json(Box::new(jwe_payload))); | ||||||
|     Ok(request) |     Ok(request) | ||||||
| } | } | ||||||
| @ -503,6 +524,8 @@ pub async fn mk_delete_card_request_hs( | |||||||
|     customer_id: &id_type::CustomerId, |     customer_id: &id_type::CustomerId, | ||||||
|     merchant_id: &id_type::MerchantId, |     merchant_id: &id_type::MerchantId, | ||||||
|     card_reference: &str, |     card_reference: &str, | ||||||
|  |     tenant_id: String, | ||||||
|  |     request_id: Option<RequestId>, | ||||||
| ) -> CustomResult<services::Request, errors::VaultError> { | ) -> CustomResult<services::Request, errors::VaultError> { | ||||||
|     let merchant_customer_id = customer_id.to_owned(); |     let merchant_customer_id = customer_id.to_owned(); | ||||||
|     let card_req_body = CardReqBody { |     let card_req_body = CardReqBody { | ||||||
| @ -527,6 +550,14 @@ pub async fn mk_delete_card_request_hs( | |||||||
|     url.push_str("/cards/delete"); |     url.push_str("/cards/delete"); | ||||||
|     let mut request = services::Request::new(services::Method::Post, &url); |     let mut request = services::Request::new(services::Method::Post, &url); | ||||||
|     request.add_header(headers::CONTENT_TYPE, "application/json".into()); |     request.add_header(headers::CONTENT_TYPE, "application/json".into()); | ||||||
|  |     request.add_header(headers::X_TENANT_ID, tenant_id.into()); | ||||||
|  |     if let Some(req_id) = request_id { | ||||||
|  |         request.add_header( | ||||||
|  |             headers::X_REQUEST_ID, | ||||||
|  |             req_id.as_hyphenated().to_string().into(), | ||||||
|  |         ); | ||||||
|  |     } | ||||||
|  |  | ||||||
|     request.set_body(RequestContent::Json(Box::new(jwe_payload))); |     request.set_body(RequestContent::Json(Box::new(jwe_payload))); | ||||||
|     Ok(request) |     Ok(request) | ||||||
| } | } | ||||||
| @ -539,6 +570,8 @@ pub async fn mk_delete_card_request_hs_by_id( | |||||||
|     id: &String, |     id: &String, | ||||||
|     merchant_id: &id_type::MerchantId, |     merchant_id: &id_type::MerchantId, | ||||||
|     card_reference: &str, |     card_reference: &str, | ||||||
|  |     tenant_id: String, | ||||||
|  |     request_id: Option<RequestId>, | ||||||
| ) -> CustomResult<services::Request, errors::VaultError> { | ) -> CustomResult<services::Request, errors::VaultError> { | ||||||
|     let merchant_customer_id = id.to_owned(); |     let merchant_customer_id = id.to_owned(); | ||||||
|     let card_req_body = CardReqBodyV2 { |     let card_req_body = CardReqBodyV2 { | ||||||
| @ -563,6 +596,14 @@ pub async fn mk_delete_card_request_hs_by_id( | |||||||
|     url.push_str("/cards/delete"); |     url.push_str("/cards/delete"); | ||||||
|     let mut request = services::Request::new(services::Method::Post, &url); |     let mut request = services::Request::new(services::Method::Post, &url); | ||||||
|     request.add_header(headers::CONTENT_TYPE, "application/json".into()); |     request.add_header(headers::CONTENT_TYPE, "application/json".into()); | ||||||
|  |     request.add_header(headers::X_TENANT_ID, tenant_id.into()); | ||||||
|  |     if let Some(req_id) = request_id { | ||||||
|  |         request.add_header( | ||||||
|  |             headers::X_REQUEST_ID, | ||||||
|  |             req_id.as_hyphenated().to_string().into(), | ||||||
|  |         ); | ||||||
|  |     } | ||||||
|  |  | ||||||
|     request.set_body(RequestContent::Json(Box::new(jwe_payload))); |     request.set_body(RequestContent::Json(Box::new(jwe_payload))); | ||||||
|     Ok(request) |     Ok(request) | ||||||
| } | } | ||||||
| @ -641,12 +682,22 @@ pub fn mk_crud_locker_request( | |||||||
|     locker: &settings::Locker, |     locker: &settings::Locker, | ||||||
|     path: &str, |     path: &str, | ||||||
|     req: api::TokenizePayloadEncrypted, |     req: api::TokenizePayloadEncrypted, | ||||||
|  |     tenant_id: String, | ||||||
|  |     request_id: Option<RequestId>, | ||||||
| ) -> CustomResult<services::Request, errors::VaultError> { | ) -> CustomResult<services::Request, errors::VaultError> { | ||||||
|     let mut url = locker.basilisk_host.to_owned(); |     let mut url = locker.basilisk_host.to_owned(); | ||||||
|     url.push_str(path); |     url.push_str(path); | ||||||
|     let mut request = services::Request::new(services::Method::Post, &url); |     let mut request = services::Request::new(services::Method::Post, &url); | ||||||
|     request.add_default_headers(); |     request.add_default_headers(); | ||||||
|     request.add_header(headers::CONTENT_TYPE, "application/json".into()); |     request.add_header(headers::CONTENT_TYPE, "application/json".into()); | ||||||
|  |     request.add_header(headers::X_TENANT_ID, tenant_id.into()); | ||||||
|  |     if let Some(req_id) = request_id { | ||||||
|  |         request.add_header( | ||||||
|  |             headers::X_REQUEST_ID, | ||||||
|  |             req_id.as_hyphenated().to_string().into(), | ||||||
|  |         ); | ||||||
|  |     } | ||||||
|  |  | ||||||
|     request.set_body(RequestContent::Json(Box::new(req))); |     request.set_body(RequestContent::Json(Box::new(req))); | ||||||
|     Ok(request) |     Ok(request) | ||||||
| } | } | ||||||
|  | |||||||
| @ -307,7 +307,7 @@ pub async fn save_payout_data_to_locker( | |||||||
|         }; |         }; | ||||||
|  |  | ||||||
|     // Store payout method in locker |     // Store payout method in locker | ||||||
|     let stored_resp = cards::call_to_locker_hs( |     let stored_resp = cards::add_card_to_hs_locker( | ||||||
|         state, |         state, | ||||||
|         &locker_req, |         &locker_req, | ||||||
|         customer_id, |         customer_id, | ||||||
| @ -559,6 +559,7 @@ pub async fn save_payout_data_to_locker( | |||||||
|             card_reference, |             card_reference, | ||||||
|         ) |         ) | ||||||
|         .await |         .await | ||||||
|  |         .change_context(errors::ApiErrorResponse::InternalServerError) | ||||||
|         .attach_printable( |         .attach_printable( | ||||||
|             "Failed to delete PMD from locker as a part of metadata update operation", |             "Failed to delete PMD from locker as a part of metadata update operation", | ||||||
|         )?; |         )?; | ||||||
| @ -566,7 +567,7 @@ pub async fn save_payout_data_to_locker( | |||||||
|         locker_req.update_requestor_card_reference(Some(card_reference.to_string())); |         locker_req.update_requestor_card_reference(Some(card_reference.to_string())); | ||||||
|  |  | ||||||
|         // Store in locker |         // Store in locker | ||||||
|         let stored_resp = cards::call_to_locker_hs( |         let stored_resp = cards::add_card_to_hs_locker( | ||||||
|             state, |             state, | ||||||
|             &locker_req, |             &locker_req, | ||||||
|             customer_id, |             customer_id, | ||||||
|  | |||||||
| @ -83,6 +83,7 @@ pub mod headers { | |||||||
|     pub const BROWSER_NAME: &str = "x-browser-name"; |     pub const BROWSER_NAME: &str = "x-browser-name"; | ||||||
|     pub const X_CLIENT_PLATFORM: &str = "x-client-platform"; |     pub const X_CLIENT_PLATFORM: &str = "x-client-platform"; | ||||||
|     pub const X_MERCHANT_DOMAIN: &str = "x-merchant-domain"; |     pub const X_MERCHANT_DOMAIN: &str = "x-merchant-domain"; | ||||||
|  |     pub const X_TENANT_ID: &str = "x-tenant-id"; | ||||||
| } | } | ||||||
|  |  | ||||||
| pub mod pii { | pub mod pii { | ||||||
|  | |||||||
		Reference in New Issue
	
	Block a user
	 Chethan Rao
					Chethan Rao