begin handling deleted subscriptions

This commit is contained in:
Brandon Thomas committed 2022-09-19 04:18:08 -04:00
1 parent 6ea1bf3226
commit dc115a7aa1
2 files changed
+62 -4

No files matched your search

@@ -4,6 +4,10 @@ use crate::stripe::webhook_event_handlers::stripe_webhook_summary::StripeWebhook
use log::{error, warn};
use sqlx::MySqlPool;
use stripe::Subscription;
use database_queries::queries::billing::subscriptions::get_subscription_by_stripe_id::get_subscription_by_stripe_id;
use database_queries::queries::billing::subscriptions::upsert_subscription_by_stripe_id::UpsertSubscriptionByStripeId;
use reusable_types::stripe::stripe_subscription_status::StripeSubscriptionStatus;
use crate::stripe::webhook_event_handlers::customer_subscription::calculate_subscription_end_date::calculate_subscription_end_date;
/// Handle event type: 'customer.subscription.deleted'
/// Sent when a customer’s subscription ends.
@@ -17,11 +21,67 @@ pub async fn customer_subscription_deleted_handler(
StripeWebhookError::ServerError // NB: This was probably *our* fault.
})?;
let mut should_process_update = true;
let mut action_was_taken = false;
let mut should_ignore_retry = false;
// NB: It's possible to receive events out of order.
let maybe_existing_subscription = get_subscription_by_stripe_id(&summary.stripe_subscription_id, &mysql_pool)
.await
.map_err(|err| {
error!("Mysql error: {:?}", err);
StripeWebhookError::ServerError
})?;
if let Some(existing_subscription) = maybe_existing_subscription {
match existing_subscription.maybe_stripe_subscription_status {
Some(StripeSubscriptionStatus::Canceled) => {
// NB: This is a terminal status and the subscription cannot be updated any further.
should_process_update = false;
should_ignore_retry = true;
}
_ => {}
}
}
// NB: Even if we haven't received a record before, we should still be able to "tombstone" it
// once we detect the deletion.
if should_process_update {
let upsert = UpsertSubscriptionByStripeId {
stripe_subscription_id: &summary.stripe_subscription_id,
maybe_user_token: summary.user_token.as_deref(),
subscription_category: "todo",
subscription_product_key: "todo",
maybe_stripe_product_id: Some(&summary.stripe_product_id),
maybe_stripe_customer_id: Some(&summary.stripe_customer_id),
maybe_stripe_recurring_interval: Some(summary.subscription_interval),
maybe_stripe_subscription_status: Some(summary.stripe_subscription_status),
maybe_stripe_is_production: Some(summary.stripe_is_production),
subscription_start_at: summary.subscription_start_date,
current_billing_period_start_at: summary.current_billing_period_start,
current_billing_period_end_at: summary.current_billing_period_end,
subscription_expires_at: calculate_subscription_end_date(&summary),
maybe_cancel_at: summary.maybe_cancel_at,
maybe_canceled_at: summary.maybe_canceled_at,
};
let _r = upsert.upsert(mysql_pool)
.await
.map_err(|err| {
error!("Mysql error: {:?}", err);
StripeWebhookError::ServerError
})?;
action_was_taken = true;
should_ignore_retry = true;
}
Ok(StripeWebhookSummary {
maybe_user_token: summary.user_token,
maybe_event_entity_id: Some(summary.stripe_subscription_id),
maybe_stripe_customer_id: Some(summary.stripe_customer_id),
action_was_taken: false,
should_ignore_retry: false,
action_was_taken,
should_ignore_retry,
})
}
@@ -45,8 +45,6 @@ pub async fn customer_subscription_updated_handler(
}
}
// TODO: record cancel_at (future_cancel_at), canceled_at, ended_at (if subscription ended, when it ended), start_date
if should_process_update {
let upsert = UpsertSubscriptionByStripeId {
stripe_subscription_id: &summary.stripe_subscription_id,