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

请求指导Django集成Stripe自定义支付流程及用户信息处理

Django集成Stripe自定义支付流完整指南

1. 后端核心逻辑:创建支付意图与用户信息存储

首先需要在Django后端实现两个核心接口:生成Stripe Payment Intent的接口,以及接收Stripe支付状态通知的Webhook接口,同时要设计订单模型来存储用户信息和支付关联数据。

定义订单模型

先创建一个Order模型,用来保存用户信息、商品详情和支付状态:

# models.py
from django.db import models

class Order(models.Model):
    STATUS_CHOICES = (
        ('pending', '待支付'),
        ('paid', '已支付'),
        ('failed', '支付失败'),
    )
    customer_name = models.CharField(max_length=100)
    customer_email = models.EmailField()
    customer_phone = models.CharField(max_length=20)
    item_id = models.CharField(max_length=50)  # 对应你商品的唯一标识,比如"xl-tshirt"
    amount = models.IntegerField()  # 金额单位为分(Stripe要求)
    stripe_payment_intent_id = models.CharField(max_length=100, blank=True)
    status = models.CharField(max_length=20, choices=STATUS_CHOICES, default='pending')
    created_at = models.DateTimeField(auto_now_add=True)

实现Payment Intent创建接口

这个接口负责接收前端传来的用户信息和商品ID,创建订单记录,并生成Stripe支付意图:

# views.py
import stripe
from django.conf import settings
from django.http import JsonResponse
from django.views.decorators.csrf import csrf_exempt
from .models import Order

stripe.api_key = settings.STRIPE_SECRET_KEY

@csrf_exempt
def create_payment_intent(request):
    if request.method != 'POST':
        return JsonResponse({'error': '仅支持POST请求'}, status=405)
    
    # 提取前端提交的用户信息和商品ID
    data = request.POST
    customer_name = data.get('customer_name')
    customer_email = data.get('customer_email')
    customer_phone = data.get('customer_phone')
    item_id = data.get('item_id')
    
    # 根据商品ID获取对应金额(实际项目中建议从商品数据库读取)
    item_amount_map = {
        'xl-tshirt': 2000,  # 代表20美元
        # 可添加更多商品配置
    }
    amount = item_amount_map.get(item_id, 0)
    if amount == 0:
        return JsonResponse({'error': '无效的商品ID'}, status=400)
    
    # 创建订单记录,保存用户信息
    order = Order.objects.create(
        customer_name=customer_name,
        customer_email=customer_email,
        customer_phone=customer_phone,
        item_id=item_id,
        amount=amount
    )
    
    # 生成Stripe Payment Intent
    try:
        payment_intent = stripe.PaymentIntent.create(
            amount=amount,
            currency='usd',
            metadata={
                'order_id': order.id,  # 关联订单ID,方便后续Webhook更新状态
                'item_id': item_id
            }
        )
        # 更新订单的支付意图ID
        order.stripe_payment_intent_id = payment_intent.id
        order.save()
        
        return JsonResponse({'clientSecret': payment_intent.client_secret})
    except stripe.error.StripeError as e:
        return JsonResponse({'error': str(e)}, status=400)

配置接口路由

在urls.py中添加对应路由:

# urls.py
from django.urls import path
from . import views

urlpatterns = [
    path('create-payment-intent/', views.create_payment_intent, name='create_payment_intent'),
    # 其他路由...
]

2. 前端自定义结账页面实现

前端需要完成商品展示、用户信息收集、Stripe支付表单渲染,以及提交数据到后端的逻辑:

<!-- checkout.html 自定义结账页面 -->
<!DOCTYPE html>
<html>
<head>
    <title>确认订单与支付</title>
    <script src="https://js.stripe.com/v3/"></script>
