*alexandre* has asked for the wisdom of the Perl Monks concerning the following question:

Hi, I'm trying to integrate a paypal ipn and I got the Following error while PayPal is Calling my script here is the code
#!/usr/bin/perl use strict; use MyDB; use warnings; use Email::Sender::Simple qw(sendmail); use Email::Sender::Transport::SMTPS (); use Email::Simple (); use Email::Simple::Creator (); my $smtpserver = 'smtp.gmail.com'; my $smtpport = '587'; my $smtpuser = 'xxxxx@gmail.com'; my $smtppassword = 'yyyyyyyccccc'; my $transport = Email::Sender::Transport::SMTPS->new({ host => $smtpserver, port => $smtpport, ssl => "starttls", sasl_username => $smtpuser, sasl_password => $smtppassword, }); #my $Just_Exit = 0; # if you need it # Lots of servers will not resolve the IP to a host name # So variable $ENV{'REMOTE_HOST'} will not have a value. # If you want any security check if it is a PayPal IP. #die('Does not match PayPal at IP:'.$ENV{'REMOTE_ADDR'}) # if ($ENV{'REMOTE_ADDR'} ne '173.0.82.66'); # comment the one your not using my $PP_server = 'ipnpb.sandbox.paypal.com'; # sandbox IP:173.0.82.66 #my $PP_server = 'ipnpb.paypal.com'; # production IP:173.0.88.40 # It is highly recommended that you use version 6 upwards of # the UserAgent module since it provides for tighter server # certificate validation use LWP::UserAgent 6; # read post from PayPal system and add 'cmd' use CGI qw(:standard); my $cgi = CGI->new(); my $db = MyDB->new(); my $query = 'cmd=_notify-validate&'; $query .= join('&', map { $_.'='.$cgi->param($_) } $cgi->param()); # post back to PayPal system to validate my $ua = LWP::UserAgent->new(ssl_opts => { keep_alive => 1, verify_hos +tname => 1,SSL_version => 'SSLv23:!TLSv12' }); my $req = HTTP::Request->new('POST', 'https://'.$PP_server.'/cgi-bin/w +ebscr'); $req->content_type('application/x-www-form-urlencoded'); $req->header(Host => $PP_server); $req->content($query); my $res = $ua->request($req); # make the variable hash my %variable = map { split(m'='x, $_, 2) } grep { m'='x } split(m'&'x, $query); # assign posted variables to local variables my $item_name = $variable{'item_name'}; my $item_number = $variable{'item_number'}; my $payment_status = $variable{'payment_status'}; my $payment_amount = $variable{'mc_gross'}; my $payment_currency = $variable{'mc_currency'}; my $txn_id = $variable{'txn_id'}; my $receiver_email = $variable{'receiver_email'}; my $payer_email = $variable{'payer_email'}; if ($res->is_error) { # HTTP error } elsif ($res->content eq 'VERIFIED') { # check the $variable{'payment_status'}=Completed if ($payment_status eq 'Completed') { my ($tx)=$db->sqlSelect("tx", "article", "id_article = $item_numbe +r"); if (!$tx eq $txn_id) { if ($receiver_email eq 'alexjaquet@gmmail.com') { print "Success"; my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst)=localtim +e(); my $date = sprintf "%4d-%02d-%02d",$year+1900,$mon+3,$mday; my $time = sprintf("%4d:%02d:%02d",$hour,$min,$sec); + $db->sqlUpdate("article","id_article = $item_number",( tx => "$txn_id", pub => "1". pub_date_end => "$date $time$item_number" )); my $email = Email::Simple->create( header => [ To => 'alexjaquet@gmail.com', From => 'robot@avant-garde.info', Subject => 'Vous avez reçu le payement', ], body => 'Vous avez reçu le payement',); sendmail($email, { transport => $transport }); } } } } elsif ($res->content eq 'INVALID') { # log for manual investigation print "Content-Type: text/html\n\n"; print "Erreur dans le payemeent d\'une publicité"; my $email = Email::Simple->create( header => [ To => 'alexjaquet@gmail.com', From => 'robot@avant-garde.info', Subject => 'Erreur dans le payement' ], body => 'Erreur dans le payement d\'une publicite +: $id_article',); sendmail($email, { transport => $transport }); } else { # error # log for manual investigation print "Content-Type: text/html\n\n"; print "Erreur dans le payemeenté";}
The log file show me Tue Nov 26 17:31:58.528979 2019 cgi:error pid 2202 client 173.0.82.126:36191 End of script output before headers: ipn.pl Hope you can help

Replies are listed 'Best First'.
Re: PayPal IPN Script End of script output before headers:
by hippo (Archbishop) on Nov 26, 2019 at 16:35 UTC
    Hope you can help

    See the Basic Debugging Checklist for how to help yourself. A consistent indent style wouldn't hurt either.

    If I had to guess I would say that this

    if ($res->is_error) { # HTTP error }

    is being triggered, perhaps caused by this

    SSL_version => 'SSLv23:!TLSv12'
Re: PayPal IPN Script End of script output before headers:
by haukex (Archbishop) on Nov 26, 2019 at 20:11 UTC

    Is that really all that the server log says? What is the output when you run the script from the command line? See also CGI Help Guide and Troubleshooting Perl CGI scripts. Perhaps try adding use CGI::Carp qw/fatalsToBrowser/; to the top of your script (for debugging only!).

        "Argument "Erreur http" isn't numeric in addition (+) at /usr/lib/cgi-bin/ipn.pl line 74.: /usr/lib/cgi-bin/ipn.pl"

        Line 74 of what you posted doesn't seem to be line 74 of what you are running to produce this error...

        These two warnings sound like perhaps you've accidentally used the + operator instead of the concatenation operator ., but as marto said, you didn't actually show the code that's causing the error. As for why it's giving you a "500 Can't connect to ipnpb.sandbox.paypal.com:443", I'd suggest trying to connect to that URL using curl and writing a simple command-line script using LWP::UserAgent to connect to that server, and debugging that.

        Using the test script below I get the INVALID response (as I would expect).

        c:\inetpub\wwwroot\test>perl ipn_test.cgi
        Content-Type: text/plain
        
        REQUEST
        POST https://ipnpb.sandbox.paypal.com/cgi-bin/webscr
        Host: ipnpb.sandbox.paypal.com
        User-Agent: libwww-perl/6.38
        Content-Type: application/x-www-form-urlencoded
        
        cmd=_notify-validate&
        
        RESPONSE
        SUCCESS : INVALID
        
        #!/usr/bin/perl # ipn_test.cgi use strict; use warnings; use CGI; use CGI::Carp 'fatalsToBrowser'; use LWP::UserAgent; my $q = CGI->new(); my $query = 'cmd=_notify-validate;'.$q->query_string; $query =~ s/;/&/g; my $PP_server = 'ipnpb.sandbox.paypal.com'; # sandbox IP:173.0.82.66 my $url = 'https://'.$PP_server.'/cgi-bin/webscr'; my $ua = LWP::UserAgent->new( ssl_opts => { keep_alive => 1, verify_hostname => 1, SSL_version => 'SSLv23:!TLSv12', } ); my $req = HTTP::Request->new('POST',$url); $req->content_type('application/x-www-form-urlencoded'); $req->header(Host => $PP_server); $req->content($query); my $msg; my $res = $ua->request($req); if ($res->is_success) { $msg = "SUCCESS : ".$res->decoded_content; } else { $msg = "ERROR : ".$res->status_line; } print "Content-Type: text/plain\n\n"; printf "REQUEST\n%s\n",$req->as_string; printf "RESPONSE\n%s\n",$msg;

        If you want to run as a cgi you can use this html form to provide parameters

        <html> <head></head> <body><h1>Paypal IPN Test</h1> <form action="ipn_test.cgi" method="post"> item_name : <input type="text" name="item_name" value="f1"/><br/> item_number : <input type="text" name="item_number" value="f2"/><br/> payment_status : <input type="text" name="payment_status" value="f3"/> +<br/> mc_gross : <input type="text" name="mc_gross" value="f4"/><br/> mc_currency : <input type="text" name="mc_currency" value="f5"/><br/> txn_id : <input type="text" name="txn_id" value="f6"/><br/> receiver_email : <input type="text" name="receiver_email" value="f7"/> +<br/> payer_email : <input type="text" name="payer_email" value="f8"/><br/> <input type=submit value="submit form"> </form> </body> </html>
        HTH
        poj