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

Django电商Buy Now支付后Payment DoesNotExist错误解决问询

问题解决:Buy Now支付后出现Payment匹配不存在错误

问题现象

电商网站集成Razorpay支付,购物车结算逻辑正常,但点击Buy Now按钮完成支付后,跳转至/buy_now_payment_done/时抛出错误:DoesNotExist at /buy_now_payment_done/ Payment matching query does not exist。

错误原因分析

  1. BuyNow视图Payment对象创建逻辑漏洞:当Razorpay订单创建状态不是created时,payment变量未初始化就执行save(),导致可能生成无效Payment记录;即使状态正常,若save()不在if块内,也可能出现数据不匹配情况。
  2. 回调URL缺失prod_id参数:buynow_payment_done视图需要prod_id获取商品,但当前回调未传递该参数,不仅会导致订单创建失败,还可能间接引发Payment查询异常。
  3. 未处理Payment查询失败场景:直接使用get()查询Payment,一旦order_id不匹配就抛出未捕获的DoesNotExist异常。

修复步骤

1. 修复BuyNow视图的Payment创建逻辑

修改views.py中的BuyNow类,确保仅在Razorpay订单创建成功时才保存Payment记录:

class BuyNow(View):
    def get(self, request):
        product_id = request.GET.get('prod_id')
        product = get_object_or_404(Product, id=product_id)
        user = request.user
        address = Customer.objects.filter(user=user)
        discounted_price = product.discounted_price
        shipping_amount = 40.00
        total_amount = discounted_price + shipping_amount
        razorpay_amount = int(total_amount * 100)

        client = razorpay.Client(auth=("rzp_test_NqHIxmro5EHkHO", "PVE3M1msR3vfdwEcVlFuMWVX"))
        data = {'amount' : razorpay_amount, 'currency' : 'INR', 'receipt': 'order_rcptid_12', 'payment_capture' : '1'}
        payment_response = client.order.create(data=data)

        order_id = payment_response['id']
        order_status = payment_response['status']
        payment = None
        if order_status == 'created':
            payment = Payment(
                user=user,
                amount=total_amount,
                razorpay_order_id=order_id,
                razorpay_payment_status=order_status,
            )
            payment.save()  # 仅订单创建成功时保存Payment
        
        # 处理订单创建失败的情况
        if not payment:
            messages.error(request, "支付订单创建失败,请重试")
            return redirect('product-detail', pk=product_id)

        total_item_in_cart = len(Cart.objects.filter(user=request.user)) if request.user.is_authenticated else 0

        return render(request, 'app/buynow_checkout.html', {
            'product': product,
            'discounted_price': discounted_price,
            'shipping_amount': shipping_amount,
            'total_amount': total_amount,
            'razorpay_amount':razorpay_amount,
            'address':address,
            'total_item_in_cart':total_item_in_cart,
            'payment':payment.id,
            'order_id':order_id  # 确保模板能获取到order_id
        })

2. 修复buynow_checkout.html的回调URL,补充prod_id参数

修改buynow_checkout.html中的handler函数,在跳转URL中加入商品ID:

<script>
  var options = {
      "key": 'rzp_test_NqHIxmro5EHkHO',
      "amount": "{{ razorpay_amount }}",
      "currency": "INR",
      "name": "Tech - Store Ecomm",
      "description": "Test Transaction",
      
      "order_id": "{{order_id}}",
      "handler": function (response){
        var form = document.getElementById('buynow_payment_form')
        window.location.href = `http://127.0.0.1:8000/buy_now_payment_done?order_id=${response.razorpay_order_id}&payment_id=${response.razorpay_payment_id}&custid=${form.elements["custid"].value}&prod_id={{ product.id }}` 
      },
      "theme": {
          "color": "#1f19e0"
      }
  };
  var rzp1 = new Razorpay(options);
  rzp1.on('payment.failed', function (response){
          alert(response.error.description);
  });
  document.getElementById('rzp-button2').onclick = function(e){
      rzp1.open();
      e.preventDefault();
  }
</script>

3. 增强buynow_payment_done视图的健壮性

使用get_object_or_404替代get(),并验证所有必要参数:

@login_required
def buynow_payment_done(request):
    order_id = request.GET.get('order_id')
    payment_id = request.GET.get('payment_id')
    custid = request.GET.get('custid')
    product_id = request.GET.get('prod_id')

    # 验证必要参数是否齐全
    if not all([order_id, payment_id, custid, product_id]):
        messages.error(request, "无效的支付请求")
        return redirect('home')

    user = request.user
    customer = get_object_or_404(Customer, id=custid)
    # 增加user过滤,确保查询的是当前用户的Payment记录
    payment = get_object_or_404(Payment, razorpay_order_id=order_id, user=user)
    
    payment.paid = True
    payment.razorpay_payment_id = payment_id
    payment.save()

    product = get_object_or_404(Product, id=product_id)
    order = OrderPlaced(user=user, customer=customer, product=product, quantity=1, payment=payment)
    order.save()
    
    messages.success(request, '支付成功,您的订单已提交')
    return redirect('orders')

4. 同步修复checkout视图的同类问题(可选)

checkout视图存在相同的Payment保存逻辑漏洞,建议同步修复:

class checkout(View):
    def get(self,request):
        user = request.user
        add = Customer.objects.filter(user=user)
        cart_items = Cart.objects.filter(user=user)
        famount = 0
        for p in cart_items:
            value = p.quantity * p.product.discounted_price
            famount = famount+value
        totalamount = famount + 40
        razorpay_amount = int(totalamount * 100)
        client = razorpay.Client(auth=("rzp_test_NqHIxmro5EHkHO", "PVE3M1msR3vfdwEcVlFuMWVX"))
        data = {'amount' : razorpay_amount, 'currency' : 'INR', 'receipt': 'order_rcptid_12', 'payment_capture' : '1'}
        payment_response = client.order.create(data=data)

        order_id = payment_response['id']
        order_status = payment_response['status']
        payment = None
        if order_status == 'created':
            payment = Payment(
                user=user,
                amount=totalamount,
                razorpay_order_id=order_id,
                razorpay_payment_status=order_status,
            )
            payment.save()
        
        if not payment:
            messages.error(request, "支付订单创建失败,请重试")
            return redirect('cart')
        
        total_item_in_cart = len(Cart.objects.filter(user=request.user)) if request.user.is_authenticated else 0
        return render(request, 'app/checkout.html',locals())

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 14:27:02