I am facing an issue when Integrating the Razorpay payment gateway into the project. I an new to Django and programming. actually what I need is when the user/nurse makes a signup, after saving data to DB and initiating the payment process. I got a bad request response in the console now.
Here is my forms.py
from typing import Any, Dict
from django import forms
from django.db import transaction
from django.contrib.auth import get_user_model
from accounts.models import Nurse, Student
User = get_user_model()
class DateInput(forms.DateInput):
input_type = 'date'
class NurseForm(forms.ModelForm):
password = forms.CharField(widget=forms.PasswordInput())
confirm_password = forms.CharField(widget=forms.PasswordInput())
class Meta:
model = User
fields = ['username', 'email', 'password']
def clean(self):
cleaned_data = super(NurseForm,self).clean()
password = cleaned_data.get("password")
confirm_password = cleaned_data.get("confirm_password")
if password != confirm_password:
raise forms.ValidationError("password and confirm_password does not match")
class NurseAddForm(forms.ModelForm):
date_of_birth = forms.DateField(
widget=DateInput)
whatsapp_number = forms.CharField(required=False)
agree = forms.BooleanField( label='I Agree', required = True, disabled = False, widget=forms.widgets.CheckboxInput( attrs={'class': 'checkbox-inline'}), help_text = "I accept the terms in the License Agreement", error_messages ={'required':'Please check the box'} )
class Meta:
model = Nurse
fields = "__all__"
exclude = ('user',)
and here is my views.py (accounts.views.py)
from payments.models import Payment
import razorpay
razorpay_client = razorpay.Client(
auth=(settings.RAZOR_KEY_ID, settings.RAZOR_KEY_SECRET))
User = get_user_model()
def NurseSignUpView(request, slug):
logout(request)
if slug == 'nurse':
member_type = MembershipType.objects.get(slug=slug)
user_type = member_type.slug
price = member_type.price
if request.method == 'POST':
nurse_user_form = NurseForm(request.POST)
nurse_add_form = NurseAddForm(request.POST)
if nurse_user_form.is_valid() and nurse_add_form.is_valid():
user_obj = nurse_user_form.save()
user_obj.set_password(user_obj.password)
user_obj.is_nurse = True
user_obj.save()
nurse = nurse_add_form.save(commit=False)
nurse.user = user_obj
nurse.save()
# registered = True
login(request,user_obj)
currency = 'INR'
amount = price
name = str(user_type)
razorpay_order = razorpay_client.order.create(dict(amount=amount,
currency=currency,
payment_capture='0')
)
razorpay_order_id = razorpay_order['id']
callback_url = "http://" + "127.0.0.1:8000" + "/pay/paymenthandler/"
context = {}
context['razorpay_order_id'] = razorpay_order_id
context['razorpay_merchant_key'] = settings.RAZOR_KEY_ID
context['razorpay_name'] = name
context['razorpay_amount'] = amount
context['currency'] = currency
context['callback_url'] = callback_url
user_obj = request.user
nurse_obj = Nurse.objects.get(user=user_obj)
context['email'] = user_obj.email
context['user_name'] = nurse_obj.first_name + " " + nurse_obj.last_name
context['phone'] = nurse_obj.mobile
payment = " "
# time = datetime.now()
try:
payment, created = Payment.objects.get_or_create(
user=user_obj,payment_order_id=razorpay_order_id,name=name,amount=amount,)
if created:
payment.save()
return HttpResponseRedirect(reverse('payment-handler'))
except ValueError as e:
print(e)
# return redirect('payment-page')
else:
print(nurse_user_form.errors)
print(nurse_add_form.errors)
else:
nurse_user_form = NurseForm()
nurse_add_form = NurseAddForm()
context = {
"user": user_type,
"price": price,
"user_form": nurse_user_form,
"add_form": nurse_add_form
}
return render(request, 'registration/signup_form.html', context)
payment handler view (payments.views.py)
@csrf_exempt
def payment_handler(request):
if request.method == "POST":
print('!!!!!!!!!!!!!!!!!!!!!!!!!!!!')
print(razorpay_order_id)
print('!!!!!!!!!!!!!!!!!!!!!!!!!!!!')
try:
payment_id = request.POST.get('razorpay_payment_id', '')
razorpay_order_id = request.POST.get('razorpay_order_id', '')
signature = request.POST.get('razorpay_signature', '')
razorpay_amount = request.POST.get('razorpay_amount')
params_dict = {
'razorpay_order_id': razorpay_order_id,
'razorpay_payment_id': payment_id,
'razorpay_signature': signature,
'razorpay_amount': razorpay_amount
}
payment = Payment.objects.get(payment_order_id=razorpay_order_id)
payment.user = request.user
payment.payment_id = payment_id
payment.signature_id = signature
payment.status = True
payment.save()
result = razorpay_client.utility.verify_payment_signature(
params_dict)
if result is not None:
print('!!!!!!!!!!!!!!!!!!!!!!!!!!!!')
print(razorpay_order_id)
print('!!!!!!!!!!!!!!!!!!!!!!!!!!!!')
amount = razorpay_amount
try:
razorpay_client.payment.capture(payment_id, amount)
payment.status = True
payment.save()
nurse = Nurse.objects.get(user=request.user)
nurse.is_paid =True
nurse.save()
# subject = 'welcome to GFG world'
# message = f'Hi {user.username}, thank you for registering in geeksforgeeks.'
# email_from = settings.EMAIL_HOST_USER
# recipient_list = [user.email, ]
# send_mail(subject, message, email_from, recipient_list)
return redirect('home')
except:
# if there is an error while capturing payment.
return HttpResponse('payment failed')
else:
# if signature verification fails.
return HttpResponse('payment failed')
except:
# if we don't find the required parameters in POST data
return HttpResponseBadRequest()
else:
# if other than POST request is made.
return HttpResponseBadRequest()
payments.urls.py
from django.urls import path
from .views import payment_handler
urlpatterns = [
# path('', payment_page, name='payment-page'),
path('paymenthandler/', payment_handler, name='payment-handler'),
]
My template HTML accounts/templates/registration/signup_form.html
{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Signup</title>
<link rel="stylesheet" href="{% static 'styles.css' %}" />
</head>
<script src="https://checkout.razorpay.com/v1/checkout.js"></script>
<script src="{% static 'razorpay.js' %}"></script>
<body>
{% for error in form.non_field_errors %}
<h1 style="color: red">{{error}}</h1>
{% endfor %}
<div class="container">
<form class="signup-form" method="post">
{% csrf_token %}
<h2>Sign Up as {{user}}</h2>
<div class="mb-3">
{{add_form.first_name.label}} {{add_form.first_name}}
{% if add_form.first_name.errors %}
<div class="invalid-feedback">
<p>{{add_form.first_name.errors.as_text}}</p>
</div>
{% endif %}
</div>
<div class="mb-3">
{{add_form.last_name.label}} {{add_form.last_name}}
{% if add_form.last_name.errors %}
<div class="invalid-feedback">
<p>{{add_form.last_name.errors.as_text}}</p>
</div>
{% endif %}
</div>
<div class="mb-3">
{{add_form.gender.label}} {{add_form.gender}}
{% if add_form.gender.errors %}
<div class="invalid-feedback">
<p>{{add_form.gender.errors.as_text}}</p>
</div>
{% endif %}
</div>
<div class="mb-3">
{{add_form.mobile.label}} {{add_form.mobile}}
{% if add_form.mobile.errors %}
<div class="invalid-feedback">
<p>{{add_form.mobile.errors.as_text}}</p>
</div>
{% endif %}
</div>
<div class="mb-3">
{{add_form.profile_image.label}} {{add_form.profile_image}}
{% if add_form.profile_image.errors %}
<div class="invalid-feedback">
<p>{{add_form.profile_image.errors.as_text}}</p>
</div>
{% endif %}
</div>
<div class="mb-3">
{{add_form.whatsapp_number.label}} {{add_form.whatsapp_number}}
{% if add_form.whatsapp_number.errors %}
<div class="invalid-feedback">
<p>{{add_form.whatsapp_number.errors.as_text}}</p>
</div>
{% endif %}
</div>
<div class="mb-3">
{{add_form.date_of_birth.label}} {{add_form.date_of_birth}}
{% if add_form.date_of_birth.errors %}
<div class="invalid-feedback">
<p>{{add_form.date_of_birth.errors.as_text}}</p>
</div>
{% endif %}
</div>
<div class="mb-3">
{{add_form.address.label}} {{add_form.address}}
{% if add_form.address.errors %}
<div class="invalid-feedback">
<p>{{add_form.address.errors.as_text}}</p>
</div>
{% endif %}
</div>
<div class="mb-3">
{{add_form.pincode.label}} {{add_form.pincode}}
{% if add_form.pincode.errors %}
<div class="invalid-feedback">
<p>{{add_form.pincode.errors.as_text}}</p>
</div>
{% endif %}
</div>
<div class="mb-3">
{{add_form.district.label}} {{add_form.district}}
{% if add_form.district.errors %}
<div class="invalid-feedback">
<p>{{add_form.district.errors.as_text}}</p>
</div>
{% endif %}
</div>
<div class="mb-3">
{{add_form.state.label}} {{add_form.state}}
{% if add_form.state.errors %}
<div class="invalid-feedback">
<p>{{add_form.state.errors.as_text}}</p>
</div>
{% endif %}
</div>
<div class="mb-3">
{{add_form.country.label}} {{add_form.country}}
{% if add_form.country.errors %}
<div class="invalid-feedback">
<p>{{add_form.country.errors.as_text}}</p>
</div>
{% endif %}
</div>
<div class="mb-3">
{{add_form.reg_no.label}} {{add_form.reg_no}}
{% if add_form.reg_no.errors %}
<div class="invalid-feedback">
<p>{{add_form.reg_no.errors.as_text}}</p>
</div>
{% endif %}
</div>
<div class="mb-3">
{{add_form.current_work.label}} {{add_form.current_work}}
{% if add_form.current_work.errors %}
<div class="invalid-feedback">
<p>{{add_form.current_work.errors.as_text}}</p>
</div>
{% endif %}
</div>
<div class="mb-3">
{{add_form.work_place.label}} {{add_form.work_place}}
{% if add_form.work_place.errors %}
<div class="invalid-feedback">
<p>{{add_form.work_place.errors.as_text}}</p>
</div>
{% endif %}
</div>
<div class="mb-3">
{{add_form.institute_name.label}} {{add_form.institute_name}}
{% if add_form.institute_name.errors %}
<div class="invalid-feedback">
<p>{{add_form.institute_name.errors.as_text}}</p>
</div>
{% endif %}
</div>
<div class="mb-3">
{{add_form.reg_state.label}} {{add_form.reg_state}}
{% if add_form.reg_state.errors %}
<div class="invalid-feedback">
<p>{{add_form.reg_state.errors.as_text}}</p>
</div>
{% endif %}
</div>
<div class="mb-3">
{{add_form.remarks.label}} {{add_form.remarks}}
{% if add_form.remarks.errors %}
<div class="invalid-feedback">
<p>{{add_form.remarks.errors.as_text}}</p>
</div>
{% endif %}
</div>
<hr />
<div class="mb-3">
{{user_form.username.label}} {{user_form.username}}
{% if user_form.username.errors %}
<div class="invalid-feedback">
<p>{{user_form.username.errors.as_text}}</p>
</div>
{% endif %}
</div>
<div class="mb-3">
{{user_form.email.label}} {{user_form.email}}
{% if user_form.email.errors %}
<div class="invalid-feedback">
<p>{{user_form.email.errors.as_text}}</p>
</div>
{% endif %}
</div>
<div class="mb-3">
{{user_form.password.label}} {{user_form.password}}
{% if user_form.password.errors %}
<div class="invalid-feedback">
<p>{{user_form.password.errors.as_text}}</p>
</div>
{% endif %}
</div>
<div class="mb-3">
{{user_form.confirm_password.label}} {{user_form.confirm_password}}
{% if user_form.confirm_password.errors %}
<div class="invalid-feedback">
<p>{{user_form.confirm_password.errors.as_text}}</p>
</div>
{% endif %}
</div>
<div class="mb-3">
{{add_form.agree.label}} {{add_form.agree}}
{% if add_form.agree.errors %}
<div class="invalid-feedback">
<p>{{add_form.agree.errors.as_text}}</p>
</div>
{% endif %}
</div>
<button id="pay-btn" type="submit">Sign Up and pay {{price}}</button>
</form>
</div>
</body>
</html>
razorpay.js
var email = document.getElementById("email").value
var options = {
// Enter the Key ID generated from the Dashboard
key: "{{ razorpay_merchant_key }}",
// Amount is in currency subunits.
// Default currency is INR. Hence,
// 50000 refers to 50000 paise
amount: "{{ razorpay_amount }}",
currency: "{{ currency }}",
// Your/store name.
name: "{{razorpay_name}}",
redirect: true,
description: "Test Transaction",
// Pass the `id` obtained in the response of Step 1
order_id: "{{ razorpay_order_id }}",
callback_url: "{{ callback_url }}",
prefill:{
'email' : "{{email}}",
'name' : "{{user_name}}",
'contact':"{{phone}}"
}
};
// initialise razorpay with the options.
var rzp1 = new Razorpay(options);
// add event listener to the payment button.
document.getElementById("pay-btn").onclick = function (e) {
rzp1.open();
e.preventDefault();
};