fixed changed customer in stripe

This commit is contained in:
ValueOn AG 2026-03-31 00:15:47 +02:00
parent 4cf24884cb
commit 3be0967936

View file

@ -283,14 +283,34 @@ class SubscriptionService:
subscriptionData["trial_end"] = trialEndTs
self._interface.updateFields(subRecord["id"], {"effectiveFrom": periodEnd.isoformat()})
session = stripe.checkout.Session.create(
mode="subscription",
customer=stripeCustomerId,
line_items=lineItems,
success_url=successUrl,
cancel_url=cancelUrl,
subscription_data=subscriptionData,
)
session = None
for attempt in range(2):
try:
session = stripe.checkout.Session.create(
mode="subscription",
customer=stripeCustomerId,
line_items=lineItems,
success_url=successUrl,
cancel_url=cancelUrl,
subscription_data=subscriptionData,
)
break
except Exception as e:
if attempt == 0 and self._isStripeMissingCustomerError(e):
logger.warning(
"Stripe reports missing customer %s for mandate %s"
"clearing stored stripeCustomerId (wrong account, deleted customer, or copied DB).",
stripeCustomerId,
mandateId,
)
self._clearStoredStripeCustomerId(mandateId)
stripeCustomerId = self._resolveStripeCustomer(mandateId)
if not stripeCustomerId:
raise ValueError(
f"Could not recreate Stripe customer for mandate {mandateId}"
) from e
continue
raise
if not session or not session.url:
raise ValueError("Stripe Checkout Session creation failed")
@ -298,6 +318,32 @@ class SubscriptionService:
logger.info("Checkout session %s created for mandate %s, plan %s", session.id, mandateId, plan.planKey)
return session.url
@staticmethod
def _isStripeMissingCustomerError(exc: BaseException) -> bool:
code = getattr(exc, "code", None)
param = getattr(exc, "param", None)
if code == "resource_missing" and param == "customer":
return True
body = getattr(exc, "json_body", None)
if isinstance(body, dict):
err = body.get("error")
if isinstance(err, dict):
return err.get("code") == "resource_missing" and err.get("param") == "customer"
return False
def _clearStoredStripeCustomerId(self, mandateId: str) -> None:
try:
from modules.interfaces.interfaceDbBilling import getInterface as getBillingInterface
billingIf = getBillingInterface(self.currentUser, mandateId)
settings = billingIf.getSettings(mandateId)
if not settings or not settings.get("stripeCustomerId"):
return
billingIf.updateSettings(settings["id"], {"stripeCustomerId": None})
logger.info("Cleared stripeCustomerId on billing settings for mandate %s", mandateId)
except Exception as e:
logger.error("Failed to clear stripeCustomerId for mandate %s: %s", mandateId, e)
def _resolveStripeCustomer(self, mandateId: str) -> Optional[str]:
try:
from modules.interfaces.interfaceDbBilling import getInterface as getBillingInterface