mirror of
				https://github.com/juspay/hyperswitch.git
				synced 2025-10-31 01:57:45 +08:00 
			
		
		
		
	feat(router): add connector mit related columns to the payment methods table (#3764)
This commit is contained in:
		| @ -1177,6 +1177,32 @@ pub enum PaymentMethodIssuerCode { | ||||
|     JpBacs, | ||||
| } | ||||
|  | ||||
| #[derive( | ||||
|     Clone, | ||||
|     Copy, | ||||
|     Debug, | ||||
|     PartialEq, | ||||
|     Eq, | ||||
|     Hash, | ||||
|     serde::Serialize, | ||||
|     serde::Deserialize, | ||||
|     strum::Display, | ||||
|     strum::EnumString, | ||||
|     ToSchema, | ||||
| )] | ||||
| #[router_derive::diesel_enum(storage_type = "text")] | ||||
| #[strum(serialize_all = "snake_case")] | ||||
| #[serde(rename_all = "snake_case")] | ||||
| pub enum PaymentMethodStatus { | ||||
|     /// Indicates that the payment method is active and can be used for payments. | ||||
|     Active, | ||||
|     /// Indicates that the payment method is not active and hence cannot be used for payments. | ||||
|     Inactive, | ||||
|     /// Indicates that the payment method is awaiting some data or action before it can be marked | ||||
|     /// as 'active'. | ||||
|     Processing, | ||||
| } | ||||
|  | ||||
| /// To indicate the type of payment experience that the customer would go through | ||||
| #[derive( | ||||
|     Eq, | ||||
|  | ||||
| @ -34,6 +34,9 @@ pub struct PaymentMethod { | ||||
|     pub metadata: Option<pii::SecretSerdeValue>, | ||||
|     pub payment_method_data: Option<Encryption>, | ||||
|     pub locker_id: Option<String>, | ||||
|     pub connector_mandate_details: Option<serde_json::Value>, | ||||
|     pub customer_acceptance: Option<pii::SecretSerdeValue>, | ||||
|     pub status: storage_enums::PaymentMethodStatus, | ||||
| } | ||||
|  | ||||
| #[derive(Clone, Debug, Eq, PartialEq, Insertable, Queryable, router_derive::DebugAsDisplay)] | ||||
| @ -61,6 +64,9 @@ pub struct PaymentMethodNew { | ||||
|     pub metadata: Option<pii::SecretSerdeValue>, | ||||
|     pub payment_method_data: Option<Encryption>, | ||||
|     pub locker_id: Option<String>, | ||||
|     pub connector_mandate_details: Option<serde_json::Value>, | ||||
|     pub customer_acceptance: Option<pii::SecretSerdeValue>, | ||||
|     pub status: storage_enums::PaymentMethodStatus, | ||||
| } | ||||
|  | ||||
| impl Default for PaymentMethodNew { | ||||
| @ -90,6 +96,9 @@ impl Default for PaymentMethodNew { | ||||
|             last_modified: now, | ||||
|             metadata: Option::default(), | ||||
|             payment_method_data: Option::default(), | ||||
|             connector_mandate_details: Option::default(), | ||||
|             customer_acceptance: Option::default(), | ||||
|             status: storage_enums::PaymentMethodStatus::Active, | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -3,7 +3,7 @@ use router_env::{instrument, tracing}; | ||||
|  | ||||
| use super::generics; | ||||
| use crate::{ | ||||
|     errors, | ||||
|     enums as storage_enums, errors, | ||||
|     payment_method::{self, PaymentMethod, PaymentMethodNew}, | ||||
|     schema::payment_methods::dsl, | ||||
|     PgPooledConn, StorageResult, | ||||
| @ -108,6 +108,31 @@ impl PaymentMethod { | ||||
|         .await | ||||
|     } | ||||
|  | ||||
|     #[instrument(skip(conn))] | ||||
|     pub async fn find_by_customer_id_merchant_id_status( | ||||
|         conn: &PgPooledConn, | ||||
|         customer_id: &str, | ||||
|         merchant_id: &str, | ||||
|         status: storage_enums::PaymentMethodStatus, | ||||
|     ) -> StorageResult<Vec<Self>> { | ||||
|         generics::generic_filter::< | ||||
|             <Self as HasTable>::Table, | ||||
|             _, | ||||
|             <<Self as HasTable>::Table as Table>::PrimaryKey, | ||||
|             _, | ||||
|         >( | ||||
|             conn, | ||||
|             dsl::customer_id | ||||
|                 .eq(customer_id.to_owned()) | ||||
|                 .and(dsl::merchant_id.eq(merchant_id.to_owned())) | ||||
|                 .and(dsl::status.eq(status)), | ||||
|             None, | ||||
|             None, | ||||
|             None, | ||||
|         ) | ||||
|         .await | ||||
|     } | ||||
|  | ||||
|     pub async fn update_with_payment_method_id( | ||||
|         self, | ||||
|         conn: &PgPooledConn, | ||||
|  | ||||
| @ -831,6 +831,10 @@ diesel::table! { | ||||
|         payment_method_data -> Nullable<Bytea>, | ||||
|         #[max_length = 64] | ||||
|         locker_id -> Nullable<Varchar>, | ||||
|         connector_mandate_details -> Nullable<Jsonb>, | ||||
|         customer_acceptance -> Nullable<Jsonb>, | ||||
|         #[max_length = 64] | ||||
|         status -> Varchar, | ||||
|     } | ||||
| } | ||||
|  | ||||
|  | ||||
| @ -2667,9 +2667,10 @@ pub async fn list_customer_payment_method( | ||||
|     let requires_cvv = is_requires_cvv.config != "false"; | ||||
|  | ||||
|     let resp = db | ||||
|         .find_payment_method_by_customer_id_merchant_id_list( | ||||
|         .find_payment_method_by_customer_id_merchant_id_status( | ||||
|             customer_id, | ||||
|             &merchant_account.merchant_id, | ||||
|             common_enums::PaymentMethodStatus::Active, | ||||
|         ) | ||||
|         .await | ||||
|         .to_not_found_response(errors::ApiErrorResponse::PaymentMethodNotFound)?; | ||||
|  | ||||
| @ -1273,6 +1273,17 @@ impl PaymentMethodInterface for KafkaStore { | ||||
|             .await | ||||
|     } | ||||
|  | ||||
|     async fn find_payment_method_by_customer_id_merchant_id_status( | ||||
|         &self, | ||||
|         customer_id: &str, | ||||
|         merchant_id: &str, | ||||
|         status: common_enums::PaymentMethodStatus, | ||||
|     ) -> CustomResult<Vec<storage::PaymentMethod>, errors::StorageError> { | ||||
|         self.diesel_store | ||||
|             .find_payment_method_by_customer_id_merchant_id_status(customer_id, merchant_id, status) | ||||
|             .await | ||||
|     } | ||||
|  | ||||
|     async fn find_payment_method_by_locker_id( | ||||
|         &self, | ||||
|         locker_id: &str, | ||||
|  | ||||
| @ -26,6 +26,13 @@ pub trait PaymentMethodInterface { | ||||
|         merchant_id: &str, | ||||
|     ) -> CustomResult<Vec<storage::PaymentMethod>, errors::StorageError>; | ||||
|  | ||||
|     async fn find_payment_method_by_customer_id_merchant_id_status( | ||||
|         &self, | ||||
|         customer_id: &str, | ||||
|         merchant_id: &str, | ||||
|         status: common_enums::PaymentMethodStatus, | ||||
|     ) -> CustomResult<Vec<storage::PaymentMethod>, errors::StorageError>; | ||||
|  | ||||
|     async fn insert_payment_method( | ||||
|         &self, | ||||
|         payment_method_new: storage::PaymentMethodNew, | ||||
| @ -105,6 +112,24 @@ impl PaymentMethodInterface for Store { | ||||
|             .into_report() | ||||
|     } | ||||
|  | ||||
|     async fn find_payment_method_by_customer_id_merchant_id_status( | ||||
|         &self, | ||||
|         customer_id: &str, | ||||
|         merchant_id: &str, | ||||
|         status: common_enums::PaymentMethodStatus, | ||||
|     ) -> CustomResult<Vec<storage::PaymentMethod>, errors::StorageError> { | ||||
|         let conn = connection::pg_connection_read(self).await?; | ||||
|         storage::PaymentMethod::find_by_customer_id_merchant_id_status( | ||||
|             &conn, | ||||
|             customer_id, | ||||
|             merchant_id, | ||||
|             status, | ||||
|         ) | ||||
|         .await | ||||
|         .map_err(Into::into) | ||||
|         .into_report() | ||||
|     } | ||||
|  | ||||
|     async fn delete_payment_method_by_merchant_id_payment_method_id( | ||||
|         &self, | ||||
|         merchant_id: &str, | ||||
| @ -196,6 +221,9 @@ impl PaymentMethodInterface for MockDb { | ||||
|             payment_method_issuer_code: payment_method_new.payment_method_issuer_code, | ||||
|             metadata: payment_method_new.metadata, | ||||
|             payment_method_data: payment_method_new.payment_method_data, | ||||
|             connector_mandate_details: payment_method_new.connector_mandate_details, | ||||
|             customer_acceptance: payment_method_new.customer_acceptance, | ||||
|             status: payment_method_new.status, | ||||
|         }; | ||||
|         payment_methods.push(payment_method.clone()); | ||||
|         Ok(payment_method) | ||||
| @ -223,6 +251,33 @@ impl PaymentMethodInterface for MockDb { | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     async fn find_payment_method_by_customer_id_merchant_id_status( | ||||
|         &self, | ||||
|         customer_id: &str, | ||||
|         merchant_id: &str, | ||||
|         status: common_enums::PaymentMethodStatus, | ||||
|     ) -> CustomResult<Vec<storage::PaymentMethod>, errors::StorageError> { | ||||
|         let payment_methods = self.payment_methods.lock().await; | ||||
|         let payment_methods_found: Vec<storage::PaymentMethod> = payment_methods | ||||
|             .iter() | ||||
|             .filter(|pm| { | ||||
|                 pm.customer_id == customer_id | ||||
|                     && pm.merchant_id == merchant_id | ||||
|                     && pm.status == status | ||||
|             }) | ||||
|             .cloned() | ||||
|             .collect(); | ||||
|  | ||||
|         if payment_methods_found.is_empty() { | ||||
|             Err(errors::StorageError::ValueNotFound( | ||||
|                 "cannot find payment methods".to_string(), | ||||
|             )) | ||||
|             .into_report() | ||||
|         } else { | ||||
|             Ok(payment_methods_found) | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     async fn delete_payment_method_by_merchant_id_payment_method_id( | ||||
|         &self, | ||||
|         merchant_id: &str, | ||||
|  | ||||
| @ -0,0 +1,10 @@ | ||||
| -- This file should undo anything in `up.sql` | ||||
|  | ||||
| ALTER TABLE payment_methods | ||||
| DROP COLUMN status; | ||||
|  | ||||
| ALTER TABLE payment_methods | ||||
| DROP COLUMN customer_acceptance; | ||||
|  | ||||
| ALTER TABLE payment_methods | ||||
| DROP COLUMN connector_mandate_details; | ||||
| @ -0,0 +1,13 @@ | ||||
| -- Your SQL goes here | ||||
|  | ||||
| ALTER TABLE payment_methods | ||||
| ADD COLUMN connector_mandate_details JSONB | ||||
| DEFAULT NULL; | ||||
|  | ||||
| ALTER TABLE payment_methods | ||||
| ADD COLUMN customer_acceptance JSONB | ||||
| DEFAULT NULL; | ||||
|  | ||||
| ALTER TABLE payment_methods | ||||
| ADD COLUMN status VARCHAR(64) | ||||
| NOT NULL DEFAULT 'active'; | ||||
		Reference in New Issue
	
	Block a user
	 Shanks
					Shanks