feat(billing): A6 — planner/supplier routes use get_price_id() + _provider()

- planner/routes.py: import get_price_id instead of get_paddle_price,
  export_checkout uses _provider().build_checkout_payload()
- suppliers/routes.py: all get_paddle_price → get_price_id,
  signup_checkout uses _provider().build_multi_item_checkout_payload(),
  dashboard boosts use get_all_price_ids() bulk load

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Deeman
2026-03-03 15:36:12 +01:00
parent 8f0a56079f
commit bf69270913
2 changed files with 30 additions and 35 deletions

View File

@@ -18,7 +18,7 @@ from ..core import (
feature_gate,
fetch_all,
fetch_one,
get_paddle_price,
get_price_id,
utcnow_iso,
)
from ..i18n import get_translations
@@ -687,7 +687,9 @@ async def export_details():
@login_required
@csrf_protect
async def export_checkout():
"""Return JSON for Paddle.js overlay checkout for business plan PDF."""
"""Return checkout JSON for business plan PDF (works with Paddle overlay or Stripe redirect)."""
from ..billing.routes import _provider
form = await request.form
scenario_id = form.get("scenario_id")
language = form.get("language", "en")
@@ -703,23 +705,20 @@ async def export_checkout():
if not scenario:
return jsonify({"error": "Scenario not found."}), 404
price_id = await get_paddle_price("business_plan")
price_id = await get_price_id("business_plan")
if not price_id:
return jsonify({"error": "Product not configured. Contact support."}), 500
return jsonify(
{
"items": [{"priceId": price_id, "quantity": 1}],
"customData": {
"user_id": str(g.user["id"]),
"scenario_id": str(scenario_id),
"language": language,
},
"settings": {
"successUrl": f"{config.BASE_URL}/planner/export/success",
},
}
payload = _provider().build_checkout_payload(
price_id=price_id,
custom_data={
"user_id": str(g.user["id"]),
"scenario_id": str(scenario_id),
"language": language,
},
success_url=f"{config.BASE_URL}/planner/export/success",
)
return jsonify(payload)
@bp.route("/export/success")

View File

@@ -17,7 +17,8 @@ from ..core import (
feature_gate,
fetch_all,
fetch_one,
get_paddle_price,
get_all_price_ids,
get_price_id,
is_flag_enabled,
)
from ..i18n import get_translations
@@ -383,7 +384,9 @@ def _compute_order(data: dict, included_boosts: list, t: dict) -> dict:
@bp.route("/signup/checkout", methods=["POST"])
@csrf_protect
async def signup_checkout():
"""Validate form, return JSON for Paddle.js overlay checkout."""
"""Validate form, return checkout JSON (Paddle overlay or Stripe redirect)."""
from ..billing.routes import _provider
form = await request.form
accumulated = _parse_accumulated(form)
@@ -401,9 +404,9 @@ async def signup_checkout():
if period == "yearly"
else plan_info.get("paddle_key_monthly", plan)
)
plan_price_id = await get_paddle_price(price_key)
plan_price_id = await get_price_id(price_key)
if not plan_price_id:
return jsonify({"error": "Invalid plan selected. Run setup_paddle first."}), 400
return jsonify({"error": "Invalid plan selected. Run setup first."}), 400
# Build items list
items = [{"priceId": plan_price_id, "quantity": 1}]
@@ -416,14 +419,14 @@ async def signup_checkout():
for b in BOOST_OPTIONS:
if b["type"] in selected_boosts and b["type"] not in included_boosts:
price_id = await get_paddle_price(b["key"])
price_id = await get_price_id(b["key"])
if price_id:
items.append({"priceId": price_id, "quantity": 1})
# Add credit pack (one-time)
credit_pack = accumulated.get("credit_pack", "")
if credit_pack:
price_id = await get_paddle_price(credit_pack)
price_id = await get_price_id(credit_pack)
if price_id:
items.append({"priceId": price_id, "quantity": 1})
@@ -477,15 +480,12 @@ async def signup_checkout():
"plan": plan,
}
return jsonify(
{
"items": items,
"customData": custom_data,
"settings": {
"successUrl": f"{config.BASE_URL}/suppliers/signup/success",
},
}
payload = _provider().build_multi_item_checkout_payload(
items=items,
custom_data=custom_data,
success_url=f"{config.BASE_URL}/suppliers/signup/success",
)
return jsonify(payload)
@bp.route("/claim/<slug>")
@@ -1035,12 +1035,8 @@ async def dashboard_boosts():
(supplier["id"],),
)
# Resolve Paddle price IDs for buy buttons
price_ids = {}
for b in BOOST_OPTIONS:
price_ids[b["key"]] = await get_paddle_price(b["key"])
for cp in CREDIT_PACK_OPTIONS:
price_ids[cp["key"]] = await get_paddle_price(cp["key"])
# Resolve price IDs for buy buttons (from active provider)
price_ids = await get_all_price_ids()
return await render_template(
"suppliers/partials/dashboard_boosts.html",