Bug: Add onboarding flow for VSAAS



- Support for endpoint to create a platform 
- Create platform org and platform merchant account
- Support to create connected merchant account inside platform org
- Modify existing list responses for org and merchant, to distinguish platform from standard.
diff --git a/crates/api_models/src/events/user.rs b/crates/api_models/src/events/user.rs
index 5e0564b4187..1a20e7b90b0 100644
--- a/crates/api_models/src/events/user.rs
+++ b/crates/api_models/src/events/user.rs
@@ -15,13 +15,13 @@ use crate::user::{
     CreateTenantUserRequest, CreateUserAuthenticationMethodRequest, ForgotPasswordRequest,
     GetSsoAuthUrlRequest, GetUserAuthenticationMethodsRequest, GetUserDetailsResponse,
     GetUserRoleDetailsRequest, GetUserRoleDetailsResponseV2, InviteUserRequest,
-    ReInviteUserRequest, RecoveryCodes, ResetPasswordRequest, RotatePasswordRequest,
-    SendVerifyEmailRequest, SignUpRequest, SignUpWithMerchantIdRequest, SsoSignInRequest,
-    SwitchMerchantRequest, SwitchOrganizationRequest, SwitchProfileRequest, TokenResponse,
-    TwoFactorAuthStatusResponse, TwoFactorStatus, UpdateUserAccountDetailsRequest,
-    UpdateUserAuthenticationMethodRequest, UserFromEmailRequest, UserMerchantAccountResponse,
-    UserMerchantCreate, UserOrgMerchantCreateRequest, VerifyEmailRequest,
-    VerifyRecoveryCodeRequest, VerifyTotpRequest,
+    PlatformAccountCreateRequest, PlatformAccountCreateResponse, ReInviteUserRequest,
+    RecoveryCodes, ResetPasswordRequest, RotatePasswordRequest, SendVerifyEmailRequest,
+    SignUpRequest, SignUpWithMerchantIdRequest, SsoSignInRequest, SwitchMerchantRequest,
+    SwitchOrganizationRequest, SwitchProfileRequest, TokenResponse, TwoFactorAuthStatusResponse,
+    TwoFactorStatus, UpdateUserAccountDetailsRequest, UpdateUserAuthenticationMethodRequest,
+    UserFromEmailRequest, UserMerchantAccountResponse, UserMerchantCreate,
+    UserOrgMerchantCreateRequest, VerifyEmailRequest, VerifyRecoveryCodeRequest, VerifyTotpRequest,
 };
 
 common_utils::impl_api_event_type!(
@@ -39,6 +39,8 @@ common_utils::impl_api_event_type!(
         SwitchProfileRequest,
         CreateInternalUserRequest,
         CreateTenantUserRequest,
+        PlatformAccountCreateRequest,
+        PlatformAccountCreateResponse,
         UserOrgMerchantCreateRequest,
         UserMerchantAccountResponse,
         UserMerchantCreate,
diff --git a/crates/api_models/src/organization.rs b/crates/api_models/src/organization.rs
index c6bc3924d11..e7ec5d32d74 100644
--- a/crates/api_models/src/organization.rs
+++ b/crates/api_models/src/organization.rs
@@ -1,14 +1,17 @@
+use common_enums::OrganizationType;
 use common_utils::{id_type, pii};
 use utoipa::ToSchema;
 pub struct OrganizationNew {
     pub org_id: id_type::OrganizationId,
+    pub org_type: OrganizationType,
     pub org_name: Option<String>,
 }
 
 impl OrganizationNew {
-    pub fn new(org_name: Option<String>) -> Self {
+    pub fn new(org_type: OrganizationType, org_name: Option<String>) -> Self {
         Self {
             org_id: id_type::OrganizationId::default(),
+            org_type,
             org_name,
         }
     }
@@ -47,6 +50,9 @@ pub struct OrganizationUpdateRequest {
     /// Metadata is useful for storing additional, unstructured information on an object.
     #[schema(value_type = Option<Object>)]
     pub metadata: Option<pii::SecretSerdeValue>,
+
+    /// Platform merchant id is unique distiguisher for special merchant in the platform org
+    pub platform_merchant_id: Option<id_type::MerchantId>,
 }
 #[cfg(feature = "v1")]
 #[derive(Debug, serde::Serialize, Clone, ToSchema)]
diff --git a/crates/api_models/src/user.rs b/crates/api_models/src/user.rs
index aa39877f0c7..d979a2d5a11 100644
--- a/crates/api_models/src/user.rs
+++ b/crates/api_models/src/user.rs
@@ -130,6 +130,20 @@ pub struct UserOrgMerchantCreateRequest {
     pub merchant_name: Secret<String>,
 }
 
+#[derive(Debug, serde::Deserialize, serde::Serialize, Clone)]
+pub struct PlatformAccountCreateRequest {
+    pub organization_name: Secret<String>,
+}
+
+#[derive(Debug, serde::Deserialize, serde::Serialize)]
+pub struct PlatformAccountCreateResponse {
+    pub org_id: id_type::OrganizationId,
+    pub org_name: Option<String>,
+    pub org_type: common_enums::OrganizationType,
+    pub merchant_id: id_type::MerchantId,
+    pub merchant_account_type: common_enums::MerchantAccountType,
+}
+
 #[derive(Debug, serde::Deserialize, serde::Serialize)]
 pub struct UserMerchantCreate {
     pub company_name: String,
@@ -381,6 +395,7 @@ pub struct UserTransferKeyResponse {
 pub struct ListOrgsForUserResponse {
     pub org_id: id_type::OrganizationId,
     pub org_name: Option<String>,
+    pub org_type: common_enums::OrganizationType,
 }
 
 #[derive(Debug, serde::Serialize)]
@@ -388,6 +403,7 @@ pub struct UserMerchantAccountResponse {
     pub merchant_id: id_type::MerchantId,
     pub merchant_name: OptionalEncryptableName,
     pub product_type: Option<common_enums::MerchantProductType>,
+    pub merchant_account_type: common_enums::MerchantAccountType,
     pub version: common_enums::ApiVersion,
 }
 
diff --git a/crates/common_enums/src/enums.rs b/crates/common_enums/src/enums.rs
index 2643b97904c..01abaf277f0 100644
--- a/crates/common_enums/src/enums.rs
+++ b/crates/common_enums/src/enums.rs
@@ -6,7 +6,7 @@ use std::{
     num::{ParseFloatError, TryFromIntError},
 };
 
-pub use accounts::MerchantProductType;
+pub use accounts::{MerchantAccountType, MerchantProductType, OrganizationType};
 pub use payments::ProductType;
 use serde::{Deserialize, Serialize};
 pub use ui::*;
diff --git a/crates/common_enums/src/enums/accounts.rs b/crates/common_enums/src/enums/accounts.rs
index e5b3ef733c6..7500dcac7c8 100644
--- a/crates/common_enums/src/enums/accounts.rs
+++ b/crates/common_enums/src/enums/accounts.rs
@@ -26,3 +26,46 @@ pub enum MerchantProductType {
     CostObservability,
     DynamicRouting,
 }
+
+#[derive(
+    Clone,
+    Copy,
+    Debug,
+    Default,
+    Eq,
+    PartialEq,
+    serde::Deserialize,
+    serde::Serialize,
+    strum::Display,
+    strum::EnumString,
+)]
+#[router_derive::diesel_enum(storage_type = "text")]
+#[strum(serialize_all = "snake_case")]
+#[serde(rename_all = "snake_case")]
+pub enum MerchantAccountType {
+    #[default]
+    Standard,
+    Platform,
+    Connected,
+}
+
+#[derive(
+    Clone,
+    Copy,
+    Debug,
+    Default,
+    Eq,
+    PartialEq,
+    serde::Deserialize,
+    serde::Serialize,
+    strum::Display,
+    strum::EnumString,
+)]
+#[router_derive::diesel_enum(storage_type = "text")]
+#[strum(serialize_all = "snake_case")]
+#[serde(rename_all = "snake_case")]
+pub enum OrganizationType {
+    #[default]
+    Standard,
+    Platform,
+}
diff --git a/crates/diesel_models/src/merchant_account.rs b/crates/diesel_models/src/merchant_account.rs
index 40c6a1e4ff3..e0b421f40c9 100644
--- a/crates/diesel_models/src/merchant_account.rs
+++ b/crates/diesel_models/src/merchant_account.rs
@@ -54,6 +54,7 @@ pub struct MerchantAccount {
     pub is_platform_account: bool,
     pub id: Option<common_utils::id_type::MerchantId>,
     pub product_type: Option<common_enums::MerchantProductType>,
+    pub merchant_account_type: Option<common_enums::MerchantAccountType>,
 }
 
 #[cfg(feature = "v1")]
@@ -88,6 +89,7 @@ pub struct MerchantAccountSetter {
     pub version: common_enums::ApiVersion,
     pub is_platform_account: bool,
     pub product_type: Option<common_enums::MerchantProductType>,
+    pub merchant_account_type: common_enums::MerchantAccountType,
 }
 
 #[cfg(feature = "v1")]
@@ -125,6 +127,7 @@ impl From<MerchantAccountSetter> for MerchantAccount {
             version: item.version,
             is_platform_account: item.is_platform_account,
             product_type: item.product_type,
+            merchant_account_type: Some(item.merchant_account_type),
         }
     }
 }
