Use Braintree payment api in iOS app - ios

I want to use Braintree API in my iOS app.
My app is used for renting purpose i.e. requester user has to make payment to the owner of asset he wanted for rent.
I have checked following links :
http://www.youtube.com/watch?v=s7GlgBFM20I
https://www.braintreepayments.com/developers
http://www.youtube.com/watch?v=2y8Tsml6JYo
https://www.braintreepayments.com/braintrust/venmo-touch-screencasts-add-one-touch-payments-to-your-app-in-15-minutes
etc.
But I didn't get any idea where to provide receiver's account details using Braintree or Venmo api, For Example we can pass e-mail of receiver in PayPal iOS sdk, and then PayPal pays the amount to the user registered with that e-mail.
The same thing I am searching in Braintree Payment API.
Any help is greatly appreciated.
Thanks in advance.
I am using below code : (Used from a sample code given by braintree)
/* Get called when user pay on Pay button on screen.
User wil see a form for entering his credit card number, CVV and expiration date. */
-(IBAction)payButtonClicked
{
self.paymentViewController =
[BTPaymentViewController paymentViewControllerWithVenmoTouchEnabled:YES];
self.paymentViewController.delegate = self;
[self presentViewController:self.paymentViewController animated:YES completion:nil];
}
// When a user types in their credit card information correctly, the BTPaymentViewController sends you
// card details via the `didSubmitCardWithInfo` delegate method.
//
// NB: you receive raw, unencrypted info in the `cardInfo` dictionary, but
// for easy PCI Compliance, you should use the `cardInfoEncrypted` dictionary
// to securely pass data through your servers to the Braintree Gateway.
- (void)paymentViewController:(BTPaymentViewController *)paymentViewController
didSubmitCardWithInfo:(NSDictionary *)cardInfo
andCardInfoEncrypted:(NSDictionary *)cardInfoEncrypted {
[self savePaymentInfoToServer:cardInfoEncrypted]; // send card through your server to Braintree Gateway
}
// When a user adds a saved card from Venmo Touch to your app, the BTPaymentViewController sends you
// a paymentMethodCode that you can pass through your servers to the Braintree Gateway to
// add the full card details to your Vault.
- (void)paymentViewController:(BTPaymentViewController *)paymentViewController
didAuthorizeCardWithPaymentMethodCode:(NSString *)paymentMethodCode {
// Create a dictionary of POST data of the format
// {"payment_method_code": "[encrypted payment_method_code data from Venmo Touch client]"}
NSMutableDictionary *paymentInfo = [NSMutableDictionary dictionaryWithObject:paymentMethodCode
forKey:#"payment_method_code"];
[self savePaymentInfoToServer:paymentInfo]; // send card through your server to Braintree Gateway
}
#define SAMPLE_CHECKOUT_BASE_URL #"http://venmo-sdk-sample-two.herokuapp.com"
//#define SAMPLE_CHECKOUT_BASE_URL #"http://localhost:4567"
// Pass payment info (eg card data) from the client to your server (and then to the Braintree Gateway).
// If card data is valid and added to your Vault, display a success message, and dismiss the BTPaymentViewController.
// If saving to your Vault fails, display an error message to the user via `BTPaymentViewController showErrorWithTitle`
// Saving to your Vault may fail, for example when
// * CVV verification does not pass
// * AVS verification does not pass
// * The card number was a valid Luhn number, but nonexistent or no longer valid
- (void) savePaymentInfoToServer:(NSDictionary *)paymentInfo {
NSURL *url;
if ([paymentInfo objectForKey:#"payment_method_code"]) {
url = [NSURL URLWithString: [NSString stringWithFormat:#"%#/card/payment_method_code", SAMPLE_CHECKOUT_BASE_URL]];
} else {
url = [NSURL URLWithString: [NSString stringWithFormat:#"%#/card/add", SAMPLE_CHECKOUT_BASE_URL]];
}
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:url];
// You need a customer id in order to save a card to the Braintree vault.
// Here, for the sake of example, we set customer_id to device id.
// In practice, this is probably whatever user_id your app has assigned to this user.
NSString *customerId = [[UIDevice currentDevice] identifierForVendor].UUIDString;
[paymentInfo setValue:customerId forKey:#"customer_id"];
request.HTTPBody = [self postDataFromDictionary:paymentInfo];
request.HTTPMethod = #"POST";
[NSURLConnection sendAsynchronousRequest:request
queue:[NSOperationQueue mainQueue]
completionHandler:^(NSURLResponse *response, NSData *body, NSError *requestError)
{
NSError *err = nil;
if (!response && requestError) {
NSLog(#"requestError: %#", requestError);
[self.paymentViewController showErrorWithTitle:#"Error" message:#"Unable to reach the network."];
return;
}
NSDictionary *responseDictionary = [NSJSONSerialization JSONObjectWithData:body options:kNilOptions error:&err];
NSLog(#"saveCardToServer: paymentInfo: %# response: %#, error: %#", paymentInfo, responseDictionary, requestError);
if ([[responseDictionary valueForKey:#"success"] isEqualToNumber:#1]) { // Success!
// Don't forget to call the cleanup method,
// `prepareForDismissal`, on your `BTPaymentViewController`
[self.paymentViewController prepareForDismissal];
// Now you can dismiss and tell the user everything worked.
[self dismissViewControllerAnimated:YES completion:^(void) {
[[[UIAlertView alloc] initWithTitle:#"Success" message:#"Saved your card!" delegate:nil
cancelButtonTitle:#"OK" otherButtonTitles:nil] show];
[[VTClient sharedVTClient] refresh];
}];
} else { // The card did not save correctly, so show the error from server with convenenience method `showErrorWithTitle`
[self.paymentViewController showErrorWithTitle:#"Error saving your card" message:[self messageStringFromResponse:responseDictionary]];
}
}];
}

I work at Braintree. If you've got more questions or need more help, please reach out to our support team.
The Braintree iOS SDK docs include a quickstart guide, as well as detailed information about the features of the library.
If you're looking for information specifically on how to make payments between users of your app / web site, you should take a look at the marketplace guide and the Venmo APIs.

Related

SKReceiptRefreshRequest asking password everytime

I am using SKReceiptRefreshRequest to validate the receipt from the server. The problem is it is asking me every time password prompt. Can anyone help suggest me a better way to validate the user receipt
Here's what I am doing (i am using refreshReceipt when the app starts)
- (void)refreshReceipt {
SKReceiptRefreshRequest *refresh = [[SKReceiptRefreshRequest alloc] initWithReceiptProperties:nil];
refresh.delegate = self;
[refresh start];
}
- (void)requestDidFinish:(SKRequest *)request API_AVAILABLE(ios(3.0), macos(10.7)) {
if ([request isKindOfClass:[SKReceiptRefreshRequest class]]) {
NSLog(#"Got a new receipt...");
[self verifyReceipt:self.loadingView :NO :^{
} :^{
[app_delegate jumpToLogin];
}];
}
}
- (void)verifyReceipt :(UIView *)view1 :(BOOL)showHUD : (void (^)(void)) complete : (void (^)(void)) incomplete
{
if (showHUD) {
[UtilityManager showHUD:view1];
}
/* Load the receipt from the app bundle. */
NSURL *receiptURL = [[NSBundle mainBundle] appStoreReceiptURL];
NSData *receipt = [NSData dataWithContentsOfURL:receiptURL];
if (!receipt) {
/* No local receipt -- handle the error. */
[UtilityManager hideHUD:view1];
incomplete();
return;
}
/* Create the JSON object that describes the request */
NSError *error;
// Verify the recipt
In your case it's asking for a password because sandbox receipt is missing on your device. It's trying to refresh existing receipt, but can't find it. So it's going to get a fresh receipt, that is why it's asking for a password.
In production (when the app is downloaded from the App Store) there will always be a receipt, so it won't require a password.
And why are you using SKReceiptRefreshRequest? It's only required for "Restore purchases" button.
Here is article from our blog: https://blog.apphud.com/receipt-validation/
The receipt_data that is saved when a purchase is made in the device, only have the purchase details. "in_app" has a list of transaction details. The initial receipt will not have cancellation_date for the transaction.
The only was to get cancellation_date for non auto-renewable subscription is by calling SKReceiptRefreshRequest from the code.
It is very inconvenient for the user to enter their password every single time we try to update the receipt. I'm calling SKReceiptRefreshRequest once a week to check for the receipt updates.
I have verified the same with Apple as well by creating a Technical Support Incidents. They don't have a better way to solve this.

How to provide functionality to search groupchat with quickblox

I want to implement a functionality in a chat app by which user will be able to search a group by its unique provided code. I have used quickblox for implementing chat functionality. so please provide me a way to do that functionality with quickblox.
Please check official Document of Quickchat .
SimpleSample-chat_users-ios
They have mention all the detail in their document.
Moreover , Just Download the demo and try to implement.
Group_chat
Before implement Group chat don't forget to read typical setting section.
Typical settings [Functionality in Groupchat]
Authentication: Chat history: you may wish to keep
the archive of all public discussion history which is easily supported
by QuickBlox. Some platforms will also require you to implement abuse
and moderation mechanisms which are also supported both via API and
admin panel. File attachments: typically attachments are not supported
1:1 / IM chat: in many applications you may wish to allow users start
a private communication with other user Friending: QuickBlox supports
friending or adding other users to favourites which you may use in
your application - see also [chat: friending / favourite users lists]
start groupchat with creating Dialogue.
Create_new_group_chat_dialog
QBChatDialog *chatDialog = [[QBChatDialog alloc]
initWithDialogID:null type:QBChatDialogTypeGroup];
chatDialog.name = #"Chat with Bob, Sam, Garry"; //set according to requirement
chatDialog.occupantIDs = #[#(55), #(678), #(22)];
[QBRequest createDialog:chatDialog successBlock:^(QBResponse *response, QBChatDialog *createdDialog) {
} errorBlock:^(QBResponse *response) {
}];
Second step --> Create chatnotification
- (QBChatMessage *)createChatNotificationForGroupChatCreation:(QBDialog *)dialog
{
// create message:
QBChatMessage *inviteMessage = [QBChatMessage message];
NSMutableDictionary *customParams = [NSMutableDictionary new];
customParams[#"xmpp_room_jid"] = dialog.roomJID;
customParams[#"name"] = dialog.name;
customParams[#"_id"] = dialog.ID;
customParams[#"type"] = #(dialog.type);
customParams[#"occupants_ids"] = [dialog.occupantIDs componentsJoinedByString:#","];
// Add notification_type=1 to extra params when you created a group chat
//
customParams[#"notification_type"] = #"1";
inviteMessage.customParameters = customParams;
return inviteMessage;
}
...
for (NSString *occupantID in dialog.occupantIDs) {
QBChatMessage *inviteMessage = [self createChatNotificationForGroupChatCreation:dialog];
NSTimeInterval timestamp = (unsigned long)[[NSDate date] timeIntervalSince1970];
customParams[#"date_sent"] = #(timestamp);
// send notification
//
inviteMessage.recipientID = [occupantID integerValue];
[[QBChat instance] sendSystemMessage:inviteMessage completion:^(NSError * _Nullable error) {
}];
}
You will receive opponent in this delegate .
- (void)chatDidReceiveSystemMessage:(QBChatMessage *)message
{
}
You can implement required functionality in group-chat with abolve link.
Like , Get online users ,Leave group chat dialog , Attachment in group. etc.

Unable to get access token from Paypal sdk. Got an Exception says “Authentication needed”

I am using PayPal SDK for adaptive payment...I get PayPal Payment Success message in
- (void)payPalPaymentViewController:(PayPalPaymentViewController *)paymentViewController didCompletePayment:(PayPalPayment *)completedPayment {
NSLog(#"PayPal Payment Success!");
[self sendCompletedPaymentToServer:completedPayment]; // Payment was processed successfully; send to server for verification and fulfillment
[self dismissViewControllerAnimated:YES completion:nil];
}
- (void)sendCompletedPaymentToServer:(PayPalPayment *)completedPayment {
// TODO: Send completedPayment.confirmation to server
NSLog(#"Here is your proof of payment:\n\n%#\n\nSend this to your server for confirmation and fulfillment.", completedPayment.confirmation);
payId=[[completedPayment.confirmation objectForKey:#"response"] objectForKey:#"id"];
[self callForAccessToken]; ///////calll webservice to get access token
}
- (void)callForAccessToken {
NSString *shippingURL=[NSString stringWithFormat:#"https://api.sandbox.paypal.com/v1/oauth2/token"];
ASIFormDataRequest *shippingRequest = [ASIFormDataRequest requestWithURL:[NSURL URLWithString:shippingURL]];
[shippingRequest setRequestMethod:#"POST"];
shippingRequest.tag=1010;
[shippingRequest setPostValue:#"application/json" forKey:#"Accept"];
[shippingRequest setPostValue:#"en_US" forKey:#"Accept-Language"];
NSString *clientIDSecret=[NSString stringWithFormat:#"kClientID:kClientsecret"];
[shippingRequest setPostValue:clientIDSecret forKey:#"clientId:secret"];
[shippingRequest setPostValue:#"client_credentials" forKey:#"grant_type"];
[shippingRequest setDelegate:self];
[shippingRequest setDidFinishSelector:#selector(uploadFinishedLocation:)];
[shippingRequest setDidFailSelector:#selector(uploadFailLocation:)];
[shippingRequest startAsynchronous];
}
- (void)uploadFinishedLocation:(ASIHTTPRequest *)requestObj {
NSString *response = [requestObj responseString];
NSLog(#"\n\nReq tag %ld Response string in Payment Didload %#\n\n",(long)requestObj.tag,response);
}
- (void)uploadFailLocation:(ASIHTTPRequest *)requestObj {
NSLog(#"%#",requestObj.error.description);
}
When I execute code uploadFailLocation is called...
And I get error:
" Authentication needed "
I got reference to pass all data in post form in key-valuse combination by this link.
https://developer.paypal.com/webapps/developer/docs/integration/direct/make-your-first-call/#get-an-access-token
So have I pass client id and secredt right way or something is missing.......
Or is there any other way to do this things.....
The generating of an access token is a server to server call and is not done from your App itself. Also, when doing so, the client ID and secret are sent in the headers and not just posted as key>value. The steps to verify a mobile payment can be found here.

PayPal SDK for iOS

I am trying to implement the Paypal SDK into my iOS app. I copied the code exactly from the Readme instructions, imported the files, and linked my button to my action but when I clicked the button it gives me a "Thread 1 signal:SIGABRT" error and crashes.
Here is the Paypal code in my .m files:
- (IBAction)pay {
// Create a PayPalPayment
PayPalPayment *payment = [[PayPalPayment alloc] init];
payment.amount = [[NSDecimalNumber alloc] initWithString:#"39.95"];
payment.currencyCode = #"USD";
payment.shortDescription = #"Product";
// Check whether payment is processable.
if (!payment.processable) {
// If, for example, the amount was negative or the shortDescription was empty, then
// this payment would not be processable. You would want to handle that here.
}
// Provide a payerId that uniquely identifies a user within the scope of your system,
// such as an email address or user ID.
NSString *aPayerId = #"someone#someone.com";
// Create a PayPalPaymentViewController with the credentials and payerId, the PayPalPayment
// from the previous step, and a PayPalPaymentDelegate to handle the results.
PayPalPaymentViewController *paymentViewController;
paymentViewController = [[PayPalPaymentViewController alloc] initWithClientId:#"MY-CLIENT-ID-HERE"
receiverEmail:#"MY-EMAIL-HERE"
payerId:aPayerId
payment:payment
delegate:self];
// Present the PayPalPaymentViewController.
[self presentViewController:paymentViewController animated:YES completion:nil];
}
#pragma mark - PayPalPaymentDelegate methods
- (void)payPalPaymentDidComplete:(PayPalPayment *)completedPayment {
// Payment was processed successfully; send to server for verification and fulfillment.
[self verifyCompletedPayment:completedPayment];
// Dismiss the PayPalPaymentViewController.
[self dismissViewControllerAnimated:YES completion:nil];
}
- (void)payPalPaymentDidCancel {
// The payment was canceled; dismiss the PayPalPaymentViewController.
[self dismissViewControllerAnimated:YES completion:nil];
}
- (void)verifyCompletedPayment:(PayPalPayment *)completedPayment {
// Send the entire confirmation dictionary
NSData *confirmation = [NSJSONSerialization dataWithJSONObject:completedPayment.confirmation
options:0
error:nil];
// Send confirmation to your server; your server should verify the proof of payment
// and give the user their goods or services. If the server is not reachable, save
// the confirmation and try again later.
}
Does anyone have any ideas what the problem might be?
You know what?
cuz you use decimal number on you currency.
so you need do something in this code
// Check whether payment is processable.
if (!payment.processable) {
// If, for example, the amount was negative or the shortDescription was empty, then
// this payment would not be processable. You would want to handle that here.
}
If you in debug point you can find a keyword in payment, display, it's mean your currency will change to 40.0.
Try it.

Can you get your Twitter email using the API?

I am developing a iOS App and I have login with Facebook, LinkedIn, Google+ and Twitter.
All of them let me read my email from my profile using API, EXCEPT Twitter.
Is there any way to get my email?
If not, is there in twitter a "internal email", a generated email like in facebook (someone#facebook.com)?
The reason is that I use email as identifier (primary key) for users in my database.
No, email address are not available via the Twitter API: https://dev.twitter.com/discussions/1737
Nor is there any "internal email" available, you will have to use the twitter username and ask the user fro there e-mail address.
You will have to use Twitter framework. Twitter has provided a beautiful framework for that, you just have to integrate it in your app.
To get user email address, your application should be whitelisted. Here is the link. Go to use this form. You can either send mail to sdk-feedback#twitter.com with some details about your App like Consumer key, App Store link of an App, Link to privacy policy, Metadata, Instructions on how to log into our App etc..They will respond within 2-3 working days.
Here is the story how I got whitelisted by conversation with Twitter support team:
Send mail to sdk-feedback#twitter.com with some details about your App like Consumer key, App Store link of an App, Link to privacy policy, Metadata, Instructions on how to log into our App. Mention in mail that you want to access user email adress inside your App.
They will review your App and reply to you withing 2-3 business days.
Once they say that your App is whitelisted, update your App's settings in Twitter Developer portal. Sign in to apps.twitter.com and:
On the 'Settings' tab, add a terms of service and privacy policy URL
On the 'Permissions' tab, change your token's scope to request email. This option will only been seen, once your App gets whitelisted.
Put your hands on code
Use of Twitter framework:
Get user email address
-(void)requestUserEmail
{
if ([[Twitter sharedInstance] session]) {
TWTRShareEmailViewController *shareEmailViewController =
[[TWTRShareEmailViewController alloc]
initWithCompletion:^(NSString *email, NSError *error) {
NSLog(#"Email %# | Error: %#", email, error);
}];
[self presentViewController:shareEmailViewController
animated:YES
completion:nil];
} else {
// Handle user not signed in (e.g. attempt to log in or show an alert)
}
}
Get user profile
-(void)usersShow:(NSString *)userID
{
NSString *statusesShowEndpoint = #"https://api.twitter.com/1.1/users/show.json";
NSDictionary *params = #{#"user_id": userID};
NSError *clientError;
NSURLRequest *request = [[[Twitter sharedInstance] APIClient]
URLRequestWithMethod:#"GET"
URL:statusesShowEndpoint
parameters:params
error:&clientError];
if (request) {
[[[Twitter sharedInstance] APIClient]
sendTwitterRequest:request
completion:^(NSURLResponse *response,
NSData *data,
NSError *connectionError) {
if (data) {
// handle the response data e.g.
NSError *jsonError;
NSDictionary *json = [NSJSONSerialization
JSONObjectWithData:data
options:0
error:&jsonError];
NSLog(#"%#",[json description]);
}
else {
NSLog(#"Error code: %ld | Error description: %#", (long)[connectionError code], [connectionError localizedDescription]);
}
}];
}
else {
NSLog(#"Error: %#", clientError);
}
}
Hope it helps !!!

Resources