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

Django+Braintree支付按钮无法跳转至payment-done视图问题

问题分析与修复方案

核心问题1:模板中表单代码被错误包裹在代码块标签内

你的process.html模板里,把实际需要渲染的<form>和<script>代码放在了<pre><code>标签中,这会导致浏览器将这些内容显示为纯文本代码,而非可交互的HTML元素。用户点击的只是文本里的"Pay now!",而非真正的按钮,自然不会触发后续支付逻辑。

修复方法:
移除模板中的<pre><code>标签,直接保留<form>和<script>代码:

{% extends "shop/base.html" %}

{% block title %} Pay by credit card {% endblock %}

{% block sidenavigation %}

{% endblock %}

{% block content %}
    <h1>Pay by credit card</h1>

    <form method="post" autocomplete="off">
        {% if braintree_error %}
            <div class="alert alert-danger fade in">
                <button class="close" data-dismiss="alert">&times;</button>
                {{ braintree_error|safe }}
            </div>
        {% endif %}
        <div class="braintree-notifications"></div>
        <div id="braintree-dropin"></div>
        <input style="background-color: #0783ca" id="submit-button" class="btn btn-success btn-lg btn-block"
               type="button" value="Pay now!"/>
    </form>

    <script>
        var braintree_client_token = "{{ client_token}}";
        var button = document.querySelector('#submit-button');

        braintree.dropin.create({
            authorization: "{{client_token}}",
            container: '#braintree-dropin',
            card: {
                cardholderName: {
                    required: false
                }
            }
        }, function (createErr, instance) {
            button.addEventListener('click', function () {
                instance.requestPaymentMethod(function (err, payload) {
                    $.ajax({
                        type: 'POST',
                        url: '{% url "payment:process" %}',
                        data: {
                            'paymentMethodNonce': payload.nonce,
                            'csrfmiddlewaretoken': '{{ csrf_token }}'
                        }
                    }).done(function (result) {
                        // 根据后端响应跳转页面
                        window.location.href = result.redirect_url;
                    }).fail(function() {
                        // 处理请求失败情况,跳转到取消页面
                        window.location.href = '{% url "payment:canceled" %}';
                    });
                });
            });
        });
    </script>
{% endblock %}

核心问题2:AJAX请求未处理后端的跳转响应

后端视图在支付成功/失败后返回redirect(),但AJAX请求不会自动处理这种响应(浏览器仅在同步请求时执行跳转)。需要修改后端返回JSON格式的跳转地址,让前端JS主动执行页面跳转。

修复后端视图payment_process:

from django.http import JsonResponse
from django.urls import reverse

def payment_process(request):
    """处理支付的视图"""
    order_id = request.session.get('order_id')
    order = get_object_or_404(Order, id=order_id)
    total_cost = order.get_total_cost()

    if request.method == 'POST':
        nonce = request.POST.get('paymentMethodNonce', None)
        # 先检查客户创建是否成功
        customer_kwargs = {
            "first_name": order.first_name,
            "last_name": order.last_name,
            "email": order.email
        }
        customer_create = gateway.customer.create(customer_kwargs)
        if not customer_create.is_success:
            # 客户创建失败,返回跳转地址
            return JsonResponse({'success': False, 'redirect_url': reverse('payment:canceled')})
        
        customer_id = customer_create.customer.id

        # 创建交易
        result = gateway.transaction.sale({
            'amount': f'{total_cost:.2f}',
            'payment_method_nonce': nonce,
            'options': {
                'submit_for_settlement': True
            }
        })

        if result.is_success:
            order.paid = True
            order.braintree_id = result.transaction.id
            order.save()
            # 返回成功跳转地址
            return JsonResponse({'success': True, 'redirect_url': reverse('payment:done')})
        else:
            # 返回失败跳转地址
            return JsonResponse({'success': False, 'redirect_url': reverse('payment:canceled')})
    else:
        client_token = gateway.client_token.generate()
        return render(
            request,
            'payment/process.html',
            {
                'order': order,
                'client_token': client_token
            }
        )

额外优化点

  • 增加客户创建失败的判断,避免无效交易请求
  • AJAX请求添加fail回调,处理网络异常等情况,确保用户能被引导到对应页面

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 22:30:59