@@ -158,6 +161,7 @@ pub struct MerchantAccount {
     pub is_platform_account: bool,
     pub id: common_utils::id_type::MerchantId,
     pub product_type: Option<common_enums::MerchantProductType>,
+    pub merchant_account_type: Option<common_enums::MerchantAccountType>,
 }
 
 #[cfg(feature = "v2")]
@@ -177,6 +181,7 @@ impl From<MerchantAccountSetter> for MerchantAccount {
             version: item.version,
             is_platform_account: item.is_platform_account,
             product_type: item.product_type,
+            merchant_account_type: Some(item.merchant_account_type),
         }
     }
 }
@@ -196,6 +201,7 @@ pub struct MerchantAccountSetter {
     pub version: common_enums::ApiVersion,
     pub is_platform_account: bool,
     pub product_type: Option<common_enums::MerchantProductType>,
+    pub merchant_account_type: common_enums::MerchantAccountType,
 }
 
 impl MerchantAccount {
@@ -245,6 +251,7 @@ pub struct MerchantAccountNew {
     pub is_platform_account: bool,
     pub id: Option<common_utils::id_type::MerchantId>,
     pub product_type: Option<common_enums::MerchantProductType>,
+    pub merchant_account_type: common_enums::MerchantAccountType,
 }
 
 #[cfg(feature = "v2")]
@@ -263,6 +270,7 @@ pub struct MerchantAccountNew {
     pub version: common_enums::ApiVersion,
     pub is_platform_account: bool,
     pub product_type: Option<common_enums::MerchantProductType>,
+    pub merchant_account_type: common_enums::MerchantAccountType,
 }
 
 #[cfg(feature = "v2")]
@@ -311,6 +319,7 @@ impl MerchantAccountUpdateInternal {
             id: source.id,
             is_platform_account: is_platform_account.unwrap_or(source.is_platform_account),
             product_type: product_type.or(source.product_type),
+            merchant_account_type: source.merchant_account_type,
         }
     }
 }
@@ -417,6 +426,7 @@ impl MerchantAccountUpdateInternal {
             is_platform_account: is_platform_account.unwrap_or(source.is_platform_account),
             id: source.id,
             product_type: product_type.or(source.product_type),
+            merchant_account_type: source.merchant_account_type,
         }
     }
 }
diff --git a/crates/diesel_models/src/organization.rs b/crates/diesel_models/src/organization.rs
index 1ca86225934..ffa1e94fcfa 100644
--- a/crates/diesel_models/src/organization.rs
+++ b/crates/diesel_models/src/organization.rs
@@ -29,6 +29,8 @@ pub struct Organization {
     #[allow(dead_code)]
     organization_name: Option<String>,
     pub version: common_enums::ApiVersion,
+    pub organization_type: Option<common_enums::OrganizationType>,
+    pub platform_merchant_id: Option<id_type::MerchantId>,
 }
 
 #[cfg(feature = "v2")]
@@ -46,6 +48,8 @@ pub struct Organization {
     id: id_type::OrganizationId,
     organization_name: Option<String>,
     pub version: common_enums::ApiVersion,
+    pub organization_type: Option<common_enums::OrganizationType>,
+    pub platform_merchant_id: Option<id_type::MerchantId>,
 }
 
 #[cfg(feature = "v1")]
@@ -61,6 +65,8 @@ impl Organization {
             id: _,
             organization_name: _,
             version,
+            organization_type,
+            platform_merchant_id,
         } = org_new;
         Self {
             id: Some(org_id.clone()),
@@ -72,8 +78,14 @@ impl Organization {
             created_at,
             modified_at,
             version,
+            organization_type: Some(organization_type),
+            platform_merchant_id,
         }
     }
+
+    pub fn get_organization_type(&self) -> common_enums::OrganizationType {
+        self.organization_type.unwrap_or_default()
+    }
 }
 
 #[cfg(feature = "v2")]
@@ -87,6 +99,8 @@ impl Organization {
             created_at,
             modified_at,
             version,
+            organization_type,
+            platform_merchant_id,
         } = org_new;
         Self {
             id,
@@ -96,8 +110,14 @@ impl Organization {
             created_at,
             modified_at,
             version,
+            organization_type: Some(organization_type),
+            platform_merchant_id,
         }
     }
+
+    pub fn get_organization_type(&self) -> common_enums::OrganizationType {
+        self.organization_type.unwrap_or_default()
+    }
 }
 
 #[cfg(feature = "v1")]
@@ -113,6 +133,8 @@ pub struct OrganizationNew {
     pub created_at: time::PrimitiveDateTime,
     pub modified_at: time::PrimitiveDateTime,
     pub version: common_enums::ApiVersion,
+    pub organization_type: common_enums::OrganizationType,
+    pub platform_merchant_id: Option<id_type::MerchantId>,
 }
 
 #[cfg(feature = "v2")]
@@ -126,11 +148,17 @@ pub struct OrganizationNew {
     pub created_at: time::PrimitiveDateTime,
     pub modified_at: time::PrimitiveDateTime,
     pub version: common_enums::ApiVersion,
+    pub organization_type: common_enums::OrganizationType,
+    pub platform_merchant_id: Option<id_type::MerchantId>,
 }
 
 #[cfg(feature = "v1")]
 impl OrganizationNew {
-    pub fn new(id: id_type::OrganizationId, organization_name: Option<String>) -> Self {
+    pub fn new(
+        id: id_type::OrganizationId,
+        organization_type: common_enums::OrganizationType,
+        organization_name: Option<String>,
+    ) -> Self {
         Self {
             org_id: id.clone(),
             org_name: organization_name.clone(),
@@ -141,13 +169,19 @@ impl OrganizationNew {
             created_at: common_utils::date_time::now(),
             modified_at: common_utils::date_time::now(),
             version: common_types::consts::API_VERSION,
+            organization_type,
+            platform_merchant_id: None,
         }
     }
 }
 
 #[cfg(feature = "v2")]
 impl OrganizationNew {
-    pub fn new(id: id_type::OrganizationId, organization_name: Option<String>) -> Self {
+    pub fn new(
+        id: id_type::OrganizationId,
+        organization_type: common_enums::OrganizationType,
+        organization_name: Option<String>,
+    ) -> Self {
         Self {
             id,
             organization_name,
@@ -156,6 +190,8 @@ impl OrganizationNew {
             created_at: common_utils::date_time::now(),
             modified_at: common_utils::date_time::now(),
             version: common_types::consts::API_VERSION,
+            organization_type,
+            platform_merchant_id: None,
         }
     }
 }
@@ -169,6 +205,7 @@ pub struct OrganizationUpdateInternal {
     organization_details: Option<pii::SecretSerdeValue>,
     metadata: Option<pii::SecretSerdeValue>,
     modified_at: time::PrimitiveDateTime,
+    platform_merchant_id: Option<id_type::MerchantId>,
 }
 
 #[cfg(feature = "v2")]
@@ -179,6 +216,7 @@ pub struct OrganizationUpdateInternal {
     organization_details: Option<pii::SecretSerdeValue>,
     metadata: Option<pii::SecretSerdeValue>,
     modified_at: time::PrimitiveDateTime,
+    platform_merchant_id: Option<id_type::MerchantId>,
 }
 
 pub enum OrganizationUpdate {
@@ -186,6 +224,7 @@ pub enum OrganizationUpdate {
         organization_name: Option<String>,
         organization_details: Option<pii::SecretSerdeValue>,
         metadata: Option<pii::SecretSerdeValue>,
+        platform_merchant_id: Option<id_type::MerchantId>,
     },
 }
 
@@ -197,12 +236,14 @@ impl From<OrganizationUpdate> for OrganizationUpdateInternal {
                 organization_name,
                 organization_details,
                 metadata,
+                platform_merchant_id,
             } => Self {
                 org_name: organization_name.clone(),
                 organization_name,
                 organization_details,
                 metadata,
                 modified_at: common_utils::date_time::now(),
+                platform_merchant_id,
             },
         }
     }
@@ -216,11 +257,13 @@ impl From<OrganizationUpdate> for OrganizationUpdateInternal {
                 organization_name,
                 organization_details,
                 metadata,
+                platform_merchant_id,
             } => Self {
                 organization_name,
                 organization_details,
                 metadata,
                 modified_at: common_utils::date_time::now(),
+                platform_merchant_id,
             },
         }
     }