</head>
<body>
    <!-- 商品详情区域 -->
    <div class="product-card">
        <h2>XL纯棉T恤</h2>
        <p>价格:$20.00</p>
        <input type="hidden" id="item-id" value="xl-tshirt">
    </div>

    <!-- 用户信息收集表单 -->
    <form id="customer-form">
        <div>
            <label>姓名:</label>
            <input type="text" id="customer-name" required>
        </div>
        <div>
            <label>邮箱:</label>
            <input type="email" id="customer-email" required>
        </div>
        <div>
            <label>电话:</label>
            <input type="tel" id="customer-phone" required>
        </div>
    </form>

    <!-- Stripe支付元素容器 -->
    <div id="payment-element"></div>
    <button id="pay-btn">完成支付</button>

    <div id="error-message"></div>

    <script>
        // 初始化Stripe,替换为你的公钥
        const stripe = Stripe('pk_test_your_public_key');
        const elements = stripe.elements();

        // 渲染支付表单
        const paymentElement = elements.create('payment');
        paymentElement.mount('#payment-element');

        const payBtn = document.getElementById('pay-btn');
        const itemId = document.getElementById('item-id').value;

        payBtn.addEventListener('click', async (e) => {
            e.preventDefault();
            payBtn.disabled = true;

            // 收集用户表单数据
            const customerName = document.getElementById('customer-name').value;
            const customerEmail = document.getElementById('customer-email').value;
            const customerPhone = document.getElementById('customer-phone').value;

            // 向后端请求生成支付意图
            const response = await fetch('/create-payment-intent/', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/x-www-form-urlencoded',
                },
                body: new URLSearchParams({
                    customer_name: customerName,
                    customer_email: customerEmail,
                    customer_phone: customerPhone,
                    item_id: itemId
                })
            });

            const data = await response.json();
            if (data.error) {
                document.getElementById('error-message').textContent = data.error;
                payBtn.disabled = false;
                return;
            }

            // 确认支付
            const { error } = await stripe.confirmPayment({
                elements,
                clientSecret: data.clientSecret,
                confirmParams: {
                    return_url: 'https://your-domain.com/payment-success/',  // 支付成功跳转页
                },
            });

            if (error) {
                document.getElementById('error-message').textContent = error.message;
                payBtn.disabled = false;
            }
        });
    </script>
</body>
</html>

3. 配置Stripe Webhook更新支付状态

为了确保支付状态的准确性,必须通过Stripe Webhook监听支付事件,更新本地订单状态:

实现Webhook接口

# views.py
@csrf_exempt
def stripe_webhook(request):
    payload = request.body
    sig_header = request.META.get('HTTP_STRIPE_SIGNATURE')
    event = None

    try:
        event = stripe.Webhook.construct_event(
            payload, sig_header, settings.STRIPE_WEBHOOK_SECRET
        )
    except (ValueError, stripe.error.SignatureVerificationError):
        return JsonResponse({'error': '验证失败'}, status=400)

    # 处理支付成功事件
    if event['type'] == 'payment_intent.succeeded':
        payment_intent = event['data']['object']
        order_id = payment_intent['metadata']['order_id']
        try:
            order = Order.objects.get(id=order_id)
            order.status = 'paid'
            order.save()
            # 这里可添加发送确认邮件、生成订单凭证等后续逻辑
        except Order.DoesNotExist:
            pass

    # 处理支付失败事件
    elif event['type'] == 'payment_intent.payment_failed':
        payment_intent = event['data']['object']
        order_id = payment_intent['metadata']['order_id']
        try:
            order = Order.objects.get(id=order_id)
            order.status = 'failed'
            order.save()
        except Order.DoesNotExist:
            pass

    return JsonResponse({'status': 'success'})

添加Webhook路由

# urls.py
urlpatterns += [
    path('stripe-webhook/', views.stripe_webhook, name='stripe_webhook'),
]

最后在Stripe后台配置Webhook端点,指向你的域名/stripe-webhook/,并监听payment_intent.succeeded和payment_intent.payment_failed事件,将生成的Webhook Secret配置到Django的settings.py中。

用户信息处理说明

  • 收集:通过前端自定义表单收集用户姓名、邮箱、电话等信息,和商品ID一起提交到后端。
  • 存储:后端接口接收数据后,直接写入Order模型,完成用户信息与订单的绑定。
  • 关联支付:创建Payment Intent时,通过metadata字段将订单ID传递给Stripe,确保Webhook能准确关联到对应订单。
  • 后续使用:支付成功后,可通过Order记录中的用户信息发送确认通知、生成订单详情页等。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 17:12:04