footpad has asked for the wisdom of the Perl Monks concerning the following question:
The apprentice, trying to avoid making too many blunders, requests the consideration of the more experienced...
I've been asked to help setup a PayPal-based signup script for an organization's membership sign-ups. They offer four types of memberships at different prices. In reviewing PayPal's documentation, it looks like I'll need to construct a script that determines the selected membership and then uses LWP::Simple to post a query to PayPal's servers. PayPal even provides a sample script that can be adapted to such a thing.
Here's *THEIR* code, with minor editing, for review and understanding of where I'm going with 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/+/ /; ### What's this doing? ### $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 }
With this in mind, here are my thoughts and petitions:
Clearly, the above needs a bit of work, such as use CGI, -wT, use strict, and so on.
Since I plan to run my converted version after the user clicks a submit button on my form, would it best to trigger something along these lines? Or should I consider a redirect instead? If the latter, what things should I keep in mind?
I note that while PayPal's services are being called using HTTPS://, I wonder if there aren't additional security concerns I should be aware of. (Note: The pricing of the memberships is preset, so I won't be relying on the form to provide those. By doing so, I hope to avoid the standard shopping cart problems. Is there a MEME in that assumption? I will be relying on a selected radio button for the membership type, but not the actual price.)
PayPal's manual contains several examples of, well, troubling code. For example, their Shopping Cart section recommends a JavaScript snippet to add items to a cart. This is disturbing since more experienced users are deactivating JavaScript or having it stripped for them. This isn't a problem for this job, but I presume that a better approach would be to add/test actions in the script itself. Is that a correct assumption?
What the heck are they trying to accomplish with that regular expression I flagged with the "### What's this doing? ###" comment? It looks like a prime candidate for simplification, for it *looks* like it's converting the submitted string to decimals representing the ASCII codes of the string. Is that correct? If so, can it be golfed or revised to something more idiomatic?
Are there other bits of wisdom and experience you'd be willing to share regarding this type of problem?
What happens if you POST tainted data through something like this? I ask because it would be nice to know how, um, retentive I should be in constructing the caller script. I know, never trust the user's data...however. If PayPal already has such measures in place, should I rely on those? Probably not, but I thought i'd ask in case one or more of you have gone through this already.
I know it seems like a laundry list, but this is (as I noted earlier) research designed to help me avoid common traps, pitfalls, or other insecurity issues. Since it's my wife who asked me to do this, I'd like to avoid make myself (or her) look like a fool in front of the rest of the organization. I'd also like to keep them (and my host) from getting cracked.
--f
|
---|
Replies are listed 'Best First'. | |
---|---|
Re: PayPal Advice
by tachyon (Chancellor) on Jul 06, 2001 at 21:44 UTC | |
Re: PayPal Advice Sought
by MeowChow (Vicar) on Jul 06, 2001 at 21:53 UTC | |
by epoptai (Curate) on Jul 07, 2001 at 03:37 UTC | |
by ariels (Curate) on Jul 08, 2001 at 01:07 UTC | |
by MeowChow (Vicar) on Jul 08, 2001 at 01:11 UTC | |
by John M. Dlugosz (Monsignor) on Jul 08, 2001 at 02:20 UTC | |
Re: PayPal Advice Sought
by strredwolf (Chaplain) on Jul 06, 2001 at 23:07 UTC |