diff --git a/crates/diesel_models/src/schema.rs b/crates/diesel_models/src/schema.rs
index c25acc386f5..46a36bab8c9 100644
--- a/crates/diesel_models/src/schema.rs
+++ b/crates/diesel_models/src/schema.rs
@@ -750,6 +750,8 @@ diesel::table! {
         id -> Nullable<Varchar>,
         #[max_length = 64]
         product_type -> Nullable<Varchar>,
+        #[max_length = 64]
+        merchant_account_type -> Nullable<Varchar>,
     }
 }
 
@@ -823,6 +825,10 @@ diesel::table! {
         id -> Nullable<Varchar>,
         organization_name -> Nullable<Text>,
         version -> ApiVersion,
+        #[max_length = 64]
+        organization_type -> Nullable<Varchar>,
+        #[max_length = 64]
+        platform_merchant_id -> Nullable<Varchar>,
     }
 }
 
diff --git a/crates/diesel_models/src/schema_v2.rs b/crates/diesel_models/src/schema_v2.rs
index 8f857a4db26..d9df67f0fb7 100644
--- a/crates/diesel_models/src/schema_v2.rs
+++ b/crates/diesel_models/src/schema_v2.rs
@@ -738,6 +738,8 @@ diesel::table! {
         id -> Varchar,
         #[max_length = 64]
         product_type -> Nullable<Varchar>,
+        #[max_length = 64]
+        merchant_account_type -> Nullable<Varchar>,
     }
 }
 
@@ -800,6 +802,10 @@ diesel::table! {
         id -> Varchar,
         organization_name -> Nullable<Text>,
         version -> ApiVersion,
+        #[max_length = 64]
+        organization_type -> Nullable<Varchar>,
+        #[max_length = 64]
+        platform_merchant_id -> Nullable<Varchar>,
     }
 }
 
diff --git a/crates/hyperswitch_domain_models/src/merchant_account.rs b/crates/hyperswitch_domain_models/src/merchant_account.rs
index 8657af91c57..2cd1af98639 100644
--- a/crates/hyperswitch_domain_models/src/merchant_account.rs
+++ b/crates/hyperswitch_domain_models/src/merchant_account.rs
@@ -49,6 +49,7 @@ pub struct MerchantAccount {
     pub version: common_enums::ApiVersion,
     pub is_platform_account: bool,
     pub product_type: Option<common_enums::MerchantProductType>,
+    pub merchant_account_type: common_enums::MerchantAccountType,
 }
 
 #[cfg(feature = "v1")]
@@ -85,6 +86,7 @@ pub struct MerchantAccountSetter {
     pub version: common_enums::ApiVersion,
     pub is_platform_account: bool,
     pub product_type: Option<common_enums::MerchantProductType>,
+    pub merchant_account_type: common_enums::MerchantAccountType,
 }
 
 #[cfg(feature = "v1")]
@@ -121,6 +123,7 @@ impl From<MerchantAccountSetter> for MerchantAccount {
             version: item.version,
             is_platform_account: item.is_platform_account,
             product_type: item.product_type,
+            merchant_account_type: item.merchant_account_type,
         }
     }
 }
@@ -142,6 +145,7 @@ pub struct MerchantAccountSetter {
     pub is_platform_account: bool,
     pub version: common_enums::ApiVersion,
     pub product_type: Option<common_enums::MerchantProductType>,
+    pub merchant_account_type: common_enums::MerchantAccountType,
 }
 
 #[cfg(feature = "v2")]
@@ -161,6 +165,7 @@ impl From<MerchantAccountSetter> for MerchantAccount {
             is_platform_account,
             version,
             product_type,
+            merchant_account_type,
         } = item;
         Self {
             id,
@@ -176,6 +181,7 @@ impl From<MerchantAccountSetter> for MerchantAccount {
             is_platform_account,
             version,
             product_type,
+            merchant_account_type,
         }
     }
 }
@@ -196,6 +202,7 @@ pub struct MerchantAccount {
     pub is_platform_account: bool,
     pub version: common_enums::ApiVersion,
     pub product_type: Option<common_enums::MerchantProductType>,
+    pub merchant_account_type: common_enums::MerchantAccountType,
 }
 
 impl MerchantAccount {
@@ -575,6 +582,7 @@ impl super::behaviour::Conversion for MerchantAccount {
             version: common_types::consts::API_VERSION,
             is_platform_account: self.is_platform_account,
             product_type: self.product_type,
+            merchant_account_type: self.merchant_account_type,
         };
 
         Ok(diesel_models::MerchantAccount::from(setter))
@@ -637,6 +645,7 @@ impl super::behaviour::Conversion for MerchantAccount {
                 is_platform_account: item.is_platform_account,
                 version: item.version,
                 product_type: item.product_type,
+                merchant_account_type: item.merchant_account_type.unwrap_or_default(),
             })
         }
         .await
@@ -662,6 +671,7 @@ impl super::behaviour::Conversion for MerchantAccount {
             product_type: self
                 .product_type
                 .or(Some(common_enums::MerchantProductType::Orchestration)),
+            merchant_account_type: self.merchant_account_type,
         })
     }
 }
@@ -703,6 +713,7 @@ impl super::behaviour::Conversion for MerchantAccount {
             version: self.version,
             is_platform_account: self.is_platform_account,
             product_type: self.product_type,
+            merchant_account_type: self.merchant_account_type,
         };
 
         Ok(diesel_models::MerchantAccount::from(setter))
@@ -782,6 +793,7 @@ impl super::behaviour::Conversion for MerchantAccount {
                 version: item.version,
                 is_platform_account: item.is_platform_account,
                 product_type: item.product_type,
+                merchant_account_type: item.merchant_account_type.unwrap_or_default(),
             })
         }
         .await
@@ -825,6 +837,7 @@ impl super::behaviour::Conversion for MerchantAccount {
             product_type: self
                 .product_type
                 .or(Some(common_enums::MerchantProductType::Orchestration)),
+            merchant_account_type: self.merchant_account_type,
         })
     }
 }
diff --git a/crates/router/src/core/admin.rs b/crates/router/src/core/admin.rs
index a5c2fbd483f..7919af296d3 100644
--- a/crates/router/src/core/admin.rs
+++ b/crates/router/src/core/admin.rs
@@ -4,6 +4,7 @@ use api_models::{
     admin::{self as admin_types},
     enums as api_enums, routing as routing_types,
 };
