What payment statuses are possible in PayPal PDT? - php

I'm going to use PDT to handle one-off payments made via a Payment Button on my site (PayPal Payments Standard). In fact, I will also use IPN, but the question is about PDT. What values of 'payment_status' variable are allowed in PDT message that PayPal sends us in their response? It seems to me that not all values are possible in PDT messages, and thus not all should be handled in my code.
I did not find any info on 'payment_status' with regard to PDT in PayPal documentation (and in any other places), so I had to come up with my own idea. I decided that these values are legal for PDT:
Completed
Processed
Pending
Failed
and also may be
Denied
So, the above 4 (5) statuses I need to handle in my PDT script and no others. I think others:
Canceled_Reversal
Expired
Refunded
Reversed
Voided
relate to IPN (not PDT). Is my guessing correct?
Thank you.

Exactly, IPN will notify you asynchronously of certain events like refunds, reversals, holds, etc, so if you are using IPN you may receive those statuses as “updates” on previously completed transactions.
However, PDT variables are sent back only when your integration’s return URL sends a POST against https://www.paypal.com/cgi-bin/webscr passing “cmd=_notify-synch” along with your PDT token and the transaction ID (“tx”), so you will only receive the status of a successful transaction, which would be “Completed” (if paymentaction=sale) or “Pending” (if paymentaction=authorization/order).
You shouldn’t receive Denied/Failed/Processed payment status either, as these usually refer to MassPay IPNs.

Related

How to validate a sale with PayPal REST API and IPN

