BTThreeDSecureV2Provider.m 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. #import "BTThreeDSecureV2Provider.h"
  2. #import "BTPaymentFlowDriver+ThreeDSecure_Internal.h"
  3. #import "BTThreeDSecureAuthenticateJWT.h"
  4. #import "BTThreeDSecureV2UICustomization_Internal.h"
  5. #import <CardinalMobile/CardinalMobile.h>
  6. #if __has_include(<Braintree/BraintreeThreeDSecure.h>) // CocoaPods
  7. #import <Braintree/BTConfiguration+ThreeDSecure.h>
  8. #import <Braintree/BTThreeDSecureRequest.h>
  9. #import <Braintree/BTThreeDSecureResult.h>
  10. #import <Braintree/BTThreeDSecureLookup.h>
  11. #import <Braintree/BraintreeCore.h>
  12. #import <Braintree/BTAPIClient_Internal.h>
  13. #elif SWIFT_PACKAGE // SPM
  14. #import <BraintreeThreeDSecure/BTConfiguration+ThreeDSecure.h>
  15. #import <BraintreeThreeDSecure/BTThreeDSecureRequest.h>
  16. #import <BraintreeThreeDSecure/BTThreeDSecureResult.h>
  17. #import <BraintreeThreeDSecure/BTThreeDSecureLookup.h>
  18. #import <BraintreeCore/BraintreeCore.h>
  19. #import "../BraintreeCore/BTAPIClient_Internal.h"
  20. #else // Carthage
  21. #import <BraintreeThreeDSecure/BTConfiguration+ThreeDSecure.h>
  22. #import <BraintreeThreeDSecure/BTThreeDSecureRequest.h>
  23. #import <BraintreeThreeDSecure/BTThreeDSecureResult.h>
  24. #import <BraintreeThreeDSecure/BTThreeDSecureLookup.h>
  25. #import <BraintreeCore/BraintreeCore.h>
  26. #import <BraintreeCore/BTAPIClient_Internal.h>
  27. #endif
  28. @interface BTThreeDSecureV2Provider() <CardinalValidationDelegate>
  29. @property (strong, nonatomic) CardinalSession *cardinalSession;
  30. @property (strong, nonatomic) BTThreeDSecureResult *lookupResult;
  31. @property (strong, nonatomic) BTAPIClient *apiClient;
  32. @property (copy, nonatomic) BTThreeDSecureV2ProviderSuccessHandler successHandler;
  33. @property (copy, nonatomic) BTThreeDSecureV2ProviderFailureHandler failureHandler;
  34. @end
  35. @implementation BTThreeDSecureV2Provider
  36. + (instancetype)initializeProviderWithConfiguration:(BTConfiguration *)configuration
  37. apiClient:(BTAPIClient *)apiClient
  38. request:(BTThreeDSecureRequest *)request
  39. completion:(BTThreeDSecureV2ProviderInitializeCompletionHandler)completionHandler {
  40. BTThreeDSecureV2Provider *instance = [self new];
  41. instance.apiClient = apiClient;
  42. instance.cardinalSession = [CardinalSession new];
  43. CardinalSessionConfiguration *cardinalConfiguration = [CardinalSessionConfiguration new];
  44. if (request.v2UICustomization) {
  45. cardinalConfiguration.uiCustomization = request.v2UICustomization.cardinalValue;
  46. }
  47. CardinalSessionEnvironment cardinalEnvironment = CardinalSessionEnvironmentStaging;
  48. if ([configuration.environment isEqualToString:@"production"]) {
  49. cardinalEnvironment = CardinalSessionEnvironmentProduction;
  50. }
  51. cardinalConfiguration.deploymentEnvironment = cardinalEnvironment;
  52. [instance.cardinalSession configure:cardinalConfiguration];
  53. [instance.cardinalSession setupWithJWT:configuration.cardinalAuthenticationJWT
  54. didComplete:^(__unused NSString * _Nonnull consumerSessionId) {
  55. [instance.apiClient sendAnalyticsEvent:@"ios.three-d-secure.cardinal-sdk.init.setup-completed"];
  56. completionHandler(@{@"dfReferenceId": consumerSessionId});
  57. } didValidate:^(__unused CardinalResponse * _Nonnull validateResponse) {
  58. [instance.apiClient sendAnalyticsEvent:@"ios.three-d-secure.cardinal-sdk.init.setup-failed"];
  59. completionHandler(@{});
  60. }];
  61. return instance;
  62. }
  63. - (void)processLookupResult:(BTThreeDSecureResult *)lookupResult
  64. success:(BTThreeDSecureV2ProviderSuccessHandler)successHandler
  65. failure:(BTThreeDSecureV2ProviderFailureHandler)failureHandler {
  66. self.lookupResult = lookupResult;
  67. self.successHandler = successHandler;
  68. self.failureHandler = failureHandler;
  69. [self.cardinalSession continueWithTransactionId:lookupResult.lookup.transactionID
  70. payload:lookupResult.lookup.PAReq
  71. didValidateDelegate:self];
  72. }
  73. - (void)callFailureHandlerWithErrorDomain:(NSErrorDomain)errorDomain
  74. errorCode:(NSInteger)errorCode
  75. errorUserInfo:(NSDictionary *)errorUserInfo
  76. failureHandler:(BTThreeDSecureV2ProviderFailureHandler)failureHandler {
  77. NSError *error = [NSError errorWithDomain:errorDomain
  78. code:errorCode
  79. userInfo:errorUserInfo];
  80. if (failureHandler != nil) {
  81. failureHandler(error);
  82. }
  83. }
  84. #pragma mark - Cardinal Delegate
  85. - (void)cardinalSession:(__unused CardinalSession *)session stepUpDidValidateWithResponse:(CardinalResponse *)validateResponse serverJWT:(__unused NSString *)serverJWT {
  86. [self.apiClient sendAnalyticsEvent:[NSString stringWithFormat:@"ios.three-d-secure.verification-flow.cardinal-sdk.action-code.%@", [self analyticsStringForActionCode:validateResponse.actionCode]]];
  87. switch (validateResponse.actionCode) {
  88. case CardinalResponseActionCodeSuccess:
  89. case CardinalResponseActionCodeNoAction:
  90. case CardinalResponseActionCodeFailure: {
  91. [BTThreeDSecureAuthenticateJWT authenticateJWT:serverJWT
  92. withAPIClient:self.apiClient
  93. forLookupResult:self.lookupResult
  94. success:self.successHandler
  95. failure:self.failureHandler];
  96. break;
  97. }
  98. case CardinalResponseActionCodeError:
  99. case CardinalResponseActionCodeTimeout: {
  100. NSMutableDictionary *userInfo = [NSMutableDictionary dictionaryWithCapacity:1];
  101. if (validateResponse.errorDescription) {
  102. userInfo[NSLocalizedDescriptionKey] = validateResponse.errorDescription;
  103. }
  104. BTThreeDSecureFlowErrorType errorCode = BTThreeDSecureFlowErrorTypeUnknown;
  105. if (validateResponse.errorNumber == 1050) {
  106. errorCode = BTThreeDSecureFlowErrorTypeFailedAuthentication;
  107. }
  108. [self callFailureHandlerWithErrorDomain:BTThreeDSecureFlowErrorDomain
  109. errorCode:errorCode
  110. errorUserInfo:userInfo
  111. failureHandler:self.failureHandler];
  112. break;
  113. }
  114. case CardinalResponseActionCodeCancel: {
  115. [self callFailureHandlerWithErrorDomain:BTPaymentFlowDriverErrorDomain
  116. errorCode:BTPaymentFlowDriverErrorTypeCanceled
  117. errorUserInfo:nil
  118. failureHandler:self.failureHandler];
  119. break;
  120. }
  121. }
  122. self.lookupResult = nil;
  123. self.successHandler = nil;
  124. self.failureHandler = nil;
  125. }
  126. - (NSString *)analyticsStringForActionCode:(CardinalResponseActionCode)actionCode {
  127. switch (actionCode) {
  128. case CardinalResponseActionCodeSuccess:
  129. return @"completed";
  130. case CardinalResponseActionCodeNoAction:
  131. return @"noaction";
  132. case CardinalResponseActionCodeFailure:
  133. return @"failure";
  134. case CardinalResponseActionCodeError:
  135. return @"failed";
  136. case CardinalResponseActionCodeCancel:
  137. return @"canceled";
  138. case CardinalResponseActionCodeTimeout:
  139. return @"timeout";
  140. }
  141. }
  142. @end