ZKTM Small Talks |
Implement Paypal Buy Now Button with ZK |
| Simply Rich | Henri Chen Principal Engineer Potix Corporation July 20, 2006 |
Version
Applicable to ZK 2.1.1 and later.
The Paypal Buy Now Button is used to let merchant to sell individual items on a web site. End users can buy the item immediately by just pressing the button, pay the price(via credit card, wiring, etc.), and complete the purchase on line.
ZK is an open-source Ajax Web framework that enables rich UI for Web applications with no JavaScript and little programming.
A legacy Paypal Buy Now Button is really only a form that submit to Paypal website. And that is the way that Paypal teachs you how to put a "Buy Now" button in your own mechant web site (See here for details.). Before jumping in the details on how to implement a ZK Paypal Buy Now Button component, let us see the form first:
<form action="https://www.paypal.com/cgi-bin/webscr" method="post">
<input type="hidden" name="cmd" value="_xclick">
<input type="hidden" name="business" value="henrichen@potix.com">
<input type="hidden" name="item_name" value="ItemName">
<input type="hidden" name="item_number" value="ItemID">
<input type="hidden" name="amount" value="123.00">
<input type="hidden" name="no_shipping" value="2">
<input type="hidden" name="no_note" value="1">
<input type="hidden" name="currency_code" value="USD">
<input type="hidden" name="bn" value="PP-BuyNowBF">
<input type="image" src="https://www.paypal.com/en_US/i/btn/x-click-but23.gif" border="0" name="submit" alt="Make payments with PayPal - it's fast, free and secure!">
<img alt="" border="0" src="https://www.paypal.com/en_US/i/scr/pixel.gif" width="1" height="1">
</form>
This form is generated via the Paypal's "Website Payments Standard: Single-Item Purchases" page. There can be more option attributes. However, to simplify the discussion, we will limit the attibutes to the list below:
Since the Paypal Buy Now Button is simply a form, can't we just copy-paste the form to the ZUL page? The smalltalk Work with Legacy Web Applications, Part I - Servlets and Forms has told us how to do that, hasn't it? Sure, you can do it that way. However, implementing a ZK Paypal Buy Now Button got a lot of advatages because ZK can do things dynamically:
The Paypal Buy Now Button is a kind of button. It is natural to extends it from the Zul's Button class.
import org.zkoss.zk.ui.*;
import org.zkoss.zk.ui.util.*;
import org.zkoss.zk.ui.event.*;
import org.zkoss.zul.*;
import org.zkoss.zul.event.*;
import org.zkoss.zhtml.Form;
import org.zkoss.zhtml.Input;
public class PaypalBuyNowButton extends Button {
private String _business = null;
private String _itemName = "";
private String _itemNumber = "";
private String _amount = null;
private String _noShipping = "0";
private String _noNote = "0";
private String _currencyCode = "USD";
//setters
public void setBusiness(String str) {
_business = str;
}
public void setItemName(String str) {
_itemName = str;
}
public void setItemNumber(String str) {
_itemNumber = str;
}
public void setAmount(String str) {
_amount = str;
}
public void setNoShipping(String str) {
_noShipping = str;
}
public void setNoNote(String str) {
_noNote = str;
}
public void setCurrencyCode(String str) {
_currencyCode = str;
}
...
}
Apparently, We have to provide setters so end user can setup the attributes of the Paypal form. The key part of the Paypal Buy Now Button is really when user click the button. We will create a form dynamically and sumbit it.
//generate form and submit
public void onClick(MouseEvent event) {
//create paypal form
Form form = new Form();
form.setDynamicProperty("action", "https://www.paypal.com/cgi-bin/webscr");
form.setDynamicProperty("method", "post");
form.setPage(this.getPage());
//cmd
{
Input input = new Input();
input.setParent(form);
input.setDynamicProperty("type", "hidden");
input.setDynamicProperty("name", "cmd");
input.setValue("_xclick");
}
//business
{
Input input = new Input();
input.setParent(form);
input.setDynamicProperty("type", "hidden");
input.setDynamicProperty("name", "business");
input.setValue(_business);
}
//item_name
{
Input input = new Input();
input.setParent(form);
input.setDynamicProperty("type", "hidden");
input.setDynamicProperty("name", "item_name");
input.setValue(_itemName);
}
//item_number
{
Input input = new Input();
input.setParent(form);
input.setDynamicProperty("type", "hidden");
input.setDynamicProperty("name", "item_number");
input.setValue(_itemNumber);
}
//amount
{
Input input = new Input();
input.setParent(form);
input.setDynamicProperty("type", "hidden");
input.setDynamicProperty("name", "amount");
input.setValue(_amount);
}
//no_shipping
{
Input input = new Input();
input.setParent(form);
input.setDynamicProperty("type", "hidden");
input.setDynamicProperty("name", "no_shipping");
input.setValue(_noShipping);
}
//no_note
{
Input input = new Input();
input.setParent(form);
input.setDynamicProperty("type", "hidden");
input.setDynamicProperty("name", "no_note");
input.setValue(_noNote);
}
//currency_code
{
Input input = new Input();
input.setParent(form);
input.setDynamicProperty("type", "hidden");
input.setDynamicProperty("name", "currency_code");
input.setValue(_currencyCode);
}
//bn
{
Input input = new Input();
input.setParent(form);
input.setDynamicProperty("type", "hidden");
input.setDynamicProperty("name", "bn");
input.setValue("PP-BuyNowBF");
}
//submit the form
Clients.submitForm(form);
}
Ok, the Paypal Buy Now Button implementation is inside the file PaypalBuyNow.java. There should be more code regarding attribute validation. e.g. The _buisiness and _amount should not be empty; the _amount has to be properly formated, etc. However, to simplify the code, we omit that part here. Also note that how an XHTML input is created and how some properties (attributes) are setup. The XHTML component implements DynamicPropertied so it accepts any attributes. Excepts some important attribute, e.g. setValue(), most other attributes are implemented as setDynamicProperty(String name, String value);
To use the Paypal Buy Now Button, there are serveral ways:
<?component name="buynow" extends="button" class="PaypalBuyNowButton"?>
...
<buynow ...>
...
Following is the paypal1.zul example that use the Paypal Buy Now Button:
<?component name="buynow" extends="button" class="PaypalBuyNowButton"
label="" image="https://www.paypal.com/en_US/i/btn/x-click-but23.gif"
style="border: 0; background-color:transparent" noShipping="2" noNote="1"
business="henrichen@potix.com" tooltiptext="Make payments with PayPal - it's fast, free and secure!"?>
<zk>
<zscript src="PaypalBuyNowButton.java"/>
<grid width="100%">
<columns>
<column label="Item No." width="100px"/>
<column label="Item Description" width="200px"/>
<column label="Price" width="100px"/>
<column label=" "/>
</columns>
<rows>
<row><label value="A100"/>ZK in action<label value="$39.99 USD"/><buynow amount="39.90" itemName="ZK in action" itemNumber="A100"/></row>
<row><label value="A200"/>Thinking in ZK<label value="$49.99 USD"/><buynow amount="49.99" itemName="Thinking in ZK" itemNumber="A200"/></row>
<row><label value="A300"/>ZK Examples<label value="$29.99 USD"/><buynow amount="29.99" itemName="ZK Examples" itemNumber="A300"/></row>
<row><label value="A400"/>ZK Clustering<label value="$79.99 USD"/><buynow amount="79.99" itemName="ZK Clustering" itemNumber="A400"/></row>
</rows>
</grid>
</zk>
Copy the paypal1.zul and the PaypalBuyNowButton.java to zkdemo/test then visit to zkdemo/test/paypal1.zul, you will see the testing code. Note that the form is submitted to real Paypal site. Don't press the "Pay" button in the Paypal page. We are not responsible for the "fund" that you wired to the Paypal account.
And, the snapshot is as follows.
In this article, we illustrate how to dynamically create a Paypal Buy Now Button form and how to encapsulate it into a PaypalBuyNowButton component. However, this is only the first step. The Paypal also provides submitting an encripted Buy Now Form that would further secure the form from being hacked. In the next smalltalk, we will show you how to encript and sumbit a Buy Now form using this ZK form submitting mechanism.
The ZK ajax framework allows you to dynamically generate a HTML form and submit it with Java methods. Anything that regarding submitting a form can be implmented this way. This PaypalBuyNowButton is an example; the smalltalk, Validate Forms, is another example. I think you should see the potential of this mechanism since all legacy web applications are form based and they can be "value-added" or "componentized" easily into ZK framework.