Hack 75 Streamlining Checkout and Payment


Use an off-eBay checkout system to integrate payments with shipping and accounting.

In the old days, any seller who wanted to accept credit cards had to get a credit card merchant account. Now, payment services like PayPal, BidPay, and C2IT have made merchant accounts largely unnecessary for everyone but the largest sellers.

But if there's any single truth when it comes to accepting payments on eBay, it's this: the more types of payment you accept, the more bids you'll get.

If you decide to use an off-eBay checkout system, you may wish to disable eBay's own checkout, as described in [Hack #49]. Otherwise, your bidders may skip your preferred checkout in haste, and instead simply use the method with which they're most accustomed.

But there are still reasons to get a merchant account. For instance, sellers who do a lot of business may be able to get a better discount rate as a credit card merchant than they could through PayPal, which essentially means that they'll get to keep a larger percentage of the payments they receive. And anyone who sells merchandise outside of eBay will not want to limit their transactions only to PayPal.

Getting a Merchant Account

This is one thing that eBay won't do for you, and one thing that requires more than spending five minutes filling out a form on some web site. The best way to start is by contacting your bank and asking them to recommend a merchant account provider with which they're affiliated.

A representative will then talk to you and request lots of information about you and your business to help them establish your identity. You'll discuss payment plans and discount rates; don't be afraid to ask questions. When all is said and done, you'll be given a terminal or other means of entering credit card information, and you'll be ready to accept credit card payments.

Be warned?setting up a merchant account is not cheap, and is not for the faint of heart. Also, be extremely wary of Internet and email ads for merchant accounts.

