In its guide, PayPal specifies the following:
The API operation initiates a payment on PayPal.
PayPal sends your IPN listener a message that notifies you of the event
Your listener sends the complete unaltered message back to PayPal; the message must contain the same fields in the same order and be encoded in the same way as the original message
PayPal sends a single word back, which is either VERIFIED if the message originated with PayPal or INVALID if there is any discrepancy with what was originally sent
What is the URL where we need to send the reply specified by step 3? Is this something we need to obtain from the HTTP request?
Guide: https://www.x.com/developers/paypal/documentation-tools/ipn/integration-guide/IPNIntro
The URLs are shown in the examples. There's one for the sandbox, and one for the real service. Append the received parameters to the end of the url to complete it.
https://www.sandbox.paypal.com/cgi-bin/webscr?cmd=_notify-validate&...
https://www.paypal.com/cgi-bin/webscr?cmd=_notify-validate&...
Related
I need to match the user who triggered the initial Http message sent to paypal, to the IPN i'm receiving on my backend when the transaction is completed. Since Paypal is unaware of my user database I'm looking for some kind of transaction ID.
the thing is, when a user clicks on a paypal hosted button, Paypal opens another window and processes the buyer login and every other payment steps there.
I've had a look at the URL of that new Paypal window and there is nothing there that will also be stated on the IPN.
Is there a way to check the initial http message sent to paypal from my frontend?
You can use the custom parameter to pass your own unique ID into the payment request. This would then be returned in the same custom parameter included in IPN.
The field is literally called custom and you can pass anything you want in it up to 256 characters.
You should be able to add it as an additional hidden field in your HTML form for the hosted button. If it doesn't pass as expected that way, though, you'll need to use a non-hosted button.
For a while I have been running a site which logs paypal transactions by sending a notify_url to the paypal site, and listens in on that notify_url. My listening page parses the IPN info sent from paypal, and returns an http 200 response, but it doesn't then "send the complete message back to PayPal using HTTPS POST" to https://ipnpb.paypal.com/cgi-bin/webscr (point 3 at https://developer.paypal.com/docs/classic/ipn/integration-guide/IPNImplementation/). The payments seems to have been going through OK. I want to know what problems I have been storing up for myself by not doing this response part of the IPN request-response flow?
You have laid yourself open to accepting IPN messages that may not be from PayPal. The purpose of the message you're omitting is to ensure that the IPN you are processing came from PayPal.
I have implemented an IPN listener in VBScript/Classic ASP.
From my side, it seems to work perfectly.
When it is called, it sends the message back to Paypal appending cmd=_notify-validate. It then checks the response for objHttp.status = 200 and objHttp.responseText = "VERIFIED" then adds the order to my database.
However Paypal are sending me emails;
Subject: PayPal Instant Payment Notification Warning
Instant Payment Notifications sent to the following URL(s) are failing:
According to IPN Testing
Every listener must include code that handles the "error notification" IPN messages.
Either way you should follow the steps in the IPN troubleshooting tips step by step.
Here is a few I've picked out that should help.
Check the URLs listed in your IPN history to ensure that PayPal is posting each IPN to your listener.
Check your web server's access and error logs.
Check your programming language's error log.
Verify that your IPN listener is responding to all messages, even those you do not intend to process.
Further to the OPs comments
the code samples Paypal give, in which this step isn't performed. Is this step required?
it sounds like you are missing Step 2 from the workflow in the documentation
2. After receiving the IPN message from PayPal, your listener returns an empty HTTP 200 response to PayPal. Otherwise, PayPal resends the IPN message.
Judging by the PHP sample as well both seem to send the verification first, which doesn't tally with the workflow suggested by the documentation.
In which case you should just be able to do
Response.Status = "200 OK"
after the rest of the code, make sure nothing else is written back using Response.Write() so the server response is blank, you could even use
Call Response.Clear()
before setting the Response.Status to make sure nothing else has been written from the Response buffer. This will only work however if Response.Buffer has been set to True beforehand (usually at the beginning of the script).
Our customers sends their requests for our products via email. Their requests are saved in our database and after we check their requests, we want to send them an email which contains the paypal payment link. To execute this, I am using BMCreateButton method of ButtonManager API of Paypal.
https://developer.paypal.com/docs/classic/api/button-manager/BMCreateButton_API_Operation_NVP/
This method returns EMAILLINK parameter and I am using this parameter in the email to redirect to user to paypal payment page. This method also returns HOSTEDBUTTONID and I am saving this parameter and EMAILLINK parameter to the database to make a relation between the email link(hostedbuttonid) and the user request.
For the payment notifications, I think my only choice is IPN of Paypal. I developed a page to handle the IPN messages from paypal and it works fine but the problem arises when I want to relate between the payment information with the email link that was sent to the customer. I mean I want to know for which request this payment was made. IPN message does not return any information about the HOSTEDBUTTONID. It returns btn_id(different than the HOSTEDBUTTONID), txn_id and ipn_track_id but none of them is useful to relate the customer request( or email sent) with the payment.
Do you have any suggestion about my issue? Or do you think I should use another way for sending the payment email to the user instead of BMCreateButton method of ButtonManager API.
In the BMCreateButton call, where you're setting up the standard PayPal variables for the button, add the CUSTOM parameter. Within that you can pass any value you want (up to 256 char.) and then that same value will come back in the IPN so you can relate it accordingly.
If you have a specific Order ID you could use the INVOICE field instead, and that would come back in IPN as well.
I'm using Paypal IPN simulator to test changes. I'm trying to generate an INVALID response.
I select
Transaction type: Cart Checkout
payment_status: Denied, Failed or Expired.
However all of these generate a notification call with response VERIFIED
update didn't read close enough. Documentation says: PayPal sends a single word back, which is either VERIFIED if the message originated with PayPal or INVALID if there is any discrepancy with what was originally sent. So if I just browse to my IPN URL directly, I will get an INVALID response from Paypal because the call to IPN did not originate with PayPal.
Regarding your update: close, but not exactly.
IPN will return VERIFIED or INVALID depending on whether or not it recognizes the POST data you're sending as having originated from PayPal.
So yes, if you browse to your IPN URL directly and it directly POST's no data / dummy data to PayPal, then yes, we won't recognize it as having originated from us and we'll return INVALID.
For example, this link will return INVALID:
https://www.paypal.com/cgi-bin/webscr?cmd=_notify-validate&dummy_data=true