1
\$\begingroup\$

I need some help to evaluate whether I am doing it right. The scenario is, a 3rd party application is sending a webhook request after a successful payment but the problem is that sometimes this application may send the same notification more than once. So it is recommended to ensure that implementation of the webhook is idempotent. So steps that I am implementing for this are if signature is correct (assume it is correct), find orders record in the database using orderId in the request params. Please note: orderId in request params is payment_gateway_order_identifier in orders table. If txStatus is 'SUCCESS' AND haven't already processed COLLECTION payment for this same order, create payments record. 201 response with nothing in the response body. Otherwise, 201 response with nothing in the response body. Otherwise, 422 response with {message: "Signature is incorrect"} in response body.

views.py

        @api_view(['POST'])
        def cashfree_request(request):                
            if request.method == 'POST':    
                data=request.POST.dict()
                payment_gateway_order_identifier= data['orderId'] 
                amount = data['orderAmount']
                transaction_status = data['txStatus'] 
                signature = data['signature']
                if(computedsignature==signature): #assume it to be true
                    order=Orders.objects.get(
                             payment_gateway_order_identifier=payment_gateway_order_identifier)
                    if transaction_status=='SUCCESS':
                        try:
                            payment= Payments.objects.get(orders=order)
                            return Response({"Payment":"Done"},status=status.HTTP_200_OK)
                        except (Payments.DoesNotExist):
                            payment = Payments(orders=order,amount=amount,datetime=datetime)
                            payment.save()
                            return Response(status=status.HTTP_200_OK)      
                else:
                    return Response(status=status.HTTP_422_UNPROCESSABLE_ENTITY)

models.py

    class Orders(models.Model):
        id= models.AutoField(primary_key=True)
        amount = models.DecimalField(max_digits=19, decimal_places=4)
        payment_gateway_order_identifier = models.UUIDField(
                                         primary_key=False,default=uuid.uuid4,editable=False,unique=True) 
       
    class Payments(models.Model):
        id = models.AutoField(primary_key=True)
        orders = models.ForeignKey(Orders, on_delete=models.CASCADE)
        amount = models.DecimalField(max_digits=19, decimal_places=4, verbose_name='Price in INR')
        datetime = models.DateTimeField(auto_now=False,auto_now_add=False)
\$\endgroup\$
3
  • 2
    \$\begingroup\$ Based on your wording, sometimes this application may send the same notification more than once is a little ambigious. Is this an issue you need help fixing (in which case this question is off-topic and needs to move to StackOverflow)? \$\endgroup\$
    – Reinderien
    May 20, 2021 at 15:07
  • 1
    \$\begingroup\$ Otherwise, if it's true that I need help to evaluate whether I am doing it right or is there a better way and your code is already doing what it should, then this question is on-topic but you might want to revisit its wording to make that clear. \$\endgroup\$
    – Reinderien
    May 20, 2021 at 15:08
  • 1
    \$\begingroup\$ No actually i just need an evaluation weather i have written the code in correct way though it is working fine. \$\endgroup\$
    – Amit Yadav
    May 20, 2021 at 16:30

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.