See [Hack #67] for some of the steps you should take to prevent chargebacks and unnecessary fees.

7.5.1 Accepting Credit Card Payments

Once you get your merchant account, the next step is to provide the means for your customers to transmit their credit card numbers and related information to you. This involves an HTML form and a backend script on a public web server. Let's start with a simple order form:

<form action="http://www.ebayhacks.com/cgi-bin/checkout.pl"
            method=post name="ccform" onSubmit="return confirmation();">
<table border><tr><td width=50% valign=top>
  <table border=0 width=100%>
  <tr><td align=right valign=top>eBay auction number(s):</td>
  <td align=left valign=top><input size=12 name="invoice"></td></tr>
  <tr><td align=right valign=top>Total amount of payment:</td>
  <td align=left valign=top><input size=12 name="total"></td></tr>
  <tr><td align=right valign=top>Method of Payment:</td>

  <td align=left valign=top>
  <select name="paytype"><option selected>(please make a selection)
    <option>Visa<option>MasterCard<option>American Express</select>
  <tr><td align=right valign=top>Credit card number:</td>
  <td align=left valign=top><input size=25 name="ccnumber"></td></tr>
  <tr><td align=right valign=top>CVV code:<br>(3-4 digits after
                     your CC number, on the back of the card)</td>
  <td align=left valign=top><input size=4 maxlength=4 name="cvv"></td></tr>
  <tr><td align=right valign=top>Expiration Date:</td>
  <td align=left valign=top>
    <select name="expiremonth"><option selected value="??">(Month)
    <option value="01">1<option value="02">2<option value="03">3
    <option value="04">4<option value="05">5<option value="06">6
    <option value="07">7<option value="08">8<option value="09">9
    <option value="10">10<option value="11">11<option value="12">12
    <select name="expireyear"><option selected value="????">(Year)
</td><td width=50% valign=top>
  <table width=100%>
  <tr><td align=right valign=top>First Name:</td>
  <td align=left valign=top><input name="firstname" size=15></td></tr>
  <tr><td align=right valign=top>Last Name:</td>
  <td align=left valign=top><input name="lastname" size=15></td></tr>
  <tr><td align=right valign=top>E-mail Address:</td>
  <td align=left valign=top><input name="email" size=30></td></tr>
  <tr><td align=right valign=top>Mailing Address:</td>
  <td align=left valign=top><input name="address1" size=30>
    <input name="address2" maxlength=50 size=30></td></tr>
  <tr><td align=right valign=top>City:</td>
  <td align=left valign=top><input name="city" size=25></td></tr>
  <tr><td align=right valign=top>State/Province:</td>
  <td align=left valign=top><input name="state" size=4></td></tr>
  <tr><td align=right valign=top>Zip:</td>
  <td align=left valign=top><input name="zip" size=10></td></tr>
  <tr><td align=right valign=top>Country:</td>
  <td align=left valign=top><input name="country" size=25></td></tr>

  <tr><td></td><td align=left valign=top>
    <input type="submit" value="Complete Your Order">

Place this HTML form on your public web server. You'll need to make sure your server supports SSL (Secure Sockets Layer), so the information your customers enter can be safely submitted to your server, as described in [Hack #29].

Next, install the following backend Perl script, checkout.pl, to process the incoming data and store it in a file.

This script requires the cgi-lib.pl Perl library (http://cgi-lib.berkeley.edu/), used to parse the arguments passed from the HTML form.


&ReadParse;     [1]

$checkoutdir = "/usr/local/home";     [2]
$myemail = "checkout\@ebayhacks.com";
$ordernum = time;

# *** empty fields ***
if ((!keys(%in)) || ($in{'firstname'} eq "") || ($in{'lastname'} eq "")     [3]
    || ($in{'address1'} eq "") || ($in{'city'} eq "") || ($in{'zip'} eq "")
    || (($in{'state'} eq "") && ($in{'country'} eq "")) ||
    ($in{'paytype'} eq "(please make a selection)")
    || ($in{'ccnumber'} eq "") || ($in{'cvv'} eq "") ||
    ($in{'expiremonth'} eq "??") || ($in{'expireyear'} eq "????")) {
  print &PrintHeader;
  print "<b>Error:</b> Please fill out all the fields and try again.\n";

# *** write data file ***
open(OUTFILE,">$checkoutdir/$ordernum.txt");     [4]

  print OUTFILE "[checkout]\r\n";
  print OUTFILE "email=$in{'email'}\r\n";
  print OUTFILE "firstname=$in{'firstname'}\r\n";
  print OUTFILE "lastname=$in{'lastname'}\r\n";
  print OUTFILE "address1=$in{'address1'}\r\n";
  print OUTFILE "address2=$in{'address2'}\r\n";
  print OUTFILE "city=$in{'city'}\r\n";
  print OUTFILE "state=$in{'state'}\r\n";
  print OUTFILE "zip=$in{'zip'}\r\n";
  print OUTFILE "country=$in{'country'}\r\n";
  print OUTFILE "invoice=$in{'invoice'}\r\n";
  print OUTFILE "total=$in{'total'}\r\n";
  print OUTFILE "paytype=$in{'paytype'}\r\n";
  print OUTFILE "cc=" . &formatccnumber($in{'ccnumber'}) . "\r\n";     [5]
  print OUTFILE "cvv=$in{'cvv'}\r\n";
  print OUTFILE "expiremonth=$in{'expiremonth'}\r\n";
  print OUTFILE "expireyear=$in{'expireyear'}\r\n";

open(MAIL,"|/usr/sbin/sendmail -t");     [6]
  print MAIL "To: $in{'email'}\n";
  print MAIL "From: $myemail\n";
  print MAIL "Reply-To: $myemail\n";
  print MAIL "Subject: Order Confirmation\n\n";
  print MAIL "Your payment information has been received.\n";
  print MAIL "Here are the details of your order:\n\n";
  print MAIL "   Name: $in{'firstname'} $in{'lastname'}\n";
  print MAIL "Address: $in{'address1'}\n";
  if ($in{'address2'} ne "") { print MAIL "         $in{'address2'}\n"; }
  print MAIL "         $in{'city'}, $in{'state'}   $in{'zip'}\n";
  print MAIL "         \U$in{'country'}\n\n";
  if (substr($in{'total'},0,1) ne "\$") { $in{'total'} = "\$$in{'total'}"; }
  print MAIL "US$in{'total'} will be charged to your $in{'paytype'}.\n\n";
  print MAIL "Your item(s) will be shipped as soon as possible.  If you\n";
  print MAIL "have any questions, please send them to $myemail\n";

open(MAIL,"|/usr/sbin/sendmail -t");     [7]
  print MAIL "To: $myemail\n";
  print MAIL "From: $in{'email'}\n";
  print MAIL "Reply-To: $in{'email'}\n";
  print MAIL "Subject: $in{'product'} Registration\n";
  print MAIL "A customer, $in{'firstname'} $in{'lastname'}, has\n";
  print MAIL "submitted a payment: order number #$ordernum.\n";

print &PrintHeader;     [8]
print "Thank you for your order.\n";
print "You will receive a confirmation email shortly.\n";

sub formatccnumber{     [9]

  $cc = "";
  $pos = 0;
  for ($i = 0; $i < length($_[0]); $i++) {
    if ("0123456789" =~ substr($_[0], $i, 1)) {
      $cc = $cc . substr($_[0], $i, 1);
      if ($pos / 4 == int($pos / 4)) { $cc = $cc . " "; }
  return $cc;

This script is pretty straightforward. Using the cgi-lib.pl module, the script parses [1] the incoming data into variables. Next, some custom variables are declared [2], which you'll want to modify to reflect your system.

A single if statement [3] checks for empty fields and spits out a generic error message if any problems are found; you'll probably want to expand this to provide more specific and appropriate error messages to your customers. The next section [4] stores the data in a text file, but you can customize this to suit your needs.

Note that on line [5], the credit card number is modified by the formatccnumber function [9], which does nothing more than insert spaces between every four digits and throw out anything else. You'll most likely want to supplement this with code that encodes the number, so you're never storing a raw credit card number on a server that can be compromised by an intruder.

After the information is stored, three more tasks are performed: a confirmation email is sent to the customer [6], a notification email is sent to the seller [7], and a brief confirmation page is shown in the browser window [8].

7.5.2 How to Use It

With these two elements in place, all that's left is to publicize the URL of your checkout form. You'll notice that in both [Hack #66] and [Hack #74], the example payment-instructions email contains a link to a custom order form, complete with the https:// prefix, signifying a secure SSL connection.

When a customer places an order with your checkout form, you'll be sent an automatic email, and a new order record file will appear in the directory you specified on line [1]. You can further automate this hack by linking the script with your inventory system or setting it up to automatically print a prepaid shipping label, as described in [Hack #68].

7.5.3 Checkout Providers

Those who don't want to create their own checkout systems may prefer an extra-cost, all-in-one "turnkey" solution, like any of the following.

  • Andale Checkout. The goal of a service like Andale Checkout (www.andale.com) is to effectively eliminate the back-and-forth emails between buyers and sellers, a necessity if you sell more than 100 items a week. Figure 7-4 shows what your customers will see when they use Andale Checkout to pay.

    Figure 7-4. What your customers see when they pay via Andale Checkout

    Andale Checkout also keeps records of your current and past sales, and offers additional automation such as invoice and shipping label printing and post-sale communications with customers.

  • Vendio Checkout. Similar to Andale Checkout, Vendio Checkout is available with several of Vendio's subscription-based services, such as Sales Manager (www.vendio.com).

  • Selling Manager. eBay's own Selling Manager (pages.ebay.com/selling_manager), discussed in [Hack #76], and Seller's Assistant Pro (pages.ebay.com/sellers_assistant/pro.html), discussed in [Hack #73], both rely on eBay's checkout system, but provide additional post-auction tools and automation not otherwise available.