Commit 72efbbbc by houweibin

1,干掉apple pay相关文件

parent fb012972
//
// BUYApplePayTestToken.h
// Mobile Buy SDK
//
// Created by Shopify.
// Copyright (c) 2015 Shopify Inc. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
#import <Foundation/Foundation.h>
#import <PassKit/PassKit.h>
static NSString * const BUYTestingToken = @"7fc9b0e9-ed1c-4d77-9bac-78c904aa03c1";
@interface BUYApplePayTestToken : PKPaymentToken
+ (instancetype)validToken;
+ (instancetype)invalidToken;
@end
//
// BUYApplePayTestToken.m
// Mobile Buy SDK
//
// Created by Shopify.
// Copyright (c) 2015 Shopify Inc. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
#import "BUYApplePayTestToken.h"
@interface BUYApplePayTestToken ()
@property (strong, nonatomic) NSData *testData;
@end
@implementation BUYApplePayTestToken
+ (instancetype)validToken {
BUYApplePayTestToken *token = [BUYApplePayTestToken new];
token.testData = [BUYTestingToken dataUsingEncoding:NSUTF8StringEncoding];
return token;
}
+ (instancetype)invalidToken {
return [BUYApplePayTestToken new];
}
- (NSData *)paymentData {
return _testData;
}
@end
//
// BUYApplePayTokenTests.m
// Mobile Buy SDK
//
// Created by Shopify.
// Copyright (c) 2015 Shopify Inc. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
#import <XCTest/XCTest.h>
#import <PassKit/PassKit.h>
#import "BUYApplePayToken.h"
#import "BUYApplePayTestToken.h"
@interface BUYApplePayToken (Private)
- (NSString *)paymentTokenString;
@end
@interface BUYApplePayTokenTests : XCTestCase
@end
@implementation BUYApplePayTokenTests
- (void)testInitWithValidSessionID {
BUYApplePayToken *token = [[BUYApplePayToken alloc] initWithPaymentToken:[BUYApplePayTestToken validToken]];
XCTAssertNotNil(token);
XCTAssertEqualObjects(BUYTestingToken, [token paymentTokenString]);
}
- (void)testInitWithInvalidSessionID {
XCTAssertThrows([[BUYApplePayToken alloc] initWithPaymentToken:nil]);
XCTAssertThrows([[BUYApplePayToken alloc] initWithPaymentToken:[BUYApplePayTestToken invalidToken]]);
}
- (void)testJSONConversion {
BUYApplePayToken *token = [[BUYApplePayToken alloc] initWithPaymentToken:[BUYApplePayTestToken validToken]];
NSDictionary *json = @{
@"payment_token" : @{
@"type" : @"apple_pay",
@"payment_data" : BUYTestingToken,
},
};
XCTAssertEqualObjects(token.JSONDictionary, json);
}
@end
......@@ -34,8 +34,6 @@
#import "BUYAccountCredentials.h"
#import "BUYClient+Customers.h"
#import "BUYClient+Internal.h"
#import "BUYApplePayToken.h"
#import "BUYApplePayTestToken.h"
#import "BUYRequestOperation.h"
@interface BUYClient_Test : BUYClient
......
//
// BUYPKContact.h
// Mobile Buy SDK
//
// Created by Shopify.
// Copyright (c) 2015 Shopify Inc. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
@import PassKit;
/**
* In order to create a custom PKContact to use in tests, we need to override this
*/
@interface BUYPKContact : PKContact
@end
//
// BUYPKContact.m
// Mobile Buy SDK
//
// Created by Shopify.
// Copyright (c) 2015 Shopify Inc. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
#import "BUYPKContact.h"
#import "BUYNSPersonNameComponents.h"
#import "BUYCNPostalAddress.h"
@interface BUYPKContact () {
BUYNSPersonNameComponents *_name;
BUYCNPostalAddress *_postalAddress;
CNPhoneNumber *_phoneNumber;
}
@end
@implementation BUYPKContact
- (void)setName:(BUYNSPersonNameComponents *)name
{
_name = name;
}
-(NSPersonNameComponents *)name
{
return _name;
}
- (void)setPostalAddress:(BUYCNPostalAddress *)postalAddress
{
_postalAddress = postalAddress;
}
- (CNPostalAddress *)postalAddress
{
return _postalAddress;
}
- (void)setPhoneNumber:(CNPhoneNumber*)phoneNumber
{
_phoneNumber = phoneNumber;
}
- (CNPhoneNumber *)phoneNumber
{
return _phoneNumber;
}
@end
......@@ -28,7 +28,6 @@
#import <Buy/Buy.h>
#import "BUYApplePayPaymentProvider.h"
#import "BUYWebCheckoutPaymentProvider.h"
#import "BUYClientTestBase.h"
#import "BUYPaymentController.h"
......@@ -107,74 +106,6 @@ extern Class SafariViewControllerClass;
}
#pragma mark - Apple Pay
- (void)testAppleAvailability
{
BUYApplePayPaymentProvider *applePay = [[BUYApplePayPaymentProvider alloc] initWithClient:self.client merchantID:@"merchant.id.1"];
XCTAssertTrue(applePay.isAvailable);
BUYApplePayPaymentProvider *applePay2 = [[BUYApplePayPaymentProvider alloc] initWithClient:self.client merchantID:@""];
XCTAssertFalse(applePay2.isAvailable);
}
- (void)testApplePayPresentationCallbacks
{
[self mockRequests];
BUYApplePayPaymentProvider *applePay = [[BUYApplePayPaymentProvider alloc] initWithClient:self.client merchantID:@"merchant.id.1"];
applePay.delegate = self;
self.expectations[@"presentController"] = [self expectationWithDescription:NSStringFromSelector(_cmd)];
[applePay startCheckout:self.checkout];
[self waitForExpectationsWithTimeout:1 handler:^(NSError *error) {
XCTAssertNil(error);
}];
}
- (void)testApplePayProvider
{
BUYApplePayPaymentProvider *applePay1 = [[BUYApplePayPaymentProvider alloc] initWithClient:self.client merchantID:@"merchant.id.1"];
XCTAssertEqualObjects(applePay1.merchantID, @"merchant.id.1");
// 4 default networks should be configured
XCTAssertEqual(applePay1.supportedNetworks.count, 4);
applePay1.supportedNetworks = @[PKPaymentNetworkMasterCard];
XCTAssertEqual(applePay1.supportedNetworks.count, 1);
XCTAssertEqualObjects(applePay1.supportedNetworks[0], PKPaymentNetworkMasterCard);
}
- (void)testCanShowApplePaySetup
{
BUYApplePayPaymentProvider *applePay = [[BUYApplePayPaymentProvider alloc] initWithClient:self.client merchantID:@"merchant.id.1"];
XCTAssertTrue(applePay.canShowApplePaySetup);
BUYApplePayPaymentProvider *applePay2 = [[BUYApplePayPaymentProvider alloc] initWithClient:self.client merchantID:@""];
XCTAssertFalse(applePay2.canShowApplePaySetup);
}
- (void)testFailedApplePayCallbacks
{
[OHHTTPStubs stubRequestsPassingTest:^BOOL(NSURLRequest * _Nonnull request) {
return YES;
} withStubResponse:^OHHTTPStubsResponse * _Nonnull(NSURLRequest * _Nonnull request) {
return [OHHTTPStubsResponse responseWithJSONObject:@{} statusCode:400 headers:nil];
}];
BUYApplePayPaymentProvider *applePay = [[BUYApplePayPaymentProvider alloc] initWithClient:self.client merchantID:@"merchant.id.1"];
applePay.delegate = self;
self.expectations[@"failedCheckout"] = [self expectationWithDescription:NSStringFromSelector(_cmd)];
self.expectations[@"failedShop"] = [self expectationWithDescription:NSStringFromSelector(_cmd)];
[applePay startCheckout:self.checkout];
[self waitForExpectationsWithTimeout:1 handler:^(NSError *error) {
XCTAssertNil(error);
}];
}
#pragma mark - Web
- (void)testWebAvailability
......@@ -201,30 +132,6 @@ extern Class SafariViewControllerClass;
#pragma mark - Payment Controller
- (void)testPaymentController
{
BUYPaymentController *controller = [[BUYPaymentController alloc] init];
BUYApplePayPaymentProvider *applePay1 = [[BUYApplePayPaymentProvider alloc] initWithClient:self.client merchantID:@"merchant.id.1"];
[controller addPaymentProvider:applePay1];
XCTAssertEqual(controller.providers.count, 1);
id <BUYPaymentProvider> provider = [controller providerForType:BUYApplePayPaymentProviderId];
XCTAssertEqualObjects(provider, applePay1);
BUYWebCheckoutPaymentProvider *webProvider = [[BUYWebCheckoutPaymentProvider alloc] initWithClient:self.client];
[controller addPaymentProvider:webProvider];
XCTAssertEqual(controller.providers.count, 2);
provider = [controller providerForType:BUYWebPaymentProviderId];
XCTAssertEqualObjects(provider, webProvider);
// Attempt to add an alternate Apple Pay provider
BUYApplePayPaymentProvider *applePay2 = [[BUYApplePayPaymentProvider alloc] initWithClient:self.client merchantID:@"merchant.id.2"];
[controller addPaymentProvider:applePay2];
XCTAssertEqual(controller.providers.count, 2);
}
- (void)testStartingPaymentWithPaymentController
{
......
......@@ -63,9 +63,6 @@
#import <Buy/BUYShopifyErrorCodes.h>
// Checkout support
#import <Buy/BUYApplePayAdditions.h>
#import <Buy/BUYApplePayAuthorizationDelegate.h>
#import <Buy/BUYApplePayPaymentProvider.h>
#import <Buy/BUYPaymentController.h>
#import <Buy/BUYPaymentProvider.h>
#import <Buy/BUYWebCheckoutPaymentProvider.h>
......
//
// BUYApplePayToken.h
// Mobile Buy SDK
//
// Created by Shopify.
// Copyright (c) 2015 Shopify Inc. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
#import <Foundation/Foundation.h>
#import <Buy/BUYPaymentToken.h>
@class PKPaymentToken;
@interface BUYApplePayToken : NSObject <BUYPaymentToken>
@property (nonatomic, strong, readonly) PKPaymentToken *paymentToken;
- (instancetype)initWithPaymentToken:(PKPaymentToken *)paymentToken;
@end
//
// BUYApplePayToken.m
// Mobile Buy SDK
//
// Created by Shopify.
// Copyright (c) 2015 Shopify Inc. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
#if __has_include(<PassKit/PassKit.h>)
#import <PassKit/PassKit.h>
#endif
#import "BUYAssert.h"
#import "BUYApplePayToken.h"
@implementation BUYApplePayToken
#pragma mark - Init -
- (instancetype)initWithPaymentToken:(PKPaymentToken *)paymentToken
{
BUYAssert(paymentToken.paymentData.length > 0, @"Failed to initialize BUYApplePayToken. Invalid or nil paymentToken.");
self = [super init];
if (self) {
_paymentToken = paymentToken;
}
return self;
}
- (NSString *)paymentTokenString {
return [[NSString alloc] initWithData:self.paymentToken.paymentData encoding:NSUTF8StringEncoding];
}
#pragma mark - BUYPaymentToken -
- (NSDictionary *)JSONDictionary
{
return @{
@"payment_token" : @{
@"type" : @"apple_pay",
@"payment_data" : [self paymentTokenString],
},
};
}
@end
......@@ -32,7 +32,6 @@ NS_ASSUME_NONNULL_BEGIN
/**
* Check if the address does not include first and last name
* and address1 field. This is used to determine whether a
* placeholder was set for shipping rates calculations in Apple Pay.
*
* @return True if first name, last name or address1 contain placeholders
*/
......
//
// BUYApplePayPaymentProvider.h
// Mobile Buy SDK
//
// Created by Shopify.
// Copyright (c) 2015 Shopify Inc. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
@import UIKit;
#import <Buy/BUYPaymentProvider.h>
NS_ASSUME_NONNULL_BEGIN
extern NSString *const BUYApplePayPaymentProviderId;
@class BUYClient;
@interface BUYApplePayPaymentProvider : NSObject <BUYPaymentProvider>
/**
* Initializer for Apple Pay payment provider
*
* @param client a `BUYClient`
* @param merchantID the merchant ID for Apple Pay
*
* @return an instance of `BUYApplePayPaymentProvider`
*/
- (instancetype)initWithClient:(BUYClient *)client merchantID:(NSString *)merchantID NS_DESIGNATED_INITIALIZER;
- (instancetype)init NS_UNAVAILABLE;
/**
* The supported credit card payment networks. Default values:
* iOS 8.3: PKPaymentNetworkAmex, PKPaymentNetworkMasterCard, PKPaymentNetworkVisa.
* iOS 9.0: PKPaymentNetworkAmex, PKPaymentNetworkDiscover, PKPaymentNetworkMasterCard, PKPaymentNetworkVisa.
*/
@property (nonatomic, copy) NSArray * supportedNetworks;
/**
* The merchant ID required for Apple Pay
*/
@property (nonatomic, copy, readonly) NSString * merchantID;
/**
* If the merchantId is set and the device support Apple Pay but no credit card is present this allows the user to add a payment pass to the Wallet.
* The user is given the option to add a payment pass or continue with web checkout. Default is set to true. The Set Up Apple Pay button will, however
* still only show if [PKAddPaymentPassViewController canAddPaymentPass] returns true, merchantId is set and the app is running iOS 9.0 and above.
*/
@property (nonatomic, assign) BOOL allowApplePaySetup;
/**
* Whether the device is setup to show the Apple Pay setup sheet.
* `allowApplePaySetup` must be set to YES, and the `merchantId` must also be set in addition to the
* device settings for this method to return YES.
*
* @return YES if the Setup Apple Pay button should be shown
*/
- (BOOL)canShowApplePaySetup;
@end
NS_ASSUME_NONNULL_END
//
// BUYApplePayAdditions.h
// Mobile Buy SDK
//
// Created by Shopify.
// Copyright (c) 2015 Shopify Inc. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
@import Foundation;
@import PassKit;
#import <Buy/BUYCheckout.h>
#import <Buy/BUYShippingRate.h>
#import <Buy/BUYAddress.h>
NS_ASSUME_NONNULL_BEGIN
@interface BUYCheckout (ApplePay)
/**
* Returns an array of summary items for all Apple Pay requests. Will use 'PAY TOTAL' as the summary label. Apple recommends
* including the business name in the summary label, so it is recommended to use `buy_summaryItemsWithShopName` instead.
*/
- (NSArray<PKPaymentSummaryItem *> *)buy_summaryItems;
/**
* Returns an array of summary items for all Apple Pay requests using the shop name in the "PAY" section
*
* @param shopName the shops name
*
* @return An array of PKPaymentSummaryItems
*/
- (NSArray<PKPaymentSummaryItem *> *)buy_summaryItemsWithShopName:(nullable NSString *)shopName;
@end
@interface BUYShippingRate (ApplePay)
/**
* Returns an array of `PKShippingMethod` objects, based on Shopify's shipping rates.
*
* @param rates Shipping rates
*
* @return An array of PKShippingMethods
*/
+ (NSArray<PKShippingMethod *> *)buy_convertShippingRatesToShippingMethods:(NSArray<BUYShippingRate *> *)rates;
@end
@interface BUYAddress (ApplePay)
+ (nullable NSString *)buy_emailFromRecord:(nullable ABRecordRef)record NS_DEPRECATED_IOS(8_0, 9_0, "Use the `emailAddress` from the PKContact object instead");
- (void)updateWithRecord:(nullable ABRecordRef)record NS_DEPRECATED_IOS(8_0, 9_0, "Use the CNContact backed `updateWithContact:` instead");
- (void)updateWithContact:(nullable PKContact*)contact NS_AVAILABLE_IOS(9_0);
@end
NS_ASSUME_NONNULL_END
//
// BUYApplePayAdditions.m
// Mobile Buy SDK
//
// Created by Shopify.
// Copyright (c) 2015 Shopify Inc. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
@import AddressBook;
@import PassKit;
#import "BUYLineItem.h"
#import "BUYGiftCard.h"
#import "BUYApplePayAdditions.h"
#import "BUYDiscount.h"
#import "NSDecimalNumber+BUYAdditions.h"
#import "NSDate+BUYAdditions.h"
#define CFSafeRelease(obj) if (obj) { CFRelease(obj); }
@implementation BUYCheckout (ApplePay)
- (nonnull NSArray<PKPaymentSummaryItem *> *)buy_summaryItemsWithShopName:(nullable NSString *)shopName {
BOOL hasDiscount = [self.discount.amount compare:[NSDecimalNumber zero]] == NSOrderedDescending;
NSMutableArray<PKPaymentSummaryItem *> *summaryItems = [[NSMutableArray alloc] init];
if (hasDiscount || [self.lineItems count] > 1) {
NSDecimalNumber *lineItemSubtotal = [NSDecimalNumber zero];
for (BUYLineItem *lineItem in self.lineItems) {
lineItemSubtotal = [lineItemSubtotal decimalNumberByAdding:lineItem.linePrice];
}
[summaryItems addObject:[PKPaymentSummaryItem summaryItemWithLabel:@"CART TOTAL" amount:lineItemSubtotal]];
}
if (hasDiscount) {
NSString *discountLabel = [self.discount.code length] > 0 ? [NSString stringWithFormat:@"DISCOUNT (%@)", self.discount.code] : @"DISCOUNT";
[summaryItems addObject:[PKPaymentSummaryItem summaryItemWithLabel:discountLabel amount:[self.discount.amount buy_decimalNumberAsNegative]]];
}
[summaryItems addObject:[PKPaymentSummaryItem summaryItemWithLabel:@"SUBTOTAL" amount:self.subtotalPrice ?: [NSDecimalNumber zero]]];
if ([self.shippingRate.price compare:[NSDecimalNumber zero]] == NSOrderedDescending) {
[summaryItems addObject:[PKPaymentSummaryItem summaryItemWithLabel:@"SHIPPING" amount:self.shippingRate.price]];
}
if ([self.totalTax compare:[NSDecimalNumber zero]] == NSOrderedDescending) {
[summaryItems addObject:[PKPaymentSummaryItem summaryItemWithLabel:@"TAXES" amount:self.totalTax]];
}
if ([self.giftCards count] > 0) {
for (BUYGiftCard *giftCard in self.giftCards) {
NSString *giftCardLabel = [giftCard.lastCharacters length] > 0 ? [NSString stringWithFormat:@"GIFT CARD (•••• %@)", giftCard.lastCharacters] : @"GIFT CARD";
[summaryItems addObject:[PKPaymentSummaryItem summaryItemWithLabel:giftCardLabel amount:giftCard.amountUsed ? [giftCard.amountUsed buy_decimalNumberAsNegative] : [giftCard.balance buy_decimalNumberAsNegative]]];
}
}
NSString *itemLabel = shopName ?: @"TOTAL";
[summaryItems addObject:[PKPaymentSummaryItem summaryItemWithLabel:itemLabel amount:self.paymentDue ?: [NSDecimalNumber zero]]];
return summaryItems;
}
- (nonnull NSArray<PKPaymentSummaryItem *> *)buy_summaryItems
{
return [self buy_summaryItemsWithShopName:nil];
}
@end
@implementation BUYShippingRate (ApplePay)
+ (nonnull NSArray<PKShippingMethod *> *)buy_convertShippingRatesToShippingMethods:(nonnull NSArray<BUYShippingRate *> *)rates
{
NSMutableArray<PKShippingMethod *> *shippingMethods = [[NSMutableArray alloc] init];
for (BUYShippingRate *shippingRate in rates) {
PKShippingMethod *shippingMethod = [[PKShippingMethod alloc] init];
shippingMethod.label = shippingRate.title;
shippingMethod.amount = shippingRate.price;
shippingMethod.identifier = shippingRate.shippingRateIdentifier;
if ([shippingRate.deliveryRange count]) {
NSInteger daysInBetweenFirst = 1 + [NSDate daysBetweenDate:[NSDate date] andDate:shippingRate.deliveryRange[0]];
NSInteger daysInBetweenLast = 1 + [NSDate daysBetweenDate:[NSDate date] andDate:[shippingRate.deliveryRange lastObject]];
BOOL plural = NO;
NSString *deliveryDetailDays = @"";
if (daysInBetweenLast - daysInBetweenFirst == 0) {
plural = daysInBetweenFirst > 1;
deliveryDetailDays = [NSString stringWithFormat:@"%lu", (long)daysInBetweenFirst];
} else {
plural = YES;
deliveryDetailDays = [NSString stringWithFormat:@"%ld-%ld", (long)daysInBetweenFirst, (long)daysInBetweenLast];
}
shippingMethod.detail = [NSString stringWithFormat:@"%@ day%@", deliveryDetailDays, plural ? @"s" : @""];
} else {
shippingMethod.detail = @"";
}
[shippingMethods addObject:shippingMethod];
}
return shippingMethods;
}
@end
@implementation BUYAddress (ApplePay)
+ (nullable NSString *)buy_emailFromRecord:(nullable ABRecordRef)record
{
ABMultiValueRef emailMultiValue = ABRecordCopyValue(record, kABPersonEmailProperty);
CFArrayRef allEmails = ABMultiValueCopyArrayOfAllValues(emailMultiValue);
NSString *email = nil;
if (allEmails && CFArrayGetCount(allEmails)) {
email = (__bridge NSString *)CFArrayGetValueAtIndex(allEmails, 0);
}
CFSafeRelease(allEmails);
CFSafeRelease(emailMultiValue);
return email;
}
- (void)updateWithRecord:(nullable ABRecordRef)record
{
//Grab the simple information
self.firstName = (__bridge_transfer NSString *)ABRecordCopyValue(record, kABPersonFirstNameProperty);
self.lastName = (__bridge_transfer NSString *)ABRecordCopyValue(record, kABPersonLastNameProperty);
//Grab the address information
ABMultiValueRef addressMultiValue = ABRecordCopyValue(record, kABPersonAddressProperty);
CFArrayRef allAddresses = ABMultiValueCopyArrayOfAllValues(addressMultiValue);
if (allAddresses && CFArrayGetCount(allAddresses) > 0) {
CFDictionaryRef firstAddress = CFArrayGetValueAtIndex(allAddresses, 0);
//NOTE: We do not receive an address1 line right now via this partial address, as Apple deemds it unimportant to calculate the shipping rates. We get the actual address later on in a later step.
self.address1 = (__bridge NSString *)CFDictionaryGetValue(firstAddress, kABPersonAddressStreetKey);
self.city = (__bridge NSString *)CFDictionaryGetValue(firstAddress, kABPersonAddressCityKey);
self.province = (__bridge NSString *)CFDictionaryGetValue(firstAddress, kABPersonAddressStateKey);
self.zip = (__bridge NSString *)CFDictionaryGetValue(firstAddress, kABPersonAddressZIPKey);
// The Checkout API accepts country OR ISO country code.
// We default to the ISO country code because it's more
// reliable regardless of locale. Fallback to country if
// we do not receive it (iOS 8 sometimes)
self.countryCode = (__bridge NSString *)CFDictionaryGetValue(firstAddress, kABPersonAddressCountryCodeKey);
if ([self.countryCode length] == 0) {
self.country = (__bridge NSString *)CFDictionaryGetValue(firstAddress, kABPersonAddressCountryKey);
}
}
CFSafeRelease(allAddresses);
CFSafeRelease(addressMultiValue);
//Grab the phone number information
ABMultiValueRef phoneMultiValue = ABRecordCopyValue(record, kABPersonPhoneProperty);
CFArrayRef allPhoneNumbers = ABMultiValueCopyArrayOfAllValues(phoneMultiValue);
if (allPhoneNumbers && CFArrayGetCount(allPhoneNumbers) > 0) {
self.phone = (__bridge NSString *)CFArrayGetValueAtIndex(allPhoneNumbers, 0);
}
CFSafeRelease(phoneMultiValue);
CFSafeRelease(allPhoneNumbers);
}
- (void)updateWithContact:(nullable PKContact*)contact
{
self.firstName = contact.name.givenName;
self.lastName = contact.name.familyName;
if (contact.postalAddress) {
// break up the address:
NSArray *addressComponents = [contact.postalAddress.street componentsSeparatedByString:@"\n"];
self.address1 = addressComponents[0];
self.address2 = (addressComponents.count > 1) ? addressComponents[1] : nil;
self.city = contact.postalAddress.city;
self.province = contact.postalAddress.state;
self.zip = contact.postalAddress.postalCode;
// The Checkout API accepts country OR ISO country code.
// We default to the ISO country code because it's more
// reliable regardless of locale. Fallback to country if
// we do not receive it (iOS 8 sometimes)
self.countryCode = [contact.postalAddress.ISOCountryCode length] ? contact.postalAddress.ISOCountryCode : nil;
if (self.countryCode == nil) {
self.country = contact.postalAddress.country;
}
}
self.phone = contact.phoneNumber.stringValue;
}
@end
//
// BUYApplePayAuthorizationDelegate.h
// Mobile Buy SDK
//
// Created by Shopify.
// Copyright (c) 2015 Shopify Inc. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
@import Foundation;
@import PassKit;
@class BUYClient;
@class BUYCheckout;
@class BUYShop;
NS_ASSUME_NONNULL_BEGIN
@interface BUYApplePayAuthorizationDelegate : NSObject <PKPaymentAuthorizationViewControllerDelegate>
/**
* Initializes a helper to support Apple Pay
*
* @param client A configured client
* @param checkout The checkout which is to be completed using Apple Pay
* @param shop A shop object to alleviate the need for ApplePayHelper to retrieve it via the BUYClient
*
* @return helper object
*/
- (instancetype)initWithClient:(BUYClient *)client checkout:(BUYCheckout *)checkout shopName:(NSString *)shopName NS_DESIGNATED_INITIALIZER;
- (instancetype)init NS_UNAVAILABLE;
/**
* The current checkout
*/
@property (nonatomic, strong, readonly) BUYCheckout *checkout;
/**
* The client used to communicate with Shopify
*/
@property (nonatomic, strong, readonly) BUYClient *client;
/**
* The last error message
*/
@property (nonatomic, strong, readonly) NSError *lastError;
/**
* The shop name
*/
@property (nonatomic, strong, readonly) NSString *shopName;
@end
NS_ASSUME_NONNULL_END
//
// BUYApplePayAuthorizationDelegate.m
// Mobile Buy SDK
//
// Created by Shopify.
// Copyright (c) 2015 Shopify Inc. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
#import "BUYApplePayAuthorizationDelegate.h"
#import "BUYApplePayAdditions.h"
#import "BUYApplePayToken.h"
#import "BUYAssert.h"
#import "BUYClient+Checkout.h"
#import "BUYClient+Storefront.h"
#import "BUYCheckout.h"
#import "BUYError.h"
#import "BUYModelManager+ApplePay.h"
#import "BUYShop.h"
#import "BUYShopifyErrorCodes.h"
const NSTimeInterval PollDelay = 0.5;
typedef void (^AddressUpdateCompletion)(PKPaymentAuthorizationStatus, NSArray<PKShippingMethod *> * _Nonnull, NSArray<PKPaymentSummaryItem *> * _Nonnull);
@interface BUYApplePayAuthorizationDelegate ()
@property (nonatomic, strong) BUYCheckout *checkout;
@property (nonatomic, strong) NSArray *shippingRates;
@property (nonatomic, strong) NSError *lastError;
@end
@implementation BUYApplePayAuthorizationDelegate
- (instancetype)initWithClient:(BUYClient *)client checkout:(BUYCheckout *)checkout shopName:(NSString *)shopName
{
BUYAssert(client, @"Failed to initialize BUYApplePayAuthorizationDelegate. Client must not be nil.");
BUYAssert(checkout, @"Failed to initialize BUYApplePayAuthorizationDelegate. Checkout must not be nil.");
BUYAssert(shopName, @"Failed to initialize BUYApplePayAuthorizationDelegate. Shop name must not be nil.");
self = [super init];
if (self) {
_client = client;
_checkout = checkout;
_shopName = shopName;
}
return self;
}
#pragma mark - PKPaymentAuthorizationDelegate methods
- (void)paymentAuthorizationViewController:(PKPaymentAuthorizationViewController *)controller
didAuthorizePayment:(PKPayment *)payment
completion:(void (^)(PKPaymentAuthorizationStatus status))completion
{
// Update the checkout with the rest of the information. Apple has now provided us with a FULL billing address and a FULL shipping address.
// We now update the checkout with our new found data so that you can ship the products to the right address, and we collect whatever else we need.
if ([payment respondsToSelector:@selector(shippingContact)]) {
self.checkout.email = payment.shippingContact.emailAddress;
if (self.checkout.requiresShipping) {
self.checkout.shippingAddress = [self buyAddressWithContact:payment.shippingContact];
}
} else {
self.checkout.email = [BUYAddress buy_emailFromRecord:payment.shippingAddress];
if (self.checkout.requiresShipping) {
self.checkout.shippingAddress = [self buyAddressWithABRecord:payment.shippingAddress];
}
}
if ([payment respondsToSelector:@selector(billingContact)]) {
self.checkout.billingAddress = [self buyAddressWithContact:payment.billingContact];
} else {
self.checkout.billingAddress = [self buyAddressWithABRecord:payment.billingAddress];
}
[self.client updateCheckout:self.checkout completion:^(BUYCheckout *checkout, NSError *error) {
if (checkout && error == nil) {
self.checkout = checkout;
id<BUYPaymentToken> token = [[BUYApplePayToken alloc] initWithPaymentToken:payment.token];
//Now that the checkout is up to date, call complete.
[self.client completeCheckoutWithToken:checkout.token paymentToken:token completion:^(BUYCheckout *checkout, NSError *error) {
if (checkout && error == nil) {
self.checkout = checkout;
completion(PKPaymentAuthorizationStatusSuccess);
} else {
self.lastError = error;
completion(PKPaymentAuthorizationStatusFailure);
}
}];
}
else {
self.lastError = error;
completion(PKPaymentAuthorizationStatusInvalidShippingPostalAddress);
}
}];
}
- (BUYAddress *)buyAddressWithABRecord:(ABRecordRef)addressRecord
{
return [self.client.modelManager buyAddressWithABRecord:addressRecord];
}
- (BUYAddress *)buyAddressWithContact:(PKContact *)contact
{
return [self.client.modelManager buyAddressWithContact:contact];
}
- (void)paymentAuthorizationViewControllerDidFinish:(PKPaymentAuthorizationViewController *)controller
{
[controller dismissViewControllerAnimated:YES completion:nil];
}
-(void)paymentAuthorizationViewController:(PKPaymentAuthorizationViewController *)controller didSelectShippingAddress:(ABRecordRef)address completion:(AddressUpdateCompletion)completion
{
self.checkout.shippingAddress = [self buyAddressWithABRecord:address];
if ([self.checkout.shippingAddress isValidAddressForShippingRates]) {
[self updateCheckoutWithAddressCompletion:completion];
}
}
-(void)paymentAuthorizationViewController:(PKPaymentAuthorizationViewController *)controller didSelectShippingContact:(PKContact *)contact completion:(AddressUpdateCompletion)completion
{
self.checkout.shippingAddress = [self buyAddressWithContact:contact];
if ([self.checkout.shippingAddress isValidAddressForShippingRates]) {
[self updateCheckoutWithAddressCompletion:completion];
}
}
-(void)paymentAuthorizationViewController:(PKPaymentAuthorizationViewController *)controller didSelectShippingMethod:(PKShippingMethod *)shippingMethod completion:(void (^)(PKPaymentAuthorizationStatus, NSArray<PKPaymentSummaryItem *> * _Nonnull))completion
{
BUYShippingRate *shippingRate = [self rateForShippingMethod:shippingMethod];
self.checkout.shippingRate = shippingRate;
[self.client updateCheckout:self.checkout completion:^(BUYCheckout *checkout, NSError *error) {
if (checkout && error == nil) {
self.checkout = checkout;
}
else {
self.lastError = error;
}
completion(error == nil ? PKPaymentAuthorizationStatusSuccess : PKPaymentAuthorizationStatusFailure, [self.checkout buy_summaryItemsWithShopName:self.shopName]);
}];
}
#pragma mark -
- (void)updateCheckoutWithAddressCompletion:(AddressUpdateCompletion)completion
{
// This method call is internal to selection of shipping address that are returned as partial from PKPaymentAuthorizationViewController
// However, to ensure we never set partialAddresses to NO, we want to guard the setter. Should PKPaymentAuthorizationViewController ever
// return a full address through it's delegate method, this will still function since a complete address can be used to calculate shipping rates
if ([self.checkout.shippingAddress isPartialAddress] == YES) {
self.checkout.partialAddresses = @YES;
}
[self.client updateCheckout:self.checkout completion:^(BUYCheckout *checkout, NSError *error) {
if (checkout && !error) {
self.checkout = checkout;
}
else if (error) {
self.lastError = error;
}
if (checkout.requiresShipping) {
self.shippingRates = @[];
[self updateShippingRatesCompletion:completion];
}
else {
completion(PKPaymentAuthorizationStatusSuccess, @[], [self.checkout buy_summaryItemsWithShopName:self.shopName]);
}
}];
}
- (void)updateShippingRatesCompletion:(AddressUpdateCompletion)completion
{
[self.client getShippingRatesForCheckoutWithToken:self.checkout.token completion:^(NSArray *shippingRates, BUYStatus status, NSError *error) {
self.shippingRates = shippingRates;
NSArray *shippingMethods = [BUYShippingRate buy_convertShippingRatesToShippingMethods:shippingRates];
if (shippingMethods.count > 0) {
[self selectShippingMethod:shippingMethods[0] completion:^(BUYCheckout *checkout, NSError *error) {
if (checkout && !error) {
self.checkout = checkout;
}
completion(error ? PKPaymentAuthorizationStatusFailure : PKPaymentAuthorizationStatusSuccess, shippingMethods, [self.checkout buy_summaryItemsWithShopName:self.shopName]);
}];
} else {
self.lastError = [NSError errorWithDomain:BUYShopifyError code:BUYShopifyError_NoShippingMethodsToAddress userInfo:nil];
completion(PKPaymentAuthorizationStatusInvalidShippingPostalAddress, @[], [self.checkout buy_summaryItemsWithShopName:self.shopName]);
}
}];
}
#pragma mark - Internal -
- (BUYShippingRate *)rateForShippingMethod:(PKShippingMethod *)method
{
BUYShippingRate *rate = nil;
NSString *identifier = [method identifier];
for (BUYShippingRate *method in self.shippingRates) {
if ([[method shippingRateIdentifier] isEqual:identifier]) {
rate = method;
break;
}
}
return rate;
}
- (void)selectShippingMethod:(PKShippingMethod *)shippingMethod completion:(BUYDataCheckoutBlock)block
{
BUYShippingRate *shippingRate = [self rateForShippingMethod:shippingMethod];
self.checkout.shippingRate = shippingRate;
[self.client updateCheckout:self.checkout completion:block];
}
@end
//
// BUYModelManager+ApplePay.h
// Mobile Buy SDK
//
// Created by Shopify.
// Copyright (c) 2015 Shopify Inc. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
@import PassKit;
#import <Buy/BUYModelManager.h>
NS_ASSUME_NONNULL_BEGIN
@class BUYAddress;
@interface BUYModelManager (ApplePay)
/**
* Creates a BUYAddress from an ABRecordRef
*
* @param record ABRecordRef to create a BUYAddress from
*
* @return The BUYAddress created from an ABRecordRef
*/
- (BUYAddress *)buyAddressWithABRecord:(ABRecordRef)addressRecord NS_DEPRECATED_IOS(8_0, 9_0, "Use the CNContact backed `buyAddressWithContact:` instead");
/**
* Creates a BUYAddress from a PKContact
*
* @param contact PKContact to create a BUYAddress from
*
* @return The BUYAddress created from a PKContact
*/
- (BUYAddress *)buyAddressWithContact:(PKContact *)contact NS_AVAILABLE_IOS(9_0);
@end
NS_ASSUME_NONNULL_END
//
// BUYModelManager+ApplePay.m
// Mobile Buy SDK
//
// Created by Shopify.
// Copyright (c) 2015 Shopify Inc. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
#import "BUYAddress.h"
#import "BUYApplePayAdditions.h"
#import "BUYModelManager+ApplePay.h"
@implementation BUYModelManager (ApplePay)
- (BUYAddress *)buyAddressWithABRecord:(ABRecordRef)addressRecord
{
BUYAddress *address = [self insertAddressWithJSONDictionary:nil];
[address updateWithRecord:addressRecord];
return address;
}
- (BUYAddress *)buyAddressWithContact:(PKContact *)contact
{
BUYAddress *address = [self insertAddressWithJSONDictionary:nil];
[address updateWithContact:contact];
return address;
}
@end
......@@ -62,10 +62,6 @@ typedef NS_ENUM(NSUInteger, BUYCheckoutError){
*/
BUYShopifyError_NoCreditCardSpecified,
/**
* No Apple Pay token was provided when attempting to complete a checkout using Apple Pay
*/
BUYShopifyError_NoApplePayTokenSpecified,
/**
* The checkout is invalid and does not have a checkout token. This generally means the BUYCheckout object
* has not been synced with Shopify via `createCheckout:completion:` before making subsequent calls to update
* or complete the checkout
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment