Shreyash mishra
Shreyash mishra

Reputation: 790

unable to show success page after completion of payment

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

Answers (3)

Sukhpreet Singh
Sukhpreet Singh

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

Ruchit Micro
Ruchit Micro

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

incrediblegiant
incrediblegiant

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

Related Questions