Alle 7 Stellen im Code, die Stripe-Objekte in Dicts konvertieren, nutzen jetzt stripeToDict(). Das funktioniert unabhängig von der Stripe-Bibliotheksversion auf DEV und INT.

This commit is contained in:
ValueOn AG 2026-03-31 02:14:33 +02:00
parent b142c0fa6c
commit bc370ef475
5 changed files with 36 additions and 12 deletions

View file

@ -875,7 +875,8 @@ def confirmCheckoutSession(
if not session: if not session:
raise HTTPException(status_code=404, detail="Stripe Checkout Session not found") raise HTTPException(status_code=404, detail="Stripe Checkout Session not found")
session_dict = session.to_dict_recursive() if hasattr(session, "to_dict_recursive") else dict(session) from modules.shared.stripeClient import stripeToDict
session_dict = stripeToDict(session)
metadata = session_dict.get("metadata") or {} metadata = session_dict.get("metadata") or {}
mandate_id = metadata.get("mandateId") mandate_id = metadata.get("mandateId")
user_id = metadata.get("userId") or None user_id = metadata.get("userId") or None
@ -995,7 +996,8 @@ def _handleSubscriptionCheckoutCompleted(session, eventId: str) -> None:
from datetime import datetime, timezone from datetime import datetime, timezone
if not isinstance(session, dict): if not isinstance(session, dict):
session = dict(session) from modules.shared.stripeClient import stripeToDict
session = stripeToDict(session)
metadata = session.get("metadata") or {} metadata = session.get("metadata") or {}
subscriptionRecordId = metadata.get("subscriptionRecordId") subscriptionRecordId = metadata.get("subscriptionRecordId")
@ -1010,7 +1012,8 @@ def _handleSubscriptionCheckoutCompleted(session, eventId: str) -> None:
try: try:
from modules.shared.stripeClient import getStripeClient from modules.shared.stripeClient import getStripeClient
stripe = getStripeClient() stripe = getStripeClient()
subObj = dict(stripe.Subscription.retrieve(stripeSub)) from modules.shared.stripeClient import stripeToDict
subObj = stripeToDict(stripe.Subscription.retrieve(stripeSub))
metadata = subObj.get("metadata") or {} metadata = subObj.get("metadata") or {}
subscriptionRecordId = metadata.get("subscriptionRecordId") subscriptionRecordId = metadata.get("subscriptionRecordId")
mandateId = metadata.get("mandateId") mandateId = metadata.get("mandateId")
@ -1042,7 +1045,8 @@ def _handleSubscriptionCheckoutCompleted(session, eventId: str) -> None:
try: try:
from modules.shared.stripeClient import getStripeClient from modules.shared.stripeClient import getStripeClient
stripe = getStripeClient() stripe = getStripeClient()
stripeSub = dict(stripe.Subscription.retrieve(stripeSubId, expand=["items"])) from modules.shared.stripeClient import stripeToDict
stripeSub = stripeToDict(stripe.Subscription.retrieve(stripeSubId, expand=["items"]))
if stripeSub.get("current_period_start"): if stripeSub.get("current_period_start"):
stripeData["currentPeriodStart"] = datetime.fromtimestamp( stripeData["currentPeriodStart"] = datetime.fromtimestamp(

View file

@ -282,10 +282,10 @@ def verifyCheckout(
_assertMandateAdmin(context, mandateId) _assertMandateAdmin(context, mandateId)
try: try:
from modules.shared.stripeClient import getStripeClient from modules.shared.stripeClient import getStripeClient, stripeToDict
stripe = getStripeClient() stripe = getStripeClient()
rawSession = stripe.checkout.Session.retrieve(data.sessionId) rawSession = stripe.checkout.Session.retrieve(data.sessionId)
session = dict(rawSession) session = stripeToDict(rawSession)
except Exception as e: except Exception as e:
logger.error("Failed to retrieve checkout session %s: %s", data.sessionId, e) logger.error("Failed to retrieve checkout session %s: %s", data.sessionId, e)
raise HTTPException(status_code=400, detail="Invalid session ID") raise HTTPException(status_code=400, detail="Invalid session ID")

View file

@ -425,7 +425,8 @@ class SubscriptionService:
try: try:
from modules.shared.stripeClient import getStripeClient from modules.shared.stripeClient import getStripeClient
stripe = getStripeClient() stripe = getStripeClient()
stripeSub = dict(stripe.Subscription.modify(stripeSubId, cancel_at_period_end=True)) from modules.shared.stripeClient import stripeToDict
stripeSub = stripeToDict(stripe.Subscription.modify(stripeSubId, cancel_at_period_end=True))
pUrl = (stripeSub.get("metadata") or {}).get("platformUrl", "") pUrl = (stripeSub.get("metadata") or {}).get("platformUrl", "")
except Exception as e: except Exception as e:
logger.error("Failed to set cancel_at_period_end for %s: %s", stripeSubId, e) logger.error("Failed to set cancel_at_period_end for %s: %s", stripeSubId, e)
@ -488,7 +489,8 @@ class SubscriptionService:
try: try:
from modules.shared.stripeClient import getStripeClient from modules.shared.stripeClient import getStripeClient
stripe = getStripeClient() stripe = getStripeClient()
stripeSub = dict(stripe.Subscription.retrieve(stripeSubId)) from modules.shared.stripeClient import stripeToDict
stripeSub = stripeToDict(stripe.Subscription.retrieve(stripeSubId))
pUrl = (stripeSub.get("metadata") or {}).get("platformUrl", "") pUrl = (stripeSub.get("metadata") or {}).get("platformUrl", "")
stripe.Subscription.cancel(stripeSubId) stripe.Subscription.cancel(stripeSubId)
except Exception as e: except Exception as e:
@ -673,7 +675,8 @@ def _buildInvoiceSummaryHtml(
stripe = getStripeClient() stripe = getStripeClient()
invoices = stripe.Invoice.list(subscription=stripeSubId, limit=1) invoices = stripe.Invoice.list(subscription=stripeSubId, limit=1)
if invoices.data: if invoices.data:
inv = dict(invoices.data[0]) if not isinstance(invoices.data[0], dict) else invoices.data[0] from modules.shared.stripeClient import stripeToDict
inv = stripeToDict(invoices.data[0])
hostedUrl = inv.get("hosted_invoice_url", "") hostedUrl = inv.get("hosted_invoice_url", "")
if hostedUrl: if hostedUrl:
invoiceLink = ( invoiceLink = (
@ -715,7 +718,8 @@ def _buildCancelSummaryHtml(subRecord: Dict[str, Any], platformUrl: str = "") ->
stripe = getStripeClient() stripe = getStripeClient()
invoices = stripe.Invoice.list(subscription=stripeSubId, limit=1) invoices = stripe.Invoice.list(subscription=stripeSubId, limit=1)
if invoices.data: if invoices.data:
inv = dict(invoices.data[0]) if not isinstance(invoices.data[0], dict) else invoices.data[0] from modules.shared.stripeClient import stripeToDict
inv = stripeToDict(invoices.data[0])
hostedUrl = inv.get("hosted_invoice_url", "") hostedUrl = inv.get("hosted_invoice_url", "")
if hostedUrl: if hostedUrl:
parts.append( parts.append(

View file

@ -108,7 +108,8 @@ def _findExistingStripePrice(stripe, productId: str, unitAmount: int, interval:
def _getStripePriceAmount(stripe, priceId: str) -> Optional[int]: def _getStripePriceAmount(stripe, priceId: str) -> Optional[int]:
"""Retrieve the unit_amount (in Rappen) of an existing Stripe Price.""" """Retrieve the unit_amount (in Rappen) of an existing Stripe Price."""
try: try:
price = dict(stripe.Price.retrieve(priceId)) from modules.shared.stripeClient import stripeToDict
price = stripeToDict(stripe.Price.retrieve(priceId))
return price.get("unit_amount") if price else None return price.get("unit_amount") if price else None
except Exception: except Exception:
return None return None

View file

@ -8,13 +8,28 @@ API key, API version, and fallback handling across billing and subscription flow
""" """
import logging import logging
from typing import Optional import json
from typing import Any, Dict, Optional
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
_stripeInitialized = False _stripeInitialized = False
def stripeToDict(obj) -> Dict[str, Any]:
"""Convert a Stripe object to a plain dict, compatible with all stripe-python versions."""
if isinstance(obj, dict):
return obj
if hasattr(obj, "to_dict_recursive"):
return obj.to_dict_recursive()
if hasattr(obj, "to_dict"):
return obj.to_dict()
try:
return json.loads(str(obj))
except (json.JSONDecodeError, TypeError):
return dict(obj)
def getStripeClient(): def getStripeClient():
""" """
Initialize and return the configured Stripe SDK module. Initialize and return the configured Stripe SDK module.