2/19/10

VBScript Paypal IPN (Instant Payment Notification)

With paypal you can have a specific URL called as soon as a customer completes any transaction through the PayPal "instant payment notification" system. Getting this going requires the creation of the URL that paypal will 'talk to' as well as an understanding of the system. I use hostmysite.com (hosting.com) and code in VBscript - so i also had to figure out how to run CDO messaging with VBscript.

Read this to get started:
https://cms.paypal.com/us/cgi-bin/?&cmd=_render-content&content_ID=developer/e_howto_admin_IPNIntro

http://www2.eventsvc.com/paypaldev/attendondemand/6ed6d820-d2bc-40b5-8477-40e32fa86ca3




Steps:


1. create a sandbox account at https://developer.paypal.com/us/cgi-bin/devscr?cmd=home/main -- this will allow you to test ping your IPN page.

2. Create the IPN page itself. Paypal offers examples using most languages - mine is VBscript - my page looks like this:
Sub SendEmail(message)

Dim iMsg
Dim iConf
Dim Flds
Dim strHTML
Const cdoSendUsingPickup = 1 'Send message using the local SMTP service pickup directory.
Const cdoSendUsingPort = 2 'Send the message using the network (SMTP over the network).

Const cdoAnonymous = 0 'Do not authenticate
Const cdoBasic = 1 'basic (clear-text) authentication
Const cdoNTLM = 2 'NTLM

set iMsg = CreateObject("CDO.Message")
set iConf = CreateObject("CDO.Configuration")

Set Flds = iConf.Fields

' Set the CDOSYS configuration fields to use port 25 on the SMTP server.

With Flds

 .Item("http://schemas.microsoft.com/cdo/configuration/sendusing") = cdoSendUsingPort
 .Item("http://schemas.microsoft.com/cdo/configuration/smtpserver") = "XXXXX"
 .Item("http://schemas.microsoft.com/cdo/configuration/smtpauthenticate") = cdoBasic
 .Item("http://schemas.microsoft.com/cdo/configuration/smtpconnectiontimeout") = 15
 .Item("http://schemas.microsoft.com/cdo/configuration/sendusername") = "root@XXXXX.com"
 .Item("http://schemas.microsoft.com/cdo/configuration/sendpassword") = "password"
 .Item("http://schemas.microsoft.com/cdo/configuration/smtpserverport") = 25
 .Item("http://schemas.microsoft.com/cdo/configuration/smtpusessl") = False

.Update

End With




' Build HTML for message body.
strHTML = message


' Apply the settings to the message.
With iMsg
 Set .Configuration = iConf
 .To = "billp@CCC"

 .Cc = "wkpatton@CCC.com"


 .Sender="admin@CXCC.com"
 .From = "admin@logsitall.com"
 .Subject = "Subject line"
 .HTMLBody = strHTML

End With

iMsg.Send

' Clean up variables.
Set iMsg = Nothing
Set iConf = Nothing
Set Flds = Nothing

End Sub


Dim Item_name, Item_number, Payment_status, Payment_amount
Dim Txn_id, Receiver_email, Payer_email
Dim objHttp, str

'read post from PayPal system and add 'cmd'
str = Request.Form & "&cmd=_notify-validate"

'post back to PayPal system to validate
'set objHttp = Server.CreateObject("Msxml2.ServerXMLHTTP")
'set objHttp = Server.CreateObject("Msxml2.ServerXMLHTTP.4.0")
set objHttp = Server.CreateObject("Microsoft.XMLHTTP")

'--when using with real site
'objHttp.open "POST", "https://www.paypal.com/cgi-bin/webscr", false


'--when using with sandbox site
objHttp.open "POST", "https://www.sandbox.paypal.com/cgi-bin/webscr", false




objHttp.setRequestHeader "Content-type", "application/x-www-form-urlencoded"
objHttp.Send str


'assign posted variables to local variables
Item_name = Request.Form("item_name")
Item_number = Request.Form("item_number")
Payment_status = Request.Form("payment_status")
Payment_amount = Request.Form("mc_gross")
Payment_currency = Request.Form("mc_currency")
Txn_id = Request.Form("txn_id")
Receiver_email = Request.Form("receiver_email")
Payer_email = Request.Form("payer_email")
Txn_type = Request.Form("txn_type")

'Check notification validation
if (objHttp.status <> 200 ) then

 'HTTP error handling

  Call SendEmail("Paypal confirmation 200 - payer is " & Payer_email)


 elseif (objHttp.responseText = "VERIFIED") then
  'check that Payment_status=Completed
  'check that Txn_id has not been previously processed
  'check that Receiver_email is your Primary PayPal email
  'check that Payment_amount/Payment_currency are correct
  'process payment

  Call SendEmail("Paypal confirmation Verified - payer is " & Payer_email & " and transaction type is: " & Txn_type)


 elseif (objHttp.responseText = "INVALID") then
  'log for manual investigation

  Call SendEmail("Paypal confirmation INVALID - payer is " & Payer_email)



else
 'error




end if

set objHttp = nothing



The code itself basically posts back a response to paypal - then i call a sub to send an email to me when done.

Tips and tricks: You have to use a different post back address when using the sandbox vs. the like site - you can see both - i've commented out the URL for the live version.
'--when using with real site
'objHttp.open "POST", "https://www.paypal.com/cgi-bin/webscr", false


'--when using with sandbox site
objHttp.open "POST", "https://www.sandbox.paypal.com/cgi-bin/webscr", false


3. Set up your account to call the IPN page.

Happy coding.

Update: In trying to deploy this for a client using wordpress I ran into a problem/conflict with a plugin called "Bad Bahavior". Turns out that this wordpress plugin was blocking the IPN call because the IPN call wasn't propertly formed HTML ("no header"). In order to make the IPN process work I had whitelist the PayPal IP address within the Bad Behavior settings. Once this was done, all was AOK.

No comments:

Post a Comment