It can be confusing to automate processing of PayPal transactions in a web app, because you have a couple of seemingly overlapping choices.
PDT (Payment Data Transfer) is a way to get information about a transaction that a user in a current session just completed within your web app. The basic flow is that the user selects something to purchase at your site, is directed to PayPal's own pages to complete the transaction, and then returns to your site where you can display information about the completed transaction.
IPN (Instant Payment Notification) is actually more of a behind-the-scenes, server-to-server transaction, in which PayPal notifies you of a transaction, asynchronously. That is, no one has to be logged on to your web site for an IPN to be completed.
This means that a user purchasing something from your site actually kicks off both a PDT and an IPN. How do you deal with that, then? A good rule of thumb is to update your database on IPNs only. The PDT is a good way to give the user confirmation in the presentation layer, but rely on IPN and only IPN to log the transaction or credit an account in your persistence layer.
There is some good information here: