From 9394a859af58c1ffc10190d43b19832c9b8d026b Mon Sep 17 00:00:00 2001 From: Ben Sima Date: Wed, 12 Nov 2025 20:16:36 -0500 Subject: Fix subscription webhook to handle Stripe API version differences - Use billing_cycle_anchor or start_date as fallback for period start - Calculate period end by adding 1 month if not provided - Handles newer Stripe API versions that don't include current_period_* fields - Fixes issue where subscription.created webhook couldn't update user plan - Works with Stripe API Version 2025-10-29.clover and newer --- Biz/PodcastItLater/Billing.py | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) (limited to 'Biz/PodcastItLater/Billing.py') diff --git a/Biz/PodcastItLater/Billing.py b/Biz/PodcastItLater/Billing.py index c5cb749..9664b9f 100644 --- a/Biz/PodcastItLater/Billing.py +++ b/Biz/PodcastItLater/Billing.py @@ -371,20 +371,35 @@ def _update_subscription_state(subscription: dict[str, typing.Any]) -> None: ) return - # Get billing period - handle both dict and object access patterns - period_start_ts = subscription.get("current_period_start") + # Get billing period - try multiple field names for API compatibility + period_start_ts = ( + subscription.get("current_period_start") + or subscription.get("billing_cycle_anchor") + or subscription.get("start_date") + ) period_end_ts = subscription.get("current_period_end") - if not period_start_ts or not period_end_ts: + if not period_start_ts: logger.warning( - "Missing period dates in subscription: %s. Available keys: %s", + "Missing period start in subscription: %s. Available keys: %s", subscription_id, list(subscription.keys()), ) return period_start = datetime.fromtimestamp(period_start_ts, tz=timezone.utc) - period_end = datetime.fromtimestamp(period_end_ts, tz=timezone.utc) + + # Calculate period end if not provided (assume monthly) + if not period_end_ts: + if period_start.month == 12: # noqa: PLR2004 + period_end = period_start.replace( + year=period_start.year + 1, + month=1, + ) + else: + period_end = period_start.replace(month=period_start.month + 1) + else: + period_end = datetime.fromtimestamp(period_end_ts, tz=timezone.utc) # Determine tier from price ID items = subscription.get("items", {}) -- cgit v1.2.3