collab: Add has_overdue_invoices to billing_customers (#24239)

This PR adds a new `has_overdue_invoices` field to the
`billing_customers` table.

This will be used to statefully track whether a customer has overdue
invoices, and also to reset it when the invoices are paid.

We will set this field to `true` when a subscription is canceled with
the reason `payment_failed`.

Release Notes:

- N/A
This commit is contained in:
Marshall Bowers 2025-02-04 18:12:35 -05:00 committed by GitHub
parent b13498a5dd
commit aa3da35e8e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 27 additions and 0 deletions

View file

@ -430,6 +430,7 @@ CREATE TABLE IF NOT EXISTS billing_customers (
id INTEGER PRIMARY KEY AUTOINCREMENT,
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
user_id INTEGER NOT NULL REFERENCES users(id),
has_overdue_invoices BOOLEAN NOT NULL DEFAULT FALSE,
stripe_customer_id TEXT NOT NULL
);

View file

@ -0,0 +1,2 @@
alter table billing_customers
add column has_overdue_invoices bool not null default false;

View file

@ -666,6 +666,27 @@ async fn handle_customer_subscription_event(
.await?
.ok_or_else(|| anyhow!("billing customer not found"))?;
let was_canceled_due_to_payment_failure = subscription.status == SubscriptionStatus::Canceled
&& subscription
.cancellation_details
.as_ref()
.and_then(|details| details.reason)
.map_or(false, |reason| {
reason == CancellationDetailsReason::PaymentFailed
});
if was_canceled_due_to_payment_failure {
app.db
.update_billing_customer(
billing_customer.id,
&UpdateBillingCustomerParams {
has_overdue_invoices: ActiveValue::set(true),
..Default::default()
},
)
.await?;
}
if let Some(existing_subscription) = app
.db
.get_billing_subscription_by_stripe_subscription_id(&subscription.id)

View file

@ -10,6 +10,7 @@ pub struct CreateBillingCustomerParams {
pub struct UpdateBillingCustomerParams {
pub user_id: ActiveValue<UserId>,
pub stripe_customer_id: ActiveValue<String>,
pub has_overdue_invoices: ActiveValue<bool>,
}
impl Database {
@ -43,6 +44,7 @@ impl Database {
id: ActiveValue::set(id),
user_id: params.user_id.clone(),
stripe_customer_id: params.stripe_customer_id.clone(),
has_overdue_invoices: params.has_overdue_invoices.clone(),
..Default::default()
})
.exec(&*tx)

View file

@ -9,6 +9,7 @@ pub struct Model {
pub id: BillingCustomerId,
pub user_id: UserId,
pub stripe_customer_id: String,
pub has_overdue_invoices: bool,
pub created_at: DateTime,
}