Using VB MVC 3 with Razor ... can I create the PayPal ipn in any controller? say I put it in its own controller say IPN. Would the URL not then be http://www.testsite.com/IPN ? and if that is correct. Do I need to create a blank view page named Ipn or what ever the Ipn action name is?? In this view would It need to contain any razor syntax? I have been back and fourth over every single post I could find about IPN but there is nothing for MVC 3 vb.net.. This has been edited... I have got the IPN handler reutrning status 200. And when I run it through the tester I get success... However actual test transactions are not being entered in the database... Anyone know why this might be???? The Ipn Controller function is this:
End Function
<AcceptVerbs(HttpVerbs.Post)>
Function IPN_Handler(ByVal sender As Object, ByVal e As System.EventArgs)
Dim strFormValues As String = Request.Form.ToString()
Dim strNewValue
Dim Txn_id As String = Request.Form("txn_id")
Dim mc_gross_1 As String = Request.Form("mc_gross_1")
Dim mc_gross_2 As String = Request.Form("mc_gross_2")
Dim mc_gross_3 As String = Request.Form("mc_gross_3")
Dim mc_gross_4 As String = Request.Form("mc_gross_4")
Dim num_cart_items As String = Request.Form("num_cart_items")
Dim Receiver_email As String = Request.Form("receiver_email")
Dim Item_name1 As String = Request.Form("item_name1")
Dim Item_name2 As String = Request.Form("item_name2")
Dim Item_name3 As String = Request.Form("item_name3")
Dim Item_name4 As String = Request.Form("item_name4")
Dim Quantity As String = Request.Form("quantity")
Dim Invoice As String = Request.Form("invoice")
Dim Custom As Integer = Request.Form("custom")
Dim transaction_subject As Integer = Request.Form("transaction_subject")
Dim Payment_status As String = Request.Form("payment_status")
Dim Pending_reason As String = Request.Form("pending_reason")
If Payment_status <> "Pending" Then
Pending_reason = " "
End If
Dim Payment_date As String = Request.Form("payment_date")
Dim Payment_fee As String = Request.Form("payment_fee")
Dim Payment_gross As String = Request.Form("payment_gross")
Dim Txn_type As String = Request.Form("txn_type")
Dim First_name As String = Request.Form("first_name")
Dim Last_name As String = Request.Form("last_name")
Dim Address_street As String = Request.Form("address_street")
Dim Address_city As String = Request.Form("address_city")
Dim Address_state As String = Request.Form("address_state")
Dim Address_zip As String = Request.Form("address_zip")
Dim Address_country As String = Request.Form("address_country")
Dim Address_status As String = Request.Form("address_status")
Dim Address_country_code As String = Request.Form("address_country_code")
Dim Payer_email As String = Request.Form("payer_email")
Dim Payer_status As String = Request.Form("payer_status")
Dim Payer_id As Integer = Request.Form("payer_id")
Dim Payment_type As String = Request.Form("payment_type")
Dim Notify_version As String = Request.Form("notify_version")
Dim Verify_sign As String = Request.Form("verify_sign")
Dim Ipn_Track_Id As String = Request.Form("ipn_track_id")
Dim req As HttpWebRequest = CType(WebRequest.Create("https://www.sandbox.paypal.com/cgi-bin/webscr"), _
HttpWebRequest)
req.Method = "POST"
req.ContentType = "application/x-www-form-urlencoded"
strNewValue = strFormValues + "&cmd=_notify-validate"
req.ContentLength = strNewValue.Length
Dim stOut As StreamWriter = New StreamWriter(req.GetRequestStream(), _
Encoding.ASCII)
stOut.Write(strNewValue)
stOut.Close()
Dim strResponse As HttpWebResponse = CType(req.GetResponse(), HttpWebResponse)
Dim ipnResponseStream As Stream = strResponse.GetResponseStream
Dim encode As Encoding = System.Text.Encoding.GetEncoding("utf-8")
Dim readStream As New StreamReader(ipnResponseStream, encode)
Dim read(256) As [Char]
Dim count As Integer = readStream.Read(read, 0, 256)
While count > 0
Dim IpnResponse As New [String](read, 0, count)
count = readStream.Read(read, 0, 256)
If IpnResponse = "VERIFIED" Then
Dim db As New mysql_31309_schoolEntities
Dim _payment_tracker As New payment_tracker
_payment_tracker.txn_id = Txn_id
_payment_tracker.Class_1_ID = Item_name1
_payment_tracker.Class_2_ID = Item_name2
_payment_tracker.Class_3_ID = Item_name3
_payment_tracker.Class_4_ID = Item_name4
_payment_tracker.num_cart_items = num_cart_items
_payment_tracker.reciever_email = Receiver_email
_payment_tracker.payer_id = Custom
_payment_tracker.payment_status = Payment_status
_payment_tracker.payment_date = Payment_date
_payment_tracker.first_name = First_name
_payment_tracker.last_name = Last_name
_payment_tracker.address1 = Address_street
_payment_tracker.city = Address_city
_payment_tracker.state = Address_state
_payment_tracker.zipcode = Address_zip
_payment_tracker.payment_fee = Payment_fee
_payment_tracker.payment_gross = Payment_gross
If Payment_status <> "Pending" Then
_payment_tracker.pending_reason = " "
Else
_payment_tracker.payment_status = Payment_status
End If
_payment_tracker.ipn_track_id = Ipn_Track_Id
db.payment_tracker.AddObject(_payment_tracker)
db.SaveChanges()
Else
If Payment_status = "Completed" Then
Dim reg As reg_info = db.reg_info.Single(Function(f) f.id = Payer_id)
reg.paid = "Paid"
reg.date_paid = Payment_date
reg.payment_method = Payment_type
db.SaveChanges()
Else
If IpnResponse = "INVALID" Then
Return Nothing
End If
End If
End If
End While
readStream.Close()
strResponse.Close()
Return Nothing
End Function
Paypal IPN and MVC 3 VB.NET when combined with remote hosting can be more than a challenge... I finally got it working... Not by creating a controller function at all... I ended up making a aspx app. for the ipn.. Throwing it in the root folder. Pointing paypal to the aspx file. And then making a short routine in my actual home controller that checks for changes made to the table that the ipn writes to. If it finds any that are new and completed it processes the payment from there. That is the only way I have been able to not get a 500 error... To debug the ipn successfully I actually started with the plain paypal source code for a ipn... Got it saying successful on the IPN tester then from there I added small blocks of code to it for each of the tasks it is to do... Then I would run it through the paypal ipn tester again... If It was successful then I knew I could carry on with a little more code... If it failed with 500 at anytime I new that it was something in what I just added... Not much help I know but I figure my 2 weeks of going from working to failing and not knowing why might help someone else out...
I cannot stress how important the last part of that is. Just use a very basic IPN handler at first because debugging is kind of complicated as it is not able to be debugged normally through VS. Start out small and work your way up testing it with the paypal ipn tester after each change to make sure that it is not broken.
In the interest of helping others out who find the documentation to be overly poor. The below is a working example of a paypal IPN handler.
The asp.net view is just a blank asp.net server page named for this example IPN_Handler.ascx . And is as follows:
<%@ Page Language="vb" AutoEventWireup="false" CodeBehind="Ipn_Handler.aspx.vb" Inherits="yourNamespace.Ipn_Handler" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<div>
</div>
</form>
</body>
And example for the code behind file is as follows. Please note that this came from a working IPN handler so there are SEVERAL references that you may not need..
Imports System.Net
Imports System.IO
Imports System.Text
Imports System.Collections.Specialized
Imports System.Web.Mail
Imports MySql.Data.MySqlClient
Imports System.Security.Principal
Imports System.Data
Imports System.Linq
Imports System.Web.Mvc
Imports System.Reflection
Imports System.Data.OleDb
Imports System.ComponentModel
Public Class Ipn_Handler
Inherits System.Web.UI.Page
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Dim strFormValues As String = Request.Form.ToString()
Dim strNewValue
Dim Txn_id As String = Request.Form("txn_id")
Dim mc_gross_1 As String = Request.Form("mc_gross_1")
Dim mc_gross_2 As String = Request.Form("mc_gross_2")
Dim mc_gross_3 As String = Request.Form("mc_gross_3")
Dim mc_gross_4 As String = Request.Form("mc_gross_4")
Dim num_cart_items As String = Request.Form("num_cart_items")
Dim Receiver_email As String = Request.Form("receiver_email")
Dim Item_name1 As String = Request.Form("item_name1")
Dim Item_name2 As String = Request.Form("item_name2")
Dim Item_name3 As String = Request.Form("item_name3")
Dim Item_name4 As String = Request.Form("item_name4")
Dim Quantity As String = Request.Form("quantity")
Dim Invoice As String = Request.Form("invoice")
Dim Custom As Integer = Request.Form("custom")
Dim transaction_subject As Integer = Request.Form("transaction_subject")
Dim Payment_status As String = Request.Form("payment_status")
Dim Pending_reason As String = Request.Form("pending_reason")
If Payment_status <> "Pending" Then
Pending_reason = " "
End If
Dim Payment_date As String = Request.Form("payment_date")
Dim Payment_fee As String = Request.Form("payment_fee")
Dim Payment_gross As String = Request.Form("payment_gross")
Dim Txn_type As String = Request.Form("txn_type")
Dim First_name As String = Request.Form("first_name")
Dim Last_name As String = Request.Form("last_name")
Dim Address_street As String = Request.Form("address_street")
Dim Address_city As String = Request.Form("address_city")
Dim Address_state As String = Request.Form("address_state")
Dim Address_zip As String = Request.Form("address_zip")
Dim Address_country As String = Request.Form("address_country")
Dim Address_status As String = Request.Form("address_status")
Dim Address_country_code As String = Request.Form("address_country_code")
Dim Payer_email As String = Request.Form("payer_email")
Dim Payer_status As String = Request.Form("payer_status")
Dim Payer_id As Integer = Request.Form("payer_id")
Dim Payment_type As String = Request.Form("payment_type")
Dim Notify_version As String = Request.Form("notify_version")
Dim Verify_sign As String = Request.Form("verify_sign")
Dim Ipn_Track_Id As String = Request.Form("ipn_track_id")
Dim req As HttpWebRequest = CType(WebRequest.Create("https://www.sandbox.paypal.com/cgi-bin/webscr"), _
HttpWebRequest)
req.Method = "POST"
req.ContentType = "application/x-www-form-urlencoded"
strNewValue = strFormValues + "&cmd=_notify-validate"
req.ContentLength = strNewValue.Length
Dim stOut As StreamWriter = New StreamWriter(req.GetRequestStream(), _
Encoding.ASCII)
stOut.Write(strNewValue)
stOut.Close()
Dim strResponse As HttpWebResponse = CType(req.GetResponse(), HttpWebResponse)
Dim ipnResponseStream As Stream = strResponse.GetResponseStream
Dim encode As Encoding = System.Text.Encoding.GetEncoding("utf-8")
Dim readStream As New StreamReader(ipnResponseStream, encode)
Dim read(256) As [Char]
Dim count As Integer = readStream.Read(read, 0, 256)
While count > 0
Dim IpnResponse As New [String](read, 0, count)
count = readStream.Read(read, 0, 256)
If IpnResponse = "VERIFIED" Then
'//Logic to handle what to do on Verified response.
If Payment_status = "Completed" Then
'// The Payment_status variable can be used to trap a completed payment response and do work.
End If
ElseIf IpnResponse = "INVALID" Then
'// This is where possible hacking attempts will be caught by paypal and returned as invalid.
Else
End If
End While
readStream.Close()
strResponse.Close()
End Sub
End Class
A simple way to test if you have placed this example in the proper location for your setup is to browse to the IPN itself. Maybe placing a simple message in the view markup of the IPN_Handler.ascx page. Whatever url you use to browse to it is the one that you will need to enter at paypal in the setup for IPN URL address. Don't message me about Localhost issues. This needs to be tested on a remote accessible server.