pythonhttp-redirectwebhooksretrywhen

How to retry code 5 times with 5 seconds space between each attempt


I have some code which checks for data coming from Stripe's Webhook. Now I got some code that queries my database to check if the payment has been confirmed. I am trying to write a function that checks my database to see if the payment has been confirmed, if the payment has not yet been confirmed, the program should wait 5 seconds and then check again, checking a maximum of 5 times. If after the fifth try the payment still does not show as confirmed, then I need to redirect the user.

This is because my code might execute faster than Stripe returns their webhook response to my server.

Current code below. How do I create the 'loop' on the if statement?

def accepted(request, payment_id):

    r = Usertasks.objects.all().filter(user=request.user).filter(randomURL=payment_id).values("TaskPostedToNetwork")
    e = Usertasks.objects.all().filter(user=request.user).filter(randomURL=payment_id).values("PaymentConfirmed")
    if r == "False" and e == "yes":
        print("true")
    else:
        return redirect('dashboard:index')
    return render(request, 'request.html',)

Solution

  • You can do this by wrapping your query/check logic in a for loop. Since you want to perform these actions a maximum of 5 times, you can do a for loop over range(5) and since on success you use return, the loop will stop on success. Thus a maximum of 5 times.

    In the other case, when you'll check again instead of breaking out of the function, you can call time.sleep(5) to stop execution and wait for 5 seconds.

    If the loop completes (executes the block 5 times without getting success and exiting) then you'll reach the return redirect... line.

    Like so:

    import time
    
    def accepted(request, payment_id):
        seconds_between_calls = 5
        max_calls = 5
        for _ in range(max_calls):
            r = Usertasks.objects.all().filter(user=request.user).filter(randomURL=payment_id).values("TaskPostedToNetwork")
            e = Usertasks.objects.all().filter(user=request.user).filter(randomURL=payment_id).values("PaymentConfirmed")
            if r == "False" and e == "yes":
                print("true")
                return render(request, 'request.html',)
            else:
                # try again
                time.sleep(seconds_between_calls)    
        return redirect('dashboard:index') # if max_calls hit