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

如何在Django Rest Framework中保存Stripe用户卡片信息用于后续交易

Stripe 存储用户支付信息实现免重复输卡方案(DRF 适配)

方案可行性

完全可行,但绝对不能自行存储用户银行卡信息(这会触发极其严格的PCI合规要求,操作成本极高且风险大)。正确的做法是利用Stripe的Customer对象托管用户支付方式:首次支付完成后,将用户的支付方式与专属的Stripe Customer绑定,后续交易直接调用已绑定的支付方式发起扣款,无需用户重复输入卡片信息,实现和Fiverr一致的体验。

前端需传入的信息

分两种业务场景:

首次支付(需绑定支付方式)

  • 支付金额(单位为对应货币的最小单位,比如1美元传100)
  • 货币类型(默认可设为usd)
  • 必传:Stripe前端SDK生成的payment_method_id(前端通过Stripe Elements收集卡信息后生成,禁止传递原始卡号、CVV等敏感数据)
  • 用户标识(登录状态下DRF可直接通过request.user获取,匿名用户需前端传唯一标识)

后续支付(已绑定支付方式)

  • 支付金额
  • 货币类型
  • 用户标识(用于关联对应的Stripe Customer)
  • 可选:payment_method_id(如果用户有多个绑定支付方式,需指定;否则默认使用用户的默认支付方式)

后端(DRF)响应内容

首次支付响应

{
  "client_secret": "pi_xxx_secret_xxx", // 前端用于完成支付确认
  "customer_id": "cus_xxx", // 绑定的Stripe Customer ID,可存入后端用户表
  "payment_method_id": "pm_xxx", // 绑定的支付方式ID,可选存储
  "payment_intent_id": "pi_xxx",
  "amount": 100
}

后续支付响应

{
  "client_secret": "pi_xxx_secret_xxx", // 前端直接用此发起扣款,无需收集卡信息
  "payment_intent_id": "pi_xxx",
  "amount": 200
}

DRF 改造后的核心代码示例

import stripe
from django.conf import settings
from rest_framework.response import Response
from rest_framework.views import APIView
from django.contrib.auth.models import User

# 从配置文件读取密钥,不要硬编码
stripe.api_key = settings.STRIPE_SECRET_KEY

class StripePaymentView(APIView):
    def post(self, request):
        user = request.user  # 假设用户已登录
        amount = request.data.get('amount')
        currency = request.data.get('currency', 'usd')
        payment_method_id = request.data.get('payment_method_id')

        # 首次支付:创建/关联Stripe Customer并绑定支付方式
        if payment_method_id:
            # 检查用户是否已有绑定的Stripe Customer
            if hasattr(user, 'stripe_customer_id') and user.stripe_customer_id:
                customer = stripe.Customer.retrieve(user.stripe_customer_id)
            else:
                # 创建新的Stripe Customer
                customer = stripe.Customer.create(email=user.email)
                # 将Customer ID存入用户表(需给User模型添加stripe_customer_id字段)
                user.stripe_customer_id = customer.id
                user.save()
            
            # 绑定支付方式到Customer
            stripe.PaymentMethod.attach(
                payment_method_id,
                customer=customer.id,
            )
            # 设置为默认支付方式(可选)
            stripe.Customer.modify(
                customer.id,
                invoice_settings={'default_payment_method': payment_method_id},
            )

            # 创建关联Customer的PaymentIntent
            intent = stripe.PaymentIntent.create(
                amount=amount,
                currency=currency,
                customer=customer.id,
                payment_method=payment_method_id,
                confirm=True,  # 可选自动确认,需前端处理3DS验证
                automatic_payment_methods={'enabled': True},
            )
        else:
            # 后续支付:使用已绑定的默认支付方式
            if not hasattr(user, 'stripe_customer_id') or not user.stripe_customer_id:
                return Response({'error': '用户未绑定支付方式'}, status=400)
            
            intent = stripe.PaymentIntent.create(
                amount=amount,
                currency=currency,
                customer=user.stripe_customer_id,
                payment_method='default',  # 使用默认支付方式
                confirm=True,
                automatic_payment_methods={'enabled': True},
            )
        
        # 返回响应数据
        response_data = {
            'client_secret': intent['client_secret'],
            'payment_intent_id': intent['id'],
            'amount': intent['amount'],
        }
        if hasattr(user, 'stripe_customer_id'):
            response_data['customer_id'] = user.stripe_customer_id
        
        return Response(response_data)

关键注意事项

  • 绝对禁止前端将原始卡号、CVV、过期日期等敏感信息传给后端,必须通过Stripe Elements或Stripe.js处理,仅传递payment_method_id
  • 需在Django用户模型中添加stripe_customer_id字段,用于关联Stripe的Customer对象
  • 若支付触发3DS验证,前端需调用stripe.confirmCardPayment完成验证流程
  • 所有支付方式托管在Stripe,无需自行处理PCI合规

内容的提问来源于stack exchange,提问作者Mossaddak

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 00:43:20