Django: Не найдена реверсия для 'verify-payment' с аргументами '('',)'. 1 pattern(s) tried: ['course/u/(?P<ref>[^/]+)/$'].

Я написал представление для проверки оплаты, но когда я нажимаю кнопку оплаты, я получаю эту ошибку, которая говорит Reverse for 'verify-payment' with arguments '('',)' not found. 1 pattern(s) tried: ['course/u/(?P<ref>[^/]+)/$']

я знаю, что это ошибка конфигурации url, я не передаю правильные аргументы, но я не знаю, что передать, я уже пробовал payment.ref

views.py

def verify_payment(request: HttpRequest, ref: str) -> HttpResponse:
    payment = get_object_or_404(Payment, ref=ref)
    verified = payment.verify_payment()
    return redirect("userauths:profile")

models.py


class Payment(models.Model):
    order_id = models.CharField(max_length = 50 , null = False)
    payment_id = models.CharField(max_length = 50)
    user_course = models.ForeignKey(UserCourse , null = True , blank = True ,  on_delete=models.CASCADE)
    user = models.ForeignKey(User ,  on_delete=models.CASCADE)
    course = models.ForeignKey(Course , on_delete=models.CASCADE)
    date = models.DateTimeField(auto_now_add=True)
    status = models.BooleanField(default=False)

    email = models.EmailField()
    ref = models.CharField(max_length=200)
    verified = models.BooleanField(default=False)

    def __str__(self):
        return f"Payment: {self.course.price}"
    
    def save(self ,*args, **kwargs):
        while not self.ref:
            ref = secrets.token_urlsafe(50)
            objects_with_similar_ref = Payment.objects.filter(ref=ref)
            if not objects_with_similar_ref:
                self.ref = ref 
            super().save(*args, **kwargs)
    
    def amount_value(self) -> int:
        return self.course.price * 100

    def verify_payment(self):
        paystack = PayStack()
        status, result = paystack,verify_payment(self.ref, self.course.price)
        if status:
            if result['course.price'] / 100 == self.course.price:
            # if result['amount'] / 100 == self.course.price:
                self.verified = True
            self.save()
        if self.verified:
            return True 
        return False

urls.py

    path('u/<str:ref>/', views.verify_payment, name = 'verify-payment'),

checkout.html

{{ course.price }}
<button id="django-paystack-button" onclick="payWithPayStack()" class="chck-btn22">Make Payment</button>

<script>
    function payWithPaystack() {
        let currency = "USD";
        let plan = "";
        let ref = "{{payment.ref}}";
        let obj = {
            key: "{{ paystack_public_key }}",
            email: "{{ request.user.email }}",
            amount: "{{course.price_value}}",
            ref: ref,
            callback: function (response) {
                window.location.href = "{% url 'course:verify-payment' payment.ref %}";
            },
        };

        if (Boolean(currency)) {
            obj.currency = currency.toUpperCase();
        }
        if (Boolean(plan)) {
            obj.plan = plan;
        }
        var handler = PaystackPop.setup(obj);
        handler.openIframe();
    }
</script>

Проблема не в конфигурации url, не в payment.ref, а в логике страницы course_checkout. Проблема в том, что пользователь может попасть на страницу course-checkout.html, даже если оплата не произведена, что и вызывает ошибку, потому что url ожидает непустой <str:ref>. Я ожидаю, и прошу прощения, если это не то, что вам нужно, что пользователь должен попасть на страницу проверки курса только в том случае, если (1) он еще не зарегистрирован на курс, или (2) курс бесплатный. В противном случае пользователь должен попасть на страницу проверки курса (нет необходимости проверять наличие if action == 'create_payment':, поскольку если (1) или (2) ложны, это единственный другой вариант, как я вижу). Я не тестировал приведенный ниже код, но думаю, что это может быть способом сделать это:

def course_checkout(request, slug):
    course = Course.objects.get(slug=slug)
    user = request.user
    action = request.GET.get('action')
    order = None 
    payment = None 
    error = None 

    try:
        user_course = UserCourse.objects.get(user=user, course=course)
    except:
        pass

    # User is already registered for course, so go to the course page
    if user_course:
        return redirect('course:course-content', course.slug)

    amount = int((course.price - (course.price * course.discount * 0.01)) * 100)

    # Redirect to my courses page with a button to start course because this course is free
    if amount == 0:
        userCourse = UserCourse(user=user, course=course)
        userCourse.save()
        return redirect('course:course-content', course.slug) 
        
    # User is not registered for the course, and the amount is NOT 0, so send 
    # to the checkout page
    currency = "NGN"
    notes = {
        "email": user.email,
        "name": user.username
    }
    reciept = f"DexxaEd-{int(time())}"
    order = client.order.create(
        {
            'reciept' : reciept,
            'notes' : notes,
            'amount' : amount,
            'currency' : currency,
            'paystack_public_key' : settings.PAYSTACK_PUBLIC_KEY,
        }
    )

    payment = Payment()
    payment.user = user 
    payment.course = course 
    payment.order_id = order.get('id')
    payment.save()

    context = {
        "course":course,
        "order":order,
        "payment":payment,
        "user":user,
        "error":error,
    }

    return render(request, "course/course-checkout.html", context)
Вернуться на верх