collab: Don't use a separate product for Zed Pro trials (#28986)

This PR removes the separate product used for the Zed Pro trials, in
favor of using Stripe's trial functionality.

Release Notes:

- N/A
This commit is contained in:
Marshall Bowers 2025-04-17 13:44:14 -04:00 committed by GitHub
parent e4f692ac75
commit fade49a11a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 37 additions and 15 deletions

View file

@ -321,8 +321,8 @@ async fn create_billing_subscription(
}
Some(ProductCode::ZedProTrial) => {
stripe_billing
.checkout_with_price(
app.config.zed_pro_trial_price_id()?,
.checkout_with_zed_pro_trial(
app.config.zed_pro_price_id()?,
customer_id,
&user.github_login,
&success_url,
@ -444,7 +444,6 @@ async fn manage_billing_subscription(
ManageSubscriptionIntent::ManageSubscription => None,
ManageSubscriptionIntent::UpgradeToPro => {
let zed_pro_price_id = app.config.zed_pro_price_id()?;
let zed_pro_trial_price_id = app.config.zed_pro_trial_price_id()?;
let zed_free_price_id = app.config.zed_free_price_id()?;
let stripe_subscription =
@ -457,7 +456,10 @@ 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_trial_price_id {
if price.id == zed_free_price_id
|| (price.id == zed_pro_price_id
&& stripe_subscription.status == SubscriptionStatus::Trialing)
{
Some(item.id.clone())
} else {
None
@ -771,16 +773,17 @@ async fn handle_customer_subscription_event(
let subscription_kind = maybe!({
let zed_pro_price_id = app.config.zed_pro_price_id().ok()?;
let zed_pro_trial_price_id = app.config.zed_pro_trial_price_id().ok()?;
let zed_free_price_id = app.config.zed_free_price_id().ok()?;
subscription.items.data.iter().find_map(|item| {
let price = item.price.as_ref()?;
if price.id == zed_pro_price_id {
Some(SubscriptionKind::ZedPro)
} else if price.id == zed_pro_trial_price_id {
Some(SubscriptionKind::ZedProTrial)
Some(if subscription.status == SubscriptionStatus::Trialing {
SubscriptionKind::ZedProTrial
} else {
SubscriptionKind::ZedPro
})
} else if price.id == zed_free_price_id {
Some(SubscriptionKind::ZedFree)
} else {

View file

@ -207,13 +207,6 @@ impl Config {
Self::parse_stripe_price_id("Zed Pro", self.stripe_zed_pro_price_id.as_deref())
}
pub fn zed_pro_trial_price_id(&self) -> anyhow::Result<stripe::PriceId> {
Self::parse_stripe_price_id(
"Zed Pro Trial",
self.stripe_zed_pro_trial_price_id.as_deref(),
)
}
pub fn zed_free_price_id(&self) -> anyhow::Result<stripe::PriceId> {
Self::parse_stripe_price_id("Zed Free", self.stripe_zed_pro_price_id.as_deref())
}

View file

@ -405,6 +405,32 @@ impl StripeBilling {
let session = stripe::CheckoutSession::create(&self.client, params).await?;
Ok(session.url.context("no checkout session URL")?)
}
pub async fn checkout_with_zed_pro_trial(
&self,
zed_pro_price_id: PriceId,
customer_id: stripe::CustomerId,
github_login: &str,
success_url: &str,
) -> Result<String> {
let mut params = stripe::CreateCheckoutSession::new();
params.subscription_data = Some(stripe::CreateCheckoutSessionSubscriptionData {
trial_period_days: Some(14),
..Default::default()
});
params.mode = Some(stripe::CheckoutSessionMode::Subscription);
params.customer = Some(customer_id);
params.client_reference_id = Some(github_login);
params.line_items = Some(vec![stripe::CreateCheckoutSessionLineItems {
price: Some(zed_pro_price_id.to_string()),
quantity: Some(1),
..Default::default()
}]);
params.success_url = Some(success_url);
let session = stripe::CheckoutSession::create(&self.client, params).await?;
Ok(session.url.context("no checkout session URL")?)
}
}
#[derive(Serialize)]