Skip to content

Commit

Permalink
Merge pull request #90 from square/msilvis/api-improvements
Browse files Browse the repository at this point in the history
Move the api to more closely match the rest of Square APIs
  • Loading branch information
MikeSilvis authored Oct 15, 2020
2 parents cee6bdc + e84feff commit e6398e3
Show file tree
Hide file tree
Showing 7 changed files with 154 additions and 87 deletions.
2 changes: 1 addition & 1 deletion Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,4 @@ SPEC CHECKSUMS:

PODFILE CHECKSUM: a679ea1c4a7a65af08221a21783dd323549bd283

COCOAPODS: 1.8.4
COCOAPODS: 1.9.3
22 changes: 12 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ let callbackURL = URL(string: "<#T##Your URL Scheme##String#>://")!

// Your client ID is the same as your Square Application ID.
// Note: You only need to set your client ID once, before creating your first request.
SCCAPIRequest.setClientID(<#T##Client ID##String#>)
SCCAPIRequest.setApplicationID(<#T##Application ID##String#>)

do {
// Specify the amount of money to charge.
Expand All @@ -96,15 +96,17 @@ do {
// Create the request.
let apiRequest =
try SCCAPIRequest(
callbackURL: callbackURL,
amount: money,
userInfoString: nil,
locationID: nil,
notes: "Coffee",
customerID: nil,
supportedTenderTypes: .all,
clearsDefaultFees: false,
returnAutomaticallyAfterPayment: false
callbackURL: callbackURL,
amount: money,
userInfoString: nil,
locationID: nil,
notes: "Coffee",
customerID: nil,
supportedTenderTypes: .all,
clearsDefaultFees: false,
returnsAutomaticallyAfterPayment: false,
disablesKeyedInCardEntry: false,
skipsReceipt: false
)

// Open Point of Sale to complete the payment.
Expand Down
4 changes: 3 additions & 1 deletion SampleApp/Sources/ViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,9 @@ class ViewController: UIViewController {
customerID: nil,
supportedTenderTypes: .all,
clearsDefaultFees: false,
returnAutomaticallyAfterPayment: false
returnsAutomaticallyAfterPayment: false,
disablesKeyedInCardEntry: false,
skipsReceipt: false
)

// Open Point of Sale to complete the payment.
Expand Down
42 changes: 23 additions & 19 deletions Sources/SCCAPIRequest.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,14 @@ typedef NS_OPTIONS(NSUInteger, SCCAPIRequestTenderTypes) {
The client ID must be set to something other than nil before the first API request object is created.
@param clientID The client ID to associate with all subsequent API requests.
*/
+ (void)setClientID:(nullable NSString *)clientID;
+ (void)setClientID:(nullable NSString *)clientID __deprecated_msg("Use the favored `setApplicationID` instead.");

/**
Sets application client ID to associate with all subsequent API requests.
The application ID must be set to something other than nil before the first API request object is created.
@param applicationID The applicationID ID to associate with all subsequent API requests.
*/
+ (void)setApplicationID:(nullable NSString *)applicationID;

/**
Designated initializer for the Point of Sale API request.
Expand Down Expand Up @@ -85,22 +92,16 @@ typedef NS_OPTIONS(NSUInteger, SCCAPIRequestTenderTypes) {
customerID:(nullable NSString*)customerID
supportedTenderTypes:(SCCAPIRequestTenderTypes)supportedTenderTypes
clearsDefaultFees:(BOOL)clearsDefaultFees
returnAutomaticallyAfterPayment:(BOOL)autoreturn
returnsAutomaticallyAfterPayment:(BOOL)autoreturn
disablesKeyedInCardEntry:(BOOL)disablesKeyedInCardEntry
skipsReceipt:(BOOL)skipsReceipt
error:(out NSError *__nullable *__nullable)error;

+ (nullable instancetype)requestWithCallbackURL:(nonnull NSURL *)callbackURL
amount:(nonnull SCCMoney *)amount
userInfoString:(nullable NSString *)userInfoString
merchantID:(nullable NSString *)merchantID
notes:(nullable NSString *)notes
customerID:(nullable NSString*)customerID
supportedTenderTypes:(SCCAPIRequestTenderTypes)supportedTenderTypes
clearsDefaultFees:(BOOL)clearsDefaultFees
returnAutomaticallyAfterPayment:(BOOL)autoreturn
error:(out NSError *__nullable *__nullable)error __deprecated_msg("Use requestWithCallbackURL:amount:userInfoString:locationID:notes:customerID:supportedTenderTypes:clearsDefaultFees:returnAutomaticallyAfterPayment:error: instead.");
/// Application Client ID bound to the request at the time of creation. Same as applicationID
@property (nonatomic, copy, readonly, nonnull) NSString *clientID __deprecated_msg("Use applicationID instead");

/// Application Client ID bound to the request at the time of creation.
@property (nonatomic, copy, readonly, nonnull) NSString *clientID;
/// Application ID bound to the request at the time of creation.
@property (nonatomic, copy, readonly, nonnull) NSString *applicationID;

/// The URL that Square Point of Sale sends responses to.
@property (nonatomic, copy, readonly, nonnull) NSURL *callbackURL;
Expand All @@ -111,9 +112,6 @@ typedef NS_OPTIONS(NSUInteger, SCCAPIRequestTenderTypes) {
/// Free-form string passed along to your application's callbackURL after the payment completes.
@property (nonatomic, copy, readonly, nullable) NSString *userInfoString;

/// The business location's Square-issued ID.
@property (nonatomic, copy, readonly, nullable) NSString *merchantID __deprecated_msg("Use locationID instead");

/// The business location's Square-issued ID.
@property (nonatomic, copy, readonly, nullable) NSString *locationID;

Expand All @@ -123,6 +121,12 @@ typedef NS_OPTIONS(NSUInteger, SCCAPIRequestTenderTypes) {
/// A custom note to associate with the resulting payment.
@property (nonatomic, copy, readonly, nullable) NSString *notes;

/// Square Point of Sale API Version
@property (nonatomic, copy, readonly, nonnull) NSString *apiVersion;

/// SquarePointOfSaleSDK Version
@property (nonatomic, copy, readonly, nonnull) NSString *sdkVersion;

/// The types of tender that Square Point of Sale is allowed to accept for the payment.
@property (nonatomic, assign, readonly) SCCAPIRequestTenderTypes supportedTenderTypes;

Expand All @@ -138,11 +142,11 @@ typedef NS_OPTIONS(NSUInteger, SCCAPIRequestTenderTypes) {

/// If YES, Point of Sale will not display the option to manually key-in a credit card number.
/// Defaults to NO.
@property (nonatomic, assign) BOOL disablesKeyedInCardEntry;
@property (nonatomic, assign, readonly) BOOL disablesKeyedInCardEntry;

/// If YES, Point of Sale will skip the receipt screen of the payment flow for non-cash payments.
/// Defaults to NO.
@property (nonatomic, assign) BOOL skipsReceipt;
@property (nonatomic, assign, readonly) BOOL skipsReceipt;

/**
@param request The request to compare the receiver to.
Expand Down
103 changes: 51 additions & 52 deletions Sources/SCCAPIRequest.m
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,7 @@
#import "SCCMoney.h"
#import "SCCMoney+Serialization.h"


NSString *__nonnull const SCCSDKVersion = @"3.1";
NSString *__nonnull const SCCSDKVersion = @"3.4.1";
NSString *__nonnull const SCCAPIVersion = @"1.3";

NSString *__nonnull const SCCAPIRequestSDKVersionKey = @"sdk_version";
Expand Down Expand Up @@ -61,12 +60,17 @@ @implementation SCCAPIRequest

+ (void)setClientID:(nullable NSString *)clientID;
{
APIClientID = clientID;
[self setApplicationID:clientID];
}

+ (void)setApplicationID:(NSString *)applicationID;
{
APIClientID = applicationID;
}

#pragma mark - Class Methods - Private

+ (nullable NSString *)_clientID;
+ (nullable NSString *)_applicationID;
{
return APIClientID;
}
Expand All @@ -76,22 +80,13 @@ + (nonnull NSString *)_URLScheme;
return @"square-commerce-v1";
}

#pragma mark - Initialization

+ (nullable instancetype)requestWithCallbackURL:(nonnull NSURL *)callbackURL
amount:(nonnull SCCMoney *)amount
userInfoString:(nullable NSString *)userInfoString
merchantID:(nullable NSString *)merchantID
notes:(nullable NSString *)notes
customerID:(nullable NSString *)customerID
supportedTenderTypes:(SCCAPIRequestTenderTypes)supportedTenderTypes
clearsDefaultFees:(BOOL)clearsDefaultFees
returnAutomaticallyAfterPayment:(BOOL)autoreturn
error:(out NSError *__nullable *__nullable)error __deprecated;
- (nonnull NSString *)sdkVersion;
{
return [self requestWithCallbackURL:callbackURL amount:amount userInfoString:userInfoString locationID:merchantID notes:notes customerID:customerID supportedTenderTypes:supportedTenderTypes clearsDefaultFees:clearsDefaultFees returnAutomaticallyAfterPayment:autoreturn error:error];
return SCCSDKVersion;
}

#pragma mark - Initialization

+ (nullable instancetype)requestWithCallbackURL:(nonnull NSURL *)callbackURL
amount:(nonnull SCCMoney *)amount
userInfoString:(nullable NSString *)userInfoString
Expand All @@ -100,10 +95,12 @@ + (nullable instancetype)requestWithCallbackURL:(nonnull NSURL *)callbackURL
customerID:(nullable NSString *)customerID
supportedTenderTypes:(SCCAPIRequestTenderTypes)supportedTenderTypes
clearsDefaultFees:(BOOL)clearsDefaultFees
returnAutomaticallyAfterPayment:(BOOL)autoreturn
returnsAutomaticallyAfterPayment:(BOOL)autoreturn
disablesKeyedInCardEntry:(BOOL)disablesKeyedInCardEntry
skipsReceipt:(BOOL)skipsReceipt
error:(out NSError *__nullable *__nullable)error;
{
if (![self.class _clientID].length) {
if (![self.class _applicationID].length) {
if (error) {
*error = [NSError SCC_missingRequestClientIDError];
}
Expand All @@ -124,28 +121,32 @@ + (nullable instancetype)requestWithCallbackURL:(nonnull NSURL *)callbackURL
return nil;
}

return [[self alloc] initWithClientID:(NSString *__nonnull)[self.class _clientID]
callbackURL:callbackURL
amount:amount
userInfoString:userInfoString
locationID:locationID
notes:notes
customerID:customerID
supportedTenderTypes:supportedTenderTypes
clearsDefaultFees:clearsDefaultFees
returnAutomaticallyAfterPayment:autoreturn];
return [[self alloc] initWithApplicationID:(NSString *__nonnull)[self.class _applicationID]
callbackURL:callbackURL
amount:amount
userInfoString:userInfoString
locationID:locationID
notes:notes
customerID:customerID
supportedTenderTypes:supportedTenderTypes
clearsDefaultFees:clearsDefaultFees
returnAutomaticallyAfterPayment:autoreturn
disablesKeyedInCardEntry:disablesKeyedInCardEntry
skipsReceipt:skipsReceipt];
}

- (instancetype)initWithClientID:(nonnull NSString *)clientID
callbackURL:(nonnull NSURL *)callbackURL
amount:(nonnull SCCMoney *)amount
userInfoString:(nullable NSString *)userInfoString
locationID:(nullable NSString *)locationID
notes:(nullable NSString *)notes
customerID:(nullable NSString *)customerID
supportedTenderTypes:(SCCAPIRequestTenderTypes)supportedTenderTypes
clearsDefaultFees:(BOOL)clearsDefaultFees
returnAutomaticallyAfterPayment:(BOOL)autoreturn;
- (instancetype)initWithApplicationID:(nonnull NSString *)applicationID
callbackURL:(nonnull NSURL *)callbackURL
amount:(nonnull SCCMoney *)amount
userInfoString:(nullable NSString *)userInfoString
locationID:(nullable NSString *)locationID
notes:(nullable NSString *)notes
customerID:(nullable NSString *)customerID
supportedTenderTypes:(SCCAPIRequestTenderTypes)supportedTenderTypes
clearsDefaultFees:(BOOL)clearsDefaultFees
returnAutomaticallyAfterPayment:(BOOL)autoreturn
disablesKeyedInCardEntry:(BOOL)disablesKeyedInCardEntry
skipsReceipt:(BOOL)skipsReceipt
{
NSAssert(callbackURL.scheme.length, @"Callback URL must be specified and have a scheme.");
NSAssert(amount && amount.amountCents >= 0, @"SCCMoney amount must be specified.");
Expand All @@ -155,16 +156,19 @@ - (instancetype)initWithClientID:(nonnull NSString *)clientID
return nil;
}

_clientID = [clientID copy];
_applicationID = [applicationID copy];
_callbackURL = [callbackURL copy];
_amount = [amount copy];
_userInfoString = [userInfoString copy];
_locationID = [locationID copy];
_notes = [notes copy];
_customerID = [customerID copy];
_supportedTenderTypes = supportedTenderTypes;
_clearsDefaultFees = clearsDefaultFees;
_returnsAutomaticallyAfterPayment = autoreturn;
_customerID = [customerID copy];
_disablesKeyedInCardEntry = disablesKeyedInCardEntry;
_skipsReceipt = skipsReceipt;
_apiVersion = SCCAPIVersion;

return self;
}
Expand All @@ -186,7 +190,7 @@ - (BOOL)isEqual:(nullable id)object;

- (NSUInteger)hash;
{
NSUInteger const hashOfRequiredFields = self.clientID.hash ^ self.callbackURL.hash ^ self.amount.hash;
NSUInteger const hashOfRequiredFields = self.applicationID.hash ^ self.callbackURL.hash ^ self.amount.hash;
NSUInteger const hashOfOptionalFields = self.userInfoString.hash ^ self.locationID.hash ^ self.notes.hash ^ self.customerID.hash;
NSUInteger const hashOfScalarFields = (NSUInteger)self.supportedTenderTypes ^ (NSUInteger)self.clearsDefaultFees ^ (NSUInteger)self.returnsAutomaticallyAfterPayment ^ (NSUInteger)self.disablesKeyedInCardEntry ^ (NSUInteger)self.skipsReceipt;

Expand All @@ -199,16 +203,11 @@ - (nonnull NSString *)description;
return [NSString stringWithFormat:@"<%@: %p> { clientID: %@, callbackURL: %@, amount: %@ }",
NSStringFromClass(self.class),
self,
self.clientID,
self.applicationID,
self.callbackURL,
self.amount];
}

- (NSString*)merchantID;
{
return self.locationID;
}

#pragma mark - NSCopying

- (nonnull id)copyWithZone:(nullable NSZone *)zone;
Expand All @@ -226,7 +225,7 @@ - (BOOL)isEqualToAPIRequest:(nullable SCCAPIRequest *)request;
}

// The following properties are required and cannot be nil.
if (![self.clientID isEqualToString:(NSString *__nonnull)request.clientID] ||
if (![self.applicationID isEqualToString:(NSString *__nonnull)request.applicationID] ||
![self.callbackURL isEqual:request.callbackURL] ||
![self.amount isEqualToSCCMoney:request.amount]) {
return NO;
Expand Down Expand Up @@ -262,9 +261,9 @@ @implementation SCCAPIRequest (Serialization)
- (nullable NSURL *)APIRequestURLWithError:(out NSError *__nullable *__nullable)error;
{
NSMutableDictionary *const data = [NSMutableDictionary dictionary];
[data setObject:SCCSDKVersion forKey:SCCAPIRequestSDKVersionKey];
[data setObject:SCCAPIVersion forKey:SCCAPIRequestAPIVersionKey];
[data setObject:self.clientID forKey:SCCAPIRequestClientIDKey];
[data setObject:[self sdkVersion] forKey:SCCAPIRequestSDKVersionKey];
[data setObject:self.apiVersion forKey:SCCAPIRequestAPIVersionKey];
[data setObject:self.applicationID forKey:SCCAPIRequestClientIDKey];

[data SCC_setSafeObject:self.amount.requestDictionaryRepresentation forKey:SCCAPIRequestAmountMoneyKey];
[data SCC_setSafeObject:[SCAPIURLConversion encode:self.callbackURL].absoluteString forKey:SCCAPIRequestCallbackURLKey];
Expand Down
55 changes: 55 additions & 0 deletions Tests/SCAPIRequestTests.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
//
// XCTestCase+SCAPIRequestTests.m
// SquarePointOfSaleSDK-Unit-Tests
//
// Created by Mike Silvis on 10/14/20.
//

@import SquarePointOfSaleSDK;

#import <XCTest/XCTest.h>

@interface SCAPIRequestTests : XCTestCase
@end

@implementation SCAPIRequestTests

- (void)test_initializerSetsAllProperties;
{

NSURL *const callbackURL = [NSURL URLWithString:@"my-app://perform-callback"];
SCCMoney *const amount = [SCCMoney moneyWithAmountCents:100 currencyCode:@"USD" error:NULL];

XCTAssertNotNil(callbackURL);
XCTAssertNotNil(amount);

[SCCAPIRequest setApplicationID:@"my-app-client-id"];

SCCAPIRequest *const request = [SCCAPIRequest requestWithCallbackURL:callbackURL
amount:amount
userInfoString:@"user-info-string"
locationID:@"location-id"
notes:@"notes"
customerID:@"customer-id"
supportedTenderTypes:SCCAPIRequestTenderTypeCard
clearsDefaultFees:YES
returnsAutomaticallyAfterPayment:YES
disablesKeyedInCardEntry:YES
skipsReceipt:YES
error:NULL];

XCTAssertEqual(request.amount, amount);
XCTAssertTrue([request.userInfoString isEqualToString:@"user-info-string"]);
XCTAssertTrue([request.locationID isEqualToString:@"location-id"]);
XCTAssertTrue([request.notes isEqualToString:@"notes"]);
XCTAssertTrue([request.customerID isEqualToString:@"customer-id"]);
XCTAssertTrue([request.apiVersion isEqualToString:@"1.3"]);
XCTAssertTrue([request.sdkVersion isEqualToString:@"3.4.1"]);
XCTAssertEqual(request.supportedTenderTypes, SCCAPIRequestTenderTypeCard);
XCTAssertEqual(request.clearsDefaultFees, YES);
XCTAssertEqual(request.returnsAutomaticallyAfterPayment, YES);
XCTAssertEqual(request.disablesKeyedInCardEntry, YES);
XCTAssertEqual(request.skipsReceipt, YES);
}

@end
Loading

0 comments on commit e6398e3

Please sign in to comment.