Editor's note: The authors of PayPal Hacks offer two hacks designed to make PayPal more customer friendly, profitable, and accountable through creating PayPal buttons with more than two fields and creating a page that enables customers to check on the status of their orders. Plus, there is an additional hack to catch IPN system errors.
Give your customers a large selection of options when purchasing their items, despite the limitations of payment buttons.
PayPal buttons enable you to easily offer fixed products to your customers. Although some flexibility is provided in the form of option fields [Hack #32], PayPal currently supports only two such fields. If your product has more than two options (e.g., Size, Color, and Material), you can employ a little JavaScript code and a hidden field to create as many option fields as you need.
Start with the basic Buy Now button code [Hack #28] for a single item, although this works with Shopping Cart, Subscription, and Donation buttons as well:
<form action="https://www.paypal.com/cgi-bin/youbscr" method="post">
<input type="hidden" name="cmd" value="_xclick">
<input type="hidden" name="business" value="sales@payloadz.com">
<input type="hidden" name="item_name" value="Widget One">
<input type="hidden" name="item_number" value="Wid-001">
<input type="hidden" name="amount" value="1.00">
<input type="hidden" name="no_note" value="1">
<input type="hidden" name="currency_code" value="USD">
<input type="image" src=
"https://www.paypal.com/en_US/i/btn/x-click-but23.gif"
border="0" name="submit>
</form>
Suppose the item you're selling has three options:
Color, Size, and Material. You can provide three drop-down lists
[Hack #32],
one for each option, with which your customers can customize their
purchases. To keep things simple, name your drop-down elements
custom1, custom2, and
custom3.
This code joins all three of the selected options into a single
variable, custom, to
be passed to PayPal. You'll need to add the custom
form element to your button as a hidden variable with no value
specified. The value will be populated by the JavaScript code when
the form is submitted. Here's an HTML form with form
options and the custom field:
Color
<select name="custom1">
<option value="White" selected>White</option>
<option value="Grey">Grey</option>
<option value="Black">Black</option>
</select>
<br>
Size
<select name="custom2">
<option value="Small">Small</option>
<option value="Medium">Medium</option>
<option value="Large" selected>Large</option>
<option value="X-Large">X-Large</option>
</select>
<br>
Material
<select name="custom3">
<option value="Spandex" selected>Spandex</option>
<option value="Cotton">Cotton</option>
</select>
<input type="hidden" name="custom" value="">
Figure 4-5 shows the additional custom fields in action. You can include as many option fields as you can fit on your page.

Figure 4-5. Including additional option fields
You can continue adding as many option fields as you need, provided
that you use the same
custom# naming format.
Just be sure that the total character count for the labels
and their possible variable values does not
exceed 256 characters, the size limit of PayPal's
custom variable.
Add the HTML code to your PayPal button form between the opening and
closing <form> tags. Then add the following
JavaScript code to the head of the web page:
<script language="JavaScript">
<!--
function joinFields( ){
fmBuy.custom.value = 'Color:' + fmBuy.custom1.value + ' Size:' +
fmBuy.custom2.value + ' Material:' + fmBuy.custom3.value
}
// -->
</script>
If you add additional fields, you'll need to modify this code to accommodate them.
Finally, add a call to the joinFields routine by
inserting the name and onSubmit
attributes to the existing <form> tag (the
values for the action and
method attributes remain unchanged):
<form action="https://www.paypal.com/cgi-bin/youbscr" method="post"
name="fmBuy" onSubmit="joinFields( )">
Here is the final code for the example form:
<form action="https://www.paypal.com/cgi-bin/youbscr" method="post" name="fmBuy"
onSubmit="joinFields( )">
<input type="hidden" name="cmd" value="_xclick">
<input type="hidden" name="business" value="sales@payloadz.com">
<input type="hidden" name="item_name" value="Widget One">
<input type="hidden" name="item_number" value="Wid-001">
<input type="hidden" name="amount" value="1.00">
<input type="hidden" name="no_note" value="1">
<input type="hidden" name="currency_code" value="USD">
Color
<select name="custom1">
<option value="White" selected>White</option>
<option value="Grey">Grey</option>
<option value="Black">Black</option>
</select>
<br>
Size
<select name="custom2">
<option value="Small">Small</option>
<option value="Medium">Medium</option>
<option value="Large" selected>Large</option>
<option value="X-Large">X-Large</option>
</select>
<br>
Material
<select name="custom3">
<option value="Spandex" selected>Spandex</option>
<option value="Cotton">Cotton</option>
</select>
<input type="hidden" name="custom" value="">
<input type="image" src="https://www.paypal.com/en_US/i/btn/x-click-but23.gif"
border="0" name="submit">
</form>
When the complete page is loaded (with the button code in the page
body and the JavaScript in the page head), the customer-selected
option fields will be concatenated into one string and passed through
to PayPal in the custom variable. For instance, if the form is
submitted with its default values, the custom variable will be set to
Color:White Size:Large Material:Spandex. The
string will appear in details of the transaction in your PayPal
account; your customers will never see it. If necessary,
you
can
also
parse this field out in the IPN page [Hack #80] .
|
Related Reading PayPal Hacks |
|
Keep your customers informed of order status using an automated system.
The Internet sped up everything, including your customers' expectations. Once you have the code in place to display the merchant transaction ID on your return page [Hack #52] and insert payment details into a database [Hack #82], it's easy to create a page that enables customers to check on the status of an order. You need to place two new pages on your system: a query page that allows your customers to ask the question and a results page that gives them the answer. Figure 5-11 shows a completed results page.

Figure 5-11. A completed order-tracking page
An order-tracking page like this one is easy to implement and goes a long way in placating customers.
The query page can be quite simple. All you need is a form that allows your customer to enter the transaction ID you previously provided. Once the customer clicks Submit, the results page takes over.
<html><body>
Enter the transaction ID corresponding to the order you wish to look up:
<form action="order_tracking.asp" method="post">
<input type="text" name="txn_id">
<input type="button" value="submit" name="submit">
</form>
</body></html>
The form is only the beginning. Obviously, the preferred method is to display a list of all relevant transaction IDs, from which the customer can select one to view the transaction details. See [Hack #22] for more information, as well as [Hack #94] for a way to get this information using the PayPal API.
This example (especially the tblOrders table)
assumes a database structure similar to the structure used in [Hack #82] .
Any web scripting language will work for this task. This example uses
ASP:
<%
'Read back customers input
Dim txn_id
Txn_id = Request ("txn_id")
'Connect to database and create recordset
connStore = "DRIVER={Microsoft Access Driver (*.mdb)};DBQ=
"C:/InetPub/wwwroot/database/dbPayPal.mdb")
set rsOrder = Server.CreateObject("ADODB.Recordset")
rsOrder.ActiveConnection = connStore
rsOrder.Source = SELECT payer_email, payer_id, payment_status, txn_id,
mc_gross, mc_fee, payment_date FROM tblOrders WHERE txn_id = '" &
txn_id &"'"
rsOrder.Open( )
%>
<!-- Check to see if the order information can be found; if so, display it.-->
<% If NOT rsOrder.EOF OR NOT rsOrder.BOF Then %>
Here are the details of your order:
<p>
Customer Email: <%=rsOrder("payer_email")%>
<br>Customer ID: <%=rsOrder("payer_id") %>
<br>Payment Status: <%=rsOrder("payment_status") %>
<br>Transaction ID: <%=rsOrder("txn_id") %>
<br>Payment Gross: <%=rsOrder("mc_gross") %>
<br>Payment Date: <%=rsOrder("payment_date") %>
<% Else %>
No matching Record Found. Please search again.
<% End If %>
Here are a few ways you can extend this hack:
Place another copy of the query form on the results page. This way, if your customers need to query for more than one transaction ID, they won't have to use their browser's Back button to enter another.
Change the query page to accept a list of transaction IDs in a
textarea box. Then modify the results page to
display the results of searching for each.
|
Effectively diagnose processing problems and overcome some of IPN's stumbling blocks.
The IPN system is one of the most powerful features of the PayPal system. Deploying it requires a certain level of programming skill, but even with perfect programming, there can be issues that arise in deploying any new system for the first time. In the case of implementing IPN, there are several things you can do to help diagnose any issues that arise.
The first step in testing your IPN system is to make a live purchase on the system so that the script gets called by PayPal [Hack #65] .
A good way to help diagnose problems is to have your IPN processing page send you all the variables and their values as they were posted to the PayPal site. You can do this by inserting a server mail component function that emails you the complete form post from PayPal when your IPN page is called. You can add the code to send an email and also to include a switch to turn this function on and off with the following code, written in VBScript for Active Server Pages:
Dim vTesting
vTesting = 1 'Uncomment for test mode on
'vTesting = 0 'Uncomment for test mode off
If vTesting = 1 Then 'Send test email
Dim TestCDO
Set TestCDO = Server.CreateObject("CDONTS.NewMail")
TestCDO.From = "youremail@yourisp.com"
TestCDO.To = "youremail@yourisp.com"
TestCDO.Subject = "IPN Variables"
TestCDO.Body = Request.Form( )
TestCDO.Send( )
Set TestCDO = Nothing
End If
With this code added to the basic IPN processing code [Hack #65], the IPN page sends you an email with all the transaction data as posted by PayPal. This can help you determine whether the problems are with the data being passed back.
The next way to test your IPN script is to
check to see if your IPN page is throwing any errors. You can do this
easily by redirecting to your IPN page after payment (using the
return variable) and having the IPN information
sent when you hit the page. This provides the same functionality that
normally occurs behind the scenes, except you are able to see it
firsthand. You need to add the following code to your test purchase
button to accomplish this:
<input type="hidden" name="rm" value="2">
<input type="hidden" name="return" value="http://yoursite.com/ipn.asp">
When this code is added to your purchase button, PayPal redirects you
back to your IPN script after payment and a form
post is sent that allows you to see if the page
has an error on it.
TIP: If you're using Internet Explorer, you should also configure your browser to show descriptive server errors by disabling the "Show friendly HTTP error messages" option, found in Tools→Internet Options→Advanced. Now, when a page with an error is loaded, you'll get a descriptive message regarding the error and the line on which it occurred.
One way to find out if your IPN script is causing an error is to insert error-capturing code within your IPN page. When a page error occurs, you can get an email letting you know that an error has occurred and what the error was. This example uses ASP written in VBScript. First, you have to add the following piece of code to the top of your IPN page:
<% On Error Resume Next %>
That line makes sure that the page continues to process if an error is detected. Then, at the bottom of your IPN page, insert the following:
<%
ErrorCheck( )
Function ErrorCheck( )
If Err.Number <> 0 then 'if there is an error then the html table will be
written out
Dim ErrorCDO
Set ErrorCDO = Server.CreateObject("CDONTS.NewMail")
ErrorCDO.From = "youremail@yourisp.com"
ErrorCDO.To = "youremail@yourisp.com"
ErrorCDO.Subject = "IPN Error"
ErrorCDO.Body = "Error: " & Err.Number & " " & VbCrLf & "Description: " &
Err.Description & ""
ErrorCDO.Send( )
Set ErrorCDO = Nothing
End If
End Function
%>
Once you add this code to your IPN script, you'll be notified via email when an error has occurred.
WARNING Since the page uses an
On Error Resume Nextstatement, it assumes that the post worked properly and does not send an error back to the PayPal system or try again. Without this statement, PayPal would continue to repost the information back to your IPN script until it was successful. Therefore, you should use this technique only during testing phases and not in a live implementation.
Another easy way to test your IPN page is to use a third-party testing script that simulates a PayPal purchase to your IPN script without having to make an actual purchase. The best third-party testing script is located at http://www.eliteweaver.co.uk/testing/ipntest.php. Test your script by simply entering your IPN page's web address. You also have to change the following line in your IPN page (the postback line) so your script does not try to send the posted data back to PayPal as it causes an Invalid response from their system:
objHttp.open "POST", "https://www.paypal.com/cgi-bin/webscr", false
Change it like so:
objHttp.open "POST", "http://www.eliteweaver.co.uk/cgi-bin/webscr", false
Then, you can fill in the script form with any information you like and submit it to simulate the post to your IPN script. You can find a list of all available testing scripts at http://www.paypal.com/cgi-bin/webscr?cmd=p/pdn/3p-solutions-ipntools-outside.
Shannon Sofield began working with Macromedia development tools when Macromedia acquired Future Splash.
Dave Nielsen is the co-founder of CloudCamp, and principal consultant at Platform D, a developer programs consulting company. He is also coauthor of PayPal Hacks.
Dave Burchell got his start with computers by programming the Radio Shack TRS-80 in BASIC and the Commodore 64 in 6510 assembly. A fervent proponent of XML, Dave enjoys solving content-management problems with markup and open source software.
View catalog information for PayPal Hacks
Return to the Web DevCenter.
Copyright © 2009 O'Reilly Media, Inc.