PayPal iOS SDK nil View Controller - ios

I am using the most recent PayPal iOS sdk in my app. For some unknown reason, when I try to init the PayPalPaymentViewContoller then present it, it is crashing. I have determined that the viewController is nil, but I have no idea why.
Here are the two lines of code to do with this.
The first line is the init, and the second is present
PayPalPaymentViewController *paymentViewController = [[PayPalPaymentViewController alloc] initWithPayment:payment configuration:self.payPalConfig delegate:self];
[self presentViewController:paymentViewController animated:YES completion:nil];
Any ideas? Let me what more information you need. I am not really sure what else to provide.

Dave from PayPal here.
#linuxer have you followed our sample code? In particular, from step 5:
// 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 the payment is not "processable", but you go ahead anyway to create the PayPalPaymentViewController, then you would indeed get back nil.
You should also see a message to that effect in your console log. Have you taken a look there?

When you create object for PayPalItem at here in withPrice param, amount always be in two value after decimal. See below example:
PayPalItem *item1 = [PayPalItem itemWithName:#"T Shirt" withQuantity:1 withPrice:[NSDecimalNumber decimalNumberWithString:**
[NSString stringWithFormat:#"%0.2f",overAllTotalAmt]
**] withCurrency:#"USD" withSku:#"Hip-00037"];

Related

iOS15: How to add a custom activity button to an SFSafariViewController?

In iOS15, there is a new API to SFSafariViewController.Configuration that suggest one can add a custom button on the SafariViewController UI. This blogpost explains this in greater detail, under "Running custom extension".
I've been trying to implement this in a sample app without success. See the code snippet below:
- (void)openSfariViewController {
SFSafariViewControllerConfiguration *config = [[SFSafariViewControllerConfiguration alloc] init];
// Also tried the following extensionIdentifiers without success
// com.atomicbird.DemoNotes
// com.apple.share-services
SFSafariViewControllerActivityButton *button = [[SFSafariViewControllerActivityButton alloc] initWithTemplateImage:[UIImage systemImageNamed:#"heart.fill"] extensionIdentifier:#"com.atomicbird.DemoNotes.DemoNotes"];
config.activityButton = button;
SFSafariViewController *safariVC = [[SFSafariViewController alloc]initWithURL:[NSURL URLWithString:#"http://developer.apple.com"] configuration:config];
// safariVC.delegate = self;
[self presentViewController:safariVC animated:NO completion:nil];}
However I try to configure the new activityButton, it doesn't seem to have an effect on how SFSafariViewController appears when it is presented. It looks exactly like it does if I don't configure the activityButton. Here are some things I think I might got wrong:
I don't know what is the extensionIdentifier, perhaps I used a wrong value?
Perhaps I got the whole thing wrong, and an ActivityButton is not what I think it is?
Maybe the Share extension is not the configured properly?
I haven't been able to find any information on the web on how an activityButton is even supposed to look like. Thanks for reading this far, let me know if you have any pointers for me.

Apple Pay detect Wallet has no credit cards

I am trying to implement Apple Pay for my app. I have the PKPaymentAuthorizationViewController trying to load up the Apple Pay View. This view controller was being returned as Nil by the constructor if I didn't have any cards already in my wallet. So, I decided to guide the user though the process where they enter their card information. I was able to achieve this using
PKPassLibrary* lib = [[PKPassLibrary alloc] init];
[lib openPaymentSetup];
Here is the part where I have the initialization of the PKPaymentAuthorizationViewController. This returns a valid object on Simulator showing the view. But on a real device without a configured credit card returns nil and runs into an runtime exception. Here is the initialization code:
if ([PKPaymentAuthorizationViewController canMakePayments]) {
// init arr
[arr addObject:total];
request.paymentSummaryItems = arr;
PKPaymentAuthorizationViewController *paymentPane = [[PKPaymentAuthorizationViewController alloc] initWithPaymentRequest:request];
paymentPane.delegate = self;
[self presentViewController:paymentPane animated:TRUE completion:nil];
}
Here the array is a valid NSArray of PKPaymentSummaryItem which is why is successfully works on simulator.
I need to call the above method of openPaymentSetup, everytime I see a user without the credit card in their wallet. Is there a way to detect that?
Currently I am using
if ( [PKPassLibrary isPassLibraryAvailable] ) {
PKPassLibrary* lib = [[PKPassLibrary alloc] init];
if ([lib passesOfType:PKPassTypePayment].count == 0 ) {
[lib openPaymentSetup];
}
}
But this will not work since I am looking at the count of passes in wallet. Which may be like boarding pass for airline, or eventbrite pass, etc.
Looked at :
PKPaymentAuthorizationViewController present as nil view controller
Apple pay PKPaymentauthorizationViewController always returning nil when loaded with Payment request
https://developer.apple.com/library/ios/documentation/PassKit/Reference/PKPaymentAuthorizationViewController_Ref/
I did as suggested by #maddy, and it actually worked. Its unfortunate that apple has very limited documentation about it. Thanks Maddy.
Here is my code
-(BOOL) openAddCardForPaymentUIIfNeeded
{
if ( [PKPassLibrary isPassLibraryAvailable] )
{
if ( ![PKPaymentAuthorizationViewController canMakePaymentsUsingNetworks:[NSArray arrayWithObjects: PKPaymentNetworkAmex, PKPaymentNetworkMasterCard, PKPaymentNetworkVisa, nil]] )
{
UIAlertView* alert = [[UIAlertView alloc] initWithTitle:#"Add a Credit Card to Wallet" message:#"Would you like to add a credit card to your wallet now?" delegate:self cancelButtonTitle:#"No" otherButtonTitles:#"Yes", nil];
[alert show];
return true;
}
}
return false;
}
Now I am directing the user to go to add a card wizard in the wallet app. Is there any way I can get the user back to the App after he/she has finished adding the card in the Wallet?
Thanks!

Apple pay PKPaymentauthorizationViewController always returning nil when loaded with Payment request

I am getting the PK Payment auth view controller instance returned as nil. What is wrong with this code?
if([PKPaymentAuthorizationViewController canMakePayments])
{
if ([PKPaymentAuthorizationViewController canMakePaymentsUsingNetworks:#[PKPaymentNetworkAmex, PKPaymentNetworkMasterCard, PKPaymentNetworkVisa]])
{
PKPaymentRequest *request = [[PKPaymentRequest alloc] init];
request.currencyCode = #"USD";
request.countryCode = #"US";
request.merchantCapabilities = 0;
request.requiredBillingAddressFields=PKAddressFieldAll;
request.merchantIdentifier = #"merchant.com.domain.mine";
PKPaymentSummaryItem *item = [[PKPaymentSummaryItem alloc] init];
item.label=#"Merchant";
item.amount=[NSDecimalNumber decimalNumberWithString:#"10"];
request.paymentSummaryItems=#[item];
PKPaymentAuthorizationViewController *viewController = [[PKPaymentAuthorizationViewController alloc] initWithPaymentRequest:request];
viewController.delegate = self;
[self presentViewController:viewController animated:YES completion:nil];
}
}
Before accessing the PKPaymentAuthorizationViewController, you should configure Apple Pay properly on your iPhone device. If you have not configured Apple Pay on your device you'll get nil value for PKPaymentAuthorizationViewController. You can even find an exception on the console stating "This device cannot make payment."
To configure Apple Pay on your device follow the below steps:
Go to Settings.
Select Passbook and Apple Pay option (if this option is not visible in settings, go to General -> Language & Region, change your region to US or UK, after this you'll be able to see the Passbook & Apple Pay option in Settings)
Open Passbook application from your home screen and configure a valid credit/debit card (US/UK based card only).
After verifying the added card, run your application you'll get a valid PKPaymentAuthorizationViewController instance.
Hope this will help.
I had a similar issue. It looks like you included it, but for anyone else struggling with this, my problem was not initially supplying merchantCapabilities to the request.
Swift:
request.merchantCapabilities = PKMerchantCapability.capability3DS
https://developer.apple.com/documentation/passkit/pkmerchantcapability?language=objc
If you are instantiating the supporting networks with raw value, make sure they are done so with the proper capitalization.
// Summarized for posting purposes
let networks = ["AmEx", "Visa", "MasterCard", "Discover"].reduce(into: [PKPaymentNetwork]()) { $0.append(PKPaymentNetwork($1)) }
if PKPaymentAuthorizationViewController.canMakePayments(usingNetworks: networks, capabilities: .capability3DS) {
// Hooray
}

Send GameCenter friendrequest

At the moment I'm working on a iPhone app and I have a problem.
I want, that the player can send a gamecenter friendrequest.
In the apple Guide there are two methods I'm interested in.
The first would be
- (void)addRecipientsWithPlayerIDs:(NSArray *)playerids
and the second would be
- (void)setMessage:(NSString *)message
Now I don't know to put them in the right order to get on.
How can I set the player ID's and the message, and after that, how can I send the request.
Suppose you have player ids in friendsArray. Then try this:
GKFriendRequestComposeViewController *friendRequestViewController = [[GKFriendRequestComposeViewController alloc] init];
friendRequestViewController.composeViewDelegate = self;
[friendRequestViewController setMessage:#"Add your message here"];
if (friendsArray)
{
[friendRequestViewController addRecipientsWithPlayerIDs: friendsArray];
}
[self presentModalViewController: friendRequestViewController animated: YES];
Hope this helps.. :)

PayPal - IOS SDK - Live production env communications error

We have implemented the IOS SDK (https://github.com/paypal/PayPal-iOS-SDK) into a Native IOS app that we are building - All was working fine during initial tests (both Sandbox and production) - a payment for 10p in GBP worked without issue in the live production environment on Nov 5th.
Checked a production environment transaction again today as part of the apps final tests and although we can log in with a live PayPal account - the payment fails with an error stating -
'Were sorry There was a problem communicating with the paypal servers. Please try again.'
No Log errors that seem to be relevant, just these -
2013-11-27 15:51:32.528 GetPTFit[2181:60b] nested push animation can result in corrupted navigation bar
2013-11-27 15:51:32.893 GetPTFit[2181:60b] Finishing up a navigation transition in an unexpected state. Navigation Bar subview tree might get corrupted.
bizarre - has anyone experienced anything similar and know how to resolve!?
This is my pay method if any help -
- (IBAction)pay {
// Remove our last completed payment, just for demo purposes.
self.completedPayment = nil;
PayPalPayment *payment = [[PayPalPayment alloc] init];
payment.amount = [[NSDecimalNumber alloc] initWithString:self.shopObject.shopIPrice];
payment.currencyCode = #"GBP";
payment.shortDescription = self.shopObject.shopITitle;
if (!payment.processable) {
// This particular payment will always be processable. If, for
// example, the amount was negative or the shortDescription was
// empty, this payment wouldn't be processable, and you'd want
// to handle that here.
}
// Any customer identifier that you have will work here. Do NOT use a device- or
// hardware-based identifier.
NSString *customerId = #"GetPTFit";
// Set the environment:
// - For live charges, use PayPalEnvironmentProduction (default).
// - To use the PayPal sandbox, use PayPalEnvironmentSandbox.
// - For testing, use PayPalEnvironmentNoNetwork.
[PayPalPaymentViewController setEnvironment:PayPalEnvironmentProduction];
PayPalPaymentViewController *paymentViewController = [[PayPalPaymentViewController alloc] initWithClientId:kPayPalClientId
receiverEmail:kPayPalReceiverEmail
payerId:customerId
payment:payment
delegate:self];
paymentViewController.hideCreditCardButton = !self.acceptCreditCards;
// Setting the languageOrLocale property is optional.
//
// If you do not set languageOrLocale, then the PayPalPaymentViewController will present
// its user interface according to the device's current language setting.
//
// Setting languageOrLocale to a particular language (e.g., #"es" for Spanish) or
// locale (e.g., #"es_MX" for Mexican Spanish) forces the PayPalPaymentViewController
// to use that language/locale.
//
// For full details, including a list of available languages and locales, see PayPalPaymentViewController.h.
paymentViewController.languageOrLocale = #"en";
[self presentViewController:paymentViewController animated:YES completion:nil];
}
Cheers
Dave from PayPal here.
Please see my response in the issue that you raised at our github repo. Feel free to respond in turn over there, or else here on StackOverflow if you prefer.

Resources