Skip to content

Commit

Permalink
Merge pull request #572 from stripe/bg-muid
Browse files Browse the repository at this point in the history
Add muid to card token creation
  • Loading branch information
bg-stripe authored Mar 6, 2017
2 parents a26ff49 + 9cf49d7 commit 58f85fc
Show file tree
Hide file tree
Showing 11 changed files with 61 additions and 63 deletions.
37 changes: 16 additions & 21 deletions Stripe/STPAPIClient+ApplePay.m
Original file line number Diff line number Diff line change
Expand Up @@ -17,30 +17,30 @@
@implementation STPAPIClient (ApplePay)

- (void)createTokenWithPayment:(PKPayment *)payment completion:(STPTokenCompletionBlock)completion {
[self createTokenWithData:[self.class formEncodedDataForPayment:payment]
completion:completion];
NSDictionary *parameters = [[self class] parametersForPayment:payment];
[self createTokenWithParameters:parameters
completion:completion];
}

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated"
+ (NSData *)formEncodedDataForPayment:(PKPayment *)payment {
+ (NSDictionary *)parametersForPayment:(PKPayment *)payment {
NSCAssert(payment != nil, @"Cannot create a token with a nil payment.");
NSMutableCharacterSet *set = [[NSCharacterSet URLQueryAllowedCharacterSet] mutableCopy];
[set removeCharactersInString:@"+="];
NSString *paymentString =
[[[NSString alloc] initWithData:payment.token.paymentData encoding:NSUTF8StringEncoding] stringByAddingPercentEncodingWithAllowedCharacters:set];
__block NSString *payloadString = [@"pk_token=" stringByAppendingString:paymentString];
[[NSString alloc] initWithData:payment.token.paymentData encoding:NSUTF8StringEncoding];
NSMutableDictionary *payload = [NSMutableDictionary new];
payload[@"pk_token"] = paymentString;

ABRecordRef billingAddress = payment.billingAddress;
if (billingAddress) {
NSMutableDictionary *params = [NSMutableDictionary dictionary];

NSString *firstName = (__bridge_transfer NSString*)ABRecordCopyValue(billingAddress, kABPersonFirstNameProperty);
NSString *lastName = (__bridge_transfer NSString*)ABRecordCopyValue(billingAddress, kABPersonLastNameProperty);
if (firstName.length && lastName.length) {
params[@"name"] = [NSString stringWithFormat:@"%@ %@", firstName, lastName];
}

ABMultiValueRef addressValues = ABRecordCopyValue(billingAddress, kABPersonAddressProperty);
if (addressValues != NULL) {
if (ABMultiValueGetCount(addressValues) > 0) {
Expand All @@ -66,38 +66,33 @@ + (NSData *)formEncodedDataForPayment:(PKPayment *)payment {
params[@"address_country"] = country;
}
CFRelease(dict);
[params enumerateKeysAndObjectsUsingBlock:^(NSString *key, NSString *obj, __unused BOOL *stop) {
NSString *param = [NSString stringWithFormat:@"&card[%@]=%@", key, [obj stringByAddingPercentEncodingWithAllowedCharacters:set]];
payloadString = [payloadString stringByAppendingString:param];
}];
payload[@"card"] = params;
}
CFRelease(addressValues);
}
}

NSString *paymentInstrumentName = payment.token.paymentInstrumentName;
if (paymentInstrumentName) {
NSString *param = [NSString stringWithFormat:@"&pk_token_instrument_name=%@", paymentInstrumentName];
payloadString = [payloadString stringByAppendingString:param];
payload[@"pk_token_instrument_name"] = paymentInstrumentName;
}

NSString *paymentNetwork = payment.token.paymentNetwork;
if (paymentNetwork) {
NSString *param = [NSString stringWithFormat:@"&pk_token_payment_network=%@", paymentNetwork];
payloadString = [payloadString stringByAppendingString:param];
payload[@"pk_token_payment_network"] = paymentNetwork;
}

NSString *transactionIdentifier = payment.token.transactionIdentifier;
if (transactionIdentifier) {
if ([payment stp_isSimulated]) {
transactionIdentifier = [PKPayment stp_testTransactionIdentifier];
}
NSString *param = [NSString stringWithFormat:@"&pk_token_transaction_id=%@", transactionIdentifier];
payloadString = [payloadString stringByAppendingString:param];
payload[@"pk_token_transaction_id"] = transactionIdentifier;
}

return [payloadString dataUsingEncoding:NSUTF8StringEncoding];
return payload;
}

#pragma clang diagnostic pop

@end
Expand Down
4 changes: 2 additions & 2 deletions Stripe/STPAPIClient+Private.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ NS_ASSUME_NONNULL_BEGIN
- (instancetype)initWithPublishableKey:(NSString *)publishableKey
baseURL:(NSString *)baseURL;

- (void)createTokenWithData:(NSData *)data
completion:(STPTokenCompletionBlock)completion;
- (void)createTokenWithParameters:(NSDictionary *)parameters
completion:(STPTokenCompletionBlock)completion;

- (NSURLSessionDataTask *)retrieveSourceWithId:(NSString *)identifier clientSecret:(NSString *)secret responseCompletion:(STPAPIResponseBlock)completion;

Expand Down
27 changes: 14 additions & 13 deletions Stripe/STPAPIClient.m
Original file line number Diff line number Diff line change
Expand Up @@ -129,15 +129,15 @@ - (NSString *)publishableKey {
return self.configuration.publishableKey;
}

- (void)createTokenWithData:(NSData *)data
completion:(STPTokenCompletionBlock)completion {
NSCAssert(data != nil, @"'data' is required to create a token");
- (void)createTokenWithParameters:(NSDictionary *)parameters
completion:(STPTokenCompletionBlock)completion {
NSCAssert(parameters != nil, @"'parameters' is required to create a token");
NSCAssert(completion != nil, @"'completion' is required to use the token that is created");
NSDate *start = [NSDate date];
[[STPAnalyticsClient sharedClient] logTokenCreationAttemptWithConfiguration:self.configuration];
[STPAPIRequest<STPToken *> postWithAPIClient:self
endpoint:tokenEndpoint
postData:data
parameters:parameters
serializer:[STPToken new]
completion:^(STPToken *object, NSHTTPURLResponse *response, NSError *error) {
NSDate *end = [NSDate date];
Expand Down Expand Up @@ -235,8 +235,8 @@ @implementation STPAPIClient (BankAccounts)

- (void)createTokenWithBankAccount:(STPBankAccountParams *)bankAccount
completion:(STPTokenCompletionBlock)completion {
NSData *data = [STPFormEncoder formEncodedDataForObject:bankAccount];
[self createTokenWithData:data completion:completion];
NSDictionary *params = [STPFormEncoder dictionaryForObject:bankAccount];
[self createTokenWithParameters:params completion:completion];
}

@end
Expand All @@ -245,8 +245,9 @@ - (void)createTokenWithBankAccount:(STPBankAccountParams *)bankAccount
@implementation STPAPIClient (CreditCards)

- (void)createTokenWithCard:(STPCard *)card completion:(STPTokenCompletionBlock)completion {
NSData *data = [STPFormEncoder formEncodedDataForObject:card];
[self createTokenWithData:data completion:completion];
NSMutableDictionary *params = [[STPFormEncoder dictionaryForObject:card] mutableCopy];
params[@"muid"] = [STPAnalyticsClient muid];
[self createTokenWithParameters:params completion:completion];
}

@end
Expand Down Expand Up @@ -294,16 +295,16 @@ + (PKPaymentRequest *)paymentRequestWithMerchantIdentifier:(NSString *)merchantI

@implementation STPAPIClient (Sources)

- (void)createSourceWithParams:(STPSourceParams *)params completion:(STPSourceCompletionBlock)completion {
NSCAssert(params != nil, @"'params' is required to create a source");
- (void)createSourceWithParams:(STPSourceParams *)sourceParams completion:(STPSourceCompletionBlock)completion {
NSCAssert(sourceParams != nil, @"'params' is required to create a source");
NSCAssert(completion != nil, @"'completion' is required to use the source that is created");
NSString *sourceType = [STPSource stringFromType:params.type];
NSString *sourceType = [STPSource stringFromType:sourceParams.type];
[[STPAnalyticsClient sharedClient] logSourceCreationAttemptWithConfiguration:self.configuration
sourceType:sourceType];
NSData *data = [STPFormEncoder formEncodedDataForObject:params];
NSDictionary *params = [STPFormEncoder dictionaryForObject:sourceParams];
[STPAPIRequest<STPSource *> postWithAPIClient:self
endpoint:sourcesEndpoint
postData:data
parameters:params
serializer:[STPSource new]
completion:^(STPSource *object, __unused NSHTTPURLResponse *response, NSError *error) {
completion(object, error);
Expand Down
2 changes: 1 addition & 1 deletion Stripe/STPAPIRequest.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ typedef void(^STPAPIResponseBlock)(ResponseType object, NSHTTPURLResponse *respo

+ (NSURLSessionDataTask *)postWithAPIClient:(STPAPIClient *)apiClient
endpoint:(NSString *)endpoint
postData:(NSData *)postData
parameters:(NSDictionary *)parameters
serializer:(ResponseType)serializer
completion:(STPAPIResponseBlock)completion;

Expand Down
9 changes: 6 additions & 3 deletions Stripe/STPAPIRequest.m
Original file line number Diff line number Diff line change
Expand Up @@ -6,25 +6,28 @@
// Copyright © 2015 Stripe, Inc. All rights reserved.
//

#import "STPAPIRequest.h"

#import "NSMutableURLRequest+Stripe.h"
#import "STPAPIClient+Private.h"
#import "STPAPIClient.h"
#import "STPDispatchFunctions.h"
#import "STPAPIRequest.h"
#import "STPFormEncoder.h"
#import "StripeError.h"

@implementation STPAPIRequest

+ (NSURLSessionDataTask *)postWithAPIClient:(STPAPIClient *)apiClient
endpoint:(NSString *)endpoint
postData:(NSData *)postData
parameters:(NSDictionary *)parameters
serializer:(id<STPAPIResponseDecodable>)serializer
completion:(STPAPIResponseBlock)completion {

NSURL *url = [apiClient.apiURL URLByAppendingPathComponent:endpoint];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:url];
request.HTTPMethod = @"POST";
request.HTTPBody = postData;
NSString *query = [STPFormEncoder queryStringFromParameters:parameters];
request.HTTPBody = [query dataUsingEncoding:NSUTF8StringEncoding];

NSURLSessionDataTask *task = [apiClient.urlSession dataTaskWithRequest:request completionHandler:^(NSData * _Nullable body, NSURLResponse * _Nullable response, NSError * _Nullable error) {
[[self class] parseResponse:response
Expand Down
2 changes: 2 additions & 0 deletions Stripe/STPAnalyticsClient.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ typedef NS_ENUM(NSUInteger, STPAddCardRememberMeUsage) {

+ (void)disableAnalytics;

+ (NSString *)muid;

- (void)logRememberMeConversion:(STPAddCardRememberMeUsage)selected;

- (void)logTokenCreationAttemptWithConfiguration:(STPPaymentConfiguration *)configuration;
Expand Down
4 changes: 4 additions & 0 deletions Stripe/STPAnalyticsClient.m
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,10 @@ + (NSNumber *)timestampWithDate:(NSDate *)date {
return @((NSInteger)([date timeIntervalSince1970]*1000));
}

+ (NSString *)muid {
return [[[UIDevice currentDevice] identifierForVendor] UUIDString];
}

- (instancetype)init {
self = [super init];
if (self) {
Expand Down
2 changes: 0 additions & 2 deletions Stripe/STPFormEncoder.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,6 @@

@interface STPFormEncoder : NSObject

+ (nonnull NSData *)formEncodedDataForObject:(nonnull NSObject<STPFormEncodable> *)object;

+ (nonnull NSDictionary *)dictionaryForObject:(nonnull NSObject<STPFormEncodable> *)object;

+ (nonnull NSString *)stringByURLEncoding:(nonnull NSString *)string;
Expand Down
5 changes: 0 additions & 5 deletions Stripe/STPFormEncoder.m
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,6 @@ + (NSString *)stringByReplacingSnakeCaseWithCamelCase:(NSString *)input {
return [camelCaseParam copy];
}

+ (nonnull NSData *)formEncodedDataForObject:(nonnull NSObject<STPFormEncodable> *)object {
NSDictionary *dict = [self dictionaryForObject:object];
return [STPQueryStringFromParameters(dict) dataUsingEncoding:NSUTF8StringEncoding];
}

+ (NSDictionary *)dictionaryForObject:(nonnull NSObject<STPFormEncodable> *)object {
NSDictionary *keyPairs = [self keyPairDictionaryForObject:object];
NSString *rootObjectName = [object.class rootObjectName];
Expand Down
27 changes: 13 additions & 14 deletions Tests/Tests/STPCertTest.m
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,14 @@ @implementation STPCertTest
- (void)testNoError {
XCTestExpectation *expectation = [self expectationWithDescription:@"Token creation"];
STPAPIClient *client = [[STPAPIClient alloc] initWithPublishableKey:STPExamplePublishableKey];
[client createTokenWithData:[NSData new]
completion:^(STPToken *token, NSError *error) {
[expectation fulfill];
// Note that this API request *will* fail, but it will return error
// messages from the server and not be blocked by local cert checks
XCTAssertNil(token, @"Expected no token");
XCTAssertNotNil(error, @"Expected error");
}];
[client createTokenWithParameters:@{}
completion:^(STPToken *token, NSError *error) {
[expectation fulfill];
// Note that this API request *will* fail, but it will return error
// messages from the server and not be blocked by local cert checks
XCTAssertNil(token, @"Expected no token");
XCTAssertNotNil(error, @"Expected error");
}];
[self waitForExpectationsWithTimeout:10.0f handler:nil];
}

Expand All @@ -60,12 +60,11 @@ - (void)createTokenWithBaseURL:(NSURL *)baseURL completion:(STPTokenCompletionBl
XCTestExpectation *expectation = [self expectationWithDescription:@"Token creation"];
STPAPIClient *client = [[STPAPIClient alloc] initWithPublishableKey:STPExamplePublishableKey];
client.apiURL = baseURL;
[client createTokenWithData:[NSData new]
completion:^(STPToken *token, NSError *error) {
[expectation fulfill];
completion(token, error);
}];

[client createTokenWithParameters:@{}
completion:^(STPToken *token, NSError *error) {
[expectation fulfill];
completion(token, error);
}];
[self waitForExpectationsWithTimeout:10.0f handler:nil];
}

Expand Down
5 changes: 3 additions & 2 deletions Tests/Tests/STPFormEncoderTest.m
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,9 @@ - (void)testStringByReplacingSnakeCaseWithCamelCase {

// helper test method
- (NSString *)encodeObject:(STPTestFormEncodableObject *)object {
NSData *encoded = [STPFormEncoder formEncodedDataForObject:object];
return [[[NSString alloc] initWithData:encoded encoding:NSUTF8StringEncoding] stringByRemovingPercentEncoding];
NSDictionary *dictionary = [STPFormEncoder dictionaryForObject:object];
NSString *queryString = [STPFormEncoder queryStringFromParameters:dictionary];
return [queryString stringByRemovingPercentEncoding];
}

- (void)testFormEncoding_emptyObject {
Expand Down

0 comments on commit 58f85fc

Please sign in to comment.