i am writing a logic to allow user pay for items using thier debit card, the logic is working fine. Now i want to save some data to the database when the status=successful
.
When a user purchase a course i want to add the course
and the user
who purchased the course to a model that i have created called UserCourse
.
I have tried adding slug to the process_payment
view that i created but it seems not to be working. I also have another view called payment_response
that checks if a payment was success or not.
How do i add the purchased course
and the user
that purchase the course in the db?
views.py
# The course detail view
def course_details(request, course_slug):
if request.user.is_authenticated:
user = request.user
course = Course.objects.get(slug=course_slug)
@login_required
def course_checkout(request, slug):
course = Course.objects.get(slug=slug)
user = request.user
# form to get the student's name, email, amount of course
if request.method == "POST":
course = Course.objects.get(slug=slug)
name = request.POST.get("name")
email = request.POST.get("email")
amount = request.POST.get("amount")
return redirect(str(process_payment(name,email,amount, course)))
else:
pass
# how to handle courses that are free
if amount == 0:
course = Course.objects.get(slug=slug)
userCourse = UserCourse(user=user, course=course)
userCourse.save()
return redirect('course:course-content', course.slug)
# View that processes the payment
def process_payment(name,email,amount):
auth_token= settings.FLUTTER_SECRET_KEY
hed = {'Authorization': 'Bearer ' auth_token}
data = {
"tx_ref":'' str(math.floor(1000000 random.random()*9000000)),
"amount":amount,
"currency":"USD",
"redirect_url":"http://localhost:8000/callback",
"payment_options":"card",
"meta":{
"consumer_id":23,
"consumer_mac":"92a3-912ba-1192a"
},
"customer":{
"email":email,
# "phonenumber":phone,
"name":name
},
"customizations":{
"title":"DexxaEd",
"description":" Limitless Learning For Everyone",
"logo":"https://getbootstrap.com/docs/4.0/assets/brand/bootstrap-solid.svg"
}
}
url = ' https://api.flutterwave.com/v3/payments'
response = requests.post(url, json=data, headers=hed)
response=response.json()
link=response['data']['link']
return link
# view that check for payment status
@require_http_methods(['GET', 'POST'])
def payment_response(request):
status=request.GET.get('status', None)
tx_ref=request.GET.get('tx_ref', None)
print(status)
print(tx_ref)
if status == "successful":
# return HttpResponse('Payment Successful')
return render(request, "payment/payment-success.html")
if status == "cancelled":
return render(request, "payment/payment-failed.html")
# return HttpResponse('Payment Cancelled')
models.py
class Course(models.Model):
course_title = models.CharField(max_length=100, null=True, blank=True)
slug = models.SlugField(unique=True)
price = models.IntegerField(default=0, null=True, blank=True)
course_creator = models.ForeignKey(User, on_delete=models.CASCADE)
# Model that store the purchased courses
class UserCourse(models.Model):
user = models.ForeignKey(User , null = False , on_delete=models.CASCADE)
course = models.ForeignKey(Course , null = False , on_delete=models.CASCADE, related_name="usercourse")
date = models.DateTimeField(auto_now_add=True)
urls.py
path('callback', payment_response, name='payment_response')
CodePudding user response:
First update your UserCourse to include paid field as
class UserCourse(models.Model):
# your previous fields
paid = models.BooleanField(default=False)
In the course checkout function create usercourse object if it is a free couse paid is set True else False
def course_checkout(request, slug):
# previous code
if request.method == "POST":
# your existing code
user_course = UserCourse.objects.create(user=user, course=course)
user_course_id = user_course.id
# your existing code
return redirect(str(process_payment(name, email, amount, course, user_course_id)))
# your other code logic
if amount == 0:
user_course = UserCourse.objects.create(user=user, course=course, paid=True)
# your other code logic
In the payment_response function provide user_course_id url arguments as
def payment_response(request, user_course_id=None):
status=request.GET.get('status', None)
tx_ref=request.GET.get('tx_ref', None)
if status == "successful":
if user_course_id:
UserCourse.objects.filter(id=user_course_id).update(paid=True)
return render(request, "payment/payment-success.html")
else:
return render(request, "payment/payment-failed.html")
if status == "cancelled":
return render(request, "payment/payment-failed.html")
In the process payment view;
def process_payment(name, email, amount, course, user_course_id):
# your existing code only change redirection url in data as
{
"redirect_url":f"http://localhost:8000/callback/{user_course_id}/",
}
In urls.py
path('callback/<int:user_course_id>/', payment_response, name='payment_response')