+use common_enums::{MerchantAccountType, OrganizationType};
 use common_utils::{
     date_time,
     ext_traits::{AsyncExt, Encode, OptionExt, ValueExt},
@@ -142,6 +143,7 @@ pub async fn update_organization(
         organization_name: req.organization_name,
         organization_details: req.organization_details,
         metadata: req.metadata,
+        platform_merchant_id: req.platform_merchant_id,
     };
     state
         .accounts_store
@@ -336,6 +338,31 @@ impl MerchantAccountCreateBridge for api::MerchantAccountCreate {
             .create_or_validate(db)
             .await?;
 
+        let merchant_account_type = match organization.get_organization_type() {
+            OrganizationType::Standard => MerchantAccountType::Standard,
+
+            OrganizationType::Platform => {
+                let accounts = state
+                    .store
+                    .list_merchant_accounts_by_organization_id(
+                        &state.into(),
+                        &organization.get_organization_id(),
+                    )
+                    .await
+                    .to_not_found_response(errors::ApiErrorResponse::MerchantAccountNotFound)?;
+
+                let platform_account_exists = accounts
+                    .iter()
+                    .any(|account| account.merchant_account_type == MerchantAccountType::Platform);
+
+                if platform_account_exists {
+                    MerchantAccountType::Connected
+                } else {
+                    MerchantAccountType::Platform
+                }
+            }
+        };
+
         let key = key_store.key.clone().into_inner();
         let key_manager_state = state.into();
 
@@ -405,6 +432,7 @@ impl MerchantAccountCreateBridge for api::MerchantAccountCreate {
                     version: common_types::consts::API_VERSION,
                     is_platform_account: false,
                     product_type: self.product_type,
+                    merchant_account_type,
                 },
             )
         }
@@ -461,7 +489,10 @@ impl CreateOrValidateOrganization {
         match self {
             #[cfg(feature = "v1")]
             Self::Create => {
-                let new_organization = api_models::organization::OrganizationNew::new(None);
+                let new_organization = api_models::organization::OrganizationNew::new(
+                    OrganizationType::Standard,
+                    None,
+                );
                 let db_organization = ForeignFrom::foreign_from(new_organization);
                 db.insert_organization(db_organization)
                     .await
@@ -629,6 +660,18 @@ impl MerchantAccountCreateBridge for api::MerchantAccountCreate {
             .create_or_validate(db)
             .await?;
 
+        let merchant_account_type = match organization.get_organization_type() {
+            OrganizationType::Standard => MerchantAccountType::Standard,
+            // Blocking v2 merchant account create for platform
+            OrganizationType::Platform => {
+                return Err(errors::ApiErrorResponse::InvalidRequestData {
+                    message: "Merchant account creation is not allowed for a platform organization"
+                        .to_string(),
+                }
+                .into())
+            }
+        };
+
         let key = key_store.key.into_inner();
         let id = identifier.to_owned();
         let key_manager_state = state.into();
@@ -675,6 +718,7 @@ impl MerchantAccountCreateBridge for api::MerchantAccountCreate {
                     is_platform_account: false,
                     version: common_types::consts::API_VERSION,
                     product_type: self.product_type,
+                    merchant_account_type,
                 }),
             )
         }
diff --git a/crates/router/src/core/user.rs b/crates/router/src/core/user.rs
index 6e5360d8848..ff90ca1dfac 100644
--- a/crates/router/src/core/user.rs
+++ b/crates/router/src/core/user.rs
@@ -1497,6 +1497,71 @@ pub async fn create_tenant_user(
     Ok(ApplicationResponse::StatusOk)
 }
 
+#[cfg(feature = "v1")]
+pub async fn create_platform_account(
+    state: SessionState,
+    user_from_token: auth::UserFromToken,
+    req: user_api::PlatformAccountCreateRequest,
+) -> UserResponse<user_api::PlatformAccountCreateResponse> {
+    let user_from_db = user_from_token.get_user_from_db(&state).await?;
+
+    let new_merchant = domain::NewUserMerchant::try_from(req)?;
+    let new_organization = new_merchant.get_new_organization();
+    let organization = new_organization.insert_org_in_db(state.clone()).await?;
+
+    let merchant_account = new_merchant
+        .create_new_merchant_and_insert_in_db(state.to_owned())
+        .await?;
+
+    state
+        .accounts_store
+        .update_organization_by_org_id(
+            &organization.get_organization_id(),
+            diesel_models::organization::OrganizationUpdate::Update {
+                organization_name: None,
+                organization_details: None,
+                metadata: None,
+                platform_merchant_id: Some(merchant_account.get_id().to_owned()),
+            },
+        )
+        .await
+        .change_context(UserErrors::InternalServerError)?;
+
+    let now = common_utils::date_time::now();
+
+    let user_role = domain::NewUserRole {
+        user_id: user_from_db.get_user_id().to_owned(),
+        role_id: common_utils::consts::ROLE_ID_ORGANIZATION_ADMIN.to_string(),
+        status: UserStatus::Active,
+        created_by: user_from_token.user_id.clone(),
+        last_modified_by: user_from_token.user_id.clone(),
+        created_at: now,
+        last_modified: now,
+        entity: domain::NoLevel,
+    };
+
+    user_role
+        .add_entity(domain::OrganizationLevel {
+            tenant_id: user_from_token
+                .tenant_id
+                .clone()
+                .unwrap_or(state.tenant.tenant_id.clone()),
+            org_id: merchant_account.organization_id.clone(),
+        })
+        .insert_in_v2(&state)
+        .await?;
+
+    Ok(ApplicationResponse::Json(
+        user_api::PlatformAccountCreateResponse {
+            org_id: organization.get_organization_id(),
+            org_name: organization.get_organization_name(),
+            org_type: organization.organization_type.unwrap_or_default(),
+            merchant_id: merchant_account.get_id().to_owned(),
+            merchant_account_type: merchant_account.merchant_account_type,
+        },
+    ))
+}
+
 #[cfg(feature = "v1")]
 pub async fn create_org_merchant_for_user(
     state: SessionState,
@@ -1537,6 +1602,7 @@ pub async fn create_merchant_account(
             merchant_id: domain_merchant_account.get_id().to_owned(),
             merchant_name: domain_merchant_account.merchant_name,
             product_type: domain_merchant_account.product_type,
+            merchant_account_type: domain_merchant_account.merchant_account_type,
             version: domain_merchant_account.version,
         },
     ))
@@ -2893,6 +2959,7 @@ pub async fn list_orgs_for_user(
     .map(|org| user_api::ListOrgsForUserResponse {
         org_id: org.get_organization_id(),
         org_name: org.get_organization_name(),
+        org_type: org.organization_type.unwrap_or_default(),
     })
     .collect::<Vec<_>>();
 
@@ -2975,6 +3042,7 @@ pub async fn list_merchants_for_user_in_org(
                 merchant_name: merchant_account.merchant_name.clone(),
                 merchant_id: merchant_account.get_id().to_owned(),
                 product_type: merchant_account.product_type,
+                merchant_account_type: merchant_account.merchant_account_type,
                 version: merchant_account.version,
             })
             .collect::<Vec<_>>(),
diff --git a/crates/router/src/db/organization.rs b/crates/router/src/db/organization.rs
index b1dc58f0402..bb4f125db2a 100644
--- a/crates/router/src/db/organization.rs
+++ b/crates/router/src/db/organization.rs
@@ -119,12 +119,14 @@ impl OrganizationInterface for super::MockDb {
                     organization_name,
                     organization_details,
                     metadata,
+                    platform_merchant_id,
                 } => {
                     organization_name
                         .as_ref()
                         .map(|org_name| org.set_organization_name(org_name.to_owned()));
                     organization_details.clone_into(&mut org.organization_details);
                     metadata.clone_into(&mut org.metadata);
+                    platform_merchant_id.clone_into(&mut org.platform_merchant_id);
                     org
                 }
             })
