Flask集成Stripe支付遇400错误:请求Content-Type非application/json
解决Flask接收Stripe结账JSON数据时的400 Bad Request错误
你遇到的400错误核心原因有两个:表单默认提交行为干扰了fetch请求,同时Flask后端的路由配置和响应逻辑也存在问题。以下是具体修复步骤:
1. 阻止表单默认提交行为
按钮放在<form>标签内时,点击会触发表单的默认POST提交,这个请求的Content-Type是application/x-www-form-urlencoded,直接覆盖了你用fetch发送的JSON请求。修改前端代码如下:
修正HTML按钮
<body> <form action="/checkout" method="POST"> <!-- 添加event参数传递给checkout函数 --> <button onclick="checkout(event)">Checkout</button> </form> </body>
修正JavaScript脚本
function checkout(event) { // 阻止表单默认提交行为,确保只有fetch请求发送 event.preventDefault(); const lineItems = [ { price: "price_1MmYqVHbLz6qKWZ5hrkATlX", quantity: 1, }, { price: "price_1MmYGHHbLz6qKWZ5rKteRTy", quantity: 2, }, ]; fetch("/checkout", { method: "POST", headers: { "Content-Type": "application/json", }, body: JSON.stringify(lineItems), }) .then(function (response) { if (!response.ok) throw new Error('请求失败'); return response.json(); }) .then(function (session) { return stripe.redirectToCheckout({ sessionId: session.id }); }) .then(function (result) { if (result.error) alert(result.error.message); }) .catch(function (error) { console.error("Error:", error); }); }
2. 修正Flask路由和响应逻辑
原代码缺少路由装饰器,且返回重定向的方式不匹配fetch请求的预期(前端需要拿到session ID自行跳转)。修改payment.py:
from flask import Flask, request, jsonify import stripe app = Flask(__name__) # 配置你的Stripe密钥 stripe.api_key = "你的Stripe密钥" DOMAIN = "http://localhost:5000" # 根据实际域名修改 # 必须指定POST方法,否则Flask默认只接受GET请求 @app.route('/checkout', methods=['POST']) def checkout(): try: request_data = request.get_json() if not request_data: return jsonify({'error': '未收到有效JSON数据'}), 400 line_items = [] for item in request_data: line_items.append({ 'price': item['price'], 'quantity': item['quantity'] }) checkout_session = stripe.checkout.Session.create( line_items=line_items, mode='payment', success_url=DOMAIN + '/success.html', cancel_url=DOMAIN + '/cancel.html', ) # 返回session ID的JSON数据,供前端调用Stripe跳转 return jsonify({'id': checkout_session.id}) except Exception as e: return jsonify({'error': str(e)}), 400 if __name__ == '__main__': app.run(port=5000, debug=True)
额外检查项
- 确认Stripe密钥配置正确,使用的Price ID是Stripe后台已存在的有效ID。
- 在浏览器开发者工具的Network面板中,查看fetch请求的Content-Type是否为
application/json,以及响应是否返回正确的session ID。
内容的提问来源于stack exchange,提问作者Sebastian Ong
相关产品推荐
相关产品推荐

