I\'m setting up a simple \'buy now\' transaction from a website with these major steps:
It's important to do a 2 way validation like you have.
You save the order info (total, quantity) before the user leaves your system towards paypal. When ipn come back you validate the request (it must be from paypal ip or whatever), you validate that it's a successful transaction then your step 2 enters the scene. You validate if the total returned from paypal ipn is the same with the total that was saved before the user left (Paypal sometime may return partial payments, the user may grab the post data and do his own post from a modified html with a lower total
set). Step 2 should also store the user_id of the buyer so you must compare that too.
here's a sample layer (no programming language just a dummy code):
if request comes from paypal:
# query the order
if order.total == request.total && order.user_id == request.custom:
payment may come in...