I currently have a fully working cart and checkout process through PayPal _xcart method, but I want to migrate it to REST API, mainly because I want to mitigate the possibility of price-jacking. Currently my IPN does check for price jack and sets the according flags so the product doesn't get downloaded (selling digital products only). Anyway more to the point, I found the PayPal documentation very confusing and I'm struggling to get the full grips of it.
This is what I have understood and worked out till now.
Using my PHP script (let's call it page A) I create the cart content, then I create a new PayPal sale and redirect the client to PayPal for authentication
Client authentication on PayPal, then it's redirected back to my site to page B (page B is defined in page A)
Page B needs to get the PaymentID (from page A) and use it to effectively complete the transaction. Once competed finalize the checkout.
Now here are my problems:
a) I had read quite a few forums and tutorials and they all mention that I should use a session to store the PaymentId from Page A and then use it in Page B to finalize the transaction. Some threads on SO suggests that PayPal should actually include the PaymentID in the call to page B, along with the token and the PayerID. Those are almost 3 years old posts and during my testing I see that PayPal now does return the PaymentID as well.
Is this a new thing, did PayPal really started to send the PaymentID as a GET variable? OK I found this on PayPal SDK documentation (not PHP of course some other language) that they return the PaymentID as well as a GET.
Is there any disadvantage on using the GET presented by PayPal compared to storing a session from page A to B? I don't really wan't sessions, so GET will be ideal for me. I guess if it is on PayPal documentation it's safe to use.
Will this work on the live page as well or only in Sandbox?
b) On Page B when I execute the Payment I get a nice JSON as response, but in the same time my IPN listener also gets called, and this is what confuses me big time. Can/Should I just trust all the data which is in the JSON response and more or less ignore the IPN listener? This will make sense for instant download, for example, much more easier to process, or should I still rely on the IPN for data validation?
If I use only the JSON returned to Page B, which are the correct fields to look for and what values? For example, there is a state field which is approved and another (Transactions -> related items -> state) which is competed. Which one do I need to check?
If I rely on the JSON do I still need to check if the paid amount matches the original amount or can I trust that the payment is equal to the amount I have requested in my call?
If I use the IPN how can I pare it with the transaction? The PaymentID doesn't show up in the variables posted to the IPN. The only way I could think of is to get the txn_id from the JSON response, but somehow that feels odd, plus how can I know if the JSON response hit the server BEFORE the IPN?
Can/Should I just trust all the data which is in the JSON response and more or less ignore the IPN listener?
Yes, and no. In that order.
In a nutshell, you can't trust the payment ID in the call to "Page B" (it could be forged, faked, repeated etc) but you can trust the response YourServer->PayPalServer as it can't be intercepted and faked by the end user.
So your process is (as you describe above)
Page A: Create a sessionID (cookie), amount, cart details etc and store in a local database/storage. You can also create a "custom" field to store your own saleID
Send off amount etc to Paypal, which returns you to ....
Page B: Grab the PayPal TransactionID and send back (server->server) to PayPal. Paypal returns the amount, state etc. Then check your database that the amount is the same and that it belongs to the sessionID. If you also use custom fields, check that too. If everything marries, you're good. If not, it's up to you how to handle.
The status should be "complete" for a simple sale at this point; but (as with IPN below) you should verify this.
Do check the amounts, just in case. They should match, but if not, the PayPal one will be what you receive and it's up to you to accept it, flag it (and phone up) or refund through the API and reject the order etc.
So why have IPN?
It is possible that the user completes the transaction on Paypal and then closes their browser before "Page B" is called. In this case, the only way you know about the order is through the IPN.
If you get an IPN notification going to your IPN handler, IPN can still be faked, but there's a slightly different way of verifying.
You actually send the IPN information back to Paypal (server to server) and Paypal confirms it's correct or wrong (https://developer.paypal.com/docs/classic/ipn/integration-guide/IPNIntro/). Your IPN handler will then check the transaction ID (yes, that's what you use) and verify everything matches in the database (just like you do in "Page B"). If it does, mark the order as complete if the status is complete (and if not already marked as complete in "Page B").
Obviously you can't display anything to the user at this point as they are not the ones that called the page.
The docs above warns you that you can get multiple IPNs for the same transaction so you also need to check status.
(Note: you could use the APIs to verify the transactionID as you do in "Page B").
So why not reply on IPN?
Paypal warn that the IPN may not arrive. Paypal explains it best:
Although PayPal usually processes IPN messages immediately, IPN is not synchronized with actions on your website. Internet connectivity is not always 100% reliable and IPN messages can be lost or delayed. The IPN service automatically resends messages until the listener acknowledges them. The service resends messages for up to 4 days.
Because IPN is not a real-time service, your checkout flow should not wait for the IPN message before it is allowed to complete. If the checkout flow is dependent on receiving an IPN message, processing can be delayed by system load or other reasons. You should configure your checkout flow to handle a possible delay.
So back to the original question
Yes: rely on the JSON (server->server) call you make to verify the parameters to "Page B" (and in and the IPN handler if you choose)
No: Don't ignore the IPN in case Page B never gets called. But still run the verification checks here too.
Yes: Check state = complete for both "Page B" and "IPN handler"
Yes: Use the Paypal TransactionID, but mix into your own database with either custom fields or sessionID.
Yes, you can/will get both Page B and IPN notifications, I'd suggest ignoring the IPN if the payment is already marked as completed, otherwise process and handle appropriately. They should be using the same database.

Payment info using paypal

