collab: Allow starting a trial from Zed Free (#30970)
This PR makes it so a user can initiate a checkout session for a Zed Pro trial while on the Zed Free plan. Release Notes: - N/A Co-authored-by: Max Brunsfeld <maxbrunsfeld@gmail.com>
This commit is contained in:
parent
5c4f9e57d8
commit
b440e1a467
2 changed files with 56 additions and 29 deletions
|
@ -280,7 +280,7 @@ async fn list_billing_subscriptions(
|
|||
}))
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, Deserialize)]
|
||||
#[derive(Debug, PartialEq, Clone, Copy, Deserialize)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
enum ProductCode {
|
||||
ZedPro,
|
||||
|
@ -325,12 +325,17 @@ async fn create_billing_subscription(
|
|||
))?
|
||||
};
|
||||
|
||||
if app.db.has_active_billing_subscription(user.id).await? {
|
||||
if let Some(existing_subscription) = app.db.get_active_billing_subscription(user.id).await? {
|
||||
let is_checkout_allowed = body.product == ProductCode::ZedProTrial
|
||||
&& existing_subscription.kind == Some(SubscriptionKind::ZedFree);
|
||||
|
||||
if !is_checkout_allowed {
|
||||
return Err(Error::http(
|
||||
StatusCode::CONFLICT,
|
||||
"user already has an active subscription".into(),
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
let existing_billing_customer = app.db.get_billing_customer_by_user_id(user.id).await?;
|
||||
if let Some(existing_billing_customer) = &existing_billing_customer {
|
||||
|
@ -1135,6 +1140,29 @@ async fn sync_subscription(
|
|||
},
|
||||
)
|
||||
.await?;
|
||||
} else {
|
||||
if let Some(existing_subscription) = app
|
||||
.db
|
||||
.get_active_billing_subscription(billing_customer.user_id)
|
||||
.await?
|
||||
{
|
||||
if existing_subscription.kind == Some(SubscriptionKind::ZedFree)
|
||||
&& subscription_kind == Some(SubscriptionKind::ZedProTrial)
|
||||
{
|
||||
let stripe_subscription_id = existing_subscription
|
||||
.stripe_subscription_id
|
||||
.parse::<stripe::SubscriptionId>()
|
||||
.context("failed to parse Stripe subscription ID from database")?;
|
||||
|
||||
Subscription::cancel(
|
||||
&stripe_client,
|
||||
&stripe_subscription_id,
|
||||
stripe::CancelSubscription {
|
||||
invoice_now: None,
|
||||
..Default::default()
|
||||
},
|
||||
)
|
||||
.await?;
|
||||
} else {
|
||||
// If the user already has an active billing subscription, ignore the
|
||||
// event and return an `Ok` to signal that it was processed
|
||||
|
@ -1150,11 +1178,7 @@ async fn sync_subscription(
|
|||
// 5. User ends up with no subscriptions
|
||||
//
|
||||
// In theory this situation shouldn't arise as we try to process the events in the order they occur.
|
||||
if app
|
||||
.db
|
||||
.has_active_billing_subscription(billing_customer.user_id)
|
||||
.await?
|
||||
{
|
||||
|
||||
log::info!(
|
||||
"user {user_id} already has an active subscription, skipping creation of subscription {subscription_id}",
|
||||
user_id = billing_customer.user_id,
|
||||
|
@ -1162,6 +1186,7 @@ async fn sync_subscription(
|
|||
);
|
||||
return Ok(billing_customer);
|
||||
}
|
||||
}
|
||||
|
||||
app.db
|
||||
.create_billing_subscription(&CreateBillingSubscriptionParams {
|
||||
|
|
|
@ -236,7 +236,9 @@ impl Database {
|
|||
.filter(
|
||||
billing_customer::Column::UserId.eq(user_id).and(
|
||||
billing_subscription::Column::StripeSubscriptionStatus
|
||||
.eq(StripeSubscriptionStatus::Active),
|
||||
.eq(StripeSubscriptionStatus::Active)
|
||||
.or(billing_subscription::Column::StripeSubscriptionStatus
|
||||
.eq(StripeSubscriptionStatus::Trialing)),
|
||||
),
|
||||
)
|
||||
.count(&*tx)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue