mirror of
				https://github.com/juspay/hyperswitch.git
				synced 2025-11-01 02:57:02 +08:00 
			
		
		
		
	This commit is contained in:
		| @ -128,6 +128,21 @@ impl PaymentsAuthorizeRouterData { | |||||||
|                             ) |                             ) | ||||||
|                             .await |                             .await | ||||||
|                             .change_context(errors::ApiErrorResponse::MandateNotFound)?; |                             .change_context(errors::ApiErrorResponse::MandateNotFound)?; | ||||||
|  |                         let mandate = match mandate.mandate_type { | ||||||
|  |                             storage_enums::MandateType::SingleUse => state | ||||||
|  |                                 .store | ||||||
|  |                                 .update_mandate_by_merchant_id_mandate_id( | ||||||
|  |                                     &resp.merchant_id, | ||||||
|  |                                     mandate_id, | ||||||
|  |                                     storage::MandateUpdate::StatusUpdate { | ||||||
|  |                                         mandate_status: storage_enums::MandateStatus::Revoked, | ||||||
|  |                                     }, | ||||||
|  |                                 ) | ||||||
|  |                                 .await | ||||||
|  |                                 .change_context(errors::ApiErrorResponse::MandateNotFound), | ||||||
|  |                             storage_enums::MandateType::MultiUse => Ok(mandate), | ||||||
|  |                         }?; | ||||||
|  |  | ||||||
|                         resp.payment_method_id = Some(mandate.payment_method_id); |                         resp.payment_method_id = Some(mandate.payment_method_id); | ||||||
|                     } |                     } | ||||||
|                     None => { |                     None => { | ||||||
| @ -173,19 +188,32 @@ impl PaymentsAuthorizeRouterData { | |||||||
|         match (self.request.setup_mandate_details.clone(), customer) { |         match (self.request.setup_mandate_details.clone(), customer) { | ||||||
|             (Some(data), Some(cus)) => { |             (Some(data), Some(cus)) => { | ||||||
|                 let mandate_id = utils::generate_id(consts::ID_LENGTH, "man"); |                 let mandate_id = utils::generate_id(consts::ID_LENGTH, "man"); | ||||||
|                 Some(storage::MandateNew { |  | ||||||
|                     mandate_id, |                 // The construction of the mandate new must be visible | ||||||
|                     customer_id: cus.customer_id.clone(), |                 let mut new_mandate = storage::MandateNew::default(); | ||||||
|                     merchant_id: self.merchant_id.clone(), |  | ||||||
|                     payment_method_id, |                 new_mandate | ||||||
|                     mandate_status: storage_enums::MandateStatus::Active, |                     .set_mandate_id(mandate_id) | ||||||
|                     mandate_type: storage_enums::MandateType::MultiUse, |                     .set_customer_id(cus.customer_id.clone()) | ||||||
|                     customer_ip_address: data.customer_acceptance.get_ip_address().map(Secret::new), |                     .set_merchant_id(self.merchant_id.clone()) | ||||||
|                     customer_user_agent: data.customer_acceptance.get_user_agent(), |                     .set_payment_method_id(payment_method_id) | ||||||
|                     customer_accepted_at: Some(data.customer_acceptance.get_accepted_at()), |                     .set_mandate_status(storage_enums::MandateStatus::Active) | ||||||
|                     ..Default::default() // network_transaction_id: Option<String>, |                     .set_customer_ip_address( | ||||||
|                                          // previous_transaction_id: Option<String>, |                         data.customer_acceptance.get_ip_address().map(Secret::new), | ||||||
|                                          // created_at: Option<PrimitiveDateTime>, |                     ) | ||||||
|  |                     .set_customer_user_agent(data.customer_acceptance.get_user_agent()) | ||||||
|  |                     .set_customer_accepted_at(Some(data.customer_acceptance.get_accepted_at())); | ||||||
|  |  | ||||||
|  |                 Some(match data.mandate_type { | ||||||
|  |                     api::MandateType::SingleUse(data) => new_mandate | ||||||
|  |                         .set_single_use_amount(Some(data.amount)) | ||||||
|  |                         .set_single_use_currency(Some(data.currency)) | ||||||
|  |                         .set_mandate_type(storage_enums::MandateType::SingleUse) | ||||||
|  |                         .to_owned(), | ||||||
|  |  | ||||||
|  |                     api::MandateType::MultiUse => new_mandate | ||||||
|  |                         .set_mandate_type(storage_enums::MandateType::MultiUse) | ||||||
|  |                         .to_owned(), | ||||||
|                 }) |                 }) | ||||||
|             } |             } | ||||||
|             (_, _) => None, |             (_, _) => None, | ||||||
|  | |||||||
| @ -139,6 +139,11 @@ pub async fn get_token_for_recurring_mandate( | |||||||
|         .await |         .await | ||||||
|         .map_err(|error| error.to_not_found_response(errors::ApiErrorResponse::MandateNotFound))?; |         .map_err(|error| error.to_not_found_response(errors::ApiErrorResponse::MandateNotFound))?; | ||||||
|  |  | ||||||
|  |     utils::when( | ||||||
|  |         mandate.mandate_status != storage_enums::MandateStatus::Active, | ||||||
|  |         Err(errors::ApiErrorResponse::MandateNotFound), | ||||||
|  |     )?; | ||||||
|  |  | ||||||
|     let customer = req.customer_id.clone().get_required_value("customer_id")?; |     let customer = req.customer_id.clone().get_required_value("customer_id")?; | ||||||
|  |  | ||||||
|     let payment_method_id = { |     let payment_method_id = { | ||||||
|  | |||||||
| @ -137,7 +137,6 @@ where | |||||||
|             payment_data.payment_attempt, |             payment_data.payment_attempt, | ||||||
|             payment_data.payment_intent, |             payment_data.payment_intent, | ||||||
|             payment_data.refunds, |             payment_data.refunds, | ||||||
|             payment_data.mandate_id, |  | ||||||
|             payment_data.payment_method_data, |             payment_data.payment_method_data, | ||||||
|             customer, |             customer, | ||||||
|             auth_flow, |             auth_flow, | ||||||
| @ -198,7 +197,6 @@ pub fn payments_to_payments_response<R, Op>( | |||||||
|     payment_attempt: storage::PaymentAttempt, |     payment_attempt: storage::PaymentAttempt, | ||||||
|     payment_intent: storage::PaymentIntent, |     payment_intent: storage::PaymentIntent, | ||||||
|     refunds: Vec<storage::Refund>, |     refunds: Vec<storage::Refund>, | ||||||
|     mandate_id: Option<String>, |  | ||||||
|     payment_method_data: Option<api::PaymentMethod>, |     payment_method_data: Option<api::PaymentMethod>, | ||||||
|     customer: Option<storage::Customer>, |     customer: Option<storage::Customer>, | ||||||
|     auth_flow: services::AuthFlow, |     auth_flow: services::AuthFlow, | ||||||
| @ -216,6 +214,7 @@ where | |||||||
|         .as_ref() |         .as_ref() | ||||||
|         .get_required_value("currency")? |         .get_required_value("currency")? | ||||||
|         .to_string(); |         .to_string(); | ||||||
|  |     let mandate_id = payment_attempt.mandate_id.clone(); | ||||||
|     let refunds_response = if refunds.is_empty() { |     let refunds_response = if refunds.is_empty() { | ||||||
|         None |         None | ||||||
|     } else { |     } else { | ||||||
|  | |||||||
| @ -14,6 +14,7 @@ use super::app::AppState; | |||||||
| use crate::{ | use crate::{ | ||||||
|     core::{errors::http_not_implemented, payments}, |     core::{errors::http_not_implemented, payments}, | ||||||
|     services::api, |     services::api, | ||||||
|  |  | ||||||
|     types::api::{ |     types::api::{ | ||||||
|         enums as api_enums, |         enums as api_enums, | ||||||
|         payments::{ |         payments::{ | ||||||
| @ -21,7 +22,7 @@ use crate::{ | |||||||
|             PaymentsRequest, PaymentsRetrieveRequest, |             PaymentsRequest, PaymentsRetrieveRequest, | ||||||
|         }, |         }, | ||||||
|         Authorize, Capture, PSync, PaymentRetrieveBody, PaymentsResponse, PaymentsStartRequest, |         Authorize, Capture, PSync, PaymentRetrieveBody, PaymentsResponse, PaymentsStartRequest, | ||||||
|         Verify, VerifyRequest, VerifyResponse, Void, |         Verify, VerifyResponse, Void, | ||||||
|     }, // FIXME imports |     }, // FIXME imports | ||||||
| }; | }; | ||||||
|  |  | ||||||
| @ -110,33 +111,6 @@ pub async fn payments_start( | |||||||
|     .await |     .await | ||||||
| } | } | ||||||
|  |  | ||||||
| #[allow(dead_code)] |  | ||||||
| #[instrument(skip(state), fields(flow = ?Flow::ValidatePaymentMethod))] |  | ||||||
| pub async fn validate_pm( |  | ||||||
|     state: web::Data<AppState>, |  | ||||||
|     req: HttpRequest, |  | ||||||
|     json_payload: web::Json<VerifyRequest>, |  | ||||||
| ) -> HttpResponse { |  | ||||||
|     let payload = json_payload.into_inner(); |  | ||||||
|     api::server_wrap( |  | ||||||
|         &state, |  | ||||||
|         &req, |  | ||||||
|         payload, |  | ||||||
|         |state, merchant_account, req| { |  | ||||||
|             payments::payments_core::<Verify, VerifyResponse, _, _, _>( |  | ||||||
|                 state, |  | ||||||
|                 merchant_account, |  | ||||||
|                 payments::PaymentMethodValidate, |  | ||||||
|                 req, |  | ||||||
|                 api::AuthFlow::Merchant, |  | ||||||
|                 payments::CallConnectorAction::Trigger, |  | ||||||
|             ) |  | ||||||
|         }, |  | ||||||
|         api::MerchantAuthentication::ApiKey, |  | ||||||
|     ) |  | ||||||
|     .await |  | ||||||
| } |  | ||||||
|  |  | ||||||
| #[instrument(skip(state), fields(flow = ?Flow::PaymentsRetrieve))] | #[instrument(skip(state), fields(flow = ?Flow::PaymentsRetrieve))] | ||||||
| // #[get("/{payment_id}")] | // #[get("/{payment_id}")] | ||||||
| pub async fn payments_retrieve( | pub async fn payments_retrieve( | ||||||
|  | |||||||
| @ -127,6 +127,8 @@ diesel::table! { | |||||||
|         network_transaction_id -> Nullable<Varchar>, |         network_transaction_id -> Nullable<Varchar>, | ||||||
|         previous_transaction_id -> Nullable<Varchar>, |         previous_transaction_id -> Nullable<Varchar>, | ||||||
|         created_at -> Timestamp, |         created_at -> Timestamp, | ||||||
|  |         single_use_amount -> Nullable<Int4>, | ||||||
|  |         single_use_currency -> Nullable<Currency>, | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | |||||||
| @ -7,7 +7,7 @@ use crate::{ | |||||||
|     core::errors, |     core::errors, | ||||||
|     pii, |     pii, | ||||||
|     services::api, |     services::api, | ||||||
|     types::{self, api as api_types, api::enums as api_enums}, |     types::{self, api as api_types, api::enums as api_enums, storage}, | ||||||
|     utils::custom_serde, |     utils::custom_serde, | ||||||
| }; | }; | ||||||
|  |  | ||||||
| @ -126,6 +126,14 @@ pub enum MandateTxnType { | |||||||
| #[serde(deny_unknown_fields)] | #[serde(deny_unknown_fields)] | ||||||
| pub struct MandateData { | pub struct MandateData { | ||||||
|     pub customer_acceptance: CustomerAcceptance, |     pub customer_acceptance: CustomerAcceptance, | ||||||
|  |     pub mandate_type: MandateType, | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #[derive(Default, Eq, PartialEq, Debug, serde::Deserialize, serde::Serialize, Clone)] | ||||||
|  | pub enum MandateType { | ||||||
|  |     SingleUse(storage::SingleUseMandate), | ||||||
|  |     #[default] | ||||||
|  |     MultiUse, | ||||||
| } | } | ||||||
|  |  | ||||||
| #[derive(Default, Eq, PartialEq, Debug, serde::Deserialize, serde::Serialize, Clone)] | #[derive(Default, Eq, PartialEq, Debug, serde::Deserialize, serde::Serialize, Clone)] | ||||||
|  | |||||||
| @ -24,9 +24,13 @@ pub struct Mandate { | |||||||
|     pub network_transaction_id: Option<String>, |     pub network_transaction_id: Option<String>, | ||||||
|     pub previous_transaction_id: Option<String>, |     pub previous_transaction_id: Option<String>, | ||||||
|     pub created_at: PrimitiveDateTime, |     pub created_at: PrimitiveDateTime, | ||||||
|  |     pub single_use_amount: Option<i32>, | ||||||
|  |     pub single_use_currency: Option<storage_enums::Currency>, | ||||||
| } | } | ||||||
|  |  | ||||||
| #[derive(Clone, Debug, Default, Insertable, router_derive::DebugAsDisplay)] | #[derive( | ||||||
|  |     router_derive::Setter, Clone, Debug, Default, Insertable, router_derive::DebugAsDisplay, | ||||||
|  | )] | ||||||
| #[diesel(table_name = mandate)] | #[diesel(table_name = mandate)] | ||||||
| pub struct MandateNew { | pub struct MandateNew { | ||||||
|     pub mandate_id: String, |     pub mandate_id: String, | ||||||
| @ -41,6 +45,8 @@ pub struct MandateNew { | |||||||
|     pub network_transaction_id: Option<String>, |     pub network_transaction_id: Option<String>, | ||||||
|     pub previous_transaction_id: Option<String>, |     pub previous_transaction_id: Option<String>, | ||||||
|     pub created_at: Option<PrimitiveDateTime>, |     pub created_at: Option<PrimitiveDateTime>, | ||||||
|  |     pub single_use_amount: Option<i32>, | ||||||
|  |     pub single_use_currency: Option<storage_enums::Currency>, | ||||||
| } | } | ||||||
|  |  | ||||||
| #[derive(Debug)] | #[derive(Debug)] | ||||||
| @ -50,6 +56,12 @@ pub enum MandateUpdate { | |||||||
|     }, |     }, | ||||||
| } | } | ||||||
|  |  | ||||||
|  | #[derive(Clone, Eq, PartialEq, Copy, Debug, Default, serde::Serialize, serde::Deserialize)] | ||||||
|  | pub struct SingleUseMandate { | ||||||
|  |     pub amount: i32, | ||||||
|  |     pub currency: storage_enums::Currency, | ||||||
|  | } | ||||||
|  |  | ||||||
| #[derive(Clone, Debug, Default, AsChangeset, router_derive::DebugAsDisplay)] | #[derive(Clone, Debug, Default, AsChangeset, router_derive::DebugAsDisplay)] | ||||||
| #[diesel(table_name = mandate)] | #[diesel(table_name = mandate)] | ||||||
| pub(super) struct MandateUpdateInternal { | pub(super) struct MandateUpdateInternal { | ||||||
|  | |||||||
| @ -0,0 +1,4 @@ | |||||||
|  | -- This file should undo anything in `up.sql` | ||||||
|  | ALTER TABLE mandate  | ||||||
|  | DROP COLUMN IF EXISTS single_use_amount, | ||||||
|  | DROP COLUMN IF EXISTS single_use_currency; | ||||||
| @ -0,0 +1,4 @@ | |||||||
|  | -- Your SQL goes here | ||||||
|  | ALTER TABLE mandate  | ||||||
|  | ADD IF NOT EXISTS single_use_amount INTEGER DEFAULT NULL, | ||||||
|  | ADD IF NOT EXISTS single_use_currency "Currency" DEFAULT NULL; | ||||||
		Reference in New Issue
	
	Block a user
	 Nishant Joshi
					Nishant Joshi