update pay function

This commit is contained in:
2025-11-20 07:46:50 +08:00
parent f515dc94f4
commit 4a1157c0b6
3 changed files with 285 additions and 48 deletions

76
app.py
View File

@@ -1323,40 +1323,96 @@ def calculate_subscription_price_simple(user_id, to_plan_name, to_cycle, promo_c
if price <= 0:
return {'error': f'{to_cycle} 周期价格未配置'}
# 4. 判断是新购还是续费
# 4. 判断订阅类型和计算价格
is_renewal = False
is_upgrade = False
is_downgrade = False
subscription_type = 'new'
current_plan = None
current_cycle = None
remaining_value = 0
final_price = price
if current_sub and current_sub.subscription_type in ['pro', 'max']:
# 如果当前是付费用户,则为续费
is_renewal = True
subscription_type = 'renew'
current_plan = current_sub.subscription_type
current_cycle = current_sub.billing_cycle
# 5. 构建结果(续费和新购价格完全一致)
if current_plan == to_plan_name:
# 同级续费:延长时长,全价购买
is_renewal = True
subscription_type = 'renew'
elif current_plan == 'pro' and to_plan_name == 'max':
# 升级Pro → Max需要计算差价
is_upgrade = True
subscription_type = 'upgrade'
# 计算当前订阅的剩余价值
if current_sub.end_date and current_sub.end_date > datetime.utcnow():
# 获取当前套餐的原始价格
current_plan_obj = SubscriptionPlan.query.filter_by(name=current_plan, is_active=True).first()
if current_plan_obj and current_plan_obj.pricing_options:
try:
pricing_opts = json.loads(current_plan_obj.pricing_options)
current_price = None
for opt in pricing_opts:
if opt.get('cycle_key') == current_cycle:
current_price = float(opt.get('price', 0))
break
if current_price and current_price > 0:
# 计算剩余天数
remaining_days = (current_sub.end_date - datetime.utcnow()).days
# 计算总天数
cycle_days_map = {
'monthly': 30,
'quarterly': 90,
'semiannual': 180,
'yearly': 365
}
total_days = cycle_days_map.get(current_cycle, 30)
# 计算剩余价值
if total_days > 0 and remaining_days > 0:
remaining_value = current_price * (remaining_days / total_days)
# 实付金额 = 新套餐价格 - 剩余价值
final_price = max(0, price - remaining_value)
except:
pass
elif current_plan == 'max' and to_plan_name == 'pro':
# 降级Max → Pro到期后切换全价购买
is_downgrade = True
subscription_type = 'downgrade'
else:
# 其他情况视为新购
subscription_type = 'new'
# 5. 构建结果
result = {
'is_renewal': is_renewal,
'is_upgrade': is_upgrade,
'is_downgrade': is_downgrade,
'subscription_type': subscription_type,
'current_plan': current_plan,
'current_cycle': current_cycle,
'new_plan_price': price,
'original_price': price, # 新套餐原价
'remaining_value': remaining_value, # 当前订阅剩余价值(仅升级时有效)
'original_amount': price,
'discount_amount': 0,
'final_amount': price,
'final_amount': final_price,
'promo_code': None,
'promo_error': None
}
# 6. 应用优惠码
# 6. 应用优惠码(基于差价后的金额)
if promo_code and promo_code.strip():
promo, error = validate_promo_code(promo_code, to_plan_name, to_cycle, price, user_id)
# 优惠码作用于差价后的金额
promo, error = validate_promo_code(promo_code, to_plan_name, to_cycle, final_price, user_id)
if promo:
discount = calculate_discount(promo, price)
discount = calculate_discount(promo, final_price)
result['discount_amount'] = float(discount)
result['final_amount'] = price - float(discount)
result['final_amount'] = final_price - float(discount)
result['promo_code'] = promo.code
elif error:
result['promo_error'] = error