collab: Upgrade from Zed Pro trial to Zed Pro by ending trial period early (#29052)

Marshall Bowers created

This PR adjusts the upgrade from a Zed Pro trial to Zed Pro to do so by
ending the trial period early.

This will transition the subscription to `active` and bill the user
without needing to send them through a Stripe Checkout flow.

Release Notes:

- N/A

Change summary

crates/collab/src/api/billing.rs | 28 ++++++++++++++++++++++++----
1 file changed, 24 insertions(+), 4 deletions(-)

Detailed changes

crates/collab/src/api/billing.rs 🔗

@@ -449,6 +449,29 @@ async fn manage_billing_subscription(
             let stripe_subscription =
                 Subscription::retrieve(&stripe_client, &subscription_id, &[]).await?;
 
+            let is_on_zed_pro_trial = stripe_subscription.status == SubscriptionStatus::Trialing
+                && stripe_subscription.items.data.iter().any(|item| {
+                    item.price
+                        .as_ref()
+                        .map_or(false, |price| price.id == zed_pro_price_id)
+                });
+            if is_on_zed_pro_trial {
+                // If the user is already on a Zed Pro trial and wants to upgrade to Pro, we just need to end their trial early.
+                Subscription::update(
+                    &stripe_client,
+                    &stripe_subscription.id,
+                    stripe::UpdateSubscription {
+                        trial_end: Some(stripe::Scheduled::now()),
+                        ..Default::default()
+                    },
+                )
+                .await?;
+
+                return Ok(Json(ManageBillingSubscriptionResponse {
+                    billing_portal_session_url: None,
+                }));
+            }
+
             let subscription_item_to_update = stripe_subscription
                 .items
                 .data
@@ -456,10 +479,7 @@ async fn manage_billing_subscription(
                 .find_map(|item| {
                     let price = item.price.as_ref()?;
 
-                    if price.id == zed_free_price_id
-                        || (price.id == zed_pro_price_id
-                            && stripe_subscription.status == SubscriptionStatus::Trialing)
-                    {
+                    if price.id == zed_free_price_id {
                         Some(item.id.clone())
                     } else {
                         None