Order Checkout


The site can now be completed by adding the ability to check out with the shopping cart and finalize the order. To do this the customer needs to provide a shipping address (which, for the sake of this tutorial, we will assume is the same as the billing address), and payment information. We will process the order by verifying the customer's payment information and sending an email to the merchant (ourselves) detailing the order.

We first need to create a checkout page. The checkout page consists of a form that receives order information from the customer and performs a simple credit card number check. In this tutorial we will use a built-in test that only checks to see if a given credit card number could be valid. If the information is acceptable the customer will move to the next phase of the order process. If it is not, an error page will be displayed.

To create a checkout page, type the following code and save it as pages/checkout.html. The section that follows explains the code.

[include top]
[include left]
<h1>Checkout Page</h1>

<form method="post" action="[process]">
<input type="hidden" name="mv_todo" value="submit" />
<input type="hidden" name="mv_order_profile" value="order_profile" />
<input type="hidden" name="mv_cyber_mode" value="minivend_test" />

<table cellpadding="3">

<td align="right"><b>First name:</b></td>
<td><input type="text" name="fname" value="[value fname]" /></td>

<td align="right"><b>Last name:</b></td>
<td><input type="text" name="lname" value="[value lname]" /></td>

<td align="right" rowspan="2"><b>Address:</b></td>
<td><input type="text" name="address1" value="[value address1]" /></td>

<td><input type="text" name="address2" value="[value address2]" /></td>

<td align="right"><b>City:</b></td>
<td><input type=text name="city" value="[value city]" /></td>

<td align="right"><b>State:</b></td>
<td><input type="text" name="state" value="[value state]" /></td>

<td align="right"><b>Postal code:</b></td>
<td><input type="text" name="zip" value="[value zip]" /></td>

<td align="right"><b>Country:</b></td>
<td><input type="text" name="country" value="[value country]" /></td>


Note: We assume that your billing address is the same as your shipping address.

<table cellpadding="3">

<td align="right"><b>Credit card number:</b></td>
<td><input type="text" name="mv_credit_card_number" value="" size="20" /></td>

<td align="right"><b>Credit card expiration date:</b></td>
Month (number from 1-12):
<input type="text" name="mv_credit_card_exp_month" value="" size="2" maxlength="2" />
Year (last two digits only):
<input type="text" name="mv_credit_card_exp_year" value="" size="2" maxlength="2" />


<input type="submit" name="submit" value="Finalize!" />
<input type="reset" name="reset" value="Reset" />


<p>[page index]Return to shopping instead</a></p>
[include bottom]


The HTML form begins with a method of 'post' (which sends the form data as its own stream, as opposed to the 'get' method which encodes the data as part of the URL). The [process] tag creates a special URL for form processing. Interchange has a built-in form processor that is configured by submitting certain fields in the form. The Finalize button will invoke this form processor and link the user to the special_pages/receipt.html page, which is described later.

The code [form-session-id] basically just expands to a hidden form variable that specifies the session ID. It is very important to always include this in every HTML form. That way, Interchange can work properly even when the client is not accepting cookies!

You are also submitting some hidden form values that will tell Interchange how to process this form. The first value, mv_todo was set to "submit". This causes the form to be submitted for validation. The second value, mv_order_profile was set to "order_profile. This determines the name of the profile according to which the validation will be performed.

The last value, mv_cyber_mode, was set to "minivend_test". The mv_cyber_mode value determines what method will be used to charge a credit card. The value of minivend_test uses the internal test method, which calculates a simple checksum against the card to determine if it is a valid number.

When preparing an order for processing, Interchange looks for certain named fields in the form to obtain name, address, and credit card information. We are using all expected (default) field names in this form so that no translation needs to take place.

View the checkout page in your browser. The "Finalize!" link has not been enabled, but the page should display properly.


You need to set up verification for the order form by defining an order profile for the form. An order profile determines what fields are necessary for the form to be accepted. Create an order profile by typing the following and saving it as etc/profiles.order. The section that follows explains the code used:

__NAME__ order_profile


&credit_card=standard keep



