I am currently working on a personnel project to interface with PayPal Payment Standard on an MVC3 and Windows Azure based application. I needed to find a nice way to convert request/response objects from PayPal to their corresponding IPN/PDT objects.
I want a payment solution that can be easily scaled on high load. So we will leverage NServiceBus as the front end –> back end service bus infrastructure. This allows decoupling of payments from the functionality of the site, so under high load the payments will not restrict the usability of the site, This is done with MSMQ and NServicebus. I will show a basic example of how.
Below is a DTO you can use for IPN or PDT data. Of course you will need logic to convert http request/response data to this DTO and you have many ways of doing so.
You can then take and IPN and convert the request form/query string values to a DTO e.g.
The same applies for the PDT which you will receive out of band on a separate listener.
Security, if you want the best security, never trust anything from Paypal, always double check the data, so when an IPN comes in, take that data and do a check with Payal and then verify the results match, and the same with PDT data.
This means checking the IPN data – currency, amount, date, subscription type etc is the same as what is in your transaction log, this way, any spoofing is protected, here is an example of a rule.
Unfortunately, I cannot show you implementation logic for this, as it may breach the security of my site if something is found which can be compromised, however this interface is a good start.
As you can see above, I do allot of checks, I ensure the amount, currency, receiver all match the original transaction object.
As you can see above, any payment processing is now totally decoupled, the Front End and Back End work independent of each other with no synchronous calls. Yes this is all wrapped within a MSDTC transaction. I prefer this than using WCF, due to no issue in dealing with latency and I have guaranteed delivery of my crucial message.,You will write a similar controller for the PDT out of band response as well. We also leveraging an IoC container to automatically inject the service bus object into the controller as well as other dependencies. My favourite is Autofac.
Remember to also deal with your dates in UTC format, and ensure the date kind property is set to UTC as well for extra safety when storing the transaction date.
So in a nutshell, you can have top notch validation that protects from spoofing attacks if you ALWAYS take a IPN and PDT and compare it with the original transaction object! If you keep your transaction id’s unpredictable, users can never guess someone else transactionid and hijack it for payment. So you can have a nice invoice number e.g. 90124, but the transactionid is not easy to predict, it could be a Guid etc.
Imagine if the above was not the case a smart user could then create two transactions, one for a cheap item and one for an expensive one, here can then hijack the ipn/pdt, or send a FAKE pdt/ipn to your system, and then swap the item information around, and then later cancel the expensive item transaction, however, he hijacked the cheap item and changed the item list and transactionid, hence why I say, check AMOUNT, CURRENCY, Items, TranactionID etc. There are allot of sites out there that are easy to hack due to them not doing these sort of double checks on Ipn and Pdt messages from Paypal. If I know you IPN or PDT listener, I can send fake messages in and try guess weaknesses by using methods such as generating two transactions on the site and trying to swap items around, currencies, etc In fact, because they cannot guess my transaction number, I do not need to check items in the list, as this is not processed in my listener, so if they changed a flower pot to a BMW, who cares, I ignore this sort of data in an IPN/PDT, as long as the fundamentals are the same we in good shape.
Matthew Will and I spent allot of time think these sort of scenarios through and nutted out a nice secure solution. The above samples should get you started in the right direction for Paypal Standard integration. Allot of implementation logic is left out, and this is done on purpose.
These vulnerabilities are well known in the wild (http://www.schneier.com/blog/archives/2011/05/vulnerabilities_2.html), so its definitely important to always validate all data ‘from’ Paypal’.
PayPal also supports some encryption options (http://subveniocomputing.com/using-encrypted-paypal-buttons-ewp-and-ipn/) to reduce the risk of the consumer fiddling with transaction details (currency, quantity etc).
Am also working on a MVC3 app hosted on Azure and want to integrate with Paypal IPN and PDT payments .
However IPIN sand box is unable to hit my ActionResult. I can hit the ActionResult by manually typing the url but the Sandbox says “Url not found” . Did you have to make any Azure specific settings to enable its visibility to the IPN Sandbox??
If you reset your browser (clear the cache, cookies etc) can you access the URL from your browser without having to login?
Thanks for the response I figured this out and the problem was that my site was hosted at custom endpoint 8080 and Paypal pushes data on port 80.