部署在Heroku的Python应用无法唤起Stripe支付页面问题求助
问题
我正尝试在Flutter Web应用中集成Stripe支付功能,为此编写了Python(Flask)脚本并部署在Heroku上。后端代码如下:
import json import os import stripe from flask import Flask, render_template, jsonify, request from flask_cors import CORS # This is your test secret API key. stripe.api_key = 'sk_test_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX' app = Flask(__name__, static_folder='public',static_url_path='', template_folder='public') CORS(app) app.config['CORS_HEADERS'] = 'Content-Type' def calculate_order_amount(items): # Replace this constant with a calculation of the order's amount # Calculate the order total on the server to prevent # people from directly manipulating the amount on the client return 1400 @app.route('/create-payment-intent', methods=['POST']) def create_payment(): print('Processing checkout') request_data = request.data request_data = json.loads(request_data.decode('utf-8')) print(request_data) try: parking = request_data['parking'] items = [ { 'price_data': { 'currency':'aud', 'product_data': { 'name': parking['name'], }, 'unit_amount': parking['amount'], }, 'quantity':1, } ], print(request.data) # Create a PaymentIntent with the order amount and currency intent = stripe.PaymentIntent.create( amount=40*100, currency='aud', payment_method_types=["card"], ) return jsonify({ 'clientSecret': intent['client_secret'] }) except Exception as e: print('Error Occured: {}'.format(e)) return jsonify(error=str(e)), 403 if __name__ == '__main__': app.run(port=4242)
Flutter端请求代码如下:
var url = Uri.parse('https://spaceshuttleparking-checkout.herokuapp.com/create-payment-intent'); final response = await http.post( headers:{ "Accept": "application/json", "Access-Control-Allow-Origin": "*" }, url, body: json.encode( { 'parking':{ 'name':parking.name, 'amount':parking.amount, } } )).then((value) { print(value.body); print(value.statusCode); print(value.request); });
Flutter端已成功获取200状态码响应及clientSecret,Heroku日志也显示请求处理正常,但Stripe支付页面始终无法打开。作为新手,不清楚遗漏了什么环节,请问无法唤起支付页面的原因是什么?
分析与解决
你已经完成了后端创建PaymentIntent并返回clientSecret的核心步骤,但Flutter端仅获取了clientSecret,没有调用Stripe SDK来初始化并唤起支付界面,这是导致支付页面无法打开的核心原因。此外还有一些细节需要调整:
1. Flutter端缺少Stripe支付唤起逻辑
目前你的Flutter代码只做了请求clientSecret的操作,没有集成Stripe的Flutter SDK来完成后续支付流程。需要按以下步骤补充:
- 在
pubspec.yaml中添加flutter_stripe依赖 - 在应用启动时初始化Stripe(传入你的Stripe公钥)
- 使用获取到的clientSecret,初始化并唤起支付表单
示例代码片段:
// 应用启动时初始化Stripe await Stripe.instance.initialize( publishableKey: 'pk_test_你的Stripe公钥', ); // 获取到clientSecret后,初始化支付表单 final paymentSheetParams = SetupPaymentSheetParameters( paymentIntentClientSecret: clientSecret, // 从后端接口拿到的clientSecret merchantDisplayName: '你的商家名称', ); await Stripe.instance.initPaymentSheet(paymentSheetParameters: paymentSheetParams); // 唤起支付页面 try { await Stripe.instance.presentPaymentSheet(); // 支付成功后的逻辑,比如跳转成功页面、更新订单状态 } catch (e) { // 处理支付失败或用户取消的情况 }
2. 后端代码的冗余与硬编码问题
- 你定义了
items变量但没有在PaymentIntent.create中使用,完全可以删除这部分冗余代码 amount字段硬编码为40*100,没有使用前端传过来的parking['amount'],这会导致实际支付金额和你预期的不一致,建议修改为:
intent = stripe.PaymentIntent.create( amount=parking['amount'], # 注意确保parking['amount']是分单位(比如1400代表14澳元) currency='aud', payment_method_types=["card"], )
3. Flutter请求头的冗余设置
Access-Control-Allow-Origin是后端需要返回的响应头,前端请求时不需要设置这个字段,可以从请求头中移除,避免不必要的错误。
内容的提问来源于stack exchange,提问作者Danish Ajaib
相关产品推荐
相关产品推荐