I have Integrated Paypal using php. I know there is return url ,that means when payment is received it will return to the url for our website.My Question is if payment is received and due to internet problem it does not return to our web page, how do I know that payment is received from a particular user?
If there is a network issue and PayPal cannot issue the IPN message, then according to their documentation, they will retry 15 times up to 4 days.
The IPN message service does not assume that your listener will receive all IPN messages. Because the Internet is not 100% reliable, IPNs can get lost or be delayed. To address these issues, the IPN message service includes a retry mechanism that re-sends a message at various intervals until your listener acknowledges receipt. An IPN message may be present up to four days after the original was sent. The maximum number of retries is 15.
https://developer.paypal.com/docs/classic/ipn/integration-guide/IPNIntro/
This item below might help. Instant Payment Notification should work, but in the case of a network failure, if the payment reached PayPal but the purchaser did not get back to your site to complete a purchase, then you should still receive an email from PayPal telling you that you have received a payment.
using paypal button - can my webpage tell if paypal transaction was successful or not?
You get a confirmation email with their name and email address - be aware that occasionally this may not be the user's current, most active email address. You can also log in to your PayPal dashboard to see all details as well, of course.
You can look up your payment details from the email and compare them to your own user records in your database. If the email they use for PayPal is not the same as the one they registered on your site with, you can still look up their name from the email - in practice it seems to happen extremely rarely that payments have such a problem in my personal experience
I set up a script which emails my users with a passcode to get to the online product they bought which is emailed to them so they can submit that later along with their email address. This is the first thing that happens on return to my script so at least if the site fails to respond properly they can get to what they bought later.
The script uses PHPMailer and cc's me with their passcode so I have it available to re-send to them if they write with a complaint. It doesn't help if the PayPal return for Instant Payment Notification fails completely but the other answers cover that very fully and detail the PayPal repeat attempt process well.
Instant Payment Notification scripts can be downloaded from PayPal for modification by yourself as per the article linked to above.
To be perfectly honest, this is one of PayPal Standard's largest holes. IPN is a POST callback (as is PDT) and they check to make sure they get a 200 response or else they retry (and you can use the IPN history in your PayPal account to resend missing IPNs). But this method still relies on you getting the callback in a timely manner and it's not foolproof. Worse, you need to verify the IPN call and that introduces yet another point of failure in calling PayPal to make sure they did indeed send you the IPN you got.
There's a couple of ways to deal with this
Audit your account regularly. This is a good idea in general, but for a small website this shouldn't be terribly hard. Match your invoices up to your PayPal payments. Obviously this doesn't scale well so...
Switch to Payments Pro. There's more hurdles to this (like more PCI compliance, SSL certificate, etc) but the major advantage is that the API is far less susceptible to the whims of the Internet and only involves one call for credit cards (you can ignore the IPN because the API tells you everything you need to know). The worst that can happen is you send a payment API call and fail to get a response. This is exceptionally rare as PayPal makes sure their API is 99.9% reliable (IPN relies on your server being reliable). Speaking from experience, Payments Pro has far fewer issues than IPN does.
In your application, you should have a status field for orders. If you haven't received the ipn, you wouldn't change the status to Paid.
After that, if you receive an email from Paypal that someone has paid, check the order number, and change the status manually.
how do I know that payment is received from a particular user?
Paypal will send an email both user and you.
Paypal offers 2 solutions for your problem.
PayPal IPN - it notifies the server with a POST request to a specific URL, whena transaction has been successful, declined, aborted by user and so on. Paypal provide an IPN Simulator (the worst simulator ever) in order to test its functionality. you may give it a try at : https://developer.paypal.com/developer/ipnSimulator/
Paypal WebHooks - The webhooks are the "New Kid in the Block",they are basically "user-defined HTTP callbacks that receive events for the subscribed event types. Webhooks are asynchronous, the order is not guaranteed, and idempotency may lead to the same event being sent more than once." as stated in the Paypal documentation.
You can read more about it on : https://developer.paypal.com/docs/integration/direct/rest-webhooks-overview/
For any further help, comment below and I shall try to help.
Cheers,
You have to use notify_url for this purpose
<input type="hidden" name="notify_url" value="https://domain-name.com/ipn.php">

PayPal detect insufficient funds

