Once your Certificate and Merchant ID are set up, you can add Apple Pay to your app.

User experience and vaulting Apple Pay cards

Apple Pay has specific user experience and identity guidelines, which Apple may enforce during the App Store review process. Please consult these guidelines as well as Apple's developer information when designing your Apple Pay user experience.

We support securely storing Apple Pay payment methods in the Vault. However, Apple recommends invoking Apple Pay as the final step in the purchasing process. As a result, you should consider restricting the storage of Apple Pay payment methods in the Vault to recurring billing transactions and/or transactions with partial or delayed shipments.

Get the SDK

In your Podfile, include both Braintree and its Braintree/Apple-Pay subspec:

Ruby
Copy
Copied
pod 'Braintree/Apple-Pay'

For other integration options, see the Getting Started section of our README.

Initialization

Like all Braintree SDK integrations, you will first need to initialize the Braintree SDK client:

Objective-C Swift
Copy
Copied
@interface MyViewController ()
@property (nonatomic, strong) BTAPIClient *braintreeClient;
@end

self.braintreeClient = [[BTAPIClient alloc] initWithAuthorization:<#CLIENT_AUTHORIZATION#>];

Your app will submit an Apple Pay authorization to Braintree and receive a payment method nonce in return, which can be used for server-side processing.

PassKit integration and payment tokenization

Set up your Apple Pay button

Apple Pay is only available to a subset of iOS users. Before presenting the Apple Pay option to the current user, you should determine whether Apple Pay is available.

Objective-C Swift
Copy
Copied
@import PassKit;
#import "BraintreeApplePay.h"

@interface MyCheckoutViewController <PKPaymentAuthorizationViewControllerDelegate>
@end

@implementation MyCheckoutViewController

- (void)viewDidLoad {
    [super viewDidLoad];

    // Conditionally show Apple Pay button based on device availability
    if ([PKPaymentAuthorizationViewController canMakePaymentsUsingNetworks:@[PKPaymentNetworkVisa, PKPaymentNetworkMasterCard, PKPaymentNetworkAmex]]) {
        UIButton *button = [self applePayButton];
        // TODO: Add button to view and set its constraints/frame...
        // [self.view addSubview:button];
    }
}

Since iOS 8.3, Apple has provided a beautiful Apple Pay button, PKPaymentButton. If your app targets older versions of iOS, you will need to create your own button using Apple's Human Interface Guidelines and assets.

Objective-C Swift
Copy
Copied
- (UIButton *)applePayButton {
    UIButton *button;

    if ([PKPaymentButton class]) { // Available in iOS 8.3+
        button = [PKPaymentButton buttonWithType:PKPaymentButtonTypeBuy style:PKPaymentButtonStyleBlack];
    } else {
        // TODO: Create and return your own apple pay button
        // button = ...
    }

    [button addTarget:self action:@selector(tappedApplePay) forControlEvents:UIControlEventTouchUpInside];

    return button;
}

Create a PKPaymentRequest

Before you can initiate a user-facing Apple Pay experience, you will need to initialize a payment request:

Objective-C Swift
Copy
Copied
- (PKPaymentRequest *)paymentRequest {
    PKPaymentRequest *paymentRequest = [[PKPaymentRequest alloc] init];
    paymentRequest.merchantIdentifier = @"<#YOUR_APPLE_PAY_MERCHANT_ID#>";
    paymentRequest.supportedNetworks = @[PKPaymentNetworkAmex, PKPaymentNetworkVisa, PKPaymentNetworkMasterCard];
    paymentRequest.merchantCapabilities = PKMerchantCapability3DS;
    paymentRequest.countryCode = @"<#COUNTRY_CODE#>"; // e.g. US
    paymentRequest.currencyCode = @"<#CURRENCY_CODE#>"; // e.g. USD
    paymentRequest.paymentSummaryItems =
        @[
            [PKPaymentSummaryItem summaryItemWithLabel:@"<#ITEM_NAME#>" amount:[NSDecimalNumber decimalNumberWithString:@"<#PRICE#>"]],
            // Add add'l payment summary items...
            [PKPaymentSummaryItem summaryItemWithLabel:@"<#COMPANY_NAME#>" amount:[NSDecimalNumber decimalNumberWithString:@"<#GRAND_TOTAL#>"]]
        ];
    return paymentRequest;
}

Here are some Braintree-specific recommendations about the various fields in the PKPaymentRequest:

  • countryCode: We suggest using the country where your business is located
  • currencyCode: This value must correspond to your Braintree merchant account's currency
  • merchantCapabilities: Please use PKMerchantCapability3DS (PKMerchantCapabilityEMV corresponds to in-store purchasing only)
  • merchantIdentifier: This value must match up with the merchantIdentifier and certificate on file in both Apple's developer center and Braintree's Control Panel
  • paymentSummaryItems: This value is required, and the grand total amount should not exceed the amount that is authorized or submitted for settlement
  • supportedNetworks: This value must match up with your merchant account's accepted payment methods

In order to be prepared to make changes without re-releasing your app, you should consider setting these values dynamically based on a response from your server.

In particular, you should be careful about keeping the PKPaymentRequest in sync with server environment (production vs. sandbox), as well as with your merchant account configuration and Apple Pay configuration. Self-service certificate management can be found in the Control Panel under Settings > Processing > Apple Pay.

Present a PKPaymentAuthorizationViewController

When your user taps on your Apple Pay UI, present a PKPaymentAuthorizationViewController to initiate Apple Pay:

Objective-C Swift
Copy
Copied
- (IBAction)tappedApplePay {
    PKPaymentRequest *paymentRequest = [self paymentRequest];
    PKPaymentAuthorizationViewController *vc = [[PKPaymentAuthorizationViewController alloc] initWithPaymentRequest:paymentRequest];
    vc.delegate = self;
    [self presentViewController:vc animated:YES completion:nil];
}

Implement PKPaymentAuthorizationViewControllerDelegate

Implement the PKPaymentAuthorizationViewControllerDelegate protocol methods. In your implementation of paymentAuthorizationViewController:didAuthorizePayment:completion:, create a nonce by tokenizing the PKPayment via the Braintree SDK:

Objective-C Swift
Copy
Copied
- (void)paymentAuthorizationViewController:(PKPaymentAuthorizationViewController *)controller
                       didAuthorizePayment:(PKPayment *)payment
                                completion:(void (^)(PKPaymentAuthorizationStatus))completion {

    // Example: Tokenize the Apple Pay payment
    BTApplePayClient *applePayClient = [[BTApplePayClient alloc]
                                        initWithAPIClient:self.braintreeClient];
    [applePayClient tokenizeApplePayPayment:payment
                                 completion:^(BTApplePayCardNonce *tokenizedApplePayPayment,
                                              NSError *error) {
        if (tokenizedApplePayPayment) {
            // On success, send nonce to your server for processing.
            // If applicable, address information is accessible in `payment`.
            NSLog(@"nonce = %@", tokenizedApplePayPayment.nonce);

            // Then indicate success or failure via the completion callback, e.g.
            completion(PKPaymentAuthorizationStatusSuccess);
        } else {
            // Tokenization failed. Check `error` for the cause of the failure.

            // Indicate failure via the completion callback:
            completion(PKPaymentAuthorizationStatusFailure);
        }
    }];
}

// Be sure to implement -paymentAuthorizationViewControllerDidFinish:
- (void)paymentAuthorizationViewControllerDidFinish:(PKPaymentAuthorizationViewController *)controller {
    [self dismissViewControllerAnimated:YES completion:nil];
}

See also

Next: Server-side →

Still have questions?

If you can’t find an answer, contact our Support team.