如何将支付结果Results变量传递至Django后端并渲染?
解决支付结果(Results)发送至Django后端并渲染的问题
当前代码的核心问题
- 前端请求不规范:发送JSON数据时未设置请求头、未携带CSRF令牌,且请求未完成就跳转,导致数据可能无法正常送达后端
- 后端解析错误:尝试用表单数据的方式获取JSON格式的支付结果,无法正确解析
- 逻辑冗余:
subscription视图中的POST处理逻辑无效,支付结果不会发送到该视图
修复后的前端代码
首先修改页面中的JS部分,添加CSRF令牌处理、正确的请求头,并等待请求完成后再跳转:
<!-- 支付按钮替换为模板变量填充用户信息 --> <button class="intaSendPayButton button is-btn-mycolor is-fullwidth" data-amount="10" data-currency="KES" data-email="{{ user.email }}" data-first_name="{{ user.first_name }}" data-last_name="{{ user.last_name }}" data-country="KE"> Pay Now </button> <script> // 获取Django的CSRF令牌 function getCookie(name) { let cookieValue = null; if (document.cookie && document.cookie !== '') { const cookies = document.cookie.split(';'); for (let i = 0; i < cookies.length; i++) { const cookie = cookies[i].trim(); if (cookie.substring(0, name.length + 1) === (name + '=')) { cookieValue = decodeURIComponent(cookie.substring(name.length + 1)); break; } } } return cookieValue; } const csrftoken = getCookie('csrftoken'); new window.IntaSend({ publicAPIKey: "publishing_key", live: false // 上线时改为true }) .on("COMPLETE", async (results) => { try { // 先完成结果发送,再跳转 await fetch("{% url 'paid' %}", { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-CSRFToken': csrftoken }, body: JSON.stringify(results) }); window.location.href = "{% url 'paid' %}"; } catch (error) { console.error('发送支付结果失败:', error); } }) .on("FAILED", async (results) => { try { await fetch("{% url 'paid' %}", { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-CSRFToken': csrftoken }, body: JSON.stringify(results) }); window.location.href = "{% url 'paid' %}"; } catch (error) { console.error('发送支付结果失败:', error); } }) .on("IN-PROGRESS", (results) => console.log("Payment in progress status", results)) </script>
修复后的后端代码
修改paid视图,正确解析JSON数据,并将结果传递给模板渲染;同时清理subscription视图的无效逻辑:
from django.http.response import HttpResponse from django.shortcuts import render, redirect from django.contrib.auth import authenticate, login, logout from django.contrib import messages from ..decorators import renew_company from ..forms import * from ..models import * from organizations.models import Organization, OrganizationUser, OrganizationOwner from django.contrib.auth.decorators import login_required from django.contrib.auth.models import User from datetime import datetime import json @login_required(login_url='login') def subscription(request): user = request.user user_organization = OrganizationUser.objects.get(user=user) company = Company.objects.filter(name=user_organization.organization.name).first() today = datetime.date.today() # 非POST请求初始化空表单 form = CompanyForm() if request.method != "POST" else CompanyForm(request.POST) subscription = Subscription.objects.all() if user_organization.is_admin: context = { 'user_organization': user_organization, 'form': form, 'subscription': subscription, 'company': company, 'today': today } return render(request, 'registration/subscription.html', context) else: return HttpResponse('你无权访问此页面') @login_required(login_url='login') def paid(request): payment_results = None if request.method == "POST": # 解析JSON格式的请求体 try: payment_results = json.loads(request.body) except json.JSONDecodeError: payment_results = "无效的支付结果数据" # 将结果传递给模板渲染 return render(request, 'registration/paid.html', {'payment_results': payment_results})
创建支付结果模板(paid.html)
新建registration/paid.html文件,用于友好展示支付结果:
{% extends 'dash.html' %} {% block 'title' %} Payment Result | Simpledocs {% endblock %} {% block extra_title %}<h2>Payment Result</h2>{% endblock %} {% block content %} <div class="columns is-centered"> <div class="column is-5 box"> <h3 class="title is-4">Payment Status</h3> {% if payment_results %} {% if payment_results.status == "COMPLETE" %} <p class="has-text-success">支付成功!</p> <p>交易ID: {{ payment_results.transaction_id }}</p> <p>金额: {{ payment_results.amount }}</p> {% elif payment_results.status == "FAILED" %} <p class="has-text-danger">支付失败!</p> <p>错误信息: {{ payment_results.error_message }}</p> {% endif %} <!-- 可选:展示完整结果JSON --> <details> <summary>查看完整结果</summary> <pre>{{ payment_results|pprint }}</pre> </details> {% else %} <p>暂无支付结果</p> {% endif %} </div> </div> {% endblock %}
额外注意事项
- 确保URL配置中
paid视图的名称为'paid',与前端{% url 'paid' %}匹配 - 生产环境中不要硬编码
publicAPIKey,建议从后端通过模板变量传递 - 若需跳过CSRF验证(不推荐),可给
paid视图添加@csrf_exempt装饰器
内容的提问来源于stack exchange,提问作者Vince Matinde
相关产品推荐
相关产品推荐

