You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.01 07:45:37