Technical FAQ: (Last Update 10/03/00)

Contact: Jason Daniel (jasond@processing.net) Note: Items in []'s represent variables. new Some sample code from Tom 6/17/99 (donate.cgi & collate.cgi) 1. How does your process work? 2. What do I get with my account? 3. How do I access my online database? 4. What do I need to give to you? 5. What are modes? 5a. Local 5b. Remote 5c. Instructions for use of msg.exe 6. Remote Mode Sample Pages and Scripts: 6a. A sample html order page with javascript that creates the orderid 6b. A sample html order page for a site with a secure server 6c. A sample perl script to check to see if the user is coming from our system 6d. A sample perl script that creates and order page with a orderid 7. Remote Mode Options: 7a. pass_thru 7b. inline 7c. cust_email 8. How do I change information in my set-up? 9. I have lost my password/vendorname what do I do? 10. What is your network set-up and location details? 11. Whom do I contact for more information? 12. What are some error codes that a bad card will produce? 13. What happens if a card is used over and over? 14. How many transactions can you handle? 15. What does Lestat mean? 16. donate.cgi & collate.cgi 1. How does your process work? We think we have developed a fairly simple system for online merchants to use. It can both be implemented in a very simple way but can also work with very complex ordering systems. The basics are as follows: 1. A "POST" request is sent to our server (https://lestat.processing.net/cgi-bin/nph-charge) 2. Our server looks for 3 key fields A. vendor - Your vendor id with us B. price - The <b>total</b> price of the transaction C. orderid - The unique orderid These fields are sent to us in the following format: <INPUT TYPE="[hidden, text, etc]" NAME="[key field]" VALUE="[value]"> example for vendor <INPUT TYPE="hidden" NAME="vendor" VALUE="VEND"> 3. Our server looks for other secondary fields. 1. card - the credit card number 2. expr - the expiration date of the card 3. pass_thru - a flag to send the return values 4. inline - a flag similar to pass_thru 5. cust_email - an optional field that will send a email to the specified value 4. If the fields "card" and "expr" are present our server goes directly to processing the card. 5. If either "card" or "expr" is missing a screen appears that requests card number and expration date. Once the card and experation date are entered, the server tries to process the card. 6. When the processing starts, a clock appears and begins to tick down. The connection is kept open until the transaction is completed. 7. Two things can happen after the response: 1. Declined: A default message of: "We're sorry, your card has been declined. This can happen for many different reasons. Often the card number or the expiration date is simply incorrect. In other cases, the card may be over its limit. The Processing Network does not make the decision and we can provide no additional information, except for the message below. If you have any questions about your card, contact the issuing bank." Your card was declined for the following reason: [ERROR MESSAGE] 2. Accepted: A link is presented back to the URL specified by you the merchant. 1. If "pass_thru" is enabled, the link is a "POST" with all of the information sent to us, "passed through" in hidden fields (see pass_thru) 2. If "pass_thru" is not enabled the link is a "GET" link 3. If "inline" is enabled instead of forcing the user to click on a button our own system, which uses a command line web browser to fetch a page from the vendor and passes the same transaction information as in the pass_thru case (approval, price, orderid, and any additional fields that appeared in the vendor's original form submission to us). (see inline) 4. If "cust_email" is enabled a email receipt is sent to the address specified 8. After an accepted transaction your online database is written with all of the information that was sent with the order. 9. An email receipt of the transaction is sent to you. 2 What do I get with my account? With your account you will get the following: Vendor name: Always four uppercase letters or numbers. Example: TPN1 Password: This will be used to access your database and to confirm identities of individuals in your organization who are not on the contact information for your account. Access to your order database which does following: 1. Allows you to search for orders by orderid, date, and last four digits of a card 2. Allows you to manually charge a card 3. Allows you to manually authorize a card (checks for funds but does not charge) 4. Allows you to manually credit any transaction in the database 5. Allows you to view individual orders which contain all of the information passed to us 5. Displays the totals of our account including our fees If you are using Local mode you will also have a 16-digit hexadecimal key, used to encrypt the transaction and verify that the transaction is authentic. 3 How do I access my online database? Open the following URL: https://lestat.processing.net/cgi-bin/vendortools/menu You will be prompted for a username and password. If you are not prompted for a username and password and get a "Document Not Found" error, try shutting down your browser and starting it again (this is bug known in Netscape that does not allow multiple usernames and passwords to be accepted in a single session) 4 What do I need to give to you? You will need to specify the following for us: 1. A return URL - this is the URL that you want a customer to go to after a successful charge 2. A email address for receipts of transactions 3. A merchant account number including the types of cards you accept 4. You processor type (i.e. VISANET, FDR type 7, GENSAR) 5. Your processors phone number 6. Your processing bank name 7. Your processing banks phone number 8. Depending on your bank and processor we will need other information such as terminal ID, SIC/MCC Code, Network routing. We will let you know what information we need when we set you up. 9. Your address, email, Company name, contact name, phone number and URL Most Processor Banks will be able to fax you this information if you tell them that you need to set-up your account to use ICverify software. 5 What are modes? Modes are different ways to use our service there are currently two: 5a Remote: Secure information is taken on The Processing Network's secure servers. The vendor sends customers to a script on the TPN server. The customer fills out and submits an order and returns to the vendor's Web site. 5b Local: Local mode happens on the vendor's server. The customer is sent to a script on the vendor's site that securely connects to TPN and processes their card. The customer never leaves the vendor's site. Local Mode is available for NT, Mac and Unix. 5c. Instructions for use of msg.exe This note describes TPN's secure transaction API for Windows NT and/or Unix. This API consists of the NT console application "msg.exe" (or the Unix command-line application msg), which provides a way to carry out a secure credit card transaction via TPN's credit card processing server. This application is suitable for use within your own CGI-based secure server or other credit card processing application. IMPORTANT NOTE TO USERS OF EARLIER VERSIONS: all arguments are now passed at standard input, NOT at the command line! This was done for important security reasons. We apologize for any inconvenience. Correct usage of the program is as follows: PLEASE NOTE: THERE ARE NO COMMAND LINE ARGUMENTS! ** ALL ** ARGUMENTS ARE PASSED AT STANDARD INPUT, *ONE* ARGUMENT *PER LINE*. This change was made for important security reasons, to protect *your* data. Arguments are shown on one line below for the sake of clarity. CHARGE: host port key vendor card expr price orderid AUTHORIZATION: /a host port key vendor card expr price orderid FORCE CHARGE: /f host port key vendor card expr price orderid APPROVAL CHARGE AGAIN: /c host port key vendor price old-orderid new-orderid "host" and "port" should currently be lestat.processing.net and 80, respectively. We will notify you of any changes. The key argument is a 16-digit hexadecimal key, used to encrypt the transaction and verify that the transaction is authentic. TPN will provide you with this key on the phone or by other secure means. IT IS VERY IMPORTANT THAT YOU KEEP THIS KEY SAFE. If you believe your key has been compromised, contact us immediately. The tpn-vendor-code argument is your TPN vendor name, which is provided to you when you sign up with TPN. The following are two examples of valid values for the "amount" argument: 25.00 25 The "orderid" argument is a unique order ID which identifies the transaction in YOUR database. You will be able to look up transactions later on our system using this order id. As a safeguard against double-charging, TPN will not accept the same order ID from you again after a successful charge. (It may be used again after an unsuccessful charge, such as after the user provides the correct card number, etc.) PLEASE NOTE: the expiration date must be in MMYY format (always four digits; two digits for the month, two for the year). AUTHORIZATION To do an authorization rather than a charge, use the second form of the msg command, as shown here: /a host port key vendor card expr price orderid That is, the first line of standard input will be the flag argument /a, and the rest of the arguments are the same as for a charge. FORCE CHARGE To do a charge based on a PRIOR AUTHORIZATION, use the third form of the msg command, as shown here: /f host port key vendor card expr price orderid APPROVAL That is, the first line of standard input will be the flag argument /f, and the rest of the arguments are the same, except for APPROVAL. "APPROVAL" is the successful approval code returned by an earlier successful authorization. This approval code consists of "Y" followed by additional digits and letters. PLEASE NOTE: a force charge will typically produce an immediate approval message. It is your responsibility to provide a correct approval code! Failure to do so will not typically produce an error message. This is the policy of most merchant banks, and it is not something we can control. CHARGE AGAIN To charge a previous customer for an additional transaction, use the fourth form of the msg command, as shown here: /c host port key vendor price old-orderid new-orderid old-orderid must be the order ID of a previous successful transaction. That transaction is looked up by TPN's computers in order to determine the correct card and expiration date. * * * HOW THE PROGRAM RESPONDS: If the transaction is successful, msg.exe will output the following to standard output: Ynnnnnn Where "nnnnnn" will be the approval code from your credit card processing company. This means that the customer HAS BEEN CHARGED SUCCESSFULLY. If the transaction is NOT successful, msg.exe will output the following to standard output: Nxxxxxxxxxx... Where xxxxxx will be an error message, which may describe a problem with the customer's card, or a problem with your TPN configuration, or a network problem between you and TPN. This message is suitable for display to the user. Any output beginning with "N" means that the customer HAS NOT BEEN CHARGED, and it may be appropriate for the customer to try the transaction again after taking corrective action such as providing a correct card number, etc. We hope that you will find this application useful and straightforward to integrate into your own CGI scripts and the like. - Tom Boutell The Processing Network 6 Remote Mode Sample Pages and Scripts: 6a A sample html order page with javascript that creates the orderid: <HTML> <HEAD> <TITLE>Order Form </TITLE> </HEAD> <BODY BGCOLOR=white><BR> <FORM ACTION="https://lestat.processing.net/cgi-bin/nph-charge" METHOD=POST> Press here to order a widget for $15.00. <P> <INPUT TYPE="hidden" NAME="price" VALUE="15.00"> <INPUT TYPE="hidden" NAME="vendor" VALUE="[vendor name]"> <INPUT TYPE="hidden" NAME="product" VALUE="widget"> <script language=javascript> var today today = new Date() document.write("<input type=hidden name=orderid value=") document.write(today.getTime()) document.write(">") </script> <INPUT TYPE="submit" VALUE="Go to Secure Sever"> </FORM> </BODY> </HTML> 6b A sample html order page for a site with a secure server: <HTML> <HEAD> <TITLE>Order Form </TITLE> </HEAD> <BODY BGCOLOR=white><BR> <h1>Secure Order Information</h1> The remaining information to complete your order is kept safe via Secure Socket Layer technology. <BR> You will be charged by $15.00 for whatever it is that you ordered.<P> <hr> <FORM ACTION="https://lestat.processing.net/cgi-bin/nph-charge" METHOD=POST> <input NAME="card" SIZE="16" MAXLENGTH="16">Card Number<br> <input NAME="expr" SIZE="4" MAXLENGTH="4">Expiration Date (MMYY)<br> <input NAME="zip" SIZE="5" MAXLENGTH="5">Billing Address Zip Code<br> <INPUT TYPE="hidden" NAME="price" VALUE="15.00"> <INPUT TYPE="hidden" NAME="vendor" VALUE="[vendor name]"> <script language=javascript> var today today = new Date() document.write("<input type=hidden name=orderid value=") document.write(today.getTime()) document.write(">") </script> <INPUT TYPE="submit" VALUE="Go to Secure Sever"> </FORM> </BODY> </HTML> 6c A sample perl script to check to see if the user is coming from our system: #! /usr/bin/perl ## Change to the path to perl on your system ## This a a quick hack to verify that the user is coming from our ## charge form. Change the 'http://www.yourdomain.com/accessdenied.html' ## to the location of an accessed denied message. We suggest that you ## have some type of contact information (email) in case the user has accessed ## you through a proxy server. If they have accessed you through a proxy server ## this will not work. ## Get the referring url information $rurl = $ENV{HTTP_REFERER}; ## Test to see if they are coming from our orderform ## If they are show them your access allowed page if (! $rurl =~ /https:\/\/lestat.processing.net/cgi-bin/nph-charge/){ print "Location: http://www.yourdomain.com/accessdenied.html\n\n"; } else{ print "Location: http://www.yourdomain.com/accessallowed.html\n\n"; } 6d A sample perl script that creates and order page with a orderid: #! /usr/bin/perl ## Change to the path to perl on your system ## This a a quick hack to create an orderid based on the time in seconds. ## Basically it will create a html page with a orderid value with the format: ## [merchant name].time_in_seconds ## It would look like this: merchantname.861766752 $time = time; $orderid = "merchantname.$time"; print "Content-type: text/html\n\n"; print <<EOF; <html> <head> <FORM ACTION="https://lestat.processing.net/cgi-bin/nph-charge" METHOD=POST > This step of the process will verify your credit card information. You will be going to our secure server to process your credit card information. <P > <INPUT TYPE="hidden" NAME="price" VALUE="15.00" > <INPUT TYPE="hidden" NAME="vendor" VALUE="[vendor name]" > <INPUT TYPE="hidden" NAME=orderid VALUE=$orderid> <INPUT TYPE="submit" VALUE="Go to Secure Sever"> </body></html> EOF exit; 7 Remote Mode Options: NAME pass_thru - pass through POSTed form elements SYNOPSIS <INPUT TYPE=hidden NAME=pass_thru VALUE=1> AVAILABILITY Remote mode DESCRIPTION "pass_thru" is an option that takes all of the form fields submitted and echoes them back to a user specified url on an accepted transaction. EXAMPLE This form: <FORM ACTION="https://lestat.processing.net/cgi-bin/nph-charge" METHOD=POST> <INPUT TYPE=text NAME="name"> <INPUT TYPE=text NAME="address"> <INPUT TYPE=hidden NAME=vendor VALUE=VEND> <INPUT TYPE=hidden NAME=price VALUE=1.00> <INPUT TYPE=hidden NAME=orderid VALUE=zxfyghdhd> <INPUT TYPE=hidden NAME=pass_thru VALUE=1> <INPUT TYPE=submit> </FORM> Will present the following form back: <FORM ACTION="[url supplied by vendor]" METHOD=POST> <INPUT TYPE=hidden NAME=name VALUE="[value sent to us]"> <INPUT TYPE=hidden NAME=address VALUE="[value sent to us]"> <INPUT TYPE=hidden NAME=orderid VALUE="[value sent to us]"> <INPUT TYPE=hidden NAME=price VALUE="1.00"> <INPUT TYPE=hidden NAME=approval VALUE="[approval code from processor]"> <INPUT TYPE=submit VALUE="Your card has been charged. Please click me to continue."> NOTES Do not use with the "inline" option. NAME cust_email - email a receipt to customer SYNOPSIS <INPUT TYPE=text NAME=cust_email> AVAILABILITY Remote Mode DESCRIPTION "cust_email" is an option that sends an email receipt to the email address specified in its value. EXAMPLE To: youremail@yourdomain.com From: TPN's Secure Server Subject: Order Receipt for [orderid] for [merchantname] Date: [date] An order was processed. Orderid was smith-123 The amount was $15.00 The approval code was Y123456 The last four digits of the card 4093 Expiration Date 0999 ___________________________________________________________________ The Processing Network http://www.processing.net Real Time Internet Credit Card Verification Services Process orders online 24 hours a day. sales@processing.net NAME inline - similar to the "pass_thru" option SYNOPSIS <INPUT TYPE=hidden NAME=inline> AVAILABILITY Remote Mode DESCRIPTION Instead of forcing the user to click on a button in order to contact the vendor's site, the vendor's server is contacted by our own system, which uses a command line web browser to fetch a page from the vendor and passes the same transaction information as in the pass_thru case (approval, price, orderid, and any additional fields that appeared in the vendor's original form submission to us). The vendor should respond with HTML that would appear in the *body* of an HTML document *only* -- no <head>, no <title>, no <html>, and not <body> itself which we take care of. Note that we also use the <BASE> tag to tell the browser to expect to find inline images, local links, et cetera, relative to the vendor's URL. This should make switching over relatively painless. NOTES: Do not use with the "pass_thru" option. 8 How do I change information in my set-up? You can either call us at 253-255-5145 and give us the changed information or email the information to securecharge@processing.net. If it is security sensitive data, please call. 9 I have lost my password/vendorname what do I do? Call us and we will let you know. We do not send passwords via email. 10 What is your network set-up and location details? We currently run our secure processing on 2 Sun Sparc 5's running Solaris 2.5.1 with 128MB RAM and a 133Mhz processor. We use Netscape Enterprise Server 2.0.1. Our Processor machine is located behind our firewall. For security reasons we do not disclose the specific network set-up or security measures in place. Our main Web server (which you are viewing this document on now) is a AMD K6 333 with 160MB of RAM running Linux with Apache server software. Transaction database back ups are performed hourly 24 hours per day. Complete system back ups are made daily and stored offline on removable media. We store transaction records for 9 years on removable media and are available upon request. We currently run the following operation systems in house: Windows NT 4.0 Windows 95 Mac OS 7.6.1 Mac OS 7.5.5 MKLinux Sun Solaris Red Hat Linux Slackware Linux Debian Linux We current have a E1 (2.2 Mbit microwave uplink) routed to four backbones: MCI, UUnet (Alternet), SprintLink, Agis. We also use a 1.1 Mbit DSL line in San Francisco California. Our main Network hub is located in a major downtown Seattle building. Our building has is on a generator system which comes on within 1 second of power failure (it was last tested on July 14, 1998), has camera controlled security access, is on the same switch grid as USWest's corporate office (we are located directly across the street). 11 Whom do I contact for more information? Network information can be gleamed from: Shane Stixrud - System Administrator/System Security shane@processing.net Database and local mode questions are best sent to: Tom Boutell - Lead Programmer tom@processing.net Other technical questions can be aimed at: Jason Daniel - Director of Operations jasond@processing.net 12 What are some error codes that a unaccepted transactions will produce? Depending on your processor these may be different but these are the typical responses: DECLINED - A straight up decline CALL CENTER - For some reason the processor wants a voice auth. This typically means that there is something strange about the card like it is close to its limit, outside the normal purchasing pattern, or several transactions have been made in the same day not the same as a DECLINED INVALID CARD # - Bad card number LOST/STOLEN CARD215 - Reported lost or stolen INVALID EXP DATE303 - bad expiration date (typically in the past) DSCV NOT ALLOWED - Account not set up for Discover AMEX NOT ALLOWED - Account not set up for American Express HOLD CALL 202 - Declined but worse (cut that sucker up!) 13 What happens if a card is used over and over? Our system will only allow 5 transactions per day for any one card. This is enabled to warn us (and you) of potential fraud. 14 How many transactions can you handle Our current system can handle about 15,000 transactions per day, with a 15 to 45 second response time per transaction. We can upgrade our system to handle over 45,000 transactions in less than two days if needed. If you plan on sustaining such a high transaction rate, please let us know. We can set up a dedicated line to your processor. Consider that there are only 86,400 seconds in a day. If you were performing a transaction every second, everyone on the Internet (60 million) would charge with you in 70 days. 15 What does Lestat mean? Lestat is the name of our credit card processing machine taken (with great care) from the Anne Rice novels of the same name. All of our machines are named for characters in Anne Rice novels. 16 Some sample code from Tom donate.cgi accepts a form submission, adds an order ID (somewhat more robustly unique than the Perl example in our technical FAQ now), and issues a redirect to TPN's nph-charge script, with all fields passed intact. The web designer just sets vendor, pass_thru, price, etc. and points the form action at this script (which should probably be renamed, huh). collate.cgi is way niftier, though: it accepts a form submission and adds an order ID *and* a price. It first looks in a vendor-specified file to find comma-separated product names and prices. It looks for form fields with the same name as each product name to find out how many units of each item are being purchased and totals up the correct price. It then redirects to nph-charge the same way donate.cgi does. This allows designers to create somewhat more complex order pages that allow clients to order one or more of each item on the page, without having to install full-blown shopping cart software. -- Thomas Boutell #!/usr/bin/perl # Determines the price to be charged for an order by # looking at the number of each item purchased and # multiplying by the prices found in the file pointed # to by $products. Also takes care of adding an order ID. # The file pointed to by $products contains one line per product. Each # line of the file consists of a product name, followed by a comma, # followed by a price. TBB 6/17/99 $products = "/home/nwwlc/public_html/secure/products.txt"; use CGI; $query = new CGI; @params = $query->param(); for $p (@params) { $params{$p} = $query->param($p); } if (!open(IN, $products)) { print "Content-type: text/html\n\nCan't access $products\n"; exit 0; } while ($line = ) { chomp $line; ($item, $p) = split(/,/, $line); $p =~ s/\s+//g; if ($query->param($item) > 0) { $price += $p * $query->param($item); } } close(IN); $price = sprintf("%.2d", $price); #Set the price $params{"price"} = $price; #Create a reasonable order ID ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) = localtime(time); $params{"orderid"} = sprintf("%04d-%02d-%02d-%02d-%02d-%02d-%05d", $year, $mon, $mday, $hour, $min, $sec, $$); #Get ready to redirect the whole thing to TPN $url = "https://lestat.processing.net/cgi-bin/nph-charge?"; while (($key, $value) = each %params) { if ($count) { $url .= "&"; } $url .= $query->escape($key) . "=" . $query->escape($value); $count++; } # We have added a price to the order. Now redirect to TPN. print $query->redirect($url); #!/usr/bin/perl # Adds an order ID to an order then redirects to TPN. use CGI; $query = new CGI; @params = $query->param(); for $p (@params) { $params{$p} = $query->param($p); } #Create a reasonable order ID ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) = localtime(time); $params{"orderid"} = sprintf("%04d-%02d-%02d-%02d-%02d-%02d-%05d", $year, $mon, $mday, $hour, $min, $sec, $$); #Get ready to redirect the whole thing to TPN $url = "https://lestat.processing.net/cgi-bin/nph-charge?"; while (($key, $value) = each %params) { if ($count) { $url .= "&"; } $url .= $query->escape($key) . "=" . $query->escape($value); $count++; } print $query->redirect($url);