Has anyone implemented the PayPal API through a native iPhone app? - iphone

It seems the only way to stay "in app" is to give them a UIWebView of the paypal mobile site and let them complete the transaction there, otherwise the user would need to use their API key.
Does this sound right and has anyone got or seen any sample code? I have to think this is a common piece of code.
UPDATE:
Will Apple allow this?
It is a charity app, so I am assuming there is no issue.
Re-UPDATE:
I assumed wrong.
Apple will not allow payments directly within apps using paypal. You have to re-direct to a web interface.

Re-Update:
As answered below this code may still be useful for the purchase of physical goods
Update:
Although this code works, App Store terms won't allow you to use this code within an app.
Original Answer:
I figured this out after some heavy API research. Below is a method that creates an HTTP POST to send to Paypal and makes an NSURLRequest. You can fill in the appropriate string format variables. I used HTTP Client to check what I was doing.
- (void)sendPayPalRequestPOST{
perfomingSetMobileCheckout=YES;
recordResults = FALSE;
NSString *parameterString = [NSString stringWithFormat:#"USER=%#&PWD=%#&SIGNATURE=%#&VERSION=57.0&METHOD=SetMobileCheckout&AMT=%.2f&CURRENCYCODE=USD&DESC=%#&RETURNURL=%#", userName, password, signature, self.donationAmount, #"Some Charge", returnCallURL];
NSLog(parameterString);
NSURL *url = [NSURL URLWithString:paypalUrlNVP];
NSMutableURLRequest *theRequest = [NSMutableURLRequest requestWithURL:url];
NSString *msgLength = [NSString stringWithFormat:#"%d", [parameterString length]];
[theRequest addValue: msgLength forHTTPHeaderField:#"Content-Length"];
[theRequest setHTTPMethod:#"POST"];
[theRequest setHTTPBody: [parameterString dataUsingEncoding:NSUTF8StringEncoding]];
NSURLConnection *theConnection = [[NSURLConnection alloc] initWithRequest:theRequest delegate:self];
if( theConnection ){
webData = [[NSMutableData data] retain];
[self displayConnectingView];
}else{
NSLog(#"theConnection is NULL");
}
}
After this you need to parse the response, grab the session key and create a UIWebView to take them to the mobile paypal site. Paypal lets you specify a "return URL" which you can make anything you want. Just keep checking the UIWebview in the delegate method for this address and then you know the transaction is complete.
Then you send one more HTTP Post (similar to the one above) to Paypal to finalize the transaction. You can find the API information in the Paypal Mobile Checkout API docs.

Apple will allow custom checkouts for physical purchases. I talked with them at the iPhone Tech Talks in London and they said that they will not support physical purchases with In App Purchase as they would have to deal with refunds, etc. They also referred to existing apps that have custom checkouts.

When you say "I assumed wrong" about Apple allowing charitable donations within an app, can you provide any more information? I'm working on an app and there's a requirement to allow charitable donations...I haven't been able to find anything from Apple strictly forbidding it, but I haven't been able to find an app that allows charitable donations in the store, either.
(I struggled with whether to post this here and not as a new top-level question, but you're the first person I've come across with direct knowledge about the charitable giving within an iPhone app question).

Is it not possible using Paypal's Mobile Payment Library?
https://www.x.com/community/ppx/xspaces/mobile/mep?view=overview

Depending on the complexity of your needs, PayPal's iOS SDK (released March 2013) might be the ticket.

Related

Response for Registering on Wordpress Site through iPhone

I am writing an app that displays content from a Wordpress Site, and also allows reading of comments as well as posting comments. I am handling logging in to leave a comment and posting a comment via XML-RPC. All that is working quite well. However, this particular site does not allow anonymous commenting. So, I need to allow Registering for an account through the app.
Currently, I take the desired "username" and "email" and submit via POST as follows:
ASIFormDataRequest *request = [[ASIFormDataRequest alloc] initWithURL:[NSURL URLWithString:#"http://www.lamebook.com/wp-signup.php"]];
[request setPostValue:#"example" forKey:#"user_name"];
[request setPostValue:#"example#test.com" forKey:#"user_test"];
[request setDelegate:self];
[request setDidFinishSelector:#selector(registerFinished:)];
[request setDidFailSelector:#selector(registerFailed:)];
[request startAsynchronous];
This works in that it will create the account. However, my issue is that in my registerFinished method:
- (void)registerFinished:(ASIFormDataRequest *)request {
NSString *response = [[NSString alloc] initWithData:[request responseData] encoding:NSASCIIStringEncoding];
NSLog(#"response %#", response);
}
The response is simply the HTML of the registration page. The HTML contains no information about the success or failure of the registration.
When using the webform the returned HTML has entries if any error occurred, for example:
<p class="error">Username must be at least 4 characters</p>
However, I do not seem to get these elements in the HTML I receive on the phone. Is there a proper way to do registration on the phone?
If you have access to the site, which I guess you do, you should be able to write a small plugin that let's you perform the registration by posting data to an URL specified by your plugin. This would be fairly simple, just hook up a function to the init action and check for the $_POST variable for any input.
Then simply use username_exists to check for existing users and wp_create_user to perform the registration. These functions will give return values that you in turn can send as a JSON reponse (or whatever is appropriate) back to you application.
In fact, my experience with XML-RPC is that it's somewhat limited, and not really up to date with the rest of WordPress, so I often make these little mini API's to handle situations like this. All that might have changed in the latest releases, however.

Newsletter and registration on iphone

I'd like to know if it was possible, if a user wishes to subscribe to updates of my applications, take a form that is automatically subscribed to this newsletter at this address http://www.gseo.it/lists/?p=subscribe&id=2 (this is my mailing list with double opt in) but I'd like to know that a user can subscibe this newsletter directly from my iphone app.
Thanks
You could do an HTTP POST to that form using ASIFormDataRequest.
This isn't working code, but it might look something like:
NSURL *url = [NSURL URLWithString:#"http://www.gseo.it/lists/?p=subscribe&id=2"];
ASIFormDataRequest *request = [[[ASIFormDataRequest alloc] initWithURL:url] autorelease];
[request setPostValue:#"someone#example.com" forKey:#"email"];
[request startSynchronous];
You can get the library here.
Yes of course you can, open up a UIWebview with the the url provided. Don't forget that this may look not good in the iphone browser so providing a custom html code depending on the user agent may improve things.

Tracking iPhone on Yahoo Web Analytics using ASIHTTPRequest

I'm trying to track an event in my app using Yahoo Web Analytics. The code I am using looks like
ASIHTTPRequest *yahooTrack = [ASIHTTPRequest requestWithURL:
[NSURL URLWithString:#"http://s.analytics.yahoo.com/p.pl?a=xxxxxxxxxxxxx&js=no&b=yyyyyyyyyyyy&cf6=zzzzzzzzzzz"]];
yahooTrack.didFinishSelector = #selector(statisticsFinished:);
yahooTrack.delegate = self;
[yahooTrack startAsynchronous];
Then the statisticsFinished looks like:
NSLog(#"Cookies: %#", request.requestCookies);
NSLog(#"Redircount: %d", [request redirectCount]);
NSLog(#"Responsecode %d %#\nMsg: %#", request.responseStatusCode,
request.responseStatusMessage, [request responseString]);
And all the information I get back looks correct. Cookies are set, redirectcount is 1 the first time (as it redirects to s.analytics.yahoo.com/itr.pl?.... a normal browser does). Then the redirectcount is 0 for subsequent request until the app is restarted and session cleared. The responseString returns GIF89a.
Even if the data looks correct, Yahoo still won't track. As soon as I call the tracking url directly in my browser it works as expected.
I realize Flurry is a better option, but I'm forced to use Yahoo in this case. Also, using a UIWebView probably would work, but I'm against putting in a webview just for tracking purposes.
Is there any difference in how ASIHTTPRequest and Safari would handle a call to a simple URL as this? Or do you see anything else that could explain why the tracking isn't working?
I finally found the problem. ASIHTTPRequest creates a user-agent based on your applications name, and requests from this user agent is ignored by Yahoo somehow (bug?). As stated in the documentation, you can override the user-agent as follows:
[request addRequestHeader:#"User-Agent" value:#"My-User-Agent-1.0"];
I used the user-agent string of Safari on iPhone, and it worked immediately! BTW; the same problem applies for Android, and the same fix works.

Difficulties signing in to Twitter from iPhone

I'm using MGTwitterEngine to add Twitter functionality to my app. It's very easy to simply prompt the user for a username and password and then start posting. Strangely, however, I've noticed other apps (eg Foursquare and Brightkite) require you to visit their website to associate your Twitter account with your foursquare/brightkite/whatever account.
Why do they do it this way?
Is there a reason why my app shouldn't prompt the user for a Twitter username and password, even though it would be so easy?
Thanks a bunch!
Tristan
This is because you're using Basic Auth, which is just a username/password. Most new Twitter apps use the more robust OAuth, which requires you to visit Twitter.com to allow access, but does not require a username/password. The Twitter API docs claim that support for Basic Auth will be dropped soon, so you should be using OAuth as well.
Twitter supports OAuth, which allows you to access their account without asking for their password directly.
The main concern is security. What happens if/when your database gets hacked? The attackers will have access to all of your user's twitter passwords.
On hte other hand, those sites don't store their users passwords; if they get hacked, twitter can easily disable the oauth credentials, locking out any attackers before they can do harm.
Use OAuth; it's a lot safer.
Just replace YOUR_TWITTER_USERNAME and YOUR_TWITTER_PASSWORD. The code below has to be included in your viewController.m
NSMutableURLRequest *theRequest=[NSMutableURLRequest requestWithURL: [NSURL
URLWithString: #”http: //YOUR_TWITTER_USERNAME: YOUR_TWITTER_PASSWORD#twitter. com/
statuses/update. xml”]
cachePolicy:NSURLRequestUseProtocolCachePolicy
timeoutInterval: 60. 0] ;
[theRequest setHTTPMethod: #”POST”] ;
[theRequest setHTTPBody: [[NSString stringWithFormat: #”status=%#”,
themessage] dataUsingEncoding: NSASCIIStringEncoding] ] ;
NSURLResponse* response;
NSError* error;
NSData* result = [NSURLConnection sendSynchronousRequest:theRequest
returningResponse: &response error: &error] ;
NSLog( #”%#”, [[[ NSString alloc] initWithData: result
encoding: NSASCIIStringEncoding] autorelease] ) ;

Unable to POST data from IPhone using google account authentication

I'm working on an IPhone application that works with a Google App Engine application. I manage to get logged by using a google account and I get the authentication token. I'm also able to GET data from the GAE service (I did it after reading another question written here) but now I need to POST data so I need to send the authentication token in the header of the POST request. I tried several options but none of them worked.
Here is the code I use to put that auth into the header:
NSString* urlStr = [NSString stringWithFormat:#"%#%#", HOST, url];
NSMutableURLRequest* urlPost = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:urlStr]];
NSString* authStr = [NSString stringWithFormat:#"GoogleLogin auth=%#", token];
[urlPost addValue:authStr forHTTPHeaderField:#"Authorization"];
but it doesn't work.
Any help?
You need to use [request setHTTPMethod: #"POST"] and [request setHTTPBody: postdata] to properly configure the POST components. See the NSMutableURLRequest docs for more details.
Whenever I'm troubleshooting a problem related to HTTP, the first tool I'll grab is Charles HTTP Proxy. It will show you the entire request and response for closer examination.
If you're authenticating against an App Engine app, you need to obtain and send an authentication cookie, rather than using the GoogleLogin authentication. The source of appengine_rpc.py in the Python SDK demonstrates how.