diff --git a/crates/schema/public/enums/src/by_table/users/user_signup_source.rs b/crates/schema/public/enums/src/by_table/users/user_signup_source.rs index 4e98f8cdc1..ee967f0b23 100644 --- a/crates/schema/public/enums/src/by_table/users/user_signup_source.rs +++ b/crates/schema/public/enums/src/by_table/users/user_signup_source.rs @@ -13,9 +13,30 @@ use utoipa::ToSchema; #[derive(Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Deserialize, Serialize, ToSchema)] #[serde(rename_all = "snake_case")] pub enum UserSignupSource { + #[deprecated(since = "2026-01-30", note = "Use other Artcraft* enum variants instead")] #[serde(rename = "artcraft")] ArtCraft, + /// ArtCraft Tauri App Onboard Flow + #[serde(rename = "artcraft_app")] + ArtCraftApp, + + /// artcraft.ai normal onboard flow + #[serde(rename = "artcraft_ai_web")] + ArtCraftAiWeb, + + /// artcraft.ai stripe checkout flow + #[serde(rename = "artcraft_ai_s")] + ArtCraftAiStripe, + + /// getartcraft.com normal onboard flow + #[serde(rename = "artcraft_get_web")] + ArtCraftGetWeb, + + /// getartcraft.com stripe checkout flow + #[serde(rename = "artcraft_get_s")] + ArtCraftGetStripe, + #[serde(rename = "fakeyou")] FakeYou, @@ -33,6 +54,11 @@ impl UserSignupSource { pub fn to_str(&self) -> &'static str { match self { Self::ArtCraft => "artcraft", + Self::ArtCraftApp => "artcraft_app", + Self::ArtCraftAiWeb => "artcraft_ai_web", + Self::ArtCraftAiStripe => "artcraft_ai_s", + Self::ArtCraftGetWeb => "artcraft_get_web", + Self::ArtCraftGetStripe => "artcraft_get_s", Self::FakeYou => "fakeyou", Self::Storyteller => "storyteller", } @@ -41,6 +67,11 @@ impl UserSignupSource { pub fn from_str(value: &str) -> Result { match value { "artcraft" => Ok(Self::ArtCraft), + "artcraft_app" => Ok(Self::ArtCraftApp), + "artcraft_ai_web" => Ok(Self::ArtCraftAiWeb), + "artcraft_ai_s" => Ok(Self::ArtCraftAiStripe), + "artcraft_get_web" => Ok(Self::ArtCraftGetWeb), + "artcraft_get_s" => Ok(Self::ArtCraftGetStripe), "fakeyou" => Ok(Self::FakeYou), "storyteller" => Ok(Self::Storyteller), _ => Err(format!("invalid value: {:?}", value)), @@ -52,6 +83,11 @@ impl UserSignupSource { // NB: BTreeSet::from() isn't const, but not worth using LazyStatic, etc. BTreeSet::from([ Self::ArtCraft, + Self::ArtCraftApp, + Self::ArtCraftAiWeb, + Self::ArtCraftAiStripe, + Self::ArtCraftGetWeb, + Self::ArtCraftGetStripe, Self::FakeYou, Self::Storyteller, ]) @@ -69,6 +105,11 @@ mod tests { #[test] fn test_serialization() { assert_serialization(UserSignupSource::ArtCraft, "artcraft"); + assert_serialization(UserSignupSource::ArtCraftApp, "artcraft_app"); + assert_serialization(UserSignupSource::ArtCraftAiWeb, "artcraft_ai_web"); + assert_serialization(UserSignupSource::ArtCraftAiStripe, "artcraft_ai_s"); + assert_serialization(UserSignupSource::ArtCraftGetWeb, "artcraft_get_web"); + assert_serialization(UserSignupSource::ArtCraftGetStripe, "artcraft_get_s"); assert_serialization(UserSignupSource::FakeYou, "fakeyou"); assert_serialization(UserSignupSource::Storyteller, "storyteller"); } @@ -80,6 +121,10 @@ mod tests { #[test] fn to_str() { assert_eq!(UserSignupSource::ArtCraft.to_str(), "artcraft"); + assert_eq!(UserSignupSource::ArtCraftApp.to_str(), "artcraft_app"); + assert_eq!(UserSignupSource::ArtCraftAiWeb.to_str(), "artcraft_ai_web"); + assert_eq!(UserSignupSource::ArtCraftAiStripe.to_str(), "artcraft_ai_s"); + assert_eq!(UserSignupSource::ArtCraftGetWeb.to_str(), "artcraft_get_web"); assert_eq!(UserSignupSource::FakeYou.to_str(), "fakeyou"); assert_eq!(UserSignupSource::Storyteller.to_str(), "storyteller"); } @@ -87,6 +132,11 @@ mod tests { #[test] fn from_str() { assert_eq!(UserSignupSource::from_str("artcraft").unwrap(), UserSignupSource::ArtCraft); + assert_eq!(UserSignupSource::from_str("artcraft_app").unwrap(), UserSignupSource::ArtCraftApp); + assert_eq!(UserSignupSource::from_str("artcraft_ai_web").unwrap(), UserSignupSource::ArtCraftAiWeb); + assert_eq!(UserSignupSource::from_str("artcraft_ai_s").unwrap(), UserSignupSource::ArtCraftAiStripe); + assert_eq!(UserSignupSource::from_str("artcraft_get_web").unwrap(), UserSignupSource::ArtCraftGetWeb); + assert_eq!(UserSignupSource::from_str("artcraft_get_s").unwrap(), UserSignupSource::ArtCraftGetStripe); assert_eq!(UserSignupSource::from_str("fakeyou").unwrap(), UserSignupSource::FakeYou); assert_eq!(UserSignupSource::from_str("storyteller").unwrap(), UserSignupSource::Storyteller); assert!(UserSignupSource::from_str("foo").is_err()); @@ -99,8 +149,13 @@ mod tests { #[test] fn all_variants() { let mut variants = UserSignupSource::all_variants(); - assert_eq!(variants.len(), 3); + assert_eq!(variants.len(), 8); assert_eq!(variants.pop_first(), Some(UserSignupSource::ArtCraft)); + assert_eq!(variants.pop_first(), Some(UserSignupSource::ArtCraftApp)); + assert_eq!(variants.pop_first(), Some(UserSignupSource::ArtCraftAiWeb)); + assert_eq!(variants.pop_first(), Some(UserSignupSource::ArtCraftAiStripe)); + assert_eq!(variants.pop_first(), Some(UserSignupSource::ArtCraftGetWeb)); + assert_eq!(variants.pop_first(), Some(UserSignupSource::ArtCraftGetStripe)); assert_eq!(variants.pop_first(), Some(UserSignupSource::FakeYou)); assert_eq!(variants.pop_first(), Some(UserSignupSource::Storyteller)); assert_eq!(variants.pop_first(), None); diff --git a/crates/service/plugins/billing_artcraft/src/endpoints/checkout_with_user_signup/stripe_artcraft_create_subscription_checkout_with_user_signup_handler.rs b/crates/service/plugins/billing_artcraft/src/endpoints/checkout_with_user_signup/stripe_artcraft_create_subscription_checkout_with_user_signup_handler.rs index cbbe74bcab..6c5438a789 100644 --- a/crates/service/plugins/billing_artcraft/src/endpoints/checkout_with_user_signup/stripe_artcraft_create_subscription_checkout_with_user_signup_handler.rs +++ b/crates/service/plugins/billing_artcraft/src/endpoints/checkout_with_user_signup/stripe_artcraft_create_subscription_checkout_with_user_signup_handler.rs @@ -25,7 +25,7 @@ use std::sync::Arc; use stripe_checkout::checkout_session::{CreateCheckoutSession, CreateCheckoutSessionAutomaticTax, CreateCheckoutSessionLineItems, CreateCheckoutSessionSavedPaymentMethodOptions, CreateCheckoutSessionSavedPaymentMethodOptionsAllowRedisplayFilters, CreateCheckoutSessionSavedPaymentMethodOptionsPaymentMethodSave, CreateCheckoutSessionSubscriptionData}; use stripe_checkout::CheckoutSessionMode; use stripe_core::CustomerId; -use stripe_shared::CheckoutSession; +use stripe_shared::{CheckoutSession, PriceId}; use user_traits_component::traits::internal_session_cache_purge::InternalSessionCachePurge; // /// Create a new user account and Stripe Checkout session and return the redirect URL in Json. @@ -79,6 +79,12 @@ pub async fn stripe_artcraft_create_checkout_with_user_signup_handler( PlanBillingCadence::Yearly => plan.yearly_price_id.clone(), }; + let price_id = PriceId::from_str(&price_id) + .map_err(|err| { + error!("Error parsing price id: {:?}", err); + CommonWebError::ServerError + })?; + let maybe_user_metadata = internal_user_lookup .lookup_user_from_http_request_and_mysql_connection(&http_request, &mut mysql_connection) .await