Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Add Multiple PayPal Buy Now Buttons to an ASP.NET Form

0.00/5 (No votes)
14 May 2014 1  
A simple tip to avoid the pain caused by PayPal providing code snippets for buttons each in its own form tag

Introduction

This tip will show you a quick and simple way to add multiple PayPal Buy Now (or other similar buttons) to an ASP.NET web form. The solution is needed because of the way PayPal provides HTML snippets for each button, each is encapsulated within its own form with hidden values specific for that button. This is far from ideal for the ASP.NET world as nested forms are not permitted (as discussed in Implementing-Non-ASP-NET-Posts-in-ASP-NET).

This tip will show you how to avoid this and other associated problems through the implementation of some simple JavaScript manipulation of the hidden input fields PayPal uses when the Buy Now buttons are clicked.

Solution

The PayPal Code

When you create a Buy Now button, you will be presented with an HTML snippet similar to the following:

<form action="https://www.paypal.com/cgi-bin/webscr" 
method="post" target="_top">
<input type="hidden" name="cmd" value="_s-xclick">
<input type="hidden" name="hosted_button_id" value="[unique identifier]">
<input type="image" src=https://www.paypalobjects.com/en_US/GB/i/btn/btn_buynowCC_LG.gif> 
border="0" name="submit" alt="PayPal - The safer, easier way to pay online.">
<img alt="" border="0" src=https://www.paypalobjects.com/en_GB/i/scr/pixel.gif 
width="1" height="1">
</form> 

If you've included some of the optional elements like specifying the quantity of items to buy, you may also have some additional HTML like the following:

<form action="https://www.paypal.com/cgi-bin/webscr" method="post" target="_top">
<input type="hidden" name="cmd" value="_s-xclick">
<input type="hidden" name="hosted_button_id" value="[unique identifier]">
<table>
<tr><td><input type="hidden" name="on0" 
value="Quantity">Quantity</td></tr><tr><td>\<select name="os0">
 <option value="1">1 £15.99 GBP</option>
 <option value="2">2 £29.98 GBP</option>
 <option value="3">3 £42.97 GBP</option>
</select> </td></tr>
</table>
<input type="image" src="https://www.paypalobjects.com/en_US/GB/i/btn/btn_buynowCC_LG.gif" 
border="0" name="submit" alt="PayPal - The safer, easier way to pay online.">
<img alt="" border="0" src="https://www.paypalobjects.com/en_GB/i/scr/pixel.gif" width="1" height="1">
</form>  

So you can see above that I have HTML for 2 buttons, one which includes an option to specify quantity. Each button has its own form, a hidden input named cmd with the same value "_s-xclick", one named hosted_button_id with a unique identifier for that button, an image input which submits the page and a 1x1 pixel img.

The Modified Cleaned Up Code

Leaving aside some of the more trivial and irksome issues with the validity of the HTML (input tags should be self-closing in HTML5, empty alt tag, etc.) for the moment the first thing needed is to remove the nested forms entirely, so you either need to move the action, method and target attributes to within the form tag on your page or, if you're working with master pages, you'll only want these attributes setting on the relevant page so I would suggest doing this programmatically in the Page_Load event like so:

 protected void Page_Load(object sender, EventArgs e)
        {
            Page.Form.Action = "https://www.paypal.com/cgi-bin/webscr";
            Page.Form.Method = "post";
            Page.Form.Target = "_top";
        }   

Now, look more closely at the hidden input elements, you can see the duplication, the PayPal target URL will simply look for an input with the correct name and take its value, thus with two or more buttons on your page, you will find they all direct to the same item rather than their own specific unique identifier. Therefore, you need to rationalise to only one instance of each of these hidden fields (you may wish to locate them all together at the top of your code) and to give each an id. This id will enable finding the hidden input elements through the DOM. You should also take the opportunity to tidy-up the HTML to suit your own personal development standards (e.g. you can remove the table from the Quantity drop down and simply use a label and your own CSS for layout) to leave the code looking something like this:

