ai_v/blueprints/payment.py
公司git 67f2621a69 feat(payment): 集成支付宝支付与订单管理功能
- 在应用中注册支付蓝图(payment_bp)以支持支付接口
- 配置支付宝相关秘钥、回调地址及环境选项
- 新增订单模型(Order),支持订单数据存储与管理
- 管理后台接口添加订单列表查询功能,支持超级管理员访问
- 购买页面与表单修改,支持不同套餐的购买提交
- 支付成功页面提示,显示订单编号及积分到账信息
- 移除买积分按钮禁用逻辑,开放购买功能
2026-01-14 17:00:43 +08:00

112 lines
3.5 KiB
Python

from flask import Blueprint, request, redirect, url_for, session, jsonify, render_template
from extensions import db
from models import Order, User
from services.alipay_service import AlipayService
import uuid
from datetime import datetime
payment_bp = Blueprint('payment', __name__, url_prefix='/payment')
# 积分价格配置
POINTS_PACKAGES = {
'50': {'points': 50, 'amount': 5.00},
'200': {'points': 200, 'amount': 20.00},
'1000': {'points': 1000, 'amount': 100.00},
'5000': {'points': 5000, 'amount': 500.00},
}
@payment_bp.route('/create', methods=['POST'])
def create_payment():
if 'user_id' not in session:
return jsonify({'code': 401, 'msg': '请先登录'}), 401
package_id = request.form.get('package_id')
if package_id not in POINTS_PACKAGES:
return jsonify({'code': 400, 'msg': '无效的套餐'}), 400
package = POINTS_PACKAGES[package_id]
user_id = session['user_id']
# 生成唯一订单号 (时间戳 + 随机位)
out_trade_no = datetime.now().strftime('%Y%m%d%H%M%S') + str(uuid.uuid4().hex[:6])
# 创建订单记录
try:
order = Order(
out_trade_no=out_trade_no,
user_id=user_id,
amount=package['amount'],
points=package['points'],
status='PENDING'
)
db.session.add(order)
db.session.commit()
except Exception as e:
db.session.rollback()
return f"订单创建失败: {str(e)}", 500
# 获取支付链接
try:
alipay_service = AlipayService()
pay_url = alipay_service.create_order_url(
out_trade_no=out_trade_no,
total_amount=package['amount'],
subject=f"购买{package['points']}积分"
)
return redirect(pay_url)
except Exception as e:
return f"支付链接生成失败: {str(e)}", 500
@payment_bp.route('/return')
def payment_return():
"""支付成功后的同步跳转页面"""
data = request.args.to_dict()
signature = data.pop("sign", None)
if not signature:
return "参数错误", 400
alipay_service = AlipayService()
success = alipay_service.verify_notify(data, signature)
out_trade_no = data.get('out_trade_no')
order = Order.query.filter_by(out_trade_no=out_trade_no).first()
if success:
# 同步通知仅用于页面展示,实际业务逻辑在异步通知 notify 中处理
return render_template('buy.html', success=True, order=order)
else:
return "支付验证失败", 400
@payment_bp.route('/notify', methods=['POST'])
def payment_notify():
"""支付宝异步通知"""
data = request.form.to_dict()
signature = data.pop("sign", None)
if not signature:
return "fail"
alipay_service = AlipayService()
success = alipay_service.verify_notify(data, signature)
if success and data.get('trade_status') in ['TRADE_SUCCESS', 'TRADE_FINISHED']:
out_trade_no = data.get('out_trade_no')
trade_no = data.get('trade_no')
order = Order.query.filter_by(out_trade_no=out_trade_no).first()
if order and order.status == 'PENDING':
order.status = 'PAID'
order.trade_no = trade_no
order.paid_at = datetime.utcnow()
# 给用户加积分
user = User.query.get(order.user_id)
if user:
user.points += order.points
db.session.commit()
return "success"
return "fail"