wrote a view to verify payment bbut when i hit the payment button i get this error that say Reverse for 'verify-payment' with arguments '('',)' not found. 1 pattern(s) tried: ['course/u/(?P<ref>[^/]+)/
i know it’s a url configuation error, i am not passing in the right arguments but i dont know what to pass in, i already tried payment.ref
views.py
@login_required
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)
error = "Congratulations! You are Already Enrolled In This Course"
except:
pass
amount = None
if error is None:
amount = int((course.price - (course.price * course.discount * 0.01)) * 100)
if amount == 0:
userCourse = UserCourse(user=user, course=course)
userCourse.save()
return redirect('course:course-content', course.slug) # change this to redirect to my courses page with a button to start course because this course is free
if action == 'create_payment':
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)
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'),
course-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>