<input type="hidden" name="cmd" value="_s-xclick"/>
<input type="hidden" id="hidButtonId" name="hosted_button_id" value="[unique identifier]"/>
<input type="hidden" id="hidQuantity" 
name="on0" value="Quantity"/>
<input type="image" src="https://www.paypalobjects.com/en_US/GB/i/btn/btn_buynowCC_LG.gif" name="submit" alt="PayPal - The safer, easier way to pay online."/>
<img alt="*"  src="https://www.paypalobjects.com/en_GB/i/scr/pixel.gif" 
width="1" height="1"/>
<label for="ddlQuantity">Quantity:</label>
<select id="ddlQuantity" name="os0"> 
 <option value="1">1 - £15.99</option> 
 <option value="2">2 - £29.98</option> 
 <option value="3">3 - £42.97</option>
</select> 
<input type="image" src="https://www.paypalobjects.com/en_US/GB/i/btn/btn_buynowCC_LG.gif" name="submit" alt="PayPal - The safer, easier way to pay online."/> 
<img alt="*" src="https://www.paypalobjects.com/en_GB/i/scr/pixel.gif" width="1" height="1"/> 

So you can see for each additional button you now only need to include the Buy Now button and 1x1 pixel img (and any additional options like the drop down list for quantity). Now we need to add the JavaScript function and attach it to the onclick event on each button. The JavaScript is simple, all we need it to do is set the hosted_button_id hidden input field value to the correct value for that item and then to also set any other hidden input fields appropriately. It is important to notice that for the buttons that don't use the extra options like Quantity you need to prevent the PayPal target page wrongly sniffing out their values, I've chosen to do this by clearing the value of the associated hidden field.

Add a JavaScript function into your page (or your JavaScript file) that is something like the following:

<script type="text/javascript">
    function setPPHiddenProperties(itemId, isQuantity) {
            document.getElementById('itemValue').value = itemId;
            if (isQuantity == 1) {
                document.getElementById('hidQuantity').value = "Quantity";
            }
            else {
                document.getElementById('hidQuantity').value = "";
            }
        }
</script>  

And then add an onclick attribute to each of your Buy Now buttons calling the function passing the relevant values for that button like so:

<input type="hidden" name="cmd" value="_s-xclick"/>
<input type="hidden" id="hidButtonId" name="hosted_button_id" value="[unique identifier]"/>
<input type="hidden" id="hidQuantity" name="on0" value="Quantity"/>
<input type="image" src="https://www.paypalobjects.com/en_US/GB/i/btn/btn_buynowCC_LG.gif" name="submit" onclick="setPPHiddenProperties('uId1',0);" alt="PayPal - The safer, easier way to pay online."/>
<img alt="*"  src="https://www.paypalobjects.com/en_GB/i/scr/pixel.gif" width="1" height="1"/>
<label for="ddlQuantity">Quantity:</label>
<select id="ddlQuantity" name="os0"> 
 <option value="1">1 £14.99 GBP</option> 
 <option value="2">2 £29.98 GBP</option> 
 <option value="3">3 £44.97 GBP</option>
</select> 
<input type="image" src="https://www.paypalobjects.com/en_US/GB/i/btn/btn_buynowCC_LG.gif" name="submit" onclick="setPPHiddenProperties('uId2',1);" alt="PayPal - The safer, easier way to pay online."/> 
<img alt="*" src="https://www.paypalobjects.com/en_GB/i/scr/pixel.gif" width="1" height="1"/>  

Using this method and extending it to cover any further button options you may implement should allow you to have as many Buy Now buttons on your page as you like.

Summary

In summary, the idea is to:

  1. Remove the form tags and move the attributes to your ASP.NET form for the relevant page.
  2. Rationalise the hidden fields and assign them an id.
  3. Write a JavaScript function to set the values of the hidden fields based upon the incoming parameters.
  4. Tidy up the HTML and add an onclick event to each of your Buy Now buttons to call the JavaScript function with the unique values for that button.
  5. Test the resulting code.
I hope this helps, I think it is an elegant and simple solution and it would have saved me some pain had someone else published it previously. The fact it is a JavaScript solution is mitigated by the fact that PayPal itself requires JavaScript to be enabled for check-out to complete.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here