Jun 28 - Update tenant bill management
This commit is contained in:
+22
-6
@@ -109,20 +109,24 @@ def _on_checkout_completed(obj):
|
||||
|
||||
|
||||
def _on_subscription_updated(obj):
|
||||
"""customer.subscription.updated — sync status from Stripe."""
|
||||
"""customer.subscription.updated — sync status and plan from Stripe."""
|
||||
customer_id = obj.get('customer')
|
||||
subscription_id = obj.get('id')
|
||||
stripe_status = obj.get('status', '')
|
||||
period_end_ts = obj.get('current_period_end')
|
||||
trial_end_ts = obj.get('trial_end')
|
||||
|
||||
# Extract the price ID from the first subscription item (plan change detection).
|
||||
items = obj.get('items', {}).get('data', [])
|
||||
new_price_id = items[0].get('price', {}).get('id') if items else None
|
||||
|
||||
our_status = _STRIPE_STATUS_MAP.get(stripe_status)
|
||||
if our_status is None:
|
||||
logger.warning('BILLING | subscription_updated_unknown_status | status=%s', stripe_status)
|
||||
return
|
||||
|
||||
from control.base import control_session
|
||||
from control.models import Tenant, TenantAudit
|
||||
from control.models import Tenant, Plan, TenantAudit
|
||||
|
||||
with control_session() as s:
|
||||
t = s.query(Tenant).filter_by(stripe_customer_id=customer_id).first()
|
||||
@@ -130,17 +134,29 @@ def _on_subscription_updated(obj):
|
||||
logger.warning('BILLING | subscription_updated_no_tenant | customer=%s', customer_id)
|
||||
return
|
||||
|
||||
old_status = t.subscription_status
|
||||
t.subscription_status = our_status
|
||||
old_status = t.subscription_status
|
||||
old_plan_id = t.plan_id
|
||||
|
||||
t.subscription_status = our_status
|
||||
t.stripe_subscription_id = subscription_id
|
||||
t.current_period_end = _ts_to_dt(period_end_ts)
|
||||
t.current_period_end = _ts_to_dt(period_end_ts)
|
||||
if trial_end_ts:
|
||||
t.trial_ends_at = _ts_to_dt(trial_end_ts)
|
||||
|
||||
# Sync plan when the price changes (upgrade / downgrade via portal).
|
||||
plan_detail = ''
|
||||
if new_price_id:
|
||||
matched_plan = s.query(Plan).filter_by(stripe_price_id=new_price_id).first()
|
||||
if matched_plan and matched_plan.id != old_plan_id:
|
||||
t.plan_id = matched_plan.id
|
||||
plan_detail = f' plan={old_plan_id}→{matched_plan.id}({matched_plan.code})'
|
||||
logger.info('BILLING | plan_changed | tenant_id=%s plan=%s→%s',
|
||||
t.id, old_plan_id, matched_plan.id)
|
||||
|
||||
s.add(TenantAudit(
|
||||
action='billing_subscription_updated',
|
||||
tenant_id=t.id,
|
||||
details=f'stripe_status={stripe_status} our_status={our_status} prev={old_status}',
|
||||
details=f'stripe_status={stripe_status} our_status={our_status} prev={old_status}{plan_detail}',
|
||||
))
|
||||
|
||||
logger.info('BILLING | subscription_updated | tenant_id=%s %s→%s', t.id, old_status, our_status)
|
||||
|
||||
Reference in New Issue
Block a user