Building a Simple PayPal Buy Now Feature

People often ask about using a PayPal Buy Now button in mojoPortal so I thought I would post some sample code how to implement it. It does require custom development but nothing too complicated and very similar to our hello world examples.

It would be nice if we could just generate the button at PayPal and paste it into an instance of the Html content feature, but there is a problem with that because the html code for the button requires a <form element, and in ASP.NET WebForms platform (this is what mojoPortal is built on) there is a limitation that there can only be one form on the page and this form already exists so you can't just add more forms. As we will see below it is easy to solve this problem from code because we don't really need another form on the page, we can use the existing form and we can specify the PostbackUrl property on our button to the same url that PayPal would use on its separate form. 

Example PayPal Button Code

The following code is what I generated for a donate button, but there is not much difference between a Donate button or a Buy Now button other than the image url.

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

So the problem is we can't just add that extra form to the page in the html content feature or it will cause errors and conflict with the form that already contains the page content.

A Solution that Can Be Used in the Html Content Feature

As we said above, we cannot just add a form into the html content without causing problems. One solution that can work is to use the code generated for email instead of button code and then put an image with it so it can look like a button. The email version of the code above is like this:

https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=SAU3LV6DTEPXJ

To make it look like a button we just add a little markup like this:

<a href="https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=SAU3LV6DTEPXJ"><img src="https://www.paypal.com/en_US/i/btn/btn_donateCC_LG.gif" alt="Donate" /></a>

An Easy Developer Solution

Below is sample code that shows how you can use a real form post by specifying the PostbackUrl on the button which allows you to use the form that already exists on the page. All you really need to add is the hosted_button_id and the image url generated from PayPal, along with any descriptive html content you would like to present with button. With a little more work you could make those editable as module settings. You can copy and paste and modify the code below, save the file as PayPalBuyNow.ascx or whateveryoulike.ascx and you can install it the same way as described in our Hello World tutorial.

<%@ Control Language="C#" ClassName="PayPalBuyNow.ascx" Inherits="mojoPortal.Web.SiteModuleControl" %>

<%@ Import Namespace="mojoPortal.Business" %>
<%@ Import Namespace="mojoPortal.Business.WebHelpers" %>
<%@ Import Namespace="mojoPortal.Web.Framework" %>
<%@ Import Namespace="mojoPortal.Web.Controls" %>
<%@ Import Namespace="mojoPortal.Web.Editor" %>
<%@ Import Namespace="mojoPortal.Net" %>

<script runat="server">
// Author: Joe Audette
// Created: 2010-12-14
// Last Modified: 2010-12-14

protected string HostedButtonId = "XXXXXXXXXX"; // your PalPal Generated value for hosted_button_id
private string buttonImageUrl = "https://www.paypal.com/en_US/i/btn/btn_buynowCC_LG.gif"; // or donate button https://www.paypal.com/en_US/i/btn/btn_donateCC_LG.gif
private string payPalPostUrl = "https://www.paypal.com/cgi-bin/webscr"; // you shouldn't need to change this

protected void Page_Load(object sender, EventArgs e)
{
LoadSettings();
}

private void LoadSettings()
{
Title1.Visible = !this.RenderInWebPartMode;
if (this.ModuleConfiguration != null)
{
this.Title = this.ModuleConfiguration.ModuleTitle;
this.Description = this.ModuleConfiguration.FeatureName;
}

btnPayPal.ImageUrl = buttonImageUrl;
btnPayPal.PostBackUrl = payPalPostUrl;
}

</script>

<portal:OuterWrapperPanel ID="pnlOuterWrap" runat="server">
<mp:CornerRounderTop id="ctop1" runat="server" EnableViewState="false" />
<portal:InnerWrapperPanel ID="pnlInnerWrap" runat="server" CssClass="panelwrapper papalmodule">
<portal:ModuleTitleControl id="Title1" runat="server" EnableViewState="false" />
<portal:OuterBodyPanel ID="pnlOuterBody" runat="server">
<portal:mojoRating runat="server" ID="Rating" Enabled="false" />
<portal:InnerBodyPanel ID="pnlContent" runat="server" CssClass="modulecontent">

<p>You can hard code the html description here.</p>

<input type="hidden" name="cmd" value="_s-xclick">
<input type="hidden" name="hosted_button_id" value='<%= HostedButtonId %>'>
<asp:ImageButton id="btnPayPal" runat="server" />
<img alt="" border="0" src="https://www.paypal.com/en_US/i/scr/pixel.gif" width="1" height="1">

</portal:InnerBodyPanel>
<portal:EmptyPanel id="divFooter" runat="server" CssClass="modulefooter" SkinID="modulefooter"></portal:EmptyPanel>
</portal:OuterBodyPanel>
<portal:EmptyPanel id="divCleared" runat="server" CssClass="cleared" SkinID="cleared"></portal:EmptyPanel>
</portal:InnerWrapperPanel>
<mp:CornerRounderBottom id="cbottom1" runat="server" EnableViewState="false" />
</portal:OuterWrapperPanel>