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

Django集成Stripe时Checkout Session的payment_intent为null问题求助

问题

我已成功创建Stripe Checkout Session,但查看payment_intent值时发现其为null。我需要将该值保存至Order对象,以便在支付成功的处理视图中关联对应订单。

创建Checkout Session的视图代码

@csrf_exempt
def create_checkout_session(request,id):
    request_data = json.loads(request.body)
    order = Order.objects.filter(id = id).last()

    stripe.api_key = PaymentConfig.objects.all().last().stripe_secret_key
    checkout_session = stripe.checkout.Session.create(
        # Customer Email is optional,
        # It is not safe to accept email directly from the client side
        customer_email=request_data['email'],
        payment_method_types=['card'],
        line_items=[
            {
                'price_data': {
                    'currency': str(order.amount_type.lower()),
                    'product_data': {
                        'name': order.plan.title,
                    },
                    'unit_amount': int(order.amount * 100),
                },
                'quantity': 1,
            }
        ],
        mode='payment',
        success_url=request.build_absolute_uri(
            reverse('paymentsuccess')
        ) + "?session_id={CHECKOUT_SESSION_ID}",
        cancel_url=request.build_absolute_uri(reverse('paymentfailed')),
    )

    order.stripe_payment_intent = checkout_session['payment_intent']
    print(payment_intent) -- **null value**
    order.save()
    return JsonResponse({'sessionId':checkout_session.id})

支付成功处理视图代码

class PaymentSuccessView(TemplateView):
    template_name = "v3/payment-successful.html"

    def get(self, request, *args, **kwargs):
        session_id = request.GET.get('session_id')

        if session_id is None:
            return HttpResponseNotFound()

        stripe.api_key = PaymentConfig.objects.all().last().stripe_secret_key
        session = stripe.checkout.Session.retrieve(session_id)
        order = get_object_or_404(Order, stripe_payment_intent=session.payment_intent) --**HERE**
        call=AfterPaymentBackend(request, order.id)
        ctx = {
            'order':order,
            'siteInfo':Company.objects.all().last()
        }
        return render(request, self.template_name, ctx)

我已尝试咨询ChatGPT、谷歌搜索,甚至部署后测试,问题仍未解决,请问我忽略了什么?


解决方案

核心原因

创建Checkout Session的瞬间,payment_intent字段确实为null——这是Stripe的正常机制:该字段仅在用户完成支付后才会生成并填充到会话对象中,会话创建阶段不会提前生成。

修正方案

方案1:改用Session ID直接关联订单(快速解决)

  1. 在Order模型中新增stripe_session_id字段(存储Checkout Session的ID)
  2. 修改创建会话的代码,保存Session ID而非payment_intent:
# 创建会话后替换原有赋值逻辑
order.stripe_session_id = checkout_session.id
order.save()
  1. 支付成功视图中通过Session ID查询订单:
# 替换支付成功视图的查询逻辑
session = stripe.checkout.Session.retrieve(session_id)
order = get_object_or_404(Order, stripe_session_id=session_id)

方案2:通过Webhook获取Payment Intent(生产环境推荐)

Webhook是Stripe官方推荐的支付状态同步方式,可靠性更高:

  1. 在Stripe后台配置checkout.session.completed事件的Webhook端点,获取Webhook密钥
  2. 编写Webhook处理视图:
@csrf_exempt
def stripe_webhook(request):
    stripe.api_key = PaymentConfig.objects.all().last().stripe_secret_key
    payload = request.body
    sig_header = request.META.get('HTTP_STRIPE_SIGNATURE')
    endpoint_secret = "你的Stripe Webhook密钥"

    try:
        event = stripe.Webhook.construct_event(payload, sig_header, endpoint_secret)
    except (ValueError, stripe.error.SignatureVerificationError):
        return HttpResponse(status=400)

    if event['type'] == 'checkout.session.completed':
        session = event['data']['object']
        # 通过metadata获取订单ID(需在创建会话时传入)
        order_id = session['metadata']['order_id']
        order = Order.objects.get(id=order_id)
        # 此时session['payment_intent']已存在
        order.stripe_payment_intent = session['payment_intent']
        order.save()
        # 执行支付成功后的业务逻辑
        AfterPaymentBackend(request, order.id)

    return HttpResponse(status=200)
  1. 创建Checkout Session时添加metadata传递订单ID:
checkout_session = stripe.checkout.Session.create(
    # 原有参数保持不变
    metadata={
        'order_id': str(order.id)
    },
)

额外注意事项

  • 禁止依赖前端传递的信息关联订单,必须使用Stripe返回的可靠标识(Session ID或Webhook事件数据)
  • 生产环境必须验证Webhook签名,防止伪造请求

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 00:33:22