collab: Anchor new subscription's billing cycle to the first of the month (#19367)

Marshall Bowers , Antonio , and Richard created

This PR makes it so new subscriptions will have their billing cycle
anchored to the first of the month.

When someone signs up today, they will be billed starting on the first
of next month.

Release Notes:

- N/A

Co-authored-by: Antonio <antontio@zed.dev>
Co-authored-by: Richard <richard@zed.dev>

Change summary

crates/collab/src/stripe_billing.rs | 12 +++++++++++-
1 file changed, 11 insertions(+), 1 deletion(-)

Detailed changes

crates/collab/src/stripe_billing.rs 🔗

@@ -2,7 +2,7 @@ use std::sync::Arc;
 
 use crate::{llm, Cents, Result};
 use anyhow::Context;
-use chrono::Utc;
+use chrono::{Datelike, Utc};
 use collections::HashMap;
 use serde::{Deserialize, Serialize};
 use tokio::sync::RwLock;
@@ -349,10 +349,20 @@ impl StripeBilling {
         model: &StripeModel,
         success_url: &str,
     ) -> Result<String> {
+        let first_of_next_month = Utc::now()
+            .checked_add_months(chrono::Months::new(1))
+            .unwrap()
+            .with_day(1)
+            .unwrap();
+
         let mut params = stripe::CreateCheckoutSession::new();
         params.mode = Some(stripe::CheckoutSessionMode::Subscription);
         params.customer = Some(customer_id);
         params.client_reference_id = Some(github_login);
+        params.subscription_data = Some(stripe::CreateCheckoutSessionSubscriptionData {
+            billing_cycle_anchor: Some(first_of_next_month.timestamp()),
+            ..Default::default()
+        });
         params.line_items = Some(
             [
                 &model.input_tokens_price.id,