Python中stripe.checkout.Session.create未触发问题排查求助
问题分析与解决
核心问题:异步函数中调用同步Stripe方法阻塞事件循环
Stripe Python SDK的所有方法都是同步阻塞的,你在async def payments这个异步函数里直接调用stripe.checkout.Session.create(),会卡住Flask的异步事件循环,导致程序挂起,这就是你感觉该方法没触发的根本原因。
其他关键问题
- 支付流程逻辑错误:创建Checkout Session后,你没有将Stripe返回的支付会话URL返回给前端,前端无法跳转到Stripe的支付页面,自然不会触发后续的success回调。当前代码在调用
payments后直接redirect到dashboard,完全跳过了用户支付的步骤。 payments函数无返回值:作为被await的异步函数,它没有任何返回内容,也没有向前端输出响应,导致请求一直处于挂起状态。- 重复解析请求体:在
signup和payments中两次调用request.get_json(),属于冗余操作,建议直接将解析后的data传入payments。
修复方案
1. 处理同步Stripe方法的阻塞问题
有两种可行方式:
- 方式一:将
payments改为同步函数:如果你的路由不需要异步特性,直接去掉async修饰符,调用时也无需await:
def payments(request): data = request.get_json() plan = data.get('submitObj', {}).get('plan') email = data.get('submitObj', {}).get('email') price_id = '' if plan == 'Bronze': price_id = 'bronze_test' elif plan == 'Silver': price_id = 'silver_test' elif plan == 'Gold': price_id = 'gold_test' session = stripe.checkout.Session.create( success_url='http://127.0.0.1:5000/subscribe/success?session_id={CHECKOUT_SESSION_ID}', cancel_url='http://127.0.0.1:5000/subscribe/cancel', mode='subscription', line_items=[{ 'price': price_id, 'quantity': 1 }], customer_email=email ) return jsonify({'url': session.url})
调用时改为:payment_response = payments(request)
- 方式二:用线程池运行同步Stripe方法:如果必须保留异步路由,使用
asyncio.to_thread()将同步的Stripe调用放到线程池中执行,避免阻塞事件循环:
import asyncio async def payments(request): data = request.get_json() plan = data.get('submitObj', {}).get('plan') email = data.get('submitObj', {}).get('email') price_id = '' if plan == 'Bronze': price_id = 'bronze_test' elif plan == 'Silver': price_id = 'silver_test' elif plan == 'Gold': price_id = 'gold_test' # 用线程池执行同步的Stripe方法 session = await asyncio.to_thread( stripe.checkout.Session.create, success_url='http://127.0.0.1:5000/subscribe/success?session_id={CHECKOUT_SESSION_ID}', cancel_url='http://127.0.0.1:5000/subscribe/cancel', mode='subscription', line_items=[{ 'price': price_id, 'quantity': 1 }], customer_email=email ) # 返回Stripe会话的URL给前端 return jsonify({'url': session.url})
2. 修正前端跳转逻辑
在signup的POST路由中,不能直接redirect,而是要接收payments返回的支付URL,让前端跳转到该URL:
@app.route('/signup', methods=['GET', 'POST']) async def signup(): if 'email' in session: return redirect(url_for('dashboard')) else: if request.method == 'POST': data = request.get_json() await insertSignUp(request) # 获取支付会话URL并返回给前端 payment_response = await payments(request) return payment_response # GET请求逻辑保持不变 plan = request.args.get('plan') return render_template('sign-up.html', plan=plan)
3. 验证Stripe基础配置
确保你已正确设置Stripe API密钥:
import stripe stripe.api_key = "sk_test_你的测试密钥"
4. 测试支付流程
使用Stripe测试卡号4242 4242 4242 4242(任意过期日期、CVC)完成支付,验证subscribe_success路由是否正常触发。
内容的提问来源于stack exchange,提问作者bobthebuilder
相关产品推荐
相关产品推荐

