mirror of
				https://github.com/juspay/hyperswitch.git
				synced 2025-10-31 18:17:13 +08:00 
			
		
		
		
	feat: add an api for toggling extended card info feature (#4444)
This commit is contained in:
		| @ -1088,3 +1088,10 @@ pub struct PaymentLinkConfig { | |||||||
|     /// Enable saved payment method option for payment link |     /// Enable saved payment method option for payment link | ||||||
|     pub enabled_saved_payment_method: bool, |     pub enabled_saved_payment_method: bool, | ||||||
| } | } | ||||||
|  |  | ||||||
|  | #[derive(Debug, Clone, serde::Serialize, serde::Deserialize, PartialEq, Eq)] | ||||||
|  | pub struct ExtendedCardInfoChoice { | ||||||
|  |     pub enabled: bool, | ||||||
|  | } | ||||||
|  |  | ||||||
|  | impl common_utils::events::ApiEventMetric for ExtendedCardInfoChoice {} | ||||||
|  | |||||||
| @ -35,6 +35,7 @@ pub struct BusinessProfile { | |||||||
|     pub payment_link_config: Option<serde_json::Value>, |     pub payment_link_config: Option<serde_json::Value>, | ||||||
|     pub session_expiry: Option<i64>, |     pub session_expiry: Option<i64>, | ||||||
|     pub authentication_connector_details: Option<serde_json::Value>, |     pub authentication_connector_details: Option<serde_json::Value>, | ||||||
|  |     pub is_extended_card_info_enabled: Option<bool>, | ||||||
| } | } | ||||||
|  |  | ||||||
| #[derive(Clone, Debug, Insertable, router_derive::DebugAsDisplay)] | #[derive(Clone, Debug, Insertable, router_derive::DebugAsDisplay)] | ||||||
| @ -61,6 +62,7 @@ pub struct BusinessProfileNew { | |||||||
|     pub payment_link_config: Option<serde_json::Value>, |     pub payment_link_config: Option<serde_json::Value>, | ||||||
|     pub session_expiry: Option<i64>, |     pub session_expiry: Option<i64>, | ||||||
|     pub authentication_connector_details: Option<serde_json::Value>, |     pub authentication_connector_details: Option<serde_json::Value>, | ||||||
|  |     pub is_extended_card_info_enabled: Option<bool>, | ||||||
| } | } | ||||||
|  |  | ||||||
| #[derive(Clone, Debug, Default, AsChangeset, router_derive::DebugAsDisplay)] | #[derive(Clone, Debug, Default, AsChangeset, router_derive::DebugAsDisplay)] | ||||||
| @ -84,6 +86,84 @@ pub struct BusinessProfileUpdateInternal { | |||||||
|     pub payment_link_config: Option<serde_json::Value>, |     pub payment_link_config: Option<serde_json::Value>, | ||||||
|     pub session_expiry: Option<i64>, |     pub session_expiry: Option<i64>, | ||||||
|     pub authentication_connector_details: Option<serde_json::Value>, |     pub authentication_connector_details: Option<serde_json::Value>, | ||||||
|  |     pub is_extended_card_info_enabled: Option<bool>, | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)] | ||||||
|  | pub enum BusinessProfileUpdate { | ||||||
|  |     Update { | ||||||
|  |         profile_name: Option<String>, | ||||||
|  |         modified_at: Option<time::PrimitiveDateTime>, | ||||||
|  |         return_url: Option<String>, | ||||||
|  |         enable_payment_response_hash: Option<bool>, | ||||||
|  |         payment_response_hash_key: Option<String>, | ||||||
|  |         redirect_to_merchant_with_http_post: Option<bool>, | ||||||
|  |         webhook_details: Option<serde_json::Value>, | ||||||
|  |         metadata: Option<pii::SecretSerdeValue>, | ||||||
|  |         routing_algorithm: Option<serde_json::Value>, | ||||||
|  |         intent_fulfillment_time: Option<i64>, | ||||||
|  |         frm_routing_algorithm: Option<serde_json::Value>, | ||||||
|  |         payout_routing_algorithm: Option<serde_json::Value>, | ||||||
|  |         is_recon_enabled: Option<bool>, | ||||||
|  |         applepay_verified_domains: Option<Vec<String>>, | ||||||
|  |         payment_link_config: Option<serde_json::Value>, | ||||||
|  |         session_expiry: Option<i64>, | ||||||
|  |         authentication_connector_details: Option<serde_json::Value>, | ||||||
|  |     }, | ||||||
|  |     ExtendedCardInfoUpdate { | ||||||
|  |         is_extended_card_info_enabled: Option<bool>, | ||||||
|  |     }, | ||||||
|  | } | ||||||
|  |  | ||||||
|  | impl From<BusinessProfileUpdate> for BusinessProfileUpdateInternal { | ||||||
|  |     fn from(business_profile_update: BusinessProfileUpdate) -> Self { | ||||||
|  |         match business_profile_update { | ||||||
|  |             BusinessProfileUpdate::Update { | ||||||
|  |                 profile_name, | ||||||
|  |                 modified_at, | ||||||
|  |                 return_url, | ||||||
|  |                 enable_payment_response_hash, | ||||||
|  |                 payment_response_hash_key, | ||||||
|  |                 redirect_to_merchant_with_http_post, | ||||||
|  |                 webhook_details, | ||||||
|  |                 metadata, | ||||||
|  |                 routing_algorithm, | ||||||
|  |                 intent_fulfillment_time, | ||||||
|  |                 frm_routing_algorithm, | ||||||
|  |                 payout_routing_algorithm, | ||||||
|  |                 is_recon_enabled, | ||||||
|  |                 applepay_verified_domains, | ||||||
|  |                 payment_link_config, | ||||||
|  |                 session_expiry, | ||||||
|  |                 authentication_connector_details, | ||||||
|  |             } => Self { | ||||||
|  |                 profile_name, | ||||||
|  |                 modified_at, | ||||||
|  |                 return_url, | ||||||
|  |                 enable_payment_response_hash, | ||||||
|  |                 payment_response_hash_key, | ||||||
|  |                 redirect_to_merchant_with_http_post, | ||||||
|  |                 webhook_details, | ||||||
|  |                 metadata, | ||||||
|  |                 routing_algorithm, | ||||||
|  |                 intent_fulfillment_time, | ||||||
|  |                 frm_routing_algorithm, | ||||||
|  |                 payout_routing_algorithm, | ||||||
|  |                 is_recon_enabled, | ||||||
|  |                 applepay_verified_domains, | ||||||
|  |                 payment_link_config, | ||||||
|  |                 session_expiry, | ||||||
|  |                 authentication_connector_details, | ||||||
|  |                 ..Default::default() | ||||||
|  |             }, | ||||||
|  |             BusinessProfileUpdate::ExtendedCardInfoUpdate { | ||||||
|  |                 is_extended_card_info_enabled, | ||||||
|  |             } => Self { | ||||||
|  |                 is_extended_card_info_enabled, | ||||||
|  |                 ..Default::default() | ||||||
|  |             }, | ||||||
|  |         } | ||||||
|  |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| impl From<BusinessProfileNew> for BusinessProfile { | impl From<BusinessProfileNew> for BusinessProfile { | ||||||
| @ -109,13 +189,14 @@ impl From<BusinessProfileNew> for BusinessProfile { | |||||||
|             payment_link_config: new.payment_link_config, |             payment_link_config: new.payment_link_config, | ||||||
|             session_expiry: new.session_expiry, |             session_expiry: new.session_expiry, | ||||||
|             authentication_connector_details: new.authentication_connector_details, |             authentication_connector_details: new.authentication_connector_details, | ||||||
|  |             is_extended_card_info_enabled: new.is_extended_card_info_enabled, | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| impl BusinessProfileUpdateInternal { | impl BusinessProfileUpdate { | ||||||
|     pub fn apply_changeset(self, source: BusinessProfile) -> BusinessProfile { |     pub fn apply_changeset(self, source: BusinessProfile) -> BusinessProfile { | ||||||
|         let Self { |         let BusinessProfileUpdateInternal { | ||||||
|             profile_name, |             profile_name, | ||||||
|             modified_at: _, |             modified_at: _, | ||||||
|             return_url, |             return_url, | ||||||
| @ -133,7 +214,8 @@ impl BusinessProfileUpdateInternal { | |||||||
|             payment_link_config, |             payment_link_config, | ||||||
|             session_expiry, |             session_expiry, | ||||||
|             authentication_connector_details, |             authentication_connector_details, | ||||||
|         } = self; |             is_extended_card_info_enabled, | ||||||
|  |         } = self.into(); | ||||||
|         BusinessProfile { |         BusinessProfile { | ||||||
|             profile_name: profile_name.unwrap_or(source.profile_name), |             profile_name: profile_name.unwrap_or(source.profile_name), | ||||||
|             modified_at: common_utils::date_time::now(), |             modified_at: common_utils::date_time::now(), | ||||||
| @ -154,6 +236,7 @@ impl BusinessProfileUpdateInternal { | |||||||
|             payment_link_config, |             payment_link_config, | ||||||
|             session_expiry, |             session_expiry, | ||||||
|             authentication_connector_details, |             authentication_connector_details, | ||||||
|  |             is_extended_card_info_enabled, | ||||||
|             ..source |             ..source | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  | |||||||
| @ -2,7 +2,9 @@ use diesel::{associations::HasTable, BoolExpressionMethods, ExpressionMethods, T | |||||||
|  |  | ||||||
| use super::generics; | use super::generics; | ||||||
| use crate::{ | use crate::{ | ||||||
|     business_profile::{BusinessProfile, BusinessProfileNew, BusinessProfileUpdateInternal}, |     business_profile::{ | ||||||
|  |         BusinessProfile, BusinessProfileNew, BusinessProfileUpdate, BusinessProfileUpdateInternal, | ||||||
|  |     }, | ||||||
|     errors, |     errors, | ||||||
|     schema::business_profile::dsl, |     schema::business_profile::dsl, | ||||||
|     PgPooledConn, StorageResult, |     PgPooledConn, StorageResult, | ||||||
| @ -18,12 +20,12 @@ impl BusinessProfile { | |||||||
|     pub async fn update_by_profile_id( |     pub async fn update_by_profile_id( | ||||||
|         self, |         self, | ||||||
|         conn: &PgPooledConn, |         conn: &PgPooledConn, | ||||||
|         business_profile: BusinessProfileUpdateInternal, |         business_profile: BusinessProfileUpdate, | ||||||
|     ) -> StorageResult<Self> { |     ) -> StorageResult<Self> { | ||||||
|         match generics::generic_update_by_id::<<Self as HasTable>::Table, _, _, _>( |         match generics::generic_update_by_id::<<Self as HasTable>::Table, _, _, _>( | ||||||
|             conn, |             conn, | ||||||
|             self.profile_id.clone(), |             self.profile_id.clone(), | ||||||
|             business_profile, |             BusinessProfileUpdateInternal::from(business_profile), | ||||||
|         ) |         ) | ||||||
|         .await |         .await | ||||||
|         { |         { | ||||||
|  | |||||||
| @ -193,6 +193,7 @@ diesel::table! { | |||||||
|         payment_link_config -> Nullable<Jsonb>, |         payment_link_config -> Nullable<Jsonb>, | ||||||
|         session_expiry -> Nullable<Int8>, |         session_expiry -> Nullable<Int8>, | ||||||
|         authentication_connector_details -> Nullable<Jsonb>, |         authentication_connector_details -> Nullable<Jsonb>, | ||||||
|  |         is_extended_card_info_enabled -> Nullable<Bool>, | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | |||||||
| @ -1648,7 +1648,7 @@ pub async fn update_business_profile( | |||||||
|         }) |         }) | ||||||
|         .transpose()?; |         .transpose()?; | ||||||
|  |  | ||||||
|     let business_profile_update = storage::business_profile::BusinessProfileUpdateInternal { |     let business_profile_update = storage::business_profile::BusinessProfileUpdate::Update { | ||||||
|         profile_name: request.profile_name, |         profile_name: request.profile_name, | ||||||
|         modified_at: Some(date_time::now()), |         modified_at: Some(date_time::now()), | ||||||
|         return_url: request.return_url.map(|return_url| return_url.to_string()), |         return_url: request.return_url.map(|return_url| return_url.to_string()), | ||||||
| @ -1691,6 +1691,39 @@ pub async fn update_business_profile( | |||||||
|     )) |     )) | ||||||
| } | } | ||||||
|  |  | ||||||
|  | pub async fn extended_card_info_toggle( | ||||||
|  |     state: AppState, | ||||||
|  |     profile_id: &str, | ||||||
|  |     ext_card_info_choice: admin_types::ExtendedCardInfoChoice, | ||||||
|  | ) -> RouterResponse<admin_types::ExtendedCardInfoChoice> { | ||||||
|  |     let db = state.store.as_ref(); | ||||||
|  |     let business_profile = db | ||||||
|  |         .find_business_profile_by_profile_id(profile_id) | ||||||
|  |         .await | ||||||
|  |         .to_not_found_response(errors::ApiErrorResponse::BusinessProfileNotFound { | ||||||
|  |             id: profile_id.to_string(), | ||||||
|  |         })?; | ||||||
|  |  | ||||||
|  |     if business_profile.is_extended_card_info_enabled.is_none() | ||||||
|  |         || business_profile | ||||||
|  |             .is_extended_card_info_enabled | ||||||
|  |             .is_some_and(|existing_config| existing_config != ext_card_info_choice.enabled) | ||||||
|  |     { | ||||||
|  |         let business_profile_update = | ||||||
|  |             storage::business_profile::BusinessProfileUpdate::ExtendedCardInfoUpdate { | ||||||
|  |                 is_extended_card_info_enabled: Some(ext_card_info_choice.enabled), | ||||||
|  |             }; | ||||||
|  |  | ||||||
|  |         db.update_business_profile_by_profile_id(business_profile, business_profile_update) | ||||||
|  |             .await | ||||||
|  |             .to_not_found_response(errors::ApiErrorResponse::BusinessProfileNotFound { | ||||||
|  |                 id: profile_id.to_owned(), | ||||||
|  |             })?; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     Ok(service_api::ApplicationResponse::Json(ext_card_info_choice)) | ||||||
|  | } | ||||||
|  |  | ||||||
| pub(crate) fn validate_auth_and_metadata_type( | pub(crate) fn validate_auth_and_metadata_type( | ||||||
|     connector_name: api_models::enums::Connector, |     connector_name: api_models::enums::Connector, | ||||||
|     val: &types::ConnectorAuthType, |     val: &types::ConnectorAuthType, | ||||||
|  | |||||||
| @ -5,7 +5,7 @@ | |||||||
| use api_models::routing as routing_types; | use api_models::routing as routing_types; | ||||||
| use common_utils::ext_traits::Encode; | use common_utils::ext_traits::Encode; | ||||||
| use diesel_models::{ | use diesel_models::{ | ||||||
|     business_profile::{BusinessProfile, BusinessProfileUpdateInternal}, |     business_profile::{BusinessProfile, BusinessProfileUpdate}, | ||||||
|     configs, |     configs, | ||||||
| }; | }; | ||||||
| use error_stack::ResultExt; | use error_stack::ResultExt; | ||||||
| @ -245,7 +245,7 @@ pub async fn update_business_profile_active_algorithm_ref( | |||||||
|         storage::enums::TransactionType::Payout => (None, Some(ref_val)), |         storage::enums::TransactionType::Payout => (None, Some(ref_val)), | ||||||
|     }; |     }; | ||||||
|  |  | ||||||
|     let business_profile_update = BusinessProfileUpdateInternal { |     let business_profile_update = BusinessProfileUpdate::Update { | ||||||
|         profile_name: None, |         profile_name: None, | ||||||
|         return_url: None, |         return_url: None, | ||||||
|         enable_payment_response_hash: None, |         enable_payment_response_hash: None, | ||||||
|  | |||||||
| @ -30,7 +30,7 @@ pub trait BusinessProfileInterface { | |||||||
|     async fn update_business_profile_by_profile_id( |     async fn update_business_profile_by_profile_id( | ||||||
|         &self, |         &self, | ||||||
|         current_state: business_profile::BusinessProfile, |         current_state: business_profile::BusinessProfile, | ||||||
|         business_profile_update: business_profile::BusinessProfileUpdateInternal, |         business_profile_update: business_profile::BusinessProfileUpdate, | ||||||
|     ) -> CustomResult<business_profile::BusinessProfile, errors::StorageError>; |     ) -> CustomResult<business_profile::BusinessProfile, errors::StorageError>; | ||||||
|  |  | ||||||
|     async fn delete_business_profile_by_profile_id_merchant_id( |     async fn delete_business_profile_by_profile_id_merchant_id( | ||||||
| @ -90,7 +90,7 @@ impl BusinessProfileInterface for Store { | |||||||
|     async fn update_business_profile_by_profile_id( |     async fn update_business_profile_by_profile_id( | ||||||
|         &self, |         &self, | ||||||
|         current_state: business_profile::BusinessProfile, |         current_state: business_profile::BusinessProfile, | ||||||
|         business_profile_update: business_profile::BusinessProfileUpdateInternal, |         business_profile_update: business_profile::BusinessProfileUpdate, | ||||||
|     ) -> CustomResult<business_profile::BusinessProfile, errors::StorageError> { |     ) -> CustomResult<business_profile::BusinessProfile, errors::StorageError> { | ||||||
|         let conn = connection::pg_connection_write(self).await?; |         let conn = connection::pg_connection_write(self).await?; | ||||||
|         storage::business_profile::BusinessProfile::update_by_profile_id( |         storage::business_profile::BusinessProfile::update_by_profile_id( | ||||||
| @ -169,7 +169,7 @@ impl BusinessProfileInterface for MockDb { | |||||||
|     async fn update_business_profile_by_profile_id( |     async fn update_business_profile_by_profile_id( | ||||||
|         &self, |         &self, | ||||||
|         current_state: business_profile::BusinessProfile, |         current_state: business_profile::BusinessProfile, | ||||||
|         business_profile_update: business_profile::BusinessProfileUpdateInternal, |         business_profile_update: business_profile::BusinessProfileUpdate, | ||||||
|     ) -> CustomResult<business_profile::BusinessProfile, errors::StorageError> { |     ) -> CustomResult<business_profile::BusinessProfile, errors::StorageError> { | ||||||
|         self.business_profiles |         self.business_profiles | ||||||
|             .lock() |             .lock() | ||||||
|  | |||||||
| @ -2039,7 +2039,7 @@ impl BusinessProfileInterface for KafkaStore { | |||||||
|     async fn update_business_profile_by_profile_id( |     async fn update_business_profile_by_profile_id( | ||||||
|         &self, |         &self, | ||||||
|         current_state: business_profile::BusinessProfile, |         current_state: business_profile::BusinessProfile, | ||||||
|         business_profile_update: business_profile::BusinessProfileUpdateInternal, |         business_profile_update: business_profile::BusinessProfileUpdate, | ||||||
|     ) -> CustomResult<business_profile::BusinessProfile, errors::StorageError> { |     ) -> CustomResult<business_profile::BusinessProfile, errors::StorageError> { | ||||||
|         self.diesel_store |         self.diesel_store | ||||||
|             .update_business_profile_by_profile_id(current_state, business_profile_update) |             .update_business_profile_by_profile_id(current_state, business_profile_update) | ||||||
|  | |||||||
| @ -612,3 +612,25 @@ pub async fn merchant_account_kv_status( | |||||||
|     ) |     ) | ||||||
|     .await |     .await | ||||||
| } | } | ||||||
|  |  | ||||||
|  | #[instrument(skip_all, fields(flow = ?Flow::ToggleExtendedCardInfo))] | ||||||
|  | pub async fn toggle_extended_card_info( | ||||||
|  |     state: web::Data<AppState>, | ||||||
|  |     req: HttpRequest, | ||||||
|  |     path: web::Path<(String, String)>, | ||||||
|  |     json_payload: web::Json<api_models::admin::ExtendedCardInfoChoice>, | ||||||
|  | ) -> HttpResponse { | ||||||
|  |     let flow = Flow::ToggleExtendedCardInfo; | ||||||
|  |     let (_, profile_id) = path.into_inner(); | ||||||
|  |  | ||||||
|  |     Box::pin(api::server_wrap( | ||||||
|  |         flow, | ||||||
|  |         state, | ||||||
|  |         &req, | ||||||
|  |         json_payload.into_inner(), | ||||||
|  |         |state, _, req, _| extended_card_info_toggle(state, &profile_id, req), | ||||||
|  |         &auth::AdminApiAuth, | ||||||
|  |         api_locking::LockAction::NotApplicable, | ||||||
|  |     )) | ||||||
|  |     .await | ||||||
|  | } | ||||||
|  | |||||||
| @ -1104,10 +1104,17 @@ impl BusinessProfile { | |||||||
|                     .route(web::get().to(business_profiles_list)), |                     .route(web::get().to(business_profiles_list)), | ||||||
|             ) |             ) | ||||||
|             .service( |             .service( | ||||||
|                 web::resource("/{profile_id}") |                 web::scope("/{profile_id}") | ||||||
|                     .route(web::get().to(business_profile_retrieve)) |                     .service( | ||||||
|                     .route(web::post().to(business_profile_update)) |                         web::resource("") | ||||||
|                     .route(web::delete().to(business_profile_delete)), |                             .route(web::get().to(business_profile_retrieve)) | ||||||
|  |                             .route(web::post().to(business_profile_update)) | ||||||
|  |                             .route(web::delete().to(business_profile_delete)), | ||||||
|  |                     ) | ||||||
|  |                     .service( | ||||||
|  |                         web::resource("/toggle_extended_card_info") | ||||||
|  |                             .route(web::post().to(toggle_extended_card_info)), | ||||||
|  |                     ), | ||||||
|             ) |             ) | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  | |||||||
| @ -166,7 +166,8 @@ impl From<Flow> for ApiIdentifier { | |||||||
|             | Flow::BusinessProfileUpdate |             | Flow::BusinessProfileUpdate | ||||||
|             | Flow::BusinessProfileRetrieve |             | Flow::BusinessProfileRetrieve | ||||||
|             | Flow::BusinessProfileDelete |             | Flow::BusinessProfileDelete | ||||||
|             | Flow::BusinessProfileList => Self::Business, |             | Flow::BusinessProfileList | ||||||
|  |             | Flow::ToggleExtendedCardInfo => Self::Business, | ||||||
|  |  | ||||||
|             Flow::PaymentLinkRetrieve |             Flow::PaymentLinkRetrieve | ||||||
|             | Flow::PaymentLinkInitiate |             | Flow::PaymentLinkInitiate | ||||||
|  | |||||||
| @ -175,6 +175,7 @@ impl ForeignTryFrom<(domain::MerchantAccount, BusinessProfileCreate)> | |||||||
|                 .change_context(errors::ApiErrorResponse::InvalidDataValue { |                 .change_context(errors::ApiErrorResponse::InvalidDataValue { | ||||||
|                     field_name: "authentication_connector_details", |                     field_name: "authentication_connector_details", | ||||||
|                 })?, |                 })?, | ||||||
|  |             is_extended_card_info_enabled: None, | ||||||
|         }) |         }) | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  | |||||||
| @ -1,3 +1,3 @@ | |||||||
| pub use diesel_models::business_profile::{ | pub use diesel_models::business_profile::{ | ||||||
|     BusinessProfile, BusinessProfileNew, BusinessProfileUpdateInternal, |     BusinessProfile, BusinessProfileNew, BusinessProfileUpdate, BusinessProfileUpdateInternal, | ||||||
| }; | }; | ||||||
|  | |||||||
| @ -406,6 +406,8 @@ pub enum Flow { | |||||||
|     WebhookEventDeliveryRetry, |     WebhookEventDeliveryRetry, | ||||||
|     /// Retrieve status of the Poll |     /// Retrieve status of the Poll | ||||||
|     RetrievePollStatus, |     RetrievePollStatus, | ||||||
|  |     /// Toggles the extended card info feature in profile level | ||||||
|  |     ToggleExtendedCardInfo, | ||||||
| } | } | ||||||
|  |  | ||||||
| /// | /// | ||||||
|  | |||||||
| @ -0,0 +1,3 @@ | |||||||
|  | -- This file should undo anything in `up.sql` | ||||||
|  |  | ||||||
|  | ALTER TABLE business_profile DROP COLUMN IF EXISTS is_extended_card_info_enabled; | ||||||
| @ -0,0 +1,3 @@ | |||||||
|  | -- Your SQL goes here | ||||||
|  |  | ||||||
|  | ALTER TABLE business_profile ADD COLUMN IF NOT EXISTS is_extended_card_info_enabled BOOLEAN DEFAULT FALSE; | ||||||
		Reference in New Issue
	
	Block a user
	 Chethan Rao
					Chethan Rao