ipn_track_id
shouldn't be used; mainly because this is for internal use only as stated, and because it's unique for every IPN message.
The txn_id
is unique for each transaction, not each IPN message.
What this means is; one transaction can have multiple IPN messages. eCheck, for example, where it will go in a 'Pending' state by default, and 'Complete' once the eCheck has cleared.
But you may also see reversals, canceled reversals, cases opened and refunds against the same txn_id
.
Pseudo code:
If not empty txn_id and txn_type = web_accept and payment_status = Completed
// New payment received; completed. May have been a transaction which was pending earlier.
Update database set payment_status = Completed and txn_id = $_POST['txn_id']
If not empty txn_id and txn_type = web_accept and payment_status = Pending
// New payment received; completed
Update database set payment_status = Pending and payment_reason = $_POST['pending_reason'] and txn_id = $_POST['txn_id']
You can find a lot more IPN variables listed on https://cms.paypal.com/us/cgi-bin/?cmd=_render-content&content_ID=developer/e_howto_html_IPNandPDTVariables#id08CTB0S055Z
Basically; PayPal will generate a unique seller transaction ID. This tranaction ID may go through various stages before it's 'Completed', so you'll need to be able to handle these exceptions.
As for PayPal's note in the documentation: PayPal may resend individual IPN mesages if it encounters errors during delivery. For example, it's required for your script to return a proper HTTP/1.1 200 OK HTTP status response whenever PayPal POST's the IPN data to it.
If you don't return a HTTP/1.1 200 OK response, PayPal will reattempt sending the same data up to 16 times per indiviudal IPN message.
Note: A seller's transaction ID is different from a buyer's transction ID, since they're two different actions (one debit, one credit).
Best Answer
they hide it well: https://www.sandbox.paypal.com/us/cgi-bin/webscr?cmd=_display-ipns-history