Handling Instant Payment Notification (IPN) from a dedicated ASPX page.
The IPNHandler component is designed for the scenario where you want to use a dedicated page for handling Instant Payment Notification instead of handling the IPN_Notified event of the same button. If you handle the IPN_Notified event directly from your Payment Button (BuyNow button, Donation button etc) then, you do not need this component at all.
In order to associate the IPNHandler component with a PayPal IPN Notified event caused by a Payment Button (i.e. BuyNow Button, Donation Button etc..) you need to follow the following steps:
(The example is shown for a BuyNow button, but the same procedure works for all other button controls)
- In the design mode of a BuyNow Button, open the smart tag wizard and go to the tab named "Step 3 (IPN) as shown in the following screen shot. Check the second option and provide the relative path of the dedicated PayPal IPN handler file.
- Once you have done that, you know that, "~/DedicatedIPNHandler.aspx" is the page which will be called by PayPal Instant Payment Notification system. So, you should place an instance of the IPNHandler component in this web form.
- Now, create an aspx page named "~/DedicatedIPNHandler.aspx" and place an instance of the IPNHandler component as follows:The "IPN_Notified" event of the IPNHandler component will be fired as soon as the page is loaded (called by PayPal IPN). You should place only one instance of this control in an aspx page. Because, if you place multiple instances, all instance's IPN_Notified event will be fired as soon as the page is loaded which is not an expected matter at all. This page is supposed to be called by PayPal IPN and so there is no need to place any User Interface control or HTML elements in this page. Even though if you place any HTML on this page, all HTML rendering will be suppressed whenever this page is loaded.
- Once you have placed an instance of this component into your web form, attach an event handler method for the event "IPN_Notified". This event handler method is the method which will contain your business logic. When the IPN_Notified event is fired, all transaction information becomes available as strongly typed object (categorized collection of composite properties and collections) through the Event Argument.
Accessing Additional Data Items:You can access the additional data items from IPN_Notified event as shown in the following snippet.By default, the temporary folder used for storing additional data items is "~/App_Data/". Because, usually this folder is privileged with WRITE permission. You could change that path from the property 'InternalSettings.TemporaryFolder" as shown below:But if you changed that path and if you want access the additional data items from a Dedicated IPNHandler component, then, you need to change the property 'TemporaryFolderUsedForAdditionalDataItems' as well as shown below:
Membership users, please note:
If you are using ASP.NET Membership feature in your website, then, you need to allow PayPal to see your page where you placed your IPN_Notified event handler code. Your IPN handler page should be accessible to all users. Assume that your IPN handler page is "DedicatedIPNHandler.aspx" located in a private folder (Not visible to everyone). Then, you need to add the following section to you web.config file which is located in that folder.
If you placed your 'DedicatedIPNHandler.aspx' page in a public folder then you do not need to worry about setting the above config unless you explicitly blocked the 'DedicatedIPNHandler.aspx' page from public.
You do not need to turn IPN option ON from your PayPal account at all. This control will take care of everything for you.
If you are testing your web site from "Local Host" and if the custom IPN URL is a relative URL then you cannot test IPN handling at all. Because, IPN is activated by a notification service from PayPal, not directly by your customer. So, PayPal needs a publicly accessible URL where it can post IPN. The relative URL is eventually converted to an absolute URL based on the URL of your web site. When you are testing from localhost, the generated absolute URL contains 'localhost' or '127.0.0.1'. Obviously that URL is not publicly accessible and so your website wont know about it and fail to fire IPN_Notified event. The story is not end here. Whenever, PayPal IPN service Fails to get HTTP '200 OK' status from your Website as as result of IPN posting, the service will keep trying to post to the same URL again after few hours and it will keep trying for a certain period until it gets HTTP '200 OK' result from your website. That is bad for PayPal as PayPal's resource is being wasted. So, PayPal can disable the IPN for your account which is bad for you. In order to avoid that problem, the control will check if the Custom IPN URL is a relative URL or not. If it is a relative URL and if you are testing from local host, that means, the final URL would be an URL with 'local host'. So, in that case, the control will not generate any IPN information so that PayPal wont submit IPN. But if your Custom IPN URL is an absolute URL which does not contain 'local host' or '127.0.0.1' then, the Payment Button control will pass IPN information to PayPal so that PayPal can submit IPN. In any case, if the control does not pass any IPN information to PayPal, then, PayPal will check if you have specified any default IPN URL in your PayPal profile. If so, then, PayPal will submit IPN to that default URL in these cases. But whenever you upload your test website to a production server where the hosting page of your IPN Handler page has a REAL accessible URL, then, IPN_Notified event will be fired as usual.
Consider the IPN_Notified event as a pure Service Event, do not perform any task that directly interacts with User Interface Controls, Session Variables, Cookies, ViewState etc. When this event is fired, your customer wont see any effect of this event. For example, if you want to set Text of a Label Control 'Thank you for your Payment' in this event, your customer will never see that. Why ? Because, your customer is not directly responsible for firing this event, rather, PayPal Notification Service fires this event in a background thread. For that reason, this control Suppresses all HTML that could be rendered to the Event firer (PayPal Notification Service). Also, this control will STOP firing the Page_Load event of the hosting page. WHY ? Maybe you placed some code in your Page_Load event that directly interacts with Session Variables, Cookies etc or time consuming tasks like Executing lengthy SQL queries which is unnecessary or sometimes harmful for IPN session. So, this control will bypass Page_Load event in the IPN Session. But if you want to let this control fire the Page_Load event in the IPN session because you want to set IPN Settings programmatically from the Page_Load event, then, you have that option too. Set "EnablePageLoadEventInIPNSession = true" from the property editor and then, Page_Load event will be fired before IPN_Notified event, but you need to be very careful about using Page_Load event in this case.
If you do not have Full Trust configuration in your ASP.NET Web site, then, you will always get e.IPN.Status = PayPalIPN.StatusCodes.CommunicationError from the DedicatedIPNEventArg. Because, IPN Status value is returned after the component tries to communicate with the PayPal notification service in the background by HttpWebRequest class. HttpWebRequest class needs Full Trust configuration.
If you are testing in SandBox, you should change the property 'NotifyValidateDestination = PayPal_Sandbox'. Otherwise, you will always get IPN Status = Invalid. But if you did not set the License Key (Trial Mode) then, no matter what value you set for this property, this component will always use NotifyValidateDestination = SandBox.
You will notice that, when you are using BuyNow button, Donation button and other payment buttons, the IPN_Notified event for those buttons use customized event args which provides only the IPN data appropriate for the associated payment button. For example, BuyNow button's IPN notified event arg is BuyNowIPNEventArg which does not contain properties for Shopping Cart related information. Because, shopping cart information is never passed in IPN for BuyNow button. But, the DedicatedIPNEventArg is meant for generic IPN handler that can be used for any Payment button. So, there are lots of properties available in DedicatedIPNEventArg although all of the properties wont contain data for a transaction. You should use the properties based on your expectation. For example, don't expect to get data for e.SubscriptionInfo.SubscriptionNumber if the IPN is not submitted for a Subscription button.
You should take appropriate measures to protect against Fraud Attempts when you write code in IPN_Notified event handler method.