PerlShop is a shopping cart program that displays a catalog that is
embedded in static html pages using hidden form field tags. You can use
any design for your catalog pages, PerlShop will only add navigational
menu bars and buttons when it displays the pages.
A unique order number is assigned to each user upon entering the store.
The order number is used to keep track of the state of each user's transactions
and is saved across each user's session using hidden fields.
PerlShop was designed from the beginning with security in mind. Please
read the security section below to
make sure you understand how to properly implement the security features
before you start accepting orders.
Upgrading from Version
1.0
If you are currently using PerlShop, there are only two things you need
to be aware of when upgrading to verision 2.2
- You must make all the changes in the Customizing
the Script section below again.
- The order of the Hidden Html tags on the catalog pages is now important.
See the "Order of Hidden
Tags" section below for more details.
Installing
the Script
- Locate your cgi directory (usually 'cgi-bin'), change to that directory,
and create a subdirectory under it to hold the PerlShop script, e.g. 'mkdir
MyStore'.
- Change the permission on the directory by entering the command 'chmod
777 MyStore' from within the cgi-bin directory.
- Copy the PerlShop.cgi script to the subdirectory created in step #1
above.
- Find the location of the Perl Interpreter on the web server (usually
/usr/bin/perl, or /usr/local/bin/perl), you can usually find it by entering
'where' perl' at the command prompt, if that doesn't work, try entering
'which perl' or 'whereis perl'. If you still have trouble finding it, ask
your ISP where it is located.
- Edit PerlShop.cgi and change the first line to point to the location
of the Perl interpreter on the server found in step 2 above, (e.g. '#!
/usr/bin/perl').
- Make it executable by entering one of the following commands at the
prompt:
- If using CgiWrap use: 'chmod 700 PerlShop.cgi'
- If not using CgiWrap use: 'chmod 755 PerlShop.cgi'
- Test it out by entering 'PerlShop.cgi' at the command prompt, it should
display a copyright notice.
- Create the following subdirectories under the subdirectory you created
in step #1 above:
customers, orders, catalog, tokens, temp_customers, temp_orders, log.
(e.g. /cgi-bin/MyStore/customers, /cgi-bin/MyStore/orders, etc.), and change
their permissions with 'chmod 777 customers', etc.
- Create a subdirectory under your main document directory (usually this
is the Public_Html, or the htdocs directory, not the cgi-bin directory!),
that will contain contain any image files (gif, jpg) that are to be used
by the PerlShop script, and copy the images there.
Customizing
the Script
- Server Customization
- Change the variable '$use_cgiwrap' to 'yes' if running the script under
cgiwrap, set it to 'no' otherwise.
- Change the variable '$server_address' to the ip address (or the equivalent
domain name, e.g. www.myserver.com) of the server the script will be running
on.
- If not using cgiwrap, change the variable '$cgi_directory' to
the subdirectory of your cgi-bin directory which was created in step #1
under "Installing the Script". e.g. '/cgi-bin/MyStore'
- If you are using cgiwrap, change the variable '$cgiwrap_directory'
to the subdirectory of your cgi-bin directory which was created in step
#1 under 'Installing the Script', using a format like '/cgi-sys/cgiwrap/username//MyStore'
(see your ISP for the exact format).
- Change the variable '$image_directory' to point to the subdirectory
created above in step #8 under "Installing the Script" to hold
image files (e.g. '/MyStore/Images')
- Change the '$mail_via' variable to the type of email program you wish
to use, either sendmail, blat, or the built-in 'sockets' email routine.
- If using 'sendmail', change the variable '$sendmail_loc' to point to
the location of the sendmail program on the server (e.g. '/usr/sbin/sendmail')
- If using 'blat', change the variable '$blat_loc' to point to the location
of the blat program (e.g. 'c:\\winnt35\\system32\\blat')
- If using the built-in 'sockets' routine, then set the value of the
'$smtp_addr' variable to the ip address of your smtp mail server.
- If you did not use the default subdirectory names as specified above
in step #9 under "Installing the script", then you must modify
the corresponding variables in the script to point to the subdirectories
that you created.
- Company Customization
- If you wish to include an image at the top of the pages generated by
PerlShop, you must change the values of the '$banner' variable, and the
associated image attribute variables ($hspace, $vspace, $border, $height,
$width, $width, $align). If you do not want to include an image, you must
set the value of '$banner' to a null string (e.g. "").
- If you wish to include a background image or change the background
color of the generated pages, change the value of the '$background' and
'$background_color' variables.
- Change the '$company_name' variable to the name of your own company.
- Change the '$company_address' variable to the address of your own company,
each address line must be separated by a '<br>' html tag.
- Change the '$company_email' variable to the email address at your company
that you will use for catalog related inquiries.
- Change the '$mail_order_to' variable to the email address at your company
that will receive the emailed order confirmations.
- Change the '@accept_payment_by' variable to include the valid methods
of payment that your company will accept.
- If your company will accept credit card payments, then change the '@valid_credit_cards'
variable to include the valid card types your company will accept.
- If your company will accept COD payments, then change the '$cod_charge'
variable to the value of the amount that will be added to the order for
COD shipments.
- If your company adds a separate handling charge to each order, change
the '$Handling' variable to the amount to be added.
- Change the '$Pay_checks' variable to the name of the person or company
that checks should be made out to if the order is being paid by check.
- Change the text of the '$return_policy' variable to reflect your own
company's return policy that will be included at the bottom of each order
confirmation.
- Change the '$catalog_country' variable to the name of the Country your
catalog site is based in.
- Change the '$accept_any_country' variable based on whether or not you
will accept orders from a country that you have not explicitly listed in
the '@Shipping_Rates' table. If you set this variable to 'yes', then you
must have an 'OTHER' entry in the '@Shipping_Rates' table.
- Change the text of the '$local_currency' and '$local_weight' variables
as appropriate for the country your catalog site is based in.
- If any of the Items in your catalog will use either the 'Item_weight'
or 'Item_option' tags, then you must enter a value for the '$weight_caption'
and/or '$item_caption' variables.
- Change the '$shipping_type' variable to the method of calculating shipping
that your company will use.
- Modify the '@Shipping_Rates' variable to reflect the shipping companies
that your company uses, and the rates your company charges.
- If your catalog will provide a discount based on the quantity ordered
or the total price, then modify the '$discount_type' and '@Discount_Rates'
variables appropriately.
- Modify the '@Tax_States' variable to include any states for which your
company must charge sales tax, and the rate charged.
- If you want to allow the shopper to see their orders (i.e. what's in
the shopping cart), without leaving the current page after pressing the
'ORDER' button, then you can make that the default mode by setting the
'$stay_on_page' variable to 'yes'.
Creating the
Catalog Pages
- Catalog Page Format
- Entering the store:
You must have a page with a submit button on it to enter the store.
You can add the button to one of your existing pages, or you can create
a new entry page. The Html for the form to create the button should have
the following tags:
- <form METHOD=POST ACTION="http://www.arpanet.com/cgi-bin/PolishBooks/perlshop.cgi>
- <input type=SUBMIT NAME=ACTION value="ENTER SHOP">
- <input TYPE=HIDDEN NAME=thispage VALUE="page1.html">
- <input TYPE=HIDDEN NAME=ORDER_ID VALUE="!ORDERID!">
- </form>
(NOTE: You can not use the !MYURL! option for the ACTION part
of the <form...> tag here!)
The text of the Submit button for can be different (change the text
of the 'VALUE=' for the 'INPUT type=SUMIT' tag), but it must start with
either 'ENTER', or 'GO TO', or '->', or '['. For example,
any of the following are valid entry buttons:
- Server Independence
Instead of using a hardcoded URL on your catalog pages, you can use
the !MYURL! and !MYWWW! tags. If you ever move your catalog to another
server or domain, you won't have to change all the references to your URL.
- !MYURL!
Use this as the action for a POST or GET tag. For example:
<form method=post action="!MYURL!">
<a href="!MYURL!?action=thispage&thispage=page1.html&ORDER_ID=!ORDERID!">
- !MYWWW!
Use this as the URL for non-cgi references (e.g. images). For example:
<img src="!MYWWW!/images/logo.gif">
- Built-in Navigation tags
Each page of your catalog that you create can have a tag on the first
line of the page that has links to the previous and next pages of the catalog.
For example, the tag for the first line of page2 of the catalog would look
like:
<PSTAG
prevpage=page1.html nextpage=page3.html>
( If page1.html was the first page, then on page1.html you would use
page1.html as the prevpage. If the last page was page3.html, then on page3.html
you would use page3.html as the nextpage).
- Custom Navigation tags
You can create a menu navigation system for your catalog by using either
a submit button or <a href ...> link for each destination. These
buttons or links can appear either on a menu page just after your Catalog
Entry Page, or on any of your individual catalog item pages, or both.
- Using Forms
Each submit button would have the format shown below (with 'NAME=none'
for the SUBMIT tag), but with a different file title for the VALUE of the
hidden 'NAME=thispage' tag. For example:
<form METHOD=POST ACTION="!MYURL!">
<input type=SUBMIT NAME=none VALUE="VCR'S">
<input TYPE=HIDDEN NAME=thispage VALUE="page1.html">
<input TYPE=HIDDEN NAME=ORDER_ID VALUE="!ORDERID!">
</form>
<form METHOD=POST ACTION="!MYURL!">
<input type=SUBMIT NAME=none VALUE="CAMERA'S">
<input TYPE=HIDDEN NAME=thispage VALUE="page2.html">
<input TYPE=HIDDEN NAME=ORDER_ID VALUE="!ORDERID!">
</form>
- Using Links
Each <a href ...> tag would have the following format:
<a href="!MYURL!?ACTION=thispage&thispage=page1.html&ORDER_ID=!ORDERID!">THISPAGE</a>
- Single Item Selection Forms.
(Click
here to see the html source of the actual Single Item selection sample
page as used in the demo store)
In this format, each individual item for sale in the catalog is contained
within it's own html <form>...</form> block. You can have both
Single Item and Multiple
Item selection forms in the same catalog, and even within the same
page. A sample Single Item Selection Form follows with an explanation of
each line below it:
- <FORM METHOD=POST ACTION="!MYURL!">
- <input type="submit" name=ACTION value="ORDER">
- <INPUT TYPE=HIDDEN NAME=ORDER_ID VALUE="!ORDERID!">
- <INPUT TYPE=HIDDEN NAME=ITEM_ID VALUE="12345">
- <INPUT TYPE=HIDDEN NAME=ITEM_NAME VALUE="Polish for Dummies">
- Polish For Dummies $212.98 <br>
- <INPUT TYPE=HIDDEN NAME=ITEM_PRICE VALUE="212.98">
- <INPUT TYPE=HIDDEN NAME=thispage value=page1.html>
- Qty:<INPUT TYPE=TEXT SIZE=3 MaxLength=3 NAME=QTY VALUE="1">
- This book is especially good for beginners. <br>
- <INPUT TYPE=HIDDEN NAME=ITEM_CODE value="!ITEMCODE!">
- </FORM>
Description of each line above:
- This is the opening form tag with the location of the perlshop.cgi
program on your server.
- This is a hidden field that tells the perlshop script to process the
'ORDER' action command, and creates the 'ORDER' button on the catalog page.
(The 'ORDER' command can actually be any text that starts with any
of the words: 'ORDER', 'ADD', 'BUY', or 'PUT')
- This is a hidden field that has a placeholder !ORDERID! that will be
replaced automatically by the perlshop script with the actual unique invoice
number for this shopping session.
- This is a hidden field whose value should be set to item number you
have assigned for this catalog item. Each item number must be unique.
- This is a hidden field whose value should be set to the name of the
item.
- This is the name of the item, and the price, as it will appear on the
catalog page.
- This is a hidden field whose value should be set to the price of the
item. The price must be in the format '999999.99', i.e. no commas, and
no leading dollar sign. There is no limit on the actual price of the item.
- This is a hidden field whose value should be set to the actual file
title of the page that this catalog item is located in.
- This is the Quantity field that will appear on the form whose value
is the default number of items that will be ordered if a customer orders
this item.
- This is some descriptive text you can add if the item name does not
sufficiently describe the item being ordered.
- This is a hidden field that has a placeholder !ITEMCODE! that will
be replaced automatically by the perlshop script with a unique digital
signature generated for this catalog item and shopping session only
- This is the closing form tag.
- Multiple Item Selection
Forms
(Click
here to see the html source of the actual Multiple Item selection sample
page as used in the demo store)
This format allows for ordering multiple items with one press of the
'ORDER' sumission button. More than one item is contained within the same
html <form>...</form> block. You can have both Multiple Item
and Single Item selection
forms in the same catalog, and even within the same page. A sample
fMultiple Item Selection form follows, note that there is only one of each
of the 'form', 'submit', 'ORDER_ID', 'ITEM_CODE', and 'thispage' tags.
<FORM METHOD=POST ACTION="!MYURL!">
<INPUT TYPE=HIDDEN NAME=ITEM_ID VALUE="12348">
<INPUT TYPE=HIDDEN NAME=ITEM_NAME VALUE="Polish in 623 Days">
Polish in 623 Days $15.98
<INPUT TYPE=HIDDEN NAME=ITEM_PRICE VALUE="15.98">
Qty:<INPUT TYPE=TEXT SIZE=3 MaxLength=3 NAME=QTY
VALUE="0">
Learn Polish at your own rate.
<INPUT TYPE=HIDDEN NAME=ITEM_ID VALUE="12349">
<INPUT TYPE=HIDDEN NAME=ITEM_NAME VALUE="Polish in 53 easy
lessons">
Polish in 53 easy lessons $31.98
<INPUT TYPE=HIDDEN NAME=ITEM_PRICE VALUE="31.98">
Qty:<INPUT TYPE=TEXT SIZE=3 MaxLength=3 NAME=QTY VALUE="0">
Easy guide to learning Polish.
<input type="submit" name=ACTION value="ORDER">
<INPUT TYPE=HIDDEN NAME=ORDER_ID VALUE="!ORDERID!">
<INPUT TYPE=HIDDEN NAME=ITEM_CODE value="!ITEMCODE!">
<INPUT TYPE=HIDDEN NAME=thispage value=multi.html>
</FORM>
- Optional Tags
The following html tags are optional:
- WEIGHT
This 'type=hidden' tag can be used if you want to calculate the shipping
charges based on weight. The value of the tag should be the shipping weight
of the item. If you want to use this tag, you must change the value
of the '$weight_caption' variable (eg. $weight_caption="Weight").
- TAXTYPE
This 'type=hidden' tag can be used if some of the items that you sell
are taxable, and some are not. The default is to add tax (if you have made
an entry in the '@Tax_States' variable), but you can override it for individual
items by using a <INPUT TYPE=HIDDEN NAME="ITEM_TAXTYPE"
VALUE="none"> tag.
- OPTIONx
These tags can be used to specify any attributes of the items that
you sell. For example, this tag can be used to specify the Color or Size,
or any other descriptive attributes of your items. You can have up to three
different OPTION tags. If you want to use this tag, you must change
the value of the '$option1_caption' variable to the name of the option
(e.g. $option1_caption = "Color"), and so on for each option.
(You can let the user pick the value of the option by creating listboxes,
radio buttons, or even through an input field.)
- StayOnPage
By placing a tag within the <form>...</form> block, this
tag can be used to override the value of the '$stay_on_page' variable in
the script. For example, the following tag allows the user to change the
default value from 'no' to 'yes' by selecting a checkbox:
<input type=checkbox name="StayOnPage" value="YES">
- Order of Html Tags
The order of the Html Tags is Very Important!
- The 'ITEM_CODE' tag MUST be the very last tag just before the
closing </form> tag.
- If any of the optional tags 'ITEM_WEIGHT', 'ITEM_TAXTYPE', or 'ITEM_OPTIONx'
exist, then they MUST appear before both the 'ITEM_ID' and 'ITEM_PRICE'
tags.
- Each Html Tag Should be on a line by itself.
- Automating Catalog
Page Creation
There are several programs currently available that will allow you
to generate your catalog pages from an existing database. The programs
usually read an html template file that you have created, replacing special
tags with data from the database.
- BestWeb
- BackPage(tm)
Free (requires Microsoft Access 95 and Microsoft Windows 95)
- 4W Publisher(tm)
- Appendix
- Security
IMPORTANT NOTE: PerlShop as distributed includes several security features,
but these must be augmented by external programs for real security. No
guarantees or warranties of any kind regarding security are made, either
using PerlShop alone or augmented by external programs. Since PerlShop
is distributed as source code, it is possible someone could modify it to
create holes in the security. One way to minimize this possibility is to
record digital signatures, using MD5, SHA or PGP, of perlshop.cgi and check
them occasionally.
- File Security
The files created by an internet server are normally created under
the user 'nobody', this is not very secure since anyone else running a
script under the default 'nobody' user would have access to those files.
The only way to secure the PerlShop output files is to run it under
your own userid. This can be done by using the program cgiwrap.
When using cgiwrap, the script itself should have it's permissions set
to 700 to prevent access from a non-cgiwrap URL.
PerlShop will also set all output file permissions so that the files
created are only accessible to your own userid.
The output files should be created in subdirectories of your cgi-bin
directory as specified in the Installing the Script section above, and
not within your server's document directory tree, (but make sure that the
server you are using is set up so that the files in your cgi-bin directory
tree are not directly accessible as html document files from a browser.)
The output files are not encrypted online, since (unless you use public-key
encryption) anyone having access to them would obviously have access to
the encryption key used within the program as well.
The output files should be periodically removed from the Internet server
as often as possible. If you don't remove them, you should at least encrypt
them manually, making sure not to store the encryption key on the server.
If transferring the files to your own computer, they should be encrypted
first.
- Transaction Security
The only way to ensure the security of each transmission is to use
an encryption enabled browser/server combination. You just need to find
out the URL of your secure server, and change the URL's generated within
PerlShop accordingly.
PerlShop attempts to guarantee the integrity of each transaction by
creating a digital signature
of the data sent in each transaction, and sending the signature along with
the data. On receipt of each transaction, the signature is re-computed
and compared to the one received, if there were any alterations of the
data, the two signatures would not compare, and the transaction is rejected.
- Debugging
Please see the following references first, then if you still have problems,
you can send email to: perlshop@arpanet.com
- Cgi Debugging
- The Idiot's
Guide to Solving Perl CGI Problems
- Output File Formats
- Customer File
A single record CSV (comma separated, quoted) file with the following
fields:
invoice#, ip address, date, time, title, first name, last name , company,
street1, street2, city, state, zip, country, email, daytime phone, daytime
extension, evening phone, evening extension, fax, Shiptype, Payby, Cardtype,
Card#, Expire month, Expiration year, source, suggestions, sub_total, tax,
shipping, grand_total, total_discount, cod_charge, handling.
- Order File
A multiple record CSV (comma separated, quoted) file with the
following fields: invoice#, item id#, item name, price, quantity. The following
optional fields also appear: weight, taxtype, option1, option2, option3
(they will appear, but be blank if the option is not applicable).
- log File
A single record CSV (comma separated, quoted) file with the following
fields:
Page title, date, ip address.
- Requirements:
PerlShop has currently been tested using Perl5 under Unix running the
Apache server, and under Windows running
the WebSite server.