From b53a7f363def5d36cc975561ac129daed555743a Mon Sep 17 00:00:00 2001 From: ValueOn AG Date: Tue, 31 Mar 2026 00:47:28 +0200 Subject: [PATCH] fixes stripe --- app.py | 25 +++++++++++++------------ env_int.env | 2 +- modules/routes/routeSubscription.py | 21 +++++++++++++++++++-- 3 files changed, 33 insertions(+), 15 deletions(-) diff --git a/app.py b/app.py index 63e5652a..f29436cc 100644 --- a/app.py +++ b/app.py @@ -489,18 +489,6 @@ def getAllowedOrigins(): CORS_ORIGIN_REGEX = r"https://.*\.(poweron\.swiss|poweron-center\.net)" -# CORS configuration using environment variables -app.add_middleware( - CORSMiddleware, - allow_origins=getAllowedOrigins(), - allow_origin_regex=CORS_ORIGIN_REGEX, - allow_credentials=True, - allow_methods=["GET", "POST", "PUT", "PATCH", "DELETE", "OPTIONS"], - allow_headers=["*"], - expose_headers=["*"], - max_age=86400, # Increased caching for preflight requests -) - # SlowAPI rate limiter initialization from modules.auth import limiter from slowapi.errors import RateLimitExceeded @@ -538,6 +526,19 @@ app.add_middleware( ProactiveTokenRefreshMiddleware, enabled=True, check_interval_minutes=5 ) +# CORS must be registered LAST so it wraps the whole stack: every response (errors, CSRF 403, +# rate limits) still gets Access-Control-Allow-Origin for browser cross-origin calls. +app.add_middleware( + CORSMiddleware, + allow_origins=getAllowedOrigins(), + allow_origin_regex=CORS_ORIGIN_REGEX, + allow_credentials=True, + allow_methods=["GET", "POST", "PUT", "PATCH", "DELETE", "OPTIONS"], + allow_headers=["*"], + expose_headers=["*"], + max_age=86400, +) + # Include all routers from modules.routes.routeAdmin import router as generalRouter diff --git a/env_int.env b/env_int.env index 61981de1..fc9c0efd 100644 --- a/env_int.env +++ b/env_int.env @@ -53,7 +53,7 @@ Service_CLICKUP_OAUTH_REDIRECT_URI = http://localhost:8000/api/clickup/auth/conn # Stripe Billing (both end with _SECRET for encryption script) STRIPE_SECRET_KEY_SECRET = INT_ENC:Z0FBQUFBQnB5dkd5ekdBaGNGVUlOQUpncTlzLWlTV0V5OWZzQkpDczhCUGw4U1JpTHZ0d3pfYlFNWElLRlNiNlNsaDRYTGZUTkg2OUFrTW1GZXpOUjBVbmRQWjN6ekhHd2ZSQ195OHlaeWh1TmxrUm10V2R3YmdncmFLbFMzVjdqcWJMSUJPR2xuSEozclNoZG1rZVBTaWg3OFQ1Qzdxb0wyQ2RKazc2dG1aZXBUTXlvbDZqLS1KOVI5M3BGc3NQZkZRbnFpRjIwWmh2ZHlVNlpxZVo2dWNmMjQ5eW02QmtzUT09 -STRIPE_WEBHOOK_SECRET = INT_ENC:Z0FBQUFBQnB5dkd5VUszOWllM1E1YXlsdldIdENlUTd4bWhycVNBZVZzSWxlMjd4NEJwRnFVbnRaNTlGOWUyLVdxRUxySEtGRDdfbEVHM1dFTU93SHZtY1RKZkh0NG92M2cwYTQxQjQ0SFhqNXZnd21jbE52WW0wZC1oMlY3OXFFSV9sd2M1TC10N0hZa2Zha3FzX1FhcE14alo2TGFHX3QybHFxOTlQWWFZR3pabkRtOEp1Zm1zOFlrbDF0MFNkUjUyVFI5NUNZaU5TRXF4X29tcEQ2RUR1MTlXcUoxbTl0dz09 +STRIPE_WEBHOOK_SECRET = whsec_2agCQEbDPSOn2C40EJcwoPCqlvaPLF7M STRIPE_API_VERSION = 2026-01-28.clover # AI configuration diff --git a/modules/routes/routeSubscription.py b/modules/routes/routeSubscription.py index 88d0b21c..3193292c 100644 --- a/modules/routes/routeSubscription.py +++ b/modules/routes/routeSubscription.py @@ -291,14 +291,31 @@ def verifyCheckout( logger.error("Failed to retrieve checkout session %s: %s", data.sessionId, e) raise HTTPException(status_code=400, detail="Invalid session ID") - if session.get("status") != "complete" or session.get("payment_status") != "paid": + payStatus = session.get("payment_status") + if session.get("status") != "complete": + return {"status": "pending", "message": "Checkout not yet completed"} + # Subscription checkouts with trial / $0 first period use no_payment_required, not paid. + if payStatus not in ("paid", "no_payment_required"): return {"status": "pending", "message": "Checkout not yet completed"} if session.get("mode") != "subscription": raise HTTPException(status_code=400, detail="Not a subscription checkout session") from modules.routes.routeBilling import _handleSubscriptionCheckoutCompleted - _handleSubscriptionCheckoutCompleted(session, f"verify-{data.sessionId}") + + try: + _handleSubscriptionCheckoutCompleted(session, f"verify-{data.sessionId}") + except Exception as e: + logger.exception( + "verifyCheckout: handler failed for session %s mandate %s: %s", + data.sessionId, + mandateId, + e, + ) + raise HTTPException( + status_code=500, + detail="Subscription-Aktivierung nach Checkout fehlgeschlagen. Bitte erneut versuchen oder Support informieren.", + ) from e return {"status": "activated", "message": "Subscription activated"}