ZKTM Small Talks

Implement Paypal Buy Now Button with ZK

Simply Rich

Home / Small Talks

Henri Chen
Principal Engineer
Potix Corporation
July 20, 2006

Version

Applicable to ZK 2.1.1 and later.

What is Paypal Buy Now Button?

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.

What is ZK?

ZK is an open-source Ajax Web framework that enables rich UI for Web applications with no JavaScript and little programming.

A Form Only

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:

Why do we need a ZK Buy Now Button?

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 implementation

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);

Use the Paypal Buy Now Button

To use the Paypal Buy Now Button, there are serveral ways:

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.

Notes and Enhancements

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.

Summary

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.

Copyright © 2006 Potix Corporation. All rights reserved.
SourceForge.net Logo