From 7cbcaacda1c8991984fb5ddf89bebd5ded395e08 Mon Sep 17 00:00:00 2001
From: ValueOn AG
Date: Tue, 31 Mar 2026 00:24:56 +0200
Subject: [PATCH] managed stripe change in env to trigger db refresh
---
.../serviceSubscription/stripeBootstrap.py | 66 +++++++++++++------
1 file changed, 45 insertions(+), 21 deletions(-)
diff --git a/modules/serviceCenter/services/serviceSubscription/stripeBootstrap.py b/modules/serviceCenter/services/serviceSubscription/stripeBootstrap.py
index 38ac29e1..edb2df1f 100644
--- a/modules/serviceCenter/services/serviceSubscription/stripeBootstrap.py
+++ b/modules/serviceCenter/services/serviceSubscription/stripeBootstrap.py
@@ -154,6 +154,23 @@ def _createStripePrice(stripe, productId: str, unitAmountCHF: float, interval: s
return price.id
+def _validateStripeIdsExist(stripe, mapping: StripePlanPrice) -> bool:
+ """Quick check whether at least the stored product IDs still exist in Stripe.
+ Returns False when running against a different Stripe account or after DB copy."""
+ try:
+ if mapping.stripeProductIdUsers:
+ stripe.Product.retrieve(mapping.stripeProductIdUsers)
+ if mapping.stripeProductIdInstances:
+ stripe.Product.retrieve(mapping.stripeProductIdInstances)
+ return True
+ except Exception as e:
+ code = getattr(e, "code", None)
+ if code == "resource_missing":
+ return False
+ logger.debug("Stripe validation check failed (non-critical): %s", e)
+ return False
+
+
def bootstrapStripePrices() -> None:
"""Ensure all paid plans have separate Stripe Products for users and instances."""
try:
@@ -183,30 +200,37 @@ def bootstrapStripePrices() -> None:
hasAllPrices = mapping.stripePriceIdUsers and mapping.stripePriceIdInstances
hasAllProducts = mapping.stripeProductIdUsers and mapping.stripeProductIdInstances
if hasAllPrices and hasAllProducts:
- changed = False
- reconciledUsers = _reconcilePrice(
- stripe, mapping.stripeProductIdUsers, mapping.stripePriceIdUsers,
- plan.pricePerUserCHF, interval, f"{planKey} — Benutzer-Lizenz",
- )
- if reconciledUsers != mapping.stripePriceIdUsers:
- changed = True
+ if _validateStripeIdsExist(stripe, mapping):
+ changed = False
+ reconciledUsers = _reconcilePrice(
+ stripe, mapping.stripeProductIdUsers, mapping.stripePriceIdUsers,
+ plan.pricePerUserCHF, interval, f"{planKey} — Benutzer-Lizenz",
+ )
+ if reconciledUsers != mapping.stripePriceIdUsers:
+ changed = True
- reconciledInstances = _reconcilePrice(
- stripe, mapping.stripeProductIdInstances, mapping.stripePriceIdInstances,
- plan.pricePerFeatureInstanceCHF, interval, f"{planKey} — Feature-Instanz",
- )
- if reconciledInstances != mapping.stripePriceIdInstances:
- changed = True
+ reconciledInstances = _reconcilePrice(
+ stripe, mapping.stripeProductIdInstances, mapping.stripePriceIdInstances,
+ plan.pricePerFeatureInstanceCHF, interval, f"{planKey} — Feature-Instanz",
+ )
+ if reconciledInstances != mapping.stripePriceIdInstances:
+ changed = True
- if changed:
- db.recordModify(StripePlanPrice, mapping.id, {
- "stripePriceIdUsers": reconciledUsers,
- "stripePriceIdInstances": reconciledInstances,
- })
- logger.info("Reconciled Stripe prices for plan %s: users=%s, instances=%s", planKey, reconciledUsers, reconciledInstances)
+ if changed:
+ db.recordModify(StripePlanPrice, mapping.id, {
+ "stripePriceIdUsers": reconciledUsers,
+ "stripePriceIdInstances": reconciledInstances,
+ })
+ logger.info("Reconciled Stripe prices for plan %s: users=%s, instances=%s", planKey, reconciledUsers, reconciledInstances)
+ else:
+ logger.debug("Stripe prices up-to-date for plan %s", planKey)
+ continue
else:
- logger.debug("Stripe prices up-to-date for plan %s", planKey)
- continue
+ logger.warning(
+ "Stored Stripe IDs for plan %s reference unknown objects "
+ "(likely wrong Stripe account or copied DB) — re-provisioning.",
+ planKey,
+ )
productIdUsers = None
productIdInstances = None