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:
@@ -18,7 +18,7 @@ from ..core import (
|
|||||||
feature_gate,
|
feature_gate,
|
||||||
fetch_all,
|
fetch_all,
|
||||||
fetch_one,
|
fetch_one,
|
||||||
get_paddle_price,
|
get_price_id,
|
||||||
utcnow_iso,
|
utcnow_iso,
|
||||||
)
|
)
|
||||||
from ..i18n import get_translations
|
from ..i18n import get_translations
|
||||||
@@ -687,7 +687,9 @@ async def export_details():
|
|||||||
@login_required
|
@login_required
|
||||||
@csrf_protect
|
@csrf_protect
|
||||||
async def export_checkout():
|
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
|
form = await request.form
|
||||||
scenario_id = form.get("scenario_id")
|
scenario_id = form.get("scenario_id")
|
||||||
language = form.get("language", "en")
|
language = form.get("language", "en")
|
||||||
@@ -703,23 +705,20 @@ async def export_checkout():
|
|||||||
if not scenario:
|
if not scenario:
|
||||||
return jsonify({"error": "Scenario not found."}), 404
|
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:
|
if not price_id:
|
||||||
return jsonify({"error": "Product not configured. Contact support."}), 500
|
return jsonify({"error": "Product not configured. Contact support."}), 500
|
||||||
|
|
||||||
return jsonify(
|
payload = _provider().build_checkout_payload(
|
||||||
{
|
price_id=price_id,
|
||||||
"items": [{"priceId": price_id, "quantity": 1}],
|
custom_data={
|
||||||
"customData": {
|
"user_id": str(g.user["id"]),
|
||||||
"user_id": str(g.user["id"]),
|
"scenario_id": str(scenario_id),
|
||||||
"scenario_id": str(scenario_id),
|
"language": language,
|
||||||
"language": language,
|
},
|
||||||
},
|
success_url=f"{config.BASE_URL}/planner/export/success",
|
||||||
"settings": {
|
|
||||||
"successUrl": f"{config.BASE_URL}/planner/export/success",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
)
|
)
|
||||||
|
return jsonify(payload)
|
||||||
|
|
||||||
|
|
||||||
@bp.route("/export/success")
|
@bp.route("/export/success")
|
||||||
|
|||||||
@@ -17,7 +17,8 @@ from ..core import (
|
|||||||
feature_gate,
|
feature_gate,
|
||||||
fetch_all,
|
fetch_all,
|
||||||
fetch_one,
|
fetch_one,
|
||||||
get_paddle_price,
|
get_all_price_ids,
|
||||||
|
get_price_id,
|
||||||
is_flag_enabled,
|
is_flag_enabled,
|
||||||
)
|
)
|
||||||
from ..i18n import get_translations
|
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"])
|
@bp.route("/signup/checkout", methods=["POST"])
|
||||||
@csrf_protect
|
@csrf_protect
|
||||||
async def signup_checkout():
|
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
|
form = await request.form
|
||||||
accumulated = _parse_accumulated(form)
|
accumulated = _parse_accumulated(form)
|
||||||
|
|
||||||
@@ -401,9 +404,9 @@ async def signup_checkout():
|
|||||||
if period == "yearly"
|
if period == "yearly"
|
||||||
else plan_info.get("paddle_key_monthly", plan)
|
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:
|
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
|
# Build items list
|
||||||
items = [{"priceId": plan_price_id, "quantity": 1}]
|
items = [{"priceId": plan_price_id, "quantity": 1}]
|
||||||
@@ -416,14 +419,14 @@ async def signup_checkout():
|
|||||||
|
|
||||||
for b in BOOST_OPTIONS:
|
for b in BOOST_OPTIONS:
|
||||||
if b["type"] in selected_boosts and b["type"] not in included_boosts:
|
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:
|
if price_id:
|
||||||
items.append({"priceId": price_id, "quantity": 1})
|
items.append({"priceId": price_id, "quantity": 1})
|
||||||
|
|
||||||
# Add credit pack (one-time)
|
# Add credit pack (one-time)
|
||||||
credit_pack = accumulated.get("credit_pack", "")
|
credit_pack = accumulated.get("credit_pack", "")
|
||||||
if credit_pack:
|
if credit_pack:
|
||||||
price_id = await get_paddle_price(credit_pack)
|
price_id = await get_price_id(credit_pack)
|
||||||
if price_id:
|
if price_id:
|
||||||
items.append({"priceId": price_id, "quantity": 1})
|
items.append({"priceId": price_id, "quantity": 1})
|
||||||
|
|
||||||
@@ -477,15 +480,12 @@ async def signup_checkout():
|
|||||||
"plan": plan,
|
"plan": plan,
|
||||||
}
|
}
|
||||||
|
|
||||||
return jsonify(
|
payload = _provider().build_multi_item_checkout_payload(
|
||||||
{
|
items=items,
|
||||||
"items": items,
|
custom_data=custom_data,
|
||||||
"customData": custom_data,
|
success_url=f"{config.BASE_URL}/suppliers/signup/success",
|
||||||
"settings": {
|
|
||||||
"successUrl": f"{config.BASE_URL}/suppliers/signup/success",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
)
|
)
|
||||||
|
return jsonify(payload)
|
||||||
|
|
||||||
|
|
||||||
@bp.route("/claim/<slug>")
|
@bp.route("/claim/<slug>")
|
||||||
@@ -1035,12 +1035,8 @@ async def dashboard_boosts():
|
|||||||
(supplier["id"],),
|
(supplier["id"],),
|
||||||
)
|
)
|
||||||
|
|
||||||
# Resolve Paddle price IDs for buy buttons
|
# Resolve price IDs for buy buttons (from active provider)
|
||||||
price_ids = {}
|
price_ids = await get_all_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"])
|
|
||||||
|
|
||||||
return await render_template(
|
return await render_template(
|
||||||
"suppliers/partials/dashboard_boosts.html",
|
"suppliers/partials/dashboard_boosts.html",
|
||||||
|
|||||||
Reference in New Issue
Block a user