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

Django集成Stripe支付按钮点击无响应问题求助

Stripe购买按钮无响应问题排查与修复

问题背景

在127.0.0.1:8000/item/1/页面点击Buy按钮后无响应,无法触发Stripe结账跳转。F12调试确认按钮关联路径为/buy/1/,相关代码如下:

Views代码

class ProductLandingPageView(DetailView):
    model = Item
    template_name = 'items/items.html'
    context_object_name = 'item'


class CreateCheckoutSessionView(View): 
    
    def get(self, request, pk):
        item_id = self.kwargs["pk"]
        item = Item.objects.get(id=item_id)

        checkout_session = stripe.checkout.Session.create(
            success_url="https://morungexpress.com/uploads/2022/01/36931750_1642339369_cc2dfdf7494bfa9436aac0d4a882a653.jpg",
            cancel_url="https://englishlib.org/dictionary/img/wlibrary/c/5ffdb27d24e086.50388072.jpg",
            mode="payment",
            line_items=[
                {
                    'price_data': {
                        'currency': 'usd',
                        'unit_amount': item.price,
                        'product_data': {
                            'name': item.name
                        },
                    },
                    "quantity": 1,
                }
            ]
            )
        return JsonResponse({
            'id': checkout_session.id
        })

URLs代码

from django.urls import path
from .views import *

urlpatterns = [
    path('item/<int:pk>/', ProductLandingPageView.as_view(), name='item'),
    path('buy/<int:pk>/', CreateCheckoutSessionView.as_view(), name='buy')
]

HTML代码

<html>
  <head>
    <title>Buy {{ item.name }}</title>
  </head>
  <body>
        <h1>{{ item.name }}</h1>
        <p>{{ item.description }}</p>
        <p>{{ item.price }}</p>
    <button id="buy-button">Buy</button>
    <script type="text/javascript">
      var stripe = Stripe('pk_test_a9nwZVa5O7b0xz3lxl318KSU00x1L9ZWsF');
      var buyButton = document.getElementById(buy-button);
      buyButton.addEventListener('click', function() {
        fetch("{% url 'buy' item.id %}", {
          method: 'GET'})
        .then(response => return response.json())
        .then(session => stripe.redirectToCheckout({ sessionId: session.id }))
      });
    </script>

  </body>
  
</html>

核心问题与修复方案

1. JavaScript语法错误(直接导致按钮无响应)

  • 元素获取错误:document.getElementById(buy-button)缺少引号,正确写法为document.getElementById('buy-button'),否则JS会把buy-button当作变量而非字符串ID。
  • 箭头函数语法错误:then(response => return response.json())中,单行箭头函数不需要显式写return,正确写法为then(response => response.json()),或用花括号包裹并加return:then(response => { return response.json(); })。

2. 请求方式不符合Stripe规范

Stripe官方推荐使用POST请求创建结账会话,避免GET请求的缓存、幂等性问题。需修改:

  • 视图类的get方法改为post
  • JS中fetch请求的method改为'POST',同时携带Django的CSRF令牌(POST请求必须验证CSRF)

3. Stripe金额单位问题

Stripe的unit_amount要求传入最小货币单位(如美元为分),如果item.price存储的是美元金额(如10.99),需乘以100转成整数,否则会因金额格式错误导致会话创建失败。

修复后的完整代码

修复后的HTML代码(含JS)

<html>
  <head>
    <title>Buy {{ item.name }}</title>
  </head>
  <body>
    {% csrf_token %} <!-- 加入CSRF令牌 -->
    <h1>{{ item.name }}</h1>
    <p>{{ item.description }}</p>
    <p>{{ item.price }}</p>
    <button id="buy-button">Buy</button>
    <script type="text/javascript">
      var stripe = Stripe('pk_test_a9nwZVa5O7b0xz3lxl318KSU00x1L9ZWsF');
      var buyButton = document.getElementById('buy-button'); // 修正引号问题
      buyButton.addEventListener('click', function() {
        // 获取CSRF令牌
        const csrfToken = document.querySelector('[name=csrfmiddlewaretoken]').value;
        fetch("{% url 'buy' item.id %}", {
          method: 'POST', // 改为POST请求
          headers: {
            'X-CSRFToken': csrfToken // 携带CSRF令牌
          }
        })
        .then(response => response.json()) // 修正箭头函数语法
        .then(session => stripe.redirectToCheckout({ sessionId: session.id }))
        .catch(error => console.error('结账请求错误:', error)); // 加入错误捕获,便于调试
      });
    </script>
  </body>
</html>

修复后的Views代码

class CreateCheckoutSessionView(View): 
    # 替换get为post方法
    def post(self, request, pk):
        item_id = self.kwargs["pk"]
        item = Item.objects.get(id=item_id)

        # 将美元金额转换为分(Stripe要求的最小单位)
        unit_amount = int(item.price * 100)

        checkout_session = stripe.checkout.Session.create(
            success_url="https://morungexpress.com/uploads/2022/01/36931750_1642339369_cc2dfdf7494bfa9436aac0d4a882a653.jpg",
            cancel_url="https://englishlib.org/dictionary/img/wlibrary/c/5ffdb27d24e086.50388072.jpg",
            mode="payment",
            line_items=[
                {
                    'price_data': {
                        'currency': 'usd',
                        'unit_amount': unit_amount,
                        'product_data': {
                            'name': item.name
                        },
                    },
                    "quantity": 1,
                }
            ]
        )
        return JsonResponse({'id': checkout_session.id})

调试建议

修改后打开F12控制台,查看Network和Console标签:

  • 检查请求是否成功发送到/buy/1/
  • 查看是否有报错信息,帮助定位剩余问题

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 20:51:20