mirror of
				https://github.com/juspay/hyperswitch.git
				synced 2025-11-01 02:50:53 +08:00 
			
		
		
		
	refactor(core): move authentication data fields to authentication table (#4093)
Co-authored-by: hyperswitch-bot[bot] <148525504+hyperswitch-bot[bot]@users.noreply.github.com> Co-authored-by: sai-harsha-vardhan <harsha111hero@gmail.com> Co-authored-by: Sai Harsha Vardhan <56996463+sai-harsha-vardhan@users.noreply.github.com>
This commit is contained in:
		| @ -1,12 +1,9 @@ | ||||
| use common_enums::DecoupledAuthenticationType; | ||||
| use common_utils::ext_traits::{Encode, ValueExt}; | ||||
| use error_stack::ResultExt; | ||||
|  | ||||
| use super::types::{AuthenticationData, ThreeDsMethodData}; | ||||
| use crate::{ | ||||
|     consts, | ||||
|     core::{ | ||||
|         errors::{ApiErrorResponse, ConnectorErrorExt, StorageErrorExt}, | ||||
|         errors::{self, ConnectorErrorExt, StorageErrorExt}, | ||||
|         payments, | ||||
|     }, | ||||
|     errors::RouterResult, | ||||
| @ -14,12 +11,11 @@ use crate::{ | ||||
|     services::{self, execute_connector_processing_step}, | ||||
|     types::{ | ||||
|         api::{self, ConnectorCallType}, | ||||
|         authentication::{AuthNFlowType, AuthenticationResponseData}, | ||||
|         authentication::AuthenticationResponseData, | ||||
|         storage, | ||||
|         transformers::ForeignFrom, | ||||
|         RouterData, | ||||
|     }, | ||||
|     utils::OptionExt, | ||||
| }; | ||||
|  | ||||
| pub fn get_connector_name_if_separate_authn_supported( | ||||
| @ -56,19 +52,8 @@ pub async fn update_trackers<F: Clone, Req>( | ||||
|     authentication: storage::Authentication, | ||||
|     token: Option<String>, | ||||
|     acquirer_details: Option<super::types::AcquirerDetails>, | ||||
| ) -> RouterResult<(storage::Authentication, Option<AuthenticationData>)> { | ||||
|     let authentication_data_option = authentication | ||||
|         .authentication_data | ||||
|         .as_ref() | ||||
|         .map(|authentication_data| { | ||||
|             authentication_data | ||||
|                 .to_owned() | ||||
|                 .parse_value::<AuthenticationData>("AuthenticationData") | ||||
|                 .change_context(ApiErrorResponse::InternalServerError) | ||||
|         }) | ||||
|         .transpose()?; | ||||
|  | ||||
|     let (authentication_update, updated_authentication_data) = match router_data.response { | ||||
| ) -> RouterResult<storage::Authentication> { | ||||
|     let authentication_update = match router_data.response { | ||||
|         Ok(response) => match response { | ||||
|             AuthenticationResponseData::PreAuthNResponse { | ||||
|                 threeds_server_transaction_id, | ||||
| @ -78,132 +63,70 @@ pub async fn update_trackers<F: Clone, Req>( | ||||
|                 three_ds_method_url, | ||||
|                 message_version, | ||||
|                 connector_metadata, | ||||
|             } => { | ||||
|                 let three_ds_method_data = ThreeDsMethodData { | ||||
|                     three_ds_method_data, | ||||
|                     three_ds_method_data_submission: three_ds_method_url.is_some(), | ||||
|                     three_ds_method_url, | ||||
|                 }; | ||||
|                 let authentication_data = AuthenticationData { | ||||
|                     maximum_supported_version: maximum_supported_3ds_version, | ||||
|                     threeds_server_transaction_id, | ||||
|                     three_ds_method_data, | ||||
|                     message_version, | ||||
|                     acquirer_details, | ||||
|                     ..Default::default() | ||||
|                 }; | ||||
|                 ( | ||||
|                     storage::AuthenticationUpdate::AuthenticationDataUpdate { | ||||
|                         authentication_data: Some( | ||||
|                             Encode::encode_to_value(&authentication_data) | ||||
|                                 .change_context(ApiErrorResponse::InternalServerError)?, | ||||
|                         ), | ||||
|                         connector_authentication_id: Some(connector_authentication_id), | ||||
|                         payment_method_id: token.map(|token| format!("eph_{}", token)), | ||||
|                         authentication_type: None, | ||||
|                         authentication_status: Some(common_enums::AuthenticationStatus::Started), | ||||
|                         authentication_lifecycle_status: None, | ||||
|                         connector_metadata, | ||||
|                     }, | ||||
|                     Some(authentication_data), | ||||
|                 ) | ||||
|             } | ||||
|             } => storage::AuthenticationUpdate::PreAuthenticationUpdate { | ||||
|                 threeds_server_transaction_id, | ||||
|                 maximum_supported_3ds_version, | ||||
|                 connector_authentication_id, | ||||
|                 three_ds_method_data, | ||||
|                 three_ds_method_url, | ||||
|                 message_version, | ||||
|                 connector_metadata, | ||||
|                 authentication_status: common_enums::AuthenticationStatus::Pending, | ||||
|                 payment_method_id: token.map(|token| format!("eph_{}", token)), | ||||
|                 acquirer_bin: acquirer_details | ||||
|                     .as_ref() | ||||
|                     .map(|acquirer_details| acquirer_details.acquirer_bin.clone()), | ||||
|                 acquirer_merchant_id: acquirer_details | ||||
|                     .map(|acquirer_details| acquirer_details.acquirer_merchant_id), | ||||
|             }, | ||||
|             AuthenticationResponseData::AuthNResponse { | ||||
|                 authn_flow_type, | ||||
|                 authentication_value: cavv, | ||||
|                 authentication_value, | ||||
|                 trans_status, | ||||
|             } => { | ||||
|                 let authentication_data = authentication_data_option | ||||
|                     .get_required_value("authentication_data") | ||||
|                     .attach_printable( | ||||
|                         "AuthenticationData is required to make Authentication call", | ||||
|                     )?; | ||||
|                 let authentication_data = AuthenticationData { | ||||
|                     authn_flow_type: Some(authn_flow_type.clone()), | ||||
|                     cavv, | ||||
|                     trans_status: trans_status.clone(), | ||||
|                     ..authentication_data | ||||
|                 }; | ||||
|                 ( | ||||
|                     storage::AuthenticationUpdate::AuthenticationDataUpdate { | ||||
|                         authentication_data: Some( | ||||
|                             Encode::encode_to_value(&authentication_data) | ||||
|                                 .change_context(ApiErrorResponse::InternalServerError)?, | ||||
|                         ), | ||||
|                         connector_authentication_id: None, | ||||
|                         payment_method_id: None, | ||||
|                         authentication_type: Some(match authn_flow_type { | ||||
|                             AuthNFlowType::Challenge { .. } => { | ||||
|                                 DecoupledAuthenticationType::Challenge | ||||
|                             } | ||||
|                             AuthNFlowType::Frictionless => { | ||||
|                                 DecoupledAuthenticationType::Frictionless | ||||
|                             } | ||||
|                         }), | ||||
|                         authentication_status: Some( | ||||
|                             common_enums::AuthenticationStatus::foreign_from(trans_status), | ||||
|                         ), | ||||
|                         authentication_lifecycle_status: None, | ||||
|                         connector_metadata: None, | ||||
|                     }, | ||||
|                     Some(authentication_data), | ||||
|                 ) | ||||
|                 let authentication_status = | ||||
|                     common_enums::AuthenticationStatus::foreign_from(trans_status.clone()); | ||||
|                 storage::AuthenticationUpdate::AuthenticationUpdate { | ||||
|                     authentication_value, | ||||
|                     trans_status, | ||||
|                     acs_url: authn_flow_type.get_acs_url(), | ||||
|                     challenge_request: authn_flow_type.get_challenge_request(), | ||||
|                     acs_reference_number: authn_flow_type.get_acs_reference_number(), | ||||
|                     acs_trans_id: authn_flow_type.get_acs_trans_id(), | ||||
|                     acs_signed_content: authn_flow_type.get_acs_signed_content(), | ||||
|                     authentication_type: authn_flow_type.get_decoupled_authentication_type(), | ||||
|                     authentication_status, | ||||
|                 } | ||||
|             } | ||||
|             AuthenticationResponseData::PostAuthNResponse { | ||||
|                 trans_status, | ||||
|                 authentication_value, | ||||
|                 eci, | ||||
|             } => { | ||||
|                 let authentication_data = authentication_data_option | ||||
|                     .get_required_value("authentication_data") | ||||
|                     .attach_printable( | ||||
|                         "AuthenticationData is required to make Post Authentication call", | ||||
|                     )?; | ||||
|                 let authentication_data = AuthenticationData { | ||||
|                     cavv: authentication_value, | ||||
|                     eci, | ||||
|                     trans_status: trans_status.clone(), | ||||
|                     ..authentication_data | ||||
|                 }; | ||||
|                 ( | ||||
|                     storage::AuthenticationUpdate::AuthenticationDataUpdate { | ||||
|                         authentication_data: Some( | ||||
|                             Encode::encode_to_value(&authentication_data) | ||||
|                                 .change_context(ApiErrorResponse::InternalServerError)?, | ||||
|                         ), | ||||
|                         connector_authentication_id: None, | ||||
|                         payment_method_id: None, | ||||
|                         authentication_type: None, | ||||
|                         authentication_status: Some( | ||||
|                             common_enums::AuthenticationStatus::foreign_from(trans_status), | ||||
|                         ), | ||||
|                         authentication_lifecycle_status: None, | ||||
|                         connector_metadata: None, | ||||
|                     }, | ||||
|                     Some(authentication_data), | ||||
|                 ) | ||||
|             } | ||||
|         }, | ||||
|         Err(error) => ( | ||||
|             storage::AuthenticationUpdate::ErrorUpdate { | ||||
|                 connector_authentication_id: error.connector_transaction_id, | ||||
|                 authentication_status: common_enums::AuthenticationStatus::Failed, | ||||
|                 error_message: Some(error.message), | ||||
|                 error_code: Some(error.code), | ||||
|             } => storage::AuthenticationUpdate::PostAuthenticationUpdate { | ||||
|                 authentication_status: common_enums::AuthenticationStatus::foreign_from( | ||||
|                     trans_status.clone(), | ||||
|                 ), | ||||
|                 trans_status, | ||||
|                 authentication_value, | ||||
|                 eci, | ||||
|             }, | ||||
|             authentication_data_option, | ||||
|         ), | ||||
|         }, | ||||
|         Err(error) => storage::AuthenticationUpdate::ErrorUpdate { | ||||
|             connector_authentication_id: error.connector_transaction_id, | ||||
|             authentication_status: common_enums::AuthenticationStatus::Failed, | ||||
|             error_message: Some(error.message), | ||||
|             error_code: Some(error.code), | ||||
|         }, | ||||
|     }; | ||||
|     let authentication_result = state | ||||
|     state | ||||
|         .store | ||||
|         .update_authentication_by_merchant_id_authentication_id( | ||||
|             authentication, | ||||
|             authentication_update, | ||||
|         ) | ||||
|         .await | ||||
|         .change_context(ApiErrorResponse::InternalServerError) | ||||
|         .attach_printable("Error while updating authentication"); | ||||
|     authentication_result.map(|authentication| (authentication, updated_authentication_data)) | ||||
|         .change_context(errors::ApiErrorResponse::InternalServerError) | ||||
|         .attach_printable("Error while updating authentication") | ||||
| } | ||||
|  | ||||
| impl ForeignFrom<common_enums::AuthenticationStatus> for common_enums::AttemptStatus { | ||||
| @ -229,7 +152,6 @@ pub async fn create_new_authentication( | ||||
|         merchant_id, | ||||
|         authentication_connector, | ||||
|         connector_authentication_id: None, | ||||
|         authentication_data: None, | ||||
|         payment_method_id: "".into(), | ||||
|         authentication_type: None, | ||||
|         authentication_status: common_enums::AuthenticationStatus::Started, | ||||
| @ -237,12 +159,29 @@ pub async fn create_new_authentication( | ||||
|         error_message: None, | ||||
|         error_code: None, | ||||
|         connector_metadata: None, | ||||
|         maximum_supported_version: None, | ||||
|         threeds_server_transaction_id: None, | ||||
|         cavv: None, | ||||
|         authentication_flow_type: None, | ||||
|         message_version: None, | ||||
|         eci: None, | ||||
|         trans_status: None, | ||||
|         acquirer_bin: None, | ||||
|         acquirer_merchant_id: None, | ||||
|         three_ds_method_data: None, | ||||
|         three_ds_method_url: None, | ||||
|         acs_url: None, | ||||
|         challenge_request: None, | ||||
|         acs_reference_number: None, | ||||
|         acs_trans_id: None, | ||||
|         three_dsserver_trans_id: None, | ||||
|         acs_signed_content: None, | ||||
|     }; | ||||
|     state | ||||
|         .store | ||||
|         .insert_authentication(new_authorization) | ||||
|         .await | ||||
|         .to_duplicate_response(ApiErrorResponse::GenericDuplicateError { | ||||
|         .to_duplicate_response(errors::ApiErrorResponse::GenericDuplicateError { | ||||
|             message: format!( | ||||
|                 "Authentication with authentication_id {} already exists", | ||||
|                 authentication_id | ||||
|  | ||||
		Reference in New Issue
	
	Block a user
	 Hrithikesh
					Hrithikesh