[Date Prev][Date Next][Thread Prev][Thread Next][Interchange by date
][Interchange by thread
]
[ic] Multi page checkout example
After a couple requests of a multi page checkout tutorial, I promised to
make one. However, I am the last person who should be making a tutorial :)
So maybe this is just an example. I don't offer any support, because I
barely know what is going on with it in the first place.
I modeled my checkout after buy.com. My site requires user registration for
a purchase. Please follow one rule.
1. if you want to see this site PLEASE USE my dev site at
http://www.imagemogul.com/cgi-bin/dev/index.html so I won't end up with alot
of erroneous "customers" in my real database. Not that anyone on this list
is erroneous :)
The database is empty, but if you click on "See" then type the word "image"
into the search engine... you will have some options. Or click "Listen" then
the sub category "Opera", or type the word opera into the search engine.
OK. I built my site around foundation (IC)4.8.3. I have 6 pages altogether
including my basket.html for the checkout scheme.
basket.html
a page that, if it has items, will display a "checkout" button.
Clicking this button will send the user to 'checkarea.html'
checkarea.html
If the user is already logged_in, a bounce will send them to
promoarea.html.
If the user is not logged in, then checkarea.html is basically
a login page. I combine my login and new account pages BTW. So
if the user is already registered, they sign in, and go to
promoarea.html.
If they are not registered, they simply start the process on
the same page under new account. After that, they are ported to
editprofile.html.
editprofile.html
This page is pretty much like account.html except after form submit,
it sends the user to promoarea.html.
This page utilizes the account_change profile in etc/profiles.order.
promoarea.html
On this page I know two things, they are logged_in and their state.
Thus I can already have my shipping calculated and ready to go.
This page has a possible total of three payment option buttons.
1. Online CC processing => checkout.html
2. Offline CC or check, by mail/fax => checkout2.html
3. Paypal
In my store, if one of the items in the cart is a downloadable,
then only option #1 appears. If there are no downloadables then
all three options appear.
Customer information cannot be edited at this point, however there
is a little "edit" link next to their information.
checkout.html
Online CC processing. One input present simply asking them to
retype email address. Plus inputs for CC information.
Customer information cannot be edited at this point, however there
is a little "edit" link next to their information.
Errors in the end submission will explain to click "edit" next to
customer information and fix said mistakes.
checkout2.html
Review order. Clicking on "next" will submit order (to IC) with
the shipping status of HOLD.
They are sent to receipt2.html which is a printable page that has
their order details, and fields for them to manually fill in their
CC#, or fold and mail with check.
Has a different Order Route than checkout.
## Order Routes are configured inside of profiles.order
--
If anybody needs the actual pages zipped, I will send them offlist. I don't
want to make any bigger of an email than it has to be, for the gist ;) Send
requests for pages to paul@gishnetwork.com
--
###################OK -- Here are the basic form
elements:#####################
--------------------------------------
basket.html
--------------------------------------
<FORM ACTION="[process-target secure=1]" METHOD=POST name="basket">
<INPUT TYPE=hidden NAME=mv_session_id VALUE="[data session id]">
<INPUT TYPE=hidden NAME=mv_doit VALUE=refresh>
<INPUT TYPE=hidden NAME=mv_orderpage VALUE="ord/basket">
[item-list]
....stuff here.....
[/item-list]
[button
text="checkout"
src="__BUTTON_DIR__/checkout.gif"
hidetext=1
form=basket
]
mv_todo=return
mv_nextpage=ord/checkarea
[/button]
</form>
--------------------------------------
checkarea.html
--------------------------------------
[if session logged_in][bounce href="[area ord/promoarea]"][else]
[if session failure]
[calc]delete $Session->{failure}[/calc]</area>
[/if]
<FORM ACTION="[process secure=1]" METHOD=POST>
<input type=hidden name=mv_session_id value="[data session id]">
<INPUT TYPE=hidden NAME=mv_click VALUE=Login>
<INPUT TYPE=hidden NAME=mv_todo VALUE=return>
<INPUT TYPE=hidden NAME=mv_nextpage VALUE="ord/promoarea">
[set Log In]
mv_nextpage=@@MV_PAGE@@
[/set]
<INPUT type="text" NAME=mv_username VALUE="[read-cookie MV_USERNAME]"
size=12px>
<INPUT TYPE=password NAME=mv_password VALUE="" size=12px>
<input type="hidden" NAME="mv_check" value="Log In">
<input type=image src="__BUTTON_DIR__/login2.gif" border="0" value="Log
In">
</form>
[if !scratch new]
[if session failure]
[data session failure]
[data base=session field=failure value=""]
[/if]
[else]
[set new][/set]
[/else]
[/if]
[set NewAccount]
[if type=explicit compare="[userdb new_account]"]
mv_nextpage=ord/editprofile
[else]
mv_nextpage=ord/checkarea
[/else]
[/if]
[/set]
<FORM ACTION="[process-target]" METHOD=POST>
<input type=hidden name=mv_session_id value="[data session id]">
<INPUT TYPE=hidden NAME=mv_click VALUE=NewAccount>
<INPUT TYPE=hidden NAME=mv_doit VALUE=return>
<INPUT TYPE=hidden NAME=function VALUE=new_account>
<input type="text" NAME=mv_username VALUE=""> (no spaces)
<INPUT TYPE=password NAME=mv_password VALUE="">
<INPUT TYPE=password NAME=mv_verify VALUE="">
<INPUT TYPE=image src="__BUTTON_DIR__/create.gif" border="0"
VALUE="Create Account">
</form>
[/else]
[/if]
--------------------------------------
promoarea.html
--------------------------------------
[if !session logged_in][bounce href="[area ord/checkarea]"][else]
[if !items][bounce href="[area ord/basket]"][/if]
[set mv_no_cache]1[/set]
[set downloadable_present][/set]
<FORM ACTION="[process secure=1]" METHOD=POST name=promo>
<input type=hidden name=mv_session_id value="[data session id]">
<INPUT TYPE=hidden NAME=mv_doit VALUE=refresh>
<INPUT TYPE=hidden NAME=mv_nextpage VALUE=ord/promoarea>
[item-list]
....more code here....
[/item-list]
Customer Information: [page ord/editprofile]edit[/page]<br>
[value company]
[value fname] [value lname]
[value address1]
[if value address2][value address2][/if]
[value city] [value state], [value country]
[value phone_day]
....................................
[if value b_fname]
Shipping Address:
[value b_fname] [value b_lname]
[value b_address1]
[value b_address2]
[value b_city] [value b_state], [value b_country]
Orders shipped to different addresses may be delayed for verification.
....................................
[/if]
[button
text="recalc"
src="__BUTTON_DIR__/recalc.gif"
hidetext=1
form=promo
]
mv_orderpage=ord/promoarea
[/button]
<SELECT NAME=mv_shipmode>
[shipping label=1 mode=|[data table=country key='[value country]'
col=shipmodes]|]
</SELECT>
Secure Online Payment:
MasterCharge, Visa, American Express
[button
text="secure online"
src="__BUTTON_DIR__/arrow.gif"
hidetext=1
form=promo
]
mv_nextpage=ord/checkout
[/button]
[if scratch downloadable_present == 1]
</form>
[else]
Mail / Fax Payment:
MasterCharge, Visa, American Express
Money Order or Check
[button
text="offline"
src="__BUTTON_DIR__/arrow.gif"
hidetext=1
form=promo
]
mv_nextpage=ord/checkout2
[/button]
</form>
Or, you can pay with Paypal:
<form action="https://www.paypal.com/cgi-bin/webscr" method="post">
<input type="hidden" name="cmd" value="_xclick">
<input type="hidden" name="business" value="orders@imagemogul.com">
<input type="hidden" name="item_name" value="[item-list][item-modifier
title],[/item-list]">
<input type="hidden" name="item_number"
value="[item-list][item-sku],[/item-list]">
<input type="hidden" name="amount" value="[subtotal]">
<input type="image" src="__BUTTON_DIR__/paypal.gif" border="0"
name="submit">
</form>
[/else][/if]
[/else][/if]
--------------------------------------
checkout.html
--------------------------------------
[if !session logged_in][bounce href="[area ord/checkarea]"][else]
<FORM ACTION="[process secure=1]" METHOD="POST" name=checkout>
<INPUT TYPE=hidden NAME=mv_session_id VALUE="[data session id]">
<INPUT TYPE=hidden NAME=mv_doit VALUE=refresh>
<INPUT TYPE=hidden NAME=mv_nextpage VALUE="ord/checkout">
[if type=explicit compare="[error all=1 show_var=1 keep=1]"]
There were errors in your last submission:
<blockquote>
<FONT color="__CONTRAST__">
[error all=1 keep=1 show_error=1 show_label=1 joiner="<br>"]
</blockquote>
<p>
[error name=fname required=1]
[error name=lname required=1]
[error name=address1 required=1]
[error name=city required=1]
[error name=state required=1]
[error name=zip required=1]
[error name=email required=1]
[error name=email2 required=1]
[error name=country required=1]
[error name=phone_day required=1]
</p>
[/if]
<!--- credit card information --->
[error std_label="Credit Card Information" name=mv_credit_card_valid]
<INPUT TYPE="hidden" NAME="payment_method" value="credit">
<input type=hidden name=mv_order_profile value=credit_card>
[calc]
my $accepted = $Variable->{CREDIT_CARDS_ACCEPTED};
my (@out);
my (@cc);
my $out;
push @cc, 'visa' if $accepted =~ /visa/;
push @cc, 'mc' if $accepted =~ /mc/;
push @cc, 'disc' if $accepted =~ /discover/;
push @cc, 'amex' if $accepted =~ /amex/;
for (@cc) {
push @out, qq{<IMG SRC="/im/images/small$_.png">};
}
return join ' ', @out;
[/calc]
<INPUT TYPE=text NAME=mv_credit_card_number SIZE=22></b>
<SELECT NAME=mv_credit_card_exp_month>
[loop
lr=1
option=mv_credit_card_exp_month
list="
1 01 - January
2 02 - February
3 03 - March
4 04 - April
5 05 - May
6 06 - June
7 07 - July
8 08 - August
9 09 - September
10 10 - October
11 11 - November
12 12 - December"]
<OPTION VALUE="[loop-code]"> [loop-pos 1]
[/loop]
</SELECT>
<SELECT NAME=mv_credit_card_exp_year>
[comment]
This should always return the current year as the first, then
7 more years.
[/comment]
[loop option=mv_credit_card_exp_year lr=1 list=`
my $year = $Tag->time( '', { format => '%Y' }, '%Y' );
my $out = '';
for ($year .. $year + 7) {
/\d\d(\d\d)/;
$last_two = $1;
$out .= "$last_two\t$_\n";
}
return $out;
`]
<OPTION VALUE="[loop-code]"> [loop-pos 1]
[/loop]
</SELECT>
[button
name="mv_click"
src="__BUTTON_DIR__/placeorder.gif"
text="Place Order"
hidetext=1
form=checkout
]
mv_todo=submit
[/button]
</form>
[seti clear_errors][error all=1 hide=1 comment="Clear errors"][/seti]
[/else][/if]
--------------------------------------
checkout2.html
--------------------------------------
[if !session logged_in][bounce href="[area ord/checkarea]"][else]
<FORM ACTION="[process secure=1]" METHOD="POST" name=checkout2>
<INPUT TYPE=hidden NAME=mv_session_id VALUE="[data session id]">
[if type=explicit compare="[error all=1 show_var=1 keep=1]"]
There were errors in your last submission:
<blockquote>
<FONT color="__CONTRAST__">
[error all=1 keep=1 show_error=1 show_label=1 joiner="<br>"]
</blockquote>
<p>
[error name=fname required=1]
[error name=lname required=1]
[error name=address1 required=1]
[error name=city required=1]
[error name=state required=1]
[error name=zip required=1]
[error name=email required=1]
[error name=email2 required=1]
[error name=country required=1]
[error name=phone_day required=1]
</p></b>
[/if]
<INPUT TYPE=hidden NAME=mv_doit VALUE=refresh>
<INPUT TYPE=hidden NAME=mv_nextpage VALUE="ord/checkout2">
<INPUT TYPE=hidden NAME=mv_order_profile VALUE="checkout_profile">
[item-list]
...more code here...
[/item-list]
<input type="hidden" name="status" value="HOLD">
<INPUT TYPE="hidden" NAME=email_copy VALUE="1">
[button
name="mv_click"
text="Next"
hidetext=1
src="__BUTTON_DIR__/next.gif"
form=checkout2
]
mv_todo=submit
[/button]
</form>
[seti clear_errors][error all=1 hide=1 comment="Clear errors"][/seti]
[/else][/if]
--------------------------------------
profiles.order => checkout_profile
#notice order route
--------------------------------------
__NAME__ checkout_profile
fname=required
lname=required
address1=required
city=required
country=required
[if value country =~ /^(US|CA)$/i]
state=state_province
zip=postcode
[/if]
&or phone_night=phone, phone_day=phone Must have day or evening phone number
&fatal = yes
email=required
email=email
&set = mv_payment Incomplete
[value name=mv_order_route set="log main_b copy_user" hide=1]
[if value fax_order == 1]
&set = mv_payment Check or Money Order (will call)
[elsif variable MV_PAYMENT_MODE]
[/elsif]
[elsif config CyberCash]
&fail=../special_pages/failed
&charge=[var CYBER_MODE]
[/elsif]
[elsif config CreditCardAuto]
[/elsif]
[else]
[/else]
[/if]
&final = yes
&setcheck=mv_email [value email]
__END__
--------------------------------------
profiles.order => credit_card
#notice order route
--------------------------------------
__NAME__ credit_card
fname=required
lname=required
email=email
address1=required
city=required
country=required
[if value country =~ /^(US|CA)$/i]
state=state_province
zip=postcode
[/if]
&or phone_night=phone, phone_day=phone Must have day or evening phone number
email=email
[if type=value term=email2 op=ne compare="[value email]"]
&calc = delete $CGI->{email2}; 1;
email2=mandatory Email2 doesn't match email.[/if]
[value name=mv_order_route set="log main copy_user" hide=1]
&fatal = yes
&set = mv_payment Incomplete
[if variable MV_PAYMENT_MODE]
&credit_card=standard keep __CREDIT_CARDS_ACCEPTED__
&charge=[var MV_PAYMENT_MODE][cgi mv_payment_test]
&set=mv_payment Real-time Credit Card (%c -- [var MV_PAYMENT_MODE])
[else]
&credit_card=standard __CREDIT_CARDS_ACCEPTED__
&set=mv_payment Credit Card (%c)
[/else]
[/if]
&calc = $Values->{mv_payment} =~ s/\%c/$Values->{mv_credit_card_type}/g; 1;
&final = yes
&setcheck=mv_email [value email]
__END__
--------------------------------------
Order Routes
--------------------------------------
Route log <<EOF
empty 1
encrypt 0
increment 0
report etc/log_transaction
supplant 0
track logs/log
EOF
Route copy_user <<EOF
empty 1
error_ok 1
encrypt 0
increment 0
report etc/mail_receipt
supplant 0
track logs/log
EOF
Route main <<EOF
attach 0
credit_card 0
default 1
email '__ORDERS_TO__'
encrypt 0
errors_to '__ORDERS_TO__'
pgp_cc_key "__PGP_KEY__"
pgp_key "__PGP_KEY__"
report etc/report
receipt etc/receipt.html
supplant 1
master 1
individual_track orders
track logs/tracking.asc
EOF
Route main_b <<EOF
attach 0
credit_card 0
default 1
email '__ORDERS_TO__'
encrypt 0
errors_to '__ORDERS_TO__'
pgp_cc_key "__PGP_KEY__"
pgp_key "__PGP_KEY__"
report etc/report
receipt etc/receipt2.html
supplant 1
master 1
individual_track orders
track logs/tracking.asc
EOF
### and comment out the default route in catalog.cfg.
---------------------------------------------------------------------------
END
Paul