mirror of
				https://github.com/juspay/hyperswitch.git
				synced 2025-10-31 01:57:45 +08:00 
			
		
		
		
	fix(mandate): make payment_method_data optional for mandate scenario (#1032)
This commit is contained in:
		| @ -520,6 +520,7 @@ pub enum PaymentMethodData { | ||||
|     BankRedirect(BankRedirectData), | ||||
|     BankDebit(BankDebitData), | ||||
|     Crypto(CryptoData), | ||||
|     MandatePayment, | ||||
| } | ||||
|  | ||||
| #[derive(Debug, Clone, Eq, PartialEq, serde::Deserialize, serde::Serialize)] | ||||
| @ -536,6 +537,7 @@ pub enum AdditionalPaymentData { | ||||
|     PayLater {}, | ||||
|     Crypto {}, | ||||
|     BankDebit {}, | ||||
|     MandatePayment {}, | ||||
| } | ||||
|  | ||||
| impl From<&PaymentMethodData> for AdditionalPaymentData { | ||||
| @ -561,6 +563,7 @@ impl From<&PaymentMethodData> for AdditionalPaymentData { | ||||
|             PaymentMethodData::PayLater(_) => Self::PayLater {}, | ||||
|             PaymentMethodData::Crypto(_) => Self::Crypto {}, | ||||
|             PaymentMethodData::BankDebit(_) => Self::BankDebit {}, | ||||
|             PaymentMethodData::MandatePayment => Self::MandatePayment {}, | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @ -790,6 +793,7 @@ pub enum PaymentMethodDataResponse { | ||||
|     BankRedirect(BankRedirectData), | ||||
|     Crypto(CryptoData), | ||||
|     BankDebit(BankDebitData), | ||||
|     MandatePayment, | ||||
| } | ||||
|  | ||||
| #[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize, ToSchema)] | ||||
| @ -1331,6 +1335,7 @@ impl From<PaymentMethodData> for PaymentMethodDataResponse { | ||||
|             } | ||||
|             PaymentMethodData::Crypto(crpto_data) => Self::Crypto(crpto_data), | ||||
|             PaymentMethodData::BankDebit(bank_debit_data) => Self::BankDebit(bank_debit_data), | ||||
|             PaymentMethodData::MandatePayment => Self::MandatePayment, | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -184,7 +184,9 @@ impl TryFrom<&types::PaymentsAuthorizeRouterData> for AciPaymentsRequest { | ||||
|                     ))?, | ||||
|                 } | ||||
|             } | ||||
|             api::PaymentMethodData::Crypto(_) | api::PaymentMethodData::BankDebit(_) => { | ||||
|             api::PaymentMethodData::Crypto(_) | ||||
|             | api::PaymentMethodData::BankDebit(_) | ||||
|             | api::PaymentMethodData::MandatePayment => { | ||||
|                 Err(errors::ConnectorError::NotSupported { | ||||
|                     message: format!("{:?}", item.payment_method), | ||||
|                     connector: "Aci", | ||||
|  | ||||
| @ -129,7 +129,9 @@ fn get_pm_and_subsequent_auth_detail( | ||||
|             api::PaymentMethodData::BankRedirect(_) => { | ||||
|                 Ok((PaymentDetails::BankRedirect, None, None)) | ||||
|             } | ||||
|             api::PaymentMethodData::Crypto(_) | api::PaymentMethodData::BankDebit(_) => { | ||||
|             api::PaymentMethodData::Crypto(_) | ||||
|             | api::PaymentMethodData::BankDebit(_) | ||||
|             | api::PaymentMethodData::MandatePayment => { | ||||
|                 Err(errors::ConnectorError::NotSupported { | ||||
|                     message: format!("{:?}", item.request.payment_method_data), | ||||
|                     connector: "AuthorizeDotNet", | ||||
|  | ||||
| @ -1864,11 +1864,14 @@ impl | ||||
|                     bank_specific_data: bank_data, | ||||
|                 })) | ||||
|             } | ||||
|             api::PaymentMethodData::Crypto(_) => Err(errors::ConnectorError::NotSupported { | ||||
|             api::PaymentMethodData::MandatePayment | api::PaymentMethodData::Crypto(_) => { | ||||
|                 Err(errors::ConnectorError::NotSupported { | ||||
|                     message: format!("{pm_type:?}"), | ||||
|                     connector: "Stripe", | ||||
|                 payment_experience: api_models::enums::PaymentExperience::RedirectToUrl.to_string(), | ||||
|             })?, | ||||
|                     payment_experience: api_models::enums::PaymentExperience::RedirectToUrl | ||||
|                         .to_string(), | ||||
|                 })? | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -721,6 +721,9 @@ where | ||||
|     let connector = payment_data.payment_attempt.connector.to_owned(); | ||||
|  | ||||
|     let payment_data_and_tokenization_action = match connector { | ||||
|         Some(_) if payment_data.mandate_id.is_some() => { | ||||
|             (payment_data, TokenizationAction::SkipConnectorTokenization) | ||||
|         } | ||||
|         Some(connector) if is_operation_confirm(&operation) => { | ||||
|             let payment_method = &payment_data | ||||
|                 .payment_attempt | ||||
|  | ||||
| @ -182,13 +182,15 @@ pub async fn get_token_for_recurring_mandate( | ||||
|         .locker_id | ||||
|         .to_owned() | ||||
|         .get_required_value("locker_id")?; | ||||
|     let _ = cards::get_lookup_key_from_locker(state, &token, &payment_method, &locker_id).await?; | ||||
|  | ||||
|     if let storage_models::enums::PaymentMethod::Card = payment_method.payment_method { | ||||
|         let _ = | ||||
|             cards::get_lookup_key_from_locker(state, &token, &payment_method, &locker_id).await?; | ||||
|         if let Some(payment_method_from_request) = req.payment_method { | ||||
|             let pm: storage_enums::PaymentMethod = payment_method_from_request.foreign_into(); | ||||
|             if pm != payment_method.payment_method { | ||||
|                 Err(report!(errors::ApiErrorResponse::PreconditionFailed { | ||||
|                 message: "payment method in request does not match previously provided payment \ | ||||
|                     message: | ||||
|                         "payment method in request does not match previously provided payment \ | ||||
|                                   method information" | ||||
|                             .into() | ||||
|                 }))? | ||||
| @ -196,6 +198,9 @@ pub async fn get_token_for_recurring_mandate( | ||||
|         }; | ||||
|  | ||||
|         Ok((Some(token), Some(payment_method.payment_method))) | ||||
|     } else { | ||||
|         Ok((None, Some(payment_method.payment_method))) | ||||
|     } | ||||
| } | ||||
|  | ||||
| #[instrument(skip_all)] | ||||
|  | ||||
| @ -520,10 +520,16 @@ impl<F: Clone> TryFrom<PaymentAdditionalData<'_, F>> for types::PaymentsAuthoriz | ||||
|             payment_data.creds_identifier.as_deref(), | ||||
|         )); | ||||
|  | ||||
|         // payment_method_data is not required during recurring mandate payment, in such case keep default PaymentMethodData as MandatePayment | ||||
|         let payment_method_data = payment_data.payment_method_data.or_else(|| { | ||||
|             if payment_data.mandate_id.is_some() { | ||||
|                 Some(api_models::payments::PaymentMethodData::MandatePayment) | ||||
|             } else { | ||||
|                 None | ||||
|             } | ||||
|         }); | ||||
|         Ok(Self { | ||||
|             payment_method_data: payment_data | ||||
|                 .payment_method_data | ||||
|                 .get_required_value("payment_method_data")?, | ||||
|             payment_method_data: payment_method_data.get_required_value("payment_method_data")?, | ||||
|             setup_future_usage: payment_data.payment_intent.setup_future_usage, | ||||
|             mandate_id: payment_data.mandate_id.clone(), | ||||
|             off_session: payment_data.mandate_id.as_ref().map(|_| true), | ||||
|  | ||||
		Reference in New Issue
	
	Block a user
	 Jagan
					Jagan