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

Django+Stripe项目支付成功页面无法跳转问题排查

Django+Stripe支付成功后无法跳转至成功页面的问题排查与解决

我正在开发首个Django+Stripe测试项目,但目前遇到支付成功后无法跳转至成功页面的问题。以下是我的相关代码:

views.py 文件

import stripe
from django.conf import settings
from django.http import HttpResponse
from django.shortcuts import get_object_or_404
from django.views import View
from django.views.generic import TemplateView

from .models import Item

stripe.api_key = settings.STRIPE_SECRET_KEY


class ProductLandingPageView(TemplateView):
    template_name = 'landing.html'

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        item_id = self.kwargs["id"]
        item = get_object_or_404(Item, id=item_id)
        context['item'] = item
        return context


class CreateCheckoutSessionView(View):
    def get(self, request, *args, **kwargs):
        item_id = self.kwargs["id"]
        DOMAIN: str = 'http://127.0.0.1:8000'
        item = Item.objects.get(id=item_id)
        session = stripe.checkout.Session.create(
            payment_method_types=['card'],
            line_items=[
                {
                    'price_data': {
                        'currency': 'usd',
                        'unit_amount': item.price * 100,
                        'product_data': {
                            'name': item.name,
                        },
                    },
                    'quantity': 1,
                },
            ],
            payment_intent_data={
                'metadata': {
                    'item_id': item.id,
                },
            },
            mode='payment',
            success_url=DOMAIN + '/success/',
            cancel_url=DOMAIN + '/cancel/',
        )
        return HttpResponse(session.id)


class SuccessView(TemplateView):
    template_name = "success.html"


class CancelView(TemplateView):
    template_name = "cancel.html"

模板文件(landing.html)

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Homepage</title>
    <script src="https://js.stripe.com/v3/"></script>
</head>
<body>
    <div class="description">
        <h3>{{ item.name }}</h3>
        <h5>{{ item.display_price }} USD.</h5>
    </div>
    <button id="buy-button" data-item-id="{{ item.id }}">Buy</button>

    <script>
    document.getElementById('buy-button').addEventListener('click', function() {
  var itemId = this.getAttribute('data-item-id');
  fetch('/buy/' + itemId)
    .then(function(response) {
      return response.json();
    })
    .then(function(data) {
      var stripe = Stripe(data.stripe_public_key);
      stripe.redirectToCheckout({ sessionId: data.session_id });
    })
    .catch(function(error) {
      console.error('Ошибка:', error);
    });
});
  </script>

</body>
</html>

settings.py 相关配置

STRIPE_PUBLISHABLE_KEY = os.getenv('STRIPE_PUBLISHABLE_KEY')
STRIPE_SECRET_KEY = os.getenv('STRIPE_SECRET_KEY')

urls.py 配置

from api.views import CancelView, SuccessView, CreateCheckoutSessionView, ProductLandingPageView
from django.contrib import admin
from django.urls import path

urlpatterns = [
path('admin/', admin.site.urls),
path('item/<int:id>', ProductLandingPageView.as_view(), name='item'),
path('buy/<int:id>', CreateCheckoutSessionView.as_view(), name='buy'),
path('cancel/', CancelView.as_view(), name='cancel'),
path('success/', SuccessView.as_view(), name='success'),]

问题解决方法(更新)

通过修改前端JS代码,已解决支付成功后无法跳转的问题,修正后的代码如下:

<script>
    document.getElementById('buy-button').addEventListener('click', function() {
  var itemId = this.getAttribute('data-item-id');
  var stripe = Stripe("{{ STRIPE_PUBLIC_KEY }}");
  fetch('/buy/' + itemId)
    .then(function(response) {
      return response.json();
    })
    .then(function (session) {
      return stripe.redirectToCheckout({ sessionId: session.id });
    })
    .catch(function(error) {
      console.error('Ошибка:', error);
    });
});
</script>

额外优化建议

  • 修正视图返回格式:原CreateCheckoutSessionView返回纯文本session.id,但前端用response.json()解析会报错,需改为返回JSON格式:
from django.http import JsonResponse

class CreateCheckoutSessionView(View):
    def get(self, request, *args, **kwargs):
        # 原有逻辑不变
        return JsonResponse({'id': session.id})
  • 模板传递公钥:在ProductLandingPageView的get_context_data中添加Stripe公钥到上下文,避免模板硬编码:
def get_context_data(self, **kwargs):
    context = super().get_context_data(**kwargs)
    # 原有逻辑不变
    context['STRIPE_PUBLIC_KEY'] = settings.STRIPE_PUBLISHABLE_KEY
    return context
  • 添加异常捕获:在创建Stripe Session的视图中捕获API调用异常,返回错误响应:
from stripe.error import StripeError

class CreateCheckoutSessionView(View):
    def get(self, request, *args, **kwargs):
        try:
            # 原有创建session的逻辑
            return JsonResponse({'id': session.id})
        except StripeError as e:
            return JsonResponse({'error': str(e)}, status=400)
  • 改用POST请求创建Session:Stripe官方推荐用POST请求创建Checkout Session,避免GET请求的缓存或参数泄露问题,同时需添加Django CSRF Token验证。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 06:09:54