mirror of
https://github.com/MODSetter/SurfSense.git
synced 2026-04-26 01:06:23 +02:00
feat: no login experience and prem tokens
Some checks are pending
Build and Push Docker Images / tag_release (push) Waiting to run
Build and Push Docker Images / build (./surfsense_backend, ./surfsense_backend/Dockerfile, backend, surfsense-backend, ubuntu-24.04-arm, linux/arm64, arm64) (push) Blocked by required conditions
Build and Push Docker Images / build (./surfsense_backend, ./surfsense_backend/Dockerfile, backend, surfsense-backend, ubuntu-latest, linux/amd64, amd64) (push) Blocked by required conditions
Build and Push Docker Images / build (./surfsense_web, ./surfsense_web/Dockerfile, web, surfsense-web, ubuntu-24.04-arm, linux/arm64, arm64) (push) Blocked by required conditions
Build and Push Docker Images / build (./surfsense_web, ./surfsense_web/Dockerfile, web, surfsense-web, ubuntu-latest, linux/amd64, amd64) (push) Blocked by required conditions
Build and Push Docker Images / create_manifest (backend, surfsense-backend) (push) Blocked by required conditions
Build and Push Docker Images / create_manifest (web, surfsense-web) (push) Blocked by required conditions
Some checks are pending
Build and Push Docker Images / tag_release (push) Waiting to run
Build and Push Docker Images / build (./surfsense_backend, ./surfsense_backend/Dockerfile, backend, surfsense-backend, ubuntu-24.04-arm, linux/arm64, arm64) (push) Blocked by required conditions
Build and Push Docker Images / build (./surfsense_backend, ./surfsense_backend/Dockerfile, backend, surfsense-backend, ubuntu-latest, linux/amd64, amd64) (push) Blocked by required conditions
Build and Push Docker Images / build (./surfsense_web, ./surfsense_web/Dockerfile, web, surfsense-web, ubuntu-24.04-arm, linux/arm64, arm64) (push) Blocked by required conditions
Build and Push Docker Images / build (./surfsense_web, ./surfsense_web/Dockerfile, web, surfsense-web, ubuntu-latest, linux/amd64, amd64) (push) Blocked by required conditions
Build and Push Docker Images / create_manifest (backend, surfsense-backend) (push) Blocked by required conditions
Build and Push Docker Images / create_manifest (web, surfsense-web) (push) Blocked by required conditions
This commit is contained in:
parent
87452bb315
commit
ff4e0f9b62
68 changed files with 5914 additions and 121 deletions
|
|
@ -1,4 +1,4 @@
|
|||
"""Reconcile pending Stripe page purchases that might miss webhook fulfillment."""
|
||||
"""Reconcile pending Stripe purchases that might miss webhook fulfillment."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
|
|
@ -11,7 +11,12 @@ from stripe import StripeClient, StripeError
|
|||
|
||||
from app.celery_app import celery_app
|
||||
from app.config import config
|
||||
from app.db import PagePurchase, PagePurchaseStatus
|
||||
from app.db import (
|
||||
PagePurchase,
|
||||
PagePurchaseStatus,
|
||||
PremiumTokenPurchase,
|
||||
PremiumTokenPurchaseStatus,
|
||||
)
|
||||
from app.routes import stripe_routes
|
||||
from app.tasks.celery_tasks import get_celery_session_maker
|
||||
|
||||
|
|
@ -126,7 +131,108 @@ async def _reconcile_pending_page_purchases() -> None:
|
|||
await db_session.rollback()
|
||||
|
||||
logger.info(
|
||||
"Stripe reconciliation completed. fulfilled=%s failed=%s checked=%s",
|
||||
"Stripe page reconciliation completed. fulfilled=%s failed=%s checked=%s",
|
||||
fulfilled_count,
|
||||
failed_count,
|
||||
len(pending_purchases),
|
||||
)
|
||||
|
||||
|
||||
@celery_app.task(name="reconcile_pending_stripe_token_purchases")
|
||||
def reconcile_pending_stripe_token_purchases_task():
|
||||
"""Recover paid token purchases that were left pending due to missed webhook handling."""
|
||||
loop = asyncio.new_event_loop()
|
||||
asyncio.set_event_loop(loop)
|
||||
|
||||
try:
|
||||
loop.run_until_complete(_reconcile_pending_token_purchases())
|
||||
finally:
|
||||
loop.close()
|
||||
|
||||
|
||||
async def _reconcile_pending_token_purchases() -> None:
|
||||
"""Reconcile stale pending token purchases against Stripe source of truth."""
|
||||
stripe_client = get_stripe_client()
|
||||
if stripe_client is None:
|
||||
return
|
||||
|
||||
lookback_minutes = max(config.STRIPE_RECONCILIATION_LOOKBACK_MINUTES, 0)
|
||||
batch_size = max(config.STRIPE_RECONCILIATION_BATCH_SIZE, 1)
|
||||
cutoff = datetime.now(UTC) - timedelta(minutes=lookback_minutes)
|
||||
|
||||
async with get_celery_session_maker()() as db_session:
|
||||
pending_purchases = (
|
||||
(
|
||||
await db_session.execute(
|
||||
select(PremiumTokenPurchase)
|
||||
.where(
|
||||
PremiumTokenPurchase.status
|
||||
== PremiumTokenPurchaseStatus.PENDING,
|
||||
PremiumTokenPurchase.created_at <= cutoff,
|
||||
)
|
||||
.order_by(PremiumTokenPurchase.created_at.asc())
|
||||
.limit(batch_size)
|
||||
)
|
||||
)
|
||||
.scalars()
|
||||
.all()
|
||||
)
|
||||
|
||||
if not pending_purchases:
|
||||
logger.debug(
|
||||
"Stripe token reconciliation found no pending purchases older than %s minutes.",
|
||||
lookback_minutes,
|
||||
)
|
||||
return
|
||||
|
||||
logger.info(
|
||||
"Stripe token reconciliation checking %s pending purchases (cutoff=%s, batch=%s).",
|
||||
len(pending_purchases),
|
||||
lookback_minutes,
|
||||
batch_size,
|
||||
)
|
||||
|
||||
fulfilled_count = 0
|
||||
failed_count = 0
|
||||
|
||||
for purchase in pending_purchases:
|
||||
checkout_session_id = purchase.stripe_checkout_session_id
|
||||
|
||||
try:
|
||||
checkout_session = stripe_client.v1.checkout.sessions.retrieve(
|
||||
checkout_session_id
|
||||
)
|
||||
except StripeError:
|
||||
logger.exception(
|
||||
"Stripe token reconciliation failed to retrieve checkout session %s",
|
||||
checkout_session_id,
|
||||
)
|
||||
await db_session.rollback()
|
||||
continue
|
||||
|
||||
payment_status = getattr(checkout_session, "payment_status", None)
|
||||
session_status = getattr(checkout_session, "status", None)
|
||||
|
||||
try:
|
||||
if payment_status in {"paid", "no_payment_required"}:
|
||||
await stripe_routes._fulfill_completed_token_purchase(
|
||||
db_session, checkout_session
|
||||
)
|
||||
fulfilled_count += 1
|
||||
elif session_status == "expired":
|
||||
await stripe_routes._mark_token_purchase_failed(
|
||||
db_session, str(checkout_session.id)
|
||||
)
|
||||
failed_count += 1
|
||||
except Exception:
|
||||
logger.exception(
|
||||
"Stripe token reconciliation failed while processing checkout session %s",
|
||||
checkout_session_id,
|
||||
)
|
||||
await db_session.rollback()
|
||||
|
||||
logger.info(
|
||||
"Stripe token reconciliation completed. fulfilled=%s failed=%s checked=%s",
|
||||
fulfilled_count,
|
||||
failed_count,
|
||||
len(pending_purchases),
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue