[Date Prev][Date Next][Thread Prev][Thread Next][Interchange by date
][Interchange by thread
]
[ic] Paypal Instant Payment Notification IPN Scripting
I'm integrating paypal instant payment notification into my interchange
store.
I'm not experienced with scripting, so I'm going to seek some help and
I've found two sources. Which looks like a better starting point? Any
other suggestions?
Thanks,
Jeff Urban
• CHOICE ONE: from
http://www.phpbuilder.com/forum/archives/1/2001/12/3/129749
Author: Randall Smith
Date: 2001-12-17 01:20:59
Subject: Complete Script for Paypal's IPN Service
Here is the script for using Paypal's Instant Payment Verification
Service with PHP. It requires cURL for posting to a secure server. My
setup is on Win2K/Apache.
To setup cURL for Win2K/Apache.
It's easy to setup. Everything you need is included in the PHP 4.10
distribution. To enable cURL, just uncomment the cURL and openssl
extensions in you php.ini file. You will then need to make sure that
your extension path (defined in php.ini points to your extensions folder
(php/extensions) that contains php_openssl.dll and php_curl.dll). You
will also need to copy ssleay32.dll and libeay32.dll from php/dlls/ to
somewhere in your path. Don't forget to restart apache. Now you should
be able to rock.
Here is the Paypal IPN code:
Note: I'm not a programmer by profession, so don't make fun of my
script. It works.
/* This script communicates with Paypal's Instant Payment Notification
System. It uses cURL and PHP. The original cURL function is by Aaron Web.
I have taken out the username/password attributes*/
function execute_requests($server, $path, $qstring) {
/* Set up cURL with curl_init. $ch is for Curl Handle. */
$ch = curl_init();
/* Set the type of request to POST */
curl_setopt($ch, CURLOPT_POST, 1);
/* Suppress header in cURL's output */
curl_setopt($ch, CURLOPT_HEADER, 0);
/* Make curl return the results to a variable instead of STDOUT */
curl_setopt($ch, CURLOPT_RETURNTRANSFER,1);
/* Set maximum time for cURL request */
curl_setopt($ch, CURLOPT_TIMEOUT, 5);
/* Construct request */
$requestedurl = "$server" . "/$path";
/* Set URL for request */
curl_setopt($ch, CURLOPT_URL, "$requestedurl");
/* Set query string for post request */
curl_setopt($ch, CURLOPT_POSTFIELDS, "$qstring");
/* Execute request */
$result = curl_exec($ch);
if(curl_error($ch)) {
echo "Error retrieving $requestedurl ";
exit;
}
curl_close ($ch);
return $result;
}
// Parse incoming form data and prepare it for posing to Paypal.
foreach ($HTTP_POST_VARS as $key=>$value) $qstring .= "$key=$value&";
$qstring .= "cmd=_notify-validate";
// Set variables for the cURL function.
//$server = "http://localhost";
//$path = "/mysql_host/paypal/dummy_post.php";
$server = "https://www.paypal.com";
$path = "/cgi-bin/webscr";
// This output contains the response from Paypal.
$output = execute_requests($server, $path, $qstring);
/* Probably not necessary, but I searched the response for the text
"VERIFIED"
or "INVALID"*/
$verified = "ERROR";
if (ereg("VERIFIED",$output))
{
$verified = "VERIFIED";
}
if (ereg("INVALID",$output))
{
$verified = "INVALID";
}
/* The hard part is done. Now you can do what you like with the data.*/
• CHOICE TWO: from http://gotany.com/cgi/paypalipn.html
#!/usr/local/bin/perl -w
#
# paypal Instant Payment Verification script (paypalipn.cgi)
# Copyright (C) 2002 Andrew Moore <amoore@gotany.com>
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# for a more robust and complete version of this program, see
# http://gotany.com
use strict;
use CGI;
use LWP;
use LWP::UserAgent;
use Data::Dumper;
use DBI;
use URI::Escape;
my $q = new CGI;
print $q->header( -type=>'text/html' );
print $q->start_html();
my $DSN = 'DBI:mysql:paypalipn;mysql_socket=/tmp/mysql.sock';
my $DB_AUTH = 'user:passwd';
my $dbh = DBI->connect($DSN, (split ':', $DB_AUTH),
{ RaiseError => 1 });
my @columns = qw(notificationid receiver_email item_name item_number
quantity invoice custom payment_status pending_reason payment_date
payment_gross payment_fee txn_id txn_type first_name last_name
address_street address_city address_state address_zip address_country
address_status payer_email payer_status payment_type notify_version
verify_sign status );
print "inserting...<br>\n";
my $insertid = insert( $q );
print "insertid = $insertid <br>\n";
print "posting...<br>\n";
my $content = postit( $q );
print "updating with:<br>\n";
print $q->pre( $content );
print "<br>\n\n";
if ( $content =~ /VERIFIED/ ) {
my @bv = ( "VERIFIED", $insertid );
$dbh->do( qq(update notification set status = ? where
notificationid = ? ),
undef, @bv) or die $dbh->errstr;
} elsif ( $content =~ /INVALID/ ) {
print "setting it to invalid<br>\n";
my @bv = ( "INVALID", $insertid );
$dbh->do( qq(update notification set status = ? where
notificationid = ? ),
undef, @bv) or die $dbh->errstr;
} else {
my @bv = ( undef, $insertid );
$dbh->do( qq(update notification set status = ? where
notificationid = ? ),
undef, @bv) or die $dbh->errstr;
}
print "done.<br>\n";
$dbh->commit;
$dbh->disconnect;
sub insert {
my $q = shift;
my $statement = qq(insert into notification ) . "( " . join( ", ",
@columns ) . " ) " . qq( values ) . " ( ". join( ", ", map { "?" }
@columns ) . " ) ";
my @bind_values = map { $q->param( $_ ) ? $q->param( $_ ) : "" }
@columns;
my $rv = $dbh->do($statement, undef, @bind_values) or die $dbh->errstr;
# XXXXX should check for error, methinks.
# XXXXX this makes it mysql specific.
$insertid = $dbh->{'mysql_insertid'};
return( $insertid );
}
sub postit {
# pass me in the CGI object;
my $q = shift;
my $ua = new LWP::UserAgent;
my %vars = $q->Vars();
$vars{'cmd'} = '_notify-validate';
my $content = join( '&', map{ $_ . "=" . uri_escape( $vars{$_} )} keys
%vars );
#my $req = HTTP::Request->new( POST =>
'http://www.mooresystems.com/~amoore/mailme.cgi', HTTP::Headers->new(),
\$content );
my $req = HTTP::Request->new( POST => 'https://www.paypal.com/cgi-
bin/webscr', HTTP::Headers->new(), \$content );
# is this really necessary?
$req->content_type('application/x-www-form-urlencoded');
# Pass request to the user agent and get a response back
my $res = $ua->request($req);
# XXXX need to check for success here, then pass content back to check
for VALID
if ( $res->is_success() ) {
return $res->content();
} else {
return 'FAILED';
}
}
# This sql should make the appropriate table in your MySQL database:
# DROP TABLE IF EXISTS notification;
# CREATE TABLE notification (
# notificationid int(10) NOT NULL auto_increment,
# receiver_email char(64) NOT NULL default '',
# item_name char(64) default NULL,
# item_number int(10) default NULL,
# quantity int(10) default NULL,
# invoice char(64) default NULL,
# custom char(64) default NULL,
# payment_status enum('Completed','Pending','Failed','Denied')
default NULL,
# pending_reason
enum('echeck','intl','verify','address','upgrade','unilateral','other')
default NULL,
# payment_date char(50) default NULL,
# payment_gross decimal(9,2) default NULL,
# payment_fee decimal(9,2) default NULL,
# txn_id char(50) default NULL,
# txn_type enum('web_accept','cart','send_money') default NULL,
# first_name char(64) default NULL,
# last_name char(64) default NULL,
# address_street char(64) default NULL,
# address_city char(64) default NULL,
# address_state char(64) default NULL,
# address_zip char(64) default NULL,
# address_country char(64) default NULL,
# address_status enum('confirmed','unconfirmed') default NULL,
# payer_email char(64) default NULL,
# payer_status
enum('verified','unverified','intl_verified','intl_unverified') default
NULL,
# payment_type enum('echeck','instant') default NULL,
# notify_version enum('1.3') default NULL,
# verify_sign char(64) default NULL,
# status enum('VERIFID','INVALID') default NULL,
# PRIMARY KEY (notificationid)
# ) TYPE=MyISAM;