diff --git a/_migrations/2022-09-17-173657_user_subscriptions/up.sql b/_migrations/2022-09-17-173657_user_subscriptions/up.sql index 403fda7879..01d9d2d5b5 100644 --- a/_migrations/2022-09-17-173657_user_subscriptions/up.sql +++ b/_migrations/2022-09-17-173657_user_subscriptions/up.sql @@ -37,9 +37,11 @@ CREATE TABLE user_subscriptions ( -- This has a UNIQUE index. maybe_stripe_subscription_id VARCHAR(255) DEFAULT NULL, + maybe_stripe_customer_id VARCHAR(255) DEFAULT NULL, + maybe_stripe_product_id VARCHAR(255) DEFAULT NULL, - maybe_stripe_customer_id VARCHAR(255) DEFAULT NULL, + maybe_stripe_price_id VARCHAR(255) DEFAULT NULL, -- How frequently the subscription is billed and updated maybe_stripe_recurring_interval VARCHAR(32) DEFAULT NULL, @@ -90,6 +92,8 @@ CREATE TABLE user_subscriptions ( UNIQUE KEY (maybe_stripe_subscription_id), KEY index_subscription_category (subscription_category), KEY index_subscription_product_key (subscription_product_key), + KEY index_maybe_stripe_customer_id (maybe_stripe_customer_id), + KEY index_maybe_stripe_product_id (maybe_stripe_product_id), KEY index_maybe_stripe_subscription_status (maybe_stripe_subscription_status), KEY fk_maybe_user_token (maybe_user_token), KEY index_subscription_expires_at (subscription_expires_at) diff --git a/crates/component_subsystem/billing/src/stripe/webhook_event_handlers/customer_subscription/customer_subscription_created_handler.rs b/crates/component_subsystem/billing/src/stripe/webhook_event_handlers/customer_subscription/customer_subscription_created_handler.rs index bdd4355bc5..6ffbda5959 100644 --- a/crates/component_subsystem/billing/src/stripe/webhook_event_handlers/customer_subscription/customer_subscription_created_handler.rs +++ b/crates/component_subsystem/billing/src/stripe/webhook_event_handlers/customer_subscription/customer_subscription_created_handler.rs @@ -52,8 +52,9 @@ pub async fn customer_subscription_created_handler( maybe_user_token: summary.user_token.as_deref(), subscription_category: "todo", subscription_product_key: "todo", - maybe_stripe_product_id: Some(&summary.stripe_product_id), maybe_stripe_customer_id: Some(&summary.stripe_customer_id), + maybe_stripe_product_id: Some(&summary.stripe_product_id), + maybe_stripe_price_id: Some(&summary.stripe_price_id), maybe_stripe_recurring_interval: Some(summary.subscription_interval), maybe_stripe_subscription_status: Some(summary.stripe_subscription_status), maybe_stripe_is_production: Some(summary.stripe_is_production), diff --git a/crates/component_subsystem/billing/src/stripe/webhook_event_handlers/customer_subscription/customer_subscription_deleted_handler.rs b/crates/component_subsystem/billing/src/stripe/webhook_event_handlers/customer_subscription/customer_subscription_deleted_handler.rs index bc520a22d0..79fecb2010 100644 --- a/crates/component_subsystem/billing/src/stripe/webhook_event_handlers/customer_subscription/customer_subscription_deleted_handler.rs +++ b/crates/component_subsystem/billing/src/stripe/webhook_event_handlers/customer_subscription/customer_subscription_deleted_handler.rs @@ -53,8 +53,9 @@ pub async fn customer_subscription_deleted_handler( maybe_user_token: summary.user_token.as_deref(), subscription_category: "todo", subscription_product_key: "todo", - maybe_stripe_product_id: Some(&summary.stripe_product_id), maybe_stripe_customer_id: Some(&summary.stripe_customer_id), + maybe_stripe_product_id: Some(&summary.stripe_product_id), + maybe_stripe_price_id: Some(&summary.stripe_price_id), maybe_stripe_recurring_interval: Some(summary.subscription_interval), maybe_stripe_subscription_status: Some(summary.stripe_subscription_status), maybe_stripe_is_production: Some(summary.stripe_is_production), diff --git a/crates/component_subsystem/billing/src/stripe/webhook_event_handlers/customer_subscription/customer_subscription_updated_handler.rs b/crates/component_subsystem/billing/src/stripe/webhook_event_handlers/customer_subscription/customer_subscription_updated_handler.rs index 36e21ad69c..17a4dba38f 100644 --- a/crates/component_subsystem/billing/src/stripe/webhook_event_handlers/customer_subscription/customer_subscription_updated_handler.rs +++ b/crates/component_subsystem/billing/src/stripe/webhook_event_handlers/customer_subscription/customer_subscription_updated_handler.rs @@ -51,8 +51,9 @@ pub async fn customer_subscription_updated_handler( maybe_user_token: summary.user_token.as_deref(), subscription_category: "todo", subscription_product_key: "todo", - maybe_stripe_product_id: Some(&summary.stripe_product_id), maybe_stripe_customer_id: Some(&summary.stripe_customer_id), + maybe_stripe_product_id: Some(&summary.stripe_product_id), + maybe_stripe_price_id: Some(&summary.stripe_price_id), maybe_stripe_recurring_interval: Some(summary.subscription_interval), maybe_stripe_subscription_status: Some(summary.stripe_subscription_status), maybe_stripe_is_production: Some(summary.stripe_is_production), diff --git a/crates/lib/database_queries/src/queries/billing/subscriptions/upsert_subscription_by_stripe_id.rs b/crates/lib/database_queries/src/queries/billing/subscriptions/upsert_subscription_by_stripe_id.rs index 3d4469c9d4..263e5191b9 100644 --- a/crates/lib/database_queries/src/queries/billing/subscriptions/upsert_subscription_by_stripe_id.rs +++ b/crates/lib/database_queries/src/queries/billing/subscriptions/upsert_subscription_by_stripe_id.rs @@ -22,8 +22,11 @@ pub struct UpsertSubscriptionByStripeId <'a> { /// The name of the product the user is subscribing to within the category. pub subscription_product_key: &'a str, - pub maybe_stripe_product_id: Option<&'a str>, pub maybe_stripe_customer_id: Option<&'a str>, + + pub maybe_stripe_product_id: Option<&'a str>, + pub maybe_stripe_price_id: Option<&'a str>, + pub maybe_stripe_recurring_interval : Option, pub maybe_stripe_subscription_status: Option, pub maybe_stripe_is_production: Option, @@ -52,10 +55,13 @@ impl <'a> UpsertSubscriptionByStripeId <'a> { let token = Tokens::new_subscription_token()?; // NB: The following behaviors are intentional - // - We only set the token initially; changing it obviously breaks. - // - Other "static" fields do not need to change on update, either. + // - We only set the "token" initially. + // - Likewise, the stripe_subscription_id will remain constant. // - The user token is updated to the new value so long as we don't // attempt to set it to null or empty. + // - The various subscription dates, expiry, and statuses can change. + // - The product and price can change (eg. upgrades, downgrades). + // - Other "static" fields do not need to change on update, either. let query = sqlx::query!( r#" INSERT INTO user_subscriptions @@ -66,9 +72,11 @@ SET subscription_product_key = ?, maybe_stripe_subscription_id = ?, + maybe_stripe_customer_id = ?, maybe_stripe_product_id = ?, - maybe_stripe_customer_id = ?, + maybe_stripe_price_id = ?, + maybe_stripe_recurring_interval = ?, maybe_stripe_subscription_status = ?, maybe_stripe_is_production = ?, @@ -84,6 +92,10 @@ SET ON DUPLICATE KEY UPDATE maybe_user_token = COALESCE(NULLIF(?, ''), maybe_user_token), + + maybe_stripe_product_id = ?, + maybe_stripe_price_id = ?, + maybe_stripe_recurring_interval = ?, maybe_stripe_subscription_status = ?, @@ -102,9 +114,11 @@ ON DUPLICATE KEY UPDATE self.subscription_product_key, self.stripe_subscription_id, + self.maybe_stripe_customer_id, self.maybe_stripe_product_id, - self.maybe_stripe_customer_id, + self.maybe_stripe_price_id, + self.maybe_stripe_recurring_interval.as_deref(), self.maybe_stripe_subscription_status.as_deref(), self.maybe_stripe_is_production, @@ -118,6 +132,10 @@ ON DUPLICATE KEY UPDATE // Upsert self.maybe_user_token, + + self.maybe_stripe_product_id, + self.maybe_stripe_price_id, + self.maybe_stripe_recurring_interval.as_deref(), self.maybe_stripe_subscription_status.as_deref(),