collab: Don't use a separate product for Zed Pro trials (#28986)
Marshall Bowers
created
This PR removes the separate product used for the Zed Pro trials, in
favor of using Stripe's trial functionality.
Release Notes:
- N/A
Change summary
crates/collab/src/api/billing.rs | 19 +++++++++++--------
crates/collab/src/lib.rs | 7 -------
crates/collab/src/stripe_billing.rs | 26 ++++++++++++++++++++++++++
3 files changed, 37 insertions(+), 15 deletions(-)
Detailed changes
@@ -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 {
@@ -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())
}
@@ -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)]