Reputation: 790
i am using razorpay payment gateway web integration for my learning eccomerce project everyhing work fine payment can be done all i want is to store some information after payment done in my order model using test mode
my views.py for checkout
class Checkout_Pre(View):
def post (self, request,):
user = request.user
address = Address.objects.filter(default=True, user=request.user)
cart = request.session.get('cart')
items = Item.get_items_by_id(list(cart.keys()))
prefer = request.POST.get('payment')
total_price = request.POST.get('paying_price')
total_item_price = json.loads(total_price)
with transaction.atomic():
order = Order.objects.create(
user=user,
total_price=total_item_price,
address=address.first(),
method = prefer,
)
for item in items:
item_order = OrderItem.objects.create(
order=order,
item=item,
size=cart.get(str(item.id)),
price=item.price,
)
request.session['cart'] = {}
order_currency = 'INR'
callback_url = 'http://'+ str(get_current_site(request))+"/handlerequest/"
print(callback_url)
notes = {'order-type': "Basic order from the coolbuy website", 'key':'value'}
razorpay_order = razorpay_client.order.create(dict(amount=total_item_price*100, currency=order_currency, notes = notes, receipt=order.order_id, payment_capture='0'))
print(razorpay_order['id'])
order.razorpay_order_id = razorpay_order['id']
order.save()
return render(request, 'payment/razorpaypaymentsummary.html', {'order':order, 'order_id': razorpay_order['id'], 'orderId':order.order_id, 'final_price':total_item_price, 'razorpay_merchant_id':settings.razorpay_id, 'callback_url':callback_url,})
so what the error is after payment completion i want to show html page and change sttus in db but after payment completion the handlerequest throwinh me http 505 error
@csrf_exempt
def handlerequest(request):
if request.method == "POST":
try:
payment_id = request.POST.get('razorpay_payment_id', '')
order_id = request.POST.get('razorpay_order_id','')
signature = request.POST.get('razorpay_signature','')
params_dict = {
'razorpay_order_id': order_id,
'razorpay_payment_id': payment_id,
'razorpay_signature': signature
}
try:
order_db = Order.objects.get(razorpay_order_id=order_id)
except:
return HttpResponse("505 Not Found")
order_db.razorpay_payment_id = payment_id
order_db.razorpay_signature = signature
order_db.save()
result = razorpay_client.utility.verify_payment_signature(params_dict)
if result==None:
amount = order_db.total_amount * 100 #we have to pass in paisa
try:
razorpay_client.payment.capture(payment_id, amount)
order_db.payment_status = 1
order_db.save()
return render(request, 'firstapp/payment/paymentsuccess.html',{'id':order_db.id})
except:
order_db.payment_status = 2
order_db.save()
return render(request, 'firstapp/payment/paymentfailed.html')
else:
order_db.payment_status = 2
order_db.save()
return render(request, 'firstapp/payment/paymentfailed.html')
except:
return HttpResponse("505 not found")
any idea what i am doing wrong here in my handlre request view
order model
class Order(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE,)
address = models.ForeignKey(Address, default= True, on_delete=models.CASCADE)
status = models.IntegerField(choices = status_choices, default=1)
method = models.CharField(max_length=50, blank=False,)
total_price = models.FloatField(blank=False, default=0)
payment_status = models.IntegerField(choices = payment_status_choices, default=3)
order_id = models.CharField(unique=True, max_length=200, null=True, default=None)
datetime_of_payment = models.DateTimeField(default=timezone.now)
created_at = models.TimeField(auto_now=True, editable=False)
razorpay_order_id = models.CharField(max_length=1000, null=True, blank=True)
razorpay_payment_id = models.CharField(max_length=1000, null=True, blank=True)
razorpay_signature = models.CharField(max_length=1000, null=True, blank=True)
def __str__(self):
return self.user.username + " " + str(self.order_id)
def save(self, *args, **kwargs):
if self.order_id is None and self.datetime_of_payment:
self.order_id = self.datetime_of_payment.strftime('ORDER%Y%m%dODR')
return super(Order,self).save(*args, **kwargs)
Upvotes: 4
Views: 1238
Reputation: 696
The problem is not with your view but with the save method of your model. in the else part you are doing nothing. You should call the super generally.
Please modify the save function as below and then try :
def save(self, *args, **kwargs):
if self.order_id is None and self.datetime_of_payment:
self.order_id = self.datetime_of_payment.strftime('ORDER%Y%m%dODR')
return super(Order,self).save(*args, **kwargs)
Upvotes: 2
Reputation: 604
In your checkout view
def get(self, request, *args, **kwargs):
order = Order.objects.get(pk = self.kwargs['order'])
settings = SiteSettings.objects.all().first()
# Razorpay client auth
client = razorpay.Client(auth = (settings.razorpay_client_id, settings.razorpay_secret))
if order.razorpay_order_id is None:
order_amount = order.total*100
order_currency = settings.currency
order_receipt = 'Reciept'
notes = {'id': order.id, 'email': order.email_id, 'date':str(datetime.now()), 'amount': order.total, 'is_ios': order.is_ios, 'is_android': order.is_android} # OPTIONAL
data = {"amount":order_amount, "currency":order_currency, "receipt":order_receipt, "notes":notes, "payment_capture":'0'}
razorpay_order = client.order.create(data = data)
# Razorpay order inserted into database order
order.razorpay_order_id = razorpay_order["id"]
order.save()
else:
razorpay_order = client.order.fetch(order.razorpay_order_id)
return render(request, self.template_name, {'settings':settings, 'order':order, 'razorpay_order': razorpay_order})
def post(self, request, *args, **kwargs):
o = self.kwargs['order']+ ' POST'
settings = SiteSettings.objects.all().first()
return render(request, self.template_name, {'settings':settings, 'order':o})
In your handler
settings = SiteSettings.objects.all().first()
order = Order.objects.get(id=request.POST.get('order_id'))
#Razorpay authentication
client = razorpay.Client(auth = (settings.razorpay_client_id, settings.razorpay_secret))
#Razorpay transaction details
razorpay_transaction_details = {
'razorpay_order_id': request.POST.get('razorpay_order_id'),
'razorpay_payment_id': request.POST.get('razorpay_payment_id'),
'razorpay_signature': request.POST.get('razorpay_signature')
}
#Razorpay payment verification
client.utility.verify_payment_signature(razorpay_transaction_details)
#Razorpay capture payment Make sure you change this accordingly.
payment_transaction_details = client.payment.capture(razorpay_transaction_details['razorpay_payment_id'], order.total*100, {"currency":"payment_currency"})
order.order_description = payment_transaction_details
order.status = 'paid'
order.save()
context = {'request': request.POST, 'order': order, 'settings':settings, 'UserData':UserData, 'Password': Password}
return render(request, 'web/rpay-success.html', context)
You can wrap a try except block in it to render failure.
Upvotes: 0
Reputation: 116
In your post method, after you assign
order.razorpay_order_id = razorpay_order['id']
you need to save it. Looks like that's missing.
Upvotes: 1