diff --git a/Demo/Application/Base/Base View Controllers/BraintreeDemoPaymentButtonBaseViewController.m b/Demo/Application/Base/Base View Controllers/BraintreeDemoPaymentButtonBaseViewController.m index 076042c8b0..3c9ed41fc8 100644 --- a/Demo/Application/Base/Base View Controllers/BraintreeDemoPaymentButtonBaseViewController.m +++ b/Demo/Application/Base/Base View Controllers/BraintreeDemoPaymentButtonBaseViewController.m @@ -26,7 +26,7 @@ - (void)viewDidLoad { [self.paymentButton.leadingAnchor constraintEqualToAnchor:self.view.leadingAnchor], [self.paymentButton.trailingAnchor constraintEqualToAnchor:self.view.trailingAnchor], [self.paymentButton.centerYAnchor constraintEqualToAnchor:self.view.centerYAnchor constant:self.centerYConstant], - [self.paymentButton.heightAnchor constraintEqualToConstant:44.0] + [self.paymentButton.heightAnchor constraintEqualToConstant:100.0] ]]; } diff --git a/Demo/Application/Features/Amex/BraintreeDemoAmexViewController.h b/Demo/Application/Features/Amex/BraintreeDemoAmexViewController.h deleted file mode 100644 index c4084e38e7..0000000000 --- a/Demo/Application/Features/Amex/BraintreeDemoAmexViewController.h +++ /dev/null @@ -1,7 +0,0 @@ -#import - -#import "BraintreeDemoPaymentButtonBaseViewController.h" - -@interface BraintreeDemoAmexViewController : BraintreeDemoBaseViewController - -@end diff --git a/Demo/Application/Features/Amex/BraintreeDemoAmexViewController.m b/Demo/Application/Features/Amex/BraintreeDemoAmexViewController.m deleted file mode 100644 index bbf59039a1..0000000000 --- a/Demo/Application/Features/Amex/BraintreeDemoAmexViewController.m +++ /dev/null @@ -1,96 +0,0 @@ -#import "BraintreeDemoAmexViewController.h" -@import BraintreeAmericanExpress; -@import BraintreeCard; -@import BraintreeCore; - -@interface BraintreeDemoAmexViewController () - -@property (nonatomic, strong) BTAPIClient *apiClient; -@property (nonatomic, strong) BTCardClient *cardClient; -@property (nonatomic, strong) BTAmericanExpressClient *amexClient; - -@end - -@implementation BraintreeDemoAmexViewController - -- (instancetype)initWithAuthorization:(NSString *)authorization { - self = [super initWithAuthorization:authorization]; - if (self) { - _apiClient = [[BTAPIClient alloc] initWithAuthorization:authorization]; - _amexClient = [[BTAmericanExpressClient alloc] initWithAPIClient:_apiClient]; - _cardClient = [[BTCardClient alloc] initWithAPIClient:_apiClient]; - } - return self; -} - -- (void)viewDidLoad { - [super viewDidLoad]; - self.title = NSLocalizedString(@"Amex", nil); - - UIButton *validCardButton = [UIButton buttonWithType:UIButtonTypeSystem]; - [validCardButton setTitle:NSLocalizedString(@"Valid card", nil) forState:UIControlStateNormal]; - [validCardButton addTarget:self action:@selector(tappedValidCard) forControlEvents:UIControlEventTouchUpInside]; - - UIButton *insufficientPointsCardButton = [UIButton buttonWithType:UIButtonTypeSystem]; - [insufficientPointsCardButton setTitle:NSLocalizedString(@"Insufficient points card", nil) forState:UIControlStateNormal]; - [insufficientPointsCardButton addTarget:self action:@selector(tappedInsufficientPointsCard) forControlEvents:UIControlEventTouchUpInside]; - - UIButton *ineligibleCardButton = [UIButton buttonWithType:UIButtonTypeSystem]; - [ineligibleCardButton setTitle:NSLocalizedString(@"Ineligible card", nil) forState:UIControlStateNormal]; - [ineligibleCardButton addTarget:self action:@selector(tappedIneligibleCard) forControlEvents:UIControlEventTouchUpInside]; - - UIStackView *stackView = [[UIStackView alloc] initWithArrangedSubviews:@[validCardButton, insufficientPointsCardButton, ineligibleCardButton]]; - stackView.axis = UILayoutConstraintAxisVertical; - stackView.distribution = UIStackViewDistributionEqualSpacing; - stackView.spacing = 20; - stackView.translatesAutoresizingMaskIntoConstraints = NO; - - [self.view addSubview:stackView]; - [NSLayoutConstraint activateConstraints:@[ - [stackView.centerXAnchor constraintEqualToAnchor:self.view.centerXAnchor], - [stackView.centerYAnchor constraintEqualToAnchor:self.view.centerYAnchor] - ]]; -} - -- (void)tappedValidCard { - [self getRewardsForCardNumber:@"371260714673002"]; -} - -- (void)tappedInsufficientPointsCard { - [self getRewardsForCardNumber:@"371544868764018"]; -} - -- (void)tappedIneligibleCard { - [self getRewardsForCardNumber:@"378267515471109"]; -} - -- (void)getRewardsForCardNumber:(NSString *)cardNumber { - BTCard *card = [BTCard new]; - card.number = cardNumber; - card.expirationMonth = @"12"; - card.expirationYear = @"2025"; - card.cvv = @"1234"; - - self.progressBlock(@"Tokenizing Card"); - - [self.cardClient tokenizeCard:card completion:^(BTCardNonce *tokenized, NSError *error) { - if (error) { - self.progressBlock(error.localizedDescription); - NSLog(@"Error: %@", error); - return; - } - - self.progressBlock(@"Amex - getting rewards balance"); - [self.amexClient getRewardsBalanceForNonce:tokenized.nonce currencyIsoCode:@"USD" completion:^(BTAmericanExpressRewardsBalance *rewardsBalance, NSError *error) { - if (error) { - self.progressBlock(error.localizedDescription); - } else if (rewardsBalance.errorCode) { - self.progressBlock([NSString stringWithFormat:@"%@: %@", rewardsBalance.errorCode, rewardsBalance.errorMessage]); - } else { - self.progressBlock([NSString stringWithFormat:@"%@ %@, %@ %@", rewardsBalance.rewardsAmount, rewardsBalance.rewardsUnit, rewardsBalance.currencyAmount, rewardsBalance.currencyIsoCode]); - } - }]; - }]; -} - -@end diff --git a/Demo/Application/Features/Amex/BraintreeDemoAmexViewController.swift b/Demo/Application/Features/Amex/BraintreeDemoAmexViewController.swift new file mode 100644 index 0000000000..1ce89ea996 --- /dev/null +++ b/Demo/Application/Features/Amex/BraintreeDemoAmexViewController.swift @@ -0,0 +1,95 @@ +import Foundation +import BraintreeAmericanExpress +import BraintreeCard + +class BraintreeDemoAmexViewController: BraintreeDemoPaymentButtonBaseViewController { + + lazy var amexClient = BTAmericanExpressClient(apiClient: apiClient) + lazy var cardClient = BTCardClient(apiClient: apiClient) + + override func viewDidLoad() { + super.viewDidLoad() + title = "Amex" + } + + override func createPaymentButton() -> UIView! { + let validCardButton = createButton(title: "Valid card", action: #selector(tappedValidCard)) + let insufficientPointsCardButton = createButton(title: "Insufficient points card", action: #selector(tappedInsufficientPointsCard)) + let ineligibleCardButton = createButton(title: "Ineligible card", action: #selector(tappedIneligibleCard)) + + let stackView = UIStackView(arrangedSubviews: [validCardButton, insufficientPointsCardButton, ineligibleCardButton]) + stackView.axis = .vertical + stackView.alignment = .center + stackView.distribution = .fillEqually + stackView.translatesAutoresizingMaskIntoConstraints = false + + return stackView + } + + @objc func tappedValidCard() { + getRewards(for: "371260714673002") + } + + @objc func tappedInsufficientPointsCard() { + getRewards(for: "371544868764018") + } + + @objc func tappedIneligibleCard() { + getRewards(for: "378267515471109") + } + + private func getRewards(for cardNumber: String) { + let card = BTCard() + card.number = cardNumber + card.expirationMonth = "12" + card.expirationYear = generateFutureYear() + card.cvv = "1234" + + progressBlock("Tokenizing Card") + + cardClient.tokenize(card) { tokenizedCard, error in + guard let tokenizedCard else { + self.progressBlock(error?.localizedDescription) + return + } + + self.progressBlock("Amex - getting rewards balance") + + self.amexClient.getRewardsBalance(forNonce: tokenizedCard.nonce, currencyISOCode: "USD") { rewardsBalance, error in + guard let rewardsBalance else { + self.progressBlock(error?.localizedDescription) + return + } + + if let errorCode = rewardsBalance.errorCode, let errorMessage = rewardsBalance.errorMessage { + self.progressBlock("\(errorCode): \(errorMessage)") + } else if let rewardsAmount = rewardsBalance.rewardsAmount, + let rewardsUnit = rewardsBalance.rewardsUnit, + let currencyAmount = rewardsBalance.currencyAmount, + let currencyIsoCode = rewardsBalance.currencyIsoCode { + self.progressBlock("\(rewardsAmount) \(rewardsUnit), \(currencyAmount) \(currencyIsoCode)") + } + } + } + } + + private func generateFutureYear() -> String { + let dateFormatter = DateFormatter() + dateFormatter.dateFormat = "yy" + + let futureYear = Calendar.current.date(byAdding: .year, value: 3, to: Date())! + return dateFormatter.string(from: futureYear) + } + + // TODO: move this helper into BraintreeDemoPaymentButtonBaseViewController once converted so all buttons share the same characteristics + private func createButton(title: String, action: Selector) -> UIButton { + let button = UIButton(type: .system) + button.setTitle(title, for: .normal) + button.setTitleColor(.blue, for: .normal) + button.setTitleColor(.lightGray, for: .highlighted) + button.setTitleColor(.lightGray, for: .disabled) + button.translatesAutoresizingMaskIntoConstraints = false + button.addTarget(self, action: action, for: .touchUpInside) + return button + } +} diff --git a/Demo/Application/Features/Apple Pay - PassKit/BraintreeDemoApplePayPassKitViewController.h b/Demo/Application/Features/Apple Pay - PassKit/BraintreeDemoApplePayPassKitViewController.h deleted file mode 100644 index 74dc2ad065..0000000000 --- a/Demo/Application/Features/Apple Pay - PassKit/BraintreeDemoApplePayPassKitViewController.h +++ /dev/null @@ -1,6 +0,0 @@ -#import - -#import "BraintreeDemoPaymentButtonBaseViewController.h" - -@interface BraintreeDemoApplePayPassKitViewController : BraintreeDemoPaymentButtonBaseViewController -@end diff --git a/Demo/Application/Features/Apple Pay - PassKit/BraintreeDemoApplePayPassKitViewController.m b/Demo/Application/Features/Apple Pay - PassKit/BraintreeDemoApplePayPassKitViewController.m deleted file mode 100644 index b123ff88fa..0000000000 --- a/Demo/Application/Features/Apple Pay - PassKit/BraintreeDemoApplePayPassKitViewController.m +++ /dev/null @@ -1,136 +0,0 @@ -#import "BraintreeDemoApplePayPassKitViewController.h" -@import BraintreeApplePay; -@import PassKit; - -@interface BraintreeDemoApplePayPassKitViewController () - -@property (nonatomic, strong) UILabel *label; -@property (nonatomic, strong) BTApplePayClient *applePayClient; - -@end - -@implementation BraintreeDemoApplePayPassKitViewController - -- (void)viewDidLoad { - [super viewDidLoad]; - - self.applePayClient = [[BTApplePayClient alloc] initWithAPIClient:self.apiClient]; - - self.label = [[UILabel alloc] init]; - self.label.translatesAutoresizingMaskIntoConstraints = NO; - self.label.numberOfLines = 1; - self.label.textAlignment = NSTextAlignmentCenter; - [self.view addSubview:self.label]; - - if (self.paymentButton) { - [NSLayoutConstraint activateConstraints:@[ - [self.paymentButton.leadingAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.leadingAnchor constant:20.0], - [self.paymentButton.trailingAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.trailingAnchor constant:-20.0], - [self.label.topAnchor constraintEqualToSystemSpacingBelowAnchor:self.paymentButton.bottomAnchor multiplier:1.0], - [self.label.leadingAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.leadingAnchor], - [self.label.trailingAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.trailingAnchor] - ]]; - } - - self.title = NSLocalizedString(@"Apple Pay via PassKit", nil); -} - -- (UIControl *)createPaymentButton { - if (![PKPaymentAuthorizationViewController canMakePayments]) { - self.progressBlock(@"canMakePayments returns NO, hiding Apple Pay button"); - return nil; - } - - UIButton *button = [PKPaymentButton buttonWithType:PKPaymentButtonTypePlain style:PKPaymentButtonStyleAutomatic]; - [button addTarget:self action:@selector(tappedApplePayButton) forControlEvents:UIControlEventTouchUpInside]; - return button; -} - -- (void)tappedApplePayButton { - self.progressBlock(@"Constructing PKPaymentRequest"); - - [self.applePayClient makePaymentRequest:^(PKPaymentRequest * _Nullable paymentRequest, NSError * _Nullable error) { - if (error) { - self.progressBlock(error.localizedDescription); - return; - } - - // Requiring PKAddressFieldPostalAddress crashes Simulator - //paymentRequest.requiredBillingAddressFields = PKAddressFieldName|PKAddressFieldPostalAddress; - paymentRequest.requiredBillingContactFields = [NSSet setWithObjects:PKContactFieldName, nil]; - - PKShippingMethod *shippingMethod1 = [PKShippingMethod summaryItemWithLabel:@"✈️ Fast Shipping" amount:[NSDecimalNumber decimalNumberWithString:@"4.99"]]; - shippingMethod1.detail = @"Fast but expensive"; - shippingMethod1.identifier = @"fast"; - PKShippingMethod *shippingMethod2 = [PKShippingMethod summaryItemWithLabel:@"🐢 Slow Shipping" amount:[NSDecimalNumber decimalNumberWithString:@"0.00"]]; - shippingMethod2.detail = @"Slow but free"; - shippingMethod2.identifier = @"slow"; - PKShippingMethod *shippingMethod3 = [PKShippingMethod summaryItemWithLabel:@"💣 Unavailable Shipping" amount:[NSDecimalNumber decimalNumberWithString:@"0xdeadbeef"]]; - shippingMethod3.detail = @"It will make Apple Pay fail"; - shippingMethod3.identifier = @"fail"; - paymentRequest.shippingMethods = @[shippingMethod1, shippingMethod2, shippingMethod3]; - paymentRequest.requiredShippingContactFields = [NSSet setWithObjects:PKContactFieldName, PKContactFieldPhoneNumber, PKContactFieldEmailAddress, nil]; - paymentRequest.paymentSummaryItems = @[ - [PKPaymentSummaryItem summaryItemWithLabel:@"SOME ITEM" amount:[NSDecimalNumber decimalNumberWithString:@"10"]], - [PKPaymentSummaryItem summaryItemWithLabel:@"SHIPPING" amount:shippingMethod1.amount], - [PKPaymentSummaryItem summaryItemWithLabel:@"BRAINTREE" amount:[NSDecimalNumber decimalNumberWithString:@"14.99"]] - ]; - - paymentRequest.merchantCapabilities = PKMerchantCapability3DS; - if ([paymentRequest respondsToSelector:@selector(setShippingType:)]) { - paymentRequest.shippingType = PKShippingTypeDelivery; - } - - PKPaymentAuthorizationViewController *viewController = [[PKPaymentAuthorizationViewController alloc] initWithPaymentRequest:paymentRequest]; - viewController.delegate = self; - - self.progressBlock(@"Presenting Apple Pay Sheet"); - [self presentViewController:viewController animated:YES completion:nil]; - }]; -} - - -#pragma mark PKPaymentAuthorizationViewControllerDelegate - -- (void)paymentAuthorizationViewControllerDidFinish:(__unused PKPaymentAuthorizationViewController *)controller { - [controller dismissViewControllerAnimated:YES completion:nil]; -} - -- (void)paymentAuthorizationViewController:(__unused PKPaymentAuthorizationViewController *)controller - didAuthorizePayment:(PKPayment *)payment - handler:(void (^)(PKPaymentAuthorizationResult * _Nonnull))completion { - self.progressBlock(@"Apple Pay Did Authorize Payment"); - [self.applePayClient tokenizeApplePayPayment:payment completion:^(BTApplePayCardNonce * _Nullable tokenizedApplePayPayment, NSError * _Nullable error) { - if (error) { - self.progressBlock(error.localizedDescription); - completion([[PKPaymentAuthorizationResult alloc] initWithStatus:PKPaymentAuthorizationStatusFailure errors:nil]); - } else { - self.label.text = tokenizedApplePayPayment.nonce; - self.completionBlock(tokenizedApplePayPayment); - completion([[PKPaymentAuthorizationResult alloc] initWithStatus:PKPaymentAuthorizationStatusSuccess errors:nil]); - } - }]; -} - -- (void)paymentAuthorizationViewController:(PKPaymentAuthorizationViewController *)controller - didSelectShippingMethod:(PKShippingMethod *)shippingMethod - handler:(void (^)(PKPaymentRequestShippingMethodUpdate * _Nonnull))completion { - PKPaymentSummaryItem *testItem = [PKPaymentSummaryItem summaryItemWithLabel:@"SOME ITEM" - amount:[NSDecimalNumber decimalNumberWithString:@"10"]]; - PKPaymentRequestShippingMethodUpdate *update = [[PKPaymentRequestShippingMethodUpdate alloc] initWithPaymentSummaryItems:@[testItem]]; - - if ([shippingMethod.identifier isEqualToString:@"fast"]) { - completion(update); - } else if ([shippingMethod.identifier isEqualToString:@"fail"]) { - update.status = PKPaymentAuthorizationStatusFailure; - completion(update); - } else { - completion(update); - } -} - -- (void)paymentAuthorizationViewControllerWillAuthorizePayment:(__unused PKPaymentAuthorizationViewController *)controller { - self.progressBlock(@"Apple Pay will Authorize Payment"); -} - -@end diff --git a/Demo/Application/Features/Apple Pay - PassKit/BraintreeDemoApplePayViewController.swift b/Demo/Application/Features/Apple Pay - PassKit/BraintreeDemoApplePayViewController.swift new file mode 100644 index 0000000000..a30c24c6fe --- /dev/null +++ b/Demo/Application/Features/Apple Pay - PassKit/BraintreeDemoApplePayViewController.swift @@ -0,0 +1,119 @@ +import Foundation +import BraintreeApplePay +import PassKit + +class BraintreeDemoApplePayPassKitViewController: BraintreeDemoPaymentButtonBaseViewController { + + lazy var applePayClient = BTApplePayClient(apiClient: apiClient) + + override func viewDidLoad() { + super.viewDidLoad() + + title = "Apple Pay" + } + + override func createPaymentButton() -> UIView! { + if !PKPaymentAuthorizationViewController.canMakePayments() { + progressBlock("canMakePayments returned false, hiding Apple Pay button") + return nil + } + + let applePayButton = PKPaymentButton(paymentButtonType: .plain, paymentButtonStyle: .automatic) + applePayButton.addTarget(self, action: #selector(tappedApplePayButton), for: .touchUpInside) + + return applePayButton + } + + @objc func tappedApplePayButton() { + progressBlock("Constructing PKPaymentRequest") + + applePayClient.makePaymentRequest { request, error in + guard let request else { + self.progressBlock(error?.localizedDescription) + return + } + + let paymentRequest = self.constructPaymentRequest(with: request) + let paymentAuthorizationViewController = PKPaymentAuthorizationViewController(paymentRequest: paymentRequest)! + paymentAuthorizationViewController.delegate = self + + self.progressBlock("Presenting Apple Pay Sheet") + self.present(paymentAuthorizationViewController, animated: true) + } + } + + private func constructPaymentRequest(with paymentRequest: PKPaymentRequest) -> PKPaymentRequest { + paymentRequest.requiredBillingContactFields = [PKContactField.name] + + let shippingMethod1 = PKShippingMethod(label: "✈️ Fast Shipping", amount: 4.99) + shippingMethod1.detail = "Fast but expensive" + shippingMethod1.identifier = "fast" + + let shippingMethod2 = PKShippingMethod(label: "🐢 Slow Shipping", amount: 0.00) + shippingMethod2.detail = "Slow but free" + shippingMethod2.identifier = "slow" + + let shippingMethod3 = PKShippingMethod(label: "💣 Unavailable Shipping", amount: NSDecimalNumber(string: "0xdeadbeef")) + shippingMethod3.detail = "It will make Apple Pay fail" + shippingMethod3.identifier = "fail" + + paymentRequest.shippingMethods = [shippingMethod1, shippingMethod2, shippingMethod3] + paymentRequest.requiredShippingContactFields = [PKContactField.name, PKContactField.phoneNumber, PKContactField.emailAddress] + + paymentRequest.paymentSummaryItems = [ + PKPaymentSummaryItem(label: "SOME ITEM", amount: 10), + PKPaymentSummaryItem(label: "SHIPPING", amount: shippingMethod1.amount), + PKPaymentSummaryItem(label: "BRAINTREE", amount: 14.99) + ] + + paymentRequest.merchantCapabilities = .capability3DS + return paymentRequest + } +} + +// MARK: - PKPaymentAuthorizationViewControllerDelegate Conformance + +extension BraintreeDemoApplePayPassKitViewController: PKPaymentAuthorizationViewControllerDelegate { + + func paymentAuthorizationViewControllerDidFinish(_ controller: PKPaymentAuthorizationViewController) { + controller.dismiss(animated: true) + } + + func paymentAuthorizationViewController( + _ controller: PKPaymentAuthorizationViewController, + didAuthorizePayment payment: PKPayment, + handler completion: @escaping (PKPaymentAuthorizationResult) -> Void + ) { + progressBlock("Apple Pay did authorize payment") + + applePayClient.tokenize(payment) { tokenizedApplePayPayment, error in + guard let tokenizedApplePayPayment else { + self.progressBlock(error?.localizedDescription) + completion(PKPaymentAuthorizationResult(status: .failure, errors: nil)) + return + } + + self.completionBlock(tokenizedApplePayPayment) + completion(PKPaymentAuthorizationResult(status: .success, errors: nil)) + } + } + + func paymentAuthorizationViewController( + _ controller: PKPaymentAuthorizationViewController, + didSelect shippingMethod: PKShippingMethod, + handler completion: @escaping (PKPaymentRequestShippingMethodUpdate) -> Void + ) { + let testItem = PKPaymentSummaryItem(label: "SOME ITEM", amount: 10) + let shippingMethodUpdate = PKPaymentRequestShippingMethodUpdate(paymentSummaryItems: [testItem]) + + if shippingMethod.identifier == "fail" { + shippingMethodUpdate.status = .failure + } + + completion(shippingMethodUpdate) + } + + func paymentAuthorizationViewControllerWillAuthorizePayment(_ controller: PKPaymentAuthorizationViewController) { + progressBlock("Apple Pay will authorize payment") + } +} diff --git a/Demo/Demo.xcodeproj/project.pbxproj b/Demo/Demo.xcodeproj/project.pbxproj index 56419082af..60d73612ff 100644 --- a/Demo/Demo.xcodeproj/project.pbxproj +++ b/Demo/Demo.xcodeproj/project.pbxproj @@ -55,8 +55,6 @@ A0988FE324DB44B20095EEEE /* Main.strings in Resources */ = {isa = PBXBuildFile; fileRef = A0988F5224DB44B10095EEEE /* Main.strings */; }; A0988FE424DB44B20095EEEE /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = A0988F5424DB44B10095EEEE /* InfoPlist.strings */; }; A0988FE624DB44B20095EEEE /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = A0988F5824DB44B10095EEEE /* main.m */; }; - A0988FF024DB44B20095EEEE /* BraintreeDemoApplePayPassKitViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = A0988F7424DB44B10095EEEE /* BraintreeDemoApplePayPassKitViewController.m */; }; - A0988FF424DB44B20095EEEE /* BraintreeDemoAmexViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = A0988F7F24DB44B10095EEEE /* BraintreeDemoAmexViewController.m */; }; A0988FF924DB44B20095EEEE /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = A0988F8D24DB44B10095EEEE /* Images.xcassets */; }; A0988FFA24DB44B20095EEEE /* BraintreeDemoMerchantAPIClient.swift in Sources */ = {isa = PBXBuildFile; fileRef = A0988F9024DB44B20095EEEE /* BraintreeDemoMerchantAPIClient.swift */; }; A9C4E07924EC28F7002F6FF2 /* PayPal_Checkout_UITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = A9C4E07824EC28F7002F6FF2 /* PayPal_Checkout_UITests.swift */; }; @@ -74,6 +72,8 @@ BEAAAA342A98E5E6001ECA63 /* BraintreeDemoIdealViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BEAAAA332A98E5E6001ECA63 /* BraintreeDemoIdealViewController.swift */; }; BEAAAD052970A70D000BD296 /* BTSEPADirectDebitTestHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = BEAAAD042970A70D000BD296 /* BTSEPADirectDebitTestHelper.swift */; }; BEBD52872AABA513005D6687 /* BraintreeDemoThreeDSecurePaymentFlowViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BEBD52862AABA513005D6687 /* BraintreeDemoThreeDSecurePaymentFlowViewController.swift */; }; + BEBD52852AAB9649005D6687 /* BraintreeDemoAmexViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BEBD52842AAB9649005D6687 /* BraintreeDemoAmexViewController.swift */; }; + BEBD52832AAB62FB005D6687 /* BraintreeDemoApplePayViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BEBD52822AAB62FB005D6687 /* BraintreeDemoApplePayViewController.swift */; }; BEE930492A98FE9200C85779 /* BraintreeDemoBTDataCollectorViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BEE930482A98FE9200C85779 /* BraintreeDemoBTDataCollectorViewController.swift */; }; BEE9304B2A992F6200C85779 /* BraintreeDemoCardTokenizationViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BEE9304A2A992F6200C85779 /* BraintreeDemoCardTokenizationViewController.swift */; }; /* End PBXBuildFile section */ @@ -176,10 +176,6 @@ A0988F5624DB44B10095EEEE /* Braintree-Demo-Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "Braintree-Demo-Prefix.pch"; sourceTree = ""; }; A0988F5724DB44B10095EEEE /* Braintree-Demo-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "Braintree-Demo-Info.plist"; sourceTree = ""; }; A0988F5824DB44B10095EEEE /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; - A0988F7324DB44B10095EEEE /* BraintreeDemoApplePayPassKitViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BraintreeDemoApplePayPassKitViewController.h; sourceTree = ""; }; - A0988F7424DB44B10095EEEE /* BraintreeDemoApplePayPassKitViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BraintreeDemoApplePayPassKitViewController.m; sourceTree = ""; }; - A0988F7F24DB44B10095EEEE /* BraintreeDemoAmexViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BraintreeDemoAmexViewController.m; sourceTree = ""; }; - A0988F8024DB44B10095EEEE /* BraintreeDemoAmexViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BraintreeDemoAmexViewController.h; sourceTree = ""; }; A0988F8D24DB44B10095EEEE /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; A0988F8E24DB44B10095EEEE /* Braintree-Demo.entitlements */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.entitlements; path = "Braintree-Demo.entitlements"; sourceTree = ""; }; A0988F9024DB44B20095EEEE /* BraintreeDemoMerchantAPIClient.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BraintreeDemoMerchantAPIClient.swift; sourceTree = ""; }; @@ -199,6 +195,8 @@ BEAAAA332A98E5E6001ECA63 /* BraintreeDemoIdealViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BraintreeDemoIdealViewController.swift; sourceTree = ""; }; BEAAAD042970A70D000BD296 /* BTSEPADirectDebitTestHelper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BTSEPADirectDebitTestHelper.swift; sourceTree = ""; }; BEBD52862AABA513005D6687 /* BraintreeDemoThreeDSecurePaymentFlowViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BraintreeDemoThreeDSecurePaymentFlowViewController.swift; sourceTree = ""; }; + BEBD52842AAB9649005D6687 /* BraintreeDemoAmexViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BraintreeDemoAmexViewController.swift; sourceTree = ""; }; + BEBD52822AAB62FB005D6687 /* BraintreeDemoApplePayViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BraintreeDemoApplePayViewController.swift; sourceTree = ""; }; BEE930482A98FE9200C85779 /* BraintreeDemoBTDataCollectorViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BraintreeDemoBTDataCollectorViewController.swift; sourceTree = ""; }; BEE9304A2A992F6200C85779 /* BraintreeDemoCardTokenizationViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BraintreeDemoCardTokenizationViewController.swift; sourceTree = ""; }; C8E5BAD1DA81AAD310B19786 /* Pods-Demo.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Demo.release.xcconfig"; path = "Target Support Files/Pods-Demo/Pods-Demo.release.xcconfig"; sourceTree = ""; }; @@ -436,8 +434,7 @@ A0988F7224DB44B10095EEEE /* Apple Pay - PassKit */ = { isa = PBXGroup; children = ( - A0988F7324DB44B10095EEEE /* BraintreeDemoApplePayPassKitViewController.h */, - A0988F7424DB44B10095EEEE /* BraintreeDemoApplePayPassKitViewController.m */, + BEBD52822AAB62FB005D6687 /* BraintreeDemoApplePayViewController.swift */, ); path = "Apple Pay - PassKit"; sourceTree = ""; @@ -461,8 +458,7 @@ A0988F7E24DB44B10095EEEE /* Amex */ = { isa = PBXGroup; children = ( - A0988F8024DB44B10095EEEE /* BraintreeDemoAmexViewController.h */, - A0988F7F24DB44B10095EEEE /* BraintreeDemoAmexViewController.m */, + BEBD52842AAB9649005D6687 /* BraintreeDemoAmexViewController.swift */, ); path = Amex; sourceTree = ""; @@ -794,7 +790,7 @@ 803FB9DE26D93146002BF92D /* BTCardFormView.swift in Sources */, A0988FFA24DB44B20095EEEE /* BraintreeDemoMerchantAPIClient.swift in Sources */, BE777AC427D9370400487D23 /* BraintreeDemoSEPADirectDebitViewController.swift in Sources */, - A0988FF424DB44B20095EEEE /* BraintreeDemoAmexViewController.m in Sources */, + BEBD52852AAB9649005D6687 /* BraintreeDemoAmexViewController.swift in Sources */, A0988FE624DB44B20095EEEE /* main.m in Sources */, A0988F9724DB44B20095EEEE /* BraintreeDemoContainmentViewController.m in Sources */, BEE9304B2A992F6200C85779 /* BraintreeDemoCardTokenizationViewController.swift in Sources */, @@ -805,9 +801,9 @@ BEE930492A98FE9200C85779 /* BraintreeDemoBTDataCollectorViewController.swift in Sources */, A0988F9624DB44B20095EEEE /* BraintreeDemoAppDelegate.m in Sources */, BEAAAD052970A70D000BD296 /* BTSEPADirectDebitTestHelper.swift in Sources */, - A0988FF024DB44B20095EEEE /* BraintreeDemoApplePayPassKitViewController.m in Sources */, 57108A152832E789004EB870 /* BraintreeDemoPayPalNativeCheckoutViewController.swift in Sources */, BE4F788E27EE394600FF4C0E /* BraintreeDemoPayPalCheckoutViewController.swift in Sources */, + BEBD52832AAB62FB005D6687 /* BraintreeDemoApplePayViewController.swift in Sources */, A0988F9224DB44B20095EEEE /* BraintreeDemoSettings.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0;