Reputation: 6839
I have implemented PayPal on my site. When user choose service to pay he is redirected to pay pal where he commit payment and in the end he is redirected back to my site.
Here I mix IPN and PDT. After payment I receive IPN message and save all variables in database.
When user is back to the site here I get his TXN_ID and UserID (from session) and store it in database.
I read somewhere that it is bad to mix pdt and ipn. Is there any better way to save IPN variables with UserID? Can I somehow send UserId to pay pal and get it with IPN message later when user finish payment?
I'm sorry I have to reopen question. I added 'invoice' field to send UserID to pay pal. But when I try to pay next time with same user ID I am redirected to pay pal page and I receive this error message:
This invoice has already been paid. For more information, please contact the merchant.
It seams that invoice is not a good option to send user id to pay pal.
I tried to put user ID in "custom" field.
<input name="custom" type="hidden" id="custom" value="<%= UserInfo.UserID%>">
But all I get in IPN message is:
custom=%3C%25%3D+UserInfo.UserID%25%3E
Upvotes: 2
Views: 1726
Reputation: 5734
The way I do it is to use the invoice field. This is a field you can send PayPal and they will send it back in the response. This is how I identify transactions coming back from PayPal.
And in my case I don't process both PDT and IPN messages. I process only the one that hits me first. When the second message (PDT or IPN) arrives I check that I have already processed that transaction and I simply discard it.
Also, please don't forget that you need to verify that the messages came from PayPal. Once you get the PDT or IPN message you need to post back to PayPal with your unique Auth_id and the tx token they sent in the original message. You should not rely on any field from the original message.
Once PayPal receives your confirmation request, it will send you a second message with the transaction details. This is the one you should rely on.
I don't see any benefit on processing both PDT and IPN messages for the same transaction. Having said that I do encourage you to implement both, because none of them are guaranteed to reach you.
Edit to include how to pass the invoice to PayPal
To pass the invoice to PayPal, just create a field like:
<input type="hidden" name="invoice" value=$uniquevaluecreatedbyyourapplication>
The unique id could be your user id.
The post to PayPal will be something like
paypal/or/sandbox/address?all the other fields&invoice=123456
Paypal will send back the invoice in the PDT and IPN messages.
Edit - non-unique invoice id number
I did further research and you can configure PayPal to accept multiple transactions for the same invoice id or to accept only one transaction per invoice id. See below the information straight from PayPal's website:
Blocking Accidental Payments
You can choose whether to accept payments with the same Invoice ID or to block payments when the Invoice ID was already used.
When you receive payments from buyers, you can include an optional Invoice ID field to track payments; buyers will not see this ID. A buyer's Invoice ID must be unique for each transaction. If PayPal receives a payment with an Invoice ID that was used for another payment, PayPal will not accept the transaction.
To set the options for blocking this type of payment:
Log in to your PayPal account at https://www.paypal.com.
The My Account Overview page opens.
Click the Profile subtab.
The Profile Summary page opens.
In the Selling Preferences column, click the Payment Receiving Preferences link.
The Payment Receiving Preferences page opens.
Scroll down the page to the Block accidental payments section as shown below.
Select one of the following options:
Yes, block multiple payments per invoice ID – Do not accept more than one payment per invoice. This option prevents duplicate payments that you must refund.
No, allow multiple payments per invoice ID – Do not limit the number of payments received for an invoice. Choosing this option might result in duplicate payments that require a refund.
Scroll to the bottom of the page and click the Save button.
Another option would be to create your invoice id with user id + a random number. This would make it unique.
See below a sample code to get unique invoice numbers.
var r = Math.floor(Math.random()*100000);
var invoice = userid + "-" + r;
You could also use date & time instead of a random number.
var d = new Date();
var invoice = userid + "-" + d;
And in the response back from PayPal, you just discard what comes after the dash.
I hope this helps.
Upvotes: 3