collab: Add separate billing_customers table (#15457)
This PR adds a new `billing_customers` table to hold the billing customers. Previously we were storing both the `stripe_customer_id` and `stripe_subscription_id` in the `billable_subscriptions` table. However, this creates problems when we need to correlate subscription events back to the subscription record, as we don't know the user that the Stripe event corresponds to. By moving the `stripe_customer_id` to a separate table we can create the Stripe customer earlier in the flow—before we create the Stripe Checkout session—and associate that customer with a user. This way when we receive events down the line we can use the Stripe customer ID to correlate it back to the user. We're doing some destructive actions to the `billing_subscriptions` table, but this is fine, as we haven't started using them yet. Release Notes: - N/A
This commit is contained in:
@@ -2,7 +2,7 @@ use std::sync::Arc;
|
||||
|
||||
use crate::db::billing_subscription::StripeSubscriptionStatus;
|
||||
use crate::db::tests::new_test_user;
|
||||
use crate::db::CreateBillingSubscriptionParams;
|
||||
use crate::db::{CreateBillingCustomerParams, CreateBillingSubscriptionParams};
|
||||
use crate::test_both_dbs;
|
||||
|
||||
use super::Database;
|
||||
@@ -25,9 +25,17 @@ async fn test_get_active_billing_subscriptions(db: &Arc<Database>) {
|
||||
// A user with an active subscription has one active billing subscription.
|
||||
{
|
||||
let user_id = new_test_user(db, "active-user@example.com").await;
|
||||
let customer = db
|
||||
.create_billing_customer(&CreateBillingCustomerParams {
|
||||
user_id,
|
||||
stripe_customer_id: "cus_active_user".into(),
|
||||
})
|
||||
.await
|
||||
.unwrap();
|
||||
assert_eq!(customer.stripe_customer_id, "cus_active_user".to_string());
|
||||
|
||||
db.create_billing_subscription(&CreateBillingSubscriptionParams {
|
||||
user_id,
|
||||
stripe_customer_id: "cus_active_user".into(),
|
||||
billing_customer_id: customer.id,
|
||||
stripe_subscription_id: "sub_active_user".into(),
|
||||
stripe_subscription_status: StripeSubscriptionStatus::Active,
|
||||
})
|
||||
@@ -38,10 +46,6 @@ async fn test_get_active_billing_subscriptions(db: &Arc<Database>) {
|
||||
assert_eq!(subscriptions.len(), 1);
|
||||
|
||||
let subscription = &subscriptions[0];
|
||||
assert_eq!(
|
||||
subscription.stripe_customer_id,
|
||||
"cus_active_user".to_string()
|
||||
);
|
||||
assert_eq!(
|
||||
subscription.stripe_subscription_id,
|
||||
"sub_active_user".to_string()
|
||||
@@ -55,9 +59,17 @@ async fn test_get_active_billing_subscriptions(db: &Arc<Database>) {
|
||||
// A user with a past-due subscription has no active billing subscriptions.
|
||||
{
|
||||
let user_id = new_test_user(db, "past-due-user@example.com").await;
|
||||
let customer = db
|
||||
.create_billing_customer(&CreateBillingCustomerParams {
|
||||
user_id,
|
||||
stripe_customer_id: "cus_past_due_user".into(),
|
||||
})
|
||||
.await
|
||||
.unwrap();
|
||||
assert_eq!(customer.stripe_customer_id, "cus_past_due_user".to_string());
|
||||
|
||||
db.create_billing_subscription(&CreateBillingSubscriptionParams {
|
||||
user_id,
|
||||
stripe_customer_id: "cus_past_due_user".into(),
|
||||
billing_customer_id: customer.id,
|
||||
stripe_subscription_id: "sub_past_due_user".into(),
|
||||
stripe_subscription_status: StripeSubscriptionStatus::PastDue,
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user