如何在Stripe支付完成后执行Python的CSV处理函数并匹配对应文件?
解决方案:关联CSV文件与Stripe支付并触发后续处理
核心思路是给每个用户上传的CSV生成唯一标识,将其绑定到Stripe支付会话中,待支付完成的Webhook事件触发时,通过这个标识找到对应的CSV文件,再执行数据补充和邮件发送逻辑。
1. 给CSV生成唯一标识并关联Stripe支付会话
用户上传CSV后,先完成以下操作:
- 生成一个唯一的
job_id(推荐用UUID),用来标记本次任务; - 将
job_id、CSV文件存储路径、用户邮箱、任务状态(初始设为pending)存入数据库; - 创建Stripe支付会话时,把
job_id放到会话的metadata字段中——Stripe会在后续的Webhook事件里返回这个元数据。
示例代码:
import stripe from uuid import uuid4 from your_app import db, Job # 假设你有Job模型和数据库实例 @app.route('/upload-csv', methods=['POST']) def upload_csv(): # 处理用户CSV上传(你的现有代码) uploaded_file = request.files['csv_file'] user_email = request.form['email'] # 存储文件到本地或对象存储,获取路径 file_path = f"/path/to/storage/{uuid4().hex}.csv" uploaded_file.save(file_path) # 生成唯一job_id并写入数据库 job_id = uuid4().hex new_job = Job( id=job_id, file_path=file_path, user_email=user_email, status='pending' ) db.session.add(new_job) db.session.commit() # 创建Stripe支付会话,绑定job_id stripe.api_key = "你的Stripe密钥" checkout_session = stripe.checkout.Session.create( payment_method_types=['card'], line_items=[{ 'price_data': { 'currency': 'usd', 'product_data': {'name': 'CSV数据补充服务'}, 'unit_amount': 500 # 5美元,单位为分 }, 'quantity': 1 }], mode='payment', success_url='https://your-domain.com/payment-success', cancel_url='https://your-domain.com/payment-cancel', metadata={'job_id': job_id} # 关键:绑定任务ID ) # 返回会话ID给前端跳转支付页面 return jsonify({'sessionId': checkout_session.id})
2. 通过Webhook接收支付完成事件并处理CSV
配置Stripe Webhook监听checkout.session.completed事件(该事件触发代表用户支付成功),在Flask路由中完成以下步骤:
- 验证Stripe请求签名(必须做,防止伪造请求);
- 从事件数据中取出
metadata里的job_id; - 通过
job_id从数据库找到对应的CSV文件和用户信息; - 执行你的数据补充和邮件发送逻辑,最后更新任务状态。
示例代码:
from flask import request, jsonify import stripe @app.route('/stripe-webhook', methods=['POST']) def stripe_webhook(): payload = request.get_data(as_text=True) sig_header = request.headers.get('Stripe-Signature') webhook_secret = "你的Stripe Webhook密钥" # 验证Stripe请求合法性 try: event = stripe.Webhook.construct_event( payload, sig_header, webhook_secret ) except (ValueError, stripe.error.SignatureVerificationError): return jsonify({'error': 'Invalid request'}), 400 # 处理支付完成事件 if event['type'] == 'checkout.session.completed': session = event['data']['object'] job_id = session['metadata'].get('job_id') if not job_id: return jsonify({'error': 'Missing job_id'}), 400 # 从数据库获取任务信息 job = Job.query.get(job_id) if not job or job.status != 'pending': return jsonify({'error': 'Invalid or processed job'}), 400 # 执行你的数据补充逻辑(调用已实现的函数) enriched_file_path = enrich_csv_data(job.file_path) # 发送邮件给用户(调用已实现的函数) send_enriched_csv_email(job.user_email, enriched_file_path) # 更新任务状态为已完成 job.status = 'completed' db.session.commit() return jsonify({'status': 'success'}), 200
3. 关键注意事项
- 签名验证:绝对不能跳过Stripe Webhook的签名验证,否则恶意攻击者可以伪造支付完成事件触发你的逻辑;
- 幂等性处理:Stripe可能会重复发送同一事件,所以处理逻辑要保证幂等——比如通过检查任务状态(
pending才处理)避免重复执行; - 文件存储:如果用户上传大文件,建议用对象存储(如S3)而非服务器本地,避免磁盘空间不足;
- 超时清理:可以定时清理数据库中状态为
pending且超过一定时间(如24小时)的任务,删除对应的CSV文件,节省存储资源。
内容的提问来源于stack exchange,提问作者user2379921
相关产品推荐
相关产品推荐

