my $USE_SIMULATOR = 0; # 0 = live, 1 = sandbox / simulator my $LIVE_URL = 'https://www.paypal.com/cgi-bin/webscr'; # live my $SANDBOX_URL = 'https://www.sandbox.paypal.com/cgi-bin/webscr'; # sandbox my $PAYPAL_HOST_HEADER = ($USE_SIMULATOR ? 'www.sandbox.paypal.com' : 'www.paypal.com'); my $RESPONSE_URL = ($USE_SIMULATOR ? $SANDBOX_URL : $LIVE_URL); # read POST params my $postdata = read_all ($content_length, $server->stdin_handle); my $post = (length ($postdata) > 0) ? CGI->new ($postdata)->Vars : {}; # extract some transaction details my $txn_type = $post->{txn_type}; my $txn_id = $post->{txn_id}; my $payment_status = lc ($post->{payment_status}); # respond to Paypal's initial HTTP request print "HTTP/1.1 200 OK\r\n\r\n"; # send back the original POST data with our extra field "cmd=_notify-validate" to get an INVALID or VERIFIED response # this makes a new HTTP request my $ua = LWP::UserAgent->new (ssl_opts => { verify_hostname => 1 }); my $req = HTTP::Request->new ('POST', $RESPONSE_URL); $req->content_type('application/x-www-form-urlencoded'); $req->header(Host => $PAYPAL_HOST_HEADER); $postdata = 'cmd=_notify-validate&' . $postdata; $req->content($postdata); my $res = $ua->request($req); # process the response if ($res->is_error) { # connection error ... } elsif ($res->content eq 'VERIFIED') { # ok ... ( further processing ) } elsif ($res->content eq 'INVALID') { # error ... } else { # unexpected error ... }