mirror of
				https://github.com/juspay/hyperswitch.git
				synced 2025-10-31 10:06:32 +08:00 
			
		
		
		
	feat(core): update card_details for an existing mandate (#3452)
Co-authored-by: hyperswitch-bot[bot] <148525504+hyperswitch-bot[bot]@users.noreply.github.com>
This commit is contained in:
		| @ -753,6 +753,7 @@ impl ForeignTryFrom<(Option<MandateData>, Option<String>)> for Option<payments:: | ||||
|                         user_agent: online.user_agent, | ||||
|                     }), | ||||
|             }), | ||||
|             update_mandate_id: None, | ||||
|         }); | ||||
|         Ok(mandate_data) | ||||
|     } | ||||
|  | ||||
| @ -1,13 +1,13 @@ | ||||
| pub mod helpers; | ||||
| pub mod utils; | ||||
|  | ||||
| use api_models::payments; | ||||
| use common_utils::{ext_traits::Encode, pii}; | ||||
| use diesel_models::enums as storage_enums; | ||||
| use diesel_models::{enums as storage_enums, Mandate}; | ||||
| use error_stack::{report, IntoReport, ResultExt}; | ||||
| use futures::future; | ||||
| use router_env::{instrument, logger, tracing}; | ||||
|  | ||||
| use super::payments::helpers; | ||||
| use super::payments::helpers as payment_helper; | ||||
| use crate::{ | ||||
|     core::{ | ||||
|         errors::{self, RouterResponse, StorageErrorExt}, | ||||
| @ -64,34 +64,17 @@ pub async fn revoke_mandate( | ||||
|         common_enums::MandateStatus::Active | ||||
|         | common_enums::MandateStatus::Inactive | ||||
|         | common_enums::MandateStatus::Pending => { | ||||
|             let profile_id = if let Some(ref payment_id) = mandate.original_payment_id { | ||||
|                 let pi = db | ||||
|                     .find_payment_intent_by_payment_id_merchant_id( | ||||
|                         payment_id, | ||||
|                         &merchant_account.merchant_id, | ||||
|                         merchant_account.storage_scheme, | ||||
|                     ) | ||||
|                     .await | ||||
|                     .change_context(errors::ApiErrorResponse::PaymentNotFound)?; | ||||
|                 let profile_id = pi.profile_id.clone().ok_or( | ||||
|                     errors::ApiErrorResponse::BusinessProfileNotFound { | ||||
|                         id: pi | ||||
|                             .profile_id | ||||
|                             .unwrap_or_else(|| "Profile id is Null".to_string()), | ||||
|                     }, | ||||
|                 )?; | ||||
|                 Ok(profile_id) | ||||
|             } else { | ||||
|                 Err(errors::ApiErrorResponse::PaymentNotFound) | ||||
|             }?; | ||||
|             let profile_id = | ||||
|                 helpers::get_profile_id_for_mandate(&state, &merchant_account, mandate.clone()) | ||||
|                     .await?; | ||||
|  | ||||
|             let merchant_connector_account = helpers::get_merchant_connector_account( | ||||
|             let merchant_connector_account = payment_helper::get_merchant_connector_account( | ||||
|                 &state, | ||||
|                 &merchant_account.merchant_id, | ||||
|                 None, | ||||
|                 &key_store, | ||||
|                 &profile_id, | ||||
|                 &mandate.connector, | ||||
|                 &mandate.connector.clone(), | ||||
|                 mandate.merchant_connector_id.as_ref(), | ||||
|             ) | ||||
|             .await?; | ||||
| @ -243,7 +226,72 @@ where | ||||
|         _ => Some(router_data.request.get_payment_method_data()), | ||||
|     } | ||||
| } | ||||
| pub async fn update_mandate_procedure<F, FData>( | ||||
|     state: &AppState, | ||||
|     resp: types::RouterData<F, FData, types::PaymentsResponseData>, | ||||
|     mandate: Mandate, | ||||
|     merchant_id: &str, | ||||
|     pm_id: Option<String>, | ||||
| ) -> errors::RouterResult<types::RouterData<F, FData, types::PaymentsResponseData>> | ||||
| where | ||||
|     FData: MandateBehaviour, | ||||
| { | ||||
|     let mandate_details = match &resp.response { | ||||
|         Ok(types::PaymentsResponseData::TransactionResponse { | ||||
|             mandate_reference, .. | ||||
|         }) => mandate_reference, | ||||
|         Ok(_) => Err(errors::ApiErrorResponse::InternalServerError) | ||||
|             .into_report() | ||||
|             .attach_printable("Unexpected response received")?, | ||||
|         Err(_) => return Ok(resp), | ||||
|     }; | ||||
|  | ||||
|     let old_record = payments::UpdateHistory { | ||||
|         connector_mandate_id: mandate.connector_mandate_id, | ||||
|         payment_method_id: mandate.payment_method_id, | ||||
|         original_payment_id: mandate.original_payment_id, | ||||
|     }; | ||||
|  | ||||
|     let mandate_ref = mandate | ||||
|         .connector_mandate_ids | ||||
|         .parse_value::<payments::ConnectorMandateReferenceId>("Connector Reference Id") | ||||
|         .change_context(errors::ApiErrorResponse::MandateDeserializationFailed)?; | ||||
|  | ||||
|     let mut update_history = mandate_ref.update_history.unwrap_or_default(); | ||||
|     update_history.push(old_record); | ||||
|  | ||||
|     let updated_mandate_ref = payments::ConnectorMandateReferenceId { | ||||
|         connector_mandate_id: mandate_details | ||||
|             .as_ref() | ||||
|             .and_then(|mandate_ref| mandate_ref.connector_mandate_id.clone()), | ||||
|         payment_method_id: pm_id.clone(), | ||||
|         update_history: Some(update_history), | ||||
|     }; | ||||
|  | ||||
|     let connector_mandate_ids = | ||||
|         Encode::<types::MandateReference>::encode_to_value(&updated_mandate_ref) | ||||
|             .change_context(errors::ApiErrorResponse::InternalServerError) | ||||
|             .map(masking::Secret::new)?; | ||||
|  | ||||
|     let _update_mandate_details = state | ||||
|         .store | ||||
|         .update_mandate_by_merchant_id_mandate_id( | ||||
|             merchant_id, | ||||
|             &mandate.mandate_id, | ||||
|             diesel_models::MandateUpdate::ConnectorMandateIdUpdate { | ||||
|                 connector_mandate_id: mandate_details | ||||
|                     .as_ref() | ||||
|                     .and_then(|man_ref| man_ref.connector_mandate_id.clone()), | ||||
|                 connector_mandate_ids: Some(connector_mandate_ids), | ||||
|                 payment_method_id: pm_id | ||||
|                     .unwrap_or("Error retrieving the payment_method_id".to_string()), | ||||
|                 original_payment_id: Some(resp.payment_id.clone()), | ||||
|             }, | ||||
|         ) | ||||
|         .await | ||||
|         .change_context(errors::ApiErrorResponse::MandateUpdateFailed)?; | ||||
|     Ok(resp) | ||||
| } | ||||
| pub async fn mandate_procedure<F, FData>( | ||||
|     state: &AppState, | ||||
|     mut resp: types::RouterData<F, FData, types::PaymentsResponseData>, | ||||
| @ -324,7 +372,7 @@ where | ||||
|                         }) | ||||
|                         .transpose()?; | ||||
|  | ||||
|                     if let Some(new_mandate_data) = helpers::generate_mandate( | ||||
|                     if let Some(new_mandate_data) = payment_helper::generate_mandate( | ||||
|                         resp.merchant_id.clone(), | ||||
|                         resp.payment_id.clone(), | ||||
|                         resp.connector.clone(), | ||||
| @ -363,6 +411,8 @@ where | ||||
|                                     api_models::payments::ConnectorMandateReferenceId { | ||||
|                                         connector_mandate_id: connector_id.connector_mandate_id, | ||||
|                                         payment_method_id: connector_id.payment_method_id, | ||||
|                                         update_history:None, | ||||
|  | ||||
|                                     } | ||||
|                                 ))) | ||||
|                         })); | ||||
|  | ||||
							
								
								
									
										35
									
								
								crates/router/src/core/mandate/helpers.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								crates/router/src/core/mandate/helpers.rs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,35 @@ | ||||
| use common_utils::errors::CustomResult; | ||||
| use diesel_models::Mandate; | ||||
| use error_stack::ResultExt; | ||||
|  | ||||
| use crate::{core::errors, routes::AppState, types::domain}; | ||||
|  | ||||
| pub async fn get_profile_id_for_mandate( | ||||
|     state: &AppState, | ||||
|     merchant_account: &domain::MerchantAccount, | ||||
|     mandate: Mandate, | ||||
| ) -> CustomResult<String, errors::ApiErrorResponse> { | ||||
|     let profile_id = if let Some(ref payment_id) = mandate.original_payment_id { | ||||
|         let pi = state | ||||
|             .store | ||||
|             .find_payment_intent_by_payment_id_merchant_id( | ||||
|                 payment_id, | ||||
|                 &merchant_account.merchant_id, | ||||
|                 merchant_account.storage_scheme, | ||||
|             ) | ||||
|             .await | ||||
|             .change_context(errors::ApiErrorResponse::PaymentNotFound)?; | ||||
|         let profile_id = | ||||
|             pi.profile_id | ||||
|                 .clone() | ||||
|                 .ok_or(errors::ApiErrorResponse::BusinessProfileNotFound { | ||||
|                     id: pi | ||||
|                         .profile_id | ||||
|                         .unwrap_or_else(|| "Profile id is Null".to_string()), | ||||
|                 })?; | ||||
|         Ok(profile_id) | ||||
|     } else { | ||||
|         Err(errors::ApiErrorResponse::PaymentNotFound) | ||||
|     }?; | ||||
|     Ok(profile_id) | ||||
| } | ||||
| @ -1823,14 +1823,24 @@ pub async fn list_payment_methods( | ||||
|         } else { | ||||
|             api_surcharge_decision_configs::MerchantSurchargeConfigs::default() | ||||
|         }; | ||||
|     print!("PAMT{:?}", payment_attempt); | ||||
|     Ok(services::ApplicationResponse::Json( | ||||
|         api::PaymentMethodListResponse { | ||||
|             redirect_url: merchant_account.return_url, | ||||
|             merchant_name: merchant_account.merchant_name, | ||||
|             payment_type, | ||||
|             payment_methods: payment_method_responses, | ||||
|             mandate_payment: payment_attempt.and_then(|inner| inner.mandate_details).map( | ||||
|                 |d| match d { | ||||
|             mandate_payment: payment_attempt | ||||
|                 .and_then(|inner| inner.mandate_details) | ||||
|                 .and_then(|man_type_details| match man_type_details { | ||||
|                     data_models::mandates::MandateTypeDetails::MandateType(mandate_type) => { | ||||
|                         Some(mandate_type) | ||||
|                     } | ||||
|                     data_models::mandates::MandateTypeDetails::MandateDetails(mandate_details) => { | ||||
|                         mandate_details.mandate_type | ||||
|                     } | ||||
|                 }) | ||||
|                 .map(|d| match d { | ||||
|                     data_models::mandates::MandateDataType::SingleUse(i) => { | ||||
|                         api::MandateType::SingleUse(api::MandateAmountData { | ||||
|                             amount: i.amount, | ||||
| @ -1852,8 +1862,7 @@ pub async fn list_payment_methods( | ||||
|                     data_models::mandates::MandateDataType::MultiUse(None) => { | ||||
|                         api::MandateType::MultiUse(None) | ||||
|                     } | ||||
|                 }, | ||||
|             ), | ||||
|                 }), | ||||
|             show_surcharge_breakup_screen: merchant_surcharge_configs | ||||
|                 .show_surcharge_breakup_screen | ||||
|                 .unwrap_or_default(), | ||||
|  | ||||
| @ -1,9 +1,10 @@ | ||||
| use async_trait::async_trait; | ||||
| use error_stack::{IntoReport, ResultExt}; | ||||
|  | ||||
| use super::{ConstructFlowSpecificData, Feature}; | ||||
| use crate::{ | ||||
|     core::{ | ||||
|         errors::{self, ConnectorErrorExt, RouterResult}, | ||||
|         errors::{self, ConnectorErrorExt, RouterResult, StorageErrorExt}, | ||||
|         mandate, | ||||
|         payments::{ | ||||
|             self, access_token, customers, helpers, tokenization, transformers, PaymentData, | ||||
| @ -65,16 +66,16 @@ impl Feature<api::SetupMandate, types::SetupMandateRequestData> for types::Setup | ||||
|             types::SetupMandateRequestData, | ||||
|             types::PaymentsResponseData, | ||||
|         > = connector.connector.get_connector_integration(); | ||||
|  | ||||
|         let resp = services::execute_connector_processing_step( | ||||
|             state, | ||||
|             connector_integration, | ||||
|             &self, | ||||
|             call_connector_action, | ||||
|             call_connector_action.clone(), | ||||
|             connector_request, | ||||
|         ) | ||||
|         .await | ||||
|         .to_setup_mandate_failed_response()?; | ||||
|  | ||||
|         let pm_id = Box::pin(tokenization::save_payment_method( | ||||
|             state, | ||||
|             connector, | ||||
| @ -86,14 +87,84 @@ impl Feature<api::SetupMandate, types::SetupMandateRequestData> for types::Setup | ||||
|         )) | ||||
|         .await?; | ||||
|  | ||||
|         mandate::mandate_procedure( | ||||
|             state, | ||||
|             resp, | ||||
|             maybe_customer, | ||||
|             pm_id, | ||||
|             connector.merchant_connector_id.clone(), | ||||
|         ) | ||||
|         .await | ||||
|         if let Some(mandate_id) = self | ||||
|             .request | ||||
|             .setup_mandate_details | ||||
|             .as_ref() | ||||
|             .and_then(|mandate_data| mandate_data.update_mandate_id.clone()) | ||||
|         { | ||||
|             let mandate = state | ||||
|                 .store | ||||
|                 .find_mandate_by_merchant_id_mandate_id(&merchant_account.merchant_id, &mandate_id) | ||||
|                 .await | ||||
|                 .to_not_found_response(errors::ApiErrorResponse::MandateNotFound)?; | ||||
|  | ||||
|             let profile_id = mandate::helpers::get_profile_id_for_mandate( | ||||
|                 state, | ||||
|                 merchant_account, | ||||
|                 mandate.clone(), | ||||
|             ) | ||||
|             .await?; | ||||
|             match resp.response { | ||||
|                 Ok(types::PaymentsResponseData::TransactionResponse { .. }) => { | ||||
|                     let connector_integration: services::BoxedConnectorIntegration< | ||||
|                         '_, | ||||
|                         types::api::MandateRevoke, | ||||
|                         types::MandateRevokeRequestData, | ||||
|                         types::MandateRevokeResponseData, | ||||
|                     > = connector.connector.get_connector_integration(); | ||||
|                     let merchant_connector_account = helpers::get_merchant_connector_account( | ||||
|                         state, | ||||
|                         &merchant_account.merchant_id, | ||||
|                         None, | ||||
|                         key_store, | ||||
|                         &profile_id, | ||||
|                         &mandate.connector, | ||||
|                         mandate.merchant_connector_id.as_ref(), | ||||
|                     ) | ||||
|                     .await?; | ||||
|  | ||||
|                     let router_data = mandate::utils::construct_mandate_revoke_router_data( | ||||
|                         merchant_connector_account, | ||||
|                         merchant_account, | ||||
|                         mandate.clone(), | ||||
|                     ) | ||||
|                     .await?; | ||||
|  | ||||
|                     let _response = services::execute_connector_processing_step( | ||||
|                         state, | ||||
|                         connector_integration, | ||||
|                         &router_data, | ||||
|                         call_connector_action, | ||||
|                         None, | ||||
|                     ) | ||||
|                     .await | ||||
|                     .change_context(errors::ApiErrorResponse::InternalServerError)?; | ||||
|                     // TODO:Add the revoke mandate task to process tracker | ||||
|                     mandate::update_mandate_procedure( | ||||
|                         state, | ||||
|                         resp, | ||||
|                         mandate, | ||||
|                         &merchant_account.merchant_id, | ||||
|                         pm_id, | ||||
|                     ) | ||||
|                     .await | ||||
|                 } | ||||
|                 Ok(_) => Err(errors::ApiErrorResponse::InternalServerError) | ||||
|                     .into_report() | ||||
|                     .attach_printable("Unexpected response received")?, | ||||
|                 Err(_) => Ok(resp), | ||||
|             } | ||||
|         } else { | ||||
|             mandate::mandate_procedure( | ||||
|                 state, | ||||
|                 resp, | ||||
|                 maybe_customer, | ||||
|                 pm_id, | ||||
|                 connector.merchant_connector_id.clone(), | ||||
|             ) | ||||
|             .await | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     async fn add_access_token<'a>( | ||||
|  | ||||
| @ -840,7 +840,7 @@ fn validate_new_mandate_request( | ||||
|     let mandate_details = match mandate_data.mandate_type { | ||||
|         Some(api_models::payments::MandateType::SingleUse(details)) => Some(details), | ||||
|         Some(api_models::payments::MandateType::MultiUse(details)) => details, | ||||
|         None => None, | ||||
|         _ => None, | ||||
|     }; | ||||
|     mandate_details.and_then(|md| md.start_date.zip(md.end_date)).map(|(start_date, end_date)| | ||||
|         utils::when (start_date >= end_date, || { | ||||
|  | ||||
| @ -431,7 +431,29 @@ impl<F: Send + Clone, Ctx: PaymentMethodRetrieve> | ||||
|  | ||||
|         // The operation merges mandate data from both request and payment_attempt | ||||
|         setup_mandate = setup_mandate.map(|mut sm| { | ||||
|             sm.mandate_type = payment_attempt.mandate_details.clone().or(sm.mandate_type); | ||||
|             sm.mandate_type = payment_attempt | ||||
|                 .mandate_details | ||||
|                 .clone() | ||||
|                 .and_then(|mandate| match mandate { | ||||
|                     data_models::mandates::MandateTypeDetails::MandateType(mandate_type) => { | ||||
|                         Some(mandate_type) | ||||
|                     } | ||||
|                     data_models::mandates::MandateTypeDetails::MandateDetails(mandate_details) => { | ||||
|                         mandate_details.mandate_type | ||||
|                     } | ||||
|                 }) | ||||
|                 .or(sm.mandate_type); | ||||
|             sm.update_mandate_id = payment_attempt | ||||
|                 .mandate_details | ||||
|                 .clone() | ||||
|                 .and_then(|mandate| match mandate { | ||||
|                     data_models::mandates::MandateTypeDetails::MandateType(_) => None, | ||||
|                     data_models::mandates::MandateTypeDetails::MandateDetails(update_id) => { | ||||
|                         Some(update_id.update_mandate_id) | ||||
|                     } | ||||
|                 }) | ||||
|                 .flatten() | ||||
|                 .or(sm.update_mandate_id); | ||||
|             sm | ||||
|         }); | ||||
|  | ||||
|  | ||||
| @ -3,7 +3,10 @@ use std::marker::PhantomData; | ||||
| use api_models::enums::FrmSuggestion; | ||||
| use async_trait::async_trait; | ||||
| use common_utils::ext_traits::{AsyncExt, Encode, ValueExt}; | ||||
| use data_models::{mandates::MandateData, payments::payment_attempt::PaymentAttempt}; | ||||
| use data_models::{ | ||||
|     mandates::{MandateData, MandateDetails, MandateTypeDetails}, | ||||
|     payments::payment_attempt::PaymentAttempt, | ||||
| }; | ||||
| use diesel_models::ephemeral_key; | ||||
| use error_stack::{self, ResultExt}; | ||||
| use masking::PeekInterface; | ||||
| @ -255,7 +258,7 @@ impl<F: Send + Clone, Ctx: PaymentMethodRetrieve> | ||||
|             .to_duplicate_response(errors::ApiErrorResponse::DuplicatePayment { | ||||
|                 payment_id: payment_id.clone(), | ||||
|             })?; | ||||
|  | ||||
|         // connector mandate reference update history | ||||
|         let mandate_id = request | ||||
|             .mandate_id | ||||
|             .as_ref() | ||||
| @ -284,10 +287,11 @@ impl<F: Send + Clone, Ctx: PaymentMethodRetrieve> | ||||
|                             api_models::payments::MandateIds { | ||||
|                                 mandate_id: mandate_obj.mandate_id, | ||||
|                                 mandate_reference_id: Some(api_models::payments::MandateReferenceId::ConnectorMandateId( | ||||
|                                     api_models::payments::ConnectorMandateReferenceId { | ||||
|                                         connector_mandate_id: connector_id.connector_mandate_id, | ||||
|                                         payment_method_id: connector_id.payment_method_id, | ||||
|                                     }, | ||||
|                                 api_models::payments::ConnectorMandateReferenceId{ | ||||
|                                     connector_mandate_id: connector_id.connector_mandate_id, | ||||
|                                     payment_method_id: connector_id.payment_method_id, | ||||
|                                     update_history: None | ||||
|                                 } | ||||
|                                 )) | ||||
|                             } | ||||
|                          }), | ||||
| @ -701,6 +705,35 @@ impl PaymentCreate { | ||||
|             .surcharge_details | ||||
|             .and_then(|surcharge_details| surcharge_details.tax_amount); | ||||
|  | ||||
|         if request.mandate_data.as_ref().map_or(false, |mandate_data| { | ||||
|             mandate_data.update_mandate_id.is_some() && mandate_data.mandate_type.is_some() | ||||
|         }) { | ||||
|             Err(errors::ApiErrorResponse::InvalidRequestData {message:"Only one field out of 'mandate_type' and 'update_mandate_id' was expected, found both".to_string()})? | ||||
|         } | ||||
|  | ||||
|         let mandate_dets = if let Some(update_id) = request | ||||
|             .mandate_data | ||||
|             .as_ref() | ||||
|             .and_then(|inner| inner.update_mandate_id.clone()) | ||||
|         { | ||||
|             let mandate_data = MandateDetails { | ||||
|                 update_mandate_id: Some(update_id), | ||||
|                 mandate_type: None, | ||||
|             }; | ||||
|             Some(MandateTypeDetails::MandateDetails(mandate_data)) | ||||
|         } else { | ||||
|             // let mandate_type: data_models::mandates::MandateDataType = | ||||
|  | ||||
|             let mandate_data = MandateDetails { | ||||
|                 update_mandate_id: None, | ||||
|                 mandate_type: request | ||||
|                     .mandate_data | ||||
|                     .as_ref() | ||||
|                     .and_then(|inner| inner.mandate_type.clone().map(Into::into)), | ||||
|             }; | ||||
|             Some(MandateTypeDetails::MandateDetails(mandate_data)) | ||||
|         }; | ||||
|  | ||||
|         Ok(( | ||||
|             storage::PaymentAttemptNew { | ||||
|                 payment_id: payment_id.to_string(), | ||||
| @ -727,10 +760,7 @@ impl PaymentCreate { | ||||
|                 business_sub_label: request.business_sub_label.clone(), | ||||
|                 surcharge_amount, | ||||
|                 tax_amount, | ||||
|                 mandate_details: request | ||||
|                     .mandate_data | ||||
|                     .as_ref() | ||||
|                     .and_then(|inner| inner.mandate_type.clone().map(Into::into)), | ||||
|                 mandate_details: mandate_dets, | ||||
|                 ..storage::PaymentAttemptNew::default() | ||||
|             }, | ||||
|             additional_pm_data, | ||||
|  | ||||
| @ -255,10 +255,7 @@ impl<F: Send + Clone, Ctx: PaymentMethodRetrieve> | ||||
|                             api_models::payments::MandateIds { | ||||
|                                 mandate_id: mandate_obj.mandate_id, | ||||
|                                 mandate_reference_id: Some(api_models::payments::MandateReferenceId::ConnectorMandateId( | ||||
|                                     api_models::payments::ConnectorMandateReferenceId { | ||||
|                                         connector_mandate_id: connector_id.connector_mandate_id, | ||||
|                                         payment_method_id: connector_id.payment_method_id, | ||||
|                                     }, | ||||
|                                     api_models::payments::ConnectorMandateReferenceId {connector_mandate_id:connector_id.connector_mandate_id,payment_method_id:connector_id.payment_method_id, update_history: None }, | ||||
|                                 )) | ||||
|                             } | ||||
|                          }), | ||||
|  | ||||
| @ -636,6 +636,7 @@ where | ||||
|                                         api::MandateType::MultiUse(None) | ||||
|                                     } | ||||
|                                 }), | ||||
|                                 update_mandate_id: d.update_mandate_id, | ||||
|                             }), | ||||
|                             auth_flow == services::AuthFlow::Merchant, | ||||
|                         ) | ||||
|  | ||||
| @ -202,6 +202,18 @@ impl MandateInterface for MockDb { | ||||
|                     } => { | ||||
|                         mandate.connector_mandate_ids = connector_mandate_ids; | ||||
|                     } | ||||
|  | ||||
|                     diesel_models::MandateUpdate::ConnectorMandateIdUpdate { | ||||
|                         connector_mandate_id, | ||||
|                         connector_mandate_ids, | ||||
|                         payment_method_id, | ||||
|                         original_payment_id, | ||||
|                     } => { | ||||
|                         mandate.connector_mandate_ids = connector_mandate_ids; | ||||
|                         mandate.connector_mandate_id = connector_mandate_id; | ||||
|                         mandate.payment_method_id = payment_method_id; | ||||
|                         mandate.original_payment_id = original_payment_id | ||||
|                     } | ||||
|                 } | ||||
|                 Ok(mandate.clone()) | ||||
|             } | ||||
|  | ||||
| @ -1674,7 +1674,7 @@ pub fn build_redirection_form( | ||||
|  | ||||
|                     // Initialize the ThreeDSService | ||||
|                     const threeDS = gateway.get3DSecure(); | ||||
|              | ||||
|  | ||||
|                     const options = {{ | ||||
|                         customerVaultId: '{customer_vault_id}', | ||||
|                         currency: '{currency}', | ||||
|  | ||||
| @ -323,6 +323,7 @@ impl ForeignFrom<api_models::payments::MandateData> for data_models::mandates::M | ||||
|                     data_models::mandates::MandateDataType::MultiUse(None) | ||||
|                 } | ||||
|             }), | ||||
|             update_mandate_id: d.update_mandate_id, | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
		Reference in New Issue
	
	Block a user
	 Amisha Prabhat
					Amisha Prabhat