Saturday, June 6, 2009

PayPal Generated Buttons and .Net Forms

I have used PayPal for some web work I have done in the past. I would use a custom cart and then just pass the entire cart to PayPal. That's not so bad.

Recently I have had the chance to put up a simple site that is a lite e-commerce site. I didn't want to write a custom cart and all the other pages and logic that go with it. So I decided to use PayPal's cart. If you are not familiar with it here is a quick overview, you first generate some PayPal "Add to Cart" buttons then copy and paste the code on your site. And you have yourself a simple e-commerce site.

So as I started to build all my buttons I noticed that they have a form tag in them which means if you are using ASP.NET like me when you go to post to PayPal you will simply see your page refresh, that's because the default action of a aspx page is to post back to itself. Well there is the problem that and I will show you how I got around it.

First let me show you what the PayPal generated button HTML looks like:

<form target="paypal" 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="999999">
<table>
<tr><td><input type="hidden" name="on0" value="Quantity">
Quantity</td></tr><tr><td><select name="os0">
<option value="25">25 $50.00
<option value="50">50 $100.00
<option value="75">75 $112.00
<option value="100">100 $150.00
</select> </td></tr>
</table>
<input type="hidden" name="currency_code" value="USD">
<input type="image" src="https://www.paypal.com/en_US/i/btn/btn_cart_SM.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>

And let me show you my modified version (actually a user control):

Here is what my control looks like on my page (notice the use of the custom properties):
<crd:Card1Day ID="Card_999999" runat="server" ButtonId="999999"
OptionDays="30" />
Here is the html to my control:
<form target="_self" 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='<%= ButtonId %>'>
<input type="hidden" name="on0" value="Quantity">
Quantity - Price
<br /><br />
<select name="os0">
<asp:Literal ID="ltOptions" runat="server"></asp:Literal>
</select>
<br /><br />
<input type="hidden" name="currency_code" value="USD">
<asp:ImageButton ID="imbAddToCart" runat="server"
PostBackUrl="https://www.paypal.com/cgi-bin/webscr"
ImageUrl="https://www.paypal.com/en_US/i/btn/btn_cart_SM.gif" />
<img alt="" border="0" src="https://www.paypal.com/en_US/i/scr/pixel.gif"
width="1" height="1">
</form>
Two things to note about my control, the hidden input "hosted_button_id" is populated via 1 of 2 public properties of this control, in this case the property name is "ButtonId" and you can see how I am setting that property when I use the control on my aspx page. The other property "OptionDays" controls what options get rendered out.

The last and most important part of my control is my use of the ASP.NET ImageButton control inplace of the standard image input PayPal generated. I use this so that I can take advantage of the "PostBackUrl" property. This allow us to post to PayPal and allow users to add items to their PayPal cart.

Also because this is a control we can reuse it as many times as needed and it will be simple to change in the future.

And just for extra points here is my code-behind for the control to show how I am populating the options:

public partial class Card_1Day : System.Web.UI.UserControl
{
public string OptionDays { get; set; }
public string ButtonId { get; set; }

protected void Page_Load(object sender, EventArgs e)
{
switch (OptionDays)
{
case "1":
ltOptions.Text = "<option value=\"25\">25 - $50.00";
ltOptions.Text += "<option value=\"50\">50 - $100.00";
ltOptions.Text += "<option value=\"75\">75 - $112.00";
ltOptions.Text += "<option value=\"100\">100 - $150.00";
break;
case "3":
ltOptions.Text = "<option value=\"25\">25 - $75.00";
ltOptions.Text += "<option value=\"50\">50 - $125.00";
ltOptions.Text += "<option value=\"75\">75 - $150.00";
ltOptions.Text += "<option value=\"100\">100 - $200.00";
break;
case "10":
ltOptions.Text = "<option value=\"25\">25 - $190.00";
ltOptions.Text += "<option value=\"50\">50 - $325.00";
ltOptions.Text += "<option value=\"75\">75 - $415.00";
ltOptions.Text += "<option value=\"100\">100 - $500.00";
break;
case "30":
ltOptions.Text = "<option value=\"25\">25 - $375.00";
ltOptions.Text += "<option value=\"50\">50 - $650.00";
ltOptions.Text += "<option value=\"75\">75 - $825.00";
ltOptions.Text += "<option value=\"100\">100 - $1,000.00";
break;
}
}
}

Saturday, February 21, 2009

Objective-C class method (function)

This is going to be a super quick and simple post about methods in the Objective-C language. I was trying to write a simple static method that would take 2 strings and then return the 2 strings together. I want this method to be static (no instance of a class required) and I thought it would be nice to put the method in its own class definition so I could expand upon it and add others to it.

So first create you a new xcode project or use an existing one and then add a Objective -C class file, its under Mac OS X then Cocoa. Be sure to leave the "Also create the .h" checked...

Put this in your .h file:

#import UIKit/UIKit.h>
@interface MyFunc : NSObject {
}
+ (NSString *)updateString:(NSString *)name age:(NSString *)ageIn;
@end

Put this in your .m file:

#import "MyFunc.h"
@implementation MyFunc
+ (NSString *)updateString:(NSString *)name age:(NSString *)ageIn{
return ([name stringByAppendingString:ageIn]);
}
@end


A few notes on what I had you copy, I named my file "MyFunc.m" and "MyFunc.h". The header just has your standard method definition but notice the + as opposed to the - that makes the method a class method and not a instance method. Let me explain the method definition (.m)

1) (NSString *) is your return type
2) updateString:(NSString *)name updateString = method name, (NSString *) parameter type, name is used inside the method and it is your first parameter value
3) age = second parameter, (NSString *) = second parameter type, ageIn is used inside the method for the second parameters value.

The first parameter and second parameter form the method signature "updateString:age"

OK so now you want to use the great method, well from another .m file in my project all I did was #import "MyFunc.h" and then used it like this inside another method:

1) NSString *tmp = [MyFunc updateString:(@"param 1 ")age:(@"param 2")];
2) NSLog(tmp);

Have ?'s, leave a comment...

Monday, February 16, 2009

TouchXML Attributes

Here is my first post to my first blog, so I will keep is short N sweet. I am a .net developer who bought an iPhone and had to start developing for it. So I have a simple project in mind that will allow users to upload photos to their personal websites.

One of the things I need to do is parse XML and I didnt care for the NSXMLParser so I decided to use TouchXML for this. I downloaded the files from google code and included them in my xcode project then followed this tutorial. Next I decided to point the url to my local web server to test a webservice that returns a XML document. All fine and great but I was'nt sure how to get to any of my attributes, so here is how I did it:


//resultElement is a CXMLElement
//attributeForName is a method of CXMLElement which returns a CXMLNode
//stringValue is a method of CXMLNode that returns the string value for attribute by name
[[resultElement attributeForName:@"id"] stringValue];


Hopefully I will have time to post some more, but most of my time is spent developing but I do want to give back!!