diff --git a/crates/router/src/routes/app.rs b/crates/router/src/routes/app.rs
index 9dc67be1d2d..61d5e709420 100644
--- a/crates/router/src/routes/app.rs
+++ b/crates/router/src/routes/app.rs
@@ -2183,6 +2183,7 @@ impl User {
             .service(
                 web::resource("/tenant_signup").route(web::post().to(user::create_tenant_user)),
             )
+            .service(web::resource("/create_platform").route(web::post().to(user::create_platform)))
             .service(web::resource("/create_org").route(web::post().to(user::user_org_create)))
             .service(
                 web::resource("/create_merchant")
diff --git a/crates/router/src/routes/lock_utils.rs b/crates/router/src/routes/lock_utils.rs
index 760a4bc890c..9e0642b4984 100644
--- a/crates/router/src/routes/lock_utils.rs
+++ b/crates/router/src/routes/lock_utils.rs
@@ -247,6 +247,7 @@ impl From<Flow> for ApiIdentifier {
             | Flow::SwitchOrg
             | Flow::SwitchMerchantV2
             | Flow::SwitchProfile
+            | Flow::CreatePlatformAccount
             | Flow::UserOrgMerchantCreate
             | Flow::UserMerchantAccountCreate
             | Flow::GenerateSampleData
diff --git a/crates/router/src/routes/user.rs b/crates/router/src/routes/user.rs
index d075048ddb6..a6d9d75dc43 100644
--- a/crates/router/src/routes/user.rs
+++ b/crates/router/src/routes/user.rs
@@ -259,6 +259,29 @@ pub async fn create_tenant_user(
     .await
 }
 
+#[cfg(feature = "v1")]
+pub async fn create_platform(
+    state: web::Data<AppState>,
+    req: HttpRequest,
+    json_payload: web::Json<user_api::PlatformAccountCreateRequest>,
+) -> HttpResponse {
+    let flow = Flow::CreatePlatformAccount;
+    Box::pin(api::server_wrap(
+        flow,
+        state,
+        &req,
+        json_payload.into_inner(),
+        |state, user: auth::UserFromToken, json_payload, _| {
+            user_core::create_platform_account(state, user, json_payload)
+        },
+        &auth::JWTAuth {
+            permission: Permission::OrganizationAccountWrite,
+        },
+        api_locking::LockAction::NotApplicable,
+    ))
+    .await
+}
+
 #[cfg(feature = "v1")]
 pub async fn user_org_create(
     state: web::Data<AppState>,
diff --git a/crates/router/src/types/domain/user.rs b/crates/router/src/types/domain/user.rs
index 016995cb550..80dbb6d5258 100644
--- a/crates/router/src/types/domain/user.rs
+++ b/crates/router/src/types/domain/user.rs
@@ -23,7 +23,7 @@ use hyperswitch_domain_models::api::ApplicationResponse;
 use masking::{ExposeInterface, PeekInterface, Secret};
 use once_cell::sync::Lazy;
 use rand::distributions::{Alphanumeric, DistString};
-use router_env::{env, logger};
+use router_env::logger;
 use time::PrimitiveDateTime;
 use unicode_segmentation::UnicodeSegmentation;
 #[cfg(feature = "keymanager_create")]
@@ -267,9 +267,10 @@ impl NewUserOrganization {
 impl TryFrom<user_api::SignUpWithMerchantIdRequest> for NewUserOrganization {
     type Error = error_stack::Report<UserErrors>;
     fn try_from(value: user_api::SignUpWithMerchantIdRequest) -> UserResult<Self> {
-        let new_organization = api_org::OrganizationNew::new(Some(
-            UserCompanyName::new(value.company_name)?.get_secret(),
-        ));
+        let new_organization = api_org::OrganizationNew::new(
+            common_enums::OrganizationType::Standard,
+            Some(UserCompanyName::new(value.company_name)?.get_secret()),
+        );
         let db_organization = ForeignFrom::foreign_from(new_organization);
         Ok(Self(db_organization))
     }
@@ -277,7 +278,8 @@ impl TryFrom<user_api::SignUpWithMerchantIdRequest> for NewUserOrganization {
 
 impl From<user_api::SignUpRequest> for NewUserOrganization {
     fn from(_value: user_api::SignUpRequest) -> Self {
-        let new_organization = api_org::OrganizationNew::new(None);
+        let new_organization =
+            api_org::OrganizationNew::new(common_enums::OrganizationType::Standard, None);
         let db_organization = ForeignFrom::foreign_from(new_organization);
         Self(db_organization)
     }
@@ -285,7 +287,8 @@ impl From<user_api::SignUpRequest> for NewUserOrganization {
 
 impl From<user_api::ConnectAccountRequest> for NewUserOrganization {
     fn from(_value: user_api::ConnectAccountRequest) -> Self {
-        let new_organization = api_org::OrganizationNew::new(None);
+        let new_organization =
+            api_org::OrganizationNew::new(common_enums::OrganizationType::Standard, None);
         let db_organization = ForeignFrom::foreign_from(new_organization);
         Self(db_organization)
     }
@@ -297,6 +300,7 @@ impl From<(user_api::CreateInternalUserRequest, id_type::OrganizationId)> for Ne
     ) -> Self {
         let new_organization = api_org::OrganizationNew {
             org_id,
+            org_type: common_enums::OrganizationType::Standard,
             org_name: None,
         };
         let db_organization = ForeignFrom::foreign_from(new_organization);
@@ -308,15 +312,28 @@ impl From<UserMerchantCreateRequestWithToken> for NewUserOrganization {
     fn from(value: UserMerchantCreateRequestWithToken) -> Self {
         Self(diesel_org::OrganizationNew::new(
             value.2.org_id,
+            common_enums::OrganizationType::Standard,
             Some(value.1.company_name),
         ))
     }
 }
 
+impl From<user_api::PlatformAccountCreateRequest> for NewUserOrganization {
+    fn from(value: user_api::PlatformAccountCreateRequest) -> Self {
+        let new_organization = api_org::OrganizationNew::new(
+            common_enums::OrganizationType::Platform,
+            Some(value.organization_name.expose()),
+        );
+        let db_organization = ForeignFrom::foreign_from(new_organization);
+        Self(db_organization)
+    }
+}
+
 type InviteeUserRequestWithInvitedUserToken = (user_api::InviteUserRequest, UserFromToken);
 impl From<InviteeUserRequestWithInvitedUserToken> for NewUserOrganization {
     fn from(_value: InviteeUserRequestWithInvitedUserToken) -> Self {
-        let new_organization = api_org::OrganizationNew::new(None);
+        let new_organization =
+            api_org::OrganizationNew::new(common_enums::OrganizationType::Standard, None);
         let db_organization = ForeignFrom::foreign_from(new_organization);
         Self(db_organization)
     }
@@ -331,6 +348,7 @@ impl From<(user_api::CreateTenantUserRequest, MerchantAccountIdentifier)> for Ne
     ) -> Self {
         let new_organization = api_org::OrganizationNew {
             org_id: merchant_account_identifier.org_id,
+            org_type: common_enums::OrganizationType::Standard,
             org_name: None,
         };
         let db_organization = ForeignFrom::foreign_from(new_organization);
@@ -349,7 +367,11 @@ impl ForeignFrom<api_models::user::UserOrgMerchantCreateRequest>
             metadata,
             ..
         } = item;
-        let mut org_new_db = Self::new(org_id, Some(organization_name.expose()));
+        let mut org_new_db = Self::new(
+            org_id,
+            common_enums::OrganizationType::Standard,
+            Some(organization_name.expose()),
+        );
         org_new_db.organization_details = organization_details;
         org_new_db.metadata = metadata;
         org_new_db
@@ -698,11 +720,8 @@ impl TryFrom<UserMerchantCreateRequestWithToken> for NewUserMerchant {
     type Error = error_stack::Report<UserErrors>;
 
     fn try_from(value: UserMerchantCreateRequestWithToken) -> UserResult<Self> {
-        let merchant_id = if matches!(env::which(), env::Env::Production) {
-            id_type::MerchantId::try_from(MerchantId::new(value.1.company_name.clone())?)?
-        } else {
-            id_type::MerchantId::new_from_unix_timestamp()
-        };
+        let merchant_id =
+            utils::user::generate_env_specific_merchant_id(value.1.company_name.clone())?;
         let (user_from_storage, user_merchant_create, user_from_token) = value;
         Ok(Self {
             merchant_id,
@@ -719,6 +738,24 @@ impl TryFrom<UserMerchantCreateRequestWithToken> for NewUserMerchant {
     }
 }
 
+impl TryFrom<user_api::PlatformAccountCreateRequest> for NewUserMerchant {
+    type Error = error_stack::Report<UserErrors>;
+
+    fn try_from(value: user_api::PlatformAccountCreateRequest) -> UserResult<Self> {
+        let merchant_id = utils::user::generate_env_specific_merchant_id(
+            value.organization_name.clone().expose(),
+        )?;
+
+        let new_organization = NewUserOrganization::from(value);
+        Ok(Self {
+            company_name: None,
+            merchant_id,
+            new_organization,
+            product_type: Some(consts::user::DEFAULT_PRODUCT_TYPE),
+        })
+    }
+}
+
 #[derive(Debug, Clone)]
 pub struct MerchantAccountIdentifier {
     pub merchant_id: id_type::MerchantId,
diff --git a/crates/router/src/types/transformers.rs b/crates/router/src/types/transformers.rs
index 187f0c864d3..fdf52240320 100644
--- a/crates/router/src/types/transformers.rs
+++ b/crates/router/src/types/transformers.rs
@@ -1817,7 +1817,7 @@ impl ForeignFrom<api_models::organization::OrganizationNew>
     for diesel_models::organization::OrganizationNew
 {
     fn foreign_from(item: api_models::organization::OrganizationNew) -> Self {
-        Self::new(item.org_id, item.org_name)
+        Self::new(item.org_id, item.org_type, item.org_name)
     }
 }
 
@@ -1825,13 +1825,17 @@ impl ForeignFrom<api_models::organization::OrganizationCreateRequest>
     for diesel_models::organization::OrganizationNew
 {
     fn foreign_from(item: api_models::organization::OrganizationCreateRequest) -> Self {
-        let org_new = api_models::organization::OrganizationNew::new(None);
+        // Create a new organization with a standard type by default
+        let org_new = api_models::organization::OrganizationNew::new(
+            common_enums::OrganizationType::Standard,
+            None,
+        );
         let api_models::organization::OrganizationCreateRequest {
             organization_name,
             organization_details,
             metadata,
         } = item;
-        let mut org_new_db = Self::new(org_new.org_id, Some(organization_name));
+        let mut org_new_db = Self::new(org_new.org_id, org_new.org_type, Some(organization_name));
         org_new_db.organization_details = organization_details;
         org_new_db.metadata = metadata;
         org_new_db
diff --git a/crates/router/src/utils/user.rs b/crates/router/src/utils/user.rs
index 13190125d7d..61fb8472f6d 100644
--- a/crates/router/src/utils/user.rs
+++ b/crates/router/src/utils/user.rs
@@ -312,11 +312,7 @@ pub fn create_merchant_account_request_for_org(
     org: organization::Organization,
     product_type: common_enums::MerchantProductType,
 ) -> UserResult<api_models::admin::MerchantAccountCreate> {
-    let merchant_id = if matches!(env::which(), env::Env::Production) {
-        id_type::MerchantId::try_from(domain::MerchantId::new(req.merchant_name.clone().expose())?)?
-    } else {
-        id_type::MerchantId::new_from_unix_timestamp()
-    };
+    let merchant_id = generate_env_specific_merchant_id(req.merchant_name.clone().expose())?;
 
     let company_name = domain::UserCompanyName::new(req.merchant_name.expose())?;
     Ok(api_models::admin::MerchantAccountCreate {
@@ -409,3 +405,12 @@ pub async fn set_lineage_context_in_cache(
 
     Ok(())
 }
+
+pub fn generate_env_specific_merchant_id(value: String) -> UserResult<id_type::MerchantId> {
+    if matches!(env::which(), env::Env::Production) {
+        let raw_id = domain::MerchantId::new(value)?;
+        Ok(id_type::MerchantId::try_from(raw_id)?)
+    } else {
+        Ok(id_type::MerchantId::new_from_unix_timestamp())
+    }
+}
diff --git a/crates/router_env/src/logger/types.rs b/crates/router_env/src/logger/types.rs
index 6a4ad4bcabe..abc115dc288 100644
--- a/crates/router_env/src/logger/types.rs
+++ b/crates/router_env/src/logger/types.rs
@@ -407,6 +407,8 @@ pub enum Flow {
     UpdateUserRole,
     /// Create merchant account for user in a org
     UserMerchantAccountCreate,
+    /// Create Platform
+    CreatePlatformAccount,
     /// Create Org in a given tenancy
     UserOrgMerchantCreate,
     /// Generate Sample Data
diff --git a/migrations/2025-04-10-095823_add_platform_context_in_organization/down.sql b/migrations/2025-04-10-095823_add_platform_context_in_organization/down.sql
new file mode 100644
index 00000000000..65379a80226
--- /dev/null
+++ b/migrations/2025-04-10-095823_add_platform_context_in_organization/down.sql
@@ -0,0 +1,6 @@
+-- This file should undo anything in `up.sql`
+ALTER TABLE organization DROP COLUMN IF EXISTS organization_type;
+ALTER TABLE organization DROP COLUMN IF EXISTS platform_merchant_id;
+
+ALTER TABLE merchant_account DROP COLUMN IF EXISTS merchant_account_type;
+
diff --git a/migrations/2025-04-10-095823_add_platform_context_in_organization/up.sql b/migrations/2025-04-10-095823_add_platform_context_in_organization/up.sql
new file mode 100644
index 00000000000..cbcabee8e06
--- /dev/null
+++ b/migrations/2025-04-10-095823_add_platform_context_in_organization/up.sql
@@ -0,0 +1,5 @@
+-- Your SQL goes here
+ALTER TABLE organization ADD COLUMN IF NOT EXISTS organization_type VARCHAR(64);
+ALTER TABLE organization ADD COLUMN IF NOT EXISTS platform_merchant_id VARCHAR(64);
+
+ALTER TABLE merchant_account ADD COLUMN IF NOT EXISTS merchant_account_type VARCHAR(64);

## Type of Change
<!-- Put an `x` in the boxes that apply -->

- [ ] Bugfix
- [x] New feature
- [x] Enhancement
- [x] Refactoring
- [ ] Dependency updates
- [ ] Documentation
- [ ] CI/CD

## Description
The PR supports onboarding for new VSAAS merchants. 
- Creating Platform Org
- Creation of Platform, and connected merchant accounts
- Change List response of merchant and organization list.

### Additional Changes

- [ ] This PR modifies the API contract
- [x] This PR modifies the database schema
- [ ] This PR modifies application configuration/environment variables

<!--
Provide links to the files with corresponding changes.

Following are the paths where you can find config files:
1. `config`
2. `crates/router/src/configs`
3. `loadtest/config`
-->


## Motivation and Context
Closes #7889



## How did you test it?
Following Flow:
- Signup --> terminate 2FA --> List orgs/merchants --> create Merchant inside standard org --> List merchants/orgs to validate
- CreatePlatform --> Swtich to Platform Org --> List merchants/orgs to validate --> Create Merchant inside platform org

We can hit the following curls:
**Signup**
```
curl --location 'http://localhost:8080/user/signup?token_only=true' \
--header 'x-tenant-id: test' \
--header 'Content-Type: application/json' \
--header 'Cookie: login_token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoiNTY5ZmY1YWQtNjczMC00ZjRhLTg1MGEtYWY5MDU3OTgyMmYzIiwicHVycG9zZSI6InRvdHAiLCJvcmlnaW4iOiJzaWduX3VwIiwicGF0aCI6W10sImV4cCI6MTc0NTY1ODA0MywidGVuYW50X2lkIjoicHVibGljIn0.1lHD7fOM64ZtP0rRaBnp5-oaC6vy411jMu-lsjHAyr0' \
--data-raw '{
    "email": "test@juspay.in",
    "password": "Test@1234"
}'
```

Response: 
```
{"token":"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoiNTY5ZmY1YWQtNjczMC00ZjRhLTg1MGEtYWY5MDU3OTgyMmYzIiwicHVycG9zZSI6InRvdHAiLCJvcmlnaW4iOiJzaWduX3VwIiwicGF0aCI6W10sImV4cCI6MTc0NTY1ODA0MywidGVuYW50X2lkIjoicHVibGljIn0.1lHD7fOM64ZtP0rRaBnp5-oaC6vy411jMu-lsjHAyr0","token_type":"totp"}
```

**Terminate 2FA**
```
curl --location 'http://localhost:8080/user/2fa/terminate?skip_two_factor_auth=true' \
--header 'Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoiNTY5ZmY1YWQtNjczMC00ZjRhLTg1MGEtYWY5MDU3OTgyMmYzIiwicHVycG9zZSI6InRvdHAiLCJvcmlnaW4iOiJzaWduX3VwIiwicGF0aCI6W10sImV4cCI6MTc0NTY1ODA0MywidGVuYW50X2lkIjoicHVibGljIn0.1lHD7fOM64ZtP0rRaBnp5-oaC6vy411jMu-lsjHAyr0' \
--header 'Cookie: login_token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoiNTY5ZmY1YWQtNjczMC00ZjRhLTg1MGEtYWY5MDU3OTgyMmYzIiwibWVyY2hhbnRfaWQiOiJtZXJjaGFudF8xNzQ1NDg1MjQyIiwicm9sZV9pZCI6Im9yZ19hZG1pbiIsImV4cCI6MTc0NTY1ODA4MCwib3JnX2lkIjoib3JnXzFUYVFseFFoY3ZLQTZKVkZxSGVoIiwicHJvZmlsZV9pZCI6InByb19xbHhJbFRwZDkwVXZmNDJsVWRHZSIsInRlbmFudF9pZCI6InB1YmxpYyJ9.cJSWGsE__epEWkuLKph8rBHJSvosq_-dfu2bR4dKb1o'
```
Response
```
{"token":"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoiNTY5ZmY1YWQtNjczMC00ZjRhLTg1MGEtYWY5MDU3OTgyMmYzIiwibWVyY2hhbnRfaWQiOiJtZXJjaGFudF8xNzQ1NDg1MjQyIiwicm9sZV9pZCI6Im9yZ19hZG1pbiIsImV4cCI6MTc0NTY1ODA4MCwib3JnX2lkIjoib3JnXzFUYVFseFFoY3ZLQTZKVkZxSGVoIiwicHJvZmlsZV9pZCI6InByb19xbHhJbFRwZDkwVXZmNDJsVWRHZSIsInRlbmFudF9pZCI6InB1YmxpYyJ9.cJSWGsE__epEWkuLKph8rBHJSvosq_-dfu2bR4dKb1o","token_type":"user_info"}
```

**Create Merchant Account**
```
curl --location 'http://localhost:8080/user/create_merchant' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoiNTY5ZmY1YWQtNjczMC00ZjRhLTg1MGEtYWY5MDU3OTgyMmYzIiwibWVyY2hhbnRfaWQiOiJtZXJjaGFudF8xNzQ1NDg1MjQyIiwicm9sZV9pZCI6Im9yZ19hZG1pbiIsImV4cCI6MTc0NTY1ODA4MCwib3JnX2lkIjoib3JnXzFUYVFseFFoY3ZLQTZKVkZxSGVoIiwicHJvZmlsZV9pZCI6InByb19xbHhJbFRwZDkwVXZmNDJsVWRHZSIsInRlbmFudF9pZCI6InB1YmxpYyJ9.cJSWGsE__epEWkuLKph8rBHJSvosq_-dfu2bR4dKb1o' \
--header 'Cookie: login_token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoiNTY5ZmY1YWQtNjczMC00ZjRhLTg1MGEtYWY5MDU3OTgyMmYzIiwibWVyY2hhbnRfaWQiOiJtZXJjaGFudF8xNzQ1NDg1MjQyIiwicm9sZV9pZCI6Im9yZ19hZG1pbiIsImV4cCI6MTc0NTY1ODA4MCwib3JnX2lkIjoib3JnXzFUYVFseFFoY3ZLQTZKVkZxSGVoIiwicHJvZmlsZV9pZCI6InByb19xbHhJbFRwZDkwVXZmNDJsVWRHZSIsInRlbmFudF9pZCI6InB1YmxpYyJ9.cJSWGsE__epEWkuLKph8rBHJSvosq_-dfu2bR4dKb1o' \
--data '{
    "company_name": "in_standard"
}'
```
Response:
```
{"merchant_id":"merchant_1745485331","merchant_name":"in_standard","product_type":"orchestration","merchant_account_type":"standard","version":"v1"}
```

**List Orgs**
```
curl --location 'http://localhost:8080/user/list/org' \
--header 'Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoiZDM2NzMyMTUtYWU3NS00NGMzLWJiYzEtMGY3YmMxYmYwMjdmIiwibWVyY2hhbnRfaWQiOiJtZXJjaGFudF8xNzEyMjE0NDE5Iiwicm9sZV9pZCI6Im9yZ19hZG1pbiIsImV4cCI6MTcxMjM4NzMyOSwib3JnX2lkIjoib3JnXzhLb2lWNmhrcG9KSGZNcllER1ZhIn0.H2G9oGp_JBoz3k5S7fMvaaJ9T0cG5VtUjM0hU3ltM3g' \
--header 'Cookie: login_token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoiNTY5ZmY1YWQtNjczMC00ZjRhLTg1MGEtYWY5MDU3OTgyMmYzIiwibWVyY2hhbnRfaWQiOiJtZXJjaGFudF8xNzQ1NDg1MjQyIiwicm9sZV9pZCI6Im9yZ19hZG1pbiIsImV4cCI6MTc0NTY1ODA4MCwib3JnX2lkIjoib3JnXzFUYVFseFFoY3ZLQTZKVkZxSGVoIiwicHJvZmlsZV9pZCI6InByb19xbHhJbFRwZDkwVXZmNDJsVWRHZSIsInRlbmFudF9pZCI6InB1YmxpYyJ9.cJSWGsE__epEWkuLKph8rBHJSvosq_-dfu2bR4dKb1o'
```
Response:
```
[{"org_id":"org_1TaQlxQhcvKA6JVFqHeh","org_name":null,"org_type":"standard"}]
```

**List Merchant**
```
curl --location 'http://localhost:8080/user/list/merchant' \
--header 'Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoiZDM2NzMyMTUtYWU3NS00NGMzLWJiYzEtMGY3YmMxYmYwMjdmIiwibWVyY2hhbnRfaWQiOiJtZXJjaGFudF8xNzEyMjE0NDE5Iiwicm9sZV9pZCI6Im9yZ19hZG1pbiIsImV4cCI6MTcxMjM4NzMyOSwib3JnX2lkIjoib3JnXzhLb2lWNmhrcG9KSGZNcllER1ZhIn0.H2G9oGp_JBoz3k5S7fMvaaJ9T0cG5VtUjM0hU3ltM3g' \
--header 'Cookie: login_token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoiNTY5ZmY1YWQtNjczMC00ZjRhLTg1MGEtYWY5MDU3OTgyMmYzIiwibWVyY2hhbnRfaWQiOiJtZXJjaGFudF8xNzQ1NDg1MjQyIiwicm9sZV9pZCI6Im9yZ19hZG1pbiIsImV4cCI6MTc0NTY1ODA4MCwib3JnX2lkIjoib3JnXzFUYVFseFFoY3ZLQTZKVkZxSGVoIiwicHJvZmlsZV9pZCI6InByb19xbHhJbFRwZDkwVXZmNDJsVWRHZSIsInRlbmFudF9pZCI6InB1YmxpYyJ9.cJSWGsE__epEWkuLKph8rBHJSvosq_-dfu2bR4dKb1o'
```
Response:
```
[{"merchant_id":"merchant_1745485242","merchant_name":null,"product_type":"orchestration","merchant_account_type":"standard","version":"v1"},{"merchant_id":"merchant_1745485331","merchant_name":"in_standard","product_type":"orchestration","merchant_account_type":"standard","version":"v1"}]
```


**Create Platform Org**
```
curl --location 'http://localhost:8080/user/create_platform' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoiNTY5ZmY1YWQtNjczMC00ZjRhLTg1MGEtYWY5MDU3OTgyMmYzIiwibWVyY2hhbnRfaWQiOiJtZXJjaGFudF8xNzQ1NDg1MjQyIiwicm9sZV9pZCI6Im9yZ19hZG1pbiIsImV4cCI6MTc0NTY1ODA4MCwib3JnX2lkIjoib3JnXzFUYVFseFFoY3ZLQTZKVkZxSGVoIiwicHJvZmlsZV9pZCI6InByb19xbHhJbFRwZDkwVXZmNDJsVWRHZSIsInRlbmFudF9pZCI6InB1YmxpYyJ9.cJSWGsE__epEWkuLKph8rBHJSvosq_-dfu2bR4dKb1o' \
--header 'Cookie: login_token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoiNTY5ZmY1YWQtNjczMC00ZjRhLTg1MGEtYWY5MDU3OTgyMmYzIiwibWVyY2hhbnRfaWQiOiJtZXJjaGFudF8xNzQ1NDg1MjQyIiwicm9sZV9pZCI6Im9yZ19hZG1pbiIsImV4cCI6MTc0NTY1ODA4MCwib3JnX2lkIjoib3JnXzFUYVFseFFoY3ZLQTZKVkZxSGVoIiwicHJvZmlsZV9pZCI6InByb19xbHhJbFRwZDkwVXZmNDJsVWRHZSIsInRlbmFudF9pZCI6InB1YmxpYyJ9.cJSWGsE__epEWkuLKph8rBHJSvosq_-dfu2bR4dKb1o' \
--data '{
    "organization_name": "platform"
}'
```
Response: status 200 OK, witth reponse containing platform details
```
{"org_id":"org_TgxsZW9EOXksNcMSeaUy","org_name":"platform","org_type":"platform","merchant_id":"merchant_1745575171","merchant_account_type":"platform"}
```


Switch Org
```
curl --location 'http://localhost:8080/user/switch/org' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoiNTY5ZmY1YWQtNjczMC00ZjRhLTg1MGEtYWY5MDU3OTgyMmYzIiwibWVyY2hhbnRfaWQiOiJtZXJjaGFudF8xNzQ1NDg1MjQyIiwicm9sZV9pZCI6Im9yZ19hZG1pbiIsImV4cCI6MTc0NTY1ODA4MCwib3JnX2lkIjoib3JnXzFUYVFseFFoY3ZLQTZKVkZxSGVoIiwicHJvZmlsZV9pZCI6InByb19xbHhJbFRwZDkwVXZmNDJsVWRHZSIsInRlbmFudF9pZCI6InB1YmxpYyJ9.cJSWGsE__epEWkuLKph8rBHJSvosq_-dfu2bR4dKb1o' \
--header 'Cookie: login_token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoiNTY5ZmY1YWQtNjczMC00ZjRhLTg1MGEtYWY5MDU3OTgyMmYzIiwibWVyY2hhbnRfaWQiOiJtZXJjaGFudF8xNzQ1NDg1NDg3Iiwicm9sZV9pZCI6Im9yZ19hZG1pbiIsImV4cCI6MTc0NTY1ODM5OSwib3JnX2lkIjoib3JnXzBFZXE4cU9ETVJGc3NiNGJXa0p5IiwicHJvZmlsZV9pZCI6InByb19QOGc0R0dhbk81dDFiUXczNVQ3aiIsInRlbmFudF9pZCI6InB1YmxpYyJ9.UW9aqcLLXYi_3xOpLCB2vB2ecmMA7M4LHNXorPT0Odc' \
--data '{
    "org_id": "org_0Eeq8qODMRFssb4bWkJy"
}'
```

Resonse:
```
{"token":"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoiNTY5ZmY1YWQtNjczMC00ZjRhLTg1MGEtYWY5MDU3OTgyMmYzIiwibWVyY2hhbnRfaWQiOiJtZXJjaGFudF8xNzQ1NDg1NDg3Iiwicm9sZV9pZCI6Im9yZ19hZG1pbiIsImV4cCI6MTc0NTY1ODM5OSwib3JnX2lkIjoib3JnXzBFZXE4cU9ETVJGc3NiNGJXa0p5IiwicHJvZmlsZV9pZCI6InByb19QOGc0R0dhbk81dDFiUXczNVQ3aiIsInRlbmFudF9pZCI6InB1YmxpYyJ9.UW9aqcLLXYi_3xOpLCB2vB2ecmMA7M4LHNXorPT0Odc","token_type":"user_info"}
```


Create Merchant inside Platfrom
```
curl --location 'http://localhost:8080/user/create_merchant' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoiNTY5ZmY1YWQtNjczMC00ZjRhLTg1MGEtYWY5MDU3OTgyMmYzIiwibWVyY2hhbnRfaWQiOiJtZXJjaGFudF8xNzQ1NDg1MjQyIiwicm9sZV9pZCI6Im9yZ19hZG1pbiIsImV4cCI6MTc0NTY1ODA4MCwib3JnX2lkIjoib3JnXzFUYVFseFFoY3ZLQTZKVkZxSGVoIiwicHJvZmlsZV9pZCI6InByb19xbHhJbFRwZDkwVXZmNDJsVWRHZSIsInRlbmFudF9pZCI6InB1YmxpYyJ9.cJSWGsE__epEWkuLKph8rBHJSvosq_-dfu2bR4dKb1o' \
--header 'Cookie: login_token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoiNTY5ZmY1YWQtNjczMC00ZjRhLTg1MGEtYWY5MDU3OTgyMmYzIiwibWVyY2hhbnRfaWQiOiJtZXJjaGFudF8xNzQ1NDg1NDg3Iiwicm9sZV9pZCI6Im9yZ19hZG1pbiIsImV4cCI6MTc0NTY1ODM5OSwib3JnX2lkIjoib3JnXzBFZXE4cU9ETVJGc3NiNGJXa0p5IiwicHJvZmlsZV9pZCI6InByb19QOGc0R0dhbk81dDFiUXczNVQ3aiIsInRlbmFudF9pZCI6InB1YmxpYyJ9.UW9aqcLLXYi_3xOpLCB2vB2ecmMA7M4LHNXorPT0Odc' \
--data '{
    "company_name": "in_platform"
}'
```
Response:
```
{"merchant_id":"merchant_1745485645","merchant_name":"in_platform","product_type":"orchestration","merchant_account_type":"connected","version":"v1"}
```

List Org
Now the list orgs for user will give following response since there are two orgs
```
[{"org_id":"org_0Eeq8qODMRFssb4bWkJy","org_name":"platform","org_type":"platform"},{"org_id":"org_1TaQlxQhcvKA6JVFqHeh","org_name":null,"org_type":"standard"}]
```

List Merchant
Inside platform there will be following merchants
```
[{"merchant_id":"merchant_1745485487","merchant_name":null,"product_type":"orchestration","merchant_account_type":"platform","version":"v1"},{"merchant_id":"merchant_1745485645","merchant_name":"in_platform","product_type":"orchestration","merchant_account_type":"connected","version":"v1"}]
```


## Checklist
<!-- Put an `x` in the boxes that apply -->

- [x] I formatted the code `cargo +nightly fmt --all`
- [x] I addressed lints thrown by `cargo clippy`
- [x] I reviewed the submitted code
- [ ] I added unit tests for my changes where possible