We have a little problem in our system, we allow customers to pay using PayPal which is great!
But in the following situation we have this issue:
A customer pays us using PayPal.
We send the product to our customer when the transaction has completed.
A few days later, PayPal refuses to pay us because the customer have his PayPal account connected with his bank account. And the funds on that bank account is too low.
So, is there a way to let PayPal know us when this happens through API/URL call to our server ?
As Dagon mentioned, IPN is the best way to handle this.
You'll setup a listener script on your server, and every time a transaction happens on your PayPal account, the PayPal server will POST data about that account to your listener script. You'll get different parameters depending on the type of transaction that occurs. You can see a list of the types and parameters here.
You can build your email notifications, database updates, etc. into your IPN script to fully automate post-payment processing tasks.
So, in the example you've provided, what would happen is when the transaction first takes place the IPN would be triggered with a payment_status of Pending, and then you'd also see a parameter called pending_reason with a value of echeck. This tells you the payment was made, but it's an echeck which takes time to clear, so the status again is Pending instead of Completed.
A few days later when that payment does clear (or fails) you'd get another IPN with an updated payment_status. Only upon receiving an actual COMPLETED payment_status would you then would you deliver the order.
Again, this can all be automated within your IPN script.

Authorize.Net DPM & Silent post

Is there any function in Authorize.Net that does the same of the IPN function on Paypal? I've read a lot about Silent Post but I have some of questions.
If I have at the moment of paying a Pending status, and after few days Authorize changes it to denied, Is Silent Post going to notify me this status change?
Does it work for DPM payment method?
Is there any php example code?
I need it very much because I'm doing a project that recharges devices like mobile phones, but in case to have a pending status I have to do this recharge, and if this status is later finally rejected I have to revert this changes, so I need in each moment to know the transaction status changes in Authorize.Net.
Silent Post is essentially Authorize.Net's version of IPN so it is what you're looking for.
If I have at the moment of paying a Pending status, and after few days Authorize changes it to denied?, is Silent Post going to notify me this status change?
No. Fortunately this rarely ever happens.
Does it work for DPM payment method?
Yes. It works for all payments regardless of method (DPM< AIM, etc) and status (approved, declined).
Is there any php example code?
Handling Authorize.Net Silent Post with PHP (I am the author of this article)

Paypal IPN needed?

I'm doing a project involving Paypal, more specifically with the NVP API in PHP. But I just can't seem to figure what to use the IPN feature for.
I mean, when the user has been redirected to Paypal to confirm the purchase, he is redirected back to my website's "Paypal-succes-page", when the transaction is complete. And just to be sure that he actually payed i could use the "PaymentDetails" operation.
Now where does IPN fit in this process? and what is the benefit of it?
Thanks
The integrate with PayPal's services you will notice there are three main channels (and IMO it's important to know this so you can decide the benefits for your application):
IPN: Instant Payment Notification
PDT: Payment Data Transfer
PayPal's API
To use PayPal's IPN you need to add a 'listener' script (example) and add the address to your PayPal account. Whenever an event occurs PayPal will send a message directly to your server via your listener and you then update your accounts appropriately. This is especially useful for running subscription services as events will occur in the background without user intervention and you can capture successful/failed recurring payments etc.
PayPal's PDT is a system for accepting data when a user is redirected back to your site from PayPal. For example, a user clicks 'Buy', they are directed to PayPal, enter information etc. Then, once the payment has been taken, they are redirected back to your site. PayPal can pass details about the transaction including whether it was successful or not so you can display the appropriate success/failed page from your site.
PayPal's API allows you to integrate more deeply with PayPal's services, and you would use this if you were managing payments directly from your site.
These services aren't mutually exclusive, so you can use any combination with your application.
I hope this helps
The IPN feature is a very useful feature which you should use to update your database in my opinion. Sure the user is redirected to your success-page after the purchase where you can validate the payment details.
But what if he closes (by accident or not) the browser before reaching your success page? You will never know the result of the transaction and you will never update your database or process his order accordingly.
When using the IPN you can be sure that the transaction result will always reach you because PayPal will keep on making an offline request to your IPN page until it has reached your servers.
Instant Payment Notification
The typical usage of the IPN is to validate the purchase and to let your script or management system know that the transaction is complete so your system can update any records you may have for your service.
But the most important part is that the transaction is validated.
IPN send all data about transaction to your server - price, items, contacts ... so you can check, if someone don't pay you only 1$ instead of 100$ and confirm your order. It prevets thiefs, cheaters, ... USE IT! ;)

Categories