fix(billing): period_end from Stripe items + test
This commit is contained in:
@@ -186,7 +186,11 @@ def parse_webhook(payload: bytes) -> dict:
|
||||
|
||||
|
||||
)
|
||||
period_end = _unix_to_iso(sub.current_period_end)
|
||||
# Stripe API 2026-02+ moved period_end to items
|
||||
ts = sub.current_period_end
|
||||
if not ts and sub.get("items", {}).get("data"):
|
||||
ts = sub["items"]["data"][0].get("current_period_end")
|
||||
period_end = _unix_to_iso(ts)
|
||||
except Exception:
|
||||
logger.warning("Failed to fetch subscription %s for period_end", subscription_id)
|
||||
|
||||
@@ -230,7 +234,7 @@ def parse_webhook(payload: bytes) -> dict:
|
||||
"supplier_id": supplier_id,
|
||||
"plan": plan,
|
||||
"status": status,
|
||||
"current_period_end": _unix_to_iso(obj.get("current_period_end")),
|
||||
"current_period_end": _get_period_end(obj),
|
||||
"data": obj,
|
||||
"items": _extract_sub_items(obj),
|
||||
"custom_data": metadata,
|
||||
@@ -246,7 +250,7 @@ def parse_webhook(payload: bytes) -> dict:
|
||||
"supplier_id": supplier_id,
|
||||
"plan": plan,
|
||||
"status": status,
|
||||
"current_period_end": _unix_to_iso(obj.get("current_period_end")),
|
||||
"current_period_end": _get_period_end(obj),
|
||||
"data": obj,
|
||||
"items": _extract_sub_items(obj),
|
||||
"custom_data": metadata,
|
||||
@@ -261,7 +265,7 @@ def parse_webhook(payload: bytes) -> dict:
|
||||
"supplier_id": supplier_id,
|
||||
"plan": plan,
|
||||
"status": "cancelled",
|
||||
"current_period_end": _unix_to_iso(obj.get("current_period_end")),
|
||||
"current_period_end": _get_period_end(obj),
|
||||
"data": obj,
|
||||
"items": _extract_sub_items(obj),
|
||||
"custom_data": metadata,
|
||||
@@ -326,6 +330,19 @@ def _unix_to_iso(ts) -> str | None:
|
||||
return datetime.fromtimestamp(int(ts), tz=UTC).strftime("%Y-%m-%dT%H:%M:%S.000000Z")
|
||||
|
||||
|
||||
def _get_period_end(obj: dict) -> str | None:
|
||||
"""Extract current_period_end from subscription or its first item.
|
||||
|
||||
Stripe API 2026-02+ moved period fields from subscription to subscription items.
|
||||
"""
|
||||
ts = obj.get("current_period_end")
|
||||
if not ts:
|
||||
items = obj.get("items", {}).get("data", [])
|
||||
if items:
|
||||
ts = items[0].get("current_period_end")
|
||||
return _unix_to_iso(ts)
|
||||
|
||||
|
||||
def _extract_line_items(session_obj: dict) -> list[dict]:
|
||||
"""Extract line items from a Checkout Session in Paddle-compatible format.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user