I'm trying to set up paypal's automatic payment notification system.
Basically, I have to be able to receive a form from them, take the variables, submit them back to paypal, and then await a response "Valid" or "invalid".
My problems: 1) How do I submit my form back to them automatically without hitting submit?
2) Who do I read their response? More details below and a perl script for this problem:
Once your server has received the Instant Payment Notification, you will need to confirm it by constructing an HTTP POST to PayPal. Your POST should be sent to "https://www.paypal.com/cgi-bin/webscr"
You must post all of the form variables you received exactly as you received them. You will also need to append a variable named "cmd" with the value "notify-validate" (e.g. cmd=notify-validate) to the POST string.
PayPal will respond to the post with a single word, "VERIFIED" or "INVALID", in the body of the response. When you receive a VERIFIED response, you need to:
Check that the "payment_status" is "completed"
If the "payment_status" is "completed", check the "txn_id" against the previous PayPal transaction you have processed to ensure it is not a duplicate.
After you have checked the "payment_status" and "txn_id", you may update your database based on the information provided.
If you receive an "INVALID" notification, it should be treated as suspicious and investigated.
The Perl Script that solves this:
#!/usr/local/bin/perl
read the post from PayPal system and add 'cmd'
read (STDIN, $query, $ENV{'CONTENT_LENGTH'});
$query .= '&cmd=_notify-validate';
post back to PayPal system to validate
use LWP::UserAgent;
$ua = new LWP::UserAgent;
$req = new HTTP::Request 'POST','https://www.paypal.com/cgi-bin/webscr';
$req->content_type('application/x-www-form-urlencoded');
$req->content($query);
$res = $ua->request($req);
split posted variables into pairs
@pairs = split(/&/, $query);
$count = 0;
foreach $pair (@pairs) {
($name, $value) = split(/=/, $pair);
$value =~ tr/+/ /;
$value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
$variable{$name} = $value;
$count++;
}
assign posted variables to local variables
$receiver_email = $variable{'receiver_email'};
$item_name = $variable{'item_name'};
$item_number = $variable{'item_number'};
$custom = $variable{'custom'};
$payment_status = $variable{'payment_status'};
$payment_date = $variable{'payment_date'};
$payment_gross = $variable{'payment_gross'};
$payment_fee = $variable{'payment_fee'};
$txn_id = $variable{'txn_id'};
$first_name = $variable{'first_name'};
$last_name = $variable{'last_name'};
$address_street = $variable{'address_street'};
$address_city = $variable{'address_city'};
$address_state = $variable{'address_state'};
$address_zip = $variable{'address_zip'};
$address_country = $variable{'address_country'};
$payer_email = $variable{'payer_email'};
if ($res->content eq 'VERIFIED') {
check transaction for uniqueness
process payment
}
elsif ($res->content eq 'INVALID') {
possible fraud
}
else {
error
}