The PayPal authorization flow includes PayPal One Touch™, which allows customers to pay by authenticating in-app via a modally presented UIViewController. After account authentication and payment authorization, customers are returned back to your app.

Setup

Before you can add PayPal:

  1. Integrate the Braintree iOS SDK into your app
  2. Create, verify, and link your PayPal account in the Braintree Control Panel

Setup for app switch

To handle workflows that involve switching to another app or SFSafariViewController for authentication, you must register a URL type and configure your app to handle return URLs.

Register a URL type

  1. In Xcode, click on your project in the Project Navigator and navigate to App Target > Info > URL Types
  2. Click [+] to add a new URL type
  3. Under URL Schemes, enter your app switch return URL scheme. This scheme must start with your app's Bundle ID and be dedicated to Braintree app switch returns. For example, if the app bundle ID is com.your-company.Your-App, then your URL scheme could be com.your-company.Your-App.payments.
important

If you have multiple app targets, be sure to add the return URL type for all of the targets.

Testing the URL type

You can test out your new URL scheme by opening up a URL that starts with it (e.g. com.your-company.Your-App.payments://test) in Mobile Safari on your iOS Device or Simulator.

In addition, always test your app switching on a real device.

Update your application delegate

In your AppDelegate's application:didFinishLaunchingWithOptions: implementation, use setReturnURLScheme: with the value you set above.

For example:

#import "AppDelegate.h"
#import <Braintree/Braintree.h>

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    [Braintree setReturnURLScheme:@"com.your-company.Your-App.payments"];
    return YES;
}

Then in your application delegate, pass the payment authorization URL to Braintree for finalization:

- (BOOL)application:(UIApplication *)application
            openURL:(NSURL *)url
            options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options {
    if ([url.scheme localizedCaseInsensitiveCompare:@"com.your-company.Your-App.payments"] == NSOrderedSame) {
        return [Braintree handleOpenURL:url sourceApplication:options[UIApplicationOpenURLOptionsSourceApplicationKey]];
    }
    return NO;
}

// If you support iOS 8, add the following method.
- (BOOL)application:(UIApplication *)application
            openURL:(NSURL *)url
  sourceApplication:(NSString *)sourceApplication
         annotation:(id)annotation {
    if ([url.scheme localizedCaseInsensitiveCompare:@"com.your-company.Your-App.payments"] == NSOrderedSame) {
        return [Braintree handleOpenURL:url sourceApplication:sourceApplication];
    }
    return NO;
}

Delegate

To start, define a class that implements BTPaymentMethodCreationDelegate:

// MyViewController.m
#import <Braintree/Braintree.h>

@interface MyViewController () <BTPaymentMethodCreationDelegate>
@property (nonatomic, strong) Braintree *braintree;
@end
  • paymentMethodCreator:didCreatePaymentMethod: Payment method creation is complete with success.
  • paymentMethodCreator:requestsDismissalOfViewController: Your implementation should ensure that the view controller is dismissed.
  • paymentMethodCreator:requestsPresentationOfViewController: The creator requires presentation of a view controller in order to proceed.
  • paymentMethodCreatorDidCancel: The creator has canceled.
  • paymentMethodCreatorWillPerformAppSwitch: Your implementation of this method should set your app to the state it should be in if the user manually switches back to your app. For example, re-enable any controls that are disabled.
  • paymentMethodCreatorWillProcess: This typically indicates asynchronous network activity. When you receive this message, your UI should indicate activity.
  • paymentMethodCreator:didFailWithError: The creator failed to create a payment method for a reason such as:
    • The authorization provider (PayPal) encountered an error
    • A network or gateway error occurred
    • The user-provided credentials led to a non-transactable payment method
note

Your paymentMethodCreator:didCreatePaymentMethod: implementation should communicate the nonce to your server. See Hello, Client for an overview and some sample code.

Showing a PayPal button

The Braintree SDK has a drop-in payment button that handles the boilerplate UI and code for accepting payments from PayPal.

availability

The drop-in button only supports the PayPal Vault flow.

When setting up your view controller's view hierarchy, create a BTPaymentButton and add it to your view:

- (void)viewDidLoad {
    [super viewDidLoad];

    // Create a `Braintree` instance, if you haven't already.
    self.braintree = [Braintree braintreeWithClientToken:self.clientToken];

    // Instantiate BTPaymentButton
    BTPaymentButton *button = [braintree paymentButtonWithDelegate:self];
    [button setFrame:CGRectMake(0, 0, 60, 120)];
    [self.view addSubview:button];
}

If you would like to only support a specific provider, you can specify that when creating the BTPaymentButton:

NSOrderedSet *types = [NSOrderedSet orderedSetWithObjects:@(BTPaymentProviderTypePayPal), nil];
BTPaymentButton *button = [braintree paymentButtonWithDelegate:self paymentProviderTypes:types];

For either flow, you should be receiving paymentMethodCreator:didCreatePaymentMethod: which gives to you a paymentMethod.nonce that can be sent to your server for processing.

Using a custom UI

You can implement a custom UI, such as your own PayPal button.

BTPaymentProvider *provider = [braintree paymentProviderWithDelegate:self];
// Start PayPal Flow
[provider createPaymentMethod:BTPaymentProviderTypePayPal];

Collecting additional data

You can gather additional data about your customers as they complete the payment process.

Billing address

To collect billing addresses you will need to enable the PayPal Billing Address Request feature in your PayPal account. To enable this feature, contact PayPal.

If you want to collect billing addresses, first set the proper scopes:

self.braintree.client.additionalPayPalScopes = [NSSet setWithObjects:BTPayPalScopeAddress, nil];

Once the scopes are set, the billingAddress property of the returned BTPayPalPaymentMethod should be populated with a BTPostalAddress:

BTPostalAddress *postalAddress = paypalPaymentMethod.billingAddress;
// Access the properties of the address
NSString *streetAddress = [postalAddress streetAddress];
NSString *extendedAddress = [postalAddress extendedAddress];
NSString *locality = [postalAddress locality];
NSString *countryCodeAlpha2 = [postalAddress countryCodeAlpha2];
NSString *postalCode = [postalAddress postalCode];
NSString *region = [postalAddress region];

If a credit card is not the underlying funding source of the transaction, the customer's primary account address will be returned instead.

note

See Braintree iOS Client SDK PayPal header files for in-depth documentation and additional custom PayPal integration options.

Next Page: Vault →