mirror of
				https://github.com/juspay/hyperswitch.git
				synced 2025-10-31 18:17:13 +08:00 
			
		
		
		
	feat(payment_methods): Filter payment methods based on pm client secret (#4249)
Co-authored-by: hyperswitch-bot[bot] <148525504+hyperswitch-bot[bot]@users.noreply.github.com>
This commit is contained in:
		| @ -613,3 +613,6 @@ payment_attempts = "hyperswitch-payment-attempt-events" | |||||||
| payment_intents = "hyperswitch-payment-intent-events" | payment_intents = "hyperswitch-payment-intent-events" | ||||||
| refunds = "hyperswitch-refund-events" | refunds = "hyperswitch-refund-events" | ||||||
| disputes = "hyperswitch-dispute-events" | disputes = "hyperswitch-dispute-events" | ||||||
|  |  | ||||||
|  | [saved_payment_methods] | ||||||
|  | sdk_eligible_payment_methods = ["card"] | ||||||
| @ -319,3 +319,6 @@ connectors_with_webhook_source_verification_call = "paypal"         # List of co | |||||||
|  |  | ||||||
| [unmasked_headers] | [unmasked_headers] | ||||||
| keys = "user-agent" | keys = "user-agent" | ||||||
|  |  | ||||||
|  | [saved_payment_methods] | ||||||
|  | sdk_eligible_payment_methods = ["card"] | ||||||
| @ -330,3 +330,6 @@ connectors_with_webhook_source_verification_call = "paypal"     # List of connec | |||||||
|  |  | ||||||
| [unmasked_headers] | [unmasked_headers] | ||||||
| keys = "user-agent" | keys = "user-agent" | ||||||
|  |  | ||||||
|  | [saved_payment_methods] | ||||||
|  | sdk_eligible_payment_methods = ["card"] | ||||||
| @ -334,3 +334,6 @@ connectors_with_webhook_source_verification_call = "paypal"        # List of con | |||||||
|  |  | ||||||
| [unmasked_headers] | [unmasked_headers] | ||||||
| keys = "user-agent" | keys = "user-agent" | ||||||
|  |  | ||||||
|  | [saved_payment_methods] | ||||||
|  | sdk_eligible_payment_methods = ["card"] | ||||||
| @ -615,3 +615,6 @@ payment_attempts = "hyperswitch-payment-attempt-events" | |||||||
| payment_intents = "hyperswitch-payment-intent-events" | payment_intents = "hyperswitch-payment-intent-events" | ||||||
| refunds = "hyperswitch-refund-events" | refunds = "hyperswitch-refund-events" | ||||||
| disputes = "hyperswitch-dispute-events" | disputes = "hyperswitch-dispute-events" | ||||||
|  |  | ||||||
|  | [saved_payment_methods] | ||||||
|  | sdk_eligible_payment_methods = ["card"] | ||||||
|  | |||||||
| @ -474,3 +474,6 @@ payment_attempts = "hyperswitch-payment-attempt-events" | |||||||
| payment_intents = "hyperswitch-payment-intent-events" | payment_intents = "hyperswitch-payment-intent-events" | ||||||
| refunds = "hyperswitch-refund-events" | refunds = "hyperswitch-refund-events" | ||||||
| disputes = "hyperswitch-dispute-events" | disputes = "hyperswitch-dispute-events" | ||||||
|  |  | ||||||
|  | [saved_payment_methods] | ||||||
|  | sdk_eligible_payment_methods = ["card"] | ||||||
| @ -143,6 +143,8 @@ pub enum PaymentMethodUpdate { | |||||||
|         status: Option<storage_enums::PaymentMethodStatus>, |         status: Option<storage_enums::PaymentMethodStatus>, | ||||||
|         locker_id: Option<String>, |         locker_id: Option<String>, | ||||||
|         payment_method: Option<storage_enums::PaymentMethod>, |         payment_method: Option<storage_enums::PaymentMethod>, | ||||||
|  |         payment_method_type: Option<storage_enums::PaymentMethodType>, | ||||||
|  |         payment_method_issuer: Option<String>, | ||||||
|     }, |     }, | ||||||
|     ConnectorMandateDetailsUpdate { |     ConnectorMandateDetailsUpdate { | ||||||
|         connector_mandate_details: Option<serde_json::Value>, |         connector_mandate_details: Option<serde_json::Value>, | ||||||
| @ -162,6 +164,8 @@ pub struct PaymentMethodUpdateInternal { | |||||||
|     locker_id: Option<String>, |     locker_id: Option<String>, | ||||||
|     payment_method: Option<storage_enums::PaymentMethod>, |     payment_method: Option<storage_enums::PaymentMethod>, | ||||||
|     connector_mandate_details: Option<serde_json::Value>, |     connector_mandate_details: Option<serde_json::Value>, | ||||||
|  |     payment_method_type: Option<storage_enums::PaymentMethodType>, | ||||||
|  |     payment_method_issuer: Option<String>, | ||||||
| } | } | ||||||
|  |  | ||||||
| impl PaymentMethodUpdateInternal { | impl PaymentMethodUpdateInternal { | ||||||
| @ -208,6 +212,8 @@ impl From<PaymentMethodUpdate> for PaymentMethodUpdateInternal { | |||||||
|                 locker_id: None, |                 locker_id: None, | ||||||
|                 payment_method: None, |                 payment_method: None, | ||||||
|                 connector_mandate_details: None, |                 connector_mandate_details: None, | ||||||
|  |                 payment_method_issuer: None, | ||||||
|  |                 payment_method_type: None, | ||||||
|             }, |             }, | ||||||
|             PaymentMethodUpdate::PaymentMethodDataUpdate { |             PaymentMethodUpdate::PaymentMethodDataUpdate { | ||||||
|                 payment_method_data, |                 payment_method_data, | ||||||
| @ -220,6 +226,8 @@ impl From<PaymentMethodUpdate> for PaymentMethodUpdateInternal { | |||||||
|                 locker_id: None, |                 locker_id: None, | ||||||
|                 payment_method: None, |                 payment_method: None, | ||||||
|                 connector_mandate_details: None, |                 connector_mandate_details: None, | ||||||
|  |                 payment_method_issuer: None, | ||||||
|  |                 payment_method_type: None, | ||||||
|             }, |             }, | ||||||
|             PaymentMethodUpdate::LastUsedUpdate { last_used_at } => Self { |             PaymentMethodUpdate::LastUsedUpdate { last_used_at } => Self { | ||||||
|                 metadata: None, |                 metadata: None, | ||||||
| @ -230,6 +238,8 @@ impl From<PaymentMethodUpdate> for PaymentMethodUpdateInternal { | |||||||
|                 locker_id: None, |                 locker_id: None, | ||||||
|                 payment_method: None, |                 payment_method: None, | ||||||
|                 connector_mandate_details: None, |                 connector_mandate_details: None, | ||||||
|  |                 payment_method_issuer: None, | ||||||
|  |                 payment_method_type: None, | ||||||
|             }, |             }, | ||||||
|             PaymentMethodUpdate::NetworkTransactionIdAndStatusUpdate { |             PaymentMethodUpdate::NetworkTransactionIdAndStatusUpdate { | ||||||
|                 network_transaction_id, |                 network_transaction_id, | ||||||
| @ -243,6 +253,8 @@ impl From<PaymentMethodUpdate> for PaymentMethodUpdateInternal { | |||||||
|                 locker_id: None, |                 locker_id: None, | ||||||
|                 payment_method: None, |                 payment_method: None, | ||||||
|                 connector_mandate_details: None, |                 connector_mandate_details: None, | ||||||
|  |                 payment_method_issuer: None, | ||||||
|  |                 payment_method_type: None, | ||||||
|             }, |             }, | ||||||
|             PaymentMethodUpdate::StatusUpdate { status } => Self { |             PaymentMethodUpdate::StatusUpdate { status } => Self { | ||||||
|                 metadata: None, |                 metadata: None, | ||||||
| @ -253,12 +265,16 @@ impl From<PaymentMethodUpdate> for PaymentMethodUpdateInternal { | |||||||
|                 locker_id: None, |                 locker_id: None, | ||||||
|                 payment_method: None, |                 payment_method: None, | ||||||
|                 connector_mandate_details: None, |                 connector_mandate_details: None, | ||||||
|  |                 payment_method_issuer: None, | ||||||
|  |                 payment_method_type: None, | ||||||
|             }, |             }, | ||||||
|             PaymentMethodUpdate::AdditionalDataUpdate { |             PaymentMethodUpdate::AdditionalDataUpdate { | ||||||
|                 payment_method_data, |                 payment_method_data, | ||||||
|                 status, |                 status, | ||||||
|                 locker_id, |                 locker_id, | ||||||
|                 payment_method, |                 payment_method, | ||||||
|  |                 payment_method_type, | ||||||
|  |                 payment_method_issuer, | ||||||
|             } => Self { |             } => Self { | ||||||
|                 metadata: None, |                 metadata: None, | ||||||
|                 payment_method_data, |                 payment_method_data, | ||||||
| @ -268,6 +284,8 @@ impl From<PaymentMethodUpdate> for PaymentMethodUpdateInternal { | |||||||
|                 locker_id, |                 locker_id, | ||||||
|                 payment_method, |                 payment_method, | ||||||
|                 connector_mandate_details: None, |                 connector_mandate_details: None, | ||||||
|  |                 payment_method_issuer, | ||||||
|  |                 payment_method_type, | ||||||
|             }, |             }, | ||||||
|             PaymentMethodUpdate::ConnectorMandateDetailsUpdate { |             PaymentMethodUpdate::ConnectorMandateDetailsUpdate { | ||||||
|                 connector_mandate_details, |                 connector_mandate_details, | ||||||
| @ -280,6 +298,8 @@ impl From<PaymentMethodUpdate> for PaymentMethodUpdateInternal { | |||||||
|                 payment_method: None, |                 payment_method: None, | ||||||
|                 connector_mandate_details, |                 connector_mandate_details, | ||||||
|                 network_transaction_id: None, |                 network_transaction_id: None, | ||||||
|  |                 payment_method_issuer: None, | ||||||
|  |                 payment_method_type: None, | ||||||
|             }, |             }, | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  | |||||||
| @ -365,5 +365,6 @@ pub(crate) async fn fetch_raw_secrets( | |||||||
|         connector_onboarding, |         connector_onboarding, | ||||||
|         cors: conf.cors, |         cors: conf.cors, | ||||||
|         unmasked_headers: conf.unmasked_headers, |         unmasked_headers: conf.unmasked_headers, | ||||||
|  |         saved_payment_methods: conf.saved_payment_methods, | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  | |||||||
| @ -119,6 +119,7 @@ pub struct Settings<S: SecretState> { | |||||||
|     #[cfg(feature = "olap")] |     #[cfg(feature = "olap")] | ||||||
|     pub connector_onboarding: SecretStateContainer<ConnectorOnboarding, S>, |     pub connector_onboarding: SecretStateContainer<ConnectorOnboarding, S>, | ||||||
|     pub unmasked_headers: UnmaskedHeaders, |     pub unmasked_headers: UnmaskedHeaders, | ||||||
|  |     pub saved_payment_methods: EligiblePaymentMethods, | ||||||
| } | } | ||||||
|  |  | ||||||
| #[derive(Debug, Deserialize, Clone, Default)] | #[derive(Debug, Deserialize, Clone, Default)] | ||||||
| @ -165,6 +166,11 @@ pub struct PaymentMethodAuth { | |||||||
|     pub pm_auth_key: Secret<String>, |     pub pm_auth_key: Secret<String>, | ||||||
| } | } | ||||||
|  |  | ||||||
|  | #[derive(Debug, Deserialize, Clone, Default)] | ||||||
|  | pub struct EligiblePaymentMethods { | ||||||
|  |     pub sdk_eligible_payment_methods: HashSet<String>, | ||||||
|  | } | ||||||
|  |  | ||||||
| #[derive(Debug, Deserialize, Clone, Default)] | #[derive(Debug, Deserialize, Clone, Default)] | ||||||
| pub struct DefaultExchangeRates { | pub struct DefaultExchangeRates { | ||||||
|     pub base_currency: String, |     pub base_currency: String, | ||||||
|  | |||||||
| @ -441,6 +441,8 @@ pub async fn add_payment_method_data( | |||||||
|                             status: Some(enums::PaymentMethodStatus::Active), |                             status: Some(enums::PaymentMethodStatus::Active), | ||||||
|                             locker_id: Some(locker_id), |                             locker_id: Some(locker_id), | ||||||
|                             payment_method: req.payment_method, |                             payment_method: req.payment_method, | ||||||
|  |                             payment_method_issuer: req.payment_method_issuer, | ||||||
|  |                             payment_method_type: req.payment_method_type, | ||||||
|                         }; |                         }; | ||||||
|  |  | ||||||
|                         db.update_payment_method( |                         db.update_payment_method( | ||||||
| @ -555,7 +557,7 @@ pub async fn add_payment_method( | |||||||
|     match duplication_check { |     match duplication_check { | ||||||
|         Some(duplication_check) => match duplication_check { |         Some(duplication_check) => match duplication_check { | ||||||
|             payment_methods::DataDuplicationCheck::Duplicated => { |             payment_methods::DataDuplicationCheck::Duplicated => { | ||||||
|                 get_or_insert_payment_method( |                 let existing_pm = get_or_insert_payment_method( | ||||||
|                     db, |                     db, | ||||||
|                     req.clone(), |                     req.clone(), | ||||||
|                     &mut resp, |                     &mut resp, | ||||||
| @ -564,6 +566,8 @@ pub async fn add_payment_method( | |||||||
|                     key_store, |                     key_store, | ||||||
|                 ) |                 ) | ||||||
|                 .await?; |                 .await?; | ||||||
|  |  | ||||||
|  |                 resp.client_secret = existing_pm.client_secret; | ||||||
|             } |             } | ||||||
|             payment_methods::DataDuplicationCheck::MetaDataChanged => { |             payment_methods::DataDuplicationCheck::MetaDataChanged => { | ||||||
|                 if let Some(card) = req.card.clone() { |                 if let Some(card) = req.card.clone() { | ||||||
| @ -577,6 +581,8 @@ pub async fn add_payment_method( | |||||||
|                     ) |                     ) | ||||||
|                     .await?; |                     .await?; | ||||||
|  |  | ||||||
|  |                     let client_secret = existing_pm.client_secret.clone(); | ||||||
|  |  | ||||||
|                     delete_card_from_locker( |                     delete_card_from_locker( | ||||||
|                         &state, |                         &state, | ||||||
|                         &customer_id, |                         &customer_id, | ||||||
| @ -653,6 +659,8 @@ pub async fn add_payment_method( | |||||||
|                     .await |                     .await | ||||||
|                     .change_context(errors::ApiErrorResponse::InternalServerError) |                     .change_context(errors::ApiErrorResponse::InternalServerError) | ||||||
|                     .attach_printable("Failed to add payment method in db")?; |                     .attach_printable("Failed to add payment method in db")?; | ||||||
|  |  | ||||||
|  |                     resp.client_secret = client_secret; | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|         }, |         }, | ||||||
| @ -667,7 +675,7 @@ pub async fn add_payment_method( | |||||||
|                 None |                 None | ||||||
|             }; |             }; | ||||||
|             resp.payment_method_id = generate_id(consts::ID_LENGTH, "pm"); |             resp.payment_method_id = generate_id(consts::ID_LENGTH, "pm"); | ||||||
|             insert_payment_method( |             let pm = insert_payment_method( | ||||||
|                 db, |                 db, | ||||||
|                 &resp, |                 &resp, | ||||||
|                 req, |                 req, | ||||||
| @ -682,6 +690,8 @@ pub async fn add_payment_method( | |||||||
|                 merchant_account.storage_scheme, |                 merchant_account.storage_scheme, | ||||||
|             ) |             ) | ||||||
|             .await?; |             .await?; | ||||||
|  |  | ||||||
|  |             resp.client_secret = pm.client_secret; | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @ -744,6 +754,18 @@ pub async fn update_customer_payment_method( | |||||||
|             .await |             .await | ||||||
|             .to_not_found_response(errors::ApiErrorResponse::PaymentMethodNotFound)?; |             .to_not_found_response(errors::ApiErrorResponse::PaymentMethodNotFound)?; | ||||||
|  |  | ||||||
|  |         if pm.status == enums::PaymentMethodStatus::AwaitingData { | ||||||
|  |             return Err(report!(errors::ApiErrorResponse::NotSupported { | ||||||
|  |                 message: "Payment method is awaiting data so it cannot be updated".into() | ||||||
|  |             })); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         if pm.payment_method_data.is_none() { | ||||||
|  |             return Err(report!(errors::ApiErrorResponse::GenericNotFoundError { | ||||||
|  |                 message: "payment_method_data not found".to_string() | ||||||
|  |             })); | ||||||
|  |         } | ||||||
|  |  | ||||||
|         // Fetch the existing payment method data from db |         // Fetch the existing payment method data from db | ||||||
|         let existing_card_data = decrypt::<serde_json::Value, masking::WithType>( |         let existing_card_data = decrypt::<serde_json::Value, masking::WithType>( | ||||||
|             pm.payment_method_data.clone(), |             pm.payment_method_data.clone(), | ||||||
| @ -812,7 +834,7 @@ pub async fn update_customer_payment_method( | |||||||
|                 wallet: req.wallet, |                 wallet: req.wallet, | ||||||
|                 metadata: req.metadata, |                 metadata: req.metadata, | ||||||
|                 customer_id: Some(pm.customer_id.clone()), |                 customer_id: Some(pm.customer_id.clone()), | ||||||
|                 client_secret: None, |                 client_secret: pm.client_secret.clone(), | ||||||
|                 payment_method_data: None, |                 payment_method_data: None, | ||||||
|                 card_network: req |                 card_network: req | ||||||
|                     .card_network |                     .card_network | ||||||
| @ -901,7 +923,7 @@ pub async fn update_customer_payment_method( | |||||||
|                 installment_payment_enabled: false, |                 installment_payment_enabled: false, | ||||||
|                 payment_experience: Some(vec![api_models::enums::PaymentExperience::RedirectToUrl]), |                 payment_experience: Some(vec![api_models::enums::PaymentExperience::RedirectToUrl]), | ||||||
|                 last_used_at: Some(common_utils::date_time::now()), |                 last_used_at: Some(common_utils::date_time::now()), | ||||||
|                 client_secret: None, |                 client_secret: pm.client_secret.clone(), | ||||||
|             } |             } | ||||||
|         }; |         }; | ||||||
|  |  | ||||||
| @ -1691,12 +1713,21 @@ pub async fn list_payment_methods( | |||||||
|     let db = &*state.store; |     let db = &*state.store; | ||||||
|     let pm_config_mapping = &state.conf.pm_filters; |     let pm_config_mapping = &state.conf.pm_filters; | ||||||
|  |  | ||||||
|     let payment_intent = helpers::verify_payment_intent_time_and_client_secret( |     let payment_intent = if let Some(cs) = &req.client_secret { | ||||||
|         db, |         if cs.starts_with("pm_") { | ||||||
|         &merchant_account, |             validate_payment_method_and_client_secret(cs, db, &merchant_account).await?; | ||||||
|         req.client_secret.clone(), |             None | ||||||
|     ) |         } else { | ||||||
|     .await?; |             helpers::verify_payment_intent_time_and_client_secret( | ||||||
|  |                 db, | ||||||
|  |                 &merchant_account, | ||||||
|  |                 req.client_secret.clone(), | ||||||
|  |             ) | ||||||
|  |             .await? | ||||||
|  |         } | ||||||
|  |     } else { | ||||||
|  |         None | ||||||
|  |     }; | ||||||
|  |  | ||||||
|     let shipping_address = payment_intent |     let shipping_address = payment_intent | ||||||
|         .as_ref() |         .as_ref() | ||||||
| @ -1839,6 +1870,7 @@ pub async fn list_payment_methods( | |||||||
|             pm_config_mapping, |             pm_config_mapping, | ||||||
|             &state.conf.mandates.supported_payment_methods, |             &state.conf.mandates.supported_payment_methods, | ||||||
|             &state.conf.mandates.update_mandate_supported, |             &state.conf.mandates.update_mandate_supported, | ||||||
|  |             &state.conf.saved_payment_methods, | ||||||
|         ) |         ) | ||||||
|         .await?; |         .await?; | ||||||
|     } |     } | ||||||
| @ -2535,6 +2567,34 @@ pub async fn list_payment_methods( | |||||||
|     )) |     )) | ||||||
| } | } | ||||||
|  |  | ||||||
|  | async fn validate_payment_method_and_client_secret( | ||||||
|  |     cs: &String, | ||||||
|  |     db: &dyn db::StorageInterface, | ||||||
|  |     merchant_account: &domain::MerchantAccount, | ||||||
|  | ) -> Result<(), error_stack::Report<errors::ApiErrorResponse>> { | ||||||
|  |     let pm_vec = cs.split("_secret").collect::<Vec<&str>>(); | ||||||
|  |     let pm_id = pm_vec | ||||||
|  |         .first() | ||||||
|  |         .ok_or(errors::ApiErrorResponse::MissingRequiredField { | ||||||
|  |             field_name: "client_secret", | ||||||
|  |         })?; | ||||||
|  |  | ||||||
|  |     let payment_method = db | ||||||
|  |         .find_payment_method(pm_id, merchant_account.storage_scheme) | ||||||
|  |         .await | ||||||
|  |         .change_context(errors::ApiErrorResponse::PaymentMethodNotFound) | ||||||
|  |         .attach_printable("Unable to find payment method")?; | ||||||
|  |  | ||||||
|  |     let client_secret_expired = | ||||||
|  |         authenticate_pm_client_secret_and_check_expiry(cs, &payment_method)?; | ||||||
|  |     if client_secret_expired { | ||||||
|  |         return Err::<(), error_stack::Report<errors::ApiErrorResponse>>( | ||||||
|  |             (errors::ApiErrorResponse::ClientSecretExpired).into(), | ||||||
|  |         ); | ||||||
|  |     } | ||||||
|  |     Ok(()) | ||||||
|  | } | ||||||
|  |  | ||||||
| pub async fn call_surcharge_decision_management( | pub async fn call_surcharge_decision_management( | ||||||
|     state: routes::AppState, |     state: routes::AppState, | ||||||
|     merchant_account: &domain::MerchantAccount, |     merchant_account: &domain::MerchantAccount, | ||||||
| @ -2644,6 +2704,7 @@ pub async fn filter_payment_methods( | |||||||
|     config: &settings::ConnectorFilters, |     config: &settings::ConnectorFilters, | ||||||
|     supported_payment_methods_for_mandate: &settings::SupportedPaymentMethodsForMandate, |     supported_payment_methods_for_mandate: &settings::SupportedPaymentMethodsForMandate, | ||||||
|     supported_payment_methods_for_update_mandate: &settings::SupportedPaymentMethodsForMandate, |     supported_payment_methods_for_update_mandate: &settings::SupportedPaymentMethodsForMandate, | ||||||
|  |     saved_payment_methods: &settings::EligiblePaymentMethods, | ||||||
| ) -> errors::CustomResult<(), errors::ApiErrorResponse> { | ) -> errors::CustomResult<(), errors::ApiErrorResponse> { | ||||||
|     for payment_method in payment_methods.into_iter() { |     for payment_method in payment_methods.into_iter() { | ||||||
|         let parse_result = serde_json::from_value::<PaymentMethodsEnabled>(payment_method); |         let parse_result = serde_json::from_value::<PaymentMethodsEnabled>(payment_method); | ||||||
| @ -2761,6 +2822,20 @@ pub async fn filter_payment_methods( | |||||||
|                         }) |                         }) | ||||||
|                         .unwrap_or(true); |                         .unwrap_or(true); | ||||||
|  |  | ||||||
|  |                     let filter9 = req | ||||||
|  |                         .client_secret | ||||||
|  |                         .as_ref() | ||||||
|  |                         .map(|cs| { | ||||||
|  |                             if cs.starts_with("pm_") { | ||||||
|  |                                 saved_payment_methods | ||||||
|  |                                     .sdk_eligible_payment_methods | ||||||
|  |                                     .contains(payment_method.to_string().as_str()) | ||||||
|  |                             } else { | ||||||
|  |                                 true | ||||||
|  |                             } | ||||||
|  |                         }) | ||||||
|  |                         .unwrap_or(true); | ||||||
|  |  | ||||||
|                     let connector = connector.clone(); |                     let connector = connector.clone(); | ||||||
|  |  | ||||||
|                     let response_pm_type = ResponsePaymentMethodIntermediate::new( |                     let response_pm_type = ResponsePaymentMethodIntermediate::new( | ||||||
| @ -2777,6 +2852,7 @@ pub async fn filter_payment_methods( | |||||||
|                         && filter6 |                         && filter6 | ||||||
|                         && filter7 |                         && filter7 | ||||||
|                         && filter8 |                         && filter8 | ||||||
|  |                         && filter9 | ||||||
|                     { |                     { | ||||||
|                         resp.push(response_pm_type); |                         resp.push(response_pm_type); | ||||||
|                     } |                     } | ||||||
|  | |||||||
| @ -374,7 +374,7 @@ pub fn mk_add_card_response_hs( | |||||||
|         installment_payment_enabled: false, // #[#256] |         installment_payment_enabled: false, // #[#256] | ||||||
|         payment_experience: Some(vec![api_models::enums::PaymentExperience::RedirectToUrl]), |         payment_experience: Some(vec![api_models::enums::PaymentExperience::RedirectToUrl]), | ||||||
|         last_used_at: Some(common_utils::date_time::now()), // [#256] |         last_used_at: Some(common_utils::date_time::now()), // [#256] | ||||||
|         client_secret: None, |         client_secret: req.client_secret, | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | |||||||
		Reference in New Issue
	
	Block a user
	 Sarthak Soni
					Sarthak Soni