A single file can contain multiple profile definitions. First the profile is named using the __NAME__ pragma (but this is unrelated to the __VARIABLE__ syntax seen elsewhere in Interchange). Then in the profile there is a list of the form fields that are required. The &fatal setting indicates that validation will fail if any of the requirements are not met. &final indicates that this form will complete the ordering process. This setting is helpful if you have a multi-page ordering process and you want to validate each page individually. The __END__ pragma signals the end of this profile, after which you can begin another one.

In order to activate your order profile, add the OrderProfile directive to the catalog.cfg:

OrderProfile etc/profiles.order

Watch for white space in front of the __NAME__ pragma, it can cause your profile to be ignored. Remember to reconfigure the catalog or simply restart Interchange altogether after modifying catalog.cfg or the profiles.


If the submitted form lacks a required field, Interchange will display an error page. The default location is special_pages/needfield.html. Here's the code for the page:

[include top]
[include left]
<p>The following information was not given:</p>

<p><b>[error all=1 show_var=1 show_error=1 joiner='<br>']</b></p>

<p>Please go back to the [page checkout]checkout page</a>
and fill out the form properly.</p>

[include bottom]


The [error] tag is the most important tag on this page. The 'all' parameter tells the tag to iterate through all of the errors reported from the failed verification, and the 'show_var' parameter indicates that the failed variable name should be displayed. For example, if the first name was left empty, 'fname' would be shown. The 'show_error' parameter displays the actual error for the variable. The joiner parameter inserts an HTML <br> tag between each error message, so each error is displayed on its own line. In more complex configurations, the [error] tag can be even more expressive.

Credit Card Processing

This tutorial uses a very simple order process. To accomplish this, we use "&credit_card=standard keep" in the file etc/profiles.order. It issues two instructions to the credit card system:

The first option, standard, uses the standard built-in encryption algorithm to encrypt the credit card number and erases the unencrypted copy from memory. We are using the standard option not to encrypt the number but to run the checksum verification on the number to verify that it is a potentially correct number. We will not be checking with a real payment processor to see if it actually is a valid card number. For testing purposes, you can use the card number 4111 1111 1111 1111, which will pass the checksum test.

The second option, keep, keeps the credit card number from getting removed from memory. We want to keep the number in memory so that it is available when it is mailed to the store owner as part of the order.

If the credit card number passes and all of the required fields are present, the customer will be sent to the final page. Interchange then sends an e-mail to the store owner.


When the customer's involvement in the order is complete, Interchange composes an email and sends it to the recipient defined in the MailOrderTo directive in catalog.cfg. The default location for this email report template is etc/report. Interchange tags can be used to fill in the body of the message.

The report should include at least the customer's name, address, and the items they ordered. The following is a simple report template; save it as etc/report:

               Name: [value fname] [value lname]
            Address: [value address1][if value address2]
                     [value address2][/if]
  City, State, etc.: [value city], [value state]  [value zip] [value country]

      Credit Card #: [cgi mv_credit_card_number]
    Expiration Date: [cgi mv_credit_card_exp_month]/[cgi mv_credit_card_exp_year]

  ************ ORDER ************
  [item-quantity] x [item-description] ([item-code]), [item-price] ea.
  Subtotal: [subtotal]
     Total: [total-cost]


This file is in plain text format where, unlike HTML, white space is relevant. It is fairly straightforward, except that the [if] tag was added to only include the optional second address line if the customer filled it in.

One of the special properties of the mv_credit_card_number field is that Interchange specifically precludes the credit card number from being saved. This makes it unavailable to you in the [value] tag. The [cgi] tag is used to circumvent this important security measure in order to get the value submitted from the last form.

[Warning] Warning

Obviously it is a bad idea to send a real credit card number over an insecure channel like email. In a real configuration, you would encrypt the number securely before emailing or storing it.


Once the report has been run, Interchange will finish the order process on the customer side by displaying a success screen containing a receipt. The default location for this page is special_pages/receipt.html. To create a receipt page, type the following code and save it as special_pages/receipt.html.

[include top]
[include left]
<p>Thank you for ordering stuff from us.<br>Have a nice day!</p>
<p>[page index]Return to our welcome page</a></p>
[include bottom]


Once the order is processed, the customer's shopping cart is emptied.

At this point you have a more-or-less functional store. Congratulations once again ;)

Phase 4: Tutorial Files

We have prepared the files from this tutorial phase for download in .tar, .tar.gz, .tar.bz2, and expanded formats.

DocBook! Interchange!