如何从React前端向Django后端传递支付金额参数
解决React前端传递支付金额到Django后端的参数获取问题
问题场景
需要将React前端输入的支付金额传递至Django后端支付网关脚本,替换原脚本中固定的amount=5000数值。当前React通过fetch发送POST请求传参,但Django使用request.POST["amount"]无法获取参数,代码无法正常运行。
核心原因
React发送的请求体为JSON格式(请求头Content-Type: application/json),而Django的request.POST仅处理表单编码(application/x-www-form-urlencoded)的数据,因此无法直接从request.POST中读取JSON参数。
解决方案
后端(Django)修改
在go_to_gateway_view函数中,从request.body解析JSON数据,并进行必要的类型转换与参数校验:
def go_to_gateway_view(request): amount = 5000 # 默认值 if request.method == "POST": try: # 解析JSON请求体 data = json.loads(request.body) # 获取amount并转为整数,同时校验合法性 amount_input = data.get("amount") if amount_input and str(amount_input).isdigit() and int(amount_input) > 0: amount = int(amount_input) except json.JSONDecodeError: # 处理JSON解析失败的情况 logging.error("Invalid JSON data received") # 后续支付网关逻辑保持不变 user_mobile_number = '+989112221234' # 可选 factory = bankfactories.BankFactory() try: bank = factory.auto_create() # or factory.create(bank_models.BankType.BMI) or set identifier bank.set_request(request) bank.set_amount(amount) bank.set_client_callback_url('/callback-gateway') bank.set_mobile_number(user_mobile_number) # 可选 bank_record = bank.ready() context = bank.get_gateway() return render(request, "redirect_to_bank.html", context) except AZBankGatewaysException as e: logging.critical(e) return render(request, "redirect_to_bank.html", {})
注意事项:
- 在文件顶部新增导入
import json - 原代码中
if request.method.POST == "POST"是错误写法,正确判断应为request.method == "POST" - 增加参数校验,避免非法金额导致支付网关报错
前端(React)优化(可选)
前端代码基本可用,可补充空值校验,避免发送无效请求:
const handleSubmit = async (event) => { event.preventDefault(); // 校验金额是否为空或非正数 if (!amount || parseInt(amount) <= 0) { alert("请输入有效的支付金额"); return; } const csrftoken = getCookie('csrftoken'); const response = await fetch('http://127.0.0.1:8000/go-to-gateway/', { method: 'POST', headers: { 'Content-Type': 'application/json', 'Accept': 'application/json', 'X-CSRFToken': csrftoken }, body: JSON.stringify({ amount: parseInt(amount) }) // 转为数字后发送 }); if (!response.ok) { throw new Error('网络响应异常'); } // 后端返回的是重定向页面,无需解析JSON,等待页面跳转即可 console.log("请求成功,正在跳转至支付网关"); };
注意:后端go_to_gateway_view最终返回的是重定向到银行网关的页面,因此前端不需要解析JSON,原代码中的response.json()会抛出错误,需调整为处理HTML响应逻辑。
完整修改后后端代码
import json # 新增导入 from django.db import models from django.contrib.auth.models import User from rest_framework import routers, serializers, viewsets from . serializer import * from azbankgateways import (bankfactories,models as bank_models,default_settings as settings,) import logging from django.urls import reverse from django.shortcuts import render from django.http import HttpResponse, Http404 from django.http import JsonResponse # Bank from azbankgateways.exceptions import AZBankGatewaysException from azbankgateways.models.banks import Bank # API # Create your models here. # ViewSets define the view behavior. class BankViewSet(viewsets.ModelViewSet): queryset = Bank.objects.all() serializer_class = BankSerializer # Bank Functions def go_to_gateway_view(request): amount = 5000 if request.method == "POST": try: data = json.loads(request.body) amount_input = data.get("amount") if amount_input and str(amount_input).isdigit() and int(amount_input) > 0: amount = int(amount_input) except json.JSONDecodeError: logging.error("Invalid JSON payload received") user_mobile_number = '+989112221234' # 可选 factory = bankfactories.BankFactory() try: bank = factory.auto_create() # or factory.create(bank_models.BankType.BMI) or set identifier bank.set_request(request) bank.set_amount(amount) bank.set_client_callback_url('/callback-gateway') bank.set_mobile_number(user_mobile_number) # 可选 bank_record = bank.ready() context = bank.get_gateway() return render(request, "redirect_to_bank.html", context) except AZBankGatewaysException as e: logging.critical(e) return render(request, "redirect_to_bank.html", {}) def callback_gateway_view(request): tracking_code = request.GET.get(settings.TRACKING_CODE_QUERY_PARAM, None) if not tracking_code: logging.debug("این لینک معتبر نیست.") raise Http404 try: bank_record = bank_models.Bank.objects.get(tracking_code=tracking_code) except bank_models.Bank.DoesNotExist: logging.debug("این لینک معتبر نیست.") raise Http404 if bank_record.is_success: return HttpResponse("پرداخت با موفقیت انجام شد.") return HttpResponse("پرداخت با شکست مواجه شده است. اگر پول کم شده است ظرف مدت ۴۸ ساعت پول به حساب شما بازخواهد گشت.")
内容的提问来源于stack exchange,提问作者Arash Khosravi
相关产品推荐
相关产品推荐

