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)