From 7dd340f0b6adf0b7b601c602a0b0dce05ec9f4ed Mon Sep 17 00:00:00 2001 From: Geometrically <18202329+Geometrically@users.noreply.github.com> Date: Thu, 15 Aug 2024 02:03:46 -0700 Subject: [PATCH] Fix subscriptions edge case (#952) * Fix subscriptions edge case * prep --- ...9174f196a50cd74c9243ddd57d6f4f3d0b062.json} | 4 ++-- src/database/models/user_subscription_item.rs | 3 ++- src/routes/internal/billing.rs | 18 ++++++++++++++++++ 3 files changed, 22 insertions(+), 3 deletions(-) rename .sqlx/{query-0e7a1aaa7999dcae156e1b1194232a12742a24740e48dd0d99582a79da873383.json => query-e82ba8bafb4e45b8a8a100c639a9174f196a50cd74c9243ddd57d6f4f3d0b062.json} (78%) diff --git a/.sqlx/query-0e7a1aaa7999dcae156e1b1194232a12742a24740e48dd0d99582a79da873383.json b/.sqlx/query-e82ba8bafb4e45b8a8a100c639a9174f196a50cd74c9243ddd57d6f4f3d0b062.json similarity index 78% rename from .sqlx/query-0e7a1aaa7999dcae156e1b1194232a12742a24740e48dd0d99582a79da873383.json rename to .sqlx/query-e82ba8bafb4e45b8a8a100c639a9174f196a50cd74c9243ddd57d6f4f3d0b062.json index 32c0cdcb..6546eb3d 100644 --- a/.sqlx/query-0e7a1aaa7999dcae156e1b1194232a12742a24740e48dd0d99582a79da873383.json +++ b/.sqlx/query-e82ba8bafb4e45b8a8a100c639a9174f196a50cd74c9243ddd57d6f4f3d0b062.json @@ -1,6 +1,6 @@ { "db_name": "PostgreSQL", - "query": "\n INSERT INTO users_subscriptions (\n id, user_id, price_id, interval, created, expires, last_charge, status\n )\n VALUES (\n $1, $2, $3, $4, $5, $6, $7, $8\n )\n ON CONFLICT (id)\n DO UPDATE\n SET interval = EXCLUDED.interval,\n expires = EXCLUDED.expires,\n last_charge = EXCLUDED.last_charge,\n status = EXCLUDED.status\n ", + "query": "\n INSERT INTO users_subscriptions (\n id, user_id, price_id, interval, created, expires, last_charge, status\n )\n VALUES (\n $1, $2, $3, $4, $5, $6, $7, $8\n )\n ON CONFLICT (id)\n DO UPDATE\n SET interval = EXCLUDED.interval,\n expires = EXCLUDED.expires,\n last_charge = EXCLUDED.last_charge,\n status = EXCLUDED.status,\n price_id = EXCLUDED.price_id\n ", "describe": { "columns": [], "parameters": { @@ -17,5 +17,5 @@ }, "nullable": [] }, - "hash": "0e7a1aaa7999dcae156e1b1194232a12742a24740e48dd0d99582a79da873383" + "hash": "e82ba8bafb4e45b8a8a100c639a9174f196a50cd74c9243ddd57d6f4f3d0b062" } diff --git a/src/database/models/user_subscription_item.rs b/src/database/models/user_subscription_item.rs index 5b638b68..b13d319f 100644 --- a/src/database/models/user_subscription_item.rs +++ b/src/database/models/user_subscription_item.rs @@ -117,7 +117,8 @@ impl UserSubscriptionItem { SET interval = EXCLUDED.interval, expires = EXCLUDED.expires, last_charge = EXCLUDED.last_charge, - status = EXCLUDED.status + status = EXCLUDED.status, + price_id = EXCLUDED.price_id ", self.id.0, self.user_id.0, diff --git a/src/routes/internal/billing.rs b/src/routes/internal/billing.rs index 76a218c2..cdb8533f 100644 --- a/src/routes/internal/billing.rs +++ b/src/routes/internal/billing.rs @@ -670,6 +670,20 @@ pub async fn initiate_payment( ..Default::default() }; + let mut metadata = HashMap::new(); + metadata.insert("modrinth_user_id".to_string(), to_base62(user.id.0)); + metadata.insert( + "modrinth_price_id".to_string(), + to_base62(price_item.id.0 as u64), + ); + if let Some(interval) = payment_request.interval { + metadata.insert( + "modrinth_subscription_interval".to_string(), + interval.as_str().to_string(), + ); + } + update_payment_intent.metadata = Some(metadata); + if let PaymentRequestType::PaymentMethod { .. } = payment_request.type_ { update_payment_intent.payment_method = Some(payment_method.id.clone()); } @@ -897,6 +911,7 @@ pub async fn stripe_webhook( user_subscription.expires += duration; user_subscription.status = SubscriptionStatus::Active; user_subscription.interval = interval; + user_subscription.price_id = metadata.product_price.id; user_subscription.upsert(&mut transaction).await?; } else { user_subscription_item::UserSubscriptionItem { @@ -952,6 +967,7 @@ pub async fn stripe_webhook( if let Some(mut user_subscription) = metadata.user_subscription { user_subscription.status = SubscriptionStatus::PaymentProcessing; user_subscription.interval = interval; + user_subscription.price_id = metadata.product_price.id; user_subscription.upsert(&mut transaction).await?; } else { user_subscription_item::UserSubscriptionItem { @@ -988,6 +1004,8 @@ pub async fn stripe_webhook( if let Some(mut user_subscription) = metadata.user_subscription { user_subscription.last_charge = Some(Utc::now()); user_subscription.status = SubscriptionStatus::PaymentFailed; + user_subscription.price_id = metadata.product_price.id; + user_subscription.interval = interval; user_subscription.upsert(&mut transaction).await?; } else { user_subscription_item::UserSubscriptionItem {