Beefy Boxes and Bandwidth Generously Provided by pair Networks
Think about Loose Coupling
 
PerlMonks  

Re^3: How do you use Paypal IPN with Dancer2?

by $h4X4_|=73}{ (Monk)
on Jul 12, 2016 at 18:16 UTC ( [id://1167637]=note: print w/replies, xml ) Need Help??


in reply to Re^2: How do you use Paypal IPN with Dancer2?
in thread How do you use Paypal IPN with Dancer2?

In the trouble shooting tips they say to keep the same encoding.
Receiving an INVALID message from PayPal in response to your listener's post back for validation "Ensure that you use the same character encoding for your response string as the encoding specified in the charset field of the original IPN message. When testing using the IPN Simulator, the character encoding will always be UTF-8."

Update: But I use PDT because "So, use PDT if your site includes a feature that requires immediate payment notification." IPN vs. PDT

Update 2: From what I can remember of IPN. It does not matter that much that it comes back "INVALID" because all that is saying is that you did not return the data back the way PayPal wanted. But the transaction still will go through and you should still receive the transaction info from the first IPN response.

Update 3: You did mention encoding and that made me think that maybe the content your getting from request->body; could be encoded or maybe decoded. Or LWP could encode the data before sending it making it a double encoded string. Just a few more things to check for.

Replies are listed 'Best First'.
Re^4: How do you use Paypal IPN with Dancer2?
by MorayJ (Beadle) on Jul 14, 2016 at 19:30 UTC

    Update 2: From what I can remember of IPN. It does not matter that much that it comes back "INVALID" because all that is saying is that you did not return the data back the way PayPal wanted. But the transaction still will go through and you should still receive the transaction info from the first IPN response.

    I've temporarily moved on, but will be coming back to this...was a bit tired of tearning at my hair. Will report back here - but this is a really good point...I could probably live with an unvalidated for the time being as we're not talking about huge amount of sales attracting thousands of cheats

      It can work perfectly. I see a spot in your code that could return 'INVALID'

      $req->content("\n\n"); my $res = $ua->request($req); debug "First response: " $res; $req->content($return_query); $res = $ua->request($req); debug "Second response: " . Dumper $res;
      I think it should be like this.
      my $return_query = request->body; debug 'First response: ' request; # a way to see if you need to decode is check the param payment_date # if it has % and + its encoded. $return_query =~ tr/+/ /; $return_query =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg; $return_query = 'cmd=_notify-validate&' . $return_query; # post back to PayPal system to validate my $ua = LWP::UserAgent->new( ssl_opts => { verify_hostname => 1 } ); +#ssl_opts => { verify_hostname => 1 } my $req = HTTP::Request->new('POST', 'https://www.sandbox.paypal.com/c +gi-bin/webscr'); $req->content_type('application/x-www-form-urlencoded; charset=UTF- +8'); # maybe Host => 'www.sandbox.paypal.com' when using sandbox? $req->header(Host => 'www.paypal.com'); $req->content($return_query); my $res = $ua->request($req); debug "Second response: " . Dumper $res; # make the variable hash my %variable = map { split(m'='x, $_, 2) } grep { m'='x } split(m'&'x, $return_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) { debug "It's an error"; # HTTP error } elsif ($res->content eq 'VERIFIED') { debug "$payment_status"; # check the $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 } elsif ($res->content eq 'INVALID') { debug "It's invalid"; # log for manual investigation } else { debug "It's an error"; # error } print "Content-type: text/plain\n\n"; exit(0);
      This code still has the die issues that perlfan mentioned. I don't use Dancer2 to know how or if it handles die errors.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://1167637]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others rifling through the Monastery: (3)
As of 2024-04-16 04:09 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found