Flask Session触发KeyError求助,疑与Stripe变量名冲突
问题分析与解决方法
核心原因
你遇到的KeyError根本不是Flask和Stripe的session变量名冲突——Stripe的session是API返回的对象,和Flask的全局session对象完全隔离,不会互相覆盖。真正的问题是:Stripe Webhook的请求没有用户会话上下文。
Flask的session依赖用户浏览器携带的Cookie维持状态,但Webhook是Stripe服务器直接向你的后端发起的POST请求,这个请求里没有用户的Cookie,所以你的Flask应用在处理Webhook时,session是空的,自然取不出location和industry字段。
正确解决方案
不要把用户的业务数据存在Flask Session里等待Webhook读取,而是在创建Stripe Checkout Session的时候,把这些数据存入Stripe Session的metadata字段,之后在Webhook里直接从Stripe返回的Session对象中读取。
代码示例
- 创建Checkout Session时添加metadata:
@app.route('/create-checkout-session', methods=['POST']) def create_checkout_session(): # 从当前用户会话中获取location和industry location = session.get('location') industry = session.get('industry') # 创建Stripe Checkout Session,把数据存入metadata checkout_session = stripe.checkout.Session.create( payment_method_types=['card'], line_items=[{ 'price': 'price_xxxxxx', 'quantity': 1, }], mode='payment', success_url=url_for('success', _external=True), cancel_url=url_for('cancel', _external=True), # 关键:存入业务数据 metadata={ 'location': location, 'industry': industry } ) return jsonify({'id': checkout_session.id})
- Webhook处理时读取metadata:
@app.route('/webhook', methods=['POST']) def stripe_webhook(): payload = request.get_data(as_text=True) sig_header = request.headers.get('Stripe-Signature') event = None try: event = stripe.Webhook.construct_event( payload, sig_header, app.config['STRIPE_WEBHOOK_SECRET'] ) except ValueError as e: return '', 400 except stripe.error.SignatureVerificationError as e: return '', 400 # 处理checkout.session.completed事件 if event['type'] == 'checkout.session.completed': session = event['data']['object'] # 从Stripe Session的metadata中读取数据 location = session['metadata'].get('location') industry = session['metadata'].get('industry') # 后续处理逻辑... return '', 200
额外注意事项
- 确保创建Checkout Session时,
location和industry确实存在于Flask Session中(可以在创建前加个判断,避免存入None) - Stripe的metadata字段仅支持字符串类型数据,如果需要存复杂结构,先转成JSON字符串再存入,读取时再解析
内容的提问来源于stack exchange,提问作者Benjamin Morales Perez
相关产品推荐
相关产品推荐

