From b4d7fef0be1df25ac2d038e7150fd8a514260053 Mon Sep 17 00:00:00 2001 From: OS-ricardomoreirasilva Date: Mon, 28 Nov 2022 15:53:38 +0000 Subject: [PATCH] feat: Add Stripe as First Payment Gateway Add all necessary logic and changes to make payment processing using Stripe including Protocols, Factories and Models to deal with the StripePayments pod. Unit tests are included. --- OSPaymentsLib.xcodeproj/project.pbxproj | 64 +- OSPaymentsLib/Error/OSPMTError.swift | 11 + .../Extensions/PKPayment+Adapter.swift | 17 +- OSPaymentsLib/Gateways/OSPMTGateway.swift | 14 + .../Gateways/OSPMTGatewayFactory.swift | 18 + .../Stripe/OSPMTStripeAPIDelegate.swift | 37 + .../OSPMTStripeRequestParametersModel.swift | 40 + .../Gateways/Stripe/OSPMTStripeWrapper.swift | 44 + .../Models/OSPMTConfigurationModel.swift | 77 +- OSPaymentsLib/Models/OSPMTDataModel.swift | 18 +- .../Models/OSPMTRequestParametersModel.swift | 36 + .../OSPMTServiceProviderInfoModel.swift | 70 + .../Protocols/OSPMTGatewayDelegate.swift | 43 + .../Protocols/OSPMTRequestDelegate.swift | 47 +- .../OSPMTGatewayFactorySpec.swift | 39 + OSPaymentsLibTests/OSPMTPaymentsSpec.swift | 30 +- .../OSPMTStripeWrapperSpec.swift | 180 + .../OSPMTTestConfigurations.swift | 48 + OSPaymentsPluginLib.podspec | 1 + Podfile | 5 +- Podfile.lock | 17 +- Pods/Manifest.lock | 17 +- Pods/Pods.xcodeproj/project.pbxproj | 3849 +++++++++++++++-- Pods/StripeCore/LICENSE | 21 + Pods/StripeCore/README.md | 141 + .../bg-BG.lproj/Localizable.strings | 31 + .../ca-ES.lproj/Localizable.strings | 31 + .../cs-CZ.lproj/Localizable.strings | 31 + .../da.lproj/Localizable.strings | 31 + .../de.lproj/Localizable.strings | 31 + .../el-GR.lproj/Localizable.strings | 31 + .../en-GB.lproj/Localizable.strings | 31 + .../en.lproj/Localizable.strings | 48 + .../es-419.lproj/Localizable.strings | 31 + .../es.lproj/Localizable.strings | 31 + .../et-EE.lproj/Localizable.strings | 31 + .../fi.lproj/Localizable.strings | 31 + .../fil.lproj/Localizable.strings | 31 + .../fr-CA.lproj/Localizable.strings | 31 + .../fr.lproj/Localizable.strings | 31 + .../hr.lproj/Localizable.strings | 31 + .../hu.lproj/Localizable.strings | 31 + .../id.lproj/Localizable.strings | 31 + .../it.lproj/Localizable.strings | 31 + .../ja.lproj/Localizable.strings | 31 + .../ko.lproj/Localizable.strings | 31 + .../lt-LT.lproj/Localizable.strings | 31 + .../lv-LV.lproj/Localizable.strings | 31 + .../ms-MY.lproj/Localizable.strings | 31 + .../mt.lproj/Localizable.strings | 31 + .../nb.lproj/Localizable.strings | 31 + .../nl.lproj/Localizable.strings | 31 + .../nn-NO.lproj/Localizable.strings | 31 + .../pl-PL.lproj/Localizable.strings | 31 + .../pt-BR.lproj/Localizable.strings | 31 + .../pt-PT.lproj/Localizable.strings | 31 + .../ro-RO.lproj/Localizable.strings | 31 + .../ru.lproj/Localizable.strings | 31 + .../sk-SK.lproj/Localizable.strings | 31 + .../sl-SI.lproj/Localizable.strings | 31 + .../sv.lproj/Localizable.strings | 31 + .../tr.lproj/Localizable.strings | 31 + .../vi.lproj/Localizable.strings | 31 + .../zh-HK.lproj/Localizable.strings | 31 + .../zh-Hans.lproj/Localizable.strings | 31 + .../zh-Hant.lproj/Localizable.strings | 31 + .../API Bindings/Models/EmptyResponse.swift | 14 + .../API Bindings/Models/StripeFile.swift | 45 + .../STPAPIClient+FileUpload.swift | 235 + .../Source/API Bindings/STPAPIClient.swift | 544 +++ .../Source/API Bindings/STPAppInfo.swift | 45 + .../STPMultipartFormDataEncoder.swift | 38 + .../STPMultipartFormDataPart.swift | 63 + .../Source/API Bindings/StripeAPI.swift | 174 + .../StripeAPIConfiguration+Version.swift | 21 + .../API Bindings/StripeAPIConfiguration.swift | 16 + .../Source/API Bindings/StripeError.swift | 80 + .../API Bindings/StripeServiceError.swift | 73 + .../Source/Analytics/Analytic.swift | 37 + .../Analytics/AnalyticLoggableError.swift | 52 + .../Source/Analytics/AnalyticsClientV2.swift | 153 + .../Source/Analytics/PluginDetector.swift | 47 + .../Source/Analytics/STPAnalyticEvent.swift | 141 + .../Source/Analytics/STPAnalyticsClient.swift | 147 + .../Categories/Decimal+StripeCore.swift | 15 + .../Source/Categories/Dictionary+Stripe.swift | 69 + .../Enums+CustomStringConvertible.swift | 29 + .../Source/Categories/NSArray+Stripe.swift | 18 + .../Categories/NSBundle+Stripe_AppName.swift | 32 + .../NSCharacterSet+StripeCore.swift | 21 + .../Source/Categories/NSError+Stripe.swift | 135 + .../Categories/NSError+StripeCore.swift | 18 + .../NSMutableURLRequest+Stripe.swift | 43 + .../Categories/NSURLComponents+Stripe.swift | 63 + .../Source/Categories/String+StripeCore.swift | 36 + .../Categories/UIImage+StripeCore.swift | 160 + .../Source/Coder/StripeCodable.swift | 172 + .../Source/Coder/StripeJSONDecoder.swift | 710 +++ .../Source/Coder/StripeJSONEncoder.swift | 564 +++ .../Source/Coder/StripeJSONShared.swift | 37 + .../Source/Coder/UnknownFields.swift | 98 + .../ConnectionsSDKInterface.swift | 37 + .../DownloadManager/DownloadManager.swift | 234 + .../StripeCore/Source/Helpers/Async.swift | 153 + .../Helpers/BundleLocatorProtocol.swift | 75 + .../Source/Helpers/FileDownloader.swift | 75 + .../Source/Helpers/InstallMethod.swift | 27 + .../Source/Helpers/PaymentsSDKVariant.swift | 57 + .../Source/Helpers/STPDeviceUtils.swift | 25 + .../Source/Helpers/STPDispatchFunctions.swift | 17 + .../StripeCore/Source/Helpers/STPError.swift | 307 ++ .../Helpers/STPNumericStringValidator.swift | 31 + .../Helpers/STPURLCallbackHandler.swift | 92 + .../Source/Helpers/ServerErrorMapper.swift | 95 + .../Helpers/StripeCoreBundleLocator.swift | 18 + .../Source/Helpers/URLEncoder.swift | 147 + .../Source/Helpers/URLSession+Retry.swift | 54 + .../Localization/STPLocalizationUtils.swift | 97 + .../Localization/STPLocalizedString.swift | 14 + .../Localization/String+Localized.swift | 51 + .../Source/Telemetry/FraudDetectionData.swift | 72 + .../Source/Telemetry/STPTelemetryClient.swift | 214 + .../Telemetry/UserDefaults+PaymentsCore.swift | 42 + .../UI/UIActivityIndicatorView+Stripe.swift | 35 + .../StripeCore/Source/UI/UIFont+Stripe.swift | 88 + Pods/StripePayments/LICENSE | 21 + Pods/StripePayments/README.md | 141 + .../Stripe3DS2/Stripe3DS2/NSData+JWEHelpers.h | 22 + .../Stripe3DS2/Stripe3DS2/NSData+JWEHelpers.m | 37 + .../Stripe3DS2/NSDictionary+DecodingHelpers.h | 49 + .../Stripe3DS2/NSDictionary+DecodingHelpers.m | 149 + .../Stripe3DS2/NSError+Stripe3DS2.h | 34 + .../Stripe3DS2/NSError+Stripe3DS2.m | 40 + .../NSLayoutConstraint+LayoutSupport.h | 55 + .../NSLayoutConstraint+LayoutSupport.m | 32 + .../Stripe3DS2/NSString+EmptyChecking.h | 21 + .../Stripe3DS2/NSString+EmptyChecking.m | 27 + .../Stripe3DS2/NSString+JWEHelpers.h | 23 + .../Stripe3DS2/NSString+JWEHelpers.m | 56 + .../Resources/Images/Chevron@3x.png | Bin 0 -> 1035 bytes .../Resources/Images/amex-logo@3x.png | Bin 0 -> 7294 bytes .../Images/cartes-bancaires-logo.png | Bin 0 -> 16322 bytes .../Resources/Images/discover-logo.png | Bin 0 -> 4669 bytes .../Stripe3DS2/Resources/Images/error@3x.png | Bin 0 -> 2100 bytes .../Resources/Images/mastercard-logo@3x.png | Bin 0 -> 5988 bytes .../Resources/Images/visa-logo@3x.png | Bin 0 -> 6852 bytes .../Resources/Images/visa-white-logo@3x.png | Bin 0 -> 6287 bytes .../Resources/bg-BG.lproj/Localizable.strings | 45 + .../Resources/ca-ES.lproj/Localizable.strings | 45 + .../Resources/cs-CZ.lproj/Localizable.strings | 45 + .../Resources/da.lproj/Localizable.strings | 39 + .../Resources/de.lproj/Localizable.strings | 39 + .../Resources/el-GR.lproj/Localizable.strings | 45 + .../Resources/en-GB.lproj/Localizable.strings | 39 + .../Resources/en.lproj/Localizable.strings | 45 + .../es-419.lproj/Localizable.strings | 39 + .../Resources/es.lproj/Localizable.strings | 39 + .../Resources/et-EE.lproj/Localizable.strings | 45 + .../Resources/fi.lproj/Localizable.strings | 39 + .../Resources/fil.lproj/Localizable.strings | 45 + .../Resources/fr-CA.lproj/Localizable.strings | 39 + .../Resources/fr.lproj/Localizable.strings | 39 + .../Resources/hr.lproj/Localizable.strings | 45 + .../Resources/hu.lproj/Localizable.strings | 39 + .../Resources/id.lproj/Localizable.strings | 45 + .../Resources/it.lproj/Localizable.strings | 39 + .../Resources/ja.lproj/Localizable.strings | 39 + .../Resources/ko.lproj/Localizable.strings | 39 + .../Resources/lt-LT.lproj/Localizable.strings | 45 + .../Resources/lv-LV.lproj/Localizable.strings | 45 + .../Resources/ms-MY.lproj/Localizable.strings | 45 + .../Resources/mt.lproj/Localizable.strings | 39 + .../Resources/nb.lproj/Localizable.strings | 39 + .../Resources/nl.lproj/Localizable.strings | 39 + .../Resources/nn-NO.lproj/Localizable.strings | 39 + .../Resources/pl-PL.lproj/Localizable.strings | 45 + .../Resources/pt-BR.lproj/Localizable.strings | 39 + .../Resources/pt-PT.lproj/Localizable.strings | 39 + .../Resources/ro-RO.lproj/Localizable.strings | 45 + .../Resources/ru.lproj/Localizable.strings | 39 + .../Resources/sk-SK.lproj/Localizable.strings | 45 + .../Resources/sl-SI.lproj/Localizable.strings | 45 + .../Resources/sv.lproj/Localizable.strings | 39 + .../Resources/tr.lproj/Localizable.strings | 39 + .../Resources/vi.lproj/Localizable.strings | 45 + .../Resources/zh-HK.lproj/Localizable.strings | 39 + .../zh-Hans.lproj/Localizable.strings | 39 + .../zh-Hant.lproj/Localizable.strings | 39 + .../Stripe3DS2/STDSACSNetworkingManager.h | 30 + .../Stripe3DS2/STDSACSNetworkingManager.m | 171 + .../STDSAlreadyInitializedException.m | 17 + .../STDSAuthenticationRequestParameters.m | 63 + .../STDSAuthenticationResponseObject.h | 20 + .../STDSAuthenticationResponseObject.m | 100 + .../Stripe3DS2/Stripe3DS2/STDSBrandingView.h | 23 + .../Stripe3DS2/Stripe3DS2/STDSBrandingView.m | 132 + .../Stripe3DS2/Stripe3DS2/STDSBundleLocator.h | 15 + .../Stripe3DS2/Stripe3DS2/STDSBundleLocator.m | 109 + .../Stripe3DS2/STDSButtonCustomization.m | 69 + .../Stripe3DS2/STDSCategoryLinker.h | 20 + .../Stripe3DS2/STDSCategoryLinker.m | 53 + .../Stripe3DS2/STDSChallengeInformationView.h | 25 + .../Stripe3DS2/STDSChallengeInformationView.m | 137 + .../Stripe3DS2/STDSChallengeParameters.m | 31 + .../STDSChallengeRequestParameters.h | 138 + .../STDSChallengeRequestParameters.m | 105 + .../Stripe3DS2/STDSChallengeResponse.h | 145 + .../Stripe3DS2/STDSChallengeResponseImage.h | 27 + .../STDSChallengeResponseImageObject.h | 23 + .../STDSChallengeResponseImageObject.m | 53 + .../STDSChallengeResponseMessageExtension.h | 30 + ...SChallengeResponseMessageExtensionObject.h | 21 + ...SChallengeResponseMessageExtensionObject.m | 72 + .../Stripe3DS2/STDSChallengeResponseObject.h | 49 + .../Stripe3DS2/STDSChallengeResponseObject.m | 321 ++ .../STDSChallengeResponseSelectionInfo.h | 24 + ...STDSChallengeResponseSelectionInfoObject.h | 21 + ...STDSChallengeResponseSelectionInfoObject.m | 46 + .../STDSChallengeResponseViewController.h | 80 + .../STDSChallengeResponseViewController.m | 571 +++ .../Stripe3DS2/STDSChallengeSelectionView.h | 35 + .../Stripe3DS2/STDSChallengeSelectionView.m | 255 ++ .../Stripe3DS2/STDSCompletionEvent.m | 26 + .../Stripe3DS2/STDSConfigParameters.m | 113 + .../Stripe3DS2/Stripe3DS2/STDSCustomization.m | 25 + .../Stripe3DS2/STDSDebuggerChecker.h | 19 + .../Stripe3DS2/STDSDebuggerChecker.m | 54 + .../Stripe3DS2/STDSDeviceInformation.h | 21 + .../Stripe3DS2/STDSDeviceInformation.m | 30 + .../Stripe3DS2/STDSDeviceInformationManager.h | 23 + .../Stripe3DS2/STDSDeviceInformationManager.m | 65 + .../STDSDeviceInformationParameter+Private.h | 76 + .../STDSDeviceInformationParameter.h | 24 + .../STDSDeviceInformationParameter.m | 449 ++ .../Stripe3DS2/STDSDirectoryServer.h | 134 + .../STDSDirectoryServerCertificate+Internal.h | 22 + .../STDSDirectoryServerCertificate.h | 43 + .../STDSDirectoryServerCertificate.m | 350 ++ .../Stripe3DS2/STDSEllipticCurvePoint.h | 26 + .../Stripe3DS2/STDSEllipticCurvePoint.m | 90 + .../Stripe3DS2/STDSEphemeralKeyPair+Testing.h | 19 + .../Stripe3DS2/STDSEphemeralKeyPair.h | 39 + .../Stripe3DS2/STDSEphemeralKeyPair.m | 108 + .../Stripe3DS2/STDSErrorMessage+Internal.h | 40 + .../Stripe3DS2/STDSErrorMessage+Internal.m | 91 + .../Stripe3DS2/Stripe3DS2/STDSErrorMessage.m | 94 + .../Stripe3DS2/STDSException+Internal.h | 19 + .../Stripe3DS2/Stripe3DS2/STDSException.m | 27 + .../STDSExpandableInformationView.h | 23 + .../STDSExpandableInformationView.m | 150 + .../Stripe3DS2/STDSFooterCustomization.m | 45 + .../Stripe3DS2/Stripe3DS2/STDSIPAddress.h | 15 + .../Stripe3DS2/Stripe3DS2/STDSIPAddress.m | 43 + .../Stripe3DS2/Stripe3DS2/STDSImageLoader.h | 36 + .../Stripe3DS2/Stripe3DS2/STDSImageLoader.m | 50 + .../Stripe3DS2/STDSIntegrityChecker.h | 19 + .../Stripe3DS2/STDSIntegrityChecker.m | 41 + .../Stripe3DS2/STDSInvalidInputException.m | 17 + .../Stripe3DS2/Stripe3DS2/STDSJSONEncoder.m | 51 + .../Stripe3DS2/STDSJSONWebEncryption.h | 45 + .../Stripe3DS2/STDSJSONWebEncryption.m | 407 ++ .../Stripe3DS2/STDSJSONWebSignature.h | 41 + .../Stripe3DS2/STDSJSONWebSignature.m | 88 + .../Stripe3DS2/STDSJailbreakChecker.h | 19 + .../Stripe3DS2/STDSJailbreakChecker.m | 31 + .../Stripe3DS2/STDSLabelCustomization.m | 43 + .../Stripe3DS2/STDSLocalizedString.h | 18 + .../STDSNavigationBarCustomization.m | 44 + .../Stripe3DS2/STDSNotInitializedException.m | 17 + .../Stripe3DS2/STDSOSVersionChecker.h | 19 + .../Stripe3DS2/STDSOSVersionChecker.m | 25 + .../Stripe3DS2/STDSProcessingView.h | 26 + .../Stripe3DS2/STDSProcessingView.m | 98 + .../Stripe3DS2/STDSProgressViewController.h | 23 + .../Stripe3DS2/STDSProgressViewController.m | 55 + .../Stripe3DS2/STDSProtocolErrorEvent.m | 28 + .../Stripe3DS2/STDSRuntimeErrorEvent.m | 37 + .../Stripe3DS2/STDSRuntimeException.m | 17 + .../Stripe3DS2/STDSSecTypeUtilities.h | 49 + .../Stripe3DS2/STDSSecTypeUtilities.m | 366 ++ .../Stripe3DS2/STDSSelectionButton.h | 26 + .../Stripe3DS2/STDSSelectionButton.m | 167 + .../Stripe3DS2/STDSSelectionCustomization.m | 77 + .../Stripe3DS2/STDSSimulatorChecker.h | 19 + .../Stripe3DS2/STDSSimulatorChecker.m | 25 + .../Stripe3DS2/Stripe3DS2/STDSSpacerView.h | 20 + .../Stripe3DS2/Stripe3DS2/STDSSpacerView.m | 34 + .../Stripe3DS2/Stripe3DS2/STDSStackView.h | 56 + .../Stripe3DS2/Stripe3DS2/STDSStackView.m | 164 + .../Stripe3DS2/STDSStripe3DS2Error.m | 15 + .../Stripe3DS2/Stripe3DS2/STDSSwiftTryCatch.m | 59 + .../STDSSynchronousLocationManager.h | 26 + .../STDSSynchronousLocationManager.m | 110 + .../Stripe3DS2/STDSTextChallengeView.h | 26 + .../Stripe3DS2/STDSTextChallengeView.m | 133 + .../Stripe3DS2/STDSTextFieldCustomization.m | 50 + .../Stripe3DS2/STDSThreeDS2Service.m | 193 + .../STDSThreeDSProtocolVersion+Private.h | 53 + .../Stripe3DS2/STDSThreeDSProtocolVersion.m | 15 + .../Stripe3DS2/STDSTransaction+Private.h | 41 + .../Stripe3DS2/Stripe3DS2/STDSTransaction.m | 531 +++ .../Stripe3DS2/STDSUICustomization.m | 83 + .../Stripe3DS2/Stripe3DS2/STDSWarning.m | 30 + .../Stripe3DS2/Stripe3DS2/STDSWebView.h | 22 + .../Stripe3DS2/Stripe3DS2/STDSWebView.m | 37 + .../Stripe3DS2/Stripe3DS2/STDSWhitelistView.h | 25 + .../Stripe3DS2/Stripe3DS2/STDSWhitelistView.m | 103 + .../Stripe3DS2/Stripe3DS2-Bridging-Header.h | 12 + .../UIButton+CustomInitialization.h | 23 + .../UIButton+CustomInitialization.m | 66 + .../Stripe3DS2/UIColor+DefaultColors.h | 23 + .../Stripe3DS2/UIColor+DefaultColors.m | 33 + .../Stripe3DS2/UIColor+ThirteenSupport.h | 26 + .../Stripe3DS2/UIColor+ThirteenSupport.m | 55 + .../Stripe3DS2/UIFont+DefaultFonts.h | 25 + .../Stripe3DS2/UIFont+DefaultFonts.m | 43 + .../Stripe3DS2/UIView+LayoutSupport.h | 26 + .../Stripe3DS2/UIView+LayoutSupport.m | 41 + .../Stripe3DS2/UIViewController+Stripe3DS2.h | 23 + .../Stripe3DS2/UIViewController+Stripe3DS2.m | 51 + .../include/STDSAlreadyInitializedException.h | 22 + .../STDSAuthenticationRequestParameters.h | 68 + .../include/STDSAuthenticationResponse.h | 115 + .../include/STDSButtonCustomization.h | 83 + .../include/STDSChallengeParameters.h | 61 + .../include/STDSChallengeStatusReceiver.h | 67 + .../Stripe3DS2/include/STDSCompletionEvent.h | 40 + .../Stripe3DS2/include/STDSConfigParameters.h | 96 + .../Stripe3DS2/include/STDSCustomization.h | 25 + .../Stripe3DS2/include/STDSErrorMessage.h | 103 + .../Stripe3DS2/include/STDSException.h | 25 + .../include/STDSFooterCustomization.h | 41 + .../include/STDSInvalidInputException.h | 21 + .../Stripe3DS2/include/STDSJSONDecodable.h | 33 + .../Stripe3DS2/include/STDSJSONEncodable.h | 22 + .../Stripe3DS2/include/STDSJSONEncoder.h | 27 + .../include/STDSLabelCustomization.h | 31 + .../include/STDSNavigationBarCustomization.h | 59 + .../include/STDSNotInitializedException.h | 23 + .../include/STDSProtocolErrorEvent.h | 42 + .../include/STDSRuntimeErrorEvent.h | 53 + .../Stripe3DS2/include/STDSRuntimeException.h | 21 + .../include/STDSSelectionCustomization.h | 48 + .../Stripe3DS2/include/STDSStripe3DS2Error.h | 68 + .../Stripe3DS2/include/STDSSwiftTryCatch.h | 50 + .../include/STDSTextFieldCustomization.h | 47 + .../Stripe3DS2/include/STDSThreeDS2Service.h | 84 + .../include/STDSThreeDSProtocolVersion.h | 15 + .../Stripe3DS2/include/STDSTransaction.h | 94 + .../Stripe3DS2/include/STDSUICustomization.h | 109 + .../Stripe3DS2/include/STDSWarning.h | 69 + .../Stripe3DS2/include/Stripe3DS2.h | 52 + .../StripeAPI+Deprecated.swift | 169 + .../StripeApplePay+Import.swift | 9 + .../StripeCore+Import.swift | 10 + .../Models/ACH/LinkAccountSession.swift | 51 + .../ACH/STPCollectBankAccountParams.swift | 39 + .../STPConfirmAlipayOptions.swift | 57 + .../STPConfirmBLIKOptions.swift | 54 + .../STPConfirmCardOptions.swift | 53 + .../STPConfirmPaymentMethodOptions.swift | 66 + .../STPConfirmUSBankAccountOptions.swift | 47 + .../STPConfirmWeChatPayOptions.swift | 60 + .../PaymentIntents/STPPaymentIntent.swift | 390 ++ .../STPPaymentIntentAction.swift | 16 + .../STPPaymentIntentActionRedirectToURL.swift | 19 + .../STPPaymentIntentEnums.swift | 135 + .../STPPaymentIntentLastPaymentError.swift | 174 + .../STPPaymentIntentParams.swift | 298 ++ .../STPPaymentIntentShippingDetails.swift | 90 + ...PPaymentIntentShippingDetailsAddress.swift | 99 + ...ntIntentShippingDetailsAddressParams.swift | 116 + ...TPPaymentIntentShippingDetailsParams.swift | 110 + .../STPPaymentIntentSourceAction.swift | 17 + ...ntIntentSourceActionAuthorizeWithURL.swift | 21 + .../PaymentMethods/STPPaymentMethod.swift | 321 ++ .../STPPaymentMethodAddress.swift | 143 + .../STPPaymentMethodBillingDetails.swift | 132 + .../STPPaymentMethodEnums.swift | 138 + .../STPPaymentMethodParams.swift | 1186 +++++ .../Types/STPPaymentMethodAUBECSDebit.swift | 64 + .../STPPaymentMethodAUBECSDebitParams.swift | 31 + .../Types/STPPaymentMethodAffirm.swift | 44 + .../Types/STPPaymentMethodAffirmParams.swift | 23 + .../STPPaymentMethodAfterpayClearpay.swift | 43 + ...PPaymentMethodAfterpayClearpayParams.swift | 24 + .../Types/STPPaymentMethodAlipay.swift | 43 + .../Types/STPPaymentMethodAlipayParams.swift | 27 + .../Types/STPPaymentMethodBLIK.swift | 44 + .../Types/STPPaymentMethodBLIKParams.swift | 27 + .../Types/STPPaymentMethodBacsDebit.swift | 54 + .../STPPaymentMethodBacsDebitParams.swift | 33 + .../Types/STPPaymentMethodBancontact.swift | 41 + .../STPPaymentMethodBancontactParams.swift | 22 + .../Types/STPPaymentMethodBoleto.swift | 56 + .../Types/STPPaymentMethodBoletoParams.swift | 49 + .../Types/STPPaymentMethodCard.swift | 124 + .../Types/STPPaymentMethodCardChecks.swift | 102 + .../Types/STPPaymentMethodCardNetworks.swift | 53 + .../Types/STPPaymentMethodCardParams.swift | 124 + .../Types/STPPaymentMethodCardPresent.swift | 38 + .../Types/STPPaymentMethodCardWallet.swift | 111 + ...STPPaymentMethodCardWalletMasterpass.swift | 66 + ...PPaymentMethodCardWalletVisaCheckout.swift | 47 + .../Types/STPPaymentMethodEPS.swift | 42 + .../Types/STPPaymentMethodEPSParams.swift | 22 + .../Types/STPPaymentMethodFPX.swift | 46 + .../Types/STPPaymentMethodFPXParams.swift | 47 + .../Types/STPPaymentMethodGiropay.swift | 41 + .../Types/STPPaymentMethodGiropayParams.swift | 22 + .../Types/STPPaymentMethodGrabPay.swift | 40 + .../Types/STPPaymentMethodGrabPayParams.swift | 23 + .../Types/STPPaymentMethodKlarna.swift | 45 + .../Types/STPPaymentMethodKlarnaParams.swift | 24 + .../Types/STPPaymentMethodLink.swift | 42 + .../Types/STPPaymentMethodLinkParams.swift | 35 + .../Types/STPPaymentMethodNetBanking.swift | 50 + .../STPPaymentMethodNetBankingParams.swift | 29 + .../Types/STPPaymentMethodOXXO.swift | 40 + .../Types/STPPaymentMethodOXXOParams.swift | 25 + .../Types/STPPaymentMethodPayPal.swift | 42 + .../Types/STPPaymentMethodPayPalParams.swift | 24 + .../Types/STPPaymentMethodPrzelewy24.swift | 42 + .../STPPaymentMethodPrzelewy24Params.swift | 24 + .../Types/STPPaymentMethodSEPADebit.swift | 69 + .../STPPaymentMethodSEPADebitParams.swift | 30 + .../Types/STPPaymentMethodSofort.swift | 48 + .../Types/STPPaymentMethodSofortParams.swift | 29 + .../STPPaymentMethodThreeDSecureUsage.swift | 54 + .../Types/STPPaymentMethodUPI.swift | 50 + .../Types/STPPaymentMethodUPIParams.swift | 29 + .../Types/STPPaymentMethodUSBankAccount.swift | 213 + .../STPPaymentMethodUSBankAccountParams.swift | 80 + .../Types/STPPaymentMethodWeChatPay.swift | 42 + .../STPPaymentMethodWeChatPayParams.swift | 24 + .../Types/STPPaymentMethodiDEAL.swift | 51 + .../Types/STPPaymentMethodiDEALParams.swift | 30 + .../Models/STPAPIResponseDecodable.swift | 23 + .../API Bindings/Models/STPAddress.swift | 305 ++ .../API Bindings/Models/STPCardBrand.swift | 67 + .../Models/STPConnectAccountAddress.swift | 82 + .../STPConnectAccountCompanyParams.swift | 107 + .../STPConnectAccountIndividualParams.swift | 246 ++ .../Models/STPConnectAccountParams.swift | 161 + .../API Bindings/Models/STPContactField.swift | 39 + .../API Bindings/Models/STPCustomer.swift | 268 ++ .../API Bindings/Models/STPFPXBankBrand.swift | 333 ++ .../API Bindings/Models/STPFile.swift | 139 + .../Models/STPFormEncodable.swift | 23 + .../Models/STPIssuingCardPin.swift | 55 + .../API Bindings/Models/STPRadarSession.swift | 38 + .../API Bindings/Models/STPToken.swift | 160 + .../API Bindings/Models/STPiDEALBank.swift | 59 + .../Models/SetupIntents/STPSetupIntent.swift | 270 ++ .../STPSetupIntentConfirmParams.swift | 173 + .../SetupIntents/STPSetupIntentEnums.swift | 41 + .../STPSetupIntentLastSetupError.swift | 140 + .../Models/Shared/LinkSettings.swift | 50 + .../Models/Shared/STPIntentAction.swift | 333 ++ .../STPIntentActionAlipayHandleRedirect.swift | 126 + .../STPIntentActionBoletoDisplayDetails.swift | 68 + .../STPIntentActionOXXODisplayDetails.swift | 71 + .../Shared/STPIntentActionRedirectToURL.swift | 79 + ...PIntentActionVerifyWithMicrodeposits.swift | 88 + ...TPIntentActionWeChatPayRedirectToApp.swift | 64 + .../STPMandateCustomerAcceptanceParams.swift | 70 + .../Models/Shared/STPMandateDataParams.swift | 40 + .../Shared/STPMandateOnlineParams.swift | 68 + .../Shared/STPPaymentMethodOptions.swift | 120 + .../Models/Sources/STPSource.swift | 331 ++ .../Models/Sources/STPSourceEnums.swift | 100 + .../Models/Sources/STPSourceOwner.swift | 61 + .../Models/Sources/STPSourceParams.swift | 975 +++++ .../Models/Sources/STPSourceProtocol.swift | 18 + .../Models/Sources/STPSourceReceiver.swift | 64 + .../Models/Sources/STPSourceRedirect.swift | 113 + .../Sources/STPSourceVerification.swift | 100 + .../Models/Sources/Types/STPBankAccount.swift | 202 + .../Sources/Types/STPBankAccountParams.swift | 128 + .../Models/Sources/Types/STPCard.swift | 338 ++ .../Models/Sources/Types/STPCardParams.swift | 212 + .../Sources/Types/STPKlarnaLineItem.swift | 54 + .../Sources/Types/STPSourceCardDetails.swift | 135 + .../Types/STPSourceKlarnaDetails.swift | 50 + .../Types/STPSourceSEPADebitDetails.swift | 74 + .../Types/STPSourceWeChatPayDetails.swift | 44 + .../API Bindings/STPAPIClient+ApplePay.swift | 198 + .../STPAPIClient+LinkAccountSession.swift | 128 + .../API Bindings/STPAPIClient+Payments.swift | 935 ++++ .../API Bindings/STPAPIClient+Radar.swift | 52 + .../API Bindings/STPRedirectContext.swift | 602 +++ .../Enums+CustomStringConvertible.swift | 879 ++++ .../Helpers/STPBINController.swift | 409 ++ .../Helpers/STPBankAccountCollector.swift | 462 ++ .../StripePayments/Helpers/STPBlocks.swift | 122 + .../Helpers/STPCardValidator.swift | 470 ++ .../Helpers/STPLocalizedString.swift | 16 + .../STPPaymentConfirmation+SwiftUI.swift | 155 + .../Helpers/StripePayments+Export.swift | 10 + .../Helpers/StripePaymentsBundleLocator.swift | 19 + .../Internal/API Bindings/APIRequest.swift | 197 + .../STP3DS2AuthenticateResponse.swift | 81 + .../API Bindings/STPEmptyStripeResponse.swift | 30 + .../API Bindings/STPFormEncoder.swift | 97 + .../STPIntentActionUseStripeSDK.swift | 224 + .../STPInternalAPIResponseDecodable.swift | 16 + .../STPPaymentMethodListDeserializer.swift | 44 + .../API Bindings/STPSourcePoller.swift | 234 + .../Analytics/Analytic+Payments.swift | 59 + .../STPAnalyticsClient+Payments.swift | 350 ++ .../Internal/Categories/NSArray+Stripe.swift | 38 + .../NSDecimalNumber+Stripe_Currency.swift | 53 + .../Categories/NSDictionary+Stripe.swift | 131 + .../Internal/Categories/NSString+Stripe.swift | 73 + .../STPAPIClient+PaymentsCore.swift | 20 + .../Helpers/ConnectionsSDKAvailability.swift | 76 + .../STPPaymentHandlerActionParams.swift | 180 + .../STPAuthenticationContext.swift | 36 + .../PaymentHandler/STPPaymentHandler.swift | 2200 ++++++++++ .../STPThreeDSButtonCustomization.swift | 126 + .../STPThreeDSCustomizationSettings.swift | 44 + .../STPThreeDSFooterCustomization.swift | 88 + .../STPThreeDSLabelCustomization.swift | 67 + ...STPThreeDSNavigationBarCustomization.swift | 101 + .../STPThreeDSSelectionCustomization.swift | 72 + .../STPThreeDSTextFieldCustomization.swift | 94 + .../STPThreeDSUICustomization.swift | 193 + .../bg-BG.lproj/Localizable.strings | 57 + .../ca-ES.lproj/Localizable.strings | 57 + .../cs-CZ.lproj/Localizable.strings | 57 + .../da.lproj/Localizable.strings | 57 + .../de.lproj/Localizable.strings | 57 + .../el-GR.lproj/Localizable.strings | 57 + .../en-GB.lproj/Localizable.strings | 57 + .../en.lproj/Localizable.strings | 87 + .../es-419.lproj/Localizable.strings | 57 + .../es.lproj/Localizable.strings | 57 + .../et-EE.lproj/Localizable.strings | 57 + .../fi.lproj/Localizable.strings | 57 + .../fil.lproj/Localizable.strings | 57 + .../fr-CA.lproj/Localizable.strings | 57 + .../fr.lproj/Localizable.strings | 57 + .../hr.lproj/Localizable.strings | 57 + .../hu.lproj/Localizable.strings | 57 + .../id.lproj/Localizable.strings | 57 + .../it.lproj/Localizable.strings | 57 + .../ja.lproj/Localizable.strings | 57 + .../ko.lproj/Localizable.strings | 57 + .../lt-LT.lproj/Localizable.strings | 57 + .../lv-LV.lproj/Localizable.strings | 57 + .../ms-MY.lproj/Localizable.strings | 57 + .../mt.lproj/Localizable.strings | 57 + .../nb.lproj/Localizable.strings | 57 + .../nl.lproj/Localizable.strings | 57 + .../nn-NO.lproj/Localizable.strings | 57 + .../pl-PL.lproj/Localizable.strings | 57 + .../pt-BR.lproj/Localizable.strings | 57 + .../pt-PT.lproj/Localizable.strings | 57 + .../ro-RO.lproj/Localizable.strings | 57 + .../ru.lproj/Localizable.strings | 57 + .../sk-SK.lproj/Localizable.strings | 57 + .../sl-SI.lproj/Localizable.strings | 57 + .../sv.lproj/Localizable.strings | 57 + .../tk.lproj/Localizable.strings | 0 .../tr.lproj/Localizable.strings | 57 + .../vi.lproj/Localizable.strings | 57 + .../zh-HK.lproj/Localizable.strings | 57 + .../zh-Hans.lproj/Localizable.strings | 57 + .../zh-Hant.lproj/Localizable.strings | 57 + ...PaymentsLibTests-acknowledgements.markdown | 50 + ...-OSPaymentsLibTests-acknowledgements.plist | 62 + ...ts-frameworks-Debug-input-files.xcfilelist | 2 + ...s-frameworks-Debug-output-files.xcfilelist | 2 + ...-frameworks-Release-input-files.xcfilelist | 2 + ...frameworks-Release-output-files.xcfilelist | 2 + ...ymentsLib-OSPaymentsLibTests-frameworks.sh | 4 + ...mentsLib-OSPaymentsLibTests.debug.xcconfig | 6 +- ...ntsLib-OSPaymentsLibTests.release.xcconfig | 6 +- ...ds-OSPaymentsLib-acknowledgements.markdown | 50 + .../Pods-OSPaymentsLib-acknowledgements.plist | 62 + .../Pods-OSPaymentsLib.debug.xcconfig | 6 + .../Pods-OSPaymentsLib.release.xcconfig | 6 + ...rceBundle-StripeCore-StripeCore-Info.plist | 24 + .../StripeCore/StripeCore-Info.plist | 26 + .../StripeCore/StripeCore-dummy.m | 5 + .../StripeCore/StripeCore-prefix.pch | 12 + .../StripeCore/StripeCore-umbrella.h | 16 + .../StripeCore/StripeCore.debug.xcconfig | 15 + .../StripeCore/StripeCore.modulemap | 6 + .../StripeCore/StripeCore.release.xcconfig | 15 + ...undle-Stripe3DS2-StripePayments-Info.plist | 24 + ...e-StripePayments-StripePayments-Info.plist | 24 + .../StripePayments/StripePayments-Info.plist | 26 + .../StripePayments/StripePayments-dummy.m | 5 + .../StripePayments/StripePayments-prefix.pch | 12 + .../StripePayments/StripePayments-umbrella.h | 113 + .../StripePayments.debug.xcconfig | 16 + .../StripePayments/StripePayments.modulemap | 6 + .../StripePayments.release.xcconfig | 16 + docs/CHANGELOG.md | 3 + 600 files changed, 51677 insertions(+), 491 deletions(-) create mode 100644 OSPaymentsLib/Gateways/OSPMTGateway.swift create mode 100644 OSPaymentsLib/Gateways/OSPMTGatewayFactory.swift create mode 100644 OSPaymentsLib/Gateways/Stripe/OSPMTStripeAPIDelegate.swift create mode 100644 OSPaymentsLib/Gateways/Stripe/OSPMTStripeRequestParametersModel.swift create mode 100644 OSPaymentsLib/Gateways/Stripe/OSPMTStripeWrapper.swift create mode 100644 OSPaymentsLib/Models/OSPMTRequestParametersModel.swift create mode 100644 OSPaymentsLib/Models/OSPMTServiceProviderInfoModel.swift create mode 100644 OSPaymentsLib/Protocols/OSPMTGatewayDelegate.swift create mode 100644 OSPaymentsLibTests/OSPMTGatewayFactorySpec.swift create mode 100644 OSPaymentsLibTests/OSPMTStripeWrapperSpec.swift create mode 100644 Pods/StripeCore/LICENSE create mode 100644 Pods/StripeCore/README.md create mode 100644 Pods/StripeCore/StripeCore/StripeCore/Resources/Localizations/bg-BG.lproj/Localizable.strings create mode 100644 Pods/StripeCore/StripeCore/StripeCore/Resources/Localizations/ca-ES.lproj/Localizable.strings create mode 100644 Pods/StripeCore/StripeCore/StripeCore/Resources/Localizations/cs-CZ.lproj/Localizable.strings create mode 100644 Pods/StripeCore/StripeCore/StripeCore/Resources/Localizations/da.lproj/Localizable.strings create mode 100644 Pods/StripeCore/StripeCore/StripeCore/Resources/Localizations/de.lproj/Localizable.strings create mode 100644 Pods/StripeCore/StripeCore/StripeCore/Resources/Localizations/el-GR.lproj/Localizable.strings create mode 100644 Pods/StripeCore/StripeCore/StripeCore/Resources/Localizations/en-GB.lproj/Localizable.strings create mode 100644 Pods/StripeCore/StripeCore/StripeCore/Resources/Localizations/en.lproj/Localizable.strings create mode 100644 Pods/StripeCore/StripeCore/StripeCore/Resources/Localizations/es-419.lproj/Localizable.strings create mode 100644 Pods/StripeCore/StripeCore/StripeCore/Resources/Localizations/es.lproj/Localizable.strings create mode 100644 Pods/StripeCore/StripeCore/StripeCore/Resources/Localizations/et-EE.lproj/Localizable.strings create mode 100644 Pods/StripeCore/StripeCore/StripeCore/Resources/Localizations/fi.lproj/Localizable.strings create mode 100644 Pods/StripeCore/StripeCore/StripeCore/Resources/Localizations/fil.lproj/Localizable.strings create mode 100644 Pods/StripeCore/StripeCore/StripeCore/Resources/Localizations/fr-CA.lproj/Localizable.strings create mode 100644 Pods/StripeCore/StripeCore/StripeCore/Resources/Localizations/fr.lproj/Localizable.strings create mode 100644 Pods/StripeCore/StripeCore/StripeCore/Resources/Localizations/hr.lproj/Localizable.strings create mode 100644 Pods/StripeCore/StripeCore/StripeCore/Resources/Localizations/hu.lproj/Localizable.strings create mode 100644 Pods/StripeCore/StripeCore/StripeCore/Resources/Localizations/id.lproj/Localizable.strings create mode 100644 Pods/StripeCore/StripeCore/StripeCore/Resources/Localizations/it.lproj/Localizable.strings create mode 100644 Pods/StripeCore/StripeCore/StripeCore/Resources/Localizations/ja.lproj/Localizable.strings create mode 100644 Pods/StripeCore/StripeCore/StripeCore/Resources/Localizations/ko.lproj/Localizable.strings create mode 100644 Pods/StripeCore/StripeCore/StripeCore/Resources/Localizations/lt-LT.lproj/Localizable.strings create mode 100644 Pods/StripeCore/StripeCore/StripeCore/Resources/Localizations/lv-LV.lproj/Localizable.strings create mode 100644 Pods/StripeCore/StripeCore/StripeCore/Resources/Localizations/ms-MY.lproj/Localizable.strings create mode 100644 Pods/StripeCore/StripeCore/StripeCore/Resources/Localizations/mt.lproj/Localizable.strings create mode 100644 Pods/StripeCore/StripeCore/StripeCore/Resources/Localizations/nb.lproj/Localizable.strings create mode 100644 Pods/StripeCore/StripeCore/StripeCore/Resources/Localizations/nl.lproj/Localizable.strings create mode 100644 Pods/StripeCore/StripeCore/StripeCore/Resources/Localizations/nn-NO.lproj/Localizable.strings create mode 100644 Pods/StripeCore/StripeCore/StripeCore/Resources/Localizations/pl-PL.lproj/Localizable.strings create mode 100644 Pods/StripeCore/StripeCore/StripeCore/Resources/Localizations/pt-BR.lproj/Localizable.strings create mode 100644 Pods/StripeCore/StripeCore/StripeCore/Resources/Localizations/pt-PT.lproj/Localizable.strings create mode 100644 Pods/StripeCore/StripeCore/StripeCore/Resources/Localizations/ro-RO.lproj/Localizable.strings create mode 100644 Pods/StripeCore/StripeCore/StripeCore/Resources/Localizations/ru.lproj/Localizable.strings create mode 100644 Pods/StripeCore/StripeCore/StripeCore/Resources/Localizations/sk-SK.lproj/Localizable.strings create mode 100644 Pods/StripeCore/StripeCore/StripeCore/Resources/Localizations/sl-SI.lproj/Localizable.strings create mode 100644 Pods/StripeCore/StripeCore/StripeCore/Resources/Localizations/sv.lproj/Localizable.strings create mode 100644 Pods/StripeCore/StripeCore/StripeCore/Resources/Localizations/tr.lproj/Localizable.strings create mode 100644 Pods/StripeCore/StripeCore/StripeCore/Resources/Localizations/vi.lproj/Localizable.strings create mode 100644 Pods/StripeCore/StripeCore/StripeCore/Resources/Localizations/zh-HK.lproj/Localizable.strings create mode 100644 Pods/StripeCore/StripeCore/StripeCore/Resources/Localizations/zh-Hans.lproj/Localizable.strings create mode 100644 Pods/StripeCore/StripeCore/StripeCore/Resources/Localizations/zh-Hant.lproj/Localizable.strings create mode 100644 Pods/StripeCore/StripeCore/StripeCore/Source/API Bindings/Models/EmptyResponse.swift create mode 100644 Pods/StripeCore/StripeCore/StripeCore/Source/API Bindings/Models/StripeFile.swift create mode 100644 Pods/StripeCore/StripeCore/StripeCore/Source/API Bindings/STPAPIClient+FileUpload.swift create mode 100644 Pods/StripeCore/StripeCore/StripeCore/Source/API Bindings/STPAPIClient.swift create mode 100644 Pods/StripeCore/StripeCore/StripeCore/Source/API Bindings/STPAppInfo.swift create mode 100644 Pods/StripeCore/StripeCore/StripeCore/Source/API Bindings/STPMultipartFormDataEncoder.swift create mode 100644 Pods/StripeCore/StripeCore/StripeCore/Source/API Bindings/STPMultipartFormDataPart.swift create mode 100644 Pods/StripeCore/StripeCore/StripeCore/Source/API Bindings/StripeAPI.swift create mode 100644 Pods/StripeCore/StripeCore/StripeCore/Source/API Bindings/StripeAPIConfiguration+Version.swift create mode 100644 Pods/StripeCore/StripeCore/StripeCore/Source/API Bindings/StripeAPIConfiguration.swift create mode 100644 Pods/StripeCore/StripeCore/StripeCore/Source/API Bindings/StripeError.swift create mode 100644 Pods/StripeCore/StripeCore/StripeCore/Source/API Bindings/StripeServiceError.swift create mode 100644 Pods/StripeCore/StripeCore/StripeCore/Source/Analytics/Analytic.swift create mode 100644 Pods/StripeCore/StripeCore/StripeCore/Source/Analytics/AnalyticLoggableError.swift create mode 100644 Pods/StripeCore/StripeCore/StripeCore/Source/Analytics/AnalyticsClientV2.swift create mode 100644 Pods/StripeCore/StripeCore/StripeCore/Source/Analytics/PluginDetector.swift create mode 100644 Pods/StripeCore/StripeCore/StripeCore/Source/Analytics/STPAnalyticEvent.swift create mode 100644 Pods/StripeCore/StripeCore/StripeCore/Source/Analytics/STPAnalyticsClient.swift create mode 100644 Pods/StripeCore/StripeCore/StripeCore/Source/Categories/Decimal+StripeCore.swift create mode 100644 Pods/StripeCore/StripeCore/StripeCore/Source/Categories/Dictionary+Stripe.swift create mode 100644 Pods/StripeCore/StripeCore/StripeCore/Source/Categories/Enums+CustomStringConvertible.swift create mode 100644 Pods/StripeCore/StripeCore/StripeCore/Source/Categories/NSArray+Stripe.swift create mode 100644 Pods/StripeCore/StripeCore/StripeCore/Source/Categories/NSBundle+Stripe_AppName.swift create mode 100644 Pods/StripeCore/StripeCore/StripeCore/Source/Categories/NSCharacterSet+StripeCore.swift create mode 100644 Pods/StripeCore/StripeCore/StripeCore/Source/Categories/NSError+Stripe.swift create mode 100644 Pods/StripeCore/StripeCore/StripeCore/Source/Categories/NSError+StripeCore.swift create mode 100644 Pods/StripeCore/StripeCore/StripeCore/Source/Categories/NSMutableURLRequest+Stripe.swift create mode 100644 Pods/StripeCore/StripeCore/StripeCore/Source/Categories/NSURLComponents+Stripe.swift create mode 100644 Pods/StripeCore/StripeCore/StripeCore/Source/Categories/String+StripeCore.swift create mode 100644 Pods/StripeCore/StripeCore/StripeCore/Source/Categories/UIImage+StripeCore.swift create mode 100644 Pods/StripeCore/StripeCore/StripeCore/Source/Coder/StripeCodable.swift create mode 100644 Pods/StripeCore/StripeCore/StripeCore/Source/Coder/StripeJSONDecoder.swift create mode 100644 Pods/StripeCore/StripeCore/StripeCore/Source/Coder/StripeJSONEncoder.swift create mode 100644 Pods/StripeCore/StripeCore/StripeCore/Source/Coder/StripeJSONShared.swift create mode 100644 Pods/StripeCore/StripeCore/StripeCore/Source/Coder/UnknownFields.swift create mode 100644 Pods/StripeCore/StripeCore/StripeCore/Source/Connections Bindings/ConnectionsSDKInterface.swift create mode 100644 Pods/StripeCore/StripeCore/StripeCore/Source/DownloadManager/DownloadManager.swift create mode 100644 Pods/StripeCore/StripeCore/StripeCore/Source/Helpers/Async.swift create mode 100644 Pods/StripeCore/StripeCore/StripeCore/Source/Helpers/BundleLocatorProtocol.swift create mode 100644 Pods/StripeCore/StripeCore/StripeCore/Source/Helpers/FileDownloader.swift create mode 100644 Pods/StripeCore/StripeCore/StripeCore/Source/Helpers/InstallMethod.swift create mode 100644 Pods/StripeCore/StripeCore/StripeCore/Source/Helpers/PaymentsSDKVariant.swift create mode 100644 Pods/StripeCore/StripeCore/StripeCore/Source/Helpers/STPDeviceUtils.swift create mode 100644 Pods/StripeCore/StripeCore/StripeCore/Source/Helpers/STPDispatchFunctions.swift create mode 100644 Pods/StripeCore/StripeCore/StripeCore/Source/Helpers/STPError.swift create mode 100644 Pods/StripeCore/StripeCore/StripeCore/Source/Helpers/STPNumericStringValidator.swift create mode 100644 Pods/StripeCore/StripeCore/StripeCore/Source/Helpers/STPURLCallbackHandler.swift create mode 100644 Pods/StripeCore/StripeCore/StripeCore/Source/Helpers/ServerErrorMapper.swift create mode 100644 Pods/StripeCore/StripeCore/StripeCore/Source/Helpers/StripeCoreBundleLocator.swift create mode 100644 Pods/StripeCore/StripeCore/StripeCore/Source/Helpers/URLEncoder.swift create mode 100644 Pods/StripeCore/StripeCore/StripeCore/Source/Helpers/URLSession+Retry.swift create mode 100644 Pods/StripeCore/StripeCore/StripeCore/Source/Localization/STPLocalizationUtils.swift create mode 100644 Pods/StripeCore/StripeCore/StripeCore/Source/Localization/STPLocalizedString.swift create mode 100644 Pods/StripeCore/StripeCore/StripeCore/Source/Localization/String+Localized.swift create mode 100644 Pods/StripeCore/StripeCore/StripeCore/Source/Telemetry/FraudDetectionData.swift create mode 100644 Pods/StripeCore/StripeCore/StripeCore/Source/Telemetry/STPTelemetryClient.swift create mode 100644 Pods/StripeCore/StripeCore/StripeCore/Source/Telemetry/UserDefaults+PaymentsCore.swift create mode 100644 Pods/StripeCore/StripeCore/StripeCore/Source/UI/UIActivityIndicatorView+Stripe.swift create mode 100644 Pods/StripeCore/StripeCore/StripeCore/Source/UI/UIFont+Stripe.swift create mode 100644 Pods/StripePayments/LICENSE create mode 100644 Pods/StripePayments/README.md create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/NSData+JWEHelpers.h create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/NSData+JWEHelpers.m create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/NSDictionary+DecodingHelpers.h create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/NSDictionary+DecodingHelpers.m create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/NSError+Stripe3DS2.h create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/NSError+Stripe3DS2.m create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/NSLayoutConstraint+LayoutSupport.h create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/NSLayoutConstraint+LayoutSupport.m create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/NSString+EmptyChecking.h create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/NSString+EmptyChecking.m create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/NSString+JWEHelpers.h create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/NSString+JWEHelpers.m create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/Resources/Images/Chevron@3x.png create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/Resources/Images/amex-logo@3x.png create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/Resources/Images/cartes-bancaires-logo.png create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/Resources/Images/discover-logo.png create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/Resources/Images/error@3x.png create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/Resources/Images/mastercard-logo@3x.png create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/Resources/Images/visa-logo@3x.png create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/Resources/Images/visa-white-logo@3x.png create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/Resources/bg-BG.lproj/Localizable.strings create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/Resources/ca-ES.lproj/Localizable.strings create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/Resources/cs-CZ.lproj/Localizable.strings create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/Resources/da.lproj/Localizable.strings create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/Resources/de.lproj/Localizable.strings create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/Resources/el-GR.lproj/Localizable.strings create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/Resources/en-GB.lproj/Localizable.strings create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/Resources/en.lproj/Localizable.strings create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/Resources/es-419.lproj/Localizable.strings create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/Resources/es.lproj/Localizable.strings create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/Resources/et-EE.lproj/Localizable.strings create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/Resources/fi.lproj/Localizable.strings create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/Resources/fil.lproj/Localizable.strings create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/Resources/fr-CA.lproj/Localizable.strings create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/Resources/fr.lproj/Localizable.strings create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/Resources/hr.lproj/Localizable.strings create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/Resources/hu.lproj/Localizable.strings create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/Resources/id.lproj/Localizable.strings create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/Resources/it.lproj/Localizable.strings create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/Resources/ja.lproj/Localizable.strings create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/Resources/ko.lproj/Localizable.strings create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/Resources/lt-LT.lproj/Localizable.strings create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/Resources/lv-LV.lproj/Localizable.strings create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/Resources/ms-MY.lproj/Localizable.strings create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/Resources/mt.lproj/Localizable.strings create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/Resources/nb.lproj/Localizable.strings create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/Resources/nl.lproj/Localizable.strings create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/Resources/nn-NO.lproj/Localizable.strings create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/Resources/pl-PL.lproj/Localizable.strings create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/Resources/pt-BR.lproj/Localizable.strings create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/Resources/pt-PT.lproj/Localizable.strings create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/Resources/ro-RO.lproj/Localizable.strings create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/Resources/ru.lproj/Localizable.strings create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/Resources/sk-SK.lproj/Localizable.strings create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/Resources/sl-SI.lproj/Localizable.strings create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/Resources/sv.lproj/Localizable.strings create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/Resources/tr.lproj/Localizable.strings create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/Resources/vi.lproj/Localizable.strings create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/Resources/zh-HK.lproj/Localizable.strings create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/Resources/zh-Hans.lproj/Localizable.strings create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/Resources/zh-Hant.lproj/Localizable.strings create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSACSNetworkingManager.h create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSACSNetworkingManager.m create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSAlreadyInitializedException.m create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSAuthenticationRequestParameters.m create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSAuthenticationResponseObject.h create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSAuthenticationResponseObject.m create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSBrandingView.h create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSBrandingView.m create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSBundleLocator.h create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSBundleLocator.m create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSButtonCustomization.m create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSCategoryLinker.h create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSCategoryLinker.m create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSChallengeInformationView.h create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSChallengeInformationView.m create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSChallengeParameters.m create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSChallengeRequestParameters.h create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSChallengeRequestParameters.m create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSChallengeResponse.h create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSChallengeResponseImage.h create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSChallengeResponseImageObject.h create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSChallengeResponseImageObject.m create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSChallengeResponseMessageExtension.h create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSChallengeResponseMessageExtensionObject.h create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSChallengeResponseMessageExtensionObject.m create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSChallengeResponseObject.h create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSChallengeResponseObject.m create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSChallengeResponseSelectionInfo.h create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSChallengeResponseSelectionInfoObject.h create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSChallengeResponseSelectionInfoObject.m create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSChallengeResponseViewController.h create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSChallengeResponseViewController.m create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSChallengeSelectionView.h create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSChallengeSelectionView.m create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSCompletionEvent.m create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSConfigParameters.m create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSCustomization.m create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSDebuggerChecker.h create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSDebuggerChecker.m create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSDeviceInformation.h create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSDeviceInformation.m create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSDeviceInformationManager.h create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSDeviceInformationManager.m create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSDeviceInformationParameter+Private.h create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSDeviceInformationParameter.h create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSDeviceInformationParameter.m create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSDirectoryServer.h create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSDirectoryServerCertificate+Internal.h create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSDirectoryServerCertificate.h create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSDirectoryServerCertificate.m create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSEllipticCurvePoint.h create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSEllipticCurvePoint.m create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSEphemeralKeyPair+Testing.h create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSEphemeralKeyPair.h create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSEphemeralKeyPair.m create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSErrorMessage+Internal.h create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSErrorMessage+Internal.m create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSErrorMessage.m create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSException+Internal.h create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSException.m create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSExpandableInformationView.h create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSExpandableInformationView.m create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSFooterCustomization.m create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSIPAddress.h create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSIPAddress.m create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSImageLoader.h create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSImageLoader.m create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSIntegrityChecker.h create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSIntegrityChecker.m create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSInvalidInputException.m create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSJSONEncoder.m create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSJSONWebEncryption.h create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSJSONWebEncryption.m create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSJSONWebSignature.h create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSJSONWebSignature.m create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSJailbreakChecker.h create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSJailbreakChecker.m create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSLabelCustomization.m create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSLocalizedString.h create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSNavigationBarCustomization.m create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSNotInitializedException.m create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSOSVersionChecker.h create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSOSVersionChecker.m create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSProcessingView.h create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSProcessingView.m create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSProgressViewController.h create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSProgressViewController.m create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSProtocolErrorEvent.m create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSRuntimeErrorEvent.m create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSRuntimeException.m create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSSecTypeUtilities.h create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSSecTypeUtilities.m create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSSelectionButton.h create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSSelectionButton.m create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSSelectionCustomization.m create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSSimulatorChecker.h create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSSimulatorChecker.m create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSSpacerView.h create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSSpacerView.m create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSStackView.h create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSStackView.m create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSStripe3DS2Error.m create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSSwiftTryCatch.m create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSSynchronousLocationManager.h create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSSynchronousLocationManager.m create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSTextChallengeView.h create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSTextChallengeView.m create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSTextFieldCustomization.m create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSThreeDS2Service.m create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSThreeDSProtocolVersion+Private.h create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSThreeDSProtocolVersion.m create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSTransaction+Private.h create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSTransaction.m create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSUICustomization.m create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSWarning.m create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSWebView.h create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSWebView.m create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSWhitelistView.h create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSWhitelistView.m create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/Stripe3DS2-Bridging-Header.h create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/UIButton+CustomInitialization.h create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/UIButton+CustomInitialization.m create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/UIColor+DefaultColors.h create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/UIColor+DefaultColors.m create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/UIColor+ThirteenSupport.h create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/UIColor+ThirteenSupport.m create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/UIFont+DefaultFonts.h create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/UIFont+DefaultFonts.m create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/UIView+LayoutSupport.h create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/UIView+LayoutSupport.m create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/UIViewController+Stripe3DS2.h create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/UIViewController+Stripe3DS2.m create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/include/STDSAlreadyInitializedException.h create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/include/STDSAuthenticationRequestParameters.h create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/include/STDSAuthenticationResponse.h create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/include/STDSButtonCustomization.h create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/include/STDSChallengeParameters.h create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/include/STDSChallengeStatusReceiver.h create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/include/STDSCompletionEvent.h create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/include/STDSConfigParameters.h create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/include/STDSCustomization.h create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/include/STDSErrorMessage.h create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/include/STDSException.h create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/include/STDSFooterCustomization.h create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/include/STDSInvalidInputException.h create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/include/STDSJSONDecodable.h create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/include/STDSJSONEncodable.h create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/include/STDSJSONEncoder.h create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/include/STDSLabelCustomization.h create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/include/STDSNavigationBarCustomization.h create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/include/STDSNotInitializedException.h create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/include/STDSProtocolErrorEvent.h create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/include/STDSRuntimeErrorEvent.h create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/include/STDSRuntimeException.h create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/include/STDSSelectionCustomization.h create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/include/STDSStripe3DS2Error.h create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/include/STDSSwiftTryCatch.h create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/include/STDSTextFieldCustomization.h create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/include/STDSThreeDS2Service.h create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/include/STDSThreeDSProtocolVersion.h create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/include/STDSTransaction.h create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/include/STDSUICustomization.h create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/include/STDSWarning.h create mode 100644 Pods/StripePayments/Stripe3DS2/Stripe3DS2/include/Stripe3DS2.h create mode 100644 Pods/StripePayments/StripePayments/StripePayments/API Bindings/Legacy Compatability/StripeAPI+Deprecated.swift create mode 100644 Pods/StripePayments/StripePayments/StripePayments/API Bindings/Legacy Compatability/StripeApplePay+Import.swift create mode 100644 Pods/StripePayments/StripePayments/StripePayments/API Bindings/Legacy Compatability/StripeCore+Import.swift create mode 100644 Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/ACH/LinkAccountSession.swift create mode 100644 Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/ACH/STPCollectBankAccountParams.swift create mode 100644 Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentIntents/STPConfirmAlipayOptions.swift create mode 100644 Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentIntents/STPConfirmBLIKOptions.swift create mode 100644 Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentIntents/STPConfirmCardOptions.swift create mode 100644 Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentIntents/STPConfirmPaymentMethodOptions.swift create mode 100644 Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentIntents/STPConfirmUSBankAccountOptions.swift create mode 100644 Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentIntents/STPConfirmWeChatPayOptions.swift create mode 100644 Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentIntents/STPPaymentIntent.swift create mode 100644 Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentIntents/STPPaymentIntentAction.swift create mode 100644 Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentIntents/STPPaymentIntentActionRedirectToURL.swift create mode 100644 Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentIntents/STPPaymentIntentEnums.swift create mode 100644 Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentIntents/STPPaymentIntentLastPaymentError.swift create mode 100644 Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentIntents/STPPaymentIntentParams.swift create mode 100644 Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentIntents/STPPaymentIntentShippingDetails.swift create mode 100644 Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentIntents/STPPaymentIntentShippingDetailsAddress.swift create mode 100644 Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentIntents/STPPaymentIntentShippingDetailsAddressParams.swift create mode 100644 Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentIntents/STPPaymentIntentShippingDetailsParams.swift create mode 100644 Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentIntents/STPPaymentIntentSourceAction.swift create mode 100644 Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentIntents/STPPaymentIntentSourceActionAuthorizeWithURL.swift create mode 100644 Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/STPPaymentMethod.swift create mode 100644 Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/STPPaymentMethodAddress.swift create mode 100644 Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/STPPaymentMethodBillingDetails.swift create mode 100644 Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/STPPaymentMethodEnums.swift create mode 100644 Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/STPPaymentMethodParams.swift create mode 100644 Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodAUBECSDebit.swift create mode 100644 Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodAUBECSDebitParams.swift create mode 100644 Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodAffirm.swift create mode 100644 Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodAffirmParams.swift create mode 100644 Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodAfterpayClearpay.swift create mode 100644 Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodAfterpayClearpayParams.swift create mode 100644 Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodAlipay.swift create mode 100644 Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodAlipayParams.swift create mode 100644 Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodBLIK.swift create mode 100644 Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodBLIKParams.swift create mode 100644 Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodBacsDebit.swift create mode 100644 Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodBacsDebitParams.swift create mode 100644 Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodBancontact.swift create mode 100644 Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodBancontactParams.swift create mode 100644 Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodBoleto.swift create mode 100644 Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodBoletoParams.swift create mode 100644 Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodCard.swift create mode 100644 Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodCardChecks.swift create mode 100644 Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodCardNetworks.swift create mode 100644 Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodCardParams.swift create mode 100644 Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodCardPresent.swift create mode 100644 Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodCardWallet.swift create mode 100644 Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodCardWalletMasterpass.swift create mode 100644 Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodCardWalletVisaCheckout.swift create mode 100644 Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodEPS.swift create mode 100644 Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodEPSParams.swift create mode 100644 Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodFPX.swift create mode 100644 Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodFPXParams.swift create mode 100644 Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodGiropay.swift create mode 100644 Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodGiropayParams.swift create mode 100644 Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodGrabPay.swift create mode 100644 Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodGrabPayParams.swift create mode 100644 Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodKlarna.swift create mode 100644 Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodKlarnaParams.swift create mode 100644 Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodLink.swift create mode 100644 Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodLinkParams.swift create mode 100644 Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodNetBanking.swift create mode 100644 Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodNetBankingParams.swift create mode 100644 Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodOXXO.swift create mode 100644 Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodOXXOParams.swift create mode 100644 Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodPayPal.swift create mode 100644 Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodPayPalParams.swift create mode 100644 Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodPrzelewy24.swift create mode 100644 Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodPrzelewy24Params.swift create mode 100644 Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodSEPADebit.swift create mode 100644 Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodSEPADebitParams.swift create mode 100644 Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodSofort.swift create mode 100644 Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodSofortParams.swift create mode 100644 Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodThreeDSecureUsage.swift create mode 100644 Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodUPI.swift create mode 100644 Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodUPIParams.swift create mode 100644 Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodUSBankAccount.swift create mode 100644 Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodUSBankAccountParams.swift create mode 100644 Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodWeChatPay.swift create mode 100644 Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodWeChatPayParams.swift create mode 100644 Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodiDEAL.swift create mode 100644 Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodiDEALParams.swift create mode 100644 Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/STPAPIResponseDecodable.swift create mode 100644 Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/STPAddress.swift create mode 100644 Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/STPCardBrand.swift create mode 100644 Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/STPConnectAccountAddress.swift create mode 100644 Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/STPConnectAccountCompanyParams.swift create mode 100644 Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/STPConnectAccountIndividualParams.swift create mode 100644 Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/STPConnectAccountParams.swift create mode 100644 Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/STPContactField.swift create mode 100644 Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/STPCustomer.swift create mode 100644 Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/STPFPXBankBrand.swift create mode 100644 Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/STPFile.swift create mode 100644 Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/STPFormEncodable.swift create mode 100644 Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/STPIssuingCardPin.swift create mode 100644 Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/STPRadarSession.swift create mode 100644 Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/STPToken.swift create mode 100644 Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/STPiDEALBank.swift create mode 100644 Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/SetupIntents/STPSetupIntent.swift create mode 100644 Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/SetupIntents/STPSetupIntentConfirmParams.swift create mode 100644 Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/SetupIntents/STPSetupIntentEnums.swift create mode 100644 Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/SetupIntents/STPSetupIntentLastSetupError.swift create mode 100644 Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/Shared/LinkSettings.swift create mode 100644 Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/Shared/STPIntentAction.swift create mode 100644 Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/Shared/STPIntentActionAlipayHandleRedirect.swift create mode 100644 Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/Shared/STPIntentActionBoletoDisplayDetails.swift create mode 100644 Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/Shared/STPIntentActionOXXODisplayDetails.swift create mode 100644 Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/Shared/STPIntentActionRedirectToURL.swift create mode 100644 Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/Shared/STPIntentActionVerifyWithMicrodeposits.swift create mode 100644 Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/Shared/STPIntentActionWeChatPayRedirectToApp.swift create mode 100644 Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/Shared/STPMandateCustomerAcceptanceParams.swift create mode 100644 Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/Shared/STPMandateDataParams.swift create mode 100644 Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/Shared/STPMandateOnlineParams.swift create mode 100644 Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/Shared/STPPaymentMethodOptions.swift create mode 100644 Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/Sources/STPSource.swift create mode 100644 Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/Sources/STPSourceEnums.swift create mode 100644 Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/Sources/STPSourceOwner.swift create mode 100644 Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/Sources/STPSourceParams.swift create mode 100644 Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/Sources/STPSourceProtocol.swift create mode 100644 Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/Sources/STPSourceReceiver.swift create mode 100644 Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/Sources/STPSourceRedirect.swift create mode 100644 Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/Sources/STPSourceVerification.swift create mode 100644 Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/Sources/Types/STPBankAccount.swift create mode 100644 Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/Sources/Types/STPBankAccountParams.swift create mode 100644 Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/Sources/Types/STPCard.swift create mode 100644 Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/Sources/Types/STPCardParams.swift create mode 100644 Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/Sources/Types/STPKlarnaLineItem.swift create mode 100644 Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/Sources/Types/STPSourceCardDetails.swift create mode 100644 Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/Sources/Types/STPSourceKlarnaDetails.swift create mode 100644 Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/Sources/Types/STPSourceSEPADebitDetails.swift create mode 100644 Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/Sources/Types/STPSourceWeChatPayDetails.swift create mode 100644 Pods/StripePayments/StripePayments/StripePayments/API Bindings/STPAPIClient+ApplePay.swift create mode 100644 Pods/StripePayments/StripePayments/StripePayments/API Bindings/STPAPIClient+LinkAccountSession.swift create mode 100644 Pods/StripePayments/StripePayments/StripePayments/API Bindings/STPAPIClient+Payments.swift create mode 100644 Pods/StripePayments/StripePayments/StripePayments/API Bindings/STPAPIClient+Radar.swift create mode 100644 Pods/StripePayments/StripePayments/StripePayments/API Bindings/STPRedirectContext.swift create mode 100644 Pods/StripePayments/StripePayments/StripePayments/Categories/Enums+CustomStringConvertible.swift create mode 100644 Pods/StripePayments/StripePayments/StripePayments/Helpers/STPBINController.swift create mode 100644 Pods/StripePayments/StripePayments/StripePayments/Helpers/STPBankAccountCollector.swift create mode 100644 Pods/StripePayments/StripePayments/StripePayments/Helpers/STPBlocks.swift create mode 100644 Pods/StripePayments/StripePayments/StripePayments/Helpers/STPCardValidator.swift create mode 100644 Pods/StripePayments/StripePayments/StripePayments/Helpers/STPLocalizedString.swift create mode 100644 Pods/StripePayments/StripePayments/StripePayments/Helpers/STPPaymentConfirmation+SwiftUI.swift create mode 100644 Pods/StripePayments/StripePayments/StripePayments/Helpers/StripePayments+Export.swift create mode 100644 Pods/StripePayments/StripePayments/StripePayments/Helpers/StripePaymentsBundleLocator.swift create mode 100644 Pods/StripePayments/StripePayments/StripePayments/Internal/API Bindings/APIRequest.swift create mode 100644 Pods/StripePayments/StripePayments/StripePayments/Internal/API Bindings/STP3DS2AuthenticateResponse.swift create mode 100644 Pods/StripePayments/StripePayments/StripePayments/Internal/API Bindings/STPEmptyStripeResponse.swift create mode 100644 Pods/StripePayments/StripePayments/StripePayments/Internal/API Bindings/STPFormEncoder.swift create mode 100644 Pods/StripePayments/StripePayments/StripePayments/Internal/API Bindings/STPIntentActionUseStripeSDK.swift create mode 100644 Pods/StripePayments/StripePayments/StripePayments/Internal/API Bindings/STPInternalAPIResponseDecodable.swift create mode 100644 Pods/StripePayments/StripePayments/StripePayments/Internal/API Bindings/STPPaymentMethodListDeserializer.swift create mode 100644 Pods/StripePayments/StripePayments/StripePayments/Internal/API Bindings/STPSourcePoller.swift create mode 100644 Pods/StripePayments/StripePayments/StripePayments/Internal/Analytics/Analytic+Payments.swift create mode 100644 Pods/StripePayments/StripePayments/StripePayments/Internal/Analytics/STPAnalyticsClient+Payments.swift create mode 100644 Pods/StripePayments/StripePayments/StripePayments/Internal/Categories/NSArray+Stripe.swift create mode 100644 Pods/StripePayments/StripePayments/StripePayments/Internal/Categories/NSDecimalNumber+Stripe_Currency.swift create mode 100644 Pods/StripePayments/StripePayments/StripePayments/Internal/Categories/NSDictionary+Stripe.swift create mode 100644 Pods/StripePayments/StripePayments/StripePayments/Internal/Categories/NSString+Stripe.swift create mode 100644 Pods/StripePayments/StripePayments/StripePayments/Internal/Categories/STPAPIClient+PaymentsCore.swift create mode 100644 Pods/StripePayments/StripePayments/StripePayments/Internal/Helpers/ConnectionsSDKAvailability.swift create mode 100644 Pods/StripePayments/StripePayments/StripePayments/Internal/STPPaymentHandlerActionParams.swift create mode 100644 Pods/StripePayments/StripePayments/StripePayments/PaymentHandler/STPAuthenticationContext.swift create mode 100644 Pods/StripePayments/StripePayments/StripePayments/PaymentHandler/STPPaymentHandler.swift create mode 100644 Pods/StripePayments/StripePayments/StripePayments/PaymentHandler/STPThreeDSButtonCustomization.swift create mode 100644 Pods/StripePayments/StripePayments/StripePayments/PaymentHandler/STPThreeDSCustomizationSettings.swift create mode 100644 Pods/StripePayments/StripePayments/StripePayments/PaymentHandler/STPThreeDSFooterCustomization.swift create mode 100644 Pods/StripePayments/StripePayments/StripePayments/PaymentHandler/STPThreeDSLabelCustomization.swift create mode 100644 Pods/StripePayments/StripePayments/StripePayments/PaymentHandler/STPThreeDSNavigationBarCustomization.swift create mode 100644 Pods/StripePayments/StripePayments/StripePayments/PaymentHandler/STPThreeDSSelectionCustomization.swift create mode 100644 Pods/StripePayments/StripePayments/StripePayments/PaymentHandler/STPThreeDSTextFieldCustomization.swift create mode 100644 Pods/StripePayments/StripePayments/StripePayments/PaymentHandler/STPThreeDSUICustomization.swift create mode 100644 Pods/StripePayments/StripePayments/StripePayments/Resources/Localizations/bg-BG.lproj/Localizable.strings create mode 100644 Pods/StripePayments/StripePayments/StripePayments/Resources/Localizations/ca-ES.lproj/Localizable.strings create mode 100644 Pods/StripePayments/StripePayments/StripePayments/Resources/Localizations/cs-CZ.lproj/Localizable.strings create mode 100644 Pods/StripePayments/StripePayments/StripePayments/Resources/Localizations/da.lproj/Localizable.strings create mode 100644 Pods/StripePayments/StripePayments/StripePayments/Resources/Localizations/de.lproj/Localizable.strings create mode 100644 Pods/StripePayments/StripePayments/StripePayments/Resources/Localizations/el-GR.lproj/Localizable.strings create mode 100644 Pods/StripePayments/StripePayments/StripePayments/Resources/Localizations/en-GB.lproj/Localizable.strings create mode 100644 Pods/StripePayments/StripePayments/StripePayments/Resources/Localizations/en.lproj/Localizable.strings create mode 100644 Pods/StripePayments/StripePayments/StripePayments/Resources/Localizations/es-419.lproj/Localizable.strings create mode 100644 Pods/StripePayments/StripePayments/StripePayments/Resources/Localizations/es.lproj/Localizable.strings create mode 100644 Pods/StripePayments/StripePayments/StripePayments/Resources/Localizations/et-EE.lproj/Localizable.strings create mode 100644 Pods/StripePayments/StripePayments/StripePayments/Resources/Localizations/fi.lproj/Localizable.strings create mode 100644 Pods/StripePayments/StripePayments/StripePayments/Resources/Localizations/fil.lproj/Localizable.strings create mode 100644 Pods/StripePayments/StripePayments/StripePayments/Resources/Localizations/fr-CA.lproj/Localizable.strings create mode 100644 Pods/StripePayments/StripePayments/StripePayments/Resources/Localizations/fr.lproj/Localizable.strings create mode 100644 Pods/StripePayments/StripePayments/StripePayments/Resources/Localizations/hr.lproj/Localizable.strings create mode 100644 Pods/StripePayments/StripePayments/StripePayments/Resources/Localizations/hu.lproj/Localizable.strings create mode 100644 Pods/StripePayments/StripePayments/StripePayments/Resources/Localizations/id.lproj/Localizable.strings create mode 100644 Pods/StripePayments/StripePayments/StripePayments/Resources/Localizations/it.lproj/Localizable.strings create mode 100644 Pods/StripePayments/StripePayments/StripePayments/Resources/Localizations/ja.lproj/Localizable.strings create mode 100644 Pods/StripePayments/StripePayments/StripePayments/Resources/Localizations/ko.lproj/Localizable.strings create mode 100644 Pods/StripePayments/StripePayments/StripePayments/Resources/Localizations/lt-LT.lproj/Localizable.strings create mode 100644 Pods/StripePayments/StripePayments/StripePayments/Resources/Localizations/lv-LV.lproj/Localizable.strings create mode 100644 Pods/StripePayments/StripePayments/StripePayments/Resources/Localizations/ms-MY.lproj/Localizable.strings create mode 100644 Pods/StripePayments/StripePayments/StripePayments/Resources/Localizations/mt.lproj/Localizable.strings create mode 100644 Pods/StripePayments/StripePayments/StripePayments/Resources/Localizations/nb.lproj/Localizable.strings create mode 100644 Pods/StripePayments/StripePayments/StripePayments/Resources/Localizations/nl.lproj/Localizable.strings create mode 100644 Pods/StripePayments/StripePayments/StripePayments/Resources/Localizations/nn-NO.lproj/Localizable.strings create mode 100644 Pods/StripePayments/StripePayments/StripePayments/Resources/Localizations/pl-PL.lproj/Localizable.strings create mode 100644 Pods/StripePayments/StripePayments/StripePayments/Resources/Localizations/pt-BR.lproj/Localizable.strings create mode 100644 Pods/StripePayments/StripePayments/StripePayments/Resources/Localizations/pt-PT.lproj/Localizable.strings create mode 100644 Pods/StripePayments/StripePayments/StripePayments/Resources/Localizations/ro-RO.lproj/Localizable.strings create mode 100644 Pods/StripePayments/StripePayments/StripePayments/Resources/Localizations/ru.lproj/Localizable.strings create mode 100644 Pods/StripePayments/StripePayments/StripePayments/Resources/Localizations/sk-SK.lproj/Localizable.strings create mode 100644 Pods/StripePayments/StripePayments/StripePayments/Resources/Localizations/sl-SI.lproj/Localizable.strings create mode 100644 Pods/StripePayments/StripePayments/StripePayments/Resources/Localizations/sv.lproj/Localizable.strings create mode 100644 Pods/StripePayments/StripePayments/StripePayments/Resources/Localizations/tk.lproj/Localizable.strings create mode 100644 Pods/StripePayments/StripePayments/StripePayments/Resources/Localizations/tr.lproj/Localizable.strings create mode 100644 Pods/StripePayments/StripePayments/StripePayments/Resources/Localizations/vi.lproj/Localizable.strings create mode 100644 Pods/StripePayments/StripePayments/StripePayments/Resources/Localizations/zh-HK.lproj/Localizable.strings create mode 100644 Pods/StripePayments/StripePayments/StripePayments/Resources/Localizations/zh-Hans.lproj/Localizable.strings create mode 100644 Pods/StripePayments/StripePayments/StripePayments/Resources/Localizations/zh-Hant.lproj/Localizable.strings create mode 100644 Pods/Target Support Files/StripeCore/ResourceBundle-StripeCore-StripeCore-Info.plist create mode 100644 Pods/Target Support Files/StripeCore/StripeCore-Info.plist create mode 100644 Pods/Target Support Files/StripeCore/StripeCore-dummy.m create mode 100644 Pods/Target Support Files/StripeCore/StripeCore-prefix.pch create mode 100644 Pods/Target Support Files/StripeCore/StripeCore-umbrella.h create mode 100644 Pods/Target Support Files/StripeCore/StripeCore.debug.xcconfig create mode 100644 Pods/Target Support Files/StripeCore/StripeCore.modulemap create mode 100644 Pods/Target Support Files/StripeCore/StripeCore.release.xcconfig create mode 100644 Pods/Target Support Files/StripePayments/ResourceBundle-Stripe3DS2-StripePayments-Info.plist create mode 100644 Pods/Target Support Files/StripePayments/ResourceBundle-StripePayments-StripePayments-Info.plist create mode 100644 Pods/Target Support Files/StripePayments/StripePayments-Info.plist create mode 100644 Pods/Target Support Files/StripePayments/StripePayments-dummy.m create mode 100644 Pods/Target Support Files/StripePayments/StripePayments-prefix.pch create mode 100644 Pods/Target Support Files/StripePayments/StripePayments-umbrella.h create mode 100644 Pods/Target Support Files/StripePayments/StripePayments.debug.xcconfig create mode 100644 Pods/Target Support Files/StripePayments/StripePayments.modulemap create mode 100644 Pods/Target Support Files/StripePayments/StripePayments.release.xcconfig diff --git a/OSPaymentsLib.xcodeproj/project.pbxproj b/OSPaymentsLib.xcodeproj/project.pbxproj index b89a5c0..2cc91fa 100644 --- a/OSPaymentsLib.xcodeproj/project.pbxproj +++ b/OSPaymentsLib.xcodeproj/project.pbxproj @@ -12,6 +12,11 @@ 7509DC7D28995A07005BA0D4 /* OSPMTAvailabilityDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7509DC7C28995A07005BA0D4 /* OSPMTAvailabilityDelegate.swift */; }; 7509DC7F28996482005BA0D4 /* OSPMTApplePayConfigurationSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7509DC7E28996482005BA0D4 /* OSPMTApplePayConfigurationSpec.swift */; }; 7509DC81289967A6005BA0D4 /* PKPaymentNetwork+Adapter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7509DC80289967A6005BA0D4 /* PKPaymentNetwork+Adapter.swift */; }; + 751B1DB2293A2744009A00B2 /* OSPMTStripeRequestParametersModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 751B1DB1293A2744009A00B2 /* OSPMTStripeRequestParametersModel.swift */; }; + 7556EA952934DAC600FF4044 /* OSPMTRequestParametersModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7556EA942934DAC600FF4044 /* OSPMTRequestParametersModel.swift */; }; + 7556EA982934E10D00FF4044 /* OSPMTStripeAPIDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7556EA972934E10D00FF4044 /* OSPMTStripeAPIDelegate.swift */; }; + 7556EA9A2934E4AB00FF4044 /* OSPMTStripeWrapperSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7556EA992934E4AB00FF4044 /* OSPMTStripeWrapperSpec.swift */; }; + 7556EA9C29350B9B00FF4044 /* OSPMTGatewayFactorySpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7556EA9B29350B9B00FF4044 /* OSPMTGatewayFactorySpec.swift */; }; 755A804B289BB96900426EAA /* PKPassLibrary+Adapter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 755A804A289BB96900426EAA /* PKPassLibrary+Adapter.swift */; }; 755A804D289BBAB300426EAA /* PKPaymentAuthorizationController+Adapter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 755A804C289BBAB300426EAA /* PKPaymentAuthorizationController+Adapter.swift */; }; 755A8050289BBDF000426EAA /* OSPMTApplePayAvailabilityBehaviourSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = 755A804F289BBDF000426EAA /* OSPMTApplePayAvailabilityBehaviourSpec.swift */; }; @@ -20,16 +25,21 @@ 755A8058289BC90A00426EAA /* OSPMTRequestDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 755A8057289BC90A00426EAA /* OSPMTRequestDelegate.swift */; }; 755A805A289BC92A00426EAA /* PKContactField+Adapter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 755A8059289BC92A00426EAA /* PKContactField+Adapter.swift */; }; 755A805C289BD4C600426EAA /* OSPMTApplePayRequestBehaviourSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = 755A805B289BD4C600426EAA /* OSPMTApplePayRequestBehaviourSpec.swift */; }; - 755A805E289BD53000426EAA /* OSPMTTokenInfoModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 755A805D289BD53000426EAA /* OSPMTTokenInfoModel.swift */; }; 755A8060289BD54E00426EAA /* OSPMTDataModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 755A805F289BD54E00426EAA /* OSPMTDataModel.swift */; }; 755A8062289BD56300426EAA /* OSPMTAddressModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 755A8061289BD56300426EAA /* OSPMTAddressModel.swift */; }; 755A8064289BD58900426EAA /* OSPMTContactInfoModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 755A8063289BD58900426EAA /* OSPMTContactInfoModel.swift */; }; + 756931E62937A9200014618D /* OSPMTTokenInfoModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 756931E52937A9200014618D /* OSPMTTokenInfoModel.swift */; }; 75760F78289C102D001BDCEC /* OSPMTAddressModelSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75760F77289C102D001BDCEC /* OSPMTAddressModelSpec.swift */; }; 75760F7A289C17AB001BDCEC /* OSPMTContactInfoModelSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75760F79289C17AB001BDCEC /* OSPMTContactInfoModelSpec.swift */; }; 75760F7D289C1AED001BDCEC /* OSPMTTokenInfoModelSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75760F7C289C1AED001BDCEC /* OSPMTTokenInfoModelSpec.swift */; }; 75760F7F289C1BF9001BDCEC /* OSPMTDataModelSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75760F7E289C1BF9001BDCEC /* OSPMTDataModelSpec.swift */; }; 75760F81289C1DF3001BDCEC /* OSPMTScopeModelSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75760F80289C1DF3001BDCEC /* OSPMTScopeModelSpec.swift */; }; 75760F83289C1F99001BDCEC /* PKPayment+Adapter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75760F82289C1F99001BDCEC /* PKPayment+Adapter.swift */; }; + 757ADE062934CF33002B3341 /* OSPMTGateway.swift in Sources */ = {isa = PBXBuildFile; fileRef = 757ADE052934CF32002B3341 /* OSPMTGateway.swift */; }; + 757ADE082934CF5E002B3341 /* OSPMTGatewayFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 757ADE072934CF5E002B3341 /* OSPMTGatewayFactory.swift */; }; + 757ADE0A2934CF92002B3341 /* OSPMTGatewayDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 757ADE092934CF92002B3341 /* OSPMTGatewayDelegate.swift */; }; + 757ADE0C2934CFE4002B3341 /* OSPMTStripeWrapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 757ADE0B2934CFE4002B3341 /* OSPMTStripeWrapper.swift */; }; + 75CC42E829375A6200149E6E /* OSPMTServiceProviderInfoModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75CC42E729375A6200149E6E /* OSPMTServiceProviderInfoModel.swift */; }; 75E4DCB12897C8AD002277FD /* OSPMTPaymentsSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75E4DCB02897C8AD002277FD /* OSPMTPaymentsSpec.swift */; }; 75EC4D122893FC3C00CF50E2 /* OSPMTPayments.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75EC4D112893FC3C00CF50E2 /* OSPMTPayments.swift */; }; 75EC4D152894143A00CF50E2 /* OSPMTCallbackDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75EC4D142894143A00CF50E2 /* OSPMTCallbackDelegate.swift */; }; @@ -64,6 +74,11 @@ 7509DC7C28995A07005BA0D4 /* OSPMTAvailabilityDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OSPMTAvailabilityDelegate.swift; sourceTree = ""; }; 7509DC7E28996482005BA0D4 /* OSPMTApplePayConfigurationSpec.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OSPMTApplePayConfigurationSpec.swift; sourceTree = ""; }; 7509DC80289967A6005BA0D4 /* PKPaymentNetwork+Adapter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "PKPaymentNetwork+Adapter.swift"; sourceTree = ""; }; + 751B1DB1293A2744009A00B2 /* OSPMTStripeRequestParametersModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OSPMTStripeRequestParametersModel.swift; sourceTree = ""; }; + 7556EA942934DAC600FF4044 /* OSPMTRequestParametersModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OSPMTRequestParametersModel.swift; sourceTree = ""; }; + 7556EA972934E10D00FF4044 /* OSPMTStripeAPIDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OSPMTStripeAPIDelegate.swift; sourceTree = ""; }; + 7556EA992934E4AB00FF4044 /* OSPMTStripeWrapperSpec.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OSPMTStripeWrapperSpec.swift; sourceTree = ""; }; + 7556EA9B29350B9B00FF4044 /* OSPMTGatewayFactorySpec.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OSPMTGatewayFactorySpec.swift; sourceTree = ""; }; 755A804A289BB96900426EAA /* PKPassLibrary+Adapter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "PKPassLibrary+Adapter.swift"; sourceTree = ""; }; 755A804C289BBAB300426EAA /* PKPaymentAuthorizationController+Adapter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "PKPaymentAuthorizationController+Adapter.swift"; sourceTree = ""; }; 755A804F289BBDF000426EAA /* OSPMTApplePayAvailabilityBehaviourSpec.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OSPMTApplePayAvailabilityBehaviourSpec.swift; sourceTree = ""; }; @@ -72,16 +87,21 @@ 755A8057289BC90A00426EAA /* OSPMTRequestDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OSPMTRequestDelegate.swift; sourceTree = ""; }; 755A8059289BC92A00426EAA /* PKContactField+Adapter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "PKContactField+Adapter.swift"; sourceTree = ""; }; 755A805B289BD4C600426EAA /* OSPMTApplePayRequestBehaviourSpec.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OSPMTApplePayRequestBehaviourSpec.swift; sourceTree = ""; }; - 755A805D289BD53000426EAA /* OSPMTTokenInfoModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OSPMTTokenInfoModel.swift; sourceTree = ""; }; 755A805F289BD54E00426EAA /* OSPMTDataModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OSPMTDataModel.swift; sourceTree = ""; }; 755A8061289BD56300426EAA /* OSPMTAddressModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OSPMTAddressModel.swift; sourceTree = ""; }; 755A8063289BD58900426EAA /* OSPMTContactInfoModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OSPMTContactInfoModel.swift; sourceTree = ""; }; + 756931E52937A9200014618D /* OSPMTTokenInfoModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OSPMTTokenInfoModel.swift; sourceTree = ""; }; 75760F77289C102D001BDCEC /* OSPMTAddressModelSpec.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OSPMTAddressModelSpec.swift; sourceTree = ""; }; 75760F79289C17AB001BDCEC /* OSPMTContactInfoModelSpec.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OSPMTContactInfoModelSpec.swift; sourceTree = ""; }; 75760F7C289C1AED001BDCEC /* OSPMTTokenInfoModelSpec.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OSPMTTokenInfoModelSpec.swift; sourceTree = ""; }; 75760F7E289C1BF9001BDCEC /* OSPMTDataModelSpec.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OSPMTDataModelSpec.swift; sourceTree = ""; }; 75760F80289C1DF3001BDCEC /* OSPMTScopeModelSpec.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OSPMTScopeModelSpec.swift; sourceTree = ""; }; 75760F82289C1F99001BDCEC /* PKPayment+Adapter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "PKPayment+Adapter.swift"; sourceTree = ""; }; + 757ADE052934CF32002B3341 /* OSPMTGateway.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OSPMTGateway.swift; sourceTree = ""; }; + 757ADE072934CF5E002B3341 /* OSPMTGatewayFactory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OSPMTGatewayFactory.swift; sourceTree = ""; }; + 757ADE092934CF92002B3341 /* OSPMTGatewayDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OSPMTGatewayDelegate.swift; sourceTree = ""; }; + 757ADE0B2934CFE4002B3341 /* OSPMTStripeWrapper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OSPMTStripeWrapper.swift; sourceTree = ""; }; + 75CC42E729375A6200149E6E /* OSPMTServiceProviderInfoModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OSPMTServiceProviderInfoModel.swift; sourceTree = ""; }; 75E4DCB02897C8AD002277FD /* OSPMTPaymentsSpec.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OSPMTPaymentsSpec.swift; sourceTree = ""; }; 75EC4D112893FC3C00CF50E2 /* OSPMTPayments.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OSPMTPayments.swift; sourceTree = ""; }; 75EC4D142894143A00CF50E2 /* OSPMTCallbackDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OSPMTCallbackDelegate.swift; sourceTree = ""; }; @@ -154,6 +174,7 @@ children = ( 75EC4D182894155D00CF50E2 /* Error */, 7509DC7528993C26005BA0D4 /* Extensions */, + 757ADE042934CEF8002B3341 /* Gateways */, 755A8052289BC8EE00426EAA /* Models */, 75EC4D132894142000CF50E2 /* Protocols */, 75EC4D1D289416B600CF50E2 /* OSPMTApplePayHandler.swift */, @@ -170,7 +191,9 @@ 7509DC7E28996482005BA0D4 /* OSPMTApplePayConfigurationSpec.swift */, 75EC4D232894449700CF50E2 /* OSPMTApplePayHandlerSpec.swift */, 755A805B289BD4C600426EAA /* OSPMTApplePayRequestBehaviourSpec.swift */, + 7556EA9B29350B9B00FF4044 /* OSPMTGatewayFactorySpec.swift */, 75E4DCB02897C8AD002277FD /* OSPMTPaymentsSpec.swift */, + 7556EA992934E4AB00FF4044 /* OSPMTStripeWrapperSpec.swift */, 75EC4D252894478200CF50E2 /* OSPMTTestConfigurations.swift */, ); path = OSPaymentsLibTests; @@ -189,6 +212,16 @@ path = Extensions; sourceTree = ""; }; + 7556EA962934E09900FF4044 /* Stripe */ = { + isa = PBXGroup; + children = ( + 7556EA972934E10D00FF4044 /* OSPMTStripeAPIDelegate.swift */, + 751B1DB1293A2744009A00B2 /* OSPMTStripeRequestParametersModel.swift */, + 757ADE0B2934CFE4002B3341 /* OSPMTStripeWrapper.swift */, + ); + path = Stripe; + sourceTree = ""; + }; 755A8052289BC8EE00426EAA /* Models */ = { isa = PBXGroup; children = ( @@ -197,8 +230,10 @@ 755A8063289BD58900426EAA /* OSPMTContactInfoModel.swift */, 755A805F289BD54E00426EAA /* OSPMTDataModel.swift */, 755A8053289BC8EE00426EAA /* OSPMTDetailsModel.swift */, + 7556EA942934DAC600FF4044 /* OSPMTRequestParametersModel.swift */, + 75CC42E729375A6200149E6E /* OSPMTServiceProviderInfoModel.swift */, 755A8054289BC8EE00426EAA /* OSPMTScopeModel.swift */, - 755A805D289BD53000426EAA /* OSPMTTokenInfoModel.swift */, + 756931E52937A9200014618D /* OSPMTTokenInfoModel.swift */, ); path = Models; sourceTree = ""; @@ -215,12 +250,23 @@ path = ModelSpecs; sourceTree = ""; }; + 757ADE042934CEF8002B3341 /* Gateways */ = { + isa = PBXGroup; + children = ( + 7556EA962934E09900FF4044 /* Stripe */, + 757ADE052934CF32002B3341 /* OSPMTGateway.swift */, + 757ADE072934CF5E002B3341 /* OSPMTGatewayFactory.swift */, + ); + path = Gateways; + sourceTree = ""; + }; 75EC4D132894142000CF50E2 /* Protocols */ = { isa = PBXGroup; children = ( 75EC4D1B2894160400CF50E2 /* OSPMTActionDelegate.swift */, 7509DC7C28995A07005BA0D4 /* OSPMTAvailabilityDelegate.swift */, 75EC4D142894143A00CF50E2 /* OSPMTCallbackDelegate.swift */, + 757ADE092934CF92002B3341 /* OSPMTGatewayDelegate.swift */, 75EC4D162894150F00CF50E2 /* OSPMTHandlerDelegate.swift */, 755A8057289BC90A00426EAA /* OSPMTRequestDelegate.swift */, ); @@ -441,14 +487,21 @@ files = ( 7509DC7D28995A07005BA0D4 /* OSPMTAvailabilityDelegate.swift in Sources */, 75EC4D1A2894156E00CF50E2 /* OSPMTError.swift in Sources */, + 757ADE082934CF5E002B3341 /* OSPMTGatewayFactory.swift in Sources */, + 757ADE062934CF33002B3341 /* OSPMTGateway.swift in Sources */, 755A8056289BC8EE00426EAA /* OSPMTScopeModel.swift in Sources */, + 7556EA952934DAC600FF4044 /* OSPMTRequestParametersModel.swift in Sources */, + 751B1DB2293A2744009A00B2 /* OSPMTStripeRequestParametersModel.swift in Sources */, + 7556EA982934E10D00FF4044 /* OSPMTStripeAPIDelegate.swift in Sources */, 7509DC7728993C4C005BA0D4 /* PKMerchantCapability+Adapter.swift in Sources */, 755A8055289BC8EE00426EAA /* OSPMTDetailsModel.swift in Sources */, 755A804B289BB96900426EAA /* PKPassLibrary+Adapter.swift in Sources */, + 75CC42E829375A6200149E6E /* OSPMTServiceProviderInfoModel.swift in Sources */, 75760F83289C1F99001BDCEC /* PKPayment+Adapter.swift in Sources */, 75EC4D2228942C3800CF50E2 /* OSPMTConfigurationModel.swift in Sources */, 75EC4D172894150F00CF50E2 /* OSPMTHandlerDelegate.swift in Sources */, 755A8058289BC90A00426EAA /* OSPMTRequestDelegate.swift in Sources */, + 757ADE0C2934CFE4002B3341 /* OSPMTStripeWrapper.swift in Sources */, 755A8062289BD56300426EAA /* OSPMTAddressModel.swift in Sources */, 755A8060289BD54E00426EAA /* OSPMTDataModel.swift in Sources */, 755A804D289BBAB300426EAA /* PKPaymentAuthorizationController+Adapter.swift in Sources */, @@ -456,8 +509,9 @@ 7509DC81289967A6005BA0D4 /* PKPaymentNetwork+Adapter.swift in Sources */, 755A8064289BD58900426EAA /* OSPMTContactInfoModel.swift in Sources */, 75EC4D152894143A00CF50E2 /* OSPMTCallbackDelegate.swift in Sources */, - 755A805E289BD53000426EAA /* OSPMTTokenInfoModel.swift in Sources */, 75EC4D1C2894160400CF50E2 /* OSPMTActionDelegate.swift in Sources */, + 757ADE0A2934CF92002B3341 /* OSPMTGatewayDelegate.swift in Sources */, + 756931E62937A9200014618D /* OSPMTTokenInfoModel.swift in Sources */, 755A805A289BC92A00426EAA /* PKContactField+Adapter.swift in Sources */, 75EC4D122893FC3C00CF50E2 /* OSPMTPayments.swift in Sources */, ); @@ -468,6 +522,7 @@ buildActionMask = 2147483647; files = ( 755A805C289BD4C600426EAA /* OSPMTApplePayRequestBehaviourSpec.swift in Sources */, + 7556EA9A2934E4AB00FF4044 /* OSPMTStripeWrapperSpec.swift in Sources */, 75760F7A289C17AB001BDCEC /* OSPMTContactInfoModelSpec.swift in Sources */, 75EC4D262894478200CF50E2 /* OSPMTTestConfigurations.swift in Sources */, 75760F81289C1DF3001BDCEC /* OSPMTScopeModelSpec.swift in Sources */, @@ -478,6 +533,7 @@ 75EC4D242894449700CF50E2 /* OSPMTApplePayHandlerSpec.swift in Sources */, 75E4DCB12897C8AD002277FD /* OSPMTPaymentsSpec.swift in Sources */, 75760F78289C102D001BDCEC /* OSPMTAddressModelSpec.swift in Sources */, + 7556EA9C29350B9B00FF4044 /* OSPMTGatewayFactorySpec.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/OSPaymentsLib/Error/OSPMTError.swift b/OSPaymentsLib/Error/OSPMTError.swift index 49c4c78..99edc3b 100644 --- a/OSPaymentsLib/Error/OSPMTError.swift +++ b/OSPaymentsLib/Error/OSPMTError.swift @@ -11,6 +11,10 @@ public enum OSPMTError: Int, CustomNSError, LocalizedError { case paymentTriggerPresentationFailed = 10 case paymentCancelled = 11 + case gatewaySetFailed = 12 + case stripePaymentMethodCreation = 13 + case paymentIssue = 14 + /// Textual description public var errorDescription: String? { switch self { @@ -30,6 +34,13 @@ public enum OSPMTError: Int, CustomNSError, LocalizedError { return "Couldn't present the Apple Pay screen." case .paymentCancelled: return "Payment was cancelled by the user." + + case .gatewaySetFailed: + return "Couldn't set payment service provider." + case .stripePaymentMethodCreation: + return "Couldn't obtain the PaymentMethod from Stripe." + case .paymentIssue: + return "Couldn't process payment." } } } diff --git a/OSPaymentsLib/Extensions/PKPayment+Adapter.swift b/OSPaymentsLib/Extensions/PKPayment+Adapter.swift index 811e251..d5197ff 100644 --- a/OSPaymentsLib/Extensions/PKPayment+Adapter.swift +++ b/OSPaymentsLib/Extensions/PKPayment+Adapter.swift @@ -2,23 +2,24 @@ import PassKit extension PKPayment { /// Converts a `PKPayment` object into a `OSPMTScopeModel` one. Returns `nil` if it can't. + /// - Parameter paymentGatewayModel: model that contains the payment gateway information resulting from completing a payment process. /// - Returns: The corresponding `OSPMTScopeModel` object. Can also return `nil` if the conversion fails. - func createScopeModel() -> OSPMTScopeModel? { - var result: [String: Any] = [OSPMTScopeModel.CodingKeys.paymentData.rawValue: self.createTokenDataData()] + func createScopeModel(for paymentGatewayModel: OSPMTServiceProviderInfoModel? = nil) -> OSPMTScopeModel? { + var result: [String: Any] = [OSPMTScopeModel.CodingKeys.paymentData.rawValue: self.createTokenDataData(for: paymentGatewayModel)] if let shippingContact = self.shippingContact { result[OSPMTScopeModel.CodingKeys.shippingInfo.rawValue] = self.createContactInfoData(for: shippingContact) } - guard - let scopeData = try? JSONSerialization.data(withJSONObject: result), + guard let scopeData = try? JSONSerialization.data(withJSONObject: result), let scopeModel = try? JSONDecoder().decode(OSPMTScopeModel.self, from: scopeData) else { return nil } return scopeModel } /// Converts a `PKPayment` object into a dictionary that relates to an `OSPMTDataModel` object. + /// - Parameter paymentGatewayModel: model that contains the payment gateway information resulting from completing a payment process. /// - Returns: The corresponding `OSPMTDataModel` dictionary object. - private func createTokenDataData() -> [String: Any] { + private func createTokenDataData(for paymentGatewayModel: OSPMTServiceProviderInfoModel?) -> [String: Any] { var result: [String: Any] = [ OSPMTDataModel.CodingKeys.tokenData.rawValue: self.createTokenData(for: self.token.paymentData) ] @@ -32,6 +33,11 @@ extension PKPayment { result[OSPMTDataModel.CodingKeys.cardNetwork.rawValue] = cardNetwork } } + if let paymentGatewayModel = paymentGatewayModel, + let paymentGatewayData = try? JSONEncoder().encode(paymentGatewayModel), + let paymentGatewayDict = try? JSONSerialization.jsonObject(with: paymentGatewayData) as? [String: String] { + result[OSPMTDataModel.CodingKeys.paymentServiceProviderData.rawValue] = paymentGatewayDict + } return result } @@ -40,7 +46,6 @@ extension PKPayment { /// - Parameter paymentData: `Data` type object that contains information related to a payment token. /// - Returns: The corresponding `OSPMTTokenInfoModel` dictionary object. private func createTokenData(for paymentData: Data) -> [String: String] { - // TODO: The type passed here will probably be changed into the Payment Service Provider's name when this is implemented. var result = [OSPMTTokenInfoModel.CodingKeys.type.rawValue: "Apple Pay"] if let token = String(data: paymentData, encoding: .utf8) { diff --git a/OSPaymentsLib/Gateways/OSPMTGateway.swift b/OSPaymentsLib/Gateways/OSPMTGateway.swift new file mode 100644 index 0000000..8626d60 --- /dev/null +++ b/OSPaymentsLib/Gateways/OSPMTGateway.swift @@ -0,0 +1,14 @@ +/// Payment Service Provider enum object +enum OSPMTGateway: String { + case stripe = "Stripe" +} + +extension OSPMTGateway { + + /// Converts a string into a `OSPMTGateway` object. + /// - Parameter text: Text to convert. + /// - Returns: A `OSPMTGateway` enum object if successful. `nil` is returned in case of error. + static func convert(from text: String) -> OSPMTGateway? { + return text.lowercased() == "stripe" ? .stripe : nil + } +} diff --git a/OSPaymentsLib/Gateways/OSPMTGatewayFactory.swift b/OSPaymentsLib/Gateways/OSPMTGatewayFactory.swift new file mode 100644 index 0000000..f4bbd0a --- /dev/null +++ b/OSPaymentsLib/Gateways/OSPMTGatewayFactory.swift @@ -0,0 +1,18 @@ +import Foundation + +/// Structure responsible for creating a Wrapper for the configured Gateway. +struct OSPMTGatewayFactory { + /// Creates the correct wrapper for the gateway the user has configured. + /// - Parameter configuration: Model with the gateway configuration information. + /// - Returns: The wrapper object is everything is correctly configured. `nil` is returned otherwise. + static func createWrapper(for configuration: OSPMTGatewayModel) -> OSPMTGatewayDelegate? { + guard let gateway = configuration.gatewayEnum, let url = URL(string: configuration.requestURL) else { return nil } + let urlRequest = URLRequest(url: url) + + switch gateway { + case .stripe: + guard let publishableKey = configuration.publishableKey else { return nil } + return OSPMTStripeWrapper(urlRequest: urlRequest, publishableKey: publishableKey) + } + } +} diff --git a/OSPaymentsLib/Gateways/Stripe/OSPMTStripeAPIDelegate.swift b/OSPaymentsLib/Gateways/Stripe/OSPMTStripeAPIDelegate.swift new file mode 100644 index 0000000..58dcd24 --- /dev/null +++ b/OSPaymentsLib/Gateways/Stripe/OSPMTStripeAPIDelegate.swift @@ -0,0 +1,37 @@ +import PassKit +import StripePayments + +/// Delegate class containing the required calls for Stripe's SDK to process. +protocol OSPMTStripeAPIDelegate: AnyObject { + /// Sets the required publishable key, required to trigger payments through Stripe + /// - Parameter publishableKey: Key obtained via Stripe's Dashboard. + func set(_ publishableKey: String) + + /// Retrieves Stripe's Payment Method's Identifier in exchange for Apple Pay's payment request result. + /// - Parameters: + /// - payment: Apple Pay's payment request result. + /// - completion: The exchange operation result. In case of success, it returns the Payment Method Id or an error otherwise. + func getPaymentMethodId(from payment: PKPayment, _ completion: @escaping (Result) -> Void) +} + +extension STPAPIClient: OSPMTStripeAPIDelegate { + /// Sets the required publishable key, required to trigger payments through Stripe + /// - Parameter publishableKey: Key obtained via Stripe's Dashboard. + func set(_ publishableKey: String) { + self.publishableKey = publishableKey + } + + /// Retrieves Stripe's Payment Method's Identifier in exchange for Apple Pay's payment request result. + /// - Parameters: + /// - payment: Apple Pay's payment request result. + /// - completion: The exchange operation result. In case of success, it returns the Payment Method Id or an error otherwise. + func getPaymentMethodId(from payment: PKPayment, _ completion: @escaping (Result) -> Void) { + self.createPaymentMethod(with: payment) { paymentMethod, _ in + if let paymentMethod = paymentMethod { + completion(.success(paymentMethod.stripeId)) + } else { + completion(.failure(.stripePaymentMethodCreation)) + } + } + } +} diff --git a/OSPaymentsLib/Gateways/Stripe/OSPMTStripeRequestParametersModel.swift b/OSPaymentsLib/Gateways/Stripe/OSPMTStripeRequestParametersModel.swift new file mode 100644 index 0000000..688b68c --- /dev/null +++ b/OSPaymentsLib/Gateways/Stripe/OSPMTStripeRequestParametersModel.swift @@ -0,0 +1,40 @@ +/// Model to manage Stripe's payment process request parameters. This is based on `OSPMTRequestParametersModel`. +final class OSPMTStripeRequestParametersModel: OSPMTRequestParametersModel { + let paymentMethodId: String + let confirm: Bool + + /// Keys used to encode and decode the model. + enum CodingKeys: String, CodingKey { + case paymentMethodId = "payment_method" + case confirm + } + + /// Constructor method. + /// - Parameters: + /// - amount: Amount to charge. + /// - currency: Currency to charge. + /// - paymentMethodId: Stripe object that represents the customer's payment instruments. + /// - confirm: Automatically confirm the triggered payment process. + init(amount: Int, currency: String, paymentMethodId: String, confirm: Bool = true) { + self.paymentMethodId = paymentMethodId + self.confirm = confirm + super.init(amount: amount, currency: currency) + } + + /// Encodes this value into the given encoder. + /// + /// If the value fails to encode anything, `encoder` will encode an empty + /// keyed container in its place. + /// + /// This function throws an error if any values are invalid for the given + /// encoder's format. + /// + /// - Parameter encoder: The encoder to write data to. + override func encode(to encoder: Encoder) throws { + var container = encoder.container(keyedBy: CodingKeys.self) + + try container.encode(paymentMethodId, forKey: .paymentMethodId) + try container.encode(confirm, forKey: .confirm) + try super.encode(to: encoder) + } +} diff --git a/OSPaymentsLib/Gateways/Stripe/OSPMTStripeWrapper.swift b/OSPaymentsLib/Gateways/Stripe/OSPMTStripeWrapper.swift new file mode 100644 index 0000000..0488475 --- /dev/null +++ b/OSPaymentsLib/Gateways/Stripe/OSPMTStripeWrapper.swift @@ -0,0 +1,44 @@ +import PassKit +import StripeCore + +/// Object responsible for making a Stripe payment process. The Wrapper deals with all calls that are required to Stripe's SDK. +final class OSPMTStripeWrapper: OSPMTGatewayDelegate { + var urlRequest: URLRequest + var urlSession: URLSession + let apiDelegate: OSPMTStripeAPIDelegate + + /// Constructor method. + /// - Parameters: + /// - urlRequest: URL load request object. + /// - urlSession: Coordinator object for network data transfer tasks. + /// - publishableKey: Key required for Stripe's API to trigger calls. + /// - apiDelegate: Object responsible for Stripe's API calls. + init(urlRequest: URLRequest, urlSession: URLSession = .shared, publishableKey: String, apiDelegate: OSPMTStripeAPIDelegate = STPAPIClient.shared) { + self.urlRequest = urlRequest + self.urlSession = urlSession + + apiDelegate.set(publishableKey) + self.apiDelegate = apiDelegate + } +} + +extension OSPMTStripeWrapper { + /// Triggers the process through the configured gateway. + /// - Parameters: + /// - payment: Apple Pay's payment request result. + /// - details: Payment details to trigger processing. + /// - completion: Payment process result. If returns the process result in case of success or an error otherwise. + func process(_ payment: PKPayment, with details: OSPMTDetailsModel, _ completion: @escaping (Result) -> Void) { + self.apiDelegate.getPaymentMethodId(from: payment) { result in + switch result { + case .success(let paymentMethodId): + let requestParametersModel = OSPMTStripeRequestParametersModel( + amount: details.paymentAmount.multiplying(by: 100).intValue, currency: details.currency, paymentMethodId: paymentMethodId + ) + self.processURLRequest(requestParametersModel, completion) + case .failure(let error): + completion(.failure(error)) + } + } + } +} diff --git a/OSPaymentsLib/Models/OSPMTConfigurationModel.swift b/OSPaymentsLib/Models/OSPMTConfigurationModel.swift index 39f2997..0ee249e 100644 --- a/OSPaymentsLib/Models/OSPMTConfigurationModel.swift +++ b/OSPaymentsLib/Models/OSPMTConfigurationModel.swift @@ -1,6 +1,43 @@ import PassKit -/// Protocol that contains all properties needed to configure a payment service. +/// Model that manages the Payment Service Provider's configuration. +struct OSPMTGatewayModel: Encodable { + let gateway: String + let publishableKey: String? + let requestURL: String + + /// Keys used to encode and decode the model. + enum CodingKeys: String, CodingKey { + case gateway + case publishableKey + case requestURL + } + + /// Encodes this value into the given encoder. + /// + /// If the value fails to encode anything, `encoder` will encode an empty + /// keyed container in its place. + /// + /// This function throws an error if any values are invalid for the given + /// encoder's format. + /// + /// - Parameter encoder: The encoder to write data to. + func encode(to encoder: Encoder) throws { + var container = encoder.container(keyedBy: CodingKeys.self) + + try container.encode(gateway, forKey: .gateway) + try container.encodeIfPresent(publishableKey, forKey: .publishableKey) + try container.encode(requestURL, forKey: .requestURL) + } +} + +extension OSPMTGatewayModel { + var gatewayEnum: OSPMTGateway? { + return OSPMTGateway.convert(from: self.gateway) + } +} + +/// Model that contains all properties needed to configure a payment service. class OSPMTConfigurationModel: Encodable { // MARK: Merchant Information var merchantID: String? @@ -18,6 +55,9 @@ class OSPMTConfigurationModel: Encodable { // MARK: Billing Information var billingSupportedContacts: [String]? + // MARK: Payment Service Provider Information + var gatewayModel: OSPMTGatewayModel? + /// Keys used to encode and decode the model. enum CodingKeys: String, CodingKey { case merchantID @@ -28,6 +68,7 @@ class OSPMTConfigurationModel: Encodable { case paymentSupportedCardCountries case shippingSupportedContacts case billingSupportedContacts + case gatewayModel = "tokenization" } /// Constructor method. @@ -40,7 +81,18 @@ class OSPMTConfigurationModel: Encodable { /// - paymentSupportedCardCountries: Payment Support Card Countries configured /// - shippingSupportedContacts: Shipping Supported Contacts configured /// - billingSupportedContacts: Billing Supported Contacts configured - init(merchantID: String?, merchantName: String?, merchantCountryCode: String?, paymentAllowedNetworks: [String]?, paymentSupportedCapabilities: [String]?, paymentSupportedCardCountries: [String]?, shippingSupportedContacts: [String]?, billingSupportedContacts: [String]?) { + /// - tokenization: Payment Service Gateway configured + init( + merchantID: String?, + merchantName: String?, + merchantCountryCode: String?, + paymentAllowedNetworks: [String]?, + paymentSupportedCapabilities: [String]?, + paymentSupportedCardCountries: [String]?, + shippingSupportedContacts: [String]?, + billingSupportedContacts: [String]?, + gatewayModel: OSPMTGatewayModel? + ) { self.merchantID = merchantID self.merchantName = merchantName self.merchantCountryCode = merchantCountryCode @@ -49,6 +101,7 @@ class OSPMTConfigurationModel: Encodable { self.paymentSupportedCardCountries = paymentSupportedCardCountries self.shippingSupportedContacts = shippingSupportedContacts self.billingSupportedContacts = billingSupportedContacts + self.gatewayModel = gatewayModel } /// Encodes this value into the given encoder. @@ -78,6 +131,9 @@ class OSPMTConfigurationModel: Encodable { // MARK: Billing Information try container.encodeIfPresent(billingSupportedContacts, forKey: .billingSupportedContacts) + + // MARK: Payment Service Provider Information + try container.encodeIfPresent(gatewayModel, forKey: .gatewayModel) } } @@ -97,6 +153,11 @@ class OSPMTApplePayConfiguration: OSPMTConfigurationModel { static let shippingSupportedContacts = "ApplePayShippingSupportedContacts" static let billingSupportedContacts = "ApplePayBillingSupportedContacts" + + static let paymentGateway = "ApplePayPaymentGateway" + static let paymentGatewayName = "ApplePayPaymentGatewayName" + static let paymentRequestURL = "ApplePayRequestURL" + static let stripePublishableKey = "ApplePayStripePublishableKey" } /// Constructor method. @@ -120,6 +181,15 @@ class OSPMTApplePayConfiguration: OSPMTConfigurationModel { // MARK: Billing Information let billingSupportedContacts: [String]? = Self.getProperty(forSource: source, andKey: ConfigurationKeys.billingSupportedContacts) + // MARK: Payment Service Provider Information + var gatewayModel: OSPMTGatewayModel? + if let providerGateway: [String: Any] = Self.getProperty(forSource: source, andKey: ConfigurationKeys.paymentGateway), + let providerGatewayName = providerGateway[ConfigurationKeys.paymentGatewayName] as? String, + let requestURL = providerGateway[ConfigurationKeys.paymentRequestURL] as? String { + let publishableKey = providerGateway[ConfigurationKeys.stripePublishableKey] as? String + gatewayModel = OSPMTGatewayModel(gateway: providerGatewayName, publishableKey: publishableKey, requestURL: requestURL) + } + self.init( merchantID: merchantID, merchantName: merchantName, @@ -128,7 +198,8 @@ class OSPMTApplePayConfiguration: OSPMTConfigurationModel { paymentSupportedCapabilities: paymentSupportedCapabilities, paymentSupportedCardCountries: paymentSupportedCardCountries, shippingSupportedContacts: shippingSupportedContacts, - billingSupportedContacts: billingSupportedContacts + billingSupportedContacts: billingSupportedContacts, + gatewayModel: gatewayModel ) } } diff --git a/OSPaymentsLib/Models/OSPMTDataModel.swift b/OSPaymentsLib/Models/OSPMTDataModel.swift index a427af8..fe860fd 100644 --- a/OSPaymentsLib/Models/OSPMTDataModel.swift +++ b/OSPaymentsLib/Models/OSPMTDataModel.swift @@ -4,10 +4,11 @@ struct OSPMTDataModel: Codable { let cardDetails: String let cardNetwork: String let tokenData: OSPMTTokenInfoModel + let paymentServiceProviderData: OSPMTServiceProviderInfoModel? /// Keys used to encode and decode the model. enum CodingKeys: String, CodingKey { - case billingInfo, cardDetails, cardNetwork, tokenData + case billingInfo, cardDetails, cardNetwork, tokenData, paymentServiceProviderData } /// Constructor method. @@ -16,11 +17,13 @@ struct OSPMTDataModel: Codable { /// - cardDetails: The last four digits of the card used for payment. /// - cardNetwork: The network of the card used for payment. /// - tokenData: The data of the token used for payment. - init(billingInfo: OSPMTContactInfoModel? = nil, cardDetails: String, cardNetwork: String, tokenData: OSPMTTokenInfoModel) { + /// - paymentServiceProviderData: Information related with the payment gateway process result. If can be `nil` if no Gateway was configured + init(billingInfo: OSPMTContactInfoModel? = nil, cardDetails: String, cardNetwork: String, tokenData: OSPMTTokenInfoModel, paymentServiceProviderData: OSPMTServiceProviderInfoModel? = nil) { self.billingInfo = billingInfo self.cardDetails = cardDetails self.cardNetwork = cardNetwork self.tokenData = tokenData + self.paymentServiceProviderData = paymentServiceProviderData } /// Creates a new instance by decoding from the given decoder. @@ -35,7 +38,14 @@ struct OSPMTDataModel: Codable { let cardDetails = try container.decode(String.self, forKey: .cardDetails) let cardNetwork = try container.decode(String.self, forKey: .cardNetwork) let tokenData = try container.decode(OSPMTTokenInfoModel.self, forKey: .tokenData) - self.init(billingInfo: billingInfo, cardDetails: cardDetails, cardNetwork: cardNetwork, tokenData: tokenData) + let paymentServiceProviderData = try container.decodeIfPresent(OSPMTServiceProviderInfoModel.self, forKey: .paymentServiceProviderData) + self.init( + billingInfo: billingInfo, + cardDetails: cardDetails, + cardNetwork: cardNetwork, + tokenData: tokenData, + paymentServiceProviderData: paymentServiceProviderData + ) } /// Encodes this value into the given encoder. @@ -53,6 +63,7 @@ struct OSPMTDataModel: Codable { try container.encode(cardDetails, forKey: .cardDetails) try container.encode(cardNetwork, forKey: .cardNetwork) try container.encode(tokenData, forKey: .tokenData) + try container.encodeIfPresent(paymentServiceProviderData, forKey: .paymentServiceProviderData) } } @@ -71,5 +82,6 @@ extension OSPMTDataModel: Equatable { && lhs.cardDetails == rhs.cardDetails && lhs.cardNetwork == rhs.cardNetwork && lhs.tokenData == rhs.tokenData + && lhs.paymentServiceProviderData == rhs.paymentServiceProviderData } } diff --git a/OSPaymentsLib/Models/OSPMTRequestParametersModel.swift b/OSPaymentsLib/Models/OSPMTRequestParametersModel.swift new file mode 100644 index 0000000..9e3dcd4 --- /dev/null +++ b/OSPaymentsLib/Models/OSPMTRequestParametersModel.swift @@ -0,0 +1,36 @@ +/// Model to manage the gateway payment process' request parameters. +class OSPMTRequestParametersModel: Encodable { + let amount: Int + let currency: String + + /// Keys used to encode and decode the model. + enum CodingKeys: String, CodingKey { + case amount + case currency + } + + /// Constructor method. + /// - Parameters: + /// - amount: Amount to charge. + /// - currency: Currency to charge. + init(amount: Int, currency: String) { + self.amount = amount + self.currency = currency + } + + /// Encodes this value into the given encoder. + /// + /// If the value fails to encode anything, `encoder` will encode an empty + /// keyed container in its place. + /// + /// This function throws an error if any values are invalid for the given + /// encoder's format. + /// + /// - Parameter encoder: The encoder to write data to. + func encode(to encoder: Encoder) throws { + var container = encoder.container(keyedBy: CodingKeys.self) + + try container.encode(amount, forKey: .amount) + try container.encode(currency, forKey: .currency) + } +} diff --git a/OSPaymentsLib/Models/OSPMTServiceProviderInfoModel.swift b/OSPaymentsLib/Models/OSPMTServiceProviderInfoModel.swift new file mode 100644 index 0000000..99a290b --- /dev/null +++ b/OSPaymentsLib/Models/OSPMTServiceProviderInfoModel.swift @@ -0,0 +1,70 @@ +/// Enum indicating the payment processing status. +enum OSPMTProcessStatus: String { + case pending = "pending" + case success = "succeeded" + case fail = "failed" +} + +/// Model indicating the resuiting payment service provider's information. +struct OSPMTServiceProviderInfoModel: Codable { + let id: String + let status: OSPMTProcessStatus? + + /// Keys used to encode and decode the model. + enum CodingKeys: String, CodingKey { + case id + case status + } + + /// Constructor method. + /// - Parameters: + /// - id: Payment process identifier. + /// - status: Payment process status. + init(id: String, status: String) { + self.id = id + self.status = OSPMTProcessStatus(rawValue: status) + } + + /// Creates a new instance by decoding from the given decoder. + /// + /// This initializer throws an error if reading from the decoder fails, or + /// if the data read is corrupted or otherwise invalid. + /// + /// - Parameter decoder: The decoder to read data from. + init(from decoder: Decoder) throws { + let container = try decoder.container(keyedBy: CodingKeys.self) + let id = try container.decode(String.self, forKey: .id) + let status = try container.decode(String.self, forKey: .status) + self.init(id: id, status: status) + } + + /// Encodes this value into the given encoder. + /// + /// If the value fails to encode anything, `encoder` will encode an empty + /// keyed container in its place. + /// + /// This function throws an error if any values are invalid for the given + /// encoder's format. + /// + /// - Parameter encoder: The encoder to write data to. + func encode(to encoder: Encoder) throws { + var container = encoder.container(keyedBy: CodingKeys.self) + try container.encode(id, forKey: .id) + try container.encode((status ?? .pending).rawValue, forKey: .status) + } +} + +extension OSPMTServiceProviderInfoModel: Equatable { + /// Returns a Boolean value indicating whether two values are equal. + /// + /// Equality is the inverse of inequality. For any values `a` and `b`, + /// `a == b` implies that `a != b` is `false`. + /// + /// - Parameters: + /// - lhs: A value to compare. + /// - rhs: Another value to compare. + /// - Returns: The comparison result. + static func == (lhs: OSPMTServiceProviderInfoModel, rhs: OSPMTServiceProviderInfoModel) -> Bool { + lhs.id == rhs.id && lhs.status == rhs.status + } +} diff --git a/OSPaymentsLib/Protocols/OSPMTGatewayDelegate.swift b/OSPaymentsLib/Protocols/OSPMTGatewayDelegate.swift new file mode 100644 index 0000000..eddd0c2 --- /dev/null +++ b/OSPaymentsLib/Protocols/OSPMTGatewayDelegate.swift @@ -0,0 +1,43 @@ +import PassKit + +/// Delegate class that triggers the backend payment process request. +protocol OSPMTGatewayDelegate: AnyObject { + var urlRequest: URLRequest { get set } + var urlSession: URLSession { get } + + /// Triggers the process through the configured gateway. + /// - Parameters: + /// - payment: Apple Pay's payment request result. + /// - details: Payment details to trigger processing. + /// - completion: Payment process result. If returns the process result in case of success or an error otherwise. + func process(_ payment: PKPayment, with details: OSPMTDetailsModel, _ completion: @escaping (Result) -> Void) +} + +extension OSPMTGatewayDelegate { + + /// Triggers the backend url request. + /// - Parameters: + /// - requestParameters: Model containing the request body to trigger + /// - completion: Payment process result. If returns the process result in case of success or an error otherwise. + func processURLRequest(_ requestParameters: OSPMTRequestParametersModel, _ completion: @escaping (Result) -> Void) { + self.urlRequest.httpMethod = "POST" + self.urlRequest.setValue("application/json", forHTTPHeaderField: "Content-Type") + self.urlRequest.setValue("application/json", forHTTPHeaderField: "Accept") + self.urlRequest.httpBody = try? JSONEncoder().encode(requestParameters) + let task = self.urlSession.dataTask(with: self.urlRequest) { data, response, error in + guard let response = response as? HTTPURLResponse, + response.statusCode == 200, + error == nil, + let data = data, + let responseModel = try? JSONDecoder().decode(OSPMTServiceProviderInfoModel.self, from: data), + responseModel.status != .fail + else { + completion(.failure(.paymentIssue)) + return + } + + completion(.success(responseModel)) + } + task.resume() + } +} diff --git a/OSPaymentsLib/Protocols/OSPMTRequestDelegate.swift b/OSPaymentsLib/Protocols/OSPMTRequestDelegate.swift index 2a5e2c3..c386c84 100644 --- a/OSPaymentsLib/Protocols/OSPMTRequestDelegate.swift +++ b/OSPaymentsLib/Protocols/OSPMTRequestDelegate.swift @@ -36,6 +36,7 @@ class OSPMTApplePayRequestBehaviour: NSObject, OSPMTRequestDelegate { var paymentStatus: PKPaymentAuthorizationStatus = .failure var paymentScope: OSPMTScopeModel? + var paymentDetails: OSPMTDetailsModel? var completionHandler: OSPMTCompletionHandler! /// Constructor method. @@ -48,6 +49,7 @@ class OSPMTApplePayRequestBehaviour: NSObject, OSPMTRequestDelegate { } func trigger(with detailsModel: OSPMTDetailsModel, _ completion: @escaping OSPMTCompletionHandler) { + self.paymentDetails = detailsModel self.completionHandler = completion let result = self.requestTriggerType.createRequestTriggerBehaviour(for: detailsModel, andDelegate: self) @@ -110,14 +112,45 @@ extension OSPMTApplePayRequestBehaviour: PKPaymentAuthorizationControllerDelegat /// - payment: The authorized payment. This object contains the payment token you need to submit to your payment processor, as well as the billing and shipping information required by the payment request. /// - completion: The completion handler to call with the result of authorizing the payment. func paymentAuthorizationController(_ controller: PKPaymentAuthorizationController, didAuthorizePayment payment: PKPayment, handler completion: @escaping (PKPaymentAuthorizationResult) -> Void) { - if let scopeModel = payment.createScopeModel() { - self.paymentScope = scopeModel - self.paymentStatus = .success + if let paymentGateway = self.configuration.gatewayModel { + guard let paymentDetails = self.paymentDetails, let gatewayWrapper = OSPMTGatewayFactory.createWrapper(for: paymentGateway) + else { + completion(PKPaymentAuthorizationResult(status: self.paymentStatus, errors: [OSPMTError.gatewaySetFailed])) + return + } + + gatewayWrapper.process(payment, with: paymentDetails) { [weak self] result in + guard let self = self else { return } + var errorArray = [OSPMTError]() + var paymentResultModel: OSPMTServiceProviderInfoModel? + + switch result { + case .success(let result): + paymentResultModel = result + case .failure(let error): + errorArray += [error] + } + + if errorArray.isEmpty, let scopeModel = payment.createScopeModel(for: paymentResultModel) { + self.paymentScope = scopeModel + self.paymentStatus = .success + } else { + self.paymentScope = nil + self.paymentStatus = .failure + } + + completion(PKPaymentAuthorizationResult(status: self.paymentStatus, errors: errorArray)) + } } else { - self.paymentScope = nil - self.paymentStatus = .failure + if let scopeModel = payment.createScopeModel() { + self.paymentScope = scopeModel + self.paymentStatus = .success + } else { + self.paymentScope = nil + self.paymentStatus = .failure + } + + completion(PKPaymentAuthorizationResult(status: self.paymentStatus, errors: [])) } - - completion(PKPaymentAuthorizationResult(status: self.paymentStatus, errors: [])) } } diff --git a/OSPaymentsLibTests/OSPMTGatewayFactorySpec.swift b/OSPaymentsLibTests/OSPMTGatewayFactorySpec.swift new file mode 100644 index 0000000..c6ddd2a --- /dev/null +++ b/OSPaymentsLibTests/OSPMTGatewayFactorySpec.swift @@ -0,0 +1,39 @@ +import Nimble +import Quick +@testable import OSPaymentsLib + +class OSPMTGatewayFactorySpec: QuickSpec { + override func spec() { + var model: OSPMTGatewayModel! + var wrapper: OSPMTGatewayDelegate! + + describe("Given a OSPMTGatewayModel") { + context("When given an invalid model") { + it("No Wrapper should be created") { + model = OSPMTTestConfigurations.invalidGatewayModel + wrapper = OSPMTGatewayFactory.createWrapper(for: model) + + expect(wrapper).to(beNil()) + } + } + + context("When given an invalid model Stripe") { + it("No Wrapper should be created") { + model = OSPMTTestConfigurations.invalidStripeModel + wrapper = OSPMTGatewayFactory.createWrapper(for: model) + + expect(wrapper).to(beNil()) + } + } + + context("When given a valid model Stripe") { + it("a OSPMTStripeWrapper should be created") { + model = OSPMTTestConfigurations.validStripeModel + wrapper = OSPMTGatewayFactory.createWrapper(for: model) + + expect(wrapper).toNot(beNil()) + } + } + } + } +} diff --git a/OSPaymentsLibTests/OSPMTPaymentsSpec.swift b/OSPaymentsLibTests/OSPMTPaymentsSpec.swift index 4770295..ed80414 100644 --- a/OSPaymentsLibTests/OSPMTPaymentsSpec.swift +++ b/OSPaymentsLibTests/OSPMTPaymentsSpec.swift @@ -189,16 +189,38 @@ class OSPMTPaymentsSpec: QuickSpec { describe("and an Apple Pay Handler correctly configured") { context("When the OSPMTPayments object is initialized") { - beforeEach { - payments = OSPMTPayments(applePayWithDelegate: mockDelegate, andConfiguration: OSPMTTestConfigurations.fullConfig) - } - it("Setup configuration should return a non empty text message") { + payments = OSPMTPayments(applePayWithDelegate: mockDelegate, andConfiguration: OSPMTTestConfigurations.fullConfig) + payments.setupConfiguration() expect(mockDelegate.successText).toNot(beEmpty()) expect(mockDelegate.error).to(beNil()) } + + context("And Payment Gateway information is provided") { + it("Setup configuration should return a non empty text message") { + payments = OSPMTPayments(applePayWithDelegate: mockDelegate, andConfiguration: OSPMTTestConfigurations.dummyGatewayConfig) + + payments.setupConfiguration() + + expect(mockDelegate.successText).toNot(beEmpty()) + expect(mockDelegate.error).to(beNil()) + } + } + + context("And a Stripe Payment Gateway information is provided") { + it("Setup configuration should return a non empty text message") { + payments = OSPMTPayments( + applePayWithDelegate: mockDelegate, andConfiguration: OSPMTTestConfigurations.stripeGatewayConfig + ) + + payments.setupConfiguration() + + expect(mockDelegate.successText).toNot(beEmpty()) + expect(mockDelegate.error).to(beNil()) + } + } } } } diff --git a/OSPaymentsLibTests/OSPMTStripeWrapperSpec.swift b/OSPaymentsLibTests/OSPMTStripeWrapperSpec.swift new file mode 100644 index 0000000..565a721 --- /dev/null +++ b/OSPaymentsLibTests/OSPMTStripeWrapperSpec.swift @@ -0,0 +1,180 @@ +import Nimble +import PassKit +import Quick +@testable import OSPaymentsLib + +class MockStripeAPIDelegate: OSPMTStripeAPIDelegate { + var paymentMethodId: String? + var error: OSPMTError? + + func set(_ publishableKey: String) {} + + func getPaymentMethodId(from payment: PKPayment, _ completion: @escaping (Result) -> Void) { + if let paymentMethodId = paymentMethodId { + completion(.success(paymentMethodId)) + } else if let error = error { + completion(.failure(error)) + } + } +} + +enum MockError: Error { + case generic +} + +class MockURLProtocol: URLProtocol { + override class func canInit(with request: URLRequest) -> Bool { + return true + } + + override class func canonicalRequest(for request: URLRequest) -> URLRequest { + return request + } + + static var requestHandler: ((URLRequest) throws -> (HTTPURLResponse, Data?))? + + override func startLoading() { + guard let handler = MockURLProtocol.requestHandler else { + fatalError("Handler is unavailable.") + } + + do { + let (response, data) = try handler(request) + client?.urlProtocol(self, didReceive: response, cacheStoragePolicy: .notAllowed) + + if let data = data { + client?.urlProtocol(self, didLoad: data) + } + + client?.urlProtocolDidFinishLoading(self) + } catch { + client?.urlProtocol(self, didFailWithError: error) + } + } + + override func stopLoading() {} +} + +class OSPMTStripeWrapperSpec: QuickSpec { + override func spec() { + var mockAPIDelegate: MockStripeAPIDelegate! + var mockPayment: PKPayment! + var mockDetailsModel: OSPMTDetailsModel! + var mockURL: URL! + + var stripeWrapper: OSPMTStripeWrapper! + + describe("Given a Stripe API Delegate object") { + beforeEach { + mockAPIDelegate = MockStripeAPIDelegate() + + let configuration = URLSessionConfiguration.default + configuration.protocolClasses = [MockURLProtocol.self] + let urlSession = URLSession.init(configuration: configuration) + + mockPayment = PKPayment() + + mockDetailsModel = OSPMTTestConfigurations.dummyDetailsModel + + mockURL = URL(string: OSPMTTestConfigurations.dummyString)! + + stripeWrapper = OSPMTStripeWrapper( + urlRequest: URLRequest(url: mockURL), + urlSession: urlSession, + publishableKey: OSPMTTestConfigurations.dummyString, + apiDelegate: mockAPIDelegate + ) + } + + context("When there's an error while obtaining a Payment Method ID") { + it("It should return a Stripe Payment Method Creation error") { + mockAPIDelegate.error = OSPMTError.stripePaymentMethodCreation + + stripeWrapper.process(mockPayment, with: mockDetailsModel) { result in + switch result { + case .failure(let errorResult): + expect(errorResult).to(equal(OSPMTError.stripePaymentMethodCreation)) + case .success: + fail() + } + } + } + } + + context("When a Payment Method ID is returned") { + beforeEach { + mockAPIDelegate.paymentMethodId = OSPMTTestConfigurations.dummyString + } + context("And there's an error on processing the Payment Request") { + it("It should return an 100 Status Code Error") { + MockURLProtocol.requestHandler = { request in + guard let url = request.url, url == mockURL else { + throw MockError.generic + } + + let response = HTTPURLResponse(url: mockURL, statusCode: 100, httpVersion: nil, headerFields: nil)! + return (response, OSPMTTestConfigurations.dummyString.data(using: .utf8)) + } + + stripeWrapper.process(mockPayment, with: mockDetailsModel) { result in + switch result { + case .failure(let errorResult): + expect(errorResult).to(equal(.paymentIssue)) + case .success: + fail() + } + } + } + + it("It should return an Failed Request Error") { + MockURLProtocol.requestHandler = { request in + guard let url = request.url, + url == mockURL, + let resultData = try? JSONEncoder().encode(OSPMTTestConfigurations.invalidPaymentProcessResultModel) + else { + throw MockError.generic + } + + let response = HTTPURLResponse(url: mockURL, statusCode: 200, httpVersion: nil, headerFields: nil)! + return (response, resultData) + } + + stripeWrapper.process(mockPayment, with: mockDetailsModel) { result in + switch result { + case .failure(let errorResult): + expect(errorResult).to(equal(.paymentIssue)) + case .success: + fail() + } + } + } + } + + context("And there's the Payment Request process is successful") { + it("It should return a success text") { + MockURLProtocol.requestHandler = { request in + guard let url = request.url, + url == mockURL, + let resultData = try? JSONEncoder().encode(OSPMTTestConfigurations.validPaymentProcessResultModel) + else { + throw MockError.generic + } + + let response = HTTPURLResponse(url: mockURL, statusCode: 200, httpVersion: nil, headerFields: nil)! + return (response, resultData) + } + + stripeWrapper.process(mockPayment, with: mockDetailsModel) { result in + switch result { + case .success(let resultModel): + expect(resultModel).to(equal(OSPMTTestConfigurations.validPaymentProcessResultModel)) + case .failure: + fail() + } + } + } + } + } + } + } +} diff --git a/OSPaymentsLibTests/OSPMTTestConfigurations.swift b/OSPaymentsLibTests/OSPMTTestConfigurations.swift index 63de031..059e39f 100644 --- a/OSPaymentsLibTests/OSPMTTestConfigurations.swift +++ b/OSPaymentsLibTests/OSPMTTestConfigurations.swift @@ -57,6 +57,39 @@ struct OSPMTTestConfigurations { static let nilNetworkCapabilityConfig: OSPMTConfiguration = [:] + static let dummyGatewayConfig: OSPMTConfiguration = [ + OSPMTApplePayConfiguration.ConfigurationKeys.merchantID: Self.dummyString, + OSPMTApplePayConfiguration.ConfigurationKeys.merchantName: Self.dummyString, + OSPMTApplePayConfiguration.ConfigurationKeys.merchantCountryCode: Self.dummyString, + OSPMTApplePayConfiguration.ConfigurationKeys.paymentAllowedNetworks: [Self.dummyString], + OSPMTApplePayConfiguration.ConfigurationKeys.paymentSupportedCapabilities: [Self.dummyString], + OSPMTApplePayConfiguration.ConfigurationKeys.paymentSupportedCardCountries: [Self.dummyString], + OSPMTApplePayConfiguration.ConfigurationKeys.shippingSupportedContacts: [Self.dummyString, Self.dummyString], + OSPMTApplePayConfiguration.ConfigurationKeys.billingSupportedContacts: [Self.dummyString, Self.dummyString], + OSPMTApplePayConfiguration.ConfigurationKeys.paymentGateway: [ + OSPMTApplePayConfiguration.ConfigurationKeys.paymentGatewayName: Self.dummyString, + OSPMTApplePayConfiguration.ConfigurationKeys.paymentRequestURL: Self.dummyString + ], + OSPMTApplePayConfiguration.ConfigurationKeys.paymentRequestURL: Self.dummyString + ] + + static let stripeGatewayConfig: OSPMTConfiguration = [ + OSPMTApplePayConfiguration.ConfigurationKeys.merchantID: Self.dummyString, + OSPMTApplePayConfiguration.ConfigurationKeys.merchantName: Self.dummyString, + OSPMTApplePayConfiguration.ConfigurationKeys.merchantCountryCode: Self.dummyString, + OSPMTApplePayConfiguration.ConfigurationKeys.paymentAllowedNetworks: [Self.dummyString], + OSPMTApplePayConfiguration.ConfigurationKeys.paymentSupportedCapabilities: [Self.dummyString], + OSPMTApplePayConfiguration.ConfigurationKeys.paymentSupportedCardCountries: [Self.dummyString], + OSPMTApplePayConfiguration.ConfigurationKeys.shippingSupportedContacts: [Self.dummyString, Self.dummyString], + OSPMTApplePayConfiguration.ConfigurationKeys.billingSupportedContacts: [Self.dummyString, Self.dummyString], + OSPMTApplePayConfiguration.ConfigurationKeys.paymentGateway: [ + OSPMTApplePayConfiguration.ConfigurationKeys.paymentGatewayName: OSPMTGateway.stripe.rawValue, + OSPMTApplePayConfiguration.ConfigurationKeys.paymentRequestURL: Self.dummyString, + OSPMTApplePayConfiguration.ConfigurationKeys.stripePublishableKey: Self.dummyString + ], + OSPMTApplePayConfiguration.ConfigurationKeys.paymentRequestURL: Self.dummyString + ] + // MARK: - OSPMTApplePayRequestBehaviourSpec Configurations static let dummyContact = OSPMTContact(isCustom: true, contactArray: [Self.dummyString]) static let dummyDetailsModel = OSPMTDetailsModel( @@ -137,4 +170,19 @@ struct OSPMTTestConfigurations { guard let data = try? JSONEncoder().encode(model), let result = String(data: data, encoding: .utf8) else { return nil } return result } + + // MARK: - OSPMTGatewayFactorySpec Configurations + + static let validStripeModel = OSPMTGatewayModel( + gateway: OSPMTGateway.stripe.rawValue, publishableKey: Self.dummyString, requestURL: Self.dummyString + ) + static let invalidStripeModel = OSPMTGatewayModel( + gateway: OSPMTGateway.stripe.rawValue, publishableKey: nil, requestURL: Self.dummyString + ) + static let invalidGatewayModel = OSPMTGatewayModel( + gateway: Self.dummyString, publishableKey: Self.dummyString, requestURL: Self.dummyString + ) + + static let invalidPaymentProcessResultModel = OSPMTServiceProviderInfoModel(id: Self.dummyString, status: OSPMTProcessStatus.fail.rawValue) + static let validPaymentProcessResultModel = OSPMTServiceProviderInfoModel(id: Self.dummyString, status: OSPMTProcessStatus.success.rawValue) } diff --git a/OSPaymentsPluginLib.podspec b/OSPaymentsPluginLib.podspec index bffeff1..1d222a6 100644 --- a/OSPaymentsPluginLib.podspec +++ b/OSPaymentsPluginLib.podspec @@ -19,4 +19,5 @@ Pod::Spec.new do |s| s.swift_versions = '5.0' s.source_files = 'OSPaymentsLib/**/*.swift' + s.dependency 'StripePayments', '23.2.0' end \ No newline at end of file diff --git a/Podfile b/Podfile index 9432713..ad7c163 100644 --- a/Podfile +++ b/Podfile @@ -4,10 +4,11 @@ target 'OSPaymentsLib' do use_frameworks! # Pods for OSPaymentsLib + pod 'StripePayments', '23.2.0' target 'OSPaymentsLibTests' do - pod 'Quick', '~> 5.0.1' - pod 'Nimble', '~> 10.0.0' + pod 'Quick', '5.0.1' + pod 'Nimble', '10.0.0' end end diff --git a/Podfile.lock b/Podfile.lock index 72d9901..5e1f895 100644 --- a/Podfile.lock +++ b/Podfile.lock @@ -1,20 +1,31 @@ PODS: - Nimble (10.0.0) - Quick (5.0.1) + - StripeCore (23.2.0) + - StripePayments (23.2.0): + - StripeCore (= 23.2.0) + - StripePayments/Stripe3DS2 (= 23.2.0) + - StripePayments/Stripe3DS2 (23.2.0): + - StripeCore (= 23.2.0) DEPENDENCIES: - - Nimble (~> 10.0.0) - - Quick (~> 5.0.1) + - Nimble (= 10.0.0) + - Quick (= 5.0.1) + - StripePayments (= 23.2.0) SPEC REPOS: trunk: - Nimble - Quick + - StripeCore + - StripePayments SPEC CHECKSUMS: Nimble: 5316ef81a170ce87baf72dd961f22f89a602ff84 Quick: 749aa754fd1e7d984f2000fe051e18a3a9809179 + StripeCore: 6da916796f87ab91f3dae1d78a93602465964cbc + StripePayments: 7651a56a2a7fe320e5e8b1cb0c2e881536b75021 -PODFILE CHECKSUM: 1dd1a31673f4cf5f75ac55de69a3a3854ab3533b +PODFILE CHECKSUM: c547ae5a2dc2e6c1ec55f7b849384bf4cf87a950 COCOAPODS: 1.11.3 diff --git a/Pods/Manifest.lock b/Pods/Manifest.lock index 72d9901..5e1f895 100644 --- a/Pods/Manifest.lock +++ b/Pods/Manifest.lock @@ -1,20 +1,31 @@ PODS: - Nimble (10.0.0) - Quick (5.0.1) + - StripeCore (23.2.0) + - StripePayments (23.2.0): + - StripeCore (= 23.2.0) + - StripePayments/Stripe3DS2 (= 23.2.0) + - StripePayments/Stripe3DS2 (23.2.0): + - StripeCore (= 23.2.0) DEPENDENCIES: - - Nimble (~> 10.0.0) - - Quick (~> 5.0.1) + - Nimble (= 10.0.0) + - Quick (= 5.0.1) + - StripePayments (= 23.2.0) SPEC REPOS: trunk: - Nimble - Quick + - StripeCore + - StripePayments SPEC CHECKSUMS: Nimble: 5316ef81a170ce87baf72dd961f22f89a602ff84 Quick: 749aa754fd1e7d984f2000fe051e18a3a9809179 + StripeCore: 6da916796f87ab91f3dae1d78a93602465964cbc + StripePayments: 7651a56a2a7fe320e5e8b1cb0c2e881536b75021 -PODFILE CHECKSUM: 1dd1a31673f4cf5f75ac55de69a3a3854ab3533b +PODFILE CHECKSUM: c547ae5a2dc2e6c1ec55f7b849384bf4cf87a950 COCOAPODS: 1.11.3 diff --git a/Pods/Pods.xcodeproj/project.pbxproj b/Pods/Pods.xcodeproj/project.pbxproj index 451c2cc..7e3c181 100644 --- a/Pods/Pods.xcodeproj/project.pbxproj +++ b/Pods/Pods.xcodeproj/project.pbxproj @@ -7,301 +7,1514 @@ objects = { /* Begin PBXBuildFile section */ - 01236C984BBB2918575C35713E2E08B4 /* BeLessThanOrEqual.swift in Sources */ = {isa = PBXBuildFile; fileRef = 586B5A37C0A10198805DA6175B2EB342 /* BeLessThanOrEqual.swift */; settings = {COMPILER_FLAGS = "-DPRODUCT_NAME=Nimble/Nimble"; }; }; - 057C1964EBAFCBC649F8012723CDADF5 /* SatisfyAnyOf.swift in Sources */ = {isa = PBXBuildFile; fileRef = 21C0C122235EDD894313B02C03C7C538 /* SatisfyAnyOf.swift */; settings = {COMPILER_FLAGS = "-DPRODUCT_NAME=Nimble/Nimble"; }; }; - 0650AF0DB8DE333CE5D99D704E29AC02 /* AllPass.swift in Sources */ = {isa = PBXBuildFile; fileRef = A12262F224D0D0A168C398C49F628A15 /* AllPass.swift */; settings = {COMPILER_FLAGS = "-DPRODUCT_NAME=Nimble/Nimble"; }; }; - 088A5A88342D60B6FCFAEADBF0749220 /* AdapterProtocols.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5523F3CB4F893F0BF3631D865BEEC2B4 /* AdapterProtocols.swift */; settings = {COMPILER_FLAGS = "-DPRODUCT_NAME=Nimble/Nimble"; }; }; - 09D4B856CFEA59F4E16AB91D1F06D50C /* XCTestObservationCenter+Register.m in Sources */ = {isa = PBXBuildFile; fileRef = E2FF0C6AC202911FB7A52FE099B9B734 /* XCTestObservationCenter+Register.m */; settings = {COMPILER_FLAGS = "-DPRODUCT_NAME=Nimble/Nimble"; }; }; - 0BAC760A19A0F7BAD74264AA4DDDD679 /* World+DSL.swift in Sources */ = {isa = PBXBuildFile; fileRef = F3ED266DDE9C244816DD6A53157F8745 /* World+DSL.swift */; }; - 0C0D56E489977C4C3AAC657267CBE490 /* Pods-OSPaymentsLib-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 8FAE50E0E3AD48853025A2E73597E47B /* Pods-OSPaymentsLib-dummy.m */; }; - 0E398EF6297FFF6CC9BC74421BF1712D /* ContainElementSatisfying.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84CC299AC522B25A61A3FAF124FF83FC /* ContainElementSatisfying.swift */; settings = {COMPILER_FLAGS = "-DPRODUCT_NAME=Nimble/Nimble"; }; }; - 0F776B26BC641CB895C2E7D961C71152 /* ExampleHooks.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2362FBD489CCE1D540C808716D1EB8C4 /* ExampleHooks.swift */; }; - 154A42D3BBF847E3C2C7A6BB4EFAEE84 /* DSL.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3CE338476557D8F2CF2B6E987F5A31CA /* DSL.swift */; }; - 19A8009537BCAD56435B2DDC620B29AA /* mach_excServer.h in Headers */ = {isa = PBXBuildFile; fileRef = E25EB083AA8985DFFE745FCF5758009A /* mach_excServer.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 1B5648DECACC2C478440DD19516ADCC5 /* MatcherProtocols.swift in Sources */ = {isa = PBXBuildFile; fileRef = E27895722ECA9E17BA1DC28F822F97B9 /* MatcherProtocols.swift */; settings = {COMPILER_FLAGS = "-DPRODUCT_NAME=Nimble/Nimble"; }; }; - 1C469C17A0E35E4508F74FEB1EDA586C /* DSL.m in Sources */ = {isa = PBXBuildFile; fileRef = 49D566AD1F3A57C62675DCFF1174ADF8 /* DSL.m */; settings = {COMPILER_FLAGS = "-DPRODUCT_NAME=Nimble/Nimble"; }; }; - 1CBAF686CA3277D9FC264A3B1E692471 /* Pods-OSPaymentsLib-OSPaymentsLibTests-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = D3A8BF3C48BD1892DD33A7126753E72F /* Pods-OSPaymentsLib-OSPaymentsLibTests-dummy.m */; }; - 1E5D8B0BD08347A08E3CC4FF6267376F /* Pods-OSPaymentsLib-OSPaymentsLibTests-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = B1D21BE1B5A742AA9C8EEE801D57559C /* Pods-OSPaymentsLib-OSPaymentsLibTests-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 207866DD86EDE603026D5AEDAF5ABE44 /* QuickConfiguration.m in Sources */ = {isa = PBXBuildFile; fileRef = E6BB1E6C30B81EDB33EC7FDB6C205C79 /* QuickConfiguration.m */; }; - 21601609288258F44177C9A71A1A5012 /* Pods-OSPaymentsLib-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 02F5AF25FD35DDCE251A9006737617A5 /* Pods-OSPaymentsLib-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 21F3408E9BD0BE7C7A9FFBF43B4F28A0 /* Nimble.h in Headers */ = {isa = PBXBuildFile; fileRef = 7C826AD498684E411DD1C792748D889C /* Nimble.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 2223D9864ED3F01713DA2180EF7190B9 /* BeVoid.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5273DD569D843C265AF46176F4A534FD /* BeVoid.swift */; settings = {COMPILER_FLAGS = "-DPRODUCT_NAME=Nimble/Nimble"; }; }; - 233AB756F67ABBD886C54BF9F12403DF /* HaveCount.swift in Sources */ = {isa = PBXBuildFile; fileRef = 16F99FA0960BE24312A4603668FD6CFA /* HaveCount.swift */; settings = {COMPILER_FLAGS = "-DPRODUCT_NAME=Nimble/Nimble"; }; }; - 2357EB01C617A8A015615080DBB012D6 /* Equal.swift in Sources */ = {isa = PBXBuildFile; fileRef = 844435B050856A3A90F2F2DC5D10C71E /* Equal.swift */; settings = {COMPILER_FLAGS = "-DPRODUCT_NAME=Nimble/Nimble"; }; }; - 289B613DD13E58EA28C0DFAF4358BA68 /* ElementsEqual.swift in Sources */ = {isa = PBXBuildFile; fileRef = C851CC15E8E0E35CE23A1222E105A809 /* ElementsEqual.swift */; settings = {COMPILER_FLAGS = "-DPRODUCT_NAME=Nimble/Nimble"; }; }; - 28D6E884D7AB6CF2B4BFF328D2537D22 /* SatisfyAllOf.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE08781F30AAAA4776BC4A79E3FA9F40 /* SatisfyAllOf.swift */; settings = {COMPILER_FLAGS = "-DPRODUCT_NAME=Nimble/Nimble"; }; }; - 2C85A44748A3F58CE8C0AE291B9EDDFB /* QCKConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 88CE28DB5FFB584E123C56C4345A73E7 /* QCKConfiguration.swift */; }; - 2D6DB63EBCA201CFABA3012CD1C360BD /* ExampleGroup.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5813F3776773A4275874BC369BB34A01 /* ExampleGroup.swift */; }; - 32995147DC30DF5022DD66C0470BFDE9 /* QuickSpecBase.h in Headers */ = {isa = PBXBuildFile; fileRef = 60403D3F19863854702A6361D7F61850 /* QuickSpecBase.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 35C095305E5FB8CF40BB6C6A7F02E678 /* ErrorUtility.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD87F111AA17D3829427C832EB042273 /* ErrorUtility.swift */; }; - 389DF9C2C99BD347316A28A8F10387D3 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CA8B94E9D3B433157168D1EECCEC11CD /* Foundation.framework */; }; - 3ABDA920FDD838A534E55347FF35ACCC /* BeNil.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C5852911233E16D8DBA632AAF28C4C0 /* BeNil.swift */; settings = {COMPILER_FLAGS = "-DPRODUCT_NAME=Nimble/Nimble"; }; }; - 3B59EB43186F324A79D05C3201369283 /* QuickSpecBase.m in Sources */ = {isa = PBXBuildFile; fileRef = 0A6115706ED27012A9F43E253D3D3DD7 /* QuickSpecBase.m */; }; - 3B5E796F1BFBB87AAB31305D6FCE160E /* Nimble-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 33FD12F984B4BA8B5D001D0AFD13F708 /* Nimble-dummy.m */; }; - 3CFE6D672FEFBE8A9D10D5723FB88BF2 /* Stringers.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6E6AA1575C0AD81F762039746AFAECDC /* Stringers.swift */; settings = {COMPILER_FLAGS = "-DPRODUCT_NAME=Nimble/Nimble"; }; }; - 3E1105B44CCBDA9EC8C6C96EACCCC28F /* Behavior.swift in Sources */ = {isa = PBXBuildFile; fileRef = 45F6B7AC8B7979F25F17036731EE339D /* Behavior.swift */; }; - 3E97A584E7FDD55A6AC072DB23043FCC /* SourceLocation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 755D25C0FCCF8F6E3E59CF4F94C8C060 /* SourceLocation.swift */; settings = {COMPILER_FLAGS = "-DPRODUCT_NAME=Nimble/Nimble"; }; }; - 3FA8E6AEBD8687BF75B467C33ADF0045 /* CwlCatchException.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0B2A30FEA2214E06D065AE8997736B53 /* CwlCatchException.swift */; settings = {COMPILER_FLAGS = "-DPRODUCT_NAME=Nimble/Nimble"; }; }; - 40D9B846E5A8AF781C0A0C41FED0E0F8 /* BeGreaterThanOrEqualTo.swift in Sources */ = {isa = PBXBuildFile; fileRef = C0DEE4FA5F5FF28F88648CF9EF3B4C39 /* BeGreaterThanOrEqualTo.swift */; settings = {COMPILER_FLAGS = "-DPRODUCT_NAME=Nimble/Nimble"; }; }; - 42BC3C3CBE7E5484F09BAD3204DE521D /* NSBundle+CurrentTestBundle.swift in Sources */ = {isa = PBXBuildFile; fileRef = AF3CEFA5153F8ACE3EA7629E00B17B8F /* NSBundle+CurrentTestBundle.swift */; }; - 498D0CEF04FDF36BE2B89A67015FF3A0 /* String+C99ExtendedIdentifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = B14A4B16D42CCCBE3D21CBDE4FFC9AA4 /* String+C99ExtendedIdentifier.swift */; }; - 4A457767C9968D139BD8AAD877DFC117 /* ThrowError.swift in Sources */ = {isa = PBXBuildFile; fileRef = D41AA0E2939FB981CED2EFF1B98A57B3 /* ThrowError.swift */; settings = {COMPILER_FLAGS = "-DPRODUCT_NAME=Nimble/Nimble"; }; }; - 4DB106EF5D81F121EA58D82401C5DD1C /* MatchError.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6BAC25BC63EBD14D35CDE94813660768 /* MatchError.swift */; settings = {COMPILER_FLAGS = "-DPRODUCT_NAME=Nimble/Nimble"; }; }; - 4DFD4AE1B1C12F59014A9C1FE8F7AE47 /* BeResult.swift in Sources */ = {isa = PBXBuildFile; fileRef = BBA4F4C4573FD9589D1CA0CA3DD18A0C /* BeResult.swift */; settings = {COMPILER_FLAGS = "-DPRODUCT_NAME=Nimble/Nimble"; }; }; - 4EC19A4F9EE9863B3CF7BDB7607FE96B /* CwlBadInstructionException.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2E9331718C3E375B9305AE6782A65CC4 /* CwlBadInstructionException.swift */; settings = {COMPILER_FLAGS = "-DPRODUCT_NAME=Nimble/Nimble"; }; }; - 51BAE003E7BD972B4F6EB54CFB7E1BF0 /* RaisesException.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2FBFBBA48C11C5DAD16F0C15F64297B /* RaisesException.swift */; settings = {COMPILER_FLAGS = "-DPRODUCT_NAME=Nimble/Nimble"; }; }; - 5258586AADBC8482EFAFB4B591A17E03 /* ToSucceed.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51320337A23D4A8E10E00BFD67B8D043 /* ToSucceed.swift */; settings = {COMPILER_FLAGS = "-DPRODUCT_NAME=Nimble/Nimble"; }; }; - 5448447D317610CE0DF66B87CF6F1094 /* Closures.swift in Sources */ = {isa = PBXBuildFile; fileRef = E1F00FC1EB20AC2CA0B5B083F84159A5 /* Closures.swift */; }; - 58CAB839E63D7D4575D3DEDF8C98EDD9 /* Await.swift in Sources */ = {isa = PBXBuildFile; fileRef = 40955816DD54EA848880AD2815A76921 /* Await.swift */; settings = {COMPILER_FLAGS = "-DPRODUCT_NAME=Nimble/Nimble"; }; }; - 5DE534ADC468F5FFC43371CE7138923F /* URL+FileName.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2AECA1C81ADFA2CA35D84DC7FF1902B2 /* URL+FileName.swift */; }; - 604A73AD1D0E82356F2A073C53BC6517 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CA8B94E9D3B433157168D1EECCEC11CD /* Foundation.framework */; }; - 60A059AA3734D5D3F2F73D07C427F4C1 /* NMBExceptionCapture.h in Headers */ = {isa = PBXBuildFile; fileRef = 7A7CD7566A962848ACAFAE01FAC08AA6 /* NMBExceptionCapture.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 612581CCD8346C696A80E6BC09D24C1F /* QCKDSL.h in Headers */ = {isa = PBXBuildFile; fileRef = 43D9B7DA298758F3F8912543839CC426 /* QCKDSL.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 61F1ADB6BE662783C1A01C2C1720A9BE /* Expression.swift in Sources */ = {isa = PBXBuildFile; fileRef = 67A91DF9E678606788A96C9150D53EA6 /* Expression.swift */; settings = {COMPILER_FLAGS = "-DPRODUCT_NAME=Nimble/Nimble"; }; }; - 654580360E6694D7F7CE85CE5390DA79 /* PostNotification.swift in Sources */ = {isa = PBXBuildFile; fileRef = E2EB0871827E9D45D4B63C66C93F292B /* PostNotification.swift */; settings = {COMPILER_FLAGS = "-DPRODUCT_NAME=Nimble/Nimble"; }; }; - 6A47C53473FBCF2FF5C85069FBD4CA8D /* QuickConfiguration.h in Headers */ = {isa = PBXBuildFile; fileRef = 32395E85CAF13637932ACEECADC2D96D /* QuickConfiguration.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 6C1386A39405BDA544D5BEE2C9155AB1 /* QuickSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = 254558E5834898D2301B3E8C4F620311 /* QuickSpec.m */; }; - 6D2F9F1DC6C1DE1C73F4382904B9C97C /* DSL+Wait.swift in Sources */ = {isa = PBXBuildFile; fileRef = 298044D1245C4BD022B7F13791639E75 /* DSL+Wait.swift */; settings = {COMPILER_FLAGS = "-DPRODUCT_NAME=Nimble/Nimble"; }; }; - 6F4F5989C108EB29AB735E9CAF4B6E0A /* BeginWith.swift in Sources */ = {isa = PBXBuildFile; fileRef = E937CE363DBBFE4523820E40E9D3F9A0 /* BeginWith.swift */; settings = {COMPILER_FLAGS = "-DPRODUCT_NAME=Nimble/Nimble"; }; }; - 6F796B7E3AA428C9D8E88F0F2269664F /* NimbleXCTestHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3D4A2AFFEAE1D8A8E4479F656ADF2D2 /* NimbleXCTestHandler.swift */; settings = {COMPILER_FLAGS = "-DPRODUCT_NAME=Nimble/Nimble"; }; }; - 707245706183C9814604FBE34CD83152 /* NMBExpectation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0F4A8507ACE009C2C0F45E1FDED202C7 /* NMBExpectation.swift */; settings = {COMPILER_FLAGS = "-DPRODUCT_NAME=Nimble/Nimble"; }; }; - 7190961540266108624E854866842A81 /* NMBStringify.h in Headers */ = {isa = PBXBuildFile; fileRef = 369990B25C94966B37B0E376A2FE93C0 /* NMBStringify.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 781AF529033437C39A1E1D5CDF9D266D /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CA8B94E9D3B433157168D1EECCEC11CD /* Foundation.framework */; }; - 79A9ADCAE72B5F30CE882F79CDDDD47F /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CA8B94E9D3B433157168D1EECCEC11CD /* Foundation.framework */; }; - 7DF5C2582E1C9DE5BC6BF84C0AF1337B /* BeCloseTo.swift in Sources */ = {isa = PBXBuildFile; fileRef = F31245591C4C010F1303DAC1BC9804C1 /* BeCloseTo.swift */; settings = {COMPILER_FLAGS = "-DPRODUCT_NAME=Nimble/Nimble"; }; }; - 80428B0834B1272AB4E96E00D3FAA081 /* Example.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7CDC6B9AB35B53FC579C731AE67FD846 /* Example.swift */; }; - 80DB7C67B0D7A32BF885B5CD17C745A1 /* NimbleEnvironment.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9215339C71BDBD5B494E9EFD44005158 /* NimbleEnvironment.swift */; settings = {COMPILER_FLAGS = "-DPRODUCT_NAME=Nimble/Nimble"; }; }; - 86037D5CAD49EC09A2B944ADBF561059 /* Errors.swift in Sources */ = {isa = PBXBuildFile; fileRef = 447626370CDD31CDCC3656C6E0B3BA05 /* Errors.swift */; settings = {COMPILER_FLAGS = "-DPRODUCT_NAME=Nimble/Nimble"; }; }; - 86F84DE049A0E2CADAC8344E20D070BE /* mach_excServer.c in Sources */ = {isa = PBXBuildFile; fileRef = 8470BE37EE9259F9FDADDFC80764A837 /* mach_excServer.c */; settings = {COMPILER_FLAGS = "-DPRODUCT_NAME=Nimble/Nimble"; }; }; - 87535E5C51E9F6B7B1517FEA95033D1C /* QuickConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 204E01215147E1CFDB134360F8F1938E /* QuickConfiguration.swift */; }; - 88380C6AB029E423E69827B204BFF18A /* NMBStringify.m in Sources */ = {isa = PBXBuildFile; fileRef = 97522C7BBA1F97437715C74303E5A686 /* NMBStringify.m */; settings = {COMPILER_FLAGS = "-DPRODUCT_NAME=Nimble/Nimble"; }; }; - 8A9FE00A3D26CFEDEF3503C93FEFC954 /* EndWith.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2C9CC327536739702EE1B8865E38BED6 /* EndWith.swift */; settings = {COMPILER_FLAGS = "-DPRODUCT_NAME=Nimble/Nimble"; }; }; - 8EFA132322053E7D8A1F9F380B5D8935 /* SuiteHooks.swift in Sources */ = {isa = PBXBuildFile; fileRef = 880EBA466E9150F71DE3C4A76DB140D8 /* SuiteHooks.swift */; }; - 8F5593DFFFCAC3D618365EC2590A3E31 /* AssertionRecorder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64B896AB55261B6E62E0FC506B92A8EC /* AssertionRecorder.swift */; settings = {COMPILER_FLAGS = "-DPRODUCT_NAME=Nimble/Nimble"; }; }; - 92DE6AC67462F0A507D3187892D4FA8A /* Equal+Tuple.swift in Sources */ = {isa = PBXBuildFile; fileRef = 16671DF91816B7CC8BAA2964E1E6414C /* Equal+Tuple.swift */; settings = {COMPILER_FLAGS = "-DPRODUCT_NAME=Nimble/Nimble"; }; }; - 981F6B1579CE5D0BDB6E936DFC0B24F1 /* BeAnInstanceOf.swift in Sources */ = {isa = PBXBuildFile; fileRef = B534FC537F198D4CB2269C659A93783F /* BeAnInstanceOf.swift */; settings = {COMPILER_FLAGS = "-DPRODUCT_NAME=Nimble/Nimble"; }; }; - 993ED0D1D74DDFAF99D4108636EFFA64 /* FailureMessage.swift in Sources */ = {isa = PBXBuildFile; fileRef = E919903C10E88C8DB75C2CD00A266948 /* FailureMessage.swift */; settings = {COMPILER_FLAGS = "-DPRODUCT_NAME=Nimble/Nimble"; }; }; - 994DAB83E925F5BF28B00DFD0F9795CB /* CwlCatchException.m in Sources */ = {isa = PBXBuildFile; fileRef = 654A3ADC4BC6E05E9BDC2D8F858A74BA /* CwlCatchException.m */; settings = {COMPILER_FLAGS = "-DPRODUCT_NAME=Nimble/Nimble"; }; }; - 9AB3D03BC12D48113C0AFB7E687A274D /* BeginWithPrefix.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7893AC67AE4B488BC3E9604A46413A06 /* BeginWithPrefix.swift */; settings = {COMPILER_FLAGS = "-DPRODUCT_NAME=Nimble/Nimble"; }; }; - 9B4B84C8A58733E87C1F30CDE34F3BEE /* Filter.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB836F954501FFEA0AA8E87E8856D7A7 /* Filter.swift */; }; - 9B981E6DB0846F597838D6995E3F2EAC /* QuickSelectedTestSuiteBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = CDDFBC1CEF007E69BBCFDEFF88615F2C /* QuickSelectedTestSuiteBuilder.swift */; }; - 9C75931ADE8431B4C3C4AE2D59E70977 /* Predicate.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB88DCC04205DB0A61C17B66FFA0AE97 /* Predicate.swift */; settings = {COMPILER_FLAGS = "-DPRODUCT_NAME=Nimble/Nimble"; }; }; - A017E1A4E1C0AA61CDB6F1E8382D3384 /* ExpectationMessage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3DB3B3904CE5F831A2214803D978A197 /* ExpectationMessage.swift */; settings = {COMPILER_FLAGS = "-DPRODUCT_NAME=Nimble/Nimble"; }; }; - A0F1DDBCD61B35967DED6A8F6A69B9A5 /* Async.swift in Sources */ = {isa = PBXBuildFile; fileRef = A1E026C7DAC445C7C813121DE7F03837 /* Async.swift */; settings = {COMPILER_FLAGS = "-DPRODUCT_NAME=Nimble/Nimble"; }; }; - A327A211C8B71069F32FAE5F5B3807C4 /* HooksPhase.swift in Sources */ = {isa = PBXBuildFile; fileRef = EBC4D3688977E2D961A8F985B1FC0F73 /* HooksPhase.swift */; }; - A357C8E38B58FA37B8E1A6103D4E9A0A /* XCTestSuite+QuickTestSuiteBuilder.m in Sources */ = {isa = PBXBuildFile; fileRef = 0BB908657F2C86943C6660C8F0130CEB /* XCTestSuite+QuickTestSuiteBuilder.m */; }; - A487451E3CC40D7F9549FA292435273B /* NMBExceptionCapture.m in Sources */ = {isa = PBXBuildFile; fileRef = 81CA9AA102BC399952DACFC1F5740345 /* NMBExceptionCapture.m */; settings = {COMPILER_FLAGS = "-DPRODUCT_NAME=Nimble/Nimble"; }; }; - AC0278DBE6921D2AA8CA82CBE8805202 /* AssertionDispatcher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 090D7BCE58F5A67C1B30F59637E0EE53 /* AssertionDispatcher.swift */; settings = {COMPILER_FLAGS = "-DPRODUCT_NAME=Nimble/Nimble"; }; }; - AC1B0A94D98FF6A485E56165BDAAFB8F /* BeAKindOf.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B95333BD525E87BFF22C57ED6E20FD5 /* BeAKindOf.swift */; settings = {COMPILER_FLAGS = "-DPRODUCT_NAME=Nimble/Nimble"; }; }; - ACAA345A1CCAFA1F4EE69B3C25D62558 /* Contain.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4149CC5C4007BD87DFDB7E2114AE830D /* Contain.swift */; settings = {COMPILER_FLAGS = "-DPRODUCT_NAME=Nimble/Nimble"; }; }; - AD022386EA01CE480072E4C2E261BEC6 /* QuickTestObservation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 350B976ED907275DDED563482009AFD2 /* QuickTestObservation.swift */; }; - AFB4F603FD0F5C407CB8920F6A5BA7A1 /* Expectation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85C9317EF9B3052FC9D544E30801F901 /* Expectation.swift */; settings = {COMPILER_FLAGS = "-DPRODUCT_NAME=Nimble/Nimble"; }; }; - B93F3526A95D7F43EEBFEE5E453E4795 /* BeLessThan.swift in Sources */ = {isa = PBXBuildFile; fileRef = EF5F8634034723707BA489895B2AC37A /* BeLessThan.swift */; settings = {COMPILER_FLAGS = "-DPRODUCT_NAME=Nimble/Nimble"; }; }; - BD3ABAC28025564DCF2E6C12009435DF /* CwlMachBadInstructionHandler.m in Sources */ = {isa = PBXBuildFile; fileRef = 1B6A8AE2D5EF989F29A4FFB4EB7D52A8 /* CwlMachBadInstructionHandler.m */; settings = {COMPILER_FLAGS = "-DPRODUCT_NAME=Nimble/Nimble"; }; }; - BF62525E5628A9F7604BA8479691318C /* BeLogical.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3B4E2AF01C07390467B2A032C1081912 /* BeLogical.swift */; settings = {COMPILER_FLAGS = "-DPRODUCT_NAME=Nimble/Nimble"; }; }; - C03116C765F1A8893559730965ECBAD8 /* Nimble-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 1FC0C54E76B49BF11F64E24F0931846C /* Nimble-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; - C20BFECB0A04FE439AE243D89E687B8A /* QuickTestSuite.swift in Sources */ = {isa = PBXBuildFile; fileRef = 289E9ACE73C6629DAAEA21D42495B76E /* QuickTestSuite.swift */; }; - C5DF891232B50DB810099403734CFCEE /* Match.swift in Sources */ = {isa = PBXBuildFile; fileRef = 516931D0E6A9461B9C20990FA366E1F9 /* Match.swift */; settings = {COMPILER_FLAGS = "-DPRODUCT_NAME=Nimble/Nimble"; }; }; - C7DB9FB7C8378ADC0DBC744F9359C0C9 /* BeIdenticalTo.swift in Sources */ = {isa = PBXBuildFile; fileRef = 115813CA22C723977B41201CF3B4C44A /* BeIdenticalTo.swift */; settings = {COMPILER_FLAGS = "-DPRODUCT_NAME=Nimble/Nimble"; }; }; - C8539F1BDF052B57BDB129D3D4B07364 /* Callsite.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF200F89D143FA102042E6D285D5B6B2 /* Callsite.swift */; }; - C85E1092F4DAACDD63FB8E8B0E144095 /* ExampleMetadata.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50FAC3D0F71CAC2AEF632440A982DF9D /* ExampleMetadata.swift */; }; - C96B370E9B3442878448F8FFFDC98C7A /* Quick-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = AD1B7F0757B5057BCF6D7D1F6B0B7BD1 /* Quick-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; - CA32F74C00C2448397720AB161360835 /* CwlDarwinDefinitions.swift in Sources */ = {isa = PBXBuildFile; fileRef = C34F47D81171E27AF285CDD1AF9F659C /* CwlDarwinDefinitions.swift */; settings = {COMPILER_FLAGS = "-DPRODUCT_NAME=Nimble/Nimble"; }; }; - D6F1A9AFE522D73CB8BDF851FF6F7ACC /* BeEmpty.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2CF56DC23988E5C892B0834949D740C5 /* BeEmpty.swift */; settings = {COMPILER_FLAGS = "-DPRODUCT_NAME=Nimble/Nimble"; }; }; - D8B8FCEC597824B40986C8F4F7B50899 /* QuickSpec.h in Headers */ = {isa = PBXBuildFile; fileRef = F75E74A600C812323367AD98A7E46500 /* QuickSpec.h */; settings = {ATTRIBUTES = (Public, ); }; }; - DA9B61878019B5428B614BDDB5948F01 /* QCKDSL.m in Sources */ = {isa = PBXBuildFile; fileRef = 230259C7BBC0AB021F9278A064AADAC1 /* QCKDSL.m */; }; - DD130331C3820B0A4A655D6422167410 /* CwlCatchBadInstruction.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4C39466E1E06F0DE2D25E4D0D4E6169 /* CwlCatchBadInstruction.swift */; settings = {COMPILER_FLAGS = "-DPRODUCT_NAME=Nimble/Nimble"; }; }; - E1CD0FEF6BA86FA9C28038C818E2514A /* Quick.h in Headers */ = {isa = PBXBuildFile; fileRef = E7639378BFCFD4BC8587A03243C01A64 /* Quick.h */; settings = {ATTRIBUTES = (Public, ); }; }; - E2EE2E7797C383576ACBFE4986179459 /* CwlMachBadInstructionHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = 23E11C41EA8F304D43F144554949AEFF /* CwlMachBadInstructionHandler.h */; settings = {ATTRIBUTES = (Public, ); }; }; - E5ACC239A1C2E515D4939ACECD147445 /* ThrowAssertion.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85254BDDFDC46F27B70DCBF181ADE6FF /* ThrowAssertion.swift */; settings = {COMPILER_FLAGS = "-DPRODUCT_NAME=Nimble/Nimble"; }; }; - EA4EC4B3853541FDC946239C036D12C9 /* CwlCatchException.h in Headers */ = {isa = PBXBuildFile; fileRef = 3EFA1693908150CAAB677FEAB89AEC2D /* CwlCatchException.h */; settings = {ATTRIBUTES = (Public, ); }; }; - EB892573E1CA332ED26DCC659406E79B /* XCTest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5EBC8F300895E39EA0DF6D6B2B5E6BCD /* XCTest.framework */; }; - F1D91144B0B756BA7723E0AE68ED6605 /* DSL.swift in Sources */ = {isa = PBXBuildFile; fileRef = A16B8BD1EFF8AB8B6940E1EC149FD38A /* DSL.swift */; settings = {COMPILER_FLAGS = "-DPRODUCT_NAME=Nimble/Nimble"; }; }; - F591765960EECDBB53CB4E5329290A4B /* World.swift in Sources */ = {isa = PBXBuildFile; fileRef = C53261F42083B42E49E80904A433DE8A /* World.swift */; }; - F8211C89835CD4106BCC584D260CF7C8 /* DispatchTimeInterval.swift in Sources */ = {isa = PBXBuildFile; fileRef = FE268F672F0856752F99A6370C6545F1 /* DispatchTimeInterval.swift */; settings = {COMPILER_FLAGS = "-DPRODUCT_NAME=Nimble/Nimble"; }; }; - F94ED0C040D8EFE1B1227A464F81E92E /* BeGreaterThan.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9AA80CEA9B4992D8F9368CEE01A42094 /* BeGreaterThan.swift */; settings = {COMPILER_FLAGS = "-DPRODUCT_NAME=Nimble/Nimble"; }; }; - F9A961CFA0E2BD3C6A94E282069AD80E /* BeWithin.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8015D0BB35ED18B858B74C6E8656EB00 /* BeWithin.swift */; settings = {COMPILER_FLAGS = "-DPRODUCT_NAME=Nimble/Nimble"; }; }; - FC4F734925BC0EDDCD7C10AFBF93C576 /* DSL.h in Headers */ = {isa = PBXBuildFile; fileRef = 5C8E70599736912CA1DB7FCDD472F2B2 /* DSL.h */; settings = {ATTRIBUTES = (Public, ); }; }; - FE67CE5AE4DFFE6B850FA43334EEBDC0 /* QuickObjCRuntime.h in Headers */ = {isa = PBXBuildFile; fileRef = 622317B228B6CF5C9D75DA1008B0F2B8 /* QuickObjCRuntime.h */; settings = {ATTRIBUTES = (Project, ); }; }; - FEA8C3E9543FB2A316D5A8F89B13D411 /* Quick-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 7F6D4322ABB010AB0EEC279249B17918 /* Quick-dummy.m */; }; + 01236C984BBB2918575C35713E2E08B4 /* BeLessThanOrEqual.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7C32B5867CD2E1958E06067CD646C7BD /* BeLessThanOrEqual.swift */; settings = {COMPILER_FLAGS = "-DPRODUCT_NAME=Nimble/Nimble"; }; }; + 013181EFBAC8B2708761AAAEA9D0E517 /* STDSDeviceInformationParameter.h in Headers */ = {isa = PBXBuildFile; fileRef = 161BEAD8BFBD8106D006C6D52B175AEE /* STDSDeviceInformationParameter.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 01CAB7DCB00DB546C3B50A01D220CFA8 /* STDSNotInitializedException.h in Headers */ = {isa = PBXBuildFile; fileRef = C928A5EABEC12D99C0C41619CDE2D94D /* STDSNotInitializedException.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 020153DF4B3CBB131DBB5A6AFE267F07 /* STPSourceCardDetails.swift in Sources */ = {isa = PBXBuildFile; fileRef = D4A0099670320E0A61A6EC006DFED651 /* STPSourceCardDetails.swift */; }; + 021D29C6A388976923614F8788CBE6EF /* STDSWhitelistView.m in Sources */ = {isa = PBXBuildFile; fileRef = 2C4AF2F997036A42580AB4A1F059F993 /* STDSWhitelistView.m */; }; + 02B42EC26A3E8ED3111F7F723F78490F /* StripeAPIConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = B329CD095DF0D07385B9DF3993CF8082 /* StripeAPIConfiguration.swift */; }; + 038D8C564ABE8C97864B8F0B03F4D177 /* STPPaymentMethodBacsDebit.swift in Sources */ = {isa = PBXBuildFile; fileRef = CDD26DC95DFB774C078DB4456FAB88E4 /* STPPaymentMethodBacsDebit.swift */; }; + 03BAA8BA74317123CA86865443592E85 /* Dictionary+Stripe.swift in Sources */ = {isa = PBXBuildFile; fileRef = EED74C365BEB0277EFBB71118ACA2ADE /* Dictionary+Stripe.swift */; }; + 03FD1E89DEC666FB21FEB2E4FEA3B719 /* NSArray+Stripe.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FA2D3847F4ECCD49144586976179FC0 /* NSArray+Stripe.swift */; }; + 0574F6274930EAE0DEE90D56B6CE8C53 /* nn-NO.lproj in Resources */ = {isa = PBXBuildFile; fileRef = 30B3483633599A7FA3B699D4CE417742 /* nn-NO.lproj */; }; + 057C1964EBAFCBC649F8012723CDADF5 /* SatisfyAnyOf.swift in Sources */ = {isa = PBXBuildFile; fileRef = A0F001C88CB75DC9956CE0E1C73E6C91 /* SatisfyAnyOf.swift */; settings = {COMPILER_FLAGS = "-DPRODUCT_NAME=Nimble/Nimble"; }; }; + 0650AF0DB8DE333CE5D99D704E29AC02 /* AllPass.swift in Sources */ = {isa = PBXBuildFile; fileRef = C326830A52B6ACCB749F98CF8A24E4E9 /* AllPass.swift */; settings = {COMPILER_FLAGS = "-DPRODUCT_NAME=Nimble/Nimble"; }; }; + 0659C102E528008D4318FDBD7FEDD35C /* STPPaymentMethodBoletoParams.swift in Sources */ = {isa = PBXBuildFile; fileRef = 212794EB430C46F7E9AFF6095CEA30B5 /* STPPaymentMethodBoletoParams.swift */; }; + 06C1123E8EAFFDC3EF43A176042BF0A8 /* STPPaymentMethodGiropayParams.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46CE0A5841318D1F266C9D542B69B9DF /* STPPaymentMethodGiropayParams.swift */; }; + 06D68613D533EDDEEF993F5FFE496170 /* STPPaymentMethodSofortParams.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1F631064D7CB9096CD13E6ACEE7BED19 /* STPPaymentMethodSofortParams.swift */; }; + 0712493E1803C913158BBA4CCF283007 /* nb.lproj in Resources */ = {isa = PBXBuildFile; fileRef = 1CE8EA6F3E1DFEBE5534C8D0F1DFB621 /* nb.lproj */; }; + 0727388CC4B1A2AC748FC6178DA50147 /* STPAPIClient.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8D46E93C2A7E6693C20C4AACD43ABF7E /* STPAPIClient.swift */; }; + 086144E52A667A7954D92FE051BD6CC8 /* STDSExpandableInformationView.m in Sources */ = {isa = PBXBuildFile; fileRef = 5F42A1E0E18999703CBBFEBB56145E7F /* STDSExpandableInformationView.m */; }; + 088A5A88342D60B6FCFAEADBF0749220 /* AdapterProtocols.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65D60532E0DFB8FA1617519318FBB503 /* AdapterProtocols.swift */; settings = {COMPILER_FLAGS = "-DPRODUCT_NAME=Nimble/Nimble"; }; }; + 092838CA3E231637F7D3D55EAE0B8C72 /* STPThreeDSUICustomization.swift in Sources */ = {isa = PBXBuildFile; fileRef = A2B26C6CDB5006E346FB443C2590CAE9 /* STPThreeDSUICustomization.swift */; }; + 0955AAAF323B87BCEBE1D0227F2FF4D3 /* UIViewController+Stripe3DS2.m in Sources */ = {isa = PBXBuildFile; fileRef = D7AB48E00CD1FC22362E33B74E6EFFFD /* UIViewController+Stripe3DS2.m */; }; + 09D4B856CFEA59F4E16AB91D1F06D50C /* XCTestObservationCenter+Register.m in Sources */ = {isa = PBXBuildFile; fileRef = 65F202B9FC21F6175762715A47B8A591 /* XCTestObservationCenter+Register.m */; settings = {COMPILER_FLAGS = "-DPRODUCT_NAME=Nimble/Nimble"; }; }; + 0A8DB6B9BB8655FEA665B4732C44965B /* STDSJailbreakChecker.m in Sources */ = {isa = PBXBuildFile; fileRef = F46F0873B0AE714CC2E6CBFD340FF352 /* STDSJailbreakChecker.m */; }; + 0B678F11209F5A613FA5F6D6702E46C2 /* STPPaymentMethodThreeDSecureUsage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6F2C49A88CCD41F403C5BE7CD357F325 /* STPPaymentMethodThreeDSecureUsage.swift */; }; + 0B6F7269D18831AEAE4A552667633587 /* NSData+JWEHelpers.h in Headers */ = {isa = PBXBuildFile; fileRef = 1B55E0D441A251A915C6E11214B5CCCC /* NSData+JWEHelpers.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 0B91799F9412C28DE43CC91E143381E1 /* STPPaymentIntentSourceActionAuthorizeWithURL.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52AFBF1868EC913273D1B45D0CBE93E5 /* STPPaymentIntentSourceActionAuthorizeWithURL.swift */; }; + 0BAC760A19A0F7BAD74264AA4DDDD679 /* World+DSL.swift in Sources */ = {isa = PBXBuildFile; fileRef = EB7B6A38D2BE807D5F5B94C96BB7325E /* World+DSL.swift */; }; + 0C26C4C97B7718D69626890A9745975A /* STDSChallengeResponseSelectionInfoObject.h in Headers */ = {isa = PBXBuildFile; fileRef = E498AA5F12E01C66B0508B5BFBDF5B94 /* STDSChallengeResponseSelectionInfoObject.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 0D28CC029F277E08E381C1FB0BB940A5 /* STPMandateCustomerAcceptanceParams.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1F4A483B9C67F1A3D2489FFA7C0040B0 /* STPMandateCustomerAcceptanceParams.swift */; }; + 0D352AB9D9FB76AF3F76AB8B76E0344F /* STDSNotInitializedException.m in Sources */ = {isa = PBXBuildFile; fileRef = F7C0B6BBB78650A9B91E8D5D5A11D170 /* STDSNotInitializedException.m */; }; + 0D6EA3EAC83C871E8CBA4C327B496A0E /* STPConfirmAlipayOptions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 15735CC2359689BE68DDD82AA64AF91D /* STPConfirmAlipayOptions.swift */; }; + 0DD28F29BF02762916D569CB60F9AB06 /* STPPaymentIntentShippingDetailsParams.swift in Sources */ = {isa = PBXBuildFile; fileRef = A3EFCE7505CCF7892AAAC7D5050D11AC /* STPPaymentIntentShippingDetailsParams.swift */; }; + 0E398EF6297FFF6CC9BC74421BF1712D /* ContainElementSatisfying.swift in Sources */ = {isa = PBXBuildFile; fileRef = B00D4B76CB214B3DF40808CA4CD2EAE3 /* ContainElementSatisfying.swift */; settings = {COMPILER_FLAGS = "-DPRODUCT_NAME=Nimble/Nimble"; }; }; + 0E4CE475D537D461671EA5E8CF176152 /* STPConfirmPaymentMethodOptions.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFDC381B81D580A4B02A5D75E2F5429A /* STPConfirmPaymentMethodOptions.swift */; }; + 0E7E03E7EB35B21CEE24267DF082555A /* STPSourceRedirect.swift in Sources */ = {isa = PBXBuildFile; fileRef = CF576601F70ADC56672DA5E916452C88 /* STPSourceRedirect.swift */; }; + 0EF5DD2821912749951D31B5EB78E1A3 /* sl-SI.lproj in Resources */ = {isa = PBXBuildFile; fileRef = 5C170C5ECB65313D7033A335EA627EF2 /* sl-SI.lproj */; }; + 0F776B26BC641CB895C2E7D961C71152 /* ExampleHooks.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6F81E85314042226003AF38B2D84665A /* ExampleHooks.swift */; }; + 0FC536648DB669163D48B002EEBF83B6 /* STDSIntegrityChecker.h in Headers */ = {isa = PBXBuildFile; fileRef = AC0688418DF7B5E75A4B1CE00FB7024E /* STDSIntegrityChecker.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 0FF078EC4B64D41F78376637C3C7457E /* STPPaymentMethodFPX.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3C564FA0EBC44CDB08A1444DED329837 /* STPPaymentMethodFPX.swift */; }; + 11A16B91E2CEC76912C9AA89DE06B472 /* Enums+CustomStringConvertible.swift in Sources */ = {isa = PBXBuildFile; fileRef = 53D48585E0DD371E7575082F5E5D2FA6 /* Enums+CustomStringConvertible.swift */; }; + 11D9B13C5D6580960979F4301217F2EF /* STDSAuthenticationRequestParameters.h in Headers */ = {isa = PBXBuildFile; fileRef = E22B1939566A7148F1B9B9D047B4D50A /* STDSAuthenticationRequestParameters.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 122A0B946148BAB1037F5FD8546AF9AC /* STPSetupIntent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1702A313BFC0C3F57587D2CD19916460 /* STPSetupIntent.swift */; }; + 12EFFA5E31998174561F3E75B0A81165 /* STDSUICustomization.h in Headers */ = {isa = PBXBuildFile; fileRef = 15AD669247185390F5190AFD168375DF /* STDSUICustomization.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 130B381F3FB091E8DE79AA7965984AFA /* vi.lproj in Resources */ = {isa = PBXBuildFile; fileRef = 5B2A61D11231525A85BFE695B2A33DCF /* vi.lproj */; }; + 13BE949EFDF50C87A22E77B6C0FA967C /* STDSAuthenticationResponseObject.m in Sources */ = {isa = PBXBuildFile; fileRef = 88C13E8D29DA0DA5DC99DA0F59E062F8 /* STDSAuthenticationResponseObject.m */; }; + 13C92A56DE90F30ACEC10BF71C07254E /* vi.lproj in Resources */ = {isa = PBXBuildFile; fileRef = CB7F84D2E403492F72A11684D332AFC8 /* vi.lproj */; }; + 14ECB9C16D895E6B3157794DB3135F19 /* StripePayments+Export.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7AAD6070C98EFE973EABC23752F3C257 /* StripePayments+Export.swift */; }; + 14F8F0ADE08D750611E78D60AF7E9C3D /* pt-PT.lproj in Resources */ = {isa = PBXBuildFile; fileRef = 9DB35445FC572AC08BE64F7313BCDD10 /* pt-PT.lproj */; }; + 150D6EA8EA175A2E593FAC636F8E35DE /* STDSChallengeResponseMessageExtensionObject.h in Headers */ = {isa = PBXBuildFile; fileRef = 7E95291ECF86585EA09E49FC52FE512D /* STDSChallengeResponseMessageExtensionObject.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 154A42D3BBF847E3C2C7A6BB4EFAEE84 /* DSL.swift in Sources */ = {isa = PBXBuildFile; fileRef = 413E55C32B8C10177DAFE56899148490 /* DSL.swift */; }; + 159F8EE74AF28D4A573CACE36DFFDBE3 /* ms-MY.lproj in Resources */ = {isa = PBXBuildFile; fileRef = 9CC280CD6D2FA8049CDD457EE84EE8AF /* ms-MY.lproj */; }; + 16A964A80F82E8955FAD0ECF727F522A /* STDSSecTypeUtilities.m in Sources */ = {isa = PBXBuildFile; fileRef = 0EC9A9407672A47FB13A5FC199883E3E /* STDSSecTypeUtilities.m */; }; + 1705B1BE5C85932B6404A3436FB601B7 /* STPPaymentMethodOptions.swift in Sources */ = {isa = PBXBuildFile; fileRef = D434B28FB35F3FD4F2BD6DCB5A84511C /* STPPaymentMethodOptions.swift */; }; + 18404665D3D8C231EC7E45807E0B7035 /* NSString+JWEHelpers.m in Sources */ = {isa = PBXBuildFile; fileRef = E7E3F956A1083AD2F1F0ACDB8EC3A19B /* NSString+JWEHelpers.m */; }; + 1862C65896619DF417C33DB320727BCB /* cs-CZ.lproj in Resources */ = {isa = PBXBuildFile; fileRef = 0AB1AE5146B37E7E38B5BC5A40BC56C0 /* cs-CZ.lproj */; }; + 18ACEA51615A8434B00B243551175F4A /* STPAnalyticsClient+Payments.swift in Sources */ = {isa = PBXBuildFile; fileRef = E10ACEC9D8441E586D253A5F01D226B8 /* STPAnalyticsClient+Payments.swift */; }; + 191B50BEC783150B89E684C427269952 /* STPPaymentMethodGrabPay.swift in Sources */ = {isa = PBXBuildFile; fileRef = AF0D4FB04C836E44752A314B31469183 /* STPPaymentMethodGrabPay.swift */; }; + 19A60369EEE16D503A472273FD951BCB /* STPPaymentMethodOXXOParams.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE83B40122127C56C473BB9BF4B8C18D /* STPPaymentMethodOXXOParams.swift */; }; + 19A8009537BCAD56435B2DDC620B29AA /* mach_excServer.h in Headers */ = {isa = PBXBuildFile; fileRef = 94758F067E90C9BD22F58D67C13CC4E8 /* mach_excServer.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 19BD3FC563FCB4D9351873C56E1B8F38 /* StripePayments-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 2D69CD9ABD5DDEE858DDA4E80A6CBA53 /* StripePayments-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 1A0CDABF0B5DC4853D71A3D8A9194BD8 /* bg-BG.lproj in Resources */ = {isa = PBXBuildFile; fileRef = DB4C698481CE6A3B234A1E1FF7D30719 /* bg-BG.lproj */; }; + 1A172B8E707A60CBD15698CCC424C418 /* ro-RO.lproj in Resources */ = {isa = PBXBuildFile; fileRef = 184CB17D9F1D079E67B9BE9D043F50EC /* ro-RO.lproj */; }; + 1B5648DECACC2C478440DD19516ADCC5 /* MatcherProtocols.swift in Sources */ = {isa = PBXBuildFile; fileRef = C92A31C8583D68FCED3476862B0B7C43 /* MatcherProtocols.swift */; settings = {COMPILER_FLAGS = "-DPRODUCT_NAME=Nimble/Nimble"; }; }; + 1C469C17A0E35E4508F74FEB1EDA586C /* DSL.m in Sources */ = {isa = PBXBuildFile; fileRef = 7839E3169FA3787A71E1C01829725758 /* DSL.m */; settings = {COMPILER_FLAGS = "-DPRODUCT_NAME=Nimble/Nimble"; }; }; + 1C4EACACAA57E65B51F41F54C6948C58 /* STDSChallengeResponseObject.h in Headers */ = {isa = PBXBuildFile; fileRef = D12030162C7F5E8DED921037116D4E3E /* STDSChallengeResponseObject.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 1E7C617E16D1B599CF499DD55EF669C0 /* STDSFooterCustomization.m in Sources */ = {isa = PBXBuildFile; fileRef = 8BD373964B676EF2C5966D4B81EC2072 /* STDSFooterCustomization.m */; }; + 1F2240C9318123D69897759B7DBD21D7 /* UIFont+DefaultFonts.m in Sources */ = {isa = PBXBuildFile; fileRef = 611A742A8611B58B61FB2CB1A9BF2426 /* UIFont+DefaultFonts.m */; }; + 1F5FD8F028C7675AB641B87350EFAC91 /* URLSession+Retry.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8D21F409ED0D7696661CA18A76E631D3 /* URLSession+Retry.swift */; }; + 1FB4E8361692A615EE25172BBB54A0FA /* STDSSpacerView.h in Headers */ = {isa = PBXBuildFile; fileRef = 0B7E0F91CC4790A329303D0CD7F34DAC /* STDSSpacerView.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 1FD113B82225B34DFDD46321B11024CA /* Async.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2C4FE4623236069C3A2DAB974A3298A8 /* Async.swift */; }; + 1FD82A85B7C64F54AD2F74909F572FE8 /* STDSTextFieldCustomization.m in Sources */ = {isa = PBXBuildFile; fileRef = E3D16E6471F8D138E3BD88E4FDC0F8FA /* STDSTextFieldCustomization.m */; }; + 2004971545222D91B6EDCACA67033613 /* Pods-OSPaymentsLib-OSPaymentsLibTests-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = D3A8BF3C48BD1892DD33A7126753E72F /* Pods-OSPaymentsLib-OSPaymentsLibTests-dummy.m */; }; + 207866DD86EDE603026D5AEDAF5ABE44 /* QuickConfiguration.m in Sources */ = {isa = PBXBuildFile; fileRef = D6A3DC41A2292AC166BEB9C49903B205 /* QuickConfiguration.m */; }; + 2096706ED57F37B7CD5CF94CC3D6AE7C /* hu.lproj in Resources */ = {isa = PBXBuildFile; fileRef = 730FC11E5EFCFE823AA4A65FC44E05AA /* hu.lproj */; }; + 210F16B35E23673227C451C32ED3DD7C /* de.lproj in Resources */ = {isa = PBXBuildFile; fileRef = EA85AA2D91AD44468F462278A69820BE /* de.lproj */; }; + 2157F4F1E30DFADECBD2473F5BC60345 /* hu.lproj in Resources */ = {isa = PBXBuildFile; fileRef = 5907CE599DD4F4A5314A7E446C1548A1 /* hu.lproj */; }; + 21915E95165BBB322AF1B9A993214C3D /* StripeServiceError.swift in Sources */ = {isa = PBXBuildFile; fileRef = D452640F36C3BA3EB2B44838F3CE5557 /* StripeServiceError.swift */; }; + 21F3408E9BD0BE7C7A9FFBF43B4F28A0 /* Nimble.h in Headers */ = {isa = PBXBuildFile; fileRef = A13750DB0E1992CD713CFCFE0CE7B11A /* Nimble.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 2223D9864ED3F01713DA2180EF7190B9 /* BeVoid.swift in Sources */ = {isa = PBXBuildFile; fileRef = 065AE8BD8BF5F67C6C62A4385F59BC6F /* BeVoid.swift */; settings = {COMPILER_FLAGS = "-DPRODUCT_NAME=Nimble/Nimble"; }; }; + 222837454C437E1D84E4C6C74D1D21C7 /* zh-Hans.lproj in Resources */ = {isa = PBXBuildFile; fileRef = 61FA3AB7DB6ED5397FCCAF504A9CE2EE /* zh-Hans.lproj */; }; + 23294E1D85D1BB5F601FB3FE6393AEB6 /* STDSAuthenticationRequestParameters.m in Sources */ = {isa = PBXBuildFile; fileRef = 210A59DA9EB67DB017B769CBBEE3E9B3 /* STDSAuthenticationRequestParameters.m */; }; + 233AB756F67ABBD886C54BF9F12403DF /* HaveCount.swift in Sources */ = {isa = PBXBuildFile; fileRef = B49EEDC7970854BAF61BD110CAA852C0 /* HaveCount.swift */; settings = {COMPILER_FLAGS = "-DPRODUCT_NAME=Nimble/Nimble"; }; }; + 2357EB01C617A8A015615080DBB012D6 /* Equal.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6743D6B280FD6633C1199C27DB374029 /* Equal.swift */; settings = {COMPILER_FLAGS = "-DPRODUCT_NAME=Nimble/Nimble"; }; }; + 236188652033F3874F7747E49466CC6D /* es.lproj in Resources */ = {isa = PBXBuildFile; fileRef = 65688FB4E15C22FBFBB007D1A68DCB72 /* es.lproj */; }; + 2386C376553947D4A6CF08B38C8A2D3C /* hr.lproj in Resources */ = {isa = PBXBuildFile; fileRef = FE746D98425B077F5CD27D98DF1B5E76 /* hr.lproj */; }; + 23AD839EFADC62D62D49290B5C9FC769 /* UIFont+Stripe.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4B5A1D68DF412D11EE224DFAF8C13C8 /* UIFont+Stripe.swift */; }; + 247FA17C9B44E7860DC39DFE61961237 /* STDSTransaction.m in Sources */ = {isa = PBXBuildFile; fileRef = 836DE9DD2FE1EB8835953F60C015D066 /* STDSTransaction.m */; }; + 2492CEBC7D15E6699CBCDB00B93C3C8A /* STDSNavigationBarCustomization.m in Sources */ = {isa = PBXBuildFile; fileRef = 9CBD97FAC70D5151B1E49A18D086FA28 /* STDSNavigationBarCustomization.m */; }; + 24AAADDFF404517C7C0AED61D7E5CD2B /* zh-HK.lproj in Resources */ = {isa = PBXBuildFile; fileRef = 68E237402E23B9113D778F5A18968D4A /* zh-HK.lproj */; }; + 25276D6260CEFC77AB1C9A399CA31291 /* ca-ES.lproj in Resources */ = {isa = PBXBuildFile; fileRef = 4B86CA140DC662A1614E7C61BB493169 /* ca-ES.lproj */; }; + 2563805C6F19F5D19343F0781CAB5819 /* STDSStackView.h in Headers */ = {isa = PBXBuildFile; fileRef = 5450B5EC7ACBAB30D5FEFE776CBB94C8 /* STDSStackView.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 2596C380CE1B2066E9A54BC82C42B759 /* STDSTextChallengeView.m in Sources */ = {isa = PBXBuildFile; fileRef = 10066A2223CBF75142915E950689891A /* STDSTextChallengeView.m */; }; + 263395935D45C1121773670783ED6E0C /* STDSChallengeInformationView.h in Headers */ = {isa = PBXBuildFile; fileRef = 1EDB2495F0CD9AEDB5FE4545BA418772 /* STDSChallengeInformationView.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 264F60294C4B6404E0E399774425DC0E /* STPPaymentIntentLastPaymentError.swift in Sources */ = {isa = PBXBuildFile; fileRef = FEC23DC7AF2BAA66F022191D678561D7 /* STPPaymentIntentLastPaymentError.swift */; }; + 265CA95FA3AAFF7E500E99D48FBD68E3 /* STPCardBrand.swift in Sources */ = {isa = PBXBuildFile; fileRef = B2ECD2688FF7C89EF3C34F25979A09DF /* STPCardBrand.swift */; }; + 2707ECE9592C4FE30346DFA99614FF1C /* et-EE.lproj in Resources */ = {isa = PBXBuildFile; fileRef = 10F02E6778D8AB97A8BF670F28940A5D /* et-EE.lproj */; }; + 272AD16E5080B9028C1012B7723CD74E /* STPPaymentIntentActionRedirectToURL.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51BA3F2D891B91AE07E4A51BEA563303 /* STPPaymentIntentActionRedirectToURL.swift */; }; + 283994F70A20FDA3E593F5848195F8FE /* PluginDetector.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64754D3C8EFC85ABC74074BD01D0B438 /* PluginDetector.swift */; }; + 289B613DD13E58EA28C0DFAF4358BA68 /* ElementsEqual.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4E59E51F071F6568DA9481DE99B8E944 /* ElementsEqual.swift */; settings = {COMPILER_FLAGS = "-DPRODUCT_NAME=Nimble/Nimble"; }; }; + 28C24A912FEBA4B1692671D80A1776D6 /* STPIntentActionRedirectToURL.swift in Sources */ = {isa = PBXBuildFile; fileRef = 876DECD5B495AF71DBAEBABF331D4D89 /* STPIntentActionRedirectToURL.swift */; }; + 28D6E884D7AB6CF2B4BFF328D2537D22 /* SatisfyAllOf.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07D2BCAAFF28918553FDE6722B50EF5D /* SatisfyAllOf.swift */; settings = {COMPILER_FLAGS = "-DPRODUCT_NAME=Nimble/Nimble"; }; }; + 28E75B0CB409AE353F3F1DD7566BF797 /* STP3DS2AuthenticateResponse.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3EDC69638EBE90E82EB702A92E9F5CD9 /* STP3DS2AuthenticateResponse.swift */; }; + 29A12BDC18155B9C0671D4B97A71F45A /* ms-MY.lproj in Resources */ = {isa = PBXBuildFile; fileRef = 85A80EDF1631B6357738E7B417B16D94 /* ms-MY.lproj */; }; + 29A1FECE0C6D458EFDB7AE0B0E873109 /* STPPaymentMethodUPIParams.swift in Sources */ = {isa = PBXBuildFile; fileRef = E1188BBCB393902B5E37C0B1746CAFCE /* STPPaymentMethodUPIParams.swift */; }; + 2A784CA93CB1A56D4711037402C04F40 /* StripePayments-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = BAF7876859F6A7CD7E75CF411F68334E /* StripePayments-dummy.m */; }; + 2A9F6A9F52F7780DF40A2DF6085BF77D /* STDSButtonCustomization.m in Sources */ = {isa = PBXBuildFile; fileRef = 4FC1520119487BEAC759E99C34521BBD /* STDSButtonCustomization.m */; }; + 2AB078409D3ACCD3EC10643EC04B75BE /* StripeApplePay+Import.swift in Sources */ = {isa = PBXBuildFile; fileRef = AB06A94245433C3D9BA6B7F1DE55F379 /* StripeApplePay+Import.swift */; }; + 2AC9195E81D0BE6AB8CCED77178F2C8F /* sv.lproj in Resources */ = {isa = PBXBuildFile; fileRef = 14121A23FD33D0DE147657BC767B60D5 /* sv.lproj */; }; + 2ACEED691C648285CD27EC987B7AB565 /* LinkAccountSession.swift in Sources */ = {isa = PBXBuildFile; fileRef = E2C9B1DAD6EDCBDE98D055665BDFFF35 /* LinkAccountSession.swift */; }; + 2B487EDAC128C40CED9EA6D6B25D6AD5 /* pt-PT.lproj in Resources */ = {isa = PBXBuildFile; fileRef = 8E3A18526902A264BA784EFA7ADDAA0F /* pt-PT.lproj */; }; + 2B5A28A4BF74AF916C7CBE907D225CE7 /* nb.lproj in Resources */ = {isa = PBXBuildFile; fileRef = EECDEDFAF80F5425938C58B2C452C3D0 /* nb.lproj */; }; + 2C160C86F93327526AB6E66EED863B5C /* STDSDebuggerChecker.h in Headers */ = {isa = PBXBuildFile; fileRef = D14176278185396E50949DD0A4368DD7 /* STDSDebuggerChecker.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 2C7A86F6A1C761A9FA4AD20A63263984 /* et-EE.lproj in Resources */ = {isa = PBXBuildFile; fileRef = E917285F227929D0403A2B2FE7FCA6D8 /* et-EE.lproj */; }; + 2C85A44748A3F58CE8C0AE291B9EDDFB /* QCKConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = C679BA4C5B2D4A2C944C1D492590A31C /* QCKConfiguration.swift */; }; + 2CDD30891C3534376BA035E18CA889BE /* STDSOSVersionChecker.h in Headers */ = {isa = PBXBuildFile; fileRef = 39A89F94F62DD307FA1B976758F78D73 /* STDSOSVersionChecker.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 2D6DB63EBCA201CFABA3012CD1C360BD /* ExampleGroup.swift in Sources */ = {isa = PBXBuildFile; fileRef = 12C00397639245C26EF6B232E3D18D39 /* ExampleGroup.swift */; }; + 2D9175D749C48D902B4B68BBF65A6DAE /* STDSOSVersionChecker.m in Sources */ = {isa = PBXBuildFile; fileRef = 891281DF53F382C2F01F71B505A2108F /* STDSOSVersionChecker.m */; }; + 2E23462149B401914EAF08BED903AD8D /* STDSTextFieldCustomization.h in Headers */ = {isa = PBXBuildFile; fileRef = 3CA726D8D07BC2DD4AC5CF3D6FB06958 /* STDSTextFieldCustomization.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 2E4D85387136D0E87EFF3CF816410A20 /* STPPaymentMethodBLIK.swift in Sources */ = {isa = PBXBuildFile; fileRef = 47360F9CFB9809719DBC7DC58EE3222F /* STPPaymentMethodBLIK.swift */; }; + 2E581DD1847ECC3D1F77A2F3F288F342 /* ro-RO.lproj in Resources */ = {isa = PBXBuildFile; fileRef = 28C3729DDBD681EA2C39DD9D2F731E5D /* ro-RO.lproj */; }; + 2EFFB904753535D2081B57240AF520B9 /* nl.lproj in Resources */ = {isa = PBXBuildFile; fileRef = 1DF82D6CFE767555CB959A5F30AB2353 /* nl.lproj */; }; + 2F4DBD9EB47B55EFB19161BE381DDCC8 /* STDSChallengeSelectionView.m in Sources */ = {isa = PBXBuildFile; fileRef = 0823109A43B7175AAA2D1C0D80EBAAB0 /* STDSChallengeSelectionView.m */; }; + 2F915AF3B125571D66E5DFD35B7CB178 /* STDSThreeDSProtocolVersion.m in Sources */ = {isa = PBXBuildFile; fileRef = 2EC5D574B6CE9C38A269696E455C14DC /* STDSThreeDSProtocolVersion.m */; }; + 3025C0F40CA75C83972903E981722EA9 /* STDSIntegrityChecker.m in Sources */ = {isa = PBXBuildFile; fileRef = 6C597B8E71A5E225982129EECCCDF62F /* STDSIntegrityChecker.m */; }; + 304E0A887F5420C0758CC21F15850DAD /* STPPaymentMethodAfterpayClearpay.swift in Sources */ = {isa = PBXBuildFile; fileRef = EB9C9643167CE17E8EFCD8AEA65A8E50 /* STPPaymentMethodAfterpayClearpay.swift */; }; + 30566EF970A20B8827E7F1AA0522D6A2 /* cs-CZ.lproj in Resources */ = {isa = PBXBuildFile; fileRef = 4CE19E837C101FE89DCEB4A796803AB2 /* cs-CZ.lproj */; }; + 306F8BF4060CFAA4481C090AE5645655 /* STDSJSONEncoder.m in Sources */ = {isa = PBXBuildFile; fileRef = AF21456AD4F54FD346DC645B6D3FA726 /* STDSJSONEncoder.m */; }; + 3087DDB3CFEBD0AA35BE02486E14E467 /* nl.lproj in Resources */ = {isa = PBXBuildFile; fileRef = 4A69A2B39F392EEAEE288BC29547CD71 /* nl.lproj */; }; + 30F02B5E637DF6A1DC8D79EE96408FE6 /* Analytic+Payments.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1567AEFC753587BCFC6E1183B54AB8EA /* Analytic+Payments.swift */; }; + 31500C1BFF2979F394F2C7CCE5B6F30B /* NSArray+Stripe.swift in Sources */ = {isa = PBXBuildFile; fileRef = 296D7B7E1FC7859637321935D2EEDA04 /* NSArray+Stripe.swift */; }; + 317FD8D75EA6F1C3A7D8A899259FE139 /* zh-Hant.lproj in Resources */ = {isa = PBXBuildFile; fileRef = 4877F075C2758793EC28F510F8C33578 /* zh-Hant.lproj */; }; + 31837A5545CAAA9D048B3FAA210FE4EA /* STDSTextChallengeView.h in Headers */ = {isa = PBXBuildFile; fileRef = FFE5DBD6034385644C0125535D30076B /* STDSTextChallengeView.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 3213D4EE8D803ECB900C2F8C42857F61 /* STPURLCallbackHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 227D1BB76FD3CE2F3F6DFAB8FD304C80 /* STPURLCallbackHandler.swift */; }; + 32890A23C6C5A59D0295872FFB71C2B3 /* zh-Hans.lproj in Resources */ = {isa = PBXBuildFile; fileRef = 051285ECD621D562C7E22360DD37AA6B /* zh-Hans.lproj */; }; + 32995147DC30DF5022DD66C0470BFDE9 /* QuickSpecBase.h in Headers */ = {isa = PBXBuildFile; fileRef = F8727829B9B2E48FA0478FE40FC9FE02 /* QuickSpecBase.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 32DBDB3004079944A6596D7258B996E6 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 03D9F470BE7939CC23898F0F41EF0B5E /* UIKit.framework */; }; + 32E830EBC42FC738D85468F6AE0B6803 /* StripeAPI.swift in Sources */ = {isa = PBXBuildFile; fileRef = 964AB07C9929986507ED52E3847352BA /* StripeAPI.swift */; }; + 3358907847E659749A146DF46023F805 /* STPCustomer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8F5857C3430F56199E5306C6F0349DF6 /* STPCustomer.swift */; }; + 33E23F2911A431352E417AD616883236 /* discover-logo.png in Resources */ = {isa = PBXBuildFile; fileRef = FE3674CB887E4AC22FB1FF789057D53F /* discover-logo.png */; }; + 34A8E6E2C7443734DA331A607EF645B1 /* en.lproj in Resources */ = {isa = PBXBuildFile; fileRef = EBA0CC1401C73CB751DB625A00921E9B /* en.lproj */; }; + 3517183FFD6B14F52921E9F8650AA63D /* STPPaymentIntentShippingDetailsAddress.swift in Sources */ = {isa = PBXBuildFile; fileRef = 848C2D30B6A61B76B8FEE685ADA9094D /* STPPaymentIntentShippingDetailsAddress.swift */; }; + 35C095305E5FB8CF40BB6C6A7F02E678 /* ErrorUtility.swift in Sources */ = {isa = PBXBuildFile; fileRef = C0173B06791A9BEDF7A74E77CB488DFA /* ErrorUtility.swift */; }; + 36239C409D0B9B719E86B55C1139FDBD /* STPPaymentMethodUPI.swift in Sources */ = {isa = PBXBuildFile; fileRef = 569C2A06774DF971F12A7C47C3884DA8 /* STPPaymentMethodUPI.swift */; }; + 36709259D5B468FDE791112806E6AA9D /* STPConfirmWeChatPayOptions.swift in Sources */ = {isa = PBXBuildFile; fileRef = C88A58FEC7E0BE3C99E16BFA8B1D7E2E /* STPConfirmWeChatPayOptions.swift */; }; + 36C770F00CFB7BECAE138754B173260B /* STPError.swift in Sources */ = {isa = PBXBuildFile; fileRef = D889009612AA978F7B4DD2F749ABAD75 /* STPError.swift */; }; + 36CAE14D256E871812C3C4BAD27DB110 /* STPAnalyticEvent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34A694CA199ED0893F5BCD8DB244F45E /* STPAnalyticEvent.swift */; }; + 381463548B8473B262B2FA27AD7DF435 /* STPPaymentMethodUSBankAccount.swift in Sources */ = {isa = PBXBuildFile; fileRef = 02C5EB104E05FA96C126340C58B899EC /* STPPaymentMethodUSBankAccount.swift */; }; + 385342D83733D3D9C7E0A388BFDBF61C /* STPPaymentMethodBacsDebitParams.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4246DC4C9A24781BA3280659F280A70 /* STPPaymentMethodBacsDebitParams.swift */; }; + 385982E8CA81B9EB950EB3F1C5E157A3 /* STDSUICustomization.m in Sources */ = {isa = PBXBuildFile; fileRef = 2E2289167D181B642613D4463E04339B /* STDSUICustomization.m */; }; + 38E2FC651D13E810BD0E3F0F745A5D86 /* STPPaymentMethodAlipay.swift in Sources */ = {isa = PBXBuildFile; fileRef = FC87D1514ECB912D2F5CED13BB9ACB49 /* STPPaymentMethodAlipay.swift */; }; + 39AC37C035DE1B8C1639B9A40F84A539 /* STPThreeDSFooterCustomization.swift in Sources */ = {isa = PBXBuildFile; fileRef = D4B91C5B9E0B11712BB70F73302CDDDF /* STPThreeDSFooterCustomization.swift */; }; + 39CD396AAAB43E7AE85595387E6B8964 /* STPSetupIntentConfirmParams.swift in Sources */ = {isa = PBXBuildFile; fileRef = 749B79C9C86B7E14C5009B78B1E0D141 /* STPSetupIntentConfirmParams.swift */; }; + 39D4E2CF72D88E464621AF8E2CACFD20 /* STDSThreeDSProtocolVersion.h in Headers */ = {isa = PBXBuildFile; fileRef = 26C20D5D39C54DAA46854DB9DC6B6EB7 /* STDSThreeDSProtocolVersion.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 39F17AF72432942F92F3B05F47995410 /* STDSSimulatorChecker.h in Headers */ = {isa = PBXBuildFile; fileRef = 7D78A4949D3C0A01AD01CC778EE68505 /* STDSSimulatorChecker.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 39F60D092FEAF7236168489CAA0AA93C /* fr.lproj in Resources */ = {isa = PBXBuildFile; fileRef = 9D6F3A6E6B05F5BA59796216A5FA8119 /* fr.lproj */; }; + 3A63B1DB85CE79907C6A50430A19B568 /* sk-SK.lproj in Resources */ = {isa = PBXBuildFile; fileRef = DB083F9E459539159BEB120E36C765AC /* sk-SK.lproj */; }; + 3A6530382C6CE29F52010A54DEFD3355 /* STPPaymentMethodPayPal.swift in Sources */ = {isa = PBXBuildFile; fileRef = FB11E840CC2E2C1D0EF2EBD6F3B83800 /* STPPaymentMethodPayPal.swift */; }; + 3AA219A606F881B65A35C036C61E6AD0 /* STDSWarning.m in Sources */ = {isa = PBXBuildFile; fileRef = E7171C229B618E7F245C1E060D855524 /* STDSWarning.m */; }; + 3ABDA920FDD838A534E55347FF35ACCC /* BeNil.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4F1D688AD2265A75D8EFB9221F7EB778 /* BeNil.swift */; settings = {COMPILER_FLAGS = "-DPRODUCT_NAME=Nimble/Nimble"; }; }; + 3AFA086E6CB837109A59A081E339E78B /* STPSourceProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = EBCAD22C7789720CF047DBF38A8D34E7 /* STPSourceProtocol.swift */; }; + 3B0D31C125C21E3D1FA6806279A7369A /* STDSFooterCustomization.h in Headers */ = {isa = PBXBuildFile; fileRef = E6518D0ADC9D010B4016FB0A7855F6F8 /* STDSFooterCustomization.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 3B59EB43186F324A79D05C3201369283 /* QuickSpecBase.m in Sources */ = {isa = PBXBuildFile; fileRef = 6D5BF6A82D35D5DA69E94704D9DA5511 /* QuickSpecBase.m */; }; + 3B5E796F1BFBB87AAB31305D6FCE160E /* Nimble-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 9415F10BEF551D362BDF622A5FE73D31 /* Nimble-dummy.m */; }; + 3B62A1DB19F43D79E76DB05F88E7B830 /* STPAPIClient+Radar.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5BE72988C0B88C57D8FAD6C8D7BF2DE4 /* STPAPIClient+Radar.swift */; }; + 3BA220FE1E469A2778730A89F390E6A0 /* fr-CA.lproj in Resources */ = {isa = PBXBuildFile; fileRef = 136D983EFF23F79D9508D3BB81A908A4 /* fr-CA.lproj */; }; + 3BDF230E8F33AD82C9EC1BAA1ECCA1ED /* STDSProgressViewController.h in Headers */ = {isa = PBXBuildFile; fileRef = 731CFC342FD7F097CD3710722F6E80E3 /* STDSProgressViewController.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 3C8183D1E5FF93B8E8C4F59AEB12DC67 /* NSBundle+Stripe_AppName.swift in Sources */ = {isa = PBXBuildFile; fileRef = 062AA013B25534B63F1D9C7A0B1DCCDA /* NSBundle+Stripe_AppName.swift */; }; + 3CC220A8FACE1DD4B1978AE955CF2737 /* STPEmptyStripeResponse.swift in Sources */ = {isa = PBXBuildFile; fileRef = C48AB1B31BDC3FB774EA3F60C778ADBF /* STPEmptyStripeResponse.swift */; }; + 3CFE6D672FEFBE8A9D10D5723FB88BF2 /* Stringers.swift in Sources */ = {isa = PBXBuildFile; fileRef = 669104F1E97535717BDCE249A3587195 /* Stringers.swift */; settings = {COMPILER_FLAGS = "-DPRODUCT_NAME=Nimble/Nimble"; }; }; + 3D1B4EF779689D4ACAEF5C2F0470DD41 /* STDSCustomization.h in Headers */ = {isa = PBXBuildFile; fileRef = FBA3A1685A206FEC59C528E5992C5DA1 /* STDSCustomization.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 3D615E7FB6345EDF26728BB7095F98E9 /* Chevron@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B37A9AC2E7D98DE4CC0C23F9DE5AC667 /* Chevron@3x.png */; }; + 3DBDD9275D0A0BFA75DB31B694B1B6CC /* es-419.lproj in Resources */ = {isa = PBXBuildFile; fileRef = 5A2D473CCF42F10E99266371FED0508B /* es-419.lproj */; }; + 3DFCA9AB63E3E4374B64FE356BAD677C /* tr.lproj in Resources */ = {isa = PBXBuildFile; fileRef = 8B33A309520322A241B1193B42EE6348 /* tr.lproj */; }; + 3E07947733CD594CF6C55EFA7C6F5825 /* STPIntentAction.swift in Sources */ = {isa = PBXBuildFile; fileRef = 325A5722DC9DE1391905216FD4AFF829 /* STPIntentAction.swift */; }; + 3E1105B44CCBDA9EC8C6C96EACCCC28F /* Behavior.swift in Sources */ = {isa = PBXBuildFile; fileRef = 693E1FDF28EBF010E045BA1CBECFE690 /* Behavior.swift */; }; + 3E2FBCC52661274287A6C69659A7FAD5 /* STDSWarning.h in Headers */ = {isa = PBXBuildFile; fileRef = 69C0509774EAEAF4CF9BC2D02989049F /* STDSWarning.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 3E93991CBB58EDBB1F547D705AEC020E /* STPSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6683A27B85EA014BFD6E373385D1110E /* STPSource.swift */; }; + 3E97A584E7FDD55A6AC072DB23043FCC /* SourceLocation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 180924D5266489E2FCC82462A8EA7CD7 /* SourceLocation.swift */; settings = {COMPILER_FLAGS = "-DPRODUCT_NAME=Nimble/Nimble"; }; }; + 3F02321014A66A554DDF1ACDBB6EE9D4 /* STPCard.swift in Sources */ = {isa = PBXBuildFile; fileRef = 972D107D6428EC5E8D81E749EB6DEFB4 /* STPCard.swift */; }; + 3FA8E6AEBD8687BF75B467C33ADF0045 /* CwlCatchException.swift in Sources */ = {isa = PBXBuildFile; fileRef = A990999E354E17DA7AB7A2FCB321A6C6 /* CwlCatchException.swift */; settings = {COMPILER_FLAGS = "-DPRODUCT_NAME=Nimble/Nimble"; }; }; + 400ED2ADEA63F8F7EB46D54349F2EA26 /* STPContactField.swift in Sources */ = {isa = PBXBuildFile; fileRef = ADD5BBE5DC1BEB17AF75F27CF281BE0B /* STPContactField.swift */; }; + 401A3889E79B0CC33D0660E7C8267712 /* NSError+Stripe3DS2.h in Headers */ = {isa = PBXBuildFile; fileRef = 22C7486D395D531F3CEA71233BEF3134 /* NSError+Stripe3DS2.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 409A101458E7C3AF6A02D45CFAAC29D0 /* StripeCoreBundleLocator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 742F741E5982B734AD60D1AF26513D27 /* StripeCoreBundleLocator.swift */; }; + 40D9B846E5A8AF781C0A0C41FED0E0F8 /* BeGreaterThanOrEqualTo.swift in Sources */ = {isa = PBXBuildFile; fileRef = 680C1DF5B047CCCB5CC6AAD90C501F63 /* BeGreaterThanOrEqualTo.swift */; settings = {COMPILER_FLAGS = "-DPRODUCT_NAME=Nimble/Nimble"; }; }; + 414A52FF2807C43A2103B89227239796 /* STDSChallengeRequestParameters.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A86E86A636998468C6AA72E338D691C /* STDSChallengeRequestParameters.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 42507DF71BD6DB7623A9A8E35E7B78BE /* NSLayoutConstraint+LayoutSupport.h in Headers */ = {isa = PBXBuildFile; fileRef = 411D3501805F770A6EDF01F816BAC6B5 /* NSLayoutConstraint+LayoutSupport.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 42686B287B78ACF11B145B038C369989 /* STDSProcessingView.h in Headers */ = {isa = PBXBuildFile; fileRef = 134A57537C47623876A363227A399DE8 /* STDSProcessingView.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 42BC3C3CBE7E5484F09BAD3204DE521D /* NSBundle+CurrentTestBundle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0F548AB251AC48E38AEC5763CEC1679D /* NSBundle+CurrentTestBundle.swift */; }; + 42DA19C1E0CB4D2B5BF12442D17287D7 /* STPPaymentMethodPrzelewy24.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6B5B072397E3B84F6004C05A7BE64C29 /* STPPaymentMethodPrzelewy24.swift */; }; + 4415DB8BA3D9130108FA4E5486504078 /* nn-NO.lproj in Resources */ = {isa = PBXBuildFile; fileRef = 16AD524274F54533DA4274E95224FDAE /* nn-NO.lproj */; }; + 443FFE3FBEDBB95A99B2DB948DE63220 /* STDSBrandingView.m in Sources */ = {isa = PBXBuildFile; fileRef = 2AC6C1C0ECB6DC8888E72B1CDE082317 /* STDSBrandingView.m */; }; + 44F31949B05DBF7DEFDCC4F70B41B603 /* ru.lproj in Resources */ = {isa = PBXBuildFile; fileRef = A6A6775DD45A9608B960E9A0B53F9DC0 /* ru.lproj */; }; + 450EC4FBCD013682127F548446D1DD17 /* STDSChallengeResponseImageObject.h in Headers */ = {isa = PBXBuildFile; fileRef = E183B527A5D113AD864FE8397EF9E718 /* STDSChallengeResponseImageObject.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 456BFC6895E43FB0A2D74B48C42E60D4 /* NSString+Stripe.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4D260EAF391420AEA7D4195E8CB97705 /* NSString+Stripe.swift */; }; + 45E50A3A821774A43869A9409F72D026 /* cs-CZ.lproj in Resources */ = {isa = PBXBuildFile; fileRef = 3F8FD76A24715EC95CF1509BEF6C3A0E /* cs-CZ.lproj */; }; + 460A8D1A9B312E32076B8554FED70DD6 /* Pods-OSPaymentsLib-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 02F5AF25FD35DDCE251A9006737617A5 /* Pods-OSPaymentsLib-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 464E0CEDFAA6A8BB7D3E29E97F7C6AF1 /* STPBankAccountCollector.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43E16FAAC49A3E73F1961D1CB93BF9BE /* STPBankAccountCollector.swift */; }; + 4698EBCAB77B194B12B039D2A0C358E7 /* STDSProcessingView.m in Sources */ = {isa = PBXBuildFile; fileRef = 8304758C2DC812DF0770A6790676DB4D /* STDSProcessingView.m */; }; + 4719292EA9231EE243B6D78D850BBED5 /* STDSExpandableInformationView.h in Headers */ = {isa = PBXBuildFile; fileRef = 25315BBCA00488C6108D8438AC2089EC /* STDSExpandableInformationView.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 482C5EEAAF5CC5D7052C554D2212932C /* STDSSynchronousLocationManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 2E4064ACE1479DD23ACEC0DC69AD61BC /* STDSSynchronousLocationManager.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 4851E14057542B14D1EEAA9C00C88774 /* Decimal+StripeCore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4D24EB31497D5ED7C72E3821B8B5DFF9 /* Decimal+StripeCore.swift */; }; + 4853485A7E6D1C1CA5C4CFB44085E6EC /* AnalyticsClientV2.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9B47978CCA25949CE4831EEAC847FE9D /* AnalyticsClientV2.swift */; }; + 494E36C4F29FD2EFEF6313CC5D063C0A /* UIView+LayoutSupport.h in Headers */ = {isa = PBXBuildFile; fileRef = AA0F9A61C7406D5FEEE182804BC1172E /* UIView+LayoutSupport.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 4955DBB9FDF4D00F2330AF65074D1CA2 /* STDSDeviceInformationParameter.m in Sources */ = {isa = PBXBuildFile; fileRef = FE59A18F9357C384D41EB0E8CA2136FF /* STDSDeviceInformationParameter.m */; }; + 498D0CEF04FDF36BE2B89A67015FF3A0 /* String+C99ExtendedIdentifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = 97E6A59FF453A35FB49B840C2B1CD471 /* String+C99ExtendedIdentifier.swift */; }; + 4A3477B394CA4DF793938185830755F0 /* STPSetupIntentEnums.swift in Sources */ = {isa = PBXBuildFile; fileRef = 17B1F0AE0203F3DB424913E455530C86 /* STPSetupIntentEnums.swift */; }; + 4A457767C9968D139BD8AAD877DFC117 /* ThrowError.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CB99E2C8E159ACE62BE2D838C454D60 /* ThrowError.swift */; settings = {COMPILER_FLAGS = "-DPRODUCT_NAME=Nimble/Nimble"; }; }; + 4A69E8EEB89D5C623CB007F9F8C3B04D /* StripeAPI+Deprecated.swift in Sources */ = {isa = PBXBuildFile; fileRef = F60D4AA67B1691FFF600656AA3B1C26E /* StripeAPI+Deprecated.swift */; }; + 4AD890A67D05B35A7D6008804B188FA4 /* fr.lproj in Resources */ = {isa = PBXBuildFile; fileRef = 0FC81EBC70D3F54547A459C447B572CC /* fr.lproj */; }; + 4B27F9C83E60A3A3717C03C96799EAC7 /* STPAPIClient+LinkAccountSession.swift in Sources */ = {isa = PBXBuildFile; fileRef = 59B2447710747DADA1A7FDE8E5D17BA8 /* STPAPIClient+LinkAccountSession.swift */; }; + 4B4B7CB6FD4E6340FA2AF7176E242282 /* STPPaymentMethodLinkParams.swift in Sources */ = {isa = PBXBuildFile; fileRef = 104E18997DC724D99094B4B2A8EA2132 /* STPPaymentMethodLinkParams.swift */; }; + 4BB9C83A37FC3CC123CE0777BD9FAB45 /* STPAPIClient+Payments.swift in Sources */ = {isa = PBXBuildFile; fileRef = C67D96EC417FA89AA73EF5270C28250D /* STPAPIClient+Payments.swift */; }; + 4C6BC008261C6C1CFA451C34CCC4D6A9 /* ServerErrorMapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9222B7FD76C3CFA3CC9BFC8CE1D9B256 /* ServerErrorMapper.swift */; }; + 4CB089F5F61442FDB48AEACB80E1B29F /* ro-RO.lproj in Resources */ = {isa = PBXBuildFile; fileRef = BD22EF79E6029B252A7C02F1551AFE24 /* ro-RO.lproj */; }; + 4DB106EF5D81F121EA58D82401C5DD1C /* MatchError.swift in Sources */ = {isa = PBXBuildFile; fileRef = F796F8F9046466A65E93BBA3541BE336 /* MatchError.swift */; settings = {COMPILER_FLAGS = "-DPRODUCT_NAME=Nimble/Nimble"; }; }; + 4DF10A5931EF1A1CCBAA58350E113BF6 /* UIViewController+Stripe3DS2.h in Headers */ = {isa = PBXBuildFile; fileRef = 834C33D3D45A0C2D5CCAB4F1C3246EA0 /* UIViewController+Stripe3DS2.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 4DFD4AE1B1C12F59014A9C1FE8F7AE47 /* BeResult.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74EB80E25DFDE9813CA10E313C254D8B /* BeResult.swift */; settings = {COMPILER_FLAGS = "-DPRODUCT_NAME=Nimble/Nimble"; }; }; + 4E45075F0AF7782356F756B55738A1C1 /* STDSStripe3DS2Error.h in Headers */ = {isa = PBXBuildFile; fileRef = C31BF779081BE5194C18F1D97EBBD240 /* STDSStripe3DS2Error.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 4EC19A4F9EE9863B3CF7BDB7607FE96B /* CwlBadInstructionException.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1B1E72523EA2324F4EF8EF152F73B08E /* CwlBadInstructionException.swift */; settings = {COMPILER_FLAGS = "-DPRODUCT_NAME=Nimble/Nimble"; }; }; + 4EC79445B363B312C74C3CE5B267F553 /* pl-PL.lproj in Resources */ = {isa = PBXBuildFile; fileRef = 2F8BCD8F4747D61721405F64E14D0979 /* pl-PL.lproj */; }; + 4EDC3E59D9D7A2C9E0C7820966B8840B /* STDSEllipticCurvePoint.h in Headers */ = {isa = PBXBuildFile; fileRef = A3F3ED2D41346BD69305376A35916633 /* STDSEllipticCurvePoint.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 4EF3D6C1102BA462B9F75AA8F318798C /* STDSConfigParameters.m in Sources */ = {isa = PBXBuildFile; fileRef = E5121480F98DCD56DFDF23FE8D93FC87 /* STDSConfigParameters.m */; }; + 4F29F55DF55238B639AA6F4458BC3076 /* STPMultipartFormDataEncoder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 32C63F975EF38DD20430EA221119E83D /* STPMultipartFormDataEncoder.swift */; }; + 4F409B48980E00C4D58C34D498DEBEA8 /* fi.lproj in Resources */ = {isa = PBXBuildFile; fileRef = C2F6A3C91B944FA238751C1C2E54353A /* fi.lproj */; }; + 4F54300CD1DF9A60FE0D65E857A840C2 /* fil.lproj in Resources */ = {isa = PBXBuildFile; fileRef = FB227FBD2833CB63EA2FD954E3F1B547 /* fil.lproj */; }; + 4F82DC515FD9ABDAD5996DA7403475CC /* STDSWebView.m in Sources */ = {isa = PBXBuildFile; fileRef = B6ACAE0E7420B0102A5B11414A885556 /* STDSWebView.m */; }; + 4FF14DEE4F47CFB5AB37949C92799028 /* STPFPXBankBrand.swift in Sources */ = {isa = PBXBuildFile; fileRef = 176A1FCF04CECEC5B248284E0F8E33D7 /* STPFPXBankBrand.swift */; }; + 4FFA353FCA74E12B1E33831B7DEDC29D /* STPPaymentIntentParams.swift in Sources */ = {isa = PBXBuildFile; fileRef = CA6F220FA443AA13A65D8D097C0F6D08 /* STPPaymentIntentParams.swift */; }; + 504F56E775C794C1C43496CFF82279C0 /* STPPaymentIntentShippingDetailsAddressParams.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0B2F0EE54C26FBAC5DEFD696CD0CCB91 /* STPPaymentIntentShippingDetailsAddressParams.swift */; }; + 508B4C848966DD16897AC114384274F9 /* STDSCategoryLinker.m in Sources */ = {isa = PBXBuildFile; fileRef = 9F3C30898EEBAEE177DDF0BC1283FE03 /* STDSCategoryLinker.m */; }; + 50CA71B286B02AD73D81F32760381E7C /* pl-PL.lproj in Resources */ = {isa = PBXBuildFile; fileRef = 515609AFE656AE99F197C89E04E08C5F /* pl-PL.lproj */; }; + 517CA1D86EA54C108B6D26E3BD0EF565 /* STPPaymentMethodAlipayParams.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9118F02EFC221FE9C59B2E6CD5362783 /* STPPaymentMethodAlipayParams.swift */; }; + 5198216234ABD8841F582DA3A416B87C /* STPPaymentHandlerActionParams.swift in Sources */ = {isa = PBXBuildFile; fileRef = 70A8E487A5A139A0AEBE9CA07D630647 /* STPPaymentHandlerActionParams.swift */; }; + 51BAE003E7BD972B4F6EB54CFB7E1BF0 /* RaisesException.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3D08A5A4B5601443EFFFBFB1AC2E385D /* RaisesException.swift */; settings = {COMPILER_FLAGS = "-DPRODUCT_NAME=Nimble/Nimble"; }; }; + 5258586AADBC8482EFAFB4B591A17E03 /* ToSucceed.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34B323CCEC4BAF3077A937A36605C648 /* ToSucceed.swift */; settings = {COMPILER_FLAGS = "-DPRODUCT_NAME=Nimble/Nimble"; }; }; + 531A3FFB720E63D899AE8792730826B6 /* pt-PT.lproj in Resources */ = {isa = PBXBuildFile; fileRef = 387CCC265AED18EEACFA2BA602EE1EE0 /* pt-PT.lproj */; }; + 537D3533C8C1ADF45A907F20B9A9C96A /* NSDictionary+DecodingHelpers.m in Sources */ = {isa = PBXBuildFile; fileRef = A21AC98AF15AF5BEC22D6BC3BE3C2A7E /* NSDictionary+DecodingHelpers.m */; }; + 53A5EBB7EB042B7CEB835CFF83C89C43 /* STPLocalizationUtils.swift in Sources */ = {isa = PBXBuildFile; fileRef = 60AB9ADFC4EF35A2857FB4F515E28C77 /* STPLocalizationUtils.swift */; }; + 53B5517387B519E406C3B5A73F3F811D /* STDSThreeDSProtocolVersion+Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 5E98E0A80EACE6D763BFF6171F22E5AF /* STDSThreeDSProtocolVersion+Private.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 53BC2AEA33D49FA9D544FF86946562B8 /* STPAuthenticationContext.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9B74AA57FD5B68F19374399206D13FA9 /* STPAuthenticationContext.swift */; }; + 5406E0B3ADF8DDC0305DEC96A1A8850A /* STPBankAccount.swift in Sources */ = {isa = PBXBuildFile; fileRef = 83001213CDB2773DE860093689A1E182 /* STPBankAccount.swift */; }; + 5448447D317610CE0DF66B87CF6F1094 /* Closures.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9063A8C24A5E606AFAC2535BD0014BDB /* Closures.swift */; }; + 54A6D1294A70008E39F187698487AAE7 /* nb.lproj in Resources */ = {isa = PBXBuildFile; fileRef = FA6AF22C064B0F8424A80A848EC86BF4 /* nb.lproj */; }; + 5512379703F7D5CD28009429ABAF83D3 /* STDSEphemeralKeyPair.h in Headers */ = {isa = PBXBuildFile; fileRef = D89A81669E4A065FF0FE35260D05B217 /* STDSEphemeralKeyPair.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 5521DE558746F2B63DE15441F5322492 /* STPThreeDSTextFieldCustomization.swift in Sources */ = {isa = PBXBuildFile; fileRef = 640EC78C807E1AA131D2EB0F2652750C /* STPThreeDSTextFieldCustomization.swift */; }; + 55C6143DA83ADF23A6CB448653B3884E /* STPMultipartFormDataPart.swift in Sources */ = {isa = PBXBuildFile; fileRef = ED3D2EB66C4DC42F56DEA740EB759457 /* STPMultipartFormDataPart.swift */; }; + 55C79F5BF5BF3DCFD571CFB76DCB1BB6 /* StripeCore-StripeCore in Resources */ = {isa = PBXBuildFile; fileRef = 18732DE2E9C58AEC17E6DD6B7CF9FFA2 /* StripeCore-StripeCore */; }; + 55CC542DBCF95120A6772C015357491F /* STDSChallengeResponseImageObject.m in Sources */ = {isa = PBXBuildFile; fileRef = 788643DE0B693BF3BE7538FE541BC9CA /* STDSChallengeResponseImageObject.m */; }; + 55E81DE2AD08EAEC57A149974226221C /* STPPaymentMethodCardPresent.swift in Sources */ = {isa = PBXBuildFile; fileRef = C88AA3D0BCBD01CEF746F5DA3D8E5B82 /* STPPaymentMethodCardPresent.swift */; }; + 5611DE6F81B398AB40683BA786E14698 /* STPPaymentMethodAUBECSDebitParams.swift in Sources */ = {isa = PBXBuildFile; fileRef = C238C0F8568BA3ADBB51C71781542E1D /* STPPaymentMethodAUBECSDebitParams.swift */; }; + 57B1D9A5DFBB06AB22AC0BCE27137371 /* STDSEllipticCurvePoint.m in Sources */ = {isa = PBXBuildFile; fileRef = 8CA21A5FBB404BC0CF4F23BD4C5416F3 /* STDSEllipticCurvePoint.m */; }; + 57E3018DEDC081BF4B445195CA43738D /* ConnectionsSDKAvailability.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07C27B89557353E8CC25C4EC7BA2B3A7 /* ConnectionsSDKAvailability.swift */; }; + 584817ED3C181B508267955AA4A97EF2 /* StripeJSONShared.swift in Sources */ = {isa = PBXBuildFile; fileRef = 702AA8B503547D54D21CC4D2C7836ECF /* StripeJSONShared.swift */; }; + 58CAB839E63D7D4575D3DEDF8C98EDD9 /* Await.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5C4B472B13C02ACDEC9F0D9B5FBCAAE /* Await.swift */; settings = {COMPILER_FLAGS = "-DPRODUCT_NAME=Nimble/Nimble"; }; }; + 597A941B9D43299E37279E9B0788C7AB /* visa-logo@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 772B0769A9D14703FD8D00A8FCFDE4B6 /* visa-logo@3x.png */; }; + 5A3C142DB4EE0306335BEE9839A15DF3 /* STPPaymentMethodBancontactParams.swift in Sources */ = {isa = PBXBuildFile; fileRef = AE34D75E315D2647406F156B2C66E509 /* STPPaymentMethodBancontactParams.swift */; }; + 5AADFB759F3F298B860A73ADCB9A577C /* StripeCore-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 5EC537635899CA4178859BACFF28917D /* StripeCore-dummy.m */; }; + 5AB4BA6467D05922B9747494C762658A /* mt.lproj in Resources */ = {isa = PBXBuildFile; fileRef = 7D56768635E337B85B786680BECE1DFA /* mt.lproj */; }; + 5B2440B6C23C16F46152FE4219D49E44 /* FileDownloader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8C4912EE1BDF346B45A19660EDBF268A /* FileDownloader.swift */; }; + 5D74A95CEB3BA624888E0A9E1E1704B5 /* UIActivityIndicatorView+Stripe.swift in Sources */ = {isa = PBXBuildFile; fileRef = C0D54B4D6898F5344AB1E0195A4196FE /* UIActivityIndicatorView+Stripe.swift */; }; + 5D9F21E15D4AB17397AE6B74120772DE /* STDSException.m in Sources */ = {isa = PBXBuildFile; fileRef = CD92FCE49C77B940DA1D70F958ED1187 /* STDSException.m */; }; + 5DE534ADC468F5FFC43371CE7138923F /* URL+FileName.swift in Sources */ = {isa = PBXBuildFile; fileRef = A517E1F0F0973404AFEE7F63ABCDEDA6 /* URL+FileName.swift */; }; + 5DEDCB91142523EAD727F06ACBFCBFCA /* hr.lproj in Resources */ = {isa = PBXBuildFile; fileRef = 53EBB9D86B35E049D6F865320CDCE915 /* hr.lproj */; }; + 5EFE91D84410F9BB6FC0F92B761D63BC /* STDSChallengeResponseSelectionInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = FC6FEF75843987D374D6F8A1E5784665 /* STDSChallengeResponseSelectionInfo.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 5F9E42E5F8D8D68740FBCF1F126A3246 /* STPIntentActionVerifyWithMicrodeposits.swift in Sources */ = {isa = PBXBuildFile; fileRef = B3AD9A6234AE08A050EE83A678B69C3D /* STPIntentActionVerifyWithMicrodeposits.swift */; }; + 5FB25BDB7662B006741D18B2D2728FB9 /* STDSDirectoryServerCertificate+Internal.h in Headers */ = {isa = PBXBuildFile; fileRef = 5DFDD80575DD9A05A06ED19D4D52AE70 /* STDSDirectoryServerCertificate+Internal.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 5FC764CD3AEC0FEFDE90C6BEE67F88E0 /* STDSAlreadyInitializedException.m in Sources */ = {isa = PBXBuildFile; fileRef = C0DCEA1D4D85AB5B85FA8A1902B03DC4 /* STDSAlreadyInitializedException.m */; }; + 604A73AD1D0E82356F2A073C53BC6517 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 54808C6C88411583D225CB43662CF2A8 /* Foundation.framework */; }; + 60A059AA3734D5D3F2F73D07C427F4C1 /* NMBExceptionCapture.h in Headers */ = {isa = PBXBuildFile; fileRef = 8F2E3ED06516DE4F8F181334EFE0CC98 /* NMBExceptionCapture.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 612581CCD8346C696A80E6BC09D24C1F /* QCKDSL.h in Headers */ = {isa = PBXBuildFile; fileRef = 053B61719B4CBA9537CBFF4C7EF8AA0F /* QCKDSL.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 61B9F6CA3288008E3844B109E029A31E /* STDSBrandingView.h in Headers */ = {isa = PBXBuildFile; fileRef = 11E6A0CBA10A6C02A9EFB6A703E5254B /* STDSBrandingView.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 61F1ADB6BE662783C1A01C2C1720A9BE /* Expression.swift in Sources */ = {isa = PBXBuildFile; fileRef = B54EC0EF37010C07F19247700B6E2A2D /* Expression.swift */; settings = {COMPILER_FLAGS = "-DPRODUCT_NAME=Nimble/Nimble"; }; }; + 6228796E148B8398B2D1B31F77D042EB /* STDSSelectionButton.m in Sources */ = {isa = PBXBuildFile; fileRef = E799BF777DAD19532060DD4EC5A4D21E /* STDSSelectionButton.m */; }; + 625D01B2A58AB0AC4F5C39DBC0D72BE3 /* STDSSelectionButton.h in Headers */ = {isa = PBXBuildFile; fileRef = 3D468BAE407184775B5DAD5E74EB7816 /* STDSSelectionButton.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 62B1FBBB4730BD586623DB586E19C2B2 /* da.lproj in Resources */ = {isa = PBXBuildFile; fileRef = 7E5046088EC6C2114646D8B07A0EBC24 /* da.lproj */; }; + 632F5CE128D6EB689DEBC02B3C3809E6 /* mastercard-logo@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 7F5F41998EFB37CF78F99CF0F791E95F /* mastercard-logo@3x.png */; }; + 6374F4F6160ABD4FED618C0B185ABD65 /* ko.lproj in Resources */ = {isa = PBXBuildFile; fileRef = 15FA8A572184CCA188DEF786D5C3825D /* ko.lproj */; }; + 639778C97DA9CD7EAD99E627C2406134 /* lv-LV.lproj in Resources */ = {isa = PBXBuildFile; fileRef = 7BA04BA2C2F951AEB0629D2648B73A3C /* lv-LV.lproj */; }; + 649BF6E2C467C6536F33929348E8F5BF /* NSError+Stripe3DS2.m in Sources */ = {isa = PBXBuildFile; fileRef = EC75797CB57718E096614861E48CFA3F /* NSError+Stripe3DS2.m */; }; + 654580360E6694D7F7CE85CE5390DA79 /* PostNotification.swift in Sources */ = {isa = PBXBuildFile; fileRef = 04C4BA6488DA9BA50F6C16F86B003E83 /* PostNotification.swift */; settings = {COMPILER_FLAGS = "-DPRODUCT_NAME=Nimble/Nimble"; }; }; + 656672FCB67916A358E8A3A03D7ED2E7 /* STPThreeDSCustomizationSettings.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1A3520C47E6A3BB8141D861D8C81B07 /* STPThreeDSCustomizationSettings.swift */; }; + 65B344D8EAC0CC0A22EA584F8F1C1715 /* STDSWebView.h in Headers */ = {isa = PBXBuildFile; fileRef = 065A9053EB46701FD1D2B278797D0E03 /* STDSWebView.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 660457395E48C263AC70C866DCE7A479 /* STDSDebuggerChecker.m in Sources */ = {isa = PBXBuildFile; fileRef = FF0B4080B203408C62452F1712DEEE72 /* STDSDebuggerChecker.m */; }; + 66918EBA9CAF1899C37B9841FFC7BD3A /* STPPaymentMethodEnums.swift in Sources */ = {isa = PBXBuildFile; fileRef = B9340FFDE6A4B4888DD54151796BD4A2 /* STPPaymentMethodEnums.swift */; }; + 67CC273972C5BE4106E3A230665EE14F /* STPPaymentMethodPayPalParams.swift in Sources */ = {isa = PBXBuildFile; fileRef = ABD503531BA02821DCD280C2288A316C /* STPPaymentMethodPayPalParams.swift */; }; + 68976CA0ECBD78B5BC8FFAC1DB70EAED /* STDSCompletionEvent.h in Headers */ = {isa = PBXBuildFile; fileRef = 546C97E71464A08D279EDEDCBC44A6DD /* STDSCompletionEvent.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 6978C8861303501E23F190E5A2F33B1B /* STDSDeviceInformationManager.m in Sources */ = {isa = PBXBuildFile; fileRef = D8FCC1853BA7EF3E5CC8D63117717701 /* STDSDeviceInformationManager.m */; }; + 69927078FE219FA15CE94F5BA50776B8 /* UIView+LayoutSupport.m in Sources */ = {isa = PBXBuildFile; fileRef = 2CA78CD1E904D7029982A7DA5AF65AAD /* UIView+LayoutSupport.m */; }; + 6A47C53473FBCF2FF5C85069FBD4CA8D /* QuickConfiguration.h in Headers */ = {isa = PBXBuildFile; fileRef = D1706788AB559B2764779D59CB3F9CFB /* QuickConfiguration.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 6AB143C321A8D680D0EF0A55C0DCD238 /* el-GR.lproj in Resources */ = {isa = PBXBuildFile; fileRef = C3DE0AFB197D44F5B86CEDD53F8632B9 /* el-GR.lproj */; }; + 6B7F5CCF546E0D3D602CFCE4A98FE2A1 /* ru.lproj in Resources */ = {isa = PBXBuildFile; fileRef = E2E8B2DBFF95E00E33BC8FCAFBFC3459 /* ru.lproj */; }; + 6B9843AA0B06FBE0E6D2A642D061C2A7 /* sk-SK.lproj in Resources */ = {isa = PBXBuildFile; fileRef = 51A9DE9335F7CC0592DC7AA72D3B4A63 /* sk-SK.lproj */; }; + 6C1386A39405BDA544D5BEE2C9155AB1 /* QuickSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = 8D0F4C067C6ED33DC645C8A9C5697B8F /* QuickSpec.m */; }; + 6C8205BED893A04967605C572C57BF3A /* STDSButtonCustomization.h in Headers */ = {isa = PBXBuildFile; fileRef = 8FFA653D29530ABA70A0D91416DF179A /* STDSButtonCustomization.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 6CA2B3D04F65BDE7ADBE8FB1C332D1F1 /* NSString+EmptyChecking.h in Headers */ = {isa = PBXBuildFile; fileRef = A8CF02440135A2CCC70F434936170066 /* NSString+EmptyChecking.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 6D2F9F1DC6C1DE1C73F4382904B9C97C /* DSL+Wait.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49A14E85E3585B6652A5D97440A4D055 /* DSL+Wait.swift */; settings = {COMPILER_FLAGS = "-DPRODUCT_NAME=Nimble/Nimble"; }; }; + 6DD10DD516783DD0C7B0E0298628F69A /* UnknownFields.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A4B6F62FC807F51F8C6FE74F065203 /* UnknownFields.swift */; }; + 6E093F97794335877D471A57CAE58B59 /* STDSCategoryLinker.h in Headers */ = {isa = PBXBuildFile; fileRef = 55ED1A89217E66F3DDA8E2191F28E79D /* STDSCategoryLinker.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 6E0F264A27DEDECFC1D982A8B4DA4A67 /* STPSourceReceiver.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A6179DC66BD0B1B7454C6A05DCD5313 /* STPSourceReceiver.swift */; }; + 6E2E247EDB9A023F6C50C7790C3A5C0E /* STPSourceWeChatPayDetails.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6B50A752E2809107CB299D3C0202B2B1 /* STPSourceWeChatPayDetails.swift */; }; + 6F4F5989C108EB29AB735E9CAF4B6E0A /* BeginWith.swift in Sources */ = {isa = PBXBuildFile; fileRef = A122539537DF4B02BC30CC40408E720C /* BeginWith.swift */; settings = {COMPILER_FLAGS = "-DPRODUCT_NAME=Nimble/Nimble"; }; }; + 6F796B7E3AA428C9D8E88F0F2269664F /* NimbleXCTestHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 15A26F6CDD349347AB55D87E3586D138 /* NimbleXCTestHandler.swift */; settings = {COMPILER_FLAGS = "-DPRODUCT_NAME=Nimble/Nimble"; }; }; + 7049CF2F9C4DC901C381FB7E84CE1376 /* STDSRuntimeException.h in Headers */ = {isa = PBXBuildFile; fileRef = FE41B23FCE5856C930AEB856BE863DFE /* STDSRuntimeException.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 707245706183C9814604FBE34CD83152 /* NMBExpectation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 27899F0C9E29C49D1C37CF38F8944ADD /* NMBExpectation.swift */; settings = {COMPILER_FLAGS = "-DPRODUCT_NAME=Nimble/Nimble"; }; }; + 7190961540266108624E854866842A81 /* NMBStringify.h in Headers */ = {isa = PBXBuildFile; fileRef = 056DA00E7E017616FF5CF5023CCED999 /* NMBStringify.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 7254F83F3CB7D30043C11CB22EB57A97 /* UIButton+CustomInitialization.h in Headers */ = {isa = PBXBuildFile; fileRef = 45CC895FC6FB5B914EAD7243B1458122 /* UIButton+CustomInitialization.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 72AADC86E10056E323FE1BE5781F92E7 /* STPConnectAccountCompanyParams.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9B26C7EA50966EF31016ED82F61A9DC6 /* STPConnectAccountCompanyParams.swift */; }; + 72DCB1645FE9AC8529ABDA1973947CDE /* STDSImageLoader.h in Headers */ = {isa = PBXBuildFile; fileRef = B01A806A185889C078952DA2E94E5372 /* STDSImageLoader.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 72EDABCF87F530030F5EE5835DC694DF /* STPConfirmUSBankAccountOptions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34A927CDFA8ADB3ACE06A83F3000FE62 /* STPConfirmUSBankAccountOptions.swift */; }; + 73065317568D1578D686880367193763 /* STPPaymentMethodWeChatPay.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9B96E139B87973CB2C525F018B20AA12 /* STPPaymentMethodWeChatPay.swift */; }; + 73ADAC6E76DA45BA9AD8E93AA86FED61 /* STDSInvalidInputException.h in Headers */ = {isa = PBXBuildFile; fileRef = 9F7356AF9FD486BC92EFA25CA3B5006F /* STDSInvalidInputException.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 73B07F9B664C675544CBD4BDCEAA5126 /* STPPaymentMethodSEPADebitParams.swift in Sources */ = {isa = PBXBuildFile; fileRef = CAB5C0235D9DD565A361624426F57448 /* STPPaymentMethodSEPADebitParams.swift */; }; + 73D5A6FC1EFECCF2666663559DE4D589 /* STPThreeDSNavigationBarCustomization.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4EDB069FE5B735AB6777009C5B0A8417 /* STPThreeDSNavigationBarCustomization.swift */; }; + 743B8A6DA10EC663C12E26B22DBC4EEA /* STPSourcePoller.swift in Sources */ = {isa = PBXBuildFile; fileRef = F2A1C609918CBF59373233370DB12637 /* STPSourcePoller.swift */; }; + 747BBEC4CF161FE7C2B526FF383D7E74 /* NSError+Stripe.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3744BDC1A0806F0DED894A00F2712B86 /* NSError+Stripe.swift */; }; + 747CAA94CC7606C5B3059954DD0E4830 /* zh-Hant.lproj in Resources */ = {isa = PBXBuildFile; fileRef = 8B3AE7859EF5DBF75496199E8B0A9498 /* zh-Hant.lproj */; }; + 752151B8399034C5C7C9DD6BC7EE5E76 /* PaymentsSDKVariant.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9885674AD68E194BC165B76CD7010AD0 /* PaymentsSDKVariant.swift */; }; + 76AE5C59F6E03C8F2D9181A69B86FCD7 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 54808C6C88411583D225CB43662CF2A8 /* Foundation.framework */; }; + 7719F4DDA13C4EB6644958C99C1A00CC /* id.lproj in Resources */ = {isa = PBXBuildFile; fileRef = 64B0E91A7B514C7093443DFC1DF53787 /* id.lproj */; }; + 7755AE0B1825275FF67240EBD52A8F8E /* URLEncoder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4826274260E8C1435364904F6E10BAAD /* URLEncoder.swift */; }; + 7834BD3EC61F467585E353117D408842 /* STPPaymentMethodBoleto.swift in Sources */ = {isa = PBXBuildFile; fileRef = 89DA4DBD9EE053423AD56C0F90220D48 /* STPPaymentMethodBoleto.swift */; }; + 7862D17B8F45E886EC3B54FBFF7927BE /* STPPaymentMethodAddress.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8706D946C8E1B31C6FF28C6C815B3AB0 /* STPPaymentMethodAddress.swift */; }; + 787F7A4134E841000990DD658FB4E1AB /* UIImage+StripeCore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 42079B2294C0AE31BA9D6760783EF328 /* UIImage+StripeCore.swift */; }; + 7906A8B1E314D4571ED317F61D625A18 /* lt-LT.lproj in Resources */ = {isa = PBXBuildFile; fileRef = 66046363AA74B29375751A2D4FE68CC7 /* lt-LT.lproj */; }; + 7965DE1868A495D8C7FD13B57DBF03FC /* STPTelemetryClient.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95CFAB09EC6E141434C0BC08D2017EC5 /* STPTelemetryClient.swift */; }; + 79A9ADCAE72B5F30CE882F79CDDDD47F /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 54808C6C88411583D225CB43662CF2A8 /* Foundation.framework */; }; + 7ADFB5438DEDDE5E4B32B69424AFC2EA /* ja.lproj in Resources */ = {isa = PBXBuildFile; fileRef = 8AD03424911FBF425195C50772474D21 /* ja.lproj */; }; + 7B68D51E405CB6B2160B89A2509F1A7D /* STDSChallengeParameters.h in Headers */ = {isa = PBXBuildFile; fileRef = C164A593BCFD54017290D1F1838F974D /* STDSChallengeParameters.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 7BC844CA7A35AD615B8F495CF68294BF /* STDSRuntimeErrorEvent.h in Headers */ = {isa = PBXBuildFile; fileRef = 46DD3A21888BE80122BB4C39AECE8C66 /* STDSRuntimeErrorEvent.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 7CCE824E9729089D8873C7E602726F92 /* STDSErrorMessage+Internal.m in Sources */ = {isa = PBXBuildFile; fileRef = 1A1B6B7E75482437E3EE31548C812FBA /* STDSErrorMessage+Internal.m */; }; + 7DF5C2582E1C9DE5BC6BF84C0AF1337B /* BeCloseTo.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5A7E15112F94F1128C0AE9FCBAB8DDF6 /* BeCloseTo.swift */; settings = {COMPILER_FLAGS = "-DPRODUCT_NAME=Nimble/Nimble"; }; }; + 7F1EC3CEE3EA9ED2B93A133B91360547 /* STPPaymentHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = E8C562D4699AF51D606386F895C007AC /* STPPaymentHandler.swift */; }; + 7FF14A601B0FA95DC03D5A79DC9E80DC /* STPRedirectContext.swift in Sources */ = {isa = PBXBuildFile; fileRef = 88EA388CF5C8EE9BB519A1E5E6091C55 /* STPRedirectContext.swift */; }; + 80428B0834B1272AB4E96E00D3FAA081 /* Example.swift in Sources */ = {isa = PBXBuildFile; fileRef = A2A3E6B30EB1966A53E390AFBBA33BFA /* Example.swift */; }; + 80A4FEC7BBEF285AA71AA19F228891DA /* ca-ES.lproj in Resources */ = {isa = PBXBuildFile; fileRef = D704C0F78EB8A406496B33883E781802 /* ca-ES.lproj */; }; + 80AA331134CA9AA79AD0CD177EA3452B /* fi.lproj in Resources */ = {isa = PBXBuildFile; fileRef = D47245DA06CD0D5DDF6943F1D1B40122 /* fi.lproj */; }; + 80CE047F3F38DAE8000E5BDB38301764 /* STPPaymentMethodWeChatPayParams.swift in Sources */ = {isa = PBXBuildFile; fileRef = FECE9A949CF578DBE8A520691843CA88 /* STPPaymentMethodWeChatPayParams.swift */; }; + 80DB7C67B0D7A32BF885B5CD17C745A1 /* NimbleEnvironment.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8752110D3D9DB57A8872CB00C4FE8030 /* NimbleEnvironment.swift */; settings = {COMPILER_FLAGS = "-DPRODUCT_NAME=Nimble/Nimble"; }; }; + 81183C395B09751B7AE3A5DFCCDA3EAF /* ja.lproj in Resources */ = {isa = PBXBuildFile; fileRef = 0EC220DB36D5291F5340C43799393C0B /* ja.lproj */; }; + 814E2CD5547867549C23CA1F12E7E645 /* UIColor+ThirteenSupport.h in Headers */ = {isa = PBXBuildFile; fileRef = 1ED24B16FAE7F929952656DAEC8C0246 /* UIColor+ThirteenSupport.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 817B2E37DA5E47634EDA6B5DEAC6106B /* da.lproj in Resources */ = {isa = PBXBuildFile; fileRef = 147806AA9A9DBD6E2E7CDF5A2733F977 /* da.lproj */; }; + 83EBFC78EE70D4A3C64B65E6C8D3F767 /* tr.lproj in Resources */ = {isa = PBXBuildFile; fileRef = 658CA849B7FD68987A046BA203033A20 /* tr.lproj */; }; + 844CB33B12AE52C7AAA0D6AB88F89562 /* STDSJailbreakChecker.h in Headers */ = {isa = PBXBuildFile; fileRef = 01A9C02EFDED19245C2C5A380F52A0ED /* STDSJailbreakChecker.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 84E439FD06B111CEC1109509478D39BC /* vi.lproj in Resources */ = {isa = PBXBuildFile; fileRef = 619E50D28D3CD3C702827667E0DC6C0C /* vi.lproj */; }; + 8506EA10F248EB2F7B0CA98731A86F6B /* STPPaymentMethodiDEAL.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7730C169501EB9BA94B6002C839BA27D /* STPPaymentMethodiDEAL.swift */; }; + 85A33C8F0E13EE87EE64187C8F1079D9 /* STPAPIClient+PaymentsCore.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECCFBD8562CEB28DAA1C33A1957FE839 /* STPAPIClient+PaymentsCore.swift */; }; + 85D69147A32CD77DD75582D545B58C23 /* STPSourceSEPADebitDetails.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA9375A5C2F58B4C0B4C74148B397674 /* STPSourceSEPADebitDetails.swift */; }; + 86037D5CAD49EC09A2B944ADBF561059 /* Errors.swift in Sources */ = {isa = PBXBuildFile; fileRef = C21A88A8A5156126F47EE1F778DC732B /* Errors.swift */; settings = {COMPILER_FLAGS = "-DPRODUCT_NAME=Nimble/Nimble"; }; }; + 86210B5A0EBAE763C407DF08B380B0E7 /* EmptyResponse.swift in Sources */ = {isa = PBXBuildFile; fileRef = 72F0E941A7AFBB57CBC007A3A0673090 /* EmptyResponse.swift */; }; + 8655B078AB39F125F19B25F136711CE6 /* NSCharacterSet+StripeCore.swift in Sources */ = {isa = PBXBuildFile; fileRef = F46B9E382AB9E78D472B92BE10842869 /* NSCharacterSet+StripeCore.swift */; }; + 86F339CD2AC66630008B7ED5C0D63487 /* STPPaymentMethodLink.swift in Sources */ = {isa = PBXBuildFile; fileRef = 372B25E935274FF2EDD7057837EDF8A2 /* STPPaymentMethodLink.swift */; }; + 86F84DE049A0E2CADAC8344E20D070BE /* mach_excServer.c in Sources */ = {isa = PBXBuildFile; fileRef = B4CBB2439D8D5FF1AA424299EE2E8240 /* mach_excServer.c */; settings = {COMPILER_FLAGS = "-DPRODUCT_NAME=Nimble/Nimble"; }; }; + 87535E5C51E9F6B7B1517FEA95033D1C /* QuickConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = A35FCF60B5E331DA456844DDA2CA38E7 /* QuickConfiguration.swift */; }; + 8822F8BF2FAD0AD508BDAB4AB4EF65E0 /* STDSLabelCustomization.m in Sources */ = {isa = PBXBuildFile; fileRef = 334B40A9E0C181C9569B78891404779D /* STDSLabelCustomization.m */; }; + 88380C6AB029E423E69827B204BFF18A /* NMBStringify.m in Sources */ = {isa = PBXBuildFile; fileRef = A264E1409E0060EE050F7C7E5A4AC4E5 /* NMBStringify.m */; settings = {COMPILER_FLAGS = "-DPRODUCT_NAME=Nimble/Nimble"; }; }; + 893892529FFE17A91CDFF4E5A2E992A0 /* id.lproj in Resources */ = {isa = PBXBuildFile; fileRef = 051B5D2B1A4E36E5CE60E4AF9F3D8323 /* id.lproj */; }; + 89A131FB1AC2EDD2E4997883769BFD70 /* STPThreeDSLabelCustomization.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9CDE34F348B121C7F912F3C9B961B044 /* STPThreeDSLabelCustomization.swift */; }; + 8A787DDDD4F317EE45FDFFBF2A2B1A9A /* NSString+EmptyChecking.m in Sources */ = {isa = PBXBuildFile; fileRef = ABA0E5F06CEDF5D25C0C510CFAE7042E /* NSString+EmptyChecking.m */; }; + 8A9FE00A3D26CFEDEF3503C93FEFC954 /* EndWith.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8B7171A3654D24299DD7F925A56489F0 /* EndWith.swift */; settings = {COMPILER_FLAGS = "-DPRODUCT_NAME=Nimble/Nimble"; }; }; + 8AD3F27AE64AEC327B266F4BC4AE6452 /* STPFormEncodable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 67BE6311C4F34E8994712859CD9CC1B1 /* STPFormEncodable.swift */; }; + 8BF51F8D9ED5F6F99F175EBB8FCA89C2 /* STDSLocalizedString.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A70E31830D31A711BFFFA3C5B24EAFA /* STDSLocalizedString.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 8D0C7CE334E5F30C6CC8487235BBDBF5 /* STDSChallengeResponseViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = B45E30C6E48B3DB63F442C883902A31A /* STDSChallengeResponseViewController.m */; }; + 8D73DFC33DD8B75BD9636E4DFA010A83 /* STPPaymentIntentEnums.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8FBF0235279ED78553212C17484C9983 /* STPPaymentIntentEnums.swift */; }; + 8E026CDD76D8E093C4EEA16398E7B6D1 /* STPPaymentMethodSofort.swift in Sources */ = {isa = PBXBuildFile; fileRef = C298BDCCBD2AACD2DEA8CDDC5FD6697A /* STPPaymentMethodSofort.swift */; }; + 8E40DF482D30552C79C18916578C7898 /* STPPaymentMethodCardChecks.swift in Sources */ = {isa = PBXBuildFile; fileRef = 09F8D6800BE948F806BA63A483D2368D /* STPPaymentMethodCardChecks.swift */; }; + 8E49E63DD350D18D4D554597D0392272 /* it.lproj in Resources */ = {isa = PBXBuildFile; fileRef = 03EFF7427F270A66E19D421DF08BAA13 /* it.lproj */; }; + 8EFA132322053E7D8A1F9F380B5D8935 /* SuiteHooks.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0495AD8123610ADD73CF2D15C24F10A4 /* SuiteHooks.swift */; }; + 8F52028BF8EAE68FF8A208576A96BCB0 /* STDSConfigParameters.h in Headers */ = {isa = PBXBuildFile; fileRef = 83A25F3DE9E03CC60ABD875634EA53F8 /* STDSConfigParameters.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 8F5593DFFFCAC3D618365EC2590A3E31 /* AssertionRecorder.swift in Sources */ = {isa = PBXBuildFile; fileRef = B86C9D473E70FD7525079A04BFB91DBA /* AssertionRecorder.swift */; settings = {COMPILER_FLAGS = "-DPRODUCT_NAME=Nimble/Nimble"; }; }; + 8F995F206F3384B30DD6FB34F14FCA9D /* es-419.lproj in Resources */ = {isa = PBXBuildFile; fileRef = 84D6C16E96B06F6F1D11342FD76BF650 /* es-419.lproj */; }; + 8FDD9E5B7479DC38D2BFCEB427475E37 /* STDSProtocolErrorEvent.h in Headers */ = {isa = PBXBuildFile; fileRef = 32899D96AA85B67283ED2547D3E05BB6 /* STDSProtocolErrorEvent.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 9091A2BE5B94E19818700C6ACB123E03 /* Stripe3DS2.h in Headers */ = {isa = PBXBuildFile; fileRef = 1FF185B963FB99EF224ED52DABA01E82 /* Stripe3DS2.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 911CB8BEC748B2574B0E7182333366CA /* NSString+JWEHelpers.h in Headers */ = {isa = PBXBuildFile; fileRef = 3C8564A486877CE043FB241FDB66590F /* NSString+JWEHelpers.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 91EE566AEC7ABEFB1CE003F67BABD8C9 /* NSDecimalNumber+Stripe_Currency.swift in Sources */ = {isa = PBXBuildFile; fileRef = 751C674B6488C830F75741C0CE6C0433 /* NSDecimalNumber+Stripe_Currency.swift */; }; + 91FFBF606785C06075DB50284B24C796 /* STDSBundleLocator.h in Headers */ = {isa = PBXBuildFile; fileRef = 252E073673E5959089D69D015A77DA80 /* STDSBundleLocator.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 9225C8010A014CD2B6FE14CBB6145E41 /* sl-SI.lproj in Resources */ = {isa = PBXBuildFile; fileRef = 27D2EDCE6B76322090EB359B6F621326 /* sl-SI.lproj */; }; + 922D04AF11AF5704A172F34CF33C2463 /* STPIntentActionWeChatPayRedirectToApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6377BB294354AAC8F5CF936CE45A39E9 /* STPIntentActionWeChatPayRedirectToApp.swift */; }; + 9246F04A77AE1B5655219BB2FFE70BC9 /* String+Localized.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9250616CA2E76E6872BA1EB12B296113 /* String+Localized.swift */; }; + 92AD6953361C38E3E45B40B13B4AA72A /* STPPaymentMethodiDEALParams.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE35A27E9F5A3639F9CEE37E4C7CC50C /* STPPaymentMethodiDEALParams.swift */; }; + 92C13829401A964FBED01CB5D7FABC8E /* STPPaymentMethodGrabPayParams.swift in Sources */ = {isa = PBXBuildFile; fileRef = A943AD416632652905E4C850E18E2F8E /* STPPaymentMethodGrabPayParams.swift */; }; + 92DE6AC67462F0A507D3187892D4FA8A /* Equal+Tuple.swift in Sources */ = {isa = PBXBuildFile; fileRef = 708F5988B98C9B3D16D7E03755DAED4E /* Equal+Tuple.swift */; settings = {COMPILER_FLAGS = "-DPRODUCT_NAME=Nimble/Nimble"; }; }; + 9305732020F8C1DFF7A2FDE3106FCE43 /* STPThreeDSButtonCustomization.swift in Sources */ = {isa = PBXBuildFile; fileRef = 86A166B019E81AF19FD7E04AE6EF6DFB /* STPThreeDSButtonCustomization.swift */; }; + 93501F087A12FE661B02E564B9189E95 /* STPKlarnaLineItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 597423E1AFB4A8E43A79EB62B8BCD961 /* STPKlarnaLineItem.swift */; }; + 93985F1570254AB7EA83E6ED3054386C /* String+StripeCore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5A087B8B9AC3FF949E888C616D76603B /* String+StripeCore.swift */; }; + 93C543F550A86AF20CEAA48104788AF9 /* fr-CA.lproj in Resources */ = {isa = PBXBuildFile; fileRef = 5C9C58815409E510E46AB774447F4480 /* fr-CA.lproj */; }; + 93E8F7D415C604D8DAFAABD977323EFB /* STDSDirectoryServerCertificate.m in Sources */ = {isa = PBXBuildFile; fileRef = 6F2B6E62B1B30F32268B7A4FECD434AA /* STDSDirectoryServerCertificate.m */; }; + 942981F693C8B00131E35DEF2A67B049 /* STPConnectAccountIndividualParams.swift in Sources */ = {isa = PBXBuildFile; fileRef = 14FBD3E0630472217181870FDB97B602 /* STPConnectAccountIndividualParams.swift */; }; + 94C084F16DDF32E67EB2580F7C369B0F /* STPIntentActionOXXODisplayDetails.swift in Sources */ = {isa = PBXBuildFile; fileRef = 68C460E9ECE53C9DD237B0E8B6270A7A /* STPIntentActionOXXODisplayDetails.swift */; }; + 95250AB0246A4E0091E64F8EE99AD944 /* ConnectionsSDKInterface.swift in Sources */ = {isa = PBXBuildFile; fileRef = BE0D6877DEC57C4A40A285AFA6AC0DB0 /* ConnectionsSDKInterface.swift */; }; + 9548AE7735765ECA10CD238DAF7AF402 /* tr.lproj in Resources */ = {isa = PBXBuildFile; fileRef = 0661BE341FD38AE6F2E228BFF0A3DE12 /* tr.lproj */; }; + 958420B6D446B2DF67DB182A49F3270C /* STPPaymentMethodNetBankingParams.swift in Sources */ = {isa = PBXBuildFile; fileRef = 90B657183C9A0D2F44AFF285746F368E /* STPPaymentMethodNetBankingParams.swift */; }; + 95B5293645152CEFBCA7C6D45C64CD1A /* STDSEphemeralKeyPair+Testing.h in Headers */ = {isa = PBXBuildFile; fileRef = 03910FB9857DD28462E8F90639BBC655 /* STDSEphemeralKeyPair+Testing.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 95C09A180A722F1CF4B9C6B40772FB6D /* STPPaymentIntentAction.swift in Sources */ = {isa = PBXBuildFile; fileRef = 442207253E69A546D816A69280A04D3F /* STPPaymentIntentAction.swift */; }; + 96F551CCB74AA395DCA01B7ADA51EB13 /* STDSDirectoryServer.h in Headers */ = {isa = PBXBuildFile; fileRef = 9D52E420FDCEBA68136BEEC6DCEF385A /* STDSDirectoryServer.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 9728DA0B9363EF3439911A4B4BA75350 /* STPPaymentMethodAUBECSDebit.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3131F557AB874A02FAC93F1EAED6CA09 /* STPPaymentMethodAUBECSDebit.swift */; }; + 976BA00607DFEFFA60B3CB54CDBE8510 /* STPNumericStringValidator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30855110E3C79E9436F5C940800643C2 /* STPNumericStringValidator.swift */; }; + 9770974D1F6AD18D0883A63F5269AD74 /* STDSChallengeResponseSelectionInfoObject.m in Sources */ = {isa = PBXBuildFile; fileRef = D59F8EA29A0E89FFB3DA6A507C616BBC /* STDSChallengeResponseSelectionInfoObject.m */; }; + 9788AD60BD2C5CA8FF796C7C4189A52E /* visa-white-logo@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 19BBC418AD7958113B769C2598369D12 /* visa-white-logo@3x.png */; }; + 981F6B1579CE5D0BDB6E936DFC0B24F1 /* BeAnInstanceOf.swift in Sources */ = {isa = PBXBuildFile; fileRef = D98979E37C5C8388A18B97CB784D1282 /* BeAnInstanceOf.swift */; settings = {COMPILER_FLAGS = "-DPRODUCT_NAME=Nimble/Nimble"; }; }; + 982CFDFE8EEC9DCD5E2389A389349F2E /* StripeError.swift in Sources */ = {isa = PBXBuildFile; fileRef = BA5E4C5DA1266174ECF6D0615DF67D3B /* StripeError.swift */; }; + 991C750FCE4137E068570AA39F1C3142 /* mt.lproj in Resources */ = {isa = PBXBuildFile; fileRef = A79C4D99EA191FAE43C7DA6F6B650FF7 /* mt.lproj */; }; + 993ED0D1D74DDFAF99D4108636EFFA64 /* FailureMessage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 70D3FC01AB2025C3F5A9C9B91ACFCCB3 /* FailureMessage.swift */; settings = {COMPILER_FLAGS = "-DPRODUCT_NAME=Nimble/Nimble"; }; }; + 994DAB83E925F5BF28B00DFD0F9795CB /* CwlCatchException.m in Sources */ = {isa = PBXBuildFile; fileRef = EE1AF7283AF5AA0D21BB49FF926D44E5 /* CwlCatchException.m */; settings = {COMPILER_FLAGS = "-DPRODUCT_NAME=Nimble/Nimble"; }; }; + 9A42C573ABD2B7829B040E5D279B2625 /* STDSChallengeResponseViewController.h in Headers */ = {isa = PBXBuildFile; fileRef = E60400F5C4B289EB41483219C94E968B /* STDSChallengeResponseViewController.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 9A6BC18B9F442CCC3CDA9E13D50CBDEB /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 03D9F470BE7939CC23898F0F41EF0B5E /* UIKit.framework */; }; + 9AB3D03BC12D48113C0AFB7E687A274D /* BeginWithPrefix.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE536D5BFF715BBF9170CA454B770C4C /* BeginWithPrefix.swift */; settings = {COMPILER_FLAGS = "-DPRODUCT_NAME=Nimble/Nimble"; }; }; + 9ADD6B34BAB3FD65053D68C3D3EBD224 /* STPAPIClient+ApplePay.swift in Sources */ = {isa = PBXBuildFile; fileRef = 56A20ECC61E5D19EA0EFC66B905D1B01 /* STPAPIClient+ApplePay.swift */; }; + 9B4B84C8A58733E87C1F30CDE34F3BEE /* Filter.swift in Sources */ = {isa = PBXBuildFile; fileRef = D80532177CEAC4A052D9C672535F39F8 /* Filter.swift */; }; + 9B8B123AA626C49649D1B168417347AA /* STDSJSONWebEncryption.m in Sources */ = {isa = PBXBuildFile; fileRef = 40B004CC31F235FB5D0299B92F3F939A /* STDSJSONWebEncryption.m */; }; + 9B981E6DB0846F597838D6995E3F2EAC /* QuickSelectedTestSuiteBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = E1CA084EE92AC1E9F6B6EA26953364FE /* QuickSelectedTestSuiteBuilder.swift */; }; + 9BB0B4EDE9F62460C83A52B3EB7D1B92 /* StripeFile.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7214D0F2B31EC4D3B8710F5DEEE20118 /* StripeFile.swift */; }; + 9C40AF83392453D4E62808BEFEC4F136 /* NSError+StripeCore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 97CE0A95804990A9BF59F85837F3EEA0 /* NSError+StripeCore.swift */; }; + 9C6E62A2B5A31C85863D0FCA8A2F4B31 /* STPIntentActionBoletoDisplayDetails.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3664BF9D1DF403E0D5CF6BC73B5171F1 /* STPIntentActionBoletoDisplayDetails.swift */; }; + 9C75931ADE8431B4C3C4AE2D59E70977 /* Predicate.swift in Sources */ = {isa = PBXBuildFile; fileRef = F1EB6B89F982600E3611EBC9989948E2 /* Predicate.swift */; settings = {COMPILER_FLAGS = "-DPRODUCT_NAME=Nimble/Nimble"; }; }; + 9C93BB10F775FA86E2A109839B56BE10 /* STPLocalizedString.swift in Sources */ = {isa = PBXBuildFile; fileRef = 42C0C827BD5426B6D3D5EAE30475AC10 /* STPLocalizedString.swift */; }; + 9D3B7EF46FDD56136777830F2173173E /* STDSAuthenticationResponse.h in Headers */ = {isa = PBXBuildFile; fileRef = C4677C898A8625631B6903F08544092B /* STDSAuthenticationResponse.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 9D7E95888E772E02E5BFC9ADBDE1BF0E /* STDSChallengeParameters.m in Sources */ = {isa = PBXBuildFile; fileRef = AD5CF8D8EBFEE99A480B0E9AF068AE06 /* STDSChallengeParameters.m */; }; + 9DAB06377586D5E1671C825C54F6C336 /* STDSTransaction+Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 3CEF0E39AF8543EB7223811AE62CCA59 /* STDSTransaction+Private.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 9E3D857CC112D7CE9BFB3DCEB21DD00D /* STPRadarSession.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5A5C99F67007365C562DD1294DBD73DA /* STPRadarSession.swift */; }; + 9E757DB7080E589FBE998F6765866280 /* Pods-OSPaymentsLib-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 8FAE50E0E3AD48853025A2E73597E47B /* Pods-OSPaymentsLib-dummy.m */; }; + 9E921B6C45E2EBD0939CCFF28CBE5A75 /* pt-BR.lproj in Resources */ = {isa = PBXBuildFile; fileRef = 9FE972D98984635A54F809DE38DC4639 /* pt-BR.lproj */; }; + 9EC7AB2EFD97FBE104802C6F0211A284 /* en-GB.lproj in Resources */ = {isa = PBXBuildFile; fileRef = 8A0CC1CD9EA3D27F6999D69A4B688807 /* en-GB.lproj */; }; + 9FFC1D91DC12B77A74FBC5A0D7F3310B /* StripeJSONEncoder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 207690A83F45986DB4608DAA78531321 /* StripeJSONEncoder.swift */; }; + A017E1A4E1C0AA61CDB6F1E8382D3384 /* ExpectationMessage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84AA17F827E17EE953033F81C18C2561 /* ExpectationMessage.swift */; settings = {COMPILER_FLAGS = "-DPRODUCT_NAME=Nimble/Nimble"; }; }; + A0F1DDBCD61B35967DED6A8F6A69B9A5 /* Async.swift in Sources */ = {isa = PBXBuildFile; fileRef = 54F009A4863C281F89977236F98D9E83 /* Async.swift */; settings = {COMPILER_FLAGS = "-DPRODUCT_NAME=Nimble/Nimble"; }; }; + A102FE1C25F4941B532C6B83280B197A /* fil.lproj in Resources */ = {isa = PBXBuildFile; fileRef = 5C42087462E099CF003FF1BEB4B6887B /* fil.lproj */; }; + A1405701968D98550AE1AABA2D7C71EE /* STPIntentActionAlipayHandleRedirect.swift in Sources */ = {isa = PBXBuildFile; fileRef = E044A86F5B76D0CC71E8D21AD25EE7ED /* STPIntentActionAlipayHandleRedirect.swift */; }; + A143CCD69D6EDAA21A75419419C6E7BA /* STPCollectBankAccountParams.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4038C3A365C65E433FE06CA7BA58F8C6 /* STPCollectBankAccountParams.swift */; }; + A15039BAAE47A622E8858820EA914564 /* STDSACSNetworkingManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 91DFA9EF117D2E004A4AD9C412760A21 /* STDSACSNetworkingManager.m */; }; + A15D7631BE816A3C8C56E53467E91A71 /* STDSChallengeSelectionView.h in Headers */ = {isa = PBXBuildFile; fileRef = 805C254CE8924BAF69E8A22BD3CCAFE8 /* STDSChallengeSelectionView.h */; settings = {ATTRIBUTES = (Public, ); }; }; + A205FB74A458D7EF2BC5C2C84FE65838 /* UIColor+DefaultColors.h in Headers */ = {isa = PBXBuildFile; fileRef = 6EA8928C59E02CC416929F0C2B66219E /* UIColor+DefaultColors.h */; settings = {ATTRIBUTES = (Public, ); }; }; + A2AE35DB77B9FD7C658615A05AC9D656 /* hu.lproj in Resources */ = {isa = PBXBuildFile; fileRef = D135AA9F59ACEBBAA2F3EC49F9C3E0A3 /* hu.lproj */; }; + A301D5A026444BA650C75378075DD4D4 /* StripeCore-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = D7D297E8AF89CAB13A3EEF3EB6D03AF8 /* StripeCore-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; + A30CC64F714608ED2E7FDA3905650EBC /* STDSImageLoader.m in Sources */ = {isa = PBXBuildFile; fileRef = 8AF5878DD180D6DE5F240D5479A7FCA2 /* STDSImageLoader.m */; }; + A327A211C8B71069F32FAE5F5B3807C4 /* HooksPhase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2FD07CCB4F714C60AF38E78DCD9F5325 /* HooksPhase.swift */; }; + A357C8E38B58FA37B8E1A6103D4E9A0A /* XCTestSuite+QuickTestSuiteBuilder.m in Sources */ = {isa = PBXBuildFile; fileRef = D89BE132FD720081D0F88167D50A37E8 /* XCTestSuite+QuickTestSuiteBuilder.m */; }; + A3952D6DAFEAC7C15BE2D60A07F5271D /* STPPaymentMethodKlarna.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB9D19863D2E487C366ABCF51F30308E /* STPPaymentMethodKlarna.swift */; }; + A3F0A5092401EA532B629C29A2311221 /* cartes-bancaires-logo.png in Resources */ = {isa = PBXBuildFile; fileRef = CFE5B7DCFAC4F2FF0A54BA45B0867808 /* cartes-bancaires-logo.png */; }; + A41B07BCE4F45FE8DB112252BD27C421 /* STDSErrorMessage+Internal.h in Headers */ = {isa = PBXBuildFile; fileRef = 452B1991BCE20FF2407E6F731208FFC4 /* STDSErrorMessage+Internal.h */; settings = {ATTRIBUTES = (Public, ); }; }; + A444343B2E48AC45C14A8C5B03FA085C /* STPPaymentMethodCardWalletMasterpass.swift in Sources */ = {isa = PBXBuildFile; fileRef = 32957EEC2E5CF94B357FB4E9AEFED7AE /* STPPaymentMethodCardWalletMasterpass.swift */; }; + A487451E3CC40D7F9549FA292435273B /* NMBExceptionCapture.m in Sources */ = {isa = PBXBuildFile; fileRef = C07C5C6690E2AC1DD83FF370C67467F5 /* NMBExceptionCapture.m */; settings = {COMPILER_FLAGS = "-DPRODUCT_NAME=Nimble/Nimble"; }; }; + A526BF25FFFFB6334858A145A6C7C962 /* STPAppInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = 593760824E1E512A3DF423BF1EA3F721 /* STPAppInfo.swift */; }; + A55D9A85997D28048FC2BF4C27383AD0 /* UIFont+DefaultFonts.h in Headers */ = {isa = PBXBuildFile; fileRef = 2752FE03683F3943213462240A793E08 /* UIFont+DefaultFonts.h */; settings = {ATTRIBUTES = (Public, ); }; }; + A63CD62E00612420A54C2A3C6A93D2B4 /* STPMandateDataParams.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84C663C041851D0E52A3F9962E7E0680 /* STPMandateDataParams.swift */; }; + A6D732437D1B5AC19EA472053DA77406 /* STDSBundleLocator.m in Sources */ = {isa = PBXBuildFile; fileRef = 5AF1751BC3596620650014810E422E40 /* STDSBundleLocator.m */; }; + A6FC1D75F34E33A97477D57B42E30B0B /* es-419.lproj in Resources */ = {isa = PBXBuildFile; fileRef = 2C2BC81412FC00A087BEDBF7DA990E2E /* es-419.lproj */; }; + A7034C926019E17F75CB4C5750D85C9F /* ru.lproj in Resources */ = {isa = PBXBuildFile; fileRef = A78E2A3A2EEA2A59499A66C3FCE4C1D5 /* ru.lproj */; }; + A754A72DE53637838CB2E7EB58F0BCD0 /* pt-BR.lproj in Resources */ = {isa = PBXBuildFile; fileRef = F9BE4F925C2126024E5ED24836EC1B68 /* pt-BR.lproj */; }; + A7B615BDF8D23CE29724AF60B97487C4 /* fil.lproj in Resources */ = {isa = PBXBuildFile; fileRef = 14781C8F71AB8D62787DE872AF313BF9 /* fil.lproj */; }; + A88D40D4ECF8A6F10CD9E64FAB7026FD /* fr.lproj in Resources */ = {isa = PBXBuildFile; fileRef = DE972EEDE56DB2BB21B58F174BFC75BC /* fr.lproj */; }; + A89A88434BF91EB84BF5A6444D20D885 /* STDSException+Internal.h in Headers */ = {isa = PBXBuildFile; fileRef = 5499F2612A331A8CBD93E46EEE3D1650 /* STDSException+Internal.h */; settings = {ATTRIBUTES = (Public, ); }; }; + A9035C00334819B884C6118B74441324 /* error@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 0F7B4901ECF2394EA1A28EE677EBEC5B /* error@3x.png */; }; + A906986DAD73CA84C70468FDC570AD6E /* STDSCustomization.m in Sources */ = {isa = PBXBuildFile; fileRef = A5C9E850E8DF436D4C01C1C689FE056D /* STDSCustomization.m */; }; + A9449E624D1B2AF016E7EC10862E9206 /* el-GR.lproj in Resources */ = {isa = PBXBuildFile; fileRef = 78D87D1A31F44B74600128A212A1CC77 /* el-GR.lproj */; }; + A954FB0784E113D0045FDA314605C1A3 /* InstallMethod.swift in Sources */ = {isa = PBXBuildFile; fileRef = C79BA5E40AC06C45B5EF8414419C0917 /* InstallMethod.swift */; }; + A99540F8CA5C86EEFCD83B3920B7513B /* STPMandateOnlineParams.swift in Sources */ = {isa = PBXBuildFile; fileRef = FB754D638D39BFC7C92A1158FB7251A8 /* STPMandateOnlineParams.swift */; }; + A9BE66263854CD548F0F1CE1A2981401 /* STPPaymentMethodOXXO.swift in Sources */ = {isa = PBXBuildFile; fileRef = DF29F7FAD43EBFA1799F81703A83964A /* STPPaymentMethodOXXO.swift */; }; + A9F90B2B49B039CD613000446CDFB997 /* APIRequest.swift in Sources */ = {isa = PBXBuildFile; fileRef = F282D0C496A4893A54A4A75061578B55 /* APIRequest.swift */; }; + AA552F64F531BD2985BCE9A1298EA5C1 /* nl.lproj in Resources */ = {isa = PBXBuildFile; fileRef = 6A7BB7F3F161A2073468BD2DCAEC6BD0 /* nl.lproj */; }; + AB35EA65C4BE948084F895EDB2FA877A /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 54808C6C88411583D225CB43662CF2A8 /* Foundation.framework */; }; + AB57F2477838A78D65DE25E54D32AD8A /* STPFormEncoder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 10F5694961D0A23DC214C7A1A614F78C /* STPFormEncoder.swift */; }; + ABF8F12C002342A625D2636210931B9A /* id.lproj in Resources */ = {isa = PBXBuildFile; fileRef = 16422242E406E9916B4C7ABBF6B3D1F2 /* id.lproj */; }; + AC0278DBE6921D2AA8CA82CBE8805202 /* AssertionDispatcher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7F2F8FF75072186C7D2D029B07EA0611 /* AssertionDispatcher.swift */; settings = {COMPILER_FLAGS = "-DPRODUCT_NAME=Nimble/Nimble"; }; }; + AC1B0A94D98FF6A485E56165BDAAFB8F /* BeAKindOf.swift in Sources */ = {isa = PBXBuildFile; fileRef = 79E1FC49BF933FE84A26E535CC4BB4AB /* BeAKindOf.swift */; settings = {COMPILER_FLAGS = "-DPRODUCT_NAME=Nimble/Nimble"; }; }; + ACAA345A1CCAFA1F4EE69B3C25D62558 /* Contain.swift in Sources */ = {isa = PBXBuildFile; fileRef = C6E5AC63C1529E4A54A48C82D9EC1ACE /* Contain.swift */; settings = {COMPILER_FLAGS = "-DPRODUCT_NAME=Nimble/Nimble"; }; }; + AD022386EA01CE480072E4C2E261BEC6 /* QuickTestObservation.swift in Sources */ = {isa = PBXBuildFile; fileRef = A26890A9CFDDF7189B2CE5DC665EA8BF /* QuickTestObservation.swift */; }; + AD215F47C733E652403AD91D2B7A26A7 /* de.lproj in Resources */ = {isa = PBXBuildFile; fileRef = ED73A19BD46774DD49D17137BC67F355 /* de.lproj */; }; + AD2F457DEF141A302A9A79AB05AB16AA /* STPiDEALBank.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC0B26FD827064802B685FBCE24C821B /* STPiDEALBank.swift */; }; + AD8EC799CFB40D2FB6CA85B503FB2BC4 /* STPInternalAPIResponseDecodable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65E460ED1ED288806FF0433F7C9E2668 /* STPInternalAPIResponseDecodable.swift */; }; + ADC39A904798DB8EE8BB2803659C267E /* STDSChallengeResponseMessageExtension.h in Headers */ = {isa = PBXBuildFile; fileRef = 074B03C63A23CC48E3CDCE64FC0A0961 /* STDSChallengeResponseMessageExtension.h */; settings = {ATTRIBUTES = (Public, ); }; }; + ADEEFA7488335E095B7AC23A2AA125A4 /* STDSDeviceInformationManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 32ECC3CE517D8C826EE3DCA91B7FDE06 /* STDSDeviceInformationManager.h */; settings = {ATTRIBUTES = (Public, ); }; }; + AECED31273935A17176765887892086E /* STPThreeDSSelectionCustomization.swift in Sources */ = {isa = PBXBuildFile; fileRef = 369928B93AB7FF9854E9571FD5DC9C88 /* STPThreeDSSelectionCustomization.swift */; }; + AF640BE386F54CE7054B45AB204FAFA4 /* StripeJSONDecoder.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5E32D92D737D28D83830126853FD3F9 /* StripeJSONDecoder.swift */; }; + AF8161AB17115AFDFFD6796352DC53BD /* STDSChallengeResponseMessageExtensionObject.m in Sources */ = {isa = PBXBuildFile; fileRef = A6F84397851ADA6444109BC69845EF86 /* STDSChallengeResponseMessageExtensionObject.m */; }; + AFB4F603FD0F5C407CB8920F6A5BA7A1 /* Expectation.swift in Sources */ = {isa = PBXBuildFile; fileRef = CDB4F75A5F4E5F3AB41B5D7B97F1A07A /* Expectation.swift */; settings = {COMPILER_FLAGS = "-DPRODUCT_NAME=Nimble/Nimble"; }; }; + AFC8CE1D64DE93F786E6634FD4B03D05 /* UIColor+ThirteenSupport.m in Sources */ = {isa = PBXBuildFile; fileRef = 7F6BD33A351A88259F6CA8F0B2C37C1C /* UIColor+ThirteenSupport.m */; }; + B0BFDA4F4358AD77627C92A7D25339D1 /* STDSJSONWebSignature.h in Headers */ = {isa = PBXBuildFile; fileRef = 0C14FCFB236C6FBB02FE6B9570F40375 /* STDSJSONWebSignature.h */; settings = {ATTRIBUTES = (Public, ); }; }; + B0C91F3BCFD6E2BC046E6CD5F2CEEC59 /* STDSErrorMessage.h in Headers */ = {isa = PBXBuildFile; fileRef = 283BAC5B7B76CCC28073F1261D92D3AE /* STDSErrorMessage.h */; settings = {ATTRIBUTES = (Public, ); }; }; + B0D2D958950AEFF2B724214136060AAA /* UIButton+CustomInitialization.m in Sources */ = {isa = PBXBuildFile; fileRef = 783EDB1FA1DD3BD623BEE6D52F603C55 /* UIButton+CustomInitialization.m */; }; + B18F546087EFBA93051B51DA734ED94A /* STDSChallengeRequestParameters.m in Sources */ = {isa = PBXBuildFile; fileRef = EEB076019C56A1D7098BD542F6BC618A /* STDSChallengeRequestParameters.m */; }; + B1EDABE49814752F1E5C2393F1B048D4 /* STDSIPAddress.h in Headers */ = {isa = PBXBuildFile; fileRef = 93F9CD920768D4661AF7CAC83BCC332D /* STDSIPAddress.h */; settings = {ATTRIBUTES = (Public, ); }; }; + B240E608E7925F75D9683D1C6E37DE25 /* StripeCodable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9ABEE426924F217CD7D941091A32F74C /* StripeCodable.swift */; }; + B297557B0B2E4FE69B4C5C0C24EAE44D /* STPConnectAccountParams.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7418FE280E333B264F556BA11328D50C /* STPConnectAccountParams.swift */; }; + B2D61DB92FE0E7E6C31D5CF100BEDC35 /* STPConfirmBLIKOptions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 732D15F8A6E845C2B923303FDF38F371 /* STPConfirmBLIKOptions.swift */; }; + B326BB53636511ADC5FE8F033DBB9F0A /* STPPaymentMethodCardParams.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4A4FC791246944C8E6B8796F90D27EAA /* STPPaymentMethodCardParams.swift */; }; + B3D92FD56F0312C2C4D8378D3EC1A569 /* STPAPIClient+FileUpload.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9905384221E499294976CE602E966FE /* STPAPIClient+FileUpload.swift */; }; + B416B20D9539AEA84634293F91CB17B3 /* STDSThreeDS2Service.h in Headers */ = {isa = PBXBuildFile; fileRef = 209BEBD40F07D43B691D3367032EBFE9 /* STDSThreeDS2Service.h */; settings = {ATTRIBUTES = (Public, ); }; }; + B4C1BC80DDC77193B28E7DD238A56890 /* hr.lproj in Resources */ = {isa = PBXBuildFile; fileRef = F21284806288A28295379C4A74411E98 /* hr.lproj */; }; + B4C44869352814DA8337C89C7A7166BD /* STDSChallengeResponseObject.m in Sources */ = {isa = PBXBuildFile; fileRef = 323FD70DD57060BAABCE7C747761D4FC /* STDSChallengeResponseObject.m */; }; + B59A8E201C9C3550E0F050D380AD1424 /* zh-Hans.lproj in Resources */ = {isa = PBXBuildFile; fileRef = 6597BB764328DA90E4C2A7D1E4BB6770 /* zh-Hans.lproj */; }; + B5BF5A7002ADBDEEAF26577FA17600D7 /* STDSSwiftTryCatch.h in Headers */ = {isa = PBXBuildFile; fileRef = 1E48F583C322F895591736E2EE3A9D74 /* STDSSwiftTryCatch.h */; settings = {ATTRIBUTES = (Public, ); }; }; + B6AE95E672AB980022B11556E0616692 /* zh-HK.lproj in Resources */ = {isa = PBXBuildFile; fileRef = 74ABAF9B171607E4E180F645D439201F /* zh-HK.lproj */; }; + B75BD3264536F3F693C750CBDE85B7A3 /* NSURLComponents+Stripe.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1471C5F4F2DB4EC1A62556579203ECDF /* NSURLComponents+Stripe.swift */; }; + B763A05CBA9CC9C4FA2FCCBEA6597E59 /* STDSSwiftTryCatch.m in Sources */ = {isa = PBXBuildFile; fileRef = C3C4694ED35A2FB67C72EB52A482243E /* STDSSwiftTryCatch.m */; }; + B85376FE31501B1B372392E3E21EBBF8 /* sl-SI.lproj in Resources */ = {isa = PBXBuildFile; fileRef = 2F29A2AB516AC599B61B93625C2891CD /* sl-SI.lproj */; }; + B882EE8FC10811B47CB327B7306806FD /* STPPaymentMethodEPS.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0F19639C8AA2CFD45C27C253BFFFAB84 /* STPPaymentMethodEPS.swift */; }; + B88FF8B2A1AD4F1A2370F4F1DF1615B9 /* bg-BG.lproj in Resources */ = {isa = PBXBuildFile; fileRef = F075F62EAFD0DF773E2CC1CE3BDF89EC /* bg-BG.lproj */; }; + B89547FFB315DF9BF545FE6F05FAC318 /* NSMutableURLRequest+Stripe.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4450AF2E54ADCF5F7D4B4EAE994D4408 /* NSMutableURLRequest+Stripe.swift */; }; + B8FEB80298F5E1C9A775F91B849541A4 /* StripePaymentsBundleLocator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A80A07639D6D832E3EC175E25BF7512 /* StripePaymentsBundleLocator.swift */; }; + B908232EBF7A2E6C535643EC5905480F /* StripePayments-StripePayments in Resources */ = {isa = PBXBuildFile; fileRef = 7075296E1C69930CC25D5670AC153811 /* StripePayments-StripePayments */; }; + B90DD32BE559DEE5853D2A69BEA80E3E /* mt.lproj in Resources */ = {isa = PBXBuildFile; fileRef = 1173EF3FFD767E414B6BFF00F321EF51 /* mt.lproj */; }; + B91A10553AF6ECD63BD02C7EF2B37FBD /* STPPaymentMethodSEPADebit.swift in Sources */ = {isa = PBXBuildFile; fileRef = 47AEC729BAF456DCA88A96334C835B27 /* STPPaymentMethodSEPADebit.swift */; }; + B93F3526A95D7F43EEBFEE5E453E4795 /* BeLessThan.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE68A66EA53204671ED691B4B84F841B /* BeLessThan.swift */; settings = {COMPILER_FLAGS = "-DPRODUCT_NAME=Nimble/Nimble"; }; }; + B9C349292765A0B0BFFAC28F2B27CC06 /* FraudDetectionData.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2C4FA16F4BF9CEC2DB082BAE796A21D0 /* FraudDetectionData.swift */; }; + BA127569977F8388BECB28BF9C38726E /* STPPaymentMethodBillingDetails.swift in Sources */ = {isa = PBXBuildFile; fileRef = E5B4C41EAF053078107667B95E340FE0 /* STPPaymentMethodBillingDetails.swift */; }; + BB55D5AA35356053CF6AB4CE94CA2B19 /* ja.lproj in Resources */ = {isa = PBXBuildFile; fileRef = 25A82BF67AEC9AC12EB651EDCFF7E284 /* ja.lproj */; }; + BBA8852D7073427D093AB72835D16C5F /* STPFile.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF82D2157807DE33D94019BE4F7F25BB /* STPFile.swift */; }; + BBD30C63ACD76A06653AAE5FBEC84470 /* STPBINController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 653C3FC026CBEB87F5C175C0FF6DC590 /* STPBINController.swift */; }; + BC75CFAB6CBFD26852CEF5D1DD710C9D /* STDSCompletionEvent.m in Sources */ = {isa = PBXBuildFile; fileRef = 625A9EBBEE9AE746354C27F9C844BDEB /* STDSCompletionEvent.m */; }; + BCE527DFFA322814185EBA4AE857864D /* STPPaymentMethodFPXParams.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6262A066A13C02F353896BCF68C284A /* STPPaymentMethodFPXParams.swift */; }; + BD3ABAC28025564DCF2E6C12009435DF /* CwlMachBadInstructionHandler.m in Sources */ = {isa = PBXBuildFile; fileRef = F24911076BD4D74BCE431B06818180B7 /* CwlMachBadInstructionHandler.m */; settings = {COMPILER_FLAGS = "-DPRODUCT_NAME=Nimble/Nimble"; }; }; + BD9C99CC3A6CBF04ECB8DAE5607B6CAA /* STDSChallengeResponse.h in Headers */ = {isa = PBXBuildFile; fileRef = DA6928017B2DBCEEBFE222E5C709A8E8 /* STDSChallengeResponse.h */; settings = {ATTRIBUTES = (Public, ); }; }; + BDC0307F8EA99C164C2003448066D80D /* STPConnectAccountAddress.swift in Sources */ = {isa = PBXBuildFile; fileRef = 44883319135827CA66740EFB62CC7429 /* STPConnectAccountAddress.swift */; }; + BE46405A1882A37F58962135FD074051 /* AnalyticLoggableError.swift in Sources */ = {isa = PBXBuildFile; fileRef = 86358511999BB628CF6F6E581FEB6FC8 /* AnalyticLoggableError.swift */; }; + BE4B1DCCA7FC5F624B704C3F36D71859 /* en-GB.lproj in Resources */ = {isa = PBXBuildFile; fileRef = B4F95FCE335B3F2CBF76F9ECA710D401 /* en-GB.lproj */; }; + BE797FA3DB0FD410B4F4AC3CF1459578 /* Pods-OSPaymentsLib-OSPaymentsLibTests-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = B1D21BE1B5A742AA9C8EEE801D57559C /* Pods-OSPaymentsLib-OSPaymentsLibTests-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; + BEBE95E223F6FADA0BF5ADA6DD9E4904 /* it.lproj in Resources */ = {isa = PBXBuildFile; fileRef = A734158ECFECA6B3FFEEB71D1B6878B6 /* it.lproj */; }; + BF62525E5628A9F7604BA8479691318C /* BeLogical.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A00905E5C9C768C295FAD0A776669AF /* BeLogical.swift */; settings = {COMPILER_FLAGS = "-DPRODUCT_NAME=Nimble/Nimble"; }; }; + C03116C765F1A8893559730965ECBAD8 /* Nimble-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = BCBD480A050003A3E0412BB33C4865DB /* Nimble-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; + C04F103AAC2160C18C927BFEA3EADDBE /* Stripe3DS2-Bridging-Header.h in Headers */ = {isa = PBXBuildFile; fileRef = C8B3102EC25FBA1A55C5DB8BAAF29A2C /* Stripe3DS2-Bridging-Header.h */; settings = {ATTRIBUTES = (Public, ); }; }; + C0E178382444DF51B9696CE45E74E6DD /* STDSErrorMessage.m in Sources */ = {isa = PBXBuildFile; fileRef = DAC85F5C5D2FD0C0550FF6374EA62CB0 /* STDSErrorMessage.m */; }; + C0E877BCBEF75E2C0DCFA592657CDFB2 /* STPPaymentMethodAffirmParams.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EDEEB7D3BB88F3F2BFD62FC58BADE58 /* STPPaymentMethodAffirmParams.swift */; }; + C0EDACD1500DBD395ED24F2900E0057C /* STPPaymentMethodKlarnaParams.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8D614D6133986855F759C86B1E3D6B40 /* STPPaymentMethodKlarnaParams.swift */; }; + C118224691757BDA3D94EAA53F0D92E1 /* STDSJSONWebEncryption.h in Headers */ = {isa = PBXBuildFile; fileRef = CAFC1ED8731AE396871EED7AC1178787 /* STDSJSONWebEncryption.h */; settings = {ATTRIBUTES = (Public, ); }; }; + C1FEC4072C1F9E1A5C2E67851D8D26AE /* STDSSecTypeUtilities.h in Headers */ = {isa = PBXBuildFile; fileRef = A16E4D52A285D227F5E248CE6098E96C /* STDSSecTypeUtilities.h */; settings = {ATTRIBUTES = (Public, ); }; }; + C20BFECB0A04FE439AE243D89E687B8A /* QuickTestSuite.swift in Sources */ = {isa = PBXBuildFile; fileRef = A48790581DE4CFC1D56F5741E2DE130D /* QuickTestSuite.swift */; }; + C24AF5E9EA09FF9B44C92098D6148080 /* STDSDeviceInformation.m in Sources */ = {isa = PBXBuildFile; fileRef = 48669968B1C33265AE0FF8820DFBB191 /* STDSDeviceInformation.m */; }; + C278A4AD9EE53032938EC5E888B275D4 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 54808C6C88411583D225CB43662CF2A8 /* Foundation.framework */; }; + C28B853DA06EF4CDE74A1EF53365A9C1 /* bg-BG.lproj in Resources */ = {isa = PBXBuildFile; fileRef = 077F00A2042A3D0C16E7463BC7B8B151 /* bg-BG.lproj */; }; + C2DA20FE02661C3C2F0618A1DC6D5747 /* STPSourceOwner.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5E6FE7DE869B97FD231A9E841B9A515D /* STPSourceOwner.swift */; }; + C3A6DE0F702DB704D784215DB02E7935 /* STPCardParams.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7E54011CA9597F3B2EC897FD70C4154A /* STPCardParams.swift */; }; + C47E9BA563D040E1C2CE668F81114D98 /* STDSACSNetworkingManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 8B6C3FC697FDB37AD5502F3EA544A6F5 /* STDSACSNetworkingManager.h */; settings = {ATTRIBUTES = (Public, ); }; }; + C4F7B99D93E88831666F3E45E4382E17 /* STPPaymentIntentShippingDetails.swift in Sources */ = {isa = PBXBuildFile; fileRef = 359723CC69A4D0C4E23A59FAA28256D6 /* STPPaymentIntentShippingDetails.swift */; }; + C53F44D60F5541B8B3086F9624325CBF /* da.lproj in Resources */ = {isa = PBXBuildFile; fileRef = 04615DC24469B5770473F2C49A13B548 /* da.lproj */; }; + C5DF891232B50DB810099403734CFCEE /* Match.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C62A366D5C5C58C42440DD1C7ADFC27 /* Match.swift */; settings = {COMPILER_FLAGS = "-DPRODUCT_NAME=Nimble/Nimble"; }; }; + C622FD41098A46A8E83980ADA4D4482E /* STDSChallengeResponseImage.h in Headers */ = {isa = PBXBuildFile; fileRef = C8B805FE5905C4F7297F23560E57E991 /* STDSChallengeResponseImage.h */; settings = {ATTRIBUTES = (Public, ); }; }; + C636A8EF0AC9FEE39106FFF2F006AF18 /* STDSStackView.m in Sources */ = {isa = PBXBuildFile; fileRef = 7BD789ACD33E73CFC7D374760BBCFC07 /* STDSStackView.m */; }; + C797E150685C683707E98EE909FF8DE3 /* STDSDeviceInformation.h in Headers */ = {isa = PBXBuildFile; fileRef = 3528BD4868D8574FF2FB171DA2BFBB5F /* STDSDeviceInformation.h */; settings = {ATTRIBUTES = (Public, ); }; }; + C7BDDB5048ECC555122DFA4B010FEC03 /* lt-LT.lproj in Resources */ = {isa = PBXBuildFile; fileRef = 0979BD7CBA1EABD3257C88B143EA3662 /* lt-LT.lproj */; }; + C7DB9FB7C8378ADC0DBC744F9359C0C9 /* BeIdenticalTo.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5FC2114F70469E415B7E2747DA3C7FBE /* BeIdenticalTo.swift */; settings = {COMPILER_FLAGS = "-DPRODUCT_NAME=Nimble/Nimble"; }; }; + C81B728031ECD7D8D50D727C3ABC58A2 /* it.lproj in Resources */ = {isa = PBXBuildFile; fileRef = D88CFDC73FC1FECF945F9EDC369396EE /* it.lproj */; }; + C8539F1BDF052B57BDB129D3D4B07364 /* Callsite.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5627B275B74FFF496E93813F7C13671 /* Callsite.swift */; }; + C85E1092F4DAACDD63FB8E8B0E144095 /* ExampleMetadata.swift in Sources */ = {isa = PBXBuildFile; fileRef = E35BA28DBB2CD8D04D3F6BAA73B05FD4 /* ExampleMetadata.swift */; }; + C8A21D7E0B92BFDAFA538BDDEB18C988 /* ms-MY.lproj in Resources */ = {isa = PBXBuildFile; fileRef = 10BC07CCB954D3F5A862B45897BCB5D5 /* ms-MY.lproj */; }; + C8FC20A9010A3B8F8FCFD179672ADBDB /* STPPaymentMethodBLIKParams.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5DE351F6BD87FDFAA928A765F4FD42B1 /* STPPaymentMethodBLIKParams.swift */; }; + C905EED2D503527500BFA2498A3F8EFC /* STPAPIResponseDecodable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 736B04281FE4BF884DED17087BC29FC8 /* STPAPIResponseDecodable.swift */; }; + C96B370E9B3442878448F8FFFDC98C7A /* Quick-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 8E179A72B1C159351C885B5156C71821 /* Quick-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; + C97A0E8F9E4096CC06430599E5F4DDE6 /* STPPaymentMethodCardNetworks.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46AE2E6FEA38E6A3B1ADF0A2A083411B /* STPPaymentMethodCardNetworks.swift */; }; + CA32F74C00C2448397720AB161360835 /* CwlDarwinDefinitions.swift in Sources */ = {isa = PBXBuildFile; fileRef = AD40E689D860042DA81285ACF0F6227D /* CwlDarwinDefinitions.swift */; settings = {COMPILER_FLAGS = "-DPRODUCT_NAME=Nimble/Nimble"; }; }; + CA3733029ABB9CDAA6D15D9491960C0E /* STPIntentActionUseStripeSDK.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0CA0604F6FBB9845BBFAAE7E13BD30AE /* STPIntentActionUseStripeSDK.swift */; }; + CA404759B9875B2BE03D9C4AA8B4E437 /* STDSInvalidInputException.m in Sources */ = {isa = PBXBuildFile; fileRef = 32A3DBB4286DB994E453A3241DC20834 /* STDSInvalidInputException.m */; }; + CBC91EBA9C4224D40AB9CD160F17DA50 /* STDSSynchronousLocationManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 56A8426512B05F3F66165BE187E7DBC3 /* STDSSynchronousLocationManager.m */; }; + CBDC558A7446BBA963C4AFD2B3A98415 /* sk-SK.lproj in Resources */ = {isa = PBXBuildFile; fileRef = 8E35F29B901662782AC73037AD726186 /* sk-SK.lproj */; }; + CC7810AB588F9A7F964FCF935C8CF80A /* STDSProtocolErrorEvent.m in Sources */ = {isa = PBXBuildFile; fileRef = FFB85B4D6964DB341F8D02835F8235FC /* STDSProtocolErrorEvent.m */; }; + CC895153274C7B49225680E843F561F1 /* zh-Hant.lproj in Resources */ = {isa = PBXBuildFile; fileRef = 3308E5D86C160F2C68B5CB75982EE128 /* zh-Hant.lproj */; }; + CCE1D380F09F27172FCB9ED3EA3D4410 /* STDSThreeDS2Service.m in Sources */ = {isa = PBXBuildFile; fileRef = 56A4C47B9C636C2E9C2169375FE3B87C /* STDSThreeDS2Service.m */; }; + CD567C85C1A55D92CB35E5D839BBC64D /* en.lproj in Resources */ = {isa = PBXBuildFile; fileRef = 82DEB14A320561F457E94CF0C65223E3 /* en.lproj */; }; + CDF5199EB1AACF73405B61319BCAA020 /* zh-HK.lproj in Resources */ = {isa = PBXBuildFile; fileRef = F97ABCC6B07DAA7FE3F8E197174A9FCB /* zh-HK.lproj */; }; + CE0FCF009CA4E5CADEDA7094B4E05C64 /* STDSLabelCustomization.h in Headers */ = {isa = PBXBuildFile; fileRef = 568118646C2B9E717286C4651734B8D0 /* STDSLabelCustomization.h */; settings = {ATTRIBUTES = (Public, ); }; }; + CE1D75F182433E6B46D9B56ABBE44DFC /* STDSJSONEncodable.h in Headers */ = {isa = PBXBuildFile; fileRef = A31ED8DAEC3BB7239795D73A0C3F3410 /* STDSJSONEncodable.h */; settings = {ATTRIBUTES = (Public, ); }; }; + CE862C94D35AE367736B8FB2A9347A82 /* STDSStripe3DS2Error.m in Sources */ = {isa = PBXBuildFile; fileRef = 8ABE8C85E8FC12796B17E780CB924846 /* STDSStripe3DS2Error.m */; }; + CEE36195D9150CFEC723D583D778A696 /* STPDispatchFunctions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 621387BC9C0ACA90CA0242F6AB9CD213 /* STPDispatchFunctions.swift */; }; + D0112C3A544DDEC8444C0DC31509E612 /* STPPaymentMethodBancontact.swift in Sources */ = {isa = PBXBuildFile; fileRef = F5315E06282EF5E942C54E96A82A704D /* STPPaymentMethodBancontact.swift */; }; + D14FCDBE8AC0C7269A27CDD5B0BE6F7C /* STPPaymentIntentSourceAction.swift in Sources */ = {isa = PBXBuildFile; fileRef = 048BC82B48E322C6ACF6435AD7C34B1A /* STPPaymentIntentSourceAction.swift */; }; + D1E2A5D51A4EA4D31178E84C8499BCAC /* STDSAuthenticationResponseObject.h in Headers */ = {isa = PBXBuildFile; fileRef = 59AA7F922673B41C277C2A84071B636A /* STDSAuthenticationResponseObject.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D2CC96FAE3E510427A4C5E6FF4891B6D /* nn-NO.lproj in Resources */ = {isa = PBXBuildFile; fileRef = FC9481A825A1D89C96258C591C7F867E /* nn-NO.lproj */; }; + D472EE65DAFF3D8DBEE79615C285702A /* STPPaymentMethod.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2FA35511EB0E5A29FA8FB39FE2925A93 /* STPPaymentMethod.swift */; }; + D5032B4738066A0A6AD516D19FEC65A9 /* UserDefaults+PaymentsCore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 562E27F799AF54E6BE1994FF9A310A7D /* UserDefaults+PaymentsCore.swift */; }; + D58AEEA957DC16D02B948DE5F865C58D /* DownloadManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = C78FCAE555CA78A6DDFA24CD5C597CF1 /* DownloadManager.swift */; }; + D6D5F283E6742594C6A16FDCE7BF780E /* STPPaymentMethodAfterpayClearpayParams.swift in Sources */ = {isa = PBXBuildFile; fileRef = AEE4FC3E871FBBBAF4AC3655CD0F588C /* STPPaymentMethodAfterpayClearpayParams.swift */; }; + D6F1A9AFE522D73CB8BDF851FF6F7ACC /* BeEmpty.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7DDE21D10B22192C6F8A47342258379D /* BeEmpty.swift */; settings = {COMPILER_FLAGS = "-DPRODUCT_NAME=Nimble/Nimble"; }; }; + D8B8FCEC597824B40986C8F4F7B50899 /* QuickSpec.h in Headers */ = {isa = PBXBuildFile; fileRef = 4C94DA0E96F62A89B36D4FAD754C1ED2 /* QuickSpec.h */; settings = {ATTRIBUTES = (Public, ); }; }; + DA9B61878019B5428B614BDDB5948F01 /* QCKDSL.m in Sources */ = {isa = PBXBuildFile; fileRef = DD9F4B778364E59D43A2F69D2E1CD0F8 /* QCKDSL.m */; }; + DAD09BEF8013B22616C54034D030B98E /* ko.lproj in Resources */ = {isa = PBXBuildFile; fileRef = B2040FE1DE10144DDAC53FBCAA512977 /* ko.lproj */; }; + DB12233C2655B3393E0EC0E7CAFF128D /* fi.lproj in Resources */ = {isa = PBXBuildFile; fileRef = 766E347A52AD98B99EEC6F90A69D9F54 /* fi.lproj */; }; + DB59D6DAD3E296B5402FA766AE955D78 /* STPPaymentMethodAffirm.swift in Sources */ = {isa = PBXBuildFile; fileRef = 70005C4375CBFB421E6FE86867C46D67 /* STPPaymentMethodAffirm.swift */; }; + DC7110DA54AA19B666FCE7F2249FA0C7 /* ca-ES.lproj in Resources */ = {isa = PBXBuildFile; fileRef = 8B55E4AA17C775811EA3FE66C8DDFDEE /* ca-ES.lproj */; }; + DC79ABFC1AB8BD9DB160295D040A7D13 /* STDSDirectoryServerCertificate.h in Headers */ = {isa = PBXBuildFile; fileRef = F738DCB87C2986498EE21E79173A6641 /* STDSDirectoryServerCertificate.h */; settings = {ATTRIBUTES = (Public, ); }; }; + DCB4550C44D006E726B15F22ADDECA5E /* STPSourceEnums.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0FC4784F6CFE516E67A500EA1188794A /* STPSourceEnums.swift */; }; + DCB81595A72B448DEC48A1ABF8434467 /* STPAddress.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7C1EF27595C3111FA09D7019FF5E3331 /* STPAddress.swift */; }; + DD130331C3820B0A4A655D6422167410 /* CwlCatchBadInstruction.swift in Sources */ = {isa = PBXBuildFile; fileRef = 557D02A61618BFDAD32138A9A64EF81B /* CwlCatchBadInstruction.swift */; settings = {COMPILER_FLAGS = "-DPRODUCT_NAME=Nimble/Nimble"; }; }; + DD177FA0C27AD81516C71CC2787D30FA /* STDSSimulatorChecker.m in Sources */ = {isa = PBXBuildFile; fileRef = A49EF7069046091B2BC0FCD9960DE8E2 /* STDSSimulatorChecker.m */; }; + DD1D5D891590FF5F3FB499012B9230CE /* sv.lproj in Resources */ = {isa = PBXBuildFile; fileRef = 4BC54E260BB8693DC327C31BEF4E1C23 /* sv.lproj */; }; + DE0B04BE2053CFC47AC3E280F8953189 /* STDSWhitelistView.h in Headers */ = {isa = PBXBuildFile; fileRef = 80FEF0315875F9EF508E8000273D5416 /* STDSWhitelistView.h */; settings = {ATTRIBUTES = (Public, ); }; }; + DE787BA1CB2B14BF3530834D3FEB3587 /* STPBlocks.swift in Sources */ = {isa = PBXBuildFile; fileRef = E012D904769549BAD68BD90860FFD7ED /* STPBlocks.swift */; }; + DF3423EFFE0F8E644904AA626D94BCE1 /* LinkSettings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 73E701E7BEF084798AF74C32917833B6 /* LinkSettings.swift */; }; + DF93796EC89300DFFDC43481ACD86DAB /* STDSAlreadyInitializedException.h in Headers */ = {isa = PBXBuildFile; fileRef = AE8B63D8981954A332F273D3B86E994A /* STDSAlreadyInitializedException.h */; settings = {ATTRIBUTES = (Public, ); }; }; + DFF4407A62E016DA4186B46582434083 /* el-GR.lproj in Resources */ = {isa = PBXBuildFile; fileRef = 06C5071A5E1022BA2DBD0DB4A27556DC /* el-GR.lproj */; }; + E00460E232D3F411D6D967B1B051A2C7 /* STDSRuntimeException.m in Sources */ = {isa = PBXBuildFile; fileRef = 923E91BF764190E7B3C0E6AE6768FC1C /* STDSRuntimeException.m */; }; + E03256423466AABA2091A532973025CF /* STPPaymentMethodCard.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEF2DCC073BD22139B9B841E3B5E517F /* STPPaymentMethodCard.swift */; }; + E0741AB67101A14ABD4FC5752AB3167D /* es.lproj in Resources */ = {isa = PBXBuildFile; fileRef = 95C7D0C979B1F9BBCC5E6F1EBD2248EC /* es.lproj */; }; + E0F1C36FC91D9D785AAA2C88A633D11D /* STPToken.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5FE6F6AD5F607A825507562A6AF83790 /* STPToken.swift */; }; + E1CD0FEF6BA86FA9C28038C818E2514A /* Quick.h in Headers */ = {isa = PBXBuildFile; fileRef = 9D766D6524D7B25D8DF641AE8471D814 /* Quick.h */; settings = {ATTRIBUTES = (Public, ); }; }; + E233D638FA3C0E2828B401C15C9CF98C /* STDSSelectionCustomization.h in Headers */ = {isa = PBXBuildFile; fileRef = D5BADA779B0940EAFCAF5D5C3BC5369F /* STDSSelectionCustomization.h */; settings = {ATTRIBUTES = (Public, ); }; }; + E25D73EA8581356D83D11497A801886D /* STPPaymentIntent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 824BDCE6763B4D03610E74DBC30F4903 /* STPPaymentIntent.swift */; }; + E2E452130207949BA34D6B95B7C4C244 /* lv-LV.lproj in Resources */ = {isa = PBXBuildFile; fileRef = 1D9076470098A7FB4C8DDE1DA51FF76C /* lv-LV.lproj */; }; + E2EE2E7797C383576ACBFE4986179459 /* CwlMachBadInstructionHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = DCF62E2DEF4B16FD0F3F995885183C25 /* CwlMachBadInstructionHandler.h */; settings = {ATTRIBUTES = (Public, ); }; }; + E35A75132E7E20A3874A772EFB39E733 /* BundleLocatorProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = D622546EB394438799B3469E08261DD5 /* BundleLocatorProtocol.swift */; }; + E3C7EDC30EAEEB1A6A662DC35B52EDCC /* STPSetupIntentLastSetupError.swift in Sources */ = {isa = PBXBuildFile; fileRef = 498401C6C3549CA6217606C586D593A2 /* STPSetupIntentLastSetupError.swift */; }; + E403B4D4D59CB0D45FB06C5225ADBED8 /* STPPaymentMethodPrzelewy24Params.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7E874403635CC972DD772EC44534DEBB /* STPPaymentMethodPrzelewy24Params.swift */; }; + E418BAB165A0757D815A2624201A521A /* lt-LT.lproj in Resources */ = {isa = PBXBuildFile; fileRef = 85C1E1D0B96FA2F2ADFCAFF86417BBFC /* lt-LT.lproj */; }; + E49316FF97A8E6748E5105B59ECBB00C /* STPPaymentMethodListDeserializer.swift in Sources */ = {isa = PBXBuildFile; fileRef = FB2AC83D43791CFB270543967C85714F /* STPPaymentMethodListDeserializer.swift */; }; + E49952725B0F5A5E7B4A8FD69E08A71D /* pt-BR.lproj in Resources */ = {isa = PBXBuildFile; fileRef = A023D6FAA60988D3CC883EF0A365BEAB /* pt-BR.lproj */; }; + E4C78DA9C4632D8B2C7BB20E6FF0788C /* sv.lproj in Resources */ = {isa = PBXBuildFile; fileRef = 47F9BE5443E9C7DAEC42690265EC06C7 /* sv.lproj */; }; + E5ACC239A1C2E515D4939ACECD147445 /* ThrowAssertion.swift in Sources */ = {isa = PBXBuildFile; fileRef = 236B5B45A473096741E6490A0EB83CFF /* ThrowAssertion.swift */; settings = {COMPILER_FLAGS = "-DPRODUCT_NAME=Nimble/Nimble"; }; }; + E672A74FFB76325B9FF8EC924E71B884 /* STPPaymentMethodUSBankAccountParams.swift in Sources */ = {isa = PBXBuildFile; fileRef = D91D402F64E85A15A9B3AFEA817B8FB2 /* STPPaymentMethodUSBankAccountParams.swift */; }; + E68FB42E04EBC6218F0B030459CB6EC4 /* NSLayoutConstraint+LayoutSupport.m in Sources */ = {isa = PBXBuildFile; fileRef = 8BF23145463B6051BC797942E38BA490 /* NSLayoutConstraint+LayoutSupport.m */; }; + E6FE8A90539AA4A3805B0A626DA4C7F9 /* STPPaymentMethodCardWalletVisaCheckout.swift in Sources */ = {isa = PBXBuildFile; fileRef = 57FE59621959B645AB0D91EE111D73C8 /* STPPaymentMethodCardWalletVisaCheckout.swift */; }; + E70E2B3A9C7D9F54A5039269B3B28465 /* STPCardValidator.swift in Sources */ = {isa = PBXBuildFile; fileRef = B966D1B340AC5F7E73477827C816B4EA /* STPCardValidator.swift */; }; + E73DFB8CCED2D914CDD1BF72D84CED41 /* fr-CA.lproj in Resources */ = {isa = PBXBuildFile; fileRef = 02E732DEFD11292BCD9174A9C6A07A98 /* fr-CA.lproj */; }; + E74A2734AE916F8E5EA0F040EA3CA96E /* STDSNavigationBarCustomization.h in Headers */ = {isa = PBXBuildFile; fileRef = CD067661A0C2C554CF5379FD1AC3BE1F /* STDSNavigationBarCustomization.h */; settings = {ATTRIBUTES = (Public, ); }; }; + E813CD63B29D9DBEEF4777CF2C5421D4 /* STDSJSONEncoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 2A5A6E2AB39AD7F0E62C71444A3FF881 /* STDSJSONEncoder.h */; settings = {ATTRIBUTES = (Public, ); }; }; + E86141DDC8ADFEC978AC7F4198E7206E /* ko.lproj in Resources */ = {isa = PBXBuildFile; fileRef = F9C29673142619F12CD52DC5620F5F50 /* ko.lproj */; }; + E890BDC505D263CF43789649B20D7E16 /* STPPaymentMethodCardWallet.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6F38DE58C92533FFAD0D80755E2180B9 /* STPPaymentMethodCardWallet.swift */; }; + E912FE78E0AC65A1E5B2F7993B49E8DB /* Enums+CustomStringConvertible.swift in Sources */ = {isa = PBXBuildFile; fileRef = A7625FA16B3529BB97D31FBF6CB29ABB /* Enums+CustomStringConvertible.swift */; }; + E98EFEF31E18A37C9B657706FA00D071 /* STDSChallengeInformationView.m in Sources */ = {isa = PBXBuildFile; fileRef = 00B7598DBDB51CDD8DEA474B7C16C37D /* STDSChallengeInformationView.m */; }; + EA0EAA4A9626750C8D747A14215CF111 /* STPBankAccountParams.swift in Sources */ = {isa = PBXBuildFile; fileRef = 00320049D7D4E5287F446E28FAA07C15 /* STPBankAccountParams.swift */; }; + EA4EC4B3853541FDC946239C036D12C9 /* CwlCatchException.h in Headers */ = {isa = PBXBuildFile; fileRef = 44669529D230594202E1BBACB273334B /* CwlCatchException.h */; settings = {ATTRIBUTES = (Public, ); }; }; + EAEF487CC506B4E919DCDFB0CBB91573 /* STPSourceKlarnaDetails.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A70552201EE224B319451BA38E504C9 /* STPSourceKlarnaDetails.swift */; }; + EB331A4254ED56A8799C0C756586BDD0 /* STPPaymentMethodEPSParams.swift in Sources */ = {isa = PBXBuildFile; fileRef = 247664F527EF0EAB580442338DE2B502 /* STPPaymentMethodEPSParams.swift */; }; + EB85AD05E9550AEE05BEABCBD0A54D52 /* STPPaymentConfirmation+SwiftUI.swift in Sources */ = {isa = PBXBuildFile; fileRef = E58DA75024D5733493F417C1567B9C28 /* STPPaymentConfirmation+SwiftUI.swift */; }; + EB892573E1CA332ED26DCC659406E79B /* XCTest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AE438E25F67548080875B1E9D861E554 /* XCTest.framework */; }; + EB9588C297966D443D6B3236DB11DEE0 /* STPDeviceUtils.swift in Sources */ = {isa = PBXBuildFile; fileRef = AE8F8F6432C8A0DB6AD810AE037FA4D5 /* STPDeviceUtils.swift */; }; + EC59BED70255C71F238B09D9AC2D1EA2 /* STPIssuingCardPin.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6A764903B3985971868A7BB7BD637EE /* STPIssuingCardPin.swift */; }; + ED8221343E282DCEC1F86058EF06D93A /* STDSSelectionCustomization.m in Sources */ = {isa = PBXBuildFile; fileRef = 5126E22B7F9BDB09DB115787314D4DF9 /* STDSSelectionCustomization.m */; }; + EE62B5EBDEE95CF64E327C407D793A17 /* STPConfirmCardOptions.swift in Sources */ = {isa = PBXBuildFile; fileRef = D744262862B82B90B5D9F4181794909B /* STPConfirmCardOptions.swift */; }; + EE89C7193918A27358AD3318384543D5 /* STDSProgressViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 5AE4E50BAA23DE344F16F409B862C98F /* STDSProgressViewController.m */; }; + EEAD0208A73938F4686CB17E3BC2483E /* NSDictionary+DecodingHelpers.h in Headers */ = {isa = PBXBuildFile; fileRef = CDBC2D073B4C177E30C6586FF83D1A77 /* NSDictionary+DecodingHelpers.h */; settings = {ATTRIBUTES = (Public, ); }; }; + EF178AD4D324BA0FC0D9351CAC5FB581 /* es.lproj in Resources */ = {isa = PBXBuildFile; fileRef = 634823EB04265CECC1ACDC95F5DC0559 /* es.lproj */; }; + EF32F328C68BDC0375FDE741B5501436 /* pl-PL.lproj in Resources */ = {isa = PBXBuildFile; fileRef = F21DCC984F5A8C9A6101163B3ACD6361 /* pl-PL.lproj */; }; + F0372BD6E4317E3D0F23E3CED51704B0 /* UIColor+DefaultColors.m in Sources */ = {isa = PBXBuildFile; fileRef = C61146BA817F5C94D62CF1642E5225C8 /* UIColor+DefaultColors.m */; }; + F04940FCE8A5779124988F6710DA2E35 /* lv-LV.lproj in Resources */ = {isa = PBXBuildFile; fileRef = 09A4FD639857D927B0E8B4AF1953F041 /* lv-LV.lproj */; }; + F07AE8BFAF6FE6AC2831BB0CCB4BD652 /* STDSChallengeStatusReceiver.h in Headers */ = {isa = PBXBuildFile; fileRef = 2BDD6F369ED85B44B472A23BC44B6D4C /* STDSChallengeStatusReceiver.h */; settings = {ATTRIBUTES = (Public, ); }; }; + F0ED669E48B43DC9B8AB6803B06910B4 /* STDSJSONWebSignature.m in Sources */ = {isa = PBXBuildFile; fileRef = 8261E3AB13EAE1E40AF14930BCEEC87A /* STDSJSONWebSignature.m */; }; + F1D415C910F2813FD4C7641DA1500EBC /* STDSEphemeralKeyPair.m in Sources */ = {isa = PBXBuildFile; fileRef = 46BB6A49A4825C4F1703C49EAD7D5BE3 /* STDSEphemeralKeyPair.m */; }; + F1D91144B0B756BA7723E0AE68ED6605 /* DSL.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9B95E6636139A828AF2BFC5FBDA80120 /* DSL.swift */; settings = {COMPILER_FLAGS = "-DPRODUCT_NAME=Nimble/Nimble"; }; }; + F1E88D29094885C08DFBD1AB9ED7E8D8 /* en.lproj in Resources */ = {isa = PBXBuildFile; fileRef = 7ADF2C73CA362B44CA48E40E9B7F17EC /* en.lproj */; }; + F1FBD90D9EE6D42AD6A61D31F0BF8D32 /* STDSTransaction.h in Headers */ = {isa = PBXBuildFile; fileRef = 04085F0021DC1396605BE5F2EE636D66 /* STDSTransaction.h */; settings = {ATTRIBUTES = (Public, ); }; }; + F248B374BD2E538D1FECDC9B05D2C5B8 /* en-GB.lproj in Resources */ = {isa = PBXBuildFile; fileRef = 6B79B7AE0DCE08C4DBCB032571274473 /* en-GB.lproj */; }; + F35702AD6013344A66100913A925A9B0 /* NSData+JWEHelpers.m in Sources */ = {isa = PBXBuildFile; fileRef = 22F4A5DC1871015B1D75725F5293511C /* NSData+JWEHelpers.m */; }; + F3D59D684D918CFD627289479042B176 /* STDSRuntimeErrorEvent.m in Sources */ = {isa = PBXBuildFile; fileRef = 5F226DBA46EA23FC0AD0054FA29C08C5 /* STDSRuntimeErrorEvent.m */; }; + F3E4BD503E80ADE907324B732C196214 /* Analytic.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A615105537FBF64E97274D44B7CFBA6 /* Analytic.swift */; }; + F4BA31F4637C69F7D0077074CE2D2CAA /* STPPaymentMethodParams.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74C1334BBB0CD640AEEE942300A5C0F9 /* STPPaymentMethodParams.swift */; }; + F4EF59D354572BFB98386FC8DC047250 /* de.lproj in Resources */ = {isa = PBXBuildFile; fileRef = 5CCFE00FEAB101DA92225E44E87BA2F0 /* de.lproj */; }; + F53E45015B7B3F54A7CA33F0DDE8A8B6 /* amex-logo@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 746F6973A7CE90E7B8443A2BC02C6A61 /* amex-logo@3x.png */; }; + F591765960EECDBB53CB4E5329290A4B /* World.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2B2B90235B1E265D07486341C7BBBDB1 /* World.swift */; }; + F65B24DDF852712C877CA3F64353C818 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 54808C6C88411583D225CB43662CF2A8 /* Foundation.framework */; }; + F676914DF10AB2BAA2F154454784C371 /* StripePayments-Stripe3DS2 in Resources */ = {isa = PBXBuildFile; fileRef = 7DBC3A921194DAA2FBCAC320884C52B5 /* StripePayments-Stripe3DS2 */; }; + F73C4808E488D4F1847459F64BA7DDF6 /* STPLocalizedString.swift in Sources */ = {isa = PBXBuildFile; fileRef = BCB3535181A18B880075F50FFF8AB72C /* STPLocalizedString.swift */; }; + F76C1C50DF2D24853DDD8130B3D89895 /* STPAnalyticsClient.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1F24AD37DC0DEA08C0161101911ABDE4 /* STPAnalyticsClient.swift */; }; + F8211C89835CD4106BCC584D260CF7C8 /* DispatchTimeInterval.swift in Sources */ = {isa = PBXBuildFile; fileRef = E43CDDA61CC85F1F63015E11796122AB /* DispatchTimeInterval.swift */; settings = {COMPILER_FLAGS = "-DPRODUCT_NAME=Nimble/Nimble"; }; }; + F889D83409DDF7FBC0079C6B7FBE5CC1 /* STDSSpacerView.m in Sources */ = {isa = PBXBuildFile; fileRef = E38EDCFC0E27E0450E7DB7D6EC60C9FE /* STDSSpacerView.m */; }; + F8DA5F4BC394B30B75912BB1C426DFEB /* StripeCore+Import.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85DB610619181E933973768373CBF80A /* StripeCore+Import.swift */; }; + F8EF13262110BC0A7124640FB4E4B4BE /* StripeAPIConfiguration+Version.swift in Sources */ = {isa = PBXBuildFile; fileRef = F88C52ABDD07C21075F06653D2F40D77 /* StripeAPIConfiguration+Version.swift */; }; + F94ED0C040D8EFE1B1227A464F81E92E /* BeGreaterThan.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B727AD03286B77B339F83B639680C4A /* BeGreaterThan.swift */; settings = {COMPILER_FLAGS = "-DPRODUCT_NAME=Nimble/Nimble"; }; }; + F95BFF4CC50156536AB80A877C1D1A1F /* STPPaymentMethodNetBanking.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7CC131053FC529177E058091853ACBB4 /* STPPaymentMethodNetBanking.swift */; }; + F9727FF50B4CDA30B1E3A3E7C28E34ED /* et-EE.lproj in Resources */ = {isa = PBXBuildFile; fileRef = 20C58246251D7176AB02C19821A6B78B /* et-EE.lproj */; }; + F9A30F02081D3CE0A00007EC34909897 /* STPPaymentMethodGiropay.swift in Sources */ = {isa = PBXBuildFile; fileRef = 979D41D78D59AA209C7CEE1078AFEADD /* STPPaymentMethodGiropay.swift */; }; + F9A961CFA0E2BD3C6A94E282069AD80E /* BeWithin.swift in Sources */ = {isa = PBXBuildFile; fileRef = EEA0BF069FE2A7864A33BBC6381D262F /* BeWithin.swift */; settings = {COMPILER_FLAGS = "-DPRODUCT_NAME=Nimble/Nimble"; }; }; + FA266048E8536D7AD9C02B7AA379D5DD /* STDSDeviceInformationParameter+Private.h in Headers */ = {isa = PBXBuildFile; fileRef = D2A49AC84E15C93206CFCE783E500FB9 /* STDSDeviceInformationParameter+Private.h */; settings = {ATTRIBUTES = (Public, ); }; }; + FA44D701996C0C5890B87E655AB09CD6 /* STDSJSONDecodable.h in Headers */ = {isa = PBXBuildFile; fileRef = A45E5CCC06EACD4C6011001C040737A5 /* STDSJSONDecodable.h */; settings = {ATTRIBUTES = (Public, ); }; }; + FAF0419FCFB02CEC2A36BCE29FA02C44 /* STDSIPAddress.m in Sources */ = {isa = PBXBuildFile; fileRef = 38FDD264C34D13D6C5139E02B5E3429E /* STDSIPAddress.m */; }; + FBBB630553CABE3EE77621869383EFC8 /* tk.lproj in Resources */ = {isa = PBXBuildFile; fileRef = CF407AFF06C34D92E915AB3C827DA955 /* tk.lproj */; }; + FC0B9CF3FDA02D8B83B72393BB1F76E4 /* NSDictionary+Stripe.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3B34FEC150B5B0919521FF02A278AD6D /* NSDictionary+Stripe.swift */; }; + FC4F734925BC0EDDCD7C10AFBF93C576 /* DSL.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F07FCCE05A15374145FFEB562FC6CE3 /* DSL.h */; settings = {ATTRIBUTES = (Public, ); }; }; + FC9384841A6BDD66EDC17640ACDB3F50 /* STPSourceParams.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74CA148030F6253CC496090DE0F88268 /* STPSourceParams.swift */; }; + FE67CE5AE4DFFE6B850FA43334EEBDC0 /* QuickObjCRuntime.h in Headers */ = {isa = PBXBuildFile; fileRef = A186D36A0EE28C51E4FDB061E865AD36 /* QuickObjCRuntime.h */; settings = {ATTRIBUTES = (Project, ); }; }; + FEA8C3E9543FB2A316D5A8F89B13D411 /* Quick-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = B99A844E813EC8C0FE7F1C1469E68644 /* Quick-dummy.m */; }; + FEEEE643D707D94977179AD61D2B0FF2 /* STPSourceVerification.swift in Sources */ = {isa = PBXBuildFile; fileRef = E5EDE192F55569328BBF6D6F4BAB9F04 /* STPSourceVerification.swift */; }; + FF1B5B34B625C2F0D99BBA0B5018F4EF /* STDSException.h in Headers */ = {isa = PBXBuildFile; fileRef = C311C57196B2E3BDF8E4A5D9D5A19382 /* STDSException.h */; settings = {ATTRIBUTES = (Public, ); }; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ - 4316B6F1CCEA7D68B7D07667F9755024 /* PBXContainerItemProxy */ = { + 04C1FDC428977C31E635B110B042119F /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 6F13695E06195A78EA8A95F8C7ED0D2F; + remoteInfo = Nimble; + }; + 2DD58164DDF6C5BCBD350A24F55FA10D /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 1A050828BB67BEF7076399FA446EE87F; + remoteInfo = "StripePayments-StripePayments"; + }; + 364A1C487390153D77FEA6BAC6999E14 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 1DFC6E27E6C76D8B0A836C5D658B038D; + remoteInfo = StripePayments; + }; + 77961FEE9C7F9614AA240E033F5D7E92 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 91ECFC81736C2875C7A5B90E324EDF11; + remoteInfo = StripeCore; + }; + 7BD730C099E566D778FEC12695D72B61 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 1DFC6E27E6C76D8B0A836C5D658B038D; + remoteInfo = StripePayments; + }; + 7E1326C39F0C0184420246927C61A0D2 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 91ECFC81736C2875C7A5B90E324EDF11; + remoteInfo = StripeCore; + }; + 94E8CE3F3997890C804A2EEE88907F8D /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 5F48D489D9B599786982F278E5F9BCBF; + remoteInfo = "StripeCore-StripeCore"; + }; + DB39676B0690864975A573F15B3D322B /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 91ECFC81736C2875C7A5B90E324EDF11; + remoteInfo = StripeCore; + }; + F4ED061E88DF8363B017EB28D32FEA6C /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; proxyType = 1; remoteGlobalIDString = C82891EAB7293DBEE916B21F57E8474D; remoteInfo = Quick; }; - 4AB6872CAE7EB20877E143891709DAD2 /* PBXContainerItemProxy */ = { + F6FB9D81D322E506785102483AA8F187 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; proxyType = 1; - remoteGlobalIDString = 6F13695E06195A78EA8A95F8C7ED0D2F; - remoteInfo = Nimble; + remoteGlobalIDString = 6660405CC6BBF9EC47B377FB74A3F5CB; + remoteInfo = "StripePayments-Stripe3DS2"; }; /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ + 00320049D7D4E5287F446E28FAA07C15 /* STPBankAccountParams.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = STPBankAccountParams.swift; path = "StripePayments/StripePayments/API Bindings/Models/Sources/Types/STPBankAccountParams.swift"; sourceTree = ""; }; + 00B7598DBDB51CDD8DEA474B7C16C37D /* STDSChallengeInformationView.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = STDSChallengeInformationView.m; path = Stripe3DS2/Stripe3DS2/STDSChallengeInformationView.m; sourceTree = ""; }; + 01A9C02EFDED19245C2C5A380F52A0ED /* STDSJailbreakChecker.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = STDSJailbreakChecker.h; path = Stripe3DS2/Stripe3DS2/STDSJailbreakChecker.h; sourceTree = ""; }; + 02C5EB104E05FA96C126340C58B899EC /* STPPaymentMethodUSBankAccount.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = STPPaymentMethodUSBankAccount.swift; path = "StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodUSBankAccount.swift"; sourceTree = ""; }; + 02E732DEFD11292BCD9174A9C6A07A98 /* fr-CA.lproj */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = folder; name = "fr-CA.lproj"; path = "StripeCore/StripeCore/Resources/Localizations/fr-CA.lproj"; sourceTree = ""; }; 02F5AF25FD35DDCE251A9006737617A5 /* Pods-OSPaymentsLib-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Pods-OSPaymentsLib-umbrella.h"; sourceTree = ""; }; - 090D7BCE58F5A67C1B30F59637E0EE53 /* AssertionDispatcher.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = AssertionDispatcher.swift; path = Sources/Nimble/Adapters/AssertionDispatcher.swift; sourceTree = ""; }; - 0A6115706ED27012A9F43E253D3D3DD7 /* QuickSpecBase.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = QuickSpecBase.m; path = Sources/QuickObjCRuntime/QuickSpecBase.m; sourceTree = ""; }; - 0B2A30FEA2214E06D065AE8997736B53 /* CwlCatchException.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = CwlCatchException.swift; path = Carthage/Checkouts/CwlCatchException/Sources/CwlCatchException/CwlCatchException.swift; sourceTree = ""; }; - 0BB908657F2C86943C6660C8F0130CEB /* XCTestSuite+QuickTestSuiteBuilder.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "XCTestSuite+QuickTestSuiteBuilder.m"; path = "Sources/QuickObjectiveC/XCTestSuite+QuickTestSuiteBuilder.m"; sourceTree = ""; }; + 03910FB9857DD28462E8F90639BBC655 /* STDSEphemeralKeyPair+Testing.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "STDSEphemeralKeyPair+Testing.h"; path = "Stripe3DS2/Stripe3DS2/STDSEphemeralKeyPair+Testing.h"; sourceTree = ""; }; + 03D9F470BE7939CC23898F0F41EF0B5E /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS14.0.sdk/System/Library/Frameworks/UIKit.framework; sourceTree = DEVELOPER_DIR; }; + 03EFF7427F270A66E19D421DF08BAA13 /* it.lproj */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = folder; name = it.lproj; path = StripePayments/StripePayments/Resources/Localizations/it.lproj; sourceTree = ""; }; + 04085F0021DC1396605BE5F2EE636D66 /* STDSTransaction.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = STDSTransaction.h; path = Stripe3DS2/Stripe3DS2/include/STDSTransaction.h; sourceTree = ""; }; + 04615DC24469B5770473F2C49A13B548 /* da.lproj */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = folder; name = da.lproj; path = Stripe3DS2/Stripe3DS2/Resources/da.lproj; sourceTree = ""; }; + 048BC82B48E322C6ACF6435AD7C34B1A /* STPPaymentIntentSourceAction.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = STPPaymentIntentSourceAction.swift; path = "StripePayments/StripePayments/API Bindings/Models/PaymentIntents/STPPaymentIntentSourceAction.swift"; sourceTree = ""; }; + 0495AD8123610ADD73CF2D15C24F10A4 /* SuiteHooks.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SuiteHooks.swift; path = Sources/Quick/Hooks/SuiteHooks.swift; sourceTree = ""; }; + 04C4BA6488DA9BA50F6C16F86B003E83 /* PostNotification.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = PostNotification.swift; path = Sources/Nimble/Matchers/PostNotification.swift; sourceTree = ""; }; + 051285ECD621D562C7E22360DD37AA6B /* zh-Hans.lproj */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = folder; name = "zh-Hans.lproj"; path = "StripeCore/StripeCore/Resources/Localizations/zh-Hans.lproj"; sourceTree = ""; }; + 051B5D2B1A4E36E5CE60E4AF9F3D8323 /* id.lproj */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = folder; name = id.lproj; path = Stripe3DS2/Stripe3DS2/Resources/id.lproj; sourceTree = ""; }; + 053B61719B4CBA9537CBFF4C7EF8AA0F /* QCKDSL.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = QCKDSL.h; path = Sources/QuickObjectiveC/DSL/QCKDSL.h; sourceTree = ""; }; + 056DA00E7E017616FF5CF5023CCED999 /* NMBStringify.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = NMBStringify.h; path = Sources/NimbleObjectiveC/NMBStringify.h; sourceTree = ""; }; + 062AA013B25534B63F1D9C7A0B1DCCDA /* NSBundle+Stripe_AppName.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "NSBundle+Stripe_AppName.swift"; path = "StripeCore/StripeCore/Source/Categories/NSBundle+Stripe_AppName.swift"; sourceTree = ""; }; + 065A9053EB46701FD1D2B278797D0E03 /* STDSWebView.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = STDSWebView.h; path = Stripe3DS2/Stripe3DS2/STDSWebView.h; sourceTree = ""; }; + 065AE8BD8BF5F67C6C62A4385F59BC6F /* BeVoid.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = BeVoid.swift; path = Sources/Nimble/Matchers/BeVoid.swift; sourceTree = ""; }; + 0661BE341FD38AE6F2E228BFF0A3DE12 /* tr.lproj */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = folder; name = tr.lproj; path = StripePayments/StripePayments/Resources/Localizations/tr.lproj; sourceTree = ""; }; + 06C5071A5E1022BA2DBD0DB4A27556DC /* el-GR.lproj */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = folder; name = "el-GR.lproj"; path = "StripeCore/StripeCore/Resources/Localizations/el-GR.lproj"; sourceTree = ""; }; + 074B03C63A23CC48E3CDCE64FC0A0961 /* STDSChallengeResponseMessageExtension.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = STDSChallengeResponseMessageExtension.h; path = Stripe3DS2/Stripe3DS2/STDSChallengeResponseMessageExtension.h; sourceTree = ""; }; + 077F00A2042A3D0C16E7463BC7B8B151 /* bg-BG.lproj */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = folder; name = "bg-BG.lproj"; path = "StripeCore/StripeCore/Resources/Localizations/bg-BG.lproj"; sourceTree = ""; }; + 07C27B89557353E8CC25C4EC7BA2B3A7 /* ConnectionsSDKAvailability.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ConnectionsSDKAvailability.swift; path = StripePayments/StripePayments/Internal/Helpers/ConnectionsSDKAvailability.swift; sourceTree = ""; }; + 07D2BCAAFF28918553FDE6722B50EF5D /* SatisfyAllOf.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SatisfyAllOf.swift; path = Sources/Nimble/Matchers/SatisfyAllOf.swift; sourceTree = ""; }; + 0823109A43B7175AAA2D1C0D80EBAAB0 /* STDSChallengeSelectionView.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = STDSChallengeSelectionView.m; path = Stripe3DS2/Stripe3DS2/STDSChallengeSelectionView.m; sourceTree = ""; }; + 091B29FC638823987C25B0C4C46942D7 /* Quick.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = Quick.release.xcconfig; sourceTree = ""; }; + 0979BD7CBA1EABD3257C88B143EA3662 /* lt-LT.lproj */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = folder; name = "lt-LT.lproj"; path = "StripePayments/StripePayments/Resources/Localizations/lt-LT.lproj"; sourceTree = ""; }; + 09A4FD639857D927B0E8B4AF1953F041 /* lv-LV.lproj */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = folder; name = "lv-LV.lproj"; path = "Stripe3DS2/Stripe3DS2/Resources/lv-LV.lproj"; sourceTree = ""; }; + 09F8D6800BE948F806BA63A483D2368D /* STPPaymentMethodCardChecks.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = STPPaymentMethodCardChecks.swift; path = "StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodCardChecks.swift"; sourceTree = ""; }; + 0A00905E5C9C768C295FAD0A776669AF /* BeLogical.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = BeLogical.swift; path = Sources/Nimble/Matchers/BeLogical.swift; sourceTree = ""; }; + 0A615105537FBF64E97274D44B7CFBA6 /* Analytic.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Analytic.swift; path = StripeCore/StripeCore/Source/Analytics/Analytic.swift; sourceTree = ""; }; + 0A6179DC66BD0B1B7454C6A05DCD5313 /* STPSourceReceiver.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = STPSourceReceiver.swift; path = "StripePayments/StripePayments/API Bindings/Models/Sources/STPSourceReceiver.swift"; sourceTree = ""; }; + 0AB1AE5146B37E7E38B5BC5A40BC56C0 /* cs-CZ.lproj */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = folder; name = "cs-CZ.lproj"; path = "StripeCore/StripeCore/Resources/Localizations/cs-CZ.lproj"; sourceTree = ""; }; + 0B2F0EE54C26FBAC5DEFD696CD0CCB91 /* STPPaymentIntentShippingDetailsAddressParams.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = STPPaymentIntentShippingDetailsAddressParams.swift; path = "StripePayments/StripePayments/API Bindings/Models/PaymentIntents/STPPaymentIntentShippingDetailsAddressParams.swift"; sourceTree = ""; }; + 0B7E0F91CC4790A329303D0CD7F34DAC /* STDSSpacerView.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = STDSSpacerView.h; path = Stripe3DS2/Stripe3DS2/STDSSpacerView.h; sourceTree = ""; }; + 0C14FCFB236C6FBB02FE6B9570F40375 /* STDSJSONWebSignature.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = STDSJSONWebSignature.h; path = Stripe3DS2/Stripe3DS2/STDSJSONWebSignature.h; sourceTree = ""; }; + 0CA0604F6FBB9845BBFAAE7E13BD30AE /* STPIntentActionUseStripeSDK.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = STPIntentActionUseStripeSDK.swift; path = "StripePayments/StripePayments/Internal/API Bindings/STPIntentActionUseStripeSDK.swift"; sourceTree = ""; }; 0D631E9908483F9525A6B3F36F16CC61 /* Quick.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Quick.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 0D904E98038DAE649AA050DAE20B884A /* Pods-OSPaymentsLib-OSPaymentsLibTests.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = "Pods-OSPaymentsLib-OSPaymentsLibTests.modulemap"; sourceTree = ""; }; - 0F4A8507ACE009C2C0F45E1FDED202C7 /* NMBExpectation.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = NMBExpectation.swift; path = Sources/Nimble/Adapters/NMBExpectation.swift; sourceTree = ""; }; + 0EC220DB36D5291F5340C43799393C0B /* ja.lproj */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = folder; name = ja.lproj; path = StripePayments/StripePayments/Resources/Localizations/ja.lproj; sourceTree = ""; }; + 0EC9A9407672A47FB13A5FC199883E3E /* STDSSecTypeUtilities.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = STDSSecTypeUtilities.m; path = Stripe3DS2/Stripe3DS2/STDSSecTypeUtilities.m; sourceTree = ""; }; + 0F07FCCE05A15374145FFEB562FC6CE3 /* DSL.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = DSL.h; path = Sources/NimbleObjectiveC/DSL.h; sourceTree = ""; }; + 0F19639C8AA2CFD45C27C253BFFFAB84 /* STPPaymentMethodEPS.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = STPPaymentMethodEPS.swift; path = "StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodEPS.swift"; sourceTree = ""; }; + 0F548AB251AC48E38AEC5763CEC1679D /* NSBundle+CurrentTestBundle.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "NSBundle+CurrentTestBundle.swift"; path = "Sources/Quick/NSBundle+CurrentTestBundle.swift"; sourceTree = ""; }; + 0F7B4901ECF2394EA1A28EE677EBEC5B /* error@3x.png */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.png; name = "error@3x.png"; path = "Stripe3DS2/Stripe3DS2/Resources/Images/error@3x.png"; sourceTree = ""; }; + 0FC4784F6CFE516E67A500EA1188794A /* STPSourceEnums.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = STPSourceEnums.swift; path = "StripePayments/StripePayments/API Bindings/Models/Sources/STPSourceEnums.swift"; sourceTree = ""; }; + 0FC81EBC70D3F54547A459C447B572CC /* fr.lproj */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = folder; name = fr.lproj; path = Stripe3DS2/Stripe3DS2/Resources/fr.lproj; sourceTree = ""; }; + 10066A2223CBF75142915E950689891A /* STDSTextChallengeView.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = STDSTextChallengeView.m; path = Stripe3DS2/Stripe3DS2/STDSTextChallengeView.m; sourceTree = ""; }; + 104E18997DC724D99094B4B2A8EA2132 /* STPPaymentMethodLinkParams.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = STPPaymentMethodLinkParams.swift; path = "StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodLinkParams.swift"; sourceTree = ""; }; 107B1F29BE07EF1662B3B4BF2A9E0BE9 /* Pods-OSPaymentsLib-acknowledgements.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-OSPaymentsLib-acknowledgements.plist"; sourceTree = ""; }; - 115813CA22C723977B41201CF3B4C44A /* BeIdenticalTo.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = BeIdenticalTo.swift; path = Sources/Nimble/Matchers/BeIdenticalTo.swift; sourceTree = ""; }; - 16671DF91816B7CC8BAA2964E1E6414C /* Equal+Tuple.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "Equal+Tuple.swift"; path = "Sources/Nimble/Matchers/Equal+Tuple.swift"; sourceTree = ""; }; - 16F99FA0960BE24312A4603668FD6CFA /* HaveCount.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = HaveCount.swift; path = Sources/Nimble/Matchers/HaveCount.swift; sourceTree = ""; }; + 10BC07CCB954D3F5A862B45897BCB5D5 /* ms-MY.lproj */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = folder; name = "ms-MY.lproj"; path = "StripeCore/StripeCore/Resources/Localizations/ms-MY.lproj"; sourceTree = ""; }; + 10F02E6778D8AB97A8BF670F28940A5D /* et-EE.lproj */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = folder; name = "et-EE.lproj"; path = "Stripe3DS2/Stripe3DS2/Resources/et-EE.lproj"; sourceTree = ""; }; + 10F5694961D0A23DC214C7A1A614F78C /* STPFormEncoder.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = STPFormEncoder.swift; path = "StripePayments/StripePayments/Internal/API Bindings/STPFormEncoder.swift"; sourceTree = ""; }; + 1173EF3FFD767E414B6BFF00F321EF51 /* mt.lproj */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = folder; name = mt.lproj; path = StripeCore/StripeCore/Resources/Localizations/mt.lproj; sourceTree = ""; }; + 11E6A0CBA10A6C02A9EFB6A703E5254B /* STDSBrandingView.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = STDSBrandingView.h; path = Stripe3DS2/Stripe3DS2/STDSBrandingView.h; sourceTree = ""; }; + 12C00397639245C26EF6B232E3D18D39 /* ExampleGroup.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ExampleGroup.swift; path = Sources/Quick/ExampleGroup.swift; sourceTree = ""; }; + 134A57537C47623876A363227A399DE8 /* STDSProcessingView.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = STDSProcessingView.h; path = Stripe3DS2/Stripe3DS2/STDSProcessingView.h; sourceTree = ""; }; + 135F3A6ABE8D575F90D1FA59ABF9FB78 /* Nimble.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = Nimble.release.xcconfig; sourceTree = ""; }; + 136D983EFF23F79D9508D3BB81A908A4 /* fr-CA.lproj */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = folder; name = "fr-CA.lproj"; path = "StripePayments/StripePayments/Resources/Localizations/fr-CA.lproj"; sourceTree = ""; }; + 14121A23FD33D0DE147657BC767B60D5 /* sv.lproj */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = folder; name = sv.lproj; path = Stripe3DS2/Stripe3DS2/Resources/sv.lproj; sourceTree = ""; }; + 1471C5F4F2DB4EC1A62556579203ECDF /* NSURLComponents+Stripe.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "NSURLComponents+Stripe.swift"; path = "StripeCore/StripeCore/Source/Categories/NSURLComponents+Stripe.swift"; sourceTree = ""; }; + 147806AA9A9DBD6E2E7CDF5A2733F977 /* da.lproj */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = folder; name = da.lproj; path = StripeCore/StripeCore/Resources/Localizations/da.lproj; sourceTree = ""; }; + 14781C8F71AB8D62787DE872AF313BF9 /* fil.lproj */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = folder; name = fil.lproj; path = StripeCore/StripeCore/Resources/Localizations/fil.lproj; sourceTree = ""; }; + 14FBD3E0630472217181870FDB97B602 /* STPConnectAccountIndividualParams.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = STPConnectAccountIndividualParams.swift; path = "StripePayments/StripePayments/API Bindings/Models/STPConnectAccountIndividualParams.swift"; sourceTree = ""; }; + 1567AEFC753587BCFC6E1183B54AB8EA /* Analytic+Payments.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "Analytic+Payments.swift"; path = "StripePayments/StripePayments/Internal/Analytics/Analytic+Payments.swift"; sourceTree = ""; }; + 15735CC2359689BE68DDD82AA64AF91D /* STPConfirmAlipayOptions.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = STPConfirmAlipayOptions.swift; path = "StripePayments/StripePayments/API Bindings/Models/PaymentIntents/STPConfirmAlipayOptions.swift"; sourceTree = ""; }; + 15A26F6CDD349347AB55D87E3586D138 /* NimbleXCTestHandler.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = NimbleXCTestHandler.swift; path = Sources/Nimble/Adapters/NimbleXCTestHandler.swift; sourceTree = ""; }; + 15AD669247185390F5190AFD168375DF /* STDSUICustomization.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = STDSUICustomization.h; path = Stripe3DS2/Stripe3DS2/include/STDSUICustomization.h; sourceTree = ""; }; + 15FA8A572184CCA188DEF786D5C3825D /* ko.lproj */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = folder; name = ko.lproj; path = StripeCore/StripeCore/Resources/Localizations/ko.lproj; sourceTree = ""; }; + 161BEAD8BFBD8106D006C6D52B175AEE /* STDSDeviceInformationParameter.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = STDSDeviceInformationParameter.h; path = Stripe3DS2/Stripe3DS2/STDSDeviceInformationParameter.h; sourceTree = ""; }; + 16422242E406E9916B4C7ABBF6B3D1F2 /* id.lproj */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = folder; name = id.lproj; path = StripePayments/StripePayments/Resources/Localizations/id.lproj; sourceTree = ""; }; + 16AD524274F54533DA4274E95224FDAE /* nn-NO.lproj */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = folder; name = "nn-NO.lproj"; path = "Stripe3DS2/Stripe3DS2/Resources/nn-NO.lproj"; sourceTree = ""; }; + 1702A313BFC0C3F57587D2CD19916460 /* STPSetupIntent.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = STPSetupIntent.swift; path = "StripePayments/StripePayments/API Bindings/Models/SetupIntents/STPSetupIntent.swift"; sourceTree = ""; }; + 1736D4BAB6DBB8E1644E09005752C2AF /* ResourceBundle-StripePayments-StripePayments-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "ResourceBundle-StripePayments-StripePayments-Info.plist"; sourceTree = ""; }; + 176A1FCF04CECEC5B248284E0F8E33D7 /* STPFPXBankBrand.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = STPFPXBankBrand.swift; path = "StripePayments/StripePayments/API Bindings/Models/STPFPXBankBrand.swift"; sourceTree = ""; }; + 17976A6E437D766A06ADD235EC645E0F /* StripePayments-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "StripePayments-Info.plist"; sourceTree = ""; }; + 17B1F0AE0203F3DB424913E455530C86 /* STPSetupIntentEnums.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = STPSetupIntentEnums.swift; path = "StripePayments/StripePayments/API Bindings/Models/SetupIntents/STPSetupIntentEnums.swift"; sourceTree = ""; }; + 180924D5266489E2FCC82462A8EA7CD7 /* SourceLocation.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SourceLocation.swift; path = Sources/Nimble/Utils/SourceLocation.swift; sourceTree = ""; }; 183EA06E783DC15564B47398DA299505 /* Pods-OSPaymentsLib-acknowledgements.markdown */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; path = "Pods-OSPaymentsLib-acknowledgements.markdown"; sourceTree = ""; }; - 1B6A8AE2D5EF989F29A4FFB4EB7D52A8 /* CwlMachBadInstructionHandler.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = CwlMachBadInstructionHandler.m; path = Carthage/Checkouts/CwlPreconditionTesting/Sources/CwlMachBadInstructionHandler/CwlMachBadInstructionHandler.m; sourceTree = ""; }; - 1FC0C54E76B49BF11F64E24F0931846C /* Nimble-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Nimble-umbrella.h"; sourceTree = ""; }; - 204E01215147E1CFDB134360F8F1938E /* QuickConfiguration.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = QuickConfiguration.swift; path = Sources/Quick/Configuration/QuickConfiguration.swift; sourceTree = ""; }; - 21C0C122235EDD894313B02C03C7C538 /* SatisfyAnyOf.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SatisfyAnyOf.swift; path = Sources/Nimble/Matchers/SatisfyAnyOf.swift; sourceTree = ""; }; - 230259C7BBC0AB021F9278A064AADAC1 /* QCKDSL.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = QCKDSL.m; path = Sources/QuickObjectiveC/DSL/QCKDSL.m; sourceTree = ""; }; - 2362FBD489CCE1D540C808716D1EB8C4 /* ExampleHooks.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ExampleHooks.swift; path = Sources/Quick/Hooks/ExampleHooks.swift; sourceTree = ""; }; - 23E11C41EA8F304D43F144554949AEFF /* CwlMachBadInstructionHandler.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = CwlMachBadInstructionHandler.h; path = Carthage/Checkouts/CwlPreconditionTesting/Sources/CwlMachBadInstructionHandler/include/CwlMachBadInstructionHandler.h; sourceTree = ""; }; - 254558E5834898D2301B3E8C4F620311 /* QuickSpec.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = QuickSpec.m; path = Sources/QuickObjectiveC/QuickSpec.m; sourceTree = ""; }; - 289E9ACE73C6629DAAEA21D42495B76E /* QuickTestSuite.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = QuickTestSuite.swift; path = Sources/Quick/QuickTestSuite.swift; sourceTree = ""; }; - 298044D1245C4BD022B7F13791639E75 /* DSL+Wait.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "DSL+Wait.swift"; path = "Sources/Nimble/DSL+Wait.swift"; sourceTree = ""; }; - 2AECA1C81ADFA2CA35D84DC7FF1902B2 /* URL+FileName.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "URL+FileName.swift"; path = "Sources/Quick/URL+FileName.swift"; sourceTree = ""; }; - 2C9CC327536739702EE1B8865E38BED6 /* EndWith.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = EndWith.swift; path = Sources/Nimble/Matchers/EndWith.swift; sourceTree = ""; }; - 2CF56DC23988E5C892B0834949D740C5 /* BeEmpty.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = BeEmpty.swift; path = Sources/Nimble/Matchers/BeEmpty.swift; sourceTree = ""; }; - 2E9331718C3E375B9305AE6782A65CC4 /* CwlBadInstructionException.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = CwlBadInstructionException.swift; path = Carthage/Checkouts/CwlPreconditionTesting/Sources/CwlPreconditionTesting/CwlBadInstructionException.swift; sourceTree = ""; }; - 32395E85CAF13637932ACEECADC2D96D /* QuickConfiguration.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = QuickConfiguration.h; path = Sources/QuickObjectiveC/Configuration/QuickConfiguration.h; sourceTree = ""; }; - 33FD12F984B4BA8B5D001D0AFD13F708 /* Nimble-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Nimble-dummy.m"; sourceTree = ""; }; - 350B976ED907275DDED563482009AFD2 /* QuickTestObservation.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = QuickTestObservation.swift; path = Sources/Quick/QuickTestObservation.swift; sourceTree = ""; }; - 369990B25C94966B37B0E376A2FE93C0 /* NMBStringify.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = NMBStringify.h; path = Sources/NimbleObjectiveC/NMBStringify.h; sourceTree = ""; }; - 3B4E2AF01C07390467B2A032C1081912 /* BeLogical.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = BeLogical.swift; path = Sources/Nimble/Matchers/BeLogical.swift; sourceTree = ""; }; - 3CE338476557D8F2CF2B6E987F5A31CA /* DSL.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = DSL.swift; path = Sources/Quick/DSL/DSL.swift; sourceTree = ""; }; - 3DB3B3904CE5F831A2214803D978A197 /* ExpectationMessage.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ExpectationMessage.swift; path = Sources/Nimble/ExpectationMessage.swift; sourceTree = ""; }; - 3EFA1693908150CAAB677FEAB89AEC2D /* CwlCatchException.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = CwlCatchException.h; path = Carthage/Checkouts/CwlCatchException/Sources/CwlCatchExceptionSupport/include/CwlCatchException.h; sourceTree = ""; }; - 40955816DD54EA848880AD2815A76921 /* Await.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Await.swift; path = Sources/Nimble/Utils/Await.swift; sourceTree = ""; }; - 4149CC5C4007BD87DFDB7E2114AE830D /* Contain.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Contain.swift; path = Sources/Nimble/Matchers/Contain.swift; sourceTree = ""; }; - 43D9B7DA298758F3F8912543839CC426 /* QCKDSL.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = QCKDSL.h; path = Sources/QuickObjectiveC/DSL/QCKDSL.h; sourceTree = ""; }; - 447626370CDD31CDCC3656C6E0B3BA05 /* Errors.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Errors.swift; path = Sources/Nimble/Utils/Errors.swift; sourceTree = ""; }; - 45F6B7AC8B7979F25F17036731EE339D /* Behavior.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Behavior.swift; path = Sources/Quick/Behavior.swift; sourceTree = ""; }; - 49D566AD1F3A57C62675DCFF1174ADF8 /* DSL.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = DSL.m; path = Sources/NimbleObjectiveC/DSL.m; sourceTree = ""; }; - 4B5ECB9D7EF3AF7D8F37CE57A988CD83 /* Nimble.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = Nimble.release.xcconfig; sourceTree = ""; }; + 184CB17D9F1D079E67B9BE9D043F50EC /* ro-RO.lproj */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = folder; name = "ro-RO.lproj"; path = "StripePayments/StripePayments/Resources/Localizations/ro-RO.lproj"; sourceTree = ""; }; + 18732DE2E9C58AEC17E6DD6B7CF9FFA2 /* StripeCore-StripeCore */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; name = "StripeCore-StripeCore"; path = StripeCore.bundle; sourceTree = BUILT_PRODUCTS_DIR; }; + 19A4B6F62FC807F51F8C6FE74F065203 /* UnknownFields.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = UnknownFields.swift; path = StripeCore/StripeCore/Source/Coder/UnknownFields.swift; sourceTree = ""; }; + 19BBC418AD7958113B769C2598369D12 /* visa-white-logo@3x.png */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.png; name = "visa-white-logo@3x.png"; path = "Stripe3DS2/Stripe3DS2/Resources/Images/visa-white-logo@3x.png"; sourceTree = ""; }; + 1A1B6B7E75482437E3EE31548C812FBA /* STDSErrorMessage+Internal.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "STDSErrorMessage+Internal.m"; path = "Stripe3DS2/Stripe3DS2/STDSErrorMessage+Internal.m"; sourceTree = ""; }; + 1A70E31830D31A711BFFFA3C5B24EAFA /* STDSLocalizedString.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = STDSLocalizedString.h; path = Stripe3DS2/Stripe3DS2/STDSLocalizedString.h; sourceTree = ""; }; + 1A86E86A636998468C6AA72E338D691C /* STDSChallengeRequestParameters.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = STDSChallengeRequestParameters.h; path = Stripe3DS2/Stripe3DS2/STDSChallengeRequestParameters.h; sourceTree = ""; }; + 1B1E72523EA2324F4EF8EF152F73B08E /* CwlBadInstructionException.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = CwlBadInstructionException.swift; path = Carthage/Checkouts/CwlPreconditionTesting/Sources/CwlPreconditionTesting/CwlBadInstructionException.swift; sourceTree = ""; }; + 1B55E0D441A251A915C6E11214B5CCCC /* NSData+JWEHelpers.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "NSData+JWEHelpers.h"; path = "Stripe3DS2/Stripe3DS2/NSData+JWEHelpers.h"; sourceTree = ""; }; + 1C62A366D5C5C58C42440DD1C7ADFC27 /* Match.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Match.swift; path = Sources/Nimble/Matchers/Match.swift; sourceTree = ""; }; + 1CE8EA6F3E1DFEBE5534C8D0F1DFB621 /* nb.lproj */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = folder; name = nb.lproj; path = StripePayments/StripePayments/Resources/Localizations/nb.lproj; sourceTree = ""; }; + 1D9076470098A7FB4C8DDE1DA51FF76C /* lv-LV.lproj */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = folder; name = "lv-LV.lproj"; path = "StripeCore/StripeCore/Resources/Localizations/lv-LV.lproj"; sourceTree = ""; }; + 1DF82D6CFE767555CB959A5F30AB2353 /* nl.lproj */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = folder; name = nl.lproj; path = StripePayments/StripePayments/Resources/Localizations/nl.lproj; sourceTree = ""; }; + 1E48F583C322F895591736E2EE3A9D74 /* STDSSwiftTryCatch.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = STDSSwiftTryCatch.h; path = Stripe3DS2/Stripe3DS2/include/STDSSwiftTryCatch.h; sourceTree = ""; }; + 1ED24B16FAE7F929952656DAEC8C0246 /* UIColor+ThirteenSupport.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "UIColor+ThirteenSupport.h"; path = "Stripe3DS2/Stripe3DS2/UIColor+ThirteenSupport.h"; sourceTree = ""; }; + 1EDB2495F0CD9AEDB5FE4545BA418772 /* STDSChallengeInformationView.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = STDSChallengeInformationView.h; path = Stripe3DS2/Stripe3DS2/STDSChallengeInformationView.h; sourceTree = ""; }; + 1F24AD37DC0DEA08C0161101911ABDE4 /* STPAnalyticsClient.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = STPAnalyticsClient.swift; path = StripeCore/StripeCore/Source/Analytics/STPAnalyticsClient.swift; sourceTree = ""; }; + 1F4A483B9C67F1A3D2489FFA7C0040B0 /* STPMandateCustomerAcceptanceParams.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = STPMandateCustomerAcceptanceParams.swift; path = "StripePayments/StripePayments/API Bindings/Models/Shared/STPMandateCustomerAcceptanceParams.swift"; sourceTree = ""; }; + 1F631064D7CB9096CD13E6ACEE7BED19 /* STPPaymentMethodSofortParams.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = STPPaymentMethodSofortParams.swift; path = "StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodSofortParams.swift"; sourceTree = ""; }; + 1FF185B963FB99EF224ED52DABA01E82 /* Stripe3DS2.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = Stripe3DS2.h; path = Stripe3DS2/Stripe3DS2/include/Stripe3DS2.h; sourceTree = ""; }; + 207690A83F45986DB4608DAA78531321 /* StripeJSONEncoder.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = StripeJSONEncoder.swift; path = StripeCore/StripeCore/Source/Coder/StripeJSONEncoder.swift; sourceTree = ""; }; + 209BEBD40F07D43B691D3367032EBFE9 /* STDSThreeDS2Service.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = STDSThreeDS2Service.h; path = Stripe3DS2/Stripe3DS2/include/STDSThreeDS2Service.h; sourceTree = ""; }; + 20C58246251D7176AB02C19821A6B78B /* et-EE.lproj */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = folder; name = "et-EE.lproj"; path = "StripePayments/StripePayments/Resources/Localizations/et-EE.lproj"; sourceTree = ""; }; + 210A59DA9EB67DB017B769CBBEE3E9B3 /* STDSAuthenticationRequestParameters.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = STDSAuthenticationRequestParameters.m; path = Stripe3DS2/Stripe3DS2/STDSAuthenticationRequestParameters.m; sourceTree = ""; }; + 212794EB430C46F7E9AFF6095CEA30B5 /* STPPaymentMethodBoletoParams.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = STPPaymentMethodBoletoParams.swift; path = "StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodBoletoParams.swift"; sourceTree = ""; }; + 227D1BB76FD3CE2F3F6DFAB8FD304C80 /* STPURLCallbackHandler.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = STPURLCallbackHandler.swift; path = StripeCore/StripeCore/Source/Helpers/STPURLCallbackHandler.swift; sourceTree = ""; }; + 22C7486D395D531F3CEA71233BEF3134 /* NSError+Stripe3DS2.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "NSError+Stripe3DS2.h"; path = "Stripe3DS2/Stripe3DS2/NSError+Stripe3DS2.h"; sourceTree = ""; }; + 22F4A5DC1871015B1D75725F5293511C /* NSData+JWEHelpers.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "NSData+JWEHelpers.m"; path = "Stripe3DS2/Stripe3DS2/NSData+JWEHelpers.m"; sourceTree = ""; }; + 236B5B45A473096741E6490A0EB83CFF /* ThrowAssertion.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ThrowAssertion.swift; path = Sources/Nimble/Matchers/ThrowAssertion.swift; sourceTree = ""; }; + 247664F527EF0EAB580442338DE2B502 /* STPPaymentMethodEPSParams.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = STPPaymentMethodEPSParams.swift; path = "StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodEPSParams.swift"; sourceTree = ""; }; + 252E073673E5959089D69D015A77DA80 /* STDSBundleLocator.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = STDSBundleLocator.h; path = Stripe3DS2/Stripe3DS2/STDSBundleLocator.h; sourceTree = ""; }; + 25315BBCA00488C6108D8438AC2089EC /* STDSExpandableInformationView.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = STDSExpandableInformationView.h; path = Stripe3DS2/Stripe3DS2/STDSExpandableInformationView.h; sourceTree = ""; }; + 25A82BF67AEC9AC12EB651EDCFF7E284 /* ja.lproj */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = folder; name = ja.lproj; path = StripeCore/StripeCore/Resources/Localizations/ja.lproj; sourceTree = ""; }; + 26C20D5D39C54DAA46854DB9DC6B6EB7 /* STDSThreeDSProtocolVersion.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = STDSThreeDSProtocolVersion.h; path = Stripe3DS2/Stripe3DS2/include/STDSThreeDSProtocolVersion.h; sourceTree = ""; }; + 2752FE03683F3943213462240A793E08 /* UIFont+DefaultFonts.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "UIFont+DefaultFonts.h"; path = "Stripe3DS2/Stripe3DS2/UIFont+DefaultFonts.h"; sourceTree = ""; }; + 27899F0C9E29C49D1C37CF38F8944ADD /* NMBExpectation.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = NMBExpectation.swift; path = Sources/Nimble/Adapters/NMBExpectation.swift; sourceTree = ""; }; + 27D2EDCE6B76322090EB359B6F621326 /* sl-SI.lproj */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = folder; name = "sl-SI.lproj"; path = "StripePayments/StripePayments/Resources/Localizations/sl-SI.lproj"; sourceTree = ""; }; + 283BAC5B7B76CCC28073F1261D92D3AE /* STDSErrorMessage.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = STDSErrorMessage.h; path = Stripe3DS2/Stripe3DS2/include/STDSErrorMessage.h; sourceTree = ""; }; + 28C3729DDBD681EA2C39DD9D2F731E5D /* ro-RO.lproj */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = folder; name = "ro-RO.lproj"; path = "Stripe3DS2/Stripe3DS2/Resources/ro-RO.lproj"; sourceTree = ""; }; + 296D7B7E1FC7859637321935D2EEDA04 /* NSArray+Stripe.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "NSArray+Stripe.swift"; path = "StripePayments/StripePayments/Internal/Categories/NSArray+Stripe.swift"; sourceTree = ""; }; + 2A5A6E2AB39AD7F0E62C71444A3FF881 /* STDSJSONEncoder.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = STDSJSONEncoder.h; path = Stripe3DS2/Stripe3DS2/include/STDSJSONEncoder.h; sourceTree = ""; }; + 2A80A07639D6D832E3EC175E25BF7512 /* StripePaymentsBundleLocator.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = StripePaymentsBundleLocator.swift; path = StripePayments/StripePayments/Helpers/StripePaymentsBundleLocator.swift; sourceTree = ""; }; + 2AC6C1C0ECB6DC8888E72B1CDE082317 /* STDSBrandingView.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = STDSBrandingView.m; path = Stripe3DS2/Stripe3DS2/STDSBrandingView.m; sourceTree = ""; }; + 2B2B90235B1E265D07486341C7BBBDB1 /* World.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = World.swift; path = Sources/Quick/World.swift; sourceTree = ""; }; + 2BDD6F369ED85B44B472A23BC44B6D4C /* STDSChallengeStatusReceiver.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = STDSChallengeStatusReceiver.h; path = Stripe3DS2/Stripe3DS2/include/STDSChallengeStatusReceiver.h; sourceTree = ""; }; + 2C2BC81412FC00A087BEDBF7DA990E2E /* es-419.lproj */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = folder; name = "es-419.lproj"; path = "StripeCore/StripeCore/Resources/Localizations/es-419.lproj"; sourceTree = ""; }; + 2C4AF2F997036A42580AB4A1F059F993 /* STDSWhitelistView.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = STDSWhitelistView.m; path = Stripe3DS2/Stripe3DS2/STDSWhitelistView.m; sourceTree = ""; }; + 2C4FA16F4BF9CEC2DB082BAE796A21D0 /* FraudDetectionData.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = FraudDetectionData.swift; path = StripeCore/StripeCore/Source/Telemetry/FraudDetectionData.swift; sourceTree = ""; }; + 2C4FE4623236069C3A2DAB974A3298A8 /* Async.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Async.swift; path = StripeCore/StripeCore/Source/Helpers/Async.swift; sourceTree = ""; }; + 2CA78CD1E904D7029982A7DA5AF65AAD /* UIView+LayoutSupport.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "UIView+LayoutSupport.m"; path = "Stripe3DS2/Stripe3DS2/UIView+LayoutSupport.m"; sourceTree = ""; }; + 2D69CD9ABD5DDEE858DDA4E80A6CBA53 /* StripePayments-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "StripePayments-umbrella.h"; sourceTree = ""; }; + 2E2289167D181B642613D4463E04339B /* STDSUICustomization.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = STDSUICustomization.m; path = Stripe3DS2/Stripe3DS2/STDSUICustomization.m; sourceTree = ""; }; + 2E4064ACE1479DD23ACEC0DC69AD61BC /* STDSSynchronousLocationManager.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = STDSSynchronousLocationManager.h; path = Stripe3DS2/Stripe3DS2/STDSSynchronousLocationManager.h; sourceTree = ""; }; + 2EC5D574B6CE9C38A269696E455C14DC /* STDSThreeDSProtocolVersion.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = STDSThreeDSProtocolVersion.m; path = Stripe3DS2/Stripe3DS2/STDSThreeDSProtocolVersion.m; sourceTree = ""; }; + 2F29A2AB516AC599B61B93625C2891CD /* sl-SI.lproj */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = folder; name = "sl-SI.lproj"; path = "Stripe3DS2/Stripe3DS2/Resources/sl-SI.lproj"; sourceTree = ""; }; + 2F8BCD8F4747D61721405F64E14D0979 /* pl-PL.lproj */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = folder; name = "pl-PL.lproj"; path = "Stripe3DS2/Stripe3DS2/Resources/pl-PL.lproj"; sourceTree = ""; }; + 2FA35511EB0E5A29FA8FB39FE2925A93 /* STPPaymentMethod.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = STPPaymentMethod.swift; path = "StripePayments/StripePayments/API Bindings/Models/PaymentMethods/STPPaymentMethod.swift"; sourceTree = ""; }; + 2FD07CCB4F714C60AF38E78DCD9F5325 /* HooksPhase.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = HooksPhase.swift; path = Sources/Quick/Hooks/HooksPhase.swift; sourceTree = ""; }; + 30855110E3C79E9436F5C940800643C2 /* STPNumericStringValidator.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = STPNumericStringValidator.swift; path = StripeCore/StripeCore/Source/Helpers/STPNumericStringValidator.swift; sourceTree = ""; }; + 30B3483633599A7FA3B699D4CE417742 /* nn-NO.lproj */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = folder; name = "nn-NO.lproj"; path = "StripeCore/StripeCore/Resources/Localizations/nn-NO.lproj"; sourceTree = ""; }; + 3131F557AB874A02FAC93F1EAED6CA09 /* STPPaymentMethodAUBECSDebit.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = STPPaymentMethodAUBECSDebit.swift; path = "StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodAUBECSDebit.swift"; sourceTree = ""; }; + 323FD70DD57060BAABCE7C747761D4FC /* STDSChallengeResponseObject.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = STDSChallengeResponseObject.m; path = Stripe3DS2/Stripe3DS2/STDSChallengeResponseObject.m; sourceTree = ""; }; + 325A5722DC9DE1391905216FD4AFF829 /* STPIntentAction.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = STPIntentAction.swift; path = "StripePayments/StripePayments/API Bindings/Models/Shared/STPIntentAction.swift"; sourceTree = ""; }; + 32899D96AA85B67283ED2547D3E05BB6 /* STDSProtocolErrorEvent.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = STDSProtocolErrorEvent.h; path = Stripe3DS2/Stripe3DS2/include/STDSProtocolErrorEvent.h; sourceTree = ""; }; + 32957EEC2E5CF94B357FB4E9AEFED7AE /* STPPaymentMethodCardWalletMasterpass.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = STPPaymentMethodCardWalletMasterpass.swift; path = "StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodCardWalletMasterpass.swift"; sourceTree = ""; }; + 32A3DBB4286DB994E453A3241DC20834 /* STDSInvalidInputException.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = STDSInvalidInputException.m; path = Stripe3DS2/Stripe3DS2/STDSInvalidInputException.m; sourceTree = ""; }; + 32C63F975EF38DD20430EA221119E83D /* STPMultipartFormDataEncoder.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = STPMultipartFormDataEncoder.swift; path = "StripeCore/StripeCore/Source/API Bindings/STPMultipartFormDataEncoder.swift"; sourceTree = ""; }; + 32ECC3CE517D8C826EE3DCA91B7FDE06 /* STDSDeviceInformationManager.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = STDSDeviceInformationManager.h; path = Stripe3DS2/Stripe3DS2/STDSDeviceInformationManager.h; sourceTree = ""; }; + 3308E5D86C160F2C68B5CB75982EE128 /* zh-Hant.lproj */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = folder; name = "zh-Hant.lproj"; path = "StripePayments/StripePayments/Resources/Localizations/zh-Hant.lproj"; sourceTree = ""; }; + 334B40A9E0C181C9569B78891404779D /* STDSLabelCustomization.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = STDSLabelCustomization.m; path = Stripe3DS2/Stripe3DS2/STDSLabelCustomization.m; sourceTree = ""; }; + 34A694CA199ED0893F5BCD8DB244F45E /* STPAnalyticEvent.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = STPAnalyticEvent.swift; path = StripeCore/StripeCore/Source/Analytics/STPAnalyticEvent.swift; sourceTree = ""; }; + 34A927CDFA8ADB3ACE06A83F3000FE62 /* STPConfirmUSBankAccountOptions.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = STPConfirmUSBankAccountOptions.swift; path = "StripePayments/StripePayments/API Bindings/Models/PaymentIntents/STPConfirmUSBankAccountOptions.swift"; sourceTree = ""; }; + 34B323CCEC4BAF3077A937A36605C648 /* ToSucceed.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ToSucceed.swift; path = Sources/Nimble/Matchers/ToSucceed.swift; sourceTree = ""; }; + 3528BD4868D8574FF2FB171DA2BFBB5F /* STDSDeviceInformation.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = STDSDeviceInformation.h; path = Stripe3DS2/Stripe3DS2/STDSDeviceInformation.h; sourceTree = ""; }; + 359723CC69A4D0C4E23A59FAA28256D6 /* STPPaymentIntentShippingDetails.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = STPPaymentIntentShippingDetails.swift; path = "StripePayments/StripePayments/API Bindings/Models/PaymentIntents/STPPaymentIntentShippingDetails.swift"; sourceTree = ""; }; + 3664BF9D1DF403E0D5CF6BC73B5171F1 /* STPIntentActionBoletoDisplayDetails.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = STPIntentActionBoletoDisplayDetails.swift; path = "StripePayments/StripePayments/API Bindings/Models/Shared/STPIntentActionBoletoDisplayDetails.swift"; sourceTree = ""; }; + 369928B93AB7FF9854E9571FD5DC9C88 /* STPThreeDSSelectionCustomization.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = STPThreeDSSelectionCustomization.swift; path = StripePayments/StripePayments/PaymentHandler/STPThreeDSSelectionCustomization.swift; sourceTree = ""; }; + 36B234BEA176DCA527565B3A67899B7B /* StripePayments.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = StripePayments.release.xcconfig; sourceTree = ""; }; + 372B25E935274FF2EDD7057837EDF8A2 /* STPPaymentMethodLink.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = STPPaymentMethodLink.swift; path = "StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodLink.swift"; sourceTree = ""; }; + 3744BDC1A0806F0DED894A00F2712B86 /* NSError+Stripe.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "NSError+Stripe.swift"; path = "StripeCore/StripeCore/Source/Categories/NSError+Stripe.swift"; sourceTree = ""; }; + 387CCC265AED18EEACFA2BA602EE1EE0 /* pt-PT.lproj */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = folder; name = "pt-PT.lproj"; path = "StripeCore/StripeCore/Resources/Localizations/pt-PT.lproj"; sourceTree = ""; }; + 38FDD264C34D13D6C5139E02B5E3429E /* STDSIPAddress.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = STDSIPAddress.m; path = Stripe3DS2/Stripe3DS2/STDSIPAddress.m; sourceTree = ""; }; + 398F0E06C95778B6C5BD548556C7E2D7 /* Nimble-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Nimble-Info.plist"; sourceTree = ""; }; + 39A89F94F62DD307FA1B976758F78D73 /* STDSOSVersionChecker.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = STDSOSVersionChecker.h; path = Stripe3DS2/Stripe3DS2/STDSOSVersionChecker.h; sourceTree = ""; }; + 3B34FEC150B5B0919521FF02A278AD6D /* NSDictionary+Stripe.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "NSDictionary+Stripe.swift"; path = "StripePayments/StripePayments/Internal/Categories/NSDictionary+Stripe.swift"; sourceTree = ""; }; + 3C564FA0EBC44CDB08A1444DED329837 /* STPPaymentMethodFPX.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = STPPaymentMethodFPX.swift; path = "StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodFPX.swift"; sourceTree = ""; }; + 3C8564A486877CE043FB241FDB66590F /* NSString+JWEHelpers.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "NSString+JWEHelpers.h"; path = "Stripe3DS2/Stripe3DS2/NSString+JWEHelpers.h"; sourceTree = ""; }; + 3CA726D8D07BC2DD4AC5CF3D6FB06958 /* STDSTextFieldCustomization.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = STDSTextFieldCustomization.h; path = Stripe3DS2/Stripe3DS2/include/STDSTextFieldCustomization.h; sourceTree = ""; }; + 3CEF0E39AF8543EB7223811AE62CCA59 /* STDSTransaction+Private.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "STDSTransaction+Private.h"; path = "Stripe3DS2/Stripe3DS2/STDSTransaction+Private.h"; sourceTree = ""; }; + 3D08A5A4B5601443EFFFBFB1AC2E385D /* RaisesException.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RaisesException.swift; path = Sources/Nimble/Matchers/RaisesException.swift; sourceTree = ""; }; + 3D468BAE407184775B5DAD5E74EB7816 /* STDSSelectionButton.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = STDSSelectionButton.h; path = Stripe3DS2/Stripe3DS2/STDSSelectionButton.h; sourceTree = ""; }; + 3EDC69638EBE90E82EB702A92E9F5CD9 /* STP3DS2AuthenticateResponse.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = STP3DS2AuthenticateResponse.swift; path = "StripePayments/StripePayments/Internal/API Bindings/STP3DS2AuthenticateResponse.swift"; sourceTree = ""; }; + 3F8FD76A24715EC95CF1509BEF6C3A0E /* cs-CZ.lproj */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = folder; name = "cs-CZ.lproj"; path = "StripePayments/StripePayments/Resources/Localizations/cs-CZ.lproj"; sourceTree = ""; }; + 4038C3A365C65E433FE06CA7BA58F8C6 /* STPCollectBankAccountParams.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = STPCollectBankAccountParams.swift; path = "StripePayments/StripePayments/API Bindings/Models/ACH/STPCollectBankAccountParams.swift"; sourceTree = ""; }; + 40B004CC31F235FB5D0299B92F3F939A /* STDSJSONWebEncryption.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = STDSJSONWebEncryption.m; path = Stripe3DS2/Stripe3DS2/STDSJSONWebEncryption.m; sourceTree = ""; }; + 40CD3D7CB1BB2C1DD656112E382319D1 /* StripeCore-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "StripeCore-Info.plist"; sourceTree = ""; }; + 411D3501805F770A6EDF01F816BAC6B5 /* NSLayoutConstraint+LayoutSupport.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "NSLayoutConstraint+LayoutSupport.h"; path = "Stripe3DS2/Stripe3DS2/NSLayoutConstraint+LayoutSupport.h"; sourceTree = ""; }; + 413E55C32B8C10177DAFE56899148490 /* DSL.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = DSL.swift; path = Sources/Quick/DSL/DSL.swift; sourceTree = ""; }; + 42079B2294C0AE31BA9D6760783EF328 /* UIImage+StripeCore.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "UIImage+StripeCore.swift"; path = "StripeCore/StripeCore/Source/Categories/UIImage+StripeCore.swift"; sourceTree = ""; }; + 42C0C827BD5426B6D3D5EAE30475AC10 /* STPLocalizedString.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = STPLocalizedString.swift; path = StripeCore/StripeCore/Source/Localization/STPLocalizedString.swift; sourceTree = ""; }; + 438D5204F2714F9C297FB5C27756E888 /* StripePayments */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = StripePayments; path = StripePayments.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 43E16FAAC49A3E73F1961D1CB93BF9BE /* STPBankAccountCollector.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = STPBankAccountCollector.swift; path = StripePayments/StripePayments/Helpers/STPBankAccountCollector.swift; sourceTree = ""; }; + 43EED01D17611406F7B707B384FC23B2 /* Nimble-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Nimble-prefix.pch"; sourceTree = ""; }; + 442207253E69A546D816A69280A04D3F /* STPPaymentIntentAction.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = STPPaymentIntentAction.swift; path = "StripePayments/StripePayments/API Bindings/Models/PaymentIntents/STPPaymentIntentAction.swift"; sourceTree = ""; }; + 4450AF2E54ADCF5F7D4B4EAE994D4408 /* NSMutableURLRequest+Stripe.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "NSMutableURLRequest+Stripe.swift"; path = "StripeCore/StripeCore/Source/Categories/NSMutableURLRequest+Stripe.swift"; sourceTree = ""; }; + 44669529D230594202E1BBACB273334B /* CwlCatchException.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = CwlCatchException.h; path = Carthage/Checkouts/CwlCatchException/Sources/CwlCatchExceptionSupport/include/CwlCatchException.h; sourceTree = ""; }; + 44883319135827CA66740EFB62CC7429 /* STPConnectAccountAddress.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = STPConnectAccountAddress.swift; path = "StripePayments/StripePayments/API Bindings/Models/STPConnectAccountAddress.swift"; sourceTree = ""; }; + 452B1991BCE20FF2407E6F731208FFC4 /* STDSErrorMessage+Internal.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "STDSErrorMessage+Internal.h"; path = "Stripe3DS2/Stripe3DS2/STDSErrorMessage+Internal.h"; sourceTree = ""; }; + 45CC895FC6FB5B914EAD7243B1458122 /* UIButton+CustomInitialization.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "UIButton+CustomInitialization.h"; path = "Stripe3DS2/Stripe3DS2/UIButton+CustomInitialization.h"; sourceTree = ""; }; + 46AE2E6FEA38E6A3B1ADF0A2A083411B /* STPPaymentMethodCardNetworks.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = STPPaymentMethodCardNetworks.swift; path = "StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodCardNetworks.swift"; sourceTree = ""; }; + 46BB6A49A4825C4F1703C49EAD7D5BE3 /* STDSEphemeralKeyPair.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = STDSEphemeralKeyPair.m; path = Stripe3DS2/Stripe3DS2/STDSEphemeralKeyPair.m; sourceTree = ""; }; + 46CE0A5841318D1F266C9D542B69B9DF /* STPPaymentMethodGiropayParams.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = STPPaymentMethodGiropayParams.swift; path = "StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodGiropayParams.swift"; sourceTree = ""; }; + 46DD3A21888BE80122BB4C39AECE8C66 /* STDSRuntimeErrorEvent.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = STDSRuntimeErrorEvent.h; path = Stripe3DS2/Stripe3DS2/include/STDSRuntimeErrorEvent.h; sourceTree = ""; }; + 47360F9CFB9809719DBC7DC58EE3222F /* STPPaymentMethodBLIK.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = STPPaymentMethodBLIK.swift; path = "StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodBLIK.swift"; sourceTree = ""; }; + 47AEC729BAF456DCA88A96334C835B27 /* STPPaymentMethodSEPADebit.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = STPPaymentMethodSEPADebit.swift; path = "StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodSEPADebit.swift"; sourceTree = ""; }; + 47F9BE5443E9C7DAEC42690265EC06C7 /* sv.lproj */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = folder; name = sv.lproj; path = StripeCore/StripeCore/Resources/Localizations/sv.lproj; sourceTree = ""; }; + 4826274260E8C1435364904F6E10BAAD /* URLEncoder.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = URLEncoder.swift; path = StripeCore/StripeCore/Source/Helpers/URLEncoder.swift; sourceTree = ""; }; + 48669968B1C33265AE0FF8820DFBB191 /* STDSDeviceInformation.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = STDSDeviceInformation.m; path = Stripe3DS2/Stripe3DS2/STDSDeviceInformation.m; sourceTree = ""; }; + 4877F075C2758793EC28F510F8C33578 /* zh-Hant.lproj */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = folder; name = "zh-Hant.lproj"; path = "Stripe3DS2/Stripe3DS2/Resources/zh-Hant.lproj"; sourceTree = ""; }; + 498401C6C3549CA6217606C586D593A2 /* STPSetupIntentLastSetupError.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = STPSetupIntentLastSetupError.swift; path = "StripePayments/StripePayments/API Bindings/Models/SetupIntents/STPSetupIntentLastSetupError.swift"; sourceTree = ""; }; + 49A14E85E3585B6652A5D97440A4D055 /* DSL+Wait.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "DSL+Wait.swift"; path = "Sources/Nimble/DSL+Wait.swift"; sourceTree = ""; }; + 4A4FC791246944C8E6B8796F90D27EAA /* STPPaymentMethodCardParams.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = STPPaymentMethodCardParams.swift; path = "StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodCardParams.swift"; sourceTree = ""; }; + 4A69A2B39F392EEAEE288BC29547CD71 /* nl.lproj */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = folder; name = nl.lproj; path = StripeCore/StripeCore/Resources/Localizations/nl.lproj; sourceTree = ""; }; + 4B86CA140DC662A1614E7C61BB493169 /* ca-ES.lproj */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = folder; name = "ca-ES.lproj"; path = "StripeCore/StripeCore/Resources/Localizations/ca-ES.lproj"; sourceTree = ""; }; + 4BC54E260BB8693DC327C31BEF4E1C23 /* sv.lproj */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = folder; name = sv.lproj; path = StripePayments/StripePayments/Resources/Localizations/sv.lproj; sourceTree = ""; }; 4C157CC35B7ABF301C81384661B151DC /* Pods-OSPaymentsLib.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-OSPaymentsLib.debug.xcconfig"; sourceTree = ""; }; - 4C965F64744CB14D8F6E2C2BBB97F4DD /* Nimble.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = Nimble.modulemap; sourceTree = ""; }; - 50FAC3D0F71CAC2AEF632440A982DF9D /* ExampleMetadata.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ExampleMetadata.swift; path = Sources/Quick/ExampleMetadata.swift; sourceTree = ""; }; - 51320337A23D4A8E10E00BFD67B8D043 /* ToSucceed.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ToSucceed.swift; path = Sources/Nimble/Matchers/ToSucceed.swift; sourceTree = ""; }; - 516931D0E6A9461B9C20990FA366E1F9 /* Match.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Match.swift; path = Sources/Nimble/Matchers/Match.swift; sourceTree = ""; }; - 51BA9038051E613E9BCC9972FB613CD3 /* Quick.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = Quick.release.xcconfig; sourceTree = ""; }; - 5273DD569D843C265AF46176F4A534FD /* BeVoid.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = BeVoid.swift; path = Sources/Nimble/Matchers/BeVoid.swift; sourceTree = ""; }; - 5523F3CB4F893F0BF3631D865BEEC2B4 /* AdapterProtocols.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = AdapterProtocols.swift; path = Sources/Nimble/Adapters/AdapterProtocols.swift; sourceTree = ""; }; - 5813F3776773A4275874BC369BB34A01 /* ExampleGroup.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ExampleGroup.swift; path = Sources/Quick/ExampleGroup.swift; sourceTree = ""; }; - 586B5A37C0A10198805DA6175B2EB342 /* BeLessThanOrEqual.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = BeLessThanOrEqual.swift; path = Sources/Nimble/Matchers/BeLessThanOrEqual.swift; sourceTree = ""; }; + 4C94DA0E96F62A89B36D4FAD754C1ED2 /* QuickSpec.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = QuickSpec.h; path = Sources/QuickObjectiveC/QuickSpec.h; sourceTree = ""; }; + 4CB99E2C8E159ACE62BE2D838C454D60 /* ThrowError.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ThrowError.swift; path = Sources/Nimble/Matchers/ThrowError.swift; sourceTree = ""; }; + 4CE19E837C101FE89DCEB4A796803AB2 /* cs-CZ.lproj */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = folder; name = "cs-CZ.lproj"; path = "Stripe3DS2/Stripe3DS2/Resources/cs-CZ.lproj"; sourceTree = ""; }; + 4D24EB31497D5ED7C72E3821B8B5DFF9 /* Decimal+StripeCore.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "Decimal+StripeCore.swift"; path = "StripeCore/StripeCore/Source/Categories/Decimal+StripeCore.swift"; sourceTree = ""; }; + 4D260EAF391420AEA7D4195E8CB97705 /* NSString+Stripe.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "NSString+Stripe.swift"; path = "StripePayments/StripePayments/Internal/Categories/NSString+Stripe.swift"; sourceTree = ""; }; + 4E59E51F071F6568DA9481DE99B8E944 /* ElementsEqual.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ElementsEqual.swift; path = Sources/Nimble/Matchers/ElementsEqual.swift; sourceTree = ""; }; + 4EDB069FE5B735AB6777009C5B0A8417 /* STPThreeDSNavigationBarCustomization.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = STPThreeDSNavigationBarCustomization.swift; path = StripePayments/StripePayments/PaymentHandler/STPThreeDSNavigationBarCustomization.swift; sourceTree = ""; }; + 4F1D688AD2265A75D8EFB9221F7EB778 /* BeNil.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = BeNil.swift; path = Sources/Nimble/Matchers/BeNil.swift; sourceTree = ""; }; + 4FC1520119487BEAC759E99C34521BBD /* STDSButtonCustomization.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = STDSButtonCustomization.m; path = Stripe3DS2/Stripe3DS2/STDSButtonCustomization.m; sourceTree = ""; }; + 5126E22B7F9BDB09DB115787314D4DF9 /* STDSSelectionCustomization.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = STDSSelectionCustomization.m; path = Stripe3DS2/Stripe3DS2/STDSSelectionCustomization.m; sourceTree = ""; }; + 515609AFE656AE99F197C89E04E08C5F /* pl-PL.lproj */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = folder; name = "pl-PL.lproj"; path = "StripePayments/StripePayments/Resources/Localizations/pl-PL.lproj"; sourceTree = ""; }; + 51A9DE9335F7CC0592DC7AA72D3B4A63 /* sk-SK.lproj */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = folder; name = "sk-SK.lproj"; path = "Stripe3DS2/Stripe3DS2/Resources/sk-SK.lproj"; sourceTree = ""; }; + 51BA3F2D891B91AE07E4A51BEA563303 /* STPPaymentIntentActionRedirectToURL.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = STPPaymentIntentActionRedirectToURL.swift; path = "StripePayments/StripePayments/API Bindings/Models/PaymentIntents/STPPaymentIntentActionRedirectToURL.swift"; sourceTree = ""; }; + 52AFBF1868EC913273D1B45D0CBE93E5 /* STPPaymentIntentSourceActionAuthorizeWithURL.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = STPPaymentIntentSourceActionAuthorizeWithURL.swift; path = "StripePayments/StripePayments/API Bindings/Models/PaymentIntents/STPPaymentIntentSourceActionAuthorizeWithURL.swift"; sourceTree = ""; }; + 53D48585E0DD371E7575082F5E5D2FA6 /* Enums+CustomStringConvertible.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "Enums+CustomStringConvertible.swift"; path = "StripeCore/StripeCore/Source/Categories/Enums+CustomStringConvertible.swift"; sourceTree = ""; }; + 53EBB9D86B35E049D6F865320CDCE915 /* hr.lproj */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = folder; name = hr.lproj; path = StripePayments/StripePayments/Resources/Localizations/hr.lproj; sourceTree = ""; }; + 5450B5EC7ACBAB30D5FEFE776CBB94C8 /* STDSStackView.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = STDSStackView.h; path = Stripe3DS2/Stripe3DS2/STDSStackView.h; sourceTree = ""; }; + 546C97E71464A08D279EDEDCBC44A6DD /* STDSCompletionEvent.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = STDSCompletionEvent.h; path = Stripe3DS2/Stripe3DS2/include/STDSCompletionEvent.h; sourceTree = ""; }; + 54808C6C88411583D225CB43662CF2A8 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS14.0.sdk/System/Library/Frameworks/Foundation.framework; sourceTree = DEVELOPER_DIR; }; + 5499F2612A331A8CBD93E46EEE3D1650 /* STDSException+Internal.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "STDSException+Internal.h"; path = "Stripe3DS2/Stripe3DS2/STDSException+Internal.h"; sourceTree = ""; }; + 54F009A4863C281F89977236F98D9E83 /* Async.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Async.swift; path = Sources/Nimble/Matchers/Async.swift; sourceTree = ""; }; + 557D02A61618BFDAD32138A9A64EF81B /* CwlCatchBadInstruction.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = CwlCatchBadInstruction.swift; path = Carthage/Checkouts/CwlPreconditionTesting/Sources/CwlPreconditionTesting/CwlCatchBadInstruction.swift; sourceTree = ""; }; + 55ED1A89217E66F3DDA8E2191F28E79D /* STDSCategoryLinker.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = STDSCategoryLinker.h; path = Stripe3DS2/Stripe3DS2/STDSCategoryLinker.h; sourceTree = ""; }; + 562E27F799AF54E6BE1994FF9A310A7D /* UserDefaults+PaymentsCore.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "UserDefaults+PaymentsCore.swift"; path = "StripeCore/StripeCore/Source/Telemetry/UserDefaults+PaymentsCore.swift"; sourceTree = ""; }; + 568118646C2B9E717286C4651734B8D0 /* STDSLabelCustomization.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = STDSLabelCustomization.h; path = Stripe3DS2/Stripe3DS2/include/STDSLabelCustomization.h; sourceTree = ""; }; + 569C2A06774DF971F12A7C47C3884DA8 /* STPPaymentMethodUPI.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = STPPaymentMethodUPI.swift; path = "StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodUPI.swift"; sourceTree = ""; }; + 56A20ECC61E5D19EA0EFC66B905D1B01 /* STPAPIClient+ApplePay.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "STPAPIClient+ApplePay.swift"; path = "StripePayments/StripePayments/API Bindings/STPAPIClient+ApplePay.swift"; sourceTree = ""; }; + 56A4C47B9C636C2E9C2169375FE3B87C /* STDSThreeDS2Service.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = STDSThreeDS2Service.m; path = Stripe3DS2/Stripe3DS2/STDSThreeDS2Service.m; sourceTree = ""; }; + 56A8426512B05F3F66165BE187E7DBC3 /* STDSSynchronousLocationManager.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = STDSSynchronousLocationManager.m; path = Stripe3DS2/Stripe3DS2/STDSSynchronousLocationManager.m; sourceTree = ""; }; + 57FE59621959B645AB0D91EE111D73C8 /* STPPaymentMethodCardWalletVisaCheckout.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = STPPaymentMethodCardWalletVisaCheckout.swift; path = "StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodCardWalletVisaCheckout.swift"; sourceTree = ""; }; + 5907CE599DD4F4A5314A7E446C1548A1 /* hu.lproj */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = folder; name = hu.lproj; path = StripeCore/StripeCore/Resources/Localizations/hu.lproj; sourceTree = ""; }; + 593760824E1E512A3DF423BF1EA3F721 /* STPAppInfo.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = STPAppInfo.swift; path = "StripeCore/StripeCore/Source/API Bindings/STPAppInfo.swift"; sourceTree = ""; }; + 597423E1AFB4A8E43A79EB62B8BCD961 /* STPKlarnaLineItem.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = STPKlarnaLineItem.swift; path = "StripePayments/StripePayments/API Bindings/Models/Sources/Types/STPKlarnaLineItem.swift"; sourceTree = ""; }; + 59AA7F922673B41C277C2A84071B636A /* STDSAuthenticationResponseObject.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = STDSAuthenticationResponseObject.h; path = Stripe3DS2/Stripe3DS2/STDSAuthenticationResponseObject.h; sourceTree = ""; }; + 59B2447710747DADA1A7FDE8E5D17BA8 /* STPAPIClient+LinkAccountSession.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "STPAPIClient+LinkAccountSession.swift"; path = "StripePayments/StripePayments/API Bindings/STPAPIClient+LinkAccountSession.swift"; sourceTree = ""; }; + 5A087B8B9AC3FF949E888C616D76603B /* String+StripeCore.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "String+StripeCore.swift"; path = "StripeCore/StripeCore/Source/Categories/String+StripeCore.swift"; sourceTree = ""; }; + 5A2D473CCF42F10E99266371FED0508B /* es-419.lproj */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = folder; name = "es-419.lproj"; path = "Stripe3DS2/Stripe3DS2/Resources/es-419.lproj"; sourceTree = ""; }; + 5A5C99F67007365C562DD1294DBD73DA /* STPRadarSession.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = STPRadarSession.swift; path = "StripePayments/StripePayments/API Bindings/Models/STPRadarSession.swift"; sourceTree = ""; }; + 5A7E15112F94F1128C0AE9FCBAB8DDF6 /* BeCloseTo.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = BeCloseTo.swift; path = Sources/Nimble/Matchers/BeCloseTo.swift; sourceTree = ""; }; 5AAA74622C8B0B2167156F4EBE359608 /* Pods-OSPaymentsLib.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-OSPaymentsLib.release.xcconfig"; sourceTree = ""; }; - 5B95333BD525E87BFF22C57ED6E20FD5 /* BeAKindOf.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = BeAKindOf.swift; path = Sources/Nimble/Matchers/BeAKindOf.swift; sourceTree = ""; }; - 5C8E70599736912CA1DB7FCDD472F2B2 /* DSL.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = DSL.h; path = Sources/NimbleObjectiveC/DSL.h; sourceTree = ""; }; - 5EBC8F300895E39EA0DF6D6B2B5E6BCD /* XCTest.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = XCTest.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS14.0.sdk/System/Library/Frameworks/XCTest.framework; sourceTree = DEVELOPER_DIR; }; - 60403D3F19863854702A6361D7F61850 /* QuickSpecBase.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = QuickSpecBase.h; path = Sources/QuickObjCRuntime/include/QuickSpecBase.h; sourceTree = ""; }; - 622317B228B6CF5C9D75DA1008B0F2B8 /* QuickObjCRuntime.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = QuickObjCRuntime.h; path = Sources/QuickObjCRuntime/include/QuickObjCRuntime.h; sourceTree = ""; }; - 64B896AB55261B6E62E0FC506B92A8EC /* AssertionRecorder.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = AssertionRecorder.swift; path = Sources/Nimble/Adapters/AssertionRecorder.swift; sourceTree = ""; }; - 654A3ADC4BC6E05E9BDC2D8F858A74BA /* CwlCatchException.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = CwlCatchException.m; path = Carthage/Checkouts/CwlCatchException/Sources/CwlCatchExceptionSupport/CwlCatchException.m; sourceTree = ""; }; - 67A91DF9E678606788A96C9150D53EA6 /* Expression.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Expression.swift; path = Sources/Nimble/Expression.swift; sourceTree = ""; }; - 6BAC25BC63EBD14D35CDE94813660768 /* MatchError.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = MatchError.swift; path = Sources/Nimble/Matchers/MatchError.swift; sourceTree = ""; }; - 6C5852911233E16D8DBA632AAF28C4C0 /* BeNil.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = BeNil.swift; path = Sources/Nimble/Matchers/BeNil.swift; sourceTree = ""; }; - 6E6AA1575C0AD81F762039746AFAECDC /* Stringers.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Stringers.swift; path = Sources/Nimble/Utils/Stringers.swift; sourceTree = ""; }; - 718ABA2E524F929C4106CFE711012B87 /* Quick.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = Quick.modulemap; sourceTree = ""; }; + 5AE4E50BAA23DE344F16F409B862C98F /* STDSProgressViewController.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = STDSProgressViewController.m; path = Stripe3DS2/Stripe3DS2/STDSProgressViewController.m; sourceTree = ""; }; + 5AF1751BC3596620650014810E422E40 /* STDSBundleLocator.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = STDSBundleLocator.m; path = Stripe3DS2/Stripe3DS2/STDSBundleLocator.m; sourceTree = ""; }; + 5B2A61D11231525A85BFE695B2A33DCF /* vi.lproj */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = folder; name = vi.lproj; path = StripePayments/StripePayments/Resources/Localizations/vi.lproj; sourceTree = ""; }; + 5BE72988C0B88C57D8FAD6C8D7BF2DE4 /* STPAPIClient+Radar.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "STPAPIClient+Radar.swift"; path = "StripePayments/StripePayments/API Bindings/STPAPIClient+Radar.swift"; sourceTree = ""; }; + 5C170C5ECB65313D7033A335EA627EF2 /* sl-SI.lproj */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = folder; name = "sl-SI.lproj"; path = "StripeCore/StripeCore/Resources/Localizations/sl-SI.lproj"; sourceTree = ""; }; + 5C42087462E099CF003FF1BEB4B6887B /* fil.lproj */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = folder; name = fil.lproj; path = Stripe3DS2/Stripe3DS2/Resources/fil.lproj; sourceTree = ""; }; + 5C9C58815409E510E46AB774447F4480 /* fr-CA.lproj */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = folder; name = "fr-CA.lproj"; path = "Stripe3DS2/Stripe3DS2/Resources/fr-CA.lproj"; sourceTree = ""; }; + 5CCFE00FEAB101DA92225E44E87BA2F0 /* de.lproj */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = folder; name = de.lproj; path = StripeCore/StripeCore/Resources/Localizations/de.lproj; sourceTree = ""; }; + 5DE351F6BD87FDFAA928A765F4FD42B1 /* STPPaymentMethodBLIKParams.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = STPPaymentMethodBLIKParams.swift; path = "StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodBLIKParams.swift"; sourceTree = ""; }; + 5DFDD80575DD9A05A06ED19D4D52AE70 /* STDSDirectoryServerCertificate+Internal.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "STDSDirectoryServerCertificate+Internal.h"; path = "Stripe3DS2/Stripe3DS2/STDSDirectoryServerCertificate+Internal.h"; sourceTree = ""; }; + 5E6FE7DE869B97FD231A9E841B9A515D /* STPSourceOwner.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = STPSourceOwner.swift; path = "StripePayments/StripePayments/API Bindings/Models/Sources/STPSourceOwner.swift"; sourceTree = ""; }; + 5E98E0A80EACE6D763BFF6171F22E5AF /* STDSThreeDSProtocolVersion+Private.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "STDSThreeDSProtocolVersion+Private.h"; path = "Stripe3DS2/Stripe3DS2/STDSThreeDSProtocolVersion+Private.h"; sourceTree = ""; }; + 5EC537635899CA4178859BACFF28917D /* StripeCore-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "StripeCore-dummy.m"; sourceTree = ""; }; + 5F226DBA46EA23FC0AD0054FA29C08C5 /* STDSRuntimeErrorEvent.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = STDSRuntimeErrorEvent.m; path = Stripe3DS2/Stripe3DS2/STDSRuntimeErrorEvent.m; sourceTree = ""; }; + 5F42A1E0E18999703CBBFEBB56145E7F /* STDSExpandableInformationView.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = STDSExpandableInformationView.m; path = Stripe3DS2/Stripe3DS2/STDSExpandableInformationView.m; sourceTree = ""; }; + 5FC2114F70469E415B7E2747DA3C7FBE /* BeIdenticalTo.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = BeIdenticalTo.swift; path = Sources/Nimble/Matchers/BeIdenticalTo.swift; sourceTree = ""; }; + 5FE6F6AD5F607A825507562A6AF83790 /* STPToken.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = STPToken.swift; path = "StripePayments/StripePayments/API Bindings/Models/STPToken.swift"; sourceTree = ""; }; + 60AB9ADFC4EF35A2857FB4F515E28C77 /* STPLocalizationUtils.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = STPLocalizationUtils.swift; path = StripeCore/StripeCore/Source/Localization/STPLocalizationUtils.swift; sourceTree = ""; }; + 611A742A8611B58B61FB2CB1A9BF2426 /* UIFont+DefaultFonts.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "UIFont+DefaultFonts.m"; path = "Stripe3DS2/Stripe3DS2/UIFont+DefaultFonts.m"; sourceTree = ""; }; + 619E50D28D3CD3C702827667E0DC6C0C /* vi.lproj */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = folder; name = vi.lproj; path = Stripe3DS2/Stripe3DS2/Resources/vi.lproj; sourceTree = ""; }; + 61FA3AB7DB6ED5397FCCAF504A9CE2EE /* zh-Hans.lproj */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = folder; name = "zh-Hans.lproj"; path = "StripePayments/StripePayments/Resources/Localizations/zh-Hans.lproj"; sourceTree = ""; }; + 621387BC9C0ACA90CA0242F6AB9CD213 /* STPDispatchFunctions.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = STPDispatchFunctions.swift; path = StripeCore/StripeCore/Source/Helpers/STPDispatchFunctions.swift; sourceTree = ""; }; + 625A9EBBEE9AE746354C27F9C844BDEB /* STDSCompletionEvent.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = STDSCompletionEvent.m; path = Stripe3DS2/Stripe3DS2/STDSCompletionEvent.m; sourceTree = ""; }; + 634823EB04265CECC1ACDC95F5DC0559 /* es.lproj */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = folder; name = es.lproj; path = StripeCore/StripeCore/Resources/Localizations/es.lproj; sourceTree = ""; }; + 6377BB294354AAC8F5CF936CE45A39E9 /* STPIntentActionWeChatPayRedirectToApp.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = STPIntentActionWeChatPayRedirectToApp.swift; path = "StripePayments/StripePayments/API Bindings/Models/Shared/STPIntentActionWeChatPayRedirectToApp.swift"; sourceTree = ""; }; + 640EC78C807E1AA131D2EB0F2652750C /* STPThreeDSTextFieldCustomization.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = STPThreeDSTextFieldCustomization.swift; path = StripePayments/StripePayments/PaymentHandler/STPThreeDSTextFieldCustomization.swift; sourceTree = ""; }; + 64754D3C8EFC85ABC74074BD01D0B438 /* PluginDetector.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = PluginDetector.swift; path = StripeCore/StripeCore/Source/Analytics/PluginDetector.swift; sourceTree = ""; }; + 64B0E91A7B514C7093443DFC1DF53787 /* id.lproj */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = folder; name = id.lproj; path = StripeCore/StripeCore/Resources/Localizations/id.lproj; sourceTree = ""; }; + 653C3FC026CBEB87F5C175C0FF6DC590 /* STPBINController.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = STPBINController.swift; path = StripePayments/StripePayments/Helpers/STPBINController.swift; sourceTree = ""; }; + 65688FB4E15C22FBFBB007D1A68DCB72 /* es.lproj */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = folder; name = es.lproj; path = StripePayments/StripePayments/Resources/Localizations/es.lproj; sourceTree = ""; }; + 658CA849B7FD68987A046BA203033A20 /* tr.lproj */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = folder; name = tr.lproj; path = StripeCore/StripeCore/Resources/Localizations/tr.lproj; sourceTree = ""; }; + 6597BB764328DA90E4C2A7D1E4BB6770 /* zh-Hans.lproj */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = folder; name = "zh-Hans.lproj"; path = "Stripe3DS2/Stripe3DS2/Resources/zh-Hans.lproj"; sourceTree = ""; }; + 65D60532E0DFB8FA1617519318FBB503 /* AdapterProtocols.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = AdapterProtocols.swift; path = Sources/Nimble/Adapters/AdapterProtocols.swift; sourceTree = ""; }; + 65E460ED1ED288806FF0433F7C9E2668 /* STPInternalAPIResponseDecodable.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = STPInternalAPIResponseDecodable.swift; path = "StripePayments/StripePayments/Internal/API Bindings/STPInternalAPIResponseDecodable.swift"; sourceTree = ""; }; + 65F202B9FC21F6175762715A47B8A591 /* XCTestObservationCenter+Register.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "XCTestObservationCenter+Register.m"; path = "Sources/NimbleObjectiveC/XCTestObservationCenter+Register.m"; sourceTree = ""; }; + 66046363AA74B29375751A2D4FE68CC7 /* lt-LT.lproj */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = folder; name = "lt-LT.lproj"; path = "StripeCore/StripeCore/Resources/Localizations/lt-LT.lproj"; sourceTree = ""; }; + 6683A27B85EA014BFD6E373385D1110E /* STPSource.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = STPSource.swift; path = "StripePayments/StripePayments/API Bindings/Models/Sources/STPSource.swift"; sourceTree = ""; }; + 669104F1E97535717BDCE249A3587195 /* Stringers.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Stringers.swift; path = Sources/Nimble/Utils/Stringers.swift; sourceTree = ""; }; + 6743D6B280FD6633C1199C27DB374029 /* Equal.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Equal.swift; path = Sources/Nimble/Matchers/Equal.swift; sourceTree = ""; }; + 67BE6311C4F34E8994712859CD9CC1B1 /* STPFormEncodable.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = STPFormEncodable.swift; path = "StripePayments/StripePayments/API Bindings/Models/STPFormEncodable.swift"; sourceTree = ""; }; + 680C1DF5B047CCCB5CC6AAD90C501F63 /* BeGreaterThanOrEqualTo.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = BeGreaterThanOrEqualTo.swift; path = Sources/Nimble/Matchers/BeGreaterThanOrEqualTo.swift; sourceTree = ""; }; + 68C460E9ECE53C9DD237B0E8B6270A7A /* STPIntentActionOXXODisplayDetails.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = STPIntentActionOXXODisplayDetails.swift; path = "StripePayments/StripePayments/API Bindings/Models/Shared/STPIntentActionOXXODisplayDetails.swift"; sourceTree = ""; }; + 68E237402E23B9113D778F5A18968D4A /* zh-HK.lproj */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = folder; name = "zh-HK.lproj"; path = "Stripe3DS2/Stripe3DS2/Resources/zh-HK.lproj"; sourceTree = ""; }; + 693E1FDF28EBF010E045BA1CBECFE690 /* Behavior.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Behavior.swift; path = Sources/Quick/Behavior.swift; sourceTree = ""; }; + 69C0509774EAEAF4CF9BC2D02989049F /* STDSWarning.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = STDSWarning.h; path = Stripe3DS2/Stripe3DS2/include/STDSWarning.h; sourceTree = ""; }; + 6A7BB7F3F161A2073468BD2DCAEC6BD0 /* nl.lproj */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = folder; name = nl.lproj; path = Stripe3DS2/Stripe3DS2/Resources/nl.lproj; sourceTree = ""; }; + 6B50A752E2809107CB299D3C0202B2B1 /* STPSourceWeChatPayDetails.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = STPSourceWeChatPayDetails.swift; path = "StripePayments/StripePayments/API Bindings/Models/Sources/Types/STPSourceWeChatPayDetails.swift"; sourceTree = ""; }; + 6B5B072397E3B84F6004C05A7BE64C29 /* STPPaymentMethodPrzelewy24.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = STPPaymentMethodPrzelewy24.swift; path = "StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodPrzelewy24.swift"; sourceTree = ""; }; + 6B79B7AE0DCE08C4DBCB032571274473 /* en-GB.lproj */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = folder; name = "en-GB.lproj"; path = "StripeCore/StripeCore/Resources/Localizations/en-GB.lproj"; sourceTree = ""; }; + 6C597B8E71A5E225982129EECCCDF62F /* STDSIntegrityChecker.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = STDSIntegrityChecker.m; path = Stripe3DS2/Stripe3DS2/STDSIntegrityChecker.m; sourceTree = ""; }; + 6D5BF6A82D35D5DA69E94704D9DA5511 /* QuickSpecBase.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = QuickSpecBase.m; path = Sources/QuickObjCRuntime/QuickSpecBase.m; sourceTree = ""; }; + 6EA8928C59E02CC416929F0C2B66219E /* UIColor+DefaultColors.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "UIColor+DefaultColors.h"; path = "Stripe3DS2/Stripe3DS2/UIColor+DefaultColors.h"; sourceTree = ""; }; + 6F2B6E62B1B30F32268B7A4FECD434AA /* STDSDirectoryServerCertificate.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = STDSDirectoryServerCertificate.m; path = Stripe3DS2/Stripe3DS2/STDSDirectoryServerCertificate.m; sourceTree = ""; }; + 6F2C49A88CCD41F403C5BE7CD357F325 /* STPPaymentMethodThreeDSecureUsage.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = STPPaymentMethodThreeDSecureUsage.swift; path = "StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodThreeDSecureUsage.swift"; sourceTree = ""; }; + 6F38DE58C92533FFAD0D80755E2180B9 /* STPPaymentMethodCardWallet.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = STPPaymentMethodCardWallet.swift; path = "StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodCardWallet.swift"; sourceTree = ""; }; + 6F81E85314042226003AF38B2D84665A /* ExampleHooks.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ExampleHooks.swift; path = Sources/Quick/Hooks/ExampleHooks.swift; sourceTree = ""; }; + 70005C4375CBFB421E6FE86867C46D67 /* STPPaymentMethodAffirm.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = STPPaymentMethodAffirm.swift; path = "StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodAffirm.swift"; sourceTree = ""; }; + 702AA8B503547D54D21CC4D2C7836ECF /* StripeJSONShared.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = StripeJSONShared.swift; path = StripeCore/StripeCore/Source/Coder/StripeJSONShared.swift; sourceTree = ""; }; + 7075296E1C69930CC25D5670AC153811 /* StripePayments-StripePayments */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; name = "StripePayments-StripePayments"; path = StripePayments.bundle; sourceTree = BUILT_PRODUCTS_DIR; }; + 708F5988B98C9B3D16D7E03755DAED4E /* Equal+Tuple.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "Equal+Tuple.swift"; path = "Sources/Nimble/Matchers/Equal+Tuple.swift"; sourceTree = ""; }; + 70A8E487A5A139A0AEBE9CA07D630647 /* STPPaymentHandlerActionParams.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = STPPaymentHandlerActionParams.swift; path = StripePayments/StripePayments/Internal/STPPaymentHandlerActionParams.swift; sourceTree = ""; }; + 70D3FC01AB2025C3F5A9C9B91ACFCCB3 /* FailureMessage.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = FailureMessage.swift; path = Sources/Nimble/FailureMessage.swift; sourceTree = ""; }; + 7214D0F2B31EC4D3B8710F5DEEE20118 /* StripeFile.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = StripeFile.swift; path = "StripeCore/StripeCore/Source/API Bindings/Models/StripeFile.swift"; sourceTree = ""; }; 72650BCF9E15BA7772C201F04B20DF8A /* Pods-OSPaymentsLib-OSPaymentsLibTests-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-OSPaymentsLib-OSPaymentsLibTests-Info.plist"; sourceTree = ""; }; - 755D25C0FCCF8F6E3E59CF4F94C8C060 /* SourceLocation.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SourceLocation.swift; path = Sources/Nimble/Utils/SourceLocation.swift; sourceTree = ""; }; - 766A5EA3A362FFD45458AAB04D1B9FB4 /* Quick-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Quick-prefix.pch"; sourceTree = ""; }; - 7893AC67AE4B488BC3E9604A46413A06 /* BeginWithPrefix.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = BeginWithPrefix.swift; path = Sources/Nimble/Matchers/BeginWithPrefix.swift; sourceTree = ""; }; - 7A7CD7566A962848ACAFAE01FAC08AA6 /* NMBExceptionCapture.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = NMBExceptionCapture.h; path = Sources/NimbleObjectiveC/NMBExceptionCapture.h; sourceTree = ""; }; - 7AE197136F8E380A9F1E7D06BD9D0FAF /* Nimble-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Nimble-prefix.pch"; sourceTree = ""; }; - 7C826AD498684E411DD1C792748D889C /* Nimble.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = Nimble.h; path = Sources/Nimble/Nimble.h; sourceTree = ""; }; - 7CDC6B9AB35B53FC579C731AE67FD846 /* Example.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Example.swift; path = Sources/Quick/Example.swift; sourceTree = ""; }; - 7F6D4322ABB010AB0EEC279249B17918 /* Quick-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Quick-dummy.m"; sourceTree = ""; }; - 8015D0BB35ED18B858B74C6E8656EB00 /* BeWithin.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = BeWithin.swift; path = Sources/Nimble/Matchers/BeWithin.swift; sourceTree = ""; }; - 81CA9AA102BC399952DACFC1F5740345 /* NMBExceptionCapture.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = NMBExceptionCapture.m; path = Sources/NimbleObjectiveC/NMBExceptionCapture.m; sourceTree = ""; }; - 8270027ACBF7A64C2B453CCBFE155E90 /* Nimble.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = Nimble.debug.xcconfig; sourceTree = ""; }; - 844435B050856A3A90F2F2DC5D10C71E /* Equal.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Equal.swift; path = Sources/Nimble/Matchers/Equal.swift; sourceTree = ""; }; - 8470BE37EE9259F9FDADDFC80764A837 /* mach_excServer.c */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.c; name = mach_excServer.c; path = Carthage/Checkouts/CwlPreconditionTesting/Sources/CwlMachBadInstructionHandler/mach_excServer.c; sourceTree = ""; }; - 84CC299AC522B25A61A3FAF124FF83FC /* ContainElementSatisfying.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ContainElementSatisfying.swift; path = Sources/Nimble/Matchers/ContainElementSatisfying.swift; sourceTree = ""; }; - 85254BDDFDC46F27B70DCBF181ADE6FF /* ThrowAssertion.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ThrowAssertion.swift; path = Sources/Nimble/Matchers/ThrowAssertion.swift; sourceTree = ""; }; - 85C9317EF9B3052FC9D544E30801F901 /* Expectation.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Expectation.swift; path = Sources/Nimble/Expectation.swift; sourceTree = ""; }; + 72655EB1E6314CBEB54830C6B89FA058 /* ResourceBundle-StripeCore-StripeCore-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "ResourceBundle-StripeCore-StripeCore-Info.plist"; sourceTree = ""; }; + 72F0E941A7AFBB57CBC007A3A0673090 /* EmptyResponse.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = EmptyResponse.swift; path = "StripeCore/StripeCore/Source/API Bindings/Models/EmptyResponse.swift"; sourceTree = ""; }; + 730FC11E5EFCFE823AA4A65FC44E05AA /* hu.lproj */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = folder; name = hu.lproj; path = StripePayments/StripePayments/Resources/Localizations/hu.lproj; sourceTree = ""; }; + 731CFC342FD7F097CD3710722F6E80E3 /* STDSProgressViewController.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = STDSProgressViewController.h; path = Stripe3DS2/Stripe3DS2/STDSProgressViewController.h; sourceTree = ""; }; + 732D15F8A6E845C2B923303FDF38F371 /* STPConfirmBLIKOptions.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = STPConfirmBLIKOptions.swift; path = "StripePayments/StripePayments/API Bindings/Models/PaymentIntents/STPConfirmBLIKOptions.swift"; sourceTree = ""; }; + 736B04281FE4BF884DED17087BC29FC8 /* STPAPIResponseDecodable.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = STPAPIResponseDecodable.swift; path = "StripePayments/StripePayments/API Bindings/Models/STPAPIResponseDecodable.swift"; sourceTree = ""; }; + 73E701E7BEF084798AF74C32917833B6 /* LinkSettings.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = LinkSettings.swift; path = "StripePayments/StripePayments/API Bindings/Models/Shared/LinkSettings.swift"; sourceTree = ""; }; + 7418FE280E333B264F556BA11328D50C /* STPConnectAccountParams.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = STPConnectAccountParams.swift; path = "StripePayments/StripePayments/API Bindings/Models/STPConnectAccountParams.swift"; sourceTree = ""; }; + 742F741E5982B734AD60D1AF26513D27 /* StripeCoreBundleLocator.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = StripeCoreBundleLocator.swift; path = StripeCore/StripeCore/Source/Helpers/StripeCoreBundleLocator.swift; sourceTree = ""; }; + 746F6973A7CE90E7B8443A2BC02C6A61 /* amex-logo@3x.png */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.png; name = "amex-logo@3x.png"; path = "Stripe3DS2/Stripe3DS2/Resources/Images/amex-logo@3x.png"; sourceTree = ""; }; + 749B79C9C86B7E14C5009B78B1E0D141 /* STPSetupIntentConfirmParams.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = STPSetupIntentConfirmParams.swift; path = "StripePayments/StripePayments/API Bindings/Models/SetupIntents/STPSetupIntentConfirmParams.swift"; sourceTree = ""; }; + 74ABAF9B171607E4E180F645D439201F /* zh-HK.lproj */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = folder; name = "zh-HK.lproj"; path = "StripePayments/StripePayments/Resources/Localizations/zh-HK.lproj"; sourceTree = ""; }; + 74C1334BBB0CD640AEEE942300A5C0F9 /* STPPaymentMethodParams.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = STPPaymentMethodParams.swift; path = "StripePayments/StripePayments/API Bindings/Models/PaymentMethods/STPPaymentMethodParams.swift"; sourceTree = ""; }; + 74CA148030F6253CC496090DE0F88268 /* STPSourceParams.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = STPSourceParams.swift; path = "StripePayments/StripePayments/API Bindings/Models/Sources/STPSourceParams.swift"; sourceTree = ""; }; + 74EB80E25DFDE9813CA10E313C254D8B /* BeResult.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = BeResult.swift; path = Sources/Nimble/Matchers/BeResult.swift; sourceTree = ""; }; + 751C674B6488C830F75741C0CE6C0433 /* NSDecimalNumber+Stripe_Currency.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "NSDecimalNumber+Stripe_Currency.swift"; path = "StripePayments/StripePayments/Internal/Categories/NSDecimalNumber+Stripe_Currency.swift"; sourceTree = ""; }; + 766E347A52AD98B99EEC6F90A69D9F54 /* fi.lproj */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = folder; name = fi.lproj; path = StripeCore/StripeCore/Resources/Localizations/fi.lproj; sourceTree = ""; }; + 772B0769A9D14703FD8D00A8FCFDE4B6 /* visa-logo@3x.png */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.png; name = "visa-logo@3x.png"; path = "Stripe3DS2/Stripe3DS2/Resources/Images/visa-logo@3x.png"; sourceTree = ""; }; + 7730C169501EB9BA94B6002C839BA27D /* STPPaymentMethodiDEAL.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = STPPaymentMethodiDEAL.swift; path = "StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodiDEAL.swift"; sourceTree = ""; }; + 7839E3169FA3787A71E1C01829725758 /* DSL.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = DSL.m; path = Sources/NimbleObjectiveC/DSL.m; sourceTree = ""; }; + 783EDB1FA1DD3BD623BEE6D52F603C55 /* UIButton+CustomInitialization.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "UIButton+CustomInitialization.m"; path = "Stripe3DS2/Stripe3DS2/UIButton+CustomInitialization.m"; sourceTree = ""; }; + 788643DE0B693BF3BE7538FE541BC9CA /* STDSChallengeResponseImageObject.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = STDSChallengeResponseImageObject.m; path = Stripe3DS2/Stripe3DS2/STDSChallengeResponseImageObject.m; sourceTree = ""; }; + 78D87D1A31F44B74600128A212A1CC77 /* el-GR.lproj */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = folder; name = "el-GR.lproj"; path = "StripePayments/StripePayments/Resources/Localizations/el-GR.lproj"; sourceTree = ""; }; + 79E1FC49BF933FE84A26E535CC4BB4AB /* BeAKindOf.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = BeAKindOf.swift; path = Sources/Nimble/Matchers/BeAKindOf.swift; sourceTree = ""; }; + 7A70552201EE224B319451BA38E504C9 /* STPSourceKlarnaDetails.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = STPSourceKlarnaDetails.swift; path = "StripePayments/StripePayments/API Bindings/Models/Sources/Types/STPSourceKlarnaDetails.swift"; sourceTree = ""; }; + 7AAD6070C98EFE973EABC23752F3C257 /* StripePayments+Export.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "StripePayments+Export.swift"; path = "StripePayments/StripePayments/Helpers/StripePayments+Export.swift"; sourceTree = ""; }; + 7ADF2C73CA362B44CA48E40E9B7F17EC /* en.lproj */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = folder; name = en.lproj; path = Stripe3DS2/Stripe3DS2/Resources/en.lproj; sourceTree = ""; }; + 7B645AFAA5A8FCE8E3D884CED75B843A /* StripeCore.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = StripeCore.modulemap; sourceTree = ""; }; + 7B727AD03286B77B339F83B639680C4A /* BeGreaterThan.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = BeGreaterThan.swift; path = Sources/Nimble/Matchers/BeGreaterThan.swift; sourceTree = ""; }; + 7BA04BA2C2F951AEB0629D2648B73A3C /* lv-LV.lproj */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = folder; name = "lv-LV.lproj"; path = "StripePayments/StripePayments/Resources/Localizations/lv-LV.lproj"; sourceTree = ""; }; + 7BD789ACD33E73CFC7D374760BBCFC07 /* STDSStackView.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = STDSStackView.m; path = Stripe3DS2/Stripe3DS2/STDSStackView.m; sourceTree = ""; }; + 7C1EF27595C3111FA09D7019FF5E3331 /* STPAddress.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = STPAddress.swift; path = "StripePayments/StripePayments/API Bindings/Models/STPAddress.swift"; sourceTree = ""; }; + 7C32B5867CD2E1958E06067CD646C7BD /* BeLessThanOrEqual.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = BeLessThanOrEqual.swift; path = Sources/Nimble/Matchers/BeLessThanOrEqual.swift; sourceTree = ""; }; + 7CC131053FC529177E058091853ACBB4 /* STPPaymentMethodNetBanking.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = STPPaymentMethodNetBanking.swift; path = "StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodNetBanking.swift"; sourceTree = ""; }; + 7D56768635E337B85B786680BECE1DFA /* mt.lproj */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = folder; name = mt.lproj; path = Stripe3DS2/Stripe3DS2/Resources/mt.lproj; sourceTree = ""; }; + 7D78A4949D3C0A01AD01CC778EE68505 /* STDSSimulatorChecker.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = STDSSimulatorChecker.h; path = Stripe3DS2/Stripe3DS2/STDSSimulatorChecker.h; sourceTree = ""; }; + 7DBC3A921194DAA2FBCAC320884C52B5 /* StripePayments-Stripe3DS2 */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; name = "StripePayments-Stripe3DS2"; path = Stripe3DS2.bundle; sourceTree = BUILT_PRODUCTS_DIR; }; + 7DDE21D10B22192C6F8A47342258379D /* BeEmpty.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = BeEmpty.swift; path = Sources/Nimble/Matchers/BeEmpty.swift; sourceTree = ""; }; + 7E5046088EC6C2114646D8B07A0EBC24 /* da.lproj */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = folder; name = da.lproj; path = StripePayments/StripePayments/Resources/Localizations/da.lproj; sourceTree = ""; }; + 7E54011CA9597F3B2EC897FD70C4154A /* STPCardParams.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = STPCardParams.swift; path = "StripePayments/StripePayments/API Bindings/Models/Sources/Types/STPCardParams.swift"; sourceTree = ""; }; + 7E874403635CC972DD772EC44534DEBB /* STPPaymentMethodPrzelewy24Params.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = STPPaymentMethodPrzelewy24Params.swift; path = "StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodPrzelewy24Params.swift"; sourceTree = ""; }; + 7E95291ECF86585EA09E49FC52FE512D /* STDSChallengeResponseMessageExtensionObject.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = STDSChallengeResponseMessageExtensionObject.h; path = Stripe3DS2/Stripe3DS2/STDSChallengeResponseMessageExtensionObject.h; sourceTree = ""; }; + 7F2F8FF75072186C7D2D029B07EA0611 /* AssertionDispatcher.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = AssertionDispatcher.swift; path = Sources/Nimble/Adapters/AssertionDispatcher.swift; sourceTree = ""; }; + 7F5F41998EFB37CF78F99CF0F791E95F /* mastercard-logo@3x.png */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.png; name = "mastercard-logo@3x.png"; path = "Stripe3DS2/Stripe3DS2/Resources/Images/mastercard-logo@3x.png"; sourceTree = ""; }; + 7F6BD33A351A88259F6CA8F0B2C37C1C /* UIColor+ThirteenSupport.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "UIColor+ThirteenSupport.m"; path = "Stripe3DS2/Stripe3DS2/UIColor+ThirteenSupport.m"; sourceTree = ""; }; + 805C254CE8924BAF69E8A22BD3CCAFE8 /* STDSChallengeSelectionView.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = STDSChallengeSelectionView.h; path = Stripe3DS2/Stripe3DS2/STDSChallengeSelectionView.h; sourceTree = ""; }; + 80FEF0315875F9EF508E8000273D5416 /* STDSWhitelistView.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = STDSWhitelistView.h; path = Stripe3DS2/Stripe3DS2/STDSWhitelistView.h; sourceTree = ""; }; + 824BDCE6763B4D03610E74DBC30F4903 /* STPPaymentIntent.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = STPPaymentIntent.swift; path = "StripePayments/StripePayments/API Bindings/Models/PaymentIntents/STPPaymentIntent.swift"; sourceTree = ""; }; + 8261E3AB13EAE1E40AF14930BCEEC87A /* STDSJSONWebSignature.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = STDSJSONWebSignature.m; path = Stripe3DS2/Stripe3DS2/STDSJSONWebSignature.m; sourceTree = ""; }; + 82DEB14A320561F457E94CF0C65223E3 /* en.lproj */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = folder; name = en.lproj; path = StripePayments/StripePayments/Resources/Localizations/en.lproj; sourceTree = ""; }; + 83001213CDB2773DE860093689A1E182 /* STPBankAccount.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = STPBankAccount.swift; path = "StripePayments/StripePayments/API Bindings/Models/Sources/Types/STPBankAccount.swift"; sourceTree = ""; }; + 8304758C2DC812DF0770A6790676DB4D /* STDSProcessingView.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = STDSProcessingView.m; path = Stripe3DS2/Stripe3DS2/STDSProcessingView.m; sourceTree = ""; }; + 8319B73D2C997403285319BE83E26C28 /* StripePayments.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = StripePayments.modulemap; sourceTree = ""; }; + 834C33D3D45A0C2D5CCAB4F1C3246EA0 /* UIViewController+Stripe3DS2.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "UIViewController+Stripe3DS2.h"; path = "Stripe3DS2/Stripe3DS2/UIViewController+Stripe3DS2.h"; sourceTree = ""; }; + 836DE9DD2FE1EB8835953F60C015D066 /* STDSTransaction.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = STDSTransaction.m; path = Stripe3DS2/Stripe3DS2/STDSTransaction.m; sourceTree = ""; }; + 83A25F3DE9E03CC60ABD875634EA53F8 /* STDSConfigParameters.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = STDSConfigParameters.h; path = Stripe3DS2/Stripe3DS2/include/STDSConfigParameters.h; sourceTree = ""; }; + 848C2D30B6A61B76B8FEE685ADA9094D /* STPPaymentIntentShippingDetailsAddress.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = STPPaymentIntentShippingDetailsAddress.swift; path = "StripePayments/StripePayments/API Bindings/Models/PaymentIntents/STPPaymentIntentShippingDetailsAddress.swift"; sourceTree = ""; }; + 84AA17F827E17EE953033F81C18C2561 /* ExpectationMessage.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ExpectationMessage.swift; path = Sources/Nimble/ExpectationMessage.swift; sourceTree = ""; }; + 84C663C041851D0E52A3F9962E7E0680 /* STPMandateDataParams.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = STPMandateDataParams.swift; path = "StripePayments/StripePayments/API Bindings/Models/Shared/STPMandateDataParams.swift"; sourceTree = ""; }; + 84D6C16E96B06F6F1D11342FD76BF650 /* es-419.lproj */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = folder; name = "es-419.lproj"; path = "StripePayments/StripePayments/Resources/Localizations/es-419.lproj"; sourceTree = ""; }; + 85A80EDF1631B6357738E7B417B16D94 /* ms-MY.lproj */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = folder; name = "ms-MY.lproj"; path = "Stripe3DS2/Stripe3DS2/Resources/ms-MY.lproj"; sourceTree = ""; }; + 85C1E1D0B96FA2F2ADFCAFF86417BBFC /* lt-LT.lproj */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = folder; name = "lt-LT.lproj"; path = "Stripe3DS2/Stripe3DS2/Resources/lt-LT.lproj"; sourceTree = ""; }; + 85DB610619181E933973768373CBF80A /* StripeCore+Import.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "StripeCore+Import.swift"; path = "StripePayments/StripePayments/API Bindings/Legacy Compatability/StripeCore+Import.swift"; sourceTree = ""; }; + 86358511999BB628CF6F6E581FEB6FC8 /* AnalyticLoggableError.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = AnalyticLoggableError.swift; path = StripeCore/StripeCore/Source/Analytics/AnalyticLoggableError.swift; sourceTree = ""; }; 8691A5A49862A69A0E7B43FCF632BD81 /* Pods-OSPaymentsLib-OSPaymentsLibTests-acknowledgements.markdown */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; path = "Pods-OSPaymentsLib-OSPaymentsLibTests-acknowledgements.markdown"; sourceTree = ""; }; - 880EBA466E9150F71DE3C4A76DB140D8 /* SuiteHooks.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SuiteHooks.swift; path = Sources/Quick/Hooks/SuiteHooks.swift; sourceTree = ""; }; - 88CE28DB5FFB584E123C56C4345A73E7 /* QCKConfiguration.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = QCKConfiguration.swift; path = Sources/Quick/Configuration/QCKConfiguration.swift; sourceTree = ""; }; + 86A166B019E81AF19FD7E04AE6EF6DFB /* STPThreeDSButtonCustomization.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = STPThreeDSButtonCustomization.swift; path = StripePayments/StripePayments/PaymentHandler/STPThreeDSButtonCustomization.swift; sourceTree = ""; }; + 8706D946C8E1B31C6FF28C6C815B3AB0 /* STPPaymentMethodAddress.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = STPPaymentMethodAddress.swift; path = "StripePayments/StripePayments/API Bindings/Models/PaymentMethods/STPPaymentMethodAddress.swift"; sourceTree = ""; }; + 8752110D3D9DB57A8872CB00C4FE8030 /* NimbleEnvironment.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = NimbleEnvironment.swift; path = Sources/Nimble/Adapters/NimbleEnvironment.swift; sourceTree = ""; }; + 876DECD5B495AF71DBAEBABF331D4D89 /* STPIntentActionRedirectToURL.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = STPIntentActionRedirectToURL.swift; path = "StripePayments/StripePayments/API Bindings/Models/Shared/STPIntentActionRedirectToURL.swift"; sourceTree = ""; }; + 88C13E8D29DA0DA5DC99DA0F59E062F8 /* STDSAuthenticationResponseObject.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = STDSAuthenticationResponseObject.m; path = Stripe3DS2/Stripe3DS2/STDSAuthenticationResponseObject.m; sourceTree = ""; }; + 88EA388CF5C8EE9BB519A1E5E6091C55 /* STPRedirectContext.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = STPRedirectContext.swift; path = "StripePayments/StripePayments/API Bindings/STPRedirectContext.swift"; sourceTree = ""; }; + 891281DF53F382C2F01F71B505A2108F /* STDSOSVersionChecker.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = STDSOSVersionChecker.m; path = Stripe3DS2/Stripe3DS2/STDSOSVersionChecker.m; sourceTree = ""; }; 898D3821CD6035CCA30F112BAE11DE10 /* Pods-OSPaymentsLib-OSPaymentsLibTests-frameworks.sh */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.script.sh; path = "Pods-OSPaymentsLib-OSPaymentsLibTests-frameworks.sh"; sourceTree = ""; }; + 89DA4DBD9EE053423AD56C0F90220D48 /* STPPaymentMethodBoleto.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = STPPaymentMethodBoleto.swift; path = "StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodBoleto.swift"; sourceTree = ""; }; + 8A0CC1CD9EA3D27F6999D69A4B688807 /* en-GB.lproj */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = folder; name = "en-GB.lproj"; path = "Stripe3DS2/Stripe3DS2/Resources/en-GB.lproj"; sourceTree = ""; }; + 8ABE8C85E8FC12796B17E780CB924846 /* STDSStripe3DS2Error.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = STDSStripe3DS2Error.m; path = Stripe3DS2/Stripe3DS2/STDSStripe3DS2Error.m; sourceTree = ""; }; + 8AD03424911FBF425195C50772474D21 /* ja.lproj */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = folder; name = ja.lproj; path = Stripe3DS2/Stripe3DS2/Resources/ja.lproj; sourceTree = ""; }; + 8AF5878DD180D6DE5F240D5479A7FCA2 /* STDSImageLoader.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = STDSImageLoader.m; path = Stripe3DS2/Stripe3DS2/STDSImageLoader.m; sourceTree = ""; }; + 8B33A309520322A241B1193B42EE6348 /* tr.lproj */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = folder; name = tr.lproj; path = Stripe3DS2/Stripe3DS2/Resources/tr.lproj; sourceTree = ""; }; + 8B3AE7859EF5DBF75496199E8B0A9498 /* zh-Hant.lproj */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = folder; name = "zh-Hant.lproj"; path = "StripeCore/StripeCore/Resources/Localizations/zh-Hant.lproj"; sourceTree = ""; }; + 8B55E4AA17C775811EA3FE66C8DDFDEE /* ca-ES.lproj */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = folder; name = "ca-ES.lproj"; path = "Stripe3DS2/Stripe3DS2/Resources/ca-ES.lproj"; sourceTree = ""; }; + 8B6C3FC697FDB37AD5502F3EA544A6F5 /* STDSACSNetworkingManager.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = STDSACSNetworkingManager.h; path = Stripe3DS2/Stripe3DS2/STDSACSNetworkingManager.h; sourceTree = ""; }; + 8B7171A3654D24299DD7F925A56489F0 /* EndWith.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = EndWith.swift; path = Sources/Nimble/Matchers/EndWith.swift; sourceTree = ""; }; + 8BD373964B676EF2C5966D4B81EC2072 /* STDSFooterCustomization.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = STDSFooterCustomization.m; path = Stripe3DS2/Stripe3DS2/STDSFooterCustomization.m; sourceTree = ""; }; + 8BF23145463B6051BC797942E38BA490 /* NSLayoutConstraint+LayoutSupport.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "NSLayoutConstraint+LayoutSupport.m"; path = "Stripe3DS2/Stripe3DS2/NSLayoutConstraint+LayoutSupport.m"; sourceTree = ""; }; + 8C4912EE1BDF346B45A19660EDBF268A /* FileDownloader.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = FileDownloader.swift; path = StripeCore/StripeCore/Source/Helpers/FileDownloader.swift; sourceTree = ""; }; + 8CA21A5FBB404BC0CF4F23BD4C5416F3 /* STDSEllipticCurvePoint.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = STDSEllipticCurvePoint.m; path = Stripe3DS2/Stripe3DS2/STDSEllipticCurvePoint.m; sourceTree = ""; }; + 8D0F4C067C6ED33DC645C8A9C5697B8F /* QuickSpec.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = QuickSpec.m; path = Sources/QuickObjectiveC/QuickSpec.m; sourceTree = ""; }; + 8D21F409ED0D7696661CA18A76E631D3 /* URLSession+Retry.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "URLSession+Retry.swift"; path = "StripeCore/StripeCore/Source/Helpers/URLSession+Retry.swift"; sourceTree = ""; }; + 8D46E93C2A7E6693C20C4AACD43ABF7E /* STPAPIClient.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = STPAPIClient.swift; path = "StripeCore/StripeCore/Source/API Bindings/STPAPIClient.swift"; sourceTree = ""; }; + 8D614D6133986855F759C86B1E3D6B40 /* STPPaymentMethodKlarnaParams.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = STPPaymentMethodKlarnaParams.swift; path = "StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodKlarnaParams.swift"; sourceTree = ""; }; + 8E179A72B1C159351C885B5156C71821 /* Quick-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Quick-umbrella.h"; sourceTree = ""; }; + 8E35F29B901662782AC73037AD726186 /* sk-SK.lproj */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = folder; name = "sk-SK.lproj"; path = "StripeCore/StripeCore/Resources/Localizations/sk-SK.lproj"; sourceTree = ""; }; + 8E3A18526902A264BA784EFA7ADDAA0F /* pt-PT.lproj */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = folder; name = "pt-PT.lproj"; path = "Stripe3DS2/Stripe3DS2/Resources/pt-PT.lproj"; sourceTree = ""; }; + 8F2E3ED06516DE4F8F181334EFE0CC98 /* NMBExceptionCapture.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = NMBExceptionCapture.h; path = Sources/NimbleObjectiveC/NMBExceptionCapture.h; sourceTree = ""; }; + 8F5857C3430F56199E5306C6F0349DF6 /* STPCustomer.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = STPCustomer.swift; path = "StripePayments/StripePayments/API Bindings/Models/STPCustomer.swift"; sourceTree = ""; }; 8FAE50E0E3AD48853025A2E73597E47B /* Pods-OSPaymentsLib-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Pods-OSPaymentsLib-dummy.m"; sourceTree = ""; }; - 9215339C71BDBD5B494E9EFD44005158 /* NimbleEnvironment.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = NimbleEnvironment.swift; path = Sources/Nimble/Adapters/NimbleEnvironment.swift; sourceTree = ""; }; - 97522C7BBA1F97437715C74303E5A686 /* NMBStringify.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = NMBStringify.m; path = Sources/NimbleObjectiveC/NMBStringify.m; sourceTree = ""; }; - 9AA80CEA9B4992D8F9368CEE01A42094 /* BeGreaterThan.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = BeGreaterThan.swift; path = Sources/Nimble/Matchers/BeGreaterThan.swift; sourceTree = ""; }; + 8FBF0235279ED78553212C17484C9983 /* STPPaymentIntentEnums.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = STPPaymentIntentEnums.swift; path = "StripePayments/StripePayments/API Bindings/Models/PaymentIntents/STPPaymentIntentEnums.swift"; sourceTree = ""; }; + 8FFA653D29530ABA70A0D91416DF179A /* STDSButtonCustomization.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = STDSButtonCustomization.h; path = Stripe3DS2/Stripe3DS2/include/STDSButtonCustomization.h; sourceTree = ""; }; + 9063A8C24A5E606AFAC2535BD0014BDB /* Closures.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Closures.swift; path = Sources/Quick/Hooks/Closures.swift; sourceTree = ""; }; + 90B657183C9A0D2F44AFF285746F368E /* STPPaymentMethodNetBankingParams.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = STPPaymentMethodNetBankingParams.swift; path = "StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodNetBankingParams.swift"; sourceTree = ""; }; + 9118F02EFC221FE9C59B2E6CD5362783 /* STPPaymentMethodAlipayParams.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = STPPaymentMethodAlipayParams.swift; path = "StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodAlipayParams.swift"; sourceTree = ""; }; + 91DFA9EF117D2E004A4AD9C412760A21 /* STDSACSNetworkingManager.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = STDSACSNetworkingManager.m; path = Stripe3DS2/Stripe3DS2/STDSACSNetworkingManager.m; sourceTree = ""; }; + 9222B7FD76C3CFA3CC9BFC8CE1D9B256 /* ServerErrorMapper.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ServerErrorMapper.swift; path = StripeCore/StripeCore/Source/Helpers/ServerErrorMapper.swift; sourceTree = ""; }; + 923E91BF764190E7B3C0E6AE6768FC1C /* STDSRuntimeException.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = STDSRuntimeException.m; path = Stripe3DS2/Stripe3DS2/STDSRuntimeException.m; sourceTree = ""; }; + 9250616CA2E76E6872BA1EB12B296113 /* String+Localized.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "String+Localized.swift"; path = "StripeCore/StripeCore/Source/Localization/String+Localized.swift"; sourceTree = ""; }; + 93F9CD920768D4661AF7CAC83BCC332D /* STDSIPAddress.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = STDSIPAddress.h; path = Stripe3DS2/Stripe3DS2/STDSIPAddress.h; sourceTree = ""; }; + 9415F10BEF551D362BDF622A5FE73D31 /* Nimble-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Nimble-dummy.m"; sourceTree = ""; }; + 94758F067E90C9BD22F58D67C13CC4E8 /* mach_excServer.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = mach_excServer.h; path = Carthage/Checkouts/CwlPreconditionTesting/Sources/CwlMachBadInstructionHandler/mach_excServer.h; sourceTree = ""; }; + 95C7D0C979B1F9BBCC5E6F1EBD2248EC /* es.lproj */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = folder; name = es.lproj; path = Stripe3DS2/Stripe3DS2/Resources/es.lproj; sourceTree = ""; }; + 95CFAB09EC6E141434C0BC08D2017EC5 /* STPTelemetryClient.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = STPTelemetryClient.swift; path = StripeCore/StripeCore/Source/Telemetry/STPTelemetryClient.swift; sourceTree = ""; }; + 964AB07C9929986507ED52E3847352BA /* StripeAPI.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = StripeAPI.swift; path = "StripeCore/StripeCore/Source/API Bindings/StripeAPI.swift"; sourceTree = ""; }; + 972D107D6428EC5E8D81E749EB6DEFB4 /* STPCard.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = STPCard.swift; path = "StripePayments/StripePayments/API Bindings/Models/Sources/Types/STPCard.swift"; sourceTree = ""; }; + 979D41D78D59AA209C7CEE1078AFEADD /* STPPaymentMethodGiropay.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = STPPaymentMethodGiropay.swift; path = "StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodGiropay.swift"; sourceTree = ""; }; + 97CE0A95804990A9BF59F85837F3EEA0 /* NSError+StripeCore.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "NSError+StripeCore.swift"; path = "StripeCore/StripeCore/Source/Categories/NSError+StripeCore.swift"; sourceTree = ""; }; + 97E6A59FF453A35FB49B840C2B1CD471 /* String+C99ExtendedIdentifier.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "String+C99ExtendedIdentifier.swift"; path = "Sources/Quick/String+C99ExtendedIdentifier.swift"; sourceTree = ""; }; + 9885674AD68E194BC165B76CD7010AD0 /* PaymentsSDKVariant.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = PaymentsSDKVariant.swift; path = StripeCore/StripeCore/Source/Helpers/PaymentsSDKVariant.swift; sourceTree = ""; }; + 99A3D2F7A445362F85C2478CC5CFFE1B /* Quick.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = Quick.debug.xcconfig; sourceTree = ""; }; + 9ABEE426924F217CD7D941091A32F74C /* StripeCodable.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = StripeCodable.swift; path = StripeCore/StripeCore/Source/Coder/StripeCodable.swift; sourceTree = ""; }; + 9B26C7EA50966EF31016ED82F61A9DC6 /* STPConnectAccountCompanyParams.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = STPConnectAccountCompanyParams.swift; path = "StripePayments/StripePayments/API Bindings/Models/STPConnectAccountCompanyParams.swift"; sourceTree = ""; }; + 9B47978CCA25949CE4831EEAC847FE9D /* AnalyticsClientV2.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = AnalyticsClientV2.swift; path = StripeCore/StripeCore/Source/Analytics/AnalyticsClientV2.swift; sourceTree = ""; }; + 9B74AA57FD5B68F19374399206D13FA9 /* STPAuthenticationContext.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = STPAuthenticationContext.swift; path = StripePayments/StripePayments/PaymentHandler/STPAuthenticationContext.swift; sourceTree = ""; }; + 9B95E6636139A828AF2BFC5FBDA80120 /* DSL.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = DSL.swift; path = Sources/Nimble/DSL.swift; sourceTree = ""; }; + 9B96E139B87973CB2C525F018B20AA12 /* STPPaymentMethodWeChatPay.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = STPPaymentMethodWeChatPay.swift; path = "StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodWeChatPay.swift"; sourceTree = ""; }; + 9CA4796B315DF582CE3C40EE8FD99F49 /* StripeCore.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = StripeCore.debug.xcconfig; sourceTree = ""; }; + 9CBD97FAC70D5151B1E49A18D086FA28 /* STDSNavigationBarCustomization.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = STDSNavigationBarCustomization.m; path = Stripe3DS2/Stripe3DS2/STDSNavigationBarCustomization.m; sourceTree = ""; }; + 9CC280CD6D2FA8049CDD457EE84EE8AF /* ms-MY.lproj */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = folder; name = "ms-MY.lproj"; path = "StripePayments/StripePayments/Resources/Localizations/ms-MY.lproj"; sourceTree = ""; }; + 9CDE34F348B121C7F912F3C9B961B044 /* STPThreeDSLabelCustomization.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = STPThreeDSLabelCustomization.swift; path = StripePayments/StripePayments/PaymentHandler/STPThreeDSLabelCustomization.swift; sourceTree = ""; }; + 9D52E420FDCEBA68136BEEC6DCEF385A /* STDSDirectoryServer.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = STDSDirectoryServer.h; path = Stripe3DS2/Stripe3DS2/STDSDirectoryServer.h; sourceTree = ""; }; + 9D6F3A6E6B05F5BA59796216A5FA8119 /* fr.lproj */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = folder; name = fr.lproj; path = StripeCore/StripeCore/Resources/Localizations/fr.lproj; sourceTree = ""; }; + 9D766D6524D7B25D8DF641AE8471D814 /* Quick.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = Quick.h; path = Sources/QuickObjectiveC/Quick.h; sourceTree = ""; }; 9D940727FF8FB9C785EB98E56350EF41 /* Podfile */ = {isa = PBXFileReference; explicitFileType = text.script.ruby; includeInIndex = 1; indentWidth = 2; name = Podfile; path = ../Podfile; sourceTree = SOURCE_ROOT; tabWidth = 2; xcLanguageSpecificationIdentifier = xcode.lang.ruby; }; - A12262F224D0D0A168C398C49F628A15 /* AllPass.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = AllPass.swift; path = Sources/Nimble/Matchers/AllPass.swift; sourceTree = ""; }; - A16B8BD1EFF8AB8B6940E1EC149FD38A /* DSL.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = DSL.swift; path = Sources/Nimble/DSL.swift; sourceTree = ""; }; - A1E026C7DAC445C7C813121DE7F03837 /* Async.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Async.swift; path = Sources/Nimble/Matchers/Async.swift; sourceTree = ""; }; - AD1B7F0757B5057BCF6D7D1F6B0B7BD1 /* Quick-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Quick-umbrella.h"; sourceTree = ""; }; - AF3CEFA5153F8ACE3EA7629E00B17B8F /* NSBundle+CurrentTestBundle.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "NSBundle+CurrentTestBundle.swift"; path = "Sources/Quick/NSBundle+CurrentTestBundle.swift"; sourceTree = ""; }; - B14A4B16D42CCCBE3D21CBDE4FFC9AA4 /* String+C99ExtendedIdentifier.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "String+C99ExtendedIdentifier.swift"; path = "Sources/Quick/String+C99ExtendedIdentifier.swift"; sourceTree = ""; }; + 9DB35445FC572AC08BE64F7313BCDD10 /* pt-PT.lproj */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = folder; name = "pt-PT.lproj"; path = "StripePayments/StripePayments/Resources/Localizations/pt-PT.lproj"; sourceTree = ""; }; + 9EDEEB7D3BB88F3F2BFD62FC58BADE58 /* STPPaymentMethodAffirmParams.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = STPPaymentMethodAffirmParams.swift; path = "StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodAffirmParams.swift"; sourceTree = ""; }; + 9F3C30898EEBAEE177DDF0BC1283FE03 /* STDSCategoryLinker.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = STDSCategoryLinker.m; path = Stripe3DS2/Stripe3DS2/STDSCategoryLinker.m; sourceTree = ""; }; + 9F7356AF9FD486BC92EFA25CA3B5006F /* STDSInvalidInputException.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = STDSInvalidInputException.h; path = Stripe3DS2/Stripe3DS2/include/STDSInvalidInputException.h; sourceTree = ""; }; + 9FA2D3847F4ECCD49144586976179FC0 /* NSArray+Stripe.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "NSArray+Stripe.swift"; path = "StripeCore/StripeCore/Source/Categories/NSArray+Stripe.swift"; sourceTree = ""; }; + 9FE972D98984635A54F809DE38DC4639 /* pt-BR.lproj */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = folder; name = "pt-BR.lproj"; path = "StripePayments/StripePayments/Resources/Localizations/pt-BR.lproj"; sourceTree = ""; }; + A023D6FAA60988D3CC883EF0A365BEAB /* pt-BR.lproj */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = folder; name = "pt-BR.lproj"; path = "StripeCore/StripeCore/Resources/Localizations/pt-BR.lproj"; sourceTree = ""; }; + A0F001C88CB75DC9956CE0E1C73E6C91 /* SatisfyAnyOf.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SatisfyAnyOf.swift; path = Sources/Nimble/Matchers/SatisfyAnyOf.swift; sourceTree = ""; }; + A122539537DF4B02BC30CC40408E720C /* BeginWith.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = BeginWith.swift; path = Sources/Nimble/Matchers/BeginWith.swift; sourceTree = ""; }; + A13750DB0E1992CD713CFCFE0CE7B11A /* Nimble.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = Nimble.h; path = Sources/Nimble/Nimble.h; sourceTree = ""; }; + A14BBC563E581FC8E511ED8EE601E2F9 /* Nimble.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = Nimble.debug.xcconfig; sourceTree = ""; }; + A16E4D52A285D227F5E248CE6098E96C /* STDSSecTypeUtilities.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = STDSSecTypeUtilities.h; path = Stripe3DS2/Stripe3DS2/STDSSecTypeUtilities.h; sourceTree = ""; }; + A186D36A0EE28C51E4FDB061E865AD36 /* QuickObjCRuntime.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = QuickObjCRuntime.h; path = Sources/QuickObjCRuntime/include/QuickObjCRuntime.h; sourceTree = ""; }; + A21AC98AF15AF5BEC22D6BC3BE3C2A7E /* NSDictionary+DecodingHelpers.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "NSDictionary+DecodingHelpers.m"; path = "Stripe3DS2/Stripe3DS2/NSDictionary+DecodingHelpers.m"; sourceTree = ""; }; + A264E1409E0060EE050F7C7E5A4AC4E5 /* NMBStringify.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = NMBStringify.m; path = Sources/NimbleObjectiveC/NMBStringify.m; sourceTree = ""; }; + A26890A9CFDDF7189B2CE5DC665EA8BF /* QuickTestObservation.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = QuickTestObservation.swift; path = Sources/Quick/QuickTestObservation.swift; sourceTree = ""; }; + A2A3E6B30EB1966A53E390AFBBA33BFA /* Example.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Example.swift; path = Sources/Quick/Example.swift; sourceTree = ""; }; + A2B26C6CDB5006E346FB443C2590CAE9 /* STPThreeDSUICustomization.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = STPThreeDSUICustomization.swift; path = StripePayments/StripePayments/PaymentHandler/STPThreeDSUICustomization.swift; sourceTree = ""; }; + A31ED8DAEC3BB7239795D73A0C3F3410 /* STDSJSONEncodable.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = STDSJSONEncodable.h; path = Stripe3DS2/Stripe3DS2/include/STDSJSONEncodable.h; sourceTree = ""; }; + A35FCF60B5E331DA456844DDA2CA38E7 /* QuickConfiguration.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = QuickConfiguration.swift; path = Sources/Quick/Configuration/QuickConfiguration.swift; sourceTree = ""; }; + A3EFCE7505CCF7892AAAC7D5050D11AC /* STPPaymentIntentShippingDetailsParams.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = STPPaymentIntentShippingDetailsParams.swift; path = "StripePayments/StripePayments/API Bindings/Models/PaymentIntents/STPPaymentIntentShippingDetailsParams.swift"; sourceTree = ""; }; + A3F3ED2D41346BD69305376A35916633 /* STDSEllipticCurvePoint.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = STDSEllipticCurvePoint.h; path = Stripe3DS2/Stripe3DS2/STDSEllipticCurvePoint.h; sourceTree = ""; }; + A45E5CCC06EACD4C6011001C040737A5 /* STDSJSONDecodable.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = STDSJSONDecodable.h; path = Stripe3DS2/Stripe3DS2/include/STDSJSONDecodable.h; sourceTree = ""; }; + A48790581DE4CFC1D56F5741E2DE130D /* QuickTestSuite.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = QuickTestSuite.swift; path = Sources/Quick/QuickTestSuite.swift; sourceTree = ""; }; + A49EF7069046091B2BC0FCD9960DE8E2 /* STDSSimulatorChecker.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = STDSSimulatorChecker.m; path = Stripe3DS2/Stripe3DS2/STDSSimulatorChecker.m; sourceTree = ""; }; + A517E1F0F0973404AFEE7F63ABCDEDA6 /* URL+FileName.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "URL+FileName.swift"; path = "Sources/Quick/URL+FileName.swift"; sourceTree = ""; }; + A5627B275B74FFF496E93813F7C13671 /* Callsite.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Callsite.swift; path = Sources/Quick/Callsite.swift; sourceTree = ""; }; + A5C4B472B13C02ACDEC9F0D9B5FBCAAE /* Await.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Await.swift; path = Sources/Nimble/Utils/Await.swift; sourceTree = ""; }; + A5C9E850E8DF436D4C01C1C689FE056D /* STDSCustomization.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = STDSCustomization.m; path = Stripe3DS2/Stripe3DS2/STDSCustomization.m; sourceTree = ""; }; + A6A6775DD45A9608B960E9A0B53F9DC0 /* ru.lproj */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = folder; name = ru.lproj; path = StripePayments/StripePayments/Resources/Localizations/ru.lproj; sourceTree = ""; }; + A6F84397851ADA6444109BC69845EF86 /* STDSChallengeResponseMessageExtensionObject.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = STDSChallengeResponseMessageExtensionObject.m; path = Stripe3DS2/Stripe3DS2/STDSChallengeResponseMessageExtensionObject.m; sourceTree = ""; }; + A734158ECFECA6B3FFEEB71D1B6878B6 /* it.lproj */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = folder; name = it.lproj; path = Stripe3DS2/Stripe3DS2/Resources/it.lproj; sourceTree = ""; }; + A7625FA16B3529BB97D31FBF6CB29ABB /* Enums+CustomStringConvertible.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "Enums+CustomStringConvertible.swift"; path = "StripePayments/StripePayments/Categories/Enums+CustomStringConvertible.swift"; sourceTree = ""; }; + A78E2A3A2EEA2A59499A66C3FCE4C1D5 /* ru.lproj */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = folder; name = ru.lproj; path = Stripe3DS2/Stripe3DS2/Resources/ru.lproj; sourceTree = ""; }; + A79C4D99EA191FAE43C7DA6F6B650FF7 /* mt.lproj */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = folder; name = mt.lproj; path = StripePayments/StripePayments/Resources/Localizations/mt.lproj; sourceTree = ""; }; + A8CF02440135A2CCC70F434936170066 /* NSString+EmptyChecking.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "NSString+EmptyChecking.h"; path = "Stripe3DS2/Stripe3DS2/NSString+EmptyChecking.h"; sourceTree = ""; }; + A943AD416632652905E4C850E18E2F8E /* STPPaymentMethodGrabPayParams.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = STPPaymentMethodGrabPayParams.swift; path = "StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodGrabPayParams.swift"; sourceTree = ""; }; + A990999E354E17DA7AB7A2FCB321A6C6 /* CwlCatchException.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = CwlCatchException.swift; path = Carthage/Checkouts/CwlCatchException/Sources/CwlCatchException/CwlCatchException.swift; sourceTree = ""; }; + A9F681E11ED0A2B5CF84A013780F3DCD /* Nimble.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = Nimble.modulemap; sourceTree = ""; }; + AA0F9A61C7406D5FEEE182804BC1172E /* UIView+LayoutSupport.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "UIView+LayoutSupport.h"; path = "Stripe3DS2/Stripe3DS2/UIView+LayoutSupport.h"; sourceTree = ""; }; + AB06A94245433C3D9BA6B7F1DE55F379 /* StripeApplePay+Import.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "StripeApplePay+Import.swift"; path = "StripePayments/StripePayments/API Bindings/Legacy Compatability/StripeApplePay+Import.swift"; sourceTree = ""; }; + ABA0E5F06CEDF5D25C0C510CFAE7042E /* NSString+EmptyChecking.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "NSString+EmptyChecking.m"; path = "Stripe3DS2/Stripe3DS2/NSString+EmptyChecking.m"; sourceTree = ""; }; + ABD503531BA02821DCD280C2288A316C /* STPPaymentMethodPayPalParams.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = STPPaymentMethodPayPalParams.swift; path = "StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodPayPalParams.swift"; sourceTree = ""; }; + AC0688418DF7B5E75A4B1CE00FB7024E /* STDSIntegrityChecker.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = STDSIntegrityChecker.h; path = Stripe3DS2/Stripe3DS2/STDSIntegrityChecker.h; sourceTree = ""; }; + AD40E689D860042DA81285ACF0F6227D /* CwlDarwinDefinitions.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = CwlDarwinDefinitions.swift; path = Carthage/Checkouts/CwlPreconditionTesting/Sources/CwlPreconditionTesting/CwlDarwinDefinitions.swift; sourceTree = ""; }; + AD5CF8D8EBFEE99A480B0E9AF068AE06 /* STDSChallengeParameters.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = STDSChallengeParameters.m; path = Stripe3DS2/Stripe3DS2/STDSChallengeParameters.m; sourceTree = ""; }; + ADD5BBE5DC1BEB17AF75F27CF281BE0B /* STPContactField.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = STPContactField.swift; path = "StripePayments/StripePayments/API Bindings/Models/STPContactField.swift"; sourceTree = ""; }; + AE34D75E315D2647406F156B2C66E509 /* STPPaymentMethodBancontactParams.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = STPPaymentMethodBancontactParams.swift; path = "StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodBancontactParams.swift"; sourceTree = ""; }; + AE438E25F67548080875B1E9D861E554 /* XCTest.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = XCTest.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS14.0.sdk/System/Library/Frameworks/XCTest.framework; sourceTree = DEVELOPER_DIR; }; + AE8B63D8981954A332F273D3B86E994A /* STDSAlreadyInitializedException.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = STDSAlreadyInitializedException.h; path = Stripe3DS2/Stripe3DS2/include/STDSAlreadyInitializedException.h; sourceTree = ""; }; + AE8F8F6432C8A0DB6AD810AE037FA4D5 /* STPDeviceUtils.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = STPDeviceUtils.swift; path = StripeCore/StripeCore/Source/Helpers/STPDeviceUtils.swift; sourceTree = ""; }; + AEE4FC3E871FBBBAF4AC3655CD0F588C /* STPPaymentMethodAfterpayClearpayParams.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = STPPaymentMethodAfterpayClearpayParams.swift; path = "StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodAfterpayClearpayParams.swift"; sourceTree = ""; }; + AF0D4FB04C836E44752A314B31469183 /* STPPaymentMethodGrabPay.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = STPPaymentMethodGrabPay.swift; path = "StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodGrabPay.swift"; sourceTree = ""; }; + AF21456AD4F54FD346DC645B6D3FA726 /* STDSJSONEncoder.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = STDSJSONEncoder.m; path = Stripe3DS2/Stripe3DS2/STDSJSONEncoder.m; sourceTree = ""; }; + B00D4B76CB214B3DF40808CA4CD2EAE3 /* ContainElementSatisfying.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ContainElementSatisfying.swift; path = Sources/Nimble/Matchers/ContainElementSatisfying.swift; sourceTree = ""; }; + B01A806A185889C078952DA2E94E5372 /* STDSImageLoader.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = STDSImageLoader.h; path = Stripe3DS2/Stripe3DS2/STDSImageLoader.h; sourceTree = ""; }; B1D21BE1B5A742AA9C8EEE801D57559C /* Pods-OSPaymentsLib-OSPaymentsLibTests-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Pods-OSPaymentsLib-OSPaymentsLibTests-umbrella.h"; sourceTree = ""; }; + B2040FE1DE10144DDAC53FBCAA512977 /* ko.lproj */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = folder; name = ko.lproj; path = StripePayments/StripePayments/Resources/Localizations/ko.lproj; sourceTree = ""; }; B22103AE676FAE45408C0FFCD20688FE /* Pods-OSPaymentsLib-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-OSPaymentsLib-Info.plist"; sourceTree = ""; }; - B534FC537F198D4CB2269C659A93783F /* BeAnInstanceOf.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = BeAnInstanceOf.swift; path = Sources/Nimble/Matchers/BeAnInstanceOf.swift; sourceTree = ""; }; + B2ECD2688FF7C89EF3C34F25979A09DF /* STPCardBrand.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = STPCardBrand.swift; path = "StripePayments/StripePayments/API Bindings/Models/STPCardBrand.swift"; sourceTree = ""; }; + B329CD095DF0D07385B9DF3993CF8082 /* StripeAPIConfiguration.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = StripeAPIConfiguration.swift; path = "StripeCore/StripeCore/Source/API Bindings/StripeAPIConfiguration.swift"; sourceTree = ""; }; + B37A9AC2E7D98DE4CC0C23F9DE5AC667 /* Chevron@3x.png */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.png; name = "Chevron@3x.png"; path = "Stripe3DS2/Stripe3DS2/Resources/Images/Chevron@3x.png"; sourceTree = ""; }; + B3AD9A6234AE08A050EE83A678B69C3D /* STPIntentActionVerifyWithMicrodeposits.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = STPIntentActionVerifyWithMicrodeposits.swift; path = "StripePayments/StripePayments/API Bindings/Models/Shared/STPIntentActionVerifyWithMicrodeposits.swift"; sourceTree = ""; }; + B45E30C6E48B3DB63F442C883902A31A /* STDSChallengeResponseViewController.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = STDSChallengeResponseViewController.m; path = Stripe3DS2/Stripe3DS2/STDSChallengeResponseViewController.m; sourceTree = ""; }; + B49EEDC7970854BAF61BD110CAA852C0 /* HaveCount.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = HaveCount.swift; path = Sources/Nimble/Matchers/HaveCount.swift; sourceTree = ""; }; + B4CBB2439D8D5FF1AA424299EE2E8240 /* mach_excServer.c */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.c; name = mach_excServer.c; path = Carthage/Checkouts/CwlPreconditionTesting/Sources/CwlMachBadInstructionHandler/mach_excServer.c; sourceTree = ""; }; + B4F95FCE335B3F2CBF76F9ECA710D401 /* en-GB.lproj */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = folder; name = "en-GB.lproj"; path = "StripePayments/StripePayments/Resources/Localizations/en-GB.lproj"; sourceTree = ""; }; + B54EC0EF37010C07F19247700B6E2A2D /* Expression.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Expression.swift; path = Sources/Nimble/Expression.swift; sourceTree = ""; }; + B6262A066A13C02F353896BCF68C284A /* STPPaymentMethodFPXParams.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = STPPaymentMethodFPXParams.swift; path = "StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodFPXParams.swift"; sourceTree = ""; }; + B6ACAE0E7420B0102A5B11414A885556 /* STDSWebView.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = STDSWebView.m; path = Stripe3DS2/Stripe3DS2/STDSWebView.m; sourceTree = ""; }; + B86C9D473E70FD7525079A04BFB91DBA /* AssertionRecorder.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = AssertionRecorder.swift; path = Sources/Nimble/Adapters/AssertionRecorder.swift; sourceTree = ""; }; + B8959DF6BE8A734C573FAFA96E84E742 /* StripePayments-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "StripePayments-prefix.pch"; sourceTree = ""; }; + B9340FFDE6A4B4888DD54151796BD4A2 /* STPPaymentMethodEnums.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = STPPaymentMethodEnums.swift; path = "StripePayments/StripePayments/API Bindings/Models/PaymentMethods/STPPaymentMethodEnums.swift"; sourceTree = ""; }; + B966D1B340AC5F7E73477827C816B4EA /* STPCardValidator.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = STPCardValidator.swift; path = StripePayments/StripePayments/Helpers/STPCardValidator.swift; sourceTree = ""; }; + B99A844E813EC8C0FE7F1C1469E68644 /* Quick-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Quick-dummy.m"; sourceTree = ""; }; + BA5E4C5DA1266174ECF6D0615DF67D3B /* StripeError.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = StripeError.swift; path = "StripeCore/StripeCore/Source/API Bindings/StripeError.swift"; sourceTree = ""; }; BAE263041362D074978BB3B577DF0A05 /* Nimble.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Nimble.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - BB5D7CE0E6246798ABFD9DAAE4915E71 /* Nimble-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Nimble-Info.plist"; sourceTree = ""; }; - BBA4F4C4573FD9589D1CA0CA3DD18A0C /* BeResult.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = BeResult.swift; path = Sources/Nimble/Matchers/BeResult.swift; sourceTree = ""; }; + BAF7876859F6A7CD7E75CF411F68334E /* StripePayments-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "StripePayments-dummy.m"; sourceTree = ""; }; + BCB3535181A18B880075F50FFF8AB72C /* STPLocalizedString.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = STPLocalizedString.swift; path = StripePayments/StripePayments/Helpers/STPLocalizedString.swift; sourceTree = ""; }; + BCBD480A050003A3E0412BB33C4865DB /* Nimble-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Nimble-umbrella.h"; sourceTree = ""; }; + BD22EF79E6029B252A7C02F1551AFE24 /* ro-RO.lproj */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = folder; name = "ro-RO.lproj"; path = "StripeCore/StripeCore/Resources/Localizations/ro-RO.lproj"; sourceTree = ""; }; + BE0D6877DEC57C4A40A285AFA6AC0DB0 /* ConnectionsSDKInterface.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ConnectionsSDKInterface.swift; path = "StripeCore/StripeCore/Source/Connections Bindings/ConnectionsSDKInterface.swift"; sourceTree = ""; }; BEB97334DF3B76513D34EB7C70369D82 /* Pods-OSPaymentsLib-OSPaymentsLibTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-OSPaymentsLib-OSPaymentsLibTests.release.xcconfig"; sourceTree = ""; }; - BF200F89D143FA102042E6D285D5B6B2 /* Callsite.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Callsite.swift; path = Sources/Quick/Callsite.swift; sourceTree = ""; }; - C0DEE4FA5F5FF28F88648CF9EF3B4C39 /* BeGreaterThanOrEqualTo.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = BeGreaterThanOrEqualTo.swift; path = Sources/Nimble/Matchers/BeGreaterThanOrEqualTo.swift; sourceTree = ""; }; - C34F47D81171E27AF285CDD1AF9F659C /* CwlDarwinDefinitions.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = CwlDarwinDefinitions.swift; path = Carthage/Checkouts/CwlPreconditionTesting/Sources/CwlPreconditionTesting/CwlDarwinDefinitions.swift; sourceTree = ""; }; - C3D4A2AFFEAE1D8A8E4479F656ADF2D2 /* NimbleXCTestHandler.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = NimbleXCTestHandler.swift; path = Sources/Nimble/Adapters/NimbleXCTestHandler.swift; sourceTree = ""; }; - C4C39466E1E06F0DE2D25E4D0D4E6169 /* CwlCatchBadInstruction.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = CwlCatchBadInstruction.swift; path = Carthage/Checkouts/CwlPreconditionTesting/Sources/CwlPreconditionTesting/CwlCatchBadInstruction.swift; sourceTree = ""; }; - C53261F42083B42E49E80904A433DE8A /* World.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = World.swift; path = Sources/Quick/World.swift; sourceTree = ""; }; - C851CC15E8E0E35CE23A1222E105A809 /* ElementsEqual.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ElementsEqual.swift; path = Sources/Nimble/Matchers/ElementsEqual.swift; sourceTree = ""; }; + BF82D2157807DE33D94019BE4F7F25BB /* STPFile.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = STPFile.swift; path = "StripePayments/StripePayments/API Bindings/Models/STPFile.swift"; sourceTree = ""; }; + BFDC381B81D580A4B02A5D75E2F5429A /* STPConfirmPaymentMethodOptions.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = STPConfirmPaymentMethodOptions.swift; path = "StripePayments/StripePayments/API Bindings/Models/PaymentIntents/STPConfirmPaymentMethodOptions.swift"; sourceTree = ""; }; + C0173B06791A9BEDF7A74E77CB488DFA /* ErrorUtility.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ErrorUtility.swift; path = Sources/Quick/ErrorUtility.swift; sourceTree = ""; }; + C07C5C6690E2AC1DD83FF370C67467F5 /* NMBExceptionCapture.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = NMBExceptionCapture.m; path = Sources/NimbleObjectiveC/NMBExceptionCapture.m; sourceTree = ""; }; + C0D54B4D6898F5344AB1E0195A4196FE /* UIActivityIndicatorView+Stripe.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "UIActivityIndicatorView+Stripe.swift"; path = "StripeCore/StripeCore/Source/UI/UIActivityIndicatorView+Stripe.swift"; sourceTree = ""; }; + C0DCEA1D4D85AB5B85FA8A1902B03DC4 /* STDSAlreadyInitializedException.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = STDSAlreadyInitializedException.m; path = Stripe3DS2/Stripe3DS2/STDSAlreadyInitializedException.m; sourceTree = ""; }; + C164A593BCFD54017290D1F1838F974D /* STDSChallengeParameters.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = STDSChallengeParameters.h; path = Stripe3DS2/Stripe3DS2/include/STDSChallengeParameters.h; sourceTree = ""; }; + C1A3520C47E6A3BB8141D861D8C81B07 /* STPThreeDSCustomizationSettings.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = STPThreeDSCustomizationSettings.swift; path = StripePayments/StripePayments/PaymentHandler/STPThreeDSCustomizationSettings.swift; sourceTree = ""; }; + C21A88A8A5156126F47EE1F778DC732B /* Errors.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Errors.swift; path = Sources/Nimble/Utils/Errors.swift; sourceTree = ""; }; + C238C0F8568BA3ADBB51C71781542E1D /* STPPaymentMethodAUBECSDebitParams.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = STPPaymentMethodAUBECSDebitParams.swift; path = "StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodAUBECSDebitParams.swift"; sourceTree = ""; }; + C298BDCCBD2AACD2DEA8CDDC5FD6697A /* STPPaymentMethodSofort.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = STPPaymentMethodSofort.swift; path = "StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodSofort.swift"; sourceTree = ""; }; + C2F6A3C91B944FA238751C1C2E54353A /* fi.lproj */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = folder; name = fi.lproj; path = Stripe3DS2/Stripe3DS2/Resources/fi.lproj; sourceTree = ""; }; + C311C57196B2E3BDF8E4A5D9D5A19382 /* STDSException.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = STDSException.h; path = Stripe3DS2/Stripe3DS2/include/STDSException.h; sourceTree = ""; }; + C31BF779081BE5194C18F1D97EBBD240 /* STDSStripe3DS2Error.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = STDSStripe3DS2Error.h; path = Stripe3DS2/Stripe3DS2/include/STDSStripe3DS2Error.h; sourceTree = ""; }; + C326830A52B6ACCB749F98CF8A24E4E9 /* AllPass.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = AllPass.swift; path = Sources/Nimble/Matchers/AllPass.swift; sourceTree = ""; }; + C3C4694ED35A2FB67C72EB52A482243E /* STDSSwiftTryCatch.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = STDSSwiftTryCatch.m; path = Stripe3DS2/Stripe3DS2/STDSSwiftTryCatch.m; sourceTree = ""; }; + C3DE0AFB197D44F5B86CEDD53F8632B9 /* el-GR.lproj */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = folder; name = "el-GR.lproj"; path = "Stripe3DS2/Stripe3DS2/Resources/el-GR.lproj"; sourceTree = ""; }; + C4246DC4C9A24781BA3280659F280A70 /* STPPaymentMethodBacsDebitParams.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = STPPaymentMethodBacsDebitParams.swift; path = "StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodBacsDebitParams.swift"; sourceTree = ""; }; + C4677C898A8625631B6903F08544092B /* STDSAuthenticationResponse.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = STDSAuthenticationResponse.h; path = Stripe3DS2/Stripe3DS2/include/STDSAuthenticationResponse.h; sourceTree = ""; }; + C48AB1B31BDC3FB774EA3F60C778ADBF /* STPEmptyStripeResponse.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = STPEmptyStripeResponse.swift; path = "StripePayments/StripePayments/Internal/API Bindings/STPEmptyStripeResponse.swift"; sourceTree = ""; }; + C4B5A1D68DF412D11EE224DFAF8C13C8 /* UIFont+Stripe.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "UIFont+Stripe.swift"; path = "StripeCore/StripeCore/Source/UI/UIFont+Stripe.swift"; sourceTree = ""; }; + C61146BA817F5C94D62CF1642E5225C8 /* UIColor+DefaultColors.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "UIColor+DefaultColors.m"; path = "Stripe3DS2/Stripe3DS2/UIColor+DefaultColors.m"; sourceTree = ""; }; + C679BA4C5B2D4A2C944C1D492590A31C /* QCKConfiguration.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = QCKConfiguration.swift; path = Sources/Quick/Configuration/QCKConfiguration.swift; sourceTree = ""; }; + C67D96EC417FA89AA73EF5270C28250D /* STPAPIClient+Payments.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "STPAPIClient+Payments.swift"; path = "StripePayments/StripePayments/API Bindings/STPAPIClient+Payments.swift"; sourceTree = ""; }; + C6E5AC63C1529E4A54A48C82D9EC1ACE /* Contain.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Contain.swift; path = Sources/Nimble/Matchers/Contain.swift; sourceTree = ""; }; + C78FCAE555CA78A6DDFA24CD5C597CF1 /* DownloadManager.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = DownloadManager.swift; path = StripeCore/StripeCore/Source/DownloadManager/DownloadManager.swift; sourceTree = ""; }; + C79BA5E40AC06C45B5EF8414419C0917 /* InstallMethod.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = InstallMethod.swift; path = StripeCore/StripeCore/Source/Helpers/InstallMethod.swift; sourceTree = ""; }; + C88A58FEC7E0BE3C99E16BFA8B1D7E2E /* STPConfirmWeChatPayOptions.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = STPConfirmWeChatPayOptions.swift; path = "StripePayments/StripePayments/API Bindings/Models/PaymentIntents/STPConfirmWeChatPayOptions.swift"; sourceTree = ""; }; + C88AA3D0BCBD01CEF746F5DA3D8E5B82 /* STPPaymentMethodCardPresent.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = STPPaymentMethodCardPresent.swift; path = "StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodCardPresent.swift"; sourceTree = ""; }; + C8B3102EC25FBA1A55C5DB8BAAF29A2C /* Stripe3DS2-Bridging-Header.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "Stripe3DS2-Bridging-Header.h"; path = "Stripe3DS2/Stripe3DS2/Stripe3DS2-Bridging-Header.h"; sourceTree = ""; }; + C8B805FE5905C4F7297F23560E57E991 /* STDSChallengeResponseImage.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = STDSChallengeResponseImage.h; path = Stripe3DS2/Stripe3DS2/STDSChallengeResponseImage.h; sourceTree = ""; }; C914B482E199C7EDA35291B58CEC2E5E /* Pods-OSPaymentsLib */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = "Pods-OSPaymentsLib"; path = Pods_OSPaymentsLib.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - CA8B94E9D3B433157168D1EECCEC11CD /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS14.0.sdk/System/Library/Frameworks/Foundation.framework; sourceTree = DEVELOPER_DIR; }; - CD87F111AA17D3829427C832EB042273 /* ErrorUtility.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ErrorUtility.swift; path = Sources/Quick/ErrorUtility.swift; sourceTree = ""; }; - CDDFBC1CEF007E69BBCFDEFF88615F2C /* QuickSelectedTestSuiteBuilder.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = QuickSelectedTestSuiteBuilder.swift; path = Sources/Quick/QuickSelectedTestSuiteBuilder.swift; sourceTree = ""; }; - D2FBFBBA48C11C5DAD16F0C15F64297B /* RaisesException.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RaisesException.swift; path = Sources/Nimble/Matchers/RaisesException.swift; sourceTree = ""; }; + C928A5EABEC12D99C0C41619CDE2D94D /* STDSNotInitializedException.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = STDSNotInitializedException.h; path = Stripe3DS2/Stripe3DS2/include/STDSNotInitializedException.h; sourceTree = ""; }; + C92A31C8583D68FCED3476862B0B7C43 /* MatcherProtocols.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = MatcherProtocols.swift; path = Sources/Nimble/Matchers/MatcherProtocols.swift; sourceTree = ""; }; + C9905384221E499294976CE602E966FE /* STPAPIClient+FileUpload.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "STPAPIClient+FileUpload.swift"; path = "StripeCore/StripeCore/Source/API Bindings/STPAPIClient+FileUpload.swift"; sourceTree = ""; }; + CA6F220FA443AA13A65D8D097C0F6D08 /* STPPaymentIntentParams.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = STPPaymentIntentParams.swift; path = "StripePayments/StripePayments/API Bindings/Models/PaymentIntents/STPPaymentIntentParams.swift"; sourceTree = ""; }; + CAB5C0235D9DD565A361624426F57448 /* STPPaymentMethodSEPADebitParams.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = STPPaymentMethodSEPADebitParams.swift; path = "StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodSEPADebitParams.swift"; sourceTree = ""; }; + CAFC1ED8731AE396871EED7AC1178787 /* STDSJSONWebEncryption.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = STDSJSONWebEncryption.h; path = Stripe3DS2/Stripe3DS2/STDSJSONWebEncryption.h; sourceTree = ""; }; + CB7F84D2E403492F72A11684D332AFC8 /* vi.lproj */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = folder; name = vi.lproj; path = StripeCore/StripeCore/Resources/Localizations/vi.lproj; sourceTree = ""; }; + CD067661A0C2C554CF5379FD1AC3BE1F /* STDSNavigationBarCustomization.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = STDSNavigationBarCustomization.h; path = Stripe3DS2/Stripe3DS2/include/STDSNavigationBarCustomization.h; sourceTree = ""; }; + CD92FCE49C77B940DA1D70F958ED1187 /* STDSException.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = STDSException.m; path = Stripe3DS2/Stripe3DS2/STDSException.m; sourceTree = ""; }; + CDB4F75A5F4E5F3AB41B5D7B97F1A07A /* Expectation.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Expectation.swift; path = Sources/Nimble/Expectation.swift; sourceTree = ""; }; + CDBC2D073B4C177E30C6586FF83D1A77 /* NSDictionary+DecodingHelpers.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "NSDictionary+DecodingHelpers.h"; path = "Stripe3DS2/Stripe3DS2/NSDictionary+DecodingHelpers.h"; sourceTree = ""; }; + CDD26DC95DFB774C078DB4456FAB88E4 /* STPPaymentMethodBacsDebit.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = STPPaymentMethodBacsDebit.swift; path = "StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodBacsDebit.swift"; sourceTree = ""; }; + CE68A66EA53204671ED691B4B84F841B /* BeLessThan.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = BeLessThan.swift; path = Sources/Nimble/Matchers/BeLessThan.swift; sourceTree = ""; }; + CEB3E4DB29598BCB37FBCF9F265A1AA6 /* StripeCore-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "StripeCore-prefix.pch"; sourceTree = ""; }; + CEF2DCC073BD22139B9B841E3B5E517F /* STPPaymentMethodCard.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = STPPaymentMethodCard.swift; path = "StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodCard.swift"; sourceTree = ""; }; + CF407AFF06C34D92E915AB3C827DA955 /* tk.lproj */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = folder; name = tk.lproj; path = StripePayments/StripePayments/Resources/Localizations/tk.lproj; sourceTree = ""; }; + CF576601F70ADC56672DA5E916452C88 /* STPSourceRedirect.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = STPSourceRedirect.swift; path = "StripePayments/StripePayments/API Bindings/Models/Sources/STPSourceRedirect.swift"; sourceTree = ""; }; + CFE5B7DCFAC4F2FF0A54BA45B0867808 /* cartes-bancaires-logo.png */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.png; name = "cartes-bancaires-logo.png"; path = "Stripe3DS2/Stripe3DS2/Resources/Images/cartes-bancaires-logo.png"; sourceTree = ""; }; + D12030162C7F5E8DED921037116D4E3E /* STDSChallengeResponseObject.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = STDSChallengeResponseObject.h; path = Stripe3DS2/Stripe3DS2/STDSChallengeResponseObject.h; sourceTree = ""; }; + D135AA9F59ACEBBAA2F3EC49F9C3E0A3 /* hu.lproj */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = folder; name = hu.lproj; path = Stripe3DS2/Stripe3DS2/Resources/hu.lproj; sourceTree = ""; }; + D14176278185396E50949DD0A4368DD7 /* STDSDebuggerChecker.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = STDSDebuggerChecker.h; path = Stripe3DS2/Stripe3DS2/STDSDebuggerChecker.h; sourceTree = ""; }; + D1706788AB559B2764779D59CB3F9CFB /* QuickConfiguration.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = QuickConfiguration.h; path = Sources/QuickObjectiveC/Configuration/QuickConfiguration.h; sourceTree = ""; }; + D2A49AC84E15C93206CFCE783E500FB9 /* STDSDeviceInformationParameter+Private.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "STDSDeviceInformationParameter+Private.h"; path = "Stripe3DS2/Stripe3DS2/STDSDeviceInformationParameter+Private.h"; sourceTree = ""; }; D3A8BF3C48BD1892DD33A7126753E72F /* Pods-OSPaymentsLib-OSPaymentsLibTests-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Pods-OSPaymentsLib-OSPaymentsLibTests-dummy.m"; sourceTree = ""; }; - D41AA0E2939FB981CED2EFF1B98A57B3 /* ThrowError.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ThrowError.swift; path = Sources/Nimble/Matchers/ThrowError.swift; sourceTree = ""; }; D433C194A6EED6E5DC527AA72FCCF1A4 /* Pods-OSPaymentsLib.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = "Pods-OSPaymentsLib.modulemap"; sourceTree = ""; }; + D434B28FB35F3FD4F2BD6DCB5A84511C /* STPPaymentMethodOptions.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = STPPaymentMethodOptions.swift; path = "StripePayments/StripePayments/API Bindings/Models/Shared/STPPaymentMethodOptions.swift"; sourceTree = ""; }; + D452640F36C3BA3EB2B44838F3CE5557 /* StripeServiceError.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = StripeServiceError.swift; path = "StripeCore/StripeCore/Source/API Bindings/StripeServiceError.swift"; sourceTree = ""; }; + D47245DA06CD0D5DDF6943F1D1B40122 /* fi.lproj */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = folder; name = fi.lproj; path = StripePayments/StripePayments/Resources/Localizations/fi.lproj; sourceTree = ""; }; + D4A0099670320E0A61A6EC006DFED651 /* STPSourceCardDetails.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = STPSourceCardDetails.swift; path = "StripePayments/StripePayments/API Bindings/Models/Sources/Types/STPSourceCardDetails.swift"; sourceTree = ""; }; + D4B91C5B9E0B11712BB70F73302CDDDF /* STPThreeDSFooterCustomization.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = STPThreeDSFooterCustomization.swift; path = StripePayments/StripePayments/PaymentHandler/STPThreeDSFooterCustomization.swift; sourceTree = ""; }; D51FDA1819AB5AE370C57A418BF75B10 /* Pods-OSPaymentsLib-OSPaymentsLibTests-acknowledgements.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-OSPaymentsLib-OSPaymentsLibTests-acknowledgements.plist"; sourceTree = ""; }; - DB836F954501FFEA0AA8E87E8856D7A7 /* Filter.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Filter.swift; path = Sources/Quick/Filter.swift; sourceTree = ""; }; - DB88DCC04205DB0A61C17B66FFA0AE97 /* Predicate.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Predicate.swift; path = Sources/Nimble/Matchers/Predicate.swift; sourceTree = ""; }; - DF776FF666679B4CB34B0A18B1F5B307 /* Quick-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Quick-Info.plist"; sourceTree = ""; }; - E1F00FC1EB20AC2CA0B5B083F84159A5 /* Closures.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Closures.swift; path = Sources/Quick/Hooks/Closures.swift; sourceTree = ""; }; - E25EB083AA8985DFFE745FCF5758009A /* mach_excServer.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = mach_excServer.h; path = Carthage/Checkouts/CwlPreconditionTesting/Sources/CwlMachBadInstructionHandler/mach_excServer.h; sourceTree = ""; }; - E27895722ECA9E17BA1DC28F822F97B9 /* MatcherProtocols.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = MatcherProtocols.swift; path = Sources/Nimble/Matchers/MatcherProtocols.swift; sourceTree = ""; }; - E2EB0871827E9D45D4B63C66C93F292B /* PostNotification.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = PostNotification.swift; path = Sources/Nimble/Matchers/PostNotification.swift; sourceTree = ""; }; - E2FF0C6AC202911FB7A52FE099B9B734 /* XCTestObservationCenter+Register.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "XCTestObservationCenter+Register.m"; path = "Sources/NimbleObjectiveC/XCTestObservationCenter+Register.m"; sourceTree = ""; }; - E6BB1E6C30B81EDB33EC7FDB6C205C79 /* QuickConfiguration.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = QuickConfiguration.m; path = Sources/QuickObjectiveC/Configuration/QuickConfiguration.m; sourceTree = ""; }; + D59F8EA29A0E89FFB3DA6A507C616BBC /* STDSChallengeResponseSelectionInfoObject.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = STDSChallengeResponseSelectionInfoObject.m; path = Stripe3DS2/Stripe3DS2/STDSChallengeResponseSelectionInfoObject.m; sourceTree = ""; }; + D5BADA779B0940EAFCAF5D5C3BC5369F /* STDSSelectionCustomization.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = STDSSelectionCustomization.h; path = Stripe3DS2/Stripe3DS2/include/STDSSelectionCustomization.h; sourceTree = ""; }; + D5E32D92D737D28D83830126853FD3F9 /* StripeJSONDecoder.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = StripeJSONDecoder.swift; path = StripeCore/StripeCore/Source/Coder/StripeJSONDecoder.swift; sourceTree = ""; }; + D622546EB394438799B3469E08261DD5 /* BundleLocatorProtocol.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = BundleLocatorProtocol.swift; path = StripeCore/StripeCore/Source/Helpers/BundleLocatorProtocol.swift; sourceTree = ""; }; + D6A3DC41A2292AC166BEB9C49903B205 /* QuickConfiguration.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = QuickConfiguration.m; path = Sources/QuickObjectiveC/Configuration/QuickConfiguration.m; sourceTree = ""; }; + D6A764903B3985971868A7BB7BD637EE /* STPIssuingCardPin.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = STPIssuingCardPin.swift; path = "StripePayments/StripePayments/API Bindings/Models/STPIssuingCardPin.swift"; sourceTree = ""; }; + D704C0F78EB8A406496B33883E781802 /* ca-ES.lproj */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = folder; name = "ca-ES.lproj"; path = "StripePayments/StripePayments/Resources/Localizations/ca-ES.lproj"; sourceTree = ""; }; + D744262862B82B90B5D9F4181794909B /* STPConfirmCardOptions.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = STPConfirmCardOptions.swift; path = "StripePayments/StripePayments/API Bindings/Models/PaymentIntents/STPConfirmCardOptions.swift"; sourceTree = ""; }; + D77381D72A4DFE90938A8B8B8B0B43C5 /* StripeCore.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = StripeCore.release.xcconfig; sourceTree = ""; }; + D7AB48E00CD1FC22362E33B74E6EFFFD /* UIViewController+Stripe3DS2.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "UIViewController+Stripe3DS2.m"; path = "Stripe3DS2/Stripe3DS2/UIViewController+Stripe3DS2.m"; sourceTree = ""; }; + D7D297E8AF89CAB13A3EEF3EB6D03AF8 /* StripeCore-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "StripeCore-umbrella.h"; sourceTree = ""; }; + D80532177CEAC4A052D9C672535F39F8 /* Filter.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Filter.swift; path = Sources/Quick/Filter.swift; sourceTree = ""; }; + D889009612AA978F7B4DD2F749ABAD75 /* STPError.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = STPError.swift; path = StripeCore/StripeCore/Source/Helpers/STPError.swift; sourceTree = ""; }; + D88CFDC73FC1FECF945F9EDC369396EE /* it.lproj */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = folder; name = it.lproj; path = StripeCore/StripeCore/Resources/Localizations/it.lproj; sourceTree = ""; }; + D89A81669E4A065FF0FE35260D05B217 /* STDSEphemeralKeyPair.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = STDSEphemeralKeyPair.h; path = Stripe3DS2/Stripe3DS2/STDSEphemeralKeyPair.h; sourceTree = ""; }; + D89BE132FD720081D0F88167D50A37E8 /* XCTestSuite+QuickTestSuiteBuilder.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "XCTestSuite+QuickTestSuiteBuilder.m"; path = "Sources/QuickObjectiveC/XCTestSuite+QuickTestSuiteBuilder.m"; sourceTree = ""; }; + D8FCC1853BA7EF3E5CC8D63117717701 /* STDSDeviceInformationManager.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = STDSDeviceInformationManager.m; path = Stripe3DS2/Stripe3DS2/STDSDeviceInformationManager.m; sourceTree = ""; }; + D91D402F64E85A15A9B3AFEA817B8FB2 /* STPPaymentMethodUSBankAccountParams.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = STPPaymentMethodUSBankAccountParams.swift; path = "StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodUSBankAccountParams.swift"; sourceTree = ""; }; + D98979E37C5C8388A18B97CB784D1282 /* BeAnInstanceOf.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = BeAnInstanceOf.swift; path = Sources/Nimble/Matchers/BeAnInstanceOf.swift; sourceTree = ""; }; + DA6928017B2DBCEEBFE222E5C709A8E8 /* STDSChallengeResponse.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = STDSChallengeResponse.h; path = Stripe3DS2/Stripe3DS2/STDSChallengeResponse.h; sourceTree = ""; }; + DA9375A5C2F58B4C0B4C74148B397674 /* STPSourceSEPADebitDetails.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = STPSourceSEPADebitDetails.swift; path = "StripePayments/StripePayments/API Bindings/Models/Sources/Types/STPSourceSEPADebitDetails.swift"; sourceTree = ""; }; + DAC85F5C5D2FD0C0550FF6374EA62CB0 /* STDSErrorMessage.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = STDSErrorMessage.m; path = Stripe3DS2/Stripe3DS2/STDSErrorMessage.m; sourceTree = ""; }; + DB083F9E459539159BEB120E36C765AC /* sk-SK.lproj */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = folder; name = "sk-SK.lproj"; path = "StripePayments/StripePayments/Resources/Localizations/sk-SK.lproj"; sourceTree = ""; }; + DB4C698481CE6A3B234A1E1FF7D30719 /* bg-BG.lproj */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = folder; name = "bg-BG.lproj"; path = "StripePayments/StripePayments/Resources/Localizations/bg-BG.lproj"; sourceTree = ""; }; + DB9D19863D2E487C366ABCF51F30308E /* STPPaymentMethodKlarna.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = STPPaymentMethodKlarna.swift; path = "StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodKlarna.swift"; sourceTree = ""; }; + DBDE9025BF46452D52CBCD5520718CF1 /* Quick-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Quick-prefix.pch"; sourceTree = ""; }; + DCF62E2DEF4B16FD0F3F995885183C25 /* CwlMachBadInstructionHandler.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = CwlMachBadInstructionHandler.h; path = Carthage/Checkouts/CwlPreconditionTesting/Sources/CwlMachBadInstructionHandler/include/CwlMachBadInstructionHandler.h; sourceTree = ""; }; + DD9F4B778364E59D43A2F69D2E1CD0F8 /* QCKDSL.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = QCKDSL.m; path = Sources/QuickObjectiveC/DSL/QCKDSL.m; sourceTree = ""; }; + DE35A27E9F5A3639F9CEE37E4C7CC50C /* STPPaymentMethodiDEALParams.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = STPPaymentMethodiDEALParams.swift; path = "StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodiDEALParams.swift"; sourceTree = ""; }; + DE972EEDE56DB2BB21B58F174BFC75BC /* fr.lproj */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = folder; name = fr.lproj; path = StripePayments/StripePayments/Resources/Localizations/fr.lproj; sourceTree = ""; }; + DF29F7FAD43EBFA1799F81703A83964A /* STPPaymentMethodOXXO.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = STPPaymentMethodOXXO.swift; path = "StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodOXXO.swift"; sourceTree = ""; }; + E012D904769549BAD68BD90860FFD7ED /* STPBlocks.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = STPBlocks.swift; path = StripePayments/StripePayments/Helpers/STPBlocks.swift; sourceTree = ""; }; + E044A86F5B76D0CC71E8D21AD25EE7ED /* STPIntentActionAlipayHandleRedirect.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = STPIntentActionAlipayHandleRedirect.swift; path = "StripePayments/StripePayments/API Bindings/Models/Shared/STPIntentActionAlipayHandleRedirect.swift"; sourceTree = ""; }; + E10ACEC9D8441E586D253A5F01D226B8 /* STPAnalyticsClient+Payments.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "STPAnalyticsClient+Payments.swift"; path = "StripePayments/StripePayments/Internal/Analytics/STPAnalyticsClient+Payments.swift"; sourceTree = ""; }; + E1188BBCB393902B5E37C0B1746CAFCE /* STPPaymentMethodUPIParams.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = STPPaymentMethodUPIParams.swift; path = "StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodUPIParams.swift"; sourceTree = ""; }; + E183B527A5D113AD864FE8397EF9E718 /* STDSChallengeResponseImageObject.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = STDSChallengeResponseImageObject.h; path = Stripe3DS2/Stripe3DS2/STDSChallengeResponseImageObject.h; sourceTree = ""; }; + E1CA084EE92AC1E9F6B6EA26953364FE /* QuickSelectedTestSuiteBuilder.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = QuickSelectedTestSuiteBuilder.swift; path = Sources/Quick/QuickSelectedTestSuiteBuilder.swift; sourceTree = ""; }; + E22B1939566A7148F1B9B9D047B4D50A /* STDSAuthenticationRequestParameters.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = STDSAuthenticationRequestParameters.h; path = Stripe3DS2/Stripe3DS2/include/STDSAuthenticationRequestParameters.h; sourceTree = ""; }; + E2C9B1DAD6EDCBDE98D055665BDFFF35 /* LinkAccountSession.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = LinkAccountSession.swift; path = "StripePayments/StripePayments/API Bindings/Models/ACH/LinkAccountSession.swift"; sourceTree = ""; }; + E2E8B2DBFF95E00E33BC8FCAFBFC3459 /* ru.lproj */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = folder; name = ru.lproj; path = StripeCore/StripeCore/Resources/Localizations/ru.lproj; sourceTree = ""; }; + E35BA28DBB2CD8D04D3F6BAA73B05FD4 /* ExampleMetadata.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ExampleMetadata.swift; path = Sources/Quick/ExampleMetadata.swift; sourceTree = ""; }; + E38EDCFC0E27E0450E7DB7D6EC60C9FE /* STDSSpacerView.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = STDSSpacerView.m; path = Stripe3DS2/Stripe3DS2/STDSSpacerView.m; sourceTree = ""; }; + E3D16E6471F8D138E3BD88E4FDC0F8FA /* STDSTextFieldCustomization.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = STDSTextFieldCustomization.m; path = Stripe3DS2/Stripe3DS2/STDSTextFieldCustomization.m; sourceTree = ""; }; + E43CDDA61CC85F1F63015E11796122AB /* DispatchTimeInterval.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = DispatchTimeInterval.swift; path = Sources/Nimble/Utils/DispatchTimeInterval.swift; sourceTree = ""; }; + E498AA5F12E01C66B0508B5BFBDF5B94 /* STDSChallengeResponseSelectionInfoObject.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = STDSChallengeResponseSelectionInfoObject.h; path = Stripe3DS2/Stripe3DS2/STDSChallengeResponseSelectionInfoObject.h; sourceTree = ""; }; + E5121480F98DCD56DFDF23FE8D93FC87 /* STDSConfigParameters.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = STDSConfigParameters.m; path = Stripe3DS2/Stripe3DS2/STDSConfigParameters.m; sourceTree = ""; }; + E58DA75024D5733493F417C1567B9C28 /* STPPaymentConfirmation+SwiftUI.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "STPPaymentConfirmation+SwiftUI.swift"; path = "StripePayments/StripePayments/Helpers/STPPaymentConfirmation+SwiftUI.swift"; sourceTree = ""; }; + E59BCCA0DC94889AFD7ADE8CD22E988F /* StripePayments.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = StripePayments.debug.xcconfig; sourceTree = ""; }; + E5B4C41EAF053078107667B95E340FE0 /* STPPaymentMethodBillingDetails.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = STPPaymentMethodBillingDetails.swift; path = "StripePayments/StripePayments/API Bindings/Models/PaymentMethods/STPPaymentMethodBillingDetails.swift"; sourceTree = ""; }; + E5EDE192F55569328BBF6D6F4BAB9F04 /* STPSourceVerification.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = STPSourceVerification.swift; path = "StripePayments/StripePayments/API Bindings/Models/Sources/STPSourceVerification.swift"; sourceTree = ""; }; + E60400F5C4B289EB41483219C94E968B /* STDSChallengeResponseViewController.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = STDSChallengeResponseViewController.h; path = Stripe3DS2/Stripe3DS2/STDSChallengeResponseViewController.h; sourceTree = ""; }; + E6518D0ADC9D010B4016FB0A7855F6F8 /* STDSFooterCustomization.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = STDSFooterCustomization.h; path = Stripe3DS2/Stripe3DS2/include/STDSFooterCustomization.h; sourceTree = ""; }; E6BD0403A56EB6AA58FE2224C68F73C4 /* Pods-OSPaymentsLib-OSPaymentsLibTests */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = "Pods-OSPaymentsLib-OSPaymentsLibTests"; path = Pods_OSPaymentsLib_OSPaymentsLibTests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - E7639378BFCFD4BC8587A03243C01A64 /* Quick.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = Quick.h; path = Sources/QuickObjectiveC/Quick.h; sourceTree = ""; }; + E7171C229B618E7F245C1E060D855524 /* STDSWarning.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = STDSWarning.m; path = Stripe3DS2/Stripe3DS2/STDSWarning.m; sourceTree = ""; }; + E799BF777DAD19532060DD4EC5A4D21E /* STDSSelectionButton.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = STDSSelectionButton.m; path = Stripe3DS2/Stripe3DS2/STDSSelectionButton.m; sourceTree = ""; }; + E7E3F956A1083AD2F1F0ACDB8EC3A19B /* NSString+JWEHelpers.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "NSString+JWEHelpers.m"; path = "Stripe3DS2/Stripe3DS2/NSString+JWEHelpers.m"; sourceTree = ""; }; + E8C562D4699AF51D606386F895C007AC /* STPPaymentHandler.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = STPPaymentHandler.swift; path = StripePayments/StripePayments/PaymentHandler/STPPaymentHandler.swift; sourceTree = ""; }; E8FFA1A64F61EB44FC28A4BF3EF8248A /* Pods-OSPaymentsLib-OSPaymentsLibTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-OSPaymentsLib-OSPaymentsLibTests.debug.xcconfig"; sourceTree = ""; }; - E919903C10E88C8DB75C2CD00A266948 /* FailureMessage.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = FailureMessage.swift; path = Sources/Nimble/FailureMessage.swift; sourceTree = ""; }; - E937CE363DBBFE4523820E40E9D3F9A0 /* BeginWith.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = BeginWith.swift; path = Sources/Nimble/Matchers/BeginWith.swift; sourceTree = ""; }; - EBC4D3688977E2D961A8F985B1FC0F73 /* HooksPhase.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = HooksPhase.swift; path = Sources/Quick/Hooks/HooksPhase.swift; sourceTree = ""; }; - EE08781F30AAAA4776BC4A79E3FA9F40 /* SatisfyAllOf.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SatisfyAllOf.swift; path = Sources/Nimble/Matchers/SatisfyAllOf.swift; sourceTree = ""; }; - EF5F8634034723707BA489895B2AC37A /* BeLessThan.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = BeLessThan.swift; path = Sources/Nimble/Matchers/BeLessThan.swift; sourceTree = ""; }; - F31245591C4C010F1303DAC1BC9804C1 /* BeCloseTo.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = BeCloseTo.swift; path = Sources/Nimble/Matchers/BeCloseTo.swift; sourceTree = ""; }; - F3ED266DDE9C244816DD6A53157F8745 /* World+DSL.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "World+DSL.swift"; path = "Sources/Quick/DSL/World+DSL.swift"; sourceTree = ""; }; - F75E74A600C812323367AD98A7E46500 /* QuickSpec.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = QuickSpec.h; path = Sources/QuickObjectiveC/QuickSpec.h; sourceTree = ""; }; - FD89D255CE96F4B06B98FE303E825DDF /* Quick.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = Quick.debug.xcconfig; sourceTree = ""; }; - FE268F672F0856752F99A6370C6545F1 /* DispatchTimeInterval.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = DispatchTimeInterval.swift; path = Sources/Nimble/Utils/DispatchTimeInterval.swift; sourceTree = ""; }; + E917285F227929D0403A2B2FE7FCA6D8 /* et-EE.lproj */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = folder; name = "et-EE.lproj"; path = "StripeCore/StripeCore/Resources/Localizations/et-EE.lproj"; sourceTree = ""; }; + EA85AA2D91AD44468F462278A69820BE /* de.lproj */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = folder; name = de.lproj; path = Stripe3DS2/Stripe3DS2/Resources/de.lproj; sourceTree = ""; }; + EB7B6A38D2BE807D5F5B94C96BB7325E /* World+DSL.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "World+DSL.swift"; path = "Sources/Quick/DSL/World+DSL.swift"; sourceTree = ""; }; + EB9C9643167CE17E8EFCD8AEA65A8E50 /* STPPaymentMethodAfterpayClearpay.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = STPPaymentMethodAfterpayClearpay.swift; path = "StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodAfterpayClearpay.swift"; sourceTree = ""; }; + EBA0CC1401C73CB751DB625A00921E9B /* en.lproj */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = folder; name = en.lproj; path = StripeCore/StripeCore/Resources/Localizations/en.lproj; sourceTree = ""; }; + EBCAD22C7789720CF047DBF38A8D34E7 /* STPSourceProtocol.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = STPSourceProtocol.swift; path = "StripePayments/StripePayments/API Bindings/Models/Sources/STPSourceProtocol.swift"; sourceTree = ""; }; + EC0B26FD827064802B685FBCE24C821B /* STPiDEALBank.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = STPiDEALBank.swift; path = "StripePayments/StripePayments/API Bindings/Models/STPiDEALBank.swift"; sourceTree = ""; }; + EC75797CB57718E096614861E48CFA3F /* NSError+Stripe3DS2.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "NSError+Stripe3DS2.m"; path = "Stripe3DS2/Stripe3DS2/NSError+Stripe3DS2.m"; sourceTree = ""; }; + ECCFBD8562CEB28DAA1C33A1957FE839 /* STPAPIClient+PaymentsCore.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "STPAPIClient+PaymentsCore.swift"; path = "StripePayments/StripePayments/Internal/Categories/STPAPIClient+PaymentsCore.swift"; sourceTree = ""; }; + ED3D2EB66C4DC42F56DEA740EB759457 /* STPMultipartFormDataPart.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = STPMultipartFormDataPart.swift; path = "StripeCore/StripeCore/Source/API Bindings/STPMultipartFormDataPart.swift"; sourceTree = ""; }; + ED73A19BD46774DD49D17137BC67F355 /* de.lproj */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = folder; name = de.lproj; path = StripePayments/StripePayments/Resources/Localizations/de.lproj; sourceTree = ""; }; + EE1AF7283AF5AA0D21BB49FF926D44E5 /* CwlCatchException.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = CwlCatchException.m; path = Carthage/Checkouts/CwlCatchException/Sources/CwlCatchExceptionSupport/CwlCatchException.m; sourceTree = ""; }; + EE536D5BFF715BBF9170CA454B770C4C /* BeginWithPrefix.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = BeginWithPrefix.swift; path = Sources/Nimble/Matchers/BeginWithPrefix.swift; sourceTree = ""; }; + EE83B40122127C56C473BB9BF4B8C18D /* STPPaymentMethodOXXOParams.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = STPPaymentMethodOXXOParams.swift; path = "StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodOXXOParams.swift"; sourceTree = ""; }; + EEA0BF069FE2A7864A33BBC6381D262F /* BeWithin.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = BeWithin.swift; path = Sources/Nimble/Matchers/BeWithin.swift; sourceTree = ""; }; + EEB076019C56A1D7098BD542F6BC618A /* STDSChallengeRequestParameters.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = STDSChallengeRequestParameters.m; path = Stripe3DS2/Stripe3DS2/STDSChallengeRequestParameters.m; sourceTree = ""; }; + EECDEDFAF80F5425938C58B2C452C3D0 /* nb.lproj */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = folder; name = nb.lproj; path = StripeCore/StripeCore/Resources/Localizations/nb.lproj; sourceTree = ""; }; + EED74C365BEB0277EFBB71118ACA2ADE /* Dictionary+Stripe.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "Dictionary+Stripe.swift"; path = "StripeCore/StripeCore/Source/Categories/Dictionary+Stripe.swift"; sourceTree = ""; }; + EF1E6022A1D6EB7DBC17A2629DEED4D3 /* Quick.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = Quick.modulemap; sourceTree = ""; }; + F075F62EAFD0DF773E2CC1CE3BDF89EC /* bg-BG.lproj */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = folder; name = "bg-BG.lproj"; path = "Stripe3DS2/Stripe3DS2/Resources/bg-BG.lproj"; sourceTree = ""; }; + F1EB6B89F982600E3611EBC9989948E2 /* Predicate.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Predicate.swift; path = Sources/Nimble/Matchers/Predicate.swift; sourceTree = ""; }; + F21284806288A28295379C4A74411E98 /* hr.lproj */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = folder; name = hr.lproj; path = StripeCore/StripeCore/Resources/Localizations/hr.lproj; sourceTree = ""; }; + F21DCC984F5A8C9A6101163B3ACD6361 /* pl-PL.lproj */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = folder; name = "pl-PL.lproj"; path = "StripeCore/StripeCore/Resources/Localizations/pl-PL.lproj"; sourceTree = ""; }; + F24911076BD4D74BCE431B06818180B7 /* CwlMachBadInstructionHandler.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = CwlMachBadInstructionHandler.m; path = Carthage/Checkouts/CwlPreconditionTesting/Sources/CwlMachBadInstructionHandler/CwlMachBadInstructionHandler.m; sourceTree = ""; }; + F282D0C496A4893A54A4A75061578B55 /* APIRequest.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = APIRequest.swift; path = "StripePayments/StripePayments/Internal/API Bindings/APIRequest.swift"; sourceTree = ""; }; + F2A1401CA8459B8838AA3410E4768D45 /* StripeCore */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = StripeCore; path = StripeCore.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + F2A1C609918CBF59373233370DB12637 /* STPSourcePoller.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = STPSourcePoller.swift; path = "StripePayments/StripePayments/Internal/API Bindings/STPSourcePoller.swift"; sourceTree = ""; }; + F46B9E382AB9E78D472B92BE10842869 /* NSCharacterSet+StripeCore.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "NSCharacterSet+StripeCore.swift"; path = "StripeCore/StripeCore/Source/Categories/NSCharacterSet+StripeCore.swift"; sourceTree = ""; }; + F46F0873B0AE714CC2E6CBFD340FF352 /* STDSJailbreakChecker.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = STDSJailbreakChecker.m; path = Stripe3DS2/Stripe3DS2/STDSJailbreakChecker.m; sourceTree = ""; }; + F5315E06282EF5E942C54E96A82A704D /* STPPaymentMethodBancontact.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = STPPaymentMethodBancontact.swift; path = "StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodBancontact.swift"; sourceTree = ""; }; + F60D4AA67B1691FFF600656AA3B1C26E /* StripeAPI+Deprecated.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "StripeAPI+Deprecated.swift"; path = "StripePayments/StripePayments/API Bindings/Legacy Compatability/StripeAPI+Deprecated.swift"; sourceTree = ""; }; + F738DCB87C2986498EE21E79173A6641 /* STDSDirectoryServerCertificate.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = STDSDirectoryServerCertificate.h; path = Stripe3DS2/Stripe3DS2/STDSDirectoryServerCertificate.h; sourceTree = ""; }; + F796F8F9046466A65E93BBA3541BE336 /* MatchError.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = MatchError.swift; path = Sources/Nimble/Matchers/MatchError.swift; sourceTree = ""; }; + F7C0B6BBB78650A9B91E8D5D5A11D170 /* STDSNotInitializedException.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = STDSNotInitializedException.m; path = Stripe3DS2/Stripe3DS2/STDSNotInitializedException.m; sourceTree = ""; }; + F8727829B9B2E48FA0478FE40FC9FE02 /* QuickSpecBase.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = QuickSpecBase.h; path = Sources/QuickObjCRuntime/include/QuickSpecBase.h; sourceTree = ""; }; + F88C52ABDD07C21075F06653D2F40D77 /* StripeAPIConfiguration+Version.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "StripeAPIConfiguration+Version.swift"; path = "StripeCore/StripeCore/Source/API Bindings/StripeAPIConfiguration+Version.swift"; sourceTree = ""; }; + F8A0B191DEFD36D11CB288C2E97EAF5C /* Quick-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Quick-Info.plist"; sourceTree = ""; }; + F97ABCC6B07DAA7FE3F8E197174A9FCB /* zh-HK.lproj */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = folder; name = "zh-HK.lproj"; path = "StripeCore/StripeCore/Resources/Localizations/zh-HK.lproj"; sourceTree = ""; }; + F9BE4F925C2126024E5ED24836EC1B68 /* pt-BR.lproj */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = folder; name = "pt-BR.lproj"; path = "Stripe3DS2/Stripe3DS2/Resources/pt-BR.lproj"; sourceTree = ""; }; + F9C29673142619F12CD52DC5620F5F50 /* ko.lproj */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = folder; name = ko.lproj; path = Stripe3DS2/Stripe3DS2/Resources/ko.lproj; sourceTree = ""; }; + FA6AF22C064B0F8424A80A848EC86BF4 /* nb.lproj */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = folder; name = nb.lproj; path = Stripe3DS2/Stripe3DS2/Resources/nb.lproj; sourceTree = ""; }; + FB11E840CC2E2C1D0EF2EBD6F3B83800 /* STPPaymentMethodPayPal.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = STPPaymentMethodPayPal.swift; path = "StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodPayPal.swift"; sourceTree = ""; }; + FB227FBD2833CB63EA2FD954E3F1B547 /* fil.lproj */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = folder; name = fil.lproj; path = StripePayments/StripePayments/Resources/Localizations/fil.lproj; sourceTree = ""; }; + FB2AC83D43791CFB270543967C85714F /* STPPaymentMethodListDeserializer.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = STPPaymentMethodListDeserializer.swift; path = "StripePayments/StripePayments/Internal/API Bindings/STPPaymentMethodListDeserializer.swift"; sourceTree = ""; }; + FB754D638D39BFC7C92A1158FB7251A8 /* STPMandateOnlineParams.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = STPMandateOnlineParams.swift; path = "StripePayments/StripePayments/API Bindings/Models/Shared/STPMandateOnlineParams.swift"; sourceTree = ""; }; + FBA3A1685A206FEC59C528E5992C5DA1 /* STDSCustomization.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = STDSCustomization.h; path = Stripe3DS2/Stripe3DS2/include/STDSCustomization.h; sourceTree = ""; }; + FC542ABE1DB9344A59A778F94A59DB9F /* ResourceBundle-Stripe3DS2-StripePayments-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "ResourceBundle-Stripe3DS2-StripePayments-Info.plist"; sourceTree = ""; }; + FC6FEF75843987D374D6F8A1E5784665 /* STDSChallengeResponseSelectionInfo.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = STDSChallengeResponseSelectionInfo.h; path = Stripe3DS2/Stripe3DS2/STDSChallengeResponseSelectionInfo.h; sourceTree = ""; }; + FC87D1514ECB912D2F5CED13BB9ACB49 /* STPPaymentMethodAlipay.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = STPPaymentMethodAlipay.swift; path = "StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodAlipay.swift"; sourceTree = ""; }; + FC9481A825A1D89C96258C591C7F867E /* nn-NO.lproj */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = folder; name = "nn-NO.lproj"; path = "StripePayments/StripePayments/Resources/Localizations/nn-NO.lproj"; sourceTree = ""; }; + FE3674CB887E4AC22FB1FF789057D53F /* discover-logo.png */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.png; name = "discover-logo.png"; path = "Stripe3DS2/Stripe3DS2/Resources/Images/discover-logo.png"; sourceTree = ""; }; + FE41B23FCE5856C930AEB856BE863DFE /* STDSRuntimeException.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = STDSRuntimeException.h; path = Stripe3DS2/Stripe3DS2/include/STDSRuntimeException.h; sourceTree = ""; }; + FE59A18F9357C384D41EB0E8CA2136FF /* STDSDeviceInformationParameter.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = STDSDeviceInformationParameter.m; path = Stripe3DS2/Stripe3DS2/STDSDeviceInformationParameter.m; sourceTree = ""; }; + FE746D98425B077F5CD27D98DF1B5E76 /* hr.lproj */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = folder; name = hr.lproj; path = Stripe3DS2/Stripe3DS2/Resources/hr.lproj; sourceTree = ""; }; + FEC23DC7AF2BAA66F022191D678561D7 /* STPPaymentIntentLastPaymentError.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = STPPaymentIntentLastPaymentError.swift; path = "StripePayments/StripePayments/API Bindings/Models/PaymentIntents/STPPaymentIntentLastPaymentError.swift"; sourceTree = ""; }; + FECE9A949CF578DBE8A520691843CA88 /* STPPaymentMethodWeChatPayParams.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = STPPaymentMethodWeChatPayParams.swift; path = "StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodWeChatPayParams.swift"; sourceTree = ""; }; + FF0B4080B203408C62452F1712DEEE72 /* STDSDebuggerChecker.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = STDSDebuggerChecker.m; path = Stripe3DS2/Stripe3DS2/STDSDebuggerChecker.m; sourceTree = ""; }; + FFB85B4D6964DB341F8D02835F8235FC /* STDSProtocolErrorEvent.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = STDSProtocolErrorEvent.m; path = Stripe3DS2/Stripe3DS2/STDSProtocolErrorEvent.m; sourceTree = ""; }; + FFE5DBD6034385644C0125535D30076B /* STDSTextChallengeView.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = STDSTextChallengeView.h; path = Stripe3DS2/Stripe3DS2/STDSTextChallengeView.h; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ - 06AB854D397AC4F5BD7AFCCCEF728C82 /* Frameworks */ = { + 2353C7BD25A0A71DD125C756A62928CE /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 23ACBCCC163D54DBAFBBE92176BA9440 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 781AF529033437C39A1E1D5CDF9D266D /* Foundation.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; - 5BACFA62F624BC18081DF90CFC27D336 /* Frameworks */ = { + 3CE467C548A08D895A2EC81E04D1880F /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 389DF9C2C99BD347316A28A8F10387D3 /* Foundation.framework in Frameworks */, + AB35EA65C4BE948084F895EDB2FA877A /* Foundation.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 8F3F573A92245FE31FD8C90E4ACF29E8 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + C278A4AD9EE53032938EC5E888B275D4 /* Foundation.framework in Frameworks */, + 32DBDB3004079944A6596D7258B996E6 /* UIKit.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 9D380316446BAE7577102FECEA11E341 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + ABAB2B20B44E0AA769E240451131658C /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 76AE5C59F6E03C8F2D9181A69B86FCD7 /* Foundation.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + B38E2F97DDC002785347B4B9A5A0A1A6 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + F65B24DDF852712C877CA3F64353C818 /* Foundation.framework in Frameworks */, + 9A6BC18B9F442CCC3CDA9E13D50CBDEB /* UIKit.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -325,121 +1538,354 @@ /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ - 14663555BFC9D8228B23F8DA0E5EC5BD /* Support Files */ = { + 03C5C200A0787E300053CFA8F53CA094 /* Frameworks */ = { isa = PBXGroup; children = ( - 4C965F64744CB14D8F6E2C2BBB97F4DD /* Nimble.modulemap */, - 33FD12F984B4BA8B5D001D0AFD13F708 /* Nimble-dummy.m */, - BB5D7CE0E6246798ABFD9DAAE4915E71 /* Nimble-Info.plist */, - 7AE197136F8E380A9F1E7D06BD9D0FAF /* Nimble-prefix.pch */, - 1FC0C54E76B49BF11F64E24F0931846C /* Nimble-umbrella.h */, - 8270027ACBF7A64C2B453CCBFE155E90 /* Nimble.debug.xcconfig */, - 4B5ECB9D7EF3AF7D8F37CE57A988CD83 /* Nimble.release.xcconfig */, + 204BF320E11014414D53166EB7C125A8 /* iOS */, ); - name = "Support Files"; - path = "../Target Support Files/Nimble"; + name = Frameworks; sourceTree = ""; }; - 1628BF05B4CAFDCC3549A101F5A10A17 /* Frameworks */ = { + 0438694B56B3F1A3280844F9B55FAC4D /* Nimble */ = { isa = PBXGroup; children = ( - 974814B39C0012DECD183BBB91B32103 /* iOS */, + 65D60532E0DFB8FA1617519318FBB503 /* AdapterProtocols.swift */, + C326830A52B6ACCB749F98CF8A24E4E9 /* AllPass.swift */, + 7F2F8FF75072186C7D2D029B07EA0611 /* AssertionDispatcher.swift */, + B86C9D473E70FD7525079A04BFB91DBA /* AssertionRecorder.swift */, + 54F009A4863C281F89977236F98D9E83 /* Async.swift */, + A5C4B472B13C02ACDEC9F0D9B5FBCAAE /* Await.swift */, + 79E1FC49BF933FE84A26E535CC4BB4AB /* BeAKindOf.swift */, + D98979E37C5C8388A18B97CB784D1282 /* BeAnInstanceOf.swift */, + 5A7E15112F94F1128C0AE9FCBAB8DDF6 /* BeCloseTo.swift */, + 7DDE21D10B22192C6F8A47342258379D /* BeEmpty.swift */, + A122539537DF4B02BC30CC40408E720C /* BeginWith.swift */, + EE536D5BFF715BBF9170CA454B770C4C /* BeginWithPrefix.swift */, + 7B727AD03286B77B339F83B639680C4A /* BeGreaterThan.swift */, + 680C1DF5B047CCCB5CC6AAD90C501F63 /* BeGreaterThanOrEqualTo.swift */, + 5FC2114F70469E415B7E2747DA3C7FBE /* BeIdenticalTo.swift */, + CE68A66EA53204671ED691B4B84F841B /* BeLessThan.swift */, + 7C32B5867CD2E1958E06067CD646C7BD /* BeLessThanOrEqual.swift */, + 0A00905E5C9C768C295FAD0A776669AF /* BeLogical.swift */, + 4F1D688AD2265A75D8EFB9221F7EB778 /* BeNil.swift */, + 74EB80E25DFDE9813CA10E313C254D8B /* BeResult.swift */, + 065AE8BD8BF5F67C6C62A4385F59BC6F /* BeVoid.swift */, + EEA0BF069FE2A7864A33BBC6381D262F /* BeWithin.swift */, + C6E5AC63C1529E4A54A48C82D9EC1ACE /* Contain.swift */, + B00D4B76CB214B3DF40808CA4CD2EAE3 /* ContainElementSatisfying.swift */, + 1B1E72523EA2324F4EF8EF152F73B08E /* CwlBadInstructionException.swift */, + 557D02A61618BFDAD32138A9A64EF81B /* CwlCatchBadInstruction.swift */, + 44669529D230594202E1BBACB273334B /* CwlCatchException.h */, + EE1AF7283AF5AA0D21BB49FF926D44E5 /* CwlCatchException.m */, + A990999E354E17DA7AB7A2FCB321A6C6 /* CwlCatchException.swift */, + AD40E689D860042DA81285ACF0F6227D /* CwlDarwinDefinitions.swift */, + DCF62E2DEF4B16FD0F3F995885183C25 /* CwlMachBadInstructionHandler.h */, + F24911076BD4D74BCE431B06818180B7 /* CwlMachBadInstructionHandler.m */, + E43CDDA61CC85F1F63015E11796122AB /* DispatchTimeInterval.swift */, + 0F07FCCE05A15374145FFEB562FC6CE3 /* DSL.h */, + 7839E3169FA3787A71E1C01829725758 /* DSL.m */, + 9B95E6636139A828AF2BFC5FBDA80120 /* DSL.swift */, + 49A14E85E3585B6652A5D97440A4D055 /* DSL+Wait.swift */, + 4E59E51F071F6568DA9481DE99B8E944 /* ElementsEqual.swift */, + 8B7171A3654D24299DD7F925A56489F0 /* EndWith.swift */, + 6743D6B280FD6633C1199C27DB374029 /* Equal.swift */, + 708F5988B98C9B3D16D7E03755DAED4E /* Equal+Tuple.swift */, + C21A88A8A5156126F47EE1F778DC732B /* Errors.swift */, + CDB4F75A5F4E5F3AB41B5D7B97F1A07A /* Expectation.swift */, + 84AA17F827E17EE953033F81C18C2561 /* ExpectationMessage.swift */, + B54EC0EF37010C07F19247700B6E2A2D /* Expression.swift */, + 70D3FC01AB2025C3F5A9C9B91ACFCCB3 /* FailureMessage.swift */, + B49EEDC7970854BAF61BD110CAA852C0 /* HaveCount.swift */, + B4CBB2439D8D5FF1AA424299EE2E8240 /* mach_excServer.c */, + 94758F067E90C9BD22F58D67C13CC4E8 /* mach_excServer.h */, + 1C62A366D5C5C58C42440DD1C7ADFC27 /* Match.swift */, + C92A31C8583D68FCED3476862B0B7C43 /* MatcherProtocols.swift */, + F796F8F9046466A65E93BBA3541BE336 /* MatchError.swift */, + A13750DB0E1992CD713CFCFE0CE7B11A /* Nimble.h */, + 8752110D3D9DB57A8872CB00C4FE8030 /* NimbleEnvironment.swift */, + 15A26F6CDD349347AB55D87E3586D138 /* NimbleXCTestHandler.swift */, + 8F2E3ED06516DE4F8F181334EFE0CC98 /* NMBExceptionCapture.h */, + C07C5C6690E2AC1DD83FF370C67467F5 /* NMBExceptionCapture.m */, + 27899F0C9E29C49D1C37CF38F8944ADD /* NMBExpectation.swift */, + 056DA00E7E017616FF5CF5023CCED999 /* NMBStringify.h */, + A264E1409E0060EE050F7C7E5A4AC4E5 /* NMBStringify.m */, + 04C4BA6488DA9BA50F6C16F86B003E83 /* PostNotification.swift */, + F1EB6B89F982600E3611EBC9989948E2 /* Predicate.swift */, + 3D08A5A4B5601443EFFFBFB1AC2E385D /* RaisesException.swift */, + 07D2BCAAFF28918553FDE6722B50EF5D /* SatisfyAllOf.swift */, + A0F001C88CB75DC9956CE0E1C73E6C91 /* SatisfyAnyOf.swift */, + 180924D5266489E2FCC82462A8EA7CD7 /* SourceLocation.swift */, + 669104F1E97535717BDCE249A3587195 /* Stringers.swift */, + 236B5B45A473096741E6490A0EB83CFF /* ThrowAssertion.swift */, + 4CB99E2C8E159ACE62BE2D838C454D60 /* ThrowError.swift */, + 34B323CCEC4BAF3077A937A36605C648 /* ToSucceed.swift */, + 65F202B9FC21F6175762715A47B8A591 /* XCTestObservationCenter+Register.m */, + C18CA5AC20E96324A57A51CEF211576C /* Support Files */, ); - name = Frameworks; + path = Nimble; sourceTree = ""; }; - 184D81A390AC32FF38FF3A0047539694 /* Nimble */ = { + 115E61B0EC34D1E9613F9233128F82D4 /* Stripe3DS2 */ = { isa = PBXGroup; children = ( - 5523F3CB4F893F0BF3631D865BEEC2B4 /* AdapterProtocols.swift */, - A12262F224D0D0A168C398C49F628A15 /* AllPass.swift */, - 090D7BCE58F5A67C1B30F59637E0EE53 /* AssertionDispatcher.swift */, - 64B896AB55261B6E62E0FC506B92A8EC /* AssertionRecorder.swift */, - A1E026C7DAC445C7C813121DE7F03837 /* Async.swift */, - 40955816DD54EA848880AD2815A76921 /* Await.swift */, - 5B95333BD525E87BFF22C57ED6E20FD5 /* BeAKindOf.swift */, - B534FC537F198D4CB2269C659A93783F /* BeAnInstanceOf.swift */, - F31245591C4C010F1303DAC1BC9804C1 /* BeCloseTo.swift */, - 2CF56DC23988E5C892B0834949D740C5 /* BeEmpty.swift */, - E937CE363DBBFE4523820E40E9D3F9A0 /* BeginWith.swift */, - 7893AC67AE4B488BC3E9604A46413A06 /* BeginWithPrefix.swift */, - 9AA80CEA9B4992D8F9368CEE01A42094 /* BeGreaterThan.swift */, - C0DEE4FA5F5FF28F88648CF9EF3B4C39 /* BeGreaterThanOrEqualTo.swift */, - 115813CA22C723977B41201CF3B4C44A /* BeIdenticalTo.swift */, - EF5F8634034723707BA489895B2AC37A /* BeLessThan.swift */, - 586B5A37C0A10198805DA6175B2EB342 /* BeLessThanOrEqual.swift */, - 3B4E2AF01C07390467B2A032C1081912 /* BeLogical.swift */, - 6C5852911233E16D8DBA632AAF28C4C0 /* BeNil.swift */, - BBA4F4C4573FD9589D1CA0CA3DD18A0C /* BeResult.swift */, - 5273DD569D843C265AF46176F4A534FD /* BeVoid.swift */, - 8015D0BB35ED18B858B74C6E8656EB00 /* BeWithin.swift */, - 4149CC5C4007BD87DFDB7E2114AE830D /* Contain.swift */, - 84CC299AC522B25A61A3FAF124FF83FC /* ContainElementSatisfying.swift */, - 2E9331718C3E375B9305AE6782A65CC4 /* CwlBadInstructionException.swift */, - C4C39466E1E06F0DE2D25E4D0D4E6169 /* CwlCatchBadInstruction.swift */, - 3EFA1693908150CAAB677FEAB89AEC2D /* CwlCatchException.h */, - 654A3ADC4BC6E05E9BDC2D8F858A74BA /* CwlCatchException.m */, - 0B2A30FEA2214E06D065AE8997736B53 /* CwlCatchException.swift */, - C34F47D81171E27AF285CDD1AF9F659C /* CwlDarwinDefinitions.swift */, - 23E11C41EA8F304D43F144554949AEFF /* CwlMachBadInstructionHandler.h */, - 1B6A8AE2D5EF989F29A4FFB4EB7D52A8 /* CwlMachBadInstructionHandler.m */, - FE268F672F0856752F99A6370C6545F1 /* DispatchTimeInterval.swift */, - 5C8E70599736912CA1DB7FCDD472F2B2 /* DSL.h */, - 49D566AD1F3A57C62675DCFF1174ADF8 /* DSL.m */, - A16B8BD1EFF8AB8B6940E1EC149FD38A /* DSL.swift */, - 298044D1245C4BD022B7F13791639E75 /* DSL+Wait.swift */, - C851CC15E8E0E35CE23A1222E105A809 /* ElementsEqual.swift */, - 2C9CC327536739702EE1B8865E38BED6 /* EndWith.swift */, - 844435B050856A3A90F2F2DC5D10C71E /* Equal.swift */, - 16671DF91816B7CC8BAA2964E1E6414C /* Equal+Tuple.swift */, - 447626370CDD31CDCC3656C6E0B3BA05 /* Errors.swift */, - 85C9317EF9B3052FC9D544E30801F901 /* Expectation.swift */, - 3DB3B3904CE5F831A2214803D978A197 /* ExpectationMessage.swift */, - 67A91DF9E678606788A96C9150D53EA6 /* Expression.swift */, - E919903C10E88C8DB75C2CD00A266948 /* FailureMessage.swift */, - 16F99FA0960BE24312A4603668FD6CFA /* HaveCount.swift */, - 8470BE37EE9259F9FDADDFC80764A837 /* mach_excServer.c */, - E25EB083AA8985DFFE745FCF5758009A /* mach_excServer.h */, - 516931D0E6A9461B9C20990FA366E1F9 /* Match.swift */, - E27895722ECA9E17BA1DC28F822F97B9 /* MatcherProtocols.swift */, - 6BAC25BC63EBD14D35CDE94813660768 /* MatchError.swift */, - 7C826AD498684E411DD1C792748D889C /* Nimble.h */, - 9215339C71BDBD5B494E9EFD44005158 /* NimbleEnvironment.swift */, - C3D4A2AFFEAE1D8A8E4479F656ADF2D2 /* NimbleXCTestHandler.swift */, - 7A7CD7566A962848ACAFAE01FAC08AA6 /* NMBExceptionCapture.h */, - 81CA9AA102BC399952DACFC1F5740345 /* NMBExceptionCapture.m */, - 0F4A8507ACE009C2C0F45E1FDED202C7 /* NMBExpectation.swift */, - 369990B25C94966B37B0E376A2FE93C0 /* NMBStringify.h */, - 97522C7BBA1F97437715C74303E5A686 /* NMBStringify.m */, - E2EB0871827E9D45D4B63C66C93F292B /* PostNotification.swift */, - DB88DCC04205DB0A61C17B66FFA0AE97 /* Predicate.swift */, - D2FBFBBA48C11C5DAD16F0C15F64297B /* RaisesException.swift */, - EE08781F30AAAA4776BC4A79E3FA9F40 /* SatisfyAllOf.swift */, - 21C0C122235EDD894313B02C03C7C538 /* SatisfyAnyOf.swift */, - 755D25C0FCCF8F6E3E59CF4F94C8C060 /* SourceLocation.swift */, - 6E6AA1575C0AD81F762039746AFAECDC /* Stringers.swift */, - 85254BDDFDC46F27B70DCBF181ADE6FF /* ThrowAssertion.swift */, - D41AA0E2939FB981CED2EFF1B98A57B3 /* ThrowError.swift */, - 51320337A23D4A8E10E00BFD67B8D043 /* ToSucceed.swift */, - E2FF0C6AC202911FB7A52FE099B9B734 /* XCTestObservationCenter+Register.m */, - 14663555BFC9D8228B23F8DA0E5EC5BD /* Support Files */, + 1B55E0D441A251A915C6E11214B5CCCC /* NSData+JWEHelpers.h */, + 22F4A5DC1871015B1D75725F5293511C /* NSData+JWEHelpers.m */, + CDBC2D073B4C177E30C6586FF83D1A77 /* NSDictionary+DecodingHelpers.h */, + A21AC98AF15AF5BEC22D6BC3BE3C2A7E /* NSDictionary+DecodingHelpers.m */, + 22C7486D395D531F3CEA71233BEF3134 /* NSError+Stripe3DS2.h */, + EC75797CB57718E096614861E48CFA3F /* NSError+Stripe3DS2.m */, + 411D3501805F770A6EDF01F816BAC6B5 /* NSLayoutConstraint+LayoutSupport.h */, + 8BF23145463B6051BC797942E38BA490 /* NSLayoutConstraint+LayoutSupport.m */, + A8CF02440135A2CCC70F434936170066 /* NSString+EmptyChecking.h */, + ABA0E5F06CEDF5D25C0C510CFAE7042E /* NSString+EmptyChecking.m */, + 3C8564A486877CE043FB241FDB66590F /* NSString+JWEHelpers.h */, + E7E3F956A1083AD2F1F0ACDB8EC3A19B /* NSString+JWEHelpers.m */, + 8B6C3FC697FDB37AD5502F3EA544A6F5 /* STDSACSNetworkingManager.h */, + 91DFA9EF117D2E004A4AD9C412760A21 /* STDSACSNetworkingManager.m */, + AE8B63D8981954A332F273D3B86E994A /* STDSAlreadyInitializedException.h */, + C0DCEA1D4D85AB5B85FA8A1902B03DC4 /* STDSAlreadyInitializedException.m */, + E22B1939566A7148F1B9B9D047B4D50A /* STDSAuthenticationRequestParameters.h */, + 210A59DA9EB67DB017B769CBBEE3E9B3 /* STDSAuthenticationRequestParameters.m */, + C4677C898A8625631B6903F08544092B /* STDSAuthenticationResponse.h */, + 59AA7F922673B41C277C2A84071B636A /* STDSAuthenticationResponseObject.h */, + 88C13E8D29DA0DA5DC99DA0F59E062F8 /* STDSAuthenticationResponseObject.m */, + 11E6A0CBA10A6C02A9EFB6A703E5254B /* STDSBrandingView.h */, + 2AC6C1C0ECB6DC8888E72B1CDE082317 /* STDSBrandingView.m */, + 252E073673E5959089D69D015A77DA80 /* STDSBundleLocator.h */, + 5AF1751BC3596620650014810E422E40 /* STDSBundleLocator.m */, + 8FFA653D29530ABA70A0D91416DF179A /* STDSButtonCustomization.h */, + 4FC1520119487BEAC759E99C34521BBD /* STDSButtonCustomization.m */, + 55ED1A89217E66F3DDA8E2191F28E79D /* STDSCategoryLinker.h */, + 9F3C30898EEBAEE177DDF0BC1283FE03 /* STDSCategoryLinker.m */, + 1EDB2495F0CD9AEDB5FE4545BA418772 /* STDSChallengeInformationView.h */, + 00B7598DBDB51CDD8DEA474B7C16C37D /* STDSChallengeInformationView.m */, + C164A593BCFD54017290D1F1838F974D /* STDSChallengeParameters.h */, + AD5CF8D8EBFEE99A480B0E9AF068AE06 /* STDSChallengeParameters.m */, + 1A86E86A636998468C6AA72E338D691C /* STDSChallengeRequestParameters.h */, + EEB076019C56A1D7098BD542F6BC618A /* STDSChallengeRequestParameters.m */, + DA6928017B2DBCEEBFE222E5C709A8E8 /* STDSChallengeResponse.h */, + C8B805FE5905C4F7297F23560E57E991 /* STDSChallengeResponseImage.h */, + E183B527A5D113AD864FE8397EF9E718 /* STDSChallengeResponseImageObject.h */, + 788643DE0B693BF3BE7538FE541BC9CA /* STDSChallengeResponseImageObject.m */, + 074B03C63A23CC48E3CDCE64FC0A0961 /* STDSChallengeResponseMessageExtension.h */, + 7E95291ECF86585EA09E49FC52FE512D /* STDSChallengeResponseMessageExtensionObject.h */, + A6F84397851ADA6444109BC69845EF86 /* STDSChallengeResponseMessageExtensionObject.m */, + D12030162C7F5E8DED921037116D4E3E /* STDSChallengeResponseObject.h */, + 323FD70DD57060BAABCE7C747761D4FC /* STDSChallengeResponseObject.m */, + FC6FEF75843987D374D6F8A1E5784665 /* STDSChallengeResponseSelectionInfo.h */, + E498AA5F12E01C66B0508B5BFBDF5B94 /* STDSChallengeResponseSelectionInfoObject.h */, + D59F8EA29A0E89FFB3DA6A507C616BBC /* STDSChallengeResponseSelectionInfoObject.m */, + E60400F5C4B289EB41483219C94E968B /* STDSChallengeResponseViewController.h */, + B45E30C6E48B3DB63F442C883902A31A /* STDSChallengeResponseViewController.m */, + 805C254CE8924BAF69E8A22BD3CCAFE8 /* STDSChallengeSelectionView.h */, + 0823109A43B7175AAA2D1C0D80EBAAB0 /* STDSChallengeSelectionView.m */, + 2BDD6F369ED85B44B472A23BC44B6D4C /* STDSChallengeStatusReceiver.h */, + 546C97E71464A08D279EDEDCBC44A6DD /* STDSCompletionEvent.h */, + 625A9EBBEE9AE746354C27F9C844BDEB /* STDSCompletionEvent.m */, + 83A25F3DE9E03CC60ABD875634EA53F8 /* STDSConfigParameters.h */, + E5121480F98DCD56DFDF23FE8D93FC87 /* STDSConfigParameters.m */, + FBA3A1685A206FEC59C528E5992C5DA1 /* STDSCustomization.h */, + A5C9E850E8DF436D4C01C1C689FE056D /* STDSCustomization.m */, + D14176278185396E50949DD0A4368DD7 /* STDSDebuggerChecker.h */, + FF0B4080B203408C62452F1712DEEE72 /* STDSDebuggerChecker.m */, + 3528BD4868D8574FF2FB171DA2BFBB5F /* STDSDeviceInformation.h */, + 48669968B1C33265AE0FF8820DFBB191 /* STDSDeviceInformation.m */, + 32ECC3CE517D8C826EE3DCA91B7FDE06 /* STDSDeviceInformationManager.h */, + D8FCC1853BA7EF3E5CC8D63117717701 /* STDSDeviceInformationManager.m */, + 161BEAD8BFBD8106D006C6D52B175AEE /* STDSDeviceInformationParameter.h */, + FE59A18F9357C384D41EB0E8CA2136FF /* STDSDeviceInformationParameter.m */, + D2A49AC84E15C93206CFCE783E500FB9 /* STDSDeviceInformationParameter+Private.h */, + 9D52E420FDCEBA68136BEEC6DCEF385A /* STDSDirectoryServer.h */, + F738DCB87C2986498EE21E79173A6641 /* STDSDirectoryServerCertificate.h */, + 6F2B6E62B1B30F32268B7A4FECD434AA /* STDSDirectoryServerCertificate.m */, + 5DFDD80575DD9A05A06ED19D4D52AE70 /* STDSDirectoryServerCertificate+Internal.h */, + A3F3ED2D41346BD69305376A35916633 /* STDSEllipticCurvePoint.h */, + 8CA21A5FBB404BC0CF4F23BD4C5416F3 /* STDSEllipticCurvePoint.m */, + D89A81669E4A065FF0FE35260D05B217 /* STDSEphemeralKeyPair.h */, + 46BB6A49A4825C4F1703C49EAD7D5BE3 /* STDSEphemeralKeyPair.m */, + 03910FB9857DD28462E8F90639BBC655 /* STDSEphemeralKeyPair+Testing.h */, + 283BAC5B7B76CCC28073F1261D92D3AE /* STDSErrorMessage.h */, + DAC85F5C5D2FD0C0550FF6374EA62CB0 /* STDSErrorMessage.m */, + 452B1991BCE20FF2407E6F731208FFC4 /* STDSErrorMessage+Internal.h */, + 1A1B6B7E75482437E3EE31548C812FBA /* STDSErrorMessage+Internal.m */, + C311C57196B2E3BDF8E4A5D9D5A19382 /* STDSException.h */, + CD92FCE49C77B940DA1D70F958ED1187 /* STDSException.m */, + 5499F2612A331A8CBD93E46EEE3D1650 /* STDSException+Internal.h */, + 25315BBCA00488C6108D8438AC2089EC /* STDSExpandableInformationView.h */, + 5F42A1E0E18999703CBBFEBB56145E7F /* STDSExpandableInformationView.m */, + E6518D0ADC9D010B4016FB0A7855F6F8 /* STDSFooterCustomization.h */, + 8BD373964B676EF2C5966D4B81EC2072 /* STDSFooterCustomization.m */, + B01A806A185889C078952DA2E94E5372 /* STDSImageLoader.h */, + 8AF5878DD180D6DE5F240D5479A7FCA2 /* STDSImageLoader.m */, + AC0688418DF7B5E75A4B1CE00FB7024E /* STDSIntegrityChecker.h */, + 6C597B8E71A5E225982129EECCCDF62F /* STDSIntegrityChecker.m */, + 9F7356AF9FD486BC92EFA25CA3B5006F /* STDSInvalidInputException.h */, + 32A3DBB4286DB994E453A3241DC20834 /* STDSInvalidInputException.m */, + 93F9CD920768D4661AF7CAC83BCC332D /* STDSIPAddress.h */, + 38FDD264C34D13D6C5139E02B5E3429E /* STDSIPAddress.m */, + 01A9C02EFDED19245C2C5A380F52A0ED /* STDSJailbreakChecker.h */, + F46F0873B0AE714CC2E6CBFD340FF352 /* STDSJailbreakChecker.m */, + A45E5CCC06EACD4C6011001C040737A5 /* STDSJSONDecodable.h */, + A31ED8DAEC3BB7239795D73A0C3F3410 /* STDSJSONEncodable.h */, + 2A5A6E2AB39AD7F0E62C71444A3FF881 /* STDSJSONEncoder.h */, + AF21456AD4F54FD346DC645B6D3FA726 /* STDSJSONEncoder.m */, + CAFC1ED8731AE396871EED7AC1178787 /* STDSJSONWebEncryption.h */, + 40B004CC31F235FB5D0299B92F3F939A /* STDSJSONWebEncryption.m */, + 0C14FCFB236C6FBB02FE6B9570F40375 /* STDSJSONWebSignature.h */, + 8261E3AB13EAE1E40AF14930BCEEC87A /* STDSJSONWebSignature.m */, + 568118646C2B9E717286C4651734B8D0 /* STDSLabelCustomization.h */, + 334B40A9E0C181C9569B78891404779D /* STDSLabelCustomization.m */, + 1A70E31830D31A711BFFFA3C5B24EAFA /* STDSLocalizedString.h */, + CD067661A0C2C554CF5379FD1AC3BE1F /* STDSNavigationBarCustomization.h */, + 9CBD97FAC70D5151B1E49A18D086FA28 /* STDSNavigationBarCustomization.m */, + C928A5EABEC12D99C0C41619CDE2D94D /* STDSNotInitializedException.h */, + F7C0B6BBB78650A9B91E8D5D5A11D170 /* STDSNotInitializedException.m */, + 39A89F94F62DD307FA1B976758F78D73 /* STDSOSVersionChecker.h */, + 891281DF53F382C2F01F71B505A2108F /* STDSOSVersionChecker.m */, + 134A57537C47623876A363227A399DE8 /* STDSProcessingView.h */, + 8304758C2DC812DF0770A6790676DB4D /* STDSProcessingView.m */, + 731CFC342FD7F097CD3710722F6E80E3 /* STDSProgressViewController.h */, + 5AE4E50BAA23DE344F16F409B862C98F /* STDSProgressViewController.m */, + 32899D96AA85B67283ED2547D3E05BB6 /* STDSProtocolErrorEvent.h */, + FFB85B4D6964DB341F8D02835F8235FC /* STDSProtocolErrorEvent.m */, + 46DD3A21888BE80122BB4C39AECE8C66 /* STDSRuntimeErrorEvent.h */, + 5F226DBA46EA23FC0AD0054FA29C08C5 /* STDSRuntimeErrorEvent.m */, + FE41B23FCE5856C930AEB856BE863DFE /* STDSRuntimeException.h */, + 923E91BF764190E7B3C0E6AE6768FC1C /* STDSRuntimeException.m */, + A16E4D52A285D227F5E248CE6098E96C /* STDSSecTypeUtilities.h */, + 0EC9A9407672A47FB13A5FC199883E3E /* STDSSecTypeUtilities.m */, + 3D468BAE407184775B5DAD5E74EB7816 /* STDSSelectionButton.h */, + E799BF777DAD19532060DD4EC5A4D21E /* STDSSelectionButton.m */, + D5BADA779B0940EAFCAF5D5C3BC5369F /* STDSSelectionCustomization.h */, + 5126E22B7F9BDB09DB115787314D4DF9 /* STDSSelectionCustomization.m */, + 7D78A4949D3C0A01AD01CC778EE68505 /* STDSSimulatorChecker.h */, + A49EF7069046091B2BC0FCD9960DE8E2 /* STDSSimulatorChecker.m */, + 0B7E0F91CC4790A329303D0CD7F34DAC /* STDSSpacerView.h */, + E38EDCFC0E27E0450E7DB7D6EC60C9FE /* STDSSpacerView.m */, + 5450B5EC7ACBAB30D5FEFE776CBB94C8 /* STDSStackView.h */, + 7BD789ACD33E73CFC7D374760BBCFC07 /* STDSStackView.m */, + C31BF779081BE5194C18F1D97EBBD240 /* STDSStripe3DS2Error.h */, + 8ABE8C85E8FC12796B17E780CB924846 /* STDSStripe3DS2Error.m */, + 1E48F583C322F895591736E2EE3A9D74 /* STDSSwiftTryCatch.h */, + C3C4694ED35A2FB67C72EB52A482243E /* STDSSwiftTryCatch.m */, + 2E4064ACE1479DD23ACEC0DC69AD61BC /* STDSSynchronousLocationManager.h */, + 56A8426512B05F3F66165BE187E7DBC3 /* STDSSynchronousLocationManager.m */, + FFE5DBD6034385644C0125535D30076B /* STDSTextChallengeView.h */, + 10066A2223CBF75142915E950689891A /* STDSTextChallengeView.m */, + 3CA726D8D07BC2DD4AC5CF3D6FB06958 /* STDSTextFieldCustomization.h */, + E3D16E6471F8D138E3BD88E4FDC0F8FA /* STDSTextFieldCustomization.m */, + 209BEBD40F07D43B691D3367032EBFE9 /* STDSThreeDS2Service.h */, + 56A4C47B9C636C2E9C2169375FE3B87C /* STDSThreeDS2Service.m */, + 26C20D5D39C54DAA46854DB9DC6B6EB7 /* STDSThreeDSProtocolVersion.h */, + 2EC5D574B6CE9C38A269696E455C14DC /* STDSThreeDSProtocolVersion.m */, + 5E98E0A80EACE6D763BFF6171F22E5AF /* STDSThreeDSProtocolVersion+Private.h */, + 04085F0021DC1396605BE5F2EE636D66 /* STDSTransaction.h */, + 836DE9DD2FE1EB8835953F60C015D066 /* STDSTransaction.m */, + 3CEF0E39AF8543EB7223811AE62CCA59 /* STDSTransaction+Private.h */, + 15AD669247185390F5190AFD168375DF /* STDSUICustomization.h */, + 2E2289167D181B642613D4463E04339B /* STDSUICustomization.m */, + 69C0509774EAEAF4CF9BC2D02989049F /* STDSWarning.h */, + E7171C229B618E7F245C1E060D855524 /* STDSWarning.m */, + 065A9053EB46701FD1D2B278797D0E03 /* STDSWebView.h */, + B6ACAE0E7420B0102A5B11414A885556 /* STDSWebView.m */, + 80FEF0315875F9EF508E8000273D5416 /* STDSWhitelistView.h */, + 2C4AF2F997036A42580AB4A1F059F993 /* STDSWhitelistView.m */, + 1FF185B963FB99EF224ED52DABA01E82 /* Stripe3DS2.h */, + C8B3102EC25FBA1A55C5DB8BAAF29A2C /* Stripe3DS2-Bridging-Header.h */, + 45CC895FC6FB5B914EAD7243B1458122 /* UIButton+CustomInitialization.h */, + 783EDB1FA1DD3BD623BEE6D52F603C55 /* UIButton+CustomInitialization.m */, + 6EA8928C59E02CC416929F0C2B66219E /* UIColor+DefaultColors.h */, + C61146BA817F5C94D62CF1642E5225C8 /* UIColor+DefaultColors.m */, + 1ED24B16FAE7F929952656DAEC8C0246 /* UIColor+ThirteenSupport.h */, + 7F6BD33A351A88259F6CA8F0B2C37C1C /* UIColor+ThirteenSupport.m */, + 2752FE03683F3943213462240A793E08 /* UIFont+DefaultFonts.h */, + 611A742A8611B58B61FB2CB1A9BF2426 /* UIFont+DefaultFonts.m */, + AA0F9A61C7406D5FEEE182804BC1172E /* UIView+LayoutSupport.h */, + 2CA78CD1E904D7029982A7DA5AF65AAD /* UIView+LayoutSupport.m */, + 834C33D3D45A0C2D5CCAB4F1C3246EA0 /* UIViewController+Stripe3DS2.h */, + D7AB48E00CD1FC22362E33B74E6EFFFD /* UIViewController+Stripe3DS2.m */, + 935FF1FEBAE425FBC1F9A9F018CE087C /* Resources */, ); - path = Nimble; + name = Stripe3DS2; + sourceTree = ""; + }; + 204BF320E11014414D53166EB7C125A8 /* iOS */ = { + isa = PBXGroup; + children = ( + 54808C6C88411583D225CB43662CF2A8 /* Foundation.framework */, + 03D9F470BE7939CC23898F0F41EF0B5E /* UIKit.framework */, + AE438E25F67548080875B1E9D861E554 /* XCTest.framework */, + ); + name = iOS; sourceTree = ""; }; - 3FBC8250D8902D858BF14BCFE2C4831B /* Support Files */ = { + 20BBABA2B7BB3870BB3BB47B8BDBBA7A /* Support Files */ = { isa = PBXGroup; children = ( - 718ABA2E524F929C4106CFE711012B87 /* Quick.modulemap */, - 7F6D4322ABB010AB0EEC279249B17918 /* Quick-dummy.m */, - DF776FF666679B4CB34B0A18B1F5B307 /* Quick-Info.plist */, - 766A5EA3A362FFD45458AAB04D1B9FB4 /* Quick-prefix.pch */, - AD1B7F0757B5057BCF6D7D1F6B0B7BD1 /* Quick-umbrella.h */, - FD89D255CE96F4B06B98FE303E825DDF /* Quick.debug.xcconfig */, - 51BA9038051E613E9BCC9972FB613CD3 /* Quick.release.xcconfig */, + FC542ABE1DB9344A59A778F94A59DB9F /* ResourceBundle-Stripe3DS2-StripePayments-Info.plist */, + 1736D4BAB6DBB8E1644E09005752C2AF /* ResourceBundle-StripePayments-StripePayments-Info.plist */, + 8319B73D2C997403285319BE83E26C28 /* StripePayments.modulemap */, + BAF7876859F6A7CD7E75CF411F68334E /* StripePayments-dummy.m */, + 17976A6E437D766A06ADD235EC645E0F /* StripePayments-Info.plist */, + B8959DF6BE8A734C573FAFA96E84E742 /* StripePayments-prefix.pch */, + 2D69CD9ABD5DDEE858DDA4E80A6CBA53 /* StripePayments-umbrella.h */, + E59BCCA0DC94889AFD7ADE8CD22E988F /* StripePayments.debug.xcconfig */, + 36B234BEA176DCA527565B3A67899B7B /* StripePayments.release.xcconfig */, ); name = "Support Files"; - path = "../Target Support Files/Quick"; + path = "../Target Support Files/StripePayments"; + sourceTree = ""; + }; + 368E4D342F17051E8AB899ED9A654F99 /* Pods */ = { + isa = PBXGroup; + children = ( + 0438694B56B3F1A3280844F9B55FAC4D /* Nimble */, + 378706EE315620F36CEDA4C8475D39CD /* Quick */, + D7C02C180F6F0EB9958C4388FAB93E42 /* StripeCore */, + 6768A3018C4677E245C704A4D55D5E1F /* StripePayments */, + ); + name = Pods; + sourceTree = ""; + }; + 378706EE315620F36CEDA4C8475D39CD /* Quick */ = { + isa = PBXGroup; + children = ( + 693E1FDF28EBF010E045BA1CBECFE690 /* Behavior.swift */, + A5627B275B74FFF496E93813F7C13671 /* Callsite.swift */, + 9063A8C24A5E606AFAC2535BD0014BDB /* Closures.swift */, + 413E55C32B8C10177DAFE56899148490 /* DSL.swift */, + C0173B06791A9BEDF7A74E77CB488DFA /* ErrorUtility.swift */, + A2A3E6B30EB1966A53E390AFBBA33BFA /* Example.swift */, + 12C00397639245C26EF6B232E3D18D39 /* ExampleGroup.swift */, + 6F81E85314042226003AF38B2D84665A /* ExampleHooks.swift */, + E35BA28DBB2CD8D04D3F6BAA73B05FD4 /* ExampleMetadata.swift */, + D80532177CEAC4A052D9C672535F39F8 /* Filter.swift */, + 2FD07CCB4F714C60AF38E78DCD9F5325 /* HooksPhase.swift */, + 0F548AB251AC48E38AEC5763CEC1679D /* NSBundle+CurrentTestBundle.swift */, + C679BA4C5B2D4A2C944C1D492590A31C /* QCKConfiguration.swift */, + 053B61719B4CBA9537CBFF4C7EF8AA0F /* QCKDSL.h */, + DD9F4B778364E59D43A2F69D2E1CD0F8 /* QCKDSL.m */, + 9D766D6524D7B25D8DF641AE8471D814 /* Quick.h */, + D1706788AB559B2764779D59CB3F9CFB /* QuickConfiguration.h */, + D6A3DC41A2292AC166BEB9C49903B205 /* QuickConfiguration.m */, + A35FCF60B5E331DA456844DDA2CA38E7 /* QuickConfiguration.swift */, + A186D36A0EE28C51E4FDB061E865AD36 /* QuickObjCRuntime.h */, + E1CA084EE92AC1E9F6B6EA26953364FE /* QuickSelectedTestSuiteBuilder.swift */, + 4C94DA0E96F62A89B36D4FAD754C1ED2 /* QuickSpec.h */, + 8D0F4C067C6ED33DC645C8A9C5697B8F /* QuickSpec.m */, + F8727829B9B2E48FA0478FE40FC9FE02 /* QuickSpecBase.h */, + 6D5BF6A82D35D5DA69E94704D9DA5511 /* QuickSpecBase.m */, + A26890A9CFDDF7189B2CE5DC665EA8BF /* QuickTestObservation.swift */, + A48790581DE4CFC1D56F5741E2DE130D /* QuickTestSuite.swift */, + 97E6A59FF453A35FB49B840C2B1CD471 /* String+C99ExtendedIdentifier.swift */, + 0495AD8123610ADD73CF2D15C24F10A4 /* SuiteHooks.swift */, + A517E1F0F0973404AFEE7F63ABCDEDA6 /* URL+FileName.swift */, + 2B2B90235B1E265D07486341C7BBBDB1 /* World.swift */, + EB7B6A38D2BE807D5F5B94C96BB7325E /* World+DSL.swift */, + D89BE132FD720081D0F88167D50A37E8 /* XCTestSuite+QuickTestSuiteBuilder.m */, + C10BAE26F491DAC5C857C63CEB0CEC89 /* Support Files */, + ); + path = Quick; sourceTree = ""; }; 46F0087507A0AAD50FB158AA72B6BD9A /* Targets Support Files */ = { @@ -451,65 +1897,309 @@ name = "Targets Support Files"; sourceTree = ""; }; - 6ED66B56EF14ED94784F9F705A021130 /* Products */ = { + 4E29D51E2176678F352FB04E0FA35831 /* Resources */ = { isa = PBXGroup; children = ( - BAE263041362D074978BB3B577DF0A05 /* Nimble.framework */, - C914B482E199C7EDA35291B58CEC2E5E /* Pods-OSPaymentsLib */, - E6BD0403A56EB6AA58FE2224C68F73C4 /* Pods-OSPaymentsLib-OSPaymentsLibTests */, - 0D631E9908483F9525A6B3F36F16CC61 /* Quick.framework */, + 077F00A2042A3D0C16E7463BC7B8B151 /* bg-BG.lproj */, + 4B86CA140DC662A1614E7C61BB493169 /* ca-ES.lproj */, + 0AB1AE5146B37E7E38B5BC5A40BC56C0 /* cs-CZ.lproj */, + 147806AA9A9DBD6E2E7CDF5A2733F977 /* da.lproj */, + 5CCFE00FEAB101DA92225E44E87BA2F0 /* de.lproj */, + 06C5071A5E1022BA2DBD0DB4A27556DC /* el-GR.lproj */, + EBA0CC1401C73CB751DB625A00921E9B /* en.lproj */, + 6B79B7AE0DCE08C4DBCB032571274473 /* en-GB.lproj */, + 634823EB04265CECC1ACDC95F5DC0559 /* es.lproj */, + 2C2BC81412FC00A087BEDBF7DA990E2E /* es-419.lproj */, + E917285F227929D0403A2B2FE7FCA6D8 /* et-EE.lproj */, + 766E347A52AD98B99EEC6F90A69D9F54 /* fi.lproj */, + 14781C8F71AB8D62787DE872AF313BF9 /* fil.lproj */, + 9D6F3A6E6B05F5BA59796216A5FA8119 /* fr.lproj */, + 02E732DEFD11292BCD9174A9C6A07A98 /* fr-CA.lproj */, + F21284806288A28295379C4A74411E98 /* hr.lproj */, + 5907CE599DD4F4A5314A7E446C1548A1 /* hu.lproj */, + 64B0E91A7B514C7093443DFC1DF53787 /* id.lproj */, + D88CFDC73FC1FECF945F9EDC369396EE /* it.lproj */, + 25A82BF67AEC9AC12EB651EDCFF7E284 /* ja.lproj */, + 15FA8A572184CCA188DEF786D5C3825D /* ko.lproj */, + 66046363AA74B29375751A2D4FE68CC7 /* lt-LT.lproj */, + 1D9076470098A7FB4C8DDE1DA51FF76C /* lv-LV.lproj */, + 10BC07CCB954D3F5A862B45897BCB5D5 /* ms-MY.lproj */, + 1173EF3FFD767E414B6BFF00F321EF51 /* mt.lproj */, + EECDEDFAF80F5425938C58B2C452C3D0 /* nb.lproj */, + 4A69A2B39F392EEAEE288BC29547CD71 /* nl.lproj */, + 30B3483633599A7FA3B699D4CE417742 /* nn-NO.lproj */, + F21DCC984F5A8C9A6101163B3ACD6361 /* pl-PL.lproj */, + A023D6FAA60988D3CC883EF0A365BEAB /* pt-BR.lproj */, + 387CCC265AED18EEACFA2BA602EE1EE0 /* pt-PT.lproj */, + BD22EF79E6029B252A7C02F1551AFE24 /* ro-RO.lproj */, + E2E8B2DBFF95E00E33BC8FCAFBFC3459 /* ru.lproj */, + 8E35F29B901662782AC73037AD726186 /* sk-SK.lproj */, + 5C170C5ECB65313D7033A335EA627EF2 /* sl-SI.lproj */, + 47F9BE5443E9C7DAEC42690265EC06C7 /* sv.lproj */, + 658CA849B7FD68987A046BA203033A20 /* tr.lproj */, + CB7F84D2E403492F72A11684D332AFC8 /* vi.lproj */, + 051285ECD621D562C7E22360DD37AA6B /* zh-Hans.lproj */, + 8B3AE7859EF5DBF75496199E8B0A9498 /* zh-Hant.lproj */, + F97ABCC6B07DAA7FE3F8E197174A9FCB /* zh-HK.lproj */, ); - name = Products; + name = Resources; sourceTree = ""; }; - 974814B39C0012DECD183BBB91B32103 /* iOS */ = { + 6768A3018C4677E245C704A4D55D5E1F /* StripePayments */ = { isa = PBXGroup; children = ( - CA8B94E9D3B433157168D1EECCEC11CD /* Foundation.framework */, - 5EBC8F300895E39EA0DF6D6B2B5E6BCD /* XCTest.framework */, + 1567AEFC753587BCFC6E1183B54AB8EA /* Analytic+Payments.swift */, + F282D0C496A4893A54A4A75061578B55 /* APIRequest.swift */, + 07C27B89557353E8CC25C4EC7BA2B3A7 /* ConnectionsSDKAvailability.swift */, + A7625FA16B3529BB97D31FBF6CB29ABB /* Enums+CustomStringConvertible.swift */, + E2C9B1DAD6EDCBDE98D055665BDFFF35 /* LinkAccountSession.swift */, + 73E701E7BEF084798AF74C32917833B6 /* LinkSettings.swift */, + 296D7B7E1FC7859637321935D2EEDA04 /* NSArray+Stripe.swift */, + 751C674B6488C830F75741C0CE6C0433 /* NSDecimalNumber+Stripe_Currency.swift */, + 3B34FEC150B5B0919521FF02A278AD6D /* NSDictionary+Stripe.swift */, + 4D260EAF391420AEA7D4195E8CB97705 /* NSString+Stripe.swift */, + 3EDC69638EBE90E82EB702A92E9F5CD9 /* STP3DS2AuthenticateResponse.swift */, + 7C1EF27595C3111FA09D7019FF5E3331 /* STPAddress.swift */, + E10ACEC9D8441E586D253A5F01D226B8 /* STPAnalyticsClient+Payments.swift */, + 56A20ECC61E5D19EA0EFC66B905D1B01 /* STPAPIClient+ApplePay.swift */, + 59B2447710747DADA1A7FDE8E5D17BA8 /* STPAPIClient+LinkAccountSession.swift */, + C67D96EC417FA89AA73EF5270C28250D /* STPAPIClient+Payments.swift */, + ECCFBD8562CEB28DAA1C33A1957FE839 /* STPAPIClient+PaymentsCore.swift */, + 5BE72988C0B88C57D8FAD6C8D7BF2DE4 /* STPAPIClient+Radar.swift */, + 736B04281FE4BF884DED17087BC29FC8 /* STPAPIResponseDecodable.swift */, + 9B74AA57FD5B68F19374399206D13FA9 /* STPAuthenticationContext.swift */, + 83001213CDB2773DE860093689A1E182 /* STPBankAccount.swift */, + 43E16FAAC49A3E73F1961D1CB93BF9BE /* STPBankAccountCollector.swift */, + 00320049D7D4E5287F446E28FAA07C15 /* STPBankAccountParams.swift */, + 653C3FC026CBEB87F5C175C0FF6DC590 /* STPBINController.swift */, + E012D904769549BAD68BD90860FFD7ED /* STPBlocks.swift */, + 972D107D6428EC5E8D81E749EB6DEFB4 /* STPCard.swift */, + B2ECD2688FF7C89EF3C34F25979A09DF /* STPCardBrand.swift */, + 7E54011CA9597F3B2EC897FD70C4154A /* STPCardParams.swift */, + B966D1B340AC5F7E73477827C816B4EA /* STPCardValidator.swift */, + 4038C3A365C65E433FE06CA7BA58F8C6 /* STPCollectBankAccountParams.swift */, + 15735CC2359689BE68DDD82AA64AF91D /* STPConfirmAlipayOptions.swift */, + 732D15F8A6E845C2B923303FDF38F371 /* STPConfirmBLIKOptions.swift */, + D744262862B82B90B5D9F4181794909B /* STPConfirmCardOptions.swift */, + BFDC381B81D580A4B02A5D75E2F5429A /* STPConfirmPaymentMethodOptions.swift */, + 34A927CDFA8ADB3ACE06A83F3000FE62 /* STPConfirmUSBankAccountOptions.swift */, + C88A58FEC7E0BE3C99E16BFA8B1D7E2E /* STPConfirmWeChatPayOptions.swift */, + 44883319135827CA66740EFB62CC7429 /* STPConnectAccountAddress.swift */, + 9B26C7EA50966EF31016ED82F61A9DC6 /* STPConnectAccountCompanyParams.swift */, + 14FBD3E0630472217181870FDB97B602 /* STPConnectAccountIndividualParams.swift */, + 7418FE280E333B264F556BA11328D50C /* STPConnectAccountParams.swift */, + ADD5BBE5DC1BEB17AF75F27CF281BE0B /* STPContactField.swift */, + 8F5857C3430F56199E5306C6F0349DF6 /* STPCustomer.swift */, + C48AB1B31BDC3FB774EA3F60C778ADBF /* STPEmptyStripeResponse.swift */, + BF82D2157807DE33D94019BE4F7F25BB /* STPFile.swift */, + 67BE6311C4F34E8994712859CD9CC1B1 /* STPFormEncodable.swift */, + 10F5694961D0A23DC214C7A1A614F78C /* STPFormEncoder.swift */, + 176A1FCF04CECEC5B248284E0F8E33D7 /* STPFPXBankBrand.swift */, + EC0B26FD827064802B685FBCE24C821B /* STPiDEALBank.swift */, + 325A5722DC9DE1391905216FD4AFF829 /* STPIntentAction.swift */, + E044A86F5B76D0CC71E8D21AD25EE7ED /* STPIntentActionAlipayHandleRedirect.swift */, + 3664BF9D1DF403E0D5CF6BC73B5171F1 /* STPIntentActionBoletoDisplayDetails.swift */, + 68C460E9ECE53C9DD237B0E8B6270A7A /* STPIntentActionOXXODisplayDetails.swift */, + 876DECD5B495AF71DBAEBABF331D4D89 /* STPIntentActionRedirectToURL.swift */, + 0CA0604F6FBB9845BBFAAE7E13BD30AE /* STPIntentActionUseStripeSDK.swift */, + B3AD9A6234AE08A050EE83A678B69C3D /* STPIntentActionVerifyWithMicrodeposits.swift */, + 6377BB294354AAC8F5CF936CE45A39E9 /* STPIntentActionWeChatPayRedirectToApp.swift */, + 65E460ED1ED288806FF0433F7C9E2668 /* STPInternalAPIResponseDecodable.swift */, + D6A764903B3985971868A7BB7BD637EE /* STPIssuingCardPin.swift */, + 597423E1AFB4A8E43A79EB62B8BCD961 /* STPKlarnaLineItem.swift */, + BCB3535181A18B880075F50FFF8AB72C /* STPLocalizedString.swift */, + 1F4A483B9C67F1A3D2489FFA7C0040B0 /* STPMandateCustomerAcceptanceParams.swift */, + 84C663C041851D0E52A3F9962E7E0680 /* STPMandateDataParams.swift */, + FB754D638D39BFC7C92A1158FB7251A8 /* STPMandateOnlineParams.swift */, + E58DA75024D5733493F417C1567B9C28 /* STPPaymentConfirmation+SwiftUI.swift */, + E8C562D4699AF51D606386F895C007AC /* STPPaymentHandler.swift */, + 70A8E487A5A139A0AEBE9CA07D630647 /* STPPaymentHandlerActionParams.swift */, + 824BDCE6763B4D03610E74DBC30F4903 /* STPPaymentIntent.swift */, + 442207253E69A546D816A69280A04D3F /* STPPaymentIntentAction.swift */, + 51BA3F2D891B91AE07E4A51BEA563303 /* STPPaymentIntentActionRedirectToURL.swift */, + 8FBF0235279ED78553212C17484C9983 /* STPPaymentIntentEnums.swift */, + FEC23DC7AF2BAA66F022191D678561D7 /* STPPaymentIntentLastPaymentError.swift */, + CA6F220FA443AA13A65D8D097C0F6D08 /* STPPaymentIntentParams.swift */, + 359723CC69A4D0C4E23A59FAA28256D6 /* STPPaymentIntentShippingDetails.swift */, + 848C2D30B6A61B76B8FEE685ADA9094D /* STPPaymentIntentShippingDetailsAddress.swift */, + 0B2F0EE54C26FBAC5DEFD696CD0CCB91 /* STPPaymentIntentShippingDetailsAddressParams.swift */, + A3EFCE7505CCF7892AAAC7D5050D11AC /* STPPaymentIntentShippingDetailsParams.swift */, + 048BC82B48E322C6ACF6435AD7C34B1A /* STPPaymentIntentSourceAction.swift */, + 52AFBF1868EC913273D1B45D0CBE93E5 /* STPPaymentIntentSourceActionAuthorizeWithURL.swift */, + 2FA35511EB0E5A29FA8FB39FE2925A93 /* STPPaymentMethod.swift */, + 8706D946C8E1B31C6FF28C6C815B3AB0 /* STPPaymentMethodAddress.swift */, + 70005C4375CBFB421E6FE86867C46D67 /* STPPaymentMethodAffirm.swift */, + 9EDEEB7D3BB88F3F2BFD62FC58BADE58 /* STPPaymentMethodAffirmParams.swift */, + EB9C9643167CE17E8EFCD8AEA65A8E50 /* STPPaymentMethodAfterpayClearpay.swift */, + AEE4FC3E871FBBBAF4AC3655CD0F588C /* STPPaymentMethodAfterpayClearpayParams.swift */, + FC87D1514ECB912D2F5CED13BB9ACB49 /* STPPaymentMethodAlipay.swift */, + 9118F02EFC221FE9C59B2E6CD5362783 /* STPPaymentMethodAlipayParams.swift */, + 3131F557AB874A02FAC93F1EAED6CA09 /* STPPaymentMethodAUBECSDebit.swift */, + C238C0F8568BA3ADBB51C71781542E1D /* STPPaymentMethodAUBECSDebitParams.swift */, + CDD26DC95DFB774C078DB4456FAB88E4 /* STPPaymentMethodBacsDebit.swift */, + C4246DC4C9A24781BA3280659F280A70 /* STPPaymentMethodBacsDebitParams.swift */, + F5315E06282EF5E942C54E96A82A704D /* STPPaymentMethodBancontact.swift */, + AE34D75E315D2647406F156B2C66E509 /* STPPaymentMethodBancontactParams.swift */, + E5B4C41EAF053078107667B95E340FE0 /* STPPaymentMethodBillingDetails.swift */, + 47360F9CFB9809719DBC7DC58EE3222F /* STPPaymentMethodBLIK.swift */, + 5DE351F6BD87FDFAA928A765F4FD42B1 /* STPPaymentMethodBLIKParams.swift */, + 89DA4DBD9EE053423AD56C0F90220D48 /* STPPaymentMethodBoleto.swift */, + 212794EB430C46F7E9AFF6095CEA30B5 /* STPPaymentMethodBoletoParams.swift */, + CEF2DCC073BD22139B9B841E3B5E517F /* STPPaymentMethodCard.swift */, + 09F8D6800BE948F806BA63A483D2368D /* STPPaymentMethodCardChecks.swift */, + 46AE2E6FEA38E6A3B1ADF0A2A083411B /* STPPaymentMethodCardNetworks.swift */, + 4A4FC791246944C8E6B8796F90D27EAA /* STPPaymentMethodCardParams.swift */, + C88AA3D0BCBD01CEF746F5DA3D8E5B82 /* STPPaymentMethodCardPresent.swift */, + 6F38DE58C92533FFAD0D80755E2180B9 /* STPPaymentMethodCardWallet.swift */, + 32957EEC2E5CF94B357FB4E9AEFED7AE /* STPPaymentMethodCardWalletMasterpass.swift */, + 57FE59621959B645AB0D91EE111D73C8 /* STPPaymentMethodCardWalletVisaCheckout.swift */, + B9340FFDE6A4B4888DD54151796BD4A2 /* STPPaymentMethodEnums.swift */, + 0F19639C8AA2CFD45C27C253BFFFAB84 /* STPPaymentMethodEPS.swift */, + 247664F527EF0EAB580442338DE2B502 /* STPPaymentMethodEPSParams.swift */, + 3C564FA0EBC44CDB08A1444DED329837 /* STPPaymentMethodFPX.swift */, + B6262A066A13C02F353896BCF68C284A /* STPPaymentMethodFPXParams.swift */, + 979D41D78D59AA209C7CEE1078AFEADD /* STPPaymentMethodGiropay.swift */, + 46CE0A5841318D1F266C9D542B69B9DF /* STPPaymentMethodGiropayParams.swift */, + AF0D4FB04C836E44752A314B31469183 /* STPPaymentMethodGrabPay.swift */, + A943AD416632652905E4C850E18E2F8E /* STPPaymentMethodGrabPayParams.swift */, + 7730C169501EB9BA94B6002C839BA27D /* STPPaymentMethodiDEAL.swift */, + DE35A27E9F5A3639F9CEE37E4C7CC50C /* STPPaymentMethodiDEALParams.swift */, + DB9D19863D2E487C366ABCF51F30308E /* STPPaymentMethodKlarna.swift */, + 8D614D6133986855F759C86B1E3D6B40 /* STPPaymentMethodKlarnaParams.swift */, + 372B25E935274FF2EDD7057837EDF8A2 /* STPPaymentMethodLink.swift */, + 104E18997DC724D99094B4B2A8EA2132 /* STPPaymentMethodLinkParams.swift */, + FB2AC83D43791CFB270543967C85714F /* STPPaymentMethodListDeserializer.swift */, + 7CC131053FC529177E058091853ACBB4 /* STPPaymentMethodNetBanking.swift */, + 90B657183C9A0D2F44AFF285746F368E /* STPPaymentMethodNetBankingParams.swift */, + D434B28FB35F3FD4F2BD6DCB5A84511C /* STPPaymentMethodOptions.swift */, + DF29F7FAD43EBFA1799F81703A83964A /* STPPaymentMethodOXXO.swift */, + EE83B40122127C56C473BB9BF4B8C18D /* STPPaymentMethodOXXOParams.swift */, + 74C1334BBB0CD640AEEE942300A5C0F9 /* STPPaymentMethodParams.swift */, + FB11E840CC2E2C1D0EF2EBD6F3B83800 /* STPPaymentMethodPayPal.swift */, + ABD503531BA02821DCD280C2288A316C /* STPPaymentMethodPayPalParams.swift */, + 6B5B072397E3B84F6004C05A7BE64C29 /* STPPaymentMethodPrzelewy24.swift */, + 7E874403635CC972DD772EC44534DEBB /* STPPaymentMethodPrzelewy24Params.swift */, + 47AEC729BAF456DCA88A96334C835B27 /* STPPaymentMethodSEPADebit.swift */, + CAB5C0235D9DD565A361624426F57448 /* STPPaymentMethodSEPADebitParams.swift */, + C298BDCCBD2AACD2DEA8CDDC5FD6697A /* STPPaymentMethodSofort.swift */, + 1F631064D7CB9096CD13E6ACEE7BED19 /* STPPaymentMethodSofortParams.swift */, + 6F2C49A88CCD41F403C5BE7CD357F325 /* STPPaymentMethodThreeDSecureUsage.swift */, + 569C2A06774DF971F12A7C47C3884DA8 /* STPPaymentMethodUPI.swift */, + E1188BBCB393902B5E37C0B1746CAFCE /* STPPaymentMethodUPIParams.swift */, + 02C5EB104E05FA96C126340C58B899EC /* STPPaymentMethodUSBankAccount.swift */, + D91D402F64E85A15A9B3AFEA817B8FB2 /* STPPaymentMethodUSBankAccountParams.swift */, + 9B96E139B87973CB2C525F018B20AA12 /* STPPaymentMethodWeChatPay.swift */, + FECE9A949CF578DBE8A520691843CA88 /* STPPaymentMethodWeChatPayParams.swift */, + 5A5C99F67007365C562DD1294DBD73DA /* STPRadarSession.swift */, + 88EA388CF5C8EE9BB519A1E5E6091C55 /* STPRedirectContext.swift */, + 1702A313BFC0C3F57587D2CD19916460 /* STPSetupIntent.swift */, + 749B79C9C86B7E14C5009B78B1E0D141 /* STPSetupIntentConfirmParams.swift */, + 17B1F0AE0203F3DB424913E455530C86 /* STPSetupIntentEnums.swift */, + 498401C6C3549CA6217606C586D593A2 /* STPSetupIntentLastSetupError.swift */, + 6683A27B85EA014BFD6E373385D1110E /* STPSource.swift */, + D4A0099670320E0A61A6EC006DFED651 /* STPSourceCardDetails.swift */, + 0FC4784F6CFE516E67A500EA1188794A /* STPSourceEnums.swift */, + 7A70552201EE224B319451BA38E504C9 /* STPSourceKlarnaDetails.swift */, + 5E6FE7DE869B97FD231A9E841B9A515D /* STPSourceOwner.swift */, + 74CA148030F6253CC496090DE0F88268 /* STPSourceParams.swift */, + F2A1C609918CBF59373233370DB12637 /* STPSourcePoller.swift */, + EBCAD22C7789720CF047DBF38A8D34E7 /* STPSourceProtocol.swift */, + 0A6179DC66BD0B1B7454C6A05DCD5313 /* STPSourceReceiver.swift */, + CF576601F70ADC56672DA5E916452C88 /* STPSourceRedirect.swift */, + DA9375A5C2F58B4C0B4C74148B397674 /* STPSourceSEPADebitDetails.swift */, + E5EDE192F55569328BBF6D6F4BAB9F04 /* STPSourceVerification.swift */, + 6B50A752E2809107CB299D3C0202B2B1 /* STPSourceWeChatPayDetails.swift */, + 86A166B019E81AF19FD7E04AE6EF6DFB /* STPThreeDSButtonCustomization.swift */, + C1A3520C47E6A3BB8141D861D8C81B07 /* STPThreeDSCustomizationSettings.swift */, + D4B91C5B9E0B11712BB70F73302CDDDF /* STPThreeDSFooterCustomization.swift */, + 9CDE34F348B121C7F912F3C9B961B044 /* STPThreeDSLabelCustomization.swift */, + 4EDB069FE5B735AB6777009C5B0A8417 /* STPThreeDSNavigationBarCustomization.swift */, + 369928B93AB7FF9854E9571FD5DC9C88 /* STPThreeDSSelectionCustomization.swift */, + 640EC78C807E1AA131D2EB0F2652750C /* STPThreeDSTextFieldCustomization.swift */, + A2B26C6CDB5006E346FB443C2590CAE9 /* STPThreeDSUICustomization.swift */, + 5FE6F6AD5F607A825507562A6AF83790 /* STPToken.swift */, + F60D4AA67B1691FFF600656AA3B1C26E /* StripeAPI+Deprecated.swift */, + AB06A94245433C3D9BA6B7F1DE55F379 /* StripeApplePay+Import.swift */, + 85DB610619181E933973768373CBF80A /* StripeCore+Import.swift */, + 7AAD6070C98EFE973EABC23752F3C257 /* StripePayments+Export.swift */, + 2A80A07639D6D832E3EC175E25BF7512 /* StripePaymentsBundleLocator.swift */, + B2F4A4BA8F0707F38C541FDEB5DEF6EA /* Resources */, + 115E61B0EC34D1E9613F9233128F82D4 /* Stripe3DS2 */, + 20BBABA2B7BB3870BB3BB47B8BDBBA7A /* Support Files */, ); - name = iOS; + path = StripePayments; sourceTree = ""; }; - 9CD6E9346741C4B09B5C94340207FFE0 /* Quick */ = { + 7CCE3476250A622A2F331AD038321E95 /* Products */ = { isa = PBXGroup; children = ( - 45F6B7AC8B7979F25F17036731EE339D /* Behavior.swift */, - BF200F89D143FA102042E6D285D5B6B2 /* Callsite.swift */, - E1F00FC1EB20AC2CA0B5B083F84159A5 /* Closures.swift */, - 3CE338476557D8F2CF2B6E987F5A31CA /* DSL.swift */, - CD87F111AA17D3829427C832EB042273 /* ErrorUtility.swift */, - 7CDC6B9AB35B53FC579C731AE67FD846 /* Example.swift */, - 5813F3776773A4275874BC369BB34A01 /* ExampleGroup.swift */, - 2362FBD489CCE1D540C808716D1EB8C4 /* ExampleHooks.swift */, - 50FAC3D0F71CAC2AEF632440A982DF9D /* ExampleMetadata.swift */, - DB836F954501FFEA0AA8E87E8856D7A7 /* Filter.swift */, - EBC4D3688977E2D961A8F985B1FC0F73 /* HooksPhase.swift */, - AF3CEFA5153F8ACE3EA7629E00B17B8F /* NSBundle+CurrentTestBundle.swift */, - 88CE28DB5FFB584E123C56C4345A73E7 /* QCKConfiguration.swift */, - 43D9B7DA298758F3F8912543839CC426 /* QCKDSL.h */, - 230259C7BBC0AB021F9278A064AADAC1 /* QCKDSL.m */, - E7639378BFCFD4BC8587A03243C01A64 /* Quick.h */, - 32395E85CAF13637932ACEECADC2D96D /* QuickConfiguration.h */, - E6BB1E6C30B81EDB33EC7FDB6C205C79 /* QuickConfiguration.m */, - 204E01215147E1CFDB134360F8F1938E /* QuickConfiguration.swift */, - 622317B228B6CF5C9D75DA1008B0F2B8 /* QuickObjCRuntime.h */, - CDDFBC1CEF007E69BBCFDEFF88615F2C /* QuickSelectedTestSuiteBuilder.swift */, - F75E74A600C812323367AD98A7E46500 /* QuickSpec.h */, - 254558E5834898D2301B3E8C4F620311 /* QuickSpec.m */, - 60403D3F19863854702A6361D7F61850 /* QuickSpecBase.h */, - 0A6115706ED27012A9F43E253D3D3DD7 /* QuickSpecBase.m */, - 350B976ED907275DDED563482009AFD2 /* QuickTestObservation.swift */, - 289E9ACE73C6629DAAEA21D42495B76E /* QuickTestSuite.swift */, - B14A4B16D42CCCBE3D21CBDE4FFC9AA4 /* String+C99ExtendedIdentifier.swift */, - 880EBA466E9150F71DE3C4A76DB140D8 /* SuiteHooks.swift */, - 2AECA1C81ADFA2CA35D84DC7FF1902B2 /* URL+FileName.swift */, - C53261F42083B42E49E80904A433DE8A /* World.swift */, - F3ED266DDE9C244816DD6A53157F8745 /* World+DSL.swift */, - 0BB908657F2C86943C6660C8F0130CEB /* XCTestSuite+QuickTestSuiteBuilder.m */, - 3FBC8250D8902D858BF14BCFE2C4831B /* Support Files */, + BAE263041362D074978BB3B577DF0A05 /* Nimble.framework */, + C914B482E199C7EDA35291B58CEC2E5E /* Pods-OSPaymentsLib */, + E6BD0403A56EB6AA58FE2224C68F73C4 /* Pods-OSPaymentsLib-OSPaymentsLibTests */, + 0D631E9908483F9525A6B3F36F16CC61 /* Quick.framework */, + F2A1401CA8459B8838AA3410E4768D45 /* StripeCore */, + 18732DE2E9C58AEC17E6DD6B7CF9FFA2 /* StripeCore-StripeCore */, + 438D5204F2714F9C297FB5C27756E888 /* StripePayments */, + 7DBC3A921194DAA2FBCAC320884C52B5 /* StripePayments-Stripe3DS2 */, + 7075296E1C69930CC25D5670AC153811 /* StripePayments-StripePayments */, ); - path = Quick; + name = Products; + sourceTree = ""; + }; + 935FF1FEBAE425FBC1F9A9F018CE087C /* Resources */ = { + isa = PBXGroup; + children = ( + 746F6973A7CE90E7B8443A2BC02C6A61 /* amex-logo@3x.png */, + F075F62EAFD0DF773E2CC1CE3BDF89EC /* bg-BG.lproj */, + 8B55E4AA17C775811EA3FE66C8DDFDEE /* ca-ES.lproj */, + CFE5B7DCFAC4F2FF0A54BA45B0867808 /* cartes-bancaires-logo.png */, + B37A9AC2E7D98DE4CC0C23F9DE5AC667 /* Chevron@3x.png */, + 4CE19E837C101FE89DCEB4A796803AB2 /* cs-CZ.lproj */, + 04615DC24469B5770473F2C49A13B548 /* da.lproj */, + EA85AA2D91AD44468F462278A69820BE /* de.lproj */, + FE3674CB887E4AC22FB1FF789057D53F /* discover-logo.png */, + C3DE0AFB197D44F5B86CEDD53F8632B9 /* el-GR.lproj */, + 7ADF2C73CA362B44CA48E40E9B7F17EC /* en.lproj */, + 8A0CC1CD9EA3D27F6999D69A4B688807 /* en-GB.lproj */, + 0F7B4901ECF2394EA1A28EE677EBEC5B /* error@3x.png */, + 95C7D0C979B1F9BBCC5E6F1EBD2248EC /* es.lproj */, + 5A2D473CCF42F10E99266371FED0508B /* es-419.lproj */, + 10F02E6778D8AB97A8BF670F28940A5D /* et-EE.lproj */, + C2F6A3C91B944FA238751C1C2E54353A /* fi.lproj */, + 5C42087462E099CF003FF1BEB4B6887B /* fil.lproj */, + 0FC81EBC70D3F54547A459C447B572CC /* fr.lproj */, + 5C9C58815409E510E46AB774447F4480 /* fr-CA.lproj */, + FE746D98425B077F5CD27D98DF1B5E76 /* hr.lproj */, + D135AA9F59ACEBBAA2F3EC49F9C3E0A3 /* hu.lproj */, + 051B5D2B1A4E36E5CE60E4AF9F3D8323 /* id.lproj */, + A734158ECFECA6B3FFEEB71D1B6878B6 /* it.lproj */, + 8AD03424911FBF425195C50772474D21 /* ja.lproj */, + F9C29673142619F12CD52DC5620F5F50 /* ko.lproj */, + 85C1E1D0B96FA2F2ADFCAFF86417BBFC /* lt-LT.lproj */, + 09A4FD639857D927B0E8B4AF1953F041 /* lv-LV.lproj */, + 7F5F41998EFB37CF78F99CF0F791E95F /* mastercard-logo@3x.png */, + 85A80EDF1631B6357738E7B417B16D94 /* ms-MY.lproj */, + 7D56768635E337B85B786680BECE1DFA /* mt.lproj */, + FA6AF22C064B0F8424A80A848EC86BF4 /* nb.lproj */, + 6A7BB7F3F161A2073468BD2DCAEC6BD0 /* nl.lproj */, + 16AD524274F54533DA4274E95224FDAE /* nn-NO.lproj */, + 2F8BCD8F4747D61721405F64E14D0979 /* pl-PL.lproj */, + F9BE4F925C2126024E5ED24836EC1B68 /* pt-BR.lproj */, + 8E3A18526902A264BA784EFA7ADDAA0F /* pt-PT.lproj */, + 28C3729DDBD681EA2C39DD9D2F731E5D /* ro-RO.lproj */, + A78E2A3A2EEA2A59499A66C3FCE4C1D5 /* ru.lproj */, + 51A9DE9335F7CC0592DC7AA72D3B4A63 /* sk-SK.lproj */, + 2F29A2AB516AC599B61B93625C2891CD /* sl-SI.lproj */, + 14121A23FD33D0DE147657BC767B60D5 /* sv.lproj */, + 8B33A309520322A241B1193B42EE6348 /* tr.lproj */, + 619E50D28D3CD3C702827667E0DC6C0C /* vi.lproj */, + 772B0769A9D14703FD8D00A8FCFDE4B6 /* visa-logo@3x.png */, + 19BBC418AD7958113B769C2598369D12 /* visa-white-logo@3x.png */, + 6597BB764328DA90E4C2A7D1E4BB6770 /* zh-Hans.lproj */, + 4877F075C2758793EC28F510F8C33578 /* zh-Hant.lproj */, + 68E237402E23B9113D778F5A18968D4A /* zh-HK.lproj */, + ); + name = Resources; sourceTree = ""; }; AAE5607300A4E45071C10DF6B35A33C1 /* Pods-OSPaymentsLib-OSPaymentsLibTests */ = { @@ -529,26 +2219,180 @@ path = "Target Support Files/Pods-OSPaymentsLib-OSPaymentsLibTests"; sourceTree = ""; }; - B716C811F0F14528B6525E2277EA7060 /* Pods */ = { + B2F4A4BA8F0707F38C541FDEB5DEF6EA /* Resources */ = { isa = PBXGroup; children = ( - 184D81A390AC32FF38FF3A0047539694 /* Nimble */, - 9CD6E9346741C4B09B5C94340207FFE0 /* Quick */, + DB4C698481CE6A3B234A1E1FF7D30719 /* bg-BG.lproj */, + D704C0F78EB8A406496B33883E781802 /* ca-ES.lproj */, + 3F8FD76A24715EC95CF1509BEF6C3A0E /* cs-CZ.lproj */, + 7E5046088EC6C2114646D8B07A0EBC24 /* da.lproj */, + ED73A19BD46774DD49D17137BC67F355 /* de.lproj */, + 78D87D1A31F44B74600128A212A1CC77 /* el-GR.lproj */, + 82DEB14A320561F457E94CF0C65223E3 /* en.lproj */, + B4F95FCE335B3F2CBF76F9ECA710D401 /* en-GB.lproj */, + 65688FB4E15C22FBFBB007D1A68DCB72 /* es.lproj */, + 84D6C16E96B06F6F1D11342FD76BF650 /* es-419.lproj */, + 20C58246251D7176AB02C19821A6B78B /* et-EE.lproj */, + D47245DA06CD0D5DDF6943F1D1B40122 /* fi.lproj */, + FB227FBD2833CB63EA2FD954E3F1B547 /* fil.lproj */, + DE972EEDE56DB2BB21B58F174BFC75BC /* fr.lproj */, + 136D983EFF23F79D9508D3BB81A908A4 /* fr-CA.lproj */, + 53EBB9D86B35E049D6F865320CDCE915 /* hr.lproj */, + 730FC11E5EFCFE823AA4A65FC44E05AA /* hu.lproj */, + 16422242E406E9916B4C7ABBF6B3D1F2 /* id.lproj */, + 03EFF7427F270A66E19D421DF08BAA13 /* it.lproj */, + 0EC220DB36D5291F5340C43799393C0B /* ja.lproj */, + B2040FE1DE10144DDAC53FBCAA512977 /* ko.lproj */, + 0979BD7CBA1EABD3257C88B143EA3662 /* lt-LT.lproj */, + 7BA04BA2C2F951AEB0629D2648B73A3C /* lv-LV.lproj */, + 9CC280CD6D2FA8049CDD457EE84EE8AF /* ms-MY.lproj */, + A79C4D99EA191FAE43C7DA6F6B650FF7 /* mt.lproj */, + 1CE8EA6F3E1DFEBE5534C8D0F1DFB621 /* nb.lproj */, + 1DF82D6CFE767555CB959A5F30AB2353 /* nl.lproj */, + FC9481A825A1D89C96258C591C7F867E /* nn-NO.lproj */, + 515609AFE656AE99F197C89E04E08C5F /* pl-PL.lproj */, + 9FE972D98984635A54F809DE38DC4639 /* pt-BR.lproj */, + 9DB35445FC572AC08BE64F7313BCDD10 /* pt-PT.lproj */, + 184CB17D9F1D079E67B9BE9D043F50EC /* ro-RO.lproj */, + A6A6775DD45A9608B960E9A0B53F9DC0 /* ru.lproj */, + DB083F9E459539159BEB120E36C765AC /* sk-SK.lproj */, + 27D2EDCE6B76322090EB359B6F621326 /* sl-SI.lproj */, + 4BC54E260BB8693DC327C31BEF4E1C23 /* sv.lproj */, + CF407AFF06C34D92E915AB3C827DA955 /* tk.lproj */, + 0661BE341FD38AE6F2E228BFF0A3DE12 /* tr.lproj */, + 5B2A61D11231525A85BFE695B2A33DCF /* vi.lproj */, + 61FA3AB7DB6ED5397FCCAF504A9CE2EE /* zh-Hans.lproj */, + 3308E5D86C160F2C68B5CB75982EE128 /* zh-Hant.lproj */, + 74ABAF9B171607E4E180F645D439201F /* zh-HK.lproj */, ); - name = Pods; + name = Resources; + sourceTree = ""; + }; + C10BAE26F491DAC5C857C63CEB0CEC89 /* Support Files */ = { + isa = PBXGroup; + children = ( + EF1E6022A1D6EB7DBC17A2629DEED4D3 /* Quick.modulemap */, + B99A844E813EC8C0FE7F1C1469E68644 /* Quick-dummy.m */, + F8A0B191DEFD36D11CB288C2E97EAF5C /* Quick-Info.plist */, + DBDE9025BF46452D52CBCD5520718CF1 /* Quick-prefix.pch */, + 8E179A72B1C159351C885B5156C71821 /* Quick-umbrella.h */, + 99A3D2F7A445362F85C2478CC5CFFE1B /* Quick.debug.xcconfig */, + 091B29FC638823987C25B0C4C46942D7 /* Quick.release.xcconfig */, + ); + name = "Support Files"; + path = "../Target Support Files/Quick"; + sourceTree = ""; + }; + C18CA5AC20E96324A57A51CEF211576C /* Support Files */ = { + isa = PBXGroup; + children = ( + A9F681E11ED0A2B5CF84A013780F3DCD /* Nimble.modulemap */, + 9415F10BEF551D362BDF622A5FE73D31 /* Nimble-dummy.m */, + 398F0E06C95778B6C5BD548556C7E2D7 /* Nimble-Info.plist */, + 43EED01D17611406F7B707B384FC23B2 /* Nimble-prefix.pch */, + BCBD480A050003A3E0412BB33C4865DB /* Nimble-umbrella.h */, + A14BBC563E581FC8E511ED8EE601E2F9 /* Nimble.debug.xcconfig */, + 135F3A6ABE8D575F90D1FA59ABF9FB78 /* Nimble.release.xcconfig */, + ); + name = "Support Files"; + path = "../Target Support Files/Nimble"; + sourceTree = ""; + }; + C9DCA0A89F8CD1AA795888BE7CF36E7B /* Support Files */ = { + isa = PBXGroup; + children = ( + 72655EB1E6314CBEB54830C6B89FA058 /* ResourceBundle-StripeCore-StripeCore-Info.plist */, + 7B645AFAA5A8FCE8E3D884CED75B843A /* StripeCore.modulemap */, + 5EC537635899CA4178859BACFF28917D /* StripeCore-dummy.m */, + 40CD3D7CB1BB2C1DD656112E382319D1 /* StripeCore-Info.plist */, + CEB3E4DB29598BCB37FBCF9F265A1AA6 /* StripeCore-prefix.pch */, + D7D297E8AF89CAB13A3EEF3EB6D03AF8 /* StripeCore-umbrella.h */, + 9CA4796B315DF582CE3C40EE8FD99F49 /* StripeCore.debug.xcconfig */, + D77381D72A4DFE90938A8B8B8B0B43C5 /* StripeCore.release.xcconfig */, + ); + name = "Support Files"; + path = "../Target Support Files/StripeCore"; sourceTree = ""; }; CF1408CF629C7361332E53B88F7BD30C = { isa = PBXGroup; children = ( 9D940727FF8FB9C785EB98E56350EF41 /* Podfile */, - 1628BF05B4CAFDCC3549A101F5A10A17 /* Frameworks */, - B716C811F0F14528B6525E2277EA7060 /* Pods */, - 6ED66B56EF14ED94784F9F705A021130 /* Products */, + 03C5C200A0787E300053CFA8F53CA094 /* Frameworks */, + 368E4D342F17051E8AB899ED9A654F99 /* Pods */, + 7CCE3476250A622A2F331AD038321E95 /* Products */, 46F0087507A0AAD50FB158AA72B6BD9A /* Targets Support Files */, ); sourceTree = ""; }; + D7C02C180F6F0EB9958C4388FAB93E42 /* StripeCore */ = { + isa = PBXGroup; + children = ( + 0A615105537FBF64E97274D44B7CFBA6 /* Analytic.swift */, + 86358511999BB628CF6F6E581FEB6FC8 /* AnalyticLoggableError.swift */, + 9B47978CCA25949CE4831EEAC847FE9D /* AnalyticsClientV2.swift */, + 2C4FE4623236069C3A2DAB974A3298A8 /* Async.swift */, + D622546EB394438799B3469E08261DD5 /* BundleLocatorProtocol.swift */, + BE0D6877DEC57C4A40A285AFA6AC0DB0 /* ConnectionsSDKInterface.swift */, + 4D24EB31497D5ED7C72E3821B8B5DFF9 /* Decimal+StripeCore.swift */, + EED74C365BEB0277EFBB71118ACA2ADE /* Dictionary+Stripe.swift */, + C78FCAE555CA78A6DDFA24CD5C597CF1 /* DownloadManager.swift */, + 72F0E941A7AFBB57CBC007A3A0673090 /* EmptyResponse.swift */, + 53D48585E0DD371E7575082F5E5D2FA6 /* Enums+CustomStringConvertible.swift */, + 8C4912EE1BDF346B45A19660EDBF268A /* FileDownloader.swift */, + 2C4FA16F4BF9CEC2DB082BAE796A21D0 /* FraudDetectionData.swift */, + C79BA5E40AC06C45B5EF8414419C0917 /* InstallMethod.swift */, + 9FA2D3847F4ECCD49144586976179FC0 /* NSArray+Stripe.swift */, + 062AA013B25534B63F1D9C7A0B1DCCDA /* NSBundle+Stripe_AppName.swift */, + F46B9E382AB9E78D472B92BE10842869 /* NSCharacterSet+StripeCore.swift */, + 3744BDC1A0806F0DED894A00F2712B86 /* NSError+Stripe.swift */, + 97CE0A95804990A9BF59F85837F3EEA0 /* NSError+StripeCore.swift */, + 4450AF2E54ADCF5F7D4B4EAE994D4408 /* NSMutableURLRequest+Stripe.swift */, + 1471C5F4F2DB4EC1A62556579203ECDF /* NSURLComponents+Stripe.swift */, + 9885674AD68E194BC165B76CD7010AD0 /* PaymentsSDKVariant.swift */, + 64754D3C8EFC85ABC74074BD01D0B438 /* PluginDetector.swift */, + 9222B7FD76C3CFA3CC9BFC8CE1D9B256 /* ServerErrorMapper.swift */, + 34A694CA199ED0893F5BCD8DB244F45E /* STPAnalyticEvent.swift */, + 1F24AD37DC0DEA08C0161101911ABDE4 /* STPAnalyticsClient.swift */, + 8D46E93C2A7E6693C20C4AACD43ABF7E /* STPAPIClient.swift */, + C9905384221E499294976CE602E966FE /* STPAPIClient+FileUpload.swift */, + 593760824E1E512A3DF423BF1EA3F721 /* STPAppInfo.swift */, + AE8F8F6432C8A0DB6AD810AE037FA4D5 /* STPDeviceUtils.swift */, + 621387BC9C0ACA90CA0242F6AB9CD213 /* STPDispatchFunctions.swift */, + D889009612AA978F7B4DD2F749ABAD75 /* STPError.swift */, + 60AB9ADFC4EF35A2857FB4F515E28C77 /* STPLocalizationUtils.swift */, + 42C0C827BD5426B6D3D5EAE30475AC10 /* STPLocalizedString.swift */, + 32C63F975EF38DD20430EA221119E83D /* STPMultipartFormDataEncoder.swift */, + ED3D2EB66C4DC42F56DEA740EB759457 /* STPMultipartFormDataPart.swift */, + 30855110E3C79E9436F5C940800643C2 /* STPNumericStringValidator.swift */, + 95CFAB09EC6E141434C0BC08D2017EC5 /* STPTelemetryClient.swift */, + 227D1BB76FD3CE2F3F6DFAB8FD304C80 /* STPURLCallbackHandler.swift */, + 9250616CA2E76E6872BA1EB12B296113 /* String+Localized.swift */, + 5A087B8B9AC3FF949E888C616D76603B /* String+StripeCore.swift */, + 964AB07C9929986507ED52E3847352BA /* StripeAPI.swift */, + B329CD095DF0D07385B9DF3993CF8082 /* StripeAPIConfiguration.swift */, + F88C52ABDD07C21075F06653D2F40D77 /* StripeAPIConfiguration+Version.swift */, + 9ABEE426924F217CD7D941091A32F74C /* StripeCodable.swift */, + 742F741E5982B734AD60D1AF26513D27 /* StripeCoreBundleLocator.swift */, + BA5E4C5DA1266174ECF6D0615DF67D3B /* StripeError.swift */, + 7214D0F2B31EC4D3B8710F5DEEE20118 /* StripeFile.swift */, + D5E32D92D737D28D83830126853FD3F9 /* StripeJSONDecoder.swift */, + 207690A83F45986DB4608DAA78531321 /* StripeJSONEncoder.swift */, + 702AA8B503547D54D21CC4D2C7836ECF /* StripeJSONShared.swift */, + D452640F36C3BA3EB2B44838F3CE5557 /* StripeServiceError.swift */, + C0D54B4D6898F5344AB1E0195A4196FE /* UIActivityIndicatorView+Stripe.swift */, + C4B5A1D68DF412D11EE224DFAF8C13C8 /* UIFont+Stripe.swift */, + 42079B2294C0AE31BA9D6760783EF328 /* UIImage+StripeCore.swift */, + 19A4B6F62FC807F51F8C6FE74F065203 /* UnknownFields.swift */, + 4826274260E8C1435364904F6E10BAAD /* URLEncoder.swift */, + 8D21F409ED0D7696661CA18A76E631D3 /* URLSession+Retry.swift */, + 562E27F799AF54E6BE1994FF9A310A7D /* UserDefaults+PaymentsCore.swift */, + 4E29D51E2176678F352FB04E0FA35831 /* Resources */, + C9DCA0A89F8CD1AA795888BE7CF36E7B /* Support Files */, + ); + path = StripeCore; + sourceTree = ""; + }; E0CF605A153CEE673050F1700727599C /* Pods-OSPaymentsLib */ = { isa = PBXGroup; children = ( @@ -568,14 +2412,6 @@ /* End PBXGroup section */ /* Begin PBXHeadersBuildPhase section */ - 1562ED0D7217E6951085B834D8034728 /* Headers */ = { - isa = PBXHeadersBuildPhase; - buildActionMask = 2147483647; - files = ( - 1E5D8B0BD08347A08E3CC4FF6267376F /* Pods-OSPaymentsLib-OSPaymentsLibTests-umbrella.h in Headers */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; 2ECA8588289B7FD3CD8D5FC71DC87C4E /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; @@ -591,11 +2427,124 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - A0983DF8D45DD32BBE3D12F0B870CFF0 /* Headers */ = { + 3E78C7CE20906907BB738AA1432A3D21 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + BE797FA3DB0FD410B4F4AC3CF1459578 /* Pods-OSPaymentsLib-OSPaymentsLibTests-umbrella.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 826D8E614A94565282F0E47EDB10F864 /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( - 21601609288258F44177C9A71A1A5012 /* Pods-OSPaymentsLib-umbrella.h in Headers */, + 0B6F7269D18831AEAE4A552667633587 /* NSData+JWEHelpers.h in Headers */, + EEAD0208A73938F4686CB17E3BC2483E /* NSDictionary+DecodingHelpers.h in Headers */, + 401A3889E79B0CC33D0660E7C8267712 /* NSError+Stripe3DS2.h in Headers */, + 42507DF71BD6DB7623A9A8E35E7B78BE /* NSLayoutConstraint+LayoutSupport.h in Headers */, + 6CA2B3D04F65BDE7ADBE8FB1C332D1F1 /* NSString+EmptyChecking.h in Headers */, + 911CB8BEC748B2574B0E7182333366CA /* NSString+JWEHelpers.h in Headers */, + C47E9BA563D040E1C2CE668F81114D98 /* STDSACSNetworkingManager.h in Headers */, + DF93796EC89300DFFDC43481ACD86DAB /* STDSAlreadyInitializedException.h in Headers */, + 11D9B13C5D6580960979F4301217F2EF /* STDSAuthenticationRequestParameters.h in Headers */, + 9D3B7EF46FDD56136777830F2173173E /* STDSAuthenticationResponse.h in Headers */, + D1E2A5D51A4EA4D31178E84C8499BCAC /* STDSAuthenticationResponseObject.h in Headers */, + 61B9F6CA3288008E3844B109E029A31E /* STDSBrandingView.h in Headers */, + 91FFBF606785C06075DB50284B24C796 /* STDSBundleLocator.h in Headers */, + 6C8205BED893A04967605C572C57BF3A /* STDSButtonCustomization.h in Headers */, + 6E093F97794335877D471A57CAE58B59 /* STDSCategoryLinker.h in Headers */, + 263395935D45C1121773670783ED6E0C /* STDSChallengeInformationView.h in Headers */, + 7B68D51E405CB6B2160B89A2509F1A7D /* STDSChallengeParameters.h in Headers */, + 414A52FF2807C43A2103B89227239796 /* STDSChallengeRequestParameters.h in Headers */, + BD9C99CC3A6CBF04ECB8DAE5607B6CAA /* STDSChallengeResponse.h in Headers */, + C622FD41098A46A8E83980ADA4D4482E /* STDSChallengeResponseImage.h in Headers */, + 450EC4FBCD013682127F548446D1DD17 /* STDSChallengeResponseImageObject.h in Headers */, + ADC39A904798DB8EE8BB2803659C267E /* STDSChallengeResponseMessageExtension.h in Headers */, + 150D6EA8EA175A2E593FAC636F8E35DE /* STDSChallengeResponseMessageExtensionObject.h in Headers */, + 1C4EACACAA57E65B51F41F54C6948C58 /* STDSChallengeResponseObject.h in Headers */, + 5EFE91D84410F9BB6FC0F92B761D63BC /* STDSChallengeResponseSelectionInfo.h in Headers */, + 0C26C4C97B7718D69626890A9745975A /* STDSChallengeResponseSelectionInfoObject.h in Headers */, + 9A42C573ABD2B7829B040E5D279B2625 /* STDSChallengeResponseViewController.h in Headers */, + A15D7631BE816A3C8C56E53467E91A71 /* STDSChallengeSelectionView.h in Headers */, + F07AE8BFAF6FE6AC2831BB0CCB4BD652 /* STDSChallengeStatusReceiver.h in Headers */, + 68976CA0ECBD78B5BC8FFAC1DB70EAED /* STDSCompletionEvent.h in Headers */, + 8F52028BF8EAE68FF8A208576A96BCB0 /* STDSConfigParameters.h in Headers */, + 3D1B4EF779689D4ACAEF5C2F0470DD41 /* STDSCustomization.h in Headers */, + 2C160C86F93327526AB6E66EED863B5C /* STDSDebuggerChecker.h in Headers */, + C797E150685C683707E98EE909FF8DE3 /* STDSDeviceInformation.h in Headers */, + ADEEFA7488335E095B7AC23A2AA125A4 /* STDSDeviceInformationManager.h in Headers */, + 013181EFBAC8B2708761AAAEA9D0E517 /* STDSDeviceInformationParameter.h in Headers */, + FA266048E8536D7AD9C02B7AA379D5DD /* STDSDeviceInformationParameter+Private.h in Headers */, + 96F551CCB74AA395DCA01B7ADA51EB13 /* STDSDirectoryServer.h in Headers */, + DC79ABFC1AB8BD9DB160295D040A7D13 /* STDSDirectoryServerCertificate.h in Headers */, + 5FB25BDB7662B006741D18B2D2728FB9 /* STDSDirectoryServerCertificate+Internal.h in Headers */, + 4EDC3E59D9D7A2C9E0C7820966B8840B /* STDSEllipticCurvePoint.h in Headers */, + 5512379703F7D5CD28009429ABAF83D3 /* STDSEphemeralKeyPair.h in Headers */, + 95B5293645152CEFBCA7C6D45C64CD1A /* STDSEphemeralKeyPair+Testing.h in Headers */, + B0C91F3BCFD6E2BC046E6CD5F2CEEC59 /* STDSErrorMessage.h in Headers */, + A41B07BCE4F45FE8DB112252BD27C421 /* STDSErrorMessage+Internal.h in Headers */, + FF1B5B34B625C2F0D99BBA0B5018F4EF /* STDSException.h in Headers */, + A89A88434BF91EB84BF5A6444D20D885 /* STDSException+Internal.h in Headers */, + 4719292EA9231EE243B6D78D850BBED5 /* STDSExpandableInformationView.h in Headers */, + 3B0D31C125C21E3D1FA6806279A7369A /* STDSFooterCustomization.h in Headers */, + 72DCB1645FE9AC8529ABDA1973947CDE /* STDSImageLoader.h in Headers */, + 0FC536648DB669163D48B002EEBF83B6 /* STDSIntegrityChecker.h in Headers */, + 73ADAC6E76DA45BA9AD8E93AA86FED61 /* STDSInvalidInputException.h in Headers */, + B1EDABE49814752F1E5C2393F1B048D4 /* STDSIPAddress.h in Headers */, + 844CB33B12AE52C7AAA0D6AB88F89562 /* STDSJailbreakChecker.h in Headers */, + FA44D701996C0C5890B87E655AB09CD6 /* STDSJSONDecodable.h in Headers */, + CE1D75F182433E6B46D9B56ABBE44DFC /* STDSJSONEncodable.h in Headers */, + E813CD63B29D9DBEEF4777CF2C5421D4 /* STDSJSONEncoder.h in Headers */, + C118224691757BDA3D94EAA53F0D92E1 /* STDSJSONWebEncryption.h in Headers */, + B0BFDA4F4358AD77627C92A7D25339D1 /* STDSJSONWebSignature.h in Headers */, + CE0FCF009CA4E5CADEDA7094B4E05C64 /* STDSLabelCustomization.h in Headers */, + 8BF51F8D9ED5F6F99F175EBB8FCA89C2 /* STDSLocalizedString.h in Headers */, + E74A2734AE916F8E5EA0F040EA3CA96E /* STDSNavigationBarCustomization.h in Headers */, + 01CAB7DCB00DB546C3B50A01D220CFA8 /* STDSNotInitializedException.h in Headers */, + 2CDD30891C3534376BA035E18CA889BE /* STDSOSVersionChecker.h in Headers */, + 42686B287B78ACF11B145B038C369989 /* STDSProcessingView.h in Headers */, + 3BDF230E8F33AD82C9EC1BAA1ECCA1ED /* STDSProgressViewController.h in Headers */, + 8FDD9E5B7479DC38D2BFCEB427475E37 /* STDSProtocolErrorEvent.h in Headers */, + 7BC844CA7A35AD615B8F495CF68294BF /* STDSRuntimeErrorEvent.h in Headers */, + 7049CF2F9C4DC901C381FB7E84CE1376 /* STDSRuntimeException.h in Headers */, + C1FEC4072C1F9E1A5C2E67851D8D26AE /* STDSSecTypeUtilities.h in Headers */, + 625D01B2A58AB0AC4F5C39DBC0D72BE3 /* STDSSelectionButton.h in Headers */, + E233D638FA3C0E2828B401C15C9CF98C /* STDSSelectionCustomization.h in Headers */, + 39F17AF72432942F92F3B05F47995410 /* STDSSimulatorChecker.h in Headers */, + 1FB4E8361692A615EE25172BBB54A0FA /* STDSSpacerView.h in Headers */, + 2563805C6F19F5D19343F0781CAB5819 /* STDSStackView.h in Headers */, + 4E45075F0AF7782356F756B55738A1C1 /* STDSStripe3DS2Error.h in Headers */, + B5BF5A7002ADBDEEAF26577FA17600D7 /* STDSSwiftTryCatch.h in Headers */, + 482C5EEAAF5CC5D7052C554D2212932C /* STDSSynchronousLocationManager.h in Headers */, + 31837A5545CAAA9D048B3FAA210FE4EA /* STDSTextChallengeView.h in Headers */, + 2E23462149B401914EAF08BED903AD8D /* STDSTextFieldCustomization.h in Headers */, + B416B20D9539AEA84634293F91CB17B3 /* STDSThreeDS2Service.h in Headers */, + 39D4E2CF72D88E464621AF8E2CACFD20 /* STDSThreeDSProtocolVersion.h in Headers */, + 53B5517387B519E406C3B5A73F3F811D /* STDSThreeDSProtocolVersion+Private.h in Headers */, + F1FBD90D9EE6D42AD6A61D31F0BF8D32 /* STDSTransaction.h in Headers */, + 9DAB06377586D5E1671C825C54F6C336 /* STDSTransaction+Private.h in Headers */, + 12EFFA5E31998174561F3E75B0A81165 /* STDSUICustomization.h in Headers */, + 3E2FBCC52661274287A6C69659A7FAD5 /* STDSWarning.h in Headers */, + 65B344D8EAC0CC0A22EA584F8F1C1715 /* STDSWebView.h in Headers */, + DE0B04BE2053CFC47AC3E280F8953189 /* STDSWhitelistView.h in Headers */, + 9091A2BE5B94E19818700C6ACB123E03 /* Stripe3DS2.h in Headers */, + C04F103AAC2160C18C927BFEA3EADDBE /* Stripe3DS2-Bridging-Header.h in Headers */, + 19BD3FC563FCB4D9351873C56E1B8F38 /* StripePayments-umbrella.h in Headers */, + 7254F83F3CB7D30043C11CB22EB57A97 /* UIButton+CustomInitialization.h in Headers */, + A205FB74A458D7EF2BC5C2C84FE65838 /* UIColor+DefaultColors.h in Headers */, + 814E2CD5547867549C23CA1F12E7E645 /* UIColor+ThirteenSupport.h in Headers */, + A55D9A85997D28048FC2BF4C27383AD0 /* UIFont+DefaultFonts.h in Headers */, + 494E36C4F29FD2EFEF6313CC5D063C0A /* UIView+LayoutSupport.h in Headers */, + 4DF10A5931EF1A1CCBAA58350E113BF6 /* UIViewController+Stripe3DS2.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + E52769F74FB4134CBAB7A0F528B2793F /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + A301D5A026444BA650C75378075DD4D4 /* StripeCore-umbrella.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -613,47 +2562,131 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + F8F80A9ACEE81B443C6FF0894E5644E9 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + 460A8D1A9B312E32076B8554FED70DD6 /* Pods-OSPaymentsLib-umbrella.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXHeadersBuildPhase section */ /* Begin PBXNativeTarget section */ 04AB15DB33DBB70D7B25012DBAB06F1A /* Pods-OSPaymentsLib-OSPaymentsLibTests */ = { isa = PBXNativeTarget; - buildConfigurationList = 00C17C5870BF07DC0D42D38500DDDB88 /* Build configuration list for PBXNativeTarget "Pods-OSPaymentsLib-OSPaymentsLibTests" */; + buildConfigurationList = 14375AC5C0A2CAC523DC4626F8F00B14 /* Build configuration list for PBXNativeTarget "Pods-OSPaymentsLib-OSPaymentsLibTests" */; buildPhases = ( - 1562ED0D7217E6951085B834D8034728 /* Headers */, - F9CF23A2BE65EAF674EE3CCC010F62ED /* Sources */, - 5BACFA62F624BC18081DF90CFC27D336 /* Frameworks */, - BBBF04B4CD4D1ABF95C3C134D06D84FC /* Resources */, + 3E78C7CE20906907BB738AA1432A3D21 /* Headers */, + CB7A3655E85E0925E9FCFE33A1D0C7E1 /* Sources */, + 3CE467C548A08D895A2EC81E04D1880F /* Frameworks */, + F08B2902635192F79460CDFE0E6140D2 /* Resources */, ); buildRules = ( ); dependencies = ( - C9897A3C5A37DA388024EF1B73474E40 /* PBXTargetDependency */, - EFC11406FB1C0273752AF7AA25C48093 /* PBXTargetDependency */, + E2792046891540720AB13E4F1D824214 /* PBXTargetDependency */, + 6B806537A5FA948098A80D1804688F01 /* PBXTargetDependency */, + 836B8F41BA8802C9CE1CE1D2B070FFB6 /* PBXTargetDependency */, + 4834E4D2DE2D286B82AC389109802DDC /* PBXTargetDependency */, ); name = "Pods-OSPaymentsLib-OSPaymentsLibTests"; productName = Pods_OSPaymentsLib_OSPaymentsLibTests; productReference = E6BD0403A56EB6AA58FE2224C68F73C4 /* Pods-OSPaymentsLib-OSPaymentsLibTests */; productType = "com.apple.product-type.framework"; }; + 1A050828BB67BEF7076399FA446EE87F /* StripePayments-StripePayments */ = { + isa = PBXNativeTarget; + buildConfigurationList = 5BF8A7B7F9F0AA6082B9D5D459F39DC1 /* Build configuration list for PBXNativeTarget "StripePayments-StripePayments" */; + buildPhases = ( + 6AF27C6D88B44AC959F24466DD32602A /* Sources */, + 2353C7BD25A0A71DD125C756A62928CE /* Frameworks */, + A1B32F6F5E1FE4A2DF2F0F5877160C26 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "StripePayments-StripePayments"; + productName = StripePayments; + productReference = 7075296E1C69930CC25D5670AC153811 /* StripePayments-StripePayments */; + productType = "com.apple.product-type.bundle"; + }; + 1DFC6E27E6C76D8B0A836C5D658B038D /* StripePayments */ = { + isa = PBXNativeTarget; + buildConfigurationList = 5713E665819F30CE132CA3F4C9E3BB9D /* Build configuration list for PBXNativeTarget "StripePayments" */; + buildPhases = ( + 826D8E614A94565282F0E47EDB10F864 /* Headers */, + 62D14C11677D8A8B08193F35CDA41694 /* Sources */, + 8F3F573A92245FE31FD8C90E4ACF29E8 /* Frameworks */, + A6EB667B5C4DF2E2428C12750D0A8831 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + 632DC3D72D6684931155AFAF67676081 /* PBXTargetDependency */, + D497A8E62607234655A3360278DA4FFF /* PBXTargetDependency */, + 8376B85C71F31B1AB147DB524A5C3369 /* PBXTargetDependency */, + ); + name = StripePayments; + productName = StripePayments; + productReference = 438D5204F2714F9C297FB5C27756E888 /* StripePayments */; + productType = "com.apple.product-type.framework"; + }; 4BB08E2983BD09E8DAED9FA5412B115D /* Pods-OSPaymentsLib */ = { isa = PBXNativeTarget; - buildConfigurationList = 2EC9DC26A2B2F522D07CE5FE7D1EF6F5 /* Build configuration list for PBXNativeTarget "Pods-OSPaymentsLib" */; + buildConfigurationList = 3241BB2EB916EAC79119A233F7C315B3 /* Build configuration list for PBXNativeTarget "Pods-OSPaymentsLib" */; buildPhases = ( - A0983DF8D45DD32BBE3D12F0B870CFF0 /* Headers */, - 14593B72CC5AB1953F9390743FA4967E /* Sources */, - 06AB854D397AC4F5BD7AFCCCEF728C82 /* Frameworks */, - 2BF7505BB62858FF37CE35550D4F3B5A /* Resources */, + F8F80A9ACEE81B443C6FF0894E5644E9 /* Headers */, + 509A86517AFAEAB438DF4AF1E980B074 /* Sources */, + ABAB2B20B44E0AA769E240451131658C /* Frameworks */, + 6877407E6A410C1B6138C33B7813B2A6 /* Resources */, ); buildRules = ( ); dependencies = ( + C9D65FF27431545AEF87FC0EA1392D94 /* PBXTargetDependency */, + 1572B13D3E3B9091F75FF31005825533 /* PBXTargetDependency */, ); name = "Pods-OSPaymentsLib"; productName = Pods_OSPaymentsLib; productReference = C914B482E199C7EDA35291B58CEC2E5E /* Pods-OSPaymentsLib */; productType = "com.apple.product-type.framework"; }; + 5F48D489D9B599786982F278E5F9BCBF /* StripeCore-StripeCore */ = { + isa = PBXNativeTarget; + buildConfigurationList = B9AD2FD5571D1110078EEEE4FC7B61B4 /* Build configuration list for PBXNativeTarget "StripeCore-StripeCore" */; + buildPhases = ( + 9A053CADE39B7F94FD728BB241BE341F /* Sources */, + 23ACBCCC163D54DBAFBBE92176BA9440 /* Frameworks */, + A9D30956908A4EBF7AA94997DA09E592 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "StripeCore-StripeCore"; + productName = StripeCore; + productReference = 18732DE2E9C58AEC17E6DD6B7CF9FFA2 /* StripeCore-StripeCore */; + productType = "com.apple.product-type.bundle"; + }; + 6660405CC6BBF9EC47B377FB74A3F5CB /* StripePayments-Stripe3DS2 */ = { + isa = PBXNativeTarget; + buildConfigurationList = CB105085B6C26121040E9C847298D6D3 /* Build configuration list for PBXNativeTarget "StripePayments-Stripe3DS2" */; + buildPhases = ( + 877050915A632DA468124619562AA8FD /* Sources */, + 9D380316446BAE7577102FECEA11E341 /* Frameworks */, + 412F98D938F01BC5AA4226504428E6B9 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "StripePayments-Stripe3DS2"; + productName = Stripe3DS2; + productReference = 7DBC3A921194DAA2FBCAC320884C52B5 /* StripePayments-Stripe3DS2 */; + productType = "com.apple.product-type.bundle"; + }; 6F13695E06195A78EA8A95F8C7ED0D2F /* Nimble */ = { isa = PBXNativeTarget; buildConfigurationList = 84E3C08133057626870418A290649C7E /* Build configuration list for PBXNativeTarget "Nimble" */; @@ -672,6 +2705,25 @@ productReference = BAE263041362D074978BB3B577DF0A05 /* Nimble.framework */; productType = "com.apple.product-type.framework"; }; + 91ECFC81736C2875C7A5B90E324EDF11 /* StripeCore */ = { + isa = PBXNativeTarget; + buildConfigurationList = D6A6BB866CBA4B13ECD5FB371021DA04 /* Build configuration list for PBXNativeTarget "StripeCore" */; + buildPhases = ( + E52769F74FB4134CBAB7A0F528B2793F /* Headers */, + CC0FAA4C11CB720AF5896EE3E9EAB3E3 /* Sources */, + B38E2F97DDC002785347B4B9A5A0A1A6 /* Frameworks */, + A166852BD799DE37C740CF9947A1FFF6 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + D4FD047ADA2B4BEB00D71713258D85A8 /* PBXTargetDependency */, + ); + name = StripeCore; + productName = StripeCore; + productReference = F2A1401CA8459B8838AA3410E4768D45 /* StripeCore */; + productType = "com.apple.product-type.framework"; + }; C82891EAB7293DBEE916B21F57E8474D /* Quick */ = { isa = PBXNativeTarget; buildConfigurationList = 1D467AF12BCFD8263C61085D135659C3 /* Build configuration list for PBXNativeTarget "Quick" */; @@ -705,10 +2757,51 @@ hasScannedForEncodings = 0; knownRegions = ( Base, + "bg-BG", + "ca-ES", + "cs-CZ", + da, + de, + "el-GR", en, + "en-GB", + es, + "es-419", + "et-EE", + fi, + fil, + fr, + "fr-CA", + hr, + hu, + id, + it, + ja, + ko, + "lt-LT", + "lv-LV", + "ms-MY", + mt, + nb, + nl, + "nn-NO", + "pl-PL", + "pt-BR", + "pt-PT", + "ro-RO", + ru, + "sk-SK", + "sl-SI", + sv, + tk, + tr, + vi, + "zh-HK", + "zh-Hans", + "zh-Hant", ); mainGroup = CF1408CF629C7361332E53B88F7BD30C; - productRefGroup = 6ED66B56EF14ED94784F9F705A021130 /* Products */; + productRefGroup = 7CCE3476250A622A2F331AD038321E95 /* Products */; projectDirPath = ""; projectRoot = ""; targets = ( @@ -716,12 +2809,73 @@ 4BB08E2983BD09E8DAED9FA5412B115D /* Pods-OSPaymentsLib */, 04AB15DB33DBB70D7B25012DBAB06F1A /* Pods-OSPaymentsLib-OSPaymentsLibTests */, C82891EAB7293DBEE916B21F57E8474D /* Quick */, + 91ECFC81736C2875C7A5B90E324EDF11 /* StripeCore */, + 5F48D489D9B599786982F278E5F9BCBF /* StripeCore-StripeCore */, + 1DFC6E27E6C76D8B0A836C5D658B038D /* StripePayments */, + 6660405CC6BBF9EC47B377FB74A3F5CB /* StripePayments-Stripe3DS2 */, + 1A050828BB67BEF7076399FA446EE87F /* StripePayments-StripePayments */, ); }; /* End PBXProject section */ /* Begin PBXResourcesBuildPhase section */ - 2BF7505BB62858FF37CE35550D4F3B5A /* Resources */ = { + 412F98D938F01BC5AA4226504428E6B9 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + F53E45015B7B3F54A7CA33F0DDE8A8B6 /* amex-logo@3x.png in Resources */, + B88FF8B2A1AD4F1A2370F4F1DF1615B9 /* bg-BG.lproj in Resources */, + DC7110DA54AA19B666FCE7F2249FA0C7 /* ca-ES.lproj in Resources */, + A3F0A5092401EA532B629C29A2311221 /* cartes-bancaires-logo.png in Resources */, + 3D615E7FB6345EDF26728BB7095F98E9 /* Chevron@3x.png in Resources */, + 30566EF970A20B8827E7F1AA0522D6A2 /* cs-CZ.lproj in Resources */, + C53F44D60F5541B8B3086F9624325CBF /* da.lproj in Resources */, + 210F16B35E23673227C451C32ED3DD7C /* de.lproj in Resources */, + 33E23F2911A431352E417AD616883236 /* discover-logo.png in Resources */, + 6AB143C321A8D680D0EF0A55C0DCD238 /* el-GR.lproj in Resources */, + F1E88D29094885C08DFBD1AB9ED7E8D8 /* en.lproj in Resources */, + 9EC7AB2EFD97FBE104802C6F0211A284 /* en-GB.lproj in Resources */, + A9035C00334819B884C6118B74441324 /* error@3x.png in Resources */, + E0741AB67101A14ABD4FC5752AB3167D /* es.lproj in Resources */, + 3DBDD9275D0A0BFA75DB31B694B1B6CC /* es-419.lproj in Resources */, + 2707ECE9592C4FE30346DFA99614FF1C /* et-EE.lproj in Resources */, + 4F409B48980E00C4D58C34D498DEBEA8 /* fi.lproj in Resources */, + A102FE1C25F4941B532C6B83280B197A /* fil.lproj in Resources */, + 4AD890A67D05B35A7D6008804B188FA4 /* fr.lproj in Resources */, + 93C543F550A86AF20CEAA48104788AF9 /* fr-CA.lproj in Resources */, + 2386C376553947D4A6CF08B38C8A2D3C /* hr.lproj in Resources */, + A2AE35DB77B9FD7C658615A05AC9D656 /* hu.lproj in Resources */, + 893892529FFE17A91CDFF4E5A2E992A0 /* id.lproj in Resources */, + BEBE95E223F6FADA0BF5ADA6DD9E4904 /* it.lproj in Resources */, + 7ADFB5438DEDDE5E4B32B69424AFC2EA /* ja.lproj in Resources */, + E86141DDC8ADFEC978AC7F4198E7206E /* ko.lproj in Resources */, + E418BAB165A0757D815A2624201A521A /* lt-LT.lproj in Resources */, + F04940FCE8A5779124988F6710DA2E35 /* lv-LV.lproj in Resources */, + 632F5CE128D6EB689DEBC02B3C3809E6 /* mastercard-logo@3x.png in Resources */, + 29A12BDC18155B9C0671D4B97A71F45A /* ms-MY.lproj in Resources */, + 5AB4BA6467D05922B9747494C762658A /* mt.lproj in Resources */, + 54A6D1294A70008E39F187698487AAE7 /* nb.lproj in Resources */, + AA552F64F531BD2985BCE9A1298EA5C1 /* nl.lproj in Resources */, + 4415DB8BA3D9130108FA4E5486504078 /* nn-NO.lproj in Resources */, + 4EC79445B363B312C74C3CE5B267F553 /* pl-PL.lproj in Resources */, + A754A72DE53637838CB2E7EB58F0BCD0 /* pt-BR.lproj in Resources */, + 2B487EDAC128C40CED9EA6D6B25D6AD5 /* pt-PT.lproj in Resources */, + 2E581DD1847ECC3D1F77A2F3F288F342 /* ro-RO.lproj in Resources */, + A7034C926019E17F75CB4C5750D85C9F /* ru.lproj in Resources */, + 6B9843AA0B06FBE0E6D2A642D061C2A7 /* sk-SK.lproj in Resources */, + B85376FE31501B1B372392E3E21EBBF8 /* sl-SI.lproj in Resources */, + 2AC9195E81D0BE6AB8CCED77178F2C8F /* sv.lproj in Resources */, + 3DFCA9AB63E3E4374B64FE356BAD677C /* tr.lproj in Resources */, + 84E439FD06B111CEC1109509478D39BC /* vi.lproj in Resources */, + 597A941B9D43299E37279E9B0788C7AB /* visa-logo@3x.png in Resources */, + 9788AD60BD2C5CA8FF796C7C4189A52E /* visa-white-logo@3x.png in Resources */, + B59A8E201C9C3550E0F050D380AD1424 /* zh-Hans.lproj in Resources */, + 317FD8D75EA6F1C3A7D8A899259FE139 /* zh-Hant.lproj in Resources */, + 24AAADDFF404517C7C0AED61D7E5CD2B /* zh-HK.lproj in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 6877407E6A410C1B6138C33B7813B2A6 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( @@ -735,10 +2889,117 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - BBBF04B4CD4D1ABF95C3C134D06D84FC /* Resources */ = { + A166852BD799DE37C740CF9947A1FFF6 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( + 55C79F5BF5BF3DCFD571CFB76DCB1BB6 /* StripeCore-StripeCore in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + A1B32F6F5E1FE4A2DF2F0F5877160C26 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 1A0CDABF0B5DC4853D71A3D8A9194BD8 /* bg-BG.lproj in Resources */, + 80A4FEC7BBEF285AA71AA19F228891DA /* ca-ES.lproj in Resources */, + 45E50A3A821774A43869A9409F72D026 /* cs-CZ.lproj in Resources */, + 62B1FBBB4730BD586623DB586E19C2B2 /* da.lproj in Resources */, + AD215F47C733E652403AD91D2B7A26A7 /* de.lproj in Resources */, + A9449E624D1B2AF016E7EC10862E9206 /* el-GR.lproj in Resources */, + CD567C85C1A55D92CB35E5D839BBC64D /* en.lproj in Resources */, + BE4B1DCCA7FC5F624B704C3F36D71859 /* en-GB.lproj in Resources */, + 236188652033F3874F7747E49466CC6D /* es.lproj in Resources */, + 8F995F206F3384B30DD6FB34F14FCA9D /* es-419.lproj in Resources */, + F9727FF50B4CDA30B1E3A3E7C28E34ED /* et-EE.lproj in Resources */, + 80AA331134CA9AA79AD0CD177EA3452B /* fi.lproj in Resources */, + 4F54300CD1DF9A60FE0D65E857A840C2 /* fil.lproj in Resources */, + A88D40D4ECF8A6F10CD9E64FAB7026FD /* fr.lproj in Resources */, + 3BA220FE1E469A2778730A89F390E6A0 /* fr-CA.lproj in Resources */, + 5DEDCB91142523EAD727F06ACBFCBFCA /* hr.lproj in Resources */, + 2096706ED57F37B7CD5CF94CC3D6AE7C /* hu.lproj in Resources */, + ABF8F12C002342A625D2636210931B9A /* id.lproj in Resources */, + 8E49E63DD350D18D4D554597D0392272 /* it.lproj in Resources */, + 81183C395B09751B7AE3A5DFCCDA3EAF /* ja.lproj in Resources */, + DAD09BEF8013B22616C54034D030B98E /* ko.lproj in Resources */, + C7BDDB5048ECC555122DFA4B010FEC03 /* lt-LT.lproj in Resources */, + 639778C97DA9CD7EAD99E627C2406134 /* lv-LV.lproj in Resources */, + 159F8EE74AF28D4A573CACE36DFFDBE3 /* ms-MY.lproj in Resources */, + 991C750FCE4137E068570AA39F1C3142 /* mt.lproj in Resources */, + 0712493E1803C913158BBA4CCF283007 /* nb.lproj in Resources */, + 2EFFB904753535D2081B57240AF520B9 /* nl.lproj in Resources */, + D2CC96FAE3E510427A4C5E6FF4891B6D /* nn-NO.lproj in Resources */, + 50CA71B286B02AD73D81F32760381E7C /* pl-PL.lproj in Resources */, + 9E921B6C45E2EBD0939CCFF28CBE5A75 /* pt-BR.lproj in Resources */, + 14F8F0ADE08D750611E78D60AF7E9C3D /* pt-PT.lproj in Resources */, + 1A172B8E707A60CBD15698CCC424C418 /* ro-RO.lproj in Resources */, + 44F31949B05DBF7DEFDCC4F70B41B603 /* ru.lproj in Resources */, + 3A63B1DB85CE79907C6A50430A19B568 /* sk-SK.lproj in Resources */, + 9225C8010A014CD2B6FE14CBB6145E41 /* sl-SI.lproj in Resources */, + DD1D5D891590FF5F3FB499012B9230CE /* sv.lproj in Resources */, + FBBB630553CABE3EE77621869383EFC8 /* tk.lproj in Resources */, + 9548AE7735765ECA10CD238DAF7AF402 /* tr.lproj in Resources */, + 130B381F3FB091E8DE79AA7965984AFA /* vi.lproj in Resources */, + 222837454C437E1D84E4C6C74D1D21C7 /* zh-Hans.lproj in Resources */, + CC895153274C7B49225680E843F561F1 /* zh-Hant.lproj in Resources */, + B6AE95E672AB980022B11556E0616692 /* zh-HK.lproj in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + A6EB667B5C4DF2E2428C12750D0A8831 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + F676914DF10AB2BAA2F154454784C371 /* StripePayments-Stripe3DS2 in Resources */, + B908232EBF7A2E6C535643EC5905480F /* StripePayments-StripePayments in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + A9D30956908A4EBF7AA94997DA09E592 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + C28B853DA06EF4CDE74A1EF53365A9C1 /* bg-BG.lproj in Resources */, + 25276D6260CEFC77AB1C9A399CA31291 /* ca-ES.lproj in Resources */, + 1862C65896619DF417C33DB320727BCB /* cs-CZ.lproj in Resources */, + 817B2E37DA5E47634EDA6B5DEAC6106B /* da.lproj in Resources */, + F4EF59D354572BFB98386FC8DC047250 /* de.lproj in Resources */, + DFF4407A62E016DA4186B46582434083 /* el-GR.lproj in Resources */, + 34A8E6E2C7443734DA331A607EF645B1 /* en.lproj in Resources */, + F248B374BD2E538D1FECDC9B05D2C5B8 /* en-GB.lproj in Resources */, + EF178AD4D324BA0FC0D9351CAC5FB581 /* es.lproj in Resources */, + A6FC1D75F34E33A97477D57B42E30B0B /* es-419.lproj in Resources */, + 2C7A86F6A1C761A9FA4AD20A63263984 /* et-EE.lproj in Resources */, + DB12233C2655B3393E0EC0E7CAFF128D /* fi.lproj in Resources */, + A7B615BDF8D23CE29724AF60B97487C4 /* fil.lproj in Resources */, + 39F60D092FEAF7236168489CAA0AA93C /* fr.lproj in Resources */, + E73DFB8CCED2D914CDD1BF72D84CED41 /* fr-CA.lproj in Resources */, + B4C1BC80DDC77193B28E7DD238A56890 /* hr.lproj in Resources */, + 2157F4F1E30DFADECBD2473F5BC60345 /* hu.lproj in Resources */, + 7719F4DDA13C4EB6644958C99C1A00CC /* id.lproj in Resources */, + C81B728031ECD7D8D50D727C3ABC58A2 /* it.lproj in Resources */, + BB55D5AA35356053CF6AB4CE94CA2B19 /* ja.lproj in Resources */, + 6374F4F6160ABD4FED618C0B185ABD65 /* ko.lproj in Resources */, + 7906A8B1E314D4571ED317F61D625A18 /* lt-LT.lproj in Resources */, + E2E452130207949BA34D6B95B7C4C244 /* lv-LV.lproj in Resources */, + C8A21D7E0B92BFDAFA538BDDEB18C988 /* ms-MY.lproj in Resources */, + B90DD32BE559DEE5853D2A69BEA80E3E /* mt.lproj in Resources */, + 2B5A28A4BF74AF916C7CBE907D225CE7 /* nb.lproj in Resources */, + 3087DDB3CFEBD0AA35BE02486E14E467 /* nl.lproj in Resources */, + 0574F6274930EAE0DEE90D56B6CE8C53 /* nn-NO.lproj in Resources */, + EF32F328C68BDC0375FDE741B5501436 /* pl-PL.lproj in Resources */, + E49952725B0F5A5E7B4A8FD69E08A71D /* pt-BR.lproj in Resources */, + 531A3FFB720E63D899AE8792730826B6 /* pt-PT.lproj in Resources */, + 4CB089F5F61442FDB48AEACB80E1B29F /* ro-RO.lproj in Resources */, + 6B7F5CCF546E0D3D602CFCE4A98FE2A1 /* ru.lproj in Resources */, + CBDC558A7446BBA963C4AFD2B3A98415 /* sk-SK.lproj in Resources */, + 0EF5DD2821912749951D31B5EB78E1A3 /* sl-SI.lproj in Resources */, + E4C78DA9C4632D8B2C7BB20E6FF0788C /* sv.lproj in Resources */, + 83EBFC78EE70D4A3C64B65E6C8D3F767 /* tr.lproj in Resources */, + 13C92A56DE90F30ACEC10BF71C07254E /* vi.lproj in Resources */, + 32890A23C6C5A59D0295872FFB71C2B3 /* zh-Hans.lproj in Resources */, + 747CAA94CC7606C5B3059954DD0E4830 /* zh-Hant.lproj in Resources */, + CDF5199EB1AACF73405B61319BCAA020 /* zh-HK.lproj in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -749,14 +3010,290 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + F08B2902635192F79460CDFE0E6140D2 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXResourcesBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ - 14593B72CC5AB1953F9390743FA4967E /* Sources */ = { + 509A86517AFAEAB438DF4AF1E980B074 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 9E757DB7080E589FBE998F6765866280 /* Pods-OSPaymentsLib-dummy.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 62D14C11677D8A8B08193F35CDA41694 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 30F02B5E637DF6A1DC8D79EE96408FE6 /* Analytic+Payments.swift in Sources */, + A9F90B2B49B039CD613000446CDFB997 /* APIRequest.swift in Sources */, + 57E3018DEDC081BF4B445195CA43738D /* ConnectionsSDKAvailability.swift in Sources */, + E912FE78E0AC65A1E5B2F7993B49E8DB /* Enums+CustomStringConvertible.swift in Sources */, + 2ACEED691C648285CD27EC987B7AB565 /* LinkAccountSession.swift in Sources */, + DF3423EFFE0F8E644904AA626D94BCE1 /* LinkSettings.swift in Sources */, + 31500C1BFF2979F394F2C7CCE5B6F30B /* NSArray+Stripe.swift in Sources */, + F35702AD6013344A66100913A925A9B0 /* NSData+JWEHelpers.m in Sources */, + 91EE566AEC7ABEFB1CE003F67BABD8C9 /* NSDecimalNumber+Stripe_Currency.swift in Sources */, + 537D3533C8C1ADF45A907F20B9A9C96A /* NSDictionary+DecodingHelpers.m in Sources */, + FC0B9CF3FDA02D8B83B72393BB1F76E4 /* NSDictionary+Stripe.swift in Sources */, + 649BF6E2C467C6536F33929348E8F5BF /* NSError+Stripe3DS2.m in Sources */, + E68FB42E04EBC6218F0B030459CB6EC4 /* NSLayoutConstraint+LayoutSupport.m in Sources */, + 8A787DDDD4F317EE45FDFFBF2A2B1A9A /* NSString+EmptyChecking.m in Sources */, + 18404665D3D8C231EC7E45807E0B7035 /* NSString+JWEHelpers.m in Sources */, + 456BFC6895E43FB0A2D74B48C42E60D4 /* NSString+Stripe.swift in Sources */, + A15039BAAE47A622E8858820EA914564 /* STDSACSNetworkingManager.m in Sources */, + 5FC764CD3AEC0FEFDE90C6BEE67F88E0 /* STDSAlreadyInitializedException.m in Sources */, + 23294E1D85D1BB5F601FB3FE6393AEB6 /* STDSAuthenticationRequestParameters.m in Sources */, + 13BE949EFDF50C87A22E77B6C0FA967C /* STDSAuthenticationResponseObject.m in Sources */, + 443FFE3FBEDBB95A99B2DB948DE63220 /* STDSBrandingView.m in Sources */, + A6D732437D1B5AC19EA472053DA77406 /* STDSBundleLocator.m in Sources */, + 2A9F6A9F52F7780DF40A2DF6085BF77D /* STDSButtonCustomization.m in Sources */, + 508B4C848966DD16897AC114384274F9 /* STDSCategoryLinker.m in Sources */, + E98EFEF31E18A37C9B657706FA00D071 /* STDSChallengeInformationView.m in Sources */, + 9D7E95888E772E02E5BFC9ADBDE1BF0E /* STDSChallengeParameters.m in Sources */, + B18F546087EFBA93051B51DA734ED94A /* STDSChallengeRequestParameters.m in Sources */, + 55CC542DBCF95120A6772C015357491F /* STDSChallengeResponseImageObject.m in Sources */, + AF8161AB17115AFDFFD6796352DC53BD /* STDSChallengeResponseMessageExtensionObject.m in Sources */, + B4C44869352814DA8337C89C7A7166BD /* STDSChallengeResponseObject.m in Sources */, + 9770974D1F6AD18D0883A63F5269AD74 /* STDSChallengeResponseSelectionInfoObject.m in Sources */, + 8D0C7CE334E5F30C6CC8487235BBDBF5 /* STDSChallengeResponseViewController.m in Sources */, + 2F4DBD9EB47B55EFB19161BE381DDCC8 /* STDSChallengeSelectionView.m in Sources */, + BC75CFAB6CBFD26852CEF5D1DD710C9D /* STDSCompletionEvent.m in Sources */, + 4EF3D6C1102BA462B9F75AA8F318798C /* STDSConfigParameters.m in Sources */, + A906986DAD73CA84C70468FDC570AD6E /* STDSCustomization.m in Sources */, + 660457395E48C263AC70C866DCE7A479 /* STDSDebuggerChecker.m in Sources */, + C24AF5E9EA09FF9B44C92098D6148080 /* STDSDeviceInformation.m in Sources */, + 6978C8861303501E23F190E5A2F33B1B /* STDSDeviceInformationManager.m in Sources */, + 4955DBB9FDF4D00F2330AF65074D1CA2 /* STDSDeviceInformationParameter.m in Sources */, + 93E8F7D415C604D8DAFAABD977323EFB /* STDSDirectoryServerCertificate.m in Sources */, + 57B1D9A5DFBB06AB22AC0BCE27137371 /* STDSEllipticCurvePoint.m in Sources */, + F1D415C910F2813FD4C7641DA1500EBC /* STDSEphemeralKeyPair.m in Sources */, + C0E178382444DF51B9696CE45E74E6DD /* STDSErrorMessage.m in Sources */, + 7CCE824E9729089D8873C7E602726F92 /* STDSErrorMessage+Internal.m in Sources */, + 5D9F21E15D4AB17397AE6B74120772DE /* STDSException.m in Sources */, + 086144E52A667A7954D92FE051BD6CC8 /* STDSExpandableInformationView.m in Sources */, + 1E7C617E16D1B599CF499DD55EF669C0 /* STDSFooterCustomization.m in Sources */, + A30CC64F714608ED2E7FDA3905650EBC /* STDSImageLoader.m in Sources */, + 3025C0F40CA75C83972903E981722EA9 /* STDSIntegrityChecker.m in Sources */, + CA404759B9875B2BE03D9C4AA8B4E437 /* STDSInvalidInputException.m in Sources */, + FAF0419FCFB02CEC2A36BCE29FA02C44 /* STDSIPAddress.m in Sources */, + 0A8DB6B9BB8655FEA665B4732C44965B /* STDSJailbreakChecker.m in Sources */, + 306F8BF4060CFAA4481C090AE5645655 /* STDSJSONEncoder.m in Sources */, + 9B8B123AA626C49649D1B168417347AA /* STDSJSONWebEncryption.m in Sources */, + F0ED669E48B43DC9B8AB6803B06910B4 /* STDSJSONWebSignature.m in Sources */, + 8822F8BF2FAD0AD508BDAB4AB4EF65E0 /* STDSLabelCustomization.m in Sources */, + 2492CEBC7D15E6699CBCDB00B93C3C8A /* STDSNavigationBarCustomization.m in Sources */, + 0D352AB9D9FB76AF3F76AB8B76E0344F /* STDSNotInitializedException.m in Sources */, + 2D9175D749C48D902B4B68BBF65A6DAE /* STDSOSVersionChecker.m in Sources */, + 4698EBCAB77B194B12B039D2A0C358E7 /* STDSProcessingView.m in Sources */, + EE89C7193918A27358AD3318384543D5 /* STDSProgressViewController.m in Sources */, + CC7810AB588F9A7F964FCF935C8CF80A /* STDSProtocolErrorEvent.m in Sources */, + F3D59D684D918CFD627289479042B176 /* STDSRuntimeErrorEvent.m in Sources */, + E00460E232D3F411D6D967B1B051A2C7 /* STDSRuntimeException.m in Sources */, + 16A964A80F82E8955FAD0ECF727F522A /* STDSSecTypeUtilities.m in Sources */, + 6228796E148B8398B2D1B31F77D042EB /* STDSSelectionButton.m in Sources */, + ED8221343E282DCEC1F86058EF06D93A /* STDSSelectionCustomization.m in Sources */, + DD177FA0C27AD81516C71CC2787D30FA /* STDSSimulatorChecker.m in Sources */, + F889D83409DDF7FBC0079C6B7FBE5CC1 /* STDSSpacerView.m in Sources */, + C636A8EF0AC9FEE39106FFF2F006AF18 /* STDSStackView.m in Sources */, + CE862C94D35AE367736B8FB2A9347A82 /* STDSStripe3DS2Error.m in Sources */, + B763A05CBA9CC9C4FA2FCCBEA6597E59 /* STDSSwiftTryCatch.m in Sources */, + CBC91EBA9C4224D40AB9CD160F17DA50 /* STDSSynchronousLocationManager.m in Sources */, + 2596C380CE1B2066E9A54BC82C42B759 /* STDSTextChallengeView.m in Sources */, + 1FD82A85B7C64F54AD2F74909F572FE8 /* STDSTextFieldCustomization.m in Sources */, + CCE1D380F09F27172FCB9ED3EA3D4410 /* STDSThreeDS2Service.m in Sources */, + 2F915AF3B125571D66E5DFD35B7CB178 /* STDSThreeDSProtocolVersion.m in Sources */, + 247FA17C9B44E7860DC39DFE61961237 /* STDSTransaction.m in Sources */, + 385982E8CA81B9EB950EB3F1C5E157A3 /* STDSUICustomization.m in Sources */, + 3AA219A606F881B65A35C036C61E6AD0 /* STDSWarning.m in Sources */, + 4F82DC515FD9ABDAD5996DA7403475CC /* STDSWebView.m in Sources */, + 021D29C6A388976923614F8788CBE6EF /* STDSWhitelistView.m in Sources */, + 28E75B0CB409AE353F3F1DD7566BF797 /* STP3DS2AuthenticateResponse.swift in Sources */, + DCB81595A72B448DEC48A1ABF8434467 /* STPAddress.swift in Sources */, + 18ACEA51615A8434B00B243551175F4A /* STPAnalyticsClient+Payments.swift in Sources */, + 9ADD6B34BAB3FD65053D68C3D3EBD224 /* STPAPIClient+ApplePay.swift in Sources */, + 4B27F9C83E60A3A3717C03C96799EAC7 /* STPAPIClient+LinkAccountSession.swift in Sources */, + 4BB9C83A37FC3CC123CE0777BD9FAB45 /* STPAPIClient+Payments.swift in Sources */, + 85A33C8F0E13EE87EE64187C8F1079D9 /* STPAPIClient+PaymentsCore.swift in Sources */, + 3B62A1DB19F43D79E76DB05F88E7B830 /* STPAPIClient+Radar.swift in Sources */, + C905EED2D503527500BFA2498A3F8EFC /* STPAPIResponseDecodable.swift in Sources */, + 53BC2AEA33D49FA9D544FF86946562B8 /* STPAuthenticationContext.swift in Sources */, + 5406E0B3ADF8DDC0305DEC96A1A8850A /* STPBankAccount.swift in Sources */, + 464E0CEDFAA6A8BB7D3E29E97F7C6AF1 /* STPBankAccountCollector.swift in Sources */, + EA0EAA4A9626750C8D747A14215CF111 /* STPBankAccountParams.swift in Sources */, + BBD30C63ACD76A06653AAE5FBEC84470 /* STPBINController.swift in Sources */, + DE787BA1CB2B14BF3530834D3FEB3587 /* STPBlocks.swift in Sources */, + 3F02321014A66A554DDF1ACDBB6EE9D4 /* STPCard.swift in Sources */, + 265CA95FA3AAFF7E500E99D48FBD68E3 /* STPCardBrand.swift in Sources */, + C3A6DE0F702DB704D784215DB02E7935 /* STPCardParams.swift in Sources */, + E70E2B3A9C7D9F54A5039269B3B28465 /* STPCardValidator.swift in Sources */, + A143CCD69D6EDAA21A75419419C6E7BA /* STPCollectBankAccountParams.swift in Sources */, + 0D6EA3EAC83C871E8CBA4C327B496A0E /* STPConfirmAlipayOptions.swift in Sources */, + B2D61DB92FE0E7E6C31D5CF100BEDC35 /* STPConfirmBLIKOptions.swift in Sources */, + EE62B5EBDEE95CF64E327C407D793A17 /* STPConfirmCardOptions.swift in Sources */, + 0E4CE475D537D461671EA5E8CF176152 /* STPConfirmPaymentMethodOptions.swift in Sources */, + 72EDABCF87F530030F5EE5835DC694DF /* STPConfirmUSBankAccountOptions.swift in Sources */, + 36709259D5B468FDE791112806E6AA9D /* STPConfirmWeChatPayOptions.swift in Sources */, + BDC0307F8EA99C164C2003448066D80D /* STPConnectAccountAddress.swift in Sources */, + 72AADC86E10056E323FE1BE5781F92E7 /* STPConnectAccountCompanyParams.swift in Sources */, + 942981F693C8B00131E35DEF2A67B049 /* STPConnectAccountIndividualParams.swift in Sources */, + B297557B0B2E4FE69B4C5C0C24EAE44D /* STPConnectAccountParams.swift in Sources */, + 400ED2ADEA63F8F7EB46D54349F2EA26 /* STPContactField.swift in Sources */, + 3358907847E659749A146DF46023F805 /* STPCustomer.swift in Sources */, + 3CC220A8FACE1DD4B1978AE955CF2737 /* STPEmptyStripeResponse.swift in Sources */, + BBA8852D7073427D093AB72835D16C5F /* STPFile.swift in Sources */, + 8AD3F27AE64AEC327B266F4BC4AE6452 /* STPFormEncodable.swift in Sources */, + AB57F2477838A78D65DE25E54D32AD8A /* STPFormEncoder.swift in Sources */, + 4FF14DEE4F47CFB5AB37949C92799028 /* STPFPXBankBrand.swift in Sources */, + AD2F457DEF141A302A9A79AB05AB16AA /* STPiDEALBank.swift in Sources */, + 3E07947733CD594CF6C55EFA7C6F5825 /* STPIntentAction.swift in Sources */, + A1405701968D98550AE1AABA2D7C71EE /* STPIntentActionAlipayHandleRedirect.swift in Sources */, + 9C6E62A2B5A31C85863D0FCA8A2F4B31 /* STPIntentActionBoletoDisplayDetails.swift in Sources */, + 94C084F16DDF32E67EB2580F7C369B0F /* STPIntentActionOXXODisplayDetails.swift in Sources */, + 28C24A912FEBA4B1692671D80A1776D6 /* STPIntentActionRedirectToURL.swift in Sources */, + CA3733029ABB9CDAA6D15D9491960C0E /* STPIntentActionUseStripeSDK.swift in Sources */, + 5F9E42E5F8D8D68740FBCF1F126A3246 /* STPIntentActionVerifyWithMicrodeposits.swift in Sources */, + 922D04AF11AF5704A172F34CF33C2463 /* STPIntentActionWeChatPayRedirectToApp.swift in Sources */, + AD8EC799CFB40D2FB6CA85B503FB2BC4 /* STPInternalAPIResponseDecodable.swift in Sources */, + EC59BED70255C71F238B09D9AC2D1EA2 /* STPIssuingCardPin.swift in Sources */, + 93501F087A12FE661B02E564B9189E95 /* STPKlarnaLineItem.swift in Sources */, + F73C4808E488D4F1847459F64BA7DDF6 /* STPLocalizedString.swift in Sources */, + 0D28CC029F277E08E381C1FB0BB940A5 /* STPMandateCustomerAcceptanceParams.swift in Sources */, + A63CD62E00612420A54C2A3C6A93D2B4 /* STPMandateDataParams.swift in Sources */, + A99540F8CA5C86EEFCD83B3920B7513B /* STPMandateOnlineParams.swift in Sources */, + EB85AD05E9550AEE05BEABCBD0A54D52 /* STPPaymentConfirmation+SwiftUI.swift in Sources */, + 7F1EC3CEE3EA9ED2B93A133B91360547 /* STPPaymentHandler.swift in Sources */, + 5198216234ABD8841F582DA3A416B87C /* STPPaymentHandlerActionParams.swift in Sources */, + E25D73EA8581356D83D11497A801886D /* STPPaymentIntent.swift in Sources */, + 95C09A180A722F1CF4B9C6B40772FB6D /* STPPaymentIntentAction.swift in Sources */, + 272AD16E5080B9028C1012B7723CD74E /* STPPaymentIntentActionRedirectToURL.swift in Sources */, + 8D73DFC33DD8B75BD9636E4DFA010A83 /* STPPaymentIntentEnums.swift in Sources */, + 264F60294C4B6404E0E399774425DC0E /* STPPaymentIntentLastPaymentError.swift in Sources */, + 4FFA353FCA74E12B1E33831B7DEDC29D /* STPPaymentIntentParams.swift in Sources */, + C4F7B99D93E88831666F3E45E4382E17 /* STPPaymentIntentShippingDetails.swift in Sources */, + 3517183FFD6B14F52921E9F8650AA63D /* STPPaymentIntentShippingDetailsAddress.swift in Sources */, + 504F56E775C794C1C43496CFF82279C0 /* STPPaymentIntentShippingDetailsAddressParams.swift in Sources */, + 0DD28F29BF02762916D569CB60F9AB06 /* STPPaymentIntentShippingDetailsParams.swift in Sources */, + D14FCDBE8AC0C7269A27CDD5B0BE6F7C /* STPPaymentIntentSourceAction.swift in Sources */, + 0B91799F9412C28DE43CC91E143381E1 /* STPPaymentIntentSourceActionAuthorizeWithURL.swift in Sources */, + D472EE65DAFF3D8DBEE79615C285702A /* STPPaymentMethod.swift in Sources */, + 7862D17B8F45E886EC3B54FBFF7927BE /* STPPaymentMethodAddress.swift in Sources */, + DB59D6DAD3E296B5402FA766AE955D78 /* STPPaymentMethodAffirm.swift in Sources */, + C0E877BCBEF75E2C0DCFA592657CDFB2 /* STPPaymentMethodAffirmParams.swift in Sources */, + 304E0A887F5420C0758CC21F15850DAD /* STPPaymentMethodAfterpayClearpay.swift in Sources */, + D6D5F283E6742594C6A16FDCE7BF780E /* STPPaymentMethodAfterpayClearpayParams.swift in Sources */, + 38E2FC651D13E810BD0E3F0F745A5D86 /* STPPaymentMethodAlipay.swift in Sources */, + 517CA1D86EA54C108B6D26E3BD0EF565 /* STPPaymentMethodAlipayParams.swift in Sources */, + 9728DA0B9363EF3439911A4B4BA75350 /* STPPaymentMethodAUBECSDebit.swift in Sources */, + 5611DE6F81B398AB40683BA786E14698 /* STPPaymentMethodAUBECSDebitParams.swift in Sources */, + 038D8C564ABE8C97864B8F0B03F4D177 /* STPPaymentMethodBacsDebit.swift in Sources */, + 385342D83733D3D9C7E0A388BFDBF61C /* STPPaymentMethodBacsDebitParams.swift in Sources */, + D0112C3A544DDEC8444C0DC31509E612 /* STPPaymentMethodBancontact.swift in Sources */, + 5A3C142DB4EE0306335BEE9839A15DF3 /* STPPaymentMethodBancontactParams.swift in Sources */, + BA127569977F8388BECB28BF9C38726E /* STPPaymentMethodBillingDetails.swift in Sources */, + 2E4D85387136D0E87EFF3CF816410A20 /* STPPaymentMethodBLIK.swift in Sources */, + C8FC20A9010A3B8F8FCFD179672ADBDB /* STPPaymentMethodBLIKParams.swift in Sources */, + 7834BD3EC61F467585E353117D408842 /* STPPaymentMethodBoleto.swift in Sources */, + 0659C102E528008D4318FDBD7FEDD35C /* STPPaymentMethodBoletoParams.swift in Sources */, + E03256423466AABA2091A532973025CF /* STPPaymentMethodCard.swift in Sources */, + 8E40DF482D30552C79C18916578C7898 /* STPPaymentMethodCardChecks.swift in Sources */, + C97A0E8F9E4096CC06430599E5F4DDE6 /* STPPaymentMethodCardNetworks.swift in Sources */, + B326BB53636511ADC5FE8F033DBB9F0A /* STPPaymentMethodCardParams.swift in Sources */, + 55E81DE2AD08EAEC57A149974226221C /* STPPaymentMethodCardPresent.swift in Sources */, + E890BDC505D263CF43789649B20D7E16 /* STPPaymentMethodCardWallet.swift in Sources */, + A444343B2E48AC45C14A8C5B03FA085C /* STPPaymentMethodCardWalletMasterpass.swift in Sources */, + E6FE8A90539AA4A3805B0A626DA4C7F9 /* STPPaymentMethodCardWalletVisaCheckout.swift in Sources */, + 66918EBA9CAF1899C37B9841FFC7BD3A /* STPPaymentMethodEnums.swift in Sources */, + B882EE8FC10811B47CB327B7306806FD /* STPPaymentMethodEPS.swift in Sources */, + EB331A4254ED56A8799C0C756586BDD0 /* STPPaymentMethodEPSParams.swift in Sources */, + 0FF078EC4B64D41F78376637C3C7457E /* STPPaymentMethodFPX.swift in Sources */, + BCE527DFFA322814185EBA4AE857864D /* STPPaymentMethodFPXParams.swift in Sources */, + F9A30F02081D3CE0A00007EC34909897 /* STPPaymentMethodGiropay.swift in Sources */, + 06C1123E8EAFFDC3EF43A176042BF0A8 /* STPPaymentMethodGiropayParams.swift in Sources */, + 191B50BEC783150B89E684C427269952 /* STPPaymentMethodGrabPay.swift in Sources */, + 92C13829401A964FBED01CB5D7FABC8E /* STPPaymentMethodGrabPayParams.swift in Sources */, + 8506EA10F248EB2F7B0CA98731A86F6B /* STPPaymentMethodiDEAL.swift in Sources */, + 92AD6953361C38E3E45B40B13B4AA72A /* STPPaymentMethodiDEALParams.swift in Sources */, + A3952D6DAFEAC7C15BE2D60A07F5271D /* STPPaymentMethodKlarna.swift in Sources */, + C0EDACD1500DBD395ED24F2900E0057C /* STPPaymentMethodKlarnaParams.swift in Sources */, + 86F339CD2AC66630008B7ED5C0D63487 /* STPPaymentMethodLink.swift in Sources */, + 4B4B7CB6FD4E6340FA2AF7176E242282 /* STPPaymentMethodLinkParams.swift in Sources */, + E49316FF97A8E6748E5105B59ECBB00C /* STPPaymentMethodListDeserializer.swift in Sources */, + F95BFF4CC50156536AB80A877C1D1A1F /* STPPaymentMethodNetBanking.swift in Sources */, + 958420B6D446B2DF67DB182A49F3270C /* STPPaymentMethodNetBankingParams.swift in Sources */, + 1705B1BE5C85932B6404A3436FB601B7 /* STPPaymentMethodOptions.swift in Sources */, + A9BE66263854CD548F0F1CE1A2981401 /* STPPaymentMethodOXXO.swift in Sources */, + 19A60369EEE16D503A472273FD951BCB /* STPPaymentMethodOXXOParams.swift in Sources */, + F4BA31F4637C69F7D0077074CE2D2CAA /* STPPaymentMethodParams.swift in Sources */, + 3A6530382C6CE29F52010A54DEFD3355 /* STPPaymentMethodPayPal.swift in Sources */, + 67CC273972C5BE4106E3A230665EE14F /* STPPaymentMethodPayPalParams.swift in Sources */, + 42DA19C1E0CB4D2B5BF12442D17287D7 /* STPPaymentMethodPrzelewy24.swift in Sources */, + E403B4D4D59CB0D45FB06C5225ADBED8 /* STPPaymentMethodPrzelewy24Params.swift in Sources */, + B91A10553AF6ECD63BD02C7EF2B37FBD /* STPPaymentMethodSEPADebit.swift in Sources */, + 73B07F9B664C675544CBD4BDCEAA5126 /* STPPaymentMethodSEPADebitParams.swift in Sources */, + 8E026CDD76D8E093C4EEA16398E7B6D1 /* STPPaymentMethodSofort.swift in Sources */, + 06D68613D533EDDEEF993F5FFE496170 /* STPPaymentMethodSofortParams.swift in Sources */, + 0B678F11209F5A613FA5F6D6702E46C2 /* STPPaymentMethodThreeDSecureUsage.swift in Sources */, + 36239C409D0B9B719E86B55C1139FDBD /* STPPaymentMethodUPI.swift in Sources */, + 29A1FECE0C6D458EFDB7AE0B0E873109 /* STPPaymentMethodUPIParams.swift in Sources */, + 381463548B8473B262B2FA27AD7DF435 /* STPPaymentMethodUSBankAccount.swift in Sources */, + E672A74FFB76325B9FF8EC924E71B884 /* STPPaymentMethodUSBankAccountParams.swift in Sources */, + 73065317568D1578D686880367193763 /* STPPaymentMethodWeChatPay.swift in Sources */, + 80CE047F3F38DAE8000E5BDB38301764 /* STPPaymentMethodWeChatPayParams.swift in Sources */, + 9E3D857CC112D7CE9BFB3DCEB21DD00D /* STPRadarSession.swift in Sources */, + 7FF14A601B0FA95DC03D5A79DC9E80DC /* STPRedirectContext.swift in Sources */, + 122A0B946148BAB1037F5FD8546AF9AC /* STPSetupIntent.swift in Sources */, + 39CD396AAAB43E7AE85595387E6B8964 /* STPSetupIntentConfirmParams.swift in Sources */, + 4A3477B394CA4DF793938185830755F0 /* STPSetupIntentEnums.swift in Sources */, + E3C7EDC30EAEEB1A6A662DC35B52EDCC /* STPSetupIntentLastSetupError.swift in Sources */, + 3E93991CBB58EDBB1F547D705AEC020E /* STPSource.swift in Sources */, + 020153DF4B3CBB131DBB5A6AFE267F07 /* STPSourceCardDetails.swift in Sources */, + DCB4550C44D006E726B15F22ADDECA5E /* STPSourceEnums.swift in Sources */, + EAEF487CC506B4E919DCDFB0CBB91573 /* STPSourceKlarnaDetails.swift in Sources */, + C2DA20FE02661C3C2F0618A1DC6D5747 /* STPSourceOwner.swift in Sources */, + FC9384841A6BDD66EDC17640ACDB3F50 /* STPSourceParams.swift in Sources */, + 743B8A6DA10EC663C12E26B22DBC4EEA /* STPSourcePoller.swift in Sources */, + 3AFA086E6CB837109A59A081E339E78B /* STPSourceProtocol.swift in Sources */, + 6E0F264A27DEDECFC1D982A8B4DA4A67 /* STPSourceReceiver.swift in Sources */, + 0E7E03E7EB35B21CEE24267DF082555A /* STPSourceRedirect.swift in Sources */, + 85D69147A32CD77DD75582D545B58C23 /* STPSourceSEPADebitDetails.swift in Sources */, + FEEEE643D707D94977179AD61D2B0FF2 /* STPSourceVerification.swift in Sources */, + 6E2E247EDB9A023F6C50C7790C3A5C0E /* STPSourceWeChatPayDetails.swift in Sources */, + 9305732020F8C1DFF7A2FDE3106FCE43 /* STPThreeDSButtonCustomization.swift in Sources */, + 656672FCB67916A358E8A3A03D7ED2E7 /* STPThreeDSCustomizationSettings.swift in Sources */, + 39AC37C035DE1B8C1639B9A40F84A539 /* STPThreeDSFooterCustomization.swift in Sources */, + 89A131FB1AC2EDD2E4997883769BFD70 /* STPThreeDSLabelCustomization.swift in Sources */, + 73D5A6FC1EFECCF2666663559DE4D589 /* STPThreeDSNavigationBarCustomization.swift in Sources */, + AECED31273935A17176765887892086E /* STPThreeDSSelectionCustomization.swift in Sources */, + 5521DE558746F2B63DE15441F5322492 /* STPThreeDSTextFieldCustomization.swift in Sources */, + 092838CA3E231637F7D3D55EAE0B8C72 /* STPThreeDSUICustomization.swift in Sources */, + E0F1C36FC91D9D785AAA2C88A633D11D /* STPToken.swift in Sources */, + 4A69E8EEB89D5C623CB007F9F8C3B04D /* StripeAPI+Deprecated.swift in Sources */, + 2AB078409D3ACCD3EC10643EC04B75BE /* StripeApplePay+Import.swift in Sources */, + F8DA5F4BC394B30B75912BB1C426DFEB /* StripeCore+Import.swift in Sources */, + 14ECB9C16D895E6B3157794DB3135F19 /* StripePayments+Export.swift in Sources */, + 2A784CA93CB1A56D4711037402C04F40 /* StripePayments-dummy.m in Sources */, + B8FEB80298F5E1C9A775F91B849541A4 /* StripePaymentsBundleLocator.swift in Sources */, + B0D2D958950AEFF2B724214136060AAA /* UIButton+CustomInitialization.m in Sources */, + F0372BD6E4317E3D0F23E3CED51704B0 /* UIColor+DefaultColors.m in Sources */, + AFC8CE1D64DE93F786E6634FD4B03D05 /* UIColor+ThirteenSupport.m in Sources */, + 1F2240C9318123D69897759B7DBD21D7 /* UIFont+DefaultFonts.m in Sources */, + 69927078FE219FA15CE94F5BA50776B8 /* UIView+LayoutSupport.m in Sources */, + 0955AAAF323B87BCEBE1D0227F2FF4D3 /* UIViewController+Stripe3DS2.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 6AF27C6D88B44AC959F24466DD32602A /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 0C0D56E489977C4C3AAC657267CBE490 /* Pods-OSPaymentsLib-dummy.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -832,6 +3369,20 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 877050915A632DA468124619562AA8FD /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 9A053CADE39B7F94FD728BB241BE341F /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; C802F10129A4770EE61F067F767E7A8B /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; @@ -867,35 +3418,186 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - F9CF23A2BE65EAF674EE3CCC010F62ED /* Sources */ = { + CB7A3655E85E0925E9FCFE33A1D0C7E1 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 1CBAF686CA3277D9FC264A3B1E692471 /* Pods-OSPaymentsLib-OSPaymentsLibTests-dummy.m in Sources */, + 2004971545222D91B6EDCACA67033613 /* Pods-OSPaymentsLib-OSPaymentsLibTests-dummy.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + CC0FAA4C11CB720AF5896EE3E9EAB3E3 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + F3E4BD503E80ADE907324B732C196214 /* Analytic.swift in Sources */, + BE46405A1882A37F58962135FD074051 /* AnalyticLoggableError.swift in Sources */, + 4853485A7E6D1C1CA5C4CFB44085E6EC /* AnalyticsClientV2.swift in Sources */, + 1FD113B82225B34DFDD46321B11024CA /* Async.swift in Sources */, + E35A75132E7E20A3874A772EFB39E733 /* BundleLocatorProtocol.swift in Sources */, + 95250AB0246A4E0091E64F8EE99AD944 /* ConnectionsSDKInterface.swift in Sources */, + 4851E14057542B14D1EEAA9C00C88774 /* Decimal+StripeCore.swift in Sources */, + 03BAA8BA74317123CA86865443592E85 /* Dictionary+Stripe.swift in Sources */, + D58AEEA957DC16D02B948DE5F865C58D /* DownloadManager.swift in Sources */, + 86210B5A0EBAE763C407DF08B380B0E7 /* EmptyResponse.swift in Sources */, + 11A16B91E2CEC76912C9AA89DE06B472 /* Enums+CustomStringConvertible.swift in Sources */, + 5B2440B6C23C16F46152FE4219D49E44 /* FileDownloader.swift in Sources */, + B9C349292765A0B0BFFAC28F2B27CC06 /* FraudDetectionData.swift in Sources */, + A954FB0784E113D0045FDA314605C1A3 /* InstallMethod.swift in Sources */, + 03FD1E89DEC666FB21FEB2E4FEA3B719 /* NSArray+Stripe.swift in Sources */, + 3C8183D1E5FF93B8E8C4F59AEB12DC67 /* NSBundle+Stripe_AppName.swift in Sources */, + 8655B078AB39F125F19B25F136711CE6 /* NSCharacterSet+StripeCore.swift in Sources */, + 747BBEC4CF161FE7C2B526FF383D7E74 /* NSError+Stripe.swift in Sources */, + 9C40AF83392453D4E62808BEFEC4F136 /* NSError+StripeCore.swift in Sources */, + B89547FFB315DF9BF545FE6F05FAC318 /* NSMutableURLRequest+Stripe.swift in Sources */, + B75BD3264536F3F693C750CBDE85B7A3 /* NSURLComponents+Stripe.swift in Sources */, + 752151B8399034C5C7C9DD6BC7EE5E76 /* PaymentsSDKVariant.swift in Sources */, + 283994F70A20FDA3E593F5848195F8FE /* PluginDetector.swift in Sources */, + 4C6BC008261C6C1CFA451C34CCC4D6A9 /* ServerErrorMapper.swift in Sources */, + 36CAE14D256E871812C3C4BAD27DB110 /* STPAnalyticEvent.swift in Sources */, + F76C1C50DF2D24853DDD8130B3D89895 /* STPAnalyticsClient.swift in Sources */, + 0727388CC4B1A2AC748FC6178DA50147 /* STPAPIClient.swift in Sources */, + B3D92FD56F0312C2C4D8378D3EC1A569 /* STPAPIClient+FileUpload.swift in Sources */, + A526BF25FFFFB6334858A145A6C7C962 /* STPAppInfo.swift in Sources */, + EB9588C297966D443D6B3236DB11DEE0 /* STPDeviceUtils.swift in Sources */, + CEE36195D9150CFEC723D583D778A696 /* STPDispatchFunctions.swift in Sources */, + 36C770F00CFB7BECAE138754B173260B /* STPError.swift in Sources */, + 53A5EBB7EB042B7CEB835CFF83C89C43 /* STPLocalizationUtils.swift in Sources */, + 9C93BB10F775FA86E2A109839B56BE10 /* STPLocalizedString.swift in Sources */, + 4F29F55DF55238B639AA6F4458BC3076 /* STPMultipartFormDataEncoder.swift in Sources */, + 55C6143DA83ADF23A6CB448653B3884E /* STPMultipartFormDataPart.swift in Sources */, + 976BA00607DFEFFA60B3CB54CDBE8510 /* STPNumericStringValidator.swift in Sources */, + 7965DE1868A495D8C7FD13B57DBF03FC /* STPTelemetryClient.swift in Sources */, + 3213D4EE8D803ECB900C2F8C42857F61 /* STPURLCallbackHandler.swift in Sources */, + 9246F04A77AE1B5655219BB2FFE70BC9 /* String+Localized.swift in Sources */, + 93985F1570254AB7EA83E6ED3054386C /* String+StripeCore.swift in Sources */, + 32E830EBC42FC738D85468F6AE0B6803 /* StripeAPI.swift in Sources */, + 02B42EC26A3E8ED3111F7F723F78490F /* StripeAPIConfiguration.swift in Sources */, + F8EF13262110BC0A7124640FB4E4B4BE /* StripeAPIConfiguration+Version.swift in Sources */, + B240E608E7925F75D9683D1C6E37DE25 /* StripeCodable.swift in Sources */, + 5AADFB759F3F298B860A73ADCB9A577C /* StripeCore-dummy.m in Sources */, + 409A101458E7C3AF6A02D45CFAAC29D0 /* StripeCoreBundleLocator.swift in Sources */, + 982CFDFE8EEC9DCD5E2389A389349F2E /* StripeError.swift in Sources */, + 9BB0B4EDE9F62460C83A52B3EB7D1B92 /* StripeFile.swift in Sources */, + AF640BE386F54CE7054B45AB204FAFA4 /* StripeJSONDecoder.swift in Sources */, + 9FFC1D91DC12B77A74FBC5A0D7F3310B /* StripeJSONEncoder.swift in Sources */, + 584817ED3C181B508267955AA4A97EF2 /* StripeJSONShared.swift in Sources */, + 21915E95165BBB322AF1B9A993214C3D /* StripeServiceError.swift in Sources */, + 5D74A95CEB3BA624888E0A9E1E1704B5 /* UIActivityIndicatorView+Stripe.swift in Sources */, + 23AD839EFADC62D62D49290B5C9FC769 /* UIFont+Stripe.swift in Sources */, + 787F7A4134E841000990DD658FB4E1AB /* UIImage+StripeCore.swift in Sources */, + 6DD10DD516783DD0C7B0E0298628F69A /* UnknownFields.swift in Sources */, + 7755AE0B1825275FF67240EBD52A8F8E /* URLEncoder.swift in Sources */, + 1F5FD8F028C7675AB641B87350EFAC91 /* URLSession+Retry.swift in Sources */, + D5032B4738066A0A6AD516D19FEC65A9 /* UserDefaults+PaymentsCore.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXSourcesBuildPhase section */ /* Begin PBXTargetDependency section */ - C9897A3C5A37DA388024EF1B73474E40 /* PBXTargetDependency */ = { + 1572B13D3E3B9091F75FF31005825533 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - name = Nimble; - target = 6F13695E06195A78EA8A95F8C7ED0D2F /* Nimble */; - targetProxy = 4AB6872CAE7EB20877E143891709DAD2 /* PBXContainerItemProxy */; + name = StripePayments; + target = 1DFC6E27E6C76D8B0A836C5D658B038D /* StripePayments */; + targetProxy = 7BD730C099E566D778FEC12695D72B61 /* PBXContainerItemProxy */; }; - EFC11406FB1C0273752AF7AA25C48093 /* PBXTargetDependency */ = { + 4834E4D2DE2D286B82AC389109802DDC /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = StripePayments; + target = 1DFC6E27E6C76D8B0A836C5D658B038D /* StripePayments */; + targetProxy = 364A1C487390153D77FEA6BAC6999E14 /* PBXContainerItemProxy */; + }; + 632DC3D72D6684931155AFAF67676081 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = StripeCore; + target = 91ECFC81736C2875C7A5B90E324EDF11 /* StripeCore */; + targetProxy = DB39676B0690864975A573F15B3D322B /* PBXContainerItemProxy */; + }; + 6B806537A5FA948098A80D1804688F01 /* PBXTargetDependency */ = { isa = PBXTargetDependency; name = Quick; target = C82891EAB7293DBEE916B21F57E8474D /* Quick */; - targetProxy = 4316B6F1CCEA7D68B7D07667F9755024 /* PBXContainerItemProxy */; + targetProxy = F4ED061E88DF8363B017EB28D32FEA6C /* PBXContainerItemProxy */; + }; + 836B8F41BA8802C9CE1CE1D2B070FFB6 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = StripeCore; + target = 91ECFC81736C2875C7A5B90E324EDF11 /* StripeCore */; + targetProxy = 77961FEE9C7F9614AA240E033F5D7E92 /* PBXContainerItemProxy */; + }; + 8376B85C71F31B1AB147DB524A5C3369 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = "StripePayments-StripePayments"; + target = 1A050828BB67BEF7076399FA446EE87F /* StripePayments-StripePayments */; + targetProxy = 2DD58164DDF6C5BCBD350A24F55FA10D /* PBXContainerItemProxy */; + }; + C9D65FF27431545AEF87FC0EA1392D94 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = StripeCore; + target = 91ECFC81736C2875C7A5B90E324EDF11 /* StripeCore */; + targetProxy = 7E1326C39F0C0184420246927C61A0D2 /* PBXContainerItemProxy */; + }; + D497A8E62607234655A3360278DA4FFF /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = "StripePayments-Stripe3DS2"; + target = 6660405CC6BBF9EC47B377FB74A3F5CB /* StripePayments-Stripe3DS2 */; + targetProxy = F6FB9D81D322E506785102483AA8F187 /* PBXContainerItemProxy */; + }; + D4FD047ADA2B4BEB00D71713258D85A8 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = "StripeCore-StripeCore"; + target = 5F48D489D9B599786982F278E5F9BCBF /* StripeCore-StripeCore */; + targetProxy = 94E8CE3F3997890C804A2EEE88907F8D /* PBXContainerItemProxy */; + }; + E2792046891540720AB13E4F1D824214 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = Nimble; + target = 6F13695E06195A78EA8A95F8C7ED0D2F /* Nimble */; + targetProxy = 04C1FDC428977C31E635B110B042119F /* PBXContainerItemProxy */; }; /* End PBXTargetDependency section */ /* Begin XCBuildConfiguration section */ - 3B58E15B5CCD60FE4DDAAA765421D182 /* Release */ = { + 0B099DB2DBC7BF43EEB96DB78C60CA7D /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = BEB97334DF3B76513D34EB7C70369D82 /* Pods-OSPaymentsLib-OSPaymentsLibTests.release.xcconfig */; + baseConfigurationReference = 36B234BEA176DCA527565B3A67899B7B /* StripePayments.release.xcconfig */; + buildSettings = { + CLANG_ENABLE_OBJC_WEAK = NO; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + GCC_PREFIX_HEADER = "Target Support Files/StripePayments/StripePayments-prefix.pch"; + INFOPLIST_FILE = "Target Support Files/StripePayments/StripePayments-Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MODULEMAP_FILE = "Target Support Files/StripePayments/StripePayments.modulemap"; + PRODUCT_MODULE_NAME = StripePayments; + PRODUCT_NAME = StripePayments; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Release; + }; + 0B35F57EF97C18C61045D9FC48DB44C4 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 4C157CC35B7ABF301C81384661B151DC /* Pods-OSPaymentsLib.debug.xcconfig */; buildSettings = { ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO; CLANG_ENABLE_OBJC_WEAK = NO; @@ -907,7 +3609,7 @@ DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; - INFOPLIST_FILE = "Target Support Files/Pods-OSPaymentsLib-OSPaymentsLibTests/Pods-OSPaymentsLib-OSPaymentsLibTests-Info.plist"; + INFOPLIST_FILE = "Target Support Files/Pods-OSPaymentsLib/Pods-OSPaymentsLib-Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; IPHONEOS_DEPLOYMENT_TARGET = 13.0; LD_RUNPATH_SEARCH_PATHS = ( @@ -916,7 +3618,7 @@ "@loader_path/Frameworks", ); MACH_O_TYPE = staticlib; - MODULEMAP_FILE = "Target Support Files/Pods-OSPaymentsLib-OSPaymentsLibTests/Pods-OSPaymentsLib-OSPaymentsLibTests.modulemap"; + MODULEMAP_FILE = "Target Support Files/Pods-OSPaymentsLib/Pods-OSPaymentsLib.modulemap"; OTHER_LDFLAGS = ""; OTHER_LIBTOOLFLAGS = ""; PODS_ROOT = "$(SRCROOT)"; @@ -925,15 +3627,30 @@ SDKROOT = iphoneos; SKIP_INSTALL = YES; TARGETED_DEVICE_FAMILY = "1,2"; - VALIDATE_PRODUCT = YES; VERSIONING_SYSTEM = "apple-generic"; VERSION_INFO_PREFIX = ""; }; + name = Debug; + }; + 3228080102A4A37CE6DD4FC6565E084E /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 36B234BEA176DCA527565B3A67899B7B /* StripePayments.release.xcconfig */; + buildSettings = { + CONFIGURATION_BUILD_DIR = "$(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)/StripePayments"; + IBSC_MODULE = StripePayments; + INFOPLIST_FILE = "Target Support Files/StripePayments/ResourceBundle-Stripe3DS2-StripePayments-Info.plist"; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; + PRODUCT_NAME = Stripe3DS2; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + TARGETED_DEVICE_FAMILY = "1,2"; + WRAPPER_EXTENSION = bundle; + }; name = Release; }; 4DA5966C6835A80985E79F8D69CB451A /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 4B5ECB9D7EF3AF7D8F37CE57A988CD83 /* Nimble.release.xcconfig */; + baseConfigurationReference = 135F3A6ABE8D575F90D1FA59ABF9FB78 /* Nimble.release.xcconfig */; buildSettings = { "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; @@ -965,7 +3682,59 @@ }; name = Release; }; - 7B0027D8FD39A07361A916896DFA1F76 /* Debug */ = { + 5D1BA1C34B512EAF4F89FC9C5AF70DE2 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = D77381D72A4DFE90938A8B8B8B0B43C5 /* StripeCore.release.xcconfig */; + buildSettings = { + CLANG_ENABLE_OBJC_WEAK = NO; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + GCC_PREFIX_HEADER = "Target Support Files/StripeCore/StripeCore-prefix.pch"; + INFOPLIST_FILE = "Target Support Files/StripeCore/StripeCore-Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MODULEMAP_FILE = "Target Support Files/StripeCore/StripeCore.modulemap"; + PRODUCT_MODULE_NAME = StripeCore; + PRODUCT_NAME = StripeCore; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Release; + }; + 5FA59DB355F40D0E85977F60E216A3B7 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = D77381D72A4DFE90938A8B8B8B0B43C5 /* StripeCore.release.xcconfig */; + buildSettings = { + CONFIGURATION_BUILD_DIR = "$(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)/StripeCore"; + IBSC_MODULE = StripeCore; + INFOPLIST_FILE = "Target Support Files/StripeCore/ResourceBundle-StripeCore-StripeCore-Info.plist"; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; + PRODUCT_NAME = StripeCore; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + TARGETED_DEVICE_FAMILY = "1,2"; + WRAPPER_EXTENSION = bundle; + }; + name = Release; + }; + 613708FD541A64F611A62E691036C38A /* Debug */ = { isa = XCBuildConfiguration; baseConfigurationReference = E8FFA1A64F61EB44FC28A4BF3EF8248A /* Pods-OSPaymentsLib-OSPaymentsLibTests.debug.xcconfig */; buildSettings = { @@ -1004,7 +3773,7 @@ }; 7C554CFBE2233E13A020638ABC37ABD7 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 8270027ACBF7A64C2B453CCBFE155E90 /* Nimble.debug.xcconfig */; + baseConfigurationReference = A14BBC563E581FC8E511ED8EE601E2F9 /* Nimble.debug.xcconfig */; buildSettings = { "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; @@ -1037,7 +3806,7 @@ }; 87348FBD840126344754C1FDCFB6020A /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 51BA9038051E613E9BCC9972FB613CD3 /* Quick.release.xcconfig */; + baseConfigurationReference = 091B29FC638823987C25B0C4C46942D7 /* Quick.release.xcconfig */; buildSettings = { "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; @@ -1135,7 +3904,7 @@ }; name = Debug; }; - 902D1415E2FD80576F0BA3C3E6919A89 /* Release */ = { + 956066D47418BDF4575236DE6EB3413E /* Release */ = { isa = XCBuildConfiguration; baseConfigurationReference = 5AAA74622C8B0B2167156F4EBE359608 /* Pods-OSPaymentsLib.release.xcconfig */; buildSettings = { @@ -1237,7 +4006,7 @@ }; 9FB1D9D883B07F6F30FCD12226177EB3 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = FD89D255CE96F4B06B98FE303E825DDF /* Quick.debug.xcconfig */; + baseConfigurationReference = 99A3D2F7A445362F85C2478CC5CFFE1B /* Quick.debug.xcconfig */; buildSettings = { "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; @@ -1268,9 +4037,76 @@ }; name = Debug; }; - D5A420976E9B94BCDCFB5C49F7536549 /* Debug */ = { + A8FAC06D56FD9A74812688431185DFEE /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 4C157CC35B7ABF301C81384661B151DC /* Pods-OSPaymentsLib.debug.xcconfig */; + baseConfigurationReference = 9CA4796B315DF582CE3C40EE8FD99F49 /* StripeCore.debug.xcconfig */; + buildSettings = { + CLANG_ENABLE_OBJC_WEAK = NO; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + GCC_PREFIX_HEADER = "Target Support Files/StripeCore/StripeCore-prefix.pch"; + INFOPLIST_FILE = "Target Support Files/StripeCore/StripeCore-Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MODULEMAP_FILE = "Target Support Files/StripeCore/StripeCore.modulemap"; + PRODUCT_MODULE_NAME = StripeCore; + PRODUCT_NAME = StripeCore; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Debug; + }; + A99C44645FB28EF1702423C1D01A0939 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = E59BCCA0DC94889AFD7ADE8CD22E988F /* StripePayments.debug.xcconfig */; + buildSettings = { + CONFIGURATION_BUILD_DIR = "$(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)/StripePayments"; + IBSC_MODULE = StripePayments; + INFOPLIST_FILE = "Target Support Files/StripePayments/ResourceBundle-Stripe3DS2-StripePayments-Info.plist"; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; + PRODUCT_NAME = Stripe3DS2; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + TARGETED_DEVICE_FAMILY = "1,2"; + WRAPPER_EXTENSION = bundle; + }; + name = Debug; + }; + ACD283773D9275246BCC24942FBD8261 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 36B234BEA176DCA527565B3A67899B7B /* StripePayments.release.xcconfig */; + buildSettings = { + CONFIGURATION_BUILD_DIR = "$(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)/StripePayments"; + IBSC_MODULE = StripePayments; + INFOPLIST_FILE = "Target Support Files/StripePayments/ResourceBundle-StripePayments-StripePayments-Info.plist"; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; + PRODUCT_NAME = StripePayments; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + TARGETED_DEVICE_FAMILY = "1,2"; + WRAPPER_EXTENSION = bundle; + }; + name = Release; + }; + B10D0F3C564ADA70C49AA45FBA1BF8AC /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = BEB97334DF3B76513D34EB7C70369D82 /* Pods-OSPaymentsLib-OSPaymentsLibTests.release.xcconfig */; buildSettings = { ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO; CLANG_ENABLE_OBJC_WEAK = NO; @@ -1282,7 +4118,7 @@ DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; - INFOPLIST_FILE = "Target Support Files/Pods-OSPaymentsLib/Pods-OSPaymentsLib-Info.plist"; + INFOPLIST_FILE = "Target Support Files/Pods-OSPaymentsLib-OSPaymentsLibTests/Pods-OSPaymentsLib-OSPaymentsLibTests-Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; IPHONEOS_DEPLOYMENT_TARGET = 13.0; LD_RUNPATH_SEARCH_PATHS = ( @@ -1291,7 +4127,7 @@ "@loader_path/Frameworks", ); MACH_O_TYPE = staticlib; - MODULEMAP_FILE = "Target Support Files/Pods-OSPaymentsLib/Pods-OSPaymentsLib.modulemap"; + MODULEMAP_FILE = "Target Support Files/Pods-OSPaymentsLib-OSPaymentsLibTests/Pods-OSPaymentsLib-OSPaymentsLibTests.modulemap"; OTHER_LDFLAGS = ""; OTHER_LIBTOOLFLAGS = ""; PODS_ROOT = "$(SRCROOT)"; @@ -1300,19 +4136,87 @@ SDKROOT = iphoneos; SKIP_INSTALL = YES; TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; VERSIONING_SYSTEM = "apple-generic"; VERSION_INFO_PREFIX = ""; }; + name = Release; + }; + C944BA2868C340523DB2EC9054CAA1E7 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = E59BCCA0DC94889AFD7ADE8CD22E988F /* StripePayments.debug.xcconfig */; + buildSettings = { + CONFIGURATION_BUILD_DIR = "$(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)/StripePayments"; + IBSC_MODULE = StripePayments; + INFOPLIST_FILE = "Target Support Files/StripePayments/ResourceBundle-StripePayments-StripePayments-Info.plist"; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; + PRODUCT_NAME = StripePayments; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + TARGETED_DEVICE_FAMILY = "1,2"; + WRAPPER_EXTENSION = bundle; + }; + name = Debug; + }; + DFAC089E4FB9A83D809E441E6F97C8E1 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = E59BCCA0DC94889AFD7ADE8CD22E988F /* StripePayments.debug.xcconfig */; + buildSettings = { + CLANG_ENABLE_OBJC_WEAK = NO; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + GCC_PREFIX_HEADER = "Target Support Files/StripePayments/StripePayments-prefix.pch"; + INFOPLIST_FILE = "Target Support Files/StripePayments/StripePayments-Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MODULEMAP_FILE = "Target Support Files/StripePayments/StripePayments.modulemap"; + PRODUCT_MODULE_NAME = StripePayments; + PRODUCT_NAME = StripePayments; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Debug; + }; + F46C8C7BDB61F0224F78048C582E94D3 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 9CA4796B315DF582CE3C40EE8FD99F49 /* StripeCore.debug.xcconfig */; + buildSettings = { + CONFIGURATION_BUILD_DIR = "$(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)/StripeCore"; + IBSC_MODULE = StripeCore; + INFOPLIST_FILE = "Target Support Files/StripeCore/ResourceBundle-StripeCore-StripeCore-Info.plist"; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; + PRODUCT_NAME = StripeCore; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + TARGETED_DEVICE_FAMILY = "1,2"; + WRAPPER_EXTENSION = bundle; + }; name = Debug; }; /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ - 00C17C5870BF07DC0D42D38500DDDB88 /* Build configuration list for PBXNativeTarget "Pods-OSPaymentsLib-OSPaymentsLibTests" */ = { + 14375AC5C0A2CAC523DC4626F8F00B14 /* Build configuration list for PBXNativeTarget "Pods-OSPaymentsLib-OSPaymentsLibTests" */ = { isa = XCConfigurationList; buildConfigurations = ( - 7B0027D8FD39A07361A916896DFA1F76 /* Debug */, - 3B58E15B5CCD60FE4DDAAA765421D182 /* Release */, + 613708FD541A64F611A62E691036C38A /* Debug */, + B10D0F3C564ADA70C49AA45FBA1BF8AC /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; @@ -1326,11 +4230,11 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 2EC9DC26A2B2F522D07CE5FE7D1EF6F5 /* Build configuration list for PBXNativeTarget "Pods-OSPaymentsLib" */ = { + 3241BB2EB916EAC79119A233F7C315B3 /* Build configuration list for PBXNativeTarget "Pods-OSPaymentsLib" */ = { isa = XCConfigurationList; buildConfigurations = ( - D5A420976E9B94BCDCFB5C49F7536549 /* Debug */, - 902D1415E2FD80576F0BA3C3E6919A89 /* Release */, + 0B35F57EF97C18C61045D9FC48DB44C4 /* Debug */, + 956066D47418BDF4575236DE6EB3413E /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; @@ -1344,6 +4248,24 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; + 5713E665819F30CE132CA3F4C9E3BB9D /* Build configuration list for PBXNativeTarget "StripePayments" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + DFAC089E4FB9A83D809E441E6F97C8E1 /* Debug */, + 0B099DB2DBC7BF43EEB96DB78C60CA7D /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 5BF8A7B7F9F0AA6082B9D5D459F39DC1 /* Build configuration list for PBXNativeTarget "StripePayments-StripePayments" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + C944BA2868C340523DB2EC9054CAA1E7 /* Debug */, + ACD283773D9275246BCC24942FBD8261 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; 84E3C08133057626870418A290649C7E /* Build configuration list for PBXNativeTarget "Nimble" */ = { isa = XCConfigurationList; buildConfigurations = ( @@ -1353,6 +4275,33 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; + B9AD2FD5571D1110078EEEE4FC7B61B4 /* Build configuration list for PBXNativeTarget "StripeCore-StripeCore" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + F46C8C7BDB61F0224F78048C582E94D3 /* Debug */, + 5FA59DB355F40D0E85977F60E216A3B7 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + CB105085B6C26121040E9C847298D6D3 /* Build configuration list for PBXNativeTarget "StripePayments-Stripe3DS2" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + A99C44645FB28EF1702423C1D01A0939 /* Debug */, + 3228080102A4A37CE6DD4FC6565E084E /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + D6A6BB866CBA4B13ECD5FB371021DA04 /* Build configuration list for PBXNativeTarget "StripeCore" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + A8FAC06D56FD9A74812688431185DFEE /* Debug */, + 5D1BA1C34B512EAF4F89FC9C5AF70DE2 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; /* End XCConfigurationList section */ }; rootObject = BFDFE7DC352907FC980B868725387E98 /* Project object */; diff --git a/Pods/StripeCore/LICENSE b/Pods/StripeCore/LICENSE new file mode 100644 index 0000000..edf2d13 --- /dev/null +++ b/Pods/StripeCore/LICENSE @@ -0,0 +1,21 @@ +The MIT License + +Copyright (c) 2011- Stripe, Inc. (https://stripe.com) + +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. diff --git a/Pods/StripeCore/README.md b/Pods/StripeCore/README.md new file mode 100644 index 0000000..6af9163 --- /dev/null +++ b/Pods/StripeCore/README.md @@ -0,0 +1,141 @@ +# Stripe iOS SDK + +[![Travis](https://img.shields.io/travis/stripe/stripe-ios/master.svg?style=flat)](https://travis-ci.org/stripe/stripe-ios) +[![CocoaPods](https://img.shields.io/cocoapods/v/Stripe.svg?style=flat)](http://cocoapods.org/?q=author%3Astripe%20name%3Astripe) +[![Carthage compatible](https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat)](https://github.com/Carthage/Carthage) +[![License](https://img.shields.io/cocoapods/l/Stripe.svg?style=flat)](https://github.com/stripe/stripe-ios/blob/master/LICENSE) +[![Platform](https://img.shields.io/cocoapods/p/Stripe.svg?style=flat)](https://github.com/stripe/stripe-ios#) + +The Stripe iOS SDK makes it quick and easy to build an excellent payment experience in your iOS app. We provide powerful and customizable UI screens and elements that can be used out-of-the-box to collect your users' payment details. We also expose the low-level APIs that power those UIs so that you can build fully custom experiences. + +Get started with our [📚 integration guides](https://stripe.com/docs/payments/accept-a-payment?platform=ios) and [example projects](#examples), or [📘 browse the SDK reference](https://stripe.dev/stripe-ios/docs/index.html). + +Learn about our [Stripe Identity iOS SDK](StripeIdentity/README.md) to verify the identity of your users on iOS. + +> Updating to a newer version of the SDK? See our [migration guide](https://github.com/stripe/stripe-ios/blob/master/MIGRATING.md) and [changelog](https://github.com/stripe/stripe-ios/blob/master/CHANGELOG.md). + +Table of contents +================= + + + * [Features](#features) + * [Releases](#releases) + * [Requirements](#requirements) + * [Getting started](#getting-started) + * [Integration](#integration) + * [Examples](#examples) + * [Card scanning](#card-scanning) + * [Contributing](#contributing) + * [Migrating](#migrating-from-older-versions) + * [Licenses](#licenses) + + + +## Features + +**Simplified security**: We make it simple for you to collect sensitive data such as credit card numbers and remain [PCI compliant](https://stripe.com/docs/security#pci-dss-guidelines). This means the sensitive data is sent directly to Stripe instead of passing through your server. For more information, see our [integration security guide](https://stripe.com/docs/security). + +**Apple Pay**: [StripeApplePay](StripeApplePay/README.md) provides a [seamless integration with Apple Pay](https://stripe.com/docs/apple-pay). + +**SCA-ready**: The SDK automatically performs native [3D Secure authentication](https://stripe.com/docs/payments/3d-secure) if needed to comply with [Strong Customer Authentication](https://stripe.com/docs/strong-customer-authentication) regulation in Europe. + +**Native UI**: We provide native screens and elements to collect payment details. For example, [PaymentSheet](https://stripe.com/docs/payments/accept-a-payment?platform=ios) is a prebuilt UI that combines all the steps required to pay - collecting payment details, billing details, and confirming the payment - into a single sheet that displays on top of your app. + +PaymentSheet + +**Stripe API**: [StripePayments](StripePayments/README.md) provides [low-level APIs](https://stripe.dev/stripe-ios/docs/Classes/STPAPIClient.html) that correspond to objects and methods in the Stripe API. You can build your own entirely custom UI on top of this layer, while still taking advantage of utilities like [STPCardValidator](https://stripe.dev/stripe-ios/docs/Classes/STPCardValidator.html) to validate your user’s input. + +**Card scanning**: We support card scanning on iOS 13 and higher. See our [Card scanning](#card-scanning) section. + +**App Clips**: The `StripeApplePay` module provides a [lightweight SDK for offering Apple Pay in an App Clip](https://stripe.com/docs/apple-pay#app-clips). + +**Localized**: We support the following localizations: Bulgarian, Catalan, Chinese (Hong Kong), Chinese (Simplified), Chinese (Traditional), Croatian, Czech, Danish, Dutch, English (US), English (United Kingdom), Estonian, Filipino, Finnish, French, French (Canada), German, Greek, Hungarian, Indonesian, Italian, Japanese, Korean, Latvian, Lithuanian, Malay, Maltese, Norwegian Bokmål, Norwegian Nynorsk (Norway), Polish, Portuguese, Portuguese (Brazil), Romanian, Russian, Slovak, Slovenian, Spanish, Spanish (Latin America), Swedish, Turkish, Thai and Vietnamese. + +#### Recommended usage + +If you're selling digital products or services that will be consumed within your app, (e.g. subscriptions, in-game currencies, game levels, access to premium content, or unlocking a full version), you must use Apple's in-app purchase APIs. See the [App Store review guidelines](https://developer.apple.com/app-store/review/guidelines/#payments) for more information. For all other scenarios you can use this SDK to process payments via Stripe. + +#### Privacy + +The Stripe iOS SDK collects data to help us improve our products and prevent fraud. This data is never used for advertising and is not rented, sold, or given to advertisers. Our full privacy policy is available at [https://stripe.com/privacy](https://stripe.com/privacy). + +For help with Apple's App Privacy Details form in App Store Connect, visit [Stripe iOS SDK Privacy Details](https://support.stripe.com/questions/stripe-ios-sdk-privacy-details). + +## Modules +|Module|Description|Compressed|Uncompressed| +|------|-----------|----------|------------| +|StripePaymentSheet|Stripe's [prebuilt payment UI](https://stripe.com/docs/payments/accept-a-payment?platform=ios&ui=payment-sheet).|2.7MB|6.3MB| +|Stripe|Contains all the below frameworks, plus [Issuing](https://stripe.com/docs/issuing/cards/digital-wallets?platform=iOS) and [Basic Integration](/docs/mobile/ios/basic).|2.3MB|5.1MB| +|StripeApplePay|[Apple Pay support](/docs/apple-pay), including `STPApplePayContext`.|0.4MB|1.0MB| +|StripePayments|Bindings for the Stripe Payments API.|1.0MB|2.6MB| +|StripePaymentsUI|Bindings for the Stripe Payments API, [STPPaymentCardTextField](https://stripe.com/docs/payments/accept-a-payment?platform=ios&ui=custom), STPCardFormView, and other UI elements.|1.7MB|3.9MB| + +## Releases + +We support Cocoapods, Carthage, and Swift Package Manager. + +If you link the library manually, use a version from our [releases](https://github.com/stripe/stripe-ios/releases) page and make sure to embed all of the required frameworks. + +For the `Stripe` module, link the following frameworks: +- `Stripe.xcframework` +- `Stripe3DS2.xcframework` +- `StripeApplePay.xcframework` +- `StripePayments.xcframework` +- `StripePaymentsUI.xcframework` +- `StripeCore.xcframework` +- `StripeUICore.xcframework` + +For other modules, follow the instructions below: +- [StripePaymentSheet](StripePaymentSheet/README.md#manual-linking) +- [StripePayments](StripePayments/README.md#manual-linking) +- [StripePaymentsUI](StripePaymentsUI/README.md#manual-linking) +- [StripeApplePay](StripeApplePay/README.md#manual-linking) +- [StripeIdentity](StripeIdentity/README.md#manual-linking) + +If you're reading this on GitHub.com, please make sure you are looking at the [tagged version](https://github.com/stripe/stripe-ios/tags) that corresponds to the release you have installed. Otherwise, the instructions and example code may be mismatched with your copy. + +## Requirements + +The Stripe iOS SDK requires Xcode 13.2.1 or later and is compatible with apps targeting iOS 13 or above. We support Catalyst on macOS 10.16 or later. + +For iOS 12 support, please use [v22.8.4](https://github.com/stripe/stripe-ios/tree/v22.8.4). For iOS 11 support, please use [v21.13.0](https://github.com/stripe/stripe-ios/tree/v21.13.0). For iOS 10, please use [v19.4.0](https://github.com/stripe/stripe-ios/tree/v19.4.0). If you need to support iOS 9, use [v17.0.2](https://github.com/stripe/stripe-ios/tree/v17.0.2). + +Requirements for the **Stripe Identity iOS SDK** can be found [here](StripeIdentity/README.md#requirements). + +## Getting started + +### Integration + +Get started with our [📚 integration guides](https://stripe.com/docs/payments/accept-a-payment?platform=ios) and [example projects](/Example), or [📘 browse the SDK reference](https://stripe.dev/stripe-ios/docs/index.html) for fine-grained documentation of all the classes and methods in the SDK. + +### Examples + +- [Prebuilt UI](Example/PaymentSheet%20Example) (Recommended) + - This example demonstrates how to build a payment flow using [`PaymentSheet`](https://stripe.com/docs/payments/accept-a-payment?platform=ios), an embeddable native UI component that lets you accept [10+ payment methods](https://stripe.com/docs/payments/payment-methods/integration-options#payment-method-product-support) with a single integration. + +- [Non-Card Payment Examples](Example/Non-Card%20Payment%20Examples) + - This example demonstrates how to manually accept various payment methods using the Stripe API. + +## Card scanning + +[PaymentSheet](https://stripe.com/docs/payments/accept-a-payment?platform=ios) offers built-in card scanning. To enable card scanning, you'll need to set `NSCameraUsageDescription` in your application's plist, and provide a reason for accessing the camera (e.g. "To scan cards"). Card scanning is supported on devices with iOS 13 or higher. + +You can demo this feature in our [PaymentSheet example app](Example/PaymentSheet%20Example). When you run the example app on a device, you'll see a "Scan Card" button when adding a new card. + +## Contributing + +We welcome contributions of any kind including new features, bug fixes, and documentation improvements. Please first open an issue describing what you want to build if it is a major change so that we can discuss how to move forward. Otherwise, go ahead and open a pull request for minor changes such as typo fixes and one liners. + +### Running tests + +1. Install Carthage 0.37 or later (if you have homebrew installed, `brew install carthage`) +2. From the root of the repo, run `bundle install && bundle exec fastlane stripeios_tests`. This will install the test dependencies and run the tests. +3. Once you have run this once, you can also run the tests in Xcode from the `StripeiOS` target in `Stripe.xcworkspace`. Make sure to use the iPhone 12 mini, iOS 15.4 simulator so the snapshot tests will pass. + +## Migrating from older versions + +See [MIGRATING.md](https://github.com/stripe/stripe-ios/blob/master/MIGRATING.md) + +## Licenses + +- [Stripe iOS SDK License](LICENSE) diff --git a/Pods/StripeCore/StripeCore/StripeCore/Resources/Localizations/bg-BG.lproj/Localizable.strings b/Pods/StripeCore/StripeCore/StripeCore/Resources/Localizations/bg-BG.lproj/Localizable.strings new file mode 100644 index 0000000..584a0a3 --- /dev/null +++ b/Pods/StripeCore/StripeCore/StripeCore/Resources/Localizations/bg-BG.lproj/Localizable.strings @@ -0,0 +1,31 @@ +"Close" = "Затваряне"; + +"Scan Card" = "Сканиране на картата"; + +"Scan card" = "Сканиране на карта"; + +"The IBAN you entered is invalid." = "IBAN, който сте въвели, е невалиден."; + +"There was an error processing your card -- try again in a few seconds" = "Възникна грешка при обработката на Вашата карта -- опитайте отново след няколко секунди"; + +"There was an unexpected error -- try again in a few seconds" = "Това беше неочаквана грешка -- опитайте отново след няколко секунди"; + +"Try again" = "Опитайте отново"; + +"We use Stripe to verify your card details. Stripe may use and store your data according its privacy policy. Learn more" = "Използваме Stripe, за да потвърдим данните на картата Ви. Stripe може да използва и съхранява данните Ви в съответствие с правилата си за защита на личните данни. Научете повече"; + +"Your card has expired" = "Вашата карта е изтекла"; + +"Your card was declined" = "Вашата карта бе отхвърлена"; + +"Your card's expiration month is invalid" = "Месецът на валидност на Вашата карта е невалиден"; + +"Your card's expiration year is invalid" = "Годината на валидност на Вашата карта е невалидна"; + +"Your card's number is invalid" = "Номерът на Вашата карта е невалиден"; + +"Your card's security code is invalid" = "Кодът за сигурност на Вашата карта е невалиден"; + +"Your name is invalid." = "Името Ви е невалидно."; + +"Your payment method was declined." = "Начинът Ви на плащане беше отказан."; diff --git a/Pods/StripeCore/StripeCore/StripeCore/Resources/Localizations/ca-ES.lproj/Localizable.strings b/Pods/StripeCore/StripeCore/StripeCore/Resources/Localizations/ca-ES.lproj/Localizable.strings new file mode 100644 index 0000000..02e221c --- /dev/null +++ b/Pods/StripeCore/StripeCore/StripeCore/Resources/Localizations/ca-ES.lproj/Localizable.strings @@ -0,0 +1,31 @@ +"Close" = "Tanca"; + +"Scan Card" = "Escanejar targeta"; + +"Scan card" = "Escanejar targeta"; + +"The IBAN you entered is invalid." = "L'IBAN és incorrecte."; + +"There was an error processing your card -- try again in a few seconds" = "Hi ha hagut un error processant la teva targeta - torna-ho a intentar en uns segons"; + +"There was an unexpected error -- try again in a few seconds" = "Hi ha hagut un error inesperat - torna-ho a intentar en uns segons"; + +"Try again" = "Intenta-ho un altre cop"; + +"We use Stripe to verify your card details. Stripe may use and store your data according its privacy policy. Learn more" = "Emprem Stripe per verificar els detalls de la vostra targeta. És possible que Stripe faci ús i emmagatzemi les dades d'acord amb la política de privadesa. Més informació"; + +"Your card has expired" = "La teva targeta ha caducat"; + +"Your card was declined" = "S'ha rebutjat la teva targeta"; + +"Your card's expiration month is invalid" = "El mes de caducitat de la teva targeta no és vàlid"; + +"Your card's expiration year is invalid" = "L'any de caducitat de la teva targeta no és vàlid"; + +"Your card's number is invalid" = "El número de la teva targeta no és vàlid"; + +"Your card's security code is invalid" = "El codi de seguretat de la teva targeta no és vàlid"; + +"Your name is invalid." = "El nom no és vàlid."; + +"Your payment method was declined." = "S'ha rebutjat el mètode de pagament."; diff --git a/Pods/StripeCore/StripeCore/StripeCore/Resources/Localizations/cs-CZ.lproj/Localizable.strings b/Pods/StripeCore/StripeCore/StripeCore/Resources/Localizations/cs-CZ.lproj/Localizable.strings new file mode 100644 index 0000000..2602882 --- /dev/null +++ b/Pods/StripeCore/StripeCore/StripeCore/Resources/Localizations/cs-CZ.lproj/Localizable.strings @@ -0,0 +1,31 @@ +"Close" = "Zavřít"; + +"Scan Card" = "Naskenovat kartu"; + +"Scan card" = "Naskenovat kartu"; + +"The IBAN you entered is invalid." = "Číslo IBAN, které jste zadali, je neplatné."; + +"There was an error processing your card -- try again in a few seconds" = "Při zpracování Vaší karty došlo k chybě -- zkuste to za několik sekund znovu"; + +"There was an unexpected error -- try again in a few seconds" = "Došlo k neočekávané chybě -- zkuste to znovu za několik sekund"; + +"Try again" = "Zkusit znovu"; + +"We use Stripe to verify your card details. Stripe may use and store your data according its privacy policy. Learn more" = "K ověření údajů o vaší kartě používáme službu Stripe. Společnost Stripe může vaše údaje používat a ukládat v souladu se svými zásadami ochrany osobních údajů. Více informací"; + +"Your card has expired" = "Platnost Vaší karty uplynula"; + +"Your card was declined" = "Vaše karta byla odmítnuta"; + +"Your card's expiration month is invalid" = "Měsíc konce platnosti Vaší karty je neplatný"; + +"Your card's expiration year is invalid" = "Rok konce platnosti Vaší karty je neplatný"; + +"Your card's number is invalid" = "Číslo Vaší karty je neplatné"; + +"Your card's security code is invalid" = "Bezpečnostní kód Vaší karty je neplatný"; + +"Your name is invalid." = "Vaše jméno je neplatné."; + +"Your payment method was declined." = "Vaše platební metoda byla zamítnuta."; diff --git a/Pods/StripeCore/StripeCore/StripeCore/Resources/Localizations/da.lproj/Localizable.strings b/Pods/StripeCore/StripeCore/StripeCore/Resources/Localizations/da.lproj/Localizable.strings new file mode 100644 index 0000000..db47ad0 --- /dev/null +++ b/Pods/StripeCore/StripeCore/StripeCore/Resources/Localizations/da.lproj/Localizable.strings @@ -0,0 +1,31 @@ +"Close" = "Luk"; + +"Scan Card" = "Scan kort"; + +"Scan card" = "Scan kort"; + +"The IBAN you entered is invalid." = "Det indtastede IBAN-nummer er ugyldigt."; + +"There was an error processing your card -- try again in a few seconds" = "Der opstod en fejl under behandling af dit kort – prøv igen om et par sekunder"; + +"There was an unexpected error -- try again in a few seconds" = "Der opstod en uventet fejl – prøv igen om et par sekunder"; + +"Try again" = "Prøv igen"; + +"We use Stripe to verify your card details. Stripe may use and store your data according its privacy policy. Learn more" = "Vi bruger Stripe til at bekræfte dine kortoplysninger. Stripe kan bruge og gemme dine oplysninger i henhold til selskabets Privatlivspolitik. Lær mere"; + +"Your card has expired" = "Dit kort er udløbet"; + +"Your card was declined" = "Dit kort blev afvist"; + +"Your card's expiration month is invalid" = "Kortets udløbsmåned er ugyldig"; + +"Your card's expiration year is invalid" = "Kortets udløbsår er ugyldigt"; + +"Your card's number is invalid" = "Kortnummeret er ugyldigt"; + +"Your card's security code is invalid" = "Kortets sikkerhedskode er ugyldig"; + +"Your name is invalid." = "Dit navn er ugyldigt."; + +"Your payment method was declined." = "Din betalingsmetode blev afvist."; diff --git a/Pods/StripeCore/StripeCore/StripeCore/Resources/Localizations/de.lproj/Localizable.strings b/Pods/StripeCore/StripeCore/StripeCore/Resources/Localizations/de.lproj/Localizable.strings new file mode 100644 index 0000000..c8ebab3 --- /dev/null +++ b/Pods/StripeCore/StripeCore/StripeCore/Resources/Localizations/de.lproj/Localizable.strings @@ -0,0 +1,31 @@ +"Close" = "Schließen"; + +"Scan Card" = "Karte scannen"; + +"Scan card" = "Karte scannen"; + +"The IBAN you entered is invalid." = "Die eingegebene IBAN ist ungültig."; + +"There was an error processing your card -- try again in a few seconds" = "Fehler bei der Verarbeitung Ihrer Karte – versuchen Sie es in ein paar Sekunden noch einmal."; + +"There was an unexpected error -- try again in a few seconds" = "Unerwarteter Fehler – versuchen Sie es in ein paar Sekunden noch einmal."; + +"Try again" = "Erneut versuchen"; + +"We use Stripe to verify your card details. Stripe may use and store your data according its privacy policy. Learn more" = "Wir nutzen Stripe, um Ihre Kartenangaben zu verifizieren. Stripe kann im Einklang mit seiner Datenschutzerklärung Ihre Daten verwenden und speichern. Mehr erfahren"; + +"Your card has expired" = "Ihre Karte ist abgelaufen."; + +"Your card was declined" = "Ihre Karte wurde abgelehnt."; + +"Your card's expiration month is invalid" = "Der Ablaufmonat Ihrer Karte ist ungültig"; + +"Your card's expiration year is invalid" = "Das Ablaufjahr Ihrer Karte ist ungültig."; + +"Your card's number is invalid" = "Die Kartennummer ist ungültig."; + +"Your card's security code is invalid" = "Der Sicherheitscode Ihrer Karte ist ungültig."; + +"Your name is invalid." = "Ihr Name ist ungültig."; + +"Your payment method was declined." = "Ihre Zahlungsmethode wurde abgelehnt."; diff --git a/Pods/StripeCore/StripeCore/StripeCore/Resources/Localizations/el-GR.lproj/Localizable.strings b/Pods/StripeCore/StripeCore/StripeCore/Resources/Localizations/el-GR.lproj/Localizable.strings new file mode 100644 index 0000000..aa5faa6 --- /dev/null +++ b/Pods/StripeCore/StripeCore/StripeCore/Resources/Localizations/el-GR.lproj/Localizable.strings @@ -0,0 +1,31 @@ +"Close" = "Κλείσιμο"; + +"Scan Card" = "Σάρωση κάρτας"; + +"Scan card" = "Σάρωση κάρτας"; + +"The IBAN you entered is invalid." = "Ο κωδικός IBAN που εισαγάγατε δεν είναι έγκυρος."; + +"There was an error processing your card -- try again in a few seconds" = "Προέκυψε απροσδόκητο σφάλμα κατά την επεξεργασία της κάρτας σας -- δοκιμάστε ξανά σε μερικά δευτερόλεπτα"; + +"There was an unexpected error -- try again in a few seconds" = "Προέκυψε απροσδόκητο σφάλμα -- δοκιμάστε ξανά σε μερικά δευτερόλεπτα"; + +"Try again" = "Δοκιμάστε ξανά"; + +"We use Stripe to verify your card details. Stripe may use and store your data according its privacy policy. Learn more" = "Χρησιμοποιούμε τη Stripe για να επαληθεύσουμε τα στοιχεία της κάρτας σας. Η Stripe μπορεί να χρησιμοποιεί και να αποθηκεύει τα δεδομένα σας σύμφωνα με την πολιτική απορρήτου της. Μάθετε περισσότερα"; + +"Your card has expired" = "Η κάρτα σας έχει λήξει"; + +"Your card was declined" = "Η κάρτα σας απορρίφθηκε"; + +"Your card's expiration month is invalid" = "Ο μήνας λήξης της κάρτας σας δεν είναι έγκυρος"; + +"Your card's expiration year is invalid" = "Το έτος λήξης της κάρτας σας δεν είναι έγκυρο"; + +"Your card's number is invalid" = "Ο αριθμός της κάρτας σας δεν είναι έγκυρος"; + +"Your card's security code is invalid" = "Ο κωδικός ασφαλείας της κάρτας σας δεν είναι έγκυρος"; + +"Your name is invalid." = "Το όνομά σας δεν είναι έγκυρο."; + +"Your payment method was declined." = "Η μέθοδος πληρωμής σας απορρίφθηκε."; diff --git a/Pods/StripeCore/StripeCore/StripeCore/Resources/Localizations/en-GB.lproj/Localizable.strings b/Pods/StripeCore/StripeCore/StripeCore/Resources/Localizations/en-GB.lproj/Localizable.strings new file mode 100644 index 0000000..c88d2ca --- /dev/null +++ b/Pods/StripeCore/StripeCore/StripeCore/Resources/Localizations/en-GB.lproj/Localizable.strings @@ -0,0 +1,31 @@ +"Close" = "Close"; + +"Scan Card" = "Scan Card"; + +"Scan card" = "Scan card"; + +"The IBAN you entered is invalid." = "The IBAN you entered is invalid."; + +"There was an error processing your card -- try again in a few seconds" = "There was an error processing your card - please try again in a few seconds"; + +"There was an unexpected error -- try again in a few seconds" = "There was an unexpected error - please try again in a few seconds"; + +"Try again" = "Try again"; + +"We use Stripe to verify your card details. Stripe may use and store your data according its privacy policy. Learn more" = "We use Stripe to verify your card details. Stripe may use and store your data according its privacy policy. Learn more"; + +"Your card has expired" = "Your card has expired"; + +"Your card was declined" = "Your card has been declined"; + +"Your card's expiration month is invalid" = "Your card's expiry month is invalid"; + +"Your card's expiration year is invalid" = "Your card's expiry year is invalid"; + +"Your card's number is invalid" = "Your card's number is invalid"; + +"Your card's security code is invalid" = "Your card's security code is invalid"; + +"Your name is invalid." = "Your name is invalid."; + +"Your payment method was declined." = "Your payment method was declined."; diff --git a/Pods/StripeCore/StripeCore/StripeCore/Resources/Localizations/en.lproj/Localizable.strings b/Pods/StripeCore/StripeCore/StripeCore/Resources/Localizations/en.lproj/Localizable.strings new file mode 100644 index 0000000..23b8cfb --- /dev/null +++ b/Pods/StripeCore/StripeCore/StripeCore/Resources/Localizations/en.lproj/Localizable.strings @@ -0,0 +1,48 @@ +/* Text for close button */ +"Close" = "Close"; + +/* Text for button to scan a credit card */ +"Scan Card" = "Scan Card"; + +/* Button title to open camera to scan credit/debit card */ +"Scan card" = "Scan card"; + +/* An error message displayed when the customer's iban is invalid. */ +"The IBAN you entered is invalid." = "The IBAN you entered is invalid."; + +/* Error when there is a problem processing the credit card */ +"There was an error processing your card -- try again in a few seconds" = "There was an error processing your card -- try again in a few seconds"; + +/* Unexpected error, such as a 500 from Stripe or a JSON parse error */ +"There was an unexpected error -- try again in a few seconds" = "There was an unexpected error -- try again in a few seconds"; + +/* Text for a retry button */ +"Try again" = "Try again"; + +/* Informational text informing the user that Stripe is used to process data and a link to Stripe's privacy policy */ +"We use Stripe to verify your card details. Stripe may use and store your data according its privacy policy. Learn more" = "We use Stripe to verify your card details. Stripe may use and store your data according its privacy policy. Learn more"; + +/* Error when the card has already expired */ +"Your card has expired" = "Your card has expired"; + +/* Error when the card was declined by the credit card networks */ +"Your card was declined" = "Your card was declined"; + +/* Error when the card's expiration month is not valid */ +"Your card's expiration month is invalid" = "Your card's expiration month is invalid"; + +/* Error when the card's expiration year is not valid */ +"Your card's expiration year is invalid" = "Your card's expiration year is invalid"; + +/* Error when the card number is not valid */ +"Your card's number is invalid" = "Your card's number is invalid"; + +/* Error when the card's CVC is not valid */ +"Your card's security code is invalid" = "Your card's security code is invalid"; + +/* Error when customer's name is invalid */ +"Your name is invalid." = "Your name is invalid."; + +/* Error message when a payment method gets declined. */ +"Your payment method was declined." = "Your payment method was declined."; + diff --git a/Pods/StripeCore/StripeCore/StripeCore/Resources/Localizations/es-419.lproj/Localizable.strings b/Pods/StripeCore/StripeCore/StripeCore/Resources/Localizations/es-419.lproj/Localizable.strings new file mode 100644 index 0000000..300eb90 --- /dev/null +++ b/Pods/StripeCore/StripeCore/StripeCore/Resources/Localizations/es-419.lproj/Localizable.strings @@ -0,0 +1,31 @@ +"Close" = "Cerrar"; + +"Scan Card" = "Escanear tarjeta"; + +"Scan card" = "Escanear tarjeta"; + +"The IBAN you entered is invalid." = "El IBAN que ingresaste no es válido."; + +"There was an error processing your card -- try again in a few seconds" = "Hubo un error al procesar tu tarjeta. Vuelve a intentar en unos segundos."; + +"There was an unexpected error -- try again in a few seconds" = "Se produjo un error inesperado. Vuelve a intentar en unos segundos."; + +"Try again" = "Reintentar"; + +"We use Stripe to verify your card details. Stripe may use and store your data according its privacy policy. Learn more" = "Usamos Stripe para verificar los datos de tu tarjeta. Stripe puede usar y almacenar tus datos de acuerdo con la política de privacidad. Más información"; + +"Your card has expired" = "Tu tarjeta ha vencido."; + +"Your card was declined" = "Tu tarjeta fue rechazada."; + +"Your card's expiration month is invalid" = "El mes de vencimiento de tu tarjeta no es válido."; + +"Your card's expiration year is invalid" = "El año de vencimiento de tu tarjeta no es válido"; + +"Your card's number is invalid" = "El número de tarjeta no es válido"; + +"Your card's security code is invalid" = "El código de seguridad de tu tarjeta no es válido."; + +"Your name is invalid." = "El nombre no es válido."; + +"Your payment method was declined." = "Tu método de pago fue rechazado."; diff --git a/Pods/StripeCore/StripeCore/StripeCore/Resources/Localizations/es.lproj/Localizable.strings b/Pods/StripeCore/StripeCore/StripeCore/Resources/Localizations/es.lproj/Localizable.strings new file mode 100644 index 0000000..45c575e --- /dev/null +++ b/Pods/StripeCore/StripeCore/StripeCore/Resources/Localizations/es.lproj/Localizable.strings @@ -0,0 +1,31 @@ +"Close" = "Cerrar"; + +"Scan Card" = "Escanear tarjeta"; + +"Scan card" = "Escanear tarjeta"; + +"The IBAN you entered is invalid." = "El IBAN introducido no es válido."; + +"There was an error processing your card -- try again in a few seconds" = "Error al procesar la tarjeta. Vuelve a intentarlo en unos segundos."; + +"There was an unexpected error -- try again in a few seconds" = "Se ha producido un error inesperado. Vuelve a intentarlo en unos segundos"; + +"Try again" = "Reintentar"; + +"We use Stripe to verify your card details. Stripe may use and store your data according its privacy policy. Learn more" = "Usamos Stripe para verificar los datos de tu tarjeta. Stripe puede usar y almacenar tus datos de acuerdo con la política de privacidad. Más información"; + +"Your card has expired" = "La tarjeta ha caducado"; + +"Your card was declined" = "La tarjeta ha sido rechazada"; + +"Your card's expiration month is invalid" = "El mes de caducidad de tu tarjeta no es válido"; + +"Your card's expiration year is invalid" = "El año de caducidad de tu tarjeta no es válido"; + +"Your card's number is invalid" = "El número de tarjeta no es válido"; + +"Your card's security code is invalid" = "El código de seguridad de tu tarjeta no es válido"; + +"Your name is invalid." = "El nombre no es válido."; + +"Your payment method was declined." = "Se ha rechazado tu método de pago."; diff --git a/Pods/StripeCore/StripeCore/StripeCore/Resources/Localizations/et-EE.lproj/Localizable.strings b/Pods/StripeCore/StripeCore/StripeCore/Resources/Localizations/et-EE.lproj/Localizable.strings new file mode 100644 index 0000000..773793e --- /dev/null +++ b/Pods/StripeCore/StripeCore/StripeCore/Resources/Localizations/et-EE.lproj/Localizable.strings @@ -0,0 +1,31 @@ +"Close" = "Sule"; + +"Scan Card" = "Skanni kaart"; + +"Scan card" = "Skanni kaart"; + +"The IBAN you entered is invalid." = "Sisestatud IBAN on kehtetu."; + +"There was an error processing your card -- try again in a few seconds" = "Kaardi töötlemisel esines tõrge – proovige mõne sekundi pärast uuesti"; + +"There was an unexpected error -- try again in a few seconds" = "Esines ootamatu tõrge – proovige mõne sekundi pärast uuesti"; + +"Try again" = "Proovi uuesti"; + +"We use Stripe to verify your card details. Stripe may use and store your data according its privacy policy. Learn more" = "Kasutame teie kaardiandmete kontrollimiseks Stripe'i. Stripe võib teie andmeid kasutada ja säilitada vastavalt oma privaatsuspoliitikale. Vaata lähemalt"; + +"Your card has expired" = "Kaart on aegunud"; + +"Your card was declined" = "Kaart lükati tagasi"; + +"Your card's expiration month is invalid" = "Kaardi aegumiskuu on kehtetu"; + +"Your card's expiration year is invalid" = "Kaardi aegumisaasta on kehtetu"; + +"Your card's number is invalid" = "Kaardi number on kehtetu"; + +"Your card's security code is invalid" = "Kaardi turvakood on kehtetu"; + +"Your name is invalid." = "Teie nimi on kehtetu."; + +"Your payment method was declined." = "Teie makseviis lükati tagasi."; diff --git a/Pods/StripeCore/StripeCore/StripeCore/Resources/Localizations/fi.lproj/Localizable.strings b/Pods/StripeCore/StripeCore/StripeCore/Resources/Localizations/fi.lproj/Localizable.strings new file mode 100644 index 0000000..d1ce73d --- /dev/null +++ b/Pods/StripeCore/StripeCore/StripeCore/Resources/Localizations/fi.lproj/Localizable.strings @@ -0,0 +1,31 @@ +"Close" = "Sulje"; + +"Scan Card" = "Skannaa kortti"; + +"Scan card" = "Skannaa kortti"; + +"The IBAN you entered is invalid." = "Antamasi IBAN on virheellinen."; + +"There was an error processing your card -- try again in a few seconds" = "Kortin käsittelyssä tapahtui virhe – kokeile uudelleen muutaman sekunnin kuluttua"; + +"There was an unexpected error -- try again in a few seconds" = "Odottamaton virhe – kokeile uudelleen muutaman sekunnin kuluttua"; + +"Try again" = "Yritä uudelleen"; + +"We use Stripe to verify your card details. Stripe may use and store your data according its privacy policy. Learn more" = "Käytämme Stripeä korttitietojen vahvistamiseen. Stripe voi käyttää ja säilyttää tietojasi heidän tietosuojaselosteensa mukaisesti. Lue lisää"; + +"Your card has expired" = "Korttisi on vanhentunut"; + +"Your card was declined" = "Korttiasi ei hyväksytty"; + +"Your card's expiration month is invalid" = "Kortin erääntymiskuukausi ei kelpaa"; + +"Your card's expiration year is invalid" = "Kortin erääntymisvuosi ei kelpaa"; + +"Your card's number is invalid" = "Kortin numero ei kelpaa"; + +"Your card's security code is invalid" = "Kortin turvakoodi ei kelpaa"; + +"Your name is invalid." = "Nimi on virheellinen."; + +"Your payment method was declined." = "Maksutapasi on hylätty."; diff --git a/Pods/StripeCore/StripeCore/StripeCore/Resources/Localizations/fil.lproj/Localizable.strings b/Pods/StripeCore/StripeCore/StripeCore/Resources/Localizations/fil.lproj/Localizable.strings new file mode 100644 index 0000000..f03968e --- /dev/null +++ b/Pods/StripeCore/StripeCore/StripeCore/Resources/Localizations/fil.lproj/Localizable.strings @@ -0,0 +1,31 @@ +"Close" = "Isara"; + +"Scan Card" = "I-scan ang kard"; + +"Scan card" = "I-scan ang kard"; + +"The IBAN you entered is invalid." = "Ang IBAN na iniligay mo ay imbalido."; + +"There was an error processing your card -- try again in a few seconds" = "Nagkaroon ng kamalian sa pagproseso ng iyong kard -- subukin muli sa ilang segundo"; + +"There was an unexpected error -- try again in a few seconds" = "Nagkaroon ng di-inaasahang kamalian -- subukin muli sa ilang segundo"; + +"Try again" = "Subukan muli"; + +"We use Stripe to verify your card details. Stripe may use and store your data according its privacy policy. Learn more" = "Gumagamit kami ng Stripe para i-verify ang mga detalye ng iyong kard. Maaaring gamitin at imbakin ng Stripe ang iyong data ayon sa patakaran sa privacy nito. Alamin ang higit pa"; + +"Your card has expired" = "Napaso na ang iyong kard"; + +"Your card was declined" = "Tinanggihan ang iyong kard"; + +"Your card's expiration month is invalid" = "Ang buwan ng pagkapaso ng iyong kard ay di balido"; + +"Your card's expiration year is invalid" = "Ang taon ng pagkapaso ng iyong kard ay di balido"; + +"Your card's number is invalid" = "Ang numero ng iyong kard ay di balido"; + +"Your card's security code is invalid" = "Ang security code ng iyong kard ay di balido"; + +"Your name is invalid." = "Ang iyong pangalan ay imbalido."; + +"Your payment method was declined." = "Tinanggihan ang iyong paraan ng pagbabayad."; diff --git a/Pods/StripeCore/StripeCore/StripeCore/Resources/Localizations/fr-CA.lproj/Localizable.strings b/Pods/StripeCore/StripeCore/StripeCore/Resources/Localizations/fr-CA.lproj/Localizable.strings new file mode 100644 index 0000000..8383289 --- /dev/null +++ b/Pods/StripeCore/StripeCore/StripeCore/Resources/Localizations/fr-CA.lproj/Localizable.strings @@ -0,0 +1,31 @@ +"Close" = "Fermer"; + +"Scan Card" = "Scanner la carte"; + +"Scan card" = "Scanner la carte"; + +"The IBAN you entered is invalid." = "L'IBAN que vous avez saisi n'est pas valide."; + +"There was an error processing your card -- try again in a few seconds" = "Une erreur est survenue lors du traitement de votre carte. Réessayez dans quelques secondes."; + +"There was an unexpected error -- try again in a few seconds" = "Une erreur inattendue est survenue. Réessayez dans quelques secondes."; + +"Try again" = "Réessayer"; + +"We use Stripe to verify your card details. Stripe may use and store your data according its privacy policy. Learn more" = "Nous faisons appel à Stripe pour vérifier les informations de votre carte. Stripe peut utiliser et stocker vos données conformément à sa politique de confidentialité. En savoir plus"; + +"Your card has expired" = "Votre carte a expiré"; + +"Your card was declined" = "Votre carte a été refusée"; + +"Your card's expiration month is invalid" = "Le mois d'expiration de votre carte n'est pas valide"; + +"Your card's expiration year is invalid" = "L'année d'expiration de votre carte n'est pas valide"; + +"Your card's number is invalid" = "Votre numéro de carte n'est pas valide"; + +"Your card's security code is invalid" = "Le code de sécurité de votre carte n'est pas valide"; + +"Your name is invalid." = "Votre nom n'est pas valide."; + +"Your payment method was declined." = "Votre moyen de paiement a été refusé."; diff --git a/Pods/StripeCore/StripeCore/StripeCore/Resources/Localizations/fr.lproj/Localizable.strings b/Pods/StripeCore/StripeCore/StripeCore/Resources/Localizations/fr.lproj/Localizable.strings new file mode 100644 index 0000000..f3ccd39 --- /dev/null +++ b/Pods/StripeCore/StripeCore/StripeCore/Resources/Localizations/fr.lproj/Localizable.strings @@ -0,0 +1,31 @@ +"Close" = "Fermer"; + +"Scan Card" = "Scanner la carte"; + +"Scan card" = "Scanner la carte"; + +"The IBAN you entered is invalid." = "L'IBAN que vous avez saisi n'est pas valide."; + +"There was an error processing your card -- try again in a few seconds" = "Une erreur est survenue lors du traitement de votre carte. Réessayez dans quelques secondes."; + +"There was an unexpected error -- try again in a few seconds" = "Une erreur inattendue est survenue. Réessayez dans quelques secondes."; + +"Try again" = "Réessayer"; + +"We use Stripe to verify your card details. Stripe may use and store your data according its privacy policy. Learn more" = "Nous faisons appel à Stripe pour vérifier les informations de votre carte. Stripe peut utiliser et stocker vos données conformément à sa politique de confidentialité. En savoir plus"; + +"Your card has expired" = "Votre carte est arrivée à expiration."; + +"Your card was declined" = "Votre carte a été refusée."; + +"Your card's expiration month is invalid" = "Le mois d'expiration de votre carte n'est pas valide."; + +"Your card's expiration year is invalid" = "L'année d'expiration de votre carte n'est pas valide."; + +"Your card's number is invalid" = "Votre numéro de carte n'est pas valide."; + +"Your card's security code is invalid" = "Le code de sécurité de votre carte n'est pas valide"; + +"Your name is invalid." = "Votre nom n'est pas valide."; + +"Your payment method was declined." = "Votre moyen de paiement a été refusé."; diff --git a/Pods/StripeCore/StripeCore/StripeCore/Resources/Localizations/hr.lproj/Localizable.strings b/Pods/StripeCore/StripeCore/StripeCore/Resources/Localizations/hr.lproj/Localizable.strings new file mode 100644 index 0000000..ce91f93 --- /dev/null +++ b/Pods/StripeCore/StripeCore/StripeCore/Resources/Localizations/hr.lproj/Localizable.strings @@ -0,0 +1,31 @@ +"Close" = "Zatvori"; + +"Scan Card" = "Skeniraj karticu"; + +"Scan card" = "Skeniraj karticu"; + +"The IBAN you entered is invalid." = "Uneseni IBAN nije valjan."; + +"There was an error processing your card -- try again in a few seconds" = "Došlo je do pogreške u obradi vaše kartice -- pokušajte ponovno za nekoliko sekundi"; + +"There was an unexpected error -- try again in a few seconds" = "Došlo je do neočekivane pogreške -- pokušajte ponovno za nekoliko sekundi"; + +"Try again" = "Pokušajte ponovo"; + +"We use Stripe to verify your card details. Stripe may use and store your data according its privacy policy. Learn more" = "Koristimo Stripe za provjeru vaših podataka o kartici. Stripe može koristiti i pohranjivati vaše podatke u skladu sa svojim pravilima privatnosti. Saznajte više"; + +"Your card has expired" = "Vaša kartica je istekla"; + +"Your card was declined" = "Kartica je odbijena"; + +"Your card's expiration month is invalid" = "Mjesec isteka kartice nije valjan"; + +"Your card's expiration year is invalid" = "Godina isteka kartice nije valjana"; + +"Your card's number is invalid" = "Broj kartice nije valjan"; + +"Your card's security code is invalid" = "Sigurnosni kod vaše kartice nije valjan"; + +"Your name is invalid." = "Vaše ime je neispravno."; + +"Your payment method was declined." = "Vaš način plaćanja je odbijen."; diff --git a/Pods/StripeCore/StripeCore/StripeCore/Resources/Localizations/hu.lproj/Localizable.strings b/Pods/StripeCore/StripeCore/StripeCore/Resources/Localizations/hu.lproj/Localizable.strings new file mode 100644 index 0000000..2a5df89 --- /dev/null +++ b/Pods/StripeCore/StripeCore/StripeCore/Resources/Localizations/hu.lproj/Localizable.strings @@ -0,0 +1,31 @@ +"Close" = "Bezárás"; + +"Scan Card" = "Kártya beolvasása"; + +"Scan card" = "Kártya beolvasása"; + +"The IBAN you entered is invalid." = "A beírt IBAN-szám érvénytelen."; + +"There was an error processing your card -- try again in a few seconds" = "Hiba történt kártyája feldolgozása során, próbálja újra néhány másodperc múlva"; + +"There was an unexpected error -- try again in a few seconds" = "Váratlan hiba lépett fel, próbálja újra néhány másodperc múlva"; + +"Try again" = "Próbálja újra"; + +"We use Stripe to verify your card details. Stripe may use and store your data according its privacy policy. Learn more" = "A Stripe-ot használjuk a kártyájának az ellenőrzésére. A Stripe az adatvédelmi szabályzatának megfelelően használhatja és tárolhatja az Ön adatait. További tudnivalók"; + +"Your card has expired" = "A kártyája lejárt"; + +"Your card was declined" = "A kártyáját elutasítottuk"; + +"Your card's expiration month is invalid" = "Kártyájának lejárati hónapja érvénytelen"; + +"Your card's expiration year is invalid" = "A kártyája lejárati éve érvénytelen"; + +"Your card's number is invalid" = "Kártyaszáma érvénytelen"; + +"Your card's security code is invalid" = "Kártyájának biztonsági kódja érvénytelen"; + +"Your name is invalid." = "Érvénytelen név."; + +"Your payment method was declined." = "Fizetési módja elutasításra került."; diff --git a/Pods/StripeCore/StripeCore/StripeCore/Resources/Localizations/id.lproj/Localizable.strings b/Pods/StripeCore/StripeCore/StripeCore/Resources/Localizations/id.lproj/Localizable.strings new file mode 100644 index 0000000..0428f10 --- /dev/null +++ b/Pods/StripeCore/StripeCore/StripeCore/Resources/Localizations/id.lproj/Localizable.strings @@ -0,0 +1,31 @@ +"Close" = "Tutup"; + +"Scan Card" = "Pindai Kartu"; + +"Scan card" = "Pindai kartu"; + +"The IBAN you entered is invalid." = "IBAN yang Anda masukkan tidak valid."; + +"There was an error processing your card -- try again in a few seconds" = "Ada kesalahan saat memproses kartu Anda -- cobalah lagi dalam beberapa detik"; + +"There was an unexpected error -- try again in a few seconds" = "Ada kesalahan tak terduga -- cobalah lagi dalam beberapa detik"; + +"Try again" = "Coba lagi"; + +"We use Stripe to verify your card details. Stripe may use and store your data according its privacy policy. Learn more" = "Kami menggunakan Stripe untuk memverifikasi detail kartu Anda. Stripe mungkin menggunakan dan menyimpan data Anda sesuai dengan kebijakan privasi mereka. Pelajari selengkapnya"; + +"Your card has expired" = "Kartu Anda telah kedaluwarsa"; + +"Your card was declined" = "Kartu Anda ditolak"; + +"Your card's expiration month is invalid" = "Bulan kedaluwarsa kartu Anda tidak valid"; + +"Your card's expiration year is invalid" = "Tahun kedaluwarsa kartu Anda tidak valid"; + +"Your card's number is invalid" = "Nomor kartu Anda tidak valid"; + +"Your card's security code is invalid" = "Kode keamanan kartu Anda tidak valid"; + +"Your name is invalid." = "Nama Anda tidak valid."; + +"Your payment method was declined." = "Metode pembayaran Anda ditolak."; diff --git a/Pods/StripeCore/StripeCore/StripeCore/Resources/Localizations/it.lproj/Localizable.strings b/Pods/StripeCore/StripeCore/StripeCore/Resources/Localizations/it.lproj/Localizable.strings new file mode 100644 index 0000000..3e02e03 --- /dev/null +++ b/Pods/StripeCore/StripeCore/StripeCore/Resources/Localizations/it.lproj/Localizable.strings @@ -0,0 +1,31 @@ +"Close" = "Chiudi"; + +"Scan Card" = "Scansiona carta"; + +"Scan card" = "Scansiona carta"; + +"The IBAN you entered is invalid." = "L'IBAN inserito non è valido."; + +"There was an error processing your card -- try again in a few seconds" = "Si è verificato un errore durante l'elaborazione della carta. Riprova fra qualche secondo."; + +"There was an unexpected error -- try again in a few seconds" = "Si è verificato un errore imprevisto. Riprova fra qualche secondo."; + +"Try again" = "Riprova"; + +"We use Stripe to verify your card details. Stripe may use and store your data according its privacy policy. Learn more" = "Utilizziamo Stripe per verificare i dati della carta. Come stabilito nella sua informativa sulla privacy, Stripe può utilizzare e conservare i tuoi dati. Ulteriori informazioni"; + +"Your card has expired" = "La carta è scaduta"; + +"Your card was declined" = "La carta è stata rifiutata"; + +"Your card's expiration month is invalid" = "Il mese di scadenza della carta non è valido"; + +"Your card's expiration year is invalid" = "L'anno di scadenza della carta non è valido"; + +"Your card's number is invalid" = "Il numero della carta non è valido"; + +"Your card's security code is invalid" = "Il codice di sicurezza della carta non è valido"; + +"Your name is invalid." = "Nome non valido."; + +"Your payment method was declined." = "La tua modalità di pagamento è stata rifiutata."; diff --git a/Pods/StripeCore/StripeCore/StripeCore/Resources/Localizations/ja.lproj/Localizable.strings b/Pods/StripeCore/StripeCore/StripeCore/Resources/Localizations/ja.lproj/Localizable.strings new file mode 100644 index 0000000..fb79bab --- /dev/null +++ b/Pods/StripeCore/StripeCore/StripeCore/Resources/Localizations/ja.lproj/Localizable.strings @@ -0,0 +1,31 @@ +"Close" = "閉じる"; + +"Scan Card" = "クレジットカードをスキャン"; + +"Scan card" = "カードをスキャン"; + +"The IBAN you entered is invalid." = "入力した IBAN が無効です。"; + +"There was an error processing your card -- try again in a few seconds" = "クレジットカード情報の処理中にエラーが発生しました。数秒後にもう一度お試しください"; + +"There was an unexpected error -- try again in a few seconds" = "予期しないエラーが発生しました。数秒後にもう一度お試しください"; + +"Try again" = "もう一度お試しください"; + +"We use Stripe to verify your card details. Stripe may use and store your data according its privacy policy. Learn more" = "Stripe を使用してカード詳細を確認します。Stripe はプライバシーポリシーに従ってお客様のデータを使用および保管することがあります。もっと知る"; + +"Your card has expired" = "クレジットカードの有効期限が切れています"; + +"Your card was declined" = "クレジットカードが拒否されました"; + +"Your card's expiration month is invalid" = "指定したクレジットカードの有効期限の月が無効です"; + +"Your card's expiration year is invalid" = "指定したクレジットカードの有効期限の年が無効です"; + +"Your card's number is invalid" = "指定したクレジットカードの番号が無効です"; + +"Your card's security code is invalid" = "指定したクレジットカードのセキュリティコードが無効です"; + +"Your name is invalid." = "名前が無効です。"; + +"Your payment method was declined." = "お客様の支払い方法が拒否されました。"; diff --git a/Pods/StripeCore/StripeCore/StripeCore/Resources/Localizations/ko.lproj/Localizable.strings b/Pods/StripeCore/StripeCore/StripeCore/Resources/Localizations/ko.lproj/Localizable.strings new file mode 100644 index 0000000..a6316bc --- /dev/null +++ b/Pods/StripeCore/StripeCore/StripeCore/Resources/Localizations/ko.lproj/Localizable.strings @@ -0,0 +1,31 @@ +"Close" = "닫기"; + +"Scan Card" = "카드 스캔"; + +"Scan card" = "카드 스캔"; + +"The IBAN you entered is invalid." = "입력한 IBAN이 잘못되었습니다."; + +"There was an error processing your card -- try again in a few seconds" = "카드를 처리하는 동안 오류가 발생했습니다. 몇 초 후에 다시 시도하십시오."; + +"There was an unexpected error -- try again in a few seconds" = "예기치 않은 오류가 발생했습니다. 몇 초 후에 다시 시도하십시오."; + +"Try again" = "다시 시도"; + +"We use Stripe to verify your card details. Stripe may use and store your data according its privacy policy. Learn more" = "Stripe를 통해 카드 세부사항을 확인합니다. Stripe에서 자사 개인정보정책에 따라 귀하의 데이터를 사용하고 저장할 수 있습니다. 자세히 알아보기"; + +"Your card has expired" = "카드가 만료되었습니다"; + +"Your card was declined" = "카드가 거절되었습니다"; + +"Your card's expiration month is invalid" = "카드의 만료 월이 유효하지 않습니다"; + +"Your card's expiration year is invalid" = "카드의 만료 연도가 유효하지 않습니다"; + +"Your card's number is invalid" = "카드 번호가 유효하지 않습니다"; + +"Your card's security code is invalid" = "카드의 보안 코드가 유효하지 않습니다"; + +"Your name is invalid." = "이름이 잘못되었습니다."; + +"Your payment method was declined." = "결제 방식이 거부되었습니다."; diff --git a/Pods/StripeCore/StripeCore/StripeCore/Resources/Localizations/lt-LT.lproj/Localizable.strings b/Pods/StripeCore/StripeCore/StripeCore/Resources/Localizations/lt-LT.lproj/Localizable.strings new file mode 100644 index 0000000..bb550e4 --- /dev/null +++ b/Pods/StripeCore/StripeCore/StripeCore/Resources/Localizations/lt-LT.lproj/Localizable.strings @@ -0,0 +1,31 @@ +"Close" = "Užverti"; + +"Scan Card" = "Skenuoti kortelę"; + +"Scan card" = "Nuskaityti kortelę"; + +"The IBAN you entered is invalid." = "Įvedėte neteisingą IBAN."; + +"There was an error processing your card -- try again in a few seconds" = "Įvyko kortelės apdorojimo klaida, po kelių sekundžių bandykite dar kartą"; + +"There was an unexpected error -- try again in a few seconds" = "Įvyko netikėta klaida, po kelių sekundžių bandykite dar kartą"; + +"Try again" = "Bandyti dar kartą"; + +"We use Stripe to verify your card details. Stripe may use and store your data according its privacy policy. Learn more" = "Naudojame „Stripe“, kad patikrintume jūsų kortelės duomenis. „Stripe“ gali naudoti ir saugoti jūsų duomenis pagal savo privatumo politiką. Sužinokite daugiau"; + +"Your card has expired" = "Kortelė baigė galioti"; + +"Your card was declined" = "Kortelė buvo atmesta"; + +"Your card's expiration month is invalid" = "Negaliojantis kortelės galiojimo pabaigos mėnuo"; + +"Your card's expiration year is invalid" = "Kortelės galiojimo pabaigos metai neteisingi"; + +"Your card's number is invalid" = "Negaliojantis kortelės numeris"; + +"Your card's security code is invalid" = "Kortelės saugos kodas negalioja"; + +"Your name is invalid." = "Jūsų vardas neteisingas."; + +"Your payment method was declined." = "Jūsų mokėjimo būdas buvo atmestas."; diff --git a/Pods/StripeCore/StripeCore/StripeCore/Resources/Localizations/lv-LV.lproj/Localizable.strings b/Pods/StripeCore/StripeCore/StripeCore/Resources/Localizations/lv-LV.lproj/Localizable.strings new file mode 100644 index 0000000..36620f2 --- /dev/null +++ b/Pods/StripeCore/StripeCore/StripeCore/Resources/Localizations/lv-LV.lproj/Localizable.strings @@ -0,0 +1,31 @@ +"Close" = "Aizvērt"; + +"Scan Card" = "Skenēt karti"; + +"Scan card" = "Skenēt karti"; + +"The IBAN you entered is invalid." = "Ievadītais IBAN nav derīgs."; + +"There was an error processing your card -- try again in a few seconds" = "Radās kļūda, apstrādājot jūsu karti — mēģiniet vēlreiz pēc dažām sekundēm"; + +"There was an unexpected error -- try again in a few seconds" = "Radusies negaidīta kļūda — mēģiniet vēlreiz pēc dažām sekundēm"; + +"Try again" = "Mēģināt vēlreiz"; + +"We use Stripe to verify your card details. Stripe may use and store your data according its privacy policy. Learn more" = "Mēs izmantojam Stripe, lai verificētu jūsu kartes informāciju. Stripe var izmantot un uzglabāt jūsu datus saskaņā ar konfidencialitātes politiku. Uzzināt vairāk"; + +"Your card has expired" = "Kartes derīguma termiņš ir beidzies"; + +"Your card was declined" = "Karte tika noraidīta"; + +"Your card's expiration month is invalid" = "Kartes derīguma termiņa mēnesis nav derīgs"; + +"Your card's expiration year is invalid" = "Kartes derīguma termiņa gads nav derīgs"; + +"Your card's number is invalid" = "Kartes numurs nav derīgs"; + +"Your card's security code is invalid" = "Kartes drošības kods nav derīgs"; + +"Your name is invalid." = "Jūsu vārds nav derīgs."; + +"Your payment method was declined." = "Maksājuma veids tika noraidīts."; diff --git a/Pods/StripeCore/StripeCore/StripeCore/Resources/Localizations/ms-MY.lproj/Localizable.strings b/Pods/StripeCore/StripeCore/StripeCore/Resources/Localizations/ms-MY.lproj/Localizable.strings new file mode 100644 index 0000000..573cdc0 --- /dev/null +++ b/Pods/StripeCore/StripeCore/StripeCore/Resources/Localizations/ms-MY.lproj/Localizable.strings @@ -0,0 +1,31 @@ +"Close" = "Tutup"; + +"Scan Card" = "Imbas Kad"; + +"Scan card" = "Imbas kad"; + +"The IBAN you entered is invalid." = "IBAN yang anda masukkan tidak sah."; + +"There was an error processing your card -- try again in a few seconds" = "Ada ralat semasa memproses kad anda -- cuba lagi dalam masa beberapa saat"; + +"There was an unexpected error -- try again in a few seconds" = "Ada ralat yang tidak dijangka -- cuba lagi dalam masa beberapa saat"; + +"Try again" = "Cuba lagi"; + +"We use Stripe to verify your card details. Stripe may use and store your data according its privacy policy. Learn more" = "Kami menggunakan Stripe untuk mengesahkan butiran kad anda. Stripe mungkin menggunakan dan menyimpan data anda menurut dasar privasi Stripe. Ketahui selanjutnya"; + +"Your card has expired" = "Kad anda telah tamat tempoh"; + +"Your card was declined" = "Kad anda telah ditolak"; + +"Your card's expiration month is invalid" = "Bulan tamat tempoh kad anda tidak sah"; + +"Your card's expiration year is invalid" = "Tahun tamat tempoh kad anda tidak sah"; + +"Your card's number is invalid" = "Nombor kad anda tidak sah"; + +"Your card's security code is invalid" = "Kod keselamatan kad anda tidak sah"; + +"Your name is invalid." = "Nama anda tidak sah."; + +"Your payment method was declined." = "Kaedah pembayaran anda ditolak."; diff --git a/Pods/StripeCore/StripeCore/StripeCore/Resources/Localizations/mt.lproj/Localizable.strings b/Pods/StripeCore/StripeCore/StripeCore/Resources/Localizations/mt.lproj/Localizable.strings new file mode 100644 index 0000000..546deb9 --- /dev/null +++ b/Pods/StripeCore/StripeCore/StripeCore/Resources/Localizations/mt.lproj/Localizable.strings @@ -0,0 +1,31 @@ +"Close" = "Agħlaq"; + +"Scan Card" = "Skennja l-Kard"; + +"Scan card" = "Skennja l-karta"; + +"The IBAN you entered is invalid." = "L-IBAN li daħħalt mhux tajjeb."; + +"There was an error processing your card -- try again in a few seconds" = "Kien hemm żball fl-ipproċessar tal-kard tiegħek -- erġa' pprova wara ftit sekondi"; + +"There was an unexpected error -- try again in a few seconds" = "Kien hemm żball mhux mistenni -- erġa' pprova wara ftit sekondi"; + +"Try again" = "Erġa' pprova"; + +"We use Stripe to verify your card details. Stripe may use and store your data according its privacy policy. Learn more" = "Aħna naħdmu ma' Stripe biex nivverifikaw id-dettalji tal-karta tiegħek. Stripe tista' tuża u taħżen id-dejta tiegħek skont il-politika tal-privatezza tagħha. Sir af iktar"; + +"Your card has expired" = "Il-kard tiegħek skadiet"; + +"Your card was declined" = "Il-kard tiegħek ma ġietx aċċettata"; + +"Your card's expiration month is invalid" = "Ix-xahar tal-iskadenza tal-kard tiegħek mhux validu"; + +"Your card's expiration year is invalid" = "Is-sena tal-iskadenza tal-kard tiegħek mhijiex valida"; + +"Your card's number is invalid" = "In-numru tal-kard tiegħek mhux validu"; + +"Your card's security code is invalid" = "Il-kodiċi tas-sigurtà tal-kard tiegħek mhux validu"; + +"Your name is invalid." = "L-isem li daħħalt mhux tajjeb."; + +"Your payment method was declined." = "Il-metodu tal-pagament tiegħek m'għaddiex."; diff --git a/Pods/StripeCore/StripeCore/StripeCore/Resources/Localizations/nb.lproj/Localizable.strings b/Pods/StripeCore/StripeCore/StripeCore/Resources/Localizations/nb.lproj/Localizable.strings new file mode 100644 index 0000000..af0a3a1 --- /dev/null +++ b/Pods/StripeCore/StripeCore/StripeCore/Resources/Localizations/nb.lproj/Localizable.strings @@ -0,0 +1,31 @@ +"Close" = "Lukk"; + +"Scan Card" = "Skann kort"; + +"Scan card" = "Skann kort"; + +"The IBAN you entered is invalid." = "IBAN-nummeret du la inn er ugyldig."; + +"There was an error processing your card -- try again in a few seconds" = "Det oppstod en feil ved prosessering av kortet -- prøv igjen om et par sekunder"; + +"There was an unexpected error -- try again in a few seconds" = "En uventet feil har oppstått -- prøv igjen om et par sekunder"; + +"Try again" = "Prøv igjen"; + +"We use Stripe to verify your card details. Stripe may use and store your data according its privacy policy. Learn more" = "Vi bruker Stripe til å verifisere kontoopplysningene. Stripe kan bruke og lagre opplysningene dine i henhold til personvernerklæringen sin. Finn ut mer"; + +"Your card has expired" = "Kortet ditt har utløpt"; + +"Your card was declined" = "Kortet ditt ble avvist"; + +"Your card's expiration month is invalid" = "Kortet sin utløpsmåned er ugyldig"; + +"Your card's expiration year is invalid" = "Kortet sitt utløpsår er ugyldig"; + +"Your card's number is invalid" = "Ugyldig kortnummer"; + +"Your card's security code is invalid" = "Ugyldig sikkerhetskode"; + +"Your name is invalid." = "Navnet er ugyldig."; + +"Your payment method was declined." = "Betalingsmetoden din ble avvist."; diff --git a/Pods/StripeCore/StripeCore/StripeCore/Resources/Localizations/nl.lproj/Localizable.strings b/Pods/StripeCore/StripeCore/StripeCore/Resources/Localizations/nl.lproj/Localizable.strings new file mode 100644 index 0000000..43792e4 --- /dev/null +++ b/Pods/StripeCore/StripeCore/StripeCore/Resources/Localizations/nl.lproj/Localizable.strings @@ -0,0 +1,31 @@ +"Close" = "Sluiten"; + +"Scan Card" = "Kaart scannen"; + +"Scan card" = "Betaalkaart scannen"; + +"The IBAN you entered is invalid." = "Het opgegeven IBAN-nummer is ongeldig."; + +"There was an error processing your card -- try again in a few seconds" = "Er is een fout met de verwerking van je kaart. Probeer het over enkele seconden opnieuw"; + +"There was an unexpected error -- try again in a few seconds" = "Er is een onverwachte fout opgetreden. Probeer het over enkele seconden opnieuw"; + +"Try again" = "Opnieuw proberen"; + +"We use Stripe to verify your card details. Stripe may use and store your data according its privacy policy. Learn more" = "We gebruiken Stripe om je kaartgegevens te verifiëren. Stripe kan je gegevens gebruiken en bewaren volgens hun privacybeleid. Meer informatie"; + +"Your card has expired" = "Je kaart is vervallen"; + +"Your card was declined" = "Je kaart is geweigerd"; + +"Your card's expiration month is invalid" = "De vervalmaand van je kaart is ongeldig"; + +"Your card's expiration year is invalid" = "Het vervaljaar van je kaart is ongeldig"; + +"Your card's number is invalid" = "Je kaartnummer is ongeldig"; + +"Your card's security code is invalid" = "De beveiligingscode van je kaart is ongeldig"; + +"Your name is invalid." = "Je naam is ongeldig."; + +"Your payment method was declined." = "Je betaalmethode is geweigerd."; diff --git a/Pods/StripeCore/StripeCore/StripeCore/Resources/Localizations/nn-NO.lproj/Localizable.strings b/Pods/StripeCore/StripeCore/StripeCore/Resources/Localizations/nn-NO.lproj/Localizable.strings new file mode 100644 index 0000000..70d88ad --- /dev/null +++ b/Pods/StripeCore/StripeCore/StripeCore/Resources/Localizations/nn-NO.lproj/Localizable.strings @@ -0,0 +1,31 @@ +"Close" = "Lukk"; + +"Scan Card" = "Skann kortet"; + +"Scan card" = "Skann kort"; + +"The IBAN you entered is invalid." = "Du skreiv inn eit ugyldig IBAN-nummer."; + +"There was an error processing your card -- try again in a few seconds" = "Det oppstod ei feil under behandlinga av kortet – prøv igjen om nokre få sekund"; + +"There was an unexpected error -- try again in a few seconds" = "Det oppstod ein uventa feil – prøv igjen om nokre få sekund"; + +"Try again" = "Prøv igjen"; + +"We use Stripe to verify your card details. Stripe may use and store your data according its privacy policy. Learn more" = "Vi brukar Stripe til å verifisere kortdetaljane dine. Stripe kan bruke og lagre dataa dine i samsvar med personvernerklæringa deira. Finn ut meir"; + +"Your card has expired" = "Kortet har gått ut"; + +"Your card was declined" = "Kortet vart avvist"; + +"Your card's expiration month is invalid" = "Utløpsmånaden på kortet er ugyldig"; + +"Your card's expiration year is invalid" = "Utløpsåret på kortet ditt er ugyldig"; + +"Your card's number is invalid" = "Kortnummeret ditt er ugyldig"; + +"Your card's security code is invalid" = "Sikkerheitskoden til kortet er ugyldig"; + +"Your name is invalid." = "Namnet ditt er ugyldig."; + +"Your payment method was declined." = "Betalingsmåten din vart avvist."; diff --git a/Pods/StripeCore/StripeCore/StripeCore/Resources/Localizations/pl-PL.lproj/Localizable.strings b/Pods/StripeCore/StripeCore/StripeCore/Resources/Localizations/pl-PL.lproj/Localizable.strings new file mode 100644 index 0000000..7502f7e --- /dev/null +++ b/Pods/StripeCore/StripeCore/StripeCore/Resources/Localizations/pl-PL.lproj/Localizable.strings @@ -0,0 +1,31 @@ +"Close" = "Zamknij"; + +"Scan Card" = "Skanuj kartę"; + +"Scan card" = "Skanuj kartę"; + +"The IBAN you entered is invalid." = "Podany IBAN jest nieprawidłowy."; + +"There was an error processing your card -- try again in a few seconds" = "Podczas przetwarzania Twojej karty wystąpił błąd – spróbuj ponownie za kilka sekund"; + +"There was an unexpected error -- try again in a few seconds" = "Wystąpił nieoczekiwany błąd – spróbuj ponownie za kilka sekund"; + +"Try again" = "Spróbuj ponownie"; + +"We use Stripe to verify your card details. Stripe may use and store your data according its privacy policy. Learn more" = "Korzystamy ze Stripe, aby weryfikować szczegóły Twojej karty. Stripe może używać Twoich danych i przechowywać je zgodnie ze swoją polityką prywatności. Dowiedz się więcej"; + +"Your card has expired" = "Ważność Twojej karty wygasła"; + +"Your card was declined" = "Karta została odrzucona"; + +"Your card's expiration month is invalid" = "Miesiąc daty ważności karty jest nieprawidłowy."; + +"Your card's expiration year is invalid" = "Rok daty ważności karty jest nieprawidłowy"; + +"Your card's number is invalid" = "Numer Twojej karty jest nieprawidłowy"; + +"Your card's security code is invalid" = "Kod bezpieczeństwa karty jest nieprawidłowy"; + +"Your name is invalid." = "Twoje imię i nazwisko jest nieprawidłowe."; + +"Your payment method was declined." = "Twoja metoda płatności została odrzucona."; diff --git a/Pods/StripeCore/StripeCore/StripeCore/Resources/Localizations/pt-BR.lproj/Localizable.strings b/Pods/StripeCore/StripeCore/StripeCore/Resources/Localizations/pt-BR.lproj/Localizable.strings new file mode 100644 index 0000000..4cede82 --- /dev/null +++ b/Pods/StripeCore/StripeCore/StripeCore/Resources/Localizations/pt-BR.lproj/Localizable.strings @@ -0,0 +1,31 @@ +"Close" = "Fechar"; + +"Scan Card" = "Digitalizar cartão"; + +"Scan card" = "Ler cartão"; + +"The IBAN you entered is invalid." = "O IBAN inserido é inválido."; + +"There was an error processing your card -- try again in a few seconds" = "Erro ao processar o cartão – tente novamente em alguns segundos"; + +"There was an unexpected error -- try again in a few seconds" = "Erro inesperado – tente novamente em alguns segundos"; + +"Try again" = "Tentar novamente"; + +"We use Stripe to verify your card details. Stripe may use and store your data according its privacy policy. Learn more" = "Usamos a Stripe para verificar os dados do seu cartão. A Stripe pode usar e armazenar seus dados de acordo com a política de privacidade da empresa. Saiba mais"; + +"Your card has expired" = "O cartão expirou"; + +"Your card was declined" = "O cartão foi recusado"; + +"Your card's expiration month is invalid" = "O mês de expiração doi cartão é inválido"; + +"Your card's expiration year is invalid" = "O ano de expiração do cartão é inválido"; + +"Your card's number is invalid" = "O número do cartão é inválido"; + +"Your card's security code is invalid" = "O código de segurança do cartão é inválido"; + +"Your name is invalid." = "Nome inválido."; + +"Your payment method was declined." = "A forma de pagamento foi recusada."; diff --git a/Pods/StripeCore/StripeCore/StripeCore/Resources/Localizations/pt-PT.lproj/Localizable.strings b/Pods/StripeCore/StripeCore/StripeCore/Resources/Localizations/pt-PT.lproj/Localizable.strings new file mode 100644 index 0000000..ee185d0 --- /dev/null +++ b/Pods/StripeCore/StripeCore/StripeCore/Resources/Localizations/pt-PT.lproj/Localizable.strings @@ -0,0 +1,31 @@ +"Close" = "Fechar"; + +"Scan Card" = "Ler cartão"; + +"Scan card" = "Ler cartão"; + +"The IBAN you entered is invalid." = "O IBAN que introduziu é inválido."; + +"There was an error processing your card -- try again in a few seconds" = "Ocorreu um erro ao processar o seu cartão -- tente novamente dentro de alguns segundos"; + +"There was an unexpected error -- try again in a few seconds" = "Ocorreu um erro inesperado -- tente novamente dentro de alguns segundos"; + +"Try again" = "Tentar novamente"; + +"We use Stripe to verify your card details. Stripe may use and store your data according its privacy policy. Learn more" = "Utilizamos a Stripe para verificar os detalhes do seu cartão. A Stripe pode utilizar e armazenar os seus dados de acordo com a sua política de privacidade. Saiba mais"; + +"Your card has expired" = "O seu cartão expirou"; + +"Your card was declined" = "O seu cartão foi recusado"; + +"Your card's expiration month is invalid" = "O mês de validade do seu cartão é inválido"; + +"Your card's expiration year is invalid" = "O ano de validade do seu cartão é inválido"; + +"Your card's number is invalid" = "O número do seu cartão é inválido"; + +"Your card's security code is invalid" = "O código de segurança do seu cartão é inválido"; + +"Your name is invalid." = "O seu nome é inválido."; + +"Your payment method was declined." = "O seu método de pagamento foi recusado."; diff --git a/Pods/StripeCore/StripeCore/StripeCore/Resources/Localizations/ro-RO.lproj/Localizable.strings b/Pods/StripeCore/StripeCore/StripeCore/Resources/Localizations/ro-RO.lproj/Localizable.strings new file mode 100644 index 0000000..c0ddbdc --- /dev/null +++ b/Pods/StripeCore/StripeCore/StripeCore/Resources/Localizations/ro-RO.lproj/Localizable.strings @@ -0,0 +1,31 @@ +"Close" = "Închidere"; + +"Scan Card" = "Scanare card"; + +"Scan card" = "Scanare card"; + +"The IBAN you entered is invalid." = "Codul IBAN pe care l-ați introdus nu este valid."; + +"There was an error processing your card -- try again in a few seconds" = "A apărut o eroare la procesarea cardului dvs. -- încercați din nou în câteva secunde"; + +"There was an unexpected error -- try again in a few seconds" = "A apărut o eroare neașteptată -- încercați din nou în câteva secunde"; + +"Try again" = "Încercați din nou"; + +"We use Stripe to verify your card details. Stripe may use and store your data according its privacy policy. Learn more" = "Folosim Stripe pentru a verifica detaliile cardului dvs. Stripe poate utiliza și stoca datele dvs. în conformitate cu politica sa de confidențialitate. Aflați mai multe"; + +"Your card has expired" = "Cardul dvs. a expirat"; + +"Your card was declined" = "Cardul dvs. a fost respins"; + +"Your card's expiration month is invalid" = "Luna de expirare a cardului dvs. nu este validă"; + +"Your card's expiration year is invalid" = "Anul de expirare al cardului dvs. nu este valid"; + +"Your card's number is invalid" = "Numărul cardului dvs. nu este valid"; + +"Your card's security code is invalid" = "Codul de securitate al cardului dvs. nu este valid"; + +"Your name is invalid." = "Numele dvs. nu este valid."; + +"Your payment method was declined." = "Metoda dvs. de plată a fost respinsă."; diff --git a/Pods/StripeCore/StripeCore/StripeCore/Resources/Localizations/ru.lproj/Localizable.strings b/Pods/StripeCore/StripeCore/StripeCore/Resources/Localizations/ru.lproj/Localizable.strings new file mode 100644 index 0000000..3face22 --- /dev/null +++ b/Pods/StripeCore/StripeCore/StripeCore/Resources/Localizations/ru.lproj/Localizable.strings @@ -0,0 +1,31 @@ +"Close" = "Закрыть"; + +"Scan Card" = "Сканировать карту"; + +"Scan card" = "Сканировать карту"; + +"The IBAN you entered is invalid." = "Введенный код IBAN содержит ошибку."; + +"There was an error processing your card -- try again in a few seconds" = "При обработке карты произошла ошибка. Подождите несколько секунд и повторите попытку"; + +"There was an unexpected error -- try again in a few seconds" = "Произошла непредвиденная ошибка. Подождите несколько секунд и повторите попытку."; + +"Try again" = "Повторите попытку"; + +"We use Stripe to verify your card details. Stripe may use and store your data according its privacy policy. Learn more" = "Мы используем Stripe для проверки данных вашей карты. Stripe может использовать и хранить ваши данные в соответствии со своей политикой конфиденциальности. Подробнее"; + +"Your card has expired" = "Срок действия карты истек"; + +"Your card was declined" = "Карта отклонена"; + +"Your card's expiration month is invalid" = "Недопустимый месяц окончания действия карты"; + +"Your card's expiration year is invalid" = "Недопустимый год окончания действия карты"; + +"Your card's number is invalid" = "Номер карты недействителен"; + +"Your card's security code is invalid" = "Недопустимый код CVV/CVC карты"; + +"Your name is invalid." = "Недействительное имя."; + +"Your payment method was declined." = "Не удалось выполнить оплату этим способом."; diff --git a/Pods/StripeCore/StripeCore/StripeCore/Resources/Localizations/sk-SK.lproj/Localizable.strings b/Pods/StripeCore/StripeCore/StripeCore/Resources/Localizations/sk-SK.lproj/Localizable.strings new file mode 100644 index 0000000..b0d16f1 --- /dev/null +++ b/Pods/StripeCore/StripeCore/StripeCore/Resources/Localizations/sk-SK.lproj/Localizable.strings @@ -0,0 +1,31 @@ +"Close" = "Zatvoriť"; + +"Scan Card" = "Naskenovať kartu"; + +"Scan card" = "Naskenovať kartu"; + +"The IBAN you entered is invalid." = "Zadaný IBAN je neplatný."; + +"There was an error processing your card -- try again in a few seconds" = "Pri spracovaní vašej karty sa vyskytla chyba -- skúste znova o niekoľko sekúnd"; + +"There was an unexpected error -- try again in a few seconds" = "Vyskytla sa neočakávaná chyba -- skúste znova o niekoľko sekúnd"; + +"Try again" = "Skúsiť znova"; + +"We use Stripe to verify your card details. Stripe may use and store your data according its privacy policy. Learn more" = "Na overenie údajov o vašej karte používame službu Stripe. Spoločnosť Stripe môže používať a uchovávať vaše údaje v súlade so zásadami ochrany osobných údajov. Ďalšie informácie"; + +"Your card has expired" = "Platnosť vašej karty vypršala"; + +"Your card was declined" = "Vaša karta bola odmietnutá"; + +"Your card's expiration month is invalid" = "Mesiac ukončenia platnosti vašej karty je neplatný"; + +"Your card's expiration year is invalid" = "Rok ukončenia platnosti vašej karty je neplatný"; + +"Your card's number is invalid" = "Číslo vašej karty je neplatné"; + +"Your card's security code is invalid" = "Bezpečnostný kód vašej karty je neplatný"; + +"Your name is invalid." = "Vaše meno je neplatné."; + +"Your payment method was declined." = "Váš spôsob platby bol odmietnutý."; diff --git a/Pods/StripeCore/StripeCore/StripeCore/Resources/Localizations/sl-SI.lproj/Localizable.strings b/Pods/StripeCore/StripeCore/StripeCore/Resources/Localizations/sl-SI.lproj/Localizable.strings new file mode 100644 index 0000000..fb120e8 --- /dev/null +++ b/Pods/StripeCore/StripeCore/StripeCore/Resources/Localizations/sl-SI.lproj/Localizable.strings @@ -0,0 +1,31 @@ +"Close" = "Zapri"; + +"Scan Card" = "Optično preberi kartico"; + +"Scan card" = "Optično preberi kartico"; + +"The IBAN you entered is invalid." = "Vnesena koda IBAN ni veljavna."; + +"There was an error processing your card -- try again in a few seconds" = "Pri obdelavi vaše kartice je prišlo do napake. Poskusite znova čez nekaj sekund."; + +"There was an unexpected error -- try again in a few seconds" = "Prišlo je do nepričakovane napake. Poskusite znova čez nekaj sekund."; + +"Try again" = "Poskusi znova"; + +"We use Stripe to verify your card details. Stripe may use and store your data according its privacy policy. Learn more" = "Za preverjanje podatkov o vaši kartici uporabljamo storitev Stripe. Stripe lahko vaše podatke uporablja in hrani v skladu s svojim pravilnikom o zasebnosti. Več informacij"; + +"Your card has expired" = "Vaša kartica je potekla"; + +"Your card was declined" = "Vaša kartica je bila zavrnjena"; + +"Your card's expiration month is invalid" = "Mesec poteka vaše kartice ni veljaven"; + +"Your card's expiration year is invalid" = "Leto poteka vaše kartice ni veljavno"; + +"Your card's number is invalid" = "Številka vaše kartice ni veljavna"; + +"Your card's security code is invalid" = "Varnostna koda vaše kartice ni veljavna"; + +"Your name is invalid." = "Vaše ime ni veljavno."; + +"Your payment method was declined." = "Vaš način plačila je bil zavrnjen."; diff --git a/Pods/StripeCore/StripeCore/StripeCore/Resources/Localizations/sv.lproj/Localizable.strings b/Pods/StripeCore/StripeCore/StripeCore/Resources/Localizations/sv.lproj/Localizable.strings new file mode 100644 index 0000000..46080f5 --- /dev/null +++ b/Pods/StripeCore/StripeCore/StripeCore/Resources/Localizations/sv.lproj/Localizable.strings @@ -0,0 +1,31 @@ +"Close" = "Stäng"; + +"Scan Card" = "Skanna kort"; + +"Scan card" = "Skanna kort"; + +"The IBAN you entered is invalid." = "Angivet IBAN är ogiltigt."; + +"There was an error processing your card -- try again in a few seconds" = "Ett fel uppstod vid behandlingen av ditt kort - försök igen om ett par sekunder"; + +"There was an unexpected error -- try again in a few seconds" = "Ett oväntat fel uppstod - försök igen om ett par sekunder"; + +"Try again" = "Försök igen"; + +"We use Stripe to verify your card details. Stripe may use and store your data according its privacy policy. Learn more" = "Vi använder Stripe för att verifiera dina kortuppgifter. Stripe kan komma att använda och lagra dina uppgifter i enlighet med sin integritetspolicy. Läs mer"; + +"Your card has expired" = "Kortet har löpt ut"; + +"Your card was declined" = "Ditt kort nekades"; + +"Your card's expiration month is invalid" = "Kortets utgångsmånad är ogiltig"; + +"Your card's expiration year is invalid" = "Kortets utgångsår är ogiltigt"; + +"Your card's number is invalid" = "Kortnumret är ogiltigt"; + +"Your card's security code is invalid" = "Kortets säkerhetskod är ogiltig"; + +"Your name is invalid." = "Ditt namn är ogiltigt."; + +"Your payment method was declined." = "Din betalningsmetod godkändes inte."; diff --git a/Pods/StripeCore/StripeCore/StripeCore/Resources/Localizations/tr.lproj/Localizable.strings b/Pods/StripeCore/StripeCore/StripeCore/Resources/Localizations/tr.lproj/Localizable.strings new file mode 100644 index 0000000..362d4dc --- /dev/null +++ b/Pods/StripeCore/StripeCore/StripeCore/Resources/Localizations/tr.lproj/Localizable.strings @@ -0,0 +1,31 @@ +"Close" = "Kapat"; + +"Scan Card" = "Kartı Tara"; + +"Scan card" = "Kartı tara"; + +"The IBAN you entered is invalid." = "Girdiğiniz IBAN geçersiz."; + +"There was an error processing your card -- try again in a few seconds" = "Kartınızla işlem yapılırken bir hata oluştu -- birazdan tekrar deneyin"; + +"There was an unexpected error -- try again in a few seconds" = "Beklenmedik bir hata oluştu -- birazdan tekrar deneyin"; + +"Try again" = "Tekrar dene"; + +"We use Stripe to verify your card details. Stripe may use and store your data according its privacy policy. Learn more" = "Kart bilgilerinizi doğrulamak için Stripe kullanıyoruz. Stripe verilerinizi gizlilik politikasına uygun şekilde kullanabilir ve saklayabilir.Daha fazlasını öğrenin"; + +"Your card has expired" = "Kartınızın kullanım süresi dolmuş"; + +"Your card was declined" = "Kartınız reddedildi"; + +"Your card's expiration month is invalid" = "Kartınızın son kullanma ayı geçersiz"; + +"Your card's expiration year is invalid" = "Kartınızın son kullanma yılı geçersiz"; + +"Your card's number is invalid" = "Kart numaranız geçersiz"; + +"Your card's security code is invalid" = "Kartınızın güvenlik kodu geçersiz"; + +"Your name is invalid." = "Adınız geçersiz."; + +"Your payment method was declined." = "Ödeme yönteminiz reddedildi."; diff --git a/Pods/StripeCore/StripeCore/StripeCore/Resources/Localizations/vi.lproj/Localizable.strings b/Pods/StripeCore/StripeCore/StripeCore/Resources/Localizations/vi.lproj/Localizable.strings new file mode 100644 index 0000000..964581a --- /dev/null +++ b/Pods/StripeCore/StripeCore/StripeCore/Resources/Localizations/vi.lproj/Localizable.strings @@ -0,0 +1,31 @@ +"Close" = "Đóng"; + +"Scan Card" = "Quét thẻ"; + +"Scan card" = "Quét thẻ"; + +"The IBAN you entered is invalid." = "IBAN quý vị đã nhập không hợp lệ."; + +"There was an error processing your card -- try again in a few seconds" = "Có lỗi bất ngờ khi xử lý thẻ -- hãy thử lại sau vài giây"; + +"There was an unexpected error -- try again in a few seconds" = "Có lỗi bất ngờ -- hãy thử lại sau vài giây"; + +"Try again" = "Thử lại"; + +"We use Stripe to verify your card details. Stripe may use and store your data according its privacy policy. Learn more" = "Chúng tôi sử dụng Stripe để xác minh chi tiết thẻ của bạn. Stripe có thể sử dụng và lưu trữ dữ liệu của bạn theo chính sách quyền riêng tư của họ. Tìm hiểu thêm"; + +"Your card has expired" = "Thẻ đã hết hạn"; + +"Your card was declined" = "Thẻ bị từ chối"; + +"Your card's expiration month is invalid" = "Tháng hết hạn trên thẻ không hợp lệ"; + +"Your card's expiration year is invalid" = "Năm hết hạn trên thẻ không hợp lệ"; + +"Your card's number is invalid" = "Số thẻ không đúng"; + +"Your card's security code is invalid" = "Mã bảo mật của thẻ không đúng"; + +"Your name is invalid." = "Tên của quý vị không hợp lệ."; + +"Your payment method was declined." = "Phương thức thanh toán của quý vị đã bị từ chối."; diff --git a/Pods/StripeCore/StripeCore/StripeCore/Resources/Localizations/zh-HK.lproj/Localizable.strings b/Pods/StripeCore/StripeCore/StripeCore/Resources/Localizations/zh-HK.lproj/Localizable.strings new file mode 100644 index 0000000..4fab6a8 --- /dev/null +++ b/Pods/StripeCore/StripeCore/StripeCore/Resources/Localizations/zh-HK.lproj/Localizable.strings @@ -0,0 +1,31 @@ +"Close" = "關閉"; + +"Scan Card" = "掃描銀行卡"; + +"Scan card" = "掃描卡"; + +"The IBAN you entered is invalid." = "您輸入的 IBAN 無效。"; + +"There was an error processing your card -- try again in a few seconds" = "處理您的卡時發生了錯誤 -- 請稍候再試"; + +"There was an unexpected error -- try again in a few seconds" = "發生了意外錯誤 -- 請稍候再試"; + +"Try again" = "重試"; + +"We use Stripe to verify your card details. Stripe may use and store your data according its privacy policy. Learn more" = "我們用 Stripe 來驗證您的銀行卡資訊。Stripe 可能會根據其私隱政策使用並存儲您的資料。瞭解更多"; + +"Your card has expired" = "您的卡已過期"; + +"Your card was declined" = "您的卡已被拒絕"; + +"Your card's expiration month is invalid" = "您的銀行卡的到期月份無效"; + +"Your card's expiration year is invalid" = "您的銀行卡的到期年份無效"; + +"Your card's number is invalid" = "您的卡號無效"; + +"Your card's security code is invalid" = "您的銀行卡的安全碼無效"; + +"Your name is invalid." = "您的姓名無效。"; + +"Your payment method was declined." = "您的支付方式被拒絕了。"; diff --git a/Pods/StripeCore/StripeCore/StripeCore/Resources/Localizations/zh-Hans.lproj/Localizable.strings b/Pods/StripeCore/StripeCore/StripeCore/Resources/Localizations/zh-Hans.lproj/Localizable.strings new file mode 100644 index 0000000..649e72b --- /dev/null +++ b/Pods/StripeCore/StripeCore/StripeCore/Resources/Localizations/zh-Hans.lproj/Localizable.strings @@ -0,0 +1,31 @@ +"Close" = "关闭"; + +"Scan Card" = "扫描银行卡"; + +"Scan card" = "扫描卡"; + +"The IBAN you entered is invalid." = "您输入的 IBAN 无效。"; + +"There was an error processing your card -- try again in a few seconds" = "处理您的卡时发生错误 —— 请稍后再试"; + +"There was an unexpected error -- try again in a few seconds" = "发生了意外错误 —— 请过几秒钟再试"; + +"Try again" = "重试"; + +"We use Stripe to verify your card details. Stripe may use and store your data according its privacy policy. Learn more" = "我们用 Stripe 来验证您的银行卡信息。Stripe 可能会根据其隐私政策使用并存储您的数据。了解更多"; + +"Your card has expired" = "您的银行卡已过期"; + +"Your card was declined" = "您的卡已被拒绝"; + +"Your card's expiration month is invalid" = "您银行卡有效期的月份无效"; + +"Your card's expiration year is invalid" = "您的银行卡的到期年份无效。"; + +"Your card's number is invalid" = "您的卡号无效"; + +"Your card's security code is invalid" = "您的银行卡的安全码无效"; + +"Your name is invalid." = "您的姓名无效。"; + +"Your payment method was declined." = "您的支付方式被拒绝了。"; diff --git a/Pods/StripeCore/StripeCore/StripeCore/Resources/Localizations/zh-Hant.lproj/Localizable.strings b/Pods/StripeCore/StripeCore/StripeCore/Resources/Localizations/zh-Hant.lproj/Localizable.strings new file mode 100644 index 0000000..4ae13cc --- /dev/null +++ b/Pods/StripeCore/StripeCore/StripeCore/Resources/Localizations/zh-Hant.lproj/Localizable.strings @@ -0,0 +1,31 @@ +"Close" = "關閉"; + +"Scan Card" = "掃描金融卡"; + +"Scan card" = "掃描卡"; + +"The IBAN you entered is invalid." = "您輸入的 IBAN 無效。"; + +"There was an error processing your card -- try again in a few seconds" = "處理您的卡時發生錯誤 -- 請等待幾秒後再試"; + +"There was an unexpected error -- try again in a few seconds" = "發生了意外錯誤 -- 請等待幾秒後再試一次"; + +"Try again" = "重試"; + +"We use Stripe to verify your card details. Stripe may use and store your data according its privacy policy. Learn more" = "我們用 Stripe 來驗證您的金融卡資訊。Stripe 可能會根據其隱私政策使用並存儲您的資料。瞭解更多"; + +"Your card has expired" = "您的卡已過期"; + +"Your card was declined" = "您的卡已被拒絕"; + +"Your card's expiration month is invalid" = "您的金融卡的到期月份無效"; + +"Your card's expiration year is invalid" = "您的金融卡的到期年份無效"; + +"Your card's number is invalid" = "您的卡號無效"; + +"Your card's security code is invalid" = "您的金融卡的安全碼無效"; + +"Your name is invalid." = "您的名稱無效。"; + +"Your payment method was declined." = "您的支付方式被拒絕了。"; diff --git a/Pods/StripeCore/StripeCore/StripeCore/Source/API Bindings/Models/EmptyResponse.swift b/Pods/StripeCore/StripeCore/StripeCore/Source/API Bindings/Models/EmptyResponse.swift new file mode 100644 index 0000000..a0da190 --- /dev/null +++ b/Pods/StripeCore/StripeCore/StripeCore/Source/API Bindings/Models/EmptyResponse.swift @@ -0,0 +1,14 @@ +// +// EmptyResponse.swift +// StripeCore +// +// Created by Jaime Park on 11/19/21. +// Copyright © 2021 Stripe, Inc. All rights reserved. +// + +import Foundation + +/// This is an object representing an empty response from a request. +@_spi(STP) public struct EmptyResponse: UnknownFieldsDecodable { + public var _allResponseFieldsStorage: NonEncodableParameters? +} diff --git a/Pods/StripeCore/StripeCore/StripeCore/Source/API Bindings/Models/StripeFile.swift b/Pods/StripeCore/StripeCore/StripeCore/Source/API Bindings/Models/StripeFile.swift new file mode 100644 index 0000000..49a625f --- /dev/null +++ b/Pods/StripeCore/StripeCore/StripeCore/Source/API Bindings/Models/StripeFile.swift @@ -0,0 +1,45 @@ +// +// StripeFile.swift +// +// Generated by swagger-codegen +// https://github.com/swagger-api/swagger-codegen +// + +import Foundation + +/// This is an object representing a file hosted on Stripe's servers. +/// +/// The file may have been uploaded by yourself using the +/// [create file](https://stripe.com/docs/api#create_file) request +/// (for example, when uploading dispute evidence) or it may have been created by Stripe +/// (for example, the results of a [Sigma scheduled query](#scheduled_queries)). +/// Related guide: [File Upload Guide](https://stripe.com/docs/file-upload). +@_spi(STP) public struct StripeFile: UnknownFieldsDecodable, Equatable { + @frozen public enum Purpose: String, SafeEnumCodable, Equatable { + // NOTE: If adding cases here that should also be available to the + // public API, please also add to `STPFilePurpose`. This is not + // necessary for cases that are only used internally. + + /// Dispute evidence file. + case disputeEvidence = "dispute_evidence" + /// Identity document file. + case identityDocument = "identity_document" + /// Identity document file used only internally. + case identityPrivate = "identity_private" + /// Not a valid purpose – only used for `SafeEnumCodable` conformance. + case unparsable = "" + } + /// Time at which the object was created. + /// + /// Measured in seconds since the Unix epoch. + public let created: Date + /// Unique identifier for the object. + public let id: String + /// The [purpose](https://stripe.com/docs/file-upload#uploading-a-file) of the uploaded file. + public let purpose: Purpose + /// The size in bytes of the file object. + public let size: Int + /// The type of the file returned (e.g., `csv`, `pdf`, `jpg`, or `png`). + public let type: String? + public var _allResponseFieldsStorage: NonEncodableParameters? +} diff --git a/Pods/StripeCore/StripeCore/StripeCore/Source/API Bindings/STPAPIClient+FileUpload.swift b/Pods/StripeCore/StripeCore/StripeCore/Source/API Bindings/STPAPIClient+FileUpload.swift new file mode 100644 index 0000000..8334fac --- /dev/null +++ b/Pods/StripeCore/StripeCore/StripeCore/Source/API Bindings/STPAPIClient+FileUpload.swift @@ -0,0 +1,235 @@ +// +// STPAPIClient+FileUpload.swift +// StripeCore +// +// Created by Mel Ludowise on 11/9/21. +// Copyright © 2021 Stripe, Inc. All rights reserved. +// + +import Foundation +import UIKit + +extension StripeFile.Purpose { + /// See max purpose sizes https://stripe.com/docs/file-upload. + var maxBytes: Int? { + switch self { + case .identityDocument, + .identityPrivate: + return 16_000_000 + case .disputeEvidence: + return 5_000_000 + case .unparsable: + return nil + } + } +} + +/// STPAPIClient extensions to upload files. +extension STPAPIClient { + @_spi(STP) public typealias FileAndUploadMetrics = ( + file: StripeFile, + metrics: ImageUploadMetrics + ) + + /// Metrics returned in callback after image is uploaded to track performance. + @_spi(STP) public struct ImageUploadMetrics { + public let timeToUpload: TimeInterval + public let fileSizeBytes: Int + } + + @_spi(STP) public static let defaultImageFileName = "image" + + func data( + forUploadedImage image: UIImage, + compressionQuality: CGFloat, + purpose: String + ) -> Data { + // Get maxBytes if file purpose is known to the client + let maxBytes = StripeFile.Purpose(rawValue: purpose)?.maxBytes + return image.jpegDataAndDimensions( + maxBytes: maxBytes, + compressionQuality: compressionQuality + ).imageData + } + + /// Uses the Stripe file upload API to upload a JPEG encoded image. + /// + /// The image will be automatically resized down if: + /// 1. The given purpose is recognized by the client. + /// 2. It's larger than the maximum allowed file size for the given purpose. + /// + /// - Parameters: + /// - image: The image to be uploaded. + /// - compressionQuality: The compression quality to use when encoding the jpeg. + /// - purpose: The purpose of this file. + /// - fileName: The name of the uploaded file. The "jpeg" extension will + /// automatically be appended to this name. + /// - ownedBy: A Stripe-internal property that sets the owner of the file. + /// - ephemeralKeySecret: Authorization key, if applicable. + /// - completion: The callback to run with the returned Stripe file (and any + /// errors that may have occurred). + /// + /// - Note: + /// The provided `purpose` must match a supported Purpose by Stripe's File + /// Upload API, or the API will respond with an error. Generally, this should + /// match a value in `StripeFile.Purpose`, but can be specified by any string + /// when forwarding the value from a Stripe server response in situations + /// where the purpose is not yet encoded in the client SDK. + @_spi(STP) public func uploadImage( + _ image: UIImage, + compressionQuality: CGFloat = UIImage.defaultCompressionQuality, + purpose: String, + fileName: String = defaultImageFileName, + ownedBy: String? = nil, + ephemeralKeySecret: String? = nil, + completion: @escaping (Result) -> Void + ) { + uploadImageAndGetMetrics( + image, + compressionQuality: compressionQuality, + purpose: purpose, + fileName: fileName, + ownedBy: ownedBy, + ephemeralKeySecret: ephemeralKeySecret + ) { result in + completion(result.map { $0.file }) + } + } + + @_spi(STP) public func uploadImageAndGetMetrics( + _ image: UIImage, + compressionQuality: CGFloat = UIImage.defaultCompressionQuality, + purpose: String, + fileName: String = defaultImageFileName, + ownedBy: String? = nil, + ephemeralKeySecret: String? = nil, + completion: @escaping (Result) -> Void + ) { + let purposePart = STPMultipartFormDataPart() + purposePart.name = "purpose" + // `unparsable` is not a valid purpose + if purpose != StripeFile.Purpose.unparsable.rawValue, + let purposeData = purpose.data(using: .utf8) + { + purposePart.data = purposeData + } + + let imagePart = STPMultipartFormDataPart() + imagePart.name = "file" + imagePart.filename = "\(fileName).jpg" + imagePart.contentType = "image/jpeg" + imagePart.data = self.data( + forUploadedImage: image, + compressionQuality: compressionQuality, + purpose: purpose + ) + + let ownedByPart: STPMultipartFormDataPart? = ownedBy?.data(using: .utf8).map { + ownedByData in + let part = STPMultipartFormDataPart() + part.name = "owned_by" + part.data = ownedByData + return part + } + + let boundary = STPMultipartFormDataEncoder.generateBoundary() + let parts = [purposePart, ownedByPart, imagePart].compactMap { $0 } + let data = STPMultipartFormDataEncoder.multipartFormData( + for: parts, + boundary: boundary + ) + + var request = configuredRequest( + for: URL(string: FileUploadURL)!, + using: ephemeralKeySecret + ) + request.httpMethod = HTTPMethod.post.rawValue + request.stp_setMultipartForm(data, boundary: boundary) + + let requestStartTime = Date() + sendRequest( + request: request, + completion: { (result: Result) in + let timeToUpload = Date().timeIntervalSince(requestStartTime) + completion( + result.map { + ( + file: $0, + metrics: .init( + timeToUpload: timeToUpload, + fileSizeBytes: imagePart.data?.count ?? 0 + ) + ) + } + ) + } + ) + } + + /// Uses the Stripe file upload API to upload a JPEG encoded image. + /// + /// The image will be automatically resized down if: + /// 1. The given purpose is recognized by the client. + /// 2. It's larger than the maximum allowed file size for the given purpose. + /// + /// - Parameters: + /// - image: The image to be uploaded. + /// - compressionQuality: The compression quality to use when encoding the jpeg. + /// - purpose: The purpose of this file. + /// - fileName: The name of the uploaded file. The "jpeg" extension will + /// automatically be appended to this name. + /// - ownedBy: A Stripe-internal property that sets the owner of the file. + /// - ephemeralKeySecret: Authorization key, if applicable. + /// + /// - Returns: A promise that resolves to a Stripe file, if successful, or an + /// error that may have occurred. + /// + /// - Note: + /// The provided `purpose` must match a supported Purpose by our API or the + /// API will return an error. Generally, this should match a value in + /// `StripeFile.Purpose`, but can be specified by any string for instances + /// where a Stripe endpoint needs to specify a newer purpose that the client + /// SDK does not recognize. + @_spi(STP) public func uploadImage( + _ image: UIImage, + compressionQuality: CGFloat = UIImage.defaultCompressionQuality, + purpose: String, + fileName: String = defaultImageFileName, + ownedBy: String? = nil, + ephemeralKeySecret: String? = nil + ) -> Future { + return uploadImageAndGetMetrics( + image, + compressionQuality: compressionQuality, + purpose: purpose, + fileName: fileName, + ownedBy: ownedBy, + ephemeralKeySecret: ephemeralKeySecret + ).chained { Promise(value: $0.file) } + } + + @_spi(STP) public func uploadImageAndGetMetrics( + _ image: UIImage, + compressionQuality: CGFloat = UIImage.defaultCompressionQuality, + purpose: String, + fileName: String = defaultImageFileName, + ownedBy: String? = nil, + ephemeralKeySecret: String? = nil + ) -> Future { + let promise = Promise() + uploadImageAndGetMetrics( + image, + compressionQuality: compressionQuality, + purpose: purpose, + fileName: fileName, + ownedBy: ownedBy, + ephemeralKeySecret: ephemeralKeySecret + ) { result in + promise.fullfill(with: result) + } + return promise + } + +} + +private let FileUploadURL = "https://uploads.stripe.com/v1/files" diff --git a/Pods/StripeCore/StripeCore/StripeCore/Source/API Bindings/STPAPIClient.swift b/Pods/StripeCore/StripeCore/StripeCore/Source/API Bindings/STPAPIClient.swift new file mode 100644 index 0000000..958b6b5 --- /dev/null +++ b/Pods/StripeCore/StripeCore/StripeCore/Source/API Bindings/STPAPIClient.swift @@ -0,0 +1,544 @@ +// +// STPAPIClient.swift +// StripeCore +// +// Created by Jack Flintermann on 12/18/14. +// Copyright (c) 2014 Stripe, Inc. All rights reserved. +// + +import Foundation +import UIKit + +/// A client for making connections to the Stripe API. +@objc public class STPAPIClient: NSObject { + /// The current version of this library. + @objc public static let STPSDKVersion = StripeAPIConfiguration.STPSDKVersion + + /// A shared singleton API client. + /// + /// By default, the SDK uses this instance to make API requests + /// eg in STPPaymentHandler, STPPaymentContext, STPCustomerContext, etc. + @objc(sharedClient) public static let shared: STPAPIClient = { + let client = STPAPIClient() + return client + }() + + /// The client's publishable key. + /// + /// The default value is `StripeAPI.defaultPublishableKey`. + @objc public var publishableKey: String? { + get { + if let publishableKey = _publishableKey { + return publishableKey + } + return StripeAPI.defaultPublishableKey + } + set { + _publishableKey = newValue + Self.validateKey(newValue) + } + } + var _publishableKey: String? + + /// A publishable key that only contains publishable keys and not secret keys. + /// + /// If a secret key is found, returns "[REDACTED_LIVE_KEY]". + var sanitizedPublishableKey: String? { + guard let publishableKey = publishableKey else { + return nil + } + + return publishableKey.isSecretKey ? "[REDACTED_LIVE_KEY]" : publishableKey + } + + // Stored STPPaymentConfiguration: Type checking handled in STPAPIClient+Payments.swift. + @_spi(STP) public var _stored_configuration: NSObject? + + /// In order to perform API requests on behalf of a connected account, e.g. to + /// create a Source or Payment Method on a connected account, set this property to the ID of the + /// account for which this request is being made. + /// + /// - seealso: https://stripe.com/docs/connect/authentication#authentication-via-the-stripe-account-header + @objc public var stripeAccount: String? + + /// Libraries wrapping the Stripe SDK should set this, so that Stripe can contact you + /// about future issues or critical updates. + /// + /// - seealso: https://stripe.com/docs/building-plugins#setappinfo + @objc public var appInfo: STPAppInfo? + + /// The API version used to communicate with Stripe. + @objc public static let apiVersion = APIVersion + + // MARK: Internal/private properties + @_spi(STP) public var apiURL: URL! = URL(string: APIBaseURL) + @_spi(STP) public var urlSession = URLSession( + configuration: StripeAPIConfiguration.sharedUrlSessionConfiguration + ) + + @_spi(STP) public var sourcePollers: [String: NSObject]? + @_spi(STP) public var sourcePollersQueue: DispatchQueue? + /// A set of beta headers to add to Stripe API requests e.g. `Set(["alipay_beta=v1"])`. + @_spi(STP) public var betas: Set = [] + + /// Returns `true` if `publishableKey` is actually a user key, `false` otherwise. + @_spi(STP) public var publishableKeyIsUserKey: Bool { + return publishableKey?.hasPrefix("uk_") ?? false + } + + // MARK: Initializers + override public init() { + sourcePollers = [:] + sourcePollersQueue = DispatchQueue(label: "com.stripe.sourcepollers") + } + + /// Initializes an API client with the given publishable key. + /// + /// - Parameter publishableKey: The publishable key to use. + /// - Returns: An instance of STPAPIClient. + @objc(initWithPublishableKey:) + public convenience init( + publishableKey: String + ) { + self.init() + self.publishableKey = publishableKey + } + + @_spi(STP) public func configuredRequest( + for url: URL, + using ephemeralKeySecret: String? = nil, + additionalHeaders: [String: String] = [:] + ) + -> URLRequest + { + var request = URLRequest(url: url) + var headers = defaultHeaders(ephemeralKeySecret: ephemeralKeySecret) + // additionalHeaders can overwrite defaultHeaders. + for (k, v) in additionalHeaders { headers[k] = v } + headers.forEach { key, value in + request.setValue(value, forHTTPHeaderField: key) + } + return request + } + + /// Headers common to all API requests for a given API Client. + func defaultHeaders(ephemeralKeySecret: String?) -> [String: String] { + var defaultHeaders: [String: String] = [:] + defaultHeaders["X-Stripe-User-Agent"] = STPAPIClient.stripeUserAgentDetails(with: appInfo) + var stripeVersion = APIVersion + for beta in betas { + stripeVersion = stripeVersion + "; \(beta)" + } + defaultHeaders["Stripe-Version"] = stripeVersion + defaultHeaders["Stripe-Account"] = stripeAccount + for (k, v) in authorizationHeader(using: ephemeralKeySecret) { defaultHeaders[k] = v } + return defaultHeaders + } + + // MARK: Helpers + + static var didShowTestmodeKeyWarning = false + class func validateKey(_ publishableKey: String?) { + guard NSClassFromString("XCTest") == nil else { + return // no asserts in unit tests + } + guard let publishableKey = publishableKey, !publishableKey.isEmpty else { + assertionFailure( + "You must use a valid publishable key. For more info, see https://stripe.com/docs/keys" + ) + return + } + let secretKey = publishableKey.hasPrefix("sk_") + assert( + !secretKey, + "You are using a secret key. Use a publishable key instead. For more info, see https://stripe.com/docs/keys" + ) + #if !DEBUG + if publishableKey.lowercased().hasPrefix("pk_test") && !didShowTestmodeKeyWarning { + print( + "ℹ️ You're using your Stripe testmode key. Make sure to use your livemode key when submitting to the App Store!" + ) + didShowTestmodeKeyWarning = true + } + #endif + } + + class func stripeUserAgentDetails(with appInfo: STPAppInfo?) -> String { + var details: [String: String] = [ + // This SDK isn't in Objective-C anymore, but we sometimes check for + // 'objective-c' to enable iOS SDK-specific behavior in the API. + "lang": "objective-c", + "bindings_version": STPSDKVersion, + ] + let version = UIDevice.current.systemVersion + if version != "" { + details["os_version"] = version + } + var systemInfo = utsname() + uname(&systemInfo) + + // Thanks to https://stackoverflow.com/questions/26028918/how-to-determine-the-current-iphone-device-model + let machineMirror = Mirror(reflecting: systemInfo.machine) + let deviceType = machineMirror.children.reduce("") { identifier, element in + guard let value = element.value as? Int8, value != 0 else { return identifier } + return identifier + String(UnicodeScalar(UInt8(value))) + } + details["type"] = deviceType + let model = UIDevice.current.localizedModel + if model != "" { + details["model"] = model + } + + if let vendorIdentifier = UIDevice.current.identifierForVendor?.uuidString { + details["vendor_identifier"] = vendorIdentifier + } + if let appInfo = appInfo { + details["name"] = appInfo.name + details["partner_id"] = appInfo.partnerId + if appInfo.version != nil { + details["version"] = appInfo.version + } + if appInfo.url != nil { + details["url"] = appInfo.url + } + } + let data = try? JSONSerialization.data(withJSONObject: details, options: []) + return String(data: data ?? Data(), encoding: .utf8) ?? "" + } + + @_spi(STP) public func authorizationHeader( + using substituteAuthorizationBearer: String? = nil + ) -> [String: String] { + let authorizationBearer = substituteAuthorizationBearer ?? publishableKey ?? "" + var headers = ["Authorization": "Bearer " + authorizationBearer] + + if publishableKeyIsUserKey { + let liveMode = ProcessInfo.processInfo.environment["Stripe-Livemode"] != "false" + headers["Stripe-Livemode"] = liveMode ? "true" : "false" + } + return headers + } + + @_spi(STP) public var isTestmode: Bool { + guard let publishableKey = publishableKey, !publishableKey.isEmpty else { + return false + } + return publishableKey.lowercased().hasPrefix("pk_test") + } +} + +private let APIVersion = "2020-08-27" +private let APIBaseURL = "https://api.stripe.com/v1" + +// MARK: Modern bindings +extension STPAPIClient { + /// Make a GET request using the passed parameters. + @_spi(STP) public func get( + resource: String, + parameters: [String: Any], + ephemeralKeySecret: String? = nil, + completion: @escaping ( + Result + ) -> Void + ) { + request( + method: .get, + parameters: parameters, + ephemeralKeySecret: ephemeralKeySecret, + resource: resource, + completion: completion + ) + } + + /// Make a GET request using the passed parameters. + @_spi(STP) public func get( + url: URL, + parameters: [String: Any], + ephemeralKeySecret: String? = nil, + completion: @escaping ( + Result + ) -> Void + ) { + request( + method: .get, + parameters: parameters, + ephemeralKeySecret: ephemeralKeySecret, + url: url, + completion: completion + ) + } + + /// Make a GET request using the passed parameters. + /// + /// - Returns: a promise that is fullfilled when the request is complete. + @_spi(STP) public func get( + resource: String, + parameters: [String: Any], + ephemeralKeySecret: String? = nil + ) -> Promise { + return request( + method: .get, + parameters: parameters, + ephemeralKeySecret: ephemeralKeySecret, + resource: resource + ) + } + + /// Make a POST request using the passed parameters. + @_spi(STP) public func post( + resource: String, + parameters: [String: Any], + ephemeralKeySecret: String? = nil, + completion: @escaping (Result) -> Void + ) { + request( + method: .post, + parameters: parameters, + ephemeralKeySecret: ephemeralKeySecret, + resource: resource, + completion: completion + ) + } + + /// Make a POST request using the passed parameters. + @_spi(STP) public func post( + url: URL, + parameters: [String: Any], + ephemeralKeySecret: String? = nil, + completion: @escaping (Result) -> Void + ) { + request( + method: .post, + parameters: parameters, + ephemeralKeySecret: ephemeralKeySecret, + url: url, + completion: completion + ) + } + + /// Make a POST request using the passed parameters. + /// + /// - Returns: a promise that is fullfilled when the request is complete. + @_spi(STP) public func post( + resource: String, + parameters: [String: Any], + ephemeralKeySecret: String? = nil + ) -> Promise { + return request( + method: .post, + parameters: parameters, + ephemeralKeySecret: ephemeralKeySecret, + resource: resource + ) + } + + func request( + method: HTTPMethod, + parameters: [String: Any], + ephemeralKeySecret: String?, + resource: String + ) -> Promise { + let promise = Promise() + self.request( + method: method, + parameters: parameters, + ephemeralKeySecret: ephemeralKeySecret, + resource: resource + ) { result in + promise.fullfill(with: result) + } + return promise + } + + func request( + method: HTTPMethod, + parameters: [String: Any], + ephemeralKeySecret: String?, + resource: String, + completion: @escaping (Result) -> Void + ) { + let url = apiURL.appendingPathComponent(resource) + request( + method: method, + parameters: parameters, + ephemeralKeySecret: ephemeralKeySecret, + url: url, + completion: completion + ) + } + + func request( + method: HTTPMethod, + parameters: [String: Any], + ephemeralKeySecret: String?, + url: URL, + completion: @escaping (Result) -> Void + ) { + var request = configuredRequest(for: url) + var urlComponents = URLComponents(url: url, resolvingAgainstBaseURL: true)! + switch method { + case .get: + let query = URLEncoder.queryString(from: parameters) + urlComponents.query = query + request.url = urlComponents.url! + case .post: + let formData = URLEncoder.queryString(from: parameters).data(using: .utf8) + request.httpBody = formData + request.setValue( + String(format: "%lu", UInt(formData?.count ?? 0)), + forHTTPHeaderField: "Content-Length" + ) + request.setValue( + "application/x-www-form-urlencoded", + forHTTPHeaderField: "Content-Type" + ) + } + + request.httpMethod = method.rawValue + for (k, v) in authorizationHeader(using: ephemeralKeySecret) { + request.setValue(v, forHTTPHeaderField: k) + } + + self.sendRequest(request: request, completion: completion) + } + + /// Make a POST request using the passed Encodable object. + /// + /// - Returns: a promise that is fullfilled when the request is complete. + @_spi(STP) public func post( + resource: String, + object: I, + ephemeralKeySecret: String? = nil + ) -> Promise { + let promise = Promise() + self.post(resource: resource, object: object, ephemeralKeySecret: ephemeralKeySecret) { + result in + promise.fullfill(with: result) + } + return promise + } + + /// Make a POST request using the passed Encodable object. + @_spi(STP) public func post( + resource: String, + object: I, + ephemeralKeySecret: String? = nil, + completion: @escaping (Result) -> Void + ) { + let url = apiURL.appendingPathComponent(resource) + post( + url: url, + object: object, + ephemeralKeySecret: ephemeralKeySecret, + completion: completion + ) + } + + /// Make a POST request using the passed Encodable object. + @_spi(STP) public func post( + url: URL, + object: I, + ephemeralKeySecret: String? = nil, + completion: @escaping (Result) -> Void + ) { + do { + let jsonDictionary = try object.encodeJSONDictionary() + let formData = URLEncoder.queryString(from: jsonDictionary).data(using: .utf8) + var request = configuredRequest( + for: url, + using: ephemeralKeySecret, + additionalHeaders: [ + "Content-Length": String(format: "%lu", UInt(formData?.count ?? 0)), + "Content-Type": "application/x-www-form-urlencoded", + ] + ) + request.httpBody = formData + request.httpMethod = HTTPMethod.post.rawValue + + self.sendRequest(request: request, completion: completion) + } catch { + // JSONEncoder can only throw two possible exceptions: + // `invalidFloatingPointValue`, which will never be thrown because of + // our encoder's NonConformingFloatEncodingStrategy. + // The other is `invalidValue` if the top-level object doesn't encode any values. + // This should ~never happen, and if it does the object will be empty, + // so it should be safe to return the un-redacted underlying error. + DispatchQueue.main.async { + completion(.failure(error)) + } + } + } + + func sendRequest( + request: URLRequest, + completion: @escaping (Result) -> Void + ) { + urlSession.stp_performDataTask( + with: request, + completionHandler: { (data, response, error) in + DispatchQueue.main.async { + completion( + STPAPIClient.decodeResponse(data: data, error: error, response: response) + ) + } + } + ) + } + + @_spi(STP) public static func decodeResponse( + data: Data?, + error: Error?, + response: URLResponse? + ) -> Result { + if let error = error { + return .failure(error) + } + guard let data = data else { + return .failure(NSError.stp_genericFailedToParseResponseError()) + } + + do { + /// HACK: We must first check if EmptyResponses contain an error since it'll always parse successfully. + if T.self == EmptyResponse.self, + let decodedStripeError = decodeStripeErrorResponse(data: data, response: response) + { + return .failure(decodedStripeError) + } + + let decodedObject: T = try StripeJSONDecoder.decode(jsonData: data) + return .success(decodedObject) + } catch { + // Try decoding the error from the service if one is available + if let decodedStripeError = decodeStripeErrorResponse(data: data, response: response) { + return .failure(decodedStripeError) + } else { + // Return decoding error directly + return .failure(error) + } + } + } + + /// Decodes request data to see if it can be parsed as a Stripe error. + private static func decodeStripeErrorResponse( + data: Data, + response: URLResponse? + ) -> StripeError? { + var decodedError: StripeError? + + if let decodedErrorResponse: StripeAPIErrorResponse = try? StripeJSONDecoder.decode( + jsonData: data + ), + var apiError = decodedErrorResponse.error + { + apiError.statusCode = (response as? HTTPURLResponse)?.statusCode + decodedError = StripeError.apiError(apiError) + } + + return decodedError + } + + enum HTTPMethod: String { + case get = "GET" + case post = "POST" + } +} diff --git a/Pods/StripeCore/StripeCore/StripeCore/Source/API Bindings/STPAppInfo.swift b/Pods/StripeCore/StripeCore/StripeCore/Source/API Bindings/STPAppInfo.swift new file mode 100644 index 0000000..8799b59 --- /dev/null +++ b/Pods/StripeCore/StripeCore/StripeCore/Source/API Bindings/STPAppInfo.swift @@ -0,0 +1,45 @@ +// +// STPAppInfo.swift +// StripeCore +// +// Created by Yuki Tokuhiro on 6/20/19. +// Copyright © 2019 Stripe, Inc. All rights reserved. +// + +import Foundation + +/// Libraries wrapping the Stripe SDK should use this object to provide information about the +/// library, and set it in on `STPAPIClient`. +/// +/// This information is passed to Stripe so that we can contact you about future issues or +/// critical updates. +/// - seealso: https://stripe.com/docs/building-plugins#setappinfo +@objc public class STPAppInfo: NSObject { + /// Initializes an instance of `STPAppInfo`. + /// + /// - Parameters: + /// - name: The name of your library (e.g. "MyAwesomeLibrary"). + /// - partnerId: Your Stripe Partner ID (e.g. "pp_partner_1234"). Required for Stripe Verified Partners, optional otherwise. + /// - version: The version of your library (e.g. "1.2.34"). Optional. + /// - url: The website for your library (e.g. "https://myawesomelibrary.info"). Optional. + @objc public init( + name: String, + partnerId: String?, + version: String?, + url: String? + ) { + self.name = name + self.partnerId = partnerId + self.version = version + self.url = url + } + + /// The name of your library (e.g. "MyAwesomeLibrary"). + @objc public private(set) var name: String + /// Your Stripe Partner ID (e.g. "pp_partner_1234"). + @objc public private(set) var partnerId: String? + /// The version of your library (e.g. "1.2.34"). + @objc public private(set) var version: String? + /// The website for your library (e.g. "https://myawesomelibrary.info"). + @objc public private(set) var url: String? +} diff --git a/Pods/StripeCore/StripeCore/StripeCore/Source/API Bindings/STPMultipartFormDataEncoder.swift b/Pods/StripeCore/StripeCore/StripeCore/Source/API Bindings/STPMultipartFormDataEncoder.swift new file mode 100644 index 0000000..c63e8d9 --- /dev/null +++ b/Pods/StripeCore/StripeCore/StripeCore/Source/API Bindings/STPMultipartFormDataEncoder.swift @@ -0,0 +1,38 @@ +// +// STPMultipartFormDataEncoder.swift +// StripeCore +// +// Created by Charles Scalesse on 12/1/16. +// Copyright © 2016 Stripe, Inc. All rights reserved. +// + +import Foundation + +/// Encoder class to generate the HTTP body data for a multipart/form-data request. +/// +/// - seealso: https://www.w3.org/TR/html401/interact/forms.html#h-17.13.4 +class STPMultipartFormDataEncoder: NSObject { + /// Generates the HTTP body data from an array of parts. + class func multipartFormData(for parts: [STPMultipartFormDataPart], boundary: String) -> Data { + var data = Data() + let boundaryData = "--\(boundary)\r\n".data(using: .utf8) + + for part in parts { + if let boundaryData = boundaryData { + data.append(boundaryData) + } + data.append(part.composedData()) + } + + if let data1 = "--\(boundary)--\r\n".data(using: .utf8) { + data.append(data1) + } + + return data + } + + /// Generates a unique boundary string to be used between parts. + class func generateBoundary() -> String { + return "Stripe-iOS-\(UUID().uuidString)" + } +} diff --git a/Pods/StripeCore/StripeCore/StripeCore/Source/API Bindings/STPMultipartFormDataPart.swift b/Pods/StripeCore/StripeCore/StripeCore/Source/API Bindings/STPMultipartFormDataPart.swift new file mode 100644 index 0000000..6d93cd8 --- /dev/null +++ b/Pods/StripeCore/StripeCore/StripeCore/Source/API Bindings/STPMultipartFormDataPart.swift @@ -0,0 +1,63 @@ +// +// STPMultipartFormDataPart.swift +// StripeCore +// +// Created by Charles Scalesse on 12/1/16. +// Copyright © 2016 Stripe, Inc. All rights reserved. +// + +import Foundation + +/// Represents a single part of a multipart/form-data upload. +/// +/// - seealso: https://www.w3.org/TR/html401/interact/forms.html#h-17.13.4 +class STPMultipartFormDataPart: NSObject { + /// The data for this part. + var data: Data? + /// The name for this part. + var name: String? + /// The filename for this part. + /// + /// As a rule of thumb, this can be ommitted when the data is just an encoded string. + /// However, this is typically required for other types of binary file data (like images). + var filename: String? + /// The content type for this part. + /// + /// When omitted, the multipart/form-data standard assumes text/plain. + var contentType: String? + + /// Returns the fully-composed data for this part. + // MARK: - Data Composition + + func composedData() -> Data { + var data = Data() + + var contentDisposition = "Content-Disposition: form-data; name=\"\(name ?? "")\"" + if filename != nil { + contentDisposition += "; filename=\"\(filename ?? "")\"" + } + contentDisposition += "\r\n" + + if let data1 = contentDisposition.data(using: .utf8) { + data.append(data1) + } + + var contentType = "" + if let _contentType = self.contentType { + contentType.append("Content-Type: \(_contentType)\r\n") + } + contentType += "\r\n" + if let data1 = contentType.data(using: .utf8) { + data.append(data1) + } + + if let _data = self.data { + data.append(_data) + } + if let data1 = "\r\n".data(using: .utf8) { + data.append(data1) + } + + return data + } +} diff --git a/Pods/StripeCore/StripeCore/StripeCore/Source/API Bindings/StripeAPI.swift b/Pods/StripeCore/StripeCore/StripeCore/Source/API Bindings/StripeAPI.swift new file mode 100644 index 0000000..4563fc6 --- /dev/null +++ b/Pods/StripeCore/StripeCore/StripeCore/Source/API Bindings/StripeAPI.swift @@ -0,0 +1,174 @@ +// +// StripeAPI.swift +// StripeCore +// +// Created by Yuki Tokuhiro on 9/22/20. +// Copyright © 2020 Stripe, Inc. All rights reserved. +// + +import Foundation +import PassKit + +/// A top-level class that imports the rest of the Stripe SDK. +@objc public class StripeAPI: NSObject { + /// Set this to your Stripe publishable API key, obtained from https://dashboard.stripe.com/apikeys. + /// + /// Set this as early as possible in your application's lifecycle, preferably in your AppDelegate or SceneDelegate. + /// New instances of STPAPIClient will be initialized with this value. + /// @warning Make sure not to ship your test API keys to the App Store! This will log a warning if you use your test key in a release build. + @objc public static var defaultPublishableKey: String? + + /// Set this to your Stripe publishable API key, obtained from https://dashboard.stripe.com/apikeys. + /// + /// Set this as early as possible in your application's lifecycle, preferably in your AppDelegate or SceneDelegate. + /// New instances of STPAPIClient will be initialized with this value. + /// @warning Make sure not to ship your test API keys to the App Store! This will log a warning if you use your test key in a release build. + @objc public func setDefaultPublishableKey(_ publishableKey: String) { + StripeAPI.defaultPublishableKey = publishableKey + } + + /// A Boolean value that determines whether additional device data is sent to Stripe for fraud prevention. + /// + /// If YES, additional device signals will be sent to Stripe. + /// For more details on the information we collect, visit https://stripe.com/docs/disputes/prevention/advanced-fraud-detection + /// Disabling this setting will reduce Stripe's ability to protect your business from fraudulent payments. + /// The default value is YES. + @objc public static var advancedFraudSignalsEnabled: Bool = true + + /// If the SDK receives a "Too Many Requests" (429) status code from Stripe, + /// it will automatically retry the request. + /// + /// The default value is 3. + /// See https://stripe.com/docs/rate-limits for more information. + @objc public static var maxRetries = 3 + + // MARK: - Apple Pay + + /// Japanese users can enable JCB for Apple Pay by setting this to `YES`, + /// after they have been approved by JCB. + /// + /// The default value is NO. + /// @note JCB is only supported on iOS 10.1+ + @objc public class var jcbPaymentNetworkSupported: Bool { + get { + return self.additionalEnabledApplePayNetworks.contains(.JCB) + } + set(JCBPaymentNetworkSupported) { + if JCBPaymentNetworkSupported + && !self.additionalEnabledApplePayNetworks.contains(.JCB) + { + self.additionalEnabledApplePayNetworks = + self.additionalEnabledApplePayNetworks + [PKPaymentNetwork.JCB] + } else if !JCBPaymentNetworkSupported { + var updatedNetworks = self.additionalEnabledApplePayNetworks + updatedNetworks.removeAll { + $0 as AnyObject === PKPaymentNetwork.JCB as AnyObject + } + self.additionalEnabledApplePayNetworks = updatedNetworks + } + } + } + /// The SDK accepts Amex, Mastercard, Visa, and Discover for Apple Pay. + /// + /// Set this property to enable other card networks in addition to these. + /// For example, `additionalEnabledApplePayNetworks = [.JCB]` enables JCB (note this requires onboarding from JCB and Stripe). + @objc public static var additionalEnabledApplePayNetworks: [PKPaymentNetwork] = [] + + /// Whether or not this device is capable of using Apple Pay. + /// + /// This checks both whether the device supports Apple Pay, as well as whether or not they have + /// stored Apple Pay cards on their device. + /// + /// - Parameter paymentRequest: The return value of this method depends on the + /// `supportedNetworks` property of this payment request, which by default should be + /// `[.amex, .masterCard, .visa, .discover]`. + /// - Returns: whether or not the user is currently able to pay with Apple Pay. + @objc public class func canSubmitPaymentRequest(_ paymentRequest: PKPaymentRequest) -> Bool { + if !self.deviceSupportsApplePay() { + return false + } + if paymentRequest.merchantIdentifier.isEmpty { + return false + } + // "In versions of iOS prior to version 12.0 and watchOS prior to version 5.0, the amount of the grand total must be greater than zero." + return paymentRequest.paymentSummaryItems.last?.amount.floatValue ?? 0.0 >= 0 + } + + class func supportedPKPaymentNetworks() -> [PKPaymentNetwork] { + var additionalOSSupportedNetworks: [PKPaymentNetwork] = [] + additionalOSSupportedNetworks.append(.maestro) + return [ + .amex, + .masterCard, + .visa, + .discover, + ] + additionalEnabledApplePayNetworks + additionalOSSupportedNetworks + } + + /// Whether or not this can make Apple Pay payments via a card network supported + /// by Stripe. + /// + /// The Stripe supported Apple Pay card networks are: + /// American Express, Visa, Mastercard, Discover, Maestro. + /// Japanese users can enable JCB by setting `JCBPaymentNetworkSupported` to YES, + /// after they have been approved by JCB. + /// - Returns: YES if the device is currently able to make Apple Pay payments via one + /// of the supported networks. NO if the user does not have a saved card of a + /// supported type, or other restrictions prevent payment (such as parental controls). + @objc public class func deviceSupportsApplePay() -> Bool { + return PKPaymentAuthorizationController.canMakePayments( + usingNetworks: self.supportedPKPaymentNetworks() + ) + } + + /// A convenience method to build a `PKPaymentRequest` with sane default values. + /// + /// You will still need to configure the `paymentSummaryItems` property to indicate + /// what the user is purchasing, as well as the optional `requiredShippingContactFields`, + /// `requiredBillingContactFields`, and `shippingMethods` properties to indicate + /// what additional contact information your application requires. + /// - Parameters: + /// - merchantIdentifier: Your Apple Merchant ID. + /// - countryCode: The two-letter code for the country where the payment + /// will be processed. This should be the country of your Stripe account. + /// - currencyCode: The three-letter code for the currency used by this + /// payment request. Apple Pay interprets the amounts provided by the summary items + /// attached to this request as amounts in this currency. + /// - Returns: a `PKPaymentRequest` with proper default values. + @objc(paymentRequestWithMerchantIdentifier:country:currency:) + public class func paymentRequest( + withMerchantIdentifier merchantIdentifier: String, + country countryCode: String, + currency currencyCode: String + ) -> PKPaymentRequest { + let paymentRequest = PKPaymentRequest() + paymentRequest.merchantIdentifier = merchantIdentifier + paymentRequest.supportedNetworks = self.supportedPKPaymentNetworks() + paymentRequest.merchantCapabilities = .capability3DS + paymentRequest.countryCode = countryCode.uppercased() + paymentRequest.currencyCode = currencyCode.uppercased() + paymentRequest.requiredBillingContactFields = Set([.postalAddress]) + return paymentRequest + } + + // MARK: - URL callbacks + + /// Call this method in your app delegate whenever you receive an URL in your + /// app delegate for a Stripe callback. + /// + /// For convenience, you can pass all URL's you receive in your app delegate + /// to this method first, and check the return value + /// to easily determine whether it is a callback URL that Stripe will handle + /// or if your app should process it normally. + /// If you are using a universal link URL, you will receive the callback in `application:continueUserActivity:restorationHandler:` + /// To learn more about universal links, see https://developer.apple.com/library/content/documentation/General/Conceptual/AppSearch/UniversalLinks.html + /// If you are using a native scheme URL, you will receive the callback in `application:openURL:options:` + /// To learn more about native url schemes, see https://developer.apple.com/library/content/documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/Inter-AppCommunication/Inter-AppCommunication.html#//apple_ref/doc/uid/TP40007072-CH6-SW10 + /// - Parameter url: The URL that you received in your app delegate + /// - Returns: YES if the URL is expected and will be handled by Stripe. NO otherwise. + @objc(handleStripeURLCallbackWithURL:) @discardableResult public static func handleURLCallback( + with url: URL + ) -> Bool { + return STPURLCallbackHandler.shared().handleURLCallback(url) + } +} diff --git a/Pods/StripeCore/StripeCore/StripeCore/Source/API Bindings/StripeAPIConfiguration+Version.swift b/Pods/StripeCore/StripeCore/StripeCore/Source/API Bindings/StripeAPIConfiguration+Version.swift new file mode 100644 index 0000000..391cb31 --- /dev/null +++ b/Pods/StripeCore/StripeCore/StripeCore/Source/API Bindings/StripeAPIConfiguration+Version.swift @@ -0,0 +1,21 @@ +// +// StripeAPIConfiguration+Version.swift +// +// This file was generated by update_version.sh +// Do not edit this file directly. +// Instead, edit the `VERSION` file and run `ci_scripts/update_version.sh` +// + +import Foundation + +public extension StripeAPIConfiguration { + /// The current version of this library. + static let STPSDKVersion = "23.2.0" + + /* + NOTE: `STPSDKVersion` must be a hard-coded static string instead of + dynamically generated from the bundle's `CFBundleShortVersionString` to + ensure the correct value is returned when the SDK is statically linked. + */ + +} diff --git a/Pods/StripeCore/StripeCore/StripeCore/Source/API Bindings/StripeAPIConfiguration.swift b/Pods/StripeCore/StripeCore/StripeCore/Source/API Bindings/StripeAPIConfiguration.swift new file mode 100644 index 0000000..ed1c0e3 --- /dev/null +++ b/Pods/StripeCore/StripeCore/StripeCore/Source/API Bindings/StripeAPIConfiguration.swift @@ -0,0 +1,16 @@ +// +// StripeAPIConfiguration.swift +// StripeCore +// +// Created by Mel Ludowise on 5/17/21. +// Copyright © 2021 Stripe, Inc. All rights reserved. +// + +import Foundation + +/// Shared configurations across all Stripe frameworks. +@_spi(STP) public struct StripeAPIConfiguration { + + public static let sharedUrlSessionConfiguration = URLSessionConfiguration.default + +} diff --git a/Pods/StripeCore/StripeCore/StripeCore/Source/API Bindings/StripeError.swift b/Pods/StripeCore/StripeCore/StripeCore/Source/API Bindings/StripeError.swift new file mode 100644 index 0000000..de097f2 --- /dev/null +++ b/Pods/StripeCore/StripeCore/StripeCore/Source/API Bindings/StripeError.swift @@ -0,0 +1,80 @@ +// +// StripeError.swift +// StripeCore +// +// Created by David Estes on 8/11/21. +// Copyright © 2021 Stripe, Inc. All rights reserved. +// + +import Foundation + +/// Error codes returned from STPAPIClient. +@_spi(STP) public enum StripeError: Error { + /// The server returned an API error. + case apiError(StripeAPIError) + + /// The request was invalid. + case invalidRequest + + /// Localized description of the error. + public var localizedDescription: String { + return errorDescription ?? NSError.stp_unexpectedErrorMessage() + } +} + +// MARK: - LocalizedError + +extension StripeError: LocalizedError { + @_spi(STP) public var errorDescription: String? { + switch self { + case .apiError(let apiError): + return apiError.errorUserInfoString(key: NSLocalizedDescriptionKey) + case .invalidRequest: + return nil + } + } + + @_spi(STP) public var failureReason: String? { + switch self { + case .apiError(let apiError): + return apiError.errorUserInfoString(key: NSLocalizedFailureReasonErrorKey) + case .invalidRequest: + return nil + } + } + + @_spi(STP) public var recoverySuggestion: String? { + switch self { + case .apiError(let apiError): + return apiError.errorUserInfoString(key: NSLocalizedRecoverySuggestionErrorKey) + case .invalidRequest: + return nil + } + } + + @_spi(STP) public var helpAnchor: String? { + switch self { + case .apiError(let apiError): + return apiError.errorUserInfoString(key: NSHelpAnchorErrorKey) + case .invalidRequest: + return nil + } + } +} + +extension StripeError: AnalyticLoggableError { + public func analyticLoggableSerializeForLogging() -> [String: Any] { + var code: Int + switch self { + case .apiError: + code = 0 + case .invalidRequest: + code = 1 + } + + return [ + "domain": (self as NSError).domain, + "code": code, + ] + } +} diff --git a/Pods/StripeCore/StripeCore/StripeCore/Source/API Bindings/StripeServiceError.swift b/Pods/StripeCore/StripeCore/StripeCore/Source/API Bindings/StripeServiceError.swift new file mode 100644 index 0000000..b5b5882 --- /dev/null +++ b/Pods/StripeCore/StripeCore/StripeCore/Source/API Bindings/StripeServiceError.swift @@ -0,0 +1,73 @@ +// +// StripeServiceError.swift +// StripeCore +// +// Created by David Estes on 8/11/21. +// Copyright © 2021 Stripe, Inc. All rights reserved. +// + +import Foundation + +/// An error returned from the Stripe API. +/// +/// https://stripe.com/docs/api/errors +@_spi(STP) public struct StripeAPIError: UnknownFieldsDecodable { + /// The type of error returned. + @_spi(STP) public var type: ErrorType + /// For some errors that could be handled programmatically, + /// a short string indicating the error code reported. + /// + /// https://stripe.com/docs/error-codes + @_spi(STP) public var code: String? + /// A URL to more information about the error code reported. + @_spi(STP) public var docUrl: URL? + /// A human-readable message providing more details about the error. + /// + /// For card errors, these messages can be shown to your users. + @_spi(STP) public var message: String? + /// If the error is parameter-specific, the parameter related to the error. + /// + /// For example, you can use this to display a message near the correct form field. + @_spi(STP) public var param: String? + /// The response’s HTTP status code. + @_spi(STP) public var statusCode: Int? + + // More information may be available in `allResponseFields`, including + // the PaymentIntent or PaymentMethod. + + /// Types of errors presented by the API. + @_spi(STP) public enum ErrorType: String, SafeEnumCodable { + case apiError = "api_error" + case cardError = "card_error" + case idempotencyError = "idempotency_error" + case invalidRequestError = "invalid_request_error" + case unparsable + } + + public var _allResponseFieldsStorage: NonEncodableParameters? +} + +@_spi(STP) public struct StripeAPIErrorResponse: UnknownFieldsDecodable { + @_spi(STP) public var error: StripeAPIError? + + public var _allResponseFieldsStorage: NonEncodableParameters? +} + +extension NSError { + static func stp_error(from stripeApiError: StripeAPIError) -> NSError? { + return stp_error( + errorType: stripeApiError.type.rawValue, + stripeErrorCode: stripeApiError.code, + stripeErrorMessage: stripeApiError.message, + errorParam: stripeApiError.param, + declineCode: nil, + httpResponse: nil + ) + } +} + +extension StripeAPIError { + func errorUserInfoString(key: String) -> String? { + return NSError.stp_error(from: self)?.userInfo[key] as? String + } +} diff --git a/Pods/StripeCore/StripeCore/StripeCore/Source/Analytics/Analytic.swift b/Pods/StripeCore/StripeCore/StripeCore/Source/Analytics/Analytic.swift new file mode 100644 index 0000000..d9f5f84 --- /dev/null +++ b/Pods/StripeCore/StripeCore/StripeCore/Source/Analytics/Analytic.swift @@ -0,0 +1,37 @@ +// +// Analytic.swift +// StripeCore +// +// Created by Mel Ludowise on 3/12/21. +// Copyright © 2021 Stripe, Inc. All rights reserved. +// + +import Foundation + +/// An analytic that can be logged to our analytics system. +@_spi(STP) public protocol Analytic { + var event: STPAnalyticEvent { get } + var params: [String: Any] { get } +} + +/// An error analytic that can be logged to our analytics system. +@_spi(STP) public protocol ErrorAnalytic: Analytic { + var error: Error { get } +} + +/// A generic analytic type. +/// +/// - NOTE: This should only be used to support legacy analytics. +/// Any new analytic events should create a new type and conform to `Analytic`. +@_spi(STP) public struct GenericAnalytic: Analytic { + public let event: STPAnalyticEvent + public let params: [String: Any] + + public init( + event: STPAnalyticEvent, + params: [String: Any] + ) { + self.event = event + self.params = params + } +} diff --git a/Pods/StripeCore/StripeCore/StripeCore/Source/Analytics/AnalyticLoggableError.swift b/Pods/StripeCore/StripeCore/StripeCore/Source/Analytics/AnalyticLoggableError.swift new file mode 100644 index 0000000..89e2cde --- /dev/null +++ b/Pods/StripeCore/StripeCore/StripeCore/Source/Analytics/AnalyticLoggableError.swift @@ -0,0 +1,52 @@ +// +// AnalyticLoggableError.swift +// StripeCore +// +// Created by Nick Porter on 9/2/21. +// Copyright © 2021 Stripe, Inc. All rights reserved. +// + +import Foundation + +/// Defines a common loggable error to our analytics service. +@_spi(STP) public protocol AnalyticLoggableError: Error { + + /// Serializes this error for analytics logging. + /// + /// - Returns: A dictionary representing this error, not containing any PII or PDE + func analyticLoggableSerializeForLogging() -> [String: Any] +} + +/// Error types that conform to this protocol and String-based RawRepresentable +/// will automatically serialize the rawValue for analytics logging. +@_spi(STP) public protocol AnalyticLoggableStringError: Error { + var loggableType: String { get } +} + +@_spi(STP) extension AnalyticLoggableStringError +where Self: RawRepresentable, Self.RawValue == String { + public var loggableType: String { + return rawValue + } +} + +@_spi(STP) extension Error { + public func serializeForLogging() -> [String: Any] { + if let loggableError = self as? AnalyticLoggableError { + return loggableError.analyticLoggableSerializeForLogging() + } + let nsError = self as NSError + + var payload: [String: Any] = [ + "domain": nsError.domain + ] + + if let stringError = self as? AnalyticLoggableStringError { + payload["type"] = stringError.loggableType + } else { + payload["code"] = nsError.code + } + + return payload + } +} diff --git a/Pods/StripeCore/StripeCore/StripeCore/Source/Analytics/AnalyticsClientV2.swift b/Pods/StripeCore/StripeCore/StripeCore/Source/Analytics/AnalyticsClientV2.swift new file mode 100644 index 0000000..a1f59af --- /dev/null +++ b/Pods/StripeCore/StripeCore/StripeCore/Source/Analytics/AnalyticsClientV2.swift @@ -0,0 +1,153 @@ +// +// AnalyticsClientV2.swift +// StripeCore +// +// Created by Mel Ludowise on 6/7/22. +// Copyright © 2022 Stripe, Inc. All rights reserved. +// + +import Foundation +import UIKit + +/// Dependency-injectable protocol for `AnalyticsClientV2`. +@_spi(STP) public protocol AnalyticsClientV2Protocol { + var clientId: String { get } + + func log(eventName: String, parameters: [String: Any]) +} + +/// Logs analytics to `r.stripe.com`. +/// +/// To log analytics to the legacy `q.stripe.com`, use `STPAnalyticsClient`. +@_spi(STP) public class AnalyticsClientV2: AnalyticsClientV2Protocol { + + static let loggerUrl = URL(string: "https://r.stripe.com/0")! + + public let clientId: String + public let origin: String + + private(set) var urlSession: URLSession = URLSession( + configuration: StripeAPIConfiguration.sharedUrlSessionConfiguration + ) + + /// Instantiates an AnalyticsClient capable of logging to a specific events table. + /// + /// - Parameters: + /// - clientId: The client identifier corresponding to `client_config.yaml`. + /// - origin: The origin corresponding to `r.stripe.com.conf`. + public init( + clientId: String, + origin: String + ) { + self.clientId = clientId + self.origin = origin + } + + static let shouldCollectAnalytics: Bool = { + #if targetEnvironment(simulator) + return false + #else + return NSClassFromString("XCTest") == nil + #endif + }() + + var requestHeaders: [String: String] { + return [ + "user-agent": "Stripe/v1 ios/\(StripeAPIConfiguration.STPSDKVersion)", + "origin": origin, + ] + } + + /// Helper to serialize errors to a dictionary that can be included in event parameters. + /// + /// - Parameters: + /// - error: The error to serialize. + /// - filePath: Optionally include the filePath of the call site that threw + /// the error. Only the name of the file (e.g. "MyClass.swift") + /// will be serialized and not the full path. + /// - line: Optionally include the line number of the call site that threw the error. + public static func serialize( + error: Error, + filePath: StaticString?, + line: UInt? + ) -> [String: Any] { + + var payload = error.serializeForLogging() + + if let filePath = filePath { + // The full file path can contain the device name, so only include the file name + let fileName = NSString(string: "\(filePath)").lastPathComponent + payload["file"] = fileName + } + if let line = line { + payload["line"] = line + } + + return payload + } + + public func log(eventName: String, parameters: [String: Any]) { + let payload = payload(withEventName: eventName, parameters: parameters) + + #if DEBUG + NSLog("LOG ANALYTICS: \(payload)") + #endif + + guard AnalyticsClientV2.shouldCollectAnalytics else { + return + } + + var request = URLRequest(url: AnalyticsClientV2.loggerUrl) + request.httpMethod = "POST" + request.stp_setFormPayload(payload.jsonEncodeNestedDicts(options: .sortedKeys)) + requestHeaders.forEach { key, value in + request.setValue(value, forHTTPHeaderField: key) + } + let task: URLSessionDataTask = urlSession.dataTask(with: request as URLRequest) + task.resume() + } +} + +extension AnalyticsClientV2Protocol { + public func makeCommonPayload() -> [String: Any] { + var payload: [String: Any] = [:] + + // Required by Analytics Event Logger + payload["client_id"] = self.clientId + payload["event_id"] = UUID().uuidString + payload["created"] = Date().timeIntervalSince1970 + + // Common payload + let version = UIDevice.current.systemVersion + if !version.isEmpty { + payload["os_version"] = version + } + payload["sdk_platform"] = "ios" + payload["sdk_version"] = StripeAPIConfiguration.STPSDKVersion + if let deviceType = STPDeviceUtils.deviceType { + payload["device_type"] = deviceType + } + payload["app_name"] = Bundle.stp_applicationName() ?? "" + payload["app_version"] = Bundle.stp_applicationVersion() ?? "" + payload["plugin_type"] = PluginDetector.shared.pluginType?.rawValue + payload["platform_info"] = [ + "install": InstallMethod.current.rawValue, + "app_bundle_id": Bundle.stp_applicationBundleId() ?? "", + ] + + return payload + } + + public func payload(withEventName eventName: String, parameters: [String: Any]) -> [String: Any] + { + var payload = makeCommonPayload() + payload["event_name"] = eventName + payload = payload.merging( + parameters, + uniquingKeysWith: { a, _ in + return a + } + ) + return payload + } +} diff --git a/Pods/StripeCore/StripeCore/StripeCore/Source/Analytics/PluginDetector.swift b/Pods/StripeCore/StripeCore/StripeCore/Source/Analytics/PluginDetector.swift new file mode 100644 index 0000000..8803603 --- /dev/null +++ b/Pods/StripeCore/StripeCore/StripeCore/Source/Analytics/PluginDetector.swift @@ -0,0 +1,47 @@ +// +// PluginDetector.swift +// StripeCore +// +// Created by Nick Porter on 10/1/21. +// Copyright © 2021 Stripe, Inc. All rights reserved. +// + +import Foundation + +/// A class which can detect if the host app is using a known cross-platform solution. +class PluginDetector { + + /// Shared instance of the `PluginDetector` to enable caching of the `pluginType`. + static let shared = PluginDetector() + + /// Represents all the known/tracked cross-platform solutions. + enum PluginType: String, CaseIterable { + case cordova + case flutter + case ionic + case reactNative = "react-native" + case unity + case xamarin + + /// Represents a known class contained in each cross-platform environment. + var className: String { + switch self { + case .cordova: return "CDVPlugin" + case .flutter: return "FlutterAppDelegate" + case .ionic: return "CAPPlugin" + case .reactNative: return "RCTBridge" + case .unity: return "UnityFramework" + case .xamarin: return "XamarinAssociatedObject" + } + } + } + + /// Determines if this app is running within a plugin environment. + /// + /// - Returns: returns the plugin type if found, otherwise nil. + lazy var pluginType: PluginType? = { + PluginType.allCases.first { type in + NSClassFromString(type.className) != nil + } + }() +} diff --git a/Pods/StripeCore/StripeCore/StripeCore/Source/Analytics/STPAnalyticEvent.swift b/Pods/StripeCore/StripeCore/StripeCore/Source/Analytics/STPAnalyticEvent.swift new file mode 100644 index 0000000..3cc5b52 --- /dev/null +++ b/Pods/StripeCore/StripeCore/StripeCore/Source/Analytics/STPAnalyticEvent.swift @@ -0,0 +1,141 @@ +// +// STPAnalyticEvent.swift +// StripeCore +// +// Created by Mel Ludowise on 3/12/21. +// Copyright © 2021 Stripe, Inc. All rights reserved. +// + +import Foundation + +/// Enumeration of all the analytic events logged by our SDK. +@_spi(STP) public enum STPAnalyticEvent: String { + // MARK: - Payment Creation + case tokenCreation = "stripeios.token_creation" + + // This was "stripeios.source_creation" in earlier SDKs, + // but we need to support both the old and new values forever. + case sourceCreation = "stripeios.source_creationn" + + case paymentMethodCreation = "stripeios.payment_method_creation" + case paymentMethodIntentCreation = "stripeios.payment_intent_confirmation" + case setupIntentConfirmationAttempt = "stripeios.setup_intent_confirmation" + + // MARK: - Payment Confirmation + case _3DS2AuthenticationRequestParamsFailed = + "stripeios.3ds2_authentication_request_params_failed" + case _3DS2AuthenticationAttempt = "stripeios.3ds2_authenticate" + case _3DS2FrictionlessFlow = "stripeios.3ds2_frictionless_flow" + case urlRedirectNextAction = "stripeios.url_redirect_next_action" + case _3DS2ChallengeFlowPresented = "stripeios.3ds2_challenge_flow_presented" + case _3DS2ChallengeFlowTimedOut = "stripeios.3ds2_challenge_flow_timed_out" + case _3DS2ChallengeFlowUserCanceled = "stripeios.3ds2_challenge_flow_canceled" + case _3DS2ChallengeFlowCompleted = "stripeios.3ds2_challenge_flow_completed" + case _3DS2ChallengeFlowErrored = "stripeios.3ds2_challenge_flow_errored" + case _3DS2RedirectUserCanceled = "stripeios.3ds2_redirect_canceled" + + // MARK: - Card Metadata + case cardMetadataLoadedTooSlow = "stripeios.card_metadata_loaded_too_slow" + case cardMetadataResponseFailure = "stripeios.card_metadata_load_failure" + case cardMetadataMissingRange = "stripeios.card_metadata_missing_range" + + // MARK: - Card Scanning + case cardScanSucceeded = "stripeios.cardscan_success" + case cardScanCancelled = "stripeios.cardscan_cancel" + + // MARK: - Identity Verification Flow + case verificationSheetPresented = "stripeios.idprod.verification_sheet.presented" + case verificationSheetClosed = "stripeios.idprod.verification_sheet.closed" + case verificationSheetFailed = "stripeios.idprod.verification_sheet.failed" + + // MARK: - FinancialConnections + case financialConnectionsSheetPresented = "stripeios.financialconnections.sheet.presented" + case financialConnectionsSheetClosed = "stripeios.financialconnections.sheet.closed" + case financialConnectionsSheetFailed = "stripeios.financialconnections.sheet.failed" + + // MARK: - PaymentSheet Init + case mcInitCustomCustomer = "mc_custom_init_customer" + case mcInitCompleteCustomer = "mc_complete_init_customer" + case mcInitCustomApplePay = "mc_custom_init_applepay" + case mcInitCompleteApplePay = "mc_complete_init_applepay" + case mcInitCustomCustomerApplePay = "mc_custom_init_customer_applepay" + case mcInitCompleteCustomerApplePay = "mc_complete_init_customer_applepay" + case mcInitCustomDefault = "mc_custom_init_default" + case mcInitCompleteDefault = "mc_complete_init_default" + + // MARK: - PaymentSheet Show + case mcShowCustomNewPM = "mc_custom_sheet_newpm_show" + case mcShowCustomSavedPM = "mc_custom_sheet_savedpm_show" + case mcShowCustomApplePay = "mc_custom_sheet_applepay_show" + case mcShowCustomLink = "mc_custom_sheet_link_show" + case mcShowCompleteNewPM = "mc_complete_sheet_newpm_show" + case mcShowCompleteSavedPM = "mc_complete_sheet_savedpm_show" + case mcShowCompleteApplePay = "mc_complete_sheet_applepay_show" + case mcShowCompleteLink = "mc_complete_sheet_link_show" + + // MARK: - PaymentSheet Payment + case mcPaymentCustomNewPMSuccess = "mc_custom_payment_newpm_success" + case mcPaymentCustomSavedPMSuccess = "mc_custom_payment_savedpm_success" + case mcPaymentCustomApplePaySuccess = "mc_custom_payment_applepay_success" + case mcPaymentCustomLinkSuccess = "mc_custom_payment_link_success" + + case mcPaymentCompleteNewPMSuccess = "mc_complete_payment_newpm_success" + case mcPaymentCompleteSavedPMSuccess = "mc_complete_payment_savedpm_success" + case mcPaymentCompleteApplePaySuccess = "mc_complete_payment_applepay_success" + case mcPaymentCompleteLinkSuccess = "mc_complete_payment_link_success" + + case mcPaymentCustomNewPMFailure = "mc_custom_payment_newpm_failure" + case mcPaymentCustomSavedPMFailure = "mc_custom_payment_savedpm_failure" + case mcPaymentCustomApplePayFailure = "mc_custom_payment_applepay_failure" + case mcPaymentCustomLinkFailure = "mc_custom_payment_link_failure" + + case mcPaymentCompleteNewPMFailure = "mc_complete_payment_newpm_failure" + case mcPaymentCompleteSavedPMFailure = "mc_complete_payment_savedpm_failure" + case mcPaymentCompleteApplePayFailure = "mc_complete_payment_applepay_failure" + case mcPaymentCompleteLinkFailure = "mc_complete_payment_link_failure" + + // MARK: - PaymentSheet Option Selected + case mcOptionSelectCustomNewPM = "mc_custom_paymentoption_newpm_select" + case mcOptionSelectCustomSavedPM = "mc_custom_paymentoption_savedpm_select" + case mcOptionSelectCustomApplePay = "mc_custom_paymentoption_applepay_select" + case mcOptionSelectCustomLink = "mc_custom_paymentoption_link_select" + case mcOptionSelectCompleteNewPM = "mc_complete_paymentoption_newpm_select" + case mcOptionSelectCompleteSavedPM = "mc_complete_paymentoption_savedpm_select" + case mcOptionSelectCompleteApplePay = "mc_complete_paymentoption_applepay_select" + case mcOptionSelectCompleteLink = "mc_complete_paymentoption_link_select" + + // MARK: - Link Signup + case linkSignupCheckboxChecked = "link.signup.checkbox_checked" + case linkSignupFlowPresented = "link.signup.flow_presented" + case linkSignupStart = "link.signup.start" + case linkSignupComplete = "link.signup.complete" + case linkSignupFailure = "link.signup.failure" + + // MARK: - Link 2FA + case link2FAStart = "link.2fa.start" + case link2FAStartFailure = "link.2fa.start_failure" + case link2FAComplete = "link.2fa.complete" + case link2FACancel = "link.2fa.cancel" + case link2FAFailure = "link.2fa.failure" + + // MARK: - Link Misc + case linkAccountLookupFailure = "link.account_lookup.failure" + + // MARK: - LUXE + case luxeSerializeFailure = "luxe_serialize_failure" + case luxeClientFilteredPaymentMethods = "luxe_client_filtered_payment_methods" + case luxeClientFilteredPaymentMethodsNone = "luxe_client_filtered_payment_methods_none" + + case luxeImageSelectorIconDownloaded = "luxe_image_selector_icon_downloaded" + case luxeImageSelectorIconFromBundle = "luxe_image_selector_icon_from_bundle" + case luxeImageSelectorIconNotFound = "luxe_image_selector_icon_not_found" + + // MARK: - Address Element + case addressShow = "mc_address_show" + case addressCompleted = "mc_address_completed" + + // MARK: - PaymentMethodMessagingView + case paymentMethodMessagingViewLoadSucceeded = "pmmv_load_succeeded" + case paymentMethodMessagingViewLoadFailed = "pmmv_load_failed" + case paymentMethodMessagingViewTapped = "pmmv_tapped" +} diff --git a/Pods/StripeCore/StripeCore/StripeCore/Source/Analytics/STPAnalyticsClient.swift b/Pods/StripeCore/StripeCore/StripeCore/Source/Analytics/STPAnalyticsClient.swift new file mode 100644 index 0000000..e083546 --- /dev/null +++ b/Pods/StripeCore/StripeCore/StripeCore/Source/Analytics/STPAnalyticsClient.swift @@ -0,0 +1,147 @@ +// +// STPAnalyticsClient.swift +// StripeCore +// +// Created by Ben Guo on 4/22/16. +// Copyright © 2016 Stripe, Inc. All rights reserved. +// + +import Foundation +import UIKit + +@_spi(STP) public protocol STPAnalyticsProtocol { + static var stp_analyticsIdentifier: String { get } +} + +@_spi(STP) public protocol STPAnalyticsClientProtocol { + func addClass(toProductUsageIfNecessary klass: T.Type) + func log(analytic: Analytic, apiClient: STPAPIClient) +} + +@_spi(STP) public class STPAnalyticsClient: NSObject, STPAnalyticsClientProtocol { + @objc public static let sharedClient = STPAnalyticsClient() + + @objc public var productUsage: Set = Set() + private var additionalInfoSet: Set = Set() + private(set) var urlSession: URLSession = URLSession( + configuration: StripeAPIConfiguration.sharedUrlSessionConfiguration + ) + + @objc public class func tokenType(fromParameters parameters: [AnyHashable: Any]) -> String? { + let parameterKeys = parameters.keys + + // Before SDK 23.0.0, this returned "card" for some Apple Pay payments. + if parameterKeys.contains("pk_token") { + return "apple_pay" + } + // these are currently mutually exclusive, so we can just run through and find the first match + let tokenTypes = ["account", "bank_account", "card", "pii", "cvc_update"] + if let type = tokenTypes.first(where: { parameterKeys.contains($0) }) { + return type + } + return nil + } + + public func addClass(toProductUsageIfNecessary klass: T.Type) { + objc_sync_enter(self) + _ = productUsage.insert(klass.stp_analyticsIdentifier) + objc_sync_exit(self) + } + + func addAdditionalInfo(_ info: String) { + _ = additionalInfoSet.insert(info) + } + + public func clearAdditionalInfo() { + additionalInfoSet.removeAll() + } + + // MARK: - Card Scanning + + @objc class func shouldCollectAnalytics() -> Bool { + #if targetEnvironment(simulator) + return false + #else + return NSClassFromString("XCTest") == nil + #endif + } + + public func additionalInfo() -> [String] { + return additionalInfoSet.sorted() + } + + func logPayload(_ payload: [String: Any]) { + #if DEBUG + NSLog("LOG ANALYTICS: \(payload)") + #endif + + guard type(of: self).shouldCollectAnalytics(), + let url = URL(string: "https://q.stripe.com") + else { + return + } + + var request = URLRequest(url: url) + request.stp_addParameters(toURL: payload) + let task: URLSessionDataTask = urlSession.dataTask(with: request as URLRequest) + task.resume() + } + + /// Creates a payload dictionary for the given analytic that includes the event name, + /// common payload, additional info, and product usage dictionary. + /// + /// - Parameters: + /// - analytic: The analytic to log. + /// - apiClient: The `STPAPIClient` instance with which this payload should be associated + /// (i.e. publishable key). Defaults to `STPAPIClient.shared`. + func payload(from analytic: Analytic, apiClient: STPAPIClient = .shared) -> [String: Any] { + var payload = commonPayload(apiClient) + + payload["event"] = analytic.event.rawValue + payload["additional_info"] = additionalInfo() + payload["product_usage"] = productUsage.sorted() + + // Attach error information if this is an error analytic + if let errorAnalytic = analytic as? ErrorAnalytic { + payload["error_dictionary"] = errorAnalytic.error.serializeForLogging() + } + + payload.merge(analytic.params) { (_, new) in new } + return payload + } + + /// Logs an analytic with a payload dictionary that includes the event name, common payload, + /// additional info, and product usage dictionary. + /// + /// - Parameters + /// - analytic: The analytic to log. + /// - apiClient: The `STPAPIClient` instance with which this payload should be associated + /// (i.e. publishable key). Defaults to `STPAPIClient.shared`. + public func log(analytic: Analytic, apiClient: STPAPIClient = .shared) { + logPayload(payload(from: analytic)) + } +} + +// MARK: - Helpers + +extension STPAnalyticsClient { + public func commonPayload(_ apiClient: STPAPIClient) -> [String: Any] { + var payload: [String: Any] = [:] + payload["bindings_version"] = StripeAPIConfiguration.STPSDKVersion + payload["analytics_ua"] = "analytics.stripeios-1.0" + let version = UIDevice.current.systemVersion + if !version.isEmpty { + payload["os_version"] = version + } + if let deviceType = STPDeviceUtils.deviceType { + payload["device_type"] = deviceType + } + payload["app_name"] = Bundle.stp_applicationName() ?? "" + payload["app_version"] = Bundle.stp_applicationVersion() ?? "" + payload["plugin_type"] = PluginDetector.shared.pluginType?.rawValue + payload["install"] = InstallMethod.current.rawValue + payload["publishable_key"] = apiClient.sanitizedPublishableKey ?? "unknown" + + return payload + } +} diff --git a/Pods/StripeCore/StripeCore/StripeCore/Source/Categories/Decimal+StripeCore.swift b/Pods/StripeCore/StripeCore/StripeCore/Source/Categories/Decimal+StripeCore.swift new file mode 100644 index 0000000..3acc025 --- /dev/null +++ b/Pods/StripeCore/StripeCore/StripeCore/Source/Categories/Decimal+StripeCore.swift @@ -0,0 +1,15 @@ +// +// Decimal+StripeCore.swift +// StripeCore +// +// Created by Mel Ludowise on 4/14/22. +// Copyright © 2022 Stripe, Inc. All rights reserved. +// + +import Foundation + +@_spi(STP) extension Decimal { + public var floatValue: Float { + return (self as NSDecimalNumber).floatValue + } +} diff --git a/Pods/StripeCore/StripeCore/StripeCore/Source/Categories/Dictionary+Stripe.swift b/Pods/StripeCore/StripeCore/StripeCore/Source/Categories/Dictionary+Stripe.swift new file mode 100644 index 0000000..2d84000 --- /dev/null +++ b/Pods/StripeCore/StripeCore/StripeCore/Source/Categories/Dictionary+Stripe.swift @@ -0,0 +1,69 @@ +// +// Dictionary+Stripe.swift +// StripeCore +// +// Created by David Estes on 10/18/21. +// Copyright © 2021 Stripe, Inc. All rights reserved. +// + +import Foundation + +extension Dictionary { + static func stp_deepMerge(old: Any, new: Any) throws -> Any { + if let oldDictionary = old as? [String: Any], + let newDictionary = new as? [String: Any] + { + return try oldDictionary.merging(newDictionary, uniquingKeysWith: stp_deepMerge) + } + return new + } + + /// Return the dictionary, minus any fields that also exist in + /// the passed dictionary. + func subtracting(_ subtractDict: Dictionary) -> Dictionary { + var newDict = self + for (key, value) in self { + if let equatableValue = value as? AnyHashable, + let equatableSubtractValue = subtractDict[key] as? AnyHashable + { + if equatableValue == equatableSubtractValue { + newDict.removeValue(forKey: key) + continue + } + } + if let dict1 = value as? Dictionary, + let dict2 = subtractDict[key] as? Dictionary + { + let subtractedDict = dict1.subtracting(dict2) + if subtractedDict.isEmpty { + newDict.removeValue(forKey: key) + } else { + newDict[key] = subtractedDict as? Value + } + } + } + return newDict + } +} + +extension Dictionary where Value == Any { + func jsonEncodeNestedDicts(options: JSONSerialization.WritingOptions = []) -> [Key: Any] { + return compactMapValues { value in + guard let dict = value as? Dictionary else { + return value + } + + // Note: An NSInvalidArgumentException can occur when the dict can't be + // serialized instead of throwing an error, resulting in an app crash. + // Call `isValidJSONObject` to ensure it's able to serialize the dict. + guard JSONSerialization.isValidJSONObject(dict), + let data = try? JSONSerialization.data(withJSONObject: dict, options: options) + else { + assertionFailure("Dictionary could not be serialized") + return nil + } + + return String(data: data, encoding: .utf8) + } + } +} diff --git a/Pods/StripeCore/StripeCore/StripeCore/Source/Categories/Enums+CustomStringConvertible.swift b/Pods/StripeCore/StripeCore/StripeCore/Source/Categories/Enums+CustomStringConvertible.swift new file mode 100644 index 0000000..09d0b19 --- /dev/null +++ b/Pods/StripeCore/StripeCore/StripeCore/Source/Categories/Enums+CustomStringConvertible.swift @@ -0,0 +1,29 @@ +// +// Enums+CustomStringConvertible.swift +// Stripe +// +// Autogenerated by generate_objc_enum_string_values.rb +// Copyright © 2021 Stripe, Inc. All rights reserved. +// + +/// :nodoc: +extension STPErrorCode: CustomStringConvertible { + public var description: String { + switch self { + case .apiError: + return "apiError" + case .authenticationError: + return "authenticationError" + case .cancellationError: + return "cancellationError" + case .cardError: + return "cardError" + case .connectionError: + return "connectionError" + case .ephemeralKeyDecodingError: + return "ephemeralKeyDecodingError" + case .invalidRequestError: + return "invalidRequestError" + } + } +} diff --git a/Pods/StripeCore/StripeCore/StripeCore/Source/Categories/NSArray+Stripe.swift b/Pods/StripeCore/StripeCore/StripeCore/Source/Categories/NSArray+Stripe.swift new file mode 100644 index 0000000..6915aaa --- /dev/null +++ b/Pods/StripeCore/StripeCore/StripeCore/Source/Categories/NSArray+Stripe.swift @@ -0,0 +1,18 @@ +// +// NSArray+Stripe.swift +// StripeCore +// +// Created by Jack Flintermann on 1/19/16. +// Copyright © 2016 Stripe, Inc. All rights reserved. +// + +import Foundation + +@_spi(STP) extension Array { + public func stp_boundSafeObject(at index: Int) -> Element? { + if index + 1 > count || index < 0 { + return nil + } + return self[index] + } +} diff --git a/Pods/StripeCore/StripeCore/StripeCore/Source/Categories/NSBundle+Stripe_AppName.swift b/Pods/StripeCore/StripeCore/StripeCore/Source/Categories/NSBundle+Stripe_AppName.swift new file mode 100644 index 0000000..0c45969 --- /dev/null +++ b/Pods/StripeCore/StripeCore/StripeCore/Source/Categories/NSBundle+Stripe_AppName.swift @@ -0,0 +1,32 @@ +// +// NSBundle+Stripe_AppName.swift +// StripeCore +// +// Created by Jack Flintermann on 4/20/16. +// Copyright © 2016 Stripe, Inc. All rights reserved. +// + +import Foundation + +extension Bundle { + @_spi(STP) public class func stp_applicationName() -> String? { + return self.main.infoDictionary?[kCFBundleNameKey as String] as? String + } + + @_spi(STP) public class func stp_applicationVersion() -> String? { + return self.main.infoDictionary?["CFBundleShortVersionString"] as? String + } + + @_spi(STP) public class func stp_applicationBundleId() -> String? { + return self.main.bundleIdentifier + } + + @_spi(STP) public class func buildVersion() -> String? { + return self.main.infoDictionary?["CFBundleVersion"] as? String + } + + @_spi(STP) public class var displayName: String? { + return self.main.object(forInfoDictionaryKey: "CFBundleDisplayName") as? String ?? self.main + .object(forInfoDictionaryKey: "CFBundleName") as? String + } +} diff --git a/Pods/StripeCore/StripeCore/StripeCore/Source/Categories/NSCharacterSet+StripeCore.swift b/Pods/StripeCore/StripeCore/StripeCore/Source/Categories/NSCharacterSet+StripeCore.swift new file mode 100644 index 0000000..c0b8e33 --- /dev/null +++ b/Pods/StripeCore/StripeCore/StripeCore/Source/Categories/NSCharacterSet+StripeCore.swift @@ -0,0 +1,21 @@ +// +// NSCharacterSet+StripeCore.swift +// StripeCore +// +// Created by Brian Dorfman on 6/9/17. +// Copyright © 2017 Stripe, Inc. All rights reserved. +// + +import Foundation + +@_spi(STP) extension CharacterSet { + public static let stp_asciiDigit = CharacterSet(charactersIn: "0123456789") + public static let stp_asciiLetters = CharacterSet( + charactersIn: "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" + ) + public static let stp_invertedAsciiDigit = stp_asciiDigit.inverted + public static let stp_postalCode = CharacterSet( + charactersIn: "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789- " + ) + public static let stp_invertedPostalCode = stp_postalCode.inverted +} diff --git a/Pods/StripeCore/StripeCore/StripeCore/Source/Categories/NSError+Stripe.swift b/Pods/StripeCore/StripeCore/StripeCore/Source/Categories/NSError+Stripe.swift new file mode 100644 index 0000000..41b3209 --- /dev/null +++ b/Pods/StripeCore/StripeCore/StripeCore/Source/Categories/NSError+Stripe.swift @@ -0,0 +1,135 @@ +// +// NSError+Stripe.swift +// StripeCore +// +// Created by Brian Dorfman on 8/4/17. +// Copyright © 2017 Stripe, Inc. All rights reserved. +// + +import Foundation + +extension NSError { + @objc @_spi(STP) public class func stp_genericConnectionError() -> NSError { + let userInfo = [ + NSLocalizedDescriptionKey: self.stp_unexpectedErrorMessage(), + STPError.errorMessageKey: "There was an error connecting to Stripe.", + ] + return NSError( + domain: STPError.stripeDomain, + code: STPErrorCode.connectionError.rawValue, + userInfo: userInfo + ) + } + + @objc @_spi(STP) public class func stp_genericFailedToParseResponseError() -> NSError { + let userInfo = [ + NSLocalizedDescriptionKey: self.stp_unexpectedErrorMessage(), + STPError.errorMessageKey: + "The response from Stripe failed to get parsed into valid JSON.", + ] + return NSError( + domain: STPError.stripeDomain, + code: STPErrorCode.apiError.rawValue, + userInfo: userInfo + ) + } + + @objc @_spi(STP) public class func stp_ephemeralKeyDecodingError() -> NSError { + let userInfo = [ + NSLocalizedDescriptionKey: self.stp_unexpectedErrorMessage(), + STPError.errorMessageKey: + "Failed to decode the ephemeral key. Make sure your backend is sending the unmodified JSON of the ephemeral key to your app.", + ] + return NSError( + domain: STPError.stripeDomain, + code: STPErrorCode.ephemeralKeyDecodingError.rawValue, + userInfo: userInfo + ) + } + + @objc @_spi(STP) public class func stp_clientSecretError() -> NSError { + let userInfo = [ + NSLocalizedDescriptionKey: self.stp_unexpectedErrorMessage(), + STPError.errorMessageKey: + "The `secret` format does not match expected client secret formatting.", + ] + return NSError( + domain: STPError.stripeDomain, + code: STPErrorCode.invalidRequestError.rawValue, + userInfo: userInfo + ) + } + + // TODO(davide): We'll want to move these into StripePayments, once it exists. + + // MARK: Strings + @objc @_spi(STP) public class func stp_cardErrorInvalidNumberUserMessage() -> String { + return STPLocalizedString( + "Your card's number is invalid", + "Error when the card number is not valid" + ) + } + + @objc @_spi(STP) public class func stp_cardInvalidCVCUserMessage() -> String { + return STPLocalizedString( + "Your card's security code is invalid", + "Error when the card's CVC is not valid" + ) + } + + @objc @_spi(STP) public class func stp_cardErrorInvalidExpMonthUserMessage() -> String { + return STPLocalizedString( + "Your card's expiration month is invalid", + "Error when the card's expiration month is not valid" + ) + } + + @objc @_spi(STP) public class func stp_cardErrorInvalidExpYearUserMessage() -> String { + return STPLocalizedString( + "Your card's expiration year is invalid", + "Error when the card's expiration year is not valid" + ) + } + + @objc @_spi(STP) public class func stp_cardErrorExpiredCardUserMessage() -> String { + return STPLocalizedString( + "Your card has expired", + "Error when the card has already expired" + ) + } + + @objc @_spi(STP) public class func stp_cardErrorDeclinedUserMessage() -> String { + return STPLocalizedString( + "Your card was declined", + "Error when the card was declined by the credit card networks" + ) + } + + @objc @_spi(STP) public class func stp_genericDeclineErrorUserMessage() -> String { + return STPLocalizedString( + "Your payment method was declined.", + "Error message when a payment method gets declined." + ) + } + + @objc @_spi(STP) public class func stp_cardErrorProcessingErrorUserMessage() -> String { + return STPLocalizedString( + "There was an error processing your card -- try again in a few seconds", + "Error when there is a problem processing the credit card" + ) + } + + @_spi(STP) public static var stp_invalidOwnerName: String { + return STPLocalizedString( + "Your name is invalid.", + "Error when customer's name is invalid" + ) + } + + @_spi(STP) public static var stp_invalidBankAccountIban: String { + return STPLocalizedString( + "The IBAN you entered is invalid.", + "An error message displayed when the customer's iban is invalid." + ) + } +} diff --git a/Pods/StripeCore/StripeCore/StripeCore/Source/Categories/NSError+StripeCore.swift b/Pods/StripeCore/StripeCore/StripeCore/Source/Categories/NSError+StripeCore.swift new file mode 100644 index 0000000..5f3cbec --- /dev/null +++ b/Pods/StripeCore/StripeCore/StripeCore/Source/Categories/NSError+StripeCore.swift @@ -0,0 +1,18 @@ +// +// NSError+StripeCore.swift +// StripeCore +// +// Created by Mel Ludowise on 7/7/21. +// Copyright © 2021 Stripe, Inc. All rights reserved. +// + +import Foundation + +@_spi(STP) extension NSError { + public class func stp_unexpectedErrorMessage() -> String { + return STPLocalizedString( + "There was an unexpected error -- try again in a few seconds", + "Unexpected error, such as a 500 from Stripe or a JSON parse error" + ) + } +} diff --git a/Pods/StripeCore/StripeCore/StripeCore/Source/Categories/NSMutableURLRequest+Stripe.swift b/Pods/StripeCore/StripeCore/StripeCore/Source/Categories/NSMutableURLRequest+Stripe.swift new file mode 100644 index 0000000..7747824 --- /dev/null +++ b/Pods/StripeCore/StripeCore/StripeCore/Source/Categories/NSMutableURLRequest+Stripe.swift @@ -0,0 +1,43 @@ +// +// NSMutableURLRequest+Stripe.swift +// StripeCore +// +// Created by Ben Guo on 4/22/16. +// Copyright © 2016 Stripe, Inc. All rights reserved. +// + +import Foundation + +extension URLRequest { + @_spi(STP) public mutating func stp_addParameters(toURL parameters: [String: Any]) { + guard let url = url else { + assertionFailure() + return + } + let urlString = url.absoluteString + let query = URLEncoder.queryString(from: parameters) + self.url = URL(string: urlString + (url.query != nil ? "&\(query)" : "?\(query)")) + } + + @_spi(STP) public mutating func stp_setFormPayload(_ formPayload: [String: Any]) { + let formData = URLEncoder.queryString(from: formPayload).data(using: .utf8) + httpBody = formData + setValue( + String(format: "%lu", UInt(formData?.count ?? 0)), + forHTTPHeaderField: "Content-Length" + ) + setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type") + } + + @_spi(STP) public mutating func stp_setMultipartForm(_ data: Data?, boundary: String?) { + httpBody = data + setValue( + String(format: "%lu", UInt(data?.count ?? 0)), + forHTTPHeaderField: "Content-Length" + ) + setValue( + "multipart/form-data; boundary=\(boundary ?? "")", + forHTTPHeaderField: "Content-Type" + ) + } +} diff --git a/Pods/StripeCore/StripeCore/StripeCore/Source/Categories/NSURLComponents+Stripe.swift b/Pods/StripeCore/StripeCore/StripeCore/Source/Categories/NSURLComponents+Stripe.swift new file mode 100644 index 0000000..b0bb90c --- /dev/null +++ b/Pods/StripeCore/StripeCore/StripeCore/Source/Categories/NSURLComponents+Stripe.swift @@ -0,0 +1,63 @@ +// +// NSURLComponents+Stripe.swift +// StripeCore +// +// Created by Brian Dorfman on 1/26/17. +// Copyright © 2017 Stripe, Inc. All rights reserved. +// + +import Foundation + +extension NSURLComponents { + /// Returns or sets self.queryItems as a dictionary where all the keys are the item + /// names and the values are the values. + /// + /// When reading, if there are duplicate + /// names, earlier ones are overwritten by later ones. + @objc var stp_queryItemsDictionary: [String: String] { + get { + guard let queryItems = queryItems else { + return [:] + } + var queryItemsDict = [String: String]() + for queryItem in queryItems { + queryItemsDict[queryItem.name] = queryItem.value + } + return queryItemsDict + } + set(stp_queryItemsDictionary) { + var queryItems: [URLQueryItem] = [] + for (key, value) in stp_queryItemsDictionary { + queryItems.append(URLQueryItem(name: key, value: value)) + } + + self.queryItems = queryItems + } + } + + /// Returns YES if the passed in url matches self in scheme, host, and path, + /// AND all the query items in self are also in the passed + /// in components (as determined by `stp_queryItemsDictionary`) + /// This is used for URL routing style matching + /// - Parameter rhsComponents: The components to match against + /// - Returns: YES if there is a match, NO otherwise. + func stp_matchesURLComponents(_ rhsComponents: NSURLComponents) -> Bool { + var matches = + (scheme?.lowercased() == rhsComponents.scheme?.lowercased()) + && (host?.lowercased() == rhsComponents.host?.lowercased()) + && (path == rhsComponents.path) + + if matches { + let rhsQueryItems = rhsComponents.stp_queryItemsDictionary + + for queryItem in queryItems ?? [] { + if !(rhsQueryItems[queryItem.name] == queryItem.value) { + matches = false + break + } + } + } + + return matches + } +} diff --git a/Pods/StripeCore/StripeCore/StripeCore/Source/Categories/String+StripeCore.swift b/Pods/StripeCore/StripeCore/StripeCore/Source/Categories/String+StripeCore.swift new file mode 100644 index 0000000..43097f0 --- /dev/null +++ b/Pods/StripeCore/StripeCore/StripeCore/Source/Categories/String+StripeCore.swift @@ -0,0 +1,36 @@ +// +// String+StripeCore.swift +// StripeCore +// +// Created by Mel Ludowise on 9/16/21. +// Copyright © 2021 Stripe, Inc. All rights reserved. +// + +import Foundation + +@_spi(STP) extension String { + public func stp_stringByRemovingCharacters(from characterSet: CharacterSet) -> String { + return String(unicodeScalars.filter { !characterSet.contains($0) }) + } + + public var isSecretKey: Bool { + return self.hasPrefix("sk_") + } + + public var nonEmpty: String? { + stringIfHasContentsElseNil(self) + } +} + +@_spi(STP) public func stringIfHasContentsElseNil( + _ string: String? +) -> // MARK: - + String? +{ + guard let string = string, + !string.isEmpty + else { + return nil + } + return string +} diff --git a/Pods/StripeCore/StripeCore/StripeCore/Source/Categories/UIImage+StripeCore.swift b/Pods/StripeCore/StripeCore/StripeCore/Source/Categories/UIImage+StripeCore.swift new file mode 100644 index 0000000..59eb975 --- /dev/null +++ b/Pods/StripeCore/StripeCore/StripeCore/Source/Categories/UIImage+StripeCore.swift @@ -0,0 +1,160 @@ +// +// UIImage+StripeCore.swift +// StripeCore +// +// Created by Brian Dorfman on 4/25/17. +// Copyright © 2017 Stripe, Inc. All rights reserved. +// +import AVFoundation +import UIKit + +@_spi(STP) public typealias ImageDataAndSize = (imageData: Data, imageSize: CGSize) + +extension UIImage { + @_spi(STP) public static let defaultCompressionQuality: CGFloat = 0.5 + + /// Encodes the image to jpeg at the specified compression quality. + /// + /// The image will be scaled down, if needed, to ensure its size does not exceed `maxBytes`. + /// + /// - Parameters: + /// - maxBytes: The maximum size of the allowed file. If value is nil, then + /// the image will not be scaled down. + /// - compressionQuality: The compression quality to use when encoding the jpeg. + /// - Returns: A tuple containing the following properties. + /// - `imageData`: Data object of the jpeg encoded image. + /// - `imageSize`: The dimensions of the the image that was encoded. + /// This size may be smaller than the original image size if the image + /// needed to be scaled down to fit the specified `maxBytes`. + @_spi(STP) public func jpegDataAndDimensions( + maxBytes: Int? = nil, + compressionQuality: CGFloat = defaultCompressionQuality + ) -> ImageDataAndSize { + dataAndDimensions(maxBytes: maxBytes, compressionQuality: compressionQuality) { + image, + quality in + image.jpegData(compressionQuality: quality) + } + } + + /// Encodes the image to heic at the specified compression quality. + /// + /// The image will be scaled down, if needed, to ensure its size does not exceed `maxBytes`. + /// + /// - Parameters: + /// - maxBytes: The maximum size of the allowed file. If value is nil, then + /// the image will not be scaled down. + /// - compressionQuality: The compression quality to use when encoding the jpeg. + /// - Returns: A tuple containing the following properties. + /// - `imageData`: Data object of the jpeg encoded image. + /// - `imageSize`: The dimensions of the the image that was encoded. + /// This size may be smaller than the original image size if the image + /// needed to be scaled down to fit the specified `maxBytes`. + @_spi(STP) public func heicDataAndDimensions( + maxBytes: Int? = nil, + compressionQuality: CGFloat = defaultCompressionQuality + ) -> ImageDataAndSize { + dataAndDimensions(maxBytes: maxBytes, compressionQuality: compressionQuality) { + image, + quality in + image.heicData(compressionQuality: quality) + } + } + + @_spi(STP) public func resized(to scale: CGFloat) -> UIImage? { + let newImageSize = CGSize( + width: CGFloat(floor(size.width * scale)), + height: CGFloat(floor(size.height * scale)) + ) + UIGraphicsBeginImageContextWithOptions(newImageSize, false, self.scale) + + defer { + UIGraphicsEndImageContext() + } + + draw(in: CGRect(x: 0, y: 0, width: newImageSize.width, height: newImageSize.height)) + return UIGraphicsGetImageFromCurrentImageContext() + } + + private func heicData(compressionQuality: CGFloat = UIImage.defaultCompressionQuality) -> Data? + { + [self].heicData(compressionQuality: compressionQuality) + } + + private func dataAndDimensions( + maxBytes: Int? = nil, + compressionQuality: CGFloat = defaultCompressionQuality, + imageDataProvider: ((_ image: UIImage, _ quality: CGFloat) -> Data?) + ) -> ImageDataAndSize { + var imageData = imageDataProvider(self, compressionQuality) + + guard imageData != nil else { + return (imageData: Data(), imageSize: .zero) + } + + var newImageSize = self.size + + // Try something smarter first + if let maxBytes = maxBytes, + (imageData?.count ?? 0) > maxBytes + { + var scale = CGFloat(1.0) + + // Assuming jpeg file size roughly scales linearly with area of the image + // which is ~correct (although breaks down at really small file sizes) + let percentSmallerNeeded = CGFloat(maxBytes) / CGFloat((imageData?.count ?? 0)) + + // Shrink to a little bit less than we need to try to ensure we're under + // (otherwise its likely our first pass will be over the limit due to + // compression variance and floating point rounding) + scale = scale * (percentSmallerNeeded - (percentSmallerNeeded * 0.05)) + + repeat { + if let newImage = resized(to: scale) { + newImageSize = newImage.size + imageData = imageDataProvider(newImage, compressionQuality) + } + + // If the smart thing doesn't work, just start scaling down a bit on a loop until we get there + scale = scale * 0.7 + } while (imageData?.count ?? 0) > maxBytes + } + + return (imageData: imageData!, imageSize: newImageSize) + } +} + +extension Array where Element: UIImage { + @_spi(STP) public func heicData( + compressionQuality: CGFloat = UIImage.defaultCompressionQuality + ) -> Data? { + guard let mutableData = CFDataCreateMutable(nil, 0) else { + return nil + } + + guard + let destination = CGImageDestinationCreateWithData( + mutableData, + AVFileType.heic as CFString, + self.count, + nil + ) + else { + return nil + } + + let properties = + [kCGImageDestinationLossyCompressionQuality: compressionQuality] as CFDictionary + + for image in self { + let cgImage = image.cgImage! + CGImageDestinationAddImage(destination, cgImage, properties) + } + + if CGImageDestinationFinalize(destination) { + return mutableData as Data + } + + return nil + } +} diff --git a/Pods/StripeCore/StripeCore/StripeCore/Source/Coder/StripeCodable.swift b/Pods/StripeCore/StripeCore/StripeCore/Source/Coder/StripeCodable.swift new file mode 100644 index 0000000..c42d31b --- /dev/null +++ b/Pods/StripeCore/StripeCore/StripeCore/Source/Coder/StripeCodable.swift @@ -0,0 +1,172 @@ +// +// StripeCodable.swift +// StripeCore +// +// Created by David Estes on 7/20/21. +// Copyright © 2021 Stripe, Inc. All rights reserved. +// + +// This contains ~most of our custom encoding/decoding logic for handling unknown fields. +// +// It isn't intended for public use, but exposing objects with this protocol +// requires that we make the protocol itself public. +// + +import Foundation + +/// A Decodable object that retains unknown fields. +/// :nodoc: +public protocol UnknownFieldsDecodable: Decodable { + /// This should not be used directly. + /// Use the `allResponseFields` accessor instead. + /// :nodoc: + var _allResponseFieldsStorage: NonEncodableParameters? { get set } +} + +/// An Encodable object that allows unknown fields to be set. +/// :nodoc: +public protocol UnknownFieldsEncodable: Encodable { + /// This should not be used directly. + /// Use the `additionalParameters` accessor instead. + /// :nodoc: + var _additionalParametersStorage: NonEncodableParameters? { get set } +} + +/// A Codable enum that sets an "unparsable" case +/// instead of failing on values that are unknown to the SDK. +/// :nodoc: +public protocol SafeEnumCodable: Codable { + /// If the value is unparsable, the result will be available in + /// the `allResponseFields` of the parent object. + static var unparsable: Self { get } + + // It'd be nice to include the value of the unparsable enum + // as an associated value, but Swift can't auto-generate the Codable + // keys if we do that. +} + +extension UnknownFieldsDecodable { + /// A dictionary containing all response fields from the original JSON, + /// including unknown fields. + public internal(set) var allResponseFields: [String: Any] { + get { + self._allResponseFieldsStorage?.storage ?? [:] + } + set { + if self._allResponseFieldsStorage == nil { + self._allResponseFieldsStorage = NonEncodableParameters() + } + self._allResponseFieldsStorage!.storage = newValue + } + } + + static func decodedObject(jsonData: Data) throws -> Self { + return try StripeJSONDecoder.decode(jsonData: jsonData) + } +} + +extension UnknownFieldsEncodable { + /// You can use this property to add additional fields to an API request that + /// are not explicitly defined by the object's interface. + /// + /// This can be useful when using beta features that haven't been added to the Stripe SDK yet. + /// For example, if the /v1/tokens API began to accept a beta field called "test_field", + /// you might do the following: + /// + /// ```swift + /// var cardParams = PaymentMethodParams.Card() + /// // add card values + /// cardParams.additionalParameters = ["test_field": "example_value"] + /// PaymentsAPI.shared.createToken(withParameters: cardParams completion:...) + /// ``` + public var additionalParameters: [String: Any] { + get { + self._additionalParametersStorage?.storage ?? [:] + } + set { + if self._additionalParametersStorage == nil { + self._additionalParametersStorage = NonEncodableParameters() + } + self._additionalParametersStorage!.storage = newValue + } + } +} + +extension Encodable { + func encodeJSONDictionary(includingUnknownFields: Bool = true) throws -> [String: Any] { + let encoder = StripeJSONEncoder() + return try encoder.encodeJSONDictionary( + self, + includingUnknownFields: includingUnknownFields + ) + } +} + +@_spi(STP) public enum UnknownFieldsCodableFloats: String { + case PositiveInfinity = "Inf" + case NegativeInfinity = "-Inf" + case NaN = "nan" +} + +/// A protocol that conforms to both UnknownFieldsEncodable and UnknownFieldsDecodable. +/// :nodoc: +public protocol UnknownFieldsCodable: UnknownFieldsEncodable, UnknownFieldsDecodable {} + +/// This should not be used directly. +/// Use the `additionalParameters` and `allResponseFields` accessors instead. +/// :nodoc: +public struct NonEncodableParameters { + @_spi(STP) public internal(set) var storage: [String: Any] = [:] +} + +extension NonEncodableParameters: Decodable { + /// :nodoc: + public init( + from decoder: Decoder + ) throws { + // no-op + } +} + +extension NonEncodableParameters: Encodable { + /// :nodoc: + public func encode(to encoder: Encoder) throws { + // no-op + } +} + +extension NonEncodableParameters: Equatable { + /// :nodoc: + public static func == (lhs: NonEncodableParameters, rhs: NonEncodableParameters) -> Bool { + return NSDictionary(dictionary: lhs.storage).isEqual(to: rhs.storage) + } +} + +// The default debugging behavior for structs is to print *everything*, +// which is undesirable as it could contain card numbers or other PII. +// For now, override it to just give an overview of the struct. +extension NonEncodableParameters: CustomStringConvertible, CustomDebugStringConvertible, + CustomLeafReflectable +{ + /// :nodoc: + public var customMirror: Mirror { + return Mirror(reflecting: self.description) + } + + /// :nodoc: + public var debugDescription: String { + return description + } + + /// :nodoc: + public var description: String { + return "\(storage.count) fields" + } +} + +extension StripeJSONDecoder { + static func decode(jsonData: Data) throws -> T { + let decoder = StripeJSONDecoder() + return try decoder.decode(T.self, from: jsonData) + } +} diff --git a/Pods/StripeCore/StripeCore/StripeCore/Source/Coder/StripeJSONDecoder.swift b/Pods/StripeCore/StripeCore/StripeCore/Source/Coder/StripeJSONDecoder.swift new file mode 100644 index 0000000..066c948 --- /dev/null +++ b/Pods/StripeCore/StripeCore/StripeCore/Source/Coder/StripeJSONDecoder.swift @@ -0,0 +1,710 @@ +// +// StripeJSONDecoder.swift +// StripeCore +// +// Copyright © 2022 Stripe, Inc. All rights reserved. +// +// This is a bridge between NSJSONSerialization and Decoder, including some Stripe-specific behavior. +// + +import Foundation + +@_spi(STP) public class StripeJSONDecoder { + @_spi(STP) public var userInfo: [CodingUserInfoKey: Any] = [:] + + @_spi(STP) public var inputFormatting: JSONSerialization.ReadingOptions = [] + + @_spi(STP) public func decode(_ type: T.Type, from data: Data) throws -> T + where T: Decodable { + var inputFormatting = self.inputFormatting + // We always allow fragments. (Though we mostly only use these for tests.) + inputFormatting.insert(.fragmentsAllowed) + let jsonObject: Any + do { + jsonObject = try JSONSerialization.jsonObject(with: data, options: inputFormatting) + } catch let error { + throw DecodingError.dataCorrupted( + .init( + codingPath: [], + debugDescription: "The given data was not valid JSON.", + underlyingError: error + ) + ) + } + guard let object = jsonObject as? NSObject else { + throw DecodingError.dataCorrupted( + .init( + codingPath: [], + debugDescription: "The given data could not be decoded from JSON.", + underlyingError: nil + ) + ) + } + let decoder = _stpinternal_JSONDecoder(jsonObject: object) + userInfo[UnknownFieldsDecodableSourceStorageKey] = data + decoder.userInfo = userInfo + let value: T = try decoder.castFromNSObject() + if var sdValue = value as? UnknownFieldsDecodable { + try sdValue.applyUnknownFieldDecodingTransforms(userInfo: userInfo, codingPath: []) + return sdValue as! T + } + return value + } +} + +private class _stpinternal_JSONDecoder: Decoder, STPDecodingContainerProtocol { + var userInfo: [CodingUserInfoKey: Any] = [:] + var codingPath: [CodingKey] = [] + var jsonObject: NSObject + + init( + jsonObject: NSObject + ) { + self.jsonObject = jsonObject + } + + func castFromNSObject() throws -> T where T: Decodable { + return try castFromNSObject(codingPath: codingPath, T.self, jsonObject) + } + + func container(keyedBy type: Key.Type) throws -> KeyedDecodingContainer + where Key: CodingKey { + guard let dict = jsonObject as? NSDictionary else { + throw DecodingError.typeMismatch( + NSDictionary.self, + .init( + codingPath: codingPath, + debugDescription: "KeyedContainer is not a dictionary", + underlyingError: nil + ) + ) + } + return KeyedDecodingContainer( + STPKeyedDecodingContainer( + codingPath: codingPath, + dict: dict, + allKeys: [], + userInfo: userInfo + ) + ) + } + + func unkeyedContainer() throws -> UnkeyedDecodingContainer { + var objectToDecode = jsonObject + + // The implementation of Codable encodes Dictionaries that have Keys that are not exactly + // `String.Type` or `Int.Type` as an `Array`. + // If we have a Dictionary that has Keys that derived from String we end up here. + // To solve this, just convert to an Array. + // see: https://github.com/apple/swift/blob/d2085d8b0ed69e40a10e555669bb6cc9b450d0b3/stdlib/public/core/Codable.swift.gyb#L1967 + // For the decoding see: https://github.com/apple/swift/blob/d2085d8b0ed69e40a10e555669bb6cc9b450d0b3/stdlib/public/core/Codable.swift.gyb#L2036 + // Interestingly the default implementation does not handle this which seems like a bug. + // See here: https://github.com/apple/swift-corelibs-foundation/blob/main/Sources/Foundation/JSONDecoder.swift + if let dict = objectToDecode as? NSDictionary { + let arrayCopy = NSMutableArray() + for (key, value) in dict { + arrayCopy.add(key) + arrayCopy.add(value) + } + + objectToDecode = arrayCopy + } + + guard let array = objectToDecode as? NSArray else { + throw DecodingError.typeMismatch( + NSArray.self, + .init( + codingPath: codingPath, + debugDescription: "UnkeyedContainer is not an array", + underlyingError: nil + ) + ) + } + return STPUnkeyedDecodingContainer(userInfo: userInfo, array: array, codingPath: codingPath) + } + + func singleValueContainer() throws -> SingleValueDecodingContainer { + return STPSingleValueDecodingContainer( + codingPath: codingPath, + userInfo: userInfo, + object: jsonObject + ) + } +} + +private protocol STPDecodingContainerProtocol { + var userInfo: [CodingUserInfoKey: Any] { + get set + } +} + +private struct STPKeyedDecodingContainer: STPDecodingContainerProtocol, + KeyedDecodingContainerProtocol +where K: CodingKey { + var codingPath: [CodingKey] + + var dict: NSDictionary + var allKeys: [K] + + var userInfo: [CodingUserInfoKey: Any] + + typealias Key = K + + func _dictionaryKey(from key: K) -> String { + let maintainExistingCase = userInfo[STPMaintainExistingCase] as? Bool ?? false + var key = key.stringValue + + if !maintainExistingCase { + key = URLEncoder.convertToSnakeCase(camelCase: key) + } + + return key + } + + func contains(_ key: K) -> Bool { + let key = _dictionaryKey(from: key) + return dict[key] != nil + } + + func _objectForKey(_ key: K) throws -> NSObject { + if !contains(key) { + throw DecodingError.keyNotFound( + key, + .init( + codingPath: codingPath, + debugDescription: "Key \(key) not found in \(codingPath)", + underlyingError: nil + ) + ) + } + + let key = _dictionaryKey(from: key) + return dict[key] as! NSObject + } + + func _decode(_ type: T.Type, forKey key: K) throws -> T where T: Decodable { + let newPath = codingPath + [key] + let value: T = try castFromNSObject(codingPath: newPath, type, _objectForKey(key)) + if var sdValue = value as? UnknownFieldsDecodable { + try sdValue.applyUnknownFieldDecodingTransforms(userInfo: userInfo, codingPath: newPath) + return sdValue as! T + } + return value + } + + func decodeNil(forKey key: K) throws -> Bool { + return (try _objectForKey(key) is NSNull) + } + + func decode(_ type: Bool.Type, forKey key: K) throws -> Bool { + return try _decode(type, forKey: key) + } + + func decode(_ type: String.Type, forKey key: K) throws -> String { + return try _decode(type, forKey: key) + } + + func decode(_ type: Double.Type, forKey key: K) throws -> Double { + return try _decode(type, forKey: key) + } + + func decode(_ type: Float.Type, forKey key: K) throws -> Float { + return try _decode(type, forKey: key) + } + + func decode(_ type: Int.Type, forKey key: K) throws -> Int { + return try _decode(type, forKey: key) + } + + func decode(_ type: Int8.Type, forKey key: K) throws -> Int8 { + return try _decode(type, forKey: key) + } + + func decode(_ type: Int16.Type, forKey key: K) throws -> Int16 { + return try _decode(type, forKey: key) + } + + func decode(_ type: Int32.Type, forKey key: K) throws -> Int32 { + return try _decode(type, forKey: key) + } + + func decode(_ type: Int64.Type, forKey key: K) throws -> Int64 { + return try _decode(type, forKey: key) + } + + func decode(_ type: UInt.Type, forKey key: K) throws -> UInt { + return try _decode(type, forKey: key) + } + + func decode(_ type: UInt8.Type, forKey key: K) throws -> UInt8 { + return try _decode(type, forKey: key) + } + + func decode(_ type: UInt16.Type, forKey key: K) throws -> UInt16 { + return try _decode(type, forKey: key) + } + + func decode(_ type: UInt32.Type, forKey key: K) throws -> UInt32 { + return try _decode(type, forKey: key) + } + + func decode(_ type: UInt64.Type, forKey key: K) throws -> UInt64 { + return try _decode(type, forKey: key) + } + + func decode(_ type: T.Type, forKey key: K) throws -> T where T: Decodable { + return try _decode(type, forKey: key) + } + + func nestedContainer( + keyedBy type: NestedKey.Type, + forKey key: K + ) throws -> KeyedDecodingContainer where NestedKey: CodingKey { + assertionFailure("nestedContainer(keyedBy:forKey:) is not implemented.") + return KeyedDecodingContainer( + STPKeyedDecodingContainer( + codingPath: [], + dict: NSMutableDictionary(), + allKeys: [], + userInfo: [:] + ) + ) + } + + func nestedUnkeyedContainer(forKey key: K) throws -> UnkeyedDecodingContainer { + assertionFailure("nestedUnkeyedContainer(forKey:) is not implemented.") + return STPUnkeyedDecodingContainer( + userInfo: [:], + array: NSArray(), + codingPath: [], + currentIndex: 0 + ) + } + + func superDecoder() throws -> Decoder { + assertionFailure("superDecoder() is not implemented.") + return _stpinternal_JSONDecoder(jsonObject: NSNull()) + } + + func superDecoder(forKey key: K) throws -> Decoder { + assertionFailure("superDecoder(forKey:) is not implemented.") + return _stpinternal_JSONDecoder(jsonObject: NSNull()) + } + +} + +private struct STPUnkeyedDecodingContainer: UnkeyedDecodingContainer, STPDecodingContainerProtocol { + var userInfo: [CodingUserInfoKey: Any] + + var array: NSArray + + var codingPath: [CodingKey] + + var count: Int? { + return array.count + } + + var isAtEnd: Bool { + return currentIndex >= count ?? 0 + } + + var currentIndex: Int = 0 + + mutating func _popObject() -> NSObject { + assert(!isAtEnd, "Tried to read past the end of the container.") + let object = array[currentIndex] as! NSObject + currentIndex += 1 + return object + } + + mutating func _decode(_ type: T.Type) throws -> T where T: Decodable { + let newPath = codingPath + [STPCodingKey(intValue: currentIndex)!] + + let value: T = try castFromNSObject(codingPath: newPath, type, _popObject()) + if var sdValue = value as? UnknownFieldsDecodable { + try sdValue.applyUnknownFieldDecodingTransforms(userInfo: userInfo, codingPath: newPath) + return sdValue as! T + } + return value + } + + mutating func decodeNil() throws -> Bool { + let object = _popObject() + return (object is NSNull) + } + + mutating func decode(_ type: Bool.Type) throws -> Bool { + return try _decode(type) + } + + mutating func decode(_ type: String.Type) throws -> String { + return try _decode(type) + } + + mutating func decode(_ type: Double.Type) throws -> Double { + return try _decode(type) + } + + mutating func decode(_ type: Float.Type) throws -> Float { + return try _decode(type) + } + + mutating func decode(_ type: Int.Type) throws -> Int { + return try _decode(type) + } + + mutating func decode(_ type: Int8.Type) throws -> Int8 { + return try _decode(type) + } + + mutating func decode(_ type: Int16.Type) throws -> Int16 { + return try _decode(type) + } + + mutating func decode(_ type: Int32.Type) throws -> Int32 { + return try _decode(type) + } + + mutating func decode(_ type: Int64.Type) throws -> Int64 { + return try _decode(type) + } + + mutating func decode(_ type: UInt.Type) throws -> UInt { + return try _decode(type) + } + + mutating func decode(_ type: UInt8.Type) throws -> UInt8 { + return try _decode(type) + } + + mutating func decode(_ type: UInt16.Type) throws -> UInt16 { + return try _decode(type) + } + + mutating func decode(_ type: UInt32.Type) throws -> UInt32 { + return try _decode(type) + } + + mutating func decode(_ type: UInt64.Type) throws -> UInt64 { + return try _decode(type) + } + + mutating func decode(_ type: T.Type) throws -> T where T: Decodable { + return try _decode(type) + } + + mutating func nestedContainer( + keyedBy type: NestedKey.Type + ) throws -> KeyedDecodingContainer where NestedKey: CodingKey { + assertionFailure("nestedContainer(keyedBy:) is not implemented.") + return KeyedDecodingContainer( + STPKeyedDecodingContainer( + codingPath: [], + dict: NSMutableDictionary(), + allKeys: [], + userInfo: [:] + ) + ) + } + + mutating func nestedUnkeyedContainer() throws -> UnkeyedDecodingContainer { + assertionFailure("nestedUnkeyedContainer(forKey:) is not implemented.") + return STPUnkeyedDecodingContainer(userInfo: [:], array: NSArray(), codingPath: []) + } + + mutating func superDecoder() throws -> Decoder { + assertionFailure("superDecoder() is not implemented.") + return _stpinternal_JSONDecoder(jsonObject: NSNull()) + } + +} + +private struct STPSingleValueDecodingContainer: SingleValueDecodingContainer, + STPDecodingContainerProtocol +{ + var codingPath: [CodingKey] + + var userInfo: [CodingUserInfoKey: Any] + + var object: NSObject + + func _decode(_ type: T.Type) throws -> T where T: Decodable { + let value: T = try castFromNSObject(codingPath: codingPath, type, object) + if var sdValue = value as? UnknownFieldsDecodable { + try sdValue.applyUnknownFieldDecodingTransforms( + userInfo: userInfo, + codingPath: codingPath + ) + return sdValue as! T + } + return value + } + + func decodeNil() -> Bool { + return object == NSNull() + } + + func decode(_ type: Bool.Type) throws -> Bool { + return try _decode(type) + } + + func decode(_ type: String.Type) throws -> String { + return try _decode(type) + } + + func decode(_ type: Double.Type) throws -> Double { + return try _decode(type) + } + + func decode(_ type: Float.Type) throws -> Float { + return try _decode(type) + } + + func decode(_ type: Int.Type) throws -> Int { + return try _decode(type) + } + + func decode(_ type: Int8.Type) throws -> Int8 { + return try _decode(type) + } + + func decode(_ type: Int16.Type) throws -> Int16 { + return try _decode(type) + } + + func decode(_ type: Int32.Type) throws -> Int32 { + return try _decode(type) + } + + func decode(_ type: Int64.Type) throws -> Int64 { + return try _decode(type) + } + + func decode(_ type: UInt.Type) throws -> UInt { + return try _decode(type) + } + + func decode(_ type: UInt8.Type) throws -> UInt8 { + return try _decode(type) + } + + func decode(_ type: UInt16.Type) throws -> UInt16 { + return try _decode(type) + } + + func decode(_ type: UInt32.Type) throws -> UInt32 { + return try _decode(type) + } + + func decode(_ type: UInt64.Type) throws -> UInt64 { + return try _decode(type) + } + + func decode(_ type: T.Type) throws -> T where T: Decodable { + return try _decode(type) + } + +} + +// MARK: Casting logic + +// These extensions help us maintain the type information for Arrays and Dictionaries within castFromNSObject, so that +// inner calls to castFromNSObject call the templated function without erasing the underlying type. +// I'm not sure if there's a cleaner way to do this... +private protocol _STPDecodableIsArray { + static var valueType: Decodable.Type { get } +} +extension Array: _STPDecodableIsArray where Element: Decodable { + static var valueType: Decodable.Type { return Element.self } +} +private protocol _STPDecodableIsDictionary { + static var valueType: Decodable.Type { get } +} +extension Dictionary: _STPDecodableIsDictionary where Key == String, Value: Decodable { + static var valueType: Decodable.Type { return Value.self } +} +extension Decodable { + fileprivate static func _castFromNSObject( + codingPath: [CodingKey] = [], + decodingContainer: STPDecodingContainerProtocol, + object: NSObject + ) throws -> Self { + return try decodingContainer.castFromNSObject(codingPath: codingPath, Self.self, object) + } +} + +extension STPDecodingContainerProtocol { + func castFromNSObject( + codingPath: [CodingKey] = [], + _ type: T.Type, + _ object: NSObject + ) throws -> T where T: Decodable { + switch type { + case is Double.Type: + switch object as? String { + case UnknownFieldsCodableFloats.PositiveInfinity.rawValue: + return Double.infinity as! T + case UnknownFieldsCodableFloats.NegativeInfinity.rawValue: + return -Double.infinity as! T + case UnknownFieldsCodableFloats.NaN.rawValue: + return Double.nan as! T + case .none, .some(_): + guard let value = object as? Double, let returnValue = value as? T else { + throw DecodingError.dataCorrupted( + .init( + codingPath: codingPath, + debugDescription: + "Parsed JSON number <\(object)> does not fit in \(type).", + underlyingError: nil + ) + ) + } + return returnValue + } + case is Float.Type: + switch object as? String { + case UnknownFieldsCodableFloats.PositiveInfinity.rawValue: + return Float.infinity as! T + case UnknownFieldsCodableFloats.NegativeInfinity.rawValue: + return -Float.infinity as! T + case UnknownFieldsCodableFloats.NaN.rawValue: + return Float.nan as! T + case .none, .some(_): + guard let value = object as? Float, let returnValue = value as? T else { + throw DecodingError.dataCorrupted( + .init( + codingPath: codingPath, + debugDescription: + "Parsed JSON number <\(object)> does not fit in \(type).", + underlyingError: nil + ) + ) + } + return returnValue + } + case is Bool.Type, + is Int.Type, + is Int8.Type, + is Int16.Type, + is Int32.Type, + is Int64.Type, + is UInt.Type, + is UInt8.Type, + is UInt16.Type, + is UInt32.Type, + is UInt64.Type, + is String.Type: + guard let value = object as? T else { + throw DecodingError.dataCorrupted( + .init( + codingPath: codingPath, + debugDescription: "Parsed JSON number <\(object)> does not fit in \(type).", + underlyingError: nil + ) + ) + } + return value + case is Decimal.Type: + guard let decimal = (object as? NSNumber)?.decimalValue else { + throw DecodingError.dataCorrupted( + .init( + codingPath: codingPath, + debugDescription: "Could not convert <\(object)> to \(type).", + underlyingError: nil + ) + ) + } + return decimal as! T + case is URL.Type: + guard let string = object as? String, let url = URL(string: string) else { + throw DecodingError.dataCorrupted( + .init( + codingPath: codingPath, + debugDescription: "Could not convert <\(object)> to \(type).", + underlyingError: nil + ) + ) + } + return url as! T + case is Data.Type: + guard let string = object as? String, let data = Data(base64Encoded: string) else { + throw DecodingError.dataCorrupted( + .init( + codingPath: codingPath, + debugDescription: "Could not convert <\(object)> to \(type).", + underlyingError: nil + ) + ) + } + return data as! T + case is Date.Type: + guard let ti = object as? TimeInterval else { + throw DecodingError.dataCorrupted( + .init( + codingPath: codingPath, + debugDescription: "Could not convert <\(object)> to \(type).", + underlyingError: nil + ) + ) + } + return Date(timeIntervalSince1970: ti) as! T + case is _STPDecodableIsDictionary.Type: + guard let dict = object as? [String: Any] else { + throw DecodingError.dataCorrupted( + .init( + codingPath: codingPath, + debugDescription: "Could not convert <\(object)> to \(type).", + underlyingError: nil + ) + ) + } + var convertedDict: [String: Any] = [:] + for (k, v) in dict { + let dictType = T.self as! (_STPDecodableIsDictionary.Type) + convertedDict[k] = try dictType.valueType._castFromNSObject( + codingPath: codingPath, + decodingContainer: self, + object: v as! NSObject + ) + } + return convertedDict as! T + case is _STPDecodableIsArray.Type: + guard let array = object as? [Any] else { + throw DecodingError.dataCorrupted( + .init( + codingPath: codingPath, + debugDescription: "Could not convert <\(object)> to \(type).", + underlyingError: nil + ) + ) + } + var convertedArray: [Any] = [] + for i in array { + let arrayType = T.self as! (_STPDecodableIsArray.Type) + convertedArray.append( + try arrayType.valueType._castFromNSObject( + codingPath: codingPath, + decodingContainer: self, + object: i as! NSObject + ) + ) + } + return convertedArray as! T + case is SafeEnumCodable.Type: + do { + let decoder = _stpinternal_JSONDecoder(jsonObject: object) + decoder.userInfo = userInfo + decoder.codingPath = codingPath + return try T(from: decoder) + } catch Swift.DecodingError.dataCorrupted { + let enumCodableType = T.self as! (SafeEnumCodable.Type) + return enumCodableType.unparsable as! T + } + default: + let decoder = _stpinternal_JSONDecoder(jsonObject: object) + decoder.userInfo = userInfo + decoder.codingPath = codingPath + return try T(from: decoder) + } + } +} diff --git a/Pods/StripeCore/StripeCore/StripeCore/Source/Coder/StripeJSONEncoder.swift b/Pods/StripeCore/StripeCore/StripeCore/Source/Coder/StripeJSONEncoder.swift new file mode 100644 index 0000000..8e9638a --- /dev/null +++ b/Pods/StripeCore/StripeCore/StripeCore/Source/Coder/StripeJSONEncoder.swift @@ -0,0 +1,564 @@ +// +// StripeJSONEncoder.swift +// StripeCore +// +// Copyright © 2022 Stripe, Inc. All rights reserved. +// +// This is a bridge between NSJSONSerialization and Encoder, including some Stripe-specific behavior. +// + +import Foundation + +@_spi(STP) public class StripeJSONEncoder { + @_spi(STP) public var userInfo: [CodingUserInfoKey: Any] = [:] + + @_spi(STP) public var outputFormatting: JSONSerialization.WritingOptions = [] + + @_spi(STP) public func encode(_ value: T, includingUnknownFields: Bool = true) throws -> Data + where T: Encodable { + var outputFormatting = self.outputFormatting + outputFormatting.insert(.fragmentsAllowed) + + if value is UnknownFieldsEncodable { + let jsonDictionary = try self.encodeJSONDictionary( + value, + includingUnknownFields: includingUnknownFields + ) + return try JSONSerialization.data( + withJSONObject: jsonDictionary, + options: outputFormatting + ) + } else { + return try JSONSerialization.data( + withJSONObject: castToNSObject(value), + options: outputFormatting + ) + } + } + + @_spi(STP) public func encodeJSONDictionary( + _ value: T, + includingUnknownFields: Bool = true + ) throws -> [String: Any] where T: Encodable { + var outputFormatting = self.outputFormatting + outputFormatting.insert(.fragmentsAllowed) + + // Set up a dictionary on the encoder to fill with additionalAPIParameters during encoding + let dictionary = NSMutableDictionary() + userInfo[UnknownFieldsEncodableSourceStorageKey] = dictionary + userInfo[StripeIncludeUnknownFieldsKey] = includingUnknownFields + + if let seValue = value as? UnknownFieldsEncodable { + // Encode the top-level additionalAPIParameters into the userInfo + seValue.applyUnknownFieldEncodingTransforms(userInfo: userInfo, codingPath: []) + } + + // Encode the object to JSON data + let jsonData = try JSONSerialization.data( + withJSONObject: castToNSObject(value), + options: outputFormatting + ) + + // Convert the JSON data into a JSON dictionary + var jsonDictionary = + try JSONSerialization.jsonObject(with: jsonData, options: []) as! [String: Any] + + // Merge in the additional parameters we collected in our encoder userInfo's NSMutableDictionary during encoding + try jsonDictionary.merge( + dictionary as! [String: Any], + uniquingKeysWith: Dictionary.stp_deepMerge + ) + + return jsonDictionary + } +} + +// Make sure StripeJSONEncoder can call castToNSObject +extension StripeJSONEncoder: StripeEncodingContainer {} + +class _stpinternal_JSONEncoder: Encoder { + var codingPath: [CodingKey] = [] + + var userInfo: [CodingUserInfoKey: Any] = [:] + + enum ContainerValue { + case dict(NSMutableDictionary) + case array(NSMutableArray) + case singleValue(NSObject) + } + + private var container: ContainerValue? + + func container(keyedBy type: Key.Type) -> KeyedEncodingContainer + where Key: CodingKey { + let dict = NSMutableDictionary() + self.container = .dict(dict) + return KeyedEncodingContainer( + STPKeyedEncodingContainer(codingPath: codingPath, dict: dict, userInfo: userInfo) + ) + } + + func unkeyedContainer() -> UnkeyedEncodingContainer { + // We've been asked for an array, so initialize a top-level empty array to handle the case of an empty array. + let array = NSMutableArray() + self.container = .array(array) + return STPUnkeyedEncodingContainer(codingPath: codingPath, array: array, userInfo: userInfo) + } + + func singleValueContainer() -> SingleValueEncodingContainer { + self.container = .singleValue(NSNull()) + return STPSingleValueEncodingContainer( + codingPath: codingPath, + encodingBlock: { self.container = .singleValue($0) }, + userInfo: userInfo + ) + } + + /// Return the NSObject contained by this encoder: Either a dictionary, an array, or a single object. + var singleContainer: NSObject { + guard let container = container else { + assertionFailure("Called singleContainer on an empty decoder") + return NSNull() + } + switch container { + case .dict(let dict): + return dict + case .array(let array): + return array + case .singleValue(let singleValue): + return singleValue + } + } +} + +struct STPKeyedEncodingContainer: StripeEncodingContainer, KeyedEncodingContainerProtocol +where K: CodingKey { + var codingPath: [CodingKey] + + typealias Key = K + + var dict: NSMutableDictionary + var userInfo: [CodingUserInfoKey: Any] + + mutating private func encode(object: NSObject, forKey key: K) throws { + let maintainExistingCase = userInfo[STPMaintainExistingCase] as? Bool ?? false + + let stringKey = key.stringValue + let key = + maintainExistingCase ? stringKey : URLEncoder.convertToSnakeCase(camelCase: stringKey) + + dict[key] = object + } + + mutating func encodeNil(forKey key: K) throws { + try encode(object: NSNull(), forKey: key) + } + + mutating func encode(_ value: Bool, forKey key: K) throws { + try encode(object: castToNSObject(value), forKey: key) + } + + mutating func encode(_ value: String, forKey key: K) throws { + try encode(object: castToNSObject(value), forKey: key) + } + + mutating func encode(_ value: Double, forKey key: K) throws { + try encode(object: castToNSObject(value), forKey: key) + } + + mutating func encode(_ value: Float, forKey key: K) throws { + try encode(object: castToNSObject(value), forKey: key) + } + + mutating func encode(_ value: Int, forKey key: K) throws { + try encode(object: castToNSObject(value), forKey: key) + } + + mutating func encode(_ value: Int8, forKey key: K) throws { + try encode(object: castToNSObject(value), forKey: key) + } + + mutating func encode(_ value: Int16, forKey key: K) throws { + try encode(object: castToNSObject(value), forKey: key) + } + + mutating func encode(_ value: Int32, forKey key: K) throws { + try encode(object: castToNSObject(value), forKey: key) + } + + mutating func encode(_ value: Int64, forKey key: K) throws { + try encode(object: castToNSObject(value), forKey: key) + } + + mutating func encode(_ value: UInt, forKey key: K) throws { + try encode(object: castToNSObject(value), forKey: key) + } + + mutating func encode(_ value: UInt8, forKey key: K) throws { + try encode(object: castToNSObject(value), forKey: key) + } + + mutating func encode(_ value: UInt16, forKey key: K) throws { + try encode(object: castToNSObject(value), forKey: key) + } + + mutating func encode(_ value: UInt32, forKey key: K) throws { + try encode(object: castToNSObject(value), forKey: key) + } + + mutating func encode(_ value: UInt64, forKey key: K) throws { + try encode(object: castToNSObject(value), forKey: key) + } + + mutating func encode(_ value: T, forKey key: K) throws where T: Encodable { + if value is NonEncodableParameters { + // Don't encode this + return + } + let newPath = codingPath + [key] + if let seValue = value as? UnknownFieldsEncodable { + seValue.applyUnknownFieldEncodingTransforms(userInfo: userInfo, codingPath: newPath) + } + try encode(object: castToNSObject(codingPath: newPath, value), forKey: key) + } + + mutating func nestedContainer( + keyedBy keyType: NestedKey.Type, + forKey key: K + ) -> KeyedEncodingContainer where NestedKey: CodingKey { + // This is messy to support and we don't have any situations + // in the Stripe SDK where we want to use it. The implementation + // would probably look similar to superEncoder() above. + assertionFailure("nestedContainer(keyedBy:) is not implemented.") + return KeyedEncodingContainer( + STPKeyedEncodingContainer( + codingPath: codingPath + [key], + dict: NSMutableDictionary(), + userInfo: userInfo + ) + ) + } + + mutating func nestedUnkeyedContainer(forKey key: K) -> UnkeyedEncodingContainer { + // This is messy to support and we don't have any situations + // in the Stripe SDK where we want to use it. The implementation + // would probably look similar to superEncoder() above. + assertionFailure("nestedUnkeyedContainer(forKey:) is not implemented.") + return STPUnkeyedEncodingContainer( + codingPath: codingPath + [key], + array: NSMutableArray(), + userInfo: userInfo + ) + } + + mutating func superEncoder() -> Encoder { + // See above superEncoder() comment. + assertionFailure("superEncoder() is not implemented.") + return _stpinternal_JSONEncoder() + } + + mutating func superEncoder(forKey key: K) -> Encoder { + // See above superEncoder() comment. + assertionFailure("superEncoder(forKey:) is not implemented.") + return _stpinternal_JSONEncoder() + } +} + +struct STPUnkeyedEncodingContainer: UnkeyedEncodingContainer, StripeEncodingContainer { + var codingPath: [CodingKey] + + var count: Int = 0 + + var array: NSMutableArray + var userInfo: [CodingUserInfoKey: Any] + + mutating func encodeNil() throws { + array.add(NSNull()) + count += 1 + } + + mutating func encode(_ value: Bool) throws { + try array.add(castToNSObject(value)) + count += 1 + } + + mutating func encode(_ value: String) throws { + try array.add(castToNSObject(value)) + count += 1 + } + + mutating func encode(_ value: Double) throws { + try array.add(castToNSObject(value)) + count += 1 + } + + mutating func encode(_ value: Float) throws { + try array.add(castToNSObject(value)) + count += 1 + } + + mutating func encode(_ value: Int) throws { + try array.add(castToNSObject(value)) + count += 1 + } + + mutating func encode(_ value: Int8) throws { + try array.add(castToNSObject(value)) + count += 1 + } + + mutating func encode(_ value: Int16) throws { + try array.add(castToNSObject(value)) + count += 1 + } + + mutating func encode(_ value: Int32) throws { + try array.add(castToNSObject(value)) + count += 1 + } + + mutating func encode(_ value: Int64) throws { + try array.add(castToNSObject(value)) + count += 1 + } + + mutating func encode(_ value: UInt) throws { + try array.add(castToNSObject(value)) + count += 1 + } + + mutating func encode(_ value: UInt8) throws { + try array.add(castToNSObject(value)) + count += 1 + } + + mutating func encode(_ value: UInt16) throws { + try array.add(castToNSObject(value)) + count += 1 + } + + mutating func encode(_ value: UInt32) throws { + try array.add(castToNSObject(value)) + count += 1 + } + + mutating func encode(_ value: UInt64) throws { + try array.add(castToNSObject(value)) + count += 1 + } + + mutating func encode(_ value: T) throws where T: Encodable { + if value is NonEncodableParameters { + // Don't encode this + return + } + let newPath = codingPath + [STPCodingKey(intValue: count)!] + if let seValue = value as? UnknownFieldsEncodable { + seValue.applyUnknownFieldEncodingTransforms(userInfo: userInfo, codingPath: newPath) + } + try array.add(castToNSObject(codingPath: newPath, value)) + + count += 1 + } + + mutating func nestedContainer( + keyedBy keyType: NestedKey.Type + ) -> KeyedEncodingContainer where NestedKey: CodingKey { + // This is messy to support and we don't have any situations + // in the Stripe SDK where we want to use it. The implementation + // would probably look similar to superEncoder() below. + assertionFailure("nestedContainer(keyedBy:) is not implemented.") + return KeyedEncodingContainer( + STPKeyedEncodingContainer( + codingPath: codingPath, + dict: NSMutableDictionary(), + userInfo: userInfo + ) + ) + } + + mutating func nestedUnkeyedContainer() -> UnkeyedEncodingContainer { + // This is messy to support and we don't have any situations + // in the Stripe SDK where we want to use it. The implementation + // would probably look similar to superEncoder() below. + assertionFailure("nestedUnkeyedContainer() is not implemented.") + return STPUnkeyedEncodingContainer( + codingPath: codingPath, + array: NSMutableArray(), + userInfo: userInfo + ) + } + + mutating func superEncoder() -> Encoder { + // Super-encoding is messy and we don't have any situations in + // the Stripe SDK where a Codable inherits from another Codable. + // If you'd like to implement this, see + // https://forums.swift.org/t/writing-encoders-and-decoders-different-question/10232/5 + // for details. + assertionFailure("superEncoder() is not implemented.") + return _stpinternal_JSONEncoder() + } + +} + +struct STPSingleValueEncodingContainer: SingleValueEncodingContainer, StripeEncodingContainer { + var codingPath: [CodingKey] + + var encodingBlock: (NSObject) -> Void + var userInfo: [CodingUserInfoKey: Any] + + mutating func encodeNil() throws { + encodingBlock(NSNull()) + } + + mutating func encode(_ value: Bool) throws { + encodingBlock(try castToNSObject(value)) + } + + mutating func encode(_ value: String) throws { + encodingBlock(try castToNSObject(value)) + } + + mutating func encode(_ value: Double) throws { + encodingBlock(try castToNSObject(value)) + } + + mutating func encode(_ value: Float) throws { + encodingBlock(try castToNSObject(value)) + } + + mutating func encode(_ value: Int) throws { + encodingBlock(try castToNSObject(value)) + } + + mutating func encode(_ value: Int8) throws { + encodingBlock(try castToNSObject(value)) + } + + mutating func encode(_ value: Int16) throws { + encodingBlock(try castToNSObject(value)) + } + + mutating func encode(_ value: Int32) throws { + encodingBlock(try castToNSObject(value)) + } + + mutating func encode(_ value: Int64) throws { + encodingBlock(try castToNSObject(value)) + } + + mutating func encode(_ value: UInt) throws { + encodingBlock(try castToNSObject(value)) + } + + mutating func encode(_ value: UInt8) throws { + encodingBlock(try castToNSObject(value)) + } + + mutating func encode(_ value: UInt16) throws { + encodingBlock(try castToNSObject(value)) + } + + mutating func encode(_ value: UInt32) throws { + encodingBlock(try castToNSObject(value)) + } + + mutating func encode(_ value: UInt64) throws { + encodingBlock(try castToNSObject(value)) + } + + mutating func encode(_ value: T) throws where T: Encodable { + if value is NonEncodableParameters { + // Don't encode this + return + } + if let seValue = value as? UnknownFieldsEncodable { + seValue.applyUnknownFieldEncodingTransforms(userInfo: userInfo, codingPath: codingPath) + } + encodingBlock(try castToNSObject(value)) + } +} + +protocol StripeEncodingContainer { + var userInfo: [CodingUserInfoKey: Any] { + get set + } +} + +extension StripeEncodingContainer { + fileprivate func castToNSObject(codingPath: [CodingKey] = [], _ value: T) throws -> NSObject + where T: Encodable { + switch value { + case let n as Bool: + return n as NSObject + case let n as String: + return n as NSObject + case let n as Double: + if n == .infinity { + return UnknownFieldsCodableFloats.PositiveInfinity.rawValue as NSObject + } + if n == -.infinity { + return UnknownFieldsCodableFloats.NegativeInfinity.rawValue as NSObject + } + if n.isNaN { + return UnknownFieldsCodableFloats.NaN.rawValue as NSObject + } + return n as NSObject + case let n as Float: + if n == .infinity { + return UnknownFieldsCodableFloats.PositiveInfinity.rawValue as NSObject + } + if n == -.infinity { + return UnknownFieldsCodableFloats.NegativeInfinity.rawValue as NSObject + } + if n.isNaN { + return UnknownFieldsCodableFloats.NaN.rawValue as NSObject + } + return n as NSObject + case let n as Int: + return n as NSObject + case let n as Int8: + return n as NSObject + case let n as Int16: + return n as NSObject + case let n as Int32: + return n as NSObject + case let n as Int64: + return n as NSObject + case let n as UInt: + return n as NSObject + case let n as UInt8: + return n as NSObject + case let n as UInt16: + return n as NSObject + case let n as UInt32: + return n as NSObject + case let n as UInt64: + return n as NSObject + case let decimal as Decimal: + return NSDecimalNumber(decimal: decimal) + case let url as URL: + return url.absoluteString as NSObject + case let date as Date: + // Stripe expects an integer number of seconds since the Unix epoch + return Int(date.timeIntervalSince1970) as NSObject + case let data as Data: + // Stripe expects base64-encoded data + return data.base64EncodedString() as NSObject + case is [AnyHashable: Any]: + let encoder = _stpinternal_JSONEncoder() + encoder.userInfo = userInfo + // If this is a dictionary, don't apply transformations to the keys + encoder.userInfo[STPMaintainExistingCase] = true + encoder.codingPath = codingPath + try value.encode(to: encoder) + return encoder.singleContainer + default: + let encoder = _stpinternal_JSONEncoder() + encoder.userInfo = userInfo + encoder.codingPath = codingPath + try value.encode(to: encoder) + return encoder.singleContainer + } + } +} diff --git a/Pods/StripeCore/StripeCore/StripeCore/Source/Coder/StripeJSONShared.swift b/Pods/StripeCore/StripeCore/StripeCore/Source/Coder/StripeJSONShared.swift new file mode 100644 index 0000000..0381b42 --- /dev/null +++ b/Pods/StripeCore/StripeCore/StripeCore/Source/Coder/StripeJSONShared.swift @@ -0,0 +1,37 @@ +// +// StripeJSONShared.swift +// StripeCore +// +// Copyright © 2022 Stripe, Inc. All rights reserved. +// + +import Foundation + +// Constants +internal let STPMaintainExistingCase = CodingUserInfoKey(rawValue: "_STPMaintainExistingCase")! + +internal struct STPCodingKey: CodingKey { + init?( + stringValue: String + ) { + self.stringValue = stringValue + } + + init?( + intValue: Int + ) { + self.intValue = intValue + self.stringValue = intValue.description + } + + init( + stringValue: String, + intValue: Int? + ) { + self.intValue = intValue + self.stringValue = stringValue + } + + var stringValue: String + var intValue: Int? +} diff --git a/Pods/StripeCore/StripeCore/StripeCore/Source/Coder/UnknownFields.swift b/Pods/StripeCore/StripeCore/StripeCore/Source/Coder/UnknownFields.swift new file mode 100644 index 0000000..281bfbe --- /dev/null +++ b/Pods/StripeCore/StripeCore/StripeCore/Source/Coder/UnknownFields.swift @@ -0,0 +1,98 @@ +// +// UnknownFields.swift +// StripeCore +// +// Copyright © 2022 Stripe, Inc. All rights reserved. +// + +import Foundation + +extension UnknownFieldsEncodable { + func applyUnknownFieldEncodingTransforms( + userInfo: [CodingUserInfoKey: Any], + codingPath: [CodingKey] + ) { + if !(userInfo[StripeIncludeUnknownFieldsKey] as? Bool ?? false) { + // Don't include unknown fields. + return + } + // If we have additional parameters, add these to the parameters we're sending. + // Follow the encoder codingPath *up*, then store it in the userInfo + + // We can't modify the userInfo of the encoder directly, + // but we *can* give it a reference to an NSMutableDictionary + // and mutate that as we go. + if !self.additionalParameters.isEmpty, + let dictionary = userInfo[UnknownFieldsEncodableSourceStorageKey] + as? NSMutableDictionary + { + var mutateDictionary = dictionary + for path in codingPath { + // Make sure we're dealing with snake_case. + let snakeValue = URLEncoder.convertToSnakeCase(camelCase: path.stringValue) + // If the dictionary exists at that level, retrieve it as an NSMutableDictionary reference + if let subDictionary = mutateDictionary[snakeValue] as? NSMutableDictionary { + mutateDictionary = subDictionary + } else { + // If it does not exist, create an NSMutableDictionary at that level. + let newDictionary = NSMutableDictionary() + mutateDictionary[snakeValue] = newDictionary + mutateDictionary = newDictionary + } + } + // Merge the additionalParameters dictionary onto the existing dictionary. + mutateDictionary.addEntries(from: self.additionalParameters) + } + } +} + +extension UnknownFieldsDecodable { + mutating func applyUnknownFieldDecodingTransforms( + userInfo: [CodingUserInfoKey: Any], + codingPath: [CodingKey] + ) throws { + var object = self + + // Follow the encoder's codingPath down the userInfo JSON dictionary + if let originalJSON = userInfo[UnknownFieldsDecodableSourceStorageKey] as? Data, + var jsonDictionary = try JSONSerialization.jsonObject(with: originalJSON, options: []) + as? [String: Any] + { + for path in codingPath { + let snakeValue = URLEncoder.convertToSnakeCase(camelCase: path.stringValue) + // This will always be a dictionary. If it isn't then something is being + // decoded as an object by JSONDecoder, but a dictionary by JSONSerialization. + jsonDictionary = jsonDictionary[snakeValue] as! [String: Any] + } + // Set the allResponseFields dictionary, so that users can access unknown fields. + object.allResponseFields = jsonDictionary + + // If the wrapped value is also *encodable*, we'll want some special behavior + // so it can be re-encoded without losing the unknown fields. + // To do this, we'll: + // 1. Re-encode it (without unknown fields) to a dictionary + // 2. Subtract the "known fields" dictionay from our source dictionary + // 3. Set additionalParameters to the resulting dictionary, giving us + // a dictionary of only our missing or uninterpretable fields. + // When the object is later re-encoded, the additionalParameters will + // be re-added to the encoded JSON. + if var encodableValue = object as? UnknownFieldsEncodable { + let encodedDictionary = try encodableValue.encodeJSONDictionary( + includingUnknownFields: false + ) + encodableValue.additionalParameters = jsonDictionary.subtracting(encodedDictionary) + object = encodableValue as! Self + } + } + self = object + } +} + +let StripeIncludeUnknownFieldsKey = CodingUserInfoKey(rawValue: "_StripeIncludeUnknownFieldsKey")! + +let UnknownFieldsEncodableSourceStorageKey = CodingUserInfoKey( + rawValue: "_UnknownFieldsEncodableSourceStorageKey" +)! +let UnknownFieldsDecodableSourceStorageKey = CodingUserInfoKey( + rawValue: "_UnknownFieldsDecodableSourceStorageKey" +)! diff --git a/Pods/StripeCore/StripeCore/StripeCore/Source/Connections Bindings/ConnectionsSDKInterface.swift b/Pods/StripeCore/StripeCore/StripeCore/Source/Connections Bindings/ConnectionsSDKInterface.swift new file mode 100644 index 0000000..fb16de6 --- /dev/null +++ b/Pods/StripeCore/StripeCore/StripeCore/Source/Connections Bindings/ConnectionsSDKInterface.swift @@ -0,0 +1,37 @@ +// +// ConnectionsSDKInterface.swift +// StripeCore +// +// Created by Vardges Avetisyan on 2/24/22. +// Copyright © 2022 Stripe, Inc. All rights reserved. +// + +import UIKit + +@_spi(STP) @frozen public enum FinancialConnectionsSDKResult { + case completed(linkedBank: LinkedBank) + case cancelled + case failed(error: Error) +} + +@_spi(STP) public protocol FinancialConnectionsSDKInterface { + init() + func presentFinancialConnectionsSheet( + apiClient: STPAPIClient, + clientSecret: String, + returnURL: String?, + from presentingViewController: UIViewController, + completion: @escaping (FinancialConnectionsSDKResult) -> Void + ) +} + +// MARK: - Types + +@_spi(STP) public protocol LinkedBank { + var sessionId: String { get } + var accountId: String { get } + var displayName: String? { get } + var bankName: String? { get } + var last4: String? { get } + var instantlyVerified: Bool { get } +} diff --git a/Pods/StripeCore/StripeCore/StripeCore/Source/DownloadManager/DownloadManager.swift b/Pods/StripeCore/StripeCore/StripeCore/Source/DownloadManager/DownloadManager.swift new file mode 100644 index 0000000..e788062 --- /dev/null +++ b/Pods/StripeCore/StripeCore/StripeCore/Source/DownloadManager/DownloadManager.swift @@ -0,0 +1,234 @@ +// +// DownloadManager.swift +// StripeCore +// + +import CoreGraphics +import Foundation +import UIKit + +/// For internal SDK use only. +@objc(STP_Internal_DownloadManager) +@_spi(STP) public class DownloadManager: NSObject, URLSessionDelegate { + public typealias UpdateImageHandler = (UIImage) -> Void + + public static let sharedManager = DownloadManager() + + let downloadQueue: DispatchQueue + let downloadOperationQueue: OperationQueue + let session: URLSession! + + var imageCache: [String: UIImage] + var pendingRequests: [String: URLSessionTask] + var updateHandlers: [String: [UpdateImageHandler]] + + let imageCacheSemaphore: DispatchSemaphore + let pendingRequestsSemaphore: DispatchSemaphore + + let STPCacheExpirationInterval = (60 * 60 * 24 * 7) // 1 week + var urlCache: URLCache? = nil + + public init( + urlSessionConfiguration: URLSessionConfiguration = .default + ) { + downloadQueue = DispatchQueue(label: "Stripe Download Cache", attributes: .concurrent) + downloadOperationQueue = OperationQueue() + downloadOperationQueue.underlyingQueue = downloadQueue + + let configuration = urlSessionConfiguration + if #available(iOS 13.0, *) { + if let cachesURL = FileManager.default.urls(for: .cachesDirectory, in: .userDomainMask) + .first + { + let diskCacheURL = cachesURL.appendingPathComponent("STPCache") + //5MB memory cache, 30MB Disk cache + let cache = URLCache( + memoryCapacity: 5_000_000, + diskCapacity: 30_000_000, + directory: diskCacheURL + ) + configuration.urlCache = cache + configuration.requestCachePolicy = .useProtocolCachePolicy + self.urlCache = cache + } + } + + session = URLSession(configuration: configuration) + + imageCache = [:] + pendingRequests = [:] + updateHandlers = [:] + + imageCacheSemaphore = DispatchSemaphore(value: 1) + pendingRequestsSemaphore = DispatchSemaphore(value: 1) + + super.init() + } +} + +// MARK: - Download management +extension DownloadManager { + public func downloadImage(url: URL, updateHandler: UpdateImageHandler?) -> UIImage { + if updateHandler == nil { + return downloadImageBlocking(url: url) + } else { + return downloadImageAsync(url: url, updateHandler: updateHandler) + } + } + + func downloadImageBlocking(url: URL) -> UIImage { + let imageName = imageNameFromURL(url: url) + if let image = cachedImageNamed(imageName) { + return image + } + + var blockingDownloadedImage: UIImage? = nil + let updateHandler: UpdateImageHandler = { image in + blockingDownloadedImage = image + } + let blockingDownloadSemaphore = DispatchSemaphore(value: 0) + + let urlRequest = URLRequest(url: url, cachePolicy: .useProtocolCachePolicy) + let task = self.session.downloadTask(with: url) { tempURL, response, error in + guard let tempURL = tempURL, + let response = response, + let data = self.getDataFromURL(tempURL), + let image = self.persistToMemory(data, forImageName: imageName) + else { + blockingDownloadSemaphore.signal() + return + } + self.urlCache?.storeCachedResponse( + CachedURLResponse(response: response, data: data), + for: urlRequest + ) + updateHandler(image) + blockingDownloadSemaphore.signal() + } + task.resume() + blockingDownloadSemaphore.wait() + return blockingDownloadedImage ?? imagePlaceHolder() + } + + func downloadImageAsync(url: URL, updateHandler: UpdateImageHandler?) -> UIImage { + let imageName = imageNameFromURL(url: url) + if let image = cachedImageNamed(imageName) { + return image + } + let urlRequest = URLRequest(url: url, cachePolicy: .useProtocolCachePolicy) + let task = self.session.downloadTask(with: url) { tempURL, response, error in + guard let tempURL = tempURL, + let response = response, + let data = self.getDataFromURL(tempURL), + let image = self.persistToMemory(data, forImageName: imageName) + else { + self.pendingRequestsSemaphore.wait() + self.pendingRequests.removeValue(forKey: imageName) + self.pendingRequestsSemaphore.signal() + return + } + self.urlCache?.storeCachedResponse( + CachedURLResponse(response: response, data: data), + for: urlRequest + ) + + self.pendingRequestsSemaphore.wait() + self.pendingRequests.removeValue(forKey: imageName) + let updates = self.updateHandlers[imageName] ?? [] + self.updateHandlers.removeValue(forKey: imageName) + self.pendingRequestsSemaphore.signal() + + for updateHandler in updates { + updateHandler(image) + } + } + + self.pendingRequestsSemaphore.wait() + guard self.pendingRequests[imageName] == nil else { + addUpdateHandlerWithoutLocking(updateHandler, forImageName: imageName) + self.pendingRequestsSemaphore.signal() + return imagePlaceHolder() + } + self.pendingRequests[imageName] = task + addUpdateHandlerWithoutLocking(updateHandler, forImageName: imageName) + self.pendingRequestsSemaphore.signal() + task.resume() + + return imagePlaceHolder() + } + + func imageNameFromURL(url: URL) -> String { + return url.lastPathComponent + } + + func addUpdateHandlerWithoutLocking( + _ handler: UpdateImageHandler?, + forImageName imageName: String + ) { + guard let handler = handler else { + return + } + if let blocks = self.updateHandlers[imageName] { + self.updateHandlers[imageName] = blocks + [handler] + } else { + self.updateHandlers[imageName] = [handler] + } + } + + func getDataFromURL(_ tempURL: URL) -> Data? { + do { + let imageData = try Data(contentsOf: tempURL) + return imageData + } catch { + } + return nil + } +} + +// MARK: Image Cache +extension DownloadManager { + func resetMemoryCache() { + imageCacheSemaphore.wait() + self.imageCache = [:] + imageCacheSemaphore.signal() + } + + func resetDiskCache() { + self.urlCache?.removeAllCachedResponses() + } + + func persistToMemory(_ imageData: Data, forImageName imageName: String) -> UIImage? { + guard let image = UIImage(data: imageData, scale: UIScreen.main.scale) else { + return nil + } + imageCacheSemaphore.wait() + self.imageCache[imageName] = image + imageCacheSemaphore.signal() + return image + } + + func cachedImageNamed(_ imageName: String) -> UIImage? { + var image: UIImage? = nil + imageCacheSemaphore.wait() + image = imageCache[imageName] + imageCacheSemaphore.signal() + return image + } +} + +// MARK: Image Placeholder +extension DownloadManager { + public func imagePlaceHolder() -> UIImage { + return imageWithSize(size: CGSize(width: 1.0, height: 1.0)) + } + + func imageWithSize(size: CGSize) -> UIImage { + let rect = CGRect(x: 0, y: 0, width: size.width, height: size.height) + UIGraphicsBeginImageContextWithOptions(size, false, 0.0) + UIColor.clear.set() + UIRectFill(rect) + let image = UIGraphicsGetImageFromCurrentImageContext() + UIGraphicsEndImageContext() + return image! + } +} diff --git a/Pods/StripeCore/StripeCore/StripeCore/Source/Helpers/Async.swift b/Pods/StripeCore/StripeCore/StripeCore/Source/Helpers/Async.swift new file mode 100644 index 0000000..40ebc9c --- /dev/null +++ b/Pods/StripeCore/StripeCore/StripeCore/Source/Helpers/Async.swift @@ -0,0 +1,153 @@ +// +// Async.swift +// StripeCore +// +// Created by Yuki Tokuhiro on 9/12/20. +// Copyright © 2020 Stripe, Inc. All rights reserved. +// +// Futures and Promises. Delete this when the SDK is iOS13+ and use the Combine framework instead. +// +// Taken from https://github.com/JohnSundell/SwiftBySundell/blob/master/Blog/Under-the-hood-of-Futures-and-Promises.swift +// +// MIT License +// +// Copyright (c) 2017 John Sundell +// +// 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 + +@_spi(STP) public class Future { + public typealias Result = Swift.Result + + fileprivate var result: Result? { + // Observe whenever a result is assigned, and report it: + didSet { result.map(report) } + } + private var callbacks = [(Result) -> Void]() + + public func observe( + on queue: DispatchQueue? = nil, + using callback: @escaping (Result) -> Void + ) { + let wrappedCallback: (Result) -> Void + if let queue = queue { + wrappedCallback = { r in + queue.async { + callback(r) + } + } + } else { + wrappedCallback = callback + } + + // If a result has already been set, call the callback directly: + if let result = result { + return wrappedCallback(result) + } + + callbacks.append(wrappedCallback) + } + + private func report(result: Result) { + callbacks.forEach { $0(result) } + callbacks = [] + } + + public func chained( + on queue: DispatchQueue? = nil, + using closure: @escaping (Value) throws -> Future + ) -> Future { + // We'll start by constructing a "wrapper" promise that will be + // returned from this method: + let promise = Promise() + + // Observe the current future: + observe(on: queue) { result in + switch result { + case .success(let value): + do { + // Attempt to construct a new future using the value + // returned from the first one: + let future = try closure(value) + + // Observe the "nested" future, and once it + // completes, resolve/reject the "wrapper" future: + future.observe { result in + switch result { + case .success(let value): + promise.resolve(with: value) + case .failure(let error): + promise.reject(with: error) + } + } + } catch { + promise.reject(with: error) + } + case .failure(let error): + promise.reject(with: error) + } + } + + return promise + } +} + +@_spi(STP) public class Promise: Future { + public override init() { + super.init() + } + + public convenience init( + value: Value + ) { + self.init() + + // If the value was already known at the time the promise + // was constructed, we can report it directly: + result = .success(value) + } + + public convenience init( + error: Error + ) { + self.init() + result = .failure(error) + } + + public func resolve(with value: Value) { + result = .success(value) + } + + public func reject(with error: Error) { + result = .failure(error) + } + + public func fullfill(with result: Result) { + self.result = result + } + + public func fulfill(with block: () throws -> Value) { + do { + self.result = .success(try block()) + } catch { + self.result = .failure(error) + } + } +} diff --git a/Pods/StripeCore/StripeCore/StripeCore/Source/Helpers/BundleLocatorProtocol.swift b/Pods/StripeCore/StripeCore/StripeCore/Source/Helpers/BundleLocatorProtocol.swift new file mode 100644 index 0000000..03c147a --- /dev/null +++ b/Pods/StripeCore/StripeCore/StripeCore/Source/Helpers/BundleLocatorProtocol.swift @@ -0,0 +1,75 @@ +// +// BundleLocatorProtocol.swift +// StripeCore +// +// Created by Brian Dorfman on 8/31/16. +// Copyright © 2016 Stripe, Inc. All rights reserved. +// + +import Foundation + +@_spi(STP) public protocol BundleLocatorProtocol { + /// A final class that is internal to the bundle implementing this protocol. + /// + /// - Note: The class must be `final` to ensure that it can't be subclassed, + /// which may change the result of `bundleForClass`. + static var internalClass: AnyClass { get } + + /// Name of the bundle. + static var bundleName: String { get } + + /// Cached result from `computeResourcesBundle()` so it doesn't need to be recomputed. + static var resourcesBundle: Bundle { get } + + #if SWIFT_PACKAGE + /// SPM Bundle, if available. + /// + /// Implementation should be should be `Bundle.module`. + static var spmResourcesBundle: Bundle { get } + #endif +} + +extension BundleLocatorProtocol { + /// Computes the bundle to fetch resources from. + /// + /// - Note: This should never be called directly. Instead, call `resourcesBundle`. + /// - Description: + /// Places to check: + /// 1. Swift Package Manager bundle. + /// 2. Stripe.bundle (for manual static installations and framework-less Cocoapods). + /// 3. Stripe.framework/Stripe.bundle (for framework-based Cocoapods). + /// 4. Stripe.framework (for Carthage, manual dynamic installations). + /// 5. main bundle (for people dragging all our files into their project). + public static func computeResourcesBundle() -> Bundle { + var ourBundle: Bundle? + + #if SWIFT_PACKAGE + ourBundle = spmResourcesBundle + #endif + + if ourBundle == nil { + ourBundle = Bundle(path: "\(bundleName).bundle") + } + + if ourBundle == nil { + // This might be the same as the previous check if not using a dynamic framework + if let path = Bundle(for: internalClass).path( + forResource: bundleName, + ofType: "bundle" + ) { + ourBundle = Bundle(path: path) + } + } + + if ourBundle == nil { + // This will be the same as mainBundle if not using a dynamic framework + ourBundle = Bundle(for: internalClass) + } + + if let ourBundle = ourBundle { + return ourBundle + } else { + return Bundle.main + } + } +} diff --git a/Pods/StripeCore/StripeCore/StripeCore/Source/Helpers/FileDownloader.swift b/Pods/StripeCore/StripeCore/StripeCore/Source/Helpers/FileDownloader.swift new file mode 100644 index 0000000..4aadf76 --- /dev/null +++ b/Pods/StripeCore/StripeCore/StripeCore/Source/Helpers/FileDownloader.swift @@ -0,0 +1,75 @@ +// +// FileDownloader.swift +// StripeCore +// +// Created by Mel Ludowise on 2/1/22. +// Copyright © 2022 Stripe, Inc. All rights reserved. +// + +import Foundation + +/// Downloads files using a downloadTask. +@_spi(STP) public final class FileDownloader { + let urlSession: URLSession + + /// Initializes the `FileDownloader`. + /// + /// - Parameter urlSession: The session to use to download files with + public init( + urlSession: URLSession + ) { + self.urlSession = urlSession + } + + /// Downloads a file from the specified URL and returns a promise that will + /// resolve to the temporary local file location where the file was downloaded to. + /// + /// The temporary file will be deleted by the file system immediately after the + /// promise is observed. If the promise must not be observed on another + /// DispatchQueue or the file will be deleted before it can be observed. + /// + /// - Parameter remoteURL: The URL to download the file from. + public func downloadFileTemporarily(from remoteURL: URL) -> Future { + let promise = Promise() + + let request = URLRequest(url: remoteURL) + + let downloadTask = urlSession.downloadTask(with: request) { url, response, error in + + if let error = error { + return promise.reject(with: error) + } + + guard let url = url else { + return promise.reject(with: NSError.stp_genericConnectionError()) + } + + promise.resolve(with: url) + } + downloadTask.resume() + + return promise + } + + /// Downloads a file from the specified URL and returns a promise that will + /// resolve to the data contents of the file. + /// + /// - Parameters: + /// - remoteURL: The URL to download the file from + /// - fileReadingOptions: Options for reading the file after it's been downloaded locally. + public func downloadFile( + from remoteURL: URL, + fileReadingOptions: Data.ReadingOptions = [] + ) -> Future { + return downloadFileTemporarily(from: remoteURL).chained { fileURL in + let promise = Promise() + promise.fulfill { + return try Data( + contentsOf: fileURL, + options: fileReadingOptions + ) + } + return promise + } + } +} diff --git a/Pods/StripeCore/StripeCore/StripeCore/Source/Helpers/InstallMethod.swift b/Pods/StripeCore/StripeCore/StripeCore/Source/Helpers/InstallMethod.swift new file mode 100644 index 0000000..5660e0e --- /dev/null +++ b/Pods/StripeCore/StripeCore/StripeCore/Source/Helpers/InstallMethod.swift @@ -0,0 +1,27 @@ +// +// InstallMethod.swift +// StripeCore +// +// Copyright © 2022 Stripe, Inc. All rights reserved. +// + +import Foundation + +enum InstallMethod: String { + case cocoapods = "C" + case spm = "S" + case binary = "B" // Built via export_builds.sh + case xcode = "X" // Directly built via Xcode or xcodebuild + + static let current: InstallMethod = { + #if COCOAPODS + return .cocoapods + #elseif SWIFT_PACKAGE + return .spm + #elseif STRIPE_BUILD_PACKAGE + return .binary + #else + return .xcode + #endif + }() +} diff --git a/Pods/StripeCore/StripeCore/StripeCore/Source/Helpers/PaymentsSDKVariant.swift b/Pods/StripeCore/StripeCore/StripeCore/Source/Helpers/PaymentsSDKVariant.swift new file mode 100644 index 0000000..630920a --- /dev/null +++ b/Pods/StripeCore/StripeCore/StripeCore/Source/Helpers/PaymentsSDKVariant.swift @@ -0,0 +1,57 @@ +// +// PaymentsSDKVariant.swift +// StripeCore +// +// Copyright © 2022 Stripe, Inc. All rights reserved. +// + +import Foundation + +@_spi(STP) public class PaymentsSDKVariant { + @_spi(STP) public static let variant: String = { + if NSClassFromString("STPPaymentContext") != nil { + // This is the full legacy Payments SDK, including Basic Integration + return "legacy" + } + if NSClassFromString("STP_Internal_PaymentSheetViewController") != nil { + // This is the PaymentSheet SDK + return "paymentsheet" + } + if NSClassFromString("STPPaymentCardTextField") != nil { + // This is the Payments UI SDK + return "payments-ui" + } + if NSClassFromString("STPCardValidator") != nil { + // This is the API-only Payments SDK + return "payments-api" + } + if NSClassFromString("STPApplePayContext") != nil { + // This is only the Apple Pay SDK + return "applepay" + } + // This is a cryptid + return "unknown" + }() + + @_spi(STP) public static var ocrTypeString: String { + // "STPCardScanner" is STPCardScanner.stp_analyticsIdentifier, but STPCardScanner only exists in Stripe.framework. + if STPAnalyticsClient.sharedClient.productUsage.contains( + "STPCardScanner" + ) + || STPAnalyticsClient.sharedClient.productUsage.contains( + "STPCardScanner_legacy" + ) + { + return "stripe" + } + return "none" + } + + @_spi(STP) public static var paymentUserAgent: String { + var paymentUserAgent = "stripe-ios/\(STPAPIClient.STPSDKVersion)" + let variant = "variant.\(variant)" + let components = [paymentUserAgent, variant] + STPAnalyticsClient.sharedClient.productUsage + paymentUserAgent = components.joined(separator: "; ") + return paymentUserAgent + } +} diff --git a/Pods/StripeCore/StripeCore/StripeCore/Source/Helpers/STPDeviceUtils.swift b/Pods/StripeCore/StripeCore/StripeCore/Source/Helpers/STPDeviceUtils.swift new file mode 100644 index 0000000..5bd8700 --- /dev/null +++ b/Pods/StripeCore/StripeCore/StripeCore/Source/Helpers/STPDeviceUtils.swift @@ -0,0 +1,25 @@ +// +// STPDeviceUtils.swift +// StripeCore +// +// Created by Mel Ludowise on 3/8/21. +// Copyright © 2021 Stripe, Inc. All rights reserved. +// + +import Foundation + +struct STPDeviceUtils { + static var deviceType: String? { + var systemInfo: utsname = utsname() + uname(&systemInfo) + let machineMirror = Mirror(reflecting: systemInfo.machine) + let deviceType = machineMirror.children.reduce("") { identifier, element in + guard let value = element.value as? Int8, value != 0 else { return identifier } + return identifier + String(UnicodeScalar(UInt8(value))) + } + guard !deviceType.isEmpty else { + return nil + } + return deviceType + } +} diff --git a/Pods/StripeCore/StripeCore/StripeCore/Source/Helpers/STPDispatchFunctions.swift b/Pods/StripeCore/StripeCore/StripeCore/Source/Helpers/STPDispatchFunctions.swift new file mode 100644 index 0000000..a0c116e --- /dev/null +++ b/Pods/StripeCore/StripeCore/StripeCore/Source/Helpers/STPDispatchFunctions.swift @@ -0,0 +1,17 @@ +// +// STPDispatchFunctions.swift +// StripeCore +// +// Created by Brian Dorfman on 10/24/16. +// Copyright © 2016 Stripe, Inc. All rights reserved. +// + +import Foundation + +@_spi(STP) public func stpDispatchToMainThreadIfNecessary(_ block: @escaping () -> Void) { + if Thread.isMainThread { + block() + } else { + DispatchQueue.main.async(execute: block) + } +} diff --git a/Pods/StripeCore/StripeCore/StripeCore/Source/Helpers/STPError.swift b/Pods/StripeCore/StripeCore/StripeCore/Source/Helpers/STPError.swift new file mode 100644 index 0000000..f22a0e4 --- /dev/null +++ b/Pods/StripeCore/StripeCore/StripeCore/Source/Helpers/STPError.swift @@ -0,0 +1,307 @@ +// +// STPError.swift +// StripeCore +// +// Created by Saikat Chakrabarti on 11/4/12. +// Copyright © 2012 Stripe, Inc. All rights reserved. +// + +import Foundation + +/// Possible error code values for NSErrors with the `StripeDomain` domain. +@objc public enum STPErrorCode: Int { + /// Trouble connecting to Stripe. + @objc(STPConnectionError) case connectionError = 40 + /// Your request had invalid parameters. + @objc(STPInvalidRequestError) case invalidRequestError = 50 + /// No valid publishable API key provided. + @objc(STPAuthenticationError) case authenticationError = 51 + /// General-purpose API error. + @objc(STPAPIError) case apiError = 60 + /// Something was wrong with the given card details. + @objc(STPCardError) case cardError = 70 + /// The operation was cancelled. + @objc(STPCancellationError) case cancellationError = 80 + /// The ephemeral key could not be decoded. Make sure your backend is sending + /// the unmodified JSON of the ephemeral key to your app. + /// https://stripe.com/docs/mobile/ios/basic#prepare-your-api + @objc(STPEphemeralKeyDecodingError) case ephemeralKeyDecodingError = 1000 +} + +// MARK: - STPError + +// swift-format-ignore: DontRepeatTypeInStaticProperties +/// Top-level class for Stripe error constants. +@objc public class STPError: NSObject { + // MARK: userInfo keys + /// All Stripe iOS errors will be under this domain. + @objc public static let stripeDomain = "com.stripe.lib" + + // swift-format-ignore: DontRepeatTypeInStaticProperties + /// The error domain for errors in `STPPaymentHandler`. + @objc public static let STPPaymentHandlerErrorDomain = "STPPaymentHandlerErrorDomain" + + /// A human-readable message providing more details about the error. + /// For card errors, these messages can be shown to your users. + /// - seealso: https://stripe.com/docs/api/errors#errors-message + @objc public static let errorMessageKey = "com.stripe.lib:ErrorMessageKey" + /// An SDK-supplied "hint" that is intended to help you, the developer, fix the error. + @objc public static let hintKey = "com.stripe.lib:hintKey" + /// What went wrong with your STPCard (e.g., STPInvalidCVC). + /// + /// See below for full list). + @objc public static let cardErrorCodeKey = "com.stripe.lib:CardErrorCodeKey" + /// Which parameter on the STPCard had an error (e.g., "cvc"). + /// + /// Useful for marking up the right UI element. + @objc public static let errorParameterKey = "com.stripe.lib:ErrorParameterKey" + /// The error code returned by the Stripe API. + /// + /// - seealso: https://stripe.com/docs/api#errors-code + /// - seealso: https://stripe.com/docs/error-codes + @objc public static let stripeErrorCodeKey = "com.stripe.lib:StripeErrorCodeKey" + /// The error type returned by the Stripe API. + /// + /// - seealso: https://stripe.com/docs/api#errors-type + @objc public static let stripeErrorTypeKey = "com.stripe.lib:StripeErrorTypeKey" + /// If the value of `userInfo[stripeErrorCodeKey]` is `STPError.cardDeclined`, + /// the value for this key contains the decline code. + /// + /// - seealso: https://stripe.com/docs/declines/codes + @objc public static let stripeDeclineCodeKey = "com.stripe.lib:DeclineCodeKey" +} + +extension NSError { + @_spi(STP) public class Utils { + private static let apiErrorCodeToMessage: [String: String] = [ + "incorrect_number": NSError.stp_cardErrorInvalidNumberUserMessage(), + "invalid_number": NSError.stp_cardErrorInvalidNumberUserMessage(), + "invalid_expiry_month": NSError.stp_cardErrorInvalidExpMonthUserMessage(), + "invalid_expiry_year": NSError.stp_cardErrorInvalidExpYearUserMessage(), + "invalid_cvc": NSError.stp_cardInvalidCVCUserMessage(), + "expired_card": NSError.stp_cardErrorExpiredCardUserMessage(), + "incorrect_cvc": NSError.stp_cardInvalidCVCUserMessage(), + "card_declined": NSError.stp_cardErrorDeclinedUserMessage(), + "processing_error": NSError.stp_cardErrorProcessingErrorUserMessage(), + "invalid_owner_name": NSError.stp_invalidOwnerName, + "invalid_bank_account_iban": NSError.stp_invalidBankAccountIban, + "generic_decline": NSError.stp_genericDeclineErrorUserMessage(), + ] + + private static let apiErrorCodeToCardErrorCode: [String: STPCardErrorCode] = [ + "incorrect_number": .incorrectNumber, + "invalid_number": .invalidNumber, + "invalid_expiry_month": .invalidExpMonth, + "invalid_expiry_year": .invalidExpYear, + "invalid_cvc": .invalidCVC, + "expired_card": .expiredCard, + "incorrect_cvc": .invalidCVC, + "card_declined": .cardDeclined, + "processing_error": .processingError, + "incorrect_zip": .incorrectZip, + ] + + private init() {} + + @_spi(STP) public static func localizedMessage( + fromAPIErrorCode errorCode: String, + declineCode: String? = nil + ) -> String? { + return + (apiErrorCodeToMessage[errorCode] + ?? declineCode.flatMap { apiErrorCodeToMessage[$0] }) + } + + @_spi(STP) public static func cardErrorCode( + fromAPIErrorCode errorCode: String + ) -> STPCardErrorCode? { + return apiErrorCodeToCardErrorCode[errorCode] + } + } +} + +/// NSError extensions for creating error objects from Stripe API responses. +extension NSError { + @_spi(STP) public static func stp_error(from modernStripeError: StripeError) -> NSError? { + switch modernStripeError { + case .apiError(let stripeAPIError): + return stp_error(fromStripeResponse: ["error": stripeAPIError.allResponseFields]) + case .invalidRequest: + return NSError( + domain: STPError.stripeDomain, + code: STPErrorCode.invalidRequestError.rawValue, + userInfo: nil + ) + } + } + + @_spi(STP) public static func stp_error( + errorType: String?, + stripeErrorCode: String?, + stripeErrorMessage: String?, + errorParam: String?, + declineCode: Any?, + httpResponse: HTTPURLResponse? + ) -> NSError? { + var code = 0 + + var userInfo: [AnyHashable: Any] = [ + NSLocalizedDescriptionKey: self.stp_unexpectedErrorMessage() + ] + userInfo[STPError.stripeErrorCodeKey] = stripeErrorCode ?? "" + userInfo[STPError.stripeErrorTypeKey] = errorType ?? "" + if let errorParam = errorParam { + userInfo[STPError.errorParameterKey] = URLEncoder.convertToCamelCase( + snakeCase: errorParam + ) + } + if let stripeErrorMessage = stripeErrorMessage { + userInfo[STPError.errorMessageKey] = stripeErrorMessage + userInfo[STPError.hintKey] = ServerErrorMapper.mobileErrorMessage( + from: stripeErrorMessage, + httpResponse: httpResponse + ) + } else { + userInfo[STPError.errorMessageKey] = + "Could not interpret the error response that was returned from Stripe." + } + if errorType == "api_error" { + code = STPErrorCode.apiError.rawValue + } else { + if errorType == "invalid_request_error" { + switch httpResponse?.statusCode { + case 401: + code = STPErrorCode.authenticationError.rawValue + default: + code = STPErrorCode.invalidRequestError.rawValue + } + } else if errorType == "card_error" { + code = STPErrorCode.cardError.rawValue + // see https://stripe.com/docs/api/errors#errors-message + userInfo[NSLocalizedDescriptionKey] = stripeErrorMessage + } else { + code = STPErrorCode.apiError.rawValue + } + + if let stripeErrorCode = stripeErrorCode, !stripeErrorCode.isEmpty { + if let cardErrorCode = Utils.cardErrorCode(fromAPIErrorCode: stripeErrorCode) { + if cardErrorCode == STPCardErrorCode.cardDeclined, + let decline_code = declineCode + { + userInfo[STPError.stripeDeclineCodeKey] = decline_code + } + userInfo[STPError.cardErrorCodeKey] = cardErrorCode.rawValue + } + + // If the server didn't send an error message, use a local one. + if stripeErrorMessage == nil { + let localizedMessage = Utils.localizedMessage( + fromAPIErrorCode: stripeErrorCode, + declineCode: declineCode as? String + ) + + if let localizedMessage = localizedMessage { + userInfo[NSLocalizedDescriptionKey] = localizedMessage + } + } + } + } + + return NSError( + domain: STPError.stripeDomain, + code: code, + userInfo: userInfo as? [String: Any] + ) + } + + @_spi(STP) public static func stp_error( + fromStripeResponse jsonDictionary: [AnyHashable: Any]?, + httpResponse: HTTPURLResponse? + ) -> NSError? { + // TODO: Refactor. A lot of this can be replaced by a lookup/decision table. Check Android implementation for cues. + guard let dict = (jsonDictionary as NSDictionary?), + let errorDictionary = dict["error"] as? NSDictionary + else { + return nil + } + let errorType = errorDictionary["type"] as? String + let errorParam = errorDictionary["param"] as? String + let stripeErrorMessage = errorDictionary["message"] as? String + let stripeErrorCode = errorDictionary["code"] as? String + let declineCode = errorDictionary["decline_code"] + + return stp_error( + errorType: errorType, + stripeErrorCode: stripeErrorCode, + stripeErrorMessage: stripeErrorMessage, + errorParam: errorParam, + declineCode: declineCode, + httpResponse: httpResponse + ) + } + + /// Creates an NSError object from a given Stripe API json response. + /// - Parameter jsonDictionary: The root dictionary from the JSON response. + /// - Returns: An NSError object with the error information from the JSON response, + /// or nil if there was no error information included in the JSON dictionary. + @objc(stp_errorFromStripeResponse:) public static func stp_error( + fromStripeResponse jsonDictionary: [AnyHashable: Any]? + ) + -> NSError? + { + stp_error(fromStripeResponse: jsonDictionary, httpResponse: nil) + } +} + +// MARK: STPCardErrorCodeKeys - + +/// Possible string values you may receive when there was an error tokenizing a card. +/// +/// These values will come back in the error `userInfo` dictionary +/// under the `STPCardErrorCodeKey` key. +public enum STPCardErrorCode: String { + /// The card number is not a valid credit card number. + case invalidNumber = "com.stripe.lib:InvalidNumber" + /// The card has an invalid expiration month. + case invalidExpMonth = "com.stripe.lib:InvalidExpiryMonth" + /// The card has an invalid expiration year. + case invalidExpYear = "com.stripe.lib:InvalidExpiryYear" + /// The card has an invalid CVC. + case invalidCVC = "com.stripe.lib:InvalidCVC" + /// The card number is incorrect. + case incorrectNumber = "com.stripe.lib:IncorrectNumber" + /// The card is expired. + case expiredCard = "com.stripe.lib:ExpiredCard" + /// The card was declined. + case cardDeclined = "com.stripe.lib:CardDeclined" + /// The card has an incorrect CVC. + case incorrectCVC = "com.stripe.lib:IncorrectCVC" + /// An error occured while processing this card. + case processingError = "com.stripe.lib:ProcessingError" + /// The postal code is incorrect. + case incorrectZip = "com.stripe.lib:IncorrectZip" +} + +// swift-format-ignore: DontRepeatTypeInStaticProperties +@objc extension STPError { + /// The card number is not a valid credit card number. + @objc public static let invalidNumber = STPCardErrorCode.invalidNumber.rawValue + /// The card has an invalid expiration month. + @objc public static let invalidExpMonth = STPCardErrorCode.invalidExpMonth.rawValue + /// The card has an invalid expiration year. + @objc public static let invalidExpYear = STPCardErrorCode.invalidExpYear.rawValue + /// The card has an invalid CVC. + @objc public static let invalidCVC = STPCardErrorCode.invalidCVC.rawValue + /// The card number is incorrect. + @objc public static let incorrectNumber = STPCardErrorCode.incorrectNumber.rawValue + /// The card is expired. + @objc public static let expiredCard = STPCardErrorCode.expiredCard.rawValue + /// The card was declined. + @objc public static let cardDeclined = STPCardErrorCode.cardDeclined.rawValue + /// An error occured while processing this card. + @objc public static let processingError = STPCardErrorCode.processingError.rawValue + /// The card has an incorrect CVC. + @objc public static let incorrectCVC = STPCardErrorCode.incorrectCVC.rawValue + /// The postal code is incorrect. + @objc public static let incorrectZip = STPCardErrorCode.incorrectZip.rawValue +} diff --git a/Pods/StripeCore/StripeCore/StripeCore/Source/Helpers/STPNumericStringValidator.swift b/Pods/StripeCore/StripeCore/StripeCore/Source/Helpers/STPNumericStringValidator.swift new file mode 100644 index 0000000..6f84c71 --- /dev/null +++ b/Pods/StripeCore/StripeCore/StripeCore/Source/Helpers/STPNumericStringValidator.swift @@ -0,0 +1,31 @@ +// +// STPNumericStringValidator.swift +// StripeCore +// +// Created by Cameron Sabol on 3/6/20. +// Copyright © 2020 Stripe, Inc. All rights reserved. +// + +import Foundation + +@_spi(STP) public enum STPTextValidationState: Int { + case empty + case incomplete + case complete + case invalid +} + +@_spi(STP) open class STPNumericStringValidator: NSObject { + /// Whether or not the target string contains only numeric characters. + @_spi(STP) public class func isStringNumeric(_ string: String) -> Bool { + return + (string as NSString).rangeOfCharacter(from: CharacterSet.stp_invertedAsciiDigit) + .location + == NSNotFound + } + + /// Returns a copy of the passed string with all non-numeric characters removed. + @_spi(STP) public class func sanitizedNumericString(for string: String) -> String { + return string.stp_stringByRemovingCharacters(from: CharacterSet.stp_invertedAsciiDigit) + } +} diff --git a/Pods/StripeCore/StripeCore/StripeCore/Source/Helpers/STPURLCallbackHandler.swift b/Pods/StripeCore/StripeCore/StripeCore/Source/Helpers/STPURLCallbackHandler.swift new file mode 100644 index 0000000..221a64e --- /dev/null +++ b/Pods/StripeCore/StripeCore/StripeCore/Source/Helpers/STPURLCallbackHandler.swift @@ -0,0 +1,92 @@ +// +// STPURLCallbackHandler.swift +// StripeCore +// +// Created by Brian Dorfman on 10/6/16. +// Copyright © 2016 Stripe, Inc. All rights reserved. +// + +import Foundation + +@_spi(STP) @objc public protocol STPURLCallbackListener: NSObjectProtocol { + func handleURLCallback(_ url: URL) -> Bool +} + +@_spi(STP) public class STPURLCallbackHandler: NSObject { + @_spi(STP) public static var sharedHandler: STPURLCallbackHandler = STPURLCallbackHandler() + + @objc @_spi(STP) public class func shared() -> STPURLCallbackHandler { + return sharedHandler + } + + @objc @discardableResult @_spi(STP) public func handleURLCallback(_ url: URL) -> Bool { + guard + let components = NSURLComponents( + url: url, + resolvingAgainstBaseURL: false + ) + else { + return false + } + + var resultsOrred = false + + for callback in callbacks { + if let listener = callback.listener { + if callback.urlComponents.stp_matchesURLComponents(components) { + resultsOrred = resultsOrred || listener.handleURLCallback(url) + } + } + } + + return resultsOrred + } + + @objc(registerListener:forURL:) @_spi(STP) public func register( + _ listener: STPURLCallbackListener, + for url: URL + ) { + + guard + let urlComponents = NSURLComponents( + url: url, + resolvingAgainstBaseURL: false + ) + else { + return + } + let callback = STPURLCallback(urlComponents: urlComponents, listener: listener) + var callbacksCopy = callbacks + callbacksCopy.append(callback) + callbacks = callbacksCopy + } + + @objc @_spi(STP) public func unregisterListener(_ listener: STPURLCallbackListener) { + var callbacksToRemove: [AnyHashable] = [] + + for callback in callbacks { + if listener.isEqual(callback.listener) { + callbacksToRemove.append(callback) + } + } + var callbacksCopy = callbacks + callbacksCopy = callbacksCopy.filter({ !callbacksToRemove.contains($0) }) + callbacks = callbacksCopy + } + + private var callbacks: [STPURLCallback] = [] +} + +class STPURLCallback: NSObject { + init( + urlComponents: NSURLComponents, + listener: STPURLCallbackListener + ) { + self.urlComponents = urlComponents + self.listener = listener + super.init() + } + + var urlComponents: NSURLComponents + weak var listener: STPURLCallbackListener? +} diff --git a/Pods/StripeCore/StripeCore/StripeCore/Source/Helpers/ServerErrorMapper.swift b/Pods/StripeCore/StripeCore/StripeCore/Source/Helpers/ServerErrorMapper.swift new file mode 100644 index 0000000..2e4842a --- /dev/null +++ b/Pods/StripeCore/StripeCore/StripeCore/Source/Helpers/ServerErrorMapper.swift @@ -0,0 +1,95 @@ +// +// ServerErrorMapper.swift +// StripeCore +// +// Created by Nick Porter on 9/13/21. +// Copyright © 2021 Stripe, Inc. All rights reserved. +// + +import Foundation + +private enum ServerErrorPrefixes: String, CaseIterable { + case missingPublishableKey = "You did not provide an API key." + case invalidApiKey = "Invalid API Key provided" + case mismatchPublishableKey = + "The client_secret provided does not match the client_secret associated with" + case noSuchPaymentIntent = "No such payment_intent" + case noSuchSetupIntent = "No such setup_intent" + + /// Maps the corresponding `ServerErrorMapper` to a `MobileErrorMessage`. + /// + /// - Parameters: + /// - serverErrorMessage: the raw server error message from the server. + /// - httpResponse: the http response for the error. + /// - Returns: a `MobileErrorMessage` that maps to this `ServerErrorPrefixes`. + func mobileError( + from serverErrorMessage: String, + httpResponse: HTTPURLResponse + ) -> MobileErrorMessage { + switch self { + case .missingPublishableKey: + return MobileErrorMessage.missingPublishableKey + case .invalidApiKey: + if httpResponse.url?.absoluteString.hasPrefix( + "https://api.stripe.com/v1/payment_methods?customer=" + ) ?? false { + // User didn't set ephemeral key correctly + return MobileErrorMessage.invalidCustomerEphKey + } else { + // User didn't set publishable key correctly + return MobileErrorMessage.missingPublishableKey + } + case .mismatchPublishableKey: + return MobileErrorMessage.mismatchPublishableKey + case .noSuchPaymentIntent: + return MobileErrorMessage.noSuchPaymentIntent + case .noSuchSetupIntent: + return MobileErrorMessage.noSuchSetupIntent + } + } +} + +/// List of mobile friendly error messages for common upstream server errors. +private enum MobileErrorMessage: String { + case missingPublishableKey = + "No valid API key provided. Set `STPAPIClient.shared().publishableKey` to your publishable key, which you can find here: https://stripe.com/docs/keys" + + case invalidCustomerEphKey = + "Invalid customer ephemeral key secret. You can find more information at https://stripe.com/docs/payments/accept-a-payment?platform=ios#add-server-endpoint" + + case mismatchPublishableKey = + "The publishable key provided does not match the publishable key associated with the PaymentIntent/SetupIntent. This is most likley caused by using a different publishable key in `STPAPIClient.shared().publishableKey` than what your server is using." + + case noSuchPaymentIntent = + "No matching PaymentIntent could be found. Ensure you are creating a PaymentIntent server side and using the same publishable key on both client and server. You can find more information at https://stripe.com/docs/api/payment_intents/create" + + case noSuchSetupIntent = + "No matching SetupIntent could be found. Ensure you are creating a SetupIntent server side and using the same publishable key on both client and server. You can find more information at https://stripe.com/docs/api/setup_intents/create" +} + +/// Maps known server error message to mobile friendly versions. +struct ServerErrorMapper { + + /// Maps common server error messages to a mobile friendly equivalent if known, + /// otherwise defaults to the server error message. + /// + /// - Parameters: + /// - serverErrorMessage: the error message returned from the server. + /// - httpResponse: the http response for this error. + /// - Returns: a mobile friendly error message if known, + /// otherwise defaults the error message from the server. + static func mobileErrorMessage( + from serverErrorMessage: String, + httpResponse: HTTPURLResponse? + ) -> String? { + guard let httpResponse = httpResponse else { + return nil + } + + let serverError = ServerErrorPrefixes.allCases.first(where: { + serverErrorMessage.hasPrefix($0.rawValue) + }) + return serverError?.mobileError(from: serverErrorMessage, httpResponse: httpResponse) + .rawValue + } +} diff --git a/Pods/StripeCore/StripeCore/StripeCore/Source/Helpers/StripeCoreBundleLocator.swift b/Pods/StripeCore/StripeCore/StripeCore/Source/Helpers/StripeCoreBundleLocator.swift new file mode 100644 index 0000000..7ac3687 --- /dev/null +++ b/Pods/StripeCore/StripeCore/StripeCore/Source/Helpers/StripeCoreBundleLocator.swift @@ -0,0 +1,18 @@ +// +// StripeCoreBundleLocator.swift +// StripeCore +// +// Created by Mel Ludowise on 7/6/21. +// Copyright © 2021 Stripe, Inc. All rights reserved. +// + +import Foundation + +final class StripeCoreBundleLocator: BundleLocatorProtocol { + static let internalClass: AnyClass = StripeCoreBundleLocator.self + static let bundleName = "StripeCore" + #if SWIFT_PACKAGE + static let spmResourcesBundle = Bundle.module + #endif + static let resourcesBundle = StripeCoreBundleLocator.computeResourcesBundle() +} diff --git a/Pods/StripeCore/StripeCore/StripeCore/Source/Helpers/URLEncoder.swift b/Pods/StripeCore/StripeCore/StripeCore/Source/Helpers/URLEncoder.swift new file mode 100644 index 0000000..de33cab --- /dev/null +++ b/Pods/StripeCore/StripeCore/StripeCore/Source/Helpers/URLEncoder.swift @@ -0,0 +1,147 @@ +// +// URLEncoder.swift +// StripeCore +// +// Created by Mel Ludowise on 5/26/21. +// Copyright © 2021 Stripe, Inc. All rights reserved. +// + +import Foundation + +@_spi(STP) public final class URLEncoder { + public class func string(byURLEncoding string: String) -> String { + return escape(string) + } + + public class func convertToCamelCase(snakeCase input: String) -> String { + let parts: [String] = input.components(separatedBy: "_") + var camelCaseParam = "" + for (idx, part) in parts.enumerated() { + camelCaseParam += idx == 0 ? part : part.capitalized + } + + return camelCaseParam + } + + public class func convertToSnakeCase(camelCase input: String) -> String { + var newString = input + + while let range = newString.rangeOfCharacter(from: .uppercaseLetters) { + let character = newString[range] + newString = newString.replacingCharacters(in: range, with: character.lowercased()) + newString.insert("_", at: range.lowerBound) + } + + return newString + } + + @objc(queryStringFromParameters:) + public class func queryString(from parameters: [String: Any]) -> String { + return query(parameters) + } +} + +// MARK: - +// The code below is adapted from https://github.com/Alamofire/Alamofire +struct Key { + enum Part { + case normal(String) + case dontEscape(String) + } + let parts: [Part] +} + +/// Creates a percent-escaped, URL encoded query string components from the given key-value pair recursively. +/// +/// - Parameters: +/// - key: Key of the query component. +/// - value: Value of the query component. +/// +/// - Returns: The percent-escaped, URL encoded query string components. +private func queryComponents(fromKey key: String, value: Any) -> [(String, String)] { + func unwrap(_ any: T) -> Any { + let mirror = Mirror(reflecting: any) + guard mirror.displayStyle == .optional, let first = mirror.children.first else { + return any + } + return first.value + } + + var components: [(String, String)] = [] + switch value { + case let dictionary as [String: Any]: + for nestedKey in dictionary.keys.sorted() { + let value = dictionary[nestedKey]! + let escapedNestedKey = escape(nestedKey) + components += queryComponents(fromKey: "\(key)[\(escapedNestedKey)]", value: value) + } + case let array as [Any]: + for (index, value) in array.enumerated() { + components += queryComponents(fromKey: "\(key)[\(index)]", value: value) + } + case let number as NSNumber: + if number.isBool { + components.append((key, escape(number.boolValue ? "true" : "false"))) + } else { + components.append((key, escape("\(number)"))) + } + case let bool as Bool: + components.append((key, escape(bool ? "true" : "false"))) + case let set as Set: + for value in Array(set) { + components += queryComponents(fromKey: "\(key)", value: value) + } + default: + let unwrappedValue = unwrap(value) + components.append((key, escape("\(unwrappedValue)"))) + } + return components +} + +/// Creates a percent-escaped string following RFC 3986 for a query string key or value. +/// +/// - Parameter string: `String` to be percent-escaped. +/// +/// - Returns: The percent-escaped `String`. +private func escape(_ string: String) -> String { + string.addingPercentEncoding(withAllowedCharacters: URLQueryAllowed) ?? string +} + +private func query(_ parameters: [String: Any]) -> String { + var components: [(String, String)] = [] + + for key in parameters.keys.sorted(by: <) { + let value = parameters[key]! + components += queryComponents(fromKey: escape(key), value: value) + } + return components.map { "\($0)=\($1)" }.joined(separator: "&") +} + +/// Creates a CharacterSet from RFC 3986 allowed characters. +/// +/// RFC 3986 states that the following characters are "reserved" characters. +/// +/// - General Delimiters: ":", "#", "[", "]", "@", "?", "/" +/// - Sub-Delimiters: "!", "$", "&", "'", "(", ")", "*", "+", ",", ";", "=" +/// +/// In RFC 3986 - Section 3.4, it states that the "?" and "/" characters should not be escaped to allow +/// query strings to include a URL. Therefore, all "reserved" characters with the exception of "?" and "/" +/// should be percent-escaped in the query string. +private let URLQueryAllowed: CharacterSet = { + // does not include "?" or "/" due to RFC 3986 - Section 3.4. + let generalDelimitersToEncode = ":#[]@" + let subDelimitersToEncode = "!$&'()*+,;=" + let encodableDelimiters = CharacterSet( + charactersIn: "\(generalDelimitersToEncode)\(subDelimitersToEncode)" + ) + + return CharacterSet.urlQueryAllowed.subtracting(encodableDelimiters) +}() + +extension NSNumber { + fileprivate var isBool: Bool { + // Use Obj-C type encoding to check whether the underlying type is a `Bool`, as it's guaranteed as part of + // swift-corelibs-foundation, per [this discussion on the Swift forums](https://forums.swift.org/t/alamofire-on-linux-possible-but-not-release-ready/34553/22). + String(cString: objCType) == "c" + } +} diff --git a/Pods/StripeCore/StripeCore/StripeCore/Source/Helpers/URLSession+Retry.swift b/Pods/StripeCore/StripeCore/StripeCore/Source/Helpers/URLSession+Retry.swift new file mode 100644 index 0000000..ac24f2b --- /dev/null +++ b/Pods/StripeCore/StripeCore/StripeCore/Source/Helpers/URLSession+Retry.swift @@ -0,0 +1,54 @@ +// +// URLSession+Retry.swift +// StripeCore +// +// Created by David Estes on 3/26/21. +// Copyright © 2021 Stripe, Inc. All rights reserved. +// + +import Foundation + +extension URLSession { + @_spi(STP) public func stp_performDataTask( + with request: URLRequest, + completionHandler: @escaping (Data?, URLResponse?, Error?) -> Void, + retryCount: Int = StripeAPI.maxRetries + ) { + let task = dataTask(with: request) { (data, response, error) in + if let httpResponse = response as? HTTPURLResponse, + httpResponse.statusCode == 429, + retryCount > 0 + { + // Add some backoff time with a little bit of jitter: + let delayTime = TimeInterval( + pow(Double(1 + StripeAPI.maxRetries - retryCount), Double(2)) + + .random(in: 0..<0.5) + ) + + if #available(iOS 13.0, *) { + let fireDate = Date() + delayTime + self.delegateQueue.schedule(after: .init(fireDate)) { + self.stp_performDataTask( + with: request, + completionHandler: completionHandler, + retryCount: retryCount - 1 + ) + } + } else { + DispatchQueue.main.asyncAfter(deadline: .now() + delayTime) { + self.delegateQueue.addOperation { + self.stp_performDataTask( + with: request, + completionHandler: completionHandler, + retryCount: retryCount - 1 + ) + } + } + } + } else { + completionHandler(data, response, error) + } + } + task.resume() + } +} diff --git a/Pods/StripeCore/StripeCore/StripeCore/Source/Localization/STPLocalizationUtils.swift b/Pods/StripeCore/StripeCore/StripeCore/Source/Localization/STPLocalizationUtils.swift new file mode 100644 index 0000000..513ac36 --- /dev/null +++ b/Pods/StripeCore/StripeCore/StripeCore/Source/Localization/STPLocalizationUtils.swift @@ -0,0 +1,97 @@ +// +// STPLocalizationUtils.swift +// StripeCore +// +// Created by Brian Dorfman on 8/11/16. +// Copyright © 2016 Stripe, Inc. All rights reserved. +// + +import Foundation + +@_spi(STP) public final class STPLocalizationUtils { + /// Acts like NSLocalizedString but tries to find the string in the Stripe + /// bundle first if possible. + /// + /// If the main app has a localization that we do not support, we want to switch + /// to pulling strings from the main bundle instead of our own bundle so that + /// users can add translations for our strings without having to fork the sdk. + /// At launch, NSBundles' store what language(s) the user requests that they + /// actually have translations for in `preferredLocalizations`. + /// We compare our framework's resource bundle to the main app's bundle, and + /// if their language choice doesn't match up we switch to pulling strings + /// from the main bundle instead. + /// This also prevents language mismatches. E.g. the user lists portuguese and + /// then spanish as their preferred languages. The main app supports both so all its + /// strings are in pt, but we support spanish so our bundle marks es as our + /// preferred language and our strings are in es. + /// If the main bundle doesn't have the correct string, we'll always fall back to + /// using the Stripe bundle so we don't inadvertently show an untranslated string. + static func localizedStripeStringUseMainBundle( + bundleLocator: BundleLocatorProtocol.Type + ) -> Bool { + if bundleLocator.resourcesBundle.preferredLocalizations.first + != Bundle.main.preferredLocalizations.first + { + return true + } + return false + } + + static let UnknownString = "STPStringNotFound" + + public class func localizedStripeString( + forKey key: String, + bundleLocator: BundleLocatorProtocol.Type + ) -> String { + if languageOverride != nil { + return testing_localizedStripeString(forKey: key, bundleLocator: bundleLocator) + } + if localizedStripeStringUseMainBundle(bundleLocator: bundleLocator) { + // Per https://developer.apple.com/documentation/foundation/bundle/1417694-localizedstring, + // iOS will give us an empty string if a string isn't found for the specified key. + // Work around this by specifying an unknown sentinel string as the value. If we get that value back, + // we know that the string wasn't present in the bundle. + let userTranslation = Bundle.main.localizedString( + forKey: key, + value: UnknownString, + table: nil + ) + if userTranslation != UnknownString { + return userTranslation + } + } + + return bundleLocator.resourcesBundle.localizedString( + forKey: key, + value: nil, + table: nil + ) + } + + // MARK: - Testing + static var languageOverride: String? + static func overrideLanguage(to string: String?) { + STPLocalizationUtils.languageOverride = string + } + static func testing_localizedStripeString( + forKey key: String, + bundleLocator: BundleLocatorProtocol.Type + ) -> String { + var bundle = bundleLocator.resourcesBundle + + if let languageOverride = languageOverride { + + let lprojPath = bundle.path(forResource: languageOverride, ofType: "lproj") + if let lprojPath = lprojPath { + bundle = Bundle(path: lprojPath)! + } + } + return bundle.localizedString(forKey: key, value: nil, table: nil) + } +} + +/// Use to explicitly ignore static analyzer warning: +/// "User-facing text should use localized string macro". +@inline(__always) @_spi(STP) public func STPNonLocalizedString(_ string: String) -> String { + return string +} diff --git a/Pods/StripeCore/StripeCore/StripeCore/Source/Localization/STPLocalizedString.swift b/Pods/StripeCore/StripeCore/StripeCore/Source/Localization/STPLocalizedString.swift new file mode 100644 index 0000000..7e44fcf --- /dev/null +++ b/Pods/StripeCore/StripeCore/StripeCore/Source/Localization/STPLocalizedString.swift @@ -0,0 +1,14 @@ +// +// STPLocalizedString.swift +// StripeCore +// +// Created by Mel Ludowise on 7/6/20. +// Copyright © 2021 Stripe, Inc. All rights reserved. +// + +@inline(__always) func STPLocalizedString(_ key: String, _ comment: String?) -> String { + return STPLocalizationUtils.localizedStripeString( + forKey: key, + bundleLocator: StripeCoreBundleLocator.self + ) +} diff --git a/Pods/StripeCore/StripeCore/StripeCore/Source/Localization/String+Localized.swift b/Pods/StripeCore/StripeCore/StripeCore/Source/Localization/String+Localized.swift new file mode 100644 index 0000000..1b292e4 --- /dev/null +++ b/Pods/StripeCore/StripeCore/StripeCore/Source/Localization/String+Localized.swift @@ -0,0 +1,51 @@ +// +// String+Localized.swift +// StripeCore +// +// Created by Mel Ludowise on 8/4/21. +// Copyright © 2021 Stripe, Inc. All rights reserved. +// + +import Foundation + +@_spi(STP) extension String { + public enum Localized { + public static var close: String { + return STPLocalizedString("Close", "Text for close button") + } + + public static var tryAgain: String { + return STPLocalizedString("Try again", "Text for a retry button") + } + + public static var scan_card_title_capitalization: String { + STPLocalizedString("Scan Card", "Text for button to scan a credit card") + } + + public static var scan_card: String { + STPLocalizedString("Scan card", "Button title to open camera to scan credit/debit card") + } + + public static var scan_card_privacy_link_text: String { + // THIS STRING SHOULD NOT BE MODIFIED + STPLocalizedString( + "We use Stripe to verify your card details. Stripe may use and store your data according its privacy policy. Learn more", + "Informational text informing the user that Stripe is used to process data and a link to Stripe's privacy policy" + ) + } + + public static func scanCardExpectedPrivacyLinkText() -> NSAttributedString? { + let stringData = Data(String.Localized.scan_card_privacy_link_text.utf8) + let stringOptions: [NSAttributedString.DocumentReadingOptionKey: Any] = [ + .documentType: NSAttributedString.DocumentType.html, + .characterEncoding: String.Encoding.utf8.rawValue, + ] + + return try? NSAttributedString( + data: stringData, + options: stringOptions, + documentAttributes: nil + ) + } + } +} diff --git a/Pods/StripeCore/StripeCore/StripeCore/Source/Telemetry/FraudDetectionData.swift b/Pods/StripeCore/StripeCore/StripeCore/Source/Telemetry/FraudDetectionData.swift new file mode 100644 index 0000000..23e6fb9 --- /dev/null +++ b/Pods/StripeCore/StripeCore/StripeCore/Source/Telemetry/FraudDetectionData.swift @@ -0,0 +1,72 @@ +// +// FraudDetectionData.swift +// StripeCore +// +// Created by Yuki Tokuhiro on 5/20/21. +// Copyright © 2021 Stripe, Inc. All rights reserved. +// + +import Foundation + +private let SIDLifetime: TimeInterval = 30 * 60 // 30 minutes + +/// Contains encoded values returned from m.stripe.com. +/// +/// - Note: See `STPTelemetryClient`. +/// - Note: See `StripeAPI.advancedFraudSignalsEnabled`. +@_spi(STP) public final class FraudDetectionData: Codable { + @_spi(STP) public static let shared: FraudDetectionData = + // Load initial value from UserDefaults + UserDefaults.standard.fraudDetectionData ?? FraudDetectionData() + + @_spi(STP) public var muid: String? + @_spi(STP) public var guid: String? + @_spi(STP) public var sid: String? + + /// The approximate time that the sid was generated from m.stripe.com + /// Intended to be used to expire the sid after `SIDLifetime` seconds + /// - Note: This class is a dumb container; users must set this value appropriately. + var sidCreationDate: Date? + + init( + sid: String? = nil, + muid: String? = nil, + guid: String? = nil, + sidCreationDate: Date? = nil + ) { + self.sid = sid + self.muid = muid + self.guid = guid + self.sidCreationDate = sidCreationDate + } + + func resetSIDIfExpired() { + guard let sidCreationDate = sidCreationDate else { + return + } + let thirtyMinutesAgo = Date(timeIntervalSinceNow: -SIDLifetime) + if sidCreationDate < thirtyMinutesAgo { + sid = nil + } + } + + deinit { + // Write latest value to disk + UserDefaults.standard.fraudDetectionData = self + } + + func reset() { + self.sid = nil + self.muid = nil + self.guid = nil + self.sidCreationDate = nil + } +} + +extension FraudDetectionData: Equatable { + @_spi(STP) public static func == (lhs: FraudDetectionData, rhs: FraudDetectionData) -> Bool { + return + lhs.muid == rhs.muid && lhs.sid == rhs.sid && lhs.guid == rhs.guid + && lhs.sidCreationDate == rhs.sidCreationDate + } +} diff --git a/Pods/StripeCore/StripeCore/StripeCore/Source/Telemetry/STPTelemetryClient.swift b/Pods/StripeCore/StripeCore/StripeCore/Source/Telemetry/STPTelemetryClient.swift new file mode 100644 index 0000000..6f6f46c --- /dev/null +++ b/Pods/StripeCore/StripeCore/StripeCore/Source/Telemetry/STPTelemetryClient.swift @@ -0,0 +1,214 @@ +// +// STPTelemetryClient.swift +// StripeCore +// +// Created by Ben Guo on 4/18/17. +// Copyright © 2016 Stripe, Inc. All rights reserved. +// + +import Foundation +import UIKit + +private let TelemetryURL = URL(string: "https://m.stripe.com/6")! + +@_spi(STP) public final class STPTelemetryClient: NSObject { + @_spi(STP) public static var shared: STPTelemetryClient = STPTelemetryClient( + sessionConfiguration: StripeAPIConfiguration.sharedUrlSessionConfiguration + ) + + @_spi(STP) public func addTelemetryFields(toParams params: inout [String: Any]) { + params["muid"] = fraudDetectionData.muid + params["guid"] = fraudDetectionData.guid + fraudDetectionData.resetSIDIfExpired() + params["sid"] = fraudDetectionData.sid + } + + @_spi(STP) public func paramsByAddingTelemetryFields( + toParams params: [String: Any] + ) -> [String: Any] { + var mutableParams = params + mutableParams["muid"] = fraudDetectionData.muid + mutableParams["guid"] = fraudDetectionData.guid + fraudDetectionData.resetSIDIfExpired() + mutableParams["sid"] = fraudDetectionData.sid + return mutableParams + } + + /// Sends a payload of telemetry to the Stripe telemetry service. + /// + /// - Parameters: + /// - forceSend: ⚠️ Always send the request. Only pass this for testing purposes. + /// - completion: Called with the result of the telemetry network request. + @_spi(STP) public func sendTelemetryData( + forceSend: Bool = false, + completion: ((Result<[String: Any], Error>) -> Void)? = nil + ) { + guard forceSend || STPTelemetryClient.shouldSendTelemetry() else { + completion?(.failure(NSError.stp_genericConnectionError())) + return + } + sendTelemetryRequest(jsonPayload: payload, completion: completion) + } + + @_spi(STP) public func updateFraudDetectionIfNecessary( + completion: @escaping ((Result) -> Void) + ) { + fraudDetectionData.resetSIDIfExpired() + if fraudDetectionData.muid == nil || fraudDetectionData.sid == nil { + sendTelemetryRequest( + jsonPayload: [ + "muid": fraudDetectionData.muid ?? "", + "guid": fraudDetectionData.guid ?? "", + "sid": fraudDetectionData.sid ?? "", + ]) { result in + switch result { + case .failure(let error): + completion(.failure(error)) + case .success: + completion(.success(self.fraudDetectionData)) + } + } + } else { + completion(.success(fraudDetectionData)) + } + } + + private let urlSession: URLSession + + @_spi(STP) public class func shouldSendTelemetry() -> Bool { + #if targetEnvironment(simulator) + return false + #else + return StripeAPI.advancedFraudSignalsEnabled && NSClassFromString("XCTest") == nil + #endif + } + + @_spi(STP) public init( + sessionConfiguration config: URLSessionConfiguration + ) { + urlSession = URLSession(configuration: config) + super.init() + } + + private var language = Locale.autoupdatingCurrent.identifier + private lazy var fraudDetectionData = { + return FraudDetectionData.shared + }() + lazy private var platform = [deviceModel, osVersion].joined(separator: " ") + + private var deviceModel: String = { + var systemInfo = utsname() + uname(&systemInfo) + let model = withUnsafePointer(to: &systemInfo.machine) { + $0.withMemoryRebound(to: CChar.self, capacity: 1) { + ptr in String.init(validatingUTF8: ptr) + } + } + return model ?? "Unknown" + }() + + private var osVersion = UIDevice.current.systemVersion + + private var screenSize: String { + let screen = UIScreen.main + let screenRect = screen.bounds + let width = screenRect.size.width + let height = screenRect.size.height + let scale = screen.scale + return String(format: "%.0fw_%.0fh_%.0fr", width, height, scale) + } + + private var timeZoneOffset: String { + let timeZone = NSTimeZone.local as NSTimeZone + let hoursFromGMT = Double(timeZone.secondsFromGMT) / (60 * 60) + return String(format: "%.0f", hoursFromGMT) + } + + private func encodeValue(_ value: String?) -> [AnyHashable: Any]? { + if let value = value { + return [ + "v": value + ] + } + return nil + } + + private var payload: [String: Any] { + var payload: [String: Any] = [:] + var data: [String: Any] = [:] + if let encode = encodeValue(language) { + data["c"] = encode + } + if let encode = encodeValue(platform) { + data["d"] = encode + } + if let encode = encodeValue(screenSize) { + data["f"] = encode + } + if let encode = encodeValue(timeZoneOffset) { + data["g"] = encode + } + payload["a"] = data + + // Don't pass expired SIDs to m.stripe.com + fraudDetectionData.resetSIDIfExpired() + + let otherData: [String: Any] = [ + "d": fraudDetectionData.muid ?? "", + "e": fraudDetectionData.sid ?? "", + "k": Bundle.stp_applicationName() ?? "", + "l": Bundle.stp_applicationVersion() ?? "", + "m": NSNumber(value: StripeAPI.deviceSupportsApplePay()), + "o": osVersion, + "s": deviceModel, + ] + payload["b"] = otherData + payload["tag"] = STPAPIClient.STPSDKVersion + payload["src"] = "ios-sdk" + payload["v2"] = NSNumber(value: 1) + return payload + } + + private func sendTelemetryRequest( + jsonPayload: [String: Any], + completion: ((Result<[String: Any], Error>) -> Void)? = nil + ) { + var request = URLRequest(url: TelemetryURL) + request.httpMethod = "POST" + request.setValue("application/json", forHTTPHeaderField: "Content-Type") + let data = try? JSONSerialization.data( + withJSONObject: jsonPayload, + options: [] + ) + request.httpBody = data + let task = urlSession.dataTask(with: request as URLRequest) { (data, response, error) in + guard + error == nil, + let response = response as? HTTPURLResponse, + response.statusCode == 200, + let data = data, + let responseDict = try? JSONSerialization.jsonObject(with: data, options: []) + as? [String: Any] + else { + completion?(.failure(error ?? NSError.stp_genericFailedToParseResponseError())) + return + } + + // Update fraudDetectionData + if let muid = responseDict["muid"] as? String { + self.fraudDetectionData.muid = muid + } + if let guid = responseDict["guid"] as? String { + self.fraudDetectionData.guid = guid + } + if self.fraudDetectionData.sid == nil, + let sid = responseDict["sid"] as? String + { + self.fraudDetectionData.sid = sid + self.fraudDetectionData.sidCreationDate = Date() + } + completion?(.success(responseDict)) + } + task.resume() + } +} diff --git a/Pods/StripeCore/StripeCore/StripeCore/Source/Telemetry/UserDefaults+PaymentsCore.swift b/Pods/StripeCore/StripeCore/StripeCore/Source/Telemetry/UserDefaults+PaymentsCore.swift new file mode 100644 index 0000000..98abd45 --- /dev/null +++ b/Pods/StripeCore/StripeCore/StripeCore/Source/Telemetry/UserDefaults+PaymentsCore.swift @@ -0,0 +1,42 @@ +// +// UserDefaults+PaymentsCore.swift +// StripeCore +// +// Created by David Estes on 11/16/21. +// Copyright © 2021 Stripe, Inc. All rights reserved. +// + +import Foundation + +extension UserDefaults { + /// Canonical list of all UserDefaults keys the SDK uses. + enum StripePaymentsCoreKeys: String { + /// The key for a dictionary FraudDetectionData dictionary. + case fraudDetectionData = "com.stripe.lib:FraudDetectionDataKey" + } + + var fraudDetectionData: FraudDetectionData? { + get { + let key = StripePaymentsCoreKeys.fraudDetectionData.rawValue + guard let data = data(forKey: key) else { + return nil + } + do { + return try JSONDecoder().decode(FraudDetectionData.self, from: data) + } catch let e { + assertionFailure("\(e)") + return nil + } + } + set { + let key = StripePaymentsCoreKeys.fraudDetectionData.rawValue + do { + let data = try JSONEncoder().encode(newValue) + setValue(data, forKey: key) + } catch let e { + assertionFailure("\(e)") + return + } + } + } +} diff --git a/Pods/StripeCore/StripeCore/StripeCore/Source/UI/UIActivityIndicatorView+Stripe.swift b/Pods/StripeCore/StripeCore/StripeCore/Source/UI/UIActivityIndicatorView+Stripe.swift new file mode 100644 index 0000000..afc18ef --- /dev/null +++ b/Pods/StripeCore/StripeCore/StripeCore/Source/UI/UIActivityIndicatorView+Stripe.swift @@ -0,0 +1,35 @@ +// +// UIActivityIndicatorView+Stripe.swift +// StripeCore +// +// Created by Mel Ludowise on 3/9/21. +// Copyright © 2021 Stripe, Inc. All rights reserved. +// + +import UIKit + +@_spi(STP) extension UIActivityIndicatorView { + #if DEBUG + /// Disables animation for `stp_startAnimatingAndShow`. + /// + /// This should be disabled in snapshot tests. + public static var stp_isAnimationEnabled = true + #endif + + /// This method should be used in place of `hidesWhenStopped` and `startAnimating()` + /// so we can ensure consistency in snapshot tests. + public func stp_startAnimatingAndShow() { + isHidden = false + #if DEBUG + guard UIActivityIndicatorView.stp_isAnimationEnabled else { return } + #endif + startAnimating() + } + + /// This method should be used in place of and `hidesWhenStopped` and `stopAnimating()` + /// so we can ensure consistency in snapshot tests. + public func stp_stopAnimatingAndHide() { + isHidden = true + stopAnimating() + } +} diff --git a/Pods/StripeCore/StripeCore/StripeCore/Source/UI/UIFont+Stripe.swift b/Pods/StripeCore/StripeCore/StripeCore/Source/UI/UIFont+Stripe.swift new file mode 100644 index 0000000..bc6f01f --- /dev/null +++ b/Pods/StripeCore/StripeCore/StripeCore/Source/UI/UIFont+Stripe.swift @@ -0,0 +1,88 @@ +// +// UIFont+Stripe.swift +// StripeCore +// +// Created by Yuki Tokuhiro on 11/11/20. +// Copyright © 2020 Stripe, Inc. All rights reserved. +// + +import Foundation +import UIKit + +@_spi(STP) extension UIFont { + /// The default size category used to compute font size prior to scaling it. + /// + /// - seealso: + /// https://developer.apple.com/documentation/uikit/uifont/scaling_fonts_automatically + private static let defaultSizeCategory: UIContentSizeCategory = .large + + public static func preferredFont( + forTextStyle style: TextStyle, + weight: Weight, + maximumPointSize: CGFloat? = nil + ) -> UIFont { + let metrics = UIFontMetrics(forTextStyle: style) + let desc = UIFontDescriptor.preferredFontDescriptor(withTextStyle: style) + let font = UIFont.systemFont(ofSize: desc.pointSize, weight: weight) + + if let maximumPointSize = maximumPointSize { + return metrics.scaledFont(for: font, maximumPointSize: maximumPointSize) + } + return metrics.scaledFont(for: font) + } + + /// Creates a copy of this `UIFont` with a point size matching the specified style and weight. + /// + /// - Parameters: + /// - style: The style used to determine the font's size. + /// - weight: The weight to apply to the font. + public func withPreferredSize( + forTextStyle style: TextStyle, + weight: Weight? = nil + ) -> UIFont { + // Determine the font size for the system default font for this style + // at the default font scale, apply the size to this font, then return a + // scaled font using UIFontMetrics. + // + // Note: We must scale the font in this way rather than directly using the + // font size for the current scale, or UILabel won't adjust the font size + // if the size category dynamically changes. + + // Get font descriptor for the font system default font with this style + // using the unscaled size category + let systemDefaultFontDescriptor = UIFontDescriptor.preferredFontDescriptor( + withTextStyle: style, + compatibleWith: UITraitCollection( + preferredContentSizeCategory: UIFont.defaultSizeCategory + ) + ) + + // If no weight was specified, use the weight associated with the system + // default font for this TextStyle + var useWeight = weight + if weight == nil, + let traits = systemDefaultFontDescriptor.fontAttributes[.traits] + as? [UIFontDescriptor.TraitKey: Any], + let systemDefaultWeight = traits[.weight] as? Weight + { + useWeight = systemDefaultWeight + } + + // Create a descriptor that set's the font to the specified weight + let descriptor = fontDescriptor.addingAttributes([ + .traits: [ + UIFontDescriptor.TraitKey.weight: useWeight + ] + ]) + + // Get the point size used by the system font for this style + let pointSize = systemDefaultFontDescriptor.pointSize + + // Apply the weight and size to the font + let font = UIFont(descriptor: descriptor, size: pointSize) + + // Scale the font for the current size category + let metrics = UIFontMetrics(forTextStyle: style) + return metrics.scaledFont(for: font) + } +} diff --git a/Pods/StripePayments/LICENSE b/Pods/StripePayments/LICENSE new file mode 100644 index 0000000..edf2d13 --- /dev/null +++ b/Pods/StripePayments/LICENSE @@ -0,0 +1,21 @@ +The MIT License + +Copyright (c) 2011- Stripe, Inc. (https://stripe.com) + +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. diff --git a/Pods/StripePayments/README.md b/Pods/StripePayments/README.md new file mode 100644 index 0000000..6af9163 --- /dev/null +++ b/Pods/StripePayments/README.md @@ -0,0 +1,141 @@ +# Stripe iOS SDK + +[![Travis](https://img.shields.io/travis/stripe/stripe-ios/master.svg?style=flat)](https://travis-ci.org/stripe/stripe-ios) +[![CocoaPods](https://img.shields.io/cocoapods/v/Stripe.svg?style=flat)](http://cocoapods.org/?q=author%3Astripe%20name%3Astripe) +[![Carthage compatible](https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat)](https://github.com/Carthage/Carthage) +[![License](https://img.shields.io/cocoapods/l/Stripe.svg?style=flat)](https://github.com/stripe/stripe-ios/blob/master/LICENSE) +[![Platform](https://img.shields.io/cocoapods/p/Stripe.svg?style=flat)](https://github.com/stripe/stripe-ios#) + +The Stripe iOS SDK makes it quick and easy to build an excellent payment experience in your iOS app. We provide powerful and customizable UI screens and elements that can be used out-of-the-box to collect your users' payment details. We also expose the low-level APIs that power those UIs so that you can build fully custom experiences. + +Get started with our [📚 integration guides](https://stripe.com/docs/payments/accept-a-payment?platform=ios) and [example projects](#examples), or [📘 browse the SDK reference](https://stripe.dev/stripe-ios/docs/index.html). + +Learn about our [Stripe Identity iOS SDK](StripeIdentity/README.md) to verify the identity of your users on iOS. + +> Updating to a newer version of the SDK? See our [migration guide](https://github.com/stripe/stripe-ios/blob/master/MIGRATING.md) and [changelog](https://github.com/stripe/stripe-ios/blob/master/CHANGELOG.md). + +Table of contents +================= + + + * [Features](#features) + * [Releases](#releases) + * [Requirements](#requirements) + * [Getting started](#getting-started) + * [Integration](#integration) + * [Examples](#examples) + * [Card scanning](#card-scanning) + * [Contributing](#contributing) + * [Migrating](#migrating-from-older-versions) + * [Licenses](#licenses) + + + +## Features + +**Simplified security**: We make it simple for you to collect sensitive data such as credit card numbers and remain [PCI compliant](https://stripe.com/docs/security#pci-dss-guidelines). This means the sensitive data is sent directly to Stripe instead of passing through your server. For more information, see our [integration security guide](https://stripe.com/docs/security). + +**Apple Pay**: [StripeApplePay](StripeApplePay/README.md) provides a [seamless integration with Apple Pay](https://stripe.com/docs/apple-pay). + +**SCA-ready**: The SDK automatically performs native [3D Secure authentication](https://stripe.com/docs/payments/3d-secure) if needed to comply with [Strong Customer Authentication](https://stripe.com/docs/strong-customer-authentication) regulation in Europe. + +**Native UI**: We provide native screens and elements to collect payment details. For example, [PaymentSheet](https://stripe.com/docs/payments/accept-a-payment?platform=ios) is a prebuilt UI that combines all the steps required to pay - collecting payment details, billing details, and confirming the payment - into a single sheet that displays on top of your app. + +PaymentSheet + +**Stripe API**: [StripePayments](StripePayments/README.md) provides [low-level APIs](https://stripe.dev/stripe-ios/docs/Classes/STPAPIClient.html) that correspond to objects and methods in the Stripe API. You can build your own entirely custom UI on top of this layer, while still taking advantage of utilities like [STPCardValidator](https://stripe.dev/stripe-ios/docs/Classes/STPCardValidator.html) to validate your user’s input. + +**Card scanning**: We support card scanning on iOS 13 and higher. See our [Card scanning](#card-scanning) section. + +**App Clips**: The `StripeApplePay` module provides a [lightweight SDK for offering Apple Pay in an App Clip](https://stripe.com/docs/apple-pay#app-clips). + +**Localized**: We support the following localizations: Bulgarian, Catalan, Chinese (Hong Kong), Chinese (Simplified), Chinese (Traditional), Croatian, Czech, Danish, Dutch, English (US), English (United Kingdom), Estonian, Filipino, Finnish, French, French (Canada), German, Greek, Hungarian, Indonesian, Italian, Japanese, Korean, Latvian, Lithuanian, Malay, Maltese, Norwegian Bokmål, Norwegian Nynorsk (Norway), Polish, Portuguese, Portuguese (Brazil), Romanian, Russian, Slovak, Slovenian, Spanish, Spanish (Latin America), Swedish, Turkish, Thai and Vietnamese. + +#### Recommended usage + +If you're selling digital products or services that will be consumed within your app, (e.g. subscriptions, in-game currencies, game levels, access to premium content, or unlocking a full version), you must use Apple's in-app purchase APIs. See the [App Store review guidelines](https://developer.apple.com/app-store/review/guidelines/#payments) for more information. For all other scenarios you can use this SDK to process payments via Stripe. + +#### Privacy + +The Stripe iOS SDK collects data to help us improve our products and prevent fraud. This data is never used for advertising and is not rented, sold, or given to advertisers. Our full privacy policy is available at [https://stripe.com/privacy](https://stripe.com/privacy). + +For help with Apple's App Privacy Details form in App Store Connect, visit [Stripe iOS SDK Privacy Details](https://support.stripe.com/questions/stripe-ios-sdk-privacy-details). + +## Modules +|Module|Description|Compressed|Uncompressed| +|------|-----------|----------|------------| +|StripePaymentSheet|Stripe's [prebuilt payment UI](https://stripe.com/docs/payments/accept-a-payment?platform=ios&ui=payment-sheet).|2.7MB|6.3MB| +|Stripe|Contains all the below frameworks, plus [Issuing](https://stripe.com/docs/issuing/cards/digital-wallets?platform=iOS) and [Basic Integration](/docs/mobile/ios/basic).|2.3MB|5.1MB| +|StripeApplePay|[Apple Pay support](/docs/apple-pay), including `STPApplePayContext`.|0.4MB|1.0MB| +|StripePayments|Bindings for the Stripe Payments API.|1.0MB|2.6MB| +|StripePaymentsUI|Bindings for the Stripe Payments API, [STPPaymentCardTextField](https://stripe.com/docs/payments/accept-a-payment?platform=ios&ui=custom), STPCardFormView, and other UI elements.|1.7MB|3.9MB| + +## Releases + +We support Cocoapods, Carthage, and Swift Package Manager. + +If you link the library manually, use a version from our [releases](https://github.com/stripe/stripe-ios/releases) page and make sure to embed all of the required frameworks. + +For the `Stripe` module, link the following frameworks: +- `Stripe.xcframework` +- `Stripe3DS2.xcframework` +- `StripeApplePay.xcframework` +- `StripePayments.xcframework` +- `StripePaymentsUI.xcframework` +- `StripeCore.xcframework` +- `StripeUICore.xcframework` + +For other modules, follow the instructions below: +- [StripePaymentSheet](StripePaymentSheet/README.md#manual-linking) +- [StripePayments](StripePayments/README.md#manual-linking) +- [StripePaymentsUI](StripePaymentsUI/README.md#manual-linking) +- [StripeApplePay](StripeApplePay/README.md#manual-linking) +- [StripeIdentity](StripeIdentity/README.md#manual-linking) + +If you're reading this on GitHub.com, please make sure you are looking at the [tagged version](https://github.com/stripe/stripe-ios/tags) that corresponds to the release you have installed. Otherwise, the instructions and example code may be mismatched with your copy. + +## Requirements + +The Stripe iOS SDK requires Xcode 13.2.1 or later and is compatible with apps targeting iOS 13 or above. We support Catalyst on macOS 10.16 or later. + +For iOS 12 support, please use [v22.8.4](https://github.com/stripe/stripe-ios/tree/v22.8.4). For iOS 11 support, please use [v21.13.0](https://github.com/stripe/stripe-ios/tree/v21.13.0). For iOS 10, please use [v19.4.0](https://github.com/stripe/stripe-ios/tree/v19.4.0). If you need to support iOS 9, use [v17.0.2](https://github.com/stripe/stripe-ios/tree/v17.0.2). + +Requirements for the **Stripe Identity iOS SDK** can be found [here](StripeIdentity/README.md#requirements). + +## Getting started + +### Integration + +Get started with our [📚 integration guides](https://stripe.com/docs/payments/accept-a-payment?platform=ios) and [example projects](/Example), or [📘 browse the SDK reference](https://stripe.dev/stripe-ios/docs/index.html) for fine-grained documentation of all the classes and methods in the SDK. + +### Examples + +- [Prebuilt UI](Example/PaymentSheet%20Example) (Recommended) + - This example demonstrates how to build a payment flow using [`PaymentSheet`](https://stripe.com/docs/payments/accept-a-payment?platform=ios), an embeddable native UI component that lets you accept [10+ payment methods](https://stripe.com/docs/payments/payment-methods/integration-options#payment-method-product-support) with a single integration. + +- [Non-Card Payment Examples](Example/Non-Card%20Payment%20Examples) + - This example demonstrates how to manually accept various payment methods using the Stripe API. + +## Card scanning + +[PaymentSheet](https://stripe.com/docs/payments/accept-a-payment?platform=ios) offers built-in card scanning. To enable card scanning, you'll need to set `NSCameraUsageDescription` in your application's plist, and provide a reason for accessing the camera (e.g. "To scan cards"). Card scanning is supported on devices with iOS 13 or higher. + +You can demo this feature in our [PaymentSheet example app](Example/PaymentSheet%20Example). When you run the example app on a device, you'll see a "Scan Card" button when adding a new card. + +## Contributing + +We welcome contributions of any kind including new features, bug fixes, and documentation improvements. Please first open an issue describing what you want to build if it is a major change so that we can discuss how to move forward. Otherwise, go ahead and open a pull request for minor changes such as typo fixes and one liners. + +### Running tests + +1. Install Carthage 0.37 or later (if you have homebrew installed, `brew install carthage`) +2. From the root of the repo, run `bundle install && bundle exec fastlane stripeios_tests`. This will install the test dependencies and run the tests. +3. Once you have run this once, you can also run the tests in Xcode from the `StripeiOS` target in `Stripe.xcworkspace`. Make sure to use the iPhone 12 mini, iOS 15.4 simulator so the snapshot tests will pass. + +## Migrating from older versions + +See [MIGRATING.md](https://github.com/stripe/stripe-ios/blob/master/MIGRATING.md) + +## Licenses + +- [Stripe iOS SDK License](LICENSE) diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/NSData+JWEHelpers.h b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/NSData+JWEHelpers.h new file mode 100644 index 0000000..fbfb990 --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/NSData+JWEHelpers.h @@ -0,0 +1,22 @@ +// +// NSData+JWEHelpers.h +// Stripe3DS2 +// +// Created by Cameron Sabol on 1/29/19. +// Copyright © 2019 Stripe. All rights reserved. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface NSData (JWEHelpers) + +- (nullable NSString *)_stds_base64URLEncodedString; +- (nullable NSString *)_stds_base64URLDecodedString; + +@end + +NS_ASSUME_NONNULL_END + +void _stds_import_nsdata_jwehelpers(void); diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/NSData+JWEHelpers.m b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/NSData+JWEHelpers.m new file mode 100644 index 0000000..4ba417c --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/NSData+JWEHelpers.m @@ -0,0 +1,37 @@ +// +// NSData+JWEHelpers.m +// Stripe3DS2 +// +// Created by Cameron Sabol on 1/29/19. +// Copyright © 2019 Stripe. All rights reserved. +// + +#import "NSData+JWEHelpers.h" + +#import "NSString+JWEHelpers.h" + +NS_ASSUME_NONNULL_BEGIN + +@implementation NSData (STDSJSONWebEncryption) + +- (nullable NSString *)_stds_base64URLEncodedString { + // ref. https://tools.ietf.org/html/draft-ietf-jose-json-web-signature-41#appendix-C + NSString *unpaddedBase64EncodedString = [[[[self base64EncodedStringWithOptions:0] + stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@"="]] // remove extra padding + stringByReplacingOccurrencesOfString:@"+" withString:@"-"] // replace "+" character w/ "-" + stringByReplacingOccurrencesOfString:@"/" withString:@"_"]; // replace "/" character w/ "_" + + return unpaddedBase64EncodedString; +} + +- (nullable NSString *)_stds_base64URLDecodedString { + return [[[self base64EncodedStringWithOptions:0] + stringByReplacingOccurrencesOfString:@"-" withString:@"+"] // replace "-" character w/ "+" + stringByReplacingOccurrencesOfString:@"_" withString:@"/"]; // replace "_" character w/ "/" +} + +@end + +NS_ASSUME_NONNULL_END + +void _stds_import_nsdata_jwehelpers() {} diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/NSDictionary+DecodingHelpers.h b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/NSDictionary+DecodingHelpers.h new file mode 100644 index 0000000..95a31a4 --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/NSDictionary+DecodingHelpers.h @@ -0,0 +1,49 @@ +// +// NSDictionary+DecodingHelpers.h +// Stripe3DS2 +// +// Created by Yuki Tokuhiro on 3/27/19. +// Copyright © 2019 Stripe. All rights reserved. +// + +#import + +#import "STDSJSONDecodable.h" + +NS_ASSUME_NONNULL_BEGIN + +/** + Errors are populated according to the following rules: + - If the field is required and... + - the value is nil or empty -> STDSErrorCodeJSONFieldMissing + - the value is the wrong type -> STDSErrorCodeJSONFieldInvalid + - validator returns NO -> STDSErrorCodeJSONFieldInvalid + + - If the field is not required and... + - the value is nil -> valid, no error + - the value is empty -> STDSErrorCodeJSONFieldInvalid + - the value is the wrong type -> STDSErrorCodeJSONFieldInvalid + - validator returns NO -> STDSErrorCodeJSONFieldInvalid + */ +@interface NSDictionary (DecodingHelpers) + +/// Convenience method to extract an NSArray and populate it with instances of arrayElementType. +/// If isRequired is YES, returns nil without error if the key is not present +- (nullable NSArray *)_stds_arrayForKey:(NSString *)key arrayElementType:(Class)arrayElementType required:(BOOL)isRequired error:(NSError **)error; + +- (nullable NSURL *)_stds_urlForKey:(NSString *)key required:(BOOL)isRequired error:(NSError **)error; + +- (nullable NSDictionary *)_stds_dictionaryForKey:(NSString *)key required:(BOOL)isRequired error:(NSError **)error; + +- (nullable NSNumber *)_stds_boolForKey:(NSString *)key required:(BOOL)isRequired error:(NSError **)error; + +/// Convenience method that calls `_stpStringForKey:validator:required:error:`, passing nil for the validator argument +- (nullable NSString *)_stds_stringForKey:(NSString *)key required:(BOOL)isRequired error:(NSError **)error; + +- (nullable NSString *)_stds_stringForKey:(NSString *)key validator:(nullable BOOL (^)(NSString *))validatorBlock required:(BOOL)isRequired error:(NSError **)error; + +@end + +NS_ASSUME_NONNULL_END + +void _stds_import_nsdictionary_decodinghelpers(void); diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/NSDictionary+DecodingHelpers.m b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/NSDictionary+DecodingHelpers.m new file mode 100644 index 0000000..684f190 --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/NSDictionary+DecodingHelpers.m @@ -0,0 +1,149 @@ +// +// NSDictionary+DecodingHelpers.m +// Stripe3DS2 +// +// Created by Yuki Tokuhiro on 3/27/19. +// Copyright © 2019 Stripe. All rights reserved. +// + +#import "NSDictionary+DecodingHelpers.h" + +#import "NSError+Stripe3DS2.h" + +@implementation NSDictionary (DecodingHelpers) + +#pragma mark - NSArray + +- (nullable NSArray *)_stds_arrayForKey:(NSString *)key arrayElementType:(Class)arrayElementType required:(BOOL)isRequired error:(NSError * _Nullable __autoreleasing * _Nullable)error { + id value = self[key]; + + // Missing? + if (value == nil || ([value isKindOfClass:[NSArray class]] && ((NSArray *)value).count == 0)) { + if (isRequired && error) { + *error = [NSError _stds_missingJSONFieldError:key]; + } + return nil; + } + + // Invalid type or value? + if (![value isKindOfClass:[NSArray class]]) { + if (error) { + *error = [NSError _stds_invalidJSONFieldError:key]; + } + return nil; + } + + NSMutableArray *returnArray = [NSMutableArray new]; + for (id json in value) { + if (![json isKindOfClass:[NSDictionary class]]) { + if (error) { + *error = [NSError _stds_invalidJSONFieldError:key]; + } + return nil; + } + id element = [arrayElementType decodedObjectFromJSON:json error:error]; + if (element) { + [returnArray addObject:element]; + } + } + + return returnArray; +} + +#pragma mark - NSURL + +- (nullable NSURL *)_stds_urlForKey:(NSString *)key required:(BOOL)isRequired error:(NSError * _Nullable __autoreleasing *)error { + NSString *urlRawString = [self _stds_stringForKey:key validator:^BOOL (NSString *value) { + return [NSURL URLWithString:value] != nil; + } required:isRequired error:error]; + + if (urlRawString) { + return [NSURL URLWithString:urlRawString]; + } else { + return nil; + } +} + +#pragma mark - NSDictionary + +- (nullable NSDictionary *)_stds_dictionaryForKey:(NSString *)key required:(BOOL)isRequired error:(NSError * _Nullable __autoreleasing *)error { + id value = self[key]; + + // Missing? + if (value == nil) { + if (error && isRequired) { + *error = [NSError _stds_missingJSONFieldError:key]; + } + return nil; + } + + // Invalid type? + if (![value isKindOfClass:[NSDictionary class]]) { + if (error) { + *error = [NSError _stds_invalidJSONFieldError:key]; + } + return nil; + } + + return value; +} + +#pragma mark - NSString + +- (nullable NSString *)_stds_stringForKey:(NSString *)key required:(BOOL)isRequired error:(NSError * _Nullable __autoreleasing * _Nullable)error { + return [self _stds_stringForKey:key validator:nil required:isRequired error:error]; +} + +- (nullable NSString *)_stds_stringForKey:(NSString *)key validator:(nullable BOOL (^)(NSString * _Nonnull))validatorBlock required:(BOOL)isRequired error:(NSError * _Nullable __autoreleasing * _Nullable)error { + id value = self[key]; + + // Missing? + if (value == nil || ([value isKindOfClass:[NSString class]] && ((NSString *)value).length == 0)) { + if (error) { + if (isRequired) { + *error = [NSError _stds_missingJSONFieldError:key]; + } else if (value != nil) { + *error = [NSError _stds_invalidJSONFieldError:key]; + } + } + return nil; + } + + // Invalid type or value? + if (![value isKindOfClass:[NSString class]] || (validatorBlock && !validatorBlock(value))) { + if (error) { + *error = [NSError _stds_invalidJSONFieldError:key]; + } + return nil; + } + + return value; +} + +#pragma mark - NSURL + +- (NSNumber *)_stds_boolForKey:(NSString *)key required:(BOOL)isRequired error:(NSError * _Nullable __autoreleasing *)error { + id value = self[key]; + + // Missing? + if (value == nil) { + if (error && isRequired) { + *error = [NSError _stds_missingJSONFieldError:key]; + } + return nil; + } + + // Invalid type? + if (![value isKindOfClass:[NSNumber class]]) { + if (error) { + *error = [NSError _stds_invalidJSONFieldError:key]; + } + return nil; + } + + return value; +} + +@end + +void _stds_import_nsdictionary_decodinghelpers() {} diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/NSError+Stripe3DS2.h b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/NSError+Stripe3DS2.h new file mode 100644 index 0000000..fcc7230 --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/NSError+Stripe3DS2.h @@ -0,0 +1,34 @@ +// +// NSError+Stripe3DS2.h +// Stripe3DS2 +// +// Created by Yuki Tokuhiro on 3/27/19. +// Copyright © 2019 Stripe. All rights reserved. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface NSError (Stripe3DS2) + + +/// Represents an error where a JSON field value is not valid (e.g. expected 'Y' or 'N' but received something else). ++ (instancetype)_stds_invalidJSONFieldError:(NSString *)fieldName; + +/// Represents an error where a JSON field was either required or conditionally required but missing, empty, or null. ++ (instancetype)_stds_missingJSONFieldError:(NSString *)fieldName; + +/// Represents an error where a network request timed out. ++ (instancetype)_stds_timedOutError; + +// We explicitly do not provide any more info here based on security recommendations +// "the recipient MUST NOT distinguish between format, padding, and length errors of encrypted keys" +// https://tools.ietf.org/html/rfc7516#section-11.5 ++ (instancetype)_stds_jweError; + +@end + +NS_ASSUME_NONNULL_END + +void _stds_import_nserror_stripe3ds2(void); diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/NSError+Stripe3DS2.m b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/NSError+Stripe3DS2.m new file mode 100644 index 0000000..6908dba --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/NSError+Stripe3DS2.m @@ -0,0 +1,40 @@ +// +// NSError+Stripe3DS2.m +// Stripe3DS2 +// +// Created by Yuki Tokuhiro on 3/27/19. +// Copyright © 2019 Stripe. All rights reserved. +// + +#import "NSError+Stripe3DS2.h" +#import "STDSLocalizedString.h" + +#import "STDSStripe3DS2Error.h" + +@implementation NSError (Stripe3DS2) + ++ (instancetype)_stds_invalidJSONFieldError:(NSString *)fieldName { + return [NSError errorWithDomain:STDSStripe3DS2ErrorDomain + code:STDSErrorCodeJSONFieldInvalid + userInfo:@{STDSStripe3DS2ErrorFieldKey: fieldName}]; +} + ++ (instancetype)_stds_missingJSONFieldError:(NSString *)fieldName { + return [NSError errorWithDomain:STDSStripe3DS2ErrorDomain + code:STDSErrorCodeJSONFieldMissing + userInfo:@{STDSStripe3DS2ErrorFieldKey: fieldName}]; +} + ++ (instancetype)_stds_timedOutError { + return [NSError errorWithDomain:STDSStripe3DS2ErrorDomain + code:STDSErrorCodeTimeout + userInfo:@{NSLocalizedDescriptionKey : STDSLocalizedString(@"Timeout", @"Error description for when a network request times out. English value is as required by UL certification.")}]; +} + ++ (instancetype)_stds_jweError { + return [[NSError alloc] initWithDomain:STDSStripe3DS2ErrorDomain code:STDSErrorCodeDecryptionVerification userInfo:nil]; +} + +@end + +void _stds_import_nserror_stripe3ds2() {} diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/NSLayoutConstraint+LayoutSupport.h b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/NSLayoutConstraint+LayoutSupport.h new file mode 100644 index 0000000..70e8126 --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/NSLayoutConstraint+LayoutSupport.h @@ -0,0 +1,55 @@ +// +// NSLayoutConstraint+LayoutSupport.h +// Stripe3DS2 +// +// Created by Andrew Harrison on 2/27/19. +// Copyright © 2019 Stripe. All rights reserved. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface NSLayoutConstraint (LayoutSupport) + +/** + Provides an NSLayoutConstraint where the `NSLayoutAttributeTop` is equal for both views, with a multiplier of 1, and a constant of 0. + + @param view1 The view to constrain. + @param view2 The view to constraint to. + @return An NSLayoutConstraint that is constraining the first view to the second at the top. + */ ++ (NSLayoutConstraint *)_stds_topConstraintWithItem:(id)view1 toItem:(id)view2; + +/** + Provides an NSLayoutConstraint where the `NSLayoutAttributeLeft` is equal for both views, with a multiplier of 1, and a constant of 0. + + @param view1 The view to constrain. + @param view2 The view to constraint to. + @return An NSLayoutConstraint that is constraining the first view to the second on the left. + */ ++ (NSLayoutConstraint *)_stds_leftConstraintWithItem:(id)view1 toItem:(id)view2; + +/** + Provides an NSLayoutConstraint where the `NSLayoutAttributeRight` is equal for both views, with a multiplier of 1, and a constant of 0. + + @param view1 The view to constrain. + @param view2 The view to constraint to. + @return An NSLayoutConstraint that is constraining the first view to the second on the right. + */ ++ (NSLayoutConstraint *)_stds_rightConstraintWithItem:(id)view1 toItem:(id)view2; + +/** + Provides an NSLayoutConstraint where the `NSLayoutAttributeBottom` is equal for both views, with a multiplier of 1, and a constant of 0. + + @param view1 The view to constrain. + @param view2 The view to constraint to. + @return An NSLayoutConstraint that is constraining the first view to the second at the bottom. + */ ++ (NSLayoutConstraint *)_stds_bottomConstraintWithItem:(id)view1 toItem:(id)view2; + +@end + +NS_ASSUME_NONNULL_END + +void _stds_import_nslayoutconstraint_layoutsupport(void); diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/NSLayoutConstraint+LayoutSupport.m b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/NSLayoutConstraint+LayoutSupport.m new file mode 100644 index 0000000..96723fa --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/NSLayoutConstraint+LayoutSupport.m @@ -0,0 +1,32 @@ +// +// NSLayoutConstraint+LayoutSupport.m +// Stripe3DS2 +// +// Created by Andrew Harrison on 2/27/19. +// Copyright © 2019 Stripe. All rights reserved. +// + +#import "NSLayoutConstraint+LayoutSupport.h" + +@implementation NSLayoutConstraint (LayoutSupport) + + ++ (NSLayoutConstraint *)_stds_topConstraintWithItem:(id)view1 toItem:(id)view2 { + return [NSLayoutConstraint constraintWithItem:view1 attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:view2 attribute:NSLayoutAttributeTop multiplier:1 constant:0]; +} + ++ (NSLayoutConstraint *)_stds_leftConstraintWithItem:(id)view1 toItem:(id)view2 { + return [NSLayoutConstraint constraintWithItem:view1 attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:view2 attribute:NSLayoutAttributeLeft multiplier:1 constant:0]; +} + ++ (NSLayoutConstraint *)_stds_rightConstraintWithItem:(id)view1 toItem:(id)view2 { + return [NSLayoutConstraint constraintWithItem:view1 attribute:NSLayoutAttributeRight relatedBy:NSLayoutRelationEqual toItem:view2 attribute:NSLayoutAttributeRight multiplier:1 constant:0]; +} + ++ (NSLayoutConstraint *)_stds_bottomConstraintWithItem:(id)view1 toItem:(id)view2 { + return [NSLayoutConstraint constraintWithItem:view1 attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:view2 attribute:NSLayoutAttributeBottom multiplier:1 constant:0]; +} + +@end + +void _stds_import_nslayoutconstraint_layoutsupport() {} diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/NSString+EmptyChecking.h b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/NSString+EmptyChecking.h new file mode 100644 index 0000000..132f10f --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/NSString+EmptyChecking.h @@ -0,0 +1,21 @@ +// +// NSString+EmptyChecking.h +// Stripe3DS2 +// +// Created by Andrew Harrison on 3/4/19. +// Copyright © 2019 Stripe. All rights reserved. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface NSString (EmptyChecking) + ++ (BOOL)_stds_isStringEmpty:(NSString *)string; + +@end + +NS_ASSUME_NONNULL_END + +void _stds_import_nsstring_emptychecking(void); diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/NSString+EmptyChecking.m b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/NSString+EmptyChecking.m new file mode 100644 index 0000000..72d4a95 --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/NSString+EmptyChecking.m @@ -0,0 +1,27 @@ +// +// NSString+EmptyChecking.m +// Stripe3DS2 +// +// Created by Andrew Harrison on 3/4/19. +// Copyright © 2019 Stripe. All rights reserved. +// + +#import "NSString+EmptyChecking.h" + +@implementation NSString (EmptyChecking) + ++ (BOOL)_stds_isStringEmpty:(NSString *)string { + if (string.length == 0) { + return YES; + } + + if(![string stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]].length) { + return YES; + } + + return NO; +} + +@end + +void _stds_import_nsstring_emptychecking() {} diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/NSString+JWEHelpers.h b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/NSString+JWEHelpers.h new file mode 100644 index 0000000..74c6380 --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/NSString+JWEHelpers.h @@ -0,0 +1,23 @@ +// +// NSString+JWEHelpers.h +// Stripe3DS2 +// +// Created by Cameron Sabol on 1/29/19. +// Copyright © 2019 Stripe. All rights reserved. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface NSString (JWEHelpers) + +- (nullable NSString *)_stds_base64URLEncodedString; +- (nullable NSString *)_stds_base64URLDecodedString; +- (nullable NSData *)_stds_base64URLDecodedData; + +@end + +NS_ASSUME_NONNULL_END + +void _stds_import_nsstring_jwehelpers(void); diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/NSString+JWEHelpers.m b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/NSString+JWEHelpers.m new file mode 100644 index 0000000..b51679c --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/NSString+JWEHelpers.m @@ -0,0 +1,56 @@ +// +// NSString+JWEHelpers.m +// Stripe3DS2 +// +// Created by Cameron Sabol on 1/29/19. +// Copyright © 2019 Stripe. All rights reserved. +// + +#import "NSString+JWEHelpers.h" + +#import "NSData+JWEHelpers.h" + +NS_ASSUME_NONNULL_BEGIN + +@implementation NSString (JWEHelpers) + +- (nullable NSString *)_stds_base64URLEncodedString { + return [[self dataUsingEncoding:NSUTF8StringEncoding] _stds_base64URLEncodedString]; +} + +- (nullable NSString *)_stds_base64URLDecodedString { + NSData *data = [self _stds_base64URLDecodedData]; + return data != nil ? [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding] : nil; +} + +// ref. https://tools.ietf.org/html/draft-ietf-jose-json-web-signature-41#appendix-C +- (nullable NSData *)_stds_base64URLDecodedData { + NSCharacterSet *illegalBase64Chars = [NSCharacterSet characterSetWithCharactersInString:@"+/ \n"]; // TC_SDK_10556_001 & TC_SDK_10557_001 & TC_SDK_10558_001 & TC_SDK_10559_001 + if ([self hasSuffix:@"="] || [self rangeOfCharacterFromSet:illegalBase64Chars].location != NSNotFound) { + return nil; // invalid base64url string TC_SDK_10554_001 & TC_SDK_10555_001 + } + NSMutableString *decodedString = [[[self stringByReplacingOccurrencesOfString:@"-" withString:@"+"] // replace "-" character w/ "+" + stringByReplacingOccurrencesOfString:@"_" withString:@"/"] mutableCopy]; // replace "_" character w/ "/"]; + + switch (decodedString.length % 4) { + case 0: + break; // no padding needed + case 2: + [decodedString appendString:@"=="]; // pad with 2 + break; + case 3: + [decodedString appendString:@"="]; // pad with 1 + break; + default: + return nil; // invalid base64url string + + } + + return [[NSData alloc] initWithBase64EncodedString:decodedString options:0]; +} + +@end + +NS_ASSUME_NONNULL_END + +void _stds_import_nsstring_jwehelpers() {} diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/Resources/Images/Chevron@3x.png b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/Resources/Images/Chevron@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..42f836e1e1883b2d507fe016b12b2a4d955b8070 GIT binary patch literal 1035 zcmV+m1oZofP)PNY{-UxdB|;d~7jz zR7>s43!|TN<$Or>pEIfOF#S=v-aD{%dV2Cb=PVUcTm6=Sm{u-!Kmud0UR6o}F=Ikh z(AqAQtfo&pdLRo8e{YoPxOMAU^+@)6hI9Vb>UKPyTvY&{gw()h(-7^^H)Znd3pA(~ zz+IS-axI?Pm1p7&!h^aFQh>L^S;|>_-bZxvQ713Lfx&a}i*dX3?U!Xs=oHEC*~Ws}U?1c^U%`myAp_^3n#l8=3ET&Lp=9FWj&@thJPUK< z(&@D8({L^VqkR-}hx=4VyT5B5-vyaDWTQcYjySP7Q_hCk{TG~U3&qR|qFT}mr~VEE zT2{jGA~gF<3EP~oG~3Zca)&UO4*TnI@&fYZ4mEHB+L(8;J7H1)B1C#qTbN;_U{6*P zW|#24xUt4l8S?pj({|ix?HGWFv75;axheJl0<9-ZlAPad@GMaw(4>UhlsN+sFRTqh zC6o7=5RHV{CA4g?(zE1X(B~Vs0CI}m8}j5bWBpLkcEaouTKBxNW_cjEfA=uq ziwZzaeSMFXk4ewE_B+2<}#;W#qs@~6k6o6h9z5Q^7nEd(9{-Gh8DLH@eM*+%K zK|G$SpAd%r&-b8gQ&hHdP_~m?wr^2czo!4?e^Aap+AldY<6)>@>)ikV002ovPDHLk FV1jxkUA&zyPY+k1#25k3t*001CTR+7{F$H@PHhx6|YtLsqvM?g1C zMHxWJ5Z%tdiyTZ}*-A|f!1d3@0{}y90a*V@{(o~CqcG8z=YSq$zt2 z1u(^efM(+6fGzGuH7JfV4rYsM8(>K9V@e0%G9k{V4SyiAbYCQxx{aFfst<@MW;W}H zFX%5w^?$L@)z!NA54YU4r$M?34$u3~PD(3{zb8i+_d?;k!U^abLi zl1Rw0m#^V)-A?GZDVfvdVaJx%wlC|`w2+H`<7L*|fPY`flQZ1fRIS($HMA1Fkxtgh z&wRH+NDm5ofG7QlB?Rr1A95Fb-!Z3q~kbcucVCY4!cRKM{E; z(j=j!0VRCC0ZL?@d9MpP7;mzoko2ps)gXpt%ZRk0`jZpD_cUt<&tLA_e`nxwOus=h)NGH+yc`~0mm#?OB&Q( z>$#26RgCn}09xVFw`__t*@DVDGT<(N_*#v=Z>Xx@T(r49?4i_*b^ zyb-#o}QU|VQ?}0*16JkG|d}p1HhZ%>Z zTVpkn<;;EdF9E;9mmF&36Ayw69wUAE^2&3@H{@vn;ShKgNlOz)oMMR{)8zA4a3itGM@(ELQ{C z>xV*5hE*6qR22phH|bx&P1V?+53mWtIw=GM?l#JcE*%fyhE1l|R z{_~y33p-FzZ{8%A)tEf5TORn7Q%fsen}c%CY;kRcvKf_q3!2KcW|5j5l-%7DtQoZj4P-7qPWW}HJ04hihXb4@~(&cRm|?N_Hl*D9O8 z%q}I$?aunOI}7;cGmHrd!r)@n-f=&;cxI1g2VL{BY%(nWqSMTJzL#3cQ+I3XxBgH` zztiNPSoTF#W>wX9{}i#TIWQa+NrEYJEHKxxzxcEt1KFHqUH_eEFcF|heRemUvI8E{ z>MT~>^d_n&ZNAtFGHm#xd@22N50bAS?3U$*%gyLMjT;>C5k&CgK;OgVl=@@4Ua40_ zV%;WdW2Ab3UT!RO+oN>rlG_oh+2Tm+;3#-Dhf)S5qM#MI*l|<$Ln7cWMh)YYY&x?X zeH=oNJ1SFndok1Qj9m9P;`UcMdSl(@cMrBzZA|V%vih2}Q>--Eo`qvOC)#p1HrO{5 ze>?tY|3rETZ-nnn3I3$jhJZI{1eYhYXp_0jMc9ceurgUUTS21H=s7j<8B~W6GU~It z`;5OjWuU_=LB!4d-Sp25-LvDJkx#nHN(CK##{6f``;{s@I~9WsTJ^@>y5{l2Bfg5* zplUxy1Yo)N;E}%M!UWAww$xlAFF)5MG`OY|&bl}(D9357TK{Z#x613cGWb-A*;f8= z^)Ge+69x3j*LxRdkD+swV1X7q$(siKpk1}P%9u2Nnq45o^_q3NvjB|T_0F(SSnbG1 znp(KZ6JGW=Wga{! zNB{>(vte^zu*dd7&1+~plW3Ou?^{_tPtBnH?9z}+MMaGBXqII_2JJNJ8+qI!D&Lj+ zuKMy9U2a=O*2-Q!#VCTAuz`Kso~-#oQhoSE_z@RjYXq-igMv|fG-2HI$Rsp%l9w?a zQL)8k3TlQXBx$?kyRa})-|asS4__5; z6G_`P>-;+~&}RU%-LbkQqg%V_mSLhlpR{U7g#nb|Qtf&(LDq#y8UYh!4Y9l&>-$xr z!;t1^E%DYP?dkF4GD>Fj0ewLwKIU$=B53-Yb-(bFot&=T#C?I|$HfBY`)Q0wQjg=i zf(xCsIh+*$^Sb_sUz#Rno|iiRm)?;t^*TFdJn7tqHHf!Funl*Y_hioXMkFKMtz<3P zeO}UwU^_|ofCi8Id)U2c;rzkGpNHytwl)VHAhC-;9ENk)aWF>Q&e$)LUGi{4tb&Xa ziK-xe&7+WS<9DHR@-US4VkP-}tFqzH_xi8X9GTcka^BYdb)VB}+HX|ih=&Ep-hPQ1 z5lO2@dDrV%+}O>+=hrt&i~7XHD~5K{USG#3Zv86J9v*ex`Qq~!$>be$z zIf$S-aGG?I|> zj0*IS_TBafCyI}npq5@c6hS7iW-Kg{tdM(sEYa5D)n9vPcS@NjRLvx4JUrqyo~B2i zgizopB*qAQLJNFk+bC}jdcMP0sfDzJ=5LOsdjy&2yK})SLMB=(SzJQ}z6IQ@p3~CI zTcIG>vMG|OiFs0h0k@)VL;`t|DPHHUjj7-06SK#S51Om2zjkcTeDv$QUO9XrG8NTG z7{IM4%sw?>znVM$zLQX^s}NK^=HGQV+Dxn1*3*n59TK zy{UxSU0&$eV26VmFg!`s*9G$5$+=DKS4UuI)15&Cy?T!wrh>h5^y*v6?t+6|T{K?e zXb_@eMwT%pc*Zj>HT-37UNueKU>Sw!KCN+mZH6F1lyVgsv5x$ut4I;LR7Qo~D&aL% zsNU09EyA_g-f%g}{W_EU1?o4twYk~~_EwUh>U@D2!c=-I6^$dg8D12)-ThLg!dg+C zgjObLx3$NW43Dvz%p-%6?vIMOrVdPg;sGl2DpH50uq)e=b?+_v**W+ZyaWIKt=XhM zP7V~A(F{4O89))7I%2#^ljspKHO1TgLG!_Y&tOD1+Z5cGZNI{%tYRy z+GK(6V;r+#qQE#`4#yA2=EoW_w~or*nxW|5TUetp^@!FEJ$FmAk(CF@77PfY?NJQG z2p1G&&B^W^N~DHF?XsygVKIeLi_MFZlItrhia}k#(!uPlRnBc&SFlt--iyTc48m4X zYywh;jCPJJrDDQ-AO6-n{@>h1V&u56GK1><$>LJQY4S`XT{{BRy$u;BF#ma8wa&SW z-M!ZIE8(q7Eb{kQg#^^Nxm#3etkRjSF&k9M@4>R^xMQargy$EGf*S=tGM`^q7=5{} z8gJ||el42?nLfNZNmOtFJ}R>Hi+NgZCKfooLTLk zb(p4HD)wH&(7}FS%LCtg@ytu(PDwP-R8&tpG_jjYUMiT`xa1{sWEx4w$oQ`QPWNlR z{l7>~3mKeWyt)OlJQDDSD-6T>;xcZAP7K%99td~ncDKWbr$ZQafRWSJ4DN-4$qg(b zARbp@JxLAk3AZ$MP~`Hv1Wc_QOMjI)bs1n@TS$jTY`nJFw$1lPVg4D)L^hr&+0SZa zpWC^k1S(Vw$h4+9pKVy{c2MF%hh+;wN=^IJ@Wpr*-*s$~!c18^JDu-))|*&3&B>$8 zh0*XU7W*Jg4YCFS`9LLR+onC|mlkZTAwSyH*7WAAdV00kqJD6Cu87HpidV9#;yqm1 znl5CON4W8rS{Tub5TCCoT*?N6QT4lSYEnR$0dq+Q{gSKAAt(;+PE;=*$5?iV&fwFVc>y>TA zNQZ%#bzW&n(a+ZXfyPf>Pg~Oe?>x8f5O=2^h}yG+?q+Y~XE1MG(6YSiSXA?EHvo%H zvvmhFhvM5^;nxv2F<%}SCC3|ouR=l>5UbUK;x zHUGuoGldY-Ss=m0RCQma*&^ot))f3T&>Tux&vFGGJ(w|f&AA=x!T=$cr7k)#-b8Tx ztyMQJJid2m!o&O>>$O5pF;?a`^+Zb(vAtwZ61WO7uR0@R*Pd_e7cx3Lc4d(WYWErIEN%; z>r(+Y?wrv$JX?~(G4L@j7i5GxQC65RfSW8S=#GVPV?E@*lBigCoqTcnz>jdZ)ssIp z&T@Sd=J)EU*KQxq*|MVjFQ@Meb^y%l=7+&7=q^U?%5=m~bpVkM_TtX;00_BGTeGhg zZ_YSlKY;JO(V$SHpv=aY9i)=_`<*g@G7zVzp4Rt?E@t#$RVcQ;lM*A`;D^0fkz?G#uWpducn z-4-GNUy+z;K3vfhwXF+ngp2hnE9eNfI?iNAtU!l$lQdQz@9gPGw8X!hc1q3ki9#cN zgK#gb7uKAIzHl+lGp%^buwOxf`VHz!DGo`?qR0-JrEUbU8M~dovH9Yxc@y<}ZyRh7 z^NK~4M+S}&L@qoAzm2*01lD^U^PFvh(a+rdox3GDm}ZBYs_}#ZMCJ9ef6b4ATx5fh z&~Ge5?*Z###{K7}hDp?#J4rk3A=MC7d6K6V`7XN56VQn(lF()_e9u@?$tD@we)XCp z=o?;SR(A!c>zjFqZ!dw0qt%vKS*e+5hg`QZSoZEap?Oo|To=w~rnjX_*7P@FdCaT}xWJ$ea+UfWuyM3R& zkKnx}jU>r_?0K?ceo{_f-?I0s#*!FR-S+ULZ@-~|i;vJ>LLWiJ3a#eGMU&#JG0Oc^ zDgB&>b z9Z&|u^}7^Gw(l>}@ zNEM9}dpZP@6lIwfmsDp{UHXF6jHHFuP8Ci5eNEQ%6=F%=h5B)yqeSA&>beHHx)+9b z&2+G%7g=`8$x=L)(Z)|L7Z_*SiH3rszYwAEg8ZJ^vaXoka8q~81yJvEpwf=*!mdWF z4H3tds@GI}@sh|QV~r9Z*BQp!FlDThpj!C7!&kWtDQy3P0FX3u#Na4|Z~we*mqB*@ z=L<;9mtmfphD8~BG0Bh6;+4#15h`bD0Ft>?M{t(^qt!13F=9EV(-d~aTxtm@)4_# zGQ5)hZNXH!rI#T=7q6riue{vURL2nD^nP1FJ3*}ZR#5;CRy?nie zvo1SFCV~=Y;wq)jSY*M5-S9oyTrKVL+B?%91m$ec9``B9GrJKxf9i+W9w* z(umyM{n7926ym+V^btW2*1J?`k2BLDeVL1QxLyiFBmLfodYe9LJ<+B;qfkGkDPy(y z8>-G*|LXF z(yE3|eoRNDg4nZGc&ehNw4Xx$GJ`mt!kAB$iY>*u^->O_w_9Z5}y&&5y0$h`w^2rU7RAegyIzwhUUjq3bZwR9poYRNPv-A;Emo(~P9cjx=hw#dB(A>!hHoHIiR zOKqXa4@;qQe|{!ep9&BT?~gg=b17~Tb-gNj6Eph$P%S>l=68JP+>Y)1$*7_iJHnk~ zHLtpVr_~qdMelU@+ zF`k;oJ@uhAs(C}-V-6Ga~09l@@{$$#_MR8sdeE8Gh1uk28>XkX^n)ck# zGdH~$Isr(IN=)NRCtPB>@z+RMU$ysb|5iQ(b-)hYCZO?*p~UhHO&j(C0Lr}x;B(+* zaP}oy#(?{mkvjn>YbZ$ST5z0!qEa(qqW%O%;kd?Tn05ZNOb%VNZNbG|m?fn^<2EAF znpL9Zj;U4P^fZ8P83)hkFOD-x7C}S7M}dQbLlYAfl81wX2g3fhAS1zkWl}XcVGW+W zu&TX+wXwaEo~;oazoE6h5viD!o{5pXk)ELoc)*AU4vx=IOo(66dGRO>HJ(t#Ww%X3 zJUjvopK~2|9S;w3R{32V-XAO6Sn|UV@y|~KV*P=t6dVxx_aXF-z@wdVQT@1;=oQis z|I{yTKR=OyKgEhxl9e~JRknO2?xi63u#*>Kb*6z~`LyV;R#JAb`uB9TQAz7LrSRnC z^+;YtNkv6PY3}Oz_Vx=r4B!9DC!7H#NtbOxeeCxF4QoP$DV4nV$mZZ1I5_Y6H$x2i zs`Zi(vox2~J-sCAO|uS35vUn2;73^fBn%uWsGSsX1c}1%4s8B@HMVEOorfs00HI=@ zGeiak0LCwrlw{{cEE(#ni>ftbdf1&zaJ%i4C4bjRUW4Mr#dB(v~Rnex(tku!s8lq+YdP8W6b#CZ{Q4hIGym|$FbTGL8MYUwUnqty+A zXk(xI_6vESuv8eICWY}QIf~sW&dWBJ$b#9pYS6K8$a-??7QFiH6z){Y?vJJuz0-&S zqL2R;kQDT@FFTNdWp2$jy!83$*#53xj>~auK(${qi+tzO!wp^pHNv1riax}i&PB0e zeB(ZZRi?m!&w-^Rqa}QmnOh1=#*J18{Xe8+CFaZjEGSc&mp*sa?KP^7yKha2gsY0p zgs?|xy(g49u`MzZ8jY)HH+$cK#ncyN{aa1&uuN4#rR252v7nkF-I46>GYnGq$Xy7& z^vbHB8H$rn9G`3W%K>ZMWCr1#t$tPoc_1M;8w;Er%%c)VZBxw-!9|R$eH7QeHKa0^ z_qoh1-^)EzNps+O9)*MWh1q`1$r4oX|Iq_gLE{)Z>z9Fu*Cre^l7(8%T$^}9C7 zQ@%SKuIsa$!c0toJjM0j_w+lxSR9kCSOAV~#=n|pxkE8(t>({kds^0OpTkm364MSC z#kG{mp)g#%>+$5|x=IV4&)KkCU!Lbyg--7w1Xw;fpE_buKGN7I0&wZyO6w<|FDvX& zGE8>BZQj85Imv881Lx?P7*|iU+OB^+97~nuCCFg(ZqxTp^{TGZum8gn4$P|FY21qp z5wINDC|eP;UU`16-h8Y0)bU#te-lKD%TXFUq0haaZd=Sbt%ij29#c?YUeqTJku(EF z{n%Pl=;~9igHe+AilQ5s`hQSG(_mWQgSYZ&F>OZuF4hKej$qig=2J(OJW;af}*8=(vbaL$|FF+Fsid ze(==kwdCmUV34{;Y)}YlXNT_(`P}!|T@N!nX|ZV36{LI=!W+zz_!D}TuNeGj>!4rt z7Q}=iKk_#}-89TilC;p7{@J*Ls38-=V0;8pkXo)j_{dO0dofuf$3J#-%ZekaqndUn)XH z{X#JJe~go24M5YdxT){ldH-;~#%JmuQ8QmHueTZUn+sm#JstX~rR#OW)kBhwz#(Hx zw6@EF;auNn1Q3IXFd|@7j?1}gj^;N%<%+^Lzd!x&L&ZS!VeL zI|}fzb4Tg*n5)s~+!M2noPmtYM*&mUG9ALTyI;Mp#FSs8?O>*#wGX5w@eD6**xouRE>X6#*eB1%&65xE3YNhvmx(m26$2)Vl2}&4qa$lML~gu-L2VB!>8yX8Jx4C7_b*?c zcwemm5$*imEHK=IAx7Bjggng(rAxQ>r(dAGq4A3A)wWq!*c=-l{=QxeF%>wq?Qc7D z5A%B-^u#q(m;C>w;=x;0w0PraC_SEi%@QMuwosRTYW&niP}>hfeN@v^wJTEUYpvRGK-#FCiU| z3aM)eEmgmL8h5LxG2XOoGQE4=G^5K?Cfrq>)wF%%ae`nygcw;qz6D6l{!>97JokEX zdYYxc_Z0J5TfPbd4BI-`dd;hZOP3z=gw^jl2Cn|9TYRuSRI>@~q+WUPYXc){T@U(} z>%C!V(wt2}iRn@%bW~#SM;uLV=;_5`b}uavH5w}H7fX`iz54pxang3X1{&>t{>P5v zzCY;iuJ8sAbHceT`X!RIpC3sIdfs^%RtALbuYMC0=RDN7YSnS!d>*y%6~0#$A~ZX5 zSm)wYd8EV8esyr&}-EtX|pSP6e$#48}B3HNBo7x%QPJSbh5gPXj%FDr*4~ zJ@=4213>>wp~SeIcdsXo0wPMm_yAVTco525)sLdrM{2Y4yRHUjvwhpc2xrjsg2|-R z((F{Xf(*gHp>2=#Gbho@L7fy`AazS<@63-stt?}+5EJMQ%*0z~l`&)L>=}=f`#CMy zjpbCmilL_v)dF1M52GdlS7sXGJDc??@_6hqBt;dM>%Hu^Kun=#G7j(|7Dlo?Q6%$^ zWAzO%%=~|c6y)?aDKda0qv>~{qZ^GgCbzq7bd|m^{u%jnYk0l{RG(0f5$s!Z_1v#I zUAx*b7=}7SKKyllD0&VOOjdva@ivNL>G$u6_{ct0uY9dm|A@`7d?{EUEk$K6T1r9f zXTF_WFi|^Kh8Jd0y|457q2#eJtR>s?nDq~b-NE9RJ0cJd285O)$I(P~Sr%UhL2rue z5pY85BrKeLz)VvBe_lIRk`=-#O#nHpJ}xN(2tUUwte2^daNz!!^Vp$UHiRLu2(Agi zkv>Lwic+g+tF6)3^SL=*O5(Y&zu0oFeo0PG&xcsIE~wSH?wXjLcT@BneO+K3ME#bo z?m$Jfa*kxe$L)BOdAw8?6&aom$@$@?DY1dm_Ka(PSF|R@n$Ojr*?24Q8m4Tk_p@tf z1Y&l&+H$9W1m}%uXlxvqpPz5~{BT{ZCnyrKsKzH?(XgPVGCe#xI=NV5VK!H)#m2|S z$KKhiZL{kN#wUGn2X*s=^oYoPlNk@o-+_cqbmmhHi1ajXzx#Tbj4 z397S2Mx95sx$iwdn2+H-;a`IoMMeMw<<1nTO!*+ZJ7|sXvWRW8h^bhVtZ_rcXr(v5 zlj_6qlKtWQ*wSE=_4BOUp~1P+WN281>v5sQ?N&5Yh?nX8ZAJ>$>(MeL&Tyu@3sQnh z^G%gb33f7!jlbf0dU}Mm%6nROI2r;Bf){M73Re=Fr%E*HBA4e_L=N6;)*))+S;Q*ECyoahYZ6fFC10`$h*_&7$IT)p?5k zqFGm%7TE4=y(6X-)LLeL(X7PgF@Ok7i8qpMsIe)1y#S^?7pqkv0V(0&!tpFW{=p<> zRiFW>&W9_s+u+2-#g+OtpJuUV=huV$OlmePmiRNLWjjGMeC5v1+f1R~Ge{uuD)fx% z*5vB-&!gfM@8RHddDdl<*(HV2o(_mjo;t4PF-R=dKph%&Ck>#CT=4tRn-Yb?*-~~R zuXu}&5JMlnZRAt~K8}+?+qXCfaP6v}9wv?yXhFRUBTYo9c1&XQK+nW@CYyd7zNy_Z z`y24x*+xaZV{5R6-8teybLAV3$ev&IMd8A`XHsjOQphkJewWiwTaTCIQ>Ov0x*OjV z=8p@X&7Ki3oXZbnv8Ps3HGVUSKc2Z=LW3rTCx2 zyodl+@S9v$qEu*8s&~m(1A6!z#^M8$GQ3(X7%0r?xRSlrYKlkqK0LBI8byB(5FleYDB_y#pY%Q(zegEHMxKtH*Md_?tI=9aQ(85x>jdL8h z#!zWrL?DNGO2igZlZbWLFls+m1J^%YIkh`3F$6ov0=He6o7_FUE9y%_`a8b=^Bcfb z?(o#HmzcfVgNJ#vZzG2@JB4BQ$BFCn8g-#Ge7{)7)RZa$z$N7w!UdOcbeMJ&$voD+ z+MF$1Q|^n}MOO#gbIi#S84#XVOHGb{GXni|A5yFK#+gcb0``20w5!~!hZ!b_ zRswd*`JWoKmIH}Sr>kj4Wdu7rJEl|lQUgz&o$yvGjWstnE1jnur#QZ4lsXFUn@At8 z?~h=L_U2?|X>N>7Xoh9TqW`uXrd7EY>zaQV?M_9F4ao1d{&O|n-;G_K!`ZGy{mFCS z$z$PUU|rZr5_;iDHjc7QzX(jua`DnC@d&kQHZs~tNRD-IOusPtwGR+Jw=`VU3E9QT z+qJBd+O@KjZ}ez%yZqx|vr3!+cpQkDYXjW;u5r@7XCGXW9yo4(zPKN7$Y|dA5z##7 zoSB@Qyl+0fQe%O8JYV4_ozAl`VNqwbwDX}A3kypt3{qHF7#Z0%bu4&xuKZ*7G~?ZY zqi^n!YFX=pxyi~#SJ1ngWJfo&C?f7zxs|Uj5rd-zBpFz+6-3)ieDo3mF1v)LhrjEg z4k$OPY4%yzzbWa0QhW^-pJgdYq;nPU^N>KvQNGb0#AH9I{8knR?-L+3eSwI;SvKKg zHv^R;n9xVe9GzV{woE!zR$VsSo%^<%Co$TRkm0B5_*TxALH&)-6n^Mqq*s87nt`)y zY_|V9ZDQ})(vmg%c%4%XoTJ8X7X6vJaLC*3YiUuC z3`zgM!7?MNQF3ufF{3dB*E8C|vK$=wN%_2*L4PTIztA3NxnjIAE`O8GI#1@AuJJo< z0A-q@d*aF0+K02&qX+2~f|gD{Z6?N?#&Wo=!`Z_Ay&#SJQIkcCo1=v|%^~Rk9XxuZ zqPJujaV<`X2X=2WH9pGHBl7dqQ^kGch>Vugzvzj~0odz)LJ?}!c7ckxDCAyT%dNW< zktot?PtxE3)FlTzhuIm3U(-Z5dk)Fdp>sV7->h%+>d06N`y~gZ<#>f1wL?U#n?!j? zLY{?VSoed4W#ehTCyZV;Dqqx-Yiq~QUp7Z(%+V?59*VprFd$nIb$F*&`()D`v4Vji z>&U!yt#p#EC!|iC`==jkOns1nEc)x%BAs5)Lvs zia80n+&}IY!szeiHp}V&L=^0rF`K9)G=Y=5sPNR{)HL2(wUN4^lh4uE401oues2d; zQ&KfaVIv~O;;`=LE+IjaTh?k=DI1Fw`eEH!KNAWV7hIyRwJ@zw{M9s@tvyM2*CH9P;05! zD5#NPZD;3G76X-!_WC_^w%?~mFNG5F$DsmjHRT1Szm5rSTV-fiha-w?%+`XbU%W^B za?(h8KH%X2<>x%8g=OPP*a41A>T`Ig1d(lT;C?R02SXC+K#J|;f|TTWiq+0h3yOd; zinpjCR;c9E^ybynhMN3w)^Uw4!?s@#F}Iadysv+u@*8L=sA)!(k7BPV$+63{?uGc@ z#rRUElj{|d!J=uj#+q4Gojh&iAx(JS-6f=&!sBUyVb!ZwMYUoI>%Xz-Y;xO+>`GLx z93bRv(>8>O;TZ=a`M5B4P*^mX!RC-Xl1%mncSo16e&zEMNBMlp**7B$vP4Tzvke81 z5S2gle$}O|CCN>`y40T#7H4UCp&h@^!XUb|T$$V6xTdq3)G%n`Tu#6#u^Y_VcWrL1@M!Y9F14e;<0sE{gZHuh($F1We za*yN^nILqcgT3!cGa*B|NoW}qI@|zjr5W42yZwB2>3)=I&`M*Z_LP%*#c zFoYN#t{ctfh+UYUVh+(?hDzL@dBUhH=i-6AV-e_yLqPQLo1*5JU(+B?Ol5Y*bmIUD zocexNH750W3V^e0gkB`SHX^Z)Tzu;8p?gkOT#htSeYSSuSNZQ8`9;&#E6v>YiR^Ez z$@oAnw-!~tx77s5MjLFLHgyF4hlVeNJkHEmz~*Q9V2JGZ4X(0%B*&JDuhq)MJLA_UEbkN`Ml$=QPsdSIgTp`w{a>Y0jYK2kg# zOTW8r&k*`WapgBWfJ~-~Bav9^B%3^;33T*pb_I)OgOZgoUlgZCft(|pQg~N`PQiiW zkjSWniwj3M#a?+rRV_yUtw{cxl2vlb?r`QU!@~%~!Nz>iWRbKmvXUyRR57%m`a;%^ z7nhoCJ&o!Is($o5?MiCmTbECb{9%y1VoM8zumy7k<%;=U%4^nW=R#WS$5|dg>nzd2 z>HorZo9e5LFAMu(L>L*9aWB&u?ge9Ebp63wN_xIGkD+^E(XLtXG>*kT(sEOgiSV3q z1p2H-=hQuI($zv#xg7Mrz^iaz+=Gyg4R^VrqXol_Ju%C&F zE7R6(u@x7UnYpqkc}YPi&xI)r_{HrpYBHma`;E$Ce>p;2IY5K;k_%MS9!vRlCJf}+ zY7lFT^#@yk*jsH${>?`f|%rl1BQW-E4vOi?*3-W!CtU zi`!v5W*Y}0q+qP*mQLB0&oHa;&oZU(H8E>l9Iji=Q*nXprlekL^a)iTL!N|h3=Ymz zyuVSOhKaf&z7ie2?&8XC%N$M7g-k6cPCG1@UlhlN;`f16o8qxWR&dp|j7(`7*2ULi zVa28NrW_c*Mj>wI`xpd6O{(bYJmWJJoo8^SQ^QL}05poMb}0YbPrx^hkLSB41`+kH z=La)I=hx_@Al(K`0fD68&qOHSZf+@s!mxxSd#b^FQkn|j$H7hZCG~Cc%4A8d_^Ogo z_V4dk)DmMMqSEQJ7q(R>L)hcWioq=v=Ugs>b>uXb!~1{REyCyJ)bQ)ExdjN(<%Xr& z0wNr$&PY|}@H>_&djfSd64cm={o%vjVTvwebKC?@b*VKkT-m5qV|s((K!v{B`AU}+ zgACi>7q3vC)yQOj-zGkjdo0-bI9zZRl)xiuaBd|8kKhfYD<(e%eZ!4$_>rd+JfKLF zuj_PHol@>#y&&M$;6}^z@pE!5y4+2AtsqB;dGD8^&n82&-zn*^i<&5P7!bFZ)5#bUci`AM#QhRdu%J^fpn}!_w*+#v^DIA-9X2u7EDZJLc zvn9MqRMM~D6kac-`=rYpneomQYSZ((sJ(uS$f?fTsHrEXQ?&Z*uTFFQg4MIB!zj6$ z+>sUGLfY|F9?2t#wizrw1EDBlI<0;5tfFEPv5pFjRRVsrHT{NW>&bND+t<$D4x1UF5|o*m4$$emIAGU^;c&^8DvplPqnE?dd?AbpIxf_-kFYI+?zOFt$v zi-Yg~Xk}|#S!7oo!TgA*k!y%!{tt2GXq++w2q@K+>V5juEF(w#{I8-Fzn&!NMk9PyAwHRH)I$h!@gn@ac*;eyQmvy~ zZ!A&f*M>%)==VwrAHprx=G4li_o28H@xkbEJs|aEAiJRhsVv9_C4&Xj?AV zG*29facR~EyDw$q`4(M>BBJUmJOX}e>x<^%bm2EU%-o*-Bpi#2C z5C|!jQQcyAbNNcR`f`R(7^@(owz_TIAg0Q$OTz3q4|j6M0+ieHj>OggR7uaUo%b84 zg8WnfZ1GL^+}Xbx#qdnDT#s~+G8qW+IDer8*_MQKqycB zTGEvRcUy+Hy<_oWHs*Qtab(R!hj$&a6I)4JrU5U~wAjaU;_^IX1{x6_dJQ|CpfCE|MAnG;!5%0F6 z29`_Ez2B&>rNsp<%SUea8cW_6uC^A@YUVkQ5u}h=7US&hc(tYPXxoC*m5J|9Xyx?k zH=1u5U?hfUP+9Rvkjc#AImLgX*@e05y`O?1;j+b2VyH+nw8PW@$PlCXvfA-|!jRd6 z8lRjzst9s=Agjx$xa%cO64y1@xz(s!dI&kyP~NQMpTGYRXdta-UFc2OhsxXfkT(_; zFk(mGW*p>sS;KaXC4)7KuXM!!{jKIp_U_j6UqcMKb5U{Z+kf!_FzXHU*ZqQ=&q4Pf z8c#Z}6V5R#u^Pe4>L_>YGPT_h9g{4teD>juMgA!GF9EljymX#E>wif&JU4LMd&tkD z2$VXVd6#X8An1{Cx*PFG%T?@8ZX|sCp%Ej6v0-}FLF*w>?qH2WG}vsxkn{X6zvt^_ zk&|WucYg#KGxAuQj@s-JX#c{J`N2S_$V309`W2g|?i5?N5(#}7R@(swM$lxTpvF-( zsa?8=#YLaNqf&~{VZ#IEbH3Gljc7_G_ssV*IY^OTbyfWrNr58mWqY5mC}e*-ziKd< z8V=aSSWyGHU8~C_sG=oo@601$aK4%F?9rD80c~O9KLS4jTe-#E%r*qpEgP?5vv`II zl}skCszx0(SU-d$Y*GN-r@$gL9v5$pp!cfZK5EHY7X@5}Z6o$tRMwg@TcVLfZ)X8_vM_BH1_$?Z zy~))$u-0-R_9+cKgbE5BYS|orfrsYv&LSq*r=q_nNqC=LSil#Nugq&@D&z1RMrAg) zYi%d2*>!)7;mKITmVB~aDV1pUZQEV4i*){%&-3FgwNCrR(C?m6n54vdO2B!a1VpT9 zdqWmLOSKW~pygnak5=9qgP6=&*&g2zdD1d?Z>a+xBny~0xN*M=Mx(qCkUS8s*zWq3 z4vE3c^jyUaPE`;RM%ZT>%ctG^f&y?1+#Y=G^wB~U_1*IHv?969&+p~S9MJp(2s~j@ zeD&LI=uYYe04P>>A&QgY$sVB)#lzp$dizo9b|&ZKJhXHt*=_L9Kzy7XA#Vkj-YLD8 zNdm6X@3r>My7+^m%$r~cdUwPPc7%sGH^RYSK`Q%|33t^4PYR!_3`IbDAuJzgfeYAo zdVRUHzYvKs>7<&{57oSlcMwC9`!G@7)kb?iXM`O2PPd8^E;H=Zcyp1#02cTkcuNX0 z*Qdn_@_eA9vzZLox65ET%Sq;Q1U9^r%^KjEvEhOH@#2q_5&J$3bhBd2o!3Qhw#3AH z$4umQmSyfq$rlEahOTRQn`-t@IfeyexI+o#?0^_vs6hJ~?-3FaB{ z&!nT}hN`QE5eQIl{^zoN=y2kNhy0799}sQWb8E9#h%AynY4{OdFsbC0SjjWJisZ>q z_0L|Y!tHHA&22L~v{%wN?NgcD;tKmYGSzp>VY}Jq_>tYte6~zgEbLM5KcR@;^9 zwbpCe_(e#1Q+UW<8G{MR>f%wZA?n$i=S#dCf4%+nNrBAse?vN5Z4Z~eR!ssfP_H4C zIN?LJ11Z+AxYH8S6)nomQgqsuJ!5sTjH|u)22=$c8D^+is4HzbTNO%s$i#>!5B$p? z;A`jom*p-mFF&%wUG>BKD%8U}Ym`nTX#P9H#CU9WZTd)cs5kodZ=j}J&K8$U``0nU z?8WzK-p(OMmyH6=vMd@ju}ku`mOY}h_KM{8_VK7GLVH46?{S-?6jhT#)A|>9vDi)9 zm_Mp^pM6QX55w(5@?M3dKAdixy7}+vO=nBBQ1zw|Z6xj!A;T?X^57?YT8Z{7U|VSf zw9rMI((-vL$!sHibKwMiq$U5xg4-p-aZE!+=>m0of_kqXW&w3*oQmpOS1XM5qS5ZC znBy5J*hu}O>;-B>h5)z6hYSd;$MX&lYV@*PtVqL+I`4P68|60J;T$90+ZdKaueVO9 zhISWxXPpT@**RoN%XNA!s;PE<(p!820>?M3*WyBOsE?auE#({-Utmh*=W;lEFIt|U zn!GmqDDoCQ)3RIh1itRU5iAM<29r*~-v=6{d5fZ5a%3pI zq`p+?IPh&QEcke^+|trId#6GmhX-L1&sQxskd0f$A>RYsXY|l5A6HleT1yK^SFajw z?7sYx{!4VENfI3RHqbCfA`*Hy81a z(6eMk2H2;h+#h{A)HdnXq3$QJyK1)Y(aQ8dW4Q%B^H5P52N#abyiT-dSk>L8wZL$z zT5|K>c(L#U33oo0{f%Oc{JD(X9r2L^=9p;C+FzXanQpW`2Hr?wtbwgr=>BdTX}+@d ztjfjEO7Y3~OLuKBX}t&>1Q7(^c059vpwhQ}vr&23bNm@41MZPV!f%^!oOnc?^b2=7 za?RThu2YmlYNZj0oDzulqN47c?;aeuy>Blyw|A$;9=lg5(uigHTb8HW7=j_-k3ezc zlvv}G$5zk7@$`Kk>$RBC4}K}Xy=|4xAVz-lj;;S8iR?Pkph*N#R{!SVVN1;6`UV|@y+icAt{KoSckm5FBBnS?K z@PRka=IW}H@!RqvltCi5f$1h{)>QXKb>Pij0r3JHdY*G8wio!FpA+NlYek>mzYjOU ztRgZTvJtmk@TLurZmQPRI5bS%+q&F-j6|4Q3L#uAU2`x$_;@h#WuvVm`lGH-JJy7(&iw;_hHFmbo^6U~OP=i!D7<${8g$(&T(#8cXB z{d0aQQp$+Q%ieQOrrsI@jHF4Hv{2uziO_Q#d32V=d8CgEq9sDe zaDYB1F_V-DYWBlPhgeY)y@$NwL7wMx_-@9iw?qX*I;x^Q;X0MzV0uo}+tlGrEBB;$ zl=>ok(I!=hbQ{MzIkB4e<-&i{xCd_<4)WXaF|>J97ea@bkLQBQxHT|}%qbXDG{tAu zR0_N_nt!ZOmlwC&vM!6FMvw>{y#u&i9;Gin6&|MC3t!z~Ri7`8^^zZjXb#_{^#lp6 z6F%)=*bYfnH{I-h!edDo-Z1rMa^%lLr9p>s_Ro{(w?X!p|O1>fa1ZHh><{Ke# zYiF3;H4))FOmVTOvrDs=w=hzy_)$xH8g%bsFQYw5B8BEKqWJ8w5DWk32LhPYxO%zp z3y~%YegT8v)7{2WMc8HPO1~}jG%M6w*fl*z z>ZeXH%k@>(656CVradN9WjR;++}&6g;Q~#7lG4(S&$j_>|Ljf%U}3qOv<=v>m~&?W zsOtVwEesc!`RxtYYiq-l6-G{=TgC)hcy>h(xIo*rDOg?xoUO%Te|R|Sz{NKBYtu9 z#J%XJ`|!mSBb9lBIpTTCgjkH^A$*Pg2#U$$?RV4S{)2Z^6sXO&Cj;U1#C zPF9uD0f?p8%bcdb&1v-;%H1WGx_Nw{dnC1Vs;KV>IZ}Ierv6YTLe&@fRaHIbnUx&qF&=f<@l_a@+8E z<*QyTxIOeqHFbOpqaq;O(1I9&K3sORQd!FlCJF$@^TT!z0=ARUj=rN5o5JOKFw?s6 zWY`jm5SDMt{ptFAg@MPuoslp)F4b1sLcUQb*&`}6KlUpzWsc;uDpoL9?7eX2r^4)! z6n!N=N+h@KA7%Z&uK%bO^ZdHxt7lC=$&OW|a%wq!w4D|S34Wg~EE&oeicL1ytU%}D zF;i>QlHPp%%{b7VOi+)1vwPV&yI>=cfX1dCYSxqpm!_-rQ|c23&*z`>;qRU}fq4S8 z4AcEy8ZGMJ&o7vr0_A4#CJmb2BP3Hk<)yi^5Vpwt1Zi@d<$P}uZSndzVvxQ~e1S~7 zO04i~7G1SaaCf6<(scfW_LJDmG$WD-Zs@nBAuiQ=PCjWA!nS4UcQ;n_Y%wIP6vR0{ z>#V(6iY;;!HxHNn%NgEqoF(qMJwq*1NLr^rJr0vD{IEh~j3+7IQ_5QC*_sO9a;^KR z1HK^po<*d$zAET%PsDqw(WwrKvfnxfk%O8lowhk1sKK)hKEgp(fKGNpfw&*mQGd&u zzbpxrQueIHvTR6Wp>;Z^FU3xC0?;cXymT8qm*zXZVvZ!F8c|FW*P~ekn!MWe}jYgY(4v@Gyog zG4b-R+-dBKzXzVuL>3l43TEr@H`BjNG?_EEGf;L%I0y@exDD2)RK}kw*GhiTR5V;x z{PvwEc7LN+2`6OttH*GPs)+sqSS7|r0&$twk@v58N#;^q#~7JIq-lR|;Nbtp~6D7ZHENUSdb#v_MMswUn9%C}NYpWy*k&%s%rbH5iQ5$hdm zFXi4**3N!#TOn&rr)TDPi74ROMVR~AJ#rRIK&Ke48e-WT@rhidckc5WY#Jxq+Atv^ zLW>O>E~NR}>P@hz7k04G#0>a5S;uBDn$n61?cd;mEUu-;I2=kVeYez2)ZhfmG0UseAV)r zst?&64BaEL>LAs6RUfQmUWJnfeNwRKItR2J1@6Kx$PRPsGh_I?ma_8oq%zbQ@9H zfLSXEX)IfT zPKbL5k3^&31l3cjDHcv*8wq+@gtcTyXAH~!FrDw3QS+990?@nBx<`UlL6Xf8srvkt z0_X9JbS8sZ(hX-U+5UC7QG=MDge$Uz{44-$`!9;dBLmb1M1#eg`IVIh9_I%3=C%4? zRW1K^%P5(11RzQZl{!#f6o2=W2#D4YN8F*<2)xjlVs;+a*Q4kO$Kig;Ti#DPW9~7w zXDy$_>sE`l$B#A}nyu>LM|lqbq+wTY>W({}xlQA6G;49kluv*6yJP*MP?xWgwSaNA zIM6Ep)Ze%LIx^ED@|PDlZRJ~!myMcbhbm>9T;VJ77ClM&3q41CX!ci+5ftG_#C%f1 zW>*$ktZ%kQv+4a=_OCI^%E;-%IQa-CU$v@B-&)Mv^{H*c4>9OUkNurgO{*l;qwQV& z6FU!a^yxwKYkL}c`@xH*3MZ?ye}ie&@gz*|6@G_4mFt}HX0e7qQ?38(x@2+Icyt;^ z_t+yy|DF_QIkG9_ zr}H-w|Eg-UwC-g?BKUZ54d(vcDU-^%MQpIff-2;odmuI2vangncfMsMWld$_IZx(* zp6JI|Rjt|9;$d~>w%guM;mspi_-pIIgI+_3>m%uH?AF}0Mq*I3*T=0|vyT};I$czX zEga9$LPVK6yLGZ{y?2?+A)mB`nXXygALP>8ASs0GBlXe~Yyiw= zA`Ef&5yM`bTfEA&nL~BigGSH#nV(IYRf*)h>@S)|!{H@0@Kv_ZTX0ieIOB~7g@sL&B(t=&}d~L z`dz^`60Xi)LND?6H=5BVc(`(9wlRWyPAZ`xw!g6e9`yGsGiNCy?eJsi*W``_5{Z{T zC`++P9(k}MW1=e4C56G;X1H#f(`PXt8lvDTGT^U1vxW5wu*V45;MJ$)07O-s4rEwaX8iYgAQDsAN> zP^#%;vU5dt4^J$CU6laHL|AzG0t&jYER=;Sugs>Hd=rx;@xU#YXqDIe86xTe25vEy z1^bVGBd3qrV8PS;w%0&v-n>cIz4f-TCVN?Gjy+lpiQo}W{o6RlS7UMC5Q48DRr@oh zMgEtE+O~3tdTh(ml_}t(AHcFU;3v@Ug_Mp8SZIQU8qAf^W!t@4eujVbL;m(D3BjV~ z?ML8hK>y*QkhG&BqhtJnF=7LJf$TaH9aJR$qWmLvHb{!hj`Op(M%qal4r(}0ScJ(8 z*e`a7L@9SjSVEC{Q(Ogme`*7t9g$_zNKx1b0Qo7`7O3*IHm&`BZY|Sasvt2a??dE~ z@cjAu_pckh86r$8=?k>LV9*48z3Yng%=goss#6h!!N$J1{pZfU-Z_hpw``~oX-GSx z!#d0492p4ZYaeAEQCP%CYH0Di97Eq^6}cU14PgaY2?u5jHCw*}wOXCBUUqSsA4N*4 z`9Ljlmd>`Sxwm)b06oWK&9;gCzJ8+Oehx^XMYV{8#~zYM2IBARnY2YuO6M+dm1_EQ-EZRvL7(QsjyWes@vK6+@CF zNM6E2YUzvk#^EuAE8#oX-3eQ1x--khDmAc6N9ZY_!F=ZLRt14xr{50^R@eKQM#Ym# z&{&1#x(V4t1dh*G+&dj&xJQrG8y=Un6?@BCFoSaYHNvWlsAd07%yac8M_Ss!$TAh& zXe$MMzA$M%lht%#w6<2<^CoN9agSZTnv_{Sr;vlpuBe~_W!}iB5k0ttS z(3qZV-)>t_i%PwacSd11UW7aG%G<=b=OyCqs9bRM{MnkKQZh;~0Wv2QNjGLW1~9+i;aav?!nz?cqEZQ!v^sm*5jXHh0nABXs~ikJy`C>%+r%t z1?%7VA(XI`9FeG6EFh|7gIe*T{#g1CE1XaNy4o`f3&nQSmI?nX`clMV5OKZz?~J9l z5e_@7tol#YKL4b;%sxIWe5^P&JY0^7ibW;)n^~{Z-%KpOu#m=MZ=6gkE+@G=1ovjz zL#a6R>gtM(k>h`l$;>u>yg7b=VcUqXqdNDM0yMwdZC+4&Y6b?gh+*;BZXsJ5{X=69 zRa3~>)s-um%TSxA8$2cfiAAt<#v!N9G| z)S2@m^qkOt(BV?x!jdBhdFZv|A|nf{aIq|#dDHVp{?*XKm1C!}`R>^85Fx9XyT7!- aA;2MxE%cF|;B-$9a&n*gZI|{-#?^y+VCHk{arqzC;lufpklih& zX(tDb;At0bMKj@_yfHm&JA4wijmyMC%f3Ngeu<)rnJ;WmeEZ&<@i4FnpbyXF9dfV-Yi;GjBKl0e4 zSp3>+=-oRT>puDjg9Z=6oVjzcVEzNBtE+<}E*}3r<8ol>LO25_VeUT=E9@8H^CCCi zeB(7NeDZfVapDAy965sQ>}*V!Gzm+WEP>T(MO0K2ety?4NENh=+3G0C<-|D@h(zK9 za){TRHZu;Co>Jc_sVUH_J$_JP`~D-Do386HQ8X-hdnrbZ9*rk{`#6Fmg$^D#0E@+f zf4%u;yz%-Qh>wrQ`>R&s*=HBQxB7K-x1B_n9x<@EcVk+QQk0aIsmT9o+cwO)aW*_2 z4=x@%7Jd5mK}>86rcIv)uh)Z1#*Kr|>ub{u#*lhASXP5kSxKb)Eb!?eT4jzN)4PlM ze&mE3$&>&SqHN~}UDTgwGN~xb$;rX-q9S+*4ARfIVb(1CYR+7IuyQ2^4jibC?a?h6 zDRF=`!2(Mc4W{lI(sGh8al%C0`jeY6Aa@|fjUP`ydWjxf&@zAKdA zw6=}&qKpLO?JCB=w0OLJ=NLp$1aqRCJvswVT|Y$8$dN(v886I*W-nWk}dbu-lnyttoBocrlzLO zT>J656%6#bX{7!0p2qy&FW&IhK3p1W^1;_V7ggi#A%X1U!ea8K-(2-k&o~oa{qw8H z%*sM~dODZ?=+dPNoKdG28C68>9$$cFj!qP2M_FM3^7kBo)$UM=X6kjyOyiHeE}>?F-?P@(qjJMRz;g><}$)Q?VCbltj7D4A+12QW?WxlAnu1&2^pR)&H@ zhcGZVSE(NuA?i7&iLX<@tt>)d`w9fM{uTQ1d}vk&G-v$T7f1wBVp0-z=jUVi$PwUm zHZF>iN!eUFaRPCz6=_5xtYErQWb1kWypnj`wCk|-%PmMEYGDe@$jG3GuO!;ZRP=b| zRaYtp8$sg&1vwaiUhoCc!V>5Q*CSX}0?lGOYj98Nia_g?nWJq94)^Ww|RUno#A32cM@90bxKD$O}!D^66P zf6f4Wz5OfNpM|2LLelZMO6%w4t;W?;rr?XuH!Fpd-ZKOFyLO>Rj~?Wpkw_zhMQhW_g0jk zQ`9o}OaXjkdTlzgXrD@gB+at>WW!2P&NMN7`gBquPR#hxOgQXzwT3cd=1d$ue3*tv z1(eOsYaSM(!$D>R(FoZS|5-Ugnx40$XHS&_CHsJ*+h7o=hKtmJ`y|XkoxrdIb^?{3 zaGWisG)lV3m@vSapJW};gPFLJ3Y`P1wilJ(b7kM;2@@xtac*{>KBxU=pc}S^+p@B= z)#m`ISiOND*5()QBs6NyxLu>=_0J}Ca<8;>C2LrWYxPlMz;3tajvh1S7UH@F-D@=M z{V*yDVAPb8N~lsmz-$efsqG~zKQY?t!r|j?yv$LnQNLAV{|&w#Ltz9wFq=%dLo*V7 zOx2vzK*#D!PM{~;-tzpSs-;%5sia=X&{cdSW@0&B%&5O=;h$QelW)88XITH~Cn%r{ z%{r7TAqJZ`FMmy5-b0N$hla%EF9WJM+r?uICzYMLw3k)tqV=rHWuu>NyK0eCn>`cXz!lg@YL3lK0k-W zqGEpoy(uB}pj^RETzvijGUI@`gA5!b`Y&>8odPlksfBK}SFC|vF(JCBYvltJ%h^Sd zp-N9qf($k^?fan%Dk3~}b@jiQ8+jyssdmXp?C6x&;M&x;M?VKTnG+yK_Ib6|fe=+7 zi1W7n(?6{~A6j#fyqGK&fbj!N&B$nA57}dF1^H>N1AYLxMUdU?iR8UMVA#oY5ir>s zahpMPxDJz{w>tm~Q7D?xF&WF?pi&F_Mu+v;=^%Hn&Of8JH8eA7>|If7552Eo4*Jiy zQLPzv;r+VF2D9OZRj*ThdaUuvX(l7kpdU2JREF&3YXxacLCped&;v`Lmio8CZ+4zB zw(}C?@%x`Y^X4e}eC8;W#|^-q)N4@XNF#Zo)2)U?iY4fU-{hdC@Cfo|2iQ6Af$ZrB5_C05-~jJF&oqq9)s zNJf{MZ(-3xn%ZNHqireZUbTz1A5#5r^l|G~vIc3cZ8(-RMqM+}eHb>1a-H^jZ1Fgj zI10rHgXy}p$S(U7$*1F-GcYy*jJadwyPruo5T5#wl+l9f&)E*_vmO0O8@!NU)e(C>`9p#%1X!iD8n~~v# z_zFc0O}@ErAhq&q6{*a%EwltOzd7g&%c@(+CQCgS_ByW#e?qqUd;obiS#BfSPmnI-Im09*S)2sn%gMs?X)?fc**8v(Wm@?Q8E3Oq zWD_F#9VzZXMquGfx*V)k-PZ*W&P(WZUENc_-QZWUt7%oS(|& zcdd-&Il1TGNq(6mIbma4R^hsd$HvLUxfPNf5c=TOMWTSC`Yr*ug6v|ls|5&-a(>Eq z57}pO-hYwtJFDAeunh28p7vzFkYg4~1m7nBa{|6rqMfh#mh>GEew{|VJf$RIa4_P@ zLbd>!FMu(9{8(mOSgY1W@Ut&sCH1dltVNT_hRF88GFG1~r0Fs)e_QF|RBZaWsD+-@g_oF>ou$!f!?v%XCZ;2XNaaQ}}@N-&LG7UG{I5$mjNveC`he zM0$Pq$>_|Iqe&xG(IU+zK$~QyIRvl|TUd#k&V}uemOE7Ui{Oac+p%Rxku}$mA zRnpNxxv77V2*h_nxIO}s1Te@FV7QgbXKI75^1ZC=klVro|1RES*UqeKEUmM||aBaRLVp_K-xzqyD>5s^K5dbU{4re~SoNWDR zqP+2ItQNk`mSo;Xg74jqQWwm1XZv56%uB~)ibvM9847i8OfnT{M~FU!q1Bl;aLN${s4nXVQG zm{kx%n{Er#4DDUEo|gcO2*+$7+a%LEDk4HpMQCl7g139`-h3FTNJUs z7ug!283ue2ulPCru3nS`gNil`!zqb3+<0d4GUI#l`yFxYV-0dhn&40;4tYxOs1)b7 z8|1r1_Z2jA%o8GEiW@}py=3o82G=EmwnrTE7mPx#L}ge>W=%~1DgXcg2mk?xX#fNO00031000^Q000001E2u_0{{R30RRC20H6W@ z1ONa40RR91QJ@0=1ONa40RR91Q2+n{0E;HByZ`_Po=HSORCodHolS@wMHI*1>)DA( zH00ypC7_r~)UXLb1cMl2M1>?qR5pPKqJj}G=Hfx4hdo5h!Hb|5MGb<6WKj^K9>f?0 zKOkt_4T(lX%^@CRWTT=x+vWe&^vw3`RCU+%^mNzmcEK{$_4(@8ud1u7>(w%q=+u_c zA-ed(dQ#!_5MwPd{uHml?{ZRV8N#lDe<>;Y8~)40JPH4w#OfFPoOl9h0mfv+lW-qgIqZ!-#gracF(lP>FrV{~=q13Z58v%Ce$6{6a>=USScdI|9E z&0Emi%42$;YW015>Yej>m6;1fb<^HDO^OhjQ!eA-F*%AYQygPQTeI42~e=<8-FTlM`n(h zA!5Gw0)^qb=)TJ{*X~0`kss~Q?a3%l&)r$SW&CmGHB4$B&RD0v*#bI5E7v{N>)TIH z5Y?uUCG-~^h4$_6mqeeEF&(2TX%~Mz_K#~x&fQsS;Cu%t)I>qhPTgKdip~&8y6}9~ zz&J2zr?l76IYDebMCRcbm;?!9zU#v#bxhQce|ZWoR2Kvf@c5DUlA50gQBS009yr&h zF-Zi{;u!0fL>rSPp#C!NI2Z zH=Ci3`le}r$8}j3N`?I0;R##yYIxVbGWRIY;o}?8J+1oN-C2Lu)L-RVQKkMaO01pL z6^ZeKjsz#oE2^grQGXXM<+G-t#Z1YN6fZX9DliD2f8{%REP?a%pt!w&1(={4KO;n?!xbf8a zrd6n5U6rj3^cLT)a1R2)x)CCM@O#Mpvt0&p{1MW zFM(@`fXKAOHFcrsYL;n?t(zArT&yzilj(xpNK;$^HC{DuHftTp{}iVhG>;cu1;XI+@%J z9zT4hRYbJqPqvWwVgm9Z4AghXm?+=;j<*E$;+N?H1xt6t0g7CDZ(w~TOyPLk3ppch zO^7i0_d=+a5Q<*s?+;ySUB-VStI${CVWs&aZW^LKGeJ!LeQ^PuO%$b;5}%kkr%3Q> zoi)+aL@8I!Oz_49S0{?1RC0V`=A0s9yk;Qc&D!wZ*e&CVdq0dm^MolO!gu27yw?<0SQt3PPdVw>s^QH}*%=xq&^tcH?BO?< z2Cv3@{uTh-ITKxyZ`MxP4u~QW?)0Y+bZbfC`ClzgHGy^29dSY1-MJlzV^7-t%F|82 zz^4nMHZPE4Pb$|<09rfJ zobF^fkjMy8XU4%h$au1|poMw`4w{F#{asJzc(Tgg88rH_cNUo1P@02B<6sw@AMH;v z7#AM)?i|sIO!p5iIC#wlA51&CK$0bP=Quc65WP7s4-|?wGVaGgLwL1&Bpzh*r)pw5 zBTg;?a#;bN|4!N|?R9j{nkeN}Cp4L!Y7mt-B8+=^=A*b39bqh4%Gw#FezT zCrykaiVog+IvzI1{Rgp9{Y;iNWQHh}>4S$<_y$&e{M@qaLPX|)GL1<&Kq#rGz94Fl z)k&V|^Teb(AaQykx@g6%*rK-|gTvfdv=BK(UdWv`kxpyBX5f;@HBEK8u`4Nubk#ZA z4v<`v=x;W1I7fBjyDKt#y6S%q*x6)?(I)@Zf5FJa&X`FXtSA3JmSuS2FTp%i%tR*j eCVdb8AItwRvTGk^VOx{{0000Px#L}ge>W=%~1DgXcg2mk?xX#fNO00031000^Q000001E2u_0{{R30RRC20H6W@ z1ONa40RR91z@P&F1ONa40RR91cmMzZ0BwwV9{>Or&PhZ;RCodHT?up?#hL!AyXTT* zN!Ec4mV|A51smhVoPmI2ATI<6>=Jtk;EP~_H@kV8kj-1d3vrGI$=gRZVK)$9!Pq9* zharT;3l0Q=6V`!^ITDD2VP#pCWbmQOvSiKGUHjF@BhP52duB98cWbKjM&12ab=6;A z)nD~j)nC<&T<$o{^7Yg3JcDQsCuI&JYUX5|Ld2$WqFN$e4O#{6RnSyMJdFDwXhWP> z53+w4v;&M-J14#uVRqM3-7ZG&47nVdQTF+!g_RM0WDYl?vp}3p01bJc${E!&PIZJU zaqc6=01KYriN9go_W?irsE>2@5omi<;(Hj^_Gmu-9=owa__^AN47F&S6~!J!tnwiTKGO1z6>q=m0zQor< z5P+BPd)AQ1r=1j{@U29~7f`6v zv&n$nVE|wcevd&-`bjPA+gogY_{MqlVSQ+w!Hl)2V0QI}Ib{>VfUyGG$W`UOz{=ud zlnZl?5P)u)K95uMb}+sI`l>IN3^*k$fP|LDp2hF(2I|~dXugDAPtoXCfX_;__JKmj zUyArJZou%3J)<(^Up=ckc9bH`OljCE00T60PME^qLZM!d79YL&#BdlVyoj9K)j(Zh z5S^DB-gN2=()I5$&Obk)FkX@nLHJ)_7G@&T zAqZ`xuyy{`okE2yi7UF^En59k3 z23r5OKrhS6A47=vOl}x2pdolftX?N#RIK}=_5eL}TC+jH{{-_F7Apg8j2EEq#sF|x z9d-VhZ$9xtQv%kzfxjkwYX1w%*3IL}iS~s;qTKU@XGBnZO z6ZV#s=N%#c+`-YT8k7ALIlYd!R?y-YjejEC0JmTJDt*h?^0p&|%um4(=hPJFCVC2$ z|1*VTa3aOUFy%1ml3wz*q|S!&Dldf>!YbKQ^mz%_LJF1WFFucY8C$XMqe5k(AOdih z=1zin{Z>@|OA5uQCWjF8X z%=R6taCr*=r}n|8if`$NFlHQ3hGchSGA>u zFs#c<0FJ9Y+hogcURpx!slKe+vgIH9HVS$w*d6g z>pwx|7rV5iGeMy8+#}>^P95-?1WzKfp$K{Y((95;a313qwQUXZZ88#%)4B zE&;$i|Lq1DUo2TpU6@edV?*ShcVen@JXuisf~5Ul|9D<4n|B}tOM(YN4~;j&ISW8H zwOlF|xyGAdIlSkc8j3A)6(Xmzp ztBF!AR3B1{J9QaZP)~Zj--HWE76>p!xdxkRa6mz3m$3&B^Zls&kIKq#4yI^DsxHLI zA4RVGf&;U_Hi0cwpaGiG5T;`vKmaCZ6InTiQM{Zc|Mfv){sPYWWCBvm z3N1c~jLL!@iJB=@SNQ`X9fos%E5Bd|vqD;{ zTp+V58F3geMq@v+3M2eX1>guZ&4T|enIb4>f3;F4{~UW3sg(W@seQ$nahfP)im|}b z;Kr7#tnyx5`c*8#0nsHG_?ls(wac-988&e`PMNqXexL4|RshiY z&qhCceYzJUZ3F>zl1{#v$83dz4TMSUmA!yvA#i?9a6{9l&BCM=0L*9n6ZEIFer6Gs z8(l1Vky6|_|7|)kAIfEt$(~6#8^NX zgu*JFIRczM9^NqR{B!|Q1RzAgFF^enw|#ZGL?#+7Ht^M87U&SCb>(Mv?T~B~l?_Z% z-+oK=aSGXXYn?g``{M@UUDRPC_L00c!%w`OjKX*0YiXpobn^ z3a$3k)Yl~?j(}%Mn3U>*pU)JJetcI0lir7%p^}X+1I2#}Q=)-T*ho?BlLUZBzp41F zxH|>^Y0j)@>Op7n<)qR^<9@?fentgAe2o#Fe=|0Kd_IAIu=h`QsMU!O_T9082u{*0 zp*emXA@)$?Nq=*i05l$7cz@d*5kl!FZ7v!N`9%hEyhz27 zCw6Xpv0yE&7n9bZX>my+M)*SUj2=Ljt$z|SsSoNTceSXp2S_c$u@o$4o*`%u0FK>X z(pe#(I?edaidpz6QU%I@5WIQp!{vnYKIQy>CbV4F0|cc_P^L1)7qXi~7zHb1asey@ zTFmcM`yUg=rBR#-Fek{E37RIJgbLJnf-LXSA)plcwC8k*6p+TEE)&=S<~@g~Mg#zB z04cjGpUn1C}v7E_^o>*5Nb0!aa|gbGcB$Av3PSPzgc0|LE6 z0jNMEH^67W$xUkjqgj#le-sMS8}(=aJplKb29O>x1ejm(5dcoc zZkrfzO|trcyDAi~a2LO}R0PI$iFB0!dET>y0T(5zA8}WOGNb@xtX(RxcSIniirNq0 zdNAV~WgNf=DP#<}Lz}TATA@5TW2nzw=&YfY=8=Wnnsfd=IqN>VM ziK&hXKt1j6g2#?TPkEn=fG~=S9(3qn7zS{>+M&E9!)V_VV;^ZNZvK5D1ET^Uh>Vn< zC3?#HR0M);6{$oAQ1mGkgkg$w76@RC@E44&PdYCnNdUZ5xdmbnvWTPXy~6F#v!h9{ zIRX1?itft*P&~TGY6cR$E~lg(LwG9#|EAATfZvPema3eq}1rMoRRQDjQRGN7AZ7KTXGJiU8D6#|})1O531x zXdS0TU>6iU=#Vu5%=;US&gzjYptHw|(IF4_K)p|ODFPsZKn?mqYEVf@L|}NAGg{r~ zv?`Kk040`8>b=6)y=+Z;+OM3a6@WUr<(Ciwxltw+%TbD06VUr?Hayc*(oc4lIyMTB zQ*Idbcq?k|H)AKQ05DoF&O*D(>?KLZdKf@B_I9hu9apF z7Ih2t)leD#2Uvb)v<|WC0Yn=0w5Jnt^3N9OmA#jNBUX<=2uk7frYbVzruPg`D?j$G z*^fGixoJ!gO)&d}2z^0j}&F1~BY@U_t9Mn$-R2?E`{X15B8qyNg|z|pyY$gXsz6}q z&6$LS#0e4u zuhf%~@1eT*&_(2odTH)pQL#|z`=R<=!iZEKr4kc@j7KYqx&B(xPm(*l%<2N#huBwUeIBRi6P)vfaavhlafmH3Wkq0h$IHdWp(s5-BGZl3`9?iWJqta-zs00F z(X;&SpYYKn40lgdegT1RP5W*iY3GR+uk3qF#(wUv^q*OZ$}g}ldJiBHi8~CC&*#J* z!Yt7laauWC0rEah%9qg?Wc&z8XjAh7BWgSZTrMaFY~p!@;J1;&*7;X=z8I&K;#yJx z5Ey>X^ToLX*@QGsiCgccpme;@-0nu!9o62RG8b)g~G7Ny-rwgg8R)}RqsjsSe;!t zvRwe;8OJJeEmn~s1pG^wF=~m^U2^Tl68*!N?YjT?r>2U+w&)Q;J%?5iH_$84oT4OB ztVnT6n?meR7H4#d z&+$6SIZgl)(dng`H3mhmg-R_7`BM1VI#vK!Lbn(8=fVv4>3sD2#C+y+KQc}@crC^V zz=>TB;i%0gzI@+3uHyU-Q@YRiSmhSBYPX{|O*vWs5(|UVbbl{Jmw>hu!f*+ChO=-j z>UV)gT6y*!(n6(Yzg9{6&17otPvpx<_xzP5TC{!71u&Vs0<%XKG0qnQqoOt%z$l8b z$)Arm48QU;R@L+YxRzp5Nu9zN?V76UV`fYprH2HB!5AoYlcn>hNZ~mx|7}ECUvA*M*0o^$O>8 zI^*?B(S5@DhM0=6JZJdo%rL;}GgRvHa^6StryOEuzbWmyN>xZQ9f?3G5cq#MtxFw_ S6!${_000000001b5ch_0Itp) z=>Px#L}ge>W=%~1DgXcg2mk?xX#fNO00031000^Q000001E2u_0{{R30RRC20H6W@ z1ONa40RR91(VznW1ONa40RR91L;wH)0GXh1Wjt#*VCa{5+!(jvD+cg9dHiRP~uq?4`;f3&JSDVd8z=s68I9blHgoGp{ zPRtoLEFQAh0v{YU25igHNE+FO7;Ir%$INus{x#BAbM#T&)jebH(%&adch!5ZURBqt zdhgY%YDzx4K5GHA!0g$zLpnQ^iE%YvMj0K?h<*x^2T}YHUD27M_fn=DBb0qinfj4h zOj;|)4Q&sH>k|Lp8<3V&)Gj1cpPJ8xPzdd1gzg_ZYUt)|+v>XVSvD`LqGHAL1WhcE zEjLJt!jZ^55hFUG(DG?KDdwl~gXI{T7N*aFJf zY(~f=;6rA_FG>ljNOm!zyrU@Wb;bg(MO#+BLn#Hh{9cSPS}}Rq3|*(wP_Ln=ile$D zxmC!)j^_I3oN`XfLQ6L=M$U7J=mk8g*~^&n^Wb3ppIYC)Z@(8bMQD^&)I7@w`-%vx z84TxrNRe8;d-s}yMlj<;HTM(7ZZpagPE(Z2_qEhNBMff=c;0z+fu@!t7c#0{g${N( zI$fy+xce+hKSJ+)kx{yCuo`-)sp+;}_r&Zmx$u;QmS0B+yA$uU+8)Ckf)aWt8mS-U zbP!N5WW>=S;^w6N%YpC~6QbW3@1ol$RxSO4e~PP7-$=HK*9fOw&doeKKb5?x>49dFrRR#|gp ziWjecxe8hyT82SJe^ge0lB^RpVnWpl$AYNri`;k7X`_Y@r>b&+Lg^17g|FscsMzR) zMqlJ=me&oPO^?Od^+;2*)15vmin7)WXXebhBIKQ6mM@e}Nn0ec>VOce0npT`D^7v% z{P1Y6)(ZRPM;I)}8-V$mgpNG|{Ymqq5U!FQ{8U?qGNd$$Y~HA@&&^J=dk%1be!Jwq zam)V*e*s;+ajq|4jM;KAhL=j7?(4BB+MT2Ho}TY}O_$R{|K>vE=u$+WxreBu<-ULIh&0Srl)&j!A@yjWPegE?!st}L z#wm^{yw3C+MPW_hDEUi}4S(7+9~n%SpG{SVGf~CV+R7t6@kVrl6GDJ^`(PmOWfr16 zy*Hw_a~HfH*O^>ZbV682h|&p0TUKv}KrIi_(lXcu-+?D)Z+gD;J);*&(=Z@VRaJW` z);KOV$a0i~`aTkg)b&^*Q6f7NX{U}X-DX)vS|+z8e0tLFGXD|?BHbbb&Wbw>0Ap@ipi&+zEX=u8t#Wv_k8>vOQp;F#`W0e zW$=w~vHa(OD#xB_Zoaq8h<+-K9qr{W027wXMTP7kcmap%3D~ZTohDP7Ke$vM8YnV# zzPK$@XXIA5xT1JiE6%SFr5Njo)W5DMWLfH2<`>Zno(fTUsOF299j3_e#Br&jSUMCq z437ZdzcLp*qC#rWp<|s7LWOgrddTqQ5cmCl2bDuKb8sF70+;q8a|my8xP!|HCFz+c zy|9II7e0zHIFg>`<{lkUZjB|YP&A74ECdy6S9I^1SF%XwKI&9jhyp=-gB%0HV$48a z&t>4mNI`oE&8AMcjWKo$;3a2y`x3$Xtm^82Lm+_I<*5*H)eb?5KNl<73W|9)6NN%` z!_n+ZtV$EfgU$B<{%m8y;E|GB=c4q;_1BcXZ^aY$9${ekcPp5}=ZVdxqI`1I6)~RI zio(mlL2D`M(OOOyr4bMX6o#YfI{0{hAPjE=$jHRe=M<)FLEKxj z64Z_c5=Ds^jTJF1FjS@b7>%(qcsM6x2AqZoVIDf$1oLuKA(hk|KQrf0*Wqii#y2c8 z)xRfbLtLd3noT_yqK?R_x5tN;euxT>m8l}@PTEDu2ns1WjD8y(PKE?*A^Jp9Q{AU_ zMBrwYR^`B{ZRdlaeNV1N12w_yx&Z=oN3^9usKX3k62jvUNrIh+LF!Tn)nW)$GN=`6 zh~1MzL*DI(q(e*IGxGP66da*rJBYAdE*h;=dqIQE%kLGYN}Bg(cKLlNdE=@ zn=|LZ;D-lyUy3O48}U5Y%Y8;=RZG9b5@fm&4}PUNaV~gj6Ae^|h6nE5-Fe}m^CCh4 zqv|VdO>5p0ss)o?WF@pDXgw1p7)E_BF69v{P5iT40m|lJ+qRqH(bhHVIwJR75+tRF zxAg8}8ui_+ZNTlcq#b6Ek)7m=5Cw@6&MwILvz&9GuL1O{oR^!4L5bKb#P{m}Q_3NN znJn7AYvsO74ls;Qc7tUX>-WsYex49jW z+l0C1H%UdvElh>IM&^9e51N{O{1@~56DNmi`pw|RQ7l`Ed(5(LrS9GQ>Vk`|z6cR# znA=5e7*E4d$pPZpoz7yPRtqg`mx>RXM=G<{Br$k2MS{vd%v- za`{>f>dS2`cNZo1U@-s49WverBXdP?eG?+E5Efy;3I;3puGFKl%4K{%kFa;ehzE>f zv66uLh*6$#ntY@J+RRpn@M4o5Fk>FXQqeY3`0BqHbm5@7waC{nYK(Ei0p4F{kd;1z z9md<-;3sheJ#@Ya5u<^yYvzw5x{F+(I+34+82QcKy{m;sF{pBqGZEEGhX_P&Q^svC z*^9=R{-~2xdD#M8;WOQ}LjeQDZ>|fA5x1il z)xTj^aoc=K*V@AL10d?W6eFh8$PQzF=gysVNA1eQ?A&PwBa)8}a&}ju`B@%yE&`u# znDWY+`7+vsswhuzo)xON7NR76Ps~=O^G%5Q8l7$E`*rspjX2Bc1}S!cEdkzecO|B< z=$kyCHuYrp+e2bpb%aUd{t^v3g?FySeJNR(j9jQ4>3s)hF`S>3Q}9PD;JTiLFnG7N zHLw03UI|T=Q0IV;O`^7Dfv-Y@#k?@Dh{QE`^X9FNqOZ{zrBylT(~jcOs3sqDswldx zJ;d7)^?O^QJ#$cb=nf7td1ZXXvL`1@U6J?0OmY}PLUr|>V_?-^X_P0DhJofuyhHdT z2-&x{z8%Axdrzdmc5z>Y2r*b;kxE;^Xe2JI(v7cNF%`Y+Tq}BZd3@VD9mjrc2bYmg zbxC`OQwvx|Dx}I&RQgit-rHaO8(L3n56&UHJE@*}OWYB)?s(6)p-mJ!LP`S;GWE%{ zN8Gx%i?GMNurm=(liZC?xj(Z)PM^d*bXY@_o`oRzk3<_Ax}9)|=n6?8qQ@4_oxfA0 z%&{Yey$Jj1un4RRn8E10clK(r=JL?e6*B8|F3L`#B-M9HzUvkrZL=l0PMJmklagz@ z2)5(6WQ<@Mz3f|GXChu0qeRXw65LzFW4EB1d^5X(&Yr0rELJSHe`nLHtXy7!*-vU` zDPH_m(e)_4Z5+Xo4`=h?=_2Y#hIx3%&~x zp=vn0Qcj*>9ga%IPuU=O5uu<^@_aAl(I}ir*0}(l3Of@;n^)~Y1psEDJ#EePf3g5E%)&v5@_UF}oD#aPwf-^8MmeLdA(LJuGII6N zn7(sDsOEC7NT$=#G+l1bkdmv)4bXS*T!8v)xmM)=OoUqC(;HHD5eQg%=;E}8$5%mC z-CuBktWCK^MXB`L3TKMK8^LkMi`!E|Pa9Qw1BAcPh^}vGIGPJPT>nsBQL~bt0q0dY z)zx*wFd(_MX}NmK!+gy6k#sJM;7600(e|tn%nIP?SOW=L<=f|(+eOKatdr~PX;?wf zV?|2Q<5mzxd7HLunT7PhMtP!XGN*)cCqs}7zXXD~Nwhq#;IMuA_J<$ue0I*9I;r}n z`03HG{aYgH9$v-1FrO5`tY50TpNTjrs+l_%@*+fty$EO3$>F29n|tHd#!H~HODz)e z#W|cO=fY5z-wrN&N+{yP4&yZ1MG&OlI&4&FaM%i$95~pyUN!~~bnu-qx$WPuXLG!A z=@l$ei(I?8Ii3E4?$b#gzt4*hMfWx|;U#w*FV*P{PP{aW@q%YddTj`2D6DnLQXjkr z_K*jsgeFg;jnrR>II({LUqV|q+|@T13m&`+x)LqF=7Nx$E0$6*srCX0(Nr;L11N;~ zV4M4&4RVerB@f+{h+MF8F62ds`fDO(7ipiya?YaTVJdtyJl;|+ZlFuQ8f|Xa;Q|%Q zL$U|gdv{7Gx99Mcw>nCdb1+~vxv7t99L6p$uU!5;xA+><+{ekGP}qgP5VL1xR66>3 zv-PsP2@$>|5q8_i{dhUf1w9tO9(k%1T?f(H>E-axnBaMOdYX%S&rb>EfwQAZ)iW@= z-i^-H>w+hjDEd7Us%k&y6q$QgF^PS}DPB5!Q1Gln8Rr7rV?$nlbF<<5&YuvefpB`o zo!@7=x%>2Jc7t;|0~pXh_D!xB_WOYp@w=l59=Xk=+7F#vC|*vSt3Jr>+gBg!Xlb}h zEuu3pEBy|sFdO~7Fe?{pnzqVmDKQeeS*{)F*6c7JGah7}3#gyrdXZEoFk{vzy}fDG zUUb^1QJz>@riYH}(dZf>Fk95aEDW!p)J%lVoIE8oyOw@Fx9wfC4KvfF0aZO0gUA+N%3@Ufcq>V_ zHZ&WLGe&}>bD>M?z7{r7PGy|X3aDhQ z6Zmx4vg#G(5JIW7DY%BWxm6|8d2w^!*1YC592>jvrOA#9;Jc5s&YmSH}|m{4n7uNUz?$3JSFO*xRA;O8^f(aS{X)*E#ypvgGuujwC zta}=8KD5Haal^ODxjX1Fr6~BC+4`Yb+1L)h+bmBc9r1l!rOTMb^D0DrOeW7=a2q3a z#)Qh6b2Xj0Uzh_E=s*vMG?*!jCcnt)w^PBC_pA&)upw^koUVB12Fwgnaeyh(I5pOC zmgX~6jCC)O8;IBt?8NOLJ*iUj^9wh5j$M>jb&gk4#x8;z^>mH7-}T7Lhb?kw?8s7K zW0d1$Us#)$vWGamA|m!l$?UTIc;;Wc2$rZzxSi$&eFUfuvZ50sUEh&a$F1o5nP=o& z$h!~)i`B41B?m(auadxrx0gI7`cYw{a`>t>gxNAQ-Uu%vjgk*rTGq5?q!sufxfzkN zr@df9rRKtzJhNPDdf9mwqP~|!+R~YDb}zNS$rLs4Q)lI6LN{*R zJQMS2Mk8iI*gwImR8V`!j6vDr0a@i>a5t)dibk+$E*{2Cl)MI4jsvKh~!;} zc!NM~fc~BT3!UUezUV7gaza{_L!g5%kqUD4N`ACi&P+)$z!dXEbykqiq@+0Wp47%65qwWp&Y^(vbX}3($*S6a*w|s!JOOv|bvTOxwLxm=1EYK%TL)X{ zi$-}TRa%yFp&&vOBt_wTHyTu^z3q|Jf0Qj3-WgdTVkM+VSZyk=Shi|nbq!QVf3Ln% zi^!GorSQ+T+-4Z~s%wc`<>{XQ6tW^03L-?2$UPB$)N6j5L-|Sn+KB67`G>ae1pr7G?AxBts&Qd=*aI2F2L z`hXXZv5TNfuHPN$Y==PI&yTS3LZJAeBgcBRx8N-CWVWMBea@(Td-eErvJM#|x`j%k zT>~E40xY(ss?F^p_N~;DzrV^a+jiV@NWKhdRSqnOM=D@FYHrS|e&0cnx9KEt8wBbI z1ZpEx%uP6;a0gTMcS}o3+wgUXm|0!9i=Lki!D!+_?0Nnc)^y}%*0h2!)9-F?S@kNV ztJ6~PmN5n45Xf6H5>N66T~7w1{ui%C!Gx%YD&bz1pPkH5F{B*|ys_ZAlC_73sybL? zwK?w$y_0VYT#R+A#Twrgo*?AV(Zg(fMa{>U=?_44?1Jji1BU?@s=+uVa@3|Rjg`rT zPE^M03&Q+>k;*)wa@ob;akAIt6_OrKg*YC$P%t6li;Xx8FoK>L^0zVQ#*UWycRVRW zHgcQNo-xCxY;O}~hEW7)I_~Yz7};oGjpqB;`2|7hD>3=gf8Uql;eXmvqE@kqR-In3tMBjH!(XmRjC7l?)^Ff^oRA_U(G&qNTo0r$2cM<+reZBdHJ#r$9tLv9X`uR|prVVEbL zs0|L5JS`3`4mo`2&~0#p^oV0*LZ%|R3o1mMC58I4UIZ0jUHh(;`!cKT?unl{E#0Yc zaG;aVwn&%fuByUVXx}~9KCvjeyTND@O45NBP~M?H$;(DxdJtyR0+25Spq+)IN3uy_ zb7*p)E4UD0EhL=HoEOhH4Roy+bU2O2p6s07?@o425^iQ;RWA7{85|t%x-g#+F?zpB zhtRXE28D@LOTPfGT+V@;PFaKV=_#i;PT;W=@R}3&bXd%?BPUefUR8J@Qj~ByV_w|j zCGTi&S@UNvXmJ{excrBWi6S0!swCJ6smfvYiDO&)56+&qa8Yz;!zWhlt7-Dl+FaEd z6e#_@RXNgm3fU+_LrWy)6><3P zS8y=IJRA!7BfC#yR!mlZ6i(_CD-5o6P?)v7ecGi_*aa@A>z4 z&>^Hw!hvA#aT2>1ZEaW)ED2O$^uG)9;G2T1dIpAa58+cKk0C^9-oDm`bE2*FFNhN7 zAE1W)catc*DIAXS3h2Y0H_i7j18S;!m5z}!3%X8}Y6r&8>1OfP)U*3vj0;NeC+_ic zF%Nbgo(6p`nwuk@f+@vtdw>;%exvgY)4mLad(TRu@K}iL}ZoOHniEPs4< zoop?@KdRNEwN2HTHUp!66}&_hh=!N|1#k@NG7>L!IMRyIk&EyQZ3985g!VuPkK*?L ygnGZiXcVjU?_tK-shm>0-N{UOvbC4r{QfVO{N_=4D`{o`0000G~DC^=XHY{%vidc5v z`@VPc&AtDfbIzPPXKnycK#zzB zg)D%d#b<+Wu2<~`Ac!?GVxoK@P69wqX-HOj83nTWY$2CL4HPnSse#PQOeWRQ-jNz1%u40*zGL~GhtSgl;0Wvd}0dQ&wp?pPtC{*k=kGa@j+2`wEwWpc^u!cL0x!z zIx{!|Vhf00vU!0~gX<9V1mXzkn(&?A$LEEG4*EqXWs79~!goTum=hz-nIiy16R|KR zYS1=fOe!~k0dWAtIUHe7)S$n_qXM3+&R|T4?}d`6*g+pj0c?J(bWLepEMN-#0|#S8 zY65Wx6R<%RmORFDGY2j!$|WWgbQldjt>n_~^>vxmdia66E|HxB59bPhz5L5FN6 z2ilhjpT2Nb0%>UwkJd6MA0e}K&<5&|^*uvcvShX}N8~=+<_qb3kOyZ(!=B;VI1L{U zhX)>td*U>iln`>{0z29KMA_W1*3X_xed`&~It$u5+WXP*8jj%!C?$sPJm?{RC_W-+ z&3h=5F(mz!pDXkvRsuokvPj1Csu3%w1;QCz)}`fr|B|(DwcCA>xA4(*A*+;>Z|VZ- zB3vb0Cfp}n2UPg{gV09khUgCAF8tm4Zd9^HVvq($)<^}gzsL<6a`I$azP0mn&IZ@{ zY6S!v;iSt}ky10^;L3PJBl(j+EQa?~nY7(kxeNSSZ%clY4xqL#J$?>QYg8J}evWn< zUY~SLsU<&^zd}zSm|m4Xz!rR_O7p;89QG;<6xh=C(t2szXf?DKwELeqXg6qo(%NWS zAmu5x8asp?!5XketQAnPPeW${u6~h{;Xem`ZR8ymCe{^K& zqoO6{AC7SPKh*2!ijijQf3s-xI$w4K_UBzkF{LM;S8`kKtP94P}`7#r__&H~~_JD}gWTE=Py{qjv_I=uWgG`V%cb(}{k>AYuS~ zI!Nb<>RQ5koV0J zg`fzOfE8dZCEl4%84{1P7Am@-P$StH3=|TQR z-k}((gleD$s0BI>bw%lD2pWSAtQafBDzRGF16r_aSO?aNy~T;RI!?vyU>1Y$Se%8=!sp>j z@p618UWcE;ui>3|AO4X*Cg>Av2<`+1VG1FQFq=?BC?!-84iQen4&6m~MI;inV18U+ z-V%uE#5u&J#Erx~#N)&(#D~Ow5{aZsvLShr!bwb$m{desPpTmuBV8qRk>1ED${EQy z$_2gRSf;pF@vLH};#(y(C2J*Lr6eVZ(lVtT zO2?IMDZL<*$rfZEaw1twUPi7apCsQWzoDp8>?sUN3S~Z}f>KAhN_nO%uWYVNSDvn% zr(CLhK>3n#uZp~ig^I5VQ)Qk?g-V0U4V8XXbyWw|aMeuJrK-DBX+k<={I{MAy_ z3e~o%om6|Mj;Wif`>M0l7pZSkKds)SLDaC+U}&UklxX~-aZ#gBQ%!S%W}Ie@W`*Vv z%?>S0%R-Bx#nW1@wO^}U>z%fNHeH*oy+pfK`>OV9oiRE-I&7U{ojp2jI`4F;y8gNu zx+`@L>)zAD^{n+G^=9jB(mSo!J4R!S#~9X_;xYTj+}20+t@Wey=jd z5E!gCIBC#psAcG5m~Obn@Tg&rk-CwW5!Yyq(J`YZR81S~&5y2iBGw9m}QY_eIt*>1Dj=JMvQ<{a~N<}K#0Ei5hK zEf!lGw&=Fhv1C~0S?;#HYely5wwh&CX?1-pajfgujIkTXUbaT9ovb<571oz*P#b3( zuFXc9E4Bn%H(S1KrR@znB|ExZw%u;KPJ1o;Q2PS=!}ia{nT<;vw{l#|xQ{d^8V{as zcO29lf*lGR8Xf+2w02}URybZCPaYpIe*XCS@y{pNOkhvgG~uR`y3=H*#ZJvmADmsB zh0e9kJuYT0$u1jQZn$c=Mz}6@J?lnro8&g%t;y}JyR*C4eZTu(9(EoX9=klcCt6Nq zPuw=~p{I!_({qbwhZof=+3RPo4sT;`rgx?H10PeL6rU=e$MmuEbb1Z_*(BN|;iN;8 zUi-TH&hbU6tCM=9#uSt%u{yDdqHX zeYxe_=jlP|o6}!sglFu?_{59n?a7qOOwMfJtMN1Vr?L#Qa(n|&ZhHHV+mnrofAB=>P%K;HH__#D=p z=6vJ)h54Ox>2tTtL*~t#*F4{Je&PJC1%V58E>u{UvGBJ7TEVJF-*;8{IA0-BXiPbNLs)U+Qb^ zYPams+EcO@?3L_&vM+gG`~Hyq%?Df$)E+cHxZ#lcq2fBEF1N1lFz0YbeM0?}hTw+g zMvulrzuN!0qsh3b;)v#v!%`5T|6Cf z`s|s2GbdZ-obMoG;Y1I<+49&FQy87o9KGU2?fpf7$JFqCZvt-0;lm*}=bj{%Y-;(%1D|`25q~OJC@|*zt10%jW)w{`;>oUk$u2exv(l z=UdmeE$`yrJsz0-p7g%#!`KgvA45Lg{gnCX(|-UhUGN<0w)KDj001~;SV?A0O#mtY z000O80f%V-1ONa40RR918UO$Q0007@0ssU600031005$(0{{d700031001-q0001V zo+_jO01FdIL_t(|0j*qnuvS$SUz?W_67on&W4t05f+8|NQiMppaI%=j8f(%N4U{mM z%&D=*G@&(>W`=m9EK>}Fk@0~bQ3*rDBSEebqJRn^fnp%)y#e>$^J|^&eCO=v+UNT& z?tjjD{MK*pd(J-l?7jB>uEHcbg=#Gcy+v!){#xNgXrK#4^cwYI?!#4dTrNA;Me3kq zu~c-X(KM0Hqv3R_L|$$ zoE#)`jOdZPBhoI>U`!HG&uNq`VQlg@F)HkcK9G!^AIpJoaAr-m*sZWMbi#SK9ZfL; z%eUML7ZhA)#n{Ru9fTj+E<zn+RKN&JB^<8Ns9eJMWUq*iIf4%)XHBoTJ{Df}oo_}&WK6(gNJFg(I=iy0jmOop1cRK}NaB*GhWUF&kWdQETQt!`9A$JzKxtVLKI39h&>Ta0f( zZyn7;xlocrW`9j1@CCF9;BvF~Ky(`_+~dkA7_rcfD$$^ldt_SvWT+Scy5pc2eZLvW zeM>5THF10k&q0d>EwlR%#O7x9N6I)V{+(`IiO#q2*$DBVSU9eVM4oF#Mjq82CXR>w ztr5;Lm-9eO=2S+194(`$`ak5x8pFHmB2rMZeQRMEQAi^+oQ~9T< z(9LRyrPrsdFM&^`t|f@vJti0OYnNOQu1hE(=|+#BM};WD5E>`>)Ev`;ZX`bp;}6I2 z^er>alUryxt*2M$5P`Z=KWd;M7_Ax#oc%xwb0(k*O><1LI+~Wq&Y&mqLO&G@s2FjV z_-eetx6LRRBO-ShFv6Ea9MFnc=w+gF8K+M?5=BRh#_jjPhE~e z-y;R`=(WE z&4O^H7}JIU_MeD(BG&rDlmAG#WP#0CzlNa_w_tCu>yXAfjap5uT5%*{G{e^%oK~My zyS0)^kUuNth}c(s#E#RNTBYR}fr)7$`NL;D5cgPp22N#Fv2SpQuBpO1nIk+F5h-M#J zu~>6J#)bDi6MyLts>iZ%ax++xy%`J_2i>W$$s#Hgyd*}9FF=C83o?1H+NEtlAVq<1 zy0EI=;@%u_Lw};sIN2<%Bf0ASX%x@Sq!Rqxh))A{7d!vrZB<{`I z9Zar1;$a`oUC#B}F0uwa`L{!otC#RCJW1RuJBSa2$Rj=X`4B#A!{i#4gW#9nnKkkQ zkjiClO}IG>O%~l&(h{gWK-ZC8h%2yc2Taok9xB^VY9Y`}FwqeU|(t$r=CWsW<| zV4Nnc@RNH?Tqg4|gjRvQy7?7YNBA^Vi!kBF2sJ^>PcK*71wL_tBc?(HB7R5SqZ_b^ z8pUKVQG*qHqqM?T=VO_L%#=0?->1>EIDn3ug#Ol!$Au>aTpniRz95tiBs{BC;BJ93 zH9xJ}f#V|ws3H^r*Q|`SjxkXj6+4lzWr>~QE`^w2SAPCR|NU|4?uh$;hVM$%*U*kd ztd5Fx-9$Mh7H)}Z^b%S*P=1-~_^jk))$1NU`yiEr+99o&HKJyzLpO0nq?vxrhv|2| zF|$Ncr@}HzVlwP!M8?D-ae*;vlo4}mVjrBI64ccb`F8`G>!@{s`fnJ``J0hp4_lp{ z$lGK$)i(L2*kW;0QQwS0dOw5?O><&{w>$ERPn-|iOU0Y<;l~U;fID$!>~H3@@hpjw z?ah1~s#4Ieu2px0vg-OptW|;!mzVQa5l)XX33;bjD0&r;pS({0x{BJxgqMw;W2=@XepZw-BJ!^qbblVsKlu4B zQL=Xw;0UmSZ%9M8Hvu--I#jfuwH&F+QVC+kv)jW ziPs5sTk1Y)q?@3nCvr}FRvX_pX?XoTG2QtS=XiNzc}97^I-)gO;urE`wx!S#+EB=u zAof`YC#rZy%`BYqN2Q5gDo|lzY~W{aDRKIKXC$sY8$5Od%&l8-VUNt ziq+0!bvELT+XxTs9Og<*E#qo6XWp1U}>MSRTETv(I{-IuV>J6(>a&}Bd zZsPjbsTlVCA>4+lRlG53qc`JfqSbY+*0~B^oix&!>Kp2i*$RA$=a^D?SaLXa=_Yn? zR9qH$HLSy#PBU1I{5a!hKAQ0ZFr9y{`DUcXs*5v`i#hw=E6DOEG5!epgd%(!E(miZ z+msJ3x9|ypYGOQqeMKDzSPK&dQSU;rg`Kf~jDXX)FAbxCJX`C}zx?m1cr}c}s+r#4 z)yobZ2sYAl{!x{@0zSRgHJ6=hOW?Gc1IbigK7@O7@_%8X-IfTCj2!>~002ovPDHLk FV1kLF?p6Q* literal 0 HcmV?d00001 diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/Resources/bg-BG.lproj/Localizable.strings b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/Resources/bg-BG.lproj/Localizable.strings new file mode 100644 index 0000000..7e16882 --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/Resources/bg-BG.lproj/Localizable.strings @@ -0,0 +1,45 @@ +/* The text for warning when a debugger is currently attached to the process. */ +"A debugger is attached to the App." = "A debugger is attached to the App."; + +/* The text for warning when an emulator is being used to run the application. */ +"An emulator is being used to run the App." = "An emulator is being used to run the App."; + +/* The text for the button that cancels the current challenge process. */ +"Cancel" = "Cancel"; + +/* Accessibility label for expandandable text control to indicate text is hidden. */ +"Collapsed" = "Collapsed"; + +/* Accessibility label for expandandable text control to indicate that the UI has been expanded and additional text is available. */ +"Expanded" = "Expanded"; + +/* Spoken by VoiceOver when the challenge is loading. */ +"Loading" = "Loading"; + +/* The no answer to a yes or no question. */ +"No" = "No"; + +/* The title for the challenge response step of an authenticated checkout. */ +"Secure checkout" = "Secure checkout"; + +/* Indicates that a button is selected. */ +"Selected" = "Selected"; + +/* The text for warning when a device is jailbroken */ +"The device is jailbroken." = "The device is jailbroken."; + +/* The text for warning when the integrity of the SDK has been tampered with */ +"The integrity of the SDK has been tampered." = "The integrity of the SDK has been tampered."; + +/* The text for warning when the SDK is running on an unsupported OS or OS version. */ +"The OS or the OS Version is not supported." = "The OS or the OS Version is not supported."; + +/* Error description for when a network request times out. English value is as required by UL certification. */ +"Timeout" = "Timeout"; + +/* Indicates that a button is not selected. */ +"Unselected" = "Unselected"; + +/* The yes answer to a yes or no question. */ +"Yes" = "Yes"; + diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/Resources/ca-ES.lproj/Localizable.strings b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/Resources/ca-ES.lproj/Localizable.strings new file mode 100644 index 0000000..7e16882 --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/Resources/ca-ES.lproj/Localizable.strings @@ -0,0 +1,45 @@ +/* The text for warning when a debugger is currently attached to the process. */ +"A debugger is attached to the App." = "A debugger is attached to the App."; + +/* The text for warning when an emulator is being used to run the application. */ +"An emulator is being used to run the App." = "An emulator is being used to run the App."; + +/* The text for the button that cancels the current challenge process. */ +"Cancel" = "Cancel"; + +/* Accessibility label for expandandable text control to indicate text is hidden. */ +"Collapsed" = "Collapsed"; + +/* Accessibility label for expandandable text control to indicate that the UI has been expanded and additional text is available. */ +"Expanded" = "Expanded"; + +/* Spoken by VoiceOver when the challenge is loading. */ +"Loading" = "Loading"; + +/* The no answer to a yes or no question. */ +"No" = "No"; + +/* The title for the challenge response step of an authenticated checkout. */ +"Secure checkout" = "Secure checkout"; + +/* Indicates that a button is selected. */ +"Selected" = "Selected"; + +/* The text for warning when a device is jailbroken */ +"The device is jailbroken." = "The device is jailbroken."; + +/* The text for warning when the integrity of the SDK has been tampered with */ +"The integrity of the SDK has been tampered." = "The integrity of the SDK has been tampered."; + +/* The text for warning when the SDK is running on an unsupported OS or OS version. */ +"The OS or the OS Version is not supported." = "The OS or the OS Version is not supported."; + +/* Error description for when a network request times out. English value is as required by UL certification. */ +"Timeout" = "Timeout"; + +/* Indicates that a button is not selected. */ +"Unselected" = "Unselected"; + +/* The yes answer to a yes or no question. */ +"Yes" = "Yes"; + diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/Resources/cs-CZ.lproj/Localizable.strings b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/Resources/cs-CZ.lproj/Localizable.strings new file mode 100644 index 0000000..7e16882 --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/Resources/cs-CZ.lproj/Localizable.strings @@ -0,0 +1,45 @@ +/* The text for warning when a debugger is currently attached to the process. */ +"A debugger is attached to the App." = "A debugger is attached to the App."; + +/* The text for warning when an emulator is being used to run the application. */ +"An emulator is being used to run the App." = "An emulator is being used to run the App."; + +/* The text for the button that cancels the current challenge process. */ +"Cancel" = "Cancel"; + +/* Accessibility label for expandandable text control to indicate text is hidden. */ +"Collapsed" = "Collapsed"; + +/* Accessibility label for expandandable text control to indicate that the UI has been expanded and additional text is available. */ +"Expanded" = "Expanded"; + +/* Spoken by VoiceOver when the challenge is loading. */ +"Loading" = "Loading"; + +/* The no answer to a yes or no question. */ +"No" = "No"; + +/* The title for the challenge response step of an authenticated checkout. */ +"Secure checkout" = "Secure checkout"; + +/* Indicates that a button is selected. */ +"Selected" = "Selected"; + +/* The text for warning when a device is jailbroken */ +"The device is jailbroken." = "The device is jailbroken."; + +/* The text for warning when the integrity of the SDK has been tampered with */ +"The integrity of the SDK has been tampered." = "The integrity of the SDK has been tampered."; + +/* The text for warning when the SDK is running on an unsupported OS or OS version. */ +"The OS or the OS Version is not supported." = "The OS or the OS Version is not supported."; + +/* Error description for when a network request times out. English value is as required by UL certification. */ +"Timeout" = "Timeout"; + +/* Indicates that a button is not selected. */ +"Unselected" = "Unselected"; + +/* The yes answer to a yes or no question. */ +"Yes" = "Yes"; + diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/Resources/da.lproj/Localizable.strings b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/Resources/da.lproj/Localizable.strings new file mode 100644 index 0000000..2388efa --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/Resources/da.lproj/Localizable.strings @@ -0,0 +1,39 @@ +/* The text for warning when a debugger is currently attached to the process. */ +"A debugger is attached to the App." = "Et fejlfindingsprogram er vedhæftet appen."; + +/* The text for warning when an emulator is being used to run the application. */ +"An emulator is being used to run the App." = "En emulator bruges til at køre appen."; + +/* The text for the button that cancels the current challenge process. */ +"Cancel" = "Annullér"; + +/* Spoken by VoiceOver when the screen is loading. */ +"Loading" = "Indlæser"; + +/* The no answer to a yes or no question. */ +"No" = "Nej"; + +/* The title for the challenge response step of an authenticated checkout. */ +"Secure checkout" = "Sikker betaling"; + +/* Indicates that a button is selected. */ +"Selected" = "Valgt"; + +/* The text for warning when a device is jailbroken */ +"The device is jailbroken." = "Enheden er jailbroken."; + +/* The text for warning when the integrity of the SDK has been tampered with */ +"The integrity of the SDK has been tampered." = "Integriteten af SDK'en er blevet ændret."; + +/* The text for warning when the SDK is running on an unsupported OS or OS version. */ +"The OS or the OS Version is not supported." = "Operativsystemet eller versionen af operativsystemet understøttes ikke."; + +/* Error description for when a network request times out. English value is as required by UL certification. */ +"Timeout" = "Udløb"; + +/* Indicates that a button is not selected. */ +"Unselected" = "Fravalgt"; + +/* The yes answer to a yes or no question. */ +"Yes" = "Ja"; + diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/Resources/de.lproj/Localizable.strings b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/Resources/de.lproj/Localizable.strings new file mode 100644 index 0000000..55a9ea4 --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/Resources/de.lproj/Localizable.strings @@ -0,0 +1,39 @@ +/* The text for warning when a debugger is currently attached to the process. */ +"A debugger is attached to the App." = "Ein Debugger ist an die App angeschlossen."; + +/* The text for warning when an emulator is being used to run the application. */ +"An emulator is being used to run the App." = "Ein Emulator wird zum Ausführen dieser App verwendet."; + +/* The text for the button that cancels the current challenge process. */ +"Cancel" = "Abbrechen"; + +/* Spoken by VoiceOver when the screen is loading. */ +"Loading" = "Wird geladen"; + +/* The no answer to a yes or no question. */ +"No" = "Nein"; + +/* The title for the challenge response step of an authenticated checkout. */ +"Secure checkout" = "Sicherer Bezahlvogang"; + +/* Indicates that a button is selected. */ +"Selected" = "Ausgewählt"; + +/* The text for warning when a device is jailbroken */ +"The device is jailbroken." = "Das Gerät ist beschädigt."; + +/* The text for warning when the integrity of the SDK has been tampered with */ +"The integrity of the SDK has been tampered." = "Die Integrität des SDK wurde manipuliert."; + +/* The text for warning when the SDK is running on an unsupported OS or OS version. */ +"The OS or the OS Version is not supported." = "Das Betriebssystem oder die Betriebssystemversion wird nicht unterstützt."; + +/* Error description for when a network request times out. English value is as required by UL certification. */ +"Timeout" = "Zeitüberschreitung"; + +/* Indicates that a button is not selected. */ +"Unselected" = "Nicht ausgewählt"; + +/* The yes answer to a yes or no question. */ +"Yes" = "Ja"; + diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/Resources/el-GR.lproj/Localizable.strings b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/Resources/el-GR.lproj/Localizable.strings new file mode 100644 index 0000000..7e16882 --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/Resources/el-GR.lproj/Localizable.strings @@ -0,0 +1,45 @@ +/* The text for warning when a debugger is currently attached to the process. */ +"A debugger is attached to the App." = "A debugger is attached to the App."; + +/* The text for warning when an emulator is being used to run the application. */ +"An emulator is being used to run the App." = "An emulator is being used to run the App."; + +/* The text for the button that cancels the current challenge process. */ +"Cancel" = "Cancel"; + +/* Accessibility label for expandandable text control to indicate text is hidden. */ +"Collapsed" = "Collapsed"; + +/* Accessibility label for expandandable text control to indicate that the UI has been expanded and additional text is available. */ +"Expanded" = "Expanded"; + +/* Spoken by VoiceOver when the challenge is loading. */ +"Loading" = "Loading"; + +/* The no answer to a yes or no question. */ +"No" = "No"; + +/* The title for the challenge response step of an authenticated checkout. */ +"Secure checkout" = "Secure checkout"; + +/* Indicates that a button is selected. */ +"Selected" = "Selected"; + +/* The text for warning when a device is jailbroken */ +"The device is jailbroken." = "The device is jailbroken."; + +/* The text for warning when the integrity of the SDK has been tampered with */ +"The integrity of the SDK has been tampered." = "The integrity of the SDK has been tampered."; + +/* The text for warning when the SDK is running on an unsupported OS or OS version. */ +"The OS or the OS Version is not supported." = "The OS or the OS Version is not supported."; + +/* Error description for when a network request times out. English value is as required by UL certification. */ +"Timeout" = "Timeout"; + +/* Indicates that a button is not selected. */ +"Unselected" = "Unselected"; + +/* The yes answer to a yes or no question. */ +"Yes" = "Yes"; + diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/Resources/en-GB.lproj/Localizable.strings b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/Resources/en-GB.lproj/Localizable.strings new file mode 100644 index 0000000..ddfe3b2 --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/Resources/en-GB.lproj/Localizable.strings @@ -0,0 +1,39 @@ +/* The text for warning when a debugger is currently attached to the process. */ +"A debugger is attached to the App." = "A debugger is attached to the App."; + +/* The text for warning when an emulator is being used to run the application. */ +"An emulator is being used to run the App." = "An emulator is being used to run the App."; + +/* The text for the button that cancels the current challenge process. */ +"Cancel" = "Cancel"; + +/* Spoken by VoiceOver when the screen is loading. */ +"Loading" = "Loading"; + +/* The no answer to a yes or no question. */ +"No" = "No"; + +/* The title for the challenge response step of an authenticated checkout. */ +"Secure checkout" = "Secure checkout"; + +/* Indicates that a button is selected. */ +"Selected" = "Selected"; + +/* The text for warning when a device is jailbroken */ +"The device is jailbroken." = "The device has been jailbroken."; + +/* The text for warning when the integrity of the SDK has been tampered with */ +"The integrity of the SDK has been tampered." = "The integrity of the SDK has been tampered with."; + +/* The text for warning when the SDK is running on an unsupported OS or OS version. */ +"The OS or the OS Version is not supported." = "The OS or the OS version is not supported."; + +/* Error description for when a network request times out. English value is as required by UL certification. */ +"Timeout" = "Timeout"; + +/* Indicates that a button is not selected. */ +"Unselected" = "Unselected"; + +/* The yes answer to a yes or no question. */ +"Yes" = "Yes"; + diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/Resources/en.lproj/Localizable.strings b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/Resources/en.lproj/Localizable.strings new file mode 100644 index 0000000..7e16882 --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/Resources/en.lproj/Localizable.strings @@ -0,0 +1,45 @@ +/* The text for warning when a debugger is currently attached to the process. */ +"A debugger is attached to the App." = "A debugger is attached to the App."; + +/* The text for warning when an emulator is being used to run the application. */ +"An emulator is being used to run the App." = "An emulator is being used to run the App."; + +/* The text for the button that cancels the current challenge process. */ +"Cancel" = "Cancel"; + +/* Accessibility label for expandandable text control to indicate text is hidden. */ +"Collapsed" = "Collapsed"; + +/* Accessibility label for expandandable text control to indicate that the UI has been expanded and additional text is available. */ +"Expanded" = "Expanded"; + +/* Spoken by VoiceOver when the challenge is loading. */ +"Loading" = "Loading"; + +/* The no answer to a yes or no question. */ +"No" = "No"; + +/* The title for the challenge response step of an authenticated checkout. */ +"Secure checkout" = "Secure checkout"; + +/* Indicates that a button is selected. */ +"Selected" = "Selected"; + +/* The text for warning when a device is jailbroken */ +"The device is jailbroken." = "The device is jailbroken."; + +/* The text for warning when the integrity of the SDK has been tampered with */ +"The integrity of the SDK has been tampered." = "The integrity of the SDK has been tampered."; + +/* The text for warning when the SDK is running on an unsupported OS or OS version. */ +"The OS or the OS Version is not supported." = "The OS or the OS Version is not supported."; + +/* Error description for when a network request times out. English value is as required by UL certification. */ +"Timeout" = "Timeout"; + +/* Indicates that a button is not selected. */ +"Unselected" = "Unselected"; + +/* The yes answer to a yes or no question. */ +"Yes" = "Yes"; + diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/Resources/es-419.lproj/Localizable.strings b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/Resources/es-419.lproj/Localizable.strings new file mode 100644 index 0000000..759db05 --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/Resources/es-419.lproj/Localizable.strings @@ -0,0 +1,39 @@ +/* The text for warning when a debugger is currently attached to the process. */ +"A debugger is attached to the App." = "Se ha asociado un depurador a la aplicación."; + +/* The text for warning when an emulator is being used to run the application. */ +"An emulator is being used to run the App." = "Se está usando un emulador para ejecutar la aplicación."; + +/* The text for the button that cancels the current challenge process. */ +"Cancel" = "Cancelar"; + +/* Spoken by VoiceOver when the screen is loading. */ +"Loading" = "Cargando"; + +/* The no answer to a yes or no question. */ +"No" = "No"; + +/* The title for the challenge response step of an authenticated checkout. */ +"Secure checkout" = "Proceso de compra seguro"; + +/* Indicates that a button is selected. */ +"Selected" = "Seleccionado"; + +/* The text for warning when a device is jailbroken */ +"The device is jailbroken." = "El dispositivo ha sido liberado."; + +/* The text for warning when the integrity of the SDK has been tampered with */ +"The integrity of the SDK has been tampered." = "Se ha alterado la integridad del SDK."; + +/* The text for warning when the SDK is running on an unsupported OS or OS version. */ +"The OS or the OS Version is not supported." = "El OS o la versión del OS no son compatibles."; + +/* Error description for when a network request times out. English value is as required by UL certification. */ +"Timeout" = "Tiempo de espera agotado"; + +/* Indicates that a button is not selected. */ +"Unselected" = "No seleccionado"; + +/* The yes answer to a yes or no question. */ +"Yes" = "Sí"; + diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/Resources/es.lproj/Localizable.strings b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/Resources/es.lproj/Localizable.strings new file mode 100644 index 0000000..5a6f273 --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/Resources/es.lproj/Localizable.strings @@ -0,0 +1,39 @@ +/* The text for warning when a debugger is currently attached to the process. */ +"A debugger is attached to the App." = "Se ha asociado un depurador a la aplicación."; + +/* The text for warning when an emulator is being used to run the application. */ +"An emulator is being used to run the App." = "Se está usando un emulador para ejecutar la aplicación."; + +/* The text for the button that cancels the current challenge process. */ +"Cancel" = "Cancelar"; + +/* Spoken by VoiceOver when the screen is loading. */ +"Loading" = "Cargando"; + +/* The no answer to a yes or no question. */ +"No" = "No"; + +/* The title for the challenge response step of an authenticated checkout. */ +"Secure checkout" = "Proceso de compra seguro"; + +/* Indicates that a button is selected. */ +"Selected" = "Seleccionado"; + +/* The text for warning when a device is jailbroken */ +"The device is jailbroken." = "El dispositivo ha sido liberado."; + +/* The text for warning when the integrity of the SDK has been tampered with */ +"The integrity of the SDK has been tampered." = "Se ha alterado la integridad del SDK."; + +/* The text for warning when the SDK is running on an unsupported OS or OS version. */ +"The OS or the OS Version is not supported." = "El SO o la versión del SO no son compatibles."; + +/* Error description for when a network request times out. English value is as required by UL certification. */ +"Timeout" = "Tiempo de espera agotado"; + +/* Indicates that a button is not selected. */ +"Unselected" = "No seleccionado"; + +/* The yes answer to a yes or no question. */ +"Yes" = "Sí"; + diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/Resources/et-EE.lproj/Localizable.strings b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/Resources/et-EE.lproj/Localizable.strings new file mode 100644 index 0000000..7e16882 --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/Resources/et-EE.lproj/Localizable.strings @@ -0,0 +1,45 @@ +/* The text for warning when a debugger is currently attached to the process. */ +"A debugger is attached to the App." = "A debugger is attached to the App."; + +/* The text for warning when an emulator is being used to run the application. */ +"An emulator is being used to run the App." = "An emulator is being used to run the App."; + +/* The text for the button that cancels the current challenge process. */ +"Cancel" = "Cancel"; + +/* Accessibility label for expandandable text control to indicate text is hidden. */ +"Collapsed" = "Collapsed"; + +/* Accessibility label for expandandable text control to indicate that the UI has been expanded and additional text is available. */ +"Expanded" = "Expanded"; + +/* Spoken by VoiceOver when the challenge is loading. */ +"Loading" = "Loading"; + +/* The no answer to a yes or no question. */ +"No" = "No"; + +/* The title for the challenge response step of an authenticated checkout. */ +"Secure checkout" = "Secure checkout"; + +/* Indicates that a button is selected. */ +"Selected" = "Selected"; + +/* The text for warning when a device is jailbroken */ +"The device is jailbroken." = "The device is jailbroken."; + +/* The text for warning when the integrity of the SDK has been tampered with */ +"The integrity of the SDK has been tampered." = "The integrity of the SDK has been tampered."; + +/* The text for warning when the SDK is running on an unsupported OS or OS version. */ +"The OS or the OS Version is not supported." = "The OS or the OS Version is not supported."; + +/* Error description for when a network request times out. English value is as required by UL certification. */ +"Timeout" = "Timeout"; + +/* Indicates that a button is not selected. */ +"Unselected" = "Unselected"; + +/* The yes answer to a yes or no question. */ +"Yes" = "Yes"; + diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/Resources/fi.lproj/Localizable.strings b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/Resources/fi.lproj/Localizable.strings new file mode 100644 index 0000000..faeaf2d --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/Resources/fi.lproj/Localizable.strings @@ -0,0 +1,39 @@ +/* The text for warning when a debugger is currently attached to the process. */ +"A debugger is attached to the App." = "Sovellukseen on liitetty virheiden tarkastusohjelma."; + +/* The text for warning when an emulator is being used to run the application. */ +"An emulator is being used to run the App." = "Sovelluksen suorittamiseen käytetään emulaattoria."; + +/* The text for the button that cancels the current challenge process. */ +"Cancel" = "Peruuta"; + +/* Spoken by VoiceOver when the screen is loading. */ +"Loading" = "Ladataan"; + +/* The no answer to a yes or no question. */ +"No" = "Ei"; + +/* The title for the challenge response step of an authenticated checkout. */ +"Secure checkout" = "Turvallinen maksaminen"; + +/* Indicates that a button is selected. */ +"Selected" = "Valittu"; + +/* The text for warning when a device is jailbroken */ +"The device is jailbroken." = "Laitteen käyttöjärjestelmän rajoitukset on poistettu."; + +/* The text for warning when the integrity of the SDK has been tampered with */ +"The integrity of the SDK has been tampered." = "SDK:n eheyttä on peukaloitu."; + +/* The text for warning when the SDK is running on an unsupported OS or OS version. */ +"The OS or the OS Version is not supported." = "Käyttöjärjestelmää tai käyttöjärjestelmäversiota ei tueta."; + +/* Error description for when a network request times out. English value is as required by UL certification. */ +"Timeout" = "Aikakatkaisu"; + +/* Indicates that a button is not selected. */ +"Unselected" = "Ei valittu"; + +/* The yes answer to a yes or no question. */ +"Yes" = "Kyllä"; + diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/Resources/fil.lproj/Localizable.strings b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/Resources/fil.lproj/Localizable.strings new file mode 100644 index 0000000..7e16882 --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/Resources/fil.lproj/Localizable.strings @@ -0,0 +1,45 @@ +/* The text for warning when a debugger is currently attached to the process. */ +"A debugger is attached to the App." = "A debugger is attached to the App."; + +/* The text for warning when an emulator is being used to run the application. */ +"An emulator is being used to run the App." = "An emulator is being used to run the App."; + +/* The text for the button that cancels the current challenge process. */ +"Cancel" = "Cancel"; + +/* Accessibility label for expandandable text control to indicate text is hidden. */ +"Collapsed" = "Collapsed"; + +/* Accessibility label for expandandable text control to indicate that the UI has been expanded and additional text is available. */ +"Expanded" = "Expanded"; + +/* Spoken by VoiceOver when the challenge is loading. */ +"Loading" = "Loading"; + +/* The no answer to a yes or no question. */ +"No" = "No"; + +/* The title for the challenge response step of an authenticated checkout. */ +"Secure checkout" = "Secure checkout"; + +/* Indicates that a button is selected. */ +"Selected" = "Selected"; + +/* The text for warning when a device is jailbroken */ +"The device is jailbroken." = "The device is jailbroken."; + +/* The text for warning when the integrity of the SDK has been tampered with */ +"The integrity of the SDK has been tampered." = "The integrity of the SDK has been tampered."; + +/* The text for warning when the SDK is running on an unsupported OS or OS version. */ +"The OS or the OS Version is not supported." = "The OS or the OS Version is not supported."; + +/* Error description for when a network request times out. English value is as required by UL certification. */ +"Timeout" = "Timeout"; + +/* Indicates that a button is not selected. */ +"Unselected" = "Unselected"; + +/* The yes answer to a yes or no question. */ +"Yes" = "Yes"; + diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/Resources/fr-CA.lproj/Localizable.strings b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/Resources/fr-CA.lproj/Localizable.strings new file mode 100644 index 0000000..19956a7 --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/Resources/fr-CA.lproj/Localizable.strings @@ -0,0 +1,39 @@ +/* The text for warning when a debugger is currently attached to the process. */ +"A debugger is attached to the App." = "Un débogueur est attaché à l'application."; + +/* The text for warning when an emulator is being used to run the application. */ +"An emulator is being used to run the App." = "Un émulateur est utilisé pour exécuter l'application."; + +/* The text for the button that cancels the current challenge process. */ +"Cancel" = "Annuler"; + +/* Spoken by VoiceOver when the screen is loading. */ +"Loading" = "Chargement"; + +/* The no answer to a yes or no question. */ +"No" = "Non"; + +/* The title for the challenge response step of an authenticated checkout. */ +"Secure checkout" = "Paiement sécurisé"; + +/* Indicates that a button is selected. */ +"Selected" = "Sélectionné"; + +/* The text for warning when a device is jailbroken */ +"The device is jailbroken." = "L'appareil est débridé."; + +/* The text for warning when the integrity of the SDK has been tampered with */ +"The integrity of the SDK has been tampered." = "L'intégrité de SDK a été modifiée."; + +/* The text for warning when the SDK is running on an unsupported OS or OS version. */ +"The OS or the OS Version is not supported." = "Le système d'exploitation ou la version du système d'exploitation n'est pas pris(e) en charge."; + +/* Error description for when a network request times out. English value is as required by UL certification. */ +"Timeout" = "Expiration"; + +/* Indicates that a button is not selected. */ +"Unselected" = "Non sélectionné"; + +/* The yes answer to a yes or no question. */ +"Yes" = "Oui"; + diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/Resources/fr.lproj/Localizable.strings b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/Resources/fr.lproj/Localizable.strings new file mode 100644 index 0000000..9d59567 --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/Resources/fr.lproj/Localizable.strings @@ -0,0 +1,39 @@ +/* The text for warning when a debugger is currently attached to the process. */ +"A debugger is attached to the App." = "Un débogueur est attaché à l'application."; + +/* The text for warning when an emulator is being used to run the application. */ +"An emulator is being used to run the App." = "Un émulateur est utilisé pour accéder à l'application."; + +/* The text for the button that cancels the current challenge process. */ +"Cancel" = "Annuler"; + +/* Spoken by VoiceOver when the screen is loading. */ +"Loading" = "Chargement"; + +/* The no answer to a yes or no question. */ +"No" = "Non"; + +/* The title for the challenge response step of an authenticated checkout. */ +"Secure checkout" = "Paiement sécurisé"; + +/* Indicates that a button is selected. */ +"Selected" = "Sélectionné"; + +/* The text for warning when a device is jailbroken */ +"The device is jailbroken." = "L'appareil est débridé."; + +/* The text for warning when the integrity of the SDK has been tampered with */ +"The integrity of the SDK has been tampered." = "L'intégrité du SDK a été altérée."; + +/* The text for warning when the SDK is running on an unsupported OS or OS version. */ +"The OS or the OS Version is not supported." = "Le système d'exploitation ou la version du système d'exploitation ne sont pas pris en charge."; + +/* Error description for when a network request times out. English value is as required by UL certification. */ +"Timeout" = "Timeout"; + +/* Indicates that a button is not selected. */ +"Unselected" = "Non sélectionné"; + +/* The yes answer to a yes or no question. */ +"Yes" = "Oui"; + diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/Resources/hr.lproj/Localizable.strings b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/Resources/hr.lproj/Localizable.strings new file mode 100644 index 0000000..7e16882 --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/Resources/hr.lproj/Localizable.strings @@ -0,0 +1,45 @@ +/* The text for warning when a debugger is currently attached to the process. */ +"A debugger is attached to the App." = "A debugger is attached to the App."; + +/* The text for warning when an emulator is being used to run the application. */ +"An emulator is being used to run the App." = "An emulator is being used to run the App."; + +/* The text for the button that cancels the current challenge process. */ +"Cancel" = "Cancel"; + +/* Accessibility label for expandandable text control to indicate text is hidden. */ +"Collapsed" = "Collapsed"; + +/* Accessibility label for expandandable text control to indicate that the UI has been expanded and additional text is available. */ +"Expanded" = "Expanded"; + +/* Spoken by VoiceOver when the challenge is loading. */ +"Loading" = "Loading"; + +/* The no answer to a yes or no question. */ +"No" = "No"; + +/* The title for the challenge response step of an authenticated checkout. */ +"Secure checkout" = "Secure checkout"; + +/* Indicates that a button is selected. */ +"Selected" = "Selected"; + +/* The text for warning when a device is jailbroken */ +"The device is jailbroken." = "The device is jailbroken."; + +/* The text for warning when the integrity of the SDK has been tampered with */ +"The integrity of the SDK has been tampered." = "The integrity of the SDK has been tampered."; + +/* The text for warning when the SDK is running on an unsupported OS or OS version. */ +"The OS or the OS Version is not supported." = "The OS or the OS Version is not supported."; + +/* Error description for when a network request times out. English value is as required by UL certification. */ +"Timeout" = "Timeout"; + +/* Indicates that a button is not selected. */ +"Unselected" = "Unselected"; + +/* The yes answer to a yes or no question. */ +"Yes" = "Yes"; + diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/Resources/hu.lproj/Localizable.strings b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/Resources/hu.lproj/Localizable.strings new file mode 100644 index 0000000..889cda1 --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/Resources/hu.lproj/Localizable.strings @@ -0,0 +1,39 @@ +/* The text for warning when a debugger is currently attached to the process. */ +"A debugger is attached to the App." = "Az alkalmazáshoz hibaelhárítót csatoltak."; + +/* The text for warning when an emulator is being used to run the application. */ +"An emulator is being used to run the App." = "Az alkalmazás futtatása emulátorral történik."; + +/* The text for the button that cancels the current challenge process. */ +"Cancel" = "Mégse"; + +/* Spoken by VoiceOver when the screen is loading. */ +"Loading" = "Betöltés folyamatban"; + +/* The no answer to a yes or no question. */ +"No" = "Nem"; + +/* The title for the challenge response step of an authenticated checkout. */ +"Secure checkout" = "Biztosnágos kifizetés"; + +/* Indicates that a button is selected. */ +"Selected" = "Kijelölve"; + +/* The text for warning when a device is jailbroken */ +"The device is jailbroken." = "Az eszközt feltörték."; + +/* The text for warning when the integrity of the SDK has been tampered with */ +"The integrity of the SDK has been tampered." = "Az SDK integritása sérült."; + +/* The text for warning when the SDK is running on an unsupported OS or OS version. */ +"The OS or the OS Version is not supported." = "Az OS vagy OS-verzió nem támogatott."; + +/* Error description for when a network request times out. English value is as required by UL certification. */ +"Timeout" = "időtúllépés"; + +/* Indicates that a button is not selected. */ +"Unselected" = "Nincs kijelölve"; + +/* The yes answer to a yes or no question. */ +"Yes" = "Igen"; + diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/Resources/id.lproj/Localizable.strings b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/Resources/id.lproj/Localizable.strings new file mode 100644 index 0000000..7e16882 --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/Resources/id.lproj/Localizable.strings @@ -0,0 +1,45 @@ +/* The text for warning when a debugger is currently attached to the process. */ +"A debugger is attached to the App." = "A debugger is attached to the App."; + +/* The text for warning when an emulator is being used to run the application. */ +"An emulator is being used to run the App." = "An emulator is being used to run the App."; + +/* The text for the button that cancels the current challenge process. */ +"Cancel" = "Cancel"; + +/* Accessibility label for expandandable text control to indicate text is hidden. */ +"Collapsed" = "Collapsed"; + +/* Accessibility label for expandandable text control to indicate that the UI has been expanded and additional text is available. */ +"Expanded" = "Expanded"; + +/* Spoken by VoiceOver when the challenge is loading. */ +"Loading" = "Loading"; + +/* The no answer to a yes or no question. */ +"No" = "No"; + +/* The title for the challenge response step of an authenticated checkout. */ +"Secure checkout" = "Secure checkout"; + +/* Indicates that a button is selected. */ +"Selected" = "Selected"; + +/* The text for warning when a device is jailbroken */ +"The device is jailbroken." = "The device is jailbroken."; + +/* The text for warning when the integrity of the SDK has been tampered with */ +"The integrity of the SDK has been tampered." = "The integrity of the SDK has been tampered."; + +/* The text for warning when the SDK is running on an unsupported OS or OS version. */ +"The OS or the OS Version is not supported." = "The OS or the OS Version is not supported."; + +/* Error description for when a network request times out. English value is as required by UL certification. */ +"Timeout" = "Timeout"; + +/* Indicates that a button is not selected. */ +"Unselected" = "Unselected"; + +/* The yes answer to a yes or no question. */ +"Yes" = "Yes"; + diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/Resources/it.lproj/Localizable.strings b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/Resources/it.lproj/Localizable.strings new file mode 100644 index 0000000..419bf6b --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/Resources/it.lproj/Localizable.strings @@ -0,0 +1,39 @@ +/* The text for warning when a debugger is currently attached to the process. */ +"A debugger is attached to the App." = "All'app è connesso un debugger."; + +/* The text for warning when an emulator is being used to run the application. */ +"An emulator is being used to run the App." = "Per eseguire l'app viene utilizzato un emulatore."; + +/* The text for the button that cancels the current challenge process. */ +"Cancel" = "Annulla"; + +/* Spoken by VoiceOver when the screen is loading. */ +"Loading" = "Caricamento in corso"; + +/* The no answer to a yes or no question. */ +"No" = "No"; + +/* The title for the challenge response step of an authenticated checkout. */ +"Secure checkout" = "Completamento del pagamento sicuro"; + +/* Indicates that a button is selected. */ +"Selected" = "Selezionato"; + +/* The text for warning when a device is jailbroken */ +"The device is jailbroken." = "Il dispositivo è jailbroken."; + +/* The text for warning when the integrity of the SDK has been tampered with */ +"The integrity of the SDK has been tampered." = "L'integrità dell'SDK è stata manomessa."; + +/* The text for warning when the SDK is running on an unsupported OS or OS version. */ +"The OS or the OS Version is not supported." = "Il sistema operativo o la versione del sistema operativo non sono supportati."; + +/* Error description for when a network request times out. English value is as required by UL certification. */ +"Timeout" = "Timeout"; + +/* Indicates that a button is not selected. */ +"Unselected" = "Non selezionato"; + +/* The yes answer to a yes or no question. */ +"Yes" = "Sì"; + diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/Resources/ja.lproj/Localizable.strings b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/Resources/ja.lproj/Localizable.strings new file mode 100644 index 0000000..9cec442 --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/Resources/ja.lproj/Localizable.strings @@ -0,0 +1,39 @@ +/* The text for warning when a debugger is currently attached to the process. */ +"A debugger is attached to the App." = "アプリにデバッガが添付されています。"; + +/* The text for warning when an emulator is being used to run the application. */ +"An emulator is being used to run the App." = "アプリの実行にエミュレータが使用されています。"; + +/* The text for the button that cancels the current challenge process. */ +"Cancel" = "キャンセル"; + +/* Spoken by VoiceOver when the screen is loading. */ +"Loading" = "読み込み中"; + +/* The no answer to a yes or no question. */ +"No" = "いいえ"; + +/* The title for the challenge response step of an authenticated checkout. */ +"Secure checkout" = "セキュアなチェックアウト"; + +/* Indicates that a button is selected. */ +"Selected" = "選択済み"; + +/* The text for warning when a device is jailbroken */ +"The device is jailbroken." = "このデバイスは脱獄状態です。"; + +/* The text for warning when the integrity of the SDK has been tampered with */ +"The integrity of the SDK has been tampered." = "SDK の完全性が改ざんされています。"; + +/* The text for warning when the SDK is running on an unsupported OS or OS version. */ +"The OS or the OS Version is not supported." = "OS または OS のバージョンがサポートされていません。"; + +/* Error description for when a network request times out. English value is as required by UL certification. */ +"Timeout" = "タイムアウト"; + +/* Indicates that a button is not selected. */ +"Unselected" = "選択解除済み"; + +/* The yes answer to a yes or no question. */ +"Yes" = "はい"; + diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/Resources/ko.lproj/Localizable.strings b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/Resources/ko.lproj/Localizable.strings new file mode 100644 index 0000000..4ae98c3 --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/Resources/ko.lproj/Localizable.strings @@ -0,0 +1,39 @@ +/* The text for warning when a debugger is currently attached to the process. */ +"A debugger is attached to the App." = "디버거가 앱에 연결되었습니다."; + +/* The text for warning when an emulator is being used to run the application. */ +"An emulator is being used to run the App." = "앱을 실행하는 데 에뮬레이터가 사용되고 있습니다."; + +/* The text for the button that cancels the current challenge process. */ +"Cancel" = "취소"; + +/* Spoken by VoiceOver when the screen is loading. */ +"Loading" = "로드 중"; + +/* The no answer to a yes or no question. */ +"No" = "아니요"; + +/* The title for the challenge response step of an authenticated checkout. */ +"Secure checkout" = "보안 체크 아웃"; + +/* Indicates that a button is selected. */ +"Selected" = "선택됨"; + +/* The text for warning when a device is jailbroken */ +"The device is jailbroken." = "장치가 무단 해제되었습니다."; + +/* The text for warning when the integrity of the SDK has been tampered with */ +"The integrity of the SDK has been tampered." = "SDK의 무결성이 변경되었습니다."; + +/* The text for warning when the SDK is running on an unsupported OS or OS version. */ +"The OS or the OS Version is not supported." = " OS 또는 OS 버전이 지원되지 않습니다."; + +/* Error description for when a network request times out. English value is as required by UL certification. */ +"Timeout" = "시간 초과"; + +/* Indicates that a button is not selected. */ +"Unselected" = "선택 해제됨"; + +/* The yes answer to a yes or no question. */ +"Yes" = "예"; + diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/Resources/lt-LT.lproj/Localizable.strings b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/Resources/lt-LT.lproj/Localizable.strings new file mode 100644 index 0000000..7e16882 --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/Resources/lt-LT.lproj/Localizable.strings @@ -0,0 +1,45 @@ +/* The text for warning when a debugger is currently attached to the process. */ +"A debugger is attached to the App." = "A debugger is attached to the App."; + +/* The text for warning when an emulator is being used to run the application. */ +"An emulator is being used to run the App." = "An emulator is being used to run the App."; + +/* The text for the button that cancels the current challenge process. */ +"Cancel" = "Cancel"; + +/* Accessibility label for expandandable text control to indicate text is hidden. */ +"Collapsed" = "Collapsed"; + +/* Accessibility label for expandandable text control to indicate that the UI has been expanded and additional text is available. */ +"Expanded" = "Expanded"; + +/* Spoken by VoiceOver when the challenge is loading. */ +"Loading" = "Loading"; + +/* The no answer to a yes or no question. */ +"No" = "No"; + +/* The title for the challenge response step of an authenticated checkout. */ +"Secure checkout" = "Secure checkout"; + +/* Indicates that a button is selected. */ +"Selected" = "Selected"; + +/* The text for warning when a device is jailbroken */ +"The device is jailbroken." = "The device is jailbroken."; + +/* The text for warning when the integrity of the SDK has been tampered with */ +"The integrity of the SDK has been tampered." = "The integrity of the SDK has been tampered."; + +/* The text for warning when the SDK is running on an unsupported OS or OS version. */ +"The OS or the OS Version is not supported." = "The OS or the OS Version is not supported."; + +/* Error description for when a network request times out. English value is as required by UL certification. */ +"Timeout" = "Timeout"; + +/* Indicates that a button is not selected. */ +"Unselected" = "Unselected"; + +/* The yes answer to a yes or no question. */ +"Yes" = "Yes"; + diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/Resources/lv-LV.lproj/Localizable.strings b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/Resources/lv-LV.lproj/Localizable.strings new file mode 100644 index 0000000..7e16882 --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/Resources/lv-LV.lproj/Localizable.strings @@ -0,0 +1,45 @@ +/* The text for warning when a debugger is currently attached to the process. */ +"A debugger is attached to the App." = "A debugger is attached to the App."; + +/* The text for warning when an emulator is being used to run the application. */ +"An emulator is being used to run the App." = "An emulator is being used to run the App."; + +/* The text for the button that cancels the current challenge process. */ +"Cancel" = "Cancel"; + +/* Accessibility label for expandandable text control to indicate text is hidden. */ +"Collapsed" = "Collapsed"; + +/* Accessibility label for expandandable text control to indicate that the UI has been expanded and additional text is available. */ +"Expanded" = "Expanded"; + +/* Spoken by VoiceOver when the challenge is loading. */ +"Loading" = "Loading"; + +/* The no answer to a yes or no question. */ +"No" = "No"; + +/* The title for the challenge response step of an authenticated checkout. */ +"Secure checkout" = "Secure checkout"; + +/* Indicates that a button is selected. */ +"Selected" = "Selected"; + +/* The text for warning when a device is jailbroken */ +"The device is jailbroken." = "The device is jailbroken."; + +/* The text for warning when the integrity of the SDK has been tampered with */ +"The integrity of the SDK has been tampered." = "The integrity of the SDK has been tampered."; + +/* The text for warning when the SDK is running on an unsupported OS or OS version. */ +"The OS or the OS Version is not supported." = "The OS or the OS Version is not supported."; + +/* Error description for when a network request times out. English value is as required by UL certification. */ +"Timeout" = "Timeout"; + +/* Indicates that a button is not selected. */ +"Unselected" = "Unselected"; + +/* The yes answer to a yes or no question. */ +"Yes" = "Yes"; + diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/Resources/ms-MY.lproj/Localizable.strings b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/Resources/ms-MY.lproj/Localizable.strings new file mode 100644 index 0000000..7e16882 --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/Resources/ms-MY.lproj/Localizable.strings @@ -0,0 +1,45 @@ +/* The text for warning when a debugger is currently attached to the process. */ +"A debugger is attached to the App." = "A debugger is attached to the App."; + +/* The text for warning when an emulator is being used to run the application. */ +"An emulator is being used to run the App." = "An emulator is being used to run the App."; + +/* The text for the button that cancels the current challenge process. */ +"Cancel" = "Cancel"; + +/* Accessibility label for expandandable text control to indicate text is hidden. */ +"Collapsed" = "Collapsed"; + +/* Accessibility label for expandandable text control to indicate that the UI has been expanded and additional text is available. */ +"Expanded" = "Expanded"; + +/* Spoken by VoiceOver when the challenge is loading. */ +"Loading" = "Loading"; + +/* The no answer to a yes or no question. */ +"No" = "No"; + +/* The title for the challenge response step of an authenticated checkout. */ +"Secure checkout" = "Secure checkout"; + +/* Indicates that a button is selected. */ +"Selected" = "Selected"; + +/* The text for warning when a device is jailbroken */ +"The device is jailbroken." = "The device is jailbroken."; + +/* The text for warning when the integrity of the SDK has been tampered with */ +"The integrity of the SDK has been tampered." = "The integrity of the SDK has been tampered."; + +/* The text for warning when the SDK is running on an unsupported OS or OS version. */ +"The OS or the OS Version is not supported." = "The OS or the OS Version is not supported."; + +/* Error description for when a network request times out. English value is as required by UL certification. */ +"Timeout" = "Timeout"; + +/* Indicates that a button is not selected. */ +"Unselected" = "Unselected"; + +/* The yes answer to a yes or no question. */ +"Yes" = "Yes"; + diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/Resources/mt.lproj/Localizable.strings b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/Resources/mt.lproj/Localizable.strings new file mode 100644 index 0000000..55b091c --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/Resources/mt.lproj/Localizable.strings @@ -0,0 +1,39 @@ +/* The text for warning when a debugger is currently attached to the process. */ +"A debugger is attached to the App." = "Debugger huwa mqabbad mal-Applikazzjoni."; + +/* The text for warning when an emulator is being used to run the application. */ +"An emulator is being used to run the App." = "Qed jintuża emulatur biex iħaddem l-Applikazzjoni."; + +/* The text for the button that cancels the current challenge process. */ +"Cancel" = "Ikkanċella"; + +/* Spoken by VoiceOver when the screen is loading. */ +"Loading" = "Qed jillowdja"; + +/* The no answer to a yes or no question. */ +"No" = "Le"; + +/* The title for the challenge response step of an authenticated checkout. */ +"Secure checkout" = "Checkout sigur"; + +/* Indicates that a button is selected. */ +"Selected" = "Attivata"; + +/* The text for warning when a device is jailbroken */ +"The device is jailbroken." = "L-apparat huwa mmodifikat (jailbroken)."; + +/* The text for warning when the integrity of the SDK has been tampered with */ +"The integrity of the SDK has been tampered." = "L-integrità tal-SDK ġiet imbagħbsa."; + +/* The text for warning when the SDK is running on an unsupported OS or OS version. */ +"The OS or the OS Version is not supported." = "Is-Sistema Operattiva (OS) jew il-Verżjoni tas-Sistema Operattiva (OS) mhijiex appoġġjata."; + +/* Error description for when a network request times out. English value is as required by UL certification. */ +"Timeout" = "Waqfa qasira"; + +/* Indicates that a button is not selected. */ +"Unselected" = "Mhijiex attivata"; + +/* The yes answer to a yes or no question. */ +"Yes" = "Iva"; + diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/Resources/nb.lproj/Localizable.strings b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/Resources/nb.lproj/Localizable.strings new file mode 100644 index 0000000..78613b3 --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/Resources/nb.lproj/Localizable.strings @@ -0,0 +1,39 @@ +/* The text for warning when a debugger is currently attached to the process. */ +"A debugger is attached to the App." = "En debugger er knyttet til App."; + +/* The text for warning when an emulator is being used to run the application. */ +"An emulator is being used to run the App." = "En emulator brukes til å kjøre App."; + +/* The text for the button that cancels the current challenge process. */ +"Cancel" = "Avbryt"; + +/* Spoken by VoiceOver when the screen is loading. */ +"Loading" = "Laster"; + +/* The no answer to a yes or no question. */ +"No" = "Nei"; + +/* The title for the challenge response step of an authenticated checkout. */ +"Secure checkout" = "Sikker utsjekk"; + +/* Indicates that a button is selected. */ +"Selected" = "Valgt"; + +/* The text for warning when a device is jailbroken */ +"The device is jailbroken." = "Enheten er jailbroken."; + +/* The text for warning when the integrity of the SDK has been tampered with */ +"The integrity of the SDK has been tampered." = "Integriteten til SDK har blitt manipulert."; + +/* The text for warning when the SDK is running on an unsupported OS or OS version. */ +"The OS or the OS Version is not supported." = "OS- eller OS-versjonen støttes ikke."; + +/* Error description for when a network request times out. English value is as required by UL certification. */ +"Timeout" = "Avbrudd"; + +/* Indicates that a button is not selected. */ +"Unselected" = "Ikke valgt"; + +/* The yes answer to a yes or no question. */ +"Yes" = "Ja"; + diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/Resources/nl.lproj/Localizable.strings b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/Resources/nl.lproj/Localizable.strings new file mode 100644 index 0000000..335a340 --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/Resources/nl.lproj/Localizable.strings @@ -0,0 +1,39 @@ +/* The text for warning when a debugger is currently attached to the process. */ +"A debugger is attached to the App." = "Er is een foutopsporingsprogramma gekoppeld aan de app."; + +/* The text for warning when an emulator is being used to run the application. */ +"An emulator is being used to run the App." = "Er wordt een emulator gebruikt om de app uit te voeren."; + +/* The text for the button that cancels the current challenge process. */ +"Cancel" = "Annuleren"; + +/* Spoken by VoiceOver when the screen is loading. */ +"Loading" = "Bezig met laden"; + +/* The no answer to a yes or no question. */ +"No" = "Nee"; + +/* The title for the challenge response step of an authenticated checkout. */ +"Secure checkout" = "Beveiligde Checkout"; + +/* Indicates that a button is selected. */ +"Selected" = "Geselecteerd"; + +/* The text for warning when a device is jailbroken */ +"The device is jailbroken." = "Het apparaat is opengebroken via een jailbreak."; + +/* The text for warning when the integrity of the SDK has been tampered with */ +"The integrity of the SDK has been tampered." = "De integriteit van de SDK is niet meer intact."; + +/* The text for warning when the SDK is running on an unsupported OS or OS version. */ +"The OS or the OS Version is not supported." = "Het besturingssysteem of de versie wordt niet ondersteund."; + +/* Error description for when a network request times out. English value is as required by UL certification. */ +"Timeout" = "Time-out"; + +/* Indicates that a button is not selected. */ +"Unselected" = "Niet geselecteerd"; + +/* The yes answer to a yes or no question. */ +"Yes" = "Ja"; + diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/Resources/nn-NO.lproj/Localizable.strings b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/Resources/nn-NO.lproj/Localizable.strings new file mode 100644 index 0000000..6544369 --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/Resources/nn-NO.lproj/Localizable.strings @@ -0,0 +1,39 @@ +/* The text for warning when a debugger is currently attached to the process. */ +"A debugger is attached to the App." = "Ein avlusar er knytta til appen."; + +/* The text for warning when an emulator is being used to run the application. */ +"An emulator is being used to run the App." = "Ein emulator blir nytta til å køyre appen."; + +/* The text for the button that cancels the current challenge process. */ +"Cancel" = "Avbryt"; + +/* Spoken by VoiceOver when the screen is loading. */ +"Loading" = "Lastar inn"; + +/* The no answer to a yes or no question. */ +"No" = "Nei"; + +/* The title for the challenge response step of an authenticated checkout. */ +"Secure checkout" = "Trygg utsjekk"; + +/* Indicates that a button is selected. */ +"Selected" = "Vald"; + +/* The text for warning when a device is jailbroken */ +"The device is jailbroken." = "Eininga er jailbroken."; + +/* The text for warning when the integrity of the SDK has been tampered with */ +"The integrity of the SDK has been tampered." = "Integriteten til SDK er manipulert."; + +/* The text for warning when the SDK is running on an unsupported OS or OS version. */ +"The OS or the OS Version is not supported." = "OS- eller OS-versjonen blir ikkje stydd."; + +/* Error description for when a network request times out. English value is as required by UL certification. */ +"Timeout" = "Tidsavbrot"; + +/* Indicates that a button is not selected. */ +"Unselected" = "Uvald"; + +/* The yes answer to a yes or no question. */ +"Yes" = "Ja"; + diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/Resources/pl-PL.lproj/Localizable.strings b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/Resources/pl-PL.lproj/Localizable.strings new file mode 100644 index 0000000..7e16882 --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/Resources/pl-PL.lproj/Localizable.strings @@ -0,0 +1,45 @@ +/* The text for warning when a debugger is currently attached to the process. */ +"A debugger is attached to the App." = "A debugger is attached to the App."; + +/* The text for warning when an emulator is being used to run the application. */ +"An emulator is being used to run the App." = "An emulator is being used to run the App."; + +/* The text for the button that cancels the current challenge process. */ +"Cancel" = "Cancel"; + +/* Accessibility label for expandandable text control to indicate text is hidden. */ +"Collapsed" = "Collapsed"; + +/* Accessibility label for expandandable text control to indicate that the UI has been expanded and additional text is available. */ +"Expanded" = "Expanded"; + +/* Spoken by VoiceOver when the challenge is loading. */ +"Loading" = "Loading"; + +/* The no answer to a yes or no question. */ +"No" = "No"; + +/* The title for the challenge response step of an authenticated checkout. */ +"Secure checkout" = "Secure checkout"; + +/* Indicates that a button is selected. */ +"Selected" = "Selected"; + +/* The text for warning when a device is jailbroken */ +"The device is jailbroken." = "The device is jailbroken."; + +/* The text for warning when the integrity of the SDK has been tampered with */ +"The integrity of the SDK has been tampered." = "The integrity of the SDK has been tampered."; + +/* The text for warning when the SDK is running on an unsupported OS or OS version. */ +"The OS or the OS Version is not supported." = "The OS or the OS Version is not supported."; + +/* Error description for when a network request times out. English value is as required by UL certification. */ +"Timeout" = "Timeout"; + +/* Indicates that a button is not selected. */ +"Unselected" = "Unselected"; + +/* The yes answer to a yes or no question. */ +"Yes" = "Yes"; + diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/Resources/pt-BR.lproj/Localizable.strings b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/Resources/pt-BR.lproj/Localizable.strings new file mode 100644 index 0000000..2e3e7b5 --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/Resources/pt-BR.lproj/Localizable.strings @@ -0,0 +1,39 @@ +/* The text for warning when a debugger is currently attached to the process. */ +"A debugger is attached to the App." = "Um depurador está anexado ao aplicativo."; + +/* The text for warning when an emulator is being used to run the application. */ +"An emulator is being used to run the App." = "Está sendo usado um emulador para executar o aplicativo."; + +/* The text for the button that cancels the current challenge process. */ +"Cancel" = "Cancelar"; + +/* Spoken by VoiceOver when the screen is loading. */ +"Loading" = "Carregando"; + +/* The no answer to a yes or no question. */ +"No" = "Não"; + +/* The title for the challenge response step of an authenticated checkout. */ +"Secure checkout" = "Finalização de compra segura"; + +/* Indicates that a button is selected. */ +"Selected" = "Selecionado"; + +/* The text for warning when a device is jailbroken */ +"The device is jailbroken." = "O dispositivo está desbloqueado."; + +/* The text for warning when the integrity of the SDK has been tampered with */ +"The integrity of the SDK has been tampered." = "A integridade do SDK foi adulterada."; + +/* The text for warning when the SDK is running on an unsupported OS or OS version. */ +"The OS or the OS Version is not supported." = "O SO ou a versão do SO não é compatível."; + +/* Error description for when a network request times out. English value is as required by UL certification. */ +"Timeout" = "Tempo esgotado"; + +/* Indicates that a button is not selected. */ +"Unselected" = "Não selecionado"; + +/* The yes answer to a yes or no question. */ +"Yes" = "Sim"; + diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/Resources/pt-PT.lproj/Localizable.strings b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/Resources/pt-PT.lproj/Localizable.strings new file mode 100644 index 0000000..3be97a5 --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/Resources/pt-PT.lproj/Localizable.strings @@ -0,0 +1,39 @@ +/* The text for warning when a debugger is currently attached to the process. */ +"A debugger is attached to the App." = "Um depurador está anexado à aplicação."; + +/* The text for warning when an emulator is being used to run the application. */ +"An emulator is being used to run the App." = "Um emulador está a ser utilizado para executar a aplicação."; + +/* The text for the button that cancels the current challenge process. */ +"Cancel" = "Cancelar"; + +/* Spoken by VoiceOver when the screen is loading. */ +"Loading" = "A carregar"; + +/* The no answer to a yes or no question. */ +"No" = "Não"; + +/* The title for the challenge response step of an authenticated checkout. */ +"Secure checkout" = "Finalização de compra segura"; + +/* Indicates that a button is selected. */ +"Selected" = "Selecionado"; + +/* The text for warning when a device is jailbroken */ +"The device is jailbroken." = "O dispositivo está desbloqueado."; + +/* The text for warning when the integrity of the SDK has been tampered with */ +"The integrity of the SDK has been tampered." = "A integridade do SDK foi adulterada."; + +/* The text for warning when the SDK is running on an unsupported OS or OS version. */ +"The OS or the OS Version is not supported." = "Sistema operativo ou versão do sistema operativo não suportado(a)."; + +/* Error description for when a network request times out. English value is as required by UL certification. */ +"Timeout" = "Tempo limite"; + +/* Indicates that a button is not selected. */ +"Unselected" = "Não selecionado"; + +/* The yes answer to a yes or no question. */ +"Yes" = "Sim"; + diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/Resources/ro-RO.lproj/Localizable.strings b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/Resources/ro-RO.lproj/Localizable.strings new file mode 100644 index 0000000..7e16882 --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/Resources/ro-RO.lproj/Localizable.strings @@ -0,0 +1,45 @@ +/* The text for warning when a debugger is currently attached to the process. */ +"A debugger is attached to the App." = "A debugger is attached to the App."; + +/* The text for warning when an emulator is being used to run the application. */ +"An emulator is being used to run the App." = "An emulator is being used to run the App."; + +/* The text for the button that cancels the current challenge process. */ +"Cancel" = "Cancel"; + +/* Accessibility label for expandandable text control to indicate text is hidden. */ +"Collapsed" = "Collapsed"; + +/* Accessibility label for expandandable text control to indicate that the UI has been expanded and additional text is available. */ +"Expanded" = "Expanded"; + +/* Spoken by VoiceOver when the challenge is loading. */ +"Loading" = "Loading"; + +/* The no answer to a yes or no question. */ +"No" = "No"; + +/* The title for the challenge response step of an authenticated checkout. */ +"Secure checkout" = "Secure checkout"; + +/* Indicates that a button is selected. */ +"Selected" = "Selected"; + +/* The text for warning when a device is jailbroken */ +"The device is jailbroken." = "The device is jailbroken."; + +/* The text for warning when the integrity of the SDK has been tampered with */ +"The integrity of the SDK has been tampered." = "The integrity of the SDK has been tampered."; + +/* The text for warning when the SDK is running on an unsupported OS or OS version. */ +"The OS or the OS Version is not supported." = "The OS or the OS Version is not supported."; + +/* Error description for when a network request times out. English value is as required by UL certification. */ +"Timeout" = "Timeout"; + +/* Indicates that a button is not selected. */ +"Unselected" = "Unselected"; + +/* The yes answer to a yes or no question. */ +"Yes" = "Yes"; + diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/Resources/ru.lproj/Localizable.strings b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/Resources/ru.lproj/Localizable.strings new file mode 100644 index 0000000..2c7cd69 --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/Resources/ru.lproj/Localizable.strings @@ -0,0 +1,39 @@ +/* The text for warning when a debugger is currently attached to the process. */ +"A debugger is attached to the App." = "К приложению подключен отладчик."; + +/* The text for warning when an emulator is being used to run the application. */ +"An emulator is being used to run the App." = "Приложение запускается и работает в симуляторе."; + +/* The text for the button that cancels the current challenge process. */ +"Cancel" = "Отмена"; + +/* Spoken by VoiceOver when the screen is loading. */ +"Loading" = "Идет загрузка"; + +/* The no answer to a yes or no question. */ +"No" = "Нет"; + +/* The title for the challenge response step of an authenticated checkout. */ +"Secure checkout" = "Безопасное оформление и оплата заказа"; + +/* Indicates that a button is selected. */ +"Selected" = "Выбранные"; + +/* The text for warning when a device is jailbroken */ +"The device is jailbroken." = "Устройство разблокировано."; + +/* The text for warning when the integrity of the SDK has been tampered with */ +"The integrity of the SDK has been tampered." = "Целостность пакета средств разработки программного обеспечения нарушена."; + +/* The text for warning when the SDK is running on an unsupported OS or OS version. */ +"The OS or the OS Version is not supported." = "Данная операционная система или данная версия операционной системы не поддерживается."; + +/* Error description for when a network request times out. English value is as required by UL certification. */ +"Timeout" = "Истечение лимита времени"; + +/* Indicates that a button is not selected. */ +"Unselected" = "Не выбранные"; + +/* The yes answer to a yes or no question. */ +"Yes" = "Да"; + diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/Resources/sk-SK.lproj/Localizable.strings b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/Resources/sk-SK.lproj/Localizable.strings new file mode 100644 index 0000000..7e16882 --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/Resources/sk-SK.lproj/Localizable.strings @@ -0,0 +1,45 @@ +/* The text for warning when a debugger is currently attached to the process. */ +"A debugger is attached to the App." = "A debugger is attached to the App."; + +/* The text for warning when an emulator is being used to run the application. */ +"An emulator is being used to run the App." = "An emulator is being used to run the App."; + +/* The text for the button that cancels the current challenge process. */ +"Cancel" = "Cancel"; + +/* Accessibility label for expandandable text control to indicate text is hidden. */ +"Collapsed" = "Collapsed"; + +/* Accessibility label for expandandable text control to indicate that the UI has been expanded and additional text is available. */ +"Expanded" = "Expanded"; + +/* Spoken by VoiceOver when the challenge is loading. */ +"Loading" = "Loading"; + +/* The no answer to a yes or no question. */ +"No" = "No"; + +/* The title for the challenge response step of an authenticated checkout. */ +"Secure checkout" = "Secure checkout"; + +/* Indicates that a button is selected. */ +"Selected" = "Selected"; + +/* The text for warning when a device is jailbroken */ +"The device is jailbroken." = "The device is jailbroken."; + +/* The text for warning when the integrity of the SDK has been tampered with */ +"The integrity of the SDK has been tampered." = "The integrity of the SDK has been tampered."; + +/* The text for warning when the SDK is running on an unsupported OS or OS version. */ +"The OS or the OS Version is not supported." = "The OS or the OS Version is not supported."; + +/* Error description for when a network request times out. English value is as required by UL certification. */ +"Timeout" = "Timeout"; + +/* Indicates that a button is not selected. */ +"Unselected" = "Unselected"; + +/* The yes answer to a yes or no question. */ +"Yes" = "Yes"; + diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/Resources/sl-SI.lproj/Localizable.strings b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/Resources/sl-SI.lproj/Localizable.strings new file mode 100644 index 0000000..7e16882 --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/Resources/sl-SI.lproj/Localizable.strings @@ -0,0 +1,45 @@ +/* The text for warning when a debugger is currently attached to the process. */ +"A debugger is attached to the App." = "A debugger is attached to the App."; + +/* The text for warning when an emulator is being used to run the application. */ +"An emulator is being used to run the App." = "An emulator is being used to run the App."; + +/* The text for the button that cancels the current challenge process. */ +"Cancel" = "Cancel"; + +/* Accessibility label for expandandable text control to indicate text is hidden. */ +"Collapsed" = "Collapsed"; + +/* Accessibility label for expandandable text control to indicate that the UI has been expanded and additional text is available. */ +"Expanded" = "Expanded"; + +/* Spoken by VoiceOver when the challenge is loading. */ +"Loading" = "Loading"; + +/* The no answer to a yes or no question. */ +"No" = "No"; + +/* The title for the challenge response step of an authenticated checkout. */ +"Secure checkout" = "Secure checkout"; + +/* Indicates that a button is selected. */ +"Selected" = "Selected"; + +/* The text for warning when a device is jailbroken */ +"The device is jailbroken." = "The device is jailbroken."; + +/* The text for warning when the integrity of the SDK has been tampered with */ +"The integrity of the SDK has been tampered." = "The integrity of the SDK has been tampered."; + +/* The text for warning when the SDK is running on an unsupported OS or OS version. */ +"The OS or the OS Version is not supported." = "The OS or the OS Version is not supported."; + +/* Error description for when a network request times out. English value is as required by UL certification. */ +"Timeout" = "Timeout"; + +/* Indicates that a button is not selected. */ +"Unselected" = "Unselected"; + +/* The yes answer to a yes or no question. */ +"Yes" = "Yes"; + diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/Resources/sv.lproj/Localizable.strings b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/Resources/sv.lproj/Localizable.strings new file mode 100644 index 0000000..e92a466 --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/Resources/sv.lproj/Localizable.strings @@ -0,0 +1,39 @@ +/* The text for warning when a debugger is currently attached to the process. */ +"A debugger is attached to the App." = "En felsökare är ansluten till appen."; + +/* The text for warning when an emulator is being used to run the application. */ +"An emulator is being used to run the App." = "En emulator används för att köra appen."; + +/* The text for the button that cancels the current challenge process. */ +"Cancel" = "Avbryt"; + +/* Spoken by VoiceOver when the screen is loading. */ +"Loading" = "Laddar"; + +/* The no answer to a yes or no question. */ +"No" = "Nej"; + +/* The title for the challenge response step of an authenticated checkout. */ +"Secure checkout" = "Säker utcheckning"; + +/* Indicates that a button is selected. */ +"Selected" = "Markerad"; + +/* The text for warning when a device is jailbroken */ +"The device is jailbroken." = "Enheten är jailbreakad."; + +/* The text for warning when the integrity of the SDK has been tampered with */ +"The integrity of the SDK has been tampered." = "SDK:ns integritet har manipulerats."; + +/* The text for warning when the SDK is running on an unsupported OS or OS version. */ +"The OS or the OS Version is not supported." = "OS eller OS-versionen stöds inte."; + +/* Error description for when a network request times out. English value is as required by UL certification. */ +"Timeout" = "Avbrott"; + +/* Indicates that a button is not selected. */ +"Unselected" = "Avmarkerad"; + +/* The yes answer to a yes or no question. */ +"Yes" = "Ja"; + diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/Resources/tr.lproj/Localizable.strings b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/Resources/tr.lproj/Localizable.strings new file mode 100644 index 0000000..bf9064f --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/Resources/tr.lproj/Localizable.strings @@ -0,0 +1,39 @@ +/* The text for warning when a debugger is currently attached to the process. */ +"A debugger is attached to the App." = "Uygulamaya hata ayıklayıcı eklendi."; + +/* The text for warning when an emulator is being used to run the application. */ +"An emulator is being used to run the App." = "Uygulamayı çalıştırmak için bir emülatör kullanılıyor."; + +/* The text for the button that cancels the current challenge process. */ +"Cancel" = "İptal"; + +/* Spoken by VoiceOver when the screen is loading. */ +"Loading" = "Yüklüyor"; + +/* The no answer to a yes or no question. */ +"No" = "Hayır"; + +/* The title for the challenge response step of an authenticated checkout. */ +"Secure checkout" = "Güvenli ödeme"; + +/* Indicates that a button is selected. */ +"Selected" = "Seçildi"; + +/* The text for warning when a device is jailbroken */ +"The device is jailbroken." = "Cihazın üretici yazılım kilidi kaldırılmış."; + +/* The text for warning when the integrity of the SDK has been tampered with */ +"The integrity of the SDK has been tampered." = "SDK bütünlüğü ihlal edilmiş."; + +/* The text for warning when the SDK is running on an unsupported OS or OS version. */ +"The OS or the OS Version is not supported." = "İS veya İS Sürümü desteklenmiyor."; + +/* Error description for when a network request times out. English value is as required by UL certification. */ +"Timeout" = "Zaman aşımı"; + +/* Indicates that a button is not selected. */ +"Unselected" = "Seçimi kaldırıldı"; + +/* The yes answer to a yes or no question. */ +"Yes" = "Evet"; + diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/Resources/vi.lproj/Localizable.strings b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/Resources/vi.lproj/Localizable.strings new file mode 100644 index 0000000..7e16882 --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/Resources/vi.lproj/Localizable.strings @@ -0,0 +1,45 @@ +/* The text for warning when a debugger is currently attached to the process. */ +"A debugger is attached to the App." = "A debugger is attached to the App."; + +/* The text for warning when an emulator is being used to run the application. */ +"An emulator is being used to run the App." = "An emulator is being used to run the App."; + +/* The text for the button that cancels the current challenge process. */ +"Cancel" = "Cancel"; + +/* Accessibility label for expandandable text control to indicate text is hidden. */ +"Collapsed" = "Collapsed"; + +/* Accessibility label for expandandable text control to indicate that the UI has been expanded and additional text is available. */ +"Expanded" = "Expanded"; + +/* Spoken by VoiceOver when the challenge is loading. */ +"Loading" = "Loading"; + +/* The no answer to a yes or no question. */ +"No" = "No"; + +/* The title for the challenge response step of an authenticated checkout. */ +"Secure checkout" = "Secure checkout"; + +/* Indicates that a button is selected. */ +"Selected" = "Selected"; + +/* The text for warning when a device is jailbroken */ +"The device is jailbroken." = "The device is jailbroken."; + +/* The text for warning when the integrity of the SDK has been tampered with */ +"The integrity of the SDK has been tampered." = "The integrity of the SDK has been tampered."; + +/* The text for warning when the SDK is running on an unsupported OS or OS version. */ +"The OS or the OS Version is not supported." = "The OS or the OS Version is not supported."; + +/* Error description for when a network request times out. English value is as required by UL certification. */ +"Timeout" = "Timeout"; + +/* Indicates that a button is not selected. */ +"Unselected" = "Unselected"; + +/* The yes answer to a yes or no question. */ +"Yes" = "Yes"; + diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/Resources/zh-HK.lproj/Localizable.strings b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/Resources/zh-HK.lproj/Localizable.strings new file mode 100644 index 0000000..1632810 --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/Resources/zh-HK.lproj/Localizable.strings @@ -0,0 +1,39 @@ +/* The text for warning when a debugger is currently attached to the process. */ +"A debugger is attached to the App." = "調試器已附在應用程式內。"; + +/* The text for warning when an emulator is being used to run the application. */ +"An emulator is being used to run the App." = "正在用模擬器執行應用程式。"; + +/* The text for the button that cancels the current challenge process. */ +"Cancel" = "取消"; + +/* Spoken by VoiceOver when the screen is loading. */ +"Loading" = "正在載入"; + +/* The no answer to a yes or no question. */ +"No" = "否"; + +/* The title for the challenge response step of an authenticated checkout. */ +"Secure checkout" = "安全結帳"; + +/* Indicates that a button is selected. */ +"Selected" = "已選"; + +/* The text for warning when a device is jailbroken */ +"The device is jailbroken." = "該設備已越獄。"; + +/* The text for warning when the integrity of the SDK has been tampered with */ +"The integrity of the SDK has been tampered." = "SDK 的完整性已受損。"; + +/* The text for warning when the SDK is running on an unsupported OS or OS version. */ +"The OS or the OS Version is not supported." = "不支援此 OS 或 OS 版本。"; + +/* Error description for when a network request times out. English value is as required by UL certification. */ +"Timeout" = "超時"; + +/* Indicates that a button is not selected. */ +"Unselected" = "已去選"; + +/* The yes answer to a yes or no question. */ +"Yes" = "是"; + diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/Resources/zh-Hans.lproj/Localizable.strings b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/Resources/zh-Hans.lproj/Localizable.strings new file mode 100644 index 0000000..b7729c4 --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/Resources/zh-Hans.lproj/Localizable.strings @@ -0,0 +1,39 @@ +/* The text for warning when a debugger is currently attached to the process. */ +"A debugger is attached to the App." = "该应用附带有调试程序。"; + +/* The text for warning when an emulator is being used to run the application. */ +"An emulator is being used to run the App." = "正在使用模拟器运行此应用。"; + +/* The text for the button that cancels the current challenge process. */ +"Cancel" = "取消"; + +/* Spoken by VoiceOver when the screen is loading. */ +"Loading" = "正在加载"; + +/* The no answer to a yes or no question. */ +"No" = "否"; + +/* The title for the challenge response step of an authenticated checkout. */ +"Secure checkout" = "安全的结账流程"; + +/* Indicates that a button is selected. */ +"Selected" = "已选择"; + +/* The text for warning when a device is jailbroken */ +"The device is jailbroken." = "该设备已越狱。"; + +/* The text for warning when the integrity of the SDK has been tampered with */ +"The integrity of the SDK has been tampered." = "该 SDK 的完整性已被破坏。"; + +/* The text for warning when the SDK is running on an unsupported OS or OS version. */ +"The OS or the OS Version is not supported." = "不支持 OS 或 OS 版本。"; + +/* Error description for when a network request times out. English value is as required by UL certification. */ +"Timeout" = "超时"; + +/* Indicates that a button is not selected. */ +"Unselected" = "未选择"; + +/* The yes answer to a yes or no question. */ +"Yes" = "是"; + diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/Resources/zh-Hant.lproj/Localizable.strings b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/Resources/zh-Hant.lproj/Localizable.strings new file mode 100644 index 0000000..4ea1210 --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/Resources/zh-Hant.lproj/Localizable.strings @@ -0,0 +1,39 @@ +/* The text for warning when a debugger is currently attached to the process. */ +"A debugger is attached to the App." = "除錯工具附加在應用程式內。"; + +/* The text for warning when an emulator is being used to run the application. */ +"An emulator is being used to run the App." = "正在用模擬器執行應用程式。"; + +/* The text for the button that cancels the current challenge process. */ +"Cancel" = "取消"; + +/* Spoken by VoiceOver when the screen is loading. */ +"Loading" = "正在載入"; + +/* The no answer to a yes or no question. */ +"No" = "否"; + +/* The title for the challenge response step of an authenticated checkout. */ +"Secure checkout" = "安全結帳"; + +/* Indicates that a button is selected. */ +"Selected" = "已選"; + +/* The text for warning when a device is jailbroken */ +"The device is jailbroken." = "該裝置已越獄。"; + +/* The text for warning when the integrity of the SDK has been tampered with */ +"The integrity of the SDK has been tampered." = "SDK 的完整性已受損。"; + +/* The text for warning when the SDK is running on an unsupported OS or OS version. */ +"The OS or the OS Version is not supported." = "不支援此 OS 或 OS 版本。"; + +/* Error description for when a network request times out. English value is as required by UL certification. */ +"Timeout" = "逾時"; + +/* Indicates that a button is not selected. */ +"Unselected" = "已去選"; + +/* The yes answer to a yes or no question. */ +"Yes" = "是"; + diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSACSNetworkingManager.h b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSACSNetworkingManager.h new file mode 100644 index 0000000..cc907e8 --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSACSNetworkingManager.h @@ -0,0 +1,30 @@ +// +// STDSACSNetworkingManager.h +// Stripe3DS2 +// +// Created by Cameron Sabol on 4/3/19. +// Copyright © 2019 Stripe. All rights reserved. +// + +#import + +@class STDSChallengeRequestParameters; +@class STDSErrorMessage; +@protocol STDSChallengeResponse; + +NS_ASSUME_NONNULL_BEGIN + +@interface STDSACSNetworkingManager : NSObject + +- (instancetype)initWithURL:(NSURL *)acsURL + sdkContentEncryptionKey:(NSData *)sdkCEK + acsContentEncryptionKey:(NSData *)acsCEK + acsTransactionIdentifier:(NSString *)acsTransactionID; + +- (void)submitChallengeRequest:(STDSChallengeRequestParameters *)request withCompletion:(void (^)(id _Nullable, NSError * _Nullable))completion; + +- (void)sendErrorMessage:(STDSErrorMessage *)errorMessage; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSACSNetworkingManager.m b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSACSNetworkingManager.m new file mode 100644 index 0000000..1f5a99c --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSACSNetworkingManager.m @@ -0,0 +1,171 @@ +// +// STDSACSNetworkingManager..m +// Stripe3DS2 +// +// Created by Cameron Sabol on 4/3/19. +// Copyright © 2019 Stripe. All rights reserved. +// + +#import "STDSACSNetworkingManager.h" + +#import "STDSChallengeRequestParameters.h" +#import "STDSChallengeResponseObject.h" +#import "STDSJSONEncoder.h" +#import "STDSJSONWebEncryption.h" +#import "STDSStripe3DS2Error.h" +#import "STDSErrorMessage+Internal.h" +#import "NSError+Stripe3DS2.h" + +NS_ASSUME_NONNULL_BEGIN + +/// [Req 239] requires us to abort if the ACS does not respond with the CRes message within 10 seconds. +static const NSTimeInterval kTimeoutInterval = 10; + +@implementation STDSACSNetworkingManager { + NSURL *_acsURL; + NSData *_sdkContentEncryptionKey; + NSData *_acsContentEncryptionKey; + NSString *_acsTransactionIdentifier; + + NSURLSession *_urlSession; + NSURLSessionTask * _Nullable _currentTask; +} + +- (instancetype)initWithURL:(NSURL *)acsURL + sdkContentEncryptionKey:(NSData *)sdkCEK + acsContentEncryptionKey:(NSData *)acsCEK + acsTransactionIdentifier:(nonnull NSString *)acsTransactionID { + self = [super init]; + if (self) { + _acsURL = acsURL; + _sdkContentEncryptionKey = sdkCEK; + _acsContentEncryptionKey = acsCEK; + _acsTransactionIdentifier = [acsTransactionID copy]; + _urlSession = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration ephemeralSessionConfiguration] + delegate:nil + delegateQueue:[NSOperationQueue mainQueue]]; + } + + return self; +} + +- (void)dealloc { + [_urlSession finishTasksAndInvalidate]; +} + +- (void)submitChallengeRequest:(STDSChallengeRequestParameters *)request withCompletion:(void (^)(id _Nullable, NSError * _Nullable))completion { + + NSAssert(_currentTask == nil, @"%@ is not intended to handle multiple concurrent tasks.", NSStringFromClass([self class])); + if (_currentTask != nil) { + dispatch_async(dispatch_get_main_queue(), ^{ + completion(nil, [NSError errorWithDomain:STDSStripe3DS2ErrorDomain + code:STDSErrorCodeAssertionFailed + userInfo:@{@"assertion": [NSString stringWithFormat:@"%@ is not intended to handle multiple concurrent tasks.", NSStringFromClass([self class])]}]); + }); + return; + } + + NSDictionary *requestJSON = [STDSJSONEncoder dictionaryForObject:request]; + NSError *encryptionError = nil; + NSString *encryptedRequest = [STDSJSONWebEncryption directEncryptJSON:requestJSON + withContentEncryptionKey:_sdkContentEncryptionKey + forACSTransactionID:_acsTransactionIdentifier + error:&encryptionError]; + + if (encryptedRequest != nil) { + NSMutableURLRequest *urlRequest = [[NSMutableURLRequest alloc] initWithURL:_acsURL]; + urlRequest.HTTPMethod = @"POST"; + urlRequest.timeoutInterval = kTimeoutInterval; + [urlRequest setValue:@"application/jose;charset=UTF-8" forHTTPHeaderField:@"Content-Type"]; + __weak __typeof(self) weakSelf = self; + NSURLSessionUploadTask *requestTask = [_urlSession uploadTaskWithRequest:[urlRequest copy] fromData:[encryptedRequest dataUsingEncoding:NSUTF8StringEncoding] completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) { + + __typeof(self) strongSelf = weakSelf; + if (strongSelf == nil) { + return; + } + + strongSelf->_currentTask = nil; + + if (data != nil) { + NSError *decryptionError = nil; + NSDictionary *decrypted = [STDSJSONWebEncryption decryptData:data + withContentEncryptionKey:strongSelf->_acsContentEncryptionKey + error:&decryptionError]; + if (decrypted != nil) { + NSError *challengeResponseError = nil; + id response = [strongSelf decodeJSON:decrypted error:&challengeResponseError]; + completion(response, challengeResponseError); + } else { + completion(nil, decryptionError); + } + } else { + if (error.code == NSURLErrorTimedOut) { + // We convert timeout errors for convenience, since the SDK must treat them differently from generic network errors. + error = [NSError _stds_timedOutError]; + } + completion(nil, error); + } + + }]; + _currentTask = requestTask; + [requestTask resume]; + } else { + dispatch_async(dispatch_get_main_queue(), ^{ + completion(nil, encryptionError); + }); + } +} + +- (void)sendErrorMessage:(STDSErrorMessage *)errorMessage { + NSDictionary *requestJSON = [STDSJSONEncoder dictionaryForObject:errorMessage]; + NSMutableURLRequest *urlRequest = [[NSMutableURLRequest alloc] initWithURL:_acsURL]; + urlRequest.HTTPMethod = @"POST"; + [urlRequest setValue:@"application/JSON; charset = UTF-8" forHTTPHeaderField:@"Content-Type"]; + NSURLSessionUploadTask *requestTask = [_urlSession uploadTaskWithRequest:[urlRequest copy] + fromData:[NSJSONSerialization dataWithJSONObject:requestJSON options:0 error:nil] + completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) { + // no-op + }]; + [requestTask resume]; +} + +#pragma mark - Helpers + +/** + Returns an STDSChallengeResponseObject instance decoded from the given dict, or populates the error argument. + */ +- (nullable id)decodeJSON:(NSDictionary *)dict error:(NSError * _Nullable *)outError { + NSString *kErrorMessageType = @"Erro"; + NSString *kChallengeResponseType = @"CRes"; + NSString *messageType = dict[@"messageType"]; + NSError *error; + id decodedObject; + + if ([messageType isEqualToString:kErrorMessageType]) { + // Error message type + STDSErrorMessage *errorMessage = [STDSErrorMessage decodedObjectFromJSON:dict error:&error]; + if (errorMessage) { + error = [NSError errorWithDomain:STDSStripe3DS2ErrorDomain + code:STDSErrorCodeReceivedErrorMessage + userInfo:@{STDSStripe3DS2ErrorMessageErrorKey: errorMessage}]; + } + } else if ([messageType isEqualToString:kChallengeResponseType]) { + // CRes message type + decodedObject = [STDSChallengeResponseObject decodedObjectFromJSON:dict error:&error]; + } else { + // Unknown message type + error = [NSError errorWithDomain:STDSStripe3DS2ErrorDomain + code:STDSErrorCodeUnknownMessageType + userInfo:nil]; + } + + if (error && outError) { + *outError = error; + } + return decodedObject; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSAlreadyInitializedException.m b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSAlreadyInitializedException.m new file mode 100644 index 0000000..af16198 --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSAlreadyInitializedException.m @@ -0,0 +1,17 @@ +// +// STDSAlreadyInitializedException.m +// Stripe3DS2 +// +// Created by Cameron Sabol on 1/22/19. +// Copyright © 2019 Stripe. All rights reserved. +// + +#import "STDSAlreadyInitializedException.h" + +NS_ASSUME_NONNULL_BEGIN + +@implementation STDSAlreadyInitializedException + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSAuthenticationRequestParameters.m b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSAuthenticationRequestParameters.m new file mode 100644 index 0000000..dc6286b --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSAuthenticationRequestParameters.m @@ -0,0 +1,63 @@ +// +// STDSAuthenticationRequestParameters.m +// Stripe3DS2 +// +// Created by Yuki Tokuhiro on 3/21/19. +// Copyright © 2019 Stripe. All rights reserved. +// + +#import "STDSAuthenticationRequestParameters.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface STDSAuthenticationRequestParameters () + +@property (nonatomic, nullable, readonly) NSDictionary *sdkEphemeralPublicKeyJSON; + +@end + +@implementation STDSAuthenticationRequestParameters + +- (instancetype)initWithSDKTransactionIdentifier:(NSString *)sdkTransactionIdentifier + deviceData:(nullable NSString *)deviceData + sdkEphemeralPublicKey:(NSString *)sdkEphemeralPublicKey + sdkAppIdentifier:(NSString *)sdkAppIdentifier + sdkReferenceNumber:(NSString *)sdkReferenceNumber + messageVersion:(NSString *)messageVersion { + self = [super init]; + if (self) { + _sdkTransactionIdentifier = [sdkTransactionIdentifier copy]; + _deviceData = [deviceData copy]; + _sdkEphemeralPublicKey = [sdkEphemeralPublicKey copy]; + _sdkAppIdentifier = [sdkAppIdentifier copy]; + _sdkReferenceNumber = [sdkReferenceNumber copy]; + _messageVersion = [messageVersion copy]; + } + return self; +} + +- (nullable NSDictionary *)sdkEphemeralPublicKeyJSON { + NSData *data = [self.sdkEphemeralPublicKey dataUsingEncoding:NSUTF8StringEncoding]; + if (data == nil) { + return nil; + } + + return [NSJSONSerialization JSONObjectWithData:data options:0 error:NULL]; +} + +#pragma mark - STDSJSONEncodable + ++ (NSDictionary *)propertyNamesToJSONKeysMapping { + return @{ + NSStringFromSelector(@selector(sdkTransactionIdentifier)): @"sdkTransID", + NSStringFromSelector(@selector(deviceData)): @"sdkEncData", + NSStringFromSelector(@selector(sdkEphemeralPublicKeyJSON)): @"sdkEphemPubKey", + NSStringFromSelector(@selector(sdkAppIdentifier)): @"sdkAppID", + NSStringFromSelector(@selector(sdkReferenceNumber)): @"sdkReferenceNumber", + NSStringFromSelector(@selector(messageVersion)): @"messageVersion", + }; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSAuthenticationResponseObject.h b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSAuthenticationResponseObject.h new file mode 100644 index 0000000..78b2c49 --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSAuthenticationResponseObject.h @@ -0,0 +1,20 @@ +// +// STDSAuthenticationResponseObject.h +// Stripe3DS2 +// +// Created by Cameron Sabol on 5/20/19. +// Copyright © 2019 Stripe. All rights reserved. +// + +#import + +#import "STDSAuthenticationResponse.h" +#import "STDSJSONDecodable.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface STDSAuthenticationResponseObject : NSObject + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSAuthenticationResponseObject.m b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSAuthenticationResponseObject.m new file mode 100644 index 0000000..4a9bd17 --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSAuthenticationResponseObject.m @@ -0,0 +1,100 @@ +// +// STDSAuthenticationResponseObject.m +// Stripe3DS2 +// +// Created by Cameron Sabol on 5/20/19. +// Copyright © 2019 Stripe. All rights reserved. +// + +#import "STDSAuthenticationResponseObject.h" + +#import "NSDictionary+DecodingHelpers.h" + +NS_ASSUME_NONNULL_BEGIN + +@implementation STDSAuthenticationResponseObject + +@synthesize acsOperatorID = _acsOperatorID; +@synthesize acsReferenceNumber = _acsReferenceNumber; +@synthesize acsSignedContent = _acsSignedContent; +@synthesize acsTransactionID = _acsTransactionID; +@synthesize acsURL = _acsURL; +@synthesize cardholderInfo = _cardholderInfo; +@synthesize status = _status; +@synthesize challengeRequired = _challengeRequired; +@synthesize directoryServerReferenceNumber = _directoryServerReferenceNumber; +@synthesize directoryServerTransactionID = _directoryServerTransactionID; +@synthesize protocolVersion = _protocolVersion; +@synthesize sdkTransactionID = _sdkTransactionID; +@synthesize threeDSServerTransactionID = _threeDSServerTransactionID; +@synthesize willUseDecoupledAuthentication = _willUseDecoupledAuthentication; + ++ (nullable instancetype)decodedObjectFromJSON:(nullable NSDictionary *)json error:(NSError **)outError { + if (json == nil) { + return nil; + } + STDSAuthenticationResponseObject *response = [[self alloc] init]; + NSError *error = nil; + + response->_threeDSServerTransactionID = [[json _stds_stringForKey:@"threeDSServerTransID" required:YES error:&error] copy]; + NSString *transStatusString = [json _stds_stringForKey:@"transStatus" required:NO error:&error]; + response->_status = [self statusTypeForString:transStatusString]; + response->_challengeRequired = (response->_status == STDSACSStatusTypeChallengeRequired); + response->_willUseDecoupledAuthentication = [[json _stds_boolForKey:@"acsDecConInd" required:NO error:&error] boolValue]; + response->_acsOperatorID = [[json _stds_stringForKey:@"acsOperatorID" required:NO error:&error] copy]; + response->_acsReferenceNumber = [[json _stds_stringForKey:@"acsReferenceNumber" required:NO error:&error] copy]; + response->_acsSignedContent = [[json _stds_stringForKey:@"acsSignedContent" required:NO error:&error] copy]; + response->_acsTransactionID = [[json _stds_stringForKey:@"acsTransID" required:YES error:&error] copy]; + response->_acsURL = [json _stds_urlForKey:@"acsURL" required:NO error:&error]; + response->_cardholderInfo = [[json _stds_stringForKey:@"cardholderInfo" required:NO error:&error] copy]; + response->_directoryServerReferenceNumber = [[json _stds_stringForKey:@"dsReferenceNumber" required:NO error:&error] copy]; + response->_directoryServerTransactionID = [[json _stds_stringForKey:@"dsTransID" required:NO error:&error] copy]; + response->_protocolVersion = [[json _stds_stringForKey:@"messageVersion" required:YES error:&error] copy]; + response->_sdkTransactionID = [[json _stds_stringForKey:@"sdkTransID" required:YES error:&error] copy]; + + if (error != nil) { + if (outError != nil) { + *outError = error; + } + + return nil; + } + + return response; +} + ++ (STDSACSStatusType)statusTypeForString:(NSString *)statusString { + if ([statusString isEqualToString:@"Y"]) { + return STDSACSStatusTypeAuthenticated; + } + if ([statusString isEqualToString:@"C"]) { + return STDSACSStatusTypeChallengeRequired; + } + if ([statusString isEqualToString:@"D"]) { + return STDSACSStatusTypeDecoupledAuthentication; + } + if ([statusString isEqualToString:@"N"]) { + return STDSACSStatusTypeNotAuthenticated; + } + if ([statusString isEqualToString:@"A"]) { + return STDSACSStatusTypeProofGenerated; + } + if ([statusString isEqualToString:@"U"]) { + return STDSACSStatusTypeError; + } + if ([statusString isEqualToString:@"R"]) { + return STDSACSStatusTypeRejected; + } + if ([statusString isEqualToString:@"I"]) { + return STDSACSStatusTypeInformationalOnly; + } + return STDSACSStatusTypeUnknown; +} + +@end + +id _Nullable STDSAuthenticationResponseFromJSON(NSDictionary *json) { + return [STDSAuthenticationResponseObject decodedObjectFromJSON:json error:NULL]; +} + +NS_ASSUME_NONNULL_END diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSBrandingView.h b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSBrandingView.h new file mode 100644 index 0000000..310e18a --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSBrandingView.h @@ -0,0 +1,23 @@ +// +// STDSBrandingView.h +// Stripe3DS2 +// +// Created by Andrew Harrison on 2/27/19. +// Copyright © 2019 Stripe. All rights reserved. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface STDSBrandingView: UIView + +/// The issuer image to present in the branding view. +@property (nonatomic, strong) UIImage *issuerImage; + +/// The payment system image to present in the branding view. +@property (nonatomic, strong) UIImage *paymentSystemImage; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSBrandingView.m b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSBrandingView.m new file mode 100644 index 0000000..9783cc7 --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSBrandingView.m @@ -0,0 +1,132 @@ +// +// STDSBrandingView.m +// Stripe3DS2 +// +// Created by Andrew Harrison on 2/27/19. +// Copyright © 2019 Stripe. All rights reserved. +// + +#import "STDSBrandingView.h" +#import "STDSStackView.h" +#import "UIView+LayoutSupport.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface STDSBrandingView() + +@property (nonatomic, strong) STDSStackView *stackView; + +@property (nonatomic, strong) UIImageView *issuerImageView; +@property (nonatomic, strong) UIImageView *paymentSystemImageView; + +@property (nonatomic, strong) UIView *issuerView; +@property (nonatomic, strong) UIView *paymentSystemView; + +@end + +@implementation STDSBrandingView + +static const CGFloat kBrandingViewBottomPadding = 24; +static const CGFloat kBrandingViewSpacing = 16; +static const CGFloat kImageViewBorderWidth = 1; +static const CGFloat kImageViewHorizontalInset = 7; +static const CGFloat kImageViewVerticalInset = 19; +static const CGFloat kImageViewCornerRadius = 6; + +- (instancetype)initWithFrame:(CGRect)frame { + self = [super initWithFrame:frame]; + + if (self) { + [self _setupViewHierarchy]; + } + + return self; +} + +- (void)setPaymentSystemImage:(UIImage *)paymentSystemImage { + _paymentSystemImage = paymentSystemImage; + + self.paymentSystemImageView.image = paymentSystemImage; +} + +- (void)setIssuerImage:(UIImage *)issuerImage { + _issuerImage = issuerImage; + + self.issuerImageView.image = issuerImage; +} + +- (void)didMoveToWindow { + [super didMoveToWindow]; + + if (self.window.screen.nativeScale > 0) { + self.issuerView.layer.borderWidth = kImageViewBorderWidth / self.window.screen.nativeScale; + self.paymentSystemView.layer.borderWidth = kImageViewBorderWidth / self.window.screen.nativeScale; + } +} + +- (void)_setupViewHierarchy { + self.layoutMargins = UIEdgeInsetsMake(0, 0, kBrandingViewBottomPadding, 0); + + self.stackView = [[STDSStackView alloc] initWithAlignment:STDSStackViewLayoutAxisHorizontal]; + [self addSubview:self.stackView]; + + [self.stackView _stds_pinToSuperviewBounds]; + + self.issuerImageView = [self _newBrandingImageView]; + self.issuerView = [self _newInsetViewWithImageView:self.issuerImageView]; + [self.stackView addArrangedSubview:self.issuerView]; + + [self.stackView addSpacer:kBrandingViewSpacing]; + + self.paymentSystemImageView = [self _newBrandingImageView]; + self.paymentSystemView = [self _newInsetViewWithImageView:self.paymentSystemImageView]; + [self.stackView addArrangedSubview:self.paymentSystemView]; + + NSLayoutConstraint *imageViewWidthConstraint = [NSLayoutConstraint constraintWithItem:self.issuerView attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeWidth multiplier:0.5 constant:0]; + // Setting the priority of the width constraint, so that the priority of the equal widths constraint below takes precedence, allowing both image views to take half of the remaining space equally. + imageViewWidthConstraint.priority = UILayoutPriorityDefaultHigh; + NSLayoutConstraint *width = [NSLayoutConstraint constraintWithItem:self.paymentSystemView attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:self.issuerView attribute:NSLayoutAttributeWidth multiplier:1 constant:0]; + + [NSLayoutConstraint activateConstraints:@[imageViewWidthConstraint, width]]; +} + +- (UIView *)_newInsetViewWithImageView:(UIImageView *)imageView { + UIView *insetView = [UIView new]; + insetView.layoutMargins = UIEdgeInsetsMake(kImageViewHorizontalInset, kImageViewVerticalInset, kImageViewHorizontalInset, kImageViewVerticalInset); + insetView.layer.cornerRadius = kImageViewCornerRadius; + insetView.backgroundColor = [UIColor whiteColor]; // Issuer images always expect a white background. + insetView.layer.masksToBounds = YES; + if (@available(iOS 12.0, *)) { + insetView.layer.borderColor = (self.traitCollection.userInterfaceStyle == UIUserInterfaceStyleLight) ? + [UIColor colorWithRed:(CGFloat)0.0 green:(CGFloat)57.0/(CGFloat)255.0 blue:(CGFloat)69.0/(CGFloat)255.0 alpha:(CGFloat)0.25].CGColor : + [UIColor colorWithRed:(CGFloat)195.0/(CGFloat)255.0 green:(CGFloat)214.0/(CGFloat)255.0 blue:(CGFloat)218.0/(CGFloat)255.0 alpha:(CGFloat)0.25].CGColor; + } else { + insetView.layer.borderColor = [UIColor colorWithRed:(CGFloat)0.0 green:(CGFloat)57.0/(CGFloat)255.0 blue:(CGFloat)69.0/(CGFloat)255.0 alpha:(CGFloat)0.25].CGColor; + } + + [insetView addSubview:imageView]; + [imageView _stds_pinToSuperviewBounds]; + + return insetView; +} + +- (UIImageView *)_newBrandingImageView { + UIImageView *imageView = [[UIImageView alloc] init]; + imageView.contentMode = UIViewContentModeScaleAspectFit; + + return imageView; +} + +- (void)traitCollectionDidChange:(UITraitCollection * _Nullable)previousTraitCollection { + if (@available(iOS 12.0, *)) { + CGColorRef borderColor = (self.traitCollection.userInterfaceStyle == UIUserInterfaceStyleLight) ? + [UIColor colorWithRed:(CGFloat)0.0 green:(CGFloat)57.0/(CGFloat)255.0 blue:(CGFloat)69.0/(CGFloat)255.0 alpha:(CGFloat)0.25].CGColor : + [UIColor colorWithRed:(CGFloat)195.0/(CGFloat)255.0 green:(CGFloat)214.0/(CGFloat)255.0 blue:(CGFloat)218.0/(CGFloat)255.0 alpha:(CGFloat)0.25].CGColor; + self.issuerView.layer.borderColor = borderColor; + self.paymentSystemView.layer.borderColor = borderColor; + } +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSBundleLocator.h b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSBundleLocator.h new file mode 100644 index 0000000..ed919fa --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSBundleLocator.h @@ -0,0 +1,15 @@ +// +// STDSBundleLocator.h +// Stripe3DS2 +// +// Created by David Estes on 7/23/19. +// Copyright © 2019 Stripe. All rights reserved. +// + +#import + +@interface STDSBundleLocator : NSObject + ++ (NSBundle *)stdsResourcesBundle; + +@end diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSBundleLocator.m b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSBundleLocator.m new file mode 100644 index 0000000..5538406 --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSBundleLocator.m @@ -0,0 +1,109 @@ +// +// STDSBundleLocator.m +// Stripe3DS2 +// +// Created by David Estes on 7/23/19. +// Copyright © 2019 Stripe. All rights reserved. +// Based on STPBundleLocator.m in Stripe.framework +// + +#import "STDSBundleLocator.h" + +/** + Using a private class to ensure that it can't be subclassed, which may + change the result of `bundleForClass` + */ +@interface STDSBundleLocatorInternal : NSObject +@end +@implementation STDSBundleLocatorInternal +@end + +@implementation STDSBundleLocator + +// This is copied from SPM's resource_bundle_accessor.m ++ (NSBundle *)stdsSPMBundle { + NSString *bundleName = @"Stripe_Stripe"; + + NSArray *candidates = @[ + NSBundle.mainBundle.resourceURL, + [NSBundle bundleForClass:[self class]].resourceURL, + NSBundle.mainBundle.bundleURL + ]; + + for (NSURL* candiate in candidates) { + NSURL *bundlePath = [candiate URLByAppendingPathComponent:[NSString stringWithFormat:@"%@.bundle", bundleName]]; + + NSBundle *bundle = [NSBundle bundleWithURL:bundlePath]; + if (bundle != nil) { + return bundle; + } + } + + return nil; +} + ++ (NSBundle *)stdsResourcesBundle { + /** + First, find Stripe.framework. + Places to check: + 1. Stripe_Stripe3DS2.bundle (for SwiftPM) + 1. Stripe_Stripe.bundle (for SwiftPM) + 2. Stripe.bundle (for manual static installations, Fabric, and framework-less Cocoapods) + 3. Stripe.framework/Stripe.bundle (for framework-based Cocoapods) + 4. Stripe.framework (for Carthage, manual dynamic installations) + 5. main bundle (for people dragging all our files into their project) + **/ + + static NSBundle *ourBundle; + + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ +#ifdef SWIFTPM_MODULE_BUNDLE + ourBundle = SWIFTPM_MODULE_BUNDLE; +#endif + + if (ourBundle == nil) { + ourBundle = [STDSBundleLocator stdsSPMBundle]; + } + + if (ourBundle == nil) { + ourBundle = [NSBundle bundleWithPath:@"Stripe.bundle"]; + } + + if (ourBundle == nil) { + // This might be the same as the previous check if not using a dynamic framework + NSString *path = [[NSBundle bundleForClass:[STDSBundleLocatorInternal class]] pathForResource:@"Stripe" ofType:@"bundle"]; + ourBundle = [NSBundle bundleWithPath:path]; + } + + if (ourBundle == nil) { + // This will be the same as mainBundle if not using a dynamic framework + ourBundle = [NSBundle bundleForClass:[STDSBundleLocatorInternal class]]; + } + + if (ourBundle == nil) { + ourBundle = [NSBundle mainBundle]; + } + + // Once we've found Stripe.framework, seek around to find Stripe3DS2.bundle. + // Try to find Stripe3DS2 bundle within our current bundle + NSString *stdsBundlePath = [[ourBundle bundlePath] stringByAppendingPathComponent:@"Stripe3DS2.bundle"]; + NSBundle *stdsBundle = [NSBundle bundleWithPath:stdsBundlePath]; + if (stdsBundle != nil) { + ourBundle = stdsBundle; + } + // If it's not there, it might be a level up from us? + // (CocoaPods arranges us this way, as an example.) + if (stdsBundle == nil) { + NSString *stdsBundlePath = [[[ourBundle bundlePath] stringByDeletingLastPathComponent] stringByAppendingPathComponent:@"Stripe3DS2.bundle"]; + stdsBundle = [NSBundle bundleWithPath:stdsBundlePath]; + if (stdsBundle != nil) { + ourBundle = stdsBundle; + } + } + }); + + return ourBundle; +} + +@end diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSButtonCustomization.m b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSButtonCustomization.m new file mode 100644 index 0000000..a82a6cb --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSButtonCustomization.m @@ -0,0 +1,69 @@ +// +// STDSButtonCustomization.m +// Stripe3DS2 +// +// Created by Andrew Harrison on 3/14/19. +// Copyright © 2019 Stripe. All rights reserved. +// + +#import "STDSButtonCustomization.h" + +#import "STDSUICustomization.h" +#import "UIColor+DefaultColors.h" +#import "UIFont+DefaultFonts.h" + +static const CGFloat kDefaultButtonCornerRadius = 8.0; +static const CGFloat kDefaultButtonFontScale = (CGFloat)0.9; + +NS_ASSUME_NONNULL_BEGIN + +@implementation STDSButtonCustomization + ++ (instancetype)defaultSettingsForButtonType:(STDSUICustomizationButtonType)type { + UIColor *backgroundColor = [UIColor _stds_blueColor]; + CGFloat cornerRadius = kDefaultButtonCornerRadius; + UIFont *font = [UIFont _stds_defaultBoldLabelTextFontWithScale:kDefaultButtonFontScale]; + UIColor *textColor = UIColor.whiteColor; + switch (type) { + case STDSUICustomizationButtonTypeContinue: + case STDSUICustomizationButtonTypeSubmit: + case STDSUICustomizationButtonTypeNext: + break; + case STDSUICustomizationButtonTypeResend: + backgroundColor = UIColor.clearColor; + textColor = [UIColor _stds_blueColor]; + font = nil; + break; + case STDSUICustomizationButtonTypeCancel: + backgroundColor = UIColor.clearColor; + textColor = nil; + font = nil; + break; + } + STDSButtonCustomization *buttonCustomization = [[self alloc] initWithBackgroundColor:backgroundColor cornerRadius:cornerRadius]; + buttonCustomization.font = font; + buttonCustomization.textColor = textColor; + return buttonCustomization; +} + +- (instancetype)initWithBackgroundColor:(UIColor *)backgroundColor cornerRadius:(CGFloat)cornerRadius { + self = [super init]; + if (self) { + _backgroundColor = backgroundColor; + _cornerRadius = cornerRadius; + } + return self; +} + +- (id)copyWithZone:(nullable NSZone *)zone { + STDSButtonCustomization *copy = [super copyWithZone:zone]; + copy.backgroundColor = self.backgroundColor; + copy.cornerRadius = self.cornerRadius; + copy.titleStyle = self.titleStyle; + + return copy; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSCategoryLinker.h b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSCategoryLinker.h new file mode 100644 index 0000000..87bbe9e --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSCategoryLinker.h @@ -0,0 +1,20 @@ +// +// STDSCategoryLinker.h +// Stripe3DS2 +// +// Created by David Estes on 11/18/20. +// Copyright © 2020 Stripe. All rights reserved. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface STDSCategoryLinker : NSObject + +/// This will reference all categories in Stripe3DS2 so the linker doesn't consider them unused code. This should make it so users don't need to add the `-ObjC` linker flag. ++ (void)referenceAllCategories; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSCategoryLinker.m b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSCategoryLinker.m new file mode 100644 index 0000000..4d67fa2 --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSCategoryLinker.m @@ -0,0 +1,53 @@ +// +// STDSCategoryLinker.m +// Stripe3DS2 +// +// Created by David Estes on 11/18/20. +// Copyright © 2020 Stripe. All rights reserved. +// + +#import "STDSCategoryLinker.h" + +#import "NSData+JWEHelpers.h" +#import "NSString+JWEHelpers.h" +#import "NSDictionary+DecodingHelpers.h" +#import "NSError+Stripe3DS2.h" +#import "NSString+EmptyChecking.h" +#import "NSLayoutConstraint+LayoutSupport.h" +#import "UIButton+CustomInitialization.h" +#import "UIColor+DefaultColors.h" +#import "UIColor+ThirteenSupport.h" +#import "UIFont+DefaultFonts.h" +#import "UIView+LayoutSupport.h" +#import "UIViewController+Stripe3DS2.h" + +@implementation STDSCategoryLinker + ++ (void)referenceAllCategories { + // NSData+JWEHelpers.h" + _stds_import_nsdata_jwehelpers(); + // NSString+JWEHelpers.h + _stds_import_nsstring_jwehelpers(); + // NSDictionary+DecodingHelpers.h + _stds_import_nsdictionary_decodinghelpers(); + // NSError+Stripe3DS2.h + _stds_import_nserror_stripe3ds2(); + // NSString+EmptyChecking.h + _stds_import_nsstring_emptychecking(); + // NSLayoutConstraint+LayoutSupport.h + _stds_import_nslayoutconstraint_layoutsupport(); + // UIButton+CustomInitialization.h + _stds_import_uibutton_custominitialization(); + // UIColor+DefaultColors.h + _stds_import_uicolor_defaultcolors(); + // UIColor+ThirteenSupport.h + _stds_import_uicolor_thirteensupport(); + // UIFont+DefaultFonts.h + _stds_import_uifont_defaultfonts(); + // UIView+LayoutSupport.h + _stds_import_uiview_layoutsupport(); + // UIViewController+Stripe3DS2.h + _stds_import_uiviewcontroller_stripe3ds2(); +} + +@end diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSChallengeInformationView.h b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSChallengeInformationView.h new file mode 100644 index 0000000..2111ea3 --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSChallengeInformationView.h @@ -0,0 +1,25 @@ +// +// STDSChallengeInformationView.h +// Stripe3DS2 +// +// Created by Andrew Harrison on 3/4/19. +// Copyright © 2019 Stripe. All rights reserved. +// + +#import +#import "STDSLabelCustomization.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface STDSChallengeInformationView: UIView + +@property (nonatomic, strong, nullable) NSString *headerText; +@property (nonatomic, strong, nullable) UIImage *textIndicatorImage; +@property (nonatomic, strong, nullable) NSString *challengeInformationText; +@property (nonatomic, strong, nullable) NSString *challengeInformationLabel; + +@property (nonatomic, strong, nullable) STDSLabelCustomization *labelCustomization; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSChallengeInformationView.m b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSChallengeInformationView.m new file mode 100644 index 0000000..6796dfe --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSChallengeInformationView.m @@ -0,0 +1,137 @@ +// +// STDSChallengeInformationView.m +// Stripe3DS2 +// +// Created by Andrew Harrison on 3/4/19. +// Copyright © 2019 Stripe. All rights reserved. +// + +#import "STDSChallengeInformationView.h" +#import "STDSStackView.h" +#import "STDSSpacerView.h" +#import "UIView+LayoutSupport.h" +#import "NSString+EmptyChecking.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface STDSChallengeInformationView () + +@property (nonatomic, strong) STDSStackView *informationStackView; +@property (nonatomic, strong) STDSStackView *indicatorStackView; + +@property (nonatomic, strong) UILabel *headerLabel; +@property (nonatomic, strong) UIImageView *textIndicatorImageView; +@property (nonatomic, strong) UILabel *textLabel; +@property (nonatomic, strong) UILabel *informationLabel; +@property (nonatomic, strong) UIView *indicatorStackViewSpacerView; +@property (nonatomic, strong) UIView *indicatorImageTextSpacerView; + +@end + +@implementation STDSChallengeInformationView + +static const CGFloat kHeaderTextBottomPadding = 8; +static const CGFloat kInformationTextBottomPadding = 20; +static const CGFloat kChallengeInformationViewBottomPadding = 6; +static const CGFloat kTextIndicatorHorizontalPadding = 8; + +- (instancetype)initWithFrame:(CGRect)frame { + self = [super initWithFrame:frame]; + + if (self) { + [self _setupViewHierarchy]; + } + + return self; +} + +- (void)setHeaderText:(NSString * _Nullable)headerText { + _headerText = headerText; + + self.headerLabel.text = headerText; + self.headerLabel.hidden = [NSString _stds_isStringEmpty:headerText]; +} + +- (void)setTextIndicatorImage:(UIImage * _Nullable)textIndicatorImage { + _textIndicatorImage = textIndicatorImage; + + self.textIndicatorImageView.image = textIndicatorImage; + self.textIndicatorImageView.hidden = textIndicatorImage == nil; + self.indicatorImageTextSpacerView.hidden = textIndicatorImage == nil; +} + +- (void)setChallengeInformationText:(NSString * _Nullable)challengeInformationText { + _challengeInformationText = challengeInformationText; + + self.textLabel.text = challengeInformationText; + self.textLabel.hidden = [NSString _stds_isStringEmpty:challengeInformationText]; +} + +- (void)setChallengeInformationLabel:(NSString * _Nullable)challengeInformationLabel { + _challengeInformationLabel = challengeInformationLabel; + + self.informationLabel.text = challengeInformationLabel; + self.informationLabel.hidden = [NSString _stds_isStringEmpty:challengeInformationLabel]; + self.indicatorStackViewSpacerView.hidden = self.informationLabel.hidden; +} + +- (void)_setupViewHierarchy { + self.layoutMargins = UIEdgeInsetsMake(0, 0, kChallengeInformationViewBottomPadding, 0); + + self.headerLabel = [self _newInformationLabel]; + + self.textIndicatorImageView = [[UIImageView alloc] init]; + self.textIndicatorImageView.contentMode = UIViewContentModeTop; + self.textIndicatorImageView.hidden = YES; + + self.textLabel = [self _newInformationLabel]; + self.informationLabel = [self _newInformationLabel]; + + self.indicatorStackView = [[STDSStackView alloc] initWithAlignment:STDSStackViewLayoutAxisHorizontal]; + + [self.indicatorStackView addArrangedSubview:self.textIndicatorImageView]; + self.indicatorImageTextSpacerView = [[STDSSpacerView alloc] initWithLayoutAxis:STDSStackViewLayoutAxisHorizontal dimension:kTextIndicatorHorizontalPadding]; + self.indicatorImageTextSpacerView.hidden = YES; + [self.indicatorStackView addArrangedSubview:self.indicatorImageTextSpacerView]; + [self.indicatorStackView addArrangedSubview:self.textLabel]; + + self.informationStackView = [[STDSStackView alloc] initWithAlignment:STDSStackViewLayoutAxisVertical]; + [self.informationStackView addArrangedSubview:self.headerLabel]; + [self.informationStackView addSpacer:kHeaderTextBottomPadding]; + [self.informationStackView addArrangedSubview:self.indicatorStackView]; + self.indicatorStackViewSpacerView = [[STDSSpacerView alloc] initWithLayoutAxis:STDSStackViewLayoutAxisVertical dimension:kInformationTextBottomPadding]; + [self.informationStackView addArrangedSubview:self.indicatorStackViewSpacerView]; + [self.informationStackView addArrangedSubview:self.informationLabel]; + + [self addSubview:self.informationStackView]; + + [self.informationStackView _stds_pinToSuperviewBounds]; + + NSLayoutConstraint *imageViewWidthConstraint = [NSLayoutConstraint constraintWithItem:self.textIndicatorImageView attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.0 constant:35]; + [NSLayoutConstraint activateConstraints:@[imageViewWidthConstraint]]; +} + +- (void)setLabelCustomization:(STDSLabelCustomization * _Nullable)labelCustomization { + _labelCustomization = labelCustomization; + + self.headerLabel.font = labelCustomization.headingFont; + self.headerLabel.textColor = labelCustomization.headingTextColor; + + self.textLabel.font = labelCustomization.font; + self.textLabel.textColor = labelCustomization.textColor; + + self.informationLabel.font = labelCustomization.font; + self.informationLabel.textColor = labelCustomization.textColor; +} + +- (UILabel *)_newInformationLabel { + UILabel *label = [[UILabel alloc] init]; + label.numberOfLines = 0; + label.hidden = YES; + + return label; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSChallengeParameters.m b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSChallengeParameters.m new file mode 100644 index 0000000..ac166cd --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSChallengeParameters.m @@ -0,0 +1,31 @@ +// +// STDSChallengeParameters.m +// Stripe3DS2 +// +// Created by Cameron Sabol on 2/13/19. +// Copyright © 2019 Stripe. All rights reserved. +// + +#import "STDSChallengeParameters.h" + +#import "STDSAuthenticationResponse.h" + +NS_ASSUME_NONNULL_BEGIN + +@implementation STDSChallengeParameters + +- (instancetype)initWithAuthenticationResponse:(id)authResponse { + self = [self init]; + if (self) { + _threeDSServerTransactionID = [authResponse.threeDSServerTransactionID copy]; + _acsTransactionID = [authResponse.acsTransactionID copy]; + _acsReferenceNumber = [authResponse.acsReferenceNumber copy]; + _acsSignedContent = [authResponse.acsSignedContent copy]; + } + + return self; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSChallengeRequestParameters.h b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSChallengeRequestParameters.h new file mode 100644 index 0000000..d080996 --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSChallengeRequestParameters.h @@ -0,0 +1,138 @@ +// +// STDSChallengeRequestParameters.h +// Stripe3DS2 +// +// Created by Yuki Tokuhiro on 4/1/19. +// Copyright © 2019 Stripe. All rights reserved. +// + +#import + +#import "STDSJSONEncodable.h" + +@class STDSChallengeParameters; + +typedef NS_ENUM(NSInteger, STDSChallengeCancelType) { + /// The cardholder selected "Cancel" from the UI + STDSChallengeCancelTypeCardholderSelectedCancel, + + /// The transaction timed out + STDSChallengeCancelTypeTransactionTimedOut, +}; + +NS_ASSUME_NONNULL_BEGIN + +@interface STDSChallengeRequestParameters : NSObject + +/** + Convenience initializer to create parameters for the first Challenge Request for a transaction. + */ +- (instancetype)initWithChallengeParameters:(STDSChallengeParameters *)challengeParams + transactionIdentifier:(NSString *)transactionIdentifier + messageVersion:(NSString *)messageVersion; + +/** + Designated initializer for `STDSChallengeRequestParameters` + */ +- (instancetype)initWithThreeDSServerTransactionIdentifier:(NSString *)threeDSServerTransactionIdentifier + acsTransactionIdentifier:(NSString *)acsTransactionIdentifier + messageVersion:(NSString *)messageVersion + sdkTransactionIdentifier:(NSString *)sdkTransactionIdentifier + requestorAppUrl:(NSString *)requestorAppUrl + sdkCounterStoA:(NSInteger)sdkCounterStoA NS_DESIGNATED_INITIALIZER; + +/** + Returns a new instance of STDSChallengeRequestParameters using the receiver, copying over the properties that are invariant across all CReqs for a given transaction and incrementing sdkCounterStoA. + */ +- (instancetype)nextChallengeRequestParametersByIncrementCounter; + +- (instancetype)init NS_UNAVAILABLE; + +#pragma mark - Required Properties + +/** + Universally unique transaction identifier assigned by the 3DS SDK to identify a single transaction. + */ +@property (nonatomic, readonly) NSString *sdkTransactionIdentifier; + +/** + Transaction identifier assigned by the 3DS Server to uniquely identify + a transaction. + */ +@property (nonatomic, readonly) NSString *threeDSServerTransactionIdentifier; + +/** + Transaction identifier assigned by the Access Control Server (ACS) + to uniquely identify a transaction. + */ +@property (nonatomic, readonly) NSString *acsTransactionIdentifier; + +/** + Identifies the type of message - always "CReq" + */ +@property (nonatomic, readonly) NSString *messageType; + +/** + The protocol version that is supported by the SDK and used for the transaction. + */ +@property (nonatomic, readonly) NSString *messageVersion; + +/** + Counter used as a security measure in the 3DS SDK to ACS secure channel. + */ +@property (nonatomic, readonly) NSString *sdkCounterStoA; + +#pragma mark - Optional/Conditional Properties + +/** + The URL for the application that is requesting 3DS2 verification. + This property can be optionally set and will be included with the + messages sent to the Directory Server during the challenge flow. + */ +@property (nonatomic, copy, nullable) NSString *threeDSRequestorAppURL; + +/** + A STDSChallengeCancelType wrapped in NSNumber, indicating that the authentication has been canceled. + */ +@property (nonatomic, copy, nullable) NSNumber *challengeCancel; + +/** + Contains the data that the Cardholder entered into the Native UI text field. + + @note The setter converts empty strings to nil. + */ +@property (nonatomic, copy, nullable) NSString *challengeDataEntry; + +/** + Data that the Cardholder entered into the HTML UI. + */ +@property (nonatomic, copy, nullable) NSString *challengeHTMLDataEntry; + +/** + Data necessary to support requirements not otherwise defined in the 3- D Secure message. + */ +@property (nonatomic, copy, nullable) NSArray *messageExtension; + +/** + A BOOL indiciating that Cardholder has completed the authentication as requested by selecting the Continue button in an Out- of-Band (OOB) authentication method. + */ +@property (nonatomic, nullable) NSNumber *oobContinue; + +/** + Indicator to resend the challenge information code to the Cardholder. + */ +@property (nonatomic, copy, nullable) NSString *resendChallenge; + +/** + Indicator confirming whether whitelisting was opted by the cardholder. + */ +@property (nonatomic, copy, nullable) NSString *whitelistingDataEntry; + +/** + Indicator informing that the Cardholder submits an empty response (no data entered in the UI). + */ +@property (nonatomic, copy, nullable) NSString *challengeNoEntry; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSChallengeRequestParameters.m b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSChallengeRequestParameters.m new file mode 100644 index 0000000..18fcb8d --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSChallengeRequestParameters.m @@ -0,0 +1,105 @@ +// +// STDSChallengeRequestParameters.m +// Stripe3DS2 +// +// Created by Yuki Tokuhiro on 4/1/19. +// Copyright © 2019 Stripe. All rights reserved. +// + +#import "STDSChallengeRequestParameters.h" + +#import "STDSChallengeParameters.h" + +@implementation STDSChallengeRequestParameters + +- (instancetype)initWithChallengeParameters:(STDSChallengeParameters *)challengeParams + transactionIdentifier:(NSString *)transactionIdentifier + messageVersion:(NSString *)messageVersion { + return [self initWithThreeDSServerTransactionIdentifier:challengeParams.threeDSServerTransactionID + acsTransactionIdentifier:challengeParams.acsTransactionID + messageVersion:messageVersion + sdkTransactionIdentifier:transactionIdentifier + requestorAppUrl:challengeParams.threeDSRequestorAppURL + sdkCounterStoA:0]; +} + +- (instancetype)initWithThreeDSServerTransactionIdentifier:(NSString *)threeDSServerTransactionIdentifier + acsTransactionIdentifier:(NSString *)acsTransactionIdentifier + messageVersion:(NSString *)messageVersion + sdkTransactionIdentifier:(NSString *)sdkTransactionIdentifier + requestorAppUrl:(NSString *)requestorAppUrl + sdkCounterStoA:(NSInteger)sdkCounterStoA { + self = [super init]; + if (self) { + _messageType = @"CReq"; + _threeDSServerTransactionIdentifier = [threeDSServerTransactionIdentifier copy]; + _acsTransactionIdentifier = [acsTransactionIdentifier copy]; + _messageVersion = [messageVersion copy]; + _sdkTransactionIdentifier = [sdkTransactionIdentifier copy]; + _threeDSRequestorAppURL = [requestorAppUrl copy]; + _sdkCounterStoA = [NSString stringWithFormat:@"%03ld", (long)sdkCounterStoA]; + } + return self; +} + +- (instancetype)nextChallengeRequestParametersByIncrementCounter { + NSInteger incrementedCounter = [self.sdkCounterStoA intValue] + 1; + return [[STDSChallengeRequestParameters alloc] initWithThreeDSServerTransactionIdentifier:self.threeDSServerTransactionIdentifier + acsTransactionIdentifier:self.acsTransactionIdentifier + messageVersion:self.messageVersion + sdkTransactionIdentifier:self.sdkTransactionIdentifier + requestorAppUrl:self.threeDSRequestorAppURL // TC_SDK_10209_001 + sdkCounterStoA:incrementedCounter]; +} + +- (void)setChallengeDataEntry:(NSString *)challengeDataEntry { + // [Req 40] ...if the cardholder has submitted the response without entering any data in the UI, the Challenge Data Entry field shall not be present in the CReq message. + if (challengeDataEntry.length == 0) { + _challengeDataEntry = nil; + _challengeNoEntry = @"Y"; + } else { + _challengeDataEntry = [challengeDataEntry copy]; + _challengeNoEntry = nil; + } +} + +#pragma mark - Helpers + +- (nullable NSString *)challengeCancelString { + if (self.challengeCancel == nil) { + return nil; + } + + STDSChallengeCancelType challengeCancelType = (STDSChallengeCancelType)[self.challengeCancel integerValue]; + switch (challengeCancelType) { + case STDSChallengeCancelTypeCardholderSelectedCancel: + return @"01"; + case STDSChallengeCancelTypeTransactionTimedOut: + return @"08"; + } + return @"07"; // Unknown +} + +#pragma mark - STDSJSONEncodable + ++ (NSDictionary *)propertyNamesToJSONKeysMapping { + return @{ + NSStringFromSelector(@selector(threeDSServerTransactionIdentifier)): @"threeDSServerTransID", + NSStringFromSelector(@selector(acsTransactionIdentifier)): @"acsTransID", + NSStringFromSelector(@selector(threeDSRequestorAppURL)): @"threeDSRequestorAppURL", + NSStringFromSelector(@selector(challengeCancelString)): @"challengeCancel", + NSStringFromSelector(@selector(challengeDataEntry)): @"challengeDataEntry", + NSStringFromSelector(@selector(challengeHTMLDataEntry)): @"challengeHTMLDataEntry", + NSStringFromSelector(@selector(challengeNoEntry)): @"challengeNoEntry", + NSStringFromSelector(@selector(messageExtension)): @"messageExtension", + NSStringFromSelector(@selector(messageVersion)): @"messageVersion", + NSStringFromSelector(@selector(messageType)): @"messageType", + NSStringFromSelector(@selector(oobContinue)): @"oobContinue", + NSStringFromSelector(@selector(resendChallenge)): @"resendChallenge", + NSStringFromSelector(@selector(sdkTransactionIdentifier)): @"sdkTransID", + NSStringFromSelector(@selector(sdkCounterStoA)): @"sdkCounterStoA", + NSStringFromSelector(@selector(whitelistingDataEntry)): @"whitelistingDataEntry", + }; +} + +@end diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSChallengeResponse.h b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSChallengeResponse.h new file mode 100644 index 0000000..58606d2 --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSChallengeResponse.h @@ -0,0 +1,145 @@ +// +// STDSChallengeResponse.h +// Stripe3DS2 +// +// Created by Andrew Harrison on 2/25/19. +// Copyright © 2019 Stripe. All rights reserved. +// + +#import +#import "STDSChallengeResponseSelectionInfo.h" +#import "STDSChallengeResponseMessageExtension.h" +#import "STDSChallengeResponseImage.h" + +NS_ASSUME_NONNULL_BEGIN + +/** + The `STDSACSUIType` enum defines the type of UI to be presented. + */ +typedef NS_ENUM(NSInteger, STDSACSUIType) { + + /// No UI associated with the response. + STDSACSUITypeNone = 0, + + /// Text challenge response UI. + STDSACSUITypeText = 1, + + /// Single-select challenge response UI. + STDSACSUITypeSingleSelect = 2, + + /// Multi-select challenge response UI. + STDSACSUITypeMultiSelect = 3, + + /// Out Of Band challenge response UI. + STDSACSUITypeOOB = 4, + + /// HTML challenge response UI. + STDSACSUITypeHTML = 5, +}; + +/// A protocol that represents the information contained within a challenge response. +@protocol STDSChallengeResponse + +/// Universally unique transaction identifier assigned by the 3DS Server to identify a single transaction. +@property (nonatomic, readonly) NSString *threeDSServerTransactionID; + +/// Counter used as a security measure in the ACS to 3DS SDK secure channel. +@property (nonatomic, readonly) NSString *acsCounterACStoSDK; + +/// Universally unique transaction identifier assigned by the ACS to identify a single transaction. +@property (nonatomic, readonly) NSString *acsTransactionID; + +/// HTML provided by the ACS in the Challenge Response message. Utilised when HTML is specified in the ACS UI Type during the Cardholder challenge. +@property (nonatomic, readonly, nullable) NSString *acsHTML; + +/// Optional HTML provided by the ACS in the CRes message to be utilised in the Out of Band flow when the HTML is specified in the ACS UI Type during the Cardholder challenge, displayed when the app is moved to the foreground. +@property (nonatomic, readonly, nullable) NSString *acsHTMLRefresh; + +/// User interface type that the 3DS SDK will render, which includes the specific data mapping and requirements. +@property (nonatomic, readonly) STDSACSUIType acsUIType; + +/** + Indicator of the state of the ACS challenge cycle and whether the challenge has completed or will require additional messages. Shall be populated in all Challenge Response messages to convey the current state of the transaction. + + - Note: + If set to YES, the ACS will populate the Transaction Status in the Challenge Response message. + */ +@property (nonatomic, readonly) BOOL challengeCompletionIndicator; + +/// Header text that for the challenge information screen that is being presented. +@property (nonatomic, readonly, nullable) NSString *challengeInfoHeader; + +/// Label to modify the Challenge Data Entry field provided by the Issuer. +@property (nonatomic, readonly, nullable) NSString *challengeInfoLabel; + +/// Text provided by the ACS/Issuer to Cardholder during the Challenge Message exchange. +@property (nonatomic, readonly, nullable) NSString *challengeInfoText; + +/// Text provided by the ACS/Issuer to Cardholder during OOB authentication to replace Challenge Information Text and Challenge Information Text Indicator +@property (nonatomic, readonly, nullable) NSString *challengeAdditionalInfoText; + +/// Indicates when the Issuer/ACS would like a warning icon or similar visual indicator to draw attention to the “Challenge Information Text” that is being displayed. +@property (nonatomic, readonly) BOOL showChallengeInfoTextIndicator; + +/// Selection information that will be presented to the Cardholder if the option is single or multi-select. The variables will be sent in a JSON Array and parsed by the SDK for display in the user interface. +@property (nonatomic, readonly, nullable) NSArray> *challengeSelectInfo; + +/// Label displayed to the Cardholder for the content in Expandable Information Text. +@property (nonatomic, readonly, nullable) NSString *expandInfoLabel; + +/// Text provided by the Issuer from the ACS to be displayed to the Cardholder for additional information and the format will be an expandable text field. +@property (nonatomic, readonly, nullable) NSString *expandInfoText; + +/// Sent in the initial Challenge Response message from the ACS to the 3DS SDK to provide the URL(s) of the Issuer logo or image to be used in the Native UI. +@property (nonatomic, readonly, nullable) id issuerImage; + +/// Data necessary to support requirements not otherwise defined in the 3-D Secure message are carried in a Message Extension. +@property (nonatomic, readonly, nullable) NSArray> *messageExtensions; + +/// Identifies the type of message that is passed. +@property (nonatomic, readonly) NSString *messageType; + +/// Protocol version identifier. This shall be the Protocol Version Number of the specification utilised by the system creating this message. The Message Version Number is set by the 3DS Server which originates the protocol with the AReq message. The Message Version Number does not change during a 3DS transaction. +@property (nonatomic, readonly) NSString *messageVersion; + +/// Mobile Deep link to an authentication app used in the out-of-band authentication. The App URL will open the appropriate location within the authentication app. +@property (nonatomic, readonly, nullable) NSURL *oobAppURL; + +/// Label to be displayed for the link to the OOB App URL. For example: “oobAppLabel”: “Click here to open Your Bank App” +@property (nonatomic, readonly, nullable) NSString *oobAppLabel; + +/// Label to be used in the UI for the button that the user selects when they have completed the OOB authentication. +@property (nonatomic, readonly, nullable) NSString *oobContinueLabel; + +/// Sent in the initial Challenge Response message from the ACS to the 3DS SDK to provide the URL(s) of the DS or Payment System logo or image to be used in the Native UI. +@property (nonatomic, readonly, nullable) id paymentSystemImage; + +/// Label to be used in the UI for the button that the user selects when they would like to have the authentication information present. +@property (nonatomic, readonly, nullable) NSString *resendInformationLabel; + +/// Universally unique transaction identifier assigned by the 3DS SDK to identify a single transaction. +@property (nonatomic, readonly) NSString *sdkTransactionID; + +/** + Label to be used in the UI for the button that the user selects when they have completed the authentication. + + - Note: + This is not used for OOB authentication. + */ +@property (nonatomic, readonly, nullable) NSString *submitAuthenticationLabel; + +/// Text provided by the ACS/Issuer to Cardholder during a Whitelisting transaction. For example, “Would you like to add this Merchant to your whitelist?” +@property (nonatomic, readonly, nullable) NSString *whitelistingInfoText; + +/// Label to be displayed to the Cardholder for the "why" information section. +@property (nonatomic, readonly, nullable) NSString *whyInfoLabel; + +/// Text provided by the Issuer to be displayed to the Cardholder to explain why the Cardholder is being asked to perform the authentication task. +@property (nonatomic, readonly, nullable) NSString *whyInfoText; + +/// Indicates the state of the associated Transaction. +@property (nonatomic, readonly, nullable) NSString *transactionStatus; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSChallengeResponseImage.h b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSChallengeResponseImage.h new file mode 100644 index 0000000..9128d77 --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSChallengeResponseImage.h @@ -0,0 +1,27 @@ +// +// STDSChallengeResponseImage.h +// Stripe3DS2 +// +// Created by Andrew Harrison on 2/25/19. +// Copyright © 2019 Stripe. All rights reserved. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +/// A protocol used to represent information about an individual image resource inside of a challenge response. +@protocol STDSChallengeResponseImage + +/// A medium density image to display as the issuer image. +@property (nonatomic, readonly, nullable) NSURL *mediumDensityURL; + +/// A high density image to display as the issuer image. +@property (nonatomic, readonly, nullable) NSURL *highDensityURL; + +/// An extra-high density image to display as the issuer image. +@property (nonatomic, readonly, nullable) NSURL *extraHighDensityURL; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSChallengeResponseImageObject.h b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSChallengeResponseImageObject.h new file mode 100644 index 0000000..59e2120 --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSChallengeResponseImageObject.h @@ -0,0 +1,23 @@ +// +// STDSChallengeResponseImageObject.h +// Stripe3DS2 +// +// Created by Andrew Harrison on 2/25/19. +// Copyright © 2019 Stripe. All rights reserved. +// + +#import +#import "STDSChallengeResponseImage.h" + +#import "STDSJSONDecodable.h" + +NS_ASSUME_NONNULL_BEGIN + +/// An object used to represent information about an individual image resource inside of a challenge response. +@interface STDSChallengeResponseImageObject: NSObject + +- (instancetype)initWithMediumDensityURL:(NSURL * _Nullable)mediumDensityURL highDensityURL:(NSURL * _Nullable)highDensityURL extraHighDensityURL:(NSURL * _Nullable)extraHighDensityURL; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSChallengeResponseImageObject.m b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSChallengeResponseImageObject.m new file mode 100644 index 0000000..a3ea684 --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSChallengeResponseImageObject.m @@ -0,0 +1,53 @@ +// +// STDSChallengeResponseImageObject.m +// Stripe3DS2 +// +// Created by Andrew Harrison on 2/25/19. +// Copyright © 2019 Stripe. All rights reserved. +// + +#import "STDSChallengeResponseImageObject.h" + +#import "NSDictionary+DecodingHelpers.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface STDSChallengeResponseImageObject() + +@property (nonatomic, nullable) NSURL *mediumDensityURL; +@property (nonatomic, nullable) NSURL *highDensityURL; +@property (nonatomic, nullable) NSURL *extraHighDensityURL; + +@end + +@implementation STDSChallengeResponseImageObject + +- (instancetype)initWithMediumDensityURL:(NSURL * _Nullable)mediumDensityURL highDensityURL:(NSURL * _Nullable)highDensityURL extraHighDensityURL:(NSURL * _Nullable)extraHighDensityURL { + self = [super init]; + + if (self) { + _mediumDensityURL = mediumDensityURL; + _highDensityURL = highDensityURL; + _extraHighDensityURL = extraHighDensityURL; + } + + return self; +} + ++ (nullable instancetype)decodedObjectFromJSON:(nullable NSDictionary *)json error:(NSError * _Nullable __autoreleasing * _Nullable)outError { + if (json == nil) { + return nil; + } + + NSURL *mediumDensityURL = [json _stds_urlForKey:@"medium" required:NO error:nil]; + NSURL *highDensityURL = [json _stds_urlForKey:@"high" required:NO error:nil]; + NSURL *extraHighDensityURL = [json _stds_urlForKey:@"extraHigh" required:NO error:nil]; + + return [[STDSChallengeResponseImageObject alloc] initWithMediumDensityURL:mediumDensityURL + highDensityURL:highDensityURL + extraHighDensityURL:extraHighDensityURL]; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSChallengeResponseMessageExtension.h b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSChallengeResponseMessageExtension.h new file mode 100644 index 0000000..c26425f --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSChallengeResponseMessageExtension.h @@ -0,0 +1,30 @@ +// +// STDSChallengeResponseMessageExtension.h +// Stripe3DS2 +// +// Created by Andrew Harrison on 2/25/19. +// Copyright © 2019 Stripe. All rights reserved. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +/// A protocol that encapsulates an individual message extension inside of a challenge response. +@protocol STDSChallengeResponseMessageExtension + +/// The name of the extension data set as defined by the extension owner. +@property (nonatomic, readonly) NSString *name; + +/// A unique identifier for the extension. +@property (nonatomic, readonly) NSString *identifier; + +/// A Boolean value indicating whether the recipient must understand the contents of the extension to interpret the entire message. +@property (nonatomic, readonly, getter = isCriticalityIndicator) BOOL criticalityIndicator; + +/// The data carried in the extension. +@property (nonatomic, readonly) NSDictionary *data; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSChallengeResponseMessageExtensionObject.h b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSChallengeResponseMessageExtensionObject.h new file mode 100644 index 0000000..5ece844 --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSChallengeResponseMessageExtensionObject.h @@ -0,0 +1,21 @@ +// +// STDSChallengeResponseMessageExtensionObject.h +// Stripe3DS2 +// +// Created by Andrew Harrison on 2/25/19. +// Copyright © 2019 Stripe. All rights reserved. +// + +#import +#import "STDSChallengeResponseMessageExtension.h" + +#import "STDSJSONDecodable.h" + +NS_ASSUME_NONNULL_BEGIN + +/// An object used to represent an individual message extension inside of a challenge response. +@interface STDSChallengeResponseMessageExtensionObject: NSObject + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSChallengeResponseMessageExtensionObject.m b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSChallengeResponseMessageExtensionObject.m new file mode 100644 index 0000000..54e58d4 --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSChallengeResponseMessageExtensionObject.m @@ -0,0 +1,72 @@ +// +// STDSChallengeResponseMessageExtensionObject.m +// Stripe3DS2 +// +// Created by Andrew Harrison on 2/25/19. +// Copyright © 2019 Stripe. All rights reserved. +// + +#import "STDSChallengeResponseMessageExtensionObject.h" + +#import "NSDictionary+DecodingHelpers.h" +#import "NSError+Stripe3DS2.h" + +NS_ASSUME_NONNULL_BEGIN + +static const NSInteger kMaximumStringFieldLength = 64; +static const NSInteger kMaximumDataFieldLength = 8059; + +@implementation STDSChallengeResponseMessageExtensionObject + +@synthesize name = _name; +@synthesize identifier = _identifier; +@synthesize criticalityIndicator = _criticalityIndicator; +@synthesize data = _data; + +- (instancetype)initWithName:(NSString *)name identifier:(NSString *)identifier criticalityIndicator:(BOOL)criticalityIndicator data:(NSDictionary *)data { + self = [super init]; + if (self) { + _name = [name copy]; + _identifier = [identifier copy]; + _criticalityIndicator = criticalityIndicator; + _data = data; + } + return self; +} + ++ (nullable instancetype)decodedObjectFromJSON:(nullable NSDictionary *)json error:(NSError * _Nullable __autoreleasing * _Nullable)outError { + if (json == nil) { + return nil; + } + NSError *error; + + NSString *name = [json _stds_stringForKey:@"name" validator:^BOOL (NSString *value) { + return value.length <= kMaximumStringFieldLength; + }required:YES error:&error]; + NSString *identifier = [json _stds_stringForKey:@"id" validator:^BOOL (NSString *value) { + return value.length <= kMaximumStringFieldLength; + } required:YES error:&error]; + BOOL criticalityIndicator= [json _stds_boolForKey:@"criticalityIndicator" required:YES error:&error].boolValue; + NSDictionary *data = [json _stds_dictionaryForKey:@"data" required:YES error:&error]; + // The spec requires data to be "Maximum 8059 characters" + if (data && [NSJSONSerialization dataWithJSONObject:data options:0 error:nil].length > kMaximumDataFieldLength) { + error = [NSError _stds_invalidJSONFieldError:@"data"]; + } + + if (error) { + if (outError) { + *outError = error; + } + return nil; + } + + if (data != nil) { + return [[STDSChallengeResponseMessageExtensionObject alloc] initWithName:name identifier:identifier criticalityIndicator:criticalityIndicator data:data]; + } else { + return nil; + } +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSChallengeResponseObject.h b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSChallengeResponseObject.h new file mode 100644 index 0000000..1f24528 --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSChallengeResponseObject.h @@ -0,0 +1,49 @@ +// +// STDSChallengeResponseObject.h +// Stripe3DS2 +// +// Created by Andrew Harrison on 2/25/19. +// Copyright © 2019 Stripe. All rights reserved. +// + +#import +#import "STDSChallengeResponse.h" +#import "STDSJSONDecodable.h" + +NS_ASSUME_NONNULL_BEGIN + +/// An object used to represent a challenge response from the ACS. +@interface STDSChallengeResponseObject: NSObject + +- (instancetype)initWithThreeDSServerTransactionID:(NSString *)threeDSServerTransactionID + acsCounterACStoSDK:(NSString *)acsCounterACStoSDK + acsTransactionID:(NSString *)acsTransactionID + acsHTML:(NSString * _Nullable)acsHTML + acsHTMLRefresh:(NSString * _Nullable)acsHTMLRefresh + acsUIType:(STDSACSUIType)acsUIType + challengeCompletionIndicator:(BOOL)challengeCompletionIndicator + challengeInfoHeader:(NSString * _Nullable)challengeInfoHeader + challengeInfoLabel:(NSString * _Nullable)challengeInfoLabel + challengeInfoText:(NSString * _Nullable)challengeInfoText + challengeAdditionalInfoText:(NSString * _Nullable)challengeAdditionalInfoText + showChallengeInfoTextIndicator:(BOOL)showChallengeInfoTextIndicator + challengeSelectInfo:(NSArray> * _Nullable)challengeSelectInfo + expandInfoLabel:(NSString * _Nullable)expandInfoLabel + expandInfoText:(NSString * _Nullable)expandInfoText + issuerImage:(id _Nullable)issuerImage + messageExtensions:(NSArray> * _Nullable)messageExtensions + messageVersion:(NSString *)messageVersion + oobAppURL:(NSURL * _Nullable)oobAppURL + oobAppLabel:(NSString * _Nullable)oobAppLabel + oobContinueLabel:(NSString * _Nullable)oobContinueLabel + paymentSystemImage:(id _Nullable)paymentSystemImage + resendInformationLabel:(NSString * _Nullable)resendInformationLabel + sdkTransactionID:(NSString *)sdkTransactionID + submitAuthenticationLabel:(NSString * _Nullable)submitAuthenticationLabel + whitelistingInfoText:(NSString * _Nullable)whitelistingInfoText + whyInfoLabel:(NSString * _Nullable)whyInfoLabel + whyInfoText:(NSString * _Nullable)whyInfoText + transactionStatus:(NSString * _Nullable)transactionStatus; +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSChallengeResponseObject.m b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSChallengeResponseObject.m new file mode 100644 index 0000000..7d952bb --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSChallengeResponseObject.m @@ -0,0 +1,321 @@ +// +// STDSChallengeResponseObject.m +// Stripe3DS2 +// +// Created by Andrew Harrison on 2/25/19. +// Copyright © 2019 Stripe. All rights reserved. +// + +#import "STDSChallengeResponseObject.h" + +#import "NSDictionary+DecodingHelpers.h" +#import "NSError+Stripe3DS2.h" +#import "STDSChallengeResponseSelectionInfoObject.h" +#import "STDSChallengeResponseImageObject.h" +#import "STDSChallengeResponseMessageExtensionObject.h" +#import "NSString+JWEHelpers.h" +#import "STDSStripe3DS2Error.h" + +NS_ASSUME_NONNULL_BEGIN + +@implementation STDSChallengeResponseObject + +@synthesize threeDSServerTransactionID = _threeDSServerTransactionID; +@synthesize acsCounterACStoSDK = _acsCounterACStoSDK; +@synthesize acsTransactionID = _acsTransactionID; +@synthesize acsHTML = _acsHTML; +@synthesize acsHTMLRefresh = _acsHTMLRefresh; +@synthesize acsUIType = _acsUIType; +@synthesize challengeCompletionIndicator = _challengeCompletionIndicator; +@synthesize challengeInfoHeader = _challengeInfoHeader; +@synthesize challengeInfoLabel = _challengeInfoLabel; +@synthesize challengeInfoText = _challengeInfoText; +@synthesize challengeAdditionalInfoText = _challengeAdditionalInfoText; +@synthesize showChallengeInfoTextIndicator = _showChallengeInfoTextIndicator; +@synthesize challengeSelectInfo = _challengeSelectInfo; +@synthesize expandInfoLabel = _expandInfoLabel; +@synthesize expandInfoText = _expandInfoText; +@synthesize issuerImage = _issuerImage; +@synthesize messageExtensions = _messageExtensions; +@synthesize messageType = _messageType; +@synthesize messageVersion = _messageVersion; +@synthesize oobAppURL = _oobAppURL; +@synthesize oobAppLabel = _oobAppLabel; +@synthesize oobContinueLabel = _oobContinueLabel; +@synthesize paymentSystemImage = _paymentSystemImage; +@synthesize resendInformationLabel = _resendInformationLabel; +@synthesize sdkTransactionID = _sdkTransactionID; +@synthesize submitAuthenticationLabel = _submitAuthenticationLabel; +@synthesize whitelistingInfoText = _whitelistingInfoText; +@synthesize whyInfoLabel = _whyInfoLabel; +@synthesize whyInfoText = _whyInfoText; +@synthesize transactionStatus = _transactionStatus; + +- (NSString *)description { + return [NSString stringWithFormat:@"%@ -- completion: %@, count: %@", [super description], @(self.challengeCompletionIndicator), self.acsCounterACStoSDK]; +} + +- (instancetype)initWithThreeDSServerTransactionID:(NSString *)threeDSServerTransactionID + acsCounterACStoSDK:(NSString *)acsCounterACStoSDK + acsTransactionID:(NSString *)acsTransactionID + acsHTML:(NSString * _Nullable)acsHTML + acsHTMLRefresh:(NSString * _Nullable)acsHTMLRefresh + acsUIType:(STDSACSUIType)acsUIType + challengeCompletionIndicator:(BOOL)challengeCompletionIndicator + challengeInfoHeader:(NSString * _Nullable)challengeInfoHeader + challengeInfoLabel:(NSString * _Nullable)challengeInfoLabel + challengeInfoText:(NSString * _Nullable)challengeInfoText + challengeAdditionalInfoText:(NSString * _Nullable)challengeAdditionalInfoText + showChallengeInfoTextIndicator:(BOOL)showChallengeInfoTextIndicator + challengeSelectInfo:(NSArray> * _Nullable)challengeSelectInfo + expandInfoLabel:(NSString * _Nullable)expandInfoLabel + expandInfoText:(NSString * _Nullable)expandInfoText + issuerImage:(id _Nullable)issuerImage + messageExtensions:(NSArray> * _Nullable)messageExtensions + messageVersion:(NSString *)messageVersion + oobAppURL:(NSURL * _Nullable)oobAppURL + oobAppLabel:(NSString * _Nullable)oobAppLabel + oobContinueLabel:(NSString * _Nullable)oobContinueLabel + paymentSystemImage:(id _Nullable)paymentSystemImage + resendInformationLabel:(NSString * _Nullable)resendInformationLabel + sdkTransactionID:(NSString *)sdkTransactionID + submitAuthenticationLabel:(NSString * _Nullable)submitAuthenticationLabel + whitelistingInfoText:(NSString * _Nullable)whitelistingInfoText + whyInfoLabel:(NSString * _Nullable)whyInfoLabel + whyInfoText:(NSString * _Nullable)whyInfoText + transactionStatus:(NSString * _Nullable)transactionStatus { + self = [super init]; + + if (self) { + _threeDSServerTransactionID = [threeDSServerTransactionID copy]; + _acsCounterACStoSDK = [acsCounterACStoSDK copy]; + _acsTransactionID = [acsTransactionID copy]; + _acsHTML = [acsHTML copy]; + _acsHTMLRefresh = [acsHTMLRefresh copy]; + _acsUIType = acsUIType; + _challengeCompletionIndicator = challengeCompletionIndicator; + _challengeInfoHeader = [challengeInfoHeader copy]; + _challengeInfoLabel = [challengeInfoLabel copy]; + _challengeInfoText = [challengeInfoText copy]; + _challengeAdditionalInfoText = [challengeAdditionalInfoText copy]; + _showChallengeInfoTextIndicator = showChallengeInfoTextIndicator; + _challengeSelectInfo = [challengeSelectInfo copy]; + _expandInfoLabel = [expandInfoLabel copy]; + _expandInfoText = [expandInfoText copy]; + _issuerImage = issuerImage; + _messageExtensions = [messageExtensions copy]; + _messageType = @"CRes"; + _messageVersion = [messageVersion copy]; + _oobAppURL = oobAppURL; + _oobAppLabel = [oobAppLabel copy]; + _oobContinueLabel = [oobContinueLabel copy]; + _paymentSystemImage = paymentSystemImage; + _resendInformationLabel = [resendInformationLabel copy]; + _sdkTransactionID = [sdkTransactionID copy]; + _submitAuthenticationLabel = [submitAuthenticationLabel copy]; + _whitelistingInfoText = [whitelistingInfoText copy]; + _whyInfoLabel = [whyInfoLabel copy]; + _whyInfoText = [whyInfoText copy]; + _transactionStatus = [transactionStatus copy]; + } + + return self; +} + +#pragma mark Private Helpers + ++ (NSDictionary *)acsUITypeStringMapping { + return @{ + @"01": @(STDSACSUITypeText), + @"02": @(STDSACSUITypeSingleSelect), + @"03": @(STDSACSUITypeMultiSelect), + @"04": @(STDSACSUITypeOOB), + @"05": @(STDSACSUITypeHTML), + }; +} + +/// The message extension identifiers that we support. ++ (NSSet *)supportedMessageExtensions { + return [NSSet new]; +} + +#pragma mark STDSJSONDecodable + ++ (nullable instancetype)decodedObjectFromJSON:(nullable NSDictionary *)json error:(NSError **)outError { + if (json == nil) { + return nil; + } + NSError *error; + +#pragma mark Required + NSString *threeDSServerTransactionID = [json _stds_stringForKey:@"threeDSServerTransID" validator:^BOOL (NSString *value) { + return [[NSUUID alloc] initWithUUIDString:value] != nil; + } required:YES error:&error]; + NSString *acsCounterACStoSDK = [json _stds_stringForKey:@"acsCounterAtoS" required:YES error:&error]; + NSString *acsTransactionID = [json _stds_stringForKey:@"acsTransID" required:YES error:&error]; + NSString *challengeCompletionIndicatorRawString = [json _stds_stringForKey:@"challengeCompletionInd" validator:^BOOL (NSString *value) { + return [value isEqualToString:@"N"] || [value isEqualToString:@"Y"]; + } required:YES error:&error]; + // There is only one valid messageType value for this object (@"CRes"), so we don't store it. + [json _stds_stringForKey:@"messageType" validator:^BOOL (NSString *value) { + return [value isEqualToString:@"CRes"]; + } required:YES error:&error]; + NSString *messageVersion = [json _stds_stringForKey:@"messageVersion" required:YES error:&error]; + NSString *sdkTransactionID = [json _stds_stringForKey:@"sdkTransID" required:YES error:&error]; + + BOOL challengeCompletionIndicator = challengeCompletionIndicatorRawString.boolValue; + + STDSACSUIType acsUIType = STDSACSUITypeNone; + if (!challengeCompletionIndicator) { + NSString *acsUITypeRawString = [json _stds_stringForKey:@"acsUiType" validator:^BOOL (NSString *value) { + return [self acsUITypeStringMapping][value] != nil; + } required:YES error:&error]; + + acsUIType = [self acsUITypeStringMapping][acsUITypeRawString].integerValue; + } + + if (error) { + // We failed to populate a required field + if (outError) { + *outError = error; + } + return nil; + } + + // At this point all the above values are valid: e.g. raw string representations of a BOOL or enum will map to a valid value. + +#pragma mark Conditional + NSString *encodedAcsHTML = [json _stds_stringForKey:@"acsHTML" required:(acsUIType == STDSACSUITypeHTML) error: &error]; + NSString *acsHTML = [encodedAcsHTML _stds_base64URLDecodedString]; + if (encodedAcsHTML && !acsHTML) { + // html was not valid base64url + error = [NSError _stds_invalidJSONFieldError:@"acsHTML"]; + } + + NSArray> *challengeSelectInfo = [json _stds_arrayForKey:@"challengeSelectInfo" + arrayElementType:[STDSChallengeResponseSelectionInfoObject class] + required:(acsUIType == STDSACSUITypeSingleSelect || acsUIType == STDSACSUITypeMultiSelect) + error:&error]; + NSString *oobContinueLabel = [json _stds_stringForKey:@"oobContinueLabel" required:(acsUIType == STDSACSUITypeOOB) error:&error]; + NSString *submitAuthenticationLabel = [json _stds_stringForKey:@"submitAuthenticationLabel" required:(acsUIType == STDSACSUITypeText || acsUIType == STDSACSUITypeSingleSelect || acsUIType == STDSACSUITypeMultiSelect || acsUIType == STDSACSUITypeText) error:&error]; + +#pragma mark Optional + NSArray> *messageExtensions = [json _stds_arrayForKey:@"messageExtension" + arrayElementType:[STDSChallengeResponseMessageExtensionObject class] + required:NO + error:&error]; + NSMutableArray *unrecognizedMessageExtensionIdentifiers = [NSMutableArray new]; + for (id messageExtension in messageExtensions) { + if (messageExtension.criticalityIndicator && ![[self supportedMessageExtensions] containsObject:messageExtension.identifier]) { + [unrecognizedMessageExtensionIdentifiers addObject:messageExtension.identifier]; + } + } + if (unrecognizedMessageExtensionIdentifiers.count > 0) { + error = [NSError errorWithDomain:STDSStripe3DS2ErrorDomain code:STDSErrorCodeUnrecognizedCriticalMessageExtension userInfo:@{STDSStripe3DS2UnrecognizedCriticalMessageExtensionsKey: unrecognizedMessageExtensionIdentifiers}]; + } + if (messageExtensions.count > 10) { + error = [NSError _stds_invalidJSONFieldError:@"messageExtension"]; + } + + NSString *encodedAcsHTMLRefresh = [json _stds_stringForKey:@"acsHTMLRefresh" required:NO error: &error]; + NSString *acsHTMLRefresh = [encodedAcsHTMLRefresh _stds_base64URLDecodedString]; + if (encodedAcsHTMLRefresh && !acsHTMLRefresh) { + // html was not valid base64url + error = [NSError _stds_invalidJSONFieldError:@"acsHTMLRefresh"]; + } + + BOOL infoLabelRequired = NO; + BOOL headerRequired = NO; + BOOL infoTextRequired = NO; + switch (acsUIType) { + case STDSACSUITypeNone: + break; // no-op + case STDSACSUITypeText: + case STDSACSUITypeSingleSelect: + case STDSACSUITypeMultiSelect: + infoLabelRequired = YES; // TC_SDK_10270_001 & TC_SDK_10276_001 & TC_SDK_10284_001 + headerRequired = YES; // TC_SDK_10268_001 & TC_SDK_10273_001 & TC_SDK_10282_001 + infoTextRequired = YES; // TC_SDK_10272_001 & TC_SDK_10278_001 & TC_SDK_10286_001 + break; + case STDSACSUITypeOOB: + + break; + case STDSACSUITypeHTML: + break; // no-op + } + + + NSString *challengeInfoLabel = [json _stds_stringForKey:@"challengeInfoLabel" validator:nil required:infoLabelRequired error:&error]; + NSString *challengeInfoHeader = [json _stds_stringForKey:@"challengeInfoHeader" required: (oobContinueLabel != nil) || headerRequired error:&error]; // TC_SDK_10292_001 + NSString *challengeInfoText = [json _stds_stringForKey:@"challengeInfoText" required:(oobContinueLabel != nil) || infoTextRequired error:&error]; // TC_SDK_10292_001 + NSString *challengeAdditionalInfoText = [json _stds_stringForKey:@"challengeAddInfo" required:NO error:&error]; + if (!error && submitAuthenticationLabel && (!challengeInfoLabel || !challengeInfoHeader || !challengeInfoText)) { + error = [NSError _stds_missingJSONFieldError:@"challengeInfoLabel or challengeInfoText"]; + } + + NSString *showChallengeInfoTextIndicatorRawString; + if (json[@"challengeInfoTextIndicator"]) { + showChallengeInfoTextIndicatorRawString = [json _stds_stringForKey:@"challengeInfoTextIndicator" validator:^BOOL (NSString *value) { + return [value isEqualToString:@"N"] || [value isEqualToString:@"Y"]; + } required:NO error:&error]; + } + BOOL showChallengeInfoTextIndicator = showChallengeInfoTextIndicatorRawString ? showChallengeInfoTextIndicatorRawString.boolValue : NO; // If the field is missing, we shouldn't show the indicator + NSString *expandInfoLabel = [json _stds_stringForKey:@"expandInfoLabel" required:NO error:&error]; + NSString *expandInfoText = [json _stds_stringForKey:@"expandInfoText" required:NO error:&error]; + NSURL *oobAppURL = [json _stds_urlForKey:@"oobAppURL" required:NO error:&error]; + NSString *oobAppLabel = [json _stds_stringForKey:@"oobAppURL" required:NO error:&error]; + NSDictionary *issuerImageJSON = [json _stds_dictionaryForKey:@"issuerImage" required:NO error:&error]; + STDSChallengeResponseImageObject *issuerImage = [STDSChallengeResponseImageObject decodedObjectFromJSON:issuerImageJSON error:&error]; + NSDictionary *paymentSystemImageJSON = [json _stds_dictionaryForKey:@"psImage" required:NO error:&error]; + STDSChallengeResponseImageObject *paymentSystemImage = [STDSChallengeResponseImageObject decodedObjectFromJSON:paymentSystemImageJSON error:&error]; + NSString *resendInformationLabel = [json _stds_stringForKey:@"resendInformationLabel" required:NO error:&error]; + NSString *whitelistingInfoText = [json _stds_stringForKey:@"whitelistingInfoText" required:NO error:&error]; + if (whitelistingInfoText.length > 64) { + // TC_SDK_10199_001 + error = [NSError _stds_invalidJSONFieldError:@"whitelisting text is greater than 64 characters"]; + } + NSString *whyInfoLabel = [json _stds_stringForKey:@"whyInfoLabel" required:NO error:&error]; + NSString *whyInfoText = [json _stds_stringForKey:@"whyInfoText" required:NO error:&error]; + NSString *transactionStatus = [json _stds_stringForKey:@"transStatus" required:challengeCompletionIndicator error:&error]; + + if (error) { + if (outError) { + *outError = error; + } + return nil; + } + + return [[self alloc] initWithThreeDSServerTransactionID:threeDSServerTransactionID + acsCounterACStoSDK:acsCounterACStoSDK + acsTransactionID:acsTransactionID + acsHTML:acsHTML + acsHTMLRefresh:acsHTMLRefresh + acsUIType:acsUIType + challengeCompletionIndicator:challengeCompletionIndicator + challengeInfoHeader:challengeInfoHeader + challengeInfoLabel:challengeInfoLabel + challengeInfoText:challengeInfoText + challengeAdditionalInfoText:challengeAdditionalInfoText + showChallengeInfoTextIndicator:showChallengeInfoTextIndicator + challengeSelectInfo:challengeSelectInfo + expandInfoLabel:expandInfoLabel + expandInfoText:expandInfoText + issuerImage:issuerImage + messageExtensions:messageExtensions + messageVersion:messageVersion + oobAppURL:oobAppURL + oobAppLabel:oobAppLabel + oobContinueLabel:oobContinueLabel + paymentSystemImage:paymentSystemImage + resendInformationLabel:resendInformationLabel + sdkTransactionID:sdkTransactionID + submitAuthenticationLabel:submitAuthenticationLabel + whitelistingInfoText:whitelistingInfoText + whyInfoLabel:whyInfoLabel + whyInfoText:whyInfoText + transactionStatus:transactionStatus]; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSChallengeResponseSelectionInfo.h b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSChallengeResponseSelectionInfo.h new file mode 100644 index 0000000..a482c8c --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSChallengeResponseSelectionInfo.h @@ -0,0 +1,24 @@ +// +// STDSChallengeResponseSelectionInfo.h +// Stripe3DS2 +// +// Created by Andrew Harrison on 2/25/19. +// Copyright © 2019 Stripe. All rights reserved. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +/// A protocol that encapsulates information about an individual selection inside of a challenge response. +@protocol STDSChallengeResponseSelectionInfo + +/// The name of the selection option. +@property (nonatomic, readonly) NSString *name; + +/// The value of the selection option. +@property (nonatomic, readonly) NSString *value; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSChallengeResponseSelectionInfoObject.h b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSChallengeResponseSelectionInfoObject.h new file mode 100644 index 0000000..6e34b6c --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSChallengeResponseSelectionInfoObject.h @@ -0,0 +1,21 @@ +// +// STDSChallengeResponseSelectionInfoObject.h +// Stripe3DS2 +// +// Created by Andrew Harrison on 2/25/19. +// Copyright © 2019 Stripe. All rights reserved. +// + +#import +#import "STDSChallengeResponseSelectionInfo.h" + +NS_ASSUME_NONNULL_BEGIN + +/// An object used to represent information about an individual selection inside of a challenge response. +@interface STDSChallengeResponseSelectionInfoObject: NSObject + +- (instancetype)initWithName:(NSString *)name value:(NSString *)value; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSChallengeResponseSelectionInfoObject.m b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSChallengeResponseSelectionInfoObject.m new file mode 100644 index 0000000..8aa22ee --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSChallengeResponseSelectionInfoObject.m @@ -0,0 +1,46 @@ +// +// STDSChallengeResponseSelectionInfoObject.m +// Stripe3DS2 +// +// Created by Andrew Harrison on 2/25/19. +// Copyright © 2019 Stripe. All rights reserved. +// + +#import "STDSChallengeResponseSelectionInfoObject.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface STDSChallengeResponseSelectionInfoObject() + +@property (nonatomic, strong) NSString *name; +@property (nonatomic, strong) NSString *value; + +@end + +@implementation STDSChallengeResponseSelectionInfoObject + +- (instancetype)initWithName:(NSString *)name value:(NSString *)value { + self = [super init]; + + if (self) { + _name = name; + _value = value; + } + + return self; +} + ++ (nullable instancetype)decodedObjectFromJSON:(nullable NSDictionary *)json error:(NSError * _Nullable __autoreleasing * _Nullable)outError { + if (json == nil) { + return nil; + } + + NSString *name = [json allKeys].firstObject; + NSString *value = [json objectForKey:name]; + + return [[STDSChallengeResponseSelectionInfoObject alloc] initWithName:name value:value]; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSChallengeResponseViewController.h b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSChallengeResponseViewController.h new file mode 100644 index 0000000..e1ace0c --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSChallengeResponseViewController.h @@ -0,0 +1,80 @@ +// +// STDSChallengeResponseViewController.h +// Stripe3DS2 +// +// Created by Andrew Harrison on 3/4/19. +// Copyright © 2019 Stripe. All rights reserved. +// + +#import +#import "STDSChallengeResponse.h" +#import "STDSUICustomization.h" +#import "STDSImageLoader.h" +#import "STDSDirectoryServer.h" + +@class STDSChallengeResponseViewController; + +NS_ASSUME_NONNULL_BEGIN + +@protocol STDSChallengeResponseViewControllerDelegate + +/** + Called when the user taps the Submit button after entering text in the Text flow (STDSACSUITypeText) + */ +- (void)challengeResponseViewController:(STDSChallengeResponseViewController *)viewController didSubmitInput:(NSString *)userInput + whitelistSelection: (id) whitelistSelection; + +/** + Called when the user taps the Submit button after selecting one or more options in the Single-Select (STDSACSUITypeSingleSelect) or Multi-Select (STDSACSUITypeMultiSelect) flow. + */ +- (void)challengeResponseViewController:(STDSChallengeResponseViewController *)viewController didSubmitSelection:(NSArray> *)selection whitelistSelection: (id) whitelistSelection; + +/** + Called when the user submits an HTML form. + */ +- (void)challengeResponseViewController:(STDSChallengeResponseViewController *)viewController didSubmitHTMLForm:(NSString *)form; + +/** + Called when the user taps the Continue button from an Out-of-Band flow (STDSACSUITypeOOB). + */ +- (void)challengeResponseViewControllerDidOOBContinue:(STDSChallengeResponseViewController *)viewController whitelistSelection: (id) whitelistSelection; + +/** + Called when the user taps the Cancel button. + */ +- (void)challengeResponseViewControllerDidCancel:(STDSChallengeResponseViewController *)viewController; + +/** + Called when the user taps the Resend button. + */ +- (void)challengeResponseViewControllerDidRequestResend:(STDSChallengeResponseViewController *)viewController; + +@end + +@protocol STDSChallengeResponseViewControllerPresentationDelegate + +- (void)dismissChallengeResponseViewController:(STDSChallengeResponseViewController *)viewController; + +@end + +@interface STDSChallengeResponseViewController : UIViewController + +@property (nonatomic, weak) id delegate; + +@property (nonatomic, nullable, weak) id presentationDelegate; + +/// Use setChallengeResponser:animated: to update this value +@property (nonatomic, strong, readonly) id response; + +- (instancetype)initWithUICustomization:(STDSUICustomization * _Nullable)uiCustomization imageLoader:(STDSImageLoader *)imageLoader directoryServer:(STDSDirectoryServer)directoryServer; + +/// If `setLoading` was called beforehand, this waits until the loading spinner has been shown for at least 1 second before displaying the challenge responseself.processingView.isHidden. +- (void)setChallengeResponse:(id)response animated:(BOOL)animated; + +- (void)setLoading; + +- (void)dismiss; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSChallengeResponseViewController.m b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSChallengeResponseViewController.m new file mode 100644 index 0000000..7f313c8 --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSChallengeResponseViewController.m @@ -0,0 +1,571 @@ +// +// STDSChallengeResponseViewController.m +// Stripe3DS2 +// +// Created by Andrew Harrison on 3/4/19. +// Copyright © 2019 Stripe. All rights reserved. +// + +@import WebKit; + +#import "STDSBundleLocator.h" +#import "STDSLocalizedString.h" +#import "STDSChallengeResponseViewController.h" +#import "STDSImageLoader.h" +#import "STDSStackView.h" +#import "STDSBrandingView.h" +#import "STDSChallengeInformationView.h" +#import "STDSChallengeSelectionView.h" +#import "STDSTextChallengeView.h" +#import "STDSWhitelistView.h" +#import "STDSExpandableInformationView.h" +#import "STDSWebView.h" +#import "STDSProcessingView.h" +#import "UIView+LayoutSupport.h" +#import "NSString+EmptyChecking.h" +#import "UIColor+DefaultColors.h" +#import "UIButton+CustomInitialization.h" +#import "UIFont+DefaultFonts.h" +#import "UIViewController+Stripe3DS2.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface STDSChallengeResponseViewController() + +@property (nonatomic, strong, nullable) id response; +@property (nonatomic) STDSDirectoryServer directoryServer; +/// Used to track how long we've been showing a loading spinner. Nil if we are not showing a spinner. +@property (nonatomic, strong, nullable) NSDate *loadingStartDate; +@property (nonatomic, strong, nullable) STDSUICustomization *uiCustomization; +@property (nonatomic, strong) STDSImageLoader *imageLoader; +@property (nonatomic, strong) NSTimer *processingTimer; +@property (nonatomic, getter=isLoading) BOOL loading; +@property (nonatomic, strong) STDSProcessingView *processingView; +@property (nonatomic, strong, nullable) UIScrollView *scrollView; +@property (nonatomic, strong, nullable) STDSWebView *webView; +@property (nonatomic, strong, nullable) STDSChallengeInformationView *challengeInformationView; +@property (nonatomic, strong) UITapGestureRecognizer *tapOutsideKeyboardGestureRecognizer; + +// User input views +@property (nonatomic, strong) STDSChallengeSelectionView *challengeSelectionView; +@property (nonatomic, strong) STDSTextChallengeView *textChallengeView; +@property (nonatomic, strong) STDSWhitelistView *whitelistView; +@property (nonatomic, strong) UIStackView *buttonStackView; +@end + +@implementation STDSChallengeResponseViewController + +static const NSTimeInterval kInterstepProcessingTime = 1.0; +static const NSTimeInterval kDefaultTransitionAnimationDuration = 0.3; +static const CGFloat kBrandingViewHeight = 107; +static const CGFloat kContentHorizontalInset = 16; +static const CGFloat kExpandableContentHorizontalInset = 27; +static const CGFloat kContentViewTopPadding = 16; +static const CGFloat kContentViewBottomPadding = 26; +static const CGFloat kExpandableContentViewTopPadding = 28; + +static NSString * const kHTMLStringLoadingURL = @"about:blank"; + +- (instancetype)initWithUICustomization:(STDSUICustomization * _Nullable)uiCustomization imageLoader:(STDSImageLoader *)imageLoader directoryServer:(STDSDirectoryServer)directoryServer { + self = [super initWithNibName:nil bundle:nil]; + + if (self) { + _uiCustomization = uiCustomization; + _imageLoader = imageLoader; + _tapOutsideKeyboardGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(_didTapOutsideKeyboard:)]; + _directoryServer = directoryServer; + } + + return self; +} + +- (void)viewDidLoad { + [super viewDidLoad]; + [self _stds_setupNavigationBarElementsWithCustomization:_uiCustomization cancelButtonSelector:@selector(_cancelButtonTapped:)]; + self.view.backgroundColor = self.uiCustomization.backgroundColor; + + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_keyboardDidShow:) name:UIKeyboardDidShowNotification object:nil]; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil]; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_applicationWillEnterForeground:) name:UIApplicationWillEnterForegroundNotification object:nil]; + + NSString *imageName = STDSDirectoryServerImageName(self.directoryServer); + UIImage *dsImage = imageName ? [UIImage imageNamed:imageName inBundle:[STDSBundleLocator stdsResourcesBundle] compatibleWithTraitCollection:nil] : nil; + self.processingView = [[STDSProcessingView alloc] initWithCustomization:self.uiCustomization directoryServerLogo:dsImage]; + self.processingView.hidden = !self.isLoading; + + [self.view addSubview:self.processingView]; + [self.processingView _stds_pinToSuperviewBoundsWithoutMargin]; + + [self.view addGestureRecognizer:self.tapOutsideKeyboardGestureRecognizer]; +} + +- (UIStatusBarStyle)preferredStatusBarStyle { + return self.uiCustomization.preferredStatusBarStyle; +} + +#pragma mark - Public APIs + +- (void)setLoading { + [self _setLoading:YES]; +} + +- (void)setChallengeResponse:(id)response animated:(BOOL)animated { + BOOL isFirstChallengeResponse = _response == nil; + _response = response; + + [self.processingTimer invalidate]; + + if (isFirstChallengeResponse || !self.isLoading || !self.loadingStartDate) { + [self _displayChallengeResponseAnimated:animated]; + } else { + // Show the loading spinner for at least kDefaultProcessingTime seconds before displaying + NSTimeInterval timeSpentLoading = [[NSDate date] timeIntervalSinceDate:self.loadingStartDate]; + if (timeSpentLoading >= kInterstepProcessingTime) { + // loadingStartDate is nil if we called this method in between viewDidLoad and viewDidAppear. + // There is no time requirement for the initial CRes. + [self _displayChallengeResponseAnimated:animated]; + } else { + self.processingTimer = [NSTimer timerWithTimeInterval:(kInterstepProcessingTime - timeSpentLoading) target:self selector:@selector(_timerDidFire:) userInfo:@(animated) repeats:NO]; + [[NSRunLoop currentRunLoop] addTimer:self.processingTimer forMode:NSDefaultRunLoopMode]; + } + } +} + +- (void)dismiss { + if (self.presentationDelegate) { + [self.presentationDelegate dismissChallengeResponseViewController:self]; + } else { + [self dismissViewControllerAnimated:YES completion:nil]; + } +} + +#pragma mark - Private Helpers + +- (void)_setLoading:(BOOL)isLoading { + self.loading = isLoading; + if (!self.viewLoaded || isLoading == !self.processingView.isHidden) { + return; + } + + /* According to the specs [0], this should be set to NO during AReq/Ares and YES during CReq/CRes. + However, according to UL test feedback [1], the AReq/ARes and initial CReq/CRes processing views should be identical. + + [0]: EMV 3-D Secure Protocol and Core Functions Specification v2.1.0 4.2.1.1 + - "The 3DS SDK shall for the CReq/CRes message exchange...[Req 148] Not include the DS logo or any other design element in the Processing screen." + - "The 3DS SDK shall for the AReq/ARes message exchange...[Req 143] If requested, integrate the DS logo into the Processing screen." + + [1]: UL_PreCompTestReport_ID846_201906_1.0 + - "Visual test case TC_SDK_10022_001 - The test case is FAILED because the processing screen for step 1 and step 2 are not identical. Step 1 displays a 'DS logo' while step 2 does not. + + To pass certification, we'll show the DS logo during the initial CReq/CRes (when self.response == nil). + */ + self.processingView.shouldDisplayDSLogo = self.response == nil; + // If there's no response, the blur view has nothing to blur and looks better visually if it's just the background color + // EDIT Jan 2021: The challenge contents is hidden so this never looks good https://jira.corp.stripe.com/browse/MOBILESDK-153 + self.processingView.shouldDisplayBlurView = NO; // self.response != nil; + + if (isLoading) { + [self.view bringSubviewToFront:self.processingView]; + self.processingView.hidden = NO; + + self.loadingStartDate = [NSDate date]; + UIAccessibilityPostNotification(UIAccessibilityScreenChangedNotification, STDSLocalizedString(@"Loading", @"Spoken by VoiceOver when the challenge is loading.")); + } else { + self.processingView.hidden = YES; + self.loadingStartDate = nil; + } +} + +- (void)_timerDidFire:(NSTimer *)timer { + BOOL animated = ((NSNumber *)timer.userInfo).boolValue; + [self.processingTimer invalidate]; + [self _displayChallengeResponseAnimated:animated]; +} + +- (void)_setupViewHierarchy { + self.scrollView = [[UIScrollView alloc] init]; + self.scrollView.backgroundColor = self.uiCustomization.footerCustomization.backgroundColor; + self.scrollView.alwaysBounceVertical = YES; + [self.view addSubview:self.scrollView]; + [self.scrollView _stds_pinToSuperviewBoundsWithoutMargin]; + + STDSStackView *containerStackView = [[STDSStackView alloc] initWithAlignment:STDSStackViewLayoutAxisVertical]; + [self.scrollView addSubview:containerStackView]; + [containerStackView _stds_pinToSuperviewBoundsWithoutMargin]; + + UIView *contentView = [UIView new]; + contentView.layoutMargins = UIEdgeInsetsMake(kContentViewTopPadding, kContentHorizontalInset, kContentViewBottomPadding, kContentHorizontalInset); + contentView.backgroundColor = self.uiCustomization.backgroundColor; + [containerStackView addArrangedSubview:contentView]; + + STDSStackView *contentStackView = [[STDSStackView alloc] initWithAlignment:STDSStackViewLayoutAxisVertical]; + [contentView addSubview:contentStackView]; + [contentStackView _stds_pinToSuperviewBounds]; + + STDSBrandingView *brandingView = [self _newConfiguredBrandingView]; + STDSChallengeInformationView *challengeInformationView = [self _newConfiguredChallengeInformationView]; + self.challengeInformationView = challengeInformationView; + UIButton *actionButton = [self _newConfiguredActionButton]; + UIButton *resendButton = [self _newConfiguredResendButton]; + STDSTextChallengeView *textChallengeView = [self _newConfiguredTextChallengeView]; + self.textChallengeView = textChallengeView; + STDSChallengeSelectionView *challengeSelectionView = [self _newConfiguredChallengeSelectionView]; + self.challengeSelectionView = challengeSelectionView; + self.whitelistView = [self _newConfiguredWhitelistView]; + + UIView *expandableContentView = [UIView new]; + expandableContentView.layoutMargins = UIEdgeInsetsMake(kExpandableContentViewTopPadding, kExpandableContentHorizontalInset, 0, kExpandableContentHorizontalInset); + [containerStackView addArrangedSubview:expandableContentView]; + + STDSStackView *expandableContentStackView = [[STDSStackView alloc] initWithAlignment:STDSStackViewLayoutAxisVertical]; + [expandableContentView addSubview:expandableContentStackView]; + [expandableContentStackView _stds_pinToSuperviewBounds]; + + STDSExpandableInformationView *whyInformationView = [self _newConfiguredWhyInformationView]; + STDSExpandableInformationView *expandableInformationView = [self _newConfiguredExpandableInformationView]; + + [contentStackView addArrangedSubview:brandingView]; + [contentStackView addArrangedSubview:challengeInformationView]; + [contentStackView addArrangedSubview:textChallengeView]; + [contentStackView addArrangedSubview:challengeSelectionView]; + + self.buttonStackView = [self _newSubmitButtonStackView]; + + [self.buttonStackView addArrangedSubview:actionButton]; + + [contentStackView addArrangedSubview:self.buttonStackView]; + + if (_response.acsUIType != STDSACSUITypeOOB && _response.acsUIType != STDSACSUITypeMultiSelect && _response.acsUIType != STDSACSUITypeSingleSelect) { + [self.buttonStackView addArrangedSubview:resendButton]; + } + if (!self.whitelistView.isHidden) { + [contentStackView addSpacer:10]; + } + [contentStackView addArrangedSubview:self.whitelistView]; + [expandableContentStackView addArrangedSubview:whyInformationView]; + [expandableContentStackView addArrangedSubview:expandableInformationView]; + + NSLayoutConstraint *contentViewWidth = [NSLayoutConstraint constraintWithItem:containerStackView attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:self.scrollView attribute:NSLayoutAttributeWidth multiplier:1 constant:0]; + NSLayoutConstraint *brandingViewHeightConstraint = [NSLayoutConstraint constraintWithItem:brandingView attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1 constant:kBrandingViewHeight]; + [NSLayoutConstraint activateConstraints:@[brandingViewHeightConstraint, contentViewWidth]]; + + [self _loadBrandingViewImages:brandingView]; +} + +- (void)_setupWebView { + self.webView = [[STDSWebView alloc] init]; + self.webView.navigationDelegate = self; + [self.view addSubview:self.webView]; + [self.webView _stds_pinToSuperviewBounds]; + [self.webView loadExternalResourceBlockingHTMLString:self.response.acsHTML]; +} + +- (void)_loadBrandingViewImages:(STDSBrandingView *)brandingView { + NSURL *issuerImageURL = [self _highestFideltyURLFromChallengeResponseImage:self.response.issuerImage]; + + if (issuerImageURL != nil) { + [self.imageLoader loadImageFromURL:issuerImageURL completion:^(UIImage * _Nullable image) { + brandingView.issuerImage = image; + }]; + } + + NSURL *paymentSystemImageURL = [self _highestFideltyURLFromChallengeResponseImage:self.response.paymentSystemImage]; + + if (paymentSystemImageURL != nil) { + [self.imageLoader loadImageFromURL:paymentSystemImageURL completion:^(UIImage * _Nullable image) { + brandingView.paymentSystemImage = image; + }]; + } +} + +- (NSURL * _Nullable)_highestFideltyURLFromChallengeResponseImage:(id )image { + return image.extraHighDensityURL ?: image.highDensityURL ?: image.mediumDensityURL; +} + +- (void)_displayChallengeResponseAnimated:(BOOL)animated { + if (self.response != nil) { + [self _setLoading:NO]; + + UIScrollView *existingScrollView = self.scrollView; + STDSWebView *existingWebView = self.webView; + + void (^transitionBlock)(UIView *, BOOL) = ^void(UIView *viewToTransition, BOOL animated) { + NSTimeInterval transitionTime = animated ? kDefaultTransitionAnimationDuration : 0; + viewToTransition.alpha = 0; + [UIView animateWithDuration:transitionTime animations:^{ + viewToTransition.alpha = 1; + } completion:^(BOOL finished) { + [existingScrollView removeFromSuperview]; + [existingWebView removeFromSuperview]; + [[NSNotificationCenter defaultCenter] postNotificationName:@"STDSChallengeResponseViewController.didDisplayChallengeResponse" object:self]; + UIAccessibilityPostNotification(UIAccessibilityScreenChangedNotification, self.navigationItem.titleView); + }]; + }; + + switch (self.response.acsUIType) { + case STDSACSUITypeNone: + break; + case STDSACSUITypeText: + case STDSACSUITypeSingleSelect: + case STDSACSUITypeMultiSelect: + case STDSACSUITypeOOB: + [self _setupViewHierarchy]; + + transitionBlock(self.scrollView, animated); + break; + case STDSACSUITypeHTML: + [self _setupWebView]; + + transitionBlock(self.webView, animated); + break; + } + } +} + +- (STDSBrandingView *)_newConfiguredBrandingView { + STDSBrandingView *brandingView = [[STDSBrandingView alloc] init]; + brandingView.hidden = self.response.issuerImage == nil && self.response.paymentSystemImage == nil; + + return brandingView; +} + +- (STDSChallengeInformationView *)_newConfiguredChallengeInformationView { + STDSChallengeInformationView *challengeInformationView = [[STDSChallengeInformationView alloc] init]; + challengeInformationView.headerText = self.response.challengeInfoHeader; + challengeInformationView.challengeInformationText = self.response.challengeInfoText; + challengeInformationView.challengeInformationLabel = self.response.challengeInfoLabel; + challengeInformationView.labelCustomization = self.uiCustomization.labelCustomization; + + if (self.response.showChallengeInfoTextIndicator) { + challengeInformationView.textIndicatorImage = [UIImage imageNamed:@"error" inBundle:[STDSBundleLocator stdsResourcesBundle] compatibleWithTraitCollection:nil]; + } + + return challengeInformationView; +} + +- (STDSTextChallengeView *)_newConfiguredTextChallengeView { + STDSTextChallengeView *textChallengeView = [[STDSTextChallengeView alloc] init]; + textChallengeView.hidden = self.response.acsUIType != STDSACSUITypeText; + textChallengeView.textFieldCustomization = self.uiCustomization.textFieldCustomization; + textChallengeView.textField.accessibilityLabel = self.response.challengeInfoLabel; + textChallengeView.backgroundColor = self.uiCustomization.backgroundColor; + + return textChallengeView; +} + +- (STDSChallengeSelectionView *)_newConfiguredChallengeSelectionView { + STDSChallengeSelectionStyle selectionStyle = self.response.acsUIType == STDSACSUITypeMultiSelect ? STDSChallengeSelectionStyleMulti : STDSChallengeSelectionStyleSingle; + STDSChallengeSelectionView *challengeSelectionView = [[STDSChallengeSelectionView alloc] initWithChallengeSelectInfo:self.response.challengeSelectInfo selectionStyle:selectionStyle]; + challengeSelectionView.hidden = self.response.acsUIType != STDSACSUITypeSingleSelect && self.response.acsUIType != STDSACSUITypeMultiSelect; + challengeSelectionView.labelCustomization = self.uiCustomization.labelCustomization; + challengeSelectionView.selectionCustomization = self.uiCustomization.selectionCustomization; + challengeSelectionView.backgroundColor = self.uiCustomization.backgroundColor; + + return challengeSelectionView; +} + +- (UIButton *)_newConfiguredActionButton { + STDSUICustomizationButtonType buttonType = STDSUICustomizationButtonTypeSubmit; + NSString *buttonTitle; + + switch (self.response.acsUIType) { + case STDSACSUITypeNone: + break; + case STDSACSUITypeText: + case STDSACSUITypeSingleSelect: + case STDSACSUITypeMultiSelect: { + buttonTitle = self.response.submitAuthenticationLabel; + + break; + } + case STDSACSUITypeOOB: { + buttonType = STDSUICustomizationButtonTypeContinue; + buttonTitle = self.response.oobContinueLabel; + + break; + } + case STDSACSUITypeHTML: + break; + } + + STDSButtonCustomization *buttonCustomization = [self.uiCustomization buttonCustomizationForButtonType:buttonType]; + UIButton *actionButton = [UIButton _stds_buttonWithTitle:buttonTitle customization:buttonCustomization]; + [actionButton addTarget:self action:@selector(_actionButtonTapped:) forControlEvents:UIControlEventTouchUpInside]; + actionButton.hidden = buttonTitle == nil || [NSString _stds_isStringEmpty:buttonTitle]; + actionButton.accessibilityIdentifier = @"Continue"; + + return actionButton; +} + +- (UIButton *)_newConfiguredResendButton { + STDSButtonCustomization *buttonCustomization = [self.uiCustomization buttonCustomizationForButtonType:STDSUICustomizationButtonTypeResend]; + + NSString *resendButtonTitle = self.response.resendInformationLabel; + UIButton *resendButton = [UIButton _stds_buttonWithTitle:resendButtonTitle customization:buttonCustomization]; + + resendButton.hidden = resendButtonTitle == nil || [NSString _stds_isStringEmpty:resendButtonTitle]; + [resendButton addTarget:self action:@selector(_resendButtonTapped:) forControlEvents:UIControlEventTouchUpInside]; + + return resendButton; +} + +- (STDSWhitelistView *)_newConfiguredWhitelistView { + STDSWhitelistView *whitelistView = [[STDSWhitelistView alloc] init]; + whitelistView.whitelistText = self.response.whitelistingInfoText; + whitelistView.labelCustomization = self.uiCustomization.labelCustomization; + whitelistView.selectionCustomization = self.uiCustomization.selectionCustomization; + whitelistView.hidden = whitelistView.whitelistText == nil; + whitelistView.accessibilityIdentifier = @"STDSWhitelistView"; + + return whitelistView; +} + +- (STDSExpandableInformationView *)_newConfiguredWhyInformationView { + STDSExpandableInformationView *whyInformationView = [[STDSExpandableInformationView alloc] init]; + whyInformationView.title = self.response.whyInfoLabel; + whyInformationView.text = self.response.whyInfoText; + whyInformationView.customization = self.uiCustomization.footerCustomization; + whyInformationView.hidden = whyInformationView.title == nil; + whyInformationView.backgroundColor = self.uiCustomization.footerCustomization.backgroundColor; + __weak typeof(self) weakSelf = self; + whyInformationView.didTap = ^{ + [weakSelf.textChallengeView endEditing:NO]; + }; + + return whyInformationView; +} + +- (STDSExpandableInformationView *)_newConfiguredExpandableInformationView { + + STDSExpandableInformationView *expandableInformationView = [[STDSExpandableInformationView alloc] init]; + expandableInformationView.title = self.response.expandInfoLabel; + expandableInformationView.text = self.response.expandInfoText; + expandableInformationView.customization = self.uiCustomization.footerCustomization; + expandableInformationView.hidden = expandableInformationView.title == nil; + expandableInformationView.backgroundColor = self.uiCustomization.footerCustomization.backgroundColor; + __weak typeof(self) weakSelf = self; + expandableInformationView.didTap = ^{ + [weakSelf.textChallengeView endEditing:NO]; + }; + + return expandableInformationView; +} + +- (UIStackView *)_newSubmitButtonStackView { + UIStackView *stackView = [[UIStackView alloc] init]; + stackView.axis = UILayoutConstraintAxisVertical; + stackView.distribution = UIStackViewDistributionFillEqually; + stackView.alignment = UIStackViewAlignmentFill; + stackView.spacing = 5; + stackView.translatesAutoresizingMaskIntoConstraints = NO; + + CGSize size = [UIScreen mainScreen].bounds.size; + if (size.width > size.height) { + // hack to detect landscape + stackView.axis = UILayoutConstraintAxisHorizontal; + stackView.alignment = UIStackViewAlignmentCenter; + } + return stackView; +} + +- (void)_keyboardDidShow:(NSNotification *)notification { + CGSize keyboardSize = [[[notification userInfo] objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue].size; + UIEdgeInsets contentInsets = UIEdgeInsetsMake(self.scrollView.contentInset.top, 0.0, keyboardSize.height, 0.0); + self.scrollView.contentInset = contentInsets; + self.scrollView.scrollIndicatorInsets = contentInsets; +} + +- (void)_keyboardWillHide:(NSNotification *)notification { + UIEdgeInsets contentInsets = UIEdgeInsetsMake(self.scrollView.contentInset.top, 0.0, 0.0, 0.0); + self.scrollView.contentInset = contentInsets; + self.scrollView.scrollIndicatorInsets = contentInsets; +} + +- (void)_applicationWillEnterForeground:(NSNotification *)notification { + if (self.response.acsUIType == STDSACSUITypeOOB && self.response.challengeAdditionalInfoText) { + // [Req 316] When Challenge Additional Information Text is present, the SDK would replace the Challenge Information Text and Challenge Information Text Indicator with the Challenge Additional Information Text when the 3DS Requestor App is moved to the foreground. + self.challengeInformationView.challengeInformationText = self.response.challengeAdditionalInfoText; + self.challengeInformationView.textIndicatorImage = nil; + } else if (self.response.acsUIType == STDSACSUITypeHTML && self.response.acsHTMLRefresh) { + // [Req 317] When the ACS HTML Refresh element is present, the SDK replaces the ACS HTML with the contents of ACS HTML Refresh when the 3DS Requestor App is moved to the foreground. + [self.webView loadExternalResourceBlockingHTMLString:self.response.acsHTMLRefresh]; + } +} + +- (void)_didTapOutsideKeyboard:(UIGestureRecognizer *)gestureRecognizer { + // Note this doesn't fire if a subview handles the touch (e.g. UIControls, STDSExpandableInformationView) + [self.textChallengeView endEditing:NO]; +} + +#pragma mark - Button callbacks + +- (void)_cancelButtonTapped:(UIButton *)sender { + [self.textChallengeView endEditing:NO]; + [self.delegate challengeResponseViewControllerDidCancel:self]; +} + +- (void)_resendButtonTapped:(UIButton *)sender { + [self.textChallengeView endEditing:NO]; + [self.delegate challengeResponseViewControllerDidRequestResend:self]; +} + +- (void)_actionButtonTapped:(UIButton *)sender { + [self.textChallengeView endEditing:NO]; + switch (self.response.acsUIType) { + case STDSACSUITypeNone: + break; + case STDSACSUITypeText: { + [self.delegate challengeResponseViewController:self + didSubmitInput:self.textChallengeView.inputText + whitelistSelection:self.whitelistView.selectedResponse]; + break; + } + case STDSACSUITypeSingleSelect: + case STDSACSUITypeMultiSelect: { + [self.delegate challengeResponseViewController:self + didSubmitSelection:self.challengeSelectionView.currentlySelectedChallengeInfo + whitelistSelection:self.whitelistView.selectedResponse]; + break; + } + case STDSACSUITypeOOB: + [self.delegate challengeResponseViewControllerDidOOBContinue:self + whitelistSelection:self.whitelistView.selectedResponse]; + break; + case STDSACSUITypeHTML: + // No action button in this case, see WKNavigationDelegate. + break; + } +} + +#pragma mark - WKNavigationDelegate + +- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler { + + NSURLRequest *request = navigationAction.request; + + if ([request.URL.absoluteString isEqualToString:kHTMLStringLoadingURL]) { + return decisionHandler(WKNavigationActionPolicyAllow); + } else { + if (navigationAction.navigationType == WKNavigationTypeFormSubmitted || navigationAction.navigationType == WKNavigationTypeOther) { + // When the Cardholder’s response is returned as a parameter string, the form data is passed to the web view instance by triggering a location change to a specified (HTTPS://EMV3DS/challenge) URL with the challenge responses appended to the location URL as query parameters (for example, HTTPS://EMV3DS/challenge?city=Pittsburgh). The web view instance, because it monitors URL changes, receives the Cardholder’s responses as query parameters. + [self.delegate challengeResponseViewController:self didSubmitHTMLForm:request.URL.query]; + } + + return decisionHandler(WKNavigationActionPolicyCancel); + } +} + +- (void) viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id)coordinator { + if (size.width > size.height) { + // hack to detect landscape + self.buttonStackView.axis = UILayoutConstraintAxisHorizontal; + self.buttonStackView.alignment = UIStackViewAlignmentCenter; + } else { + self.buttonStackView.axis = UILayoutConstraintAxisVertical; + self.buttonStackView.alignment = UIStackViewAlignmentFill; + } +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSChallengeSelectionView.h b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSChallengeSelectionView.h new file mode 100644 index 0000000..5ac5be0 --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSChallengeSelectionView.h @@ -0,0 +1,35 @@ +// +// STDSChallengeSelectionView.h +// Stripe3DS2 +// +// Created by Andrew Harrison on 3/6/19. +// Copyright © 2019 Stripe. All rights reserved. +// + +#import +#import "STDSChallengeResponseSelectionInfo.h" +#import "STDSLabelCustomization.h" +#import "STDSSelectionCustomization.h" + +NS_ASSUME_NONNULL_BEGIN + +typedef NS_ENUM(NSInteger, STDSChallengeSelectionStyle) { + + /// A display style for selecting a single option. + STDSChallengeSelectionStyleSingle = 0, + + /// A display style for selection multiple options. + STDSChallengeSelectionStyleMulti = 1, +}; + +@interface STDSChallengeSelectionView : UIView + +@property (nonatomic, strong, readonly) NSArray> *currentlySelectedChallengeInfo; +@property (nonatomic, strong) STDSLabelCustomization *labelCustomization; +@property (nonatomic, strong) STDSSelectionCustomization *selectionCustomization; + +- (instancetype)initWithChallengeSelectInfo:(NSArray> *)challengeSelectInfo selectionStyle:(STDSChallengeSelectionStyle)selectionStyle; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSChallengeSelectionView.m b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSChallengeSelectionView.m new file mode 100644 index 0000000..0b4d15b --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSChallengeSelectionView.m @@ -0,0 +1,255 @@ +// +// STDSChallengeSelectionView.m +// Stripe3DS2 +// +// Created by Andrew Harrison on 3/6/19. +// Copyright © 2019 Stripe. All rights reserved. +// + +#import "STDSLocalizedString.h" +#import "STDSBundleLocator.h" +#import "STDSChallengeSelectionView.h" +#import "STDSStackView.h" +#import "UIView+LayoutSupport.h" +#import "STDSSelectionButton.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface STDSChallengeResponseSelectionRow: STDSStackView + +typedef NS_ENUM(NSInteger, STDSChallengeResponseSelectionRowStyle) { + + /// A display style for showing a radio button. + STDSChallengeResponseSelectionRowStyleRadio = 0, + + /// A display style for shows a checkbox. + STDSChallengeResponseSelectionRowStyleCheckbox = 1, +}; + +typedef void (^STDSChallengeResponseRowSelectedBlock)(STDSChallengeResponseSelectionRow *); + +@property (nonatomic, strong, readonly) id challengeSelectInfo; +@property (nonatomic, getter=isSelected) BOOL selected; +@property (nonatomic, strong) STDSLabelCustomization *labelCustomization; +@property (nonatomic, strong) STDSSelectionCustomization *selectionCustomization; + +- (instancetype)initWithChallengeSelectInfo:(id)challengeSelectInfo rowStyle:(STDSChallengeResponseSelectionRowStyle)rowStyle rowSelectedBlock:(STDSChallengeResponseRowSelectedBlock)rowSelectedBlock; + +@end + +@interface STDSChallengeResponseSelectionRow() + +@property (nonatomic, strong) id challengeSelectInfo; +@property (nonatomic, strong) STDSChallengeResponseRowSelectedBlock rowSelectedBlock; +@property (nonatomic) STDSChallengeResponseSelectionRowStyle rowStyle; +@property (nonatomic, strong) STDSSelectionButton *selectionButton; +@property (nonatomic, strong) UILabel *valueLabel; +@property (nonatomic, strong) UITapGestureRecognizer *valueLabelTapRecognizer; + +@end + +@implementation STDSChallengeResponseSelectionRow + +- (instancetype)initWithChallengeSelectInfo:(id)challengeSelectInfo rowStyle:(STDSChallengeResponseSelectionRowStyle)rowStyle rowSelectedBlock:(STDSChallengeResponseRowSelectedBlock)rowSelectedBlock { + self = [super initWithAlignment:STDSStackViewLayoutAxisHorizontal]; + + if (self) { + _challengeSelectInfo = challengeSelectInfo; + _rowStyle = rowStyle; + _rowSelectedBlock = rowSelectedBlock; + self.isAccessibilityElement = YES; + self.accessibilityIdentifier = @"STDSChallengeResponseSelectionRow"; + + [self _setupViewHierarchy]; + } + + return self; +} + +- (void)_setupViewHierarchy { + self.selectionButton = [[STDSSelectionButton alloc] initWithCustomization:self.selectionCustomization]; + self.selectionButton.customization = self.selectionCustomization; + [self.selectionButton addTarget:self action:@selector(_rowWasSelected) forControlEvents:UIControlEventTouchUpInside]; + + if (self.rowStyle == STDSChallengeResponseSelectionRowStyleCheckbox) { + self.selectionButton.isCheckbox = YES; + } + + self.valueLabel = [[UILabel alloc] init]; + self.valueLabel.text = self.challengeSelectInfo.value; + self.valueLabel.userInteractionEnabled = YES; + self.valueLabel.numberOfLines = 0; + self.valueLabelTapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(_rowWasSelected)]; + [self.valueLabel addGestureRecognizer:self.valueLabelTapRecognizer]; + + [self addArrangedSubview:self.selectionButton]; + [self addSpacer:15.0]; + [self addArrangedSubview:self.valueLabel]; + [self addArrangedSubview:[UIView new]]; +} + +- (void)_rowWasSelected { + self.rowSelectedBlock(self); +} + +- (BOOL)isSelected { + /// Placeholder until visual and interaction design is complete. + return self.selectionButton.isSelected; +} + +- (void)setSelected:(BOOL)selected { + /// Placeholder until visual and interaction design is complete. + self.selectionButton.selected = selected; +} + +- (void)setLabelCustomization:(STDSLabelCustomization *)labelCustomization { + _labelCustomization = labelCustomization; + + self.valueLabel.font = labelCustomization.font; + self.valueLabel.textColor = labelCustomization.textColor; +} + +- (void)setSelectionCustomization:(STDSSelectionCustomization *)selectionCustomization { + _selectionCustomization = selectionCustomization; + + self.selectionButton.customization = selectionCustomization; +} + +#pragma mark - UIAccessibility + +- (BOOL)accessibilityActivate { + self.rowSelectedBlock(self); + return YES; +} + +- (nullable NSString *)accessibilityLabel { + return self.valueLabel.text; +} + +- (nullable NSString *)accessibilityValue { + return self.selected ? STDSLocalizedString(@"Selected", @"Indicates that a button is selected.") : STDSLocalizedString(@"Unselected", @"Indicates that a button is not selected."); +} + +- (UIAccessibilityTraits)accessibilityTraits { + // remove the selected trait since we manually add that as an accessibilityValue above + return (self.selectionButton.accessibilityTraits & ~UIAccessibilityTraitSelected); +} + +@end + +@interface STDSChallengeSelectionView() + +@property (nonatomic, strong) STDSStackView *containerView; +@property (nonatomic, strong) NSArray *challengeSelectionRows; + +@property (nonatomic) STDSChallengeSelectionStyle selectionStyle; + +@end + +@implementation STDSChallengeSelectionView + +static const CGFloat kChallengeSelectionViewTopPadding = 5; +static const CGFloat kChallengeSelectionViewBottomPadding = 20; +static const CGFloat kChallengeSelectionViewInterRowVerticalPadding = 16; + +- (instancetype)initWithChallengeSelectInfo:(NSArray> *)challengeSelectInfo selectionStyle:(STDSChallengeSelectionStyle)selectionStyle { + self = [super init]; + + if (self) { + _selectionStyle = selectionStyle; + _challengeSelectionRows = [self _rowsForChallengeSelectInfo:challengeSelectInfo]; + + [self _setupViewHierarchy]; + } + + return self; +} + +- (void)_setupViewHierarchy { + self.containerView = [[STDSStackView alloc] initWithAlignment:STDSStackViewLayoutAxisVertical]; + + for (STDSChallengeResponseSelectionRow *selectionRow in self.challengeSelectionRows) { + [self.containerView addArrangedSubview:selectionRow]; + + if (selectionRow != self.challengeSelectionRows.lastObject) { + [self.containerView addSpacer:kChallengeSelectionViewInterRowVerticalPadding]; + } + } + + if (self.challengeSelectionRows.count > 0) { + self.layoutMargins = UIEdgeInsetsMake(kChallengeSelectionViewTopPadding, 0, kChallengeSelectionViewBottomPadding, 0); + } else { + self.layoutMargins = UIEdgeInsetsZero; + } + + [self addSubview:self.containerView]; + [self.containerView _stds_pinToSuperviewBounds]; +} + +- (NSArray *)_rowsForChallengeSelectInfo:(NSArray> *)challengeSelectInfo { + NSMutableArray *challengeRows = [NSMutableArray array]; + STDSChallengeResponseSelectionRowStyle rowStyle = self.selectionStyle == STDSChallengeSelectionStyleSingle ? STDSChallengeResponseSelectionRowStyleRadio : STDSChallengeResponseSelectionRowStyleCheckbox; + + for (id selectionInfo in challengeSelectInfo) { + __weak typeof(self) weakSelf = self; + STDSChallengeResponseSelectionRow *challengeRow = [[STDSChallengeResponseSelectionRow alloc] initWithChallengeSelectInfo:selectionInfo rowStyle:rowStyle rowSelectedBlock:^(STDSChallengeResponseSelectionRow * _Nonnull selectedRow) { + __strong typeof(self) strongSelf = weakSelf; + + [strongSelf _rowWasSelected:selectedRow]; + }]; + + if (selectionInfo == challengeSelectInfo.firstObject && self.selectionStyle == STDSChallengeSelectionStyleSingle) { + challengeRow.selected = YES; + } + + [challengeRows addObject:challengeRow]; + } + + return [challengeRows copy]; +} + +- (void)_rowWasSelected:(STDSChallengeResponseSelectionRow *)selectedRow { + switch (self.selectionStyle) { + case STDSChallengeSelectionStyleSingle: + for (STDSChallengeResponseSelectionRow *row in self.challengeSelectionRows) { + row.selected = row == selectedRow; + } + + break; + case STDSChallengeSelectionStyleMulti: + selectedRow.selected = !selectedRow.isSelected; + break; + } +} + +- (NSArray> *)currentlySelectedChallengeInfo { + NSMutableArray *selectedChallengeInfo = [NSMutableArray array]; + + for (STDSChallengeResponseSelectionRow *selectionRow in self.challengeSelectionRows) { + if (selectionRow.isSelected) { + [selectedChallengeInfo addObject:selectionRow.challengeSelectInfo]; + } + } + + return [selectedChallengeInfo copy]; +} + +- (void)setLabelCustomization:(STDSLabelCustomization *)labelCustomization { + _labelCustomization = labelCustomization; + + for (STDSChallengeResponseSelectionRow *row in self.challengeSelectionRows) { + row.labelCustomization = labelCustomization; + } +} + +- (void)setSelectionCustomization:(STDSSelectionCustomization *)selectionCustomization { + _selectionCustomization = selectionCustomization; + + for (STDSChallengeResponseSelectionRow *row in self.challengeSelectionRows) { + row.selectionCustomization = selectionCustomization; + } +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSCompletionEvent.m b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSCompletionEvent.m new file mode 100644 index 0000000..6ee3c43 --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSCompletionEvent.m @@ -0,0 +1,26 @@ +// +// STDSCompletionEvent.m +// Stripe3DS2 +// +// Created by Yuki Tokuhiro on 3/20/19. +// Copyright © 2019 Stripe. All rights reserved. +// + +#import "STDSCompletionEvent.h" + +NS_ASSUME_NONNULL_BEGIN + +@implementation STDSCompletionEvent + +- (instancetype)initWithSDKTransactionIdentifier:(NSString *)identifier transactionStatus:(NSString *)transactionStatus { + self = [super init]; + if (self) { + _sdkTransactionIdentifier = [identifier copy]; + _transactionStatus = [transactionStatus copy]; + } + return self; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSConfigParameters.m b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSConfigParameters.m new file mode 100644 index 0000000..e334a5b --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSConfigParameters.m @@ -0,0 +1,113 @@ +// +// STDSConfigParameters.m +// Stripe3DS2 +// +// Created by Cameron Sabol on 1/22/19. +// Copyright © 2019 Stripe. All rights reserved. +// + +#import "STDSConfigParameters.h" + +#import "STDSException+Internal.h" +#import "STDSInvalidInputException.h" + +NS_ASSUME_NONNULL_BEGIN + +NSString * const kSTDSConfigDefaultGroupName = @"STDSConfigParameters.group.default"; + +@implementation STDSConfigParameters +{ + NSMutableDictionary *_parameters; +} + +- (instancetype)init { + self = [super init]; + if (self) { + _parameters = [[NSMutableDictionary alloc] init]; + } + + return self; +} + +- (instancetype)initWithStandardParameters { + self = [self init]; + if (self) { + // Nothing for now because we don't have any standard parameters + } + + return self; +} + +- (void)addParameterNamed:(NSString *)paramName withValue:(NSString *)paramValue { + [self _addParameterNamed:paramName withValue:paramValue toGroup:kSTDSConfigDefaultGroupName]; +} + +- (void)addParameterNamed:(NSString *)paramName withValue:(NSString *)paramValue toGroup:(nullable NSString *)paramGroup { + [self _addParameterNamed:paramName withValue:paramValue toGroup:paramGroup ?: kSTDSConfigDefaultGroupName]; +} + +- (void)_addParameterNamed:(NSString *)paramName withValue:(NSString *)paramValue toGroup:(NSString *)paramGroup { + if (paramName == nil) { + @throw [STDSInvalidInputException exceptionWithMessage:@"nil paramName passed to instance %@", self]; + } else if (paramValue == nil) { + @throw [STDSInvalidInputException exceptionWithMessage:@"nil paramValue passed to instance %@", self]; + } else if (paramGroup == nil) { + @throw [STDSInvalidInputException exceptionWithMessage:@"nil paramGroup passed to instance %@", self]; + } + + NSMutableDictionary *groupParameters = _parameters[paramGroup]; + if (groupParameters == nil) { + groupParameters = [[NSMutableDictionary alloc] init]; + _parameters[paramGroup] = groupParameters; + } + + if (groupParameters[paramName] != nil) { + @throw [STDSInvalidInputException exceptionWithMessage:@"Cannot override value of %@ for parameter %@ in group %@ with value %@", groupParameters[paramName], paramName, paramGroup, paramValue]; + } + + groupParameters[paramName] = paramValue; +} + +- (nullable NSString *)parameterValue:(NSString *)paramName { + return [self _parameterValue:paramName inGroup:kSTDSConfigDefaultGroupName]; +} + +- (nullable NSString *)parameterValue:(NSString *)paramName inGroup:(nullable NSString *)paramGroup { + return [self _parameterValue:paramName inGroup:paramGroup ?: kSTDSConfigDefaultGroupName]; +} + +- (nullable NSString *)_parameterValue:(NSString *)paramName inGroup:(NSString *)paramGroup { + if (paramName == nil) { + @throw [STDSInvalidInputException exceptionWithMessage:@"nil paramName passed to instance %@", self]; + } else if (paramGroup == nil) { + @throw [STDSInvalidInputException exceptionWithMessage:@"nil paramGroup passed to instance %@", self]; + } + + NSMutableDictionary *groupParameters = _parameters[paramGroup]; + return groupParameters[paramName]; +} + +- (nullable NSString *)removeParameterNamed:(NSString *)paramName { + return [self _removeParameterNamed:paramName fromGroup:kSTDSConfigDefaultGroupName]; +} + +- (nullable NSString *)removeParameterNamed:(NSString *)paramName fromGroup:(nullable NSString *)paramGroup { + return [self _removeParameterNamed:paramName fromGroup:paramGroup ?: kSTDSConfigDefaultGroupName]; +} + +- (nullable NSString *)_removeParameterNamed:(NSString *)paramName fromGroup:(NSString *)paramGroup { + if (paramName == nil) { + @throw [STDSInvalidInputException exceptionWithMessage:@"nil paramName passed to instance %@", self]; + } else if (paramGroup == nil) { + @throw [STDSInvalidInputException exceptionWithMessage:@"nil paramGroup passed to instance %@", self]; + } + + NSMutableDictionary *groupParameters = _parameters[paramGroup]; + NSString *paramValue = groupParameters[paramName]; + [groupParameters removeObjectForKey:paramName]; + return paramValue; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSCustomization.m b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSCustomization.m new file mode 100644 index 0000000..4544024 --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSCustomization.m @@ -0,0 +1,25 @@ +// +// STDSCustomization.m +// Stripe3DS2 +// +// Created by Andrew Harrison on 3/14/19. +// Copyright © 2019 Stripe. All rights reserved. +// + +#import "STDSCustomization.h" + +NS_ASSUME_NONNULL_BEGIN + +@implementation STDSCustomization + +- (id)copyWithZone:(nullable NSZone *)zone { + STDSCustomization *copy = [[[self class] allocWithZone:zone] init]; + copy.font = self.font; + copy.textColor = self.textColor; + + return copy; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSDebuggerChecker.h b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSDebuggerChecker.h new file mode 100644 index 0000000..a50689f --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSDebuggerChecker.h @@ -0,0 +1,19 @@ +// +// STDSDebuggerChecker.h +// Stripe3DS2 +// +// Created by Andrew Harrison on 4/8/19. +// Copyright © 2019 Stripe. All rights reserved. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface STDSDebuggerChecker : NSObject + ++ (BOOL)processIsCurrentlyAttachedToDebugger; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSDebuggerChecker.m b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSDebuggerChecker.m new file mode 100644 index 0000000..cbe3a05 --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSDebuggerChecker.m @@ -0,0 +1,54 @@ +// +// STDSDebuggerChecker.m +// Stripe3DS2 +// +// Created by Andrew Harrison on 4/8/19. +// Copyright © 2019 Stripe. All rights reserved. +// + +#import "STDSDebuggerChecker.h" + +#include +#include +#include +#include +#include + +NS_ASSUME_NONNULL_BEGIN + +@implementation STDSDebuggerChecker + +// This checking code has been lifted from the apple documentation on how to determine if you're attached to a debugger: https://developer.apple.com/library/archive/qa/qa1361/_index.html ++ (BOOL)processIsCurrentlyAttachedToDebugger { + int junk; + int mib[4]; + struct kinfo_proc info; + size_t size; + + // Initialize the flags so that, if sysctl fails for some bizarre + // reason, we get a predictable result. + + info.kp_proc.p_flag = 0; + + // Initialize mib, which tells sysctl the info we want, in this case + // we're looking for information about a specific process ID. + + mib[0] = CTL_KERN; + mib[1] = KERN_PROC; + mib[2] = KERN_PROC_PID; + mib[3] = getpid(); + + // Call sysctl. + + size = sizeof(info); + junk = sysctl(mib, sizeof(mib) / sizeof(*mib), &info, &size, NULL, 0); + assert(junk == 0); + + // We're being debugged if the P_TRACED flag is set. + + return ( (info.kp_proc.p_flag & P_TRACED) != 0 ); +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSDeviceInformation.h b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSDeviceInformation.h new file mode 100644 index 0000000..d73e187 --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSDeviceInformation.h @@ -0,0 +1,21 @@ +// +// STDSDeviceInformation.h +// Stripe3DS2 +// +// Created by Cameron Sabol on 3/25/19. +// Copyright © 2019 Stripe. All rights reserved. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface STDSDeviceInformation : NSObject + +- (instancetype)initWithDictionary:(NSDictionary *)deviceInformationDict; + +@property (nonatomic, copy, readonly) NSDictionary *dictionaryValue; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSDeviceInformation.m b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSDeviceInformation.m new file mode 100644 index 0000000..9242543 --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSDeviceInformation.m @@ -0,0 +1,30 @@ +// +// STDSDeviceInformation.m +// Stripe3DS2 +// +// Created by Cameron Sabol on 3/25/19. +// Copyright © 2019 Stripe. All rights reserved. +// + +#import "STDSDeviceInformation.h" + +NS_ASSUME_NONNULL_BEGIN + +@implementation STDSDeviceInformation + +- (instancetype)initWithDictionary:(NSDictionary *)deviceInformationDict { + self = [super init]; + if (self) { + _dictionaryValue = [deviceInformationDict copy]; + } + + return self; +} + +- (NSString *)description { + return [NSString stringWithFormat:@"%@ : %@", [super description], _dictionaryValue]; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSDeviceInformationManager.h b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSDeviceInformationManager.h new file mode 100644 index 0000000..b23abfe --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSDeviceInformationManager.h @@ -0,0 +1,23 @@ +// +// STDSDeviceInformationManager.h +// Stripe3DS2 +// +// Created by Cameron Sabol on 1/23/19. +// Copyright © 2019 Stripe. All rights reserved. +// + +#import + +@class STDSDeviceInformation; +@class STDSWarning; + +NS_ASSUME_NONNULL_BEGIN + +@interface STDSDeviceInformationManager : NSObject + ++ (STDSDeviceInformation *)deviceInformationWithWarnings:(NSArray *)warnings + ignoringRestrictions:(BOOL)ignoreRestrictions; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSDeviceInformationManager.m b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSDeviceInformationManager.m new file mode 100644 index 0000000..5bd65e9 --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSDeviceInformationManager.m @@ -0,0 +1,65 @@ +// +// STDSDeviceInformationManager.m +// Stripe3DS2 +// +// Created by Cameron Sabol on 1/23/19. +// Copyright © 2019 Stripe. All rights reserved. +// + +#import "STDSDeviceInformationManager.h" + +#import "STDSDeviceInformation.h" +#import "STDSDeviceInformationParameter.h" +#import "STDSWarning.h" + +NS_ASSUME_NONNULL_BEGIN + +// TC_SDK_10089_001, Req 2 & 5 +static const NSString * const k3DSDataVersion = @"1.4"; + +static const NSString * const kDataVersionKey = @"DV"; +static const NSString * const kDeviceDataKey = @"DD"; +static const NSString * const kDeviceParameterNotAvailableKey = @"DPNA"; +static const NSString * const kDeviceWarningsKey = @"SW"; + +@implementation STDSDeviceInformationManager + ++ (STDSDeviceInformation *)deviceInformationWithWarnings:(NSArray *)warnings + ignoringRestrictions:(BOOL)ignoreRestrictions { + NSMutableDictionary *deviceInformation = [NSMutableDictionary dictionaryWithObject:k3DSDataVersion forKey:kDataVersionKey]; + + for (STDSDeviceInformationParameter *parameter in [STDSDeviceInformationParameter allParameters]) { + + [parameter collectIgnoringRestrictions:ignoreRestrictions withHandler:^(BOOL collected, NSString * _Nonnull identifier, id _Nonnull value) { + if (collected) { + NSMutableDictionary *deviceData = deviceInformation[kDeviceDataKey]; + if (deviceData == nil) { + deviceData = [NSMutableDictionary dictionary]; + deviceInformation[kDeviceDataKey] = deviceData; + } + deviceData[identifier] = value; + } else { + NSMutableDictionary *notAvailableData = deviceInformation[kDeviceParameterNotAvailableKey]; + if (notAvailableData == nil) { + notAvailableData = [NSMutableDictionary dictionary]; + deviceInformation[kDeviceParameterNotAvailableKey] = notAvailableData; + } + notAvailableData[identifier] = value; + } + }]; + } + + NSMutableArray *warningIDs = [NSMutableArray arrayWithCapacity:warnings.count]; + for (STDSWarning *warning in warnings) { + [warningIDs addObject:warning.identifier]; + } + if (warningIDs.count > 0) { + deviceInformation[kDeviceWarningsKey] = [warningIDs copy]; + } + + return [[STDSDeviceInformation alloc] initWithDictionary:deviceInformation]; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSDeviceInformationParameter+Private.h b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSDeviceInformationParameter+Private.h new file mode 100644 index 0000000..22d9f1a --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSDeviceInformationParameter+Private.h @@ -0,0 +1,76 @@ +// +// STDSDeviceInformationParameter+Private.h +// Stripe3DS2 +// +// Created by Cameron Sabol on 1/23/19. +// Copyright © 2019 Stripe. All rights reserved. +// + +#import "STDSDeviceInformationParameter.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface STDSDeviceInformationParameter (Private) + +- (instancetype)initWithIdentifier:(NSString *)identifier + permissionCheck:(nullable BOOL (^)(void))permissionCheck + valueCheck:(id _Nullable (^)(void))valueCheck; + +/// Platform: Platform that the device is using ++ (instancetype)platform; +/// Device Model: Mobile device manufacturer and model ++ (instancetype)deviceModel; +/// OS Name: Operating system name ++ (instancetype)OSName; +/// OS Version: Operating system version ++ (instancetype)OSVersion; +/// Locale: Device locale set by the user ++ (instancetype)locale; +/// Time zone: Device time zone ++ (instancetype)timeZone; +/// Advertising ID: Unique ID available for adertising and fraud detection purposes ++ (instancetype)advertisingID; +/// Screen Resolution: Pixel width and pixel height ++ (instancetype)screenResolution; +/// Device Name: User-assigned device name ++ (instancetype)deviceName; +/// IP Address: IP address of device ++ (instancetype)IPAddress; +/// Latitude: Device physical location latitude ++ (instancetype)latitude; +/// Longitude: Device physical location longitude ++ (instancetype)longitude; + +/// Identifier for Vendor: Alphanumeric string that uniquely ideitifies a device to the app's vendor ++ (instancetype)identiferForVendor; +/// UserInterfaceIdiom: Style of interface to use on the current device ++ (instancetype)userInterfaceIdiom; + +/// familyNames: an array of font family names available on the system ++ (instancetype)familyNames; +/// fontNamesForFamilyName: an array of font names available in a particular font family using the system font family ++ (instancetype)fontNamesForFamilyName; +/// systemFont: System font ++ (instancetype)systemFont; +/// labelFontSize: standard font size used for labels ++ (instancetype)labelFontSize; +/// buttonFontSize: standard font size used for buttons ++ (instancetype)buttonFontSize; +/// smallSystemFontSize: size of the standard small system font ++ (instancetype)smallSystemFontSize; +/// systemFontSize: size of the standard system font ++ (instancetype)systemFontSize; + +/// systemLocale: the ID of the generic locale that contains fixed "backstop" settings that provide values for otherwise undefined keys ++ (instancetype)systemLocale; +/// availableLocaleIdentifiers: an array of NSString objecgts, each of which identifies a locale available on the system ++ (instancetype)availableLocaleIdentifiers; +/// preferredLanguages: the user's language preference order as an array of strings ++ (instancetype)preferredLanguages; + +/// defaultTimeZone: the default time zone for the current application ++ (instancetype)defaultTimeZone; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSDeviceInformationParameter.h b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSDeviceInformationParameter.h new file mode 100644 index 0000000..46a3f66 --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSDeviceInformationParameter.h @@ -0,0 +1,24 @@ +// +// STDSDeviceInformationParameter.h +// Stripe3DS2 +// +// Created by Cameron Sabol on 1/23/19. +// Copyright © 2019 Stripe. All rights reserved. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface STDSDeviceInformationParameter : NSObject + ++ (NSArray *)allParameters; + +/// Returns a UUID unique to the app version ++ (NSString *)sdkAppIdentifier; + +- (void)collectIgnoringRestrictions:(BOOL)ignoreRestrictions withHandler:(void (^)(BOOL, NSString *, id))handler; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSDeviceInformationParameter.m b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSDeviceInformationParameter.m new file mode 100644 index 0000000..23edbf3 --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSDeviceInformationParameter.m @@ -0,0 +1,449 @@ +// +// STDSDeviceInformationParameter.m +// Stripe3DS2 +// +// Created by Cameron Sabol on 1/23/19. +// Copyright © 2019 Stripe. All rights reserved. +// + +#import "STDSDeviceInformationParameter.h" + +#import +#import + +#import "STDSIPAddress.h" +#import "STDSSynchronousLocationManager.h" + +NS_ASSUME_NONNULL_BEGIN + +// Code value to use if the parameter is restricted by the region or market +static const NSString * const kParameterRestrictedCode = @"RE01"; +// Code value to use if the platform version does not support the parameter or the parameter has been deprecated +static const NSString * const kParameterUnavailableCode = @"RE02"; +// Code value to use if parameter collection not possible without prompting the user for permission +static const NSString * const kParameterMissingPermissionsCode = @"RE03"; +// Code value to use if parameter value returned is null or blank +static const NSString * const kParameterNilCode = @"RE04"; + +@implementation STDSDeviceInformationParameter +{ + NSString *_identifier; + BOOL (^ _Nullable _permissionCheck)(void); + id (^_valueCheck)(void); +} + +- (instancetype)initWithIdentifier:(NSString *)identifier + permissionCheck:(nullable BOOL (^)(void))permissionCheck + valueCheck:(id (^)(void))valueCheck { + self = [super init]; + if (self) { + _identifier = [identifier copy]; + _permissionCheck = [permissionCheck copy]; + _valueCheck = [valueCheck copy]; + } + + return self; +} + +- (BOOL)_hasPermissions { + if (_permissionCheck == nil) { + return YES; + } + return _permissionCheck(); +} + +- (BOOL)_isRestricted { + static NSSet *sApprovedParameters = nil; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + sApprovedParameters = [NSSet setWithObjects: + // platform + @"C001", + // device model + @"C002", + // OS name + @"C003", + // OS version + @"C004", + // locale + @"C005", + // time zone + @"C006", + // advertising id (i.e. hardware id) + @"C007", + // screen solution + @"C008", + nil + ]; + }); + + return ![sApprovedParameters containsObject:_identifier]; +} + +- (void)collectIgnoringRestrictions:(BOOL)ignoreRestrictions withHandler:(void (^)(BOOL, NSString *, id))handler { + if (!ignoreRestrictions && [self _isRestricted]) { + handler(NO, _identifier, kParameterRestrictedCode); + return; + } else if (![self _hasPermissions]) { + handler(NO, _identifier, kParameterMissingPermissionsCode); + return; + } + + NSAssert(_valueCheck != nil, @"STDSDeviceInformationParameter should not have nil _valueCheck."); + id value = _valueCheck != nil ? _valueCheck() : nil; + + handler(value != nil, _identifier, value ?: kParameterUnavailableCode); +} + ++ (NSArray *)allParameters { + static NSArray *allParameters = nil; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + allParameters = @[ + +#pragma mark - Common Parameters + + [STDSDeviceInformationParameter platform], + [STDSDeviceInformationParameter deviceModel], + [STDSDeviceInformationParameter OSName], + [STDSDeviceInformationParameter OSVersion], + [STDSDeviceInformationParameter locale], + [STDSDeviceInformationParameter timeZone], + [STDSDeviceInformationParameter advertisingID], + [STDSDeviceInformationParameter screenResolution], + [STDSDeviceInformationParameter deviceName], + [STDSDeviceInformationParameter IPAddress], + [STDSDeviceInformationParameter latitude], + [STDSDeviceInformationParameter longitude], + [STDSDeviceInformationParameter applicationPackageName], + [STDSDeviceInformationParameter sdkAppId], + [STDSDeviceInformationParameter sdkVersion], + + +#pragma mark - iOS-Specific Parameters + + [STDSDeviceInformationParameter identiferForVendor], + [STDSDeviceInformationParameter userInterfaceIdiom], + [STDSDeviceInformationParameter familyNames], + [STDSDeviceInformationParameter fontNamesForFamilyName], + [STDSDeviceInformationParameter systemFont], + [STDSDeviceInformationParameter labelFontSize], + [STDSDeviceInformationParameter buttonFontSize], + [STDSDeviceInformationParameter smallSystemFontSize], + [STDSDeviceInformationParameter systemFontSize], + [STDSDeviceInformationParameter systemLocale], + [STDSDeviceInformationParameter availableLocaleIdentifiers], + [STDSDeviceInformationParameter preferredLanguages], + [STDSDeviceInformationParameter defaultTimeZone], + [STDSDeviceInformationParameter appStoreReciptURL], + ]; + + + }); + + return allParameters; +} + ++ (instancetype)platform { + return [[STDSDeviceInformationParameter alloc] initWithIdentifier:@"C001" + permissionCheck:nil + valueCheck:^id _Nullable{ + return @"iOS"; + }]; +} + ++ (instancetype)deviceModel { + return [[STDSDeviceInformationParameter alloc] initWithIdentifier:@"C002" + permissionCheck:nil + valueCheck:^id _Nullable{ + return [[UIDevice currentDevice] model]; + }]; +} + ++ (instancetype)OSName { + return [[STDSDeviceInformationParameter alloc] initWithIdentifier:@"C003" + permissionCheck:nil + valueCheck:^id _Nullable{ + return [[UIDevice currentDevice] systemName]; + }]; +} + ++ (instancetype)OSVersion { + return [[STDSDeviceInformationParameter alloc] initWithIdentifier:@"C004" + permissionCheck:nil + valueCheck:^id _Nullable{ + return [[UIDevice currentDevice] systemVersion]; + }]; +} + ++ (instancetype)locale { + return [[STDSDeviceInformationParameter alloc] initWithIdentifier:@"C005" + permissionCheck:nil + valueCheck:^id _Nullable{ + NSLocale *locale = [NSLocale currentLocale]; + NSString *language = locale.languageCode; + NSString *country = locale.countryCode; + if (language != nil && country != nil) { + return [@[language, country] componentsJoinedByString:@"-"]; + } else { + return nil; + } + }]; +} + ++ (instancetype)timeZone { + return [[STDSDeviceInformationParameter alloc] initWithIdentifier:@"C006" + permissionCheck:nil + valueCheck:^id _Nullable{ + return [NSTimeZone localTimeZone].name; + }]; +} + ++ (instancetype)advertisingID { + return [[STDSDeviceInformationParameter alloc] initWithIdentifier:@"C007" + permissionCheck:nil + valueCheck:^id _Nullable{ + // Actually collecting advertisingIdentifier would require our users to tell Apple they're using it during app submission. + // advertisingIdentifier returns all zeros when the user has limited ad tracking. + return @"00000000-0000-0000-0000-000000000000"; + }]; +} + ++ (instancetype)screenResolution { + return [[STDSDeviceInformationParameter alloc] initWithIdentifier:@"C008" + permissionCheck:nil + valueCheck:^id _Nullable{ + CGRect boundsInPixels = [UIScreen mainScreen].nativeBounds; + return [NSString stringWithFormat:@"%ldx%ld", (long)boundsInPixels.size.width, (long)boundsInPixels.size.height]; + + }]; +} + ++ (instancetype)deviceName +{ + return [[STDSDeviceInformationParameter alloc] initWithIdentifier:@"C009" + permissionCheck:nil + valueCheck:^id _Nullable{ + return [UIDevice currentDevice].name; + }]; +} + ++ (instancetype)IPAddress { + return [[STDSDeviceInformationParameter alloc] initWithIdentifier:@"C010" + permissionCheck:nil + valueCheck:^id _Nullable{ + return STDSCurrentDeviceIPAddress(); + }]; +} + ++ (instancetype)latitude { + return [[STDSDeviceInformationParameter alloc] initWithIdentifier:@"C011" + permissionCheck:^BOOL{ + return [STDSSynchronousLocationManager hasPermissions]; + } + valueCheck:^id _Nullable{ + CLLocation *location = [[STDSSynchronousLocationManager sharedManager] deviceLocation]; + return location != nil ? @(location.coordinate.latitude).stringValue : nil; + }]; +} + ++ (instancetype)longitude { + return [[STDSDeviceInformationParameter alloc] initWithIdentifier:@"C012" + permissionCheck:^BOOL{ + return [STDSSynchronousLocationManager hasPermissions]; + } + valueCheck:^id _Nullable{ + CLLocation *location = [[STDSSynchronousLocationManager sharedManager] deviceLocation]; + return location != nil ? @(location.coordinate.longitude).stringValue : nil; + }]; +} + ++ (instancetype)applicationPackageName { + /* + The unique package name/bundle identifier of the application in which the + 3DS SDK is embedded. + • iOS: obtained from the [NSBundle mainBundle] bundleIdentifier + property. + */ + return [[STDSDeviceInformationParameter alloc] initWithIdentifier:@"C013" + permissionCheck:nil + valueCheck:^id _Nullable{ + return [[NSBundle mainBundle] bundleIdentifier]; + }]; +} + + ++ (instancetype)sdkAppId { + /* + Universally unique ID that is created for each installation of the 3DS + Requestor App on a Consumer Device. + Note: This should be the same ID that is passed to the Requestor App in + the AuthenticationRequestParameters object (Refer to Section + 4.12.1 in the EMV 3DS SDK Specification). + */ + return [[STDSDeviceInformationParameter alloc] initWithIdentifier:@"C014" + permissionCheck:nil + valueCheck:^id _Nullable{ + return [STDSDeviceInformationParameter sdkAppIdentifier]; + }]; +} + + ++ (instancetype)sdkVersion { + /* + 3DS SDK version as applied by the implementer and stored securely in the + SDK (refer to Req 58 in the EMV 3DS SDK Specification). + */ + return [[STDSDeviceInformationParameter alloc] initWithIdentifier:@"C015" + permissionCheck:nil + valueCheck:^id _Nullable{ + return @"2.2.0"; + }]; +} + ++ (instancetype)identiferForVendor { + return [[STDSDeviceInformationParameter alloc] initWithIdentifier:@"I001" + permissionCheck:nil + valueCheck:^id _Nullable{ + // N.B. This can return nil if the device is locked + // We've decided to mark this case and similar as parameter unavailable, + // even though we have permission and the device _can_ provide it when + // it's in a different state + return [UIDevice currentDevice].identifierForVendor.UUIDString; + }]; +} + ++ (instancetype)userInterfaceIdiom { + return [[STDSDeviceInformationParameter alloc] initWithIdentifier:@"I002" + permissionCheck:nil + valueCheck:^id _Nullable{ + return @([UIDevice currentDevice].userInterfaceIdiom).stringValue; + }]; +} + ++ (instancetype)familyNames { + return [[STDSDeviceInformationParameter alloc] initWithIdentifier:@"I003" + permissionCheck:nil + valueCheck:^id _Nullable{ + return UIFont.familyNames; + }]; +} + ++ (instancetype)fontNamesForFamilyName { + return [[STDSDeviceInformationParameter alloc] initWithIdentifier:@"I004" + permissionCheck:nil + valueCheck:^id _Nullable{ + NSArray *fontNames = [UIFont fontNamesForFamilyName:[UIFont systemFontOfSize:[UIFont systemFontSize]].familyName]; + if (fontNames.count == 0) { + return @[@""]; // Workaround for TC_SDK_10176_001 + } + return fontNames; + }]; +} + ++ (instancetype)systemFont { + return [[STDSDeviceInformationParameter alloc] initWithIdentifier:@"I005" + permissionCheck:nil + valueCheck:^id _Nullable{ + return [UIFont systemFontOfSize:[UIFont systemFontSize]].fontName; + }]; +} + ++ (instancetype)labelFontSize { + return [[STDSDeviceInformationParameter alloc] initWithIdentifier:@"I006" + permissionCheck:nil + valueCheck:^id _Nullable{ + return @([UIFont labelFontSize]).stringValue; + }]; +} + ++ (instancetype)buttonFontSize { + return [[STDSDeviceInformationParameter alloc] initWithIdentifier:@"I007" + permissionCheck:nil + valueCheck:^id _Nullable{ + return @([UIFont buttonFontSize]).stringValue; + }]; +} + ++ (instancetype)smallSystemFontSize { + return [[STDSDeviceInformationParameter alloc] initWithIdentifier:@"I008" + permissionCheck:nil + valueCheck:^id _Nullable{ + return @([UIFont smallSystemFontSize]).stringValue; + }]; +} + ++ (instancetype)systemFontSize { + return [[STDSDeviceInformationParameter alloc] initWithIdentifier:@"I009" + permissionCheck:nil + valueCheck:^id _Nullable{ + return @([UIFont systemFontSize]).stringValue; + }]; +} + ++ (instancetype)systemLocale { + return [[STDSDeviceInformationParameter alloc] initWithIdentifier:@"I010" + permissionCheck:nil + valueCheck:^id _Nullable{ + return [NSLocale currentLocale].localeIdentifier; + }]; +} + ++ (instancetype)availableLocaleIdentifiers { + return [[STDSDeviceInformationParameter alloc] initWithIdentifier:@"I011" + permissionCheck:nil + valueCheck:^id _Nullable{ + return [NSLocale availableLocaleIdentifiers]; + }]; +} + ++ (instancetype)preferredLanguages { + return [[STDSDeviceInformationParameter alloc] initWithIdentifier:@"I012" + permissionCheck:nil + valueCheck:^id _Nullable{ + return [NSLocale preferredLanguages]; + }]; +} + ++ (instancetype)defaultTimeZone { + return [[STDSDeviceInformationParameter alloc] initWithIdentifier:@"I013" + permissionCheck:nil + valueCheck:^id _Nullable{ + return [NSTimeZone defaultTimeZone].name; + }]; +} + ++ (instancetype)appStoreReciptURL { + return [[STDSDeviceInformationParameter alloc] initWithIdentifier:@"I014" + permissionCheck:nil + valueCheck:^id _Nullable { + NSString *appStoreReceiptURL = [[NSBundle mainBundle] appStoreReceiptURL].absoluteString; + if (appStoreReceiptURL) { + return appStoreReceiptURL; + } + return kParameterNilCode; + }]; +} + ++ (NSString *)sdkAppIdentifier { + static NSString * const appIdentifierKeyPrefix = @"STDSStripe3DS2AppIdentifierKey"; + NSString *appVersion = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleShortVersionString"] ?: @""; + NSString *appIdentifierUserDefaultsKey = [appIdentifierKeyPrefix stringByAppendingString:appVersion]; + NSString *appIdentifier = [[NSUserDefaults standardUserDefaults] stringForKey:appIdentifierUserDefaultsKey]; + if (appIdentifier == nil) { + appIdentifier = [[NSUUID UUID] UUIDString].lowercaseString; + // Clean up any previous app identifiers + NSSet *previousKeys = [[[NSUserDefaults standardUserDefaults] dictionaryRepresentation] keysOfEntriesPassingTest:^BOOL (NSString *key, id obj, BOOL *stop) { + return [key hasPrefix:appIdentifierKeyPrefix] && ![key isEqualToString:appIdentifierUserDefaultsKey]; + }]; + for (NSString *key in previousKeys) { + [[NSUserDefaults standardUserDefaults] removeObjectForKey:key]; + } + } + [[NSUserDefaults standardUserDefaults] setObject:appIdentifier forKey:appIdentifierUserDefaultsKey]; + return appIdentifier; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSDirectoryServer.h b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSDirectoryServer.h new file mode 100644 index 0000000..e658e38 --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSDirectoryServer.h @@ -0,0 +1,134 @@ +// +// Header.h +// Stripe3DS2 +// +// Created by Cameron Sabol on 3/25/19. +// Copyright © 2019 Stripe. All rights reserved. +// + +#import +#import + +NS_ASSUME_NONNULL_BEGIN +typedef NS_ENUM(NSInteger, STDSDirectoryServer) { + STDSDirectoryServerULTestRSA, + STDSDirectoryServerULTestEC, + STDSDirectoryServerSTPTestRSA, + STDSDirectoryServerSTPTestEC, + STDSDirectoryServerAmex, + STDSDirectoryServerCartesBancaires, + STDSDirectoryServerDiscover, + STDSDirectoryServerMastercard, + STDSDirectoryServerVisa, + STDSDirectoryServerCustom, + STDSDirectoryServerUnknown, +}; + +static NSString * const kULTestRSADirectoryServerID = @"F055545342"; +static NSString * const kULTestECDirectoryServerID = @"F155545342"; + +static NSString * const kSTDSTestRSADirectoryServerID = @"ul_test"; +static NSString * const kSTDSTestECDirectoryServerID = @"ec_test"; + +static NSString * const kSTDSAmexDirectoryServerID = @"A000000025"; +static NSString * const kSTDSCartesBancairesServerID = @"A000000042"; +static NSString * const kSTDSDiscoverDirectoryServerID = @"A000000324"; +static NSString * const kSTDSDiscoverDirectoryServerID_2 = @"A000000152"; +static NSString * const kSTDSMastercardDirectoryServerID = @"A000000004"; +static NSString * const kSTDSVisaDirectoryServerID = @"A000000003"; + + +/// Returns the typed directory server enum or STDSDirectoryServerUnknown if the directoryServerID is not recognized +NS_INLINE STDSDirectoryServer STDSDirectoryServerForID(NSString *directoryServerID) { + if ([directoryServerID isEqualToString:kULTestRSADirectoryServerID]) { + return STDSDirectoryServerULTestRSA; + } else if ([directoryServerID isEqualToString:kULTestECDirectoryServerID]) { + return STDSDirectoryServerULTestEC; + } else if ([directoryServerID isEqualToString:kSTDSTestRSADirectoryServerID]) { + return STDSDirectoryServerSTPTestRSA; + } else if ([directoryServerID isEqualToString:kSTDSTestECDirectoryServerID]) { + return STDSDirectoryServerSTPTestEC; + } else if ([directoryServerID isEqualToString:kSTDSAmexDirectoryServerID]) { + return STDSDirectoryServerAmex; + } else if ([directoryServerID isEqualToString:kSTDSDiscoverDirectoryServerID] || [directoryServerID isEqualToString:kSTDSDiscoverDirectoryServerID_2]) { + return STDSDirectoryServerDiscover; + } else if ([directoryServerID isEqualToString:kSTDSMastercardDirectoryServerID]) { + return STDSDirectoryServerMastercard; + } else if ([directoryServerID isEqualToString:kSTDSVisaDirectoryServerID]) { + return STDSDirectoryServerVisa; + } else if ([directoryServerID isEqualToString:kSTDSCartesBancairesServerID]) { + return STDSDirectoryServerCartesBancaires; + } + + return STDSDirectoryServerUnknown; +} + +/// Returns the directory server ID or nil for STDSDirectoryServerUnknown +NS_INLINE NSString * _Nullable STDSDirectoryServerIdentifier(STDSDirectoryServer directoryServer) { + switch (directoryServer) { + case STDSDirectoryServerULTestRSA: + return kULTestRSADirectoryServerID; + + case STDSDirectoryServerULTestEC: + return kULTestECDirectoryServerID; + + case STDSDirectoryServerSTPTestRSA: + return kSTDSTestRSADirectoryServerID; + + case STDSDirectoryServerSTPTestEC: + return kSTDSTestECDirectoryServerID; + + case STDSDirectoryServerAmex: + return kSTDSAmexDirectoryServerID; + + case STDSDirectoryServerDiscover: + return kSTDSDiscoverDirectoryServerID; + + case STDSDirectoryServerMastercard: + return kSTDSMastercardDirectoryServerID; + + case STDSDirectoryServerVisa: + return kSTDSVisaDirectoryServerID; + + case STDSDirectoryServerCartesBancaires: + return kSTDSCartesBancairesServerID; + + case STDSDirectoryServerCustom: + return nil; + + case STDSDirectoryServerUnknown: + return nil; + } +} + +/// Returns the directory server image name if one exists +NS_INLINE NSString * _Nullable STDSDirectoryServerImageName(STDSDirectoryServer directoryServer) { + switch (directoryServer) { + case STDSDirectoryServerAmex: + return @"amex-logo"; + case STDSDirectoryServerDiscover: + return @"discover-logo"; + case STDSDirectoryServerMastercard: + return @"mastercard-logo"; + case STDSDirectoryServerCartesBancaires: + return @"cartes-bancaires-logo"; + // just default to an arbitrary logo for the test servers + case STDSDirectoryServerULTestEC: + case STDSDirectoryServerULTestRSA: + case STDSDirectoryServerSTPTestRSA: + case STDSDirectoryServerSTPTestEC: + case STDSDirectoryServerVisa: + if (@available(iOS 13.0, *)) { + if ([[UITraitCollection currentTraitCollection] userInterfaceStyle] == UIUserInterfaceStyleDark) { + return @"visa-white-logo"; + } + } + return @"visa-logo"; + case STDSDirectoryServerCustom: + case STDSDirectoryServerUnknown: + return nil; + + } +} + +NS_ASSUME_NONNULL_END diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSDirectoryServerCertificate+Internal.h b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSDirectoryServerCertificate+Internal.h new file mode 100644 index 0000000..8f45d98 --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSDirectoryServerCertificate+Internal.h @@ -0,0 +1,22 @@ +// +// STDSDirectoryServerCertificate+Internal.h +// Stripe3DS2 +// +// Created by Cameron Sabol on 4/2/19. +// Copyright © 2019 Stripe. All rights reserved. +// + +#import + +#import "STDSDirectoryServerCertificate.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface STDSDirectoryServerCertificate (Internal) + +/// Verifies the certificate chain represented by certificates where each element is a base64 encoded (NOT base64url) certificate ++ (BOOL)_verifyCertificateChain:(NSArray *)certificates withRootCertificates:(NSArray *)rootCertificates; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSDirectoryServerCertificate.h b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSDirectoryServerCertificate.h new file mode 100644 index 0000000..4ac91b0 --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSDirectoryServerCertificate.h @@ -0,0 +1,43 @@ +// +// STDSDirectoryServerCertificate.h +// Stripe3DS2 +// +// Created by Cameron Sabol on 3/27/19. +// Copyright © 2019 Stripe. All rights reserved. +// + +#import + +@class STDSJSONWebSignature; + +#import "STDSDirectoryServer.h" + +NS_ASSUME_NONNULL_BEGIN + +typedef NS_ENUM(NSInteger, STDSDirectoryServerKeyType) { + STDSDirectoryServerKeyTypeRSA, + STDSDirectoryServerKeyTypeEC, + STDSDirectoryServerKeyTypeUnknown, +}; + +@interface STDSDirectoryServerCertificate : NSObject + ++ (nullable instancetype)certificateForDirectoryServer:(STDSDirectoryServer)directoryServer; + ++ (nullable instancetype)customCertificateWithData:(NSData *)certificateData; + ++ (nullable instancetype)customCertificateWithString:(NSString *)certificateString; + +@property (nonatomic, readonly) STDSDirectoryServerKeyType keyType; + +@property (nonatomic, readonly) SecKeyRef publicKey; + +@property (nonatomic, readonly, copy) NSString *certificateString; + +- (nullable NSData *)encryptDataUsingRSA_OAEP_SHA256:(NSData *)plaintext; + ++ (BOOL)verifyJSONWebSignature:(STDSJSONWebSignature *)jws withRootCertificates:(NSArray *)rootCertificates; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSDirectoryServerCertificate.m b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSDirectoryServerCertificate.m new file mode 100644 index 0000000..08d3d08 --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSDirectoryServerCertificate.m @@ -0,0 +1,350 @@ +// +// STDSDirectoryServerCertificate.m +// Stripe3DS2 +// +// Created by Cameron Sabol on 3/27/19. +// Copyright © 2019 Stripe. All rights reserved. +// + +#import "STDSDirectoryServerCertificate.h" +#import "STDSDirectoryServerCertificate+Internal.h" + +#import "NSData+JWEHelpers.h" +#import "NSString+JWEHelpers.h" +#import "STDSEllipticCurvePoint.h" +#import "STDSJSONWebSignature.h" +#import "STDSSecTypeUtilities.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface STDSDirectoryServerCertificate () +{ + SecCertificateRef _certificate; + STDSDirectoryServer _directoryServer; +} + +- (instancetype)_initForDirectoryServer:(STDSDirectoryServer)directoryServer; + +@end + +@implementation STDSDirectoryServerCertificate + +- (instancetype)_initWithCertificate:(SecCertificateRef _Nullable)certificate forDirectorySever:(STDSDirectoryServer)directoryServer { + self = [super init]; + if (self) { + _certificate = certificate; + switch (directoryServer) { + + case STDSDirectoryServerULTestRSA: { + /** + UL provides the following, which is PKCS#8, but Security framework wants PKCS#1. Luckily all we have to do is remove the first 32 characters which are just a header to convert + @"-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAr/O0BfXWngO9OJDBsqdR\n5U2h28jrX6Y+LlblTBaYeT2tW7+ca3YzTFXA8duVUwdlWxl3JZCOOeL1feVP6g0TNOHVCkCnirVDLkcozod4aSkNvx+929aDr1ithqhruf0skBc2sMZGBBCNpso6XGzyAf2uZ2+9DvXoKIUYgcr7PQmL2Y0awyQN7KCRcusaotYNz2mOPrL/hAv6hTexkNrQ\nKzFcPwCuc6kN6aNjD+p2CJ51/5p02SNS70nPOmwmg63j6f3n7xVykQ56kNc1l5B5xOpeHJmqk3+hyF1dF/47rQmMFicN41QSvZ5AZJKgWlIn2VQROMkEHkF9ZBRLx1nF\nTwIDAQAB\n-----END PUBLIC KEY-----\n" + */ + static NSString * const kULTestRSAPublicKey = @"MIIBCgKCAQEAr/O0BfXWngO9OJDBsqdR\n5U2h28jrX6Y+LlblTBaYeT2tW7+ca3YzTFXA8duVUwdlWxl3JZCOOeL1feVP6g0TNOHVCkCnirVDLkcozod4aSkNvx+929aDr1ithqhruf0skBc2sMZGBBCNpso6XGzyAf2uZ2+9DvXoKIUYgcr7PQmL2Y0awyQN7KCRcusaotYNz2mOPrL/hAv6hTexkNrQ\nKzFcPwCuc6kN6aNjD+p2CJ51/5p02SNS70nPOmwmg63j6f3n7xVykQ56kNc1l5B5xOpeHJmqk3+hyF1dF/47rQmMFicN41QSvZ5AZJKgWlIn2VQROMkEHkF9ZBRLx1nF\nTwIDAQAB"; + + NSString *cleanedString = [[[kULTestRSAPublicKey stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]] componentsSeparatedByCharactersInSet:[NSCharacterSet newlineCharacterSet]] componentsJoinedByString:@""]; + + NSData *base64Decoded = [[NSData alloc] initWithBase64EncodedString:cleanedString options:0]; + NSDictionary *attributes = @{ + (__bridge NSString *)kSecAttrKeyType: (__bridge NSString *)kSecAttrKeyTypeRSA, + (__bridge NSString *)kSecAttrKeyClass: (__bridge NSString *)kSecAttrKeyClassPublic, + }; + CFErrorRef error = NULL; + SecKeyRef key = SecKeyCreateWithData((__bridge CFDataRef)base64Decoded, (__bridge CFDictionaryRef)attributes, &error); + if (key == NULL) { + return nil; + } + _publicKey = key; + } + break; + + case STDSDirectoryServerULTestEC: { + static NSString * const kULTestECPublicKey = @"MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEYktbLuAv0v52erE5LPscomKaOmQs\nvevxzOyn9k4sF1hqpBc5kUygzxA9Jl0R/2dTuk8ka7UCujk36xeUsLVpWA=="; + NSString *cleanedString = [[[kULTestECPublicKey stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]] componentsSeparatedByCharactersInSet:[NSCharacterSet newlineCharacterSet]] componentsJoinedByString:@""]; + NSData *base64Decoded = [[NSData alloc] initWithBase64EncodedString:cleanedString options:0]; + // This data is PEM encoded, to get to ec standard we take the last 65 bytes + if (base64Decoded.length >= 65) { + base64Decoded = [base64Decoded subdataWithRange:NSMakeRange(base64Decoded.length - 65, 65)]; + } + NSDictionary *attributes = @{ + (__bridge NSString *)kSecAttrKeyType: (__bridge NSString *)kSecAttrKeyTypeECSECPrimeRandom, + (__bridge NSString *)kSecAttrKeyClass: (__bridge NSString *)kSecAttrKeyClassPublic, + }; + CFErrorRef error = NULL; + SecKeyRef key = SecKeyCreateWithData((__bridge CFDataRef)base64Decoded, (__bridge CFDictionaryRef)attributes, &error); + if (key == NULL) { + return nil; + } + _publicKey = key; + } + break; + + case STDSDirectoryServerSTPTestRSA: + // fall-through + case STDSDirectoryServerSTPTestEC: + // fall-through + case STDSDirectoryServerAmex: + // fall-through + case STDSDirectoryServerCartesBancaires: + // fall-through + case STDSDirectoryServerDiscover: + // fall-through + case STDSDirectoryServerMastercard: + // fall-through + case STDSDirectoryServerVisa: + // fall-through + case STDSDirectoryServerCustom: + // fall-through + case STDSDirectoryServerUnknown: + NSAssert(certificate != NULL, @"Must provide a certificate"); + _publicKey = SecCertificateCopyKey(certificate); + } + _directoryServer = directoryServer; + + if (_publicKey == NULL) { + return nil; + } + } + + return self; +} + +- (instancetype)_initForDirectoryServer:(STDSDirectoryServer)directoryServer { + SecCertificateRef certificate = NULL; + + switch (directoryServer) { + case STDSDirectoryServerULTestRSA: + // fall-through + case STDSDirectoryServerULTestEC: + // The UL test servers don't actually have certificates, just hard-coded key values + break; + + case STDSDirectoryServerSTPTestRSA: + // fall-through + case STDSDirectoryServerSTPTestEC: + // fall-through + case STDSDirectoryServerAmex: + // fall-through + case STDSDirectoryServerCartesBancaires: + // fall-through + case STDSDirectoryServerDiscover: + // fall-through; + case STDSDirectoryServerMastercard: + // fall-through + case STDSDirectoryServerVisa: { + certificate = STDSCertificateForServer(directoryServer); + if (certificate == NULL) { + return nil; + } + } + break; + + case STDSDirectoryServerCustom: + return nil; + + case STDSDirectoryServerUnknown: + return nil; + } + return [self _initWithCertificate:certificate forDirectorySever:directoryServer]; +} + ++ (nullable instancetype)certificateForDirectoryServer:(STDSDirectoryServer)directoryServer { + return [[self alloc] _initForDirectoryServer:directoryServer]; +} + ++ (nullable instancetype)customCertificateWithData:(NSData *)certificateData { + SecCertificateRef certificate = STDSSecCertificateFromData(certificateData); + if (certificate == NULL) { + return nil; + } + return [[self alloc] _initWithCertificate:certificate forDirectorySever:STDSDirectoryServerCustom]; +} + ++ (nullable instancetype)customCertificateWithString:(NSString *)certificateString { + SecCertificateRef certificate = STDSSecCertificateFromString(certificateString); + if (certificate == NULL) { + return nil; + } + + return [[self alloc] _initWithCertificate:certificate forDirectorySever:STDSDirectoryServerCustom]; +} + +- (void)dealloc { + if (_certificate != NULL) { + CFRelease(_certificate); + } + if (_publicKey != NULL) { + CFRelease(_publicKey); + } +} + +- (NSString *)certificateString { + NSData *data = (NSData *)CFBridgingRelease(SecCertificateCopyData(_certificate)); + return [data base64EncodedStringWithOptions:0]; +} + +- (STDSDirectoryServerKeyType)keyType { + switch (_directoryServer) { + case STDSDirectoryServerULTestRSA: + return STDSDirectoryServerKeyTypeRSA; + + case STDSDirectoryServerULTestEC: + return STDSDirectoryServerKeyTypeEC; + + + case STDSDirectoryServerSTPTestRSA: + // fall-through + case STDSDirectoryServerSTPTestEC: + // fall-through + case STDSDirectoryServerAmex: + // fall-through + case STDSDirectoryServerCartesBancaires: + // fall-through + case STDSDirectoryServerDiscover: + // fall-through; + case STDSDirectoryServerMastercard: + // fall-through + case STDSDirectoryServerVisa: + // fall-through + case STDSDirectoryServerCustom: { + NSAssert(_certificate != NULL, @"Must have a valid certificate file"); + if (_certificate == NULL) { + return STDSDirectoryServerKeyTypeUnknown; + } + CFStringRef keyType = STDSSecCertificateCopyPublicKeyType(_certificate); + STDSDirectoryServerKeyType ret = STDSDirectoryServerKeyTypeUnknown; + if (keyType != NULL) { + if (CFStringCompare(keyType, kSecAttrKeyTypeRSA, 0) == kCFCompareEqualTo) { + ret = STDSDirectoryServerKeyTypeRSA; + } else if (CFStringCompare(keyType, kSecAttrKeyTypeECSECPrimeRandom, 0) == kCFCompareEqualTo) { + ret = STDSDirectoryServerKeyTypeEC; + } + + CFRelease(keyType); + } + return ret; + } + + case STDSDirectoryServerUnknown: + NSAssert(0, @"Should not have an STDSDirectoryServerCertificate instance withSTPDirectoryServerUnknown"); + return STDSDirectoryServerKeyTypeUnknown; + } +} + +- (nullable NSData *)encryptDataUsingRSA_OAEP_SHA256:(NSData *)plaintext { + NSAssert(_publicKey != NULL, @"STDSDirectoryServerCertificate should always have _publicKey"); + if (_publicKey == NULL) { + return nil; + } + + CFDataRef encryptedData = SecKeyCreateEncryptedData(_publicKey, + kSecKeyAlgorithmRSAEncryptionOAEPSHA256, + (CFDataRef)plaintext, + NULL); + return (NSData *)CFBridgingRelease(encryptedData); +} + ++ (BOOL)_verifyCertificateChain:(NSArray *)certificatesStrings withRootCertificates:(NSArray *)rootCertificateStrings { + if (certificatesStrings.count == 0 || rootCertificateStrings.count == 0) { + return NO; + } + + NSMutableArray *certificates = [[NSMutableArray alloc] initWithCapacity:certificatesStrings.count]; + for (NSString *certificateString in certificatesStrings) { + SecCertificateRef certificate = STDSSecCertificateFromString(certificateString); + if (certificate == NULL) { + return NO; + } + [certificates addObject:(id)CFBridgingRelease(certificate)]; + } + + NSMutableArray *rootCertificates = [[NSMutableArray alloc] initWithCapacity:rootCertificateStrings.count]; + for (NSString *certificateString in rootCertificateStrings) { + SecCertificateRef certificate = STDSSecCertificateFromString(certificateString); + if (certificate == NULL) { + return NO; + } + [rootCertificates addObject:(id)CFBridgingRelease(certificate)]; + } + + SecPolicyRef policy = SecPolicyCreateBasicX509(); + SecTrustRef trust; + OSStatus status = SecTrustCreateWithCertificates((__bridge CFTypeRef)certificates, + policy, + &trust); + if (policy) { + CFRelease(policy); + } + if (status != errSecSuccess) { + return NO; + } + if (rootCertificates.count > 0) { + status = SecTrustSetAnchorCertificates(trust, (__bridge CFTypeRef)rootCertificates); + if (status != errSecSuccess) { + return NO; + } + } + + if (@available(iOS 12.0, *)) { + CFErrorRef error = NULL; + + bool verified = SecTrustEvaluateWithError(trust, &error); + return (BOOL)verified; + } else { +#if TARGET_OS_MACCATALYST + return NO; +#else + // Fallback on earlier versions + dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0); + __block BOOL verified = NO; + dispatch_group_t group = dispatch_group_create(); + dispatch_group_enter(group); + dispatch_async(queue, ^{ + // SecTrustEvaluateAsyncWithError must be called from the same queue that is passed as an arg + SecTrustEvaluateAsyncWithError(trust, queue, ^(SecTrustRef _Nonnull trustRef, bool result, CFErrorRef _Nullable error) { + if (result) { + verified = YES; + } + dispatch_group_leave(group); + }); + }); + dispatch_group_wait(group, dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.2 * NSEC_PER_SEC))); // timeout after 200 ms + + return verified; +#endif + } +} + ++ (BOOL)verifyJSONWebSignature:(STDSJSONWebSignature *)jws withRootCertificates:(NSArray *)rootCertificates { + if (jws.certificateChain.count == 0 || ![self _verifyCertificateChain:jws.certificateChain withRootCertificates:rootCertificates]) { + return NO; + } + + switch (jws.algorithm) { + case STDSJSONWebSignatureAlgorithmES256: + return STDSVerifyEllipticCurveP256Signature(jws.ellipticCurvePoint.x, jws.ellipticCurvePoint.y, jws.digest, jws.signature); + + case STDSJSONWebSignatureAlgorithmPS256: { + if (jws.certificateChain.count == 0) { + return NO; + } + NSString *certificateString = [jws.certificateChain firstObject]; + SecCertificateRef certificate = STDSSecCertificateFromString(certificateString); + if (certificate == NULL) { + return NO; + } + + BOOL verified = STDSVerifyRSASignature(certificate, jws.digest, jws.signature); + CFRelease(certificate); + return verified; + } + + + case STDSJSONWebSignatureAlgorithmUnknown: + return NO; + } +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSEllipticCurvePoint.h b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSEllipticCurvePoint.h new file mode 100644 index 0000000..c856951 --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSEllipticCurvePoint.h @@ -0,0 +1,26 @@ +// +// STDSEllipticCurvePoint.h +// Stripe3DS2 +// +// Created by Cameron Sabol on 3/20/19. +// Copyright © 2019 Stripe. All rights reserved. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface STDSEllipticCurvePoint : NSObject + +- (nullable instancetype)initWithX:(NSData *)x y:(NSData *)y; +- (nullable instancetype)initWithCertificateData:(NSData *)certificateData; +- (nullable instancetype)initWithKey:(SecKeyRef)key; +- (nullable instancetype)initWithJWK:(NSDictionary *)jwk; + +@property (nonatomic, readonly) NSData *x; +@property (nonatomic, readonly) NSData *y; + +@property (nonatomic, readonly) SecKeyRef publicKey; + +@end +NS_ASSUME_NONNULL_END diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSEllipticCurvePoint.m b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSEllipticCurvePoint.m new file mode 100644 index 0000000..49fdf3e --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSEllipticCurvePoint.m @@ -0,0 +1,90 @@ +// +// STDSEllipticCurvePoint.m +// Stripe3DS2 +// +// Created by Cameron Sabol on 3/20/19. +// Copyright © 2019 Stripe. All rights reserved. +// + +#import "STDSEllipticCurvePoint.h" + +#import "NSDictionary+DecodingHelpers.h" +#import "NSString+JWEHelpers.h" +#import "STDSSecTypeUtilities.h" + +NS_ASSUME_NONNULL_BEGIN + +@implementation STDSEllipticCurvePoint + +- (nullable instancetype)initWithX:(NSData *)x y:(NSData *)y { + self = [super init]; + if (self) { + _x = x; + _y = y; + _publicKey = STDSSecKeyRefFromCoordinates(x, y); + if (_publicKey == NULL) { + return nil; + } + } + + return self; +} + +- (nullable instancetype)initWithKey:(SecKeyRef)key { + self = [super init]; + if (self) { + _publicKey = key; + CFErrorRef error = NULL; + NSData *keyData = (NSData *)CFBridgingRelease(SecKeyCopyExternalRepresentation(key, &error)); + if (keyData == nil) { + return nil; + } + + NSUInteger coordinateLength = (keyData.length - 1) / 2; // -1 because the first byte is formatting 0x04 + NSData *xData = [keyData subdataWithRange:NSMakeRange(1, coordinateLength)]; + NSData *yData = [keyData subdataWithRange:NSMakeRange(1 + coordinateLength, coordinateLength)]; + _x = xData; + _y = yData; + } + + return self; +} + +- (nullable instancetype)initWithCertificateData:(NSData *)certificateData { + SecCertificateRef certificate = STDSSecCertificateFromData(certificateData); + if (certificateData != NULL) { + SecKeyRef key = SecCertificateCopyKey(certificate); + CFRelease(certificate); + if (key != NULL) { + STDSEllipticCurvePoint *point = [self initWithKey:key]; + CFRelease(key); + return point; + } + } + return nil; +} + +- (nullable instancetype)initWithJWK:(NSDictionary *)jwk { + NSString *kty = [jwk _stds_stringForKey:@"kty" validator:^BOOL(NSString * _Nonnull val) { + return [val isEqualToString:@"EC"]; + } required:YES error:NULL]; + NSString *crv = [jwk _stds_stringForKey:@"crv" validator:^BOOL(NSString * _Nonnull val) { + return [val isEqualToString:@"P-256"]; + } required:YES error:NULL]; + + NSData *coordinateX = [[jwk _stds_stringForKey:@"x" required:YES error:NULL] _stds_base64URLDecodedData]; + NSData *coordinateY = [[jwk _stds_stringForKey:@"y" required:YES error:NULL] _stds_base64URLDecodedData]; + + if (kty == nil || + crv == nil || + coordinateX == nil || + coordinateY == nil + ) { + return nil; + } + return [self initWithX:coordinateX y:coordinateY]; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSEphemeralKeyPair+Testing.h b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSEphemeralKeyPair+Testing.h new file mode 100644 index 0000000..d8efb11 --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSEphemeralKeyPair+Testing.h @@ -0,0 +1,19 @@ +// +// STDSEphemeralKeyPair+Testing.h +// Stripe3DS2 +// +// Created by Cameron Sabol on 4/18/19. +// Copyright © 2019 Stripe. All rights reserved. +// + +#import "STDSEphemeralKeyPair.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface STDSEphemeralKeyPair (Testing) + ++ (nullable instancetype)testKeyPair; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSEphemeralKeyPair.h b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSEphemeralKeyPair.h new file mode 100644 index 0000000..515fbb5 --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSEphemeralKeyPair.h @@ -0,0 +1,39 @@ +// +// STDSEphemeralKeyPair.h +// Stripe3DS2 +// +// Created by Cameron Sabol on 3/25/19. +// Copyright © 2019 Stripe. All rights reserved. +// + +#import + +@class STDSDirectoryServerCertificate; +@class STDSEllipticCurvePoint; + +#import "STDSDirectoryServer.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface STDSEphemeralKeyPair : NSObject + +/// Creates a returns a new elliptic curve key pair using curve P-256 ++ (nullable instancetype)ephemeralKeyPair; + +- (instancetype)init NS_UNAVAILABLE; + +@property (nonatomic, readonly) NSString *publicKeyJWK; +@property (nonatomic, readonly) STDSEllipticCurvePoint *publicKeyCurvePoint; + +/** + Creates and returns a new secret key derived using Elliptic Curve Diffie-Hellman + and the certificate's public key (return nil on failure). + Per OpenSSL documentation: Never use a derived secret directly. Typically it is passed through some + hash function to produce a key (e.g. pass the secret as the first argument to STDSCreateConcatKDFWithSHA256) + */ +- (nullable NSData *)createSharedSecretWithEllipticCurveKey:(STDSEllipticCurvePoint *)ecKey; +- (nullable NSData *)createSharedSecretWithCertificate:(STDSDirectoryServerCertificate *)certificate; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSEphemeralKeyPair.m b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSEphemeralKeyPair.m new file mode 100644 index 0000000..426ebc5 --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSEphemeralKeyPair.m @@ -0,0 +1,108 @@ +// +// STDSEphemeralKeyPair.m +// Stripe3DS2 +// +// Created by Cameron Sabol on 3/25/19. +// Copyright © 2019 Stripe. All rights reserved. +// + +#import "STDSEphemeralKeyPair.h" + +#import "NSData+JWEHelpers.h" +#import "NSDictionary+DecodingHelpers.h" +#import "NSString+JWEHelpers.h" +#import "STDSDirectoryServerCertificate.h" +#import "STDSEllipticCurvePoint.h" +#import "STDSSecTypeUtilities.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface STDSEphemeralKeyPair () +{ + SecKeyRef _privateKey; + SecKeyRef _publicKey; +} + +@end + + +@implementation STDSEphemeralKeyPair + +- (instancetype)_initWithPrivateKey:(SecKeyRef)privateKey publicKey:(SecKeyRef)publicKey { + self = [super init]; + if (self) { + _privateKey = privateKey; + _publicKey = publicKey; + } + + return self; +} + ++ (nullable instancetype)ephemeralKeyPair { + NSDictionary *parameters = @{ + (__bridge NSString *)kSecAttrKeyType: (__bridge NSString *)kSecAttrKeyTypeECSECPrimeRandom, + (__bridge NSString *)kSecAttrKeySizeInBits: @(256), + }; + CFErrorRef error = NULL; + SecKeyRef privateKey = SecKeyCreateRandomKey((__bridge CFDictionaryRef)parameters, &error); + + if (privateKey != NULL) { + SecKeyRef publicKey = SecKeyCopyPublicKey(privateKey); + return [[self alloc] _initWithPrivateKey:privateKey publicKey:publicKey]; + } + + return nil; +} + ++ (nullable instancetype)testKeyPair { + + // values from EMVCo_3DS_-AppBased_CryptoExamples_082018.pdf + NSData *d = [@"iyn--IbkBeNoPu8cN245L6pOQWt2lTH8V0Ds92jQmWA" _stds_base64URLDecodedData]; + NSData *x = [@"C1PL42i6kmNkM61aupEAgLJ4gF1ZRzcV7lqo1TG0mL4" _stds_base64URLDecodedData]; + NSData *y = [@"cNToWLSdcFQKG--PGVEUQrIHP8w6TcRyj0pyFx4-ZMc" _stds_base64URLDecodedData]; + + SecKeyRef privateKey = STDSPrivateSecKeyRefFromCoordinates(x, y, d); + if (privateKey == NULL) { + return nil; + } + SecKeyRef publicKey = SecKeyCopyPublicKey(privateKey); + if (publicKey == NULL) { + return nil; + } + + return [[STDSEphemeralKeyPair alloc] _initWithPrivateKey:privateKey publicKey:publicKey]; +} + +- (void)dealloc { + if (_privateKey != NULL) { + CFRelease(_privateKey); + } + if (_publicKey != NULL) { + CFRelease(_publicKey); + } +} + +- (NSString *)publicKeyJWK { + STDSEllipticCurvePoint *publicKeyCurvePoint = [[STDSEllipticCurvePoint alloc] initWithKey:_publicKey]; + return [NSString stringWithFormat:@"{\"kty\":\"EC\",\"crv\":\"P-256\",\"x\":\"%@\",\"y\":\"%@\"}", [publicKeyCurvePoint.x _stds_base64URLEncodedString], [publicKeyCurvePoint.y _stds_base64URLEncodedString]]; +} + +- (nullable NSData *)createSharedSecretWithEllipticCurveKey:(STDSEllipticCurvePoint *)ecKey { + return [self _createSharedSecretWithPrivateKey:_privateKey publicKey:ecKey.publicKey]; +} + +- (nullable NSData *)createSharedSecretWithCertificate:(STDSDirectoryServerCertificate *)certificate { + return [self _createSharedSecretWithPrivateKey:_privateKey publicKey:certificate.publicKey]; +} + +- (nullable NSData *)_createSharedSecretWithPrivateKey:(SecKeyRef)privateKey publicKey:(SecKeyRef)publicKey { + NSDictionary *params = @{(__bridge NSString *)kSecKeyKeyExchangeParameterRequestedSize: @(32)}; + CFErrorRef error = NULL; + CFDataRef secret = SecKeyCopyKeyExchangeResult(privateKey, kSecKeyAlgorithmECDHKeyExchangeStandard, publicKey, (__bridge CFDictionaryRef)params, &error); + + return (NSData *)CFBridgingRelease(secret); +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSErrorMessage+Internal.h b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSErrorMessage+Internal.h new file mode 100644 index 0000000..3a0730c --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSErrorMessage+Internal.h @@ -0,0 +1,40 @@ +// +// STDSErrorMessage+Internal.h +// Stripe3DS2 +// +// Created by Yuki Tokuhiro on 4/9/19. +// Copyright © 2019 Stripe. All rights reserved. +// + +#import +#import "STDSErrorMessage.h" + +NS_ASSUME_NONNULL_BEGIN + +// Constructors for the circumstances in which we are required to send an ErrorMessage to the ACS +@interface STDSErrorMessage (Internal) + +/// Received an invalid message type ++ (instancetype)errorForInvalidMessageWithACSTransactionID:(NSString *)acsTransactionID + messageVersion:(NSString *)messageVersion; + +/// Encountered an invalid field parsing a JSON response ++ (nullable instancetype)errorForJSONFieldInvalidWithACSTransactionID:(NSString *)acsTransactionID messageVersion:(NSString *)messageVersion error:(NSError *)error; + +/// Encountered a missing field parsing a JSON response ++ (nullable instancetype)errorForJSONFieldMissingWithACSTransactionID:(NSString *)acsTransactionID messageVersion:(NSString *)messageVersion error:(NSError *)error; + +/// Encountered an error decrypting a networking response ++ (instancetype)errorForDecryptionErrorWithACSTransactionID:(NSString *)acsTransactionID messageVersion:(NSString *)messageVersion; + +/// Timed out ++ (instancetype)errorForTimeoutWithACSTransactionID:(NSString *)acsTransactionID messageVersion:(NSString *)messageVersion; + ++ (instancetype)errorForUnrecognizedIDWithACSTransactionID:(NSString *)transactionID messageVersion:(NSString *)messageVersion; + +/// Encountered unrecognized critical message extension(s) ++ (instancetype)errorForUnrecognizedCriticalMessageExtensionsWithACSTransactionID:(NSString *)acsTransactionID messageVersion:(NSString *)messageVersion error:(NSError *)error; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSErrorMessage+Internal.m b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSErrorMessage+Internal.m new file mode 100644 index 0000000..02eed1d --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSErrorMessage+Internal.m @@ -0,0 +1,91 @@ +// +// STDSErrorMessage+Internal.m +// Stripe3DS2 +// +// Created by Yuki Tokuhiro on 4/9/19. +// Copyright © 2019 Stripe. All rights reserved. +// + +#import "STDSErrorMessage+Internal.h" +#import "STDSStripe3DS2Error.h" + +@implementation STDSErrorMessage (Internal) + ++ (NSString *)_stringForErrorCode:(STDSErrorMessageCode)errorCode { + return [NSString stringWithFormat:@"%ld", (long)errorCode]; +} + ++ (instancetype)errorForInvalidMessageWithACSTransactionID:(nonnull NSString *)acsTransactionID messageVersion:(nonnull NSString *)messageVersion { + return [[[self class] alloc] initWithErrorCode:[self _stringForErrorCode:STDSErrorMessageCodeInvalidMessage] + errorComponent:@"C" + errorDescription:@"Message not recognized" + errorDetails:@"Unknown message type" + messageVersion:messageVersion + acsTransactionIdentifier:acsTransactionID + errorMessageType:@"CRes"]; + +} + ++ (nullable instancetype)errorForJSONFieldMissingWithACSTransactionID:(NSString *)acsTransactionID messageVersion:(NSString *)messageVersion error:(NSError *)error { + return [[[self class] alloc] initWithErrorCode:[self _stringForErrorCode:STDSErrorMessageCodeRequiredDataElementMissing] + errorComponent:@"C" + errorDescription:@"Missing Field" + errorDetails:error.userInfo[STDSStripe3DS2ErrorFieldKey] + messageVersion:messageVersion + acsTransactionIdentifier:acsTransactionID + errorMessageType:@"CRes"]; +} + ++ (nullable instancetype)errorForJSONFieldInvalidWithACSTransactionID:(NSString *)acsTransactionID messageVersion:(NSString *)messageVersion error:(NSError *)error { + return [[[self class] alloc] initWithErrorCode:[self _stringForErrorCode:STDSErrorMessageErrorInvalidDataElement] + errorComponent:@"C" + errorDescription:@"Invalid Field" + errorDetails:error.userInfo[STDSStripe3DS2ErrorFieldKey] + messageVersion:messageVersion + acsTransactionIdentifier:acsTransactionID + errorMessageType:@"CRes"]; +} + ++ (instancetype)errorForDecryptionErrorWithACSTransactionID:(NSString *)acsTransactionID messageVersion:(NSString *)messageVersion { + return [[[self class] alloc] initWithErrorCode:[self _stringForErrorCode:STDSErrorMessageErrorDataDecryptionFailure] + errorComponent:@"C" + errorDescription:@"Response could not be decrypted." + errorDetails:@"Response could not be decrypted.s" + messageVersion:messageVersion + acsTransactionIdentifier:acsTransactionID + errorMessageType:@"CRes"]; +} + ++ (instancetype)errorForTimeoutWithACSTransactionID:(NSString *)acsTransactionID messageVersion:(NSString *)messageVersion { + return [[[self class] alloc] initWithErrorCode:[self _stringForErrorCode:STDSErrorMessageErrorTimeout] + errorComponent:@"C" + errorDescription:@"Transaction timed out." + errorDetails:@"Transaction timed out." + messageVersion:messageVersion + acsTransactionIdentifier:acsTransactionID + errorMessageType:@"CRes"]; +} + ++ (instancetype)errorForUnrecognizedIDWithACSTransactionID:(NSString *)acsTransactionID messageVersion:(NSString *)messageVersion { + return [[[self class] alloc] initWithErrorCode:[self _stringForErrorCode:STDSErrorMessageErrorTransactionIDNotRecognized] + errorComponent:@"C" + errorDescription:@"Unrecognized transaction ID" + errorDetails:@"Unrecognized transaction ID" + messageVersion:messageVersion + acsTransactionIdentifier:acsTransactionID + errorMessageType:@"CRes"]; +} + ++ (instancetype)errorForUnrecognizedCriticalMessageExtensionsWithACSTransactionID:(NSString *)acsTransactionID messageVersion:(NSString *)messageVersion error:(NSError *)error { + NSArray *unrecognizedIDs = error.userInfo[STDSStripe3DS2UnrecognizedCriticalMessageExtensionsKey]; + + return [[[self class] alloc] initWithErrorCode:[self _stringForErrorCode:STDSErrorMessageCodeUnrecognizedCriticalMessageExtension] + errorComponent:@"C" + errorDescription:@"Critical message extension not recognised." + errorDetails:[unrecognizedIDs componentsJoinedByString:@","] + messageVersion:messageVersion + acsTransactionIdentifier:acsTransactionID + errorMessageType:@"CRes"]; +} + +@end diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSErrorMessage.m b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSErrorMessage.m new file mode 100644 index 0000000..1e80b64 --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSErrorMessage.m @@ -0,0 +1,94 @@ +// +// STDSErrorMessage.m +// Stripe3DS2 +// +// Created by Yuki Tokuhiro on 3/21/19. +// Copyright © 2019 Stripe. All rights reserved. +// + +#import "STDSErrorMessage.h" + +#import "NSDictionary+DecodingHelpers.h" +#import "STDSJSONEncoder.h" +#import "STDSStripe3DS2Error.h" + +NS_ASSUME_NONNULL_BEGIN + +@implementation STDSErrorMessage + +- (instancetype)initWithErrorCode:(NSString *)errorCode + errorComponent:(NSString *)errorComponent + errorDescription:(NSString *)errorDescription + errorDetails:(nullable NSString *)errorDetails + messageVersion:(NSString *)messageVersion + acsTransactionIdentifier:(nullable NSString *)acsTransactionIdentifier + errorMessageType:(NSString *)errorMessageType { + self = [super init]; + if (self) { + _errorCode = [errorCode copy]; + _errorComponent = [errorComponent copy]; + _errorDescription = [errorDescription copy]; + _errorDetails = [errorDetails copy]; + _messageVersion = [messageVersion copy]; + _acsTransactionIdentifier = [acsTransactionIdentifier copy]; + _errorMessageType = [errorMessageType copy]; + } + return self; +} + +- (NSString *)messageType { + return @"Erro"; +} + +- (NSError *)NSErrorValue { + return [NSError errorWithDomain:STDSStripe3DS2ErrorDomain + code:[self.errorCode integerValue] + userInfo: [STDSJSONEncoder dictionaryForObject:self]]; +} + +#pragma mark - STDSJSONEncodable + ++ (NSDictionary *)propertyNamesToJSONKeysMapping { + return @{ + NSStringFromSelector(@selector(errorCode)): @"errorCode", + NSStringFromSelector(@selector(errorComponent)): @"errorComponent", + NSStringFromSelector(@selector(errorDescription)): @"errorDescription", + NSStringFromSelector(@selector(errorDetails)): @"errorDetail", + NSStringFromSelector(@selector(messageType)): @"messageType", + NSStringFromSelector(@selector(messageVersion)): @"messageVersion", + NSStringFromSelector(@selector(acsTransactionIdentifier)): @"acsTransID", + NSStringFromSelector(@selector(errorMessageType)): @"errorMessageType", + }; +} + +#pragma mark - STDSJSONDecodable + ++ (nullable instancetype)decodedObjectFromJSON:(nullable NSDictionary *)json error:(NSError * _Nullable __autoreleasing * _Nullable)outError { + if (json == nil) { + return nil; + } + NSError *error; + + // Required + NSString *errorCode = [json _stds_stringForKey:@"errorCode" required:YES error:&error]; + NSString *errorComponent = [json _stds_stringForKey:@"errorComponent" required:YES error:&error]; + NSString *errorDescription = [json _stds_stringForKey:@"errorDescription" required:YES error:&error]; + NSString *errorDetail = [json _stds_stringForKey:@"errorDetail" required:YES error:&error]; + NSString *messageVersion = [json _stds_stringForKey:@"messageVersion" required:YES error:&error]; + + // Optional + NSString *errorMessageType = [json _stds_stringForKey:@"errorMessageType" required:NO error:&error]; + NSString *acsTransactionIdentifier = [json _stds_stringForKey:@"acsTransID" required:NO error:nil]; + + if (error) { + if (outError) { + *outError = error; + } + return nil; + } + return [[self alloc] initWithErrorCode:errorCode errorComponent:errorComponent errorDescription:errorDescription errorDetails:errorDetail messageVersion:messageVersion acsTransactionIdentifier:acsTransactionIdentifier errorMessageType:errorMessageType]; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSException+Internal.h b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSException+Internal.h new file mode 100644 index 0000000..3429aba --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSException+Internal.h @@ -0,0 +1,19 @@ +// +// STDSException+Internal.h +// Stripe3DS2 +// +// Created by Cameron Sabol on 1/22/19. +// Copyright © 2019 Stripe. All rights reserved. +// + +#import "STDSException.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface STDSException (Internal) + ++ (instancetype)exceptionWithMessage:(NSString *)format, ...; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSException.m b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSException.m new file mode 100644 index 0000000..673d5bb --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSException.m @@ -0,0 +1,27 @@ +// +// STDSException.m +// Stripe3DS2 +// +// Created by Cameron Sabol on 1/22/19. +// Copyright © 2019 Stripe. All rights reserved. +// + +#import "STDSException.h" + +NS_ASSUME_NONNULL_BEGIN + +@implementation STDSException + ++ (instancetype)exceptionWithMessage:(NSString *)format, ... { + va_list args; + va_start(args, format); + NSString *message = [[NSString alloc] initWithFormat:format arguments:args]; + va_end(args); + STDSException *exception = [[[self class] alloc] initWithName:NSStringFromClass([self class]) reason:message userInfo:nil]; + exception->_message = [message copy]; + return exception; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSExpandableInformationView.h b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSExpandableInformationView.h new file mode 100644 index 0000000..f6f3ee0 --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSExpandableInformationView.h @@ -0,0 +1,23 @@ +// +// STDSExpandableInformationView.h +// Stripe3DS2 +// +// Created by Andrew Harrison on 3/11/19. +// Copyright © 2019 Stripe. All rights reserved. +// + +#import +#import "STDSFooterCustomization.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface STDSExpandableInformationView : UIView + +@property (nonatomic, strong, nullable) NSString *title; +@property (nonatomic, strong, nullable) NSString *text; +@property (nonatomic, strong, nullable) STDSFooterCustomization *customization; +@property (nonatomic, strong, nullable) void (^didTap)(void); + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSExpandableInformationView.m b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSExpandableInformationView.m new file mode 100644 index 0000000..9b1bbdf --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSExpandableInformationView.m @@ -0,0 +1,150 @@ +// +// STDSExpandableInformationView.m +// Stripe3DS2 +// +// Created by Andrew Harrison on 3/11/19. +// Copyright © 2019 Stripe. All rights reserved. +// + +#import "STDSLocalizedString.h" +#import "STDSBundleLocator.h" +#import "STDSExpandableInformationView.h" +#import "STDSStackView.h" +#import "UIView+LayoutSupport.h" +#import "NSString+EmptyChecking.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface STDSExpandableInformationView() + +@property (nonatomic, strong) UIView *tappableView; +@property (nonatomic, strong) STDSStackView *textContainerView; +@property (nonatomic, strong) STDSStackView *imageViewStackView; +@property (nonatomic, strong) UIView *imageViewSpacerView; +@property (nonatomic, strong) UILabel *titleLabel; +@property (nonatomic, strong) UILabel *textLabel; +@property (nonatomic, strong) UIImageView *titleImageView; + +@end + +@implementation STDSExpandableInformationView + +static const CGFloat kTitleContainerSpacing = 20; +static const CGFloat kTextContainerSpacing = 13; +static const CGFloat kExpandableInformationViewBottomMargin = 30; +static const CGFloat kTitleImageViewRotationAnimationDuration = (CGFloat)0.2; + +- (instancetype)initWithFrame:(CGRect)frame { + self = [super initWithFrame:frame]; + + if (self) { + [self _setupViewHierarchy]; + self.accessibilityIdentifier = @"STDSExpandableInformationView"; + } + + return self; +} + +- (void)_setupViewHierarchy { + self.layoutMargins = UIEdgeInsetsMake(0, 0, kExpandableInformationViewBottomMargin, 0); + + self.titleLabel = [[UILabel alloc] init]; + // Set titleLabel as not an accessibility element because we make the + // container, which is the actual control, have the same accessibility label + // and accurately reflects that interactivity and state of the control + self.titleLabel.isAccessibilityElement = NO; + self.titleLabel.numberOfLines = 0; + + self.textLabel = [[UILabel alloc] init]; + self.textLabel.numberOfLines = 0; + + UIImage *chevronImage = [[UIImage imageNamed:@"Chevron" inBundle:[STDSBundleLocator stdsResourcesBundle] compatibleWithTraitCollection:nil] imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate]; + self.titleImageView = [[UIImageView alloc] initWithImage:chevronImage]; + self.titleImageView.contentMode = UIViewContentModeScaleAspectFit; + + STDSStackView *containerView = [[STDSStackView alloc] initWithAlignment:STDSStackViewLayoutAxisHorizontal]; + [self addSubview:containerView]; + [containerView _stds_pinToSuperviewBounds]; + + STDSStackView *titleContainerView = [[STDSStackView alloc] initWithAlignment:STDSStackViewLayoutAxisVertical]; + [titleContainerView addArrangedSubview:self.titleLabel]; + + self.imageViewStackView = [[STDSStackView alloc] initWithAlignment:STDSStackViewLayoutAxisVertical]; + self.imageViewSpacerView = [UIView new]; + [self.imageViewStackView addArrangedSubview:self.titleImageView]; + + [containerView addArrangedSubview:self.imageViewStackView]; + [containerView addSpacer:kTitleContainerSpacing]; + [containerView addArrangedSubview:titleContainerView]; + [containerView addArrangedSubview:[UIView new]]; + + self.textContainerView = [[STDSStackView alloc] initWithAlignment:STDSStackViewLayoutAxisVertical]; + self.textContainerView.hidden = YES; + [self.textContainerView addSpacer:kTextContainerSpacing]; + [self.textContainerView addArrangedSubview:self.textLabel]; + [titleContainerView addArrangedSubview:self.textContainerView]; + + UITapGestureRecognizer *expandTextTapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(_toggleTextExpansion)]; + [containerView addGestureRecognizer:expandTextTapRecognizer]; + containerView.accessibilityTraits |= UIAccessibilityTraitButton; + containerView.isAccessibilityElement = YES; + self.tappableView = containerView; + [self _updateTappableViewAccessibilityValue]; +} + +- (void)setTitle:(NSString * _Nullable)title { + _title = title; + + self.titleLabel.text = title; + self.tappableView.accessibilityLabel = title; +} + +- (void)setText:(NSString * _Nullable)text { + _text = text; + + self.textLabel.text = text; +} + +- (void)_updateTappableViewAccessibilityValue { + if (self.textContainerView.isHidden) { + self.tappableView.accessibilityValue = STDSLocalizedString(@"Collapsed", @"Accessibility label for expandandable text control to indicate text is hidden."); + } else { + self.tappableView.accessibilityValue = STDSLocalizedString(@"Expanded", @"Accessibility label for expandandable text control to indicate that the UI has been expanded and additional text is available."); + } +} + +- (void)_toggleTextExpansion { + if (self.didTap) { + self.didTap(); + } + self.textContainerView.hidden = !self.textContainerView.hidden; + + CGFloat rotationValue = (CGFloat)M_PI_2; + if (self.textContainerView.isHidden) { + rotationValue = (CGFloat)0; + [self.imageViewStackView removeArrangedSubview:self.imageViewSpacerView]; + UIAccessibilityPostNotification(UIAccessibilityLayoutChangedNotification, self.titleLabel); + } else { + [self.imageViewStackView addArrangedSubview:self.imageViewSpacerView]; + UIAccessibilityPostNotification(UIAccessibilityLayoutChangedNotification, self.textLabel); + } + [self _updateTappableViewAccessibilityValue]; + + [UIView animateWithDuration:kTitleImageViewRotationAnimationDuration animations:^{ + self.titleImageView.transform = CGAffineTransformMakeRotation(rotationValue); + }]; +} + +- (void)setCustomization:(STDSFooterCustomization * _Nullable)customization { + self.titleLabel.font = customization.headingFont; + self.titleLabel.textColor = customization.headingTextColor; + + self.textLabel.font = customization.font; + self.textLabel.textColor = customization.textColor; + + self.titleImageView.tintColor = customization.chevronColor; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSFooterCustomization.m b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSFooterCustomization.m new file mode 100644 index 0000000..6c770fd --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSFooterCustomization.m @@ -0,0 +1,45 @@ +// +// STDSFooterCustomization.m +// Stripe3DS2 +// +// Created by Yuki Tokuhiro on 6/10/19. +// Copyright © 2019 Stripe. All rights reserved. +// + +#import "STDSFooterCustomization.h" + +#import "UIFont+DefaultFonts.h" +#import "UIColor+DefaultColors.h" +#import "UIColor+ThirteenSupport.h" + +@implementation STDSFooterCustomization + ++ (instancetype)defaultSettings { + return [self new]; +} + +- (instancetype)init { + self = [super init]; + if (self) { + self.textColor = UIColor._stds_labelColor; + _headingTextColor = UIColor._stds_labelColor; + _backgroundColor = [UIColor _stds_defaultFooterBackgroundColor]; + _chevronColor = [UIColor _stds_systemGray2Color]; + self.font = [UIFont _stds_defaultLabelTextFontWithScale:(CGFloat)0.9]; + _headingFont = [UIFont _stds_defaultLabelTextFontWithScale:(CGFloat)0.9]; + } + return self; +} + +- (instancetype)copyWithZone:(nullable NSZone *)zone { + STDSFooterCustomization *copy = [super copyWithZone:zone]; + copy.headingTextColor = self.headingTextColor; + copy.headingFont = self.headingFont; + copy.backgroundColor = self.backgroundColor; + copy.chevronColor = self.chevronColor; + + return copy; +} + + +@end diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSIPAddress.h b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSIPAddress.h new file mode 100644 index 0000000..a6d5911 --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSIPAddress.h @@ -0,0 +1,15 @@ +// +// STDSIPAddress.h +// Stripe3DS2 +// +// Created by Cameron Sabol on 1/23/19. +// Copyright © 2019 Stripe. All rights reserved. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +NSString * _Nullable STDSCurrentDeviceIPAddress(void); + +NS_ASSUME_NONNULL_END diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSIPAddress.m b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSIPAddress.m new file mode 100644 index 0000000..4c8ccc9 --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSIPAddress.m @@ -0,0 +1,43 @@ +// +// STDSIPAddress.m +// Stripe3DS2 +// +// Created by Cameron Sabol on 1/23/19. +// Copyright © 2019 Stripe. All rights reserved. +// + +#import "STDSIPAddress.h" + +#include +#include + +// source: https://zachwaugh.com/posts/programmatically-retrieving-ip-address-of-iphone +NSString * STDSCurrentDeviceIPAddress() { + NSString *address = nil; + struct ifaddrs *interfaces = NULL; + struct ifaddrs *temp_addr = NULL; + int success = 0; + + // retrieve the current interfaces - returns 0 on success + success = getifaddrs(&interfaces); + if (success == 0) { + // Loop through linked list of interfaces + temp_addr = interfaces; + while (temp_addr != NULL) { + if( temp_addr->ifa_addr->sa_family == AF_INET) { + // Check if interface is en0 which is the wifi connection on the iPhone + if ([[NSString stringWithUTF8String:temp_addr->ifa_name] isEqualToString:@"en0"]) { + // Get NSString from C String + address = [NSString stringWithUTF8String:inet_ntoa(((struct sockaddr_in *)temp_addr->ifa_addr)->sin_addr)]; + } + } + + temp_addr = temp_addr->ifa_next; + } + } + + // Free memory + freeifaddrs(interfaces); + + return address; +} diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSImageLoader.h b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSImageLoader.h new file mode 100644 index 0000000..15f1396 --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSImageLoader.h @@ -0,0 +1,36 @@ +// +// STDSImageLoader.h +// Stripe3DS2 +// +// Created by Andrew Harrison on 3/5/19. +// Copyright © 2019 Stripe. All rights reserved. +// + +#import +#import + +NS_ASSUME_NONNULL_BEGIN + +typedef void (^STDSImageDownloadCompletionBlock)(UIImage * _Nullable); + +@interface STDSImageLoader: NSObject + +/** + Initializes an `STDSImageLoader` with the given parameters. + + @param session The session to initialize the loader with. + @return Returns an initialized `STDSImageLoader` object. + */ +- (instancetype)initWithURLSession:(NSURLSession *)session; + +/** + Attempts to load an image from the specified URL. + + @param URL The URL to load an image for. + @param completion A completion block that is called when the image loading has finished. This will be called on the main queue. + */ +- (void)loadImageFromURL:(NSURL *)URL completion:(STDSImageDownloadCompletionBlock)completion; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSImageLoader.m b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSImageLoader.m new file mode 100644 index 0000000..1d87e44 --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSImageLoader.m @@ -0,0 +1,50 @@ +// +// STDSImageLoader.m +// Stripe3DS2 +// +// Created by Andrew Harrison on 3/5/19. +// Copyright © 2019 Stripe. All rights reserved. +// + +#import +#import "STDSImageLoader.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface STDSImageLoader() + +@property (nonatomic, strong) NSURLSession *session; + +@end + +@implementation STDSImageLoader + +- (instancetype)initWithURLSession:(NSURLSession *)session { + self = [super init]; + + if (self) { + _session = session; + } + + return self; +} + +- (void)loadImageFromURL:(NSURL *)URL completion:(STDSImageDownloadCompletionBlock)completion { + NSURLSessionDataTask *dataTask = [self.session dataTaskWithURL:URL completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) { + UIImage *image; + + if (data != nil) { + image = [UIImage imageWithData:data]; + } + + [NSOperationQueue.mainQueue addOperationWithBlock:^{ + completion(image); + }]; + }]; + + [dataTask resume]; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSIntegrityChecker.h b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSIntegrityChecker.h new file mode 100644 index 0000000..ed584de --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSIntegrityChecker.h @@ -0,0 +1,19 @@ +// +// STDSIntegrityChecker.h +// Stripe3DS2 +// +// Created by Andrew Harrison on 4/8/19. +// Copyright © 2019 Stripe. All rights reserved. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface STDSIntegrityChecker : NSObject + ++ (BOOL)SDKIntegrityIsValid; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSIntegrityChecker.m b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSIntegrityChecker.m new file mode 100644 index 0000000..73ed1ea --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSIntegrityChecker.m @@ -0,0 +1,41 @@ +// +// STDSIntegrityChecker.m +// Stripe3DS2 +// +// Created by Andrew Harrison on 4/8/19. +// Copyright © 2019 Stripe. All rights reserved. +// + +#import "STDSIntegrityChecker.h" +#import "Stripe3DS2.h" + +NS_ASSUME_NONNULL_BEGIN + +@implementation STDSIntegrityChecker + ++ (BOOL)SDKIntegrityIsValid { + + if (NSClassFromString(@"STDSIntegrityChecker") == [STDSIntegrityChecker class] && + NSClassFromString(@"STDSConfigParameters") == [STDSConfigParameters class] && + NSClassFromString(@"STDSThreeDS2Service") == [STDSThreeDS2Service class] && + NSClassFromString(@"STDSUICustomization") == [STDSUICustomization class] && + NSClassFromString(@"STDSWarning") == [STDSWarning class] && + NSClassFromString(@"STDSAlreadyInitializedException") == [STDSAlreadyInitializedException class] && + NSClassFromString(@"STDSNotInitializedException") == [STDSNotInitializedException class] && + NSClassFromString(@"STDSRuntimeException") == [STDSRuntimeException class] && + NSClassFromString(@"STDSErrorMessage") == [STDSErrorMessage class] && + NSClassFromString(@"STDSRuntimeErrorEvent") == [STDSRuntimeErrorEvent class] && + NSClassFromString(@"STDSProtocolErrorEvent") == [STDSProtocolErrorEvent class] && + NSClassFromString(@"STDSAuthenticationRequestParameters") == [STDSAuthenticationRequestParameters class] && + NSClassFromString(@"STDSChallengeParameters") == [STDSChallengeParameters class] && + NSClassFromString(@"STDSCompletionEvent") == [STDSCompletionEvent class] && + NSClassFromString(@"STDSTransaction") == [STDSTransaction class]) { + return YES; + } + + return NO; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSInvalidInputException.m b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSInvalidInputException.m new file mode 100644 index 0000000..7ff4cd3 --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSInvalidInputException.m @@ -0,0 +1,17 @@ +// +// STDSInvalidInputException.m +// Stripe3DS2 +// +// Created by Cameron Sabol on 1/22/19. +// Copyright © 2019 Stripe. All rights reserved. +// + +#import "STDSInvalidInputException.h" + +NS_ASSUME_NONNULL_BEGIN + +@implementation STDSInvalidInputException + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSJSONEncoder.m b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSJSONEncoder.m new file mode 100644 index 0000000..4c55b02 --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSJSONEncoder.m @@ -0,0 +1,51 @@ +// +// STDSJSONEncoder.m +// Stripe3DS2 +// +// Created by Yuki Tokuhiro on 3/25/19. +// Copyright © 2019 Stripe. All rights reserved. +// + +#import "STDSJSONEncoder.h" + +@implementation STDSJSONEncoder + ++ (NSDictionary *)dictionaryForObject:(nonnull NSObject *)object { + NSMutableDictionary *keyPairs = [NSMutableDictionary dictionary]; + [[object.class propertyNamesToJSONKeysMapping] enumerateKeysAndObjectsUsingBlock:^(NSString * _Nonnull propertyName, NSString * _Nonnull keyName, __unused BOOL * _Nonnull stop) { + id value = [self jsonEncodableValueForObject:[object valueForKey:propertyName]]; + if (value != [NSNull null]) { + keyPairs[keyName] = value; + } + }]; + return [keyPairs copy]; +} + ++ (id)jsonEncodableValueForObject:(NSObject *)object { + if ([object conformsToProtocol:@protocol(STDSJSONEncodable)]) { + return [self dictionaryForObject:(NSObject*)object]; + } else if ([object isKindOfClass:[NSDictionary class]]) { + NSDictionary *dict = (NSDictionary *)object; + NSMutableDictionary *result = [NSMutableDictionary dictionaryWithCapacity:dict.count]; + + [dict enumerateKeysAndObjectsUsingBlock:^(id _Nonnull key, id _Nonnull value, __unused BOOL * _Nonnull stop) { + result[key] = [self jsonEncodableValueForObject:value]; + }]; + + return result; + } else if ([object isKindOfClass:[NSArray class]]) { + NSArray *array = (NSArray *)object; + NSMutableArray *result = [NSMutableArray arrayWithCapacity:array.count]; + + for (NSObject *element in array) { + [result addObject:[self jsonEncodableValueForObject:element]]; + } + return result; + } else if ([object isKindOfClass:[NSString class]] || [object isKindOfClass:[NSNumber class]]) { + return object; + } else { + return [NSNull null]; + } +} + +@end diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSJSONWebEncryption.h b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSJSONWebEncryption.h new file mode 100644 index 0000000..2b2bc30 --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSJSONWebEncryption.h @@ -0,0 +1,45 @@ +// +// STDSJSONWebEncryption.h +// Stripe3DS2 +// +// Created by Cameron Sabol on 1/24/19. +// Copyright © 2019 Stripe. All rights reserved. +// + +#import + +#import "STDSDirectoryServer.h" + +@class STDSDirectoryServerCertificate; +@class STDSJSONWebSignature; + +NS_ASSUME_NONNULL_BEGIN + +@interface STDSJSONWebEncryption : NSObject + ++ (nullable NSString *)encryptJSON:(NSDictionary *)json + forDirectoryServer:(STDSDirectoryServer)directoryServer + error:(out NSError * _Nullable *)error; + ++ (nullable NSString *)encryptJSON:(NSDictionary *)json + withCertificate:(STDSDirectoryServerCertificate *)certificate + directoryServerID:(NSString *)directoryServerID + serverKeyID:(nullable NSString *)serverKeyID + error:(out NSError * _Nullable *)error; + ++ (nullable NSString *)directEncryptJSON:(NSDictionary *)json + withContentEncryptionKey:(NSData *)contentEncryptionKey + forACSTransactionID:(NSString *)acsTransactionID + error:(out NSError * _Nullable *)error; + ++ (nullable NSDictionary *)decryptData:(NSData *)data + withContentEncryptionKey:(NSData *)contentEncryptionKey + error:(out NSError * _Nullable *)error; + ++ (BOOL)verifyJSONWebSignature:(STDSJSONWebSignature *)jws forDirectoryServer:(STDSDirectoryServer)directoryServer; + ++ (BOOL)verifyJSONWebSignature:(STDSJSONWebSignature *)jws withCertificate:(STDSDirectoryServerCertificate *)certificate rootCertificates:(NSArray *)rootCertificates; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSJSONWebEncryption.m b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSJSONWebEncryption.m new file mode 100644 index 0000000..57023a5 --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSJSONWebEncryption.m @@ -0,0 +1,407 @@ +// +// STDSJSONWebEncryption.m +// Stripe3DS2 +// +// Created by Cameron Sabol on 1/24/19. +// Copyright © 2019 Stripe. All rights reserved. +// + +#import "STDSJSONWebEncryption.h" + +#import +#import + +#import "NSData+JWEHelpers.h" +#import "NSError+Stripe3DS2.h" +#import "NSString+JWEHelpers.h" +#import "STDSDirectoryServerCertificate.h" +#import "STDSEphemeralKeyPair.h" +#import "STDSJSONWebSignature.h" +#import "STDSSecTypeUtilities.h" + +NS_ASSUME_NONNULL_BEGIN + +#pragma mark - _STPJSONWebEncryptionResult +@interface _STPJSONWebEncryptionResult : NSObject + +- (instancetype)initWithCiphertext:(NSData *)ciphertextData + initializationVector:(NSData *)initializationVector + hmacTag:(NSData *)hmacTag; + +@property (nonatomic, copy, readonly) NSData *ciphertextData; +@property (nonatomic, copy, readonly) NSData *initializationVector; +@property (nonatomic, copy, readonly) NSData *hmacTag; + +@end + +@implementation _STPJSONWebEncryptionResult + +- (instancetype)initWithCiphertext:(NSData *)ciphertextData + initializationVector:(NSData *)initializationVector + hmacTag:(NSData *)hmacTag { + self = [super init]; + if (self) { + _ciphertextData = [ciphertextData copy]; + _initializationVector = [initializationVector copy]; + _hmacTag = [hmacTag copy]; + } + + return self; +} + +@end + +#pragma mark - STDSJSONWebEncryption + +static const size_t kContentEncryptionKeyByteCount = 32; +static const size_t kHMACSubKeyByteCount = 16; +static const size_t kAESSubKeyByteCount = 16; + +@implementation STDSJSONWebEncryption + ++ (nullable NSString *)encryptJSON:(NSDictionary *)json + forDirectoryServer:(STDSDirectoryServer)directoryServer + error:(out NSError *__autoreleasing _Nullable * _Nullable)error { + + NSString *ciphertext = nil; + + STDSDirectoryServerCertificate *certificate = [STDSDirectoryServerCertificate certificateForDirectoryServer:directoryServer]; + NSString *directoryServerID = STDSDirectoryServerIdentifier(directoryServer); + + if (certificate != nil && directoryServerID != nil) { + + ciphertext = [self encryptJSON:json + withCertificate:certificate + directoryServerID:directoryServerID + serverKeyID:nil + error:error]; + } + + if (error != nil && ciphertext == nil) { + *error = *error ?: [NSError _stds_jweError]; + } + + return ciphertext; +} + ++ (nullable NSString *)encryptJSON:(NSDictionary *)json + withCertificate:(STDSDirectoryServerCertificate *)certificate + directoryServerID:(NSString *)directoryServerID + serverKeyID:(nullable NSString *)serverKeyID + error:(out NSError * _Nullable *)error { + + NSString *ciphertext = nil; + NSError *jsonError = nil; + NSData * jsonData = [NSJSONSerialization dataWithJSONObject:json options:0 error:&jsonError]; + + if (jsonData != nil) { + + switch (certificate.keyType) { + case STDSDirectoryServerKeyTypeRSA: + ciphertext = [self _RSAEncryptPlaintext:jsonData + withCertificate:certificate + serverKeyID:serverKeyID]; + break; + + case STDSDirectoryServerKeyTypeEC: + ciphertext = [self _directEncryptPlaintext:jsonData + withCertificate:certificate + forDirectoryServer:directoryServerID]; + break; + + case STDSDirectoryServerKeyTypeUnknown: + break; + } + } + + if (error != nil && ciphertext == nil) { + *error = jsonError ?: [NSError _stds_jweError]; + } + + return ciphertext; +} + ++ (nullable NSString *)directEncryptJSON:(NSDictionary *)json + withContentEncryptionKey:(NSData *)contentEncryptionKey + forACSTransactionID:(NSString *)acsTransactionID + error:(out NSError * _Nullable *)error { + NSString *ciphertext = nil; + + NSError *jsonError = nil; + + + NSData * jsonData = [NSJSONSerialization dataWithJSONObject:json options:0 error:&jsonError]; + + if (jsonData != nil) { + NSString *headerString = [NSString stringWithFormat:@"{\"kid\":\"%@\",\"enc\":\"A128CBC-HS256\",\"alg\":\"dir\"}", acsTransactionID]; + ciphertext = [self _directEncryptPlaintext:jsonData + withContentEncryptionKey:contentEncryptionKey + headerString:headerString]; + } + + if (error != nil && ciphertext == nil) { + *error = jsonError ?: [NSError _stds_jweError]; + } + + return ciphertext; +} + ++ (nullable NSData *)_hmacTagWithKey:(NSData *)hmacSubKey + headerString:(NSString *)headerString + initializationVector:(NSData *)initializationVector + cipherText:(NSData *)cipherText { + NSString *encodedHeaderString = [headerString _stds_base64URLEncodedString]; + + // Per JWE spec, the encoded header data is included as additional authenticated data but with ASCII encoding https://tools.ietf.org/html/rfc7516#section-5.1 + NSData *additionalAuthenticatedData = [encodedHeaderString dataUsingEncoding:NSASCIIStringEncoding]; + uint64_t AL = CFSwapInt64HostToBig(additionalAuthenticatedData.length*8); + + NSMutableData *d = [NSMutableData data]; + [d appendBytes:additionalAuthenticatedData.bytes length:additionalAuthenticatedData.length]; + [d appendBytes:initializationVector.bytes length:initializationVector.length]; + [d appendBytes:cipherText.bytes length:cipherText.length]; + [d appendBytes:&AL length:sizeof(AL)]; + + NSMutableData *M = [[NSMutableData alloc] initWithLength:CC_SHA256_DIGEST_LENGTH]; + + CCHmac(kCCHmacAlgSHA256, + hmacSubKey.bytes, + kHMACSubKeyByteCount, + d.bytes, + d.length, + M.mutableBytes); + + + NSData *hmacTag = [M subdataWithRange:NSMakeRange(0, 16)]; + + return hmacTag; +} + ++ (nullable _STPJSONWebEncryptionResult *)_encryptPlaintext:(NSData *)plaintextData + withKey:(NSData *)contentEncryptionKeyData + headerString:(NSString *)headerString { + // ecrypt JSON according to JWE (RFC 7516) using JWE Compact Serialization + // enc: A128CBC-HS256 + + // Ref: rfc7518 sec 5.2.3 https://www.rfc-editor.org/rfc/rfc7518.txt + + _STPJSONWebEncryptionResult *result = nil; + + static const size_t kInitializationVectorByteCount = 16; + + NSAssert(contentEncryptionKeyData.length == kContentEncryptionKeyByteCount, @"Must use a valid 256 content encryption key"); + if (contentEncryptionKeyData.length == kContentEncryptionKeyByteCount) { + + NSData *hmacSubKeyData = [contentEncryptionKeyData subdataWithRange:NSMakeRange(0, kHMACSubKeyByteCount)]; + NSData *aesSubKeyData = [contentEncryptionKeyData subdataWithRange:NSMakeRange(kHMACSubKeyByteCount, kAESSubKeyByteCount)]; + NSData *initializationVectorData = STDSCryptoRandomData(kInitializationVectorByteCount); + + + // pad with block size for AES + NSMutableData *ciphertextData = [NSMutableData dataWithLength:plaintextData.length + kCCBlockSizeAES128]; + size_t outLength; + CCCryptorStatus aesEncryptionResult = CCCrypt(kCCEncrypt, + kCCAlgorithmAES, + kCCOptionPKCS7Padding, + aesSubKeyData.bytes, + kAESSubKeyByteCount, + initializationVectorData.bytes, + plaintextData.bytes, + (size_t)plaintextData.length, + ciphertextData.mutableBytes, + ciphertextData.length, + &outLength); + if (aesEncryptionResult == kCCSuccess) { + ciphertextData.length = outLength; + + NSData *hmacTag = [self _hmacTagWithKey:hmacSubKeyData + headerString:headerString + initializationVector:initializationVectorData + cipherText:ciphertextData]; + + result = [[_STPJSONWebEncryptionResult alloc] initWithCiphertext:ciphertextData + initializationVector:initializationVectorData + hmacTag:hmacTag]; + } + } + + return result; +} + ++ (nullable NSString *)_RSAEncryptPlaintext:(NSData *)plaintextData + withCertificate:(STDSDirectoryServerCertificate *)certificate + serverKeyID:(nullable NSString *)serverKeyID { + NSData *contentEncryptionKey = STDSCryptoRandomData(kContentEncryptionKeyByteCount); + if (contentEncryptionKey != nil) { + NSString *headerString = nil; + + if (serverKeyID != nil) { + headerString = [NSString stringWithFormat:@"{\"enc\":\"A128CBC-HS256\",\"alg\":\"RSA-OAEP-256\",\"kid\":\"%@\"}", serverKeyID]; + } else { + headerString = @"{\"enc\":\"A128CBC-HS256\",\"alg\":\"RSA-OAEP-256\"}"; + + } + _STPJSONWebEncryptionResult *encryptedData = [self _encryptPlaintext:plaintextData + withKey:contentEncryptionKey + headerString:headerString]; + if (encryptedData != nil) { + NSData *encryptedCEK = [certificate encryptDataUsingRSA_OAEP_SHA256:contentEncryptionKey]; + if (encryptedCEK != nil) { + return [NSString stringWithFormat:@"%@.%@.%@.%@.%@", [headerString _stds_base64URLEncodedString], [encryptedCEK _stds_base64URLEncodedString], [encryptedData.initializationVector _stds_base64URLEncodedString], [encryptedData.ciphertextData _stds_base64URLEncodedString], [encryptedData.hmacTag _stds_base64URLEncodedString]]; + } + } + } + + return nil; +} + ++ (nullable NSString *)_directEncryptPlaintext:(NSData *)plaintextData + withCertificate:(STDSDirectoryServerCertificate *)certificate + forDirectoryServer:(NSString *)directoryServerID { + + STDSEphemeralKeyPair *ephemeralKeyPair = [STDSEphemeralKeyPair ephemeralKeyPair]; + NSData *rawSharedSecret = [ephemeralKeyPair createSharedSecretWithCertificate:certificate]; + NSData *contentEncryptionKey = STDSCreateConcatKDFWithSHA256(rawSharedSecret, kContentEncryptionKeyByteCount, directoryServerID); + + NSString *headerString = [NSString stringWithFormat:@"{\"enc\":\"A128CBC-HS256\",\"alg\":\"ECDH-ES\",\"epk\":%@}", ephemeralKeyPair.publicKeyJWK]; + + return [self _directEncryptPlaintext:plaintextData + withContentEncryptionKey:contentEncryptionKey + headerString:headerString]; +} + ++ (nullable NSString *)_directEncryptPlaintext:(NSData *)plaintextData + withContentEncryptionKey:(NSData *)contentEncryptionKey + headerString:(NSString *)headerString { + + _STPJSONWebEncryptionResult *encryptedData = [self _encryptPlaintext:plaintextData + withKey:contentEncryptionKey + headerString:headerString]; + if (encryptedData != nil) { + return [NSString stringWithFormat:@"%@..%@.%@.%@", [headerString _stds_base64URLEncodedString], [encryptedData.initializationVector _stds_base64URLEncodedString], [encryptedData.ciphertextData _stds_base64URLEncodedString], [encryptedData.hmacTag _stds_base64URLEncodedString]]; + } + + return nil; +} + +#pragma mark - Decryption + ++ (nullable NSDictionary *)decryptData:(NSData *)data + withContentEncryptionKey:(NSData *)contentEncryptionKey + error:(out NSError * _Nullable *)error { + NSString *jweString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; + NSArray *jweComponents = [jweString componentsSeparatedByString:@"."]; + if (jweComponents.count != 5) { + + // Data may be JSON describing error + NSError *jsonError = nil; + NSDictionary *errorJSON = [NSJSONSerialization JSONObjectWithData:data options:0 error:&jsonError]; + if (errorJSON != nil) { + return errorJSON; + } + if (error != NULL) { + *error = jsonError ?: [NSError _stds_jweError]; + } + return nil; + } + + NSString *headerString = [jweComponents[0] _stds_base64URLDecodedString]; + NSData *initializationVector = [jweComponents[2] _stds_base64URLDecodedData]; + NSData *ciphertextData = [jweComponents[3] _stds_base64URLDecodedData]; + NSData *hmacTag = [jweComponents[4] _stds_base64URLDecodedData]; + + if (headerString == nil || + initializationVector == nil || + ciphertextData == nil || + hmacTag == nil + ) { + if (error != NULL) { + *error = [NSError _stds_jweError]; + } + return nil; + } + NSAssert(contentEncryptionKey.length == kContentEncryptionKeyByteCount, @"Must use a valid 256 content encryption key"); + if (contentEncryptionKey.length != kContentEncryptionKeyByteCount) { + if (error != NULL) { + *error = [NSError _stds_jweError]; + } + return nil; + } + + NSData *hmacSubKeyData = [contentEncryptionKey subdataWithRange:NSMakeRange(0, kHMACSubKeyByteCount)]; + NSData *aesSubKeyData = [contentEncryptionKey subdataWithRange:NSMakeRange(kHMACSubKeyByteCount, kAESSubKeyByteCount)]; + + // pad with block size for AES + NSMutableData *plaintextData = [NSMutableData dataWithLength:ciphertextData.length + kCCBlockSizeAES128]; + size_t outLength; + CCCryptorStatus aesDecryptionResult = CCCrypt(kCCDecrypt, + kCCAlgorithmAES, + kCCOptionPKCS7Padding, + aesSubKeyData.bytes, + kAESSubKeyByteCount, + initializationVector.bytes, + ciphertextData.bytes, + (size_t)ciphertextData.length, + plaintextData.mutableBytes, + plaintextData.length, + &outLength); + + if (aesDecryptionResult != kCCSuccess) { + if (error != NULL) { + *error = [NSError _stds_jweError]; + } + return nil; + } + + plaintextData.length = outLength; + NSData *calculatedHMACTag = [self _hmacTagWithKey:hmacSubKeyData + headerString:headerString + initializationVector:initializationVector + cipherText:ciphertextData]; + + if (![calculatedHMACTag isEqualToData:hmacTag]) { + if (error != NULL) { + *error = [NSError _stds_jweError]; + } + return nil; + } + + NSDictionary *decryptedJSON = [NSJSONSerialization JSONObjectWithData:plaintextData + options:0 + error:error]; + if (*error != NULL) { + *error = [NSError _stds_jweError]; + return nil; + } + + return decryptedJSON; +} + +#pragma mark - JSON Web Signature Verification + ++ (BOOL)verifyJSONWebSignature:(STDSJSONWebSignature *)jws forDirectoryServer:(STDSDirectoryServer)directoryServer { + STDSDirectoryServerCertificate *certificate = [STDSDirectoryServerCertificate certificateForDirectoryServer:directoryServer]; + NSString *certificateString = nil; + + if (directoryServer == STDSDirectoryServerULTestRSA || directoryServer == STDSDirectoryServerULTestEC) { + // for UL tests, the last certificate in the chain is the anchor/root + certificateString = jws.certificateChain.lastObject; + } else { + NSAssert(0, @"We shouldn't be using this path outside of UL testing"); + certificateString = certificate.certificateString; + } + + if (certificateString == nil) { + return NO; + } + + return [self verifyJSONWebSignature:jws withCertificate:certificate rootCertificates:@[certificateString]]; +} + ++ (BOOL)verifyJSONWebSignature:(STDSJSONWebSignature *)jws withCertificate:(__unused STDSDirectoryServerCertificate *)certificate rootCertificates:(NSArray *)rootCertificates { + return [STDSDirectoryServerCertificate verifyJSONWebSignature:jws withRootCertificates:rootCertificates]; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSJSONWebSignature.h b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSJSONWebSignature.h new file mode 100644 index 0000000..d6f17a1 --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSJSONWebSignature.h @@ -0,0 +1,41 @@ +// +// STDSJSONWebSignature.h +// Stripe3DS2 +// +// Created by Cameron Sabol on 4/2/19. +// Copyright © 2019 Stripe. All rights reserved. +// + +#import + +@class STDSEllipticCurvePoint; + +NS_ASSUME_NONNULL_BEGIN + +typedef NS_ENUM(NSInteger, STDSJSONWebSignatureAlgorithm) { + STDSJSONWebSignatureAlgorithmES256, + STDSJSONWebSignatureAlgorithmPS256, + STDSJSONWebSignatureAlgorithmUnknown, +}; + +@interface STDSJSONWebSignature : NSObject + +- (nullable instancetype)initWithString:(NSString *)jwsString; +- (nullable instancetype)initWithString:(NSString *)jwsString allowNilKey:(BOOL)allowNilKey; + +@property (nonatomic, readonly) STDSJSONWebSignatureAlgorithm algorithm; + +@property (nonatomic, readonly) NSData *digest; +@property (nonatomic, readonly) NSData *signature; + +@property (nonatomic, readonly) NSData *payload; + +/// non-nil if algorithm == STDSJSONWebSignatureAlgorithmES256 +@property (nonatomic, nullable, readonly) STDSEllipticCurvePoint *ellipticCurvePoint; + +/// non-nil if algorithm == STDSJSONWebSignatureAlgorithmPS256, can be non-nil for algorithm == STDSJSONWebSignatureAlgorithmES256 +@property (nonatomic, nullable, readonly) NSArray *certificateChain; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSJSONWebSignature.m b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSJSONWebSignature.m new file mode 100644 index 0000000..2e29493 --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSJSONWebSignature.m @@ -0,0 +1,88 @@ +// +// STDSJSONWebSignature.m +// Stripe3DS2 +// +// Created by Cameron Sabol on 4/2/19. +// Copyright © 2019 Stripe. All rights reserved. +// + +#import "STDSJSONWebSignature.h" + +#import "NSString+JWEHelpers.h" +#import "STDSEllipticCurvePoint.h" +#import "STDSSecTypeUtilities.h" + +NS_ASSUME_NONNULL_BEGIN + +static NSString * const kJWSAlgorithmKey = @"alg"; +static NSString * const kJWSAlgorithmES256 = @"ES256"; +static NSString * const kJWSAlgorithmPS256 = @"PS256"; + +static NSString * const kJWSCertificateChainKey = @"x5c"; + +@implementation STDSJSONWebSignature + +- (nullable instancetype)initWithString:(NSString *)jwsString { + return [self initWithString:jwsString allowNilKey:NO]; +} + +- (nullable instancetype)initWithString:(NSString *)jwsString allowNilKey:(BOOL)allowNilKey { + self = [super init]; + if (self) { + NSArray *components = [jwsString componentsSeparatedByString:@"."]; + if (components.count != 3) { + return nil; + } + NSData *headerData = [components[0] _stds_base64URLDecodedData]; + if (headerData == nil) { + return nil; + } + NSError *jsonError = nil; + NSDictionary * headerJSON = [NSJSONSerialization JSONObjectWithData:headerData options:0 error:&jsonError]; + if (headerJSON == nil) { + return nil; + } + + if (headerJSON[kJWSCertificateChainKey] != nil && ![headerJSON[kJWSCertificateChainKey] isKindOfClass:[NSArray class]]) { + return nil; + } + + _certificateChain = headerJSON[kJWSCertificateChainKey]; + + NSString *algorithm = headerJSON[kJWSAlgorithmKey]; + if ([algorithm compare:kJWSAlgorithmES256 options: NSCaseInsensitiveSearch] == NSOrderedSame) { + _algorithm = STDSJSONWebSignatureAlgorithmES256; + if (_certificateChain.count > 0) { + SecCertificateRef certificate = STDSSecCertificateFromString(_certificateChain.firstObject); + if (certificate != NULL) { + SecKeyRef key = SecCertificateCopyKey(certificate); + CFRelease(certificate); + if (key != NULL) { + _ellipticCurvePoint = [[STDSEllipticCurvePoint alloc] initWithKey:key]; + CFRelease(key); + } + } + if (_ellipticCurvePoint == nil && !allowNilKey) { + return nil; + } + } else if (!allowNilKey) { + return nil; + } + + } else if ([algorithm compare:kJWSAlgorithmPS256 options: NSCaseInsensitiveSearch] == NSOrderedSame) { + _algorithm = STDSJSONWebSignatureAlgorithmPS256; + } else { + return nil; + } + + _digest = [[@[components[0], components[1]] componentsJoinedByString:@"."] dataUsingEncoding:NSUTF8StringEncoding]; + _signature = [components[2] _stds_base64URLDecodedData]; + _payload = [components[1] _stds_base64URLDecodedData]; + } + + return self; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSJailbreakChecker.h b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSJailbreakChecker.h new file mode 100644 index 0000000..303575c --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSJailbreakChecker.h @@ -0,0 +1,19 @@ +// +// STDSJailbreakChecker.h +// Stripe3DS2 +// +// Created by Andrew Harrison on 4/8/19. +// Copyright © 2019 Stripe. All rights reserved. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface STDSJailbreakChecker : NSObject + ++ (BOOL)isJailbroken; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSJailbreakChecker.m b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSJailbreakChecker.m new file mode 100644 index 0000000..6c0dcbf --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSJailbreakChecker.m @@ -0,0 +1,31 @@ +// +// STDSJailbreakChecker.m +// Stripe3DS2 +// +// Created by Andrew Harrison on 4/8/19. +// Copyright © 2019 Stripe. All rights reserved. +// + +#import "STDSJailbreakChecker.h" + +@import UIKit; + +NS_ASSUME_NONNULL_BEGIN + +@implementation STDSJailbreakChecker + +// This was implemented under the following guidance: https://medium.com/@pinmadhon/how-to-check-your-app-is-installed-on-a-jailbroken-device-67fa0170cf56 ++ (BOOL)isJailbroken { + + // Check for existence of files that are common for jailbroken devices + if ([[NSFileManager defaultManager] fileExistsAtPath:@"/Applications/Cydia.app"] || + [[NSFileManager defaultManager] fileExistsAtPath:@"/Library/MobileSubstrate/MobileSubstrate.dylib"]) { + return YES; + } + + return NO; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSLabelCustomization.m b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSLabelCustomization.m new file mode 100644 index 0000000..bb57c5f --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSLabelCustomization.m @@ -0,0 +1,43 @@ +// +// STDSLabelCustomization.m +// Stripe3DS2 +// +// Created by Andrew Harrison on 3/14/19. +// Copyright © 2019 Stripe. All rights reserved. +// + +#import "STDSLabelCustomization.h" + +#import "UIFont+DefaultFonts.h" +#import "UIColor+ThirteenSupport.h" + +NS_ASSUME_NONNULL_BEGIN + +@implementation STDSLabelCustomization + ++ (instancetype)defaultSettings { + return [self new]; +} + +- (instancetype)init { + self = [super init]; + if (self) { + self.textColor = UIColor._stds_labelColor; + _headingTextColor = UIColor._stds_labelColor; + self.font = [UIFont _stds_defaultLabelTextFontWithScale:(CGFloat)0.9]; + _headingFont = [UIFont _stds_defaultHeadingTextFont]; + } + return self; +} + +- (id)copyWithZone:(nullable NSZone *)zone { + STDSLabelCustomization *copy = [super copyWithZone:zone]; + copy.headingTextColor = self.headingTextColor; + copy.headingFont = self.headingFont; + + return copy; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSLocalizedString.h b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSLocalizedString.h new file mode 100644 index 0000000..7a3a76c --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSLocalizedString.h @@ -0,0 +1,18 @@ +// +// STDSLocalizedString.h +// Stripe3DS2 +// +// Created by Cameron Sabol on 7/9/19. +// Copyright © 2019 Stripe. All rights reserved. +// + +#import "STDSBundleLocator.h" + +#ifndef STDSLocalizedString_h +#define STDSLocalizedString_h + +#define STDSLocalizedString(key, comment) \ +[[STDSBundleLocator stdsResourcesBundle] localizedStringForKey:(key) value:@"" table:nil] + + +#endif /* STDSLocalizedString_h */ diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSNavigationBarCustomization.m b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSNavigationBarCustomization.m new file mode 100644 index 0000000..5e06235 --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSNavigationBarCustomization.m @@ -0,0 +1,44 @@ +// +// STDSNavigationBarCustomization.m +// Stripe3DS2 +// +// Created by Andrew Harrison on 3/14/19. +// Copyright © 2019 Stripe. All rights reserved. +// + +#import "STDSLocalizedString.h" +#import "STDSNavigationBarCustomization.h" + +NS_ASSUME_NONNULL_BEGIN + +@implementation STDSNavigationBarCustomization + ++ (instancetype)defaultSettings { + return [self new]; +} + +- (instancetype)init { + self = [super init]; + if (self) { + _barTintColor = nil; + _headerText = STDSLocalizedString(@"Secure checkout", @"The title for the challenge response step of an authenticated checkout."); + _buttonText = STDSLocalizedString(@"Cancel", "The text for the button that cancels the current challenge process."); + _translucent = YES; + } + return self; +} + +- (id)copyWithZone:(nullable NSZone *)zone { + STDSNavigationBarCustomization *copy = [super copyWithZone:zone]; + copy.barTintColor = self.barTintColor; + copy.headerText = self.headerText; + copy.buttonText = self.buttonText; + copy.barStyle = self.barStyle; + copy.translucent = self.translucent; + + return copy; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSNotInitializedException.m b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSNotInitializedException.m new file mode 100644 index 0000000..58544cc --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSNotInitializedException.m @@ -0,0 +1,17 @@ +// +// STDSNotInitializedException.m +// Stripe3DS2 +// +// Created by Cameron Sabol on 2/13/19. +// Copyright © 2019 Stripe. All rights reserved. +// + +#import "STDSNotInitializedException.h" + +NS_ASSUME_NONNULL_BEGIN + +@implementation STDSNotInitializedException + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSOSVersionChecker.h b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSOSVersionChecker.h new file mode 100644 index 0000000..72b79cf --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSOSVersionChecker.h @@ -0,0 +1,19 @@ +// +// STDSOSVersionChecker.h +// Stripe3DS2 +// +// Created by Andrew Harrison on 4/8/19. +// Copyright © 2019 Stripe. All rights reserved. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface STDSOSVersionChecker : NSObject + ++ (BOOL)isSupportedOSVersion; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSOSVersionChecker.m b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSOSVersionChecker.m new file mode 100644 index 0000000..f5f880e --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSOSVersionChecker.m @@ -0,0 +1,25 @@ +// +// STDSOSVersionChecker.m +// Stripe3DS2 +// +// Created by Andrew Harrison on 4/8/19. +// Copyright © 2019 Stripe. All rights reserved. +// + +#import "STDSOSVersionChecker.h" + +NS_ASSUME_NONNULL_BEGIN + +@implementation STDSOSVersionChecker + ++ (BOOL)isSupportedOSVersion { + if (@available(iOS 11, *)) { + return YES; + } else { + return NO; + } +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSProcessingView.h b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSProcessingView.h new file mode 100644 index 0000000..95364fc --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSProcessingView.h @@ -0,0 +1,26 @@ +// +// STDSProcessingView.h +// Stripe3DS2 +// +// Created by Andrew Harrison on 3/19/19. +// Copyright © 2019 Stripe. All rights reserved. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +@class STDSUICustomization; + +@interface STDSProcessingView : UIView + +/// Defaults to NO +@property (nonatomic) BOOL shouldDisplayBlurView; +/// Defaults to YES +@property (nonatomic) BOOL shouldDisplayDSLogo; + +- (instancetype)initWithCustomization:(STDSUICustomization *)customization directoryServerLogo:(nullable UIImage *)directoryServerLogo; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSProcessingView.m b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSProcessingView.m new file mode 100644 index 0000000..3126f97 --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSProcessingView.m @@ -0,0 +1,98 @@ +// +// STDSProcessingView.m +// Stripe3DS2 +// +// Created by Andrew Harrison on 3/19/19. +// Copyright © 2019 Stripe. All rights reserved. +// + +#import "STDSProcessingView.h" +#import "STDSStackView.h" +#import "UIView+LayoutSupport.h" +#import "UIFont+DefaultFonts.h" +#import "STDSUICustomization.h" +#import "STDSBundleLocator.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface STDSProcessingView() + +@property (nonatomic, strong) STDSStackView *imageStackView; +@property (nonatomic, strong) UIView *blurViewPlaceholder; +@property (nonatomic, strong) UIImageView *imageView; + +@end + +@implementation STDSProcessingView + +static const CGFloat kProcessingViewHorizontalMargin = 8; +static const CGFloat kProcessingViewTopPadding = 22; +static const CGFloat kProcessingViewBottomPadding = 36; + +- (instancetype)initWithCustomization:(STDSUICustomization *)customization directoryServerLogo:(nullable UIImage *)directoryServerLogo { + self = [super initWithFrame:CGRectZero]; + + if (self) { + _blurViewPlaceholder = [UIView new]; + _imageView = [[UIImageView alloc] initWithImage:directoryServerLogo]; + _imageView.contentMode = UIViewContentModeScaleAspectFit; + _shouldDisplayDSLogo = YES; + [self _setupViewHierarchyWithCustomization:customization]; + } + + return self; +} + +- (void)setShouldDisplayBlurView:(BOOL)shouldDisplayBlurView { + _shouldDisplayBlurView = shouldDisplayBlurView; + self.blurViewPlaceholder.hidden = shouldDisplayBlurView; +} + +- (void)setShouldDisplayDSLogo:(BOOL)shouldDisplayDSLogo { + _shouldDisplayDSLogo = shouldDisplayDSLogo; + self.imageView.hidden = !shouldDisplayDSLogo; +} + +- (void)_setupViewHierarchyWithCustomization:(STDSUICustomization *)customization { + self.blurViewPlaceholder.backgroundColor = customization.backgroundColor; + UIVisualEffectView *blurView = [[UIVisualEffectView alloc] initWithEffect:[UIBlurEffect effectWithStyle:customization.blurStyle]]; + blurView.translatesAutoresizingMaskIntoConstraints = NO; + + STDSStackView *containerView = [[STDSStackView alloc] initWithAlignment:STDSStackViewLayoutAxisVertical]; + containerView.backgroundColor = customization.backgroundColor; + containerView.layer.cornerRadius = 13; + containerView.translatesAutoresizingMaskIntoConstraints = NO; + + UIActivityIndicatorView *indicatorView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:customization.activityIndicatorViewStyle]; + + [self addSubview:blurView]; + [blurView.contentView addSubview:self.blurViewPlaceholder]; + [self addSubview:containerView]; + + [self.blurViewPlaceholder _stds_pinToSuperviewBoundsWithoutMargin]; + [blurView _stds_pinToSuperviewBoundsWithoutMargin]; + + NSLayoutConstraint *centerXConstraint = [NSLayoutConstraint constraintWithItem:containerView attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeCenterX multiplier:1.0 constant:0]; + NSLayoutConstraint *centerYConstraint = [NSLayoutConstraint constraintWithItem:containerView attribute:NSLayoutAttributeCenterY relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeCenterY multiplier:1.0 constant:0]; + NSLayoutConstraint *widthConstraint = [NSLayoutConstraint constraintWithItem:containerView attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeWidth multiplier:1.0 constant:-kProcessingViewHorizontalMargin * 2]; + + [NSLayoutConstraint activateConstraints:@[ + centerXConstraint, + centerYConstraint, + widthConstraint, + [containerView.topAnchor constraintGreaterThanOrEqualToAnchor:self.topAnchor], + [self.bottomAnchor constraintGreaterThanOrEqualToAnchor:containerView.bottomAnchor], + ]]; + + [containerView addSpacer:kProcessingViewTopPadding]; + [containerView addArrangedSubview:self.imageView]; + [containerView addSpacer:20]; + [containerView addArrangedSubview:indicatorView]; + [containerView addSpacer:kProcessingViewBottomPadding]; + + [indicatorView startAnimating]; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSProgressViewController.h b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSProgressViewController.h new file mode 100644 index 0000000..147fa4e --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSProgressViewController.h @@ -0,0 +1,23 @@ +// +// STDSProgressViewController.h +// Stripe3DS2 +// +// Created by Yuki Tokuhiro on 5/6/19. +// Copyright © 2019 Stripe. All rights reserved. +// + +#import + +#import "STDSDirectoryServer.h" + +@class STDSImageLoader, STDSUICustomization; + +NS_ASSUME_NONNULL_BEGIN + +@interface STDSProgressViewController : UIViewController + +- (instancetype)initWithDirectoryServer:(STDSDirectoryServer)directoryServer uiCustomization:(STDSUICustomization * _Nullable)uiCustomization didCancel:(void (^)(void))didCancel; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSProgressViewController.m b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSProgressViewController.m new file mode 100644 index 0000000..d53fe7f --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSProgressViewController.m @@ -0,0 +1,55 @@ +// +// STDSProgressViewController.m +// Stripe3DS2 +// +// Created by Yuki Tokuhiro on 5/6/19. +// Copyright © 2019 Stripe. All rights reserved. +// + +#import "STDSProgressViewController.h" + +#import "STDSBundleLocator.h" +#import "STDSUICustomization.h" +#import "UIViewController+Stripe3DS2.h" +#import "STDSProcessingView.h" + +@interface STDSProgressViewController() +@property (nonatomic, strong, nullable) STDSUICustomization *uiCustomization; +@property (nonatomic, strong) void (^didCancel)(void); +@property (nonatomic) STDSDirectoryServer directoryServer; +@end + +@implementation STDSProgressViewController + +- (instancetype)initWithDirectoryServer:(STDSDirectoryServer)directoryServer uiCustomization:(STDSUICustomization * _Nullable)uiCustomization didCancel:(void (^)(void))didCancel { + self = [super initWithNibName:nil bundle:nil]; + + if (self) { + _directoryServer = directoryServer; + _uiCustomization = uiCustomization; + _didCancel = didCancel; + } + + return self; +} + +- (void)loadView { + NSString *imageName = STDSDirectoryServerImageName(self.directoryServer); + UIImage *dsImage = imageName ? [UIImage imageNamed:imageName inBundle:[STDSBundleLocator stdsResourcesBundle] compatibleWithTraitCollection:nil] : nil; + self.view = [[STDSProcessingView alloc] initWithCustomization:self.uiCustomization directoryServerLogo:dsImage]; +} + +- (UIStatusBarStyle)preferredStatusBarStyle { + return self.uiCustomization.preferredStatusBarStyle; +} + +- (void)viewDidLoad { + [super viewDidLoad]; + [self _stds_setupNavigationBarElementsWithCustomization:self.uiCustomization cancelButtonSelector:@selector(_cancelButtonTapped:)]; +} + +- (void)_cancelButtonTapped:(UIButton *)sender { + self.didCancel(); +} + +@end diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSProtocolErrorEvent.m b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSProtocolErrorEvent.m new file mode 100644 index 0000000..0dbd75b --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSProtocolErrorEvent.m @@ -0,0 +1,28 @@ +// +// STDSProtocolErrorEvent.m +// Stripe3DS2 +// +// Created by Yuki Tokuhiro on 3/20/19. +// Copyright © 2019 Stripe. All rights reserved. +// + +#import "STDSProtocolErrorEvent.h" + +#import "STDSErrorMessage.h" + +NS_ASSUME_NONNULL_BEGIN + +@implementation STDSProtocolErrorEvent + +- (instancetype)initWithSDKTransactionIdentifier:(NSString *)identifier errorMessage:(STDSErrorMessage *)errorMessage { + self = [super init]; + if (self) { + _sdkTransactionIdentifier = identifier; + _errorMessage = errorMessage; + } + return self; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSRuntimeErrorEvent.m b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSRuntimeErrorEvent.m new file mode 100644 index 0000000..8155e06 --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSRuntimeErrorEvent.m @@ -0,0 +1,37 @@ +// +// STDSRuntimeErrorEvent.m +// Stripe3DS2 +// +// Created by Yuki Tokuhiro on 3/20/19. +// Copyright © 2019 Stripe. All rights reserved. +// + +#import "STDSRuntimeErrorEvent.h" + +#import "STDSStripe3DS2Error.h" + +NS_ASSUME_NONNULL_BEGIN + +NSString * const kSTDSRuntimeErrorCodeParsingError = @"STDSRuntimeErrorCodeParsingError"; +NSString * const kSTDSRuntimeErrorCodeEncryptionError = @"STDSRuntimeErrorCodeEncryptionError"; + +@implementation STDSRuntimeErrorEvent + +- (instancetype)initWithErrorCode:(NSString *)errorCode errorMessage:(NSString *)errorMessage { + self = [super init]; + if (self) { + _errorCode = [errorCode copy]; + _errorMessage = [errorMessage copy]; + } + return self; +} + +- (NSError *)NSErrorValue { + return [NSError errorWithDomain:STDSStripe3DS2ErrorDomain + code:[self.errorCode isEqualToString:kSTDSRuntimeErrorCodeParsingError] ? STDSErrorCodeRuntimeParsing : STDSErrorCodeRuntimeEncryption + userInfo:@{@"errorMessage": self.errorMessage}]; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSRuntimeException.m b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSRuntimeException.m new file mode 100644 index 0000000..3a70d37 --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSRuntimeException.m @@ -0,0 +1,17 @@ +// +// STDSRuntimeException.m +// Stripe3DS2 +// +// Created by Cameron Sabol on 1/22/19. +// Copyright © 2019 Stripe. All rights reserved. +// + +#import "STDSRuntimeException.h" + +NS_ASSUME_NONNULL_BEGIN + +@implementation STDSRuntimeException + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSSecTypeUtilities.h b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSSecTypeUtilities.h new file mode 100644 index 0000000..d0d416e --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSSecTypeUtilities.h @@ -0,0 +1,49 @@ +// +// STDSSecTypeUtilities.h +// Stripe3DS2 +// +// Created by Cameron Sabol on 1/28/19. +// Copyright © 2019 Stripe. All rights reserved. +// + +#import + +#import "STDSDirectoryServer.h" + +NS_ASSUME_NONNULL_BEGIN + +/// Returns the SecCertificateRef for the specified server or NULL if there's an error +SecCertificateRef _Nullable STDSCertificateForServer(STDSDirectoryServer server); + +/// Returns the public key in the certificate or NULL if there's an error +SecKeyRef _Nullable SecCertificateCopyKey(SecCertificateRef certificate); + +/// Returns one of the values defined for kSecAttrKeyType in or NULL +CFStringRef _Nullable STDSSecCertificateCopyPublicKeyType(SecCertificateRef certificate); + +/// Returns the hashed secret or nil +NSData * _Nullable STDSCreateConcatKDFWithSHA256(NSData *sharedSecret, NSUInteger keyLength, NSString *apv); + +/// Verifies the signature and payload using the Elliptic Curve P-256 with coordinateX and coordinateY +BOOL STDSVerifyEllipticCurveP256Signature(NSData *coordinateX, NSData *coordinateY, NSData *payload, NSData *signature); + +/// Verifies the signature and payload using RSA-PSS +BOOL STDSVerifyRSASignature(SecCertificateRef certificate, NSData *payload, NSData *signature); + +/// Returns data of length numBytes generated using CommonCrypto's CCRandomGenerateBytes or nil on failure +NSData * _Nullable STDSCryptoRandomData(size_t numBytes); + +/// Creates a certificate from base64encoded data +SecCertificateRef _Nullable STDSSecCertificateFromData(NSData *data); + +/// Creates a certificate from a PEM or DER encoded certificate string +SecCertificateRef _Nullable STDSSecCertificateFromString(NSString *certificateString); + +// Creates a public key using Elliptic Curve P-256 with coordinateX and coordinateY +SecKeyRef _Nullable STDSSecKeyRefFromCoordinates(NSData *coordinateX, NSData *coordinateY); + +// Creates a private key using Elliptic Curve P-256 with x, y, and d +SecKeyRef _Nullable STDSPrivateSecKeyRefFromCoordinates(NSData *x, NSData *y, NSData *d); + + +NS_ASSUME_NONNULL_END diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSSecTypeUtilities.m b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSSecTypeUtilities.m new file mode 100644 index 0000000..2a2331f --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSSecTypeUtilities.m @@ -0,0 +1,366 @@ +// +// STDSSecTypeUtilities.m +// Stripe3DS2 +// +// Created by Cameron Sabol on 1/28/19. +// Copyright © 2019 Stripe. All rights reserved. +// + +#import "STDSSecTypeUtilities.h" + +#import +#import +#import + +#import "STDSBundleLocator.h" +#import "STDSEllipticCurvePoint.h" + +NS_ASSUME_NONNULL_BEGIN + +SecCertificateRef _Nullable STDSCertificateForServer(STDSDirectoryServer server) { + static NSMutableDictionary *sCertificateData = nil; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + sCertificateData = [[NSMutableDictionary alloc] init]; + }); + + NSString *serverKey = nil; + switch (server) { + case STDSDirectoryServerULTestRSA: + serverKey = @"STDSDirectoryServerULTestRSA"; + break; + + case STDSDirectoryServerULTestEC: + serverKey = @"STDSDirectoryServerULTestEC"; + break; + + case STDSDirectoryServerSTPTestRSA: + serverKey = @"STDSDirectoryServerSTPTestRSA"; + break; + + case STDSDirectoryServerSTPTestEC: + serverKey = @"STDSDirectoryServerSTPTestEC"; + break; + + case STDSDirectoryServerAmex: + serverKey = @"STDSDirectoryServerAmex"; + break; + + case STDSDirectoryServerDiscover: + serverKey = @"STDSDirectoryServerDiscover"; + break; + + case STDSDirectoryServerMastercard: + serverKey = @"STDSDirectoryServerMastercard"; + break; + + case STDSDirectoryServerVisa: + serverKey = @"STDSDirectoryServerVisa"; + break; + + case STDSDirectoryServerCartesBancaires: + serverKey = @"STDSDirectoryServerCartesBancaires"; + break; + + case STDSDirectoryServerCustom: + break; + + case STDSDirectoryServerUnknown: + break; + } + + if (serverKey == nil) { + return NULL; + } + + NSData *certificateData = sCertificateData[serverKey]; + if (certificateData == nil) { + NSString *certificatePath = nil; + switch (server) { + case STDSDirectoryServerULTestRSA: + break; + + case STDSDirectoryServerULTestEC: + break; + + case STDSDirectoryServerSTPTestRSA: + certificatePath = [[STDSBundleLocator stdsResourcesBundle] pathForResource:@"ul-test" ofType:@"der"]; + break; + + case STDSDirectoryServerSTPTestEC: + certificatePath = [[STDSBundleLocator stdsResourcesBundle] pathForResource:@"ec_test" ofType:@"der"]; + break; + + case STDSDirectoryServerAmex: + certificatePath = [[STDSBundleLocator stdsResourcesBundle] pathForResource:@"amex" ofType:@"der"]; + break; + + case STDSDirectoryServerDiscover: + certificatePath = [[STDSBundleLocator stdsResourcesBundle] pathForResource:@"discover" ofType:@"der"]; + break; + + case STDSDirectoryServerMastercard: + certificatePath = [[STDSBundleLocator stdsResourcesBundle] pathForResource:@"mastercard" ofType:@"der"]; + break; + + case STDSDirectoryServerVisa: + certificatePath = [[STDSBundleLocator stdsResourcesBundle] pathForResource:@"visa" ofType:@"der"]; + break; + + case STDSDirectoryServerCartesBancaires: + certificatePath = [[STDSBundleLocator stdsResourcesBundle] pathForResource:@"cartes_bancaires" ofType:@"der"]; + break; + + case STDSDirectoryServerCustom: + break; + + case STDSDirectoryServerUnknown: + break; + } + + if (certificatePath != nil) { + certificateData = [NSData dataWithContentsOfFile:certificatePath]; + // cache the file data to limit file IO + sCertificateData[serverKey] = certificateData; + } + } + + // Note to Future: SecCertificateCreateWithData only works with DER formatted data. The other popular + // format for certificate files is PEM. These can be converted before adding to the SDK by invoking + // `openssl x509 -in certificate_PEM.crt -outform der -out certificate_DER.der` + return certificateData != nil ? SecCertificateCreateWithData(NULL, (CFDataRef)certificateData): NULL; +}; + +CFStringRef _Nullable STDSSecCertificateCopyPublicKeyType(SecCertificateRef certificate) { + CFStringRef ret = NULL; + + SecKeyRef key = SecCertificateCopyKey(certificate); + + if (key != NULL) { + CFDictionaryRef attributes = SecKeyCopyAttributes(key); + if (attributes == NULL) { + CFRelease(key); + return NULL; + } + + if (attributes != NULL) { + const void *keyType = CFDictionaryGetValue(attributes, kSecAttrKeyType); + if (keyType != NULL && CFGetTypeID(keyType) == CFStringGetTypeID()) { + ret = CFStringCreateCopy(kCFAllocatorDefault, (CFStringRef)keyType); + } + CFRelease(attributes); + } + CFRelease(key); + } + + return ret; +} + +SecCertificateRef _Nullable STDSSecCertificateFromString(NSString *certificateString) { + static NSString * const kCertificateAnchorPrefix = @"-----BEGIN CERTIFICATE-----"; + static NSString * const kCertificateAnchorSuffix = @"-----END CERTIFICATE-----"; + + // first remove newlines + NSString *certificateStringNoAnchors = [[[certificateString stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]] componentsSeparatedByCharactersInSet:[NSCharacterSet newlineCharacterSet]] componentsJoinedByString:@""]; + + // remove the begin/end certificate markers + NSUInteger fromIndex = [certificateStringNoAnchors hasPrefix:kCertificateAnchorPrefix] ? kCertificateAnchorPrefix.length : 0; + NSUInteger toIndex = [certificateStringNoAnchors hasSuffix:kCertificateAnchorSuffix] ? certificateStringNoAnchors.length - kCertificateAnchorSuffix.length : certificateStringNoAnchors.length; + certificateStringNoAnchors = [[certificateStringNoAnchors substringWithRange:NSMakeRange(fromIndex, toIndex - fromIndex)] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]; + + if (certificateStringNoAnchors.length == 0) { + return NULL; + } + NSData *certificateData = [[NSData alloc] initWithBase64EncodedString:certificateStringNoAnchors options:0]; + if (certificateData == nil) { + return NULL; + } + + return STDSSecCertificateFromData(certificateData); +} + +SecCertificateRef _Nullable STDSSecCertificateFromData(NSData *data) { + SecCertificateRef certificate = SecCertificateCreateWithData(NULL, (__bridge CFDataRef)data); + return certificate; +} + +SecKeyRef _Nullable STDSPrivateSecKeyRefFromCoordinates(NSData *x, NSData *y, NSData *d) { + static unsigned char prefixBytes[] = {0x04}; + NSMutableData *bytes = [[NSMutableData alloc] initWithBytes:(void *)prefixBytes length:1]; + [bytes appendData:x]; + [bytes appendData:y]; + [bytes appendData:d]; + NSDictionary *attributes = @{ + (__bridge NSString *)kSecAttrKeyType: (__bridge NSString *)kSecAttrKeyTypeECSECPrimeRandom, + (__bridge NSString *)kSecAttrKeyClass: (__bridge NSString *)kSecAttrKeyClassPrivate, + (__bridge NSString *)kSecAttrKeySizeInBits: @(256), + }; + CFErrorRef error = NULL; + SecKeyRef key = SecKeyCreateWithData((__bridge CFDataRef)bytes, (__bridge CFDictionaryRef)attributes, &error); + return key; +} + +SecKeyRef _Nullable STDSSecKeyRefFromCoordinates(NSData *coordinateX, NSData *coordinateY) { + static unsigned char prefixBytes[] = {0x04}; + NSMutableData *bytes = [[NSMutableData alloc] initWithBytes:(void *)prefixBytes length:1]; + [bytes appendData:coordinateX]; + [bytes appendData:coordinateY]; + NSDictionary *attributes = @{ + (__bridge NSString *)kSecAttrKeyType: (__bridge NSString *)kSecAttrKeyTypeECSECPrimeRandom, + (__bridge NSString *)kSecAttrKeyClass: (__bridge NSString *)kSecAttrKeyClassPublic, + (__bridge NSString *)kSecAttrKeySizeInBits: @(256), + }; + CFErrorRef error = NULL; + SecKeyRef key = SecKeyCreateWithData((__bridge CFDataRef)bytes, (__bridge CFDictionaryRef)attributes, &error); + return key; +} + +// ref. https://crypto.stackexchange.com/questions/1795/how-can-i-convert-a-der-ecdsa-signature-to-asn-1/1797#1797 +NSData * _Nullable STDSDEREncodedSignature(NSData * signature) { + // make sure input signature is of correct R || S format + NSUInteger signatureLength = signature.length; + if (signatureLength == 0 || signatureLength % 2 != 0) { + return nil; + } + + static const uint8_t bytePrefix = 0x00; + + NSMutableData *rBytes = [[NSMutableData alloc] init]; + uint8_t firstRByte; + [signature getBytes:&firstRByte length:1]; + + if (firstRByte >= 0x80) { + // "Signed big-endian encoding of minimal length", we can't have the first bit be 1 because these are postive values + [rBytes appendBytes:&bytePrefix length:1]; + } + [rBytes appendBytes:signature.bytes length:signatureLength / 2]; + + NSMutableData *sBytes = [[NSMutableData alloc] init]; + uint8_t firstSByte; + [signature getBytes:&firstSByte range:NSMakeRange(signatureLength / 2, 1)]; + + if (firstSByte >= 0x80) { + // "Signed big-endian encoding of minimal length", we can't have the first bit be 1 because these are postive values + [sBytes appendBytes:&bytePrefix length:1]; + } + [sBytes appendBytes:(signature.bytes + (signatureLength / 2)) length:signatureLength / 2]; + + uint8_t rLength = (uint8_t)rBytes.length; + uint8_t sLength = (uint8_t)sBytes.length; + + static const uint8_t derBytePrefix = 0x30; + NSMutableData *derEncoded = [[NSMutableData alloc] initWithBytes:&derBytePrefix length:1]; + + static const uint8_t derSeparatorByte = 0x02; + // numBytes does not include the 0x30 byte + uint8_t numBytes = rLength + sLength + 2 + 2; // + 2 for separators, + 2 for r and s size bytes + [derEncoded appendBytes:&numBytes length:1]; + [derEncoded appendBytes:&derSeparatorByte length:1]; + + [derEncoded appendBytes:&rLength length:1]; + [derEncoded appendBytes:rBytes.bytes length:rBytes.length]; + + [derEncoded appendBytes:&derSeparatorByte length:1]; + + [derEncoded appendBytes:&sLength length:1]; + [derEncoded appendBytes:sBytes.bytes length:sBytes.length]; + + return [derEncoded copy]; +} + +BOOL STDSVerifyEllipticCurveP256Signature(NSData *coordinateX, NSData *coordinateY, NSData *payload, NSData *signature) { + BOOL ret = NO; + + // make P-256 curve key from coordinates + SecKeyRef key = STDSSecKeyRefFromCoordinates(coordinateX, coordinateY); + + if (key != NULL) { + size_t hashBytesSize = CC_SHA256_DIGEST_LENGTH; + unsigned char hashBytes[hashBytesSize]; + CC_SHA256(payload.bytes, (CC_LONG)payload.length, hashBytes); + CFErrorRef error = NULL; + NSData *derEncodedSignature = STDSDEREncodedSignature(signature); + if (derEncodedSignature == nil) { + CFRelease(key); + return NO; + } + ret = (BOOL)SecKeyVerifySignature(key, kSecKeyAlgorithmECDSASignatureDigestX962SHA256, (__bridge CFDataRef)[NSData dataWithBytes:hashBytes length:hashBytesSize], (__bridge CFDataRef)derEncodedSignature, &error); + CFRelease(key); + } + return ret; +} + +BOOL STDSVerifyRSASignature(SecCertificateRef certificate, NSData *payload, NSData *signature) { + BOOL ret = NO; + + SecKeyRef key = SecCertificateCopyKey(certificate); + if (key != NULL && signature) { + CFErrorRef error = NULL; + size_t hashBytesSize = CC_SHA256_DIGEST_LENGTH; + unsigned char hashBytes[hashBytesSize]; + CC_SHA256(payload.bytes, (CC_LONG)payload.length, hashBytes); + + ret = (BOOL)SecKeyVerifySignature(key, kSecKeyAlgorithmRSASignatureDigestPSSSHA256, (__bridge CFDataRef)[NSData dataWithBytes:hashBytes length:hashBytesSize], (__bridge CFDataRef)signature, &error); + CFRelease(key); + } + return ret; +} + +NSData * _Nullable STDSCryptoRandomData(size_t numBytes) { + void *randomBytes[numBytes]; + memset(randomBytes, 0, numBytes); + if (CCRandomGenerateBytes(randomBytes, numBytes) == kCCSuccess) { + NSData *data = [NSData dataWithBytes:randomBytes length:numBytes]; + return data; + } + return NULL; +} + +NSData * _Nullable _STPCreateKDFFormattedData(NSData *data) { + uint32_t bigEndianLength = CFSwapInt32HostToBig((uint32_t)data.length); + NSMutableData *encodedLength = [NSMutableData dataWithBytes:&bigEndianLength length:4]; + [encodedLength appendData:data]; + return [encodedLength copy]; +} + +NSData * _Nullable STDSCreateConcatKDFWithSHA256(NSData *sharedSecret, NSUInteger keyLength, NSString *apv) { + NSData *concatKDFData = nil; + + uint32_t bigEndianKeyLength = CFSwapInt32HostToBig((uint32_t)keyLength*8); + + // algorithmID and partyUInfo are intentionally empty strings based on the Core Spec + // section 6.2.3.3 which states that they should be null. The KDF standard, NIST.800-56A, + // requires that null values still have the length bytes set to 0. + NSData *algorithmID = _STPCreateKDFFormattedData([@"" dataUsingEncoding:NSASCIIStringEncoding]); + NSData *partyUInfo = _STPCreateKDFFormattedData([@"" dataUsingEncoding:NSUTF8StringEncoding]); + NSData *partyVInfo = _STPCreateKDFFormattedData([apv dataUsingEncoding:NSUTF8StringEncoding]); + NSData *suppPubInfo = [NSData dataWithBytes:&bigEndianKeyLength length:4]; + + if (algorithmID == nil || + partyUInfo == nil || + partyVInfo == nil || + suppPubInfo == nil + ) { + return nil; + } + + NSMutableData *otherInfo = [algorithmID mutableCopy]; + [otherInfo appendData:partyUInfo]; + [otherInfo appendData:partyVInfo]; + [otherInfo appendData:suppPubInfo]; + + const unsigned char roundOneBytes[4] = {0, 0, 0, 1}; + NSMutableData *roundOneHashInput = [[NSMutableData alloc] initWithBytes:roundOneBytes length:4]; + [roundOneHashInput appendData:sharedSecret]; + [roundOneHashInput appendData:otherInfo]; + + NSMutableData *roundOneHashOutput = [NSMutableData dataWithLength:CC_SHA256_DIGEST_LENGTH]; + + if (CC_SHA256(roundOneHashInput.bytes, (CC_LONG)roundOneHashInput.length, roundOneHashOutput.mutableBytes) != nil) { + concatKDFData = [NSData dataWithBytes:roundOneHashOutput.bytes length:MAX(keyLength, roundOneHashOutput.length)]; + } + + return concatKDFData; +} + +NS_ASSUME_NONNULL_END diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSSelectionButton.h b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSSelectionButton.h new file mode 100644 index 0000000..5cb78b7 --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSSelectionButton.h @@ -0,0 +1,26 @@ +// +// STDSSelectionButton.h +// Stripe3DS2 +// +// Created by Yuki Tokuhiro on 6/11/19. +// Copyright © 2019 Stripe. All rights reserved. +// + +#import + +@class STDSSelectionCustomization; + +NS_ASSUME_NONNULL_BEGIN + +@interface STDSSelectionButton : UIButton + +@property (nonatomic) STDSSelectionCustomization *customization; + +/// This control can either be styled as a radio button or a checkbox +@property (nonatomic) BOOL isCheckbox; + +- (instancetype)initWithCustomization:(STDSSelectionCustomization *)customization; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSSelectionButton.m b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSSelectionButton.m new file mode 100644 index 0000000..97bf19e --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSSelectionButton.m @@ -0,0 +1,167 @@ +// +// STDSSelectionButton.h +// Stripe3DS2 +// +// Created by Yuki Tokuhiro on 6/11/19. +// Copyright © 2019 Stripe. All rights reserved. +// + +#import "STDSSelectionButton.h" + +#import "STDSSelectionCustomization.h" + +@interface _STDSSelectionButtonView: UIView +@property (nonatomic) BOOL isCheckbox; +@property (nonatomic) STDSSelectionCustomization *customization; +@property (nonatomic, getter = isSelected) BOOL selected; +@end + +@implementation _STDSSelectionButtonView + +- (instancetype)initWithFrame:(CGRect)frame { + self = [super initWithFrame:frame]; + if (self) { + self.opaque = NO; + } + + return self; +} + +- (void)setSelected:(BOOL)selected { + _selected = selected; + [self setNeedsDisplay]; +} + + +- (void)setCustomization:(STDSSelectionCustomization *)customization { + _customization = customization; + [self setNeedsDisplay]; +} + + +- (void)drawRect:(CGRect)rect { + if (self.isCheckbox) { + [self _drawCheckboxWithRect:rect]; + } else { + [self _drawRadioButtonWithRect:rect]; + } +} + +- (void)_drawRadioButtonWithRect:(CGRect)rect { + // Draw background + UIBezierPath *background = [UIBezierPath bezierPathWithOvalInRect:rect]; + if (self.isSelected) { + [self.customization.primarySelectedColor setFill]; + } else { + [self.customization.unselectedBackgroundColor setFill]; + } + [background fill]; + + // Draw unselected border + if (!self.isSelected) { + UIBezierPath *border = [UIBezierPath bezierPathWithOvalInRect:CGRectInset(rect, 0.5, 0.5)]; + [self.customization.unselectedBorderColor setStroke]; + [border stroke]; + } + + // Draw inner circle if selected + if (self.isSelected) { + CGRect selectedRect = CGRectInset(rect, 9, 9); + UIBezierPath *selected = [UIBezierPath bezierPathWithOvalInRect:selectedRect]; + [self.customization.secondarySelectedColor setFill]; + [selected fill]; + } +} + +- (void)_drawCheckboxWithRect:(CGRect)rect { + // Draw background + UIBezierPath *background = [UIBezierPath bezierPathWithRoundedRect:rect cornerRadius:8]; + if (self.isSelected) { + [self.customization.primarySelectedColor setFill]; + } else { + [self.customization.unselectedBackgroundColor setFill]; + } + [background fill]; + + // Draw unselected border + if (!self.isSelected) { + UIBezierPath *border = [UIBezierPath bezierPathWithRoundedRect:CGRectInset(rect, 0.5, 0.5) cornerRadius:8]; + border.lineWidth = 0.5; + [self.customization.unselectedBorderColor setStroke]; + [border stroke]; + } + + // Draw check mark if selected + if (self.isSelected) { + UIBezierPath *checkmark = [UIBezierPath bezierPath]; + [checkmark moveToPoint: CGPointMake(10, 15)]; + [checkmark addLineToPoint:CGPointMake(13.5, 18.5)]; + [checkmark addLineToPoint:CGPointMake(22, 10)]; + [self.customization.secondarySelectedColor setStroke]; + checkmark.lineWidth = 2; + [checkmark stroke]; + } +} + +@end + +static const CGFloat kMinimumTouchAreaDimension = 42.f; +static const CGFloat kContentSizeDimension = 30.f; + +@implementation STDSSelectionButton { + _STDSSelectionButtonView *_contentView; +} + +- (instancetype)initWithCustomization:(STDSSelectionCustomization *)customization { + self = [super init]; + if (self) { + _contentView = [[_STDSSelectionButtonView alloc] initWithFrame:CGRectMake(0, 0, kContentSizeDimension, kContentSizeDimension)]; + _contentView.userInteractionEnabled = NO; + [self addSubview:_contentView]; + self.customization = customization; + } + return self; +} + +- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event { + BOOL pointInside = [super pointInside:point withEvent:event]; + if (!pointInside && + self.enabled && + !self.isHidden && + (CGRectGetWidth(self.bounds) < kMinimumTouchAreaDimension || CGRectGetHeight(self.bounds) < kMinimumTouchAreaDimension) + ) { + // Make sure that we intercept touch events even outside our bounds if they are within the + // minimum touch area. Otherwise this button is too hard to tap + CGRect expandedBounds = CGRectInset(self.bounds, MIN(CGRectGetWidth(self.bounds) - kMinimumTouchAreaDimension, 0), MIN(CGRectGetHeight(self.bounds) < kMinimumTouchAreaDimension, 0)); + pointInside = CGRectContainsPoint(expandedBounds, point); + } + + return pointInside; +} + +- (CGSize)intrinsicContentSize { + return CGSizeMake(kContentSizeDimension, kContentSizeDimension); +} + +- (void)setSelected:(BOOL)selected { + [super setSelected:selected]; + _contentView.selected = selected; +} + +- (void)setCustomization:(STDSSelectionCustomization *)customization { + _contentView.customization = customization; +} + +- (STDSSelectionCustomization *)customization { + return _contentView.customization; +} + +- (void)setIsCheckbox:(BOOL)isCheckbox { + _contentView.isCheckbox = isCheckbox; +} + +- (BOOL)isCheckbox { + return _contentView.isCheckbox; +} + +@end diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSSelectionCustomization.m b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSSelectionCustomization.m new file mode 100644 index 0000000..c5301ef --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSSelectionCustomization.m @@ -0,0 +1,77 @@ +// +// STDSSelectionCustomization.m +// Stripe3DS2 +// +// Created by Yuki Tokuhiro on 6/11/19. +// Copyright © 2019 Stripe. All rights reserved. +// + +#import "STDSSelectionCustomization.h" + +#import "UIColor+DefaultColors.h" +#import "UIColor+ThirteenSupport.h" + +NS_ASSUME_NONNULL_BEGIN + +@implementation STDSSelectionCustomization + ++ (instancetype)defaultSettings { + return [self new]; +} + +- (instancetype)init { + self = [super init]; + if (self) { + if (@available(iOS 12.0, *)) { + _primarySelectedColor = [UIColor _stds_blueColor]; + _secondarySelectedColor = UIColor.whiteColor; + _unselectedBackgroundColor = [UIColor _stds_colorWithDynamicProvider:^UIColor * _Nonnull(UITraitCollection * _Nonnull traitCollection) { + return (traitCollection.userInterfaceStyle == UIUserInterfaceStyleLight) ? + [UIColor colorWithRed:(CGFloat)231.0 / (CGFloat)255.0 + green:(CGFloat)241.0 / (CGFloat)255.0 + blue:(CGFloat)254.0 / (CGFloat)255.0 + alpha:1.0] : + [UIColor colorWithRed:(CGFloat)30.0 / (CGFloat)255.0 + green:(CGFloat)63.0 / (CGFloat)255.0 + blue:(CGFloat)84.0 / (CGFloat)255.0 + alpha:1.0]; + }]; + _unselectedBorderColor = [UIColor _stds_colorWithDynamicProvider:^UIColor * _Nonnull(UITraitCollection * _Nonnull traitCollection) { + return (traitCollection.userInterfaceStyle == UIUserInterfaceStyleLight) ? + [UIColor colorWithRed:(CGFloat)131.0 / (CGFloat)255.0 + green:(CGFloat)191.0 / (CGFloat)255.0 + blue:(CGFloat)250.0 / (CGFloat)255.0 + alpha:1] : + [UIColor colorWithRed:(CGFloat)65.0 / (CGFloat)255.0 + green:(CGFloat)94.0 / (CGFloat)255.0 + blue:(CGFloat)123.0 / (CGFloat)255.0 + alpha:1]; + }]; + } else { + _primarySelectedColor = [UIColor _stds_blueColor]; + _secondarySelectedColor = UIColor.whiteColor; + _unselectedBackgroundColor = [UIColor colorWithRed:(CGFloat)231.0 / (CGFloat)255.0 + green:(CGFloat)241.0 / (CGFloat)255.0 + blue:(CGFloat)254.0 / (CGFloat)255.0 + alpha:1.0]; + _unselectedBorderColor = [UIColor colorWithRed:(CGFloat)131.0 / (CGFloat)255.0 + green:(CGFloat)191.0 / (CGFloat)255.0 + blue:(CGFloat)250.0 / (CGFloat)255.0 + alpha:1]; + } + } + return self; +} + +- (nonnull id)copyWithZone:(nullable NSZone *)zone { + STDSSelectionCustomization *copy = [STDSSelectionCustomization new]; + copy.primarySelectedColor = self.primarySelectedColor; + copy.secondarySelectedColor = self.secondarySelectedColor; + copy.unselectedBackgroundColor = self.unselectedBackgroundColor; + copy.unselectedBorderColor = self.unselectedBorderColor; + return copy; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSSimulatorChecker.h b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSSimulatorChecker.h new file mode 100644 index 0000000..7b6e77d --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSSimulatorChecker.h @@ -0,0 +1,19 @@ +// +// STDSSimulatorChecker.h +// Stripe3DS2 +// +// Created by Andrew Harrison on 4/8/19. +// Copyright © 2019 Stripe. All rights reserved. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface STDSSimulatorChecker : NSObject + ++ (BOOL)isRunningOnSimulator; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSSimulatorChecker.m b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSSimulatorChecker.m new file mode 100644 index 0000000..47ea89e --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSSimulatorChecker.m @@ -0,0 +1,25 @@ +// +// STDSSimulatorChecker.m +// Stripe3DS2 +// +// Created by Andrew Harrison on 4/8/19. +// Copyright © 2019 Stripe. All rights reserved. +// + +#import "STDSSimulatorChecker.h" + +NS_ASSUME_NONNULL_BEGIN + +@implementation STDSSimulatorChecker + ++ (BOOL)isRunningOnSimulator { +#if TARGET_IPHONE_SIMULATOR + return YES; +#else + return NO; +#endif +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSSpacerView.h b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSSpacerView.h new file mode 100644 index 0000000..072ad1e --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSSpacerView.h @@ -0,0 +1,20 @@ +// +// STDSSpacerView.h +// Stripe3DS2 +// +// Created by Andrew Harrison on 3/4/19. +// Copyright © 2019 Stripe. All rights reserved. +// + +#import +#import "STDSStackView.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface STDSSpacerView : UIView + +- (instancetype)initWithLayoutAxis:(STDSStackViewLayoutAxis)layoutAxis dimension:(CGFloat)dimension; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSSpacerView.m b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSSpacerView.m new file mode 100644 index 0000000..a674e68 --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSSpacerView.m @@ -0,0 +1,34 @@ +// +// STDSSpacerView.m +// Stripe3DS2 +// +// Created by Andrew Harrison on 3/4/19. +// Copyright © 2019 Stripe. All rights reserved. +// + +#import "STDSSpacerView.h" + +@implementation STDSSpacerView + +- (instancetype)initWithLayoutAxis:(STDSStackViewLayoutAxis)layoutAxis dimension:(CGFloat)dimension { + self = [super initWithFrame:CGRectZero]; + + if (self) { + NSLayoutConstraint *constraint; + + switch (layoutAxis) { + case STDSStackViewLayoutAxisHorizontal: + constraint = [NSLayoutConstraint constraintWithItem:self attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.0 constant:dimension]; + break; + case STDSStackViewLayoutAxisVertical: + constraint = [NSLayoutConstraint constraintWithItem:self attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.0 constant:dimension]; + break; + } + + [NSLayoutConstraint activateConstraints:@[constraint]]; + } + + return self; +} + +@end diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSStackView.h b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSStackView.h new file mode 100644 index 0000000..cfedb01 --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSStackView.h @@ -0,0 +1,56 @@ +// +// STDSStackView.h +// Stripe3DS2 +// +// Created by Andrew Harrison on 2/27/19. +// Copyright © 2019 Stripe. All rights reserved. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +typedef NS_ENUM(NSInteger, STDSStackViewLayoutAxis) { + + /// A horizontal layout for the stack view to use. + STDSStackViewLayoutAxisHorizontal = 0, + + /// A vertical layout for the stack view to use. + STDSStackViewLayoutAxisVertical = 1, +}; + +@interface STDSStackView: UIView + +/** + Initializes an `STDSStackView`. + + @param alignment The alignment for the stack view to use. + @return An initialized `STDSStackView`. + */ +- (instancetype)initWithAlignment:(STDSStackViewLayoutAxis)alignment; + +/** + Adds a subview to the list of arranged subviews. Views will be displayed in the order they are added. + + @param view The view to add to the stack view. + */ +- (void)addArrangedSubview:(UIView *)view; + +/** + Removes a subview from the list of arranged subviews. + + @param view The view to remove. + */ +- (void)removeArrangedSubview:(UIView *)view; + +/** + Adds a spacer that fits the layout axis of the `STDSStackView`. + + @param dimension How wide or tall the spacer should be, depending on the axis of the `STDSStackView`. + @note Spacers added through this function will not be removed or hidden automatically when they no longer fall between two views. For more precise interactions, add an `STDSSpacerView` manually through `addArrangedSubview:`. + */ +- (void)addSpacer:(CGFloat)dimension; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSStackView.m b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSStackView.m new file mode 100644 index 0000000..7ec01d1 --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSStackView.m @@ -0,0 +1,164 @@ +// +// STDSStackView.m +// Stripe3DS2 +// +// Created by Andrew Harrison on 2/27/19. +// Copyright © 2019 Stripe. All rights reserved. +// + +#import "STDSStackView.h" +#import "STDSSpacerView.h" +#import "NSLayoutConstraint+LayoutSupport.h" + +@interface STDSStackView() + +@property (nonatomic) STDSStackViewLayoutAxis layoutAxis; +@property (nonatomic, strong) NSMutableArray *arrangedSubviews; +@property (nonatomic, strong, readonly) NSArray *visibleArrangedSubviews; + +@end + +@implementation STDSStackView + +static NSString *UIViewHiddenKeyPath = @"hidden"; + +- (instancetype)initWithAlignment:(STDSStackViewLayoutAxis)layoutAxis { + self = [super initWithFrame:CGRectZero]; + + if (self) { + _layoutAxis = layoutAxis; + _arrangedSubviews = [NSMutableArray array]; + } + + return self; +} + +- (NSArray *)visibleArrangedSubviews { + return [self.arrangedSubviews filteredArrayUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(UIView *object, NSDictionary *bindings) { + return !object.isHidden; + }]]; +} + +- (void)addArrangedSubview:(UIView *)view { + view.translatesAutoresizingMaskIntoConstraints = false; + + [self _deactivateExistingConstraints]; + + [self.arrangedSubviews addObject:view]; + [self addSubview:view]; + + [self _applyConstraints]; + + [view addObserver:self forKeyPath:UIViewHiddenKeyPath options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld context:NULL]; +} + +- (void)removeArrangedSubview:(UIView *)view { + if (![self.arrangedSubviews containsObject:view]) { + return; + } + + [self _deactivateExistingConstraints]; + + [view removeObserver:self forKeyPath:UIViewHiddenKeyPath]; + + [self.arrangedSubviews removeObject:view]; + [view removeFromSuperview]; + + [self _applyConstraints]; +} + +- (void)addSpacer:(CGFloat)dimension { + STDSSpacerView *spacerView = [[STDSSpacerView alloc] initWithLayoutAxis:self.layoutAxis dimension:dimension]; + + [self addArrangedSubview:spacerView]; +} + +- (void)dealloc { + for (UIView *view in self.arrangedSubviews) { + [view removeObserver:self forKeyPath:UIViewHiddenKeyPath]; + } +} + +- (void)_applyConstraints { + if (self.layoutAxis == STDSStackViewLayoutAxisHorizontal) { + [self _applyHorizontalConstraints]; + } else { + [self _applyVerticalConstraints]; + } +} + +- (void)_deactivateExistingConstraints { + [NSLayoutConstraint deactivateConstraints:self.constraints]; +} + +- (void)_applyVerticalConstraints { + UIView *previousView; + + for (UIView *view in self.visibleArrangedSubviews) { + NSLayoutConstraint *leftConstraint = [NSLayoutConstraint _stds_leftConstraintWithItem:view toItem:self]; + NSLayoutConstraint *rightConstraint = [NSLayoutConstraint _stds_rightConstraintWithItem:view toItem:self]; + NSLayoutConstraint *topConstraint; + + if (previousView == nil) { + topConstraint = [NSLayoutConstraint _stds_topConstraintWithItem:view toItem:self]; + } else { + topConstraint = [NSLayoutConstraint constraintWithItem:view attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:previousView attribute:NSLayoutAttributeBottom multiplier:1 constant:0]; + } + + [NSLayoutConstraint activateConstraints:@[topConstraint, leftConstraint, rightConstraint]]; + + if (view == self.visibleArrangedSubviews.lastObject) { + NSLayoutConstraint *bottomConstraint = [NSLayoutConstraint _stds_bottomConstraintWithItem:view toItem:self]; + + [NSLayoutConstraint activateConstraints:@[bottomConstraint]]; + } + + previousView = view; + } +} + +- (void)_applyHorizontalConstraints { + UIView *previousView; + NSLayoutConstraint *previousRightConstraint; + + for (UIView *view in self.visibleArrangedSubviews) { + NSLayoutConstraint *topConstraint = [NSLayoutConstraint _stds_topConstraintWithItem:view toItem:self]; + NSLayoutConstraint *bottomConstraint = [NSLayoutConstraint _stds_bottomConstraintWithItem:view toItem:self]; + NSLayoutConstraint *rightConstraint = [NSLayoutConstraint _stds_rightConstraintWithItem:view toItem:self]; + + if (previousView == nil) { + NSLayoutConstraint *leftConstraint = [NSLayoutConstraint _stds_leftConstraintWithItem:view toItem:self]; + + [NSLayoutConstraint activateConstraints:@[topConstraint, leftConstraint, rightConstraint, bottomConstraint]]; + } else { + NSLayoutConstraint *leftConstraint = [NSLayoutConstraint constraintWithItem:view attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:previousView attribute:NSLayoutAttributeRight multiplier:1 constant:0]; + + if (previousRightConstraint != nil) { + [NSLayoutConstraint deactivateConstraints:@[previousRightConstraint]]; + } + + NSLayoutConstraint *previousConstraint = [NSLayoutConstraint constraintWithItem:previousView attribute:NSLayoutAttributeRight relatedBy:NSLayoutRelationEqual toItem:view attribute:NSLayoutAttributeLeft multiplier:1 constant:0]; + + [NSLayoutConstraint activateConstraints:@[topConstraint, leftConstraint, rightConstraint, previousConstraint, bottomConstraint]]; + } + + previousView = view; + previousRightConstraint = rightConstraint; + } +} + +- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context { + if ([object isKindOfClass:[UIView class]] && [keyPath isEqualToString:UIViewHiddenKeyPath]) { + BOOL hiddenStatusChanged = [change[NSKeyValueChangeNewKey] boolValue] != [change[NSKeyValueChangeOldKey] boolValue]; + + if (hiddenStatusChanged) { + [self _deactivateExistingConstraints]; + + [self _applyConstraints]; + } + } else { + [super observeValueForKeyPath:keyPath ofObject:object change:change context:context]; + } +} + +@end diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSStripe3DS2Error.m b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSStripe3DS2Error.m new file mode 100644 index 0000000..6d2330e --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSStripe3DS2Error.m @@ -0,0 +1,15 @@ +// +// STDSStripe3DS2Error.m +// Stripe3DS2 +// +// Created by Yuki Tokuhiro on 3/27/19. +// Copyright © 2019 Stripe. All rights reserved. +// + +#import "STDSStripe3DS2Error.h" + +NSString * const STDSStripe3DS2ErrorDomain = @"com.stripe3ds2"; +NSString * const STDSStripe3DS2ErrorMessageErrorKey = @"STDSStripe3DS2ErrorMessageErrorKey"; +NSString * const STDSStripe3DS2ErrorFieldKey = @"STDSStripe3DS2ErrorFieldKey"; +NSString * const STDSStripe3DS2UnrecognizedCriticalMessageExtensionsKey = @"STDSStripe3DS2UnrecognizedCriticalMessageExtensionsKey"; + diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSSwiftTryCatch.m b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSSwiftTryCatch.m new file mode 100644 index 0000000..a9ac860 --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSSwiftTryCatch.m @@ -0,0 +1,59 @@ +// +// STDSSwiftTryCatch.h +// +// Created by William Falcon on 10/10/14. +// Copyright (c) 2014 William Falcon. 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 "STDSSwiftTryCatch.h" + +NS_ASSUME_NONNULL_BEGIN + +@implementation STDSSwiftTryCatch + ++ (void)tryBlock:(void(^)(void))tryBlock catchBlock:(void(^)(NSException*exception))catchBlock finallyBlock:(void(^)(void))finallyBlock { + @try { + tryBlock ? tryBlock() : nil; + } + + @catch (NSException *exception) { + catchBlock ? catchBlock(exception) : nil; + } + @finally { + finallyBlock ? finallyBlock() : nil; + } +} + ++ (void)throwString:(NSString*)s +{ + @throw [NSException exceptionWithName:s reason:s userInfo:nil]; +} + ++ (void)throwException:(NSException*)e +{ + @throw e; +} + + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSSynchronousLocationManager.h b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSSynchronousLocationManager.h new file mode 100644 index 0000000..883c6a3 --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSSynchronousLocationManager.h @@ -0,0 +1,26 @@ +// +// STDSSynchronousLocationManager.h +// Stripe3DS2 +// +// Created by Cameron Sabol on 1/23/19. +// Copyright © 2019 Stripe. All rights reserved. +// + +#import + +@class CLLocation; + +NS_ASSUME_NONNULL_BEGIN + +@interface STDSSynchronousLocationManager : NSObject + ++ (instancetype)sharedManager; + ++ (BOOL)hasPermissions; + +// May be long running. Will return nil on failure or if app lacks permissions +- (nullable CLLocation *)deviceLocation; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSSynchronousLocationManager.m b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSSynchronousLocationManager.m new file mode 100644 index 0000000..c492c6f --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSSynchronousLocationManager.m @@ -0,0 +1,110 @@ +// +// STDSSynchronousLocationManager.m +// Stripe3DS2 +// +// Created by Cameron Sabol on 1/23/19. +// Copyright © 2019 Stripe. All rights reserved. +// + +#import "STDSSynchronousLocationManager.h" + +#import + +NS_ASSUME_NONNULL_BEGIN + +static const int64_t kLocationFetchTimeoutSeconds = 15; + +typedef void (^LocationUpdateCompletionBlock)(CLLocation * _Nullable); + +@interface STDSSynchronousLocationManager () + +@end + +@implementation STDSSynchronousLocationManager +{ + CLLocationManager * _Nullable _locationManager; + dispatch_queue_t _Nullable _locationFetchQueue; + NSMutableArray *_pendingLocationUpdateCompletions; +} + ++ (instancetype)sharedManager { + static STDSSynchronousLocationManager *sharedManager = nil; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + sharedManager = [[STDSSynchronousLocationManager alloc] init]; + }); + return sharedManager; +} + ++ (BOOL)hasPermissions { + CLAuthorizationStatus authorizationStatus = [CLLocationManager authorizationStatus]; + return [CLLocationManager locationServicesEnabled] && + (authorizationStatus == kCLAuthorizationStatusAuthorizedAlways || authorizationStatus == kCLAuthorizationStatusAuthorizedWhenInUse); +} + +- (instancetype)init { + self = [super init]; + if (self) { + if ([STDSSynchronousLocationManager hasPermissions]) { + _locationManager = [[CLLocationManager alloc] init]; + _locationManager.delegate = self; + _locationFetchQueue = dispatch_queue_create("com.stripe.3ds2locationqueue", DISPATCH_QUEUE_SERIAL); + } + _pendingLocationUpdateCompletions = [NSMutableArray array]; + } + + return self; +} + +- (nullable CLLocation *)deviceLocation { + + __block CLLocation *location = nil; + dispatch_group_t group = dispatch_group_create(); + dispatch_group_enter(group); + [self _fetchDeviceLocation:^(CLLocation * _Nullable latestLocation) { + location = latestLocation; + dispatch_group_leave(group); + }]; + + dispatch_group_wait(group, dispatch_time(DISPATCH_TIME_NOW, NSEC_PER_SEC * kLocationFetchTimeoutSeconds)); + return location; +} + +- (void)_fetchDeviceLocation:(void (^)(CLLocation * _Nullable))completion { + + if (![STDSSynchronousLocationManager hasPermissions] || _locationFetchQueue == nil) { + return completion(nil); + } + + dispatch_async(_locationFetchQueue, ^{ + [self->_pendingLocationUpdateCompletions addObject:completion]; + + if (self->_pendingLocationUpdateCompletions.count == 1) { + [self->_locationManager requestLocation]; + } + }); +} + +- (void)_stopUpdatingLocationAndReportResult:(nullable CLLocation *)location { + [_locationManager stopUpdatingLocation]; + + dispatch_async(_locationFetchQueue, ^{ + for (LocationUpdateCompletionBlock completion in self->_pendingLocationUpdateCompletions) { + completion(location); + } + [self->_pendingLocationUpdateCompletions removeAllObjects]; + }); +} + +#pragma mark - CLLocationManagerDelegate +- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations { + [self _stopUpdatingLocationAndReportResult:locations.firstObject]; +} + +- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error { + [self _stopUpdatingLocationAndReportResult:nil]; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSTextChallengeView.h b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSTextChallengeView.h new file mode 100644 index 0000000..d44ea54 --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSTextChallengeView.h @@ -0,0 +1,26 @@ +// +// STDSTextChallengeView.h +// Stripe3DS2 +// +// Created by Andrew Harrison on 3/5/19. +// Copyright © 2019 Stripe. All rights reserved. +// + +#import +#import "STDSTextFieldCustomization.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface STDSTextField: UITextField + +@end + +@interface STDSTextChallengeView : UIView + +@property (nonatomic, strong, nullable) STDSTextFieldCustomization *textFieldCustomization; +@property (nonatomic, copy, readonly, nullable) NSString *inputText; +@property (nonatomic, strong) STDSTextField *textField; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSTextChallengeView.m b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSTextChallengeView.m new file mode 100644 index 0000000..f67fc5a --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSTextChallengeView.m @@ -0,0 +1,133 @@ +// +// STDSTextChallengeView.m +// Stripe3DS2 +// +// Created by Andrew Harrison on 3/5/19. +// Copyright © 2019 Stripe. All rights reserved. +// + +#import "STDSTextChallengeView.h" +#import "STDSStackView.h" +#import "UIView+LayoutSupport.h" +#import "NSString+EmptyChecking.h" +#import "UIColor+ThirteenSupport.h" + +NS_ASSUME_NONNULL_BEGIN + +@implementation STDSTextField + +static const CGFloat kTextFieldMargin = (CGFloat)8.0; + +- (CGRect)textRectForBounds:(CGRect)bounds { + return CGRectInset(bounds, kTextFieldMargin, 0); +} + +- (CGRect)editingRectForBounds:(CGRect)bounds { + return CGRectInset(bounds, kTextFieldMargin, 0); +} + +- (nullable NSString *)accessibilityIdentifier { + return @"STDSTextField"; +} + +@end + +@interface STDSTextChallengeView() + +@property (nonatomic, strong) STDSStackView *containerView; +@property (nonatomic, strong) NSLayoutConstraint *borderViewHeightConstraint; + +@end + +@implementation STDSTextChallengeView + +static const CGFloat kBorderViewHeight = 1; +static const CGFloat kTextFieldKernSpacing = 3; +static const CGFloat kTextFieldPlaceholderKernSpacing = 14; +static const CGFloat kTextChallengeViewBottomPadding = 11; + +- (instancetype)initWithFrame:(CGRect)frame { + self = [super initWithFrame:frame]; + + if (self) { + [self _setupViewHierarchy]; + } + + return self; +} + +- (void)_setupViewHierarchy { + self.layoutMargins = UIEdgeInsetsMake(0, 0, kTextChallengeViewBottomPadding, 0); + + self.containerView = [[STDSStackView alloc] initWithAlignment:STDSStackViewLayoutAxisVertical]; + + self.textField = [[STDSTextField alloc] init]; + self.textField.autocorrectionType = UITextAutocorrectionTypeNo; + self.textField.autocapitalizationType = UITextAutocapitalizationTypeNone; + self.textField.delegate = self; + self.textField.clearButtonMode = UITextFieldViewModeWhileEditing; + if (@available(iOS 12, *)) { + self.textField.textContentType = UITextContentTypeOneTimeCode; + } else { + // no-op + } + [self.textField.defaultTextAttributes setValue:@(kTextFieldKernSpacing) forKey:NSKernAttributeName]; + + UIView *borderView = [UIView new]; + if (@available(iOS 12.0, *)) { + borderView.backgroundColor = [UIColor _stds_colorWithDynamicProvider:^UIColor * _Nonnull(UITraitCollection * _Nonnull traitCollection) { + return [[UIColor _stds_systemGray2Color] colorWithAlphaComponent:(CGFloat)0.6]; + }]; + } else { + borderView.backgroundColor = [[UIColor lightGrayColor] colorWithAlphaComponent:(CGFloat)0.6]; + } + + [self.containerView addArrangedSubview:self.textField]; + [self.containerView addArrangedSubview:borderView]; + [self addSubview:self.containerView]; + [self.containerView _stds_pinToSuperviewBounds]; + + self.borderViewHeightConstraint = [NSLayoutConstraint constraintWithItem:borderView attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.0 constant:kBorderViewHeight]; + [NSLayoutConstraint activateConstraints:@[self.borderViewHeightConstraint]]; +} + +- (void)setTextFieldCustomization:(STDSTextFieldCustomization * _Nullable)textFieldCustomization { + _textFieldCustomization = textFieldCustomization; + + self.textField.font = textFieldCustomization.font; + self.textField.textColor = textFieldCustomization.textColor; + self.textField.layer.borderColor = textFieldCustomization.borderColor.CGColor; + self.textField.layer.borderWidth = textFieldCustomization.borderWidth; + self.textField.layer.cornerRadius = textFieldCustomization.cornerRadius; + self.textField.keyboardAppearance = textFieldCustomization.keyboardAppearance; + NSDictionary *placeholderTextAttributes = @{ + NSKernAttributeName: @(kTextFieldPlaceholderKernSpacing), + NSBaselineOffsetAttributeName: @(3.0f), + NSForegroundColorAttributeName: textFieldCustomization.placeholderTextColor, + }; + self.textField.attributedPlaceholder = [[NSAttributedString alloc] initWithString:@"••••••" attributes:placeholderTextAttributes]; +} + +- (NSString * _Nullable)inputText { + return self.textField.text; +} + +- (void)didMoveToWindow { + [super didMoveToWindow]; + + if (self.window.screen.nativeScale > 0) { + self.borderViewHeightConstraint.constant = kBorderViewHeight / self.window.screen.nativeScale; + } +} + +#pragma mark - UITextFieldDelegate + +- (BOOL)textFieldShouldReturn:(UITextField *)textField { + [textField resignFirstResponder]; + + return NO; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSTextFieldCustomization.m b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSTextFieldCustomization.m new file mode 100644 index 0000000..18a85c8 --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSTextFieldCustomization.m @@ -0,0 +1,50 @@ +// +// STDSTextFieldCustomization.m +// Stripe3DS2 +// +// Created by Andrew Harrison on 3/14/19. +// Copyright © 2019 Stripe. All rights reserved. +// + +#import "STDSTextFieldCustomization.h" + +#import "UIFont+DefaultFonts.h" +#import "UIColor+ThirteenSupport.h" + +NS_ASSUME_NONNULL_BEGIN + +@implementation STDSTextFieldCustomization + ++ (instancetype)defaultSettings { + return [self new]; +} + +- (instancetype)init { + self = [super init]; + if (self) { + self.font = [UIFont _stds_defaultLabelTextFontWithScale:(CGFloat)1.9]; + _borderWidth = 2; + _cornerRadius = 8; + _keyboardAppearance = UIKeyboardAppearanceDefault; + + self.textColor = UIColor._stds_labelColor; + _borderColor = UIColor.clearColor; + _placeholderTextColor = UIColor._stds_systemGray2Color; + } + return self; +} + +- (id)copyWithZone:(nullable NSZone *)zone { + STDSTextFieldCustomization *copy = [super copyWithZone:zone]; + copy.borderWidth = self.borderWidth; + copy.borderColor = self.borderColor; + copy.cornerRadius = self.cornerRadius; + copy.keyboardAppearance = self.keyboardAppearance; + copy.placeholderTextColor = self.placeholderTextColor; + + return copy; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSThreeDS2Service.m b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSThreeDS2Service.m new file mode 100644 index 0000000..f8a8823 --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSThreeDS2Service.m @@ -0,0 +1,193 @@ +// +// STDSThreeDS2Service.m +// Stripe3DS2 +// +// Created by Cameron Sabol on 1/22/19. +// Copyright © 2019 Stripe. All rights reserved. +// + +#import "STDSThreeDS2Service.h" + +#include + +#import "STDSAlreadyInitializedException.h" +#import "STDSCategoryLinker.h" +#import "STDSConfigParameters.h" +#import "STDSDebuggerChecker.h" +#import "STDSDeviceInformationManager.h" +#import "STDSDirectoryServerCertificate.h" +#import "STDSException+Internal.h" +#import "STDSInvalidInputException.h" +#import "STDSLocalizedString.h" +#import "STDSJailbreakChecker.h" +#import "STDSIntegrityChecker.h" +#import "STDSNotInitializedException.h" +#import "STDSOSVersionChecker.h" +#import "STDSSecTypeUtilities.h" +#import "STDSSimulatorChecker.h" +#import "STDSThreeDSProtocolVersion.h" +#import "STDSTransaction+Private.h" +#import "STDSWarning.h" + +static const int kServiceNotInitialized = 0; +static const int kServiceInitialized = 1; + +static NSString * const kInternalStripeTestingConfigParam = @"kInternalStripeTestingConfigParam"; +static NSString * const kIgnoreDeviceInformationRestrictionsParam = @"kIgnoreDeviceInformationRestrictionsParam"; +static NSString * const kUseULTestLOAParam = @"kUseULTestLOAParam"; + +@implementation STDSThreeDS2Service +{ + atomic_int _initialized; + + STDSDeviceInformation *_deviceInformation; + STDSUICustomization *_uiSettings; + STDSConfigParameters *_configuration; +} + +@synthesize warnings = _warnings; + +- (void)initializeWithConfig:(STDSConfigParameters *)config + locale:(nullable NSLocale *)locale + uiSettings:(nullable STDSUICustomization *)uiSettings { + [STDSCategoryLinker referenceAllCategories]; + if (config == nil) { + @throw [STDSInvalidInputException exceptionWithMessage:[NSString stringWithFormat:@"%@ config parameter must be non-nil.", NSStringFromSelector(_cmd)]]; + } + + int notInitialized = kServiceNotInitialized; // Can't pass a const to atomic_compare_exchange_strong_explicit so copy here + if (!atomic_compare_exchange_strong_explicit(&_initialized, ¬Initialized, kServiceInitialized, memory_order_release, memory_order_relaxed)) { + @throw [STDSAlreadyInitializedException exceptionWithMessage:[NSString stringWithFormat:@"STDSThreeDS2Service instance %p has already been initialized.", self]]; + } + + _configuration = config; + _uiSettings = uiSettings ? [uiSettings copy] : [STDSUICustomization defaultSettings]; + + NSMutableArray *warnings = [NSMutableArray array]; + if ([STDSJailbreakChecker isJailbroken]) { + STDSWarning *jailbrokenWarning = [[STDSWarning alloc] initWithIdentifier:@"SW01" message:STDSLocalizedString(@"The device is jailbroken.", @"The text for warning when a device is jailbroken") severity:STDSWarningSeverityHigh]; + [warnings addObject:jailbrokenWarning]; + } + + if (![STDSIntegrityChecker SDKIntegrityIsValid]) { + STDSWarning *integrityWarning = [[STDSWarning alloc] initWithIdentifier:@"SW02" message:STDSLocalizedString(@"The integrity of the SDK has been tampered.", @"The text for warning when the integrity of the SDK has been tampered with") severity:STDSWarningSeverityHigh]; + [warnings addObject:integrityWarning]; + } + + if ([STDSSimulatorChecker isRunningOnSimulator]) { + STDSWarning *simulatorWarning = [[STDSWarning alloc] initWithIdentifier:@"SW03" message:STDSLocalizedString(@"An emulator is being used to run the App.", @"The text for warning when an emulator is being used to run the application.") severity:STDSWarningSeverityHigh]; + [warnings addObject:simulatorWarning]; + } + + if ([STDSDebuggerChecker processIsCurrentlyAttachedToDebugger]) { + STDSWarning *debuggerWarning = [[STDSWarning alloc] initWithIdentifier:@"SW04" message:STDSLocalizedString(@"A debugger is attached to the App.", @"The text for warning when a debugger is currently attached to the process.") severity:STDSWarningSeverityMedium]; + [warnings addObject:debuggerWarning]; + } + + if (![STDSOSVersionChecker isSupportedOSVersion]) { + STDSWarning *versionWarning = [[STDSWarning alloc] initWithIdentifier:@"SW05" message:STDSLocalizedString(@"The OS or the OS Version is not supported.", "The text for warning when the SDK is running on an unsupported OS or OS version.") severity:STDSWarningSeverityHigh]; + [warnings addObject:versionWarning]; + } + + _warnings = [warnings copy]; + + _deviceInformation = [STDSDeviceInformationManager deviceInformationWithWarnings:_warnings + ignoringRestrictions:[[_configuration parameterValue:kIgnoreDeviceInformationRestrictionsParam] isEqualToString:@"Y"]]; + +} + +- (STDSTransaction *)createTransactionForDirectoryServer:(NSString *)directoryServerID + withProtocolVersion:(nullable NSString *)protocolVersion { + if (_initialized != kServiceInitialized) { + @throw [STDSNotInitializedException exceptionWithMessage:@"STDSThreeDS2Service instance %p has not been initialized before call to %@", self, NSStringFromSelector(_cmd)]; + } + + if (directoryServerID == nil) { + @throw [STDSInvalidInputException exceptionWithMessage:@"%@ directoryServerID parameter must be non-nil.", NSStringFromSelector(_cmd)]; + } + + STDSDirectoryServer directoryServer = STDSDirectoryServerForID(directoryServerID); + if (directoryServer == STDSDirectoryServerUnknown) { + if ([[_configuration parameterValue:kInternalStripeTestingConfigParam] isEqualToString:@"Y"]) { + directoryServer = STDSDirectoryServerULTestRSA; + } else { + @throw [STDSInvalidInputException exceptionWithMessage:@"%@ is an invalid directoryServerID value", directoryServerID]; + } + } + + if (protocolVersion != nil && ![self _supportsProtocolVersion:protocolVersion]) { + @throw [STDSInvalidInputException exceptionWithMessage:@"3DS2 Protocol Version %@ is not supported by this SDK", protocolVersion]; + } + + + + STDSTransaction *transaction = [[STDSTransaction alloc] initWithDeviceInformation:_deviceInformation + directoryServer:directoryServer + protocolVersion:(protocolVersion != nil) ? STDSThreeDSProtocolVersionForString(protocolVersion) : STDSThreeDSProtocolVersion2_1_0 + uiCustomization:_uiSettings]; + transaction.bypassTestModeVerification = [[_configuration parameterValue:kInternalStripeTestingConfigParam] isEqualToString:@"Y"]; + transaction.useULTestLOA = [[_configuration parameterValue:kUseULTestLOAParam] isEqualToString:@"Y"]; + return transaction; + +} + +- (nullable STDSTransaction *)createTransactionForDirectoryServer:(NSString *)directoryServerID + serverKeyID:(nullable NSString *)serverKeyID + certificateString:(NSString *)certificateString + rootCertificateStrings:(NSArray *)rootCertificateStrings + withProtocolVersion:(nullable NSString *)protocolVersion { + if (_initialized != kServiceInitialized) { + @throw [STDSNotInitializedException exceptionWithMessage:@"STDSThreeDS2Service instance %p has not been initialized before call to %@", self, NSStringFromSelector(_cmd)]; + } + + if (protocolVersion != nil && ![self _supportsProtocolVersion:protocolVersion]) { + @throw [STDSInvalidInputException exceptionWithMessage:@"3DS2 Protocol Version %@ is not supported by this SDK", protocolVersion]; + } + + STDSTransaction *transaction = nil; + + STDSDirectoryServerCertificate *certificate = [STDSDirectoryServerCertificate customCertificateWithString:certificateString]; + + if (certificate != nil) { + transaction = [[STDSTransaction alloc] initWithDeviceInformation:_deviceInformation + directoryServerID:directoryServerID + serverKeyID:serverKeyID + directoryServerCertificate:certificate + rootCertificateStrings:rootCertificateStrings + protocolVersion:(protocolVersion != nil) ? STDSThreeDSProtocolVersionForString(protocolVersion) : STDSThreeDSProtocolVersion2_1_0 + uiCustomization:_uiSettings]; + transaction.bypassTestModeVerification = [_configuration parameterValue:kInternalStripeTestingConfigParam] != nil; + } + + return transaction; +} + +- (nullable NSArray *)warnings { + if (_initialized != kServiceInitialized) { + @throw [STDSNotInitializedException exceptionWithMessage:@"STDSThreeDS2Service instance %p has not been initialized before call to %@", self, NSStringFromSelector(_cmd)]; + } + + return _warnings; +} + +#pragma mark - Internal + +- (BOOL)_supportsProtocolVersion:(NSString *)protocolVersion { + STDSThreeDSProtocolVersion version = STDSThreeDSProtocolVersionForString(protocolVersion); + switch (version) { + case STDSThreeDSProtocolVersion2_1_0: + return YES; + + case STDSThreeDSProtocolVersion2_2_0: + return YES; + + case STDSThreeDSProtocolVersionFallbackTest: + // only support fallback test if we have the internal testing config param + return [[_configuration parameterValue:kInternalStripeTestingConfigParam] isEqualToString:@"Y"]; + + case STDSThreeDSProtocolVersionUnknown: + return NO; + } +} + +@end diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSThreeDSProtocolVersion+Private.h b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSThreeDSProtocolVersion+Private.h new file mode 100644 index 0000000..43257e7 --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSThreeDSProtocolVersion+Private.h @@ -0,0 +1,53 @@ +// +// STDSThreeDSProtocolVersion+Private.h +// Stripe3DS2 +// +// Created by Cameron Sabol on 3/25/19. +// Copyright © 2019 Stripe. All rights reserved. +// + +#import "STDSThreeDSProtocolVersion.h" + +NS_ASSUME_NONNULL_BEGIN + + +typedef NS_ENUM(NSInteger, STDSThreeDSProtocolVersion) { + STDSThreeDSProtocolVersion2_1_0, + STDSThreeDSProtocolVersion2_2_0, + STDSThreeDSProtocolVersionUnknown, + STDSThreeDSProtocolVersionFallbackTest, +}; + +static NSString * const kThreeDS2ProtocolVersion2_1_0 = @"2.1.0"; +static NSString * const kThreeDS2ProtocolVersion2_2_0 = @"2.2.0"; +static NSString * const kThreeDSProtocolVersionFallbackTest = @"2.0.0"; + +NS_INLINE STDSThreeDSProtocolVersion STDSThreeDSProtocolVersionForString(NSString *stringValue) { + if ([stringValue isEqualToString:kThreeDS2ProtocolVersion2_1_0]) { + return STDSThreeDSProtocolVersion2_1_0; + } else if ([stringValue isEqualToString:kThreeDS2ProtocolVersion2_2_0]) { + return STDSThreeDSProtocolVersion2_2_0; + } else if ([stringValue isEqualToString:kThreeDSProtocolVersionFallbackTest]) { + return STDSThreeDSProtocolVersionFallbackTest; + } else { + return STDSThreeDSProtocolVersionUnknown; + } +} + +NS_INLINE NSString * _Nullable STDSThreeDSProtocolVersionStringValue(STDSThreeDSProtocolVersion protocolVersion) { + switch (protocolVersion) { + case STDSThreeDSProtocolVersion2_1_0: + return kThreeDS2ProtocolVersion2_1_0; + + case STDSThreeDSProtocolVersion2_2_0: + return kThreeDS2ProtocolVersion2_2_0; + + case STDSThreeDSProtocolVersionFallbackTest: + return kThreeDSProtocolVersionFallbackTest; + + case STDSThreeDSProtocolVersionUnknown: + return nil; + } +} + +NS_ASSUME_NONNULL_END diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSThreeDSProtocolVersion.m b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSThreeDSProtocolVersion.m new file mode 100644 index 0000000..3d275b1 --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSThreeDSProtocolVersion.m @@ -0,0 +1,15 @@ +// +// STDSThreeDSProtocolVersion.m +// Stripe3DS2 +// +// Created by Cameron Sabol on 6/27/19. +// Copyright © 2019 Stripe. All rights reserved. +// + +#import "STDSThreeDSProtocolVersion+Private.h" + +NS_ASSUME_NONNULL_BEGIN + +NSString * const Stripe3DS2ProtocolVersion = @"2.1.0"; + +NS_ASSUME_NONNULL_END diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSTransaction+Private.h b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSTransaction+Private.h new file mode 100644 index 0000000..2c35e95 --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSTransaction+Private.h @@ -0,0 +1,41 @@ +// +// STDSTransaction+Private.h +// Stripe3DS2 +// +// Created by Yuki Tokuhiro on 3/22/19. +// Copyright © 2019 Stripe. All rights reserved. +// + +#import "STDSTransaction.h" + +@class STDSDeviceInformation; +@class STDSDirectoryServerCertificate; + +#import "STDSDirectoryServer.h" +#import "STDSThreeDSProtocolVersion+Private.h" +#import "STDSUICustomization.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface STDSTransaction () + +- (instancetype)initWithDeviceInformation:(STDSDeviceInformation *)deviceInformation + directoryServer:(STDSDirectoryServer)directoryServer + protocolVersion:(STDSThreeDSProtocolVersion)protocolVersion + uiCustomization:(STDSUICustomization *)uiCustomization; + +- (instancetype)initWithDeviceInformation:(STDSDeviceInformation *)deviceInformation + directoryServerID:(NSString *)directoryServerID + serverKeyID:(nullable NSString *)serverKeyID + directoryServerCertificate:(STDSDirectoryServerCertificate *)directoryServerCertificate + rootCertificateStrings:(NSArray *)rootCertificateStrings + protocolVersion:(STDSThreeDSProtocolVersion)protocolVersion + uiCustomization:(STDSUICustomization *)uiCustomization; + +@property (nonatomic, strong) NSTimer *timeoutTimer; +@property (nonatomic) BOOL bypassTestModeVerification; // Should be used during internal testing ONLY +@property (nonatomic) BOOL useULTestLOA; // Should only be used when running tests with the UL reference app + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSTransaction.m b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSTransaction.m new file mode 100644 index 0000000..654efa6 --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSTransaction.m @@ -0,0 +1,531 @@ +// +// STDSTransaction.m +// Stripe3DS2 +// +// Created by Yuki Tokuhiro on 3/21/19. +// Copyright © 2019 Stripe. All rights reserved. +// + +#import "STDSTransaction.h" +#import "STDSTransaction+Private.h" + +#import "STDSBundleLocator.h" +#import "NSDictionary+DecodingHelpers.h" +#import "NSError+Stripe3DS2.h" +#import "NSString+JWEHelpers.h" +#import "STDSACSNetworkingManager.h" +#import "STDSAuthenticationRequestParameters.h" +#import "STDSChallengeRequestParameters.h" +#import "STDSCompletionEvent.h" +#import "STDSChallengeParameters.h" +#import "STDSChallengeResponseObject.h" +#import "STDSChallengeResponseViewController.h" +#import "STDSChallengeStatusReceiver.h" +#import "STDSDeviceInformation.h" +#import "STDSEllipticCurvePoint.h" +#import "STDSEphemeralKeyPair.h" +#import "STDSErrorMessage+Internal.h" +#import "STDSException+Internal.h" +#import "STDSInvalidInputException.h" +#import "STDSJSONWebEncryption.h" +#import "STDSJSONWebSignature.h" +#import "STDSProgressViewController.h" +#import "STDSProtocolErrorEvent.h" +#import "STDSRuntimeErrorEvent.h" +#import "STDSRuntimeException.h" +#import "STDSSecTypeUtilities.h" +#import "STDSStripe3DS2Error.h" +#import "STDSDeviceInformationParameter.h" + +static const NSTimeInterval kMinimumTimeout = 5 * 60; +static NSString * const kStripeLOA = @"3DS_LOA_SDK_STIN_020100_00162"; +static NSString * const kULTestLOA = @"3DS_LOA_SDK_PPFU_020100_00007"; + +NS_ASSUME_NONNULL_BEGIN + +@interface STDSTransaction() + +@property (nonatomic, weak) id challengeStatusReceiver; +@property (nonatomic, strong, nullable) STDSChallengeResponseViewController *challengeResponseViewController; +/// Stores the most recent parameters used to make a CReq +@property (nonatomic, nullable) STDSChallengeRequestParameters *challengeRequestParameters; +/// YES if `close` was called or the challenge flow finished. +@property (nonatomic, getter=isCompleted) BOOL completed; +@end + +@implementation STDSTransaction +{ + STDSDeviceInformation *_deviceInformation; + STDSDirectoryServer _directoryServer; + STDSEphemeralKeyPair *_ephemeralKeyPair; + STDSThreeDSProtocolVersion _protocolVersion; + NSString *_identifier; + + STDSDirectoryServerCertificate *_customDirectoryServerCertificate; + NSArray *_rootCertificateStrings; + NSString *_customDirectoryServerID; + NSString *_serverKeyID; + + STDSACSNetworkingManager *_networkingManager; + + STDSUICustomization *_uiCustomization; +} + +- (instancetype)initWithDeviceInformation:(STDSDeviceInformation *)deviceInformation + directoryServer:(STDSDirectoryServer)directoryServer + protocolVersion:(STDSThreeDSProtocolVersion)protocolVersion + uiCustomization:(nonnull STDSUICustomization *)uiCustomization { + self = [super init]; + if (self) { + _deviceInformation = deviceInformation; + _directoryServer = directoryServer; + _protocolVersion = protocolVersion; + _completed = NO; + _identifier = [NSUUID UUID].UUIDString.lowercaseString; + _ephemeralKeyPair = [STDSEphemeralKeyPair ephemeralKeyPair]; + _uiCustomization = uiCustomization; + if (_ephemeralKeyPair == nil) { + return nil; + } + } + + return self; +} + +- (instancetype)initWithDeviceInformation:(STDSDeviceInformation *)deviceInformation + directoryServerID:(NSString *)directoryServerID + serverKeyID:(nullable NSString *)serverKeyID + directoryServerCertificate:(STDSDirectoryServerCertificate *)directoryServerCertificate + rootCertificateStrings:(NSArray *)rootCertificateStrings + protocolVersion:(STDSThreeDSProtocolVersion)protocolVersion + uiCustomization:(STDSUICustomization *)uiCustomization { + self = [super init]; + if (self) { + _deviceInformation = deviceInformation; + _directoryServer = STDSDirectoryServerCustom; + _customDirectoryServerCertificate = directoryServerCertificate; + _rootCertificateStrings = rootCertificateStrings; + _customDirectoryServerID = [directoryServerID copy]; + _serverKeyID = [serverKeyID copy]; + _protocolVersion = protocolVersion; + _completed = NO; + _identifier = [NSUUID UUID].UUIDString.lowercaseString; + _ephemeralKeyPair = [STDSEphemeralKeyPair ephemeralKeyPair]; + _uiCustomization = uiCustomization; + if (_ephemeralKeyPair == nil) { + return nil; + } + } + + return self; +} + +- (NSString *)sdkVersion { + return [[STDSBundleLocator stdsResourcesBundle] objectForInfoDictionaryKey:@"CFBundleVersion"]; +} + +- (NSString *)presentedChallengeUIType { + switch (self.challengeResponseViewController.response.acsUIType) { + + case STDSACSUITypeNone: + return @"none"; + + case STDSACSUITypeText: + return @"text"; + + case STDSACSUITypeSingleSelect: + return @"single_select"; + + case STDSACSUITypeMultiSelect: + return @"multi_select"; + + case STDSACSUITypeOOB: + return @"oob"; + + case STDSACSUITypeHTML: + return @"html"; + } +} + +- (STDSAuthenticationRequestParameters *)createAuthenticationRequestParameters { + NSError *error = nil; + NSString *encryptedDeviceData = nil; + + if (_directoryServer == STDSDirectoryServerCustom) { + encryptedDeviceData = [STDSJSONWebEncryption encryptJSON:_deviceInformation.dictionaryValue + withCertificate:_customDirectoryServerCertificate + directoryServerID:_customDirectoryServerID + serverKeyID:_serverKeyID + error:&error]; + } else { + encryptedDeviceData = [STDSJSONWebEncryption encryptJSON:_deviceInformation.dictionaryValue + forDirectoryServer:_directoryServer + error:&error]; + } + if (encryptedDeviceData == nil) { + @throw [STDSRuntimeException exceptionWithMessage:@"Error encrypting device information %@", error]; + } + + return [[STDSAuthenticationRequestParameters alloc] initWithSDKTransactionIdentifier:_identifier + deviceData:encryptedDeviceData + sdkEphemeralPublicKey:_ephemeralKeyPair.publicKeyJWK + sdkAppIdentifier:[STDSDeviceInformationParameter sdkAppIdentifier] + sdkReferenceNumber:self.useULTestLOA ? kULTestLOA : kStripeLOA + messageVersion:[self _messageVersion]]; +} + +- (UIViewController *)createProgressViewControllerWithDidCancel:(void (^)(void))didCancel { + return [[STDSProgressViewController alloc] initWithDirectoryServer:[self _directoryServerForUI] uiCustomization:_uiCustomization didCancel:didCancel]; +} + +- (void)doChallengeWithViewController:(UIViewController *)presentingViewController + challengeParameters:(STDSChallengeParameters *)challengeParameters + challengeStatusReceiver:(id)challengeStatusReceiver + timeout:(NSTimeInterval)timeout { + + [self doChallengeWithChallengeParameters:challengeParameters + challengeStatusReceiver:challengeStatusReceiver + timeout:timeout + presentationBlock:^(UIViewController * _Nonnull challengeVC, void (^completion)(void)) { + UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:challengeVC]; + + // Disable "swipe to dismiss" behavior in iOS 13 + if ([navigationController respondsToSelector:NSSelectorFromString(@"isModalInPresentation")]) { + [navigationController setValue:@YES forKey:@"modalInPresentation"]; + } + + [presentingViewController presentViewController:navigationController animated:YES completion:^{ + completion(); + }]; + }]; +} + +- (void)doChallengeWithChallengeParameters:(STDSChallengeParameters *)challengeParameters + challengeStatusReceiver:(id)challengeStatusReceiver + timeout:(NSTimeInterval)timeout + presentationBlock:(void (^)(UIViewController *, void(^)(void)))presentationBlock { + if (self.isCompleted) { + @throw [STDSRuntimeException exceptionWithMessage:@"The transaction has already completed."]; + } else if (timeout < kMinimumTimeout) { + @throw [STDSInvalidInputException exceptionWithMessage:@"Timeout value of %lf seconds is less than 5 minutes", timeout]; + } + self.challengeStatusReceiver = challengeStatusReceiver; + self.timeoutTimer = [NSTimer scheduledTimerWithTimeInterval:(timeout) target:self selector:@selector(_didTimeout) userInfo:nil repeats:NO]; + + self.challengeRequestParameters = [[STDSChallengeRequestParameters alloc] initWithChallengeParameters:challengeParameters + transactionIdentifier:_identifier + messageVersion:[self _messageVersion]]; + + STDSJSONWebSignature *jws = [[STDSJSONWebSignature alloc] initWithString:challengeParameters.acsSignedContent allowNilKey:self.bypassTestModeVerification]; + BOOL validJWS = jws != nil; + if (validJWS && !self.bypassTestModeVerification) { + if (_customDirectoryServerCertificate != nil) { + if (_rootCertificateStrings.count == 0) { + validJWS = NO; + } else { + validJWS = [STDSJSONWebEncryption verifyJSONWebSignature:jws withCertificate:_customDirectoryServerCertificate rootCertificates:_rootCertificateStrings]; + } + } else { + validJWS = [STDSJSONWebEncryption verifyJSONWebSignature:jws forDirectoryServer:_directoryServer]; + } + } + if (!validJWS) { + dispatch_async(dispatch_get_main_queue(), ^{ + [challengeStatusReceiver transaction:self + didErrorWithRuntimeErrorEvent:[[STDSRuntimeErrorEvent alloc] initWithErrorCode:kSTDSRuntimeErrorCodeEncryptionError errorMessage:@"Error verifying JWS response."]]; + [self _cleanUp]; + }); + return; + } + + NSError *jsonError = nil; + NSDictionary *json = [NSJSONSerialization JSONObjectWithData:jws.payload options:0 error:&jsonError]; + NSDictionary *acsEphmeralKeyJWK = [json _stds_dictionaryForKey:@"acsEphemPubKey" required:NO error:NULL]; + STDSEllipticCurvePoint *acsEphemeralKey = [[STDSEllipticCurvePoint alloc] initWithJWK:acsEphmeralKeyJWK]; + NSString *acsURLString = [json _stds_stringForKey:@"acsURL" required:NO error:NULL]; + NSURL *acsURL = [NSURL URLWithString:acsURLString ?: @""]; + if (acsEphemeralKey == nil || acsURL == nil) { + dispatch_async(dispatch_get_main_queue(), ^{ + [challengeStatusReceiver transaction:self + didErrorWithRuntimeErrorEvent:[[STDSRuntimeErrorEvent alloc] initWithErrorCode:kSTDSRuntimeErrorCodeParsingError errorMessage:[NSString stringWithFormat:@"Unable to create key or url from ACS json: %@\n\n jsonError: %@", json, jsonError]]]; + [self _cleanUp]; + }); + return; + } + + NSData *ecdhSecret = [_ephemeralKeyPair createSharedSecretWithEllipticCurveKey:acsEphemeralKey]; + if (ecdhSecret == nil) { + dispatch_async(dispatch_get_main_queue(), ^{ + [challengeStatusReceiver transaction:self + didErrorWithRuntimeErrorEvent:[[STDSRuntimeErrorEvent alloc] initWithErrorCode:kSTDSRuntimeErrorCodeEncryptionError errorMessage:@"Error during Diffie-Helman key exchange"]]; + [self _cleanUp]; + }); + return; + } + + NSData *contentEncryptionKeySDKtoACS = STDSCreateConcatKDFWithSHA256(ecdhSecret, 32, self.useULTestLOA ? kULTestLOA : kStripeLOA); + // These two keys are intentionally identical + // ref. Protocol and Core Functions Specification Version 2.2.0 Section 6.2.3.2 & 6.2.3.3 + // "In this version of the specification [contentEncryptionKeyACStoSDK] and [contentEncryptionKeySDKtoACS] + // are extracted with the same value." + NSData *contentEncryptionKeyACStoSDK = [contentEncryptionKeySDKtoACS copy]; + + _networkingManager = [[STDSACSNetworkingManager alloc] initWithURL:acsURL + sdkContentEncryptionKey:contentEncryptionKeySDKtoACS + acsContentEncryptionKey:contentEncryptionKeyACStoSDK + acsTransactionIdentifier:self.challengeRequestParameters.acsTransactionIdentifier]; + // Start the Challenge flow + STDSImageLoader *imageLoader = [[STDSImageLoader alloc] initWithURLSession:NSURLSession.sharedSession]; + self.challengeResponseViewController = [[STDSChallengeResponseViewController alloc] initWithUICustomization:_uiCustomization imageLoader:imageLoader directoryServer:[self _directoryServerForUI]]; + self.challengeResponseViewController.delegate = self; + + presentationBlock(self.challengeResponseViewController, ^{ [self _makeChallengeRequest:self.challengeRequestParameters didCancel:NO]; }); +} + +- (void)close { + [self _cleanUp]; +} + +- (void)cancelChallengeFlow { + [self challengeResponseViewControllerDidCancel:self.challengeResponseViewController]; +} + +- (void)dealloc { + [self _cleanUp]; +} + +#pragma mark - Private + +// When we get a directory certificate and ID from the server, we mark it as Custom for encryption, +// but may have a correct mapping to a DS logo for the UI +- (STDSDirectoryServer)_directoryServerForUI { + return (_customDirectoryServerID != nil) ? STDSDirectoryServerForID(_customDirectoryServerID) : _directoryServer; +} + +- (void)_makeChallengeRequest:(STDSChallengeRequestParameters *)challengeRequestParameters didCancel:(BOOL)didCancel { + [self.challengeResponseViewController setLoading]; + __weak STDSTransaction *weakSelf = self; + [_networkingManager submitChallengeRequest:self.challengeRequestParameters + withCompletion:^(id _Nullable response, NSError * _Nullable error) { + STDSTransaction *strongSelf = weakSelf; + if (strongSelf == nil || strongSelf.isCompleted) { + return; + } + // Parsing or network errors + if (response == nil || error) { + if (!error) { + error = [NSError errorWithDomain:STDSStripe3DS2ErrorDomain code:STDSErrorCodeUnknownError userInfo:nil]; + } + [strongSelf _handleError:error]; + return; + } + // Consistency errors (e.g. acsTransID changes) + NSError *validationError; + if (![strongSelf _validateChallengeResponse:response error:&validationError]) { + [strongSelf _handleError:validationError]; + return; + } + [strongSelf _handleChallengeResponse:response didCancel:didCancel]; + }]; +} + +- (BOOL)_validateChallengeResponse:(id)challengeResponse error:(NSError **)outError { + NSError *error; + if (![challengeResponse.acsTransactionID isEqualToString:self.challengeRequestParameters.acsTransactionIdentifier] || + ![challengeResponse.threeDSServerTransactionID isEqualToString:self.challengeRequestParameters.threeDSServerTransactionIdentifier] || + ![challengeResponse.sdkTransactionID isEqualToString:self.challengeRequestParameters.sdkTransactionIdentifier]) { + error = [NSError errorWithDomain:STDSStripe3DS2ErrorDomain code:STDSErrorMessageErrorTransactionIDNotRecognized userInfo:nil]; + } else if (![challengeResponse.messageVersion isEqualToString:self.challengeRequestParameters.messageVersion]) { + error = [NSError _stds_invalidJSONFieldError:@"messageVersion"]; + } else if (!self.bypassTestModeVerification && ![challengeResponse.acsCounterACStoSDK isEqualToString:self.challengeRequestParameters.sdkCounterStoA]) { + error = [NSError errorWithDomain:STDSStripe3DS2ErrorDomain code:STDSErrorCodeDecryptionVerification userInfo:nil]; + } else if (challengeResponse.acsUIType == STDSACSUITypeHTML && !challengeResponse.acsHTML) { + error = [NSError errorWithDomain:STDSStripe3DS2ErrorDomain code:STDSErrorCodeDecryptionVerification userInfo:nil]; + } + + if (error && outError) { + *outError = error; + } + return error == nil; +} + +- (void) _handleError:(NSError *)error { + // All the codes corresponding to errors that we treat as protocol errors (ie send to the ACS and report as an STDSProtocolErrorEvent) + NSSet *protocolErrorCodes = [NSSet setWithArray:@[@(STDSErrorCodeUnknownMessageType), + @(STDSErrorCodeJSONFieldInvalid), + @(STDSErrorCodeJSONFieldMissing), + @(STDSErrorCodeReceivedErrorMessage), + @(STDSErrorMessageErrorTransactionIDNotRecognized), + @(STDSErrorCodeUnrecognizedCriticalMessageExtension), + @(STDSErrorCodeDecryptionVerification)]]; + if (error.domain == STDSStripe3DS2ErrorDomain) { + NSString *sdkTransactionIdentifier = _identifier; + NSString *acsTransactionIdentifier = self.challengeRequestParameters.acsTransactionIdentifier; + NSString *messageVersion = [self _messageVersion]; + STDSErrorMessage *errorMessage; + switch (error.code) { + case STDSErrorCodeReceivedErrorMessage: + errorMessage = error.userInfo[STDSStripe3DS2ErrorMessageErrorKey]; + break; + case STDSErrorCodeUnknownMessageType: + errorMessage = [STDSErrorMessage errorForInvalidMessageWithACSTransactionID:acsTransactionIdentifier messageVersion:messageVersion]; + break; + case STDSErrorCodeJSONFieldInvalid: + errorMessage = [STDSErrorMessage errorForJSONFieldInvalidWithACSTransactionID:acsTransactionIdentifier messageVersion:messageVersion error:error]; + break; + case STDSErrorCodeJSONFieldMissing: + errorMessage = [STDSErrorMessage errorForJSONFieldMissingWithACSTransactionID:acsTransactionIdentifier messageVersion:messageVersion error:error]; + break; + case STDSErrorCodeTimeout: + errorMessage = [STDSErrorMessage errorForTimeoutWithACSTransactionID:acsTransactionIdentifier messageVersion:messageVersion]; + break; + case STDSErrorMessageErrorTransactionIDNotRecognized: + errorMessage = [STDSErrorMessage errorForUnrecognizedIDWithACSTransactionID:acsTransactionIdentifier messageVersion:messageVersion]; + break; + case STDSErrorCodeUnrecognizedCriticalMessageExtension: + errorMessage = [STDSErrorMessage errorForUnrecognizedCriticalMessageExtensionsWithACSTransactionID:acsTransactionIdentifier messageVersion:messageVersion error:error]; + break; + case STDSErrorCodeDecryptionVerification: + errorMessage = [STDSErrorMessage errorForDecryptionErrorWithACSTransactionID:acsTransactionIdentifier messageVersion:messageVersion]; + break; + default: + break; + } + + // Send the ErrorMessage (unless we received one) + if (error.code != STDSErrorCodeReceivedErrorMessage && errorMessage != nil) { + [_networkingManager sendErrorMessage:errorMessage]; + } + + // If it's a protocol error, call back to the challengeStatusReceiver + if ([protocolErrorCodes containsObject:@(error.code)] && errorMessage != nil) { + STDSProtocolErrorEvent *protocolErrorEvent = [[STDSProtocolErrorEvent alloc] initWithSDKTransactionIdentifier:sdkTransactionIdentifier + errorMessage:errorMessage]; + [self.challengeStatusReceiver transaction:self didErrorWithProtocolErrorEvent:protocolErrorEvent]; + } + + } + + if (error.domain != STDSStripe3DS2ErrorDomain || ![protocolErrorCodes containsObject:@(error.code)]) { + // This error is not a protocol error, and therefore a runtime error. + NSString *errorCode = [NSString stringWithFormat:@"%ld", (long)error.code]; + STDSRuntimeErrorEvent *runtimeErrorEvent = [[STDSRuntimeErrorEvent alloc] initWithErrorCode:errorCode errorMessage:error.localizedDescription]; + [self.challengeStatusReceiver transaction:self didErrorWithRuntimeErrorEvent:runtimeErrorEvent]; + } + + [self _dismissChallengeResponseViewController]; + [self _cleanUp]; +} + +- (void)_handleChallengeResponse:(id)challengeResponse didCancel:(BOOL)didCancel { + if (challengeResponse.challengeCompletionIndicator) { + // Final CRes + // We need to pass didCancel to here because we can't distinguish between cancellation and auth failure from the CRes + // (they both result in a transactionStatus of "N") + if (didCancel) { + // We already dismissed the view controller + [self.challengeStatusReceiver transactionDidCancel:self]; + [self _cleanUp]; + } else { + [self _dismissChallengeResponseViewController]; + STDSCompletionEvent *completionEvent = [[STDSCompletionEvent alloc] initWithSDKTransactionIdentifier:_identifier + transactionStatus:challengeResponse.transactionStatus]; + [self.challengeStatusReceiver transaction:self didCompleteChallengeWithCompletionEvent:completionEvent]; + [self _cleanUp]; + } + } else { + [self.challengeResponseViewController setChallengeResponse:challengeResponse animated:YES]; + + if ([self.challengeStatusReceiver respondsToSelector:@selector(transactionDidPresentChallengeScreen:)]) { + [self.challengeStatusReceiver transactionDidPresentChallengeScreen:self]; + } + } +} + +- (void)_cleanUp { + [self.timeoutTimer invalidate]; + self.completed = YES; + self.challengeResponseViewController = nil; + self.challengeStatusReceiver = nil; + _networkingManager = nil; +} + +- (void)_didTimeout { + [self _dismissChallengeResponseViewController]; + [_networkingManager sendErrorMessage:[STDSErrorMessage errorForTimeoutWithACSTransactionID:self.challengeRequestParameters.acsTransactionIdentifier messageVersion:[self _messageVersion]]]; + [self.challengeStatusReceiver transactionDidTimeOut:self]; + [self _cleanUp]; +} + +- (void)_dismissChallengeResponseViewController { + if ([self.challengeStatusReceiver respondsToSelector:@selector(dismissChallengeViewController:forTransaction:)]) { + [self.challengeStatusReceiver dismissChallengeViewController:self.challengeResponseViewController forTransaction:self]; + } else { + [self.challengeResponseViewController dismissViewControllerAnimated:YES completion:nil]; + } +} + +#pragma mark Helpers + +- (nullable NSString *)_messageVersion { + NSString *messageVersion = STDSThreeDSProtocolVersionStringValue(_protocolVersion); + if (messageVersion == nil) { + @throw [STDSRuntimeException exceptionWithMessage:@"Error determining message version."]; + } + return messageVersion; +} + +/// Convenience method to construct a CSV from the names of each STDSChallengeResponseSelectionInfo in the given array +- (NSString *)_csvForChallengeResponseSelectionInfo:(NSArray> *)selectionInfoArray { + NSMutableArray *selectionInfoNames = [NSMutableArray new]; + for (id selectionInfo in selectionInfoArray) { + [selectionInfoNames addObject:selectionInfo.name]; + } + return [selectionInfoNames componentsJoinedByString:@","]; +} + +#pragma mark - STDSChallengeResponseViewController + +- (void)challengeResponseViewController:(nonnull STDSChallengeResponseViewController *)viewController didSubmitInput:(nonnull NSString *)userInput whitelistSelection:(nonnull id)whitelistSelection { + self.challengeRequestParameters = [self.challengeRequestParameters nextChallengeRequestParametersByIncrementCounter]; + self.challengeRequestParameters.challengeDataEntry = userInput; + self.challengeRequestParameters.whitelistingDataEntry = whitelistSelection.name; + [self _makeChallengeRequest:self.challengeRequestParameters didCancel:NO]; +} + +- (void)challengeResponseViewController:(nonnull STDSChallengeResponseViewController *)viewController didSubmitSelection:(nonnull NSArray> *)selection whitelistSelection:(nonnull id)whitelistSelection { + self.challengeRequestParameters = [self.challengeRequestParameters nextChallengeRequestParametersByIncrementCounter]; + self.challengeRequestParameters.challengeDataEntry = [self _csvForChallengeResponseSelectionInfo:selection]; + self.challengeRequestParameters.whitelistingDataEntry = whitelistSelection.name; + [self _makeChallengeRequest:self.challengeRequestParameters didCancel:NO]; +} + +- (void)challengeResponseViewControllerDidOOBContinue:(nonnull STDSChallengeResponseViewController *)viewController whitelistSelection:(nonnull id)whitelistSelection { + self.challengeRequestParameters = [self.challengeRequestParameters nextChallengeRequestParametersByIncrementCounter]; + self.challengeRequestParameters.oobContinue = @(YES); + self.challengeRequestParameters.whitelistingDataEntry = whitelistSelection.name; + [self _makeChallengeRequest:self.challengeRequestParameters didCancel:NO]; +} + +- (void)challengeResponseViewControllerDidCancel:(STDSChallengeResponseViewController *)viewController { + self.challengeRequestParameters = [self.challengeRequestParameters nextChallengeRequestParametersByIncrementCounter]; + self.challengeRequestParameters.challengeCancel = @(STDSChallengeCancelTypeCardholderSelectedCancel); + [self _dismissChallengeResponseViewController]; + [self _makeChallengeRequest:self.challengeRequestParameters didCancel:YES]; +} + +- (void)challengeResponseViewControllerDidRequestResend:(STDSChallengeResponseViewController *)viewController { + self.challengeRequestParameters = [self.challengeRequestParameters nextChallengeRequestParametersByIncrementCounter]; + self.challengeRequestParameters.resendChallenge = @"Y"; + [self _makeChallengeRequest:self.challengeRequestParameters didCancel:NO]; +} + +- (void)challengeResponseViewController:(nonnull STDSChallengeResponseViewController *)viewController didSubmitHTMLForm:(nonnull NSString *)form { + self.challengeRequestParameters = [self.challengeRequestParameters nextChallengeRequestParametersByIncrementCounter]; + self.challengeRequestParameters.challengeHTMLDataEntry = form; + [self _makeChallengeRequest:self.challengeRequestParameters didCancel:NO]; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSUICustomization.m b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSUICustomization.m new file mode 100644 index 0000000..8d1d681 --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSUICustomization.m @@ -0,0 +1,83 @@ +// +// STDSUICustomization.m +// Stripe3DS2 +// +// Created by Andrew Harrison on 3/14/19. +// Copyright © 2019 Stripe. All rights reserved. +// + +#import "STDSUICustomization.h" +#import "UIColor+ThirteenSupport.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface STDSUICustomization() + +@property (nonatomic, strong) NSMutableDictionary *buttonCustomizationDictionary; + +@end + +@implementation STDSUICustomization + ++ (instancetype)defaultSettings { + return [[STDSUICustomization alloc] init]; +} + +- (instancetype)init { + self = [super init]; + + if (self) { + _buttonCustomizationDictionary = [@{ + @(STDSUICustomizationButtonTypeNext): [STDSButtonCustomization defaultSettingsForButtonType:STDSUICustomizationButtonTypeNext + ], + @(STDSUICustomizationButtonTypeCancel): [STDSButtonCustomization defaultSettingsForButtonType:STDSUICustomizationButtonTypeCancel], + @(STDSUICustomizationButtonTypeResend): [STDSButtonCustomization defaultSettingsForButtonType:STDSUICustomizationButtonTypeResend], + @(STDSUICustomizationButtonTypeSubmit): [STDSButtonCustomization defaultSettingsForButtonType:STDSUICustomizationButtonTypeSubmit], + @(STDSUICustomizationButtonTypeContinue): [STDSButtonCustomization defaultSettingsForButtonType:STDSUICustomizationButtonTypeContinue], + } mutableCopy]; + _navigationBarCustomization = [STDSNavigationBarCustomization defaultSettings]; + _labelCustomization = [STDSLabelCustomization defaultSettings]; + _textFieldCustomization = [STDSTextFieldCustomization defaultSettings]; + _footerCustomization = [STDSFooterCustomization defaultSettings]; + _selectionCustomization = [STDSSelectionCustomization defaultSettings]; + _backgroundColor = UIColor._stds_systemBackgroundColor; + _activityIndicatorViewStyle = UIActivityIndicatorViewStyleMedium; + _blurStyle = UIBlurEffectStyleRegular; + _preferredStatusBarStyle = UIStatusBarStyleDefault; + } + + return self; +} + +- (void)setButtonCustomization:(STDSButtonCustomization *)buttonCustomization forType:(STDSUICustomizationButtonType)buttonType { + self.buttonCustomizationDictionary[@(buttonType)] = buttonCustomization; +} + +- (STDSButtonCustomization *)buttonCustomizationForButtonType:(STDSUICustomizationButtonType)buttonType { + return self.buttonCustomizationDictionary[@(buttonType)]; +} + +#pragma mark - NSCopying + +- (instancetype)copyWithZone:(nullable NSZone *)zone { + STDSUICustomization *copy = [[[self class] allocWithZone:zone] init]; + copy.navigationBarCustomization = [self.navigationBarCustomization copy]; + copy.labelCustomization = [self.labelCustomization copy]; + copy.textFieldCustomization = [self.textFieldCustomization copy]; + NSMutableDictionary *buttonCustomizationDictionary = [NSMutableDictionary new]; + for (NSNumber *buttonCustomization in self.buttonCustomizationDictionary) { + buttonCustomizationDictionary[buttonCustomization] = [self.buttonCustomizationDictionary[buttonCustomization] copy]; + } + copy.buttonCustomizationDictionary = buttonCustomizationDictionary; + copy.footerCustomization = [self.footerCustomization copy]; + copy.selectionCustomization = [self.selectionCustomization copy]; + copy.backgroundColor = self.backgroundColor; + copy.activityIndicatorViewStyle = self.activityIndicatorViewStyle; + copy.blurStyle = self.blurStyle; + copy.preferredStatusBarStyle = self.preferredStatusBarStyle; + return copy; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSWarning.m b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSWarning.m new file mode 100644 index 0000000..ad0d630 --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSWarning.m @@ -0,0 +1,30 @@ +// +// STDSWarning.m +// Stripe3DS2 +// +// Created by Cameron Sabol on 2/12/19. +// Copyright © 2019 Stripe. All rights reserved. +// + +#import "STDSWarning.h" + +NS_ASSUME_NONNULL_BEGIN + +@implementation STDSWarning + +- (instancetype)initWithIdentifier:(NSString *)identifier + message:(NSString *)message + severity:(STDSWarningSeverity)severity { + self = [super init]; + if (self) { + _identifier = [identifier copy]; + _message = [message copy]; + _severity = severity; + } + + return self; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSWebView.h b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSWebView.h new file mode 100644 index 0000000..7e6673f --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSWebView.h @@ -0,0 +1,22 @@ +// +// STDSWebView.h +// Stripe3DS2 +// +// Created by Andrew Harrison on 3/13/19. +// Copyright © 2019 Stripe. All rights reserved. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface STDSWebView : WKWebView + +/** + Convenience method that prepends the given HTML string with a CSP meta tag that disables external resource loading, and passes it to `loadHTMLString:baseURL:`. + */ +- (WKNavigation *)loadExternalResourceBlockingHTMLString:(NSString *)html; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSWebView.m b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSWebView.m new file mode 100644 index 0000000..d30da6b --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSWebView.m @@ -0,0 +1,37 @@ +// +// STDSWebView.m +// Stripe3DS2 +// +// Created by Andrew Harrison on 3/13/19. +// Copyright © 2019 Stripe. All rights reserved. +// + +#import "STDSWebView.h" + +NS_ASSUME_NONNULL_BEGIN + +@implementation STDSWebView + +- (instancetype)init { + WKWebViewConfiguration *configuration = [[WKWebViewConfiguration alloc] init]; + configuration.preferences.javaScriptEnabled = NO; + return [super initWithFrame:CGRectZero configuration:configuration]; +} + +/// Overriden to do nothing per 3DS2 security guidelines. +- (void)evaluateJavaScript:(NSString *)javaScriptString completionHandler:(void (^ _Nullable)(_Nullable id, NSError * _Nullable error))completionHandler { + +} + +- (WKNavigation *)loadExternalResourceBlockingHTMLString:(NSString *)html { + NSString *cspMetaTag = @""; + return [self loadHTMLString:[cspMetaTag stringByAppendingString:html] baseURL:nil]; +} + +- (nullable NSString *)accessibilityIdentifier { + return @"STDSWebView"; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSWhitelistView.h b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSWhitelistView.h new file mode 100644 index 0000000..a744f2b --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSWhitelistView.h @@ -0,0 +1,25 @@ +// +// STDSWhitelistView.h +// Stripe3DS2 +// +// Created by Andrew Harrison on 3/11/19. +// Copyright © 2019 Stripe. All rights reserved. +// + +#import +#import "STDSChallengeResponseSelectionInfo.h" +#import "STDSLabelCustomization.h" +#import "STDSSelectionCustomization.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface STDSWhitelistView : UIView + +@property (nonatomic, strong, nullable) NSString *whitelistText; +@property (nonatomic, readonly, nullable) id selectedResponse; +@property (nonatomic, strong, nullable) STDSLabelCustomization *labelCustomization; +@property (nonatomic, strong, nullable) STDSSelectionCustomization *selectionCustomization; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSWhitelistView.m b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSWhitelistView.m new file mode 100644 index 0000000..a5181fa --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/STDSWhitelistView.m @@ -0,0 +1,103 @@ +// +// STDSWhitelistView.m +// Stripe3DS2 +// +// Created by Andrew Harrison on 3/11/19. +// Copyright © 2019 Stripe. All rights reserved. +// + +#import "STDSLocalizedString.h" +#import "STDSWhitelistView.h" +#import "STDSStackView.h" +#import "STDSChallengeResponseSelectionInfoObject.h" +#import "NSString+EmptyChecking.h" +#import "UIView+LayoutSupport.h" +#import "STDSSelectionButton.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface STDSWhitelistView() + +@property (nonatomic, strong) UILabel *whitelistLabel; +@property (nonatomic, strong) STDSSelectionButton *selectionButton; + +@end + +@implementation STDSWhitelistView + +- (instancetype)initWithFrame:(CGRect)frame { + self = [super initWithFrame:frame]; + + if (self) { + [self _setupViewHierarchy]; + } + + return self; +} + +- (void)_setupViewHierarchy { + self.layoutMargins = UIEdgeInsetsZero; + + STDSStackView *containerView = [[STDSStackView alloc] initWithAlignment:STDSStackViewLayoutAxisVertical]; + [self addSubview:containerView]; + [containerView _stds_pinToSuperviewBounds]; + + self.whitelistLabel = [[UILabel alloc] init]; + self.whitelistLabel.numberOfLines = 0; + + self.selectionButton = [[STDSSelectionButton alloc] initWithCustomization:self.selectionCustomization]; + self.selectionButton.isCheckbox = YES; + [self.selectionButton addTarget:self action:@selector(_selectionButtonWasTapped) forControlEvents:UIControlEventTouchUpInside]; + + UIStackView *stackView = [self _buildStackView]; + [stackView addArrangedSubview:self.selectionButton]; + [stackView addArrangedSubview:self.whitelistLabel]; + + [containerView addArrangedSubview:stackView]; +} + +- (void)setWhitelistText:(NSString * _Nullable)whitelistText { + _whitelistText = whitelistText; + + self.whitelistLabel.text = whitelistText; + self.whitelistLabel.hidden = [NSString _stds_isStringEmpty:whitelistText]; + self.selectionButton.hidden = self.whitelistLabel.hidden; +} + +- (id _Nullable)selectedResponse { + if (self.selectionButton.selected) { + return [[STDSChallengeResponseSelectionInfoObject alloc] initWithName:@"Y" value:STDSLocalizedString(@"Yes", @"The yes answer to a yes or no question.")];; + } + + return [[STDSChallengeResponseSelectionInfoObject alloc] initWithName:@"N" value:STDSLocalizedString(@"No", @"The no answer to a yes or no question.")]; +} + +- (void)setLabelCustomization:(STDSLabelCustomization * _Nullable)labelCustomization { + _labelCustomization = labelCustomization; + + self.whitelistLabel.font = labelCustomization.font; + self.whitelistLabel.textColor = labelCustomization.textColor; +} + +- (void)setSelectionCustomization:(STDSSelectionCustomization * _Nullable)selectionCustomization { + _selectionCustomization = selectionCustomization; + self.selectionButton.customization = selectionCustomization; +} + +- (UIStackView *)_buildStackView { + UIStackView *stackView = [[UIStackView alloc] init]; + stackView.axis = UILayoutConstraintAxisHorizontal; + stackView.distribution = UIStackViewDistributionFillProportionally; + stackView.alignment = UIStackViewAlignmentCenter; + stackView.spacing = 20; + stackView.translatesAutoresizingMaskIntoConstraints = NO; + return stackView; +} + +- (void)_selectionButtonWasTapped { + self.selectionButton.selected = !self.selectionButton.selected; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/Stripe3DS2-Bridging-Header.h b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/Stripe3DS2-Bridging-Header.h new file mode 100644 index 0000000..cfc1861 --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/Stripe3DS2-Bridging-Header.h @@ -0,0 +1,12 @@ +// +// Stripe3DS2-Bridging-Header.h +// Stripe3DS2 +// +// Created by Andrew Harrison on 4/10/19. +// Copyright © 2019 Stripe. All rights reserved. +// + +#ifndef Stripe3DS2_Bridging_Header_h +#define Stripe3DS2_Bridging_Header_h + +#endif /* Stripe3DS2_Bridging_Header_h */ diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/UIButton+CustomInitialization.h b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/UIButton+CustomInitialization.h new file mode 100644 index 0000000..b15396f --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/UIButton+CustomInitialization.h @@ -0,0 +1,23 @@ +// +// UIButton+CustomInitialization.h +// Stripe3DS2 +// +// Created by Andrew Harrison on 3/18/19. +// Copyright © 2019 Stripe. All rights reserved. +// + +#import + +#import "STDSUICustomization.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface UIButton (CustomInitialization) + ++ (UIButton *)_stds_buttonWithTitle:(NSString * _Nullable)title customization:(STDSButtonCustomization * _Nullable)customization; + +@end + +NS_ASSUME_NONNULL_END + +void _stds_import_uibutton_custominitialization(void); diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/UIButton+CustomInitialization.m b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/UIButton+CustomInitialization.m new file mode 100644 index 0000000..6e8bc2f --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/UIButton+CustomInitialization.m @@ -0,0 +1,66 @@ +// +// UIButton+CustomInitialization.m +// Stripe3DS2 +// +// Created by Andrew Harrison on 3/18/19. +// Copyright © 2019 Stripe. All rights reserved. +// + +#import "UIButton+CustomInitialization.h" + +NS_ASSUME_NONNULL_BEGIN + +@implementation UIButton (CustomInitialization) + +static const CGFloat kDefaultButtonContentInset = (CGFloat)12.0; + ++ (UIButton *)_stds_buttonWithTitle:(NSString * _Nullable)title customization:(STDSButtonCustomization * _Nullable)customization { + UIButton *button = [UIButton buttonWithType:UIButtonTypeSystem]; + button.clipsToBounds = YES; + button.contentEdgeInsets = UIEdgeInsetsMake(kDefaultButtonContentInset, 0, kDefaultButtonContentInset, 0); + [[self class] _stds_configureButton:button withTitle:title customization:customization]; + + return button; +} + ++ (void)_stds_configureButton:(UIButton *)button withTitle:(NSString * _Nullable)buttonTitle customization:(STDSButtonCustomization * _Nullable)buttonCustomization { + button.backgroundColor = buttonCustomization.backgroundColor; + button.layer.cornerRadius = buttonCustomization.cornerRadius; + + UIFont *font = buttonCustomization.font; + UIColor *textColor = buttonCustomization.textColor; + + if (buttonTitle != nil) { + NSMutableDictionary *attributesDictionary = [NSMutableDictionary dictionary]; + + if (font != nil) { + attributesDictionary[NSFontAttributeName] = font; + } + + if (textColor != nil) { + attributesDictionary[NSForegroundColorAttributeName] = textColor; + } + switch (buttonCustomization.titleStyle) { + case STDSButtonTitleStyleDefault: + break; + case STDSButtonTitleStyleSentenceCapitalized: + buttonTitle = [buttonTitle localizedCapitalizedString]; + break; + case STDSButtonTitleStyleLowercase: + buttonTitle = [buttonTitle localizedLowercaseString]; + break; + case STDSButtonTitleStyleUppercase: + buttonTitle = [buttonTitle localizedUppercaseString]; + break; + } + + NSAttributedString *title = [[NSAttributedString alloc] initWithString:buttonTitle attributes:attributesDictionary]; + [button setAttributedTitle:title forState:UIControlStateNormal]; + } +} + +@end + +NS_ASSUME_NONNULL_END + +void _stds_import_uibutton_custominitialization() {} diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/UIColor+DefaultColors.h b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/UIColor+DefaultColors.h new file mode 100644 index 0000000..0f7e643 --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/UIColor+DefaultColors.h @@ -0,0 +1,23 @@ +// +// UIColor+DefaultColors.h +// Stripe3DS2 +// +// Created by Andrew Harrison on 3/18/19. +// Copyright © 2019 Stripe. All rights reserved. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface UIColor (DefaultColors) + +/// The challenge view footer background color ++ (UIColor *)_stds_defaultFooterBackgroundColor; ++ (UIColor *)_stds_blueColor; + +@end + +NS_ASSUME_NONNULL_END + +void _stds_import_uicolor_defaultcolors(void); diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/UIColor+DefaultColors.m b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/UIColor+DefaultColors.m new file mode 100644 index 0000000..53a7362 --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/UIColor+DefaultColors.m @@ -0,0 +1,33 @@ +// +// UIColor+DefaultColors.m +// Stripe3DS2 +// +// Created by Andrew Harrison on 3/18/19. +// Copyright © 2019 Stripe. All rights reserved. +// + +#import "UIColor+DefaultColors.h" +#import "UIColor+ThirteenSupport.h" + +@implementation UIColor (DefaultColors) + ++ (UIColor *)_stds_defaultFooterBackgroundColor { + return [UIColor _stds_systemGray5Color]; +} + ++ (UIColor *)_stds_blueColor { + if (@available(iOS 12.0, *)) { + return [UIColor _stds_colorWithDynamicProvider:^UIColor * _Nonnull(UITraitCollection * _Nonnull traitCollection) { + return (traitCollection.userInterfaceStyle == UIUserInterfaceStyleLight) ? [UIColor colorWithRed:(CGFloat)(29.0 / 255.0) green:(CGFloat)(115.0 / 255.0) blue:(CGFloat)(250.0 / 255.0) alpha:1.0] : [UIColor colorWithRed:(CGFloat)(39.0 / 255.0) green:(CGFloat)(125.0 / 255.0) blue:(CGFloat)(255.0 / 255.0) alpha:1.0]; + }]; + } else { + CGFloat redValue = (CGFloat)29.0 / (CGFloat)255.0; + CGFloat greenValue = (CGFloat)115.0 / (CGFloat)255.0; + CGFloat blueValue = (CGFloat)250.0 / (CGFloat)255.0; + return [UIColor colorWithRed:redValue green:greenValue blue:blueValue alpha:1.0]; + } +} + +@end + +void _stds_import_uicolor_defaultcolors() { } diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/UIColor+ThirteenSupport.h b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/UIColor+ThirteenSupport.h new file mode 100644 index 0000000..9d77a5e --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/UIColor+ThirteenSupport.h @@ -0,0 +1,26 @@ +// +// UIColor+ThirteenSupport.h +// Stripe3DS2 +// +// Created by David Estes on 8/21/19. +// Copyright © 2019 Stripe. All rights reserved. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface UIColor (STDSThirteenSupport) + ++ (UIColor *)_stds_colorWithDynamicProvider:(UIColor * _Nonnull (^)(UITraitCollection *traitCollection))dynamicProvider; ++ (UIColor *)_stds_systemGray5Color; ++ (UIColor *)_stds_systemGray2Color; ++ (UIColor *)_stds_systemBackgroundColor; ++ (UIColor *)_stds_labelColor; + + +@end + +NS_ASSUME_NONNULL_END + +void _stds_import_uicolor_thirteensupport(void); diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/UIColor+ThirteenSupport.m b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/UIColor+ThirteenSupport.m new file mode 100644 index 0000000..a0e43a2 --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/UIColor+ThirteenSupport.m @@ -0,0 +1,55 @@ +// +// UIColor+ThirteenSupport.m +// Stripe3DS2 +// +// Created by David Estes on 8/21/19. +// Copyright © 2019 Stripe. All rights reserved. +// + +#import "UIColor+ThirteenSupport.h" + +@implementation UIColor (STDSThirteenSupport) + ++ (UIColor *)_stds_colorWithDynamicProvider:(UIColor * _Nonnull (^)(UITraitCollection *traitCollection))dynamicProvider { + if (@available(iOS 13.0, *)) { + return [UIColor colorWithDynamicProvider:dynamicProvider]; + } else { + return dynamicProvider([[UITraitCollection alloc] init]); + } +} + ++ (UIColor *)_stds_systemGray5Color { + if (@available(iOS 13.0, *)) { + return [UIColor systemGray5Color]; + } else { + return [UIColor colorWithRed:(CGFloat)229.0/(CGFloat)255.0 green:(CGFloat)229.0/(CGFloat)255.0 blue:(CGFloat)234.0/(CGFloat)255.0 alpha:1.0]; + } +} + ++ (UIColor *)_stds_systemGray2Color { + if (@available(iOS 13.0, *)) { + return [UIColor systemGray2Color]; + } else { + return [UIColor colorWithRed:(CGFloat)174.0/(CGFloat)255.0 green:(CGFloat)174.0/(CGFloat)255.0 blue:(CGFloat)178.0/(CGFloat)255.0 alpha:1.0]; + } +} + ++ (UIColor *)_stds_systemBackgroundColor { + if (@available(iOS 13.0, *)) { + return [UIColor systemBackgroundColor]; + } else { + return [UIColor whiteColor]; + } +} + ++ (UIColor *)_stds_labelColor { + if (@available(iOS 13.0, *)) { + return [UIColor labelColor]; + } else { + return [UIColor blackColor]; + } +} + +@end + +void _stds_import_uicolor_thirteensupport(void) {} diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/UIFont+DefaultFonts.h b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/UIFont+DefaultFonts.h new file mode 100644 index 0000000..f301ebf --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/UIFont+DefaultFonts.h @@ -0,0 +1,25 @@ +// +// UIFont+DefaultFonts.h +// Stripe3DS2 +// +// Created by Andrew Harrison on 3/18/19. +// Copyright © 2019 Stripe. All rights reserved. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface UIFont (DefaultFonts) + ++ (UIFont *)_stds_defaultHeadingTextFont; + ++ (UIFont *)_stds_defaultLabelTextFontWithScale:(CGFloat)scale; ++ (UIFont *)_stds_defaultButtonTextFontWithScale:(CGFloat)scale; ++ (UIFont *)_stds_defaultBoldLabelTextFontWithScale:(CGFloat)scale; + +@end + +NS_ASSUME_NONNULL_END + +void _stds_import_uifont_defaultfonts(void); diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/UIFont+DefaultFonts.m b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/UIFont+DefaultFonts.m new file mode 100644 index 0000000..e8ebf3a --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/UIFont+DefaultFonts.m @@ -0,0 +1,43 @@ +// +// UIFont+DefaultFonts.m +// Stripe3DS2 +// +// Created by Andrew Harrison on 3/18/19. +// Copyright © 2019 Stripe. All rights reserved. +// + +#import "UIFont+DefaultFonts.h" + +NS_ASSUME_NONNULL_BEGIN + +@implementation UIFont (DefaultFonts) + ++ (UIFont *)_stds_defaultHeadingTextFont { + UIFontDescriptor *fontDescriptor = [[UIFontDescriptor preferredFontDescriptorWithTextStyle:UIFontTextStyleHeadline] fontDescriptorWithSymbolicTraits:UIFontDescriptorTraitBold]; + + return [UIFont fontWithDescriptor:fontDescriptor size:fontDescriptor.pointSize * (CGFloat)1.1]; +} + ++ (UIFont *)_stds_defaultLabelTextFontWithScale:(CGFloat)scale { + UIFontDescriptor *fontDescriptor = [UIFontDescriptor preferredFontDescriptorWithTextStyle:UIFontTextStyleBody]; + + return [UIFont fontWithDescriptor:fontDescriptor size:fontDescriptor.pointSize * scale]; +} + ++ (UIFont *)_stds_defaultBoldLabelTextFontWithScale:(CGFloat)scale { + UIFontDescriptor *fontDescriptor = [[UIFontDescriptor preferredFontDescriptorWithTextStyle:UIFontTextStyleBody] fontDescriptorWithSymbolicTraits:UIFontDescriptorTraitBold]; + + return [UIFont fontWithDescriptor:fontDescriptor size:fontDescriptor.pointSize * scale]; +} + ++ (UIFont *)_stds_defaultButtonTextFontWithScale:(CGFloat)scale { + UIFontDescriptor *fontDescriptor = [UIFontDescriptor preferredFontDescriptorWithTextStyle:UIFontTextStyleHeadline]; + + return [UIFont fontWithDescriptor:fontDescriptor size:fontDescriptor.pointSize * scale]; +} + +@end + +NS_ASSUME_NONNULL_END + +void _stds_import_uifont_defaultfonts() {} diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/UIView+LayoutSupport.h b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/UIView+LayoutSupport.h new file mode 100644 index 0000000..ea49bb1 --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/UIView+LayoutSupport.h @@ -0,0 +1,26 @@ +// +// UIView+LayoutSupport.h +// Stripe3DS2 +// +// Created by Andrew Harrison on 2/27/19. +// Copyright © 2019 Stripe. All rights reserved. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface UIView (LayoutSupport) + +/** + Pins the view to its superview's bounds. + */ +- (void)_stds_pinToSuperviewBounds; + +- (void)_stds_pinToSuperviewBoundsWithoutMargin; + +@end + +NS_ASSUME_NONNULL_END + +void _stds_import_uiview_layoutsupport(void); diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/UIView+LayoutSupport.m b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/UIView+LayoutSupport.m new file mode 100644 index 0000000..fc774a6 --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/UIView+LayoutSupport.m @@ -0,0 +1,41 @@ +// +// UIView+LayoutSupport.m +// Stripe3DS2 +// +// Created by Andrew Harrison on 2/27/19. +// Copyright © 2019 Stripe. All rights reserved. +// + +#import "UIView+LayoutSupport.h" + +@implementation UIView (LayoutSupport) + +- (void)_stds_pinToSuperviewBounds { + self.translatesAutoresizingMaskIntoConstraints = false; + + NSLayoutConstraint *topConstraint = [NSLayoutConstraint constraintWithItem:self attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self.superview attribute:NSLayoutAttributeTopMargin multiplier:1 constant:0]; + NSLayoutConstraint *bottomConstraint = [NSLayoutConstraint constraintWithItem:self attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:self.superview attribute:NSLayoutAttributeBottomMargin multiplier:1 constant:0]; + NSLayoutConstraint *leftConstraint = [NSLayoutConstraint constraintWithItem:self attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:self.superview attribute:NSLayoutAttributeLeftMargin multiplier:1 constant:0]; + NSLayoutConstraint *rightConstraint = [NSLayoutConstraint constraintWithItem:self attribute:NSLayoutAttributeRight relatedBy:NSLayoutRelationEqual toItem:self.superview attribute:NSLayoutAttributeRightMargin multiplier:1 constant:0]; + + [NSLayoutConstraint activateConstraints:@[topConstraint, bottomConstraint, leftConstraint, rightConstraint]]; +} + +- (void)_stds_pinToSuperviewBoundsWithoutMargin { + self.translatesAutoresizingMaskIntoConstraints = false; + + NSLayoutConstraint *topConstraint = [NSLayoutConstraint constraintWithItem:self attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self.superview attribute:NSLayoutAttributeTop multiplier:1 constant:0]; + NSLayoutConstraint *bottomConstraint = [NSLayoutConstraint constraintWithItem:self attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:self.superview attribute:NSLayoutAttributeBottom multiplier:1 constant:0]; + NSLayoutConstraint *leftConstraint = [NSLayoutConstraint constraintWithItem:self attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:self.superview attribute:NSLayoutAttributeLeft multiplier:1 constant:0]; + NSLayoutConstraint *rightConstraint = [NSLayoutConstraint constraintWithItem:self attribute:NSLayoutAttributeRight relatedBy:NSLayoutRelationEqual toItem:self.superview attribute:NSLayoutAttributeRight multiplier:1 constant:0]; + + [NSLayoutConstraint activateConstraints:@[topConstraint, bottomConstraint, leftConstraint, rightConstraint]]; +} + ++ (void)_stds_linkCategory { + +} + +@end + +void _stds_import_uiview_layoutsupport() {} diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/UIViewController+Stripe3DS2.h b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/UIViewController+Stripe3DS2.h new file mode 100644 index 0000000..aab130c --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/UIViewController+Stripe3DS2.h @@ -0,0 +1,23 @@ +// +// UIViewController+Stripe3DS2.h +// Stripe3DS2 +// +// Created by Yuki Tokuhiro on 5/6/19. +// Copyright © 2019 Stripe. All rights reserved. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +@class STDSUICustomization; + +@interface UIViewController (Stripe3DS2) + +- (void)_stds_setupNavigationBarElementsWithCustomization:(STDSUICustomization *)customization cancelButtonSelector:(SEL)cancelButtonSelector; + +@end + +NS_ASSUME_NONNULL_END + +void _stds_import_uiviewcontroller_stripe3ds2(void); diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/UIViewController+Stripe3DS2.m b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/UIViewController+Stripe3DS2.m new file mode 100644 index 0000000..11e5421 --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/UIViewController+Stripe3DS2.m @@ -0,0 +1,51 @@ +// +// UIViewController+Stripe3DS2.m +// Stripe3DS2 +// +// Created by Yuki Tokuhiro on 5/6/19. +// Copyright © 2019 Stripe. All rights reserved. +// + +#import "UIViewController+Stripe3DS2.h" + +#import "UIButton+CustomInitialization.h" +#import "STDSUICustomization.h" + +@implementation UIViewController (Stripe3DS2) + +- (void)_stds_setupNavigationBarElementsWithCustomization:(STDSUICustomization *)customization cancelButtonSelector:(SEL)cancelButtonSelector { + STDSNavigationBarCustomization *navigationBarCustomization = customization.navigationBarCustomization; + + self.navigationController.navigationBar.barStyle = customization.navigationBarCustomization.barStyle; + + // Cancel button + STDSButtonCustomization *cancelButtonCustomization = [customization buttonCustomizationForButtonType:STDSUICustomizationButtonTypeCancel]; + UIButton *cancelButton = [UIButton _stds_buttonWithTitle:navigationBarCustomization.buttonText customization:cancelButtonCustomization]; + // The cancel button's frame has a size of 0 in iOS 8 + cancelButton.frame = CGRectMake(0, 0, cancelButton.intrinsicContentSize.width, cancelButton.intrinsicContentSize.height); + cancelButton.accessibilityIdentifier = @"Cancel"; + [cancelButton addTarget:self action:cancelButtonSelector forControlEvents:UIControlEventTouchUpInside]; + UIBarButtonItem *cancelBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:cancelButton]; + self.navigationItem.rightBarButtonItem = cancelBarButtonItem; + + // Title + self.title = navigationBarCustomization.headerText; + NSMutableDictionary *titleTextAttributes = [NSMutableDictionary dictionary]; + UIFont *headerFont = navigationBarCustomization.font; + if (headerFont) { + titleTextAttributes[NSFontAttributeName] = headerFont; + } + UIColor *headerColor = navigationBarCustomization.textColor; + if (headerColor) { + titleTextAttributes[NSForegroundColorAttributeName] = headerColor; + } + self.navigationController.navigationBar.titleTextAttributes = titleTextAttributes; + + // Color + self.navigationController.navigationBar.barTintColor = navigationBarCustomization.barTintColor; + self.navigationController.navigationBar.translucent = navigationBarCustomization.translucent; +} + +@end + +void _stds_import_uiviewcontroller_stripe3ds2() {} diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/include/STDSAlreadyInitializedException.h b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/include/STDSAlreadyInitializedException.h new file mode 100644 index 0000000..c39a85d --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/include/STDSAlreadyInitializedException.h @@ -0,0 +1,22 @@ +// +// STDSAlreadyInitializedException.h +// Stripe3DS2 +// +// Created by Cameron Sabol on 1/22/19. +// Copyright © 2019 Stripe. All rights reserved. +// + +#import "STDSException.h" + +NS_ASSUME_NONNULL_BEGIN + +/** + `STDSAlreadyInitializedException` represents an exception that will be thrown in the `STDSThreeDS2Service` instance has already been initialized. + + @see STDSThreeDS2Service + */ +@interface STDSAlreadyInitializedException : STDSException + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/include/STDSAuthenticationRequestParameters.h b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/include/STDSAuthenticationRequestParameters.h new file mode 100644 index 0000000..766e485 --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/include/STDSAuthenticationRequestParameters.h @@ -0,0 +1,68 @@ +// +// STDSAuthenticationRequestParameters.h +// Stripe3DS2 +// +// Created by Yuki Tokuhiro on 3/21/19. +// Copyright © 2019 Stripe. All rights reserved. +// + +#import + +#import "STDSJSONEncodable.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface STDSAuthenticationRequestParameters : NSObject + +/** + Designated initializer for `STDSAuthenticationRequestParameters`. + + @param sdkTransactionIdentifier The SDK Transaction Identifier, as created by `[STDSTransaction createTransaction]` + @param deviceData Optional device data collected by the SDK. + @param sdkEphemeralPublicKey The SDK ephemeral public key. + @param sdkAppIdentifier The SDK app identifier. + @param sdkReferenceNumber The SDK reference number. + @param messageVersion The protocol version that is supported by the SDK and used for the transaction. + + @exception InvalidInputException Thrown if an input parameter is invalid. @see InvalidInputException + */ +- (instancetype)initWithSDKTransactionIdentifier:(NSString *)sdkTransactionIdentifier + deviceData:(nullable NSString *)deviceData + sdkEphemeralPublicKey:(NSString *)sdkEphemeralPublicKey + sdkAppIdentifier:(NSString *)sdkAppIdentifier + sdkReferenceNumber:(NSString *)sdkReferenceNumber + messageVersion:(NSString *)messageVersion; + +/** + The encrypted device data as a JWE string. + */ +@property (nonatomic, readonly, nullable) NSString *deviceData; + +/** + The SDK Transaction Identifier. + */ +@property (nonatomic, readonly) NSString *sdkTransactionIdentifier; + +/** + The SDK App Identifier. + */ +@property (nonatomic, readonly) NSString *sdkAppIdentifier; + +/** + The SDK reference number. + */ +@property (nonatomic, readonly) NSString *sdkReferenceNumber; + +/** + The SDK ephemeral public key. + */ +@property (nonatomic, readonly) NSString *sdkEphemeralPublicKey; + +/** + The protocol version that is used for the transaction. + */ +@property (nonatomic, readonly) NSString *messageVersion; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/include/STDSAuthenticationResponse.h b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/include/STDSAuthenticationResponse.h new file mode 100644 index 0000000..d527f38 --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/include/STDSAuthenticationResponse.h @@ -0,0 +1,115 @@ +// +// STDSAuthenticationResponse.h +// Stripe3DS2 +// +// Created by Cameron Sabol on 2/13/19. +// Copyright © 2019 Stripe. All rights reserved. +// + +#import + +#import "STDSJSONDecodable.h" + +NS_ASSUME_NONNULL_BEGIN + +/** + The `STDSACSStatusType` enum defines the status of a transaction, as detailed in + 3DS2 Spec Seq 3.33: + */ +typedef NS_ENUM(NSInteger, STDSACSStatusType) { + /// The status is unknown or invalid + STDSACSStatusTypeUnknown = 0, + + /// Authenticated + STDSACSStatusTypeAuthenticated = 1, + + /// Requires a Cardholder challenge to complete authentication + STDSACSStatusTypeChallengeRequired = 2, + + /// Requires a Cardholder challenge using Decoupled Authentication + STDSACSStatusTypeDecoupledAuthentication = 3, + + /// Not authenticated + STDSACSStatusTypeNotAuthenticated = 4, + + /// Not authenticated, but a proof of authentication attempt (Authentication Value) + /// was generated + STDSACSStatusTypeProofGenerated = 5, + + /// Not authenticated, as authentication could not be performed due to technical or + /// other issue + STDSACSStatusTypeError = 6, + + /// Not authenticated because the Issuer is rejecting authentication and requesting + /// that authorisation not be attempted + STDSACSStatusTypeRejected = 7, + + /// Authentication not requested by the 3DS Server for data sent for informational + /// purposes only + STDSACSStatusTypeInformationalOnly = 8, +}; + +/** + A native protocol representing the response sent by the 3DS Server. + Only parameters relevant to performing 3DS2 authentication in the mobile SDK are exposed. + */ +@protocol STDSAuthenticationResponse + +/// Universally unique transaction identifier assigned by the 3DS Server to identify a single transaction. +@property (nonatomic, readonly) NSString *threeDSServerTransactionID; + +/// Transaction status +@property (nonatomic, readonly) STDSACSStatusType status; + +/// Indication of whether a challenge is required. +@property (nonatomic, readonly, getter=isChallengeRequired) BOOL challengeRequired; + +/// Indicates whether the ACS confirms utilisation of Decoupled Authentication and agrees to utilise Decoupled Authentication to authenticate the Cardholder. +@property (nonatomic, readonly) BOOL willUseDecoupledAuthentication; + +/** + DS assigned ACS identifier. + Each DS can provide a unique ID to each ACS on an individual basis. + */ +@property (nonatomic, readonly, nullable) NSString *acsOperatorID; + +/// Unique identifier assigned by the EMVCo Secretariat upon Testing and Approval. +@property (nonatomic, readonly, nullable) NSString *acsReferenceNumber; + +/// Contains the JWS object (represented as a string) created by the ACS for the ARes message. +@property (nonatomic, readonly, nullable) NSString *acsSignedContent; + +/// Universally Unique transaction identifier assigned by the ACS to identify a single transaction. +@property (nonatomic, readonly) NSString *acsTransactionID; + +/// Fully qualified URL of the ACS to be used for the challenge. +@property (nonatomic, readonly, nullable) NSURL *acsURL; + +/** + Text provided by the ACS/Issuer to Cardholder during a Frictionless or Decoupled transaction. The Issuer can provide information to Cardholder. + For example, “Additional authentication is needed for this transaction, please contact (Issuer Name) at xxx-xxx-xxxx.” + */ +@property (nonatomic, readonly, nullable) NSString *cardholderInfo; + +/// EMVCo-assigned unique identifier to track approved DS. +@property (nonatomic, readonly, nullable) NSString *directoryServerReferenceNumber; + +/// Universally unique transaction identifier assigned by the DS to identify a single transaction. +@property (nonatomic, readonly, nullable) NSString *directoryServerTransactionID; + +/** + Protocol version identifier This shall be the Protocol Version Number of the specification utilised by the system creating this message. + The Message Version Number is set by the 3DS Server which originates the protocol with the AReq message. + The Message Version Number does not change during a 3DS transaction. + */ +@property (nonatomic, readonly) NSString *protocolVersion; + +/// Universally unique transaction identifier assigned by the 3DS SDK to identify a single transaction. +@property (nonatomic, readonly) NSString *sdkTransactionID; + +@end + +/// A utility to parse an STDSAuthenticationResponse from JSON +id _Nullable STDSAuthenticationResponseFromJSON(NSDictionary *json); + +NS_ASSUME_NONNULL_END diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/include/STDSButtonCustomization.h b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/include/STDSButtonCustomization.h new file mode 100644 index 0000000..dd63f98 --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/include/STDSButtonCustomization.h @@ -0,0 +1,83 @@ +// +// STDSButtonCustomization.h +// Stripe3DS2 +// +// Created by Andrew Harrison on 3/14/19. +// Copyright © 2019 Stripe. All rights reserved. +// +#import +#import + +#import "STDSCustomization.h" + +/// An enum that defines the different types of buttons that are able to be customized. +typedef NS_ENUM(NSInteger, STDSUICustomizationButtonType) { + + /// The submit button type. + STDSUICustomizationButtonTypeSubmit = 0, + + /// The continue button type. + STDSUICustomizationButtonTypeContinue = 1, + + /// The next button type. + STDSUICustomizationButtonTypeNext = 2, + + /// The cancel button type. + STDSUICustomizationButtonTypeCancel = 3, + + /// The resend button type. + STDSUICustomizationButtonTypeResend = 4, +}; + +/// An enumeration of the case transformations that can be applied to the button's title +typedef NS_ENUM(NSInteger, STDSButtonTitleStyle) { + /// Default style, doesn't modify the title + STDSButtonTitleStyleDefault, + + /// Applies localizedUppercaseString to the title + STDSButtonTitleStyleUppercase, + + /// Applies localizedLowercaseString to the title + STDSButtonTitleStyleLowercase, + + /// Applies localizedCapitalizedString to the title + STDSButtonTitleStyleSentenceCapitalized, +}; + +NS_ASSUME_NONNULL_BEGIN + +/// A customization object to use to configure the UI of a button. +@interface STDSButtonCustomization: STDSCustomization + +/// The default settings for the provided button type. ++ (instancetype)defaultSettingsForButtonType:(STDSUICustomizationButtonType)type; + +/** + Initializes an instance of STDSButtonCustomization with the given backgroundColor and colorRadius. + */ +- (instancetype)initWithBackgroundColor:(UIColor *)backgroundColor cornerRadius:(CGFloat)cornerRadius; + +/** + This is unavailable because there are no sensible default property values without a button type. + Use `defaultSettingsForButtonType:` or `initWithBackgroundColor:cornerRadius:` instead. + */ +- (instancetype)init NS_UNAVAILABLE; + +/** + The background color of the button. + The default for .resend and .cancel is clear. + The default for .submit, .continue, and .next is blue. + */ +@property (nonatomic) UIColor *backgroundColor; + +/// The corner radius of the button. Defaults to 8. +@property (nonatomic) CGFloat cornerRadius; + +/** + The capitalization style of the button title + */ +@property (nonatomic) STDSButtonTitleStyle titleStyle; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/include/STDSChallengeParameters.h b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/include/STDSChallengeParameters.h new file mode 100644 index 0000000..e1aa151 --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/include/STDSChallengeParameters.h @@ -0,0 +1,61 @@ +// +// STDSChallengeParameters.h +// Stripe3DS2 +// +// Created by Cameron Sabol on 2/13/19. +// Copyright © 2019 Stripe. All rights reserved. +// + +#import + +@protocol STDSAuthenticationResponse; + +NS_ASSUME_NONNULL_BEGIN + +/** + `STDSChallengeParameters` contains information from the 3DS Server's + authentication response that are used by the 3DS2 SDK to initiate + the challenge flow. + */ +@interface STDSChallengeParameters : NSObject + +/** + Convenience intiializer to create an instace of `STDSChallengeParameters` from an + `STDSAuthenticationResponse` + */ +- (instancetype)initWithAuthenticationResponse:(id)authResponse; + +/** + Transaction identifier assigned by the 3DS Server to uniquely identify + a transaction. + */ +@property (nonatomic, copy) NSString *threeDSServerTransactionID; + +/** + Transaction identifier assigned by the Access Control Server (ACS) + to uniquely identify a transaction. + */ +@property (nonatomic, copy) NSString *acsTransactionID; + +/** + The reference number of the relevant Access Control Server. + */ +@property (nonatomic, copy) NSString *acsReferenceNumber; + +/** + The encrypted message sent by the Access Control Server + containing the ACS URL, epthemeral public key, and the + 3DS2 SDK ephemeral public key. + */ +@property (nonatomic, copy) NSString *acsSignedContent; + +/** + The URL for the application that is requesting 3DS2 verification. + This property can be optionally set and will be included with the + messages sent to the Directory Server during the challenge flow. + */ +@property (nonatomic, copy, nullable) NSString *threeDSRequestorAppURL; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/include/STDSChallengeStatusReceiver.h b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/include/STDSChallengeStatusReceiver.h new file mode 100644 index 0000000..a352e0c --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/include/STDSChallengeStatusReceiver.h @@ -0,0 +1,67 @@ +// +// STDSChallengeStatusReceiver.h +// Stripe3DS2 +// +// Created by Yuki Tokuhiro on 3/20/19. +// Copyright © 2019 Stripe. All rights reserved. +// + +#import +#import + +@class STDSTransaction, STDSCompletionEvent, STDSRuntimeErrorEvent, STDSProtocolErrorEvent; + +NS_ASSUME_NONNULL_BEGIN + +/** + Implement the `STDSChallengeStatusReceiver` protocol to receive challenge status notifications at the end of the challenge process. + @see `STDSTransaction.doChallenge` + */ +@protocol STDSChallengeStatusReceiver + +/** + Called when the challenge process is completed. + + @param completionEvent Information about the completion of the challenge process. @see `STDSCompletionEvent` + */ +- (void)transaction:(STDSTransaction *)transaction didCompleteChallengeWithCompletionEvent:(STDSCompletionEvent *)completionEvent; + +/** + Called when the user selects the option to cancel the transaction on the challenge screen. + */ +- (void)transactionDidCancel:(STDSTransaction *)transaction; + +/** + Called when the challenge process reaches or exceeds the timeout interval that was passed to `STDSTransaction.doChallenge` + */ +- (void)transactionDidTimeOut:(STDSTransaction *)transaction; + +/** + Called when the 3DS SDK receives an EMV 3-D Secure protocol-defined error message from the ACS. + + @param protocolErrorEvent The error code and details. @see `STDSProtocolErrorEvent` + */ +- (void)transaction:(STDSTransaction *)transaction didErrorWithProtocolErrorEvent:(STDSProtocolErrorEvent *)protocolErrorEvent; + +/** + Called when the 3DS SDK encounters errors during the challenge process. These errors include all errors except those covered by `didErrorWithProtocolErrorEvent`. + + @param runtimeErrorEvent The error code and details. @see `STDSRuntimeErrorEvent` + */ +- (void)transaction:(STDSTransaction *)transaction didErrorWithRuntimeErrorEvent:(STDSRuntimeErrorEvent *)runtimeErrorEvent; + +@optional + +/** + Optional method that will be called when the transaction displays a new challenge screen. + */ +- (void)transactionDidPresentChallengeScreen:(STDSTransaction *)transaction; + +/** + Optional method for custom dismissal of the challenge view controller. Meant only for internal use by Stripe SDK. + */ +- (void)dismissChallengeViewController:(UIViewController *)challengeViewController forTransaction:(STDSTransaction *)transaction; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/include/STDSCompletionEvent.h b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/include/STDSCompletionEvent.h new file mode 100644 index 0000000..851c71d --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/include/STDSCompletionEvent.h @@ -0,0 +1,40 @@ +// +// STDSCompletionEvent.h +// Stripe3DS2 +// +// Created by Yuki Tokuhiro on 3/20/19. +// Copyright © 2019 Stripe. All rights reserved. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +/** + `STDSCompletionEvent` contains information about completion of the challenge process. + */ +@interface STDSCompletionEvent : NSObject + +/** + Designated initializer for `STDSCompletionEvent`. + */ +- (instancetype)initWithSDKTransactionIdentifier:(NSString *)identifier transactionStatus:(NSString *)transactionStatus NS_DESIGNATED_INITIALIZER; + +/** + `STDSCompletionEvent` should not be directly initialized. + */ +- (instancetype)init NS_UNAVAILABLE; + +/** + The SDK Transaction ID. + */ +@property (nonatomic, readonly) NSString *sdkTransactionIdentifier; + +/** + The transaction status that was received in the final challenge response. + */ +@property (nonatomic, readonly) NSString *transactionStatus; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/include/STDSConfigParameters.h b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/include/STDSConfigParameters.h new file mode 100644 index 0000000..4d77ba5 --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/include/STDSConfigParameters.h @@ -0,0 +1,96 @@ +// +// STDSConfigParameters.h +// Stripe3DS2 +// +// Created by Cameron Sabol on 1/22/19. +// Copyright © 2019 Stripe. All rights reserved. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +/** + The default group name that will be used to group additional + configuration parameters. + */ +extern NSString * const kSTDSConfigDefaultGroupName; + +/** + `STDSConfigParameters` represents additional configuration parameters + that can be passed to the Stripe3DS2 SDK during initialization. + + There are currently no supported additional parameters and apps can + just pass `[STDSConfigParameters alloc] initWithStandardParameters` + to the `STDSThreeDS2Service` instance. + */ +@interface STDSConfigParameters : NSObject + +/** + Convenience initializer to get an `STDSConfigParameters` instance + with the default expected configuration parameters. + */ +- (instancetype)initWithStandardParameters; + +/** + Adds the parameter to this instance. + + @param paramName The name of the parameter to add + @param paramValue The value of the parameter to add + @param paramGroup The group to which this parameter will be added. If `nil` the parameter will be added to `kSTDSConfigDefaultGroupName` + + @exception STDSInvalidInputException Will throw an `STDSInvalidInputException` if `paramName` or `paramValue` are `nil`. @see STDSInvalidInputException + */ +- (void)addParameterNamed:(NSString *)paramName withValue:(NSString *)paramValue toGroup:(nullable NSString *)paramGroup; + +/** + Adds the parameter to the default group in this instance. + + @param paramName The name of the parameter to add + @param paramValue The value of the parameter to add + + @exception STDSInvalidInputException Will throw an `STDSInvalidInputException` if `paramName` or `paramValue` are `nil`. @see STDSInvalidInputException + */ +- (void)addParameterNamed:(NSString *)paramName withValue:(NSString *)paramValue; + +/** + Returns the value for `paramName` in `paramGroup` or `nil` if the parameter value is not set. + + @param paramName The name of the parameter to return + @param paramGroup The group from which to fetch the parameter value. If `nil` will default to `kSTDSConfigDefaultGroupName` + + @exception STDSInvalidInputException Will throw an `STDSInvalidInputException` if `paramName` is `nil`. @see STDSInvalidInputException + */ +- (nullable NSString *)parameterValue:(NSString *)paramName inGroup:(nullable NSString *)paramGroup; + +/** + Returns the value for `paramName` in the default group or `nil` if the parameter value is not set. + + @param paramName The name of the parameter to return + + @exception STDSInvalidInputException Will throw an `STDSInvalidInputException` if `paramName` is `nil`. @see STDSInvalidInputException + */ +- (nullable NSString *)parameterValue:(NSString *)paramName; + +/** + Removes the specified parameter from the group and returns the value or `nil` if the parameter was not found. + + @param paramName The name of the parameter to remove + @param paramGroup The group from which to remove this parameter. If `nil` will default to `kSTDSConfigDefaultGroupName` + + @exception STDSInvalidInputException Will throw an `STDSInvalidInputException` if `paramName` is `nil`. @see STDSInvalidInputException + */ +- (nullable NSString *)removeParameterNamed:(NSString *)paramName fromGroup:(nullable NSString *)paramGroup; + +/** + Removes the specified parameter from the default group and returns the value or `nil` if the parameter was not found. + + @param paramName The name of the parameter to remove + + @exception STDSInvalidInputException Will throw an `STDSInvalidInputException` if `paramName` is `nil`. @see STDSInvalidInputException + */ +- (nullable NSString *)removeParameterNamed:(NSString *)paramName; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/include/STDSCustomization.h b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/include/STDSCustomization.h new file mode 100644 index 0000000..516eff9 --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/include/STDSCustomization.h @@ -0,0 +1,25 @@ +// +// STDSCustomization.h +// Stripe3DS2 +// +// Created by Andrew Harrison on 3/14/19. +// Copyright © 2019 Stripe. All rights reserved. +// + +#import +#import + +NS_ASSUME_NONNULL_BEGIN + +/// This class provides a common set of customization parameters, used to customize elements of the UI. +@interface STDSCustomization : NSObject + +/// The font to use for text. +@property (nonatomic, nullable) UIFont *font; + +/// The color to use for the text. +@property (nonatomic, nullable) UIColor *textColor; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/include/STDSErrorMessage.h b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/include/STDSErrorMessage.h new file mode 100644 index 0000000..29c6c5a --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/include/STDSErrorMessage.h @@ -0,0 +1,103 @@ +// +// STDSErrorMessage.h +// Stripe3DS2 +// +// Created by Yuki Tokuhiro on 3/21/19. +// Copyright © 2019 Stripe. All rights reserved. +// + +#import + +#import "STDSJSONEncodable.h" +#import "STDSJSONDecodable.h" + +NS_ASSUME_NONNULL_BEGIN + +/// Error codes as defined by the 3DS2 spec. +typedef NS_ENUM(NSInteger, STDSErrorMessageCode) { + /// The SDK received a message that is not an ARes, CRes, or ErrorMessage. + STDSErrorMessageCodeInvalidMessage = 101, + + /// A required data element is missing from the network response. + STDSErrorMessageCodeRequiredDataElementMissing = 201, + + // Critical message extension not recognised + STDSErrorMessageCodeUnrecognizedCriticalMessageExtension = 202, + + /// A data element is not in the required format or the value is invalid. + STDSErrorMessageErrorInvalidDataElement = 203, + + // Transaction ID not recognized + STDSErrorMessageErrorTransactionIDNotRecognized = 301, + + /// A network response could not be decrypted or verified. + STDSErrorMessageErrorDataDecryptionFailure = 302, + + /// The SDK timed out + STDSErrorMessageErrorTimeout = 402, +}; + +/** + `STDSErrorMessage` represents an error message that is returned by the ACS or to be sent to the ACS. + */ +@interface STDSErrorMessage : NSObject + +/** + Designated initializer for `STDSErrorMessage`. + + @param errorCode The error code. + @param errorComponent The component that identified the error. + @param errorDescription Text describing the error. + @param errorDetails Additional error details. Optional. + */ +- (instancetype)initWithErrorCode:(NSString *)errorCode + errorComponent:(NSString *)errorComponent + errorDescription:(NSString *)errorDescription + errorDetails:(nullable NSString *)errorDetails + messageVersion:(NSString *)messageVersion + acsTransactionIdentifier:(nullable NSString *)acsTransactionIdentifier + errorMessageType:(NSString *)errorMessageType; + +/** + The error code. + */ +@property (nonatomic, readonly) NSString *errorCode; + +/** + The 3-D Secure component that identified the error. + */ +@property (nonatomic, readonly) NSString *errorComponent; + +/** + Text describing the error. + */ +@property (nonatomic, readonly) NSString *errorDescription; + +/** + Additional error details. + */ +@property (nonatomic, nullable, readonly) NSString *errorDetails; + +/** + The protocol version identifier. + */ +@property (nonatomic, readonly) NSString *messageVersion; + +/** + The ACS transaction identifier. + */ +@property (nonatomic, readonly, nullable) NSString *acsTransactionIdentifier; + +/** + The message type that was identified as erroneous. + */ +@property (nonatomic, readonly, nullable) NSString *errorMessageType; + +/** + A representation of the `STDSErrorMessage` as an `NSError` + */ +- (NSError *)NSErrorValue; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/include/STDSException.h b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/include/STDSException.h new file mode 100644 index 0000000..1f2c5ec --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/include/STDSException.h @@ -0,0 +1,25 @@ +// +// STDSException.h +// Stripe3DS2 +// +// Created by Cameron Sabol on 1/22/19. +// Copyright © 2019 Stripe. All rights reserved. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +/** + An abstract class to represent 3DS2 SDK custom exceptions + */ +@interface STDSException : NSException + +/** + A description of the exception. + */ +@property (nonatomic, readonly) NSString *message; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/include/STDSFooterCustomization.h b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/include/STDSFooterCustomization.h new file mode 100644 index 0000000..990ffd9 --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/include/STDSFooterCustomization.h @@ -0,0 +1,41 @@ +// +// STDSFooterCustomization.h +// Stripe3DS2 +// +// Created by Yuki Tokuhiro on 6/10/19. +// Copyright © 2019 Stripe. All rights reserved. +// + +#import + +#import "STDSCustomization.h" + +NS_ASSUME_NONNULL_BEGIN + +/** + The Challenge view displays a footer with additional details that + expand when tapped. This object configures the appearance of that view. +*/ +@interface STDSFooterCustomization : STDSCustomization + +/// The default settings. ++ (instancetype)defaultSettings; + +/** + The background color of the footer. + Defaults to gray. + */ +@property (nonatomic) UIColor *backgroundColor; + +/// The color of the chevron. Defaults to a dark gray. +@property (nonatomic) UIColor *chevronColor; + +/// The color of the heading text. Defaults to black. +@property (nonatomic) UIColor *headingTextColor; + +/// The font to use for the heading text. +@property (nonatomic) UIFont *headingFont; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/include/STDSInvalidInputException.h b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/include/STDSInvalidInputException.h new file mode 100644 index 0000000..b30d4e1 --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/include/STDSInvalidInputException.h @@ -0,0 +1,21 @@ +// +// STDSInvalidInputException.h +// Stripe3DS2 +// +// Created by Cameron Sabol on 1/22/19. +// Copyright © 2019 Stripe. All rights reserved. +// + +#import "STDSException.h" + +NS_ASSUME_NONNULL_BEGIN + +/** + `STDSInvalidInputException` represents an exception that will be thrown by + Stripe3DS2 SDK methods that are called with invalid input arguments. + */ +@interface STDSInvalidInputException : STDSException + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/include/STDSJSONDecodable.h b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/include/STDSJSONDecodable.h new file mode 100644 index 0000000..f93428a --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/include/STDSJSONDecodable.h @@ -0,0 +1,33 @@ +// +// STDSJSONDecodable.h +// Stripe3DS2 +// +// Created by Yuki Tokuhiro on 3/27/19. +// Copyright © 2019 Stripe. All rights reserved. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +@protocol STDSJSONDecodable + +/** + Initializes an instance of the class from its JSON representation. + + This method recognizes two categories of errors: + - a required field is missing. + - a required field value is in valid (e.g. expected 'Y' or 'N' but received 'X'). + + Errors populating optional fields are ignored. + + @param json The JSON dictionary that represents an object of this type + @param outError If there was a missing required field or invalid field value, contains an instance of NSError. + + @return The object represented by the JSON dictionary. If the object could not be decoded, returns nil and populates the outError argument. + */ ++ (nullable instancetype)decodedObjectFromJSON:(nullable NSDictionary *)json error:(NSError **)outError; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/include/STDSJSONEncodable.h b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/include/STDSJSONEncodable.h new file mode 100644 index 0000000..9861a23 --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/include/STDSJSONEncodable.h @@ -0,0 +1,22 @@ +// +// STDSJSONEncodable.h +// Stripe3DS2 +// +// Created by Yuki Tokuhiro on 3/25/19. +// Copyright © 2019 Stripe. All rights reserved. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +@protocol STDSJSONEncodable + +/** + Returns a map of property names to their JSON representation's key value. For example, `STDSChallengeParameters` has a property called `acsTransactionID`, but the 3DS2 JSON spec expects a field called `acsTransID`. This dictionary represents a mapping from the former to the latter (in other words, [STDSChallengeParameters propertyNamesToJSONKeysMapping][@"acsTransactionID"] == @"acsTransID".) + */ ++ (NSDictionary *)propertyNamesToJSONKeysMapping; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/include/STDSJSONEncoder.h b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/include/STDSJSONEncoder.h new file mode 100644 index 0000000..7ccc07e --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/include/STDSJSONEncoder.h @@ -0,0 +1,27 @@ +// +// STDSJSONEncoder.h +// Stripe3DS2 +// +// Created by Yuki Tokuhiro on 3/25/19. +// Copyright © 2019 Stripe. All rights reserved. +// + +#import + +#import "STDSJSONEncodable.h" + +NS_ASSUME_NONNULL_BEGIN + +/** + `STDSJSONEncoder` is a utility class to help with converting API objects into JSON + */ +@interface STDSJSONEncoder : NSObject + +/** + Method to convert an STDSJSONEncodable object into a JSON dictionary. + */ ++ (NSDictionary *)dictionaryForObject:(NSObject *)object; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/include/STDSLabelCustomization.h b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/include/STDSLabelCustomization.h new file mode 100644 index 0000000..af75cf3 --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/include/STDSLabelCustomization.h @@ -0,0 +1,31 @@ +// +// STDSLabelCustomization.h +// Stripe3DS2 +// +// Created by Andrew Harrison on 3/14/19. +// Copyright © 2019 Stripe. All rights reserved. +// + +#import "STDSCustomization.h" + +NS_ASSUME_NONNULL_BEGIN + +/** + A customization object to use to configure the UI of a text label. + + The font and textColor inherited from `STDSCustomization` configure non-heading labels. + */ +@interface STDSLabelCustomization : STDSCustomization + +/// The default settings. ++ (instancetype)defaultSettings; + +/// The color of the heading text. Defaults to black. +@property (nonatomic) UIColor *headingTextColor; + +/// The font to use for the heading text. +@property (nonatomic) UIFont *headingFont; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/include/STDSNavigationBarCustomization.h b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/include/STDSNavigationBarCustomization.h new file mode 100644 index 0000000..18affaa --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/include/STDSNavigationBarCustomization.h @@ -0,0 +1,59 @@ +// +// STDSNavigationBarCustomization.h +// Stripe3DS2 +// +// Created by Andrew Harrison on 3/14/19. +// Copyright © 2019 Stripe. All rights reserved. +// + +#import +#import + +#import "STDSCustomization.h" + +NS_ASSUME_NONNULL_BEGIN + +/** + A customization object to use to configure a UINavigationBar. + + The font and textColor inherited from `STDSCustomization` configure the + title of the navigation bar, and default to nil. + */ +@interface STDSNavigationBarCustomization : STDSCustomization + +/// The default settings. ++ (instancetype)defaultSettings; + +/** + The tint color of the navigation bar background. + Defaults to nil. + */ +@property (nonatomic, nullable) UIColor *barTintColor; + +/** + The navigation bar style. + Defaults to UIBarStyleDefault. + */ +@property (nonatomic) UIBarStyle barStyle; + +/** + A Boolean value indicating whether the navigation bar is translucent or not. + Defaults to YES. + */ +@property (nonatomic) BOOL translucent; + +/** + The text to display in the title of the navigation bar. + Defaults to "Secure checkout". + */ +@property (nonatomic, copy) NSString *headerText; + +/** + The text to display for the button in the navigation bar. + Defaults to "Cancel". + */ +@property (nonatomic, copy) NSString *buttonText; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/include/STDSNotInitializedException.h b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/include/STDSNotInitializedException.h new file mode 100644 index 0000000..cb836d5 --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/include/STDSNotInitializedException.h @@ -0,0 +1,23 @@ +// +// STDSNotInitializedException.h +// Stripe3DS2 +// +// Created by Cameron Sabol on 2/13/19. +// Copyright © 2019 Stripe. All rights reserved. +// + +#import "STDSException.h" + +NS_ASSUME_NONNULL_BEGIN + +/** + `STDSNotInitializedException` represents an exception that will be thrown by + the the Stripe3DS2 SDK if methods are called without initializing `STDSThreeDS2Service`. + + @see STDSThreeDS2Service + */ +@interface STDSNotInitializedException : STDSException + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/include/STDSProtocolErrorEvent.h b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/include/STDSProtocolErrorEvent.h new file mode 100644 index 0000000..1e3142a --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/include/STDSProtocolErrorEvent.h @@ -0,0 +1,42 @@ +// +// STDSProtocolErrorEvent.h +// Stripe3DS2 +// +// Created by Yuki Tokuhiro on 3/20/19. +// Copyright © 2019 Stripe. All rights reserved. +// + +#import + +@class STDSErrorMessage; + +NS_ASSUME_NONNULL_BEGIN + +/** + `STDSProtocolErrorEvent` contains details about erorrs received from or sent to the ACS. + */ +@interface STDSProtocolErrorEvent : NSObject + +/** + Designated initializer for `STDSProtocolErrorEvent`. + */ +- (instancetype)initWithSDKTransactionIdentifier:(NSString *)identifier errorMessage:(STDSErrorMessage *)errorMessage; + +/** + `STDSProtocolErrorEvent` should not be directly initialized. + */ +- (instancetype)init NS_UNAVAILABLE; + +/** + Details about the error. + */ +@property (nonatomic, readonly) STDSErrorMessage *errorMessage; + +/** + The SDK Transaction Identifier. + */ +@property (nonatomic, readonly) NSString *sdkTransactionIdentifier; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/include/STDSRuntimeErrorEvent.h b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/include/STDSRuntimeErrorEvent.h new file mode 100644 index 0000000..658cdb9 --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/include/STDSRuntimeErrorEvent.h @@ -0,0 +1,53 @@ +// +// STDSRuntimeErrorEvent.h +// Stripe3DS2 +// +// Created by Yuki Tokuhiro on 3/20/19. +// Copyright © 2019 Stripe. All rights reserved. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +FOUNDATION_EXTERN NSString * const kSTDSRuntimeErrorCodeParsingError; +FOUNDATION_EXTERN NSString * const kSTDSRuntimeErrorCodeEncryptionError; + +/** + `STDSRuntimeErrorEvent` contains details about run-time errors encountered during authentication. + + The following are examples of run-time errors: + - ACS is unreachable + - Unparseable message + - Network issues + */ +@interface STDSRuntimeErrorEvent : NSObject + +/** + A code corresponding to the type of error this represents. + */ +@property (nonatomic, readonly) NSString *errorCode; + +/** + Details about the error. + */ +@property (nonatomic, readonly) NSString *errorMessage; + +/** + Designated initializer for `STDSRuntimeErrorEvent`. + */ +- (instancetype)initWithErrorCode:(NSString *)errorCode errorMessage:(NSString *)errorMessage NS_DESIGNATED_INITIALIZER; + +/** + A representation of the `STDSRuntimeErrorEvent` as an `NSError` + */ +- (NSError *)NSErrorValue; + +/** + `STDSRuntimeErrorEvent` should not be directly initialized. + */ +- (instancetype)init NS_UNAVAILABLE; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/include/STDSRuntimeException.h b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/include/STDSRuntimeException.h new file mode 100644 index 0000000..5b63a2d --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/include/STDSRuntimeException.h @@ -0,0 +1,21 @@ +// +// STDSRuntimeException.h +// Stripe3DS2 +// +// Created by Cameron Sabol on 1/22/19. +// Copyright © 2019 Stripe. All rights reserved. +// + +#import "STDSException.h" + +NS_ASSUME_NONNULL_BEGIN + +/** + `STDSRuntimeException` represents an exception that will be thrown by the + Stripe3DS2 SDK if it encounters an internal error. + */ +@interface STDSRuntimeException : STDSException + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/include/STDSSelectionCustomization.h b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/include/STDSSelectionCustomization.h new file mode 100644 index 0000000..a9818bb --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/include/STDSSelectionCustomization.h @@ -0,0 +1,48 @@ +// +// STDSSelectionCustomization.h +// Stripe3DS2 +// +// Created by Yuki Tokuhiro on 6/11/19. +// Copyright © 2019 Stripe. All rights reserved. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +/** + A customization object that configures the appearance of + radio buttons and checkboxes. + */ +@interface STDSSelectionCustomization: NSObject + +/// The default settings. ++ (instancetype)defaultSettings; + +/** + The primary color of the selected state. + Defaults to blue. + */ +@property (nonatomic) UIColor *primarySelectedColor; + +/** + The secondary color of the selected state (e.g. the checkmark color). + Defaults to white. + */ +@property (nonatomic) UIColor *secondarySelectedColor; + +/** + The background color displayed in the unselected state. + Defaults to light blue. + */ +@property (nonatomic) UIColor *unselectedBackgroundColor; + +/** + The color of the border drawn around the view in the unselected state. + Defaults to blue. + */ +@property (nonatomic) UIColor *unselectedBorderColor; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/include/STDSStripe3DS2Error.h b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/include/STDSStripe3DS2Error.h new file mode 100644 index 0000000..2e506fe --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/include/STDSStripe3DS2Error.h @@ -0,0 +1,68 @@ +// +// STDSStripe3DS2Error.h +// Stripe3DS2 +// +// Created by Yuki Tokuhiro on 3/27/19. +// Copyright © 2019 Stripe. All rights reserved. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +FOUNDATION_EXPORT NSString * const STDSStripe3DS2ErrorDomain; + +/** + NSError.userInfo contains this key if we received an ErrorMessage instead of the expected response object. + The value of this key is the ErrorMessage. + */ +FOUNDATION_EXPORT NSString * const STDSStripe3DS2ErrorMessageErrorKey; + +/** + NSError.userInfo contains this key if we errored parsing JSON. + The value of this key is the invalid or missing field. + */ +FOUNDATION_EXPORT NSString * const STDSStripe3DS2ErrorFieldKey; + +/** + NSError.userInfo contains this key if we couldn't recognize critical message extension(s) + The value of this key is an array of identifiers. + */ +FOUNDATION_EXPORT NSString * const STDSStripe3DS2UnrecognizedCriticalMessageExtensionsKey; + + +typedef NS_ENUM(NSInteger, STDSErrorCode) { + + /// Code triggered an assertion + STDSErrorCodeAssertionFailed = 204, + + // JSON Parsing + /// Received invalid or malformed data + STDSErrorCodeJSONFieldInvalid = 203, + /// Expected field missing + STDSErrorCodeJSONFieldMissing = 201, + + /// Critical message extension not recognised + STDSErrorCodeUnrecognizedCriticalMessageExtension = 202, + + /// Decryption or verification error + STDSErrorCodeDecryptionVerification = 302, + + /// Error code corresponding to a `STDSRuntimeErrorEvent` for an unparseable network response + STDSErrorCodeRuntimeParsing = 400, + /// Error code corresponding to a `STDSRuntimeErrorEvent` for an error with decrypting or verifying a network response + STDSErrorCodeRuntimeEncryption = 401, + + // Networking + /// We received an ErrorMessage instead of the expected response object. `userInfo[STDSStripe3DS2ErrorMessageErrorKey]` will contain the ErrorMessage object. + STDSErrorCodeReceivedErrorMessage = 1000, + /// We received an unknown message type. + STDSErrorCodeUnknownMessageType = 1001, + /// Request timed out + STDSErrorCodeTimeout = 1002, + + /// Unknown + STDSErrorCodeUnknownError = 2000, +}; + +NS_ASSUME_NONNULL_END diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/include/STDSSwiftTryCatch.h b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/include/STDSSwiftTryCatch.h new file mode 100644 index 0000000..4744336 --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/include/STDSSwiftTryCatch.h @@ -0,0 +1,50 @@ +// +// STDSSwiftTryCatch.h +// +// Created by William Falcon on 10/10/14. +// Copyright (c) 2014 William Falcon. 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 + +NS_ASSUME_NONNULL_BEGIN + +/** + Provides try catch functionality for swift by wrapping around Objective-C + */ +@interface STDSSwiftTryCatch : NSObject + +/** + Provides try catch functionality for swift by wrapping around Objective-C + */ ++ (void)tryBlock:(void(^)(void))tryBlock catchBlock:(void(^)(NSException*exception))catchBlock finallyBlock:(void(^)(void))finallyBlock; +/** + Throws Objective-C exception with name and reason set to `s` + */ ++ (void)throwString:(NSString*)s; + +/** + Throws exception `e` + */ ++ (void)throwException:(NSException*)e; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/include/STDSTextFieldCustomization.h b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/include/STDSTextFieldCustomization.h new file mode 100644 index 0000000..6f2bfed --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/include/STDSTextFieldCustomization.h @@ -0,0 +1,47 @@ +// +// STDSTextFieldCustomization.h +// Stripe3DS2 +// +// Created by Andrew Harrison on 3/14/19. +// Copyright © 2019 Stripe. All rights reserved. +// + +#import + +#import "STDSCustomization.h" + +NS_ASSUME_NONNULL_BEGIN + +/** + A customization object to use to configure the UI of a text field. + + The font and textColor inherited from `STDSCustomization` configure + the user input text. + */ +@interface STDSTextFieldCustomization : STDSCustomization + +/** + The default settings. + + The default textColor is black. + */ ++ (instancetype)defaultSettings; + +/// The border width of the text field. Defaults to 2. +@property (nonatomic) CGFloat borderWidth; + +/// The color of the border of the text field. Defaults to clear. +@property (nonatomic) UIColor *borderColor; + +/// The corner radius of the edges of the text field. Defaults to 8. +@property (nonatomic) CGFloat cornerRadius; + +/// The appearance of the keyboard. Defaults to UIKeyboardAppearanceDefault. +@property (nonatomic) UIKeyboardAppearance keyboardAppearance; + +/// The color of the placeholder text. Defaults to light gray. +@property (nonatomic) UIColor *placeholderTextColor; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/include/STDSThreeDS2Service.h b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/include/STDSThreeDS2Service.h new file mode 100644 index 0000000..c0baa55 --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/include/STDSThreeDS2Service.h @@ -0,0 +1,84 @@ +// +// STDSThreeDS2Service.h +// Stripe3DS2 +// +// Created by Cameron Sabol on 1/22/19. +// Copyright © 2019 Stripe. All rights reserved. +// + +#import + +@class STDSConfigParameters; +@class STDSTransaction; +@class STDSUICustomization; +@class STDSWarning; + +NS_ASSUME_NONNULL_BEGIN + +/** + `STDSThreeDS2Service` is the main 3DS SDK interface and provides methods to process transactions. + */ +@interface STDSThreeDS2Service : NSObject + +/** + A list of warnings that may be populated once the SDK has been initialized. + */ +@property (nonatomic, readonly, nullable) NSArray *warnings; + +/** + Initializes the 3DS SDK instance. + + This method should be called at the start of the payment stage of a transaction. + **Note: Until the `STDSThreeDS2Service instance is initialized, it will be unusable.** + + - Performs security checks + - Collects device information + + @param config Configuration information that will be used during initialization. @see STDSConfigParameters + @param locale Optional override for the locale to use in UI. If `nil`, will default to the current system locale. + @param uiSettings Optional custom UI settings. If `nil`, will default to `[STDSUICustomization defaultSettings]`. + This argument is copied; any further changes to the customization object have no effect. @see STDSUICustomization + + @exception STDSInvalidInputException Will throw an `STDSInvalidInputException` if `config` is `nil` or any of `config`, `locale`, or `uiSettings` are invalid. @see STDSInvalidInputException + @exception STDSAlreadyInitializedException Will throw an `STDSAlreadyInitializedException` if the 3DS SDK instance has already been initialized. @see STDSSDKAlreadyInitializedException + @exception STDSRuntimeException Will throw an `STDSRuntimeException` if there is an internal error in the SDK. @see STDSRuntimeException + */ +- (void)initializeWithConfig:(STDSConfigParameters *)config + locale:(nullable NSLocale *)locale + uiSettings:(nullable STDSUICustomization *)uiSettings; + +/** + Creates and returns an instance of `STDSTransaction`. + + @param directoryServerID The Directory Server identifier returned in the authentication response + @param protocolVersion 3DS protocol version according to which the transaction will be created. Uses the default value of 2.1.0 if nil + + @exception STDSNotInitializedException Will throw an `STDSNotInitializedException` if the the `STDSThreeDS2Service` instance hasn't been initialized with a call to `initializeWithConfig:locale:uiSettings:`. @see STDSNotInitializedException + @exception STDSInvalidInputException Will throw an `STDSInvalidInputException` if `directoryServerID` is not recognized or if the `protocolVersion` is not supported by this version of the SDK. @see STDSInvalidInputException + @exception STDSRuntimeException Will throw an `STDSRuntimeException` if there is an internal error in the SDK. @see STDSRuntimeException + */ +- (STDSTransaction *)createTransactionForDirectoryServer:(NSString *)directoryServerID + withProtocolVersion:(nullable NSString *)protocolVersion; + +/** + Creates and returns an instance of `STDSTransaction` using a custom directory server certificate. + Will return nil if unable to create a certificate from the provided params. + + @param directoryServerID The Directory Server identifier returned in the authentication response + @param serverKeyID An additional authentication key used by some Directory Servers + @param certificateString A Base64-encoded PEM or DER formatted certificate string containing the directory server's public key + @param rootCertificateStrings An arry of base64-encoded PEM or DER formatted certificate strings containing the DS root certificate used for signature checks + @param protocolVersion 3DS protocol version according to which the transaction will be created. Uses the default value of 2.1.0 if nil + + @exception STDSNotInitializedException Will throw an `STDSNotInitializedException` if the the `STDSThreeDS2Service` instance hasn't been initialized with a call to `initializeWithConfig:locale:uiSettings:`. @see STDSNotInitializedException + @exception STDSInvalidInputException Will throw an `STDSInvalidInputException` if the `protocolVersion` is not supported by this version of the SDK. @see STDSInvalidInputException + */ +- (nullable STDSTransaction *)createTransactionForDirectoryServer:(NSString *)directoryServerID + serverKeyID:(nullable NSString *)serverKeyID + certificateString:(NSString *)certificateString + rootCertificateStrings:(NSArray *)rootCertificateStrings + withProtocolVersion:(nullable NSString *)protocolVersion; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/include/STDSThreeDSProtocolVersion.h b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/include/STDSThreeDSProtocolVersion.h new file mode 100644 index 0000000..b4161a6 --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/include/STDSThreeDSProtocolVersion.h @@ -0,0 +1,15 @@ +// +// STDSThreeDSProtocolVersion.h +// Stripe3DS2 +// +// Created by Cameron Sabol on 6/27/19. +// Copyright © 2019 Stripe. All rights reserved. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +FOUNDATION_EXPORT NSString * const Stripe3DS2ProtocolVersion; + +NS_ASSUME_NONNULL_END diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/include/STDSTransaction.h b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/include/STDSTransaction.h new file mode 100644 index 0000000..02a1f1a --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/include/STDSTransaction.h @@ -0,0 +1,94 @@ +// +// STDSTransaction.h +// Stripe3DS2 +// +// Created by Yuki Tokuhiro on 3/21/19. +// Copyright © 2019 Stripe. All rights reserved. +// + +#import +#import + +typedef void (^STDSTransactionVoidBlock)(void); + +@class STDSAuthenticationRequestParameters, STDSChallengeParameters; +@protocol STDSChallengeStatusReceiver; + +NS_ASSUME_NONNULL_BEGIN + +/** + `STDSTransaction` holds parameters that the 3DS Server requires to create AReq messages and to perform the Challenge Flow. + */ +@interface STDSTransaction : NSObject + +/** + The UI type of the presented challenge for this transaction if applicable. Will be one of + "none" + "text" + "single_select" + "multi_select" + "oob" + "html" + */ +@property (nonatomic, readonly, copy) NSString *presentedChallengeUIType; + +/** + Encrypts device information collected during initialization and returns it along with SDK details. + + @return Encrypted device information and details about this SDK. @see STDSAuthenticationRequestParameters + + @exception SDKRuntimeException Thrown if an internal error is encountered. + */ +- (STDSAuthenticationRequestParameters *)createAuthenticationRequestParameters; + +/** + Returns a UIViewController instance displaying the Directory Server logo and a spinner. Present this during the Authentication Request/Response. + */ +- (UIViewController *)createProgressViewControllerWithDidCancel:(STDSTransactionVoidBlock)didCancel; + +/** + Initiates the challenge process, displaying challenge UI as needed. + + @param presentingViewController The UIViewController used to present the challenge response UIViewController + @param challengeParameters Details required to conduct the challenge process. @see STDSChallengeParameters + @param challengeStatusReceiver A callback object to receive the status of the challenge. See @STDSChallengeStatusReceiver + @param timeout An interval in seconds within which the challenge process will finish. Must be at least 5 minutes. + + @exception STDSInvalidInputException Thrown if an argument is invalid (e.g. timeout less than 5 minutes). @see STDSInvalidInputException + @exception STDSSDKRuntimeException Thrown if an internal error is encountered, and if you call this method after calling `close`. @see SDKRuntimeException + + @note challengeStatusReceiver must conform to . This is a workaround: When the static Stripe3DS2 is compiled into Stripe.framework, the resulting swiftinterface and generated .h files reference this protocol. To allow users to build without including Stripe3DS2 directly, we'll take an `id` here instead. + */ +- (void)doChallengeWithViewController:(UIViewController *)presentingViewController + challengeParameters:(STDSChallengeParameters *)challengeParameters + challengeStatusReceiver:(id)challengeStatusReceiver + timeout:(NSTimeInterval)timeout; + +/** + Returns the version of the Stripe3DS2 SDK, e.g. @"1.0" + */ +- (NSString *)sdkVersion; + +/** +Cleans up resources held by `STDSTransaction`. Call this when the transaction is completed, if `doChallengeWithChallengeParameters:challengeStatusReceiver:timeout` is not called. + + @note Don't use this object after calling this method. Calling `doChallengeWithViewController:challengeParameters:challengeStatusReceiver:timeout` after calling this method will throw an `STDSSDKRuntimeException` + */ +- (void)close; + +/** + Alternate challenge initiation method meant only for internal use by Stripe SDK. + */ +- (void)doChallengeWithChallengeParameters:(STDSChallengeParameters *)challengeParameters + challengeStatusReceiver:(id)challengeStatusReceiver + timeout:(NSTimeInterval)timeout + presentationBlock:(void (^)(UIViewController *, void(^)(void)))presentationBlock; + +/** + Function to manually cancel the challenge flow. + */ +- (void)cancelChallengeFlow; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/include/STDSUICustomization.h b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/include/STDSUICustomization.h new file mode 100644 index 0000000..651b22f --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/include/STDSUICustomization.h @@ -0,0 +1,109 @@ +// +// STDSUICustomization.h +// Stripe3DS2 +// +// Created by Andrew Harrison on 3/14/19. +// Copyright © 2019 Stripe. All rights reserved. +// + +#import +#import "STDSCustomization.h" +#import "STDSButtonCustomization.h" +#import "STDSNavigationBarCustomization.h" +#import "STDSLabelCustomization.h" +#import "STDSTextFieldCustomization.h" +#import "STDSFooterCustomization.h" +#import "STDSSelectionCustomization.h" + +NS_ASSUME_NONNULL_BEGIN + +/** + The `STDSUICustomization` provides configuration for UI elements. + + It's important to configure this object appropriately before using it to initialize a + `STDSThreeDS2Service` object. `STDSThreeDS2Service` makes a copy of the customization + settings you provide; it ignores any subsequent changes you make to your `STDSUICustomization` instance. +*/ +@interface STDSUICustomization: NSObject + +/// The default settings. See individual properties for their default values. ++ (instancetype)defaultSettings; + +/** + Provides custom settings for the UINavigationBar of all UIViewControllers the SDK display. + The default is `[STDSNavigationBarCustomization defaultSettings]`. + */ +@property (nonatomic) STDSNavigationBarCustomization *navigationBarCustomization; + +/** + Provides custom settings for labels. + The default is `[STDSLabelCustomization defaultSettings]`. + */ +@property (nonatomic) STDSLabelCustomization *labelCustomization; + +/** + Provides custom settings for text fields. + The default is `[STDSTextFieldCustomization defaultSettings]`. + */ +@property (nonatomic) STDSTextFieldCustomization *textFieldCustomization; + +/** + The primary background color of all UIViewControllers the SDK display. + Defaults to white. + */ +@property (nonatomic) UIColor *backgroundColor; + +/** + The Challenge view displays a footer with additional details. This controls the background color of that view. + Defaults to gray. + */ +@property (nonatomic) STDSFooterCustomization *footerCustomization; + +/** + Sets a given button customization for the specified type. + + @param buttonCustomization The buttom customization to use. + @param buttonType The type of button to use the customization for. + */ +- (void)setButtonCustomization:(STDSButtonCustomization *)buttonCustomization forType:(STDSUICustomizationButtonType)buttonType; + +/** + Retrieves a button customization object for the given button type. + + @param buttonType The button type to retrieve a customization object for. + @return A button customization object, or the default if none was set. + @see STDSButtonCustomization + */ +- (STDSButtonCustomization *)buttonCustomizationForButtonType:(STDSUICustomizationButtonType)buttonType; + +/** + Provides custom settings for radio buttons and checkboxes. + The default is `[STDSSelectionCustomization defaultSettings]`. + */ +@property (nonatomic) STDSSelectionCustomization *selectionCustomization; + + +/** + The preferred status bar style for all UIViewControllers the SDK display. + Defaults to UIStatusBarStyleDefault. + */ +@property (nonatomic) UIStatusBarStyle preferredStatusBarStyle; + +#pragma mark - Progress View + +/** + The style of UIActivityIndicatorViews displayed. + This should contrast with `backgroundColor`. Defaults to regular on iOS 13+, + gray on iOS 10-12. + */ +@property (nonatomic) UIActivityIndicatorViewStyle activityIndicatorViewStyle; + +/** + The style of the UIBlurEffect displayed underneath the UIActivityIndicatorView. + Defaults to UIBlurEffectStyleDefault. + */ +@property (nonatomic) UIBlurEffectStyle blurStyle; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/include/STDSWarning.h b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/include/STDSWarning.h new file mode 100644 index 0000000..5f09fe7 --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/include/STDSWarning.h @@ -0,0 +1,69 @@ +// +// STDSWarning.h +// Stripe3DS2 +// +// Created by Cameron Sabol on 2/12/19. +// Copyright © 2019 Stripe. All rights reserved. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +/** + The `STDSWarningSeverity` enum defines the severity levels of warnings generated + during SDK initialization. @see STDSThreeDS2Service + */ +typedef NS_ENUM(NSInteger, STDSWarningSeverity) { + /** + Low severity + */ + STDSWarningSeverityLow = 0, + + /** + Medium severity + */ + STDSWarningSeverityMedium, + + /** + High severity + */ + STDSWarningSeverityHigh, +}; + +/** + The `STDSWarning` class represents warnings generated by `STDSThreeDS2Service` during + security checks run during initialization. @see STDSThreeDS2Service + */ +@interface STDSWarning : NSObject + +/** + Designated initializer for `STDSWarning`. + */ +- (instancetype)initWithIdentifier:(NSString *)identifier + message:(NSString *)message + severity:(STDSWarningSeverity)severity NS_DESIGNATED_INITIALIZER; + +/** + `STDSWarning` should not be directly initialized. + */ +- (instancetype)init NS_UNAVAILABLE; + +/** + The identifier for this warning instance. + */ +@property (nonatomic, readonly) NSString *identifier; + +/** + The descriptive message for this warning. + */ +@property (nonatomic, readonly) NSString *message; + +/** + The severity of this warning. + */ +@property (nonatomic, readonly) STDSWarningSeverity severity; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/StripePayments/Stripe3DS2/Stripe3DS2/include/Stripe3DS2.h b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/include/Stripe3DS2.h new file mode 100644 index 0000000..9e9f3eb --- /dev/null +++ b/Pods/StripePayments/Stripe3DS2/Stripe3DS2/include/Stripe3DS2.h @@ -0,0 +1,52 @@ +// +// Stripe3DS2.h +// Stripe3DS2 +// +// Created by Cameron Sabol on 1/16/19. +// Copyright © 2019 Stripe. All rights reserved. +// + +#import + +//! Project version number for Stripe3DS2. +FOUNDATION_EXPORT double Stripe3DS2VersionNumber; + +//! Project version string for Stripe3DS2. +FOUNDATION_EXPORT const unsigned char Stripe3DS2VersionString[]; + +#import "STDSConfigParameters.h" +#import "STDSThreeDS2Service.h" +#import "STDSUICustomization.h" +#import "STDSWarning.h" + +#import "STDSAlreadyInitializedException.h" +#import "STDSInvalidInputException.h" +#import "STDSNotInitializedException.h" +#import "STDSRuntimeException.h" + +#import "STDSErrorMessage.h" +#import "STDSProtocolErrorEvent.h" +#import "STDSRuntimeErrorEvent.h" +#import "STDSStripe3DS2Error.h" +#import "STDSThreeDSProtocolVersion.h" + +#import "STDSAuthenticationRequestParameters.h" +#import "STDSAuthenticationResponse.h" +#import "STDSChallengeParameters.h" +#import "STDSChallengeStatusReceiver.h" +#import "STDSCompletionEvent.h" +#import "STDSJSONDecodable.h" +#import "STDSJSONEncoder.h" +#import "STDSTransaction.h" + +#import "STDSButtonCustomization.h" +#import "STDSCustomization.h" +#import "STDSException.h" +#import "STDSFooterCustomization.h" +#import "STDSJSONEncodable.h" +#import "STDSLabelCustomization.h" +#import "STDSNavigationBarCustomization.h" +#import "STDSSelectionCustomization.h" +#import "STDSTextFieldCustomization.h" + +#import "STDSSwiftTryCatch.h" diff --git a/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Legacy Compatability/StripeAPI+Deprecated.swift b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Legacy Compatability/StripeAPI+Deprecated.swift new file mode 100644 index 0000000..2caf0d6 --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Legacy Compatability/StripeAPI+Deprecated.swift @@ -0,0 +1,169 @@ +// +// StripeAPI+Deprecated.swift +// StripePayments +// +// Created by David Estes on 10/15/21. +// Copyright © 2021 Stripe, Inc. All rights reserved. +// + +import Foundation +import PassKit + +extension StripeAPI { + + /// A convenience method to build a `PKPaymentRequest` with sane default values. + /// You will still need to configure the `paymentSummaryItems` property to indicate + /// what the user is purchasing, as well as the optional `requiredShippingAddressFields`, + /// `requiredBillingAddressFields`, and `shippingMethods` properties to indicate + /// what contact information your application requires. + /// Note that this method sets the payment request's countryCode to "US" and its + /// currencyCode to "USD". + /// - Parameter merchantIdentifier: Your Apple Merchant ID. + /// - Returns: a `PKPaymentRequest` with proper default values. Returns nil if running on < iOS8. + /// @deprecated Use `paymentRequestWithMerchantIdentifier:country:currency:` instead. + /// Apple Pay is available in many countries and currencies, and you should use + /// the appropriate values for your business. + @available( + *, + deprecated, + message: "Use `paymentRequestWithMerchantIdentifier:country:currency:` instead." + ) + @objc(paymentRequestWithMerchantIdentifier:) + public class func paymentRequest( + withMerchantIdentifier merchantIdentifier: String + ) + -> PKPaymentRequest + { + return self.paymentRequest( + withMerchantIdentifier: merchantIdentifier, + country: "US", + currency: "USD" + ) + } + +} + +// MARK: Deprecated top-level Stripe functions. +// These are included so Xcode can offer guidance on how to replace top-level Stripe usage. + +/// :nodoc: +@available( + *, + deprecated, + message: + "Use StripeAPI.defaultPublishableKey instead. (StripeAPI.defaultPublishableKey = \"pk_12345_xyzabc\")" +) +public func setDefaultPublishableKey(_ publishableKey: String) { + StripeAPI.defaultPublishableKey = publishableKey +} + +/// :nodoc: +@available( + *, + deprecated, + message: "Use StripeAPI.advancedFraudSignalsEnabled instead." +) +public var advancedFraudSignalsEnabled: Bool { + get { + StripeAPI.advancedFraudSignalsEnabled + } + set { + StripeAPI.advancedFraudSignalsEnabled = newValue + } +} + +/// :nodoc: +@available( + *, + deprecated, + message: "Use StripeAPI.jcbPaymentNetworkSupported instead." +) +public var jcbPaymentNetworkSupported: Bool { + get { + StripeAPI.jcbPaymentNetworkSupported + } + set { + StripeAPI.jcbPaymentNetworkSupported = newValue + } +} + +/// :nodoc: +@available( + *, + deprecated, + message: "Use StripeAPI.additionalEnabledApplePayNetworks instead." +) +public var additionalEnabledApplePayNetworks: [PKPaymentNetwork] { + get { + StripeAPI.additionalEnabledApplePayNetworks + } + set { + StripeAPI.additionalEnabledApplePayNetworks = newValue + } +} + +/// :nodoc: +@available( + *, + deprecated, + message: "Use StripeAPI.canSubmitPaymentRequest(_:) instead." +) +public func canSubmitPaymentRequest(_ paymentRequest: PKPaymentRequest) -> Bool { + return StripeAPI.canSubmitPaymentRequest(paymentRequest) +} + +/// :nodoc: +@available( + *, + deprecated, + message: "Use StripeAPI.deviceSupportsApplePay() instead." +) +public func deviceSupportsApplePay() -> Bool { + return StripeAPI.deviceSupportsApplePay() +} + +/// :nodoc: +@available( + *, + deprecated, + message: "Use StripeAPI.paymentRequest(withMerchantIdentifier:country:currency:) instead." +) +public func paymentRequest( + withMerchantIdentifier merchantIdentifier: String, + country countryCode: String, + currency currencyCode: String +) -> PKPaymentRequest { + return StripeAPI.paymentRequest( + withMerchantIdentifier: merchantIdentifier, + country: countryCode, + currency: currencyCode + ) +} + +/// :nodoc: +@available( + *, + deprecated, + message: "Use StripeAPI.paymentRequest(withMerchantIdentifier:country:currency:) instead." +) +func paymentRequest( + withMerchantIdentifier merchantIdentifier: String +) + -> PKPaymentRequest +{ + return StripeAPI.paymentRequest( + withMerchantIdentifier: merchantIdentifier, + country: "US", + currency: "USD" + ) +} + +/// :nodoc: +@available( + *, + deprecated, + message: "Use StripeAPI.handleURLCallback(with:) instead." +) +public func handleURLCallback(with url: URL) -> Bool { + return StripeAPI.handleURLCallback(with: url) +} diff --git a/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Legacy Compatability/StripeApplePay+Import.swift b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Legacy Compatability/StripeApplePay+Import.swift new file mode 100644 index 0000000..318915a --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Legacy Compatability/StripeApplePay+Import.swift @@ -0,0 +1,9 @@ +// +// StripeApplePay+Import.swift +// StripePayments +// +// Created by David Estes on 11/16/21. +// Copyright © 2021 Stripe, Inc. All rights reserved. +// + +import Foundation diff --git a/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Legacy Compatability/StripeCore+Import.swift b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Legacy Compatability/StripeCore+Import.swift new file mode 100644 index 0000000..e2411b3 --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Legacy Compatability/StripeCore+Import.swift @@ -0,0 +1,10 @@ +// +// StripeCore+Import.swift +// StripePayments +// +// Created by David Estes on 9/8/21. +// Copyright © 2021 Stripe, Inc. All rights reserved. +// + +import Foundation +@_exported import StripeCore diff --git a/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/ACH/LinkAccountSession.swift b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/ACH/LinkAccountSession.swift new file mode 100644 index 0000000..13c7cd4 --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/ACH/LinkAccountSession.swift @@ -0,0 +1,51 @@ +// +// LinkAccountSession.swift +// StripePayments +// +// Created by Cameron Sabol on 10/22/21. +// Copyright © 2021 Stripe, Inc. All rights reserved. +// + +import UIKit + +/// For internal SDK use only +@objc(STP_Internal_LinkAccountSession) +@_spi(STP) public class LinkAccountSession: NSObject, STPAPIResponseDecodable { + @_spi(STP) public let stripeID: String + @_spi(STP) public let livemode: Bool + @_spi(STP) public let clientSecret: String + + @_spi(STP) public let allResponseFields: [AnyHashable: Any] + + @_spi(STP) public required init( + stripeID: String, + livemode: Bool, + clientSecret: String, + allResponseFields: [AnyHashable: Any] + ) { + self.stripeID = stripeID + self.livemode = livemode + self.clientSecret = clientSecret + self.allResponseFields = allResponseFields + super.init() + } + + @_spi(STP) public static func decodedObject( + fromAPIResponse response: [AnyHashable: Any]? + ) -> Self? { + guard let response = response, + let stripeID = response["id"] as? String, + let livemode = response["livemode"] as? Bool, + let clientSecret = response["client_secret"] as? String + else { + return nil + } + + return LinkAccountSession( + stripeID: stripeID, + livemode: livemode, + clientSecret: clientSecret, + allResponseFields: response + ) as? Self + } +} diff --git a/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/ACH/STPCollectBankAccountParams.swift b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/ACH/STPCollectBankAccountParams.swift new file mode 100644 index 0000000..2b1eaeb --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/ACH/STPCollectBankAccountParams.swift @@ -0,0 +1,39 @@ +// +// STPCollectBankAccountParams.swift +// StripePayments +// +// Copyright © 2022 Stripe, Inc. All rights reserved. +// + +import Foundation + +/// Parameters to use with `STPBankAccountCollector` to collect bank account details for payments. +/// @see `STPBankAccountCollector` +public class STPCollectBankAccountParams: NSObject { + internal let paymentMethodParams: STPPaymentMethodParams + + internal init( + paymentMethodParams: STPPaymentMethodParams + ) { + self.paymentMethodParams = paymentMethodParams + } + + /// Configures and returns an instance of `STPCollectBankAccountParams` for US Bank Accounts + /// - Parameters: + /// - name: The customer's full name. _required_ + /// - email: The customer's email. If included, can be used to notify the customer of pending micro-deposit verification. + @objc(collectUSBankAccountParamsWithName:email:) + public class func collectUSBankAccountParams( + with name: String, + email: String? + ) -> STPCollectBankAccountParams { + let billingDetails = STPPaymentMethodBillingDetails() + billingDetails.name = name + billingDetails.email = email + + let paymentMethodParams = STPPaymentMethodParams() + paymentMethodParams.billingDetails = billingDetails + paymentMethodParams.type = .USBankAccount + return STPCollectBankAccountParams(paymentMethodParams: paymentMethodParams) + } +} diff --git a/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentIntents/STPConfirmAlipayOptions.swift b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentIntents/STPConfirmAlipayOptions.swift new file mode 100644 index 0000000..1348776 --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentIntents/STPConfirmAlipayOptions.swift @@ -0,0 +1,57 @@ +// +// STPConfirmAlipayOptions.swift +// StripePayments +// +// Created by Yuki Tokuhiro on 5/13/20. +// Copyright © 2020 Stripe, Inc. All rights reserved. +// + +import Foundation +@_spi(STP) import StripeCore + +/// Alipay options to pass to `STPConfirmPaymentMethodOptions`` +public class STPConfirmAlipayOptions: NSObject { + + /// The app bundle ID. + /// @note This is automatically populated by the SDK. + @objc public var appBundleID: String { + return Bundle.main.bundleIdentifier ?? "" + } + + /// The app version. + /// @note This is automatically populated by the SDK. + @objc public var appVersionKey: String { + return Bundle.stp_applicationVersion() ?? "1.0.0" // Should only be nil for tests + } + + @objc public var additionalAPIParameters: [AnyHashable: Any] = [:] + + /// :nodoc: + @objc public override var description: String { + let props = [ + // Object + String(format: "%@: %p", NSStringFromClass(type(of: self)), self), + "appBundleID = \(appBundleID)", + "appVersionKey = \(appVersionKey)", + ] + + return "<\(props.joined(separator: "; "))>" + } + +} + +// MARK: - STPFormEncodable +extension STPConfirmAlipayOptions: STPFormEncodable { + @objc + public class func propertyNamesToFormFieldNamesMapping() -> [String: String] { + return [ + NSStringFromSelector(#selector(getter:appBundleID)): "app_bundle_id", + NSStringFromSelector(#selector(getter:appVersionKey)): "app_version_key", + ] + } + + @objc + public class func rootObjectName() -> String? { + return "alipay" + } +} diff --git a/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentIntents/STPConfirmBLIKOptions.swift b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentIntents/STPConfirmBLIKOptions.swift new file mode 100644 index 0000000..5137fec --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentIntents/STPConfirmBLIKOptions.swift @@ -0,0 +1,54 @@ +// +// STPConfirmBLIKOptions.swift +// StripePayments +// +// Created by Yuki Tokuhiro on 3/10/21. +// Copyright © 2021 Stripe, Inc. All rights reserved. +// + +import Foundation + +/// BLIK options to pass to `STPConfirmPaymentMethodOptions`` +/// - seealso: https://site-admin.stripe.com/docs/api/payment_intents/confirm#confirm_payment_intent-payment_method_options-blik +public class STPConfirmBLIKOptions: NSObject { + + /// The 6-digit BLIK code that a customer has generated using their banking application. + @objc public var code: String + + @objc public var additionalAPIParameters: [AnyHashable: Any] = [:] + + /// :nodoc: + @objc public override var description: String { + let props = [ + // Object + String(format: "%@: %p", NSStringFromClass(type(of: self)), self), + "code = \(code)", + ] + + return "<\(props.joined(separator: "; "))>" + } + + /// Initializes STPConfirmBLIKOptions + /// - parameter code: The 6-digit BLIK code that a customer has generated using their banking application. + @objc public required init( + code: String + ) { + self.code = code + super.init() + } +} + +// MARK: - STPFormEncodable +extension STPConfirmBLIKOptions: STPFormEncodable { + @objc + public class func propertyNamesToFormFieldNamesMapping() -> [String: String] { + return [ + NSStringFromSelector(#selector(getter:code)): "code" + ] + } + + @objc + public class func rootObjectName() -> String? { + return "blik" + } +} diff --git a/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentIntents/STPConfirmCardOptions.swift b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentIntents/STPConfirmCardOptions.swift new file mode 100644 index 0000000..0d0b756 --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentIntents/STPConfirmCardOptions.swift @@ -0,0 +1,53 @@ +// +// STPConfirmCardOptions.swift +// StripePayments +// +// Created by Cameron Sabol on 1/10/20. +// Copyright © 2020 Stripe, Inc. All rights reserved. +// + +import Foundation + +/// Options to update a Card PaymentMethod during PaymentIntent confirmation. +/// - seealso: https://stripe.com/docs/api/payment_intents/confirm#confirm_payment_intent-payment_method_options-card +public class STPConfirmCardOptions: NSObject { + + /// CVC value with which to update the Card PaymentMethod. + @objc public var cvc: String? + + /// Selected network to process this PaymentIntent on. Depends on the available networks of the card attached to the PaymentIntent. Can be only set confirm-time. + @objc public var network: String? + + /// :nodoc: + @objc public var additionalAPIParameters: [AnyHashable: Any] = [:] + + /// :nodoc: + @objc public override var description: String { + let props = [ + // Object + String(format: "%@: %p", NSStringFromClass(type(of: self)), self), + "cvc = \(String(describing: cvc))", + "network = \(String(describing: network))", + ] + + return "<\(props.joined(separator: "; "))>" + } + +} + +// MARK: - STPFormEncodable +extension STPConfirmCardOptions: STPFormEncodable { + + @objc + public class func propertyNamesToFormFieldNamesMapping() -> [String: String] { + return [ + NSStringFromSelector(#selector(getter:cvc)): "cvc", + NSStringFromSelector(#selector(getter:network)): "network", + ] + } + + @objc + public class func rootObjectName() -> String? { + return "card" + } +} diff --git a/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentIntents/STPConfirmPaymentMethodOptions.swift b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentIntents/STPConfirmPaymentMethodOptions.swift new file mode 100644 index 0000000..575fc0f --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentIntents/STPConfirmPaymentMethodOptions.swift @@ -0,0 +1,66 @@ +// +// STPConfirmPaymentMethodOptions.swift +// StripePayments +// +// Created by Cameron Sabol on 1/10/20. +// Copyright © 2020 Stripe, Inc. All rights reserved. +// + +import Foundation + +/// Options to update the associated PaymentMethod during PaymentIntent confirmation. +/// - seealso: https://stripe.com/docs/api/payment_intents/confirm#confirm_payment_intent-payment_method_options +public class STPConfirmPaymentMethodOptions: NSObject { + + /// Options to update a Card PaymentMethod. + /// - seealso: STPConfirmCardOptions + @objc public var cardOptions: STPConfirmCardOptions? + + /// Options for an Alipay Payment Method. + @objc public var alipayOptions: STPConfirmAlipayOptions? + + /// Options for a BLIK Payment Method. + @objc public var blikOptions: STPConfirmBLIKOptions? + + /// Options for a WeChat Pay Payment Method. + @objc public var weChatPayOptions: STPConfirmWeChatPayOptions? + + /// Options for a US Bank Account Payment Method. + @objc public var usBankAccountOptions: STPConfirmUSBankAccountOptions? + + /// :nodoc: + @objc public var additionalAPIParameters: [AnyHashable: Any] = [:] + + /// :nodoc: + @objc public override var description: String { + let props: [String] = [ + // Object + String(format: "%@: %p", NSStringFromClass(type(of: self)), self), + "alipay = \(String(describing: alipayOptions))", + "card = \(String(describing: cardOptions))", + "blik = \(String(describing: blikOptions))", + "wechat_pay = \(String(describing: weChatPayOptions))", + "us_bank_account = \(String(describing: usBankAccountOptions))", + ] + return "<\(props.joined(separator: "; "))>" + } +} + +// MARK: - STPFormEncodable +extension STPConfirmPaymentMethodOptions: STPFormEncodable { + @objc + public class func propertyNamesToFormFieldNamesMapping() -> [String: String] { + return [ + NSStringFromSelector(#selector(getter:alipayOptions)): "alipay", + NSStringFromSelector(#selector(getter:cardOptions)): "card", + NSStringFromSelector(#selector(getter:blikOptions)): "blik", + NSStringFromSelector(#selector(getter:weChatPayOptions)): "wechat_pay", + NSStringFromSelector(#selector(getter:usBankAccountOptions)): "us_bank_account", + ] + } + + @objc + public class func rootObjectName() -> String? { + return "payment_method_options" + } +} diff --git a/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentIntents/STPConfirmUSBankAccountOptions.swift b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentIntents/STPConfirmUSBankAccountOptions.swift new file mode 100644 index 0000000..1a936ec --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentIntents/STPConfirmUSBankAccountOptions.swift @@ -0,0 +1,47 @@ +// +// STPConfirmUSBankAccountOptions.swift +// StripePayments +// +// Created by Cameron Sabol on 3/16/22. +// Copyright © 2022 Stripe, Inc. All rights reserved. +// + +import Foundation + +// MARK: - STPConfirmUSBankAccountOptions + +/// Options for US Bank Account Payment Methods during PaymentIntent or SetupIntent confirmation +/// - seealso https://stripe.com/docs/api/payment_intents/confirm#confirm_payment_intent-payment_method_options-us_bank_account +public class STPConfirmUSBankAccountOptions: NSObject { + /// Initializer for `STPConfirmUSBankAccountOptions` + /// - Parameter setupFutureUsage: Indicates that you intend to make future payments with this payment method. + @objc public init( + setupFutureUsage: STPPaymentIntentSetupFutureUsage + ) { + self.setupFutureUsage = setupFutureUsage + } + + /// Indicates that you intend to make future payments with this payment method. + /// Providing this parameter will attach the payment method to the PaymentIntent’s Customer, if present, after the Intent is confirmed and any required actions from the user are complete. If no Customer was provided, the payment method can still be attached to a Customer after the transaction completes. + /// + /// If setup_future_usage is already set, you may only update the value from on_session to off_session. + @objc public var setupFutureUsage: STPPaymentIntentSetupFutureUsage + + @objc public var additionalAPIParameters: [AnyHashable: Any] = [:] +} + +// MARK: - STPFormEncodable +extension STPConfirmUSBankAccountOptions: STPFormEncodable { + + @objc internal var setupFutureUsageRawString: String? { + return setupFutureUsage.stringValue + } + + public static func rootObjectName() -> String? { + return "us_bank_account" + } + + public static func propertyNamesToFormFieldNamesMapping() -> [String: String] { + [NSStringFromSelector(#selector(getter:setupFutureUsageRawString)): "setup_future_usage"] + } +} diff --git a/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentIntents/STPConfirmWeChatPayOptions.swift b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentIntents/STPConfirmWeChatPayOptions.swift new file mode 100644 index 0000000..dcf7518 --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentIntents/STPConfirmWeChatPayOptions.swift @@ -0,0 +1,60 @@ +// +// STPConfirmWeChatPayOptions.swift +// StripePayments +// +// Copyright © 2021 Stripe, Inc. All rights reserved. +// + +import Foundation + +/// WeChat Pay options to pass to `STPConfirmPaymentMethodOptions`` +/// - seealso: https://site-admin.stripe.com/docs/api/payment_intents/confirm#confirm_payment_intent-payment_method_options-wechat_pay +public class STPConfirmWeChatPayOptions: NSObject { + + /// WeChat client. On iOS, this is always "ios". + @objc let client = "ios" + + /// Your WeChat-provided application ID. WeChat Pay uses + /// this as the redirect URL scheme. + @objc public var appId: String? + + @objc public var additionalAPIParameters: [AnyHashable: Any] = [:] + + /// :nodoc: + @objc public override var description: String { + let props = [ + // Object + String(format: "%@: %p", NSStringFromClass(type(of: self)), self), + "client = \(client)", + "appId = \(String(describing: appId))", + ] + + return "<\(props.joined(separator: "; "))>" + } + + /// Initializes STPConfirmWeChatPayOptions + /// - parameter appId: Your WeChat-provided application ID. WeChat Pay + /// uses this as the redirect URL scheme. + @objc public required init( + appId: String + ) { + self.appId = appId + super.init() + } +} + +// MARK: - STPFormEncodable +extension STPConfirmWeChatPayOptions: STPFormEncodable { + @objc + public class func propertyNamesToFormFieldNamesMapping() -> [String: String] { + return [ + NSStringFromSelector(#selector(getter:client)): "client", + NSStringFromSelector(#selector(getter:appId)): "app_id", + ] + } + + @objc + public class func rootObjectName() -> String? { + return "wechat_pay" + } +} diff --git a/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentIntents/STPPaymentIntent.swift b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentIntents/STPPaymentIntent.swift new file mode 100644 index 0000000..8064cd2 --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentIntents/STPPaymentIntent.swift @@ -0,0 +1,390 @@ +// +// STPPaymentIntent.swift +// StripePayments +// +// Created by Daniel Jackson on 6/27/18. +// Copyright © 2018 Stripe, Inc. All rights reserved. +// + +import Foundation + +/// Capture methods for a STPPaymentIntent +@objc public enum STPPaymentIntentCaptureMethod: Int { + /// Unknown capture method + case unknown + /// The PaymentIntent will be automatically captured + case automatic + /// The PaymentIntent must be manually captured once it has the status + /// `STPPaymentIntentStatusRequiresCapture` + case manual + + /// Parse the string and return the correct `STPPaymentIntentCaptureMethod`, + /// or `STPPaymentIntentCaptureMethodUnknown` if it's unrecognized by this version of the SDK. + /// - Parameter string: the NSString with the capture method + internal static func captureMethod(from string: String) -> STPPaymentIntentCaptureMethod { + let map: [String: STPPaymentIntentCaptureMethod] = [ + "manual": .manual, + "automatic": .automatic, + ] + + let key = string.lowercased() + return map[key] ?? .unknown + } +} + +/// Confirmation methods for a STPPaymentIntent +@objc public enum STPPaymentIntentConfirmationMethod: Int { + /// Unknown confirmation method + case unknown + /// Confirmed via publishable key + case manual + /// Confirmed via secret key + case automatic + + /// Parse the string and return the correct `STPPaymentIntentConfirmationMethod`, + /// or `STPPaymentIntentConfirmationMethodUnknown` if it's unrecognized by this version of the SDK. + /// - Parameter string: the NSString with the confirmation method + internal static func confirmationMethod( + from string: String + ) + -> STPPaymentIntentConfirmationMethod + { + let map: [String: STPPaymentIntentConfirmationMethod] = [ + "automatic": .automatic, + "manual": .manual, + ] + + let key = string.lowercased() + return map[key] ?? .unknown + } +} + +/// A PaymentIntent tracks the process of collecting a payment from your customer. +/// - seealso: https://stripe.com/docs/api#payment_intents +/// - seealso: https://stripe.com/docs/payments/3d-secure +public class STPPaymentIntent: NSObject { + + /// The Stripe ID of the PaymentIntent. + @objc public let stripeId: String + + /// The client secret used to fetch this PaymentIntent + @objc public let clientSecret: String + + /// Amount intended to be collected by this PaymentIntent. + @objc public let amount: Int + + /// If status is `.canceled`, when the PaymentIntent was canceled. + @objc public let canceledAt: Date? + + /// Capture method of this PaymentIntent + @objc public let captureMethod: STPPaymentIntentCaptureMethod + + /// Confirmation method of this PaymentIntent + @objc public let confirmationMethod: STPPaymentIntentConfirmationMethod + + /// When the PaymentIntent was created. + @objc public let created: Date + + /// The currency associated with the PaymentIntent. + @objc public let currency: String + + /// The `description` field of the PaymentIntent. + /// An arbitrary string attached to the object. Often useful for displaying to users. + @objc public let stripeDescription: String? + + /// Whether or not this PaymentIntent was created in livemode. + @objc public let livemode: Bool + + /// If `status == .requiresAction`, this + /// property contains the next action to take for this PaymentIntent. + @objc public let nextAction: STPIntentAction? + + /// Email address that the receipt for the resulting payment will be sent to. + @objc public let receiptEmail: String? + + /// The Stripe ID of the Source used in this PaymentIntent. + @objc public let sourceId: String? + + /// The Stripe ID of the PaymentMethod used in this PaymentIntent. + @objc public let paymentMethodId: String? + + /// Status of the PaymentIntent + @objc public let status: STPPaymentIntentStatus + + /// The list of payment method types (e.g. `[NSNumber(value: STPPaymentMethodType.card.rawValue)]`) that this PaymentIntent is allowed to use. + @objc public let paymentMethodTypes: [NSNumber] + + /// When provided, this property indicates how you intend to use the payment method that your customer provides after the current payment completes. If applicable, additional authentication may be performed to comply with regional legislation or network rules required to enable the usage of the same payment method for additional payments. + /// Use on_session if you intend to only reuse the payment method when the customer is in your checkout flow. Use off_session if your customer may or may not be in your checkout flow. + @objc public let setupFutureUsage: STPPaymentIntentSetupFutureUsage + + /// The payment error encountered in the previous PaymentIntent confirmation. + @objc public let lastPaymentError: STPPaymentIntentLastPaymentError? + + /// Shipping information for this PaymentIntent. + @objc public let shipping: STPPaymentIntentShippingDetails? + + @objc public let allResponseFields: [AnyHashable: Any] + + /// The optionally expanded PaymentMethod used in this PaymentIntent. + @objc public let paymentMethod: STPPaymentMethod? + + /// The ordered payment method preference for this PaymentIntent + @_spi(STP) public let orderedPaymentMethodTypes: [STPPaymentMethodType] + + /// A list of payment method types that are not activated in live mode, but activated in test mode + @_spi(STP) public let unactivatedPaymentMethodTypes: [STPPaymentMethodType] + + /// Payment-method-specific configuration for this PaymentIntent. + @_spi(STP) public let paymentMethodOptions: STPPaymentMethodOptions? + + /// Link-specific settings for this PaymentIntent. + @_spi(STP) public let linkSettings: LinkSettings? + + /// Country code of the user. + @_spi(STP) public let countryCode: String? + + /// :nodoc: + @objc public override var description: String { + let props: [String] = [ + // Object + String(format: "%@: %p", NSStringFromClass(STPPaymentIntent.self), self), + // Identifier + "stripeId = \(stripeId)", + // PaymentIntent details (alphabetical) + "amount = \(amount)", + "canceledAt = \(String(describing: canceledAt))", + "captureMethod = \(String(describing: allResponseFields["capture_method"] as? String))", + "clientSecret = ", + "confirmationMethod = \(String(describing: allResponseFields["confirmation_method"] as? String))", + "countryCode = \(String(describing: countryCode))", + "created = \(created)", + "currency = \(currency)", + "description = \(String(describing: stripeDescription))", + "lastPaymentError = \(String(describing: lastPaymentError))", + "linkSettings = \(String(describing: linkSettings))", + "livemode = \(livemode)", + "nextAction = \(String(describing: nextAction))", + "paymentMethodId = \(String(describing: paymentMethodId))", + "paymentMethod = \(String(describing: paymentMethod))", + "paymentMethodOptions = \(String(describing: paymentMethodOptions))", + "paymentMethodTypes = \(String(describing: allResponseFields["payment_method_types"] as? [String]))", + "receiptEmail = \(String(describing: receiptEmail))", + "setupFutureUsage = \(String(describing: allResponseFields["setup_future_usage"] as? String))", + "shipping = \(String(describing: shipping))", + "sourceId = \(String(describing: sourceId))", + "status = \(String(describing: allResponseFields["status"] as? String))", + "unactivatedPaymentMethodTypes = \(allResponseFields.stp_array(forKey: "unactivated_payment_method_types") ?? [])", + ] + + return "<\(props.joined(separator: "; "))>" + } + + private init( + allResponseFields: [AnyHashable: Any], + amount: Int, + canceledAt: Date?, + captureMethod: STPPaymentIntentCaptureMethod, + clientSecret: String, + confirmationMethod: STPPaymentIntentConfirmationMethod, + countryCode: String?, + created: Date, + currency: String, + lastPaymentError: STPPaymentIntentLastPaymentError?, + linkSettings: LinkSettings?, + livemode: Bool, + nextAction: STPIntentAction?, + orderedPaymentMethodTypes: [STPPaymentMethodType], + paymentMethod: STPPaymentMethod?, + paymentMethodId: String?, + paymentMethodOptions: STPPaymentMethodOptions?, + paymentMethodTypes: [NSNumber], + receiptEmail: String?, + setupFutureUsage: STPPaymentIntentSetupFutureUsage, + shipping: STPPaymentIntentShippingDetails?, + sourceId: String?, + status: STPPaymentIntentStatus, + stripeDescription: String?, + stripeId: String, + unactivatedPaymentMethodTypes: [STPPaymentMethodType] + ) { + self.allResponseFields = allResponseFields + self.amount = amount + self.canceledAt = canceledAt + self.captureMethod = captureMethod + self.clientSecret = clientSecret + self.confirmationMethod = confirmationMethod + self.countryCode = countryCode + self.created = created + self.currency = currency + self.lastPaymentError = lastPaymentError + self.linkSettings = linkSettings + self.livemode = livemode + self.nextAction = nextAction + self.orderedPaymentMethodTypes = orderedPaymentMethodTypes + self.paymentMethod = paymentMethod + self.paymentMethodId = paymentMethodId + self.paymentMethodOptions = paymentMethodOptions + self.paymentMethodTypes = paymentMethodTypes + self.receiptEmail = receiptEmail + self.setupFutureUsage = setupFutureUsage + self.shipping = shipping + self.sourceId = sourceId + self.status = status + self.stripeDescription = stripeDescription + self.stripeId = stripeId + self.unactivatedPaymentMethodTypes = unactivatedPaymentMethodTypes + super.init() + } +} + +// MARK: - STPAPIResponseDecodable +extension STPPaymentIntent: STPAPIResponseDecodable { + + @objc + public class func decodedObject(fromAPIResponse response: [AnyHashable: Any]?) -> Self? { + guard let response = response else { + return nil + } + + if let paymentMethodPrefDict = response["payment_method_preference"] as? [AnyHashable: Any], + let paymentIntentDict = paymentMethodPrefDict["payment_intent"] as? [AnyHashable: Any], + let orderedPaymentMethodTypes = paymentMethodPrefDict["ordered_payment_method_types"] + as? [String] + { + // Consolidates expanded payment_intent and ordered_payment_method_types into singular dict for decoding + var dict = paymentIntentDict + dict["country_code"] = paymentMethodPrefDict["country_code"] + dict["ordered_payment_method_types"] = orderedPaymentMethodTypes + dict["unactivated_payment_method_types"] = response["unactivated_payment_method_types"] + dict["link_settings"] = response["link_settings"] + dict["payment_method_specs"] = response["payment_method_specs"] + return decodeSTPPaymentIntentObject(fromAPIResponse: dict) + } else { + return decodeSTPPaymentIntentObject(fromAPIResponse: response) + } + } + + class func decodeSTPPaymentIntentObject(fromAPIResponse response: [AnyHashable: Any]?) -> Self? + { + guard let dict = response, + let stripeId = dict["id"] as? String, + let clientSecret = dict["client_secret"] as? String, + let amount = dict["amount"] as? Int, + let currency = dict["currency"] as? String, + let rawStatus = dict["status"] as? String, + let livemode = dict["livemode"] as? Bool, + let createdUnixTime = dict["created"] as? TimeInterval, + let paymentMethodTypeStrings = dict["payment_method_types"] as? [String] + else { + return nil + } + + let paymentMethod = STPPaymentMethod.decodedObject( + fromAPIResponse: dict["payment_method"] as? [AnyHashable: Any] + ) + let setupFutureUsageString = dict["setup_future_usage"] as? String + let canceledAtUnixTime = dict["canceled_at"] as? TimeInterval + let unactivatedPaymentTypes = STPPaymentMethod.paymentMethodTypes( + from: dict["unactivated_payment_method_types"] as? [String] ?? [] + ) + return STPPaymentIntent( + allResponseFields: dict, + amount: amount, + canceledAt: canceledAtUnixTime != nil + ? Date(timeIntervalSince1970: canceledAtUnixTime!) : nil, + captureMethod: STPPaymentIntentCaptureMethod.captureMethod( + from: dict["capture_method"] as? String ?? "" + ), + clientSecret: clientSecret, + confirmationMethod: STPPaymentIntentConfirmationMethod.confirmationMethod( + from: dict["confirmation_method"] as? String ?? "" + ), + countryCode: dict["country_code"] as? String, + created: Date(timeIntervalSince1970: createdUnixTime), + currency: currency, + lastPaymentError: STPPaymentIntentLastPaymentError.decodedObject( + fromAPIResponse: dict["last_payment_error"] as? [AnyHashable: Any] + ), + linkSettings: LinkSettings.decodedObject( + fromAPIResponse: dict["link_settings"] as? [AnyHashable: Any] + ), + livemode: livemode, + nextAction: STPIntentAction.decodedObject( + fromAPIResponse: dict["next_action"] as? [AnyHashable: Any] + ), + orderedPaymentMethodTypes: STPPaymentMethod.paymentMethodTypes( + from: dict["ordered_payment_method_types"] as? [String] ?? paymentMethodTypeStrings + ), + paymentMethod: paymentMethod, + paymentMethodId: paymentMethod?.stripeId ?? dict["payment_method"] as? String, + paymentMethodOptions: STPPaymentMethodOptions.decodedObject( + fromAPIResponse: dict["payment_method_options"] as? [AnyHashable: Any] + ), + paymentMethodTypes: STPPaymentMethod.types(from: paymentMethodTypeStrings), + receiptEmail: dict["receipt_email"] as? String, + setupFutureUsage: setupFutureUsageString != nil + ? STPPaymentIntentSetupFutureUsage(string: setupFutureUsageString!) : .none, + shipping: STPPaymentIntentShippingDetails.decodedObject( + fromAPIResponse: dict["shipping"] as? [AnyHashable: Any] + ), + sourceId: dict["source"] as? String, + status: STPPaymentIntentStatus.status(from: rawStatus), + stripeDescription: dict["description"] as? String, + stripeId: stripeId, + unactivatedPaymentMethodTypes: unactivatedPaymentTypes + ) as? Self + } +} + +// MARK: - Deprecated +extension STPPaymentIntent { + + /// If `status == STPPaymentIntentStatusRequiresAction`, this + /// property contains the next source action to take for this PaymentIntent. + /// @deprecated Use nextAction instead + @available(*, deprecated, message: "Use nextAction instead", renamed: "nextAction") + @objc public var nextSourceAction: STPIntentAction? { + return nextAction + } +} + +// MARK: - Internal +extension STPPaymentIntent { + + /// Helper function for extracting PaymentIntent id from the Client Secret. + /// This avoids having to pass around both the id and the secret. + /// - Parameter clientSecret: The `client_secret` from the PaymentIntent + @_spi(STP) public class func id(fromClientSecret clientSecret: String) -> String? { + // see parseClientSecret from stripe-js-v3 + let components = clientSecret.components(separatedBy: "_secret_") + if components.count >= 2 && components[0].hasPrefix("pi_") { + return components[0] + } else { + return nil + } + } +} + +// MARK: - STPPaymentIntentEnum support + +extension STPPaymentIntentStatus { + + /// Parse the string and return the correct `STPPaymentIntentStatus`, + /// or `STPPaymentIntentStatusUnknown` if it's unrecognized by this version of the SDK. + /// - Parameter string: the NSString with the status + internal static func status(from string: String) -> STPPaymentIntentStatus { + let map: [String: STPPaymentIntentStatus] = [ + "requires_payment_method": .requiresPaymentMethod, + "requires_confirmation": .requiresConfirmation, + "requires_action": .requiresAction, + "processing": .processing, + "succeeded": .succeeded, + "requires_capture": .requiresCapture, + "canceled": .canceled, + ] + + let key = string.lowercased() + return map[key] ?? .unknown + } +} diff --git a/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentIntents/STPPaymentIntentAction.swift b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentIntents/STPPaymentIntentAction.swift new file mode 100644 index 0000000..ac15f77 --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentIntents/STPPaymentIntentAction.swift @@ -0,0 +1,16 @@ +// +// STPPaymentIntentAction.swift +// StripePayments +// +// Created by Yuki Tokuhiro on 3/8/19. +// Copyright © 2019 Stripe, Inc. All rights reserved. +// + +import Foundation + +/// Action details for an STPPaymentIntent. This is a container for +/// the various types that are available. Check the `type` to see which one +/// it is, and then use the related property for the details necessary to handle it. +/// @deprecated Use `STPIntentAction` instead. +@available(*, deprecated, message: "Use `STPIntentAction` instead.", renamed: "STPIntentAction") +@objc public final class STPPaymentIntentAction: STPIntentAction {} diff --git a/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentIntents/STPPaymentIntentActionRedirectToURL.swift b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentIntents/STPPaymentIntentActionRedirectToURL.swift new file mode 100644 index 0000000..4a56862 --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentIntents/STPPaymentIntentActionRedirectToURL.swift @@ -0,0 +1,19 @@ +// +// STPPaymentIntentActionRedirectToURL.swift +// StripePayments +// +// Created by Yuki Tokuhiro on 3/8/19. +// Copyright © 2019 Stripe, Inc. All rights reserved. +// + +import Foundation + +/// Contains instructions for authenticating a payment by redirecting your customer to another page or application. +/// @deprecated Use `STPIntentActionRedirectToURL` instead. +@available( + *, + unavailable, + message: "Use `STPIntentActionRedirectToURL` instead.", + renamed: "STPIntentActionRedirectToURL" +) +@objc public final class STPPaymentIntentActionRedirectToURL: STPIntentActionRedirectToURL {} diff --git a/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentIntents/STPPaymentIntentEnums.swift b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentIntents/STPPaymentIntentEnums.swift new file mode 100644 index 0000000..8919309 --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentIntents/STPPaymentIntentEnums.swift @@ -0,0 +1,135 @@ +// +// STPPaymentIntentEnums.swift +// StripePayments +// +// Created by Daniel Jackson on 6/27/18. +// Copyright © 2018 Stripe, Inc. All rights reserved. +// + +import Foundation + +/// Status types for an STPPaymentIntent +@objc public enum STPPaymentIntentStatus: Int { + /// Unknown status + case unknown + /// This PaymentIntent requires a PaymentMethod or Source + case requiresPaymentMethod + /// This PaymentIntent requires a Source + /// Deprecated: Use STPPaymentIntentStatusRequiresPaymentMethod instead. + @available( + *, + deprecated, + message: "Use STPPaymentIntentStatus.requiresPaymentMethod instead", + renamed: "STPPaymentIntentStatus.requiresPaymentMethod" + ) + case requiresSource + /// This PaymentIntent needs to be confirmed + case requiresConfirmation + /// The selected PaymentMethod or Source requires additional authentication steps. + /// Additional actions found via `next_action` + case requiresAction + /// The selected Source requires additional authentication steps. + /// Additional actions found via `next_source_action` + /// Deprecated: Use STPPaymentIntentStatusRequiresAction instead. + @available( + *, + deprecated, + message: "Use STPPaymentIntentStatus.requiresAction instead", + renamed: "STPPaymentIntentStatus.requiresAction" + ) + case requiresSourceAction + /// Stripe is processing this PaymentIntent + case processing + /// The payment has succeeded + case succeeded + /// Indicates the payment must be captured, for STPPaymentIntentCaptureMethodManual + case requiresCapture + /// This PaymentIntent was canceled and cannot be changed. + case canceled +} + +/// Indicates how you intend to use the payment method that your customer provides after the current payment completes. +/// If applicable, additional authentication may be performed to comply with regional legislation or network rules required to enable the usage of the same payment method for additional payments. +/// - seealso: https://stripe.com/docs/api/payment_intents/object#payment_intent_object-setup_future_usage +@objc public enum STPPaymentIntentSetupFutureUsage: Int { + /// Unknown value. Update your SDK, or use `allResponseFields` for custom handling. + case unknown + /// No value was provided. + case none + /// Indicates you intend to only reuse the payment method when the customer is in your checkout flow. + case onSession + /// Indicates you intend to reuse the payment method when the customer may or may not be in your checkout flow. + case offSession + + /// Parse the string and return the correct `STPPaymentIntentSetupFutureUsage`, + /// or `STPPaymentIntentSetupFutureUsageUnknown` if it's unrecognized by this version of the SDK. + /// - Parameter string: the NSString with the setup future usage value + internal init( + string: String + ) { + let map: [String: STPPaymentIntentSetupFutureUsage] = [ + "on_session": .onSession, + "off_session": .offSession, + ] + + let key = string.lowercased() + self = map[key] ?? .unknown + } + + var stringValue: String? { + switch self { + case .onSession: + return "on_session" + case .offSession: + return "off_session" + case .none, .unknown: + return nil + } + } +} + +// MARK: - Deprecated +/// Types of Actions from a `STPPaymentIntent`, when the payment intent +/// status is `STPPaymentIntentStatusRequiresAction`. +@objc public enum STPPaymentIntentActionType: Int { + /// This is an unknown action, that's been added since the SDK + /// was last updated. + /// Update your SDK, or use the `nextAction.allResponseFields` + /// for custom handling. + @available( + *, + deprecated, + message: "Use STPIntentActionType instead", + renamed: "STPIntentActionType.unknown" + ) + case unknown + /// The payment intent needs to be authorized by the user. We provide + /// `STPRedirectContext` to handle the url redirections necessary. + @available( + *, + deprecated, + message: "Use STPIntentActionType instead", + renamed: "STPIntentActionType.redirectToURL" + ) + case redirectToURL +} + +/// Types of Source Actions from a `STPPaymentIntent`, when the payment intent +/// status is `STPPaymentIntentStatusRequiresSourceAction`. +/// @deprecated Use`STPPaymentIntentActionType` instead. +@available( + *, + deprecated, + message: "Use STPIntentActionType instead", + renamed: "STPIntentActionType" +) +@objc public enum STPPaymentIntentSourceActionType: Int { + /// This is an unknown source action, that's been added since the SDK + /// was last updated. + /// Update your SDK, or use the `nextSourceAction.allResponseFields` + /// for custom handling. + case unknown + /// The payment intent needs to be authorized by the user. We provide + /// `STPRedirectContext` to handle the url redirections necessary. + case authorizeWithURL +} diff --git a/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentIntents/STPPaymentIntentLastPaymentError.swift b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentIntents/STPPaymentIntentLastPaymentError.swift new file mode 100644 index 0000000..358bd85 --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentIntents/STPPaymentIntentLastPaymentError.swift @@ -0,0 +1,174 @@ +// +// STPPaymentIntentLastPaymentError.swift +// StripePayments +// +// Created by Yuki Tokuhiro on 8/8/19. +// Copyright © 2019 Stripe, Inc. All rights reserved. +// + +import Foundation + +/// The type of the error represented by `STPPaymentIntentLastPaymentError`. +/// Some STPPaymentIntentLastPaymentError properties are only populated for certain error types. +@objc public enum STPPaymentIntentLastPaymentErrorType: Int { + + /// An unknown error type. + case unknown + + /// An error connecting to Stripe's API. + @objc(STPPaymentIntentLastPaymentErrorTypeAPIConnection) + case apiConnection + + /// An error with the Stripe API. + @objc(STPPaymentIntentLastPaymentErrorTypeAPI) + case api + + /// A failure to authenticate your customer. + case authentication + + /// Card errors are the most common type of error you should expect to handle. + /// They result when the user enters a card that can't be charged for some reason. + /// Check the `declineCode` property for the decline code. The `message` property contains a message you can show to your users. + case card + + /// Keys for idempotent requests can only be used with the same parameters they were first used with. + case idempotency + + /// Invalid request errors. Typically, this is because your request has invalid parameters. + case invalidRequest + + /// Too many requests hit the API too quickly. + case rateLimit + + internal init( + string: String + ) { + switch string.lowercased() { + case "api_connection_error": + self = .apiConnection + case "api_error": + self = .api + case "authentication_error": + self = .authentication + case "card_error": + self = .card + case "idempotency_error": + self = .idempotency + case "invalid_request_error": + self = .invalidRequest + case "rate_limit_error": + self = .rateLimit + default: + self = .unknown + } + } +} + +/// A value for `code` indicating the provided payment method failed authentication./// The payment error encountered in the previous PaymentIntent confirmation. +/// - seealso: https://stripe.com/docs/api/payment_intents/object#payment_intent_object-last_payment_error +public class STPPaymentIntentLastPaymentError: NSObject { + + /// A value for `code` indicating the provided payment method failed authentication. + @objc public static let ErrorCodeAuthenticationFailure = "payment_intent_authentication_failure" + + /// For some errors that could be handled programmatically, a short string indicating the error code reported. + /// - seealso: https://stripe.com/docs/error-codes + @objc public let code: String? + + /// For card (`STPPaymentIntentLastPaymentErrorType.card`) errors resulting from a card issuer decline, + /// a short string indicating the card issuer’s reason for the decline if they provide one. + /// - seealso: https://stripe.com/docs/declines#issuer-declines + @objc public let declineCode: String? + + /// A URL to more information about the error code reported. + /// - seealso: https://stripe.com/docs/error-codes + @objc public let docURL: String? + + /// A human-readable message providing more details about the error. + /// For card (`STPPaymentIntentLastPaymentErrorType.card`) errors, these messages can be shown to your users. + @objc public let message: String? + + /// If the error is parameter-specific, the parameter related to the error. + /// For example, you can use this to display a message near the correct form field. + @objc public let param: String? + + /// The PaymentMethod object for errors returned on a request involving a PaymentMethod. + @objc public let paymentMethod: STPPaymentMethod? + + /// The type of error. + @objc public let type: STPPaymentIntentLastPaymentErrorType + + /// :nodoc: + @objc public let allResponseFields: [AnyHashable: Any] + + /// :nodoc: + @objc public override var description: String { + let props: [String] = [ + // Object + String( + format: "%@: %p", + NSStringFromClass(STPPaymentIntentLastPaymentError.self), + self + ), + // PaymentIntentLastError details (alphabetical) + "code = \(String(describing: code))", + "declineCode = \(String(describing: declineCode))", + "docURL = \(String(describing: docURL))", + "message = \(String(describing: message))", + "param = \(String(describing: param))", + "paymentMethod = \(String(describing: paymentMethod))", + "type = \(String(describing: allResponseFields["type"]))", + ] + + return "<\(props.joined(separator: "; "))>" + } + + private init( + code: String?, + declineCode: String?, + docURL: String?, + message: String?, + param: String?, + paymentMethod: STPPaymentMethod?, + type: STPPaymentIntentLastPaymentErrorType, + allResponseFields: [AnyHashable: Any] + ) { + self.code = code + self.declineCode = declineCode + self.docURL = docURL + self.message = message + self.param = param + self.paymentMethod = paymentMethod + self.type = type + self.allResponseFields = allResponseFields + super.init() + } + +} + +// MARK: - STPAPIResponseDecodable +extension STPPaymentIntentLastPaymentError: STPAPIResponseDecodable { + + @objc + public class func decodedObject(fromAPIResponse response: [AnyHashable: Any]?) -> Self? { + guard let dict = response, + let typeString = dict["type"] as? String + else { + return nil + } + + return STPPaymentIntentLastPaymentError( + code: dict["code"] as? String, + declineCode: dict["decline_code"] as? String, + docURL: dict["doc_url"] as? String, + message: dict["message"] as? String, + param: dict["param"] as? String, + paymentMethod: STPPaymentMethod.decodedObject( + fromAPIResponse: dict["payment_method"] as? [AnyHashable: Any] + ), + type: STPPaymentIntentLastPaymentErrorType(string: typeString), + allResponseFields: dict + ) as? Self + } + +} diff --git a/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentIntents/STPPaymentIntentParams.swift b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentIntents/STPPaymentIntentParams.swift new file mode 100644 index 0000000..fb7bc13 --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentIntents/STPPaymentIntentParams.swift @@ -0,0 +1,298 @@ +// +// STPPaymentIntentParams.swift +// StripePayments +// +// Created by Daniel Jackson on 7/3/18. +// Copyright © 2018 Stripe, Inc. All rights reserved. +// + +import Foundation + +/// An object representing parameters used to confirm a PaymentIntent object. +/// A PaymentIntent must have a PaymentMethod or Source associated in order to successfully confirm it. +/// That PaymentMethod or Source can either be: +/// - created during confirmation, by passing in a `STPPaymentMethodParams` or `STPSourceParams` object in the `paymentMethodParams` or `sourceParams` field +/// - a pre-existing PaymentMethod or Source can be associated by passing its id in the `paymentMethodId` or `sourceId` field +/// - or already set via your backend, either when creating or updating the PaymentIntent +/// - seealso: https://stripe.com/docs/api#confirm_payment_intent +public class STPPaymentIntentParams: NSObject { + + /// Initialize this `STPPaymentIntentParams` with a `clientSecret`, which is the only required + /// field. + /// - Parameter clientSecret: the client secret for this PaymentIntent + @objc + public init( + clientSecret: String + ) { + self.clientSecret = clientSecret + super.init() + } + + /// Initializes this `STPPaymentIntentParams` with a `clientSecret` and `paymentMethodType`. + /// Use this initializer for PaymentIntents that already have a PaymentMethod attached. + /// - Parameter clientSecret: the client secret for this PaymentIntent + /// - Parameter paymentMethodType: the known type of the PaymentIntent's attached PaymentMethod + @objc + public init( + clientSecret: String, + paymentMethodType: STPPaymentMethodType + ) { + self.clientSecret = clientSecret + self._paymentMethodType = paymentMethodType + super.init() + } + + @objc convenience override init() { + self.init(clientSecret: "") + } + + /// The Stripe id of the PaymentIntent, extracted from the clientSecret. + @objc public var stripeId: String? { + return STPPaymentIntent.id(fromClientSecret: clientSecret) + } + + /// The client secret of the PaymentIntent. Required + @objc public var clientSecret: String + + /// Provide a supported `STPPaymentMethodParams` object, and Stripe will create a + /// PaymentMethod during PaymentIntent confirmation. + /// @note alternative to `paymentMethodId` + @objc public var paymentMethodParams: STPPaymentMethodParams? + + /// Provide an already created PaymentMethod's id, and it will be used to confirm the PaymentIntent. + /// @note alternative to `paymentMethodParams` + @objc public var paymentMethodId: String? + + /// Provide a supported `STPSourceParams` object into here, and Stripe will create a Source + /// during PaymentIntent confirmation. + /// @note alternative to `sourceId` + @objc public var sourceParams: STPSourceParams? + + /// Provide an already created Source's id, and it will be used to confirm the PaymentIntent. + /// @note alternative to `sourceParams` + @objc public var sourceId: String? + + /// Email address that the receipt for the resulting payment will be sent to. + @objc public var receiptEmail: String? + + /// `@YES` to save this PaymentIntent’s PaymentMethod or Source to the associated Customer, + /// if the PaymentMethod/Source is not already attached. + /// This should be a boolean NSNumber, so that it can be `nil` + @objc public var savePaymentMethod: NSNumber? + + /// The URL to redirect your customer back to after they authenticate or cancel + /// their payment on the payment method’s app or site. + /// This should probably be a URL that opens your iOS app. + @objc public var returnURL: String? + + /// When provided, this property indicates how you intend to use the payment method that your customer provides after the current payment completes. + /// If applicable, additional authentication may be performed to comply with regional legislation or network rules required to enable the usage of the same payment method for additional payments. + public var setupFutureUsage: STPPaymentIntentSetupFutureUsage? + + /// When provided, this property indicates how you intend to use the payment method that your customer provides after the current payment completes. + /// If applicable, additional authentication may be performed to comply with regional legislation or network rules required to enable the usage of the same payment method for additional payments. + /// This property should only be used in Objective-C. In Swift, use `setupFutureUsage`. + /// - seealso: STPPaymentIntentSetupFutureUsage for more details on what values you can provide. + @available(swift, obsoleted: 1.0, renamed: "setupFutureUsage") + @objc(setupFutureUsage) public var setupFutureUsage_objc: NSNumber? { + get { + setupFutureUsage?.rawValue as NSNumber? + } + set { + if let newValue = newValue { + setupFutureUsage = STPPaymentIntentSetupFutureUsage( + rawValue: Int(truncating: newValue) + ) + } else { + setupFutureUsage = nil + } + } + } + + /// A boolean number to indicate whether you intend to use the Stripe SDK's functionality to handle any PaymentIntent next actions. + /// If set to false, STPPaymentIntent.nextAction will only ever contain a redirect url that can be opened in a webview or mobile browser. + /// When set to true, the nextAction may contain information that the Stripe SDK can use to perform native authentication within your + /// app. + @objc public var useStripeSDK: NSNumber? + + internal var _paymentMethodType: STPPaymentMethodType? + internal var paymentMethodType: STPPaymentMethodType? { + if let type = _paymentMethodType { + return type + } + return paymentMethodParams?.type + } + + internal var _mandateData: STPMandateDataParams? + /// Details about the Mandate to create. + /// @note If this value is null and the (self.paymentMethod.type == STPPaymentMethodTypeSEPADebit | | self.paymentMethodParams.type == STPPaymentMethodTypeAUBECSDebit || self.paymentMethodParams.type == STPPaymentMethodTypeBacsDebit) && self.mandate == nil`, the SDK will set this to an internal value indicating that the mandate data should be inferred from the current context. + @objc public var mandateData: STPMandateDataParams? { + set { + _mandateData = newValue + } + get { + if let _mandateData = _mandateData { + return _mandateData + } + switch paymentMethodType { + case .AUBECSDebit, .bacsDebit, .bancontact, .iDEAL, .SEPADebit, .EPS, .sofort, .link, + .USBankAccount: + // Create default infer from client mandate_data + let onlineParams = STPMandateOnlineParams(ipAddress: "", userAgent: "") + onlineParams.inferFromClient = NSNumber(value: true) + + if let customerAcceptance = STPMandateCustomerAcceptanceParams( + type: .online, + onlineParams: onlineParams + ) { + return STPMandateDataParams(customerAcceptance: customerAcceptance) + } + default: break + } + return nil + } + } + + /// Options to update the associated PaymentMethod during confirmation. + /// - seealso: STPConfirmPaymentMethodOptions + @objc public var paymentMethodOptions: STPConfirmPaymentMethodOptions? + + /// Shipping information. + @objc public var shipping: STPPaymentIntentShippingDetailsParams? + + /// The URL to redirect your customer back to after they authenticate or cancel + /// their payment on the payment method’s app or site. + /// This property has been renamed to `returnURL` and deprecated. + @available(*, deprecated, renamed: "returnURL") + @objc public var returnUrl: String? { + get { + return returnURL + } + set(returnUrl) { + returnURL = returnUrl + } + } + /// `@YES` to save this PaymentIntent’s Source to the associated Customer, + /// if the Source is not already attached. + /// This should be a boolean NSNumber, so that it can be `nil` + /// This property has been renamed to `savePaymentMethod` and deprecated. + @available(*, deprecated, renamed: "savePaymentMethod") + @objc public var saveSourceToCustomer: NSNumber? { + get { + return savePaymentMethod + } + set(saveSourceToCustomer) { + savePaymentMethod = saveSourceToCustomer + } + } + + /// :nodoc: + @objc public var additionalAPIParameters: [AnyHashable: Any] = [:] + + /// :nodoc: + @objc public override var description: String { + let props: [String] = [ + // Object + String(format: "%@: %p", NSStringFromClass(STPPaymentIntentParams.self), self), + // Identifier + "stripeId = \(String(describing: stripeId))", + // PaymentIntentParams details (alphabetical) + "clientSecret = \((clientSecret.count > 0) ? "" : "")", + "receiptEmail = \(String(describing: receiptEmail))", + "returnURL = \(String(describing: returnURL))", + "savePaymentMethod = \(String(describing: savePaymentMethod?.boolValue))", + "setupFutureUsage = \(String(describing: setupFutureUsage))", + "shipping = \(String(describing: shipping))", + "useStripeSDK = \(String(describing: useStripeSDK?.boolValue))", + // Source + "sourceId = \(String(describing: sourceId))", + "sourceParams = \(String(describing: sourceParams))", + // PaymentMethod + "paymentMethodId = \(String(describing: paymentMethodId))", + "paymentMethodParams = \(String(describing: paymentMethodParams))", + // Mandate + "mandateData = \(String(describing: mandateData))", + // PaymentMethodOptions + "paymentMethodOptions = @\(String(describing: paymentMethodOptions))", + // Additional params set by app + "additionalAPIParameters = \(additionalAPIParameters)", + ] + + return "<\(props.joined(separator: "; "))>" + } + + static internal let isClientSecretValidRegex: NSRegularExpression? = try? NSRegularExpression( + pattern: "^pi_[^_]+_secret_[^_]+$", + options: [] + ) + + @_spi(STP) public class func isClientSecretValid(_ clientSecret: String) -> Bool { + + return + (isClientSecretValidRegex?.numberOfMatches( + in: clientSecret, + options: .anchored, + range: NSRange(location: 0, length: clientSecret.count) + )) == 1 + } +} + +// MARK: - STPFormEncodable +extension STPPaymentIntentParams: STPFormEncodable { + + @objc internal var setupFutureUsageRawString: String? { + return setupFutureUsage?.stringValue + } + + @objc + public class func rootObjectName() -> String? { + return nil + } + + @objc + public class func propertyNamesToFormFieldNamesMapping() -> [String: String] { + return [ + NSStringFromSelector(#selector(getter:clientSecret)): "client_secret", + NSStringFromSelector(#selector(getter:paymentMethodParams)): "payment_method_data", + NSStringFromSelector(#selector(getter:paymentMethodId)): "payment_method", + NSStringFromSelector(#selector(getter:setupFutureUsageRawString)): "setup_future_usage", + NSStringFromSelector(#selector(getter:sourceParams)): "source_data", + NSStringFromSelector(#selector(getter:sourceId)): "source", + NSStringFromSelector(#selector(getter:receiptEmail)): "receipt_email", + NSStringFromSelector(#selector(getter:savePaymentMethod)): "save_payment_method", + NSStringFromSelector(#selector(getter:returnURL)): "return_url", + NSStringFromSelector(#selector(getter:useStripeSDK)): "use_stripe_sdk", + NSStringFromSelector(#selector(getter:mandateData)): "mandate_data", + NSStringFromSelector(#selector(getter:paymentMethodOptions)): "payment_method_options", + NSStringFromSelector(#selector(getter:shipping)): "shipping", + ] + } +} + +// MARK: - NSCopying +extension STPPaymentIntentParams: NSCopying { + + /// :nodoc: + @objc + public func copy(with zone: NSZone? = nil) -> Any { + let copy = STPPaymentIntentParams(clientSecret: clientSecret) + + copy.paymentMethodParams = paymentMethodParams + copy._paymentMethodType = _paymentMethodType + copy.paymentMethodId = paymentMethodId + copy.sourceParams = sourceParams + copy.sourceId = sourceId + copy.receiptEmail = receiptEmail + copy.savePaymentMethod = savePaymentMethod + copy.returnURL = returnURL + copy.setupFutureUsage = setupFutureUsage + copy.useStripeSDK = useStripeSDK + copy.mandateData = mandateData + copy.paymentMethodOptions = paymentMethodOptions + copy.shipping = shipping + copy.additionalAPIParameters = additionalAPIParameters + + return copy + } + +} diff --git a/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentIntents/STPPaymentIntentShippingDetails.swift b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentIntents/STPPaymentIntentShippingDetails.swift new file mode 100644 index 0000000..38f8b99 --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentIntents/STPPaymentIntentShippingDetails.swift @@ -0,0 +1,90 @@ +// +// STPPaymentIntentShippingDetails.swift +// StripePayments +// +// Created by Yuki Tokuhiro on 4/27/20. +// Copyright © 2020 Stripe, Inc. All rights reserved. +// + +import Foundation + +/// Shipping information for a PaymentIntent +/// You cannot directly instantiate an `STPPaymentIntentShippingDetails`. +/// You should only use one that is part of an existing `STPPaymentMethod` object. +/// - seealso: https://stripe.com/docs/api/payment_intents/object#payment_intent_object-shipping +public class STPPaymentIntentShippingDetails: NSObject { + + /// Shipping address. + @objc public let address: STPPaymentIntentShippingDetailsAddress? + + /// Recipient name. + @objc public let name: String? + + /// The delivery service that shipped a physical product, such as Fedex, UPS, USPS, etc. + @objc public let carrier: String? + + /// Recipient phone (including extension). + @objc public let phone: String? + + /// The tracking number for a physical product, obtained from the delivery service. If multiple tracking numbers were generated for this purchase, please separate them with commas. + @objc public let trackingNumber: String? + + /// :nodoc: + @objc public let allResponseFields: [AnyHashable: Any] + + /// :nodoc: + @objc public override var description: String { + let props: [String] = [ + // Object + String(format: "%@: %p", NSStringFromClass(STPPaymentIntentShippingDetails.self), self), + // Properties + "address = \(String(describing: address))", + "name = \(String(describing: name))", + "carrier = \(String(describing: carrier))", + "phone = \(String(describing: phone))", + "trackingNumber = \(String(describing: trackingNumber))", + ] + + return "<\(props.joined(separator: "; "))>" + } + + private init( + address: STPPaymentIntentShippingDetailsAddress?, + name: String?, + carrier: String?, + phone: String?, + trackingNumber: String?, + allResponseFields: [AnyHashable: Any] + ) { + self.address = address + self.name = name + self.carrier = carrier + self.phone = phone + self.trackingNumber = trackingNumber + self.allResponseFields = allResponseFields + super.init() + } +} + +// MARK: - STPAPIResponseDecodable +extension STPPaymentIntentShippingDetails: STPAPIResponseDecodable { + + @objc + public class func decodedObject(fromAPIResponse response: [AnyHashable: Any]?) -> Self? { + guard let dict = response else { + return nil + } + + return STPPaymentIntentShippingDetails( + address: STPPaymentIntentShippingDetailsAddress.decodedObject( + fromAPIResponse: dict["address"] as? [AnyHashable: Any] + ), + name: dict["name"] as? String, + carrier: dict["carrier"] as? String, + phone: dict["phone"] as? String, + trackingNumber: dict["tracking_number"] as? String, + allResponseFields: dict + ) as? Self + } + +} diff --git a/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentIntents/STPPaymentIntentShippingDetailsAddress.swift b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentIntents/STPPaymentIntentShippingDetailsAddress.swift new file mode 100644 index 0000000..c81265b --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentIntents/STPPaymentIntentShippingDetailsAddress.swift @@ -0,0 +1,99 @@ +// +// STPPaymentIntentShippingDetailsAddress.swift +// StripePayments +// +// Created by Yuki Tokuhiro on 4/27/20. +// Copyright © 2020 Stripe, Inc. All rights reserved. +// + +import Foundation + +/// Shipping address for a PaymentIntent's shipping details. +/// You cannot directly instantiate an `STPPaymentIntentShippingDetailsAddress`. +/// You should only use one that is part of an existing `STPPaymentMethod` object. +/// - seealso: https://stripe.com/docs/api/payment_intents/object#payment_intent_object-shipping +public class STPPaymentIntentShippingDetailsAddress: NSObject { + + /// City/District/Suburb/Town/Village. + @objc public let city: String? + + /// Two-letter country code (ISO 3166-1 alpha-2). + @objc public let country: String? + + /// Address line 1 (Street address/PO Box/Company name). + @objc public let line1: String? + + /// Address line 2 (Apartment/Suite/Unit/Building). + @objc public let line2: String? + + /// ZIP or postal code. + @objc public let postalCode: String? + + /// State/County/Province/Region. + @objc public let state: String? + + /// :nodoc: + @objc public let allResponseFields: [AnyHashable: Any] + + /// :nodoc: + @objc public override var description: String { + let props = [ + // Object + String( + format: "%@: %p", + NSStringFromClass(STPPaymentIntentShippingDetailsAddress.self), + self + ), + // Properties + "line1 = \(String(describing: line1))", + "line2 = \(String(describing: line2))", + "city = \(String(describing: city))", + "state = \(String(describing: state))", + "postalCode = \(String(describing: postalCode))", + "country = \(String(describing: country))", + ] + + return "<\(props.joined(separator: "; "))>" + } + + private init( + city: String?, + country: String?, + line1: String?, + line2: String?, + postalCode: String?, + state: String?, + allResponseFields: [AnyHashable: Any] + ) { + self.city = city + self.country = country + self.line1 = line1 + self.line2 = line2 + self.postalCode = postalCode + self.state = state + self.allResponseFields = allResponseFields + super.init() + } +} + +// MARK: - STPAPIResponseDecodable +extension STPPaymentIntentShippingDetailsAddress: STPAPIResponseDecodable { + + @objc + public class func decodedObject(fromAPIResponse response: [AnyHashable: Any]?) -> Self? { + guard let dict = response else { + return nil + } + + return STPPaymentIntentShippingDetailsAddress( + city: dict["city"] as? String, + country: dict["country"] as? String, + line1: dict["line1"] as? String, + line2: dict["line2"] as? String, + postalCode: dict["postal_code"] as? String, + state: dict["state"] as? String, + allResponseFields: dict + ) as? Self + } + +} diff --git a/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentIntents/STPPaymentIntentShippingDetailsAddressParams.swift b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentIntents/STPPaymentIntentShippingDetailsAddressParams.swift new file mode 100644 index 0000000..0b34453 --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentIntents/STPPaymentIntentShippingDetailsAddressParams.swift @@ -0,0 +1,116 @@ +// +// STPPaymentIntentShippingDetailsAddressParams.swift +// StripePayments +// +// Created by Yuki Tokuhiro on 4/27/20. +// Copyright © 2020 Stripe, Inc. All rights reserved. +// + +import Contacts +import Foundation + +/// Shipping address for a PaymentIntent's shipping details. +/// - seealso: https://stripe.com/docs/api/payment_intents/confirm#confirm_payment_intent-shipping-address +public class STPPaymentIntentShippingDetailsAddressParams: NSObject { + + /// City/District/Suburb/Town/Village. + @objc public var city: String? + + /// Two-letter country code (ISO 3166-1 alpha-2). + @objc public var country: String? + + /// Address line 1 (Street address/PO Box/Company name). + @objc public var line1: String + + /// Address line 2 (Apartment/Suite/Unit/Building). + @objc public var line2: String? + + /// ZIP or postal code. + @objc public var postalCode: String? + + /// State/County/Province/Region. + @objc public var state: String? + + @objc public var additionalAPIParameters: [AnyHashable: Any] = [:] + + /// Initialize an `STPPaymentIntentShippingDetailsAddressParams` instance with required properties. + @objc + public init( + line1: String + ) { + self.line1 = line1 + super.init() + } + + /// :nodoc: + @objc public override var description: String { + let props = [ + // Object + String( + format: "%@: %p", + NSStringFromClass(STPPaymentIntentShippingDetailsAddressParams.self), + self + ), + // Properties + "line1 = \(line1)", + "line2 = \(String(describing: line2))", + "city = \(String(describing: city))", + "state = \(String(describing: state))", + "postalCode = \(String(describing: postalCode))", + "country = \(String(describing: country))", + ] + + return "<\(props.joined(separator: "; "))>" + } + + public override func isEqual(_ object: Any?) -> Bool { + guard let other = object as? Self else { + return false + } + return other.city == city && other.country == country && other.line1 == line1 + && other.line2 == line2 && other.postalCode == postalCode && other.state == state + } +} + +// MARK: - STPFormEncodable +extension STPPaymentIntentShippingDetailsAddressParams: STPFormEncodable { + + @objc + public class func propertyNamesToFormFieldNamesMapping() -> [String: String] { + return [ + NSStringFromSelector(#selector(getter:line1)): "line1", + NSStringFromSelector(#selector(getter:line2)): "line2", + NSStringFromSelector(#selector(getter:city)): "city", + NSStringFromSelector(#selector(getter:country)): "country", + NSStringFromSelector(#selector(getter:state)): "state", + NSStringFromSelector(#selector(getter:CNMutablePostalAddress.postalCode)): + "postal_code", + ] + } + + @objc + public class func rootObjectName() -> String? { + return nil + } + +} + +// MARK: - NSCopying +extension STPPaymentIntentShippingDetailsAddressParams: NSCopying { + /// :nodoc: + @objc + public func copy(with zone: NSZone? = nil) -> Any { + let copy = STPPaymentIntentShippingDetailsAddressParams(line1: line1) + + copy.line1 = line1 + copy.line2 = line2 + copy.city = city + copy.country = country + copy.state = state + copy.postalCode = postalCode + copy.additionalAPIParameters = additionalAPIParameters + + return copy + } + +} diff --git a/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentIntents/STPPaymentIntentShippingDetailsParams.swift b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentIntents/STPPaymentIntentShippingDetailsParams.swift new file mode 100644 index 0000000..86cf078 --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentIntents/STPPaymentIntentShippingDetailsParams.swift @@ -0,0 +1,110 @@ +// +// STPPaymentIntentShippingDetailsParams.swift +// StripePayments +// +// Created by Yuki Tokuhiro on 4/27/20. +// Copyright © 2020 Stripe, Inc. All rights reserved. +// + +import Foundation + +/// Shipping information for a PaymentIntent +/// - seealso: https://stripe.com/docs/api/payment_intents/confirm#confirm_payment_intent-shipping +public class STPPaymentIntentShippingDetailsParams: NSObject { + + /// Shipping address. + @objc public var address: STPPaymentIntentShippingDetailsAddressParams + + /// Recipient name. + @objc public var name: String + + /// The delivery service that shipped a physical product, such as Fedex, UPS, USPS, etc. + @objc public var carrier: String? + + /// Recipient phone (including extension). + @objc public var phone: String? + + /// The tracking number for a physical product, obtained from the delivery service. If multiple tracking numbers were generated for this purchase, please separate them with commas. + @objc public var trackingNumber: String? + + /// :nodoc: + @objc public var additionalAPIParameters: [AnyHashable: Any] = [:] + + /// Initialize an `STPPaymentIntentShippingDetailsParams` with required properties. + @objc + public init( + address: STPPaymentIntentShippingDetailsAddressParams, + name: String + ) { + self.address = address + self.name = name + super.init() + + } + + /// :nodoc: + @objc public override var description: String { + let props: [String] = [ + // Object + String( + format: "%@: %p", + NSStringFromClass(STPPaymentIntentShippingDetailsParams.self), + self + ), + // Properties + "address = \(address)", + "name = \(name)", + "carrier = \(String(describing: carrier))", + "phone = \(String(describing: phone))", + "trackingNumber = \(String(describing: trackingNumber))", + ] + + return "<\(props.joined(separator: "; "))>" + } + + public override func isEqual(_ object: Any?) -> Bool { + guard let other = object as? Self else { + return false + } + return other.name == name && other.carrier == carrier && other.phone == phone + && other.trackingNumber == trackingNumber && other.address == address + } +} + +// MARK: - STPFormEncodable +extension STPPaymentIntentShippingDetailsParams: STPFormEncodable { + + @objc + public class func propertyNamesToFormFieldNamesMapping() -> [String: String] { + return [ + NSStringFromSelector(#selector(getter:address)): "address", + NSStringFromSelector(#selector(getter:name)): "name", + NSStringFromSelector(#selector(getter:carrier)): "carrier", + NSStringFromSelector(#selector(getter:phone)): "phone", + NSStringFromSelector(#selector(getter:trackingNumber)): "tracking_number", + ] + } + + @objc + public class func rootObjectName() -> String? { + return nil + } + +} + +// MARK: - NSCopying +extension STPPaymentIntentShippingDetailsParams: NSCopying { + /// :nodoc: + @objc + public func copy(with zone: NSZone? = nil) -> Any { + let copy = STPPaymentIntentShippingDetailsParams(address: address, name: name) + + copy.carrier = carrier + copy.phone = phone + copy.trackingNumber = trackingNumber + copy.additionalAPIParameters = additionalAPIParameters + + return copy + } + +} diff --git a/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentIntents/STPPaymentIntentSourceAction.swift b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentIntents/STPPaymentIntentSourceAction.swift new file mode 100644 index 0000000..a16e114 --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentIntents/STPPaymentIntentSourceAction.swift @@ -0,0 +1,17 @@ +// +// STPPaymentIntentSourceAction.swift +// StripePayments +// +// Created by Daniel Jackson on 11/7/18. +// Copyright © 2018 Stripe, Inc. All rights reserved. +// + +import Foundation + +/// Source Action details for an STPPaymentIntent. This is a container for +/// the various types that are available. Check the `type` to see which one +/// it is, and then use the related property for the details necessary to handle +/// it. +/// @deprecated Use `STPIntentAction` instead. +@available(*, unavailable, message: "Use `STPIntentAction` instead.", renamed: "STPIntentAction") +@objc public final class STPPaymentIntentSourceAction: STPIntentAction {} diff --git a/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentIntents/STPPaymentIntentSourceActionAuthorizeWithURL.swift b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentIntents/STPPaymentIntentSourceActionAuthorizeWithURL.swift new file mode 100644 index 0000000..bf2dee3 --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentIntents/STPPaymentIntentSourceActionAuthorizeWithURL.swift @@ -0,0 +1,21 @@ +// +// STPPaymentIntentSourceActionAuthorizeWithURL.swift +// StripePayments +// +// Created by Daniel Jackson on 11/7/18. +// Copyright © 2018 Stripe, Inc. All rights reserved. +// + +import Foundation + +/// The `STPPaymentIntentSourceAction` details when type is `STPPaymentIntentSourceActionTypeAuthorizeWithURL`. +/// These are created & owned by the containing `STPPaymentIntent`. +/// @deprecated Use `STPIntentActionRedirectToURL` instead. +@available( + *, + unavailable, + message: "Use `STPIntentActionRedirectToURL` instead.", + renamed: "STPIntentActionRedirectToURL" +) +@objc public final class STPPaymentIntentSourceActionAuthorizeWithURL: STPIntentActionRedirectToURL +{} diff --git a/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/STPPaymentMethod.swift b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/STPPaymentMethod.swift new file mode 100644 index 0000000..4079581 --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/STPPaymentMethod.swift @@ -0,0 +1,321 @@ +// +// STPPaymentMethod.swift +// StripePayments +// +// Created by Yuki Tokuhiro on 3/5/19. +// Copyright © 2019 Stripe, Inc. All rights reserved. +// + +import Foundation +@_spi(STP) import StripeCore +import UIKit + +/// PaymentMethod objects represent your customer's payment instruments. They can be used with PaymentIntents to collect payments. +/// - seealso: https://stripe.com/docs/api/payment_methods +public class STPPaymentMethod: NSObject, STPAPIResponseDecodable { + /// Unique identifier for the object. + @objc private(set) public var stripeId: String + /// Time at which the object was created. Measured in seconds since the Unix epoch. + @objc private(set) public var created: Date? + /// `YES` if the object exists in live mode or the value `NO` if the object exists in test mode. + @objc private(set) public var liveMode = false + /// The type of the PaymentMethod. The corresponding, similarly named property contains additional information specific to the PaymentMethod type. + /// e.g. if the type is `STPPaymentMethodTypeCard`, the `card` property is also populated. + @objc private(set) public var type: STPPaymentMethodType = .unknown + /// Billing information associated with the PaymentMethod that may be used or required by particular types of payment methods. + @objc private(set) public var billingDetails: STPPaymentMethodBillingDetails? + /// If this is an Alipay PaymentMethod (ie `self.type == STPPaymentMethodTypeAlipay`), this contains additional detailsl + @objc private(set) public var alipay: STPPaymentMethodAlipay? + /// If this is a GrabPay PaymentMethod (ie `self.type == STPPaymentMethodTypeGrabPay`), this contains additional details. + @objc private(set) public var grabPay: STPPaymentMethodGrabPay? + /// If this is a card PaymentMethod (ie `self.type == STPPaymentMethodTypeCard`), this contains additional details. + @objc private(set) public var card: STPPaymentMethodCard? + /// If this is a iDEAL PaymentMethod (ie `self.type == STPPaymentMethodTypeiDEAL`), this contains additional details. + @objc private(set) public var iDEAL: STPPaymentMethodiDEAL? + /// If this is an FPX PaymentMethod (ie `self.type == STPPaymentMethodTypeFPX`), this contains additional details. + @objc private(set) public var fpx: STPPaymentMethodFPX? + /// If this is a card present PaymentMethod (ie `self.type == STPPaymentMethodTypeCardPresent`), this contains additional details. + @objc private(set) public var cardPresent: STPPaymentMethodCardPresent? + /// If this is a SEPA Debit PaymentMethod (ie `self.type == STPPaymentMethodTypeSEPADebit`), this contains additional details. + @objc private(set) public var sepaDebit: STPPaymentMethodSEPADebit? + /// If this is a Bacs Debit PaymentMethod (ie `self.type == STPPaymentMethodTypeBacsDebit`), this contains additional details. + @objc private(set) public var bacsDebit: STPPaymentMethodBacsDebit? + /// If this is an AU BECS Debit PaymentMethod (i.e. `self.type == STPPaymentMethodTypeAUBECSDebit`), this contains additional details. + @objc private(set) public var auBECSDebit: STPPaymentMethodAUBECSDebit? + /// If this is a giropay PaymentMethod (i.e. `self.type == STPPaymentMethodTypeGiropay`), this contains additional details. + @objc private(set) public var giropay: STPPaymentMethodGiropay? + /// If this is an EPS PaymentMethod (i.e. `self.type == STPPaymentMethodTypeEPS`), this contains additional details. + @objc private(set) public var eps: STPPaymentMethodEPS? + /// If this is a Przelewy24 PaymentMethod (i.e. `self.type == STPPaymentMethodTypePrzelewy24`), this contains additional details. + @objc private(set) public var przelewy24: STPPaymentMethodPrzelewy24? + /// If this is a Bancontact PaymentMethod (i.e. `self.type == STPPaymentMethodTypeBancontact`), this contains additional details. + @objc private(set) public var bancontact: STPPaymentMethodBancontact? + /// If this is a NetBanking PaymentMethod (i.e. `self.type == STPPaymentMethodTypeNetBanking`), this contains additional details. + @objc private(set) public var netBanking: STPPaymentMethodNetBanking? + /// If this is an OXXO PaymentMethod (i.e. `self.type == STPPaymentMethodTypeOXXO`), this contains additional details. + @objc private(set) public var oxxo: STPPaymentMethodOXXO? + /// If this is a Sofort PaymentMethod (i.e. `self.type == STPPaymentMethodTypeSofort`), this contains additional details. + @objc private(set) public var sofort: STPPaymentMethodSofort? + /// If this is a UPI PaymentMethod (i.e. `self.type == STPPaymentMethodTypeUPI`), this contains additional details. :nodoc: + @objc private(set) public var upi: STPPaymentMethodUPI? + /// If this is a PayPal PaymentMethod (i.e. `self.type == STPPaymentMethodTypePayPal`), this contains additional details. :nodoc: + @objc private(set) public var payPal: STPPaymentMethodPayPal? + /// If this is an AfterpayClearpay PaymentMethod (i.e. `self.type == STPPaymentMethodTypeAfterpayClearpay`), this contains additional details. :nodoc: + @objc private(set) public var afterpayClearpay: STPPaymentMethodAfterpayClearpay? + /// If this is a BLIK PaymentMethod (i.e. `self.type == STPPaymentMethodTypeBLIK`), this contains additional details. :nodoc: + @objc private(set) public var blik: STPPaymentMethodBLIK? + /// If this is a WeChat Pay PaymentMethod (i.e. `self.type == STPPaymentMethodTypeWeChatPay`), this contains additional details. + @objc private(set) var weChatPay: STPPaymentMethodWeChatPay? + /// If this is an Boleto PaymentMethod (i.e. `self.type == STPPaymentMethodTypeBoleto`), this contains additional details. + @objc private(set) public var boleto: STPPaymentMethodBoleto? + /// If this is a Link PaymentMethod (i.e. `self.type == STPPaymentMethodTypeLink`), this contains additional details. + @objc private(set) public var link: STPPaymentMethodLink? + /// If this is an Klarna PaymentMethod (i.e. `self.type == STPPaymentMethodTypeKlarna`), this contains additional details. + @objc private(set) public var klarna: STPPaymentMethodKlarna? + /// If this is an Affirm PaymentMethod (i.e. `self.type == STPPaymentMethodTypeAffirm`), this contains additional details. + @objc private(set) public var affirm: STPPaymentMethodAffirm? + /// If this is a US Bank Account PaymentMethod (i.e. `self.type == STPPaymentMethodTypeUSBankAccount`), this contains additional details. + @objc private(set) public var usBankAccount: STPPaymentMethodUSBankAccount? + /// The ID of the Customer to which this PaymentMethod is saved. Nil when the PaymentMethod has not been saved to a Customer. + @objc private(set) public var customerId: String? + // MARK: - Deprecated + + /// Set of key-value pairs that you can attach to an object. This can be useful for storing additional information about the object in a structured format. + /// @deprecated Metadata is no longer returned to clients using publishable keys. Retrieve them on your server using yoursecret key instead. + /// - seealso: https://stripe.com/docs/api#metadata + @available( + *, + deprecated, + message: + "Metadata is no longer returned to clients using publishable keys. Retrieve them on your server using your secret key instead." + ) + @objc private(set) public var metadata: [String: String]? + + /// :nodoc: + @objc private(set) public var allResponseFields: [AnyHashable: Any] = [:] + + /// :nodoc: + @objc public override var description: String { + let props = [ + // Object + String(format: "%@: %p", NSStringFromClass(STPPaymentMethod.self), self), + // Identifier + "stripeId = \(stripeId)", + // STPPaymentMethod details (alphabetical) + "alipay = \(String(describing: alipay))", + "auBECSDebit = \(String(describing: auBECSDebit))", + "bacsDebit = \(String(describing: bacsDebit))", + "bancontact = \(String(describing: bancontact))", + "billingDetails = \(String(describing: billingDetails))", + "card = \(String(describing: card))", + "cardPresent = \(String(describing: cardPresent))", + "created = \(String(describing: created))", + "customerId = \(customerId ?? "")", + "ideal = \(String(describing: iDEAL))", + "eps = \(String(describing: eps))", + "fpx = \(String(describing: fpx))", + "giropay = \(String(describing: giropay))", + "netBanking = \(String(describing: netBanking))", + "oxxo = \(String(describing: oxxo))", + "grabPay = \(String(describing: grabPay))", + "payPal = \(String(describing: payPal))", + "przelewy24 = \(String(describing: przelewy24))", + "sepaDebit = \(String(describing: sepaDebit))", + "sofort = \(String(describing: sofort))", + "upi = \(String(describing: upi))", + "afterpay_clearpay = \(String(describing: afterpayClearpay))", + "blik = \(String(describing: blik))", + "weChatPay = \(String(describing: weChatPay))", + "boleto = \(String(describing: boleto))", + "link = \(String(describing: link))", + "klarna = \(String(describing: klarna))", + "affirm = \(String(describing: affirm))", + "usBankAccount = \(String(describing: usBankAccount))", + "liveMode = \(liveMode ? "YES" : "NO")", + "type = \(allResponseFields["type"] as? String ?? "")", + ] + return "<\(props.joined(separator: "; "))>" + } + + // MARK: - STPPaymentMethodType + class func stringToTypeMapping() -> [String: NSNumber] { + return [ + "card": NSNumber(value: STPPaymentMethodType.card.rawValue), + "ideal": NSNumber(value: STPPaymentMethodType.iDEAL.rawValue), + "fpx": NSNumber(value: STPPaymentMethodType.FPX.rawValue), + "card_present": NSNumber(value: STPPaymentMethodType.cardPresent.rawValue), + "sepa_debit": NSNumber(value: STPPaymentMethodType.SEPADebit.rawValue), + "bacs_debit": NSNumber(value: STPPaymentMethodType.bacsDebit.rawValue), + "au_becs_debit": NSNumber(value: STPPaymentMethodType.AUBECSDebit.rawValue), + "grabpay": NSNumber(value: STPPaymentMethodType.grabPay.rawValue), + "giropay": NSNumber(value: STPPaymentMethodType.giropay.rawValue), + "p24": NSNumber(value: STPPaymentMethodType.przelewy24.rawValue), + "eps": NSNumber(value: STPPaymentMethodType.EPS.rawValue), + "bancontact": NSNumber(value: STPPaymentMethodType.bancontact.rawValue), + "netbanking": NSNumber(value: STPPaymentMethodType.netBanking.rawValue), + "oxxo": NSNumber(value: STPPaymentMethodType.OXXO.rawValue), + "sofort": NSNumber(value: STPPaymentMethodType.sofort.rawValue), + "upi": NSNumber(value: STPPaymentMethodType.UPI.rawValue), + "alipay": NSNumber(value: STPPaymentMethodType.alipay.rawValue), + "paypal": NSNumber(value: STPPaymentMethodType.payPal.rawValue), + "afterpay_clearpay": NSNumber(value: STPPaymentMethodType.afterpayClearpay.rawValue), + "blik": NSNumber(value: STPPaymentMethodType.blik.rawValue), + "link": NSNumber(value: STPPaymentMethodType.link.rawValue), + "wechat_pay": NSNumber(value: STPPaymentMethodType.weChatPay.rawValue), + "boleto": NSNumber(value: STPPaymentMethodType.boleto.rawValue), + "klarna": NSNumber(value: STPPaymentMethodType.klarna.rawValue), + "affirm": NSNumber(value: STPPaymentMethodType.affirm.rawValue), + "us_bank_account": NSNumber(value: STPPaymentMethodType.USBankAccount.rawValue), + ] + } + + @_spi(STP) public class func string(from type: STPPaymentMethodType) -> String? { + return + (self.stringToTypeMapping() as NSDictionary).allKeys( + for: NSNumber(value: type.rawValue) + ) + .first as? String + } + + @_spi(STP) public class func type(from string: String) -> STPPaymentMethodType { + let key = string.lowercased() + let typeNumber = self.stringToTypeMapping()[key] + + if let typeNumber = typeNumber { + return STPPaymentMethodType(rawValue: Int(truncating: typeNumber)) ?? .unknown + } + + return .unknown + } + + class func types(from strings: [String]) -> [NSNumber] { + var types: [AnyHashable] = [] + for string in strings { + types.append(NSNumber(value: self.type(from: string).rawValue)) + } + return types as? [NSNumber] ?? [] + } + + class func paymentMethodTypes(from strings: [String]) -> [STPPaymentMethodType] { + var types: [STPPaymentMethodType] = [] + for string in strings { + types.append(self.type(from: string)) + } + return types + } + + // MARK: - STPAPIResponseDecodable + /// :nodoc: + @objc required init( + stripeId: String + ) { + self.stripeId = stripeId + super.init() + } + + @objc + public class func decodedObject(fromAPIResponse response: [AnyHashable: Any]?) -> Self? { + guard let response = response else { + return nil + } + let dict = response.stp_dictionaryByRemovingNulls() + + // Required fields + guard let stripeId = dict.stp_string(forKey: "id") else { + return nil + } + + let paymentMethod = self.init(stripeId: stripeId) + paymentMethod.allResponseFields = response + paymentMethod.stripeId = stripeId + paymentMethod.created = dict.stp_date(forKey: "created") + paymentMethod.liveMode = dict.stp_bool(forKey: "livemode", or: false) + paymentMethod.billingDetails = STPPaymentMethodBillingDetails.decodedObject( + fromAPIResponse: dict.stp_dictionary(forKey: "billing_details") + ) + paymentMethod.card = STPPaymentMethodCard.decodedObject( + fromAPIResponse: dict.stp_dictionary(forKey: "card") + ) + paymentMethod.type = self.type(from: dict.stp_string(forKey: "type") ?? "") + paymentMethod.iDEAL = STPPaymentMethodiDEAL.decodedObject( + fromAPIResponse: dict.stp_dictionary(forKey: "ideal") + ) + if let stp = dict.stp_dictionary(forKey: "fpx") { + paymentMethod.fpx = STPPaymentMethodFPX.decodedObject(fromAPIResponse: stp) + } + if let stp = dict.stp_dictionary(forKey: "card_present") { + paymentMethod.cardPresent = STPPaymentMethodCardPresent.decodedObject( + fromAPIResponse: stp + ) + } + paymentMethod.sepaDebit = STPPaymentMethodSEPADebit.decodedObject( + fromAPIResponse: dict.stp_dictionary(forKey: "sepa_debit") + ) + paymentMethod.bacsDebit = STPPaymentMethodBacsDebit.decodedObject( + fromAPIResponse: dict.stp_dictionary(forKey: "bacs_debit") + ) + paymentMethod.auBECSDebit = STPPaymentMethodAUBECSDebit.decodedObject( + fromAPIResponse: dict.stp_dictionary(forKey: "au_becs_debit") + ) + paymentMethod.giropay = STPPaymentMethodGiropay.decodedObject( + fromAPIResponse: dict.stp_dictionary(forKey: "giropay") + ) + paymentMethod.eps = STPPaymentMethodEPS.decodedObject( + fromAPIResponse: dict.stp_dictionary(forKey: "eps") + ) + paymentMethod.przelewy24 = STPPaymentMethodPrzelewy24.decodedObject( + fromAPIResponse: dict.stp_dictionary(forKey: "p24") + ) + paymentMethod.bancontact = STPPaymentMethodBancontact.decodedObject( + fromAPIResponse: dict.stp_dictionary(forKey: "bancontact") + ) + paymentMethod.netBanking = STPPaymentMethodNetBanking.decodedObject( + fromAPIResponse: dict.stp_dictionary(forKey: "netbanking") + ) + paymentMethod.oxxo = STPPaymentMethodOXXO.decodedObject( + fromAPIResponse: dict.stp_dictionary(forKey: "oxxo") + ) + paymentMethod.sofort = STPPaymentMethodSofort.decodedObject( + fromAPIResponse: dict.stp_dictionary(forKey: "sofort") + ) + paymentMethod.upi = STPPaymentMethodUPI.decodedObject( + fromAPIResponse: dict.stp_dictionary(forKey: "upi") + ) + paymentMethod.customerId = dict.stp_string(forKey: "customer") + paymentMethod.alipay = STPPaymentMethodAlipay.decodedObject( + fromAPIResponse: dict.stp_dictionary(forKey: "alipay") + ) + paymentMethod.grabPay = STPPaymentMethodGrabPay.decodedObject( + fromAPIResponse: dict.stp_dictionary(forKey: "grabpay") + ) + paymentMethod.payPal = STPPaymentMethodPayPal.decodedObject( + fromAPIResponse: dict.stp_dictionary(forKey: "paypal") + ) + paymentMethod.afterpayClearpay = STPPaymentMethodAfterpayClearpay.decodedObject( + fromAPIResponse: dict.stp_dictionary(forKey: "afterpay_clearpay") + ) + paymentMethod.blik = STPPaymentMethodBLIK.decodedObject( + fromAPIResponse: dict.stp_dictionary(forKey: "blik") + ) + paymentMethod.weChatPay = STPPaymentMethodWeChatPay.decodedObject( + fromAPIResponse: dict.stp_dictionary(forKey: "wechat_pay") + ) + paymentMethod.boleto = STPPaymentMethodBoleto.decodedObject( + fromAPIResponse: dict.stp_dictionary(forKey: "boleto") + ) + paymentMethod.link = STPPaymentMethodLink.decodedObject( + fromAPIResponse: dict.stp_dictionary(forKey: "link") + ) + paymentMethod.klarna = STPPaymentMethodKlarna.decodedObject( + fromAPIResponse: dict.stp_dictionary(forKey: "klarna") + ) + paymentMethod.affirm = STPPaymentMethodAffirm.decodedObject( + fromAPIResponse: dict.stp_dictionary(forKey: "affirm") + ) + paymentMethod.usBankAccount = STPPaymentMethodUSBankAccount.decodedObject( + fromAPIResponse: dict.stp_dictionary(forKey: "us_bank_account") + ) + + return paymentMethod + } +} diff --git a/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/STPPaymentMethodAddress.swift b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/STPPaymentMethodAddress.swift new file mode 100644 index 0000000..a217ec1 --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/STPPaymentMethodAddress.swift @@ -0,0 +1,143 @@ +// +// STPPaymentMethodAddress.swift +// StripePayments +// +// Created by Yuki Tokuhiro on 3/5/19. +// Copyright © 2019 Stripe, Inc. All rights reserved. +// + +import Contacts +import Foundation + +/// The billing address, a property on `STPPaymentMethodBillingDetails` +public class STPPaymentMethodAddress: NSObject, STPAPIResponseDecodable, STPFormEncodable { + @objc public var additionalAPIParameters: [AnyHashable: Any] = [:] + + /// City/District/Suburb/Town/Village. + @objc public var city: String? + /// 2-letter country code. + @objc public var country: String? + /// Address line 1 (Street address/PO Box/Company name). + @objc public var line1: String? + /// Address line 2 (Apartment/Suite/Unit/Building). + @objc public var line2: String? + /// ZIP or postal code. + @objc public var postalCode: String? + /// State/County/Province/Region. + @objc public var state: String? + + /// Convenience initializer for creating a STPPaymentMethodAddress from an STPAddress. + @objc + public init( + address: STPAddress + ) { + super.init() + city = address.city + country = address.country + line1 = address.line1 + line2 = address.line2 + postalCode = address.postalCode + state = address.state + } + + /// :nodoc: + @objc public required override init() { + super.init() + } + + /// :nodoc: + private(set) public var allResponseFields: [AnyHashable: Any] = [:] + + /// :nodoc: + @objc public override var description: String { + let props = [ + // Object + String(format: "%@: %p", NSStringFromClass(STPPaymentMethodAddress.self), self), + // Properties + "line1 = \(line1 ?? "")", + "line2 = \(line2 ?? "")", + "city = \(city ?? "")", + "state = \(state ?? "")", + "postalCode = \(postalCode ?? "")", + "country = \(country ?? "")", + ] + + return "<\(props.joined(separator: "; "))>" + } + + // MARK: - STPFormEncodable + + @objc + public class func propertyNamesToFormFieldNamesMapping() -> [String: String] { + return [ + NSStringFromSelector(#selector(getter:line1)): "line1", + NSStringFromSelector(#selector(getter:line2)): "line2", + NSStringFromSelector(#selector(getter:city)): "city", + NSStringFromSelector(#selector(getter:country)): "country", + NSStringFromSelector(#selector(getter:state)): "state", + NSStringFromSelector(#selector(getter:CNMutablePostalAddress.postalCode)): + "postal_code", + ] + } + + @objc + public class func rootObjectName() -> String? { + return nil + } + + // MARK: - NSCopying + @objc(copyWithZone:) func copy(with zone: NSZone? = nil) -> Any { + let copyPaymentMethodAddress = type(of: self).init() + + copyPaymentMethodAddress.allResponseFields = allResponseFields + copyPaymentMethodAddress.city = city + copyPaymentMethodAddress.country = country + copyPaymentMethodAddress.line1 = line1 + copyPaymentMethodAddress.line2 = line2 + copyPaymentMethodAddress.postalCode = postalCode + copyPaymentMethodAddress.state = state + return copyPaymentMethodAddress + } + + // MARK: - Equality + /// :nodoc: + @objc + public override func isEqual(_ other: Any?) -> Bool { + return isEqual(to: other as? STPPaymentMethodAddress) + } + + func isEqual(to other: STPPaymentMethodAddress?) -> Bool { + if self === other { + return true + } + + guard let other = other else { + return false + } + + if !((additionalAPIParameters as NSDictionary).isEqual(to: other.additionalAPIParameters)) { + return false + } + + return city == other.city && country == other.country && line1 == other.line1 + && line2 == other.line2 && postalCode == other.postalCode && state == other.state + } + + // MARK: - STPAPIResponseDecodable + @objc + public class func decodedObject(fromAPIResponse response: [AnyHashable: Any]?) -> Self? { + guard let response = response else { + return nil + } + let dict = response.stp_dictionaryByRemovingNulls() + let address = self.init() + address.allResponseFields = response + address.city = dict.stp_string(forKey: "city") + address.country = dict.stp_string(forKey: "country") + address.line1 = dict.stp_string(forKey: "line1") + address.line2 = dict.stp_string(forKey: "line2") + address.postalCode = dict.stp_string(forKey: "postal_code") + address.state = dict.stp_string(forKey: "state") + return address + } +} diff --git a/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/STPPaymentMethodBillingDetails.swift b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/STPPaymentMethodBillingDetails.swift new file mode 100644 index 0000000..ffca058 --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/STPPaymentMethodBillingDetails.swift @@ -0,0 +1,132 @@ +// +// STPPaymentMethodBillingDetails.swift +// StripePayments +// +// Created by Yuki Tokuhiro on 3/5/19. +// Copyright © 2019 Stripe, Inc. All rights reserved. +// + +import Foundation + +/// Billing information associated with a `STPPaymentMethod` that may be used or required by particular types of payment methods. +/// - seealso: https://stripe.com/docs/api/payment_methods/object#payment_method_object-billing_details +public class STPPaymentMethodBillingDetails: NSObject, STPAPIResponseDecodable, STPFormEncodable { + @objc public var additionalAPIParameters: [AnyHashable: Any] = [:] + + /// Billing address. + @objc public var address: STPPaymentMethodAddress? + /// Email address. + @objc public var email: String? + /// Full name. + @objc public var name: String? + /// Billing phone number (including extension). + @objc public var phone: String? + @objc public private(set) var allResponseFields: [AnyHashable: Any] = [:] + + /// :nodoc: + @objc public override var description: String { + let props = [ + // Object + String(format: "%@: %p", NSStringFromClass(STPPaymentMethodBillingDetails.self), self), + // Properties + "name = \(name ?? "")", + "phone = \(phone ?? "")", + "email = \(email ?? "")", + "address = \(String(describing: address))", + ] + return "<\(props.joined(separator: "; "))>" + } + + /// :nodoc: + @objc public override required init() { + super.init() + } + + // MARK: - STPFormEncodable + + @objc + public class func propertyNamesToFormFieldNamesMapping() -> [String: String] { + return [ + NSStringFromSelector(#selector(getter:address)): "address", + NSStringFromSelector(#selector(getter:email)): "email", + NSStringFromSelector(#selector(getter:name)): "name", + NSStringFromSelector(#selector(getter:phone)): "phone", + ] + } + + @objc + public class func rootObjectName() -> String? { + return nil + } + + // MARK: - NSCopying + @objc(copyWithZone:) func copy(with zone: NSZone? = nil) -> Any { + let copyBillingDetails = type(of: self).init() + + copyBillingDetails.allResponseFields = allResponseFields + copyBillingDetails.address = address?.copy() as? STPPaymentMethodAddress + copyBillingDetails.email = email + copyBillingDetails.name = name + copyBillingDetails.phone = phone + + return copyBillingDetails + } + + // MARK: - Equality + /// :nodoc: + @objc + public override func isEqual(_ other: Any?) -> Bool { + return isEqual(to: other as? STPPaymentMethodBillingDetails) + } + + func isEqual(to other: STPPaymentMethodBillingDetails?) -> Bool { + if self === other { + return true + } + + guard let other = other else { + return false + } + + if !((additionalAPIParameters as NSDictionary).isEqual(to: other.additionalAPIParameters)) { + return false + } + + return + address == other.address && email == other.email && name == other.name + && phone == other.phone + } + + // MARK: - STPAPIResponseDecodable + @objc + public class func decodedObject(fromAPIResponse response: [AnyHashable: Any]?) -> Self? { + guard let response = response else { + return nil + } + let dict = response.stp_dictionaryByRemovingNulls() + let billingDetails = self.init() + billingDetails.allResponseFields = response + billingDetails.address = STPPaymentMethodAddress.decodedObject( + fromAPIResponse: dict.stp_dictionary(forKey: "address") + ) + billingDetails.email = dict.stp_string(forKey: "email") + billingDetails.name = dict.stp_string(forKey: "name") + billingDetails.phone = dict.stp_string(forKey: "phone") + return billingDetails + } +} + +/// :nodoc: +extension STPPaymentMethodBillingDetails { + /// Convenience initializer for creating an `STPPaymentMethodBillingDetails` instance with a postal and country code + @objc convenience init( + postalCode: String, + countryCode: String? = Locale.autoupdatingCurrent.regionCode + ) { + self.init() + let address = STPPaymentMethodAddress() + address.postalCode = postalCode + address.country = countryCode + self.address = address + } +} diff --git a/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/STPPaymentMethodEnums.swift b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/STPPaymentMethodEnums.swift new file mode 100644 index 0000000..a3f55cb --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/STPPaymentMethodEnums.swift @@ -0,0 +1,138 @@ +// +// STPPaymentMethodEnums.swift +// StripePayments +// +// Created by Yuki Tokuhiro on 3/12/19. +// Copyright © 2019 Stripe, Inc. All rights reserved. +// + +import Foundation + +/// The type of the PaymentMethod. +@objc public enum STPPaymentMethodType: Int { + /// A card payment method. + case card + /// An Alipay payment method. + case alipay + /// A GrabPay payment method. + case grabPay + /// An iDEAL payment method. + @objc(STPPaymentMethodTypeiDEAL) case iDEAL + /// An FPX payment method. + case FPX + /// A card present payment method. + case cardPresent + /// A SEPA Debit payment method. + @objc(STPPaymentMethodTypeSEPADebit) case SEPADebit + /// An AU BECS Debit payment method. + @objc(STPPaymentMethodTypeAUBECSDebit) case AUBECSDebit + /// A Bacs Debit payment method. + case bacsDebit + /// A giropay payment method. + case giropay + /// A Przelewy24 Debit payment method. + case przelewy24 + /// An EPS payment method. + @objc(STPPaymentMethodTypeEPS) case EPS + /// A Bancontact payment method. + case bancontact + /// A NetBanking payment method. + case netBanking + /// An OXXO payment method. + @objc(STPPaymentMethodTypeOXXO) case OXXO + /// A Sofort payment method. + case sofort + /// A UPI payment method. + case UPI + /// A PayPal payment method. :nodoc: + case payPal + /// An AfterpayClearpay payment method + case afterpayClearpay + /// A BLIK payment method + @objc(STPPaymentMethodTypeBLIK) + case blik + /// A WeChat Pay payment method + case weChatPay + /// A Boleto payment method. + case boleto + /// A Link payment method + case link + /// A Klarna payment method. + case klarna + /// A Link Instant Debit payment method + case linkInstantDebit + /// An Affirm payment method + case affirm + /// A US Bank Account payment method (ACH) + case USBankAccount + /// An unknown type. + case unknown + + /// Localized display name for this payment method type + @_spi(STP) public var displayName: String { + switch self { + case .alipay: + return STPLocalizedString("Alipay", "Payment Method type brand name") + case .card: + return STPLocalizedString("Card", "Payment Method for credit card") + case .iDEAL: + return STPLocalizedString("iDEAL", "Source type brand name") + case .FPX: + return STPLocalizedString("FPX", "Payment Method type brand name") + case .SEPADebit: + return STPLocalizedString("SEPA Debit", "Payment method brand name") + case .AUBECSDebit: + return STPLocalizedString("AU BECS Direct Debit", "Payment Method type brand name.") + case .grabPay: + return STPLocalizedString("GrabPay", "Payment Method type brand name.") + case .giropay: + return STPLocalizedString("giropay", "Payment Method type brand name.") + case .EPS: + return STPLocalizedString("EPS", "Payment Method type brand name.") + case .przelewy24: + return STPLocalizedString("Przelewy24", "Payment Method type brand name.") + case .bancontact: + return STPLocalizedString("Bancontact", "Payment Method type brand name") + case .netBanking: + return STPLocalizedString("NetBanking", "Payment Method type brand name") + case .OXXO: + return STPLocalizedString("OXXO", "Payment Method type brand name") + case .sofort: + return STPLocalizedString("Sofort", "Payment Method type brand name") + case .UPI: + return STPLocalizedString("UPI", "Payment Method type brand name") + case .payPal: + return STPLocalizedString("PayPal", "Payment Method type brand name") + case .afterpayClearpay: + return Locale.current.regionCode == "GB" || Locale.current.regionCode == "FR" + || Locale.current.regionCode == "ES" || Locale.current.regionCode == "IT" + ? STPLocalizedString("Clearpay", "Payment Method type brand name") + : STPLocalizedString("Afterpay", "Payment Method type brand name") + case .blik: + return STPLocalizedString("BLIK", "Payment Method type brand name") + case .weChatPay: + return STPLocalizedString("WeChat Pay", "Payment Method type brand name") + case .boleto: + return STPLocalizedString("Boleto", "Payment Method type brand name") + case .link: + return STPLocalizedString("Link", "Link Payment Method type brand name") + case .klarna: + return STPLocalizedString("Klarna", "Payment Method type brand name") + case .linkInstantDebit: + return STPLocalizedString("Bank", "Link Instant Debit payment method display name") + case .affirm: + return STPLocalizedString("Affirm", "Payment Method type brand name") + case .USBankAccount: + return STPLocalizedString( + "US Bank Account", + "Payment Method type name for US Bank Account payments." + ) + case .bacsDebit, + .cardPresent, + .unknown: + return STPLocalizedString("Unknown", "Default missing source type label") + @unknown default: + return STPLocalizedString("Unknown", "Default missing source type label") + } + } +} diff --git a/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/STPPaymentMethodParams.swift b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/STPPaymentMethodParams.swift new file mode 100644 index 0000000..ebc51b0 --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/STPPaymentMethodParams.swift @@ -0,0 +1,1186 @@ +// +// STPPaymentMethodParams.swift +// StripePayments +// +// Created by Yuki Tokuhiro on 3/6/19. +// Copyright © 2019 Stripe, Inc. All rights reserved. +// + +import Foundation +import UIKit + +/// An object representing parameters used to create a PaymentMethod object. +/// @note To create a PaymentMethod from an Apple Pay PKPaymentToken, see `STPAPIClient createPaymentMethodWithPayment:completion:` +/// - seealso: https://stripe.com/docs/api/payment_methods/create +public class STPPaymentMethodParams: NSObject, STPFormEncodable { + @objc public var additionalAPIParameters: [AnyHashable: Any] = [:] + + /// The type of payment method. The associated property will contain additional information (e.g. `type == STPPaymentMethodTypeCard` means `card` should also be populated). + + @objc public var type: STPPaymentMethodType { + get { + return STPPaymentMethod.type(from: rawTypeString ?? "") + } + set(newType) { + if newType != self.type { + rawTypeString = STPPaymentMethod.string(from: newType) + } + } + } + /// The raw underlying type string sent to the server. + /// Generally you should use `type` instead unless you have a reason not to. + /// You can use this if you want to create a param of a type not yet supported + /// by the current version of the SDK's `STPPaymentMethodType` enum. + /// Setting this to a value not known by the SDK causes `type` to + /// return `STPPaymentMethodTypeUnknown` + @objc public var rawTypeString: String? + /// Billing information associated with the PaymentMethod that may be used or required by particular types of payment methods. + @objc public var billingDetails: STPPaymentMethodBillingDetails? + /// If this is a card PaymentMethod, this contains the user’s card details. + @objc public var card: STPPaymentMethodCardParams? + /// If this is an Alipay PaymentMethod, this contains additional details. + @objc public var alipay: STPPaymentMethodAlipayParams? + /// If this is a iDEAL PaymentMethod, this contains details about user's bank. + @objc public var iDEAL: STPPaymentMethodiDEALParams? + /// If this is a FPX PaymentMethod, this contains details about user's bank. + @objc public var fpx: STPPaymentMethodFPXParams? + /// If this is a SEPA Debit PaymentMethod, this contains details about the bank to debit. + @objc public var sepaDebit: STPPaymentMethodSEPADebitParams? + /// If this is a Bacs Debit PaymentMethod, this contains details about the bank account to debit. + @objc public var bacsDebit: STPPaymentMethodBacsDebitParams? + /// If this is an AU BECS Debit PaymentMethod, this contains details about the bank to debit. + @objc public var auBECSDebit: STPPaymentMethodAUBECSDebitParams? + /// If this is a giropay PaymentMethod, this contains additional details. + @objc public var giropay: STPPaymentMethodGiropayParams? + /// If this is a PayPal PaymentMethod, this contains additional details. :nodoc: + @objc public var payPal: STPPaymentMethodPayPalParams? + /// If this is a Przelewy24 PaymentMethod, this contains additional details. + @objc public var przelewy24: STPPaymentMethodPrzelewy24Params? + /// If this is an EPS PaymentMethod, this contains additional details. + @objc public var eps: STPPaymentMethodEPSParams? + /// If this is a Bancontact PaymentMethod, this contains additional details. + @objc public var bancontact: STPPaymentMethodBancontactParams? + /// If this is a NetBanking PaymentMethod, this contains additional details. + @objc public var netBanking: STPPaymentMethodNetBankingParams? + /// If this is an OXXO PaymentMethod, this contains additional details. + @objc public var oxxo: STPPaymentMethodOXXOParams? + /// If this is a Sofort PaymentMethod, this contains additional details. + @objc public var sofort: STPPaymentMethodSofortParams? + /// If this is a UPI PaymentMethod, this contains additional details. + @objc public var upi: STPPaymentMethodUPIParams? + /// If this is a GrabPay PaymentMethod, this contains additional details. + @objc public var grabPay: STPPaymentMethodGrabPayParams? + /// If this is a Afterpay PaymentMethod, this contains additional details. + @objc public var afterpayClearpay: STPPaymentMethodAfterpayClearpayParams? + /// If this is a BLIK PaymentMethod, this contains additional details. + @objc public var blik: STPPaymentMethodBLIKParams? + /// If this is a WeChat Pay PaymentMethod, this contains additional details. + @objc var weChatPay: STPPaymentMethodWeChatPayParams? + /// If this is an Boleto PaymentMethod, this contains additional details. + @objc public var boleto: STPPaymentMethodBoletoParams? + /// If this is a Link PaymentMethod, this contains additional details + @objc public var link: STPPaymentMethodLinkParams? + /// If this is an Klarna PaymentMethod, this contains additional details. + @objc public var klarna: STPPaymentMethodKlarnaParams? + /// If this is an Affirm PaymentMethod, this contains additional details. + @objc public var affirm: STPPaymentMethodAffirmParams? + /// If this is a US Bank Account PaymentMethod, this contains additional details. + @objc public var usBankAccount: STPPaymentMethodUSBankAccountParams? + + /// Set of key-value pairs that you can attach to the PaymentMethod. This can be useful for storing additional information about the PaymentMethod in a structured format. + @objc public var metadata: [String: String]? + + /// Creates params for a card PaymentMethod. + /// - Parameters: + /// - card: An object containing the user's card details. + /// - billingDetails: An object containing the user's billing details. + /// - metadata: Additional information to attach to the PaymentMethod. + @objc + public convenience init( + card: STPPaymentMethodCardParams, + billingDetails: STPPaymentMethodBillingDetails?, + metadata: [String: String]? + ) { + self.init() + self.type = .card + self.card = card + self.billingDetails = billingDetails + self.metadata = metadata + } + + /// Creates params for an iDEAL PaymentMethod. + /// - Parameters: + /// - iDEAL: An object containing the user's iDEAL bank details. + /// - billingDetails: An object containing the user's billing details. + /// - metadata: Additional information to attach to the PaymentMethod. + @objc + public convenience init( + iDEAL: STPPaymentMethodiDEALParams, + billingDetails: STPPaymentMethodBillingDetails?, + metadata: [String: String]? + ) { + self.init() + self.type = .iDEAL + self.iDEAL = iDEAL + self.billingDetails = billingDetails + self.metadata = metadata + } + + /// Creates params for an FPX PaymentMethod. + /// - Parameters: + /// - fpx: An object containing the user's FPX bank details. + /// - billingDetails: An object containing the user's billing details. + /// - metadata: Additional information to attach to the PaymentMethod. + @objc + public convenience init( + fpx: STPPaymentMethodFPXParams, + billingDetails: STPPaymentMethodBillingDetails?, + metadata: [String: String]? + ) { + self.init() + self.type = .FPX + self.fpx = fpx + self.billingDetails = billingDetails + self.metadata = metadata + } + + /// Creates params for a SEPA Debit PaymentMethod; + /// - Parameters: + /// - sepaDebit: An object containing the SEPA bank debit details. + /// - billingDetails: An object containing the user's billing details. Note that `billingDetails.name` is required for SEPA Debit PaymentMethods. + /// - metadata: Additional information to attach to the PaymentMethod. + @objc + public convenience init( + sepaDebit: STPPaymentMethodSEPADebitParams, + billingDetails: STPPaymentMethodBillingDetails, + metadata: [String: String]? + ) { + self.init() + self.type = .SEPADebit + self.sepaDebit = sepaDebit + self.billingDetails = billingDetails + self.metadata = metadata + } + + /// Creates params for a Bacs Debit PaymentMethod; + /// - Parameters: + /// - bacsDebit: An object containing the Bacs bank debit details. + /// - billingDetails: An object containing the user's billing details. Note that name, email, and address are required for Bacs Debit PaymentMethods. + /// - metadata: Additional information to attach to the PaymentMethod. + @objc + public convenience init( + bacsDebit: STPPaymentMethodBacsDebitParams, + billingDetails: STPPaymentMethodBillingDetails, + metadata: [String: String]? + ) { + self.init() + self.type = .bacsDebit + self.bacsDebit = bacsDebit + self.billingDetails = billingDetails + self.metadata = metadata + } + + /// Creates params for an AU BECS Debit PaymentMethod; + /// - Parameters: + /// - auBECSDebit: An object containing the AU BECS bank debit details. + /// - billingDetails: An object containing the user's billing details. Note that `billingDetails.name` and `billingDetails.email` are required for AU BECS Debit PaymentMethods. + /// - metadata: Additional information to attach to the PaymentMethod. + @objc + public convenience init( + aubecsDebit auBECSDebit: STPPaymentMethodAUBECSDebitParams, + billingDetails: STPPaymentMethodBillingDetails, + metadata: [String: String]? + ) { + self.init() + self.type = .AUBECSDebit + self.auBECSDebit = auBECSDebit + self.billingDetails = billingDetails + self.metadata = metadata + } + + /// Creates params for a giropay PaymentMethod; + /// - Parameters: + /// - giropay: An object containing additional giropay details. + /// - billingDetails: An object containing the user's billing details. Note that `billingDetails.name` is required for giropay PaymentMethods. + /// - metadata: Additional information to attach to the PaymentMethod. + @objc + public convenience init( + giropay: STPPaymentMethodGiropayParams, + billingDetails: STPPaymentMethodBillingDetails, + metadata: [String: String]? + ) { + self.init() + self.type = .giropay + self.giropay = giropay + self.billingDetails = billingDetails + self.metadata = metadata + } + + /// Creates params for an EPS PaymentMethod; + /// - Parameters: + /// - eps: An object containing additional EPS details. + /// - billingDetails: An object containing the user's billing details. Note that `billingDetails.name` is required for EPS PaymentMethods. + /// - metadata: Additional information to attach to the PaymentMethod. + @objc + public convenience init( + eps: STPPaymentMethodEPSParams, + billingDetails: STPPaymentMethodBillingDetails, + metadata: [String: String]? + ) { + self.init() + self.type = .EPS + self.eps = eps + self.billingDetails = billingDetails + self.metadata = metadata + } + + /// Creates params for a Przelewy24 PaymentMethod; + /// - Parameters: + /// - przelewy24: An object containing additional Przelewy24 details. + /// - billingDetails: An object containing the user's billing details. Note that `billingDetails.email` is required for Przelewy24 PaymentMethods. + /// - metadata: Additional information to attach to the PaymentMethod. + @objc + public convenience init( + przelewy24: STPPaymentMethodPrzelewy24Params, + billingDetails: STPPaymentMethodBillingDetails, + metadata: [String: String]? + ) { + self.init() + self.type = .przelewy24 + self.przelewy24 = przelewy24 + self.billingDetails = billingDetails + self.metadata = metadata + } + + /// Creates params for a Bancontact PaymentMethod; + /// - Parameters: + /// - bancontact: An object containing additional Bancontact details. + /// - billingDetails: An object containing the user's billing details. Note that `billingDetails.name` is required for Bancontact PaymentMethods. + /// - metadata: Additional information to attach to the PaymentMethod. + @objc + public convenience init( + bancontact: STPPaymentMethodBancontactParams, + billingDetails: STPPaymentMethodBillingDetails, + metadata: [String: String]? + ) { + self.init() + self.type = .bancontact + self.bancontact = bancontact + self.billingDetails = billingDetails + self.metadata = metadata + } + + /// Creates params for a NetBanking PaymentMethod; + /// - Parameters: + /// - netBanking: An object containing additional NetBanking details. + /// - billingDetails: An object containing the user's billing details. + /// - metadata: Additional information to attach to the PaymentMethod. + @objc + public convenience init( + netBanking: STPPaymentMethodNetBankingParams, + billingDetails: STPPaymentMethodBillingDetails, + metadata: [String: String]? + ) { + self.init() + self.type = .netBanking + self.netBanking = netBanking + self.billingDetails = billingDetails + self.metadata = metadata + } + + /// Creates params for a GrabPay PaymentMethod; + /// - Parameters: + /// - grabPay: An object containing additional GrabPay details. + /// - billingDetails: An object containing the user's billing details. + /// - metadata: Additional information to attach to the PaymentMethod. + @objc + public convenience init( + grabPay: STPPaymentMethodGrabPayParams, + billingDetails: STPPaymentMethodBillingDetails?, + metadata: [String: String]? + ) { + self.init() + self.type = .grabPay + self.grabPay = grabPay + self.billingDetails = billingDetails + } + + /// Creates params for an OXXO PaymentMethod; + /// - Parameters: + /// - oxxo: An object containing additional OXXO details. + /// - billingDetails: An object containing the user's billing details. + /// - metadata: Additional information to attach to the PaymentMethod. + @objc + public convenience init( + oxxo: STPPaymentMethodOXXOParams, + billingDetails: STPPaymentMethodBillingDetails?, + metadata: [String: String]? + ) { + self.init() + self.type = .OXXO + self.oxxo = oxxo + self.billingDetails = billingDetails + } + + /// Creates params for a Sofort PaymentMethod; + /// - Parameters: + /// - sofort: An object containing additional Sofort details. + /// - billingDetails: An object containing the user's billing details. Note that `billingDetails.name` and `billingDetails.email` are required to save bank details from a Sofort payment. + /// - metadata: Additional information to attach to the PaymentMethod. + @objc + public convenience init( + sofort: STPPaymentMethodSofortParams, + billingDetails: STPPaymentMethodBillingDetails?, + metadata: [String: String]? + ) { + self.init() + self.type = .sofort + self.sofort = sofort + self.billingDetails = billingDetails + self.metadata = metadata + } + + /// Creates params for a UPI PaymentMethod; + /// - Parameters: + /// - upi: An object containing additional UPI details. + /// - billingDetails: An object containing the user's billing details. + /// - metadata: Additional information to attach to the PaymentMethod. + @objc + public convenience init( + upi: STPPaymentMethodUPIParams, + billingDetails: STPPaymentMethodBillingDetails?, + metadata: [String: String]? + ) { + self.init() + self.type = .UPI + self.upi = upi + self.billingDetails = billingDetails + self.metadata = metadata + } + + /// Creates params for an Alipay PaymentMethod. + /// - Parameters: + /// - alipay: An object containing additional Alipay details. + /// - billingDetails: An object containing the user's billing details. + /// - metadata: Additional information to attach to the PaymentMethod. + @objc + public convenience init( + alipay: STPPaymentMethodAlipayParams, + billingDetails: STPPaymentMethodBillingDetails?, + metadata: [String: String]? + ) { + self.init() + self.type = .alipay + self.alipay = alipay + self.billingDetails = billingDetails + } + + /// Creates params for a PayPal PaymentMethod. :nodoc: + /// - Parameters: + /// - payPal: An object containing additional PayPal details. + /// - billingDetails: An object containing the user's billing details. + /// - metadata: Additional information to attach to the PaymentMethod. + @objc + public convenience init( + payPal: STPPaymentMethodPayPalParams, + billingDetails: STPPaymentMethodBillingDetails?, + metadata: [String: String]? + ) { + self.init() + self.type = .payPal + self.payPal = payPal + self.billingDetails = billingDetails + } + + /// Creates params for an AfterpayClearpay PaymentMethod. :nodoc: + /// - Parameters: + /// - afterpayClearpay: An object containing additional AfterpayClearpay details. + /// - billingDetails: An object containing the user's billing details. + /// - metadata: Additional information to attach to the PaymentMethod. + @objc + public convenience init( + afterpayClearpay: STPPaymentMethodAfterpayClearpayParams, + billingDetails: STPPaymentMethodBillingDetails?, + metadata: [String: String]? + ) { + self.init() + self.type = .afterpayClearpay + self.afterpayClearpay = afterpayClearpay + self.billingDetails = billingDetails + self.metadata = metadata + } + + /// Creates params for a BLIK PaymentMethod. + /// - Parameters: + /// - blik: An object containing additional BLIK details. + /// - billingDetails: An object containing the user's billing details. + /// - metadata: Additional information to attach to the PaymentMethod. + @objc + public convenience init( + blik: STPPaymentMethodBLIKParams, + billingDetails: STPPaymentMethodBillingDetails?, + metadata: [String: String]? + ) { + self.init() + self.type = .blik + self.blik = blik + self.billingDetails = billingDetails + self.metadata = metadata + } + + /// Creates params for a WeChat Pay PaymentMethod. + /// - Parameters: + /// - weChatPay: An object containing additional WeChat Pay details. + /// - billingDetails: An object containing the user's billing details. + /// - metadata: Additional information to attach to the PaymentMethod. + @objc + convenience init( + weChatPay: STPPaymentMethodWeChatPayParams, + billingDetails: STPPaymentMethodBillingDetails?, + metadata: [String: String]? + ) { + self.init() + self.type = .weChatPay + self.weChatPay = weChatPay + self.billingDetails = billingDetails + self.metadata = metadata + } + + /// Creates params for an Boleto PaymentMethod; + /// - Parameters: + /// - boleto: An object containing additional Boleto details. + /// - billingDetails: An object containing the user's billing details. + /// - metadata: Additional information to attach to the PaymentMethod. + @objc + public convenience init( + boleto: STPPaymentMethodBoletoParams, + billingDetails: STPPaymentMethodBillingDetails?, + metadata: [String: String]? + ) { + self.init() + self.type = .boleto + self.boleto = boleto + self.billingDetails = billingDetails + } + + /// Creates params for an Klarna PaymentMethod. :nodoc: + /// - Parameters: + /// - klarna: An object containing additional Klarna details. + /// - billingDetails: An object containing the user's billing details. + /// - metadata: Additional information to attach to the PaymentMethod. + @objc + public convenience init( + klarna: STPPaymentMethodKlarnaParams, + billingDetails: STPPaymentMethodBillingDetails?, + metadata: [String: String]? + ) { + self.init() + self.type = .klarna + self.klarna = klarna + self.billingDetails = billingDetails + self.metadata = metadata + } + + /// Creates params for an Affirm PaymentMethod. :nodoc: + /// - Parameters: + /// - affirm: An object containing additional Affirm details. + /// - metadata: Additional information to attach to the PaymentMethod. + @objc + public convenience init( + affirm: STPPaymentMethodAffirmParams, + metadata: [String: String]? + ) { + self.init() + self.type = .affirm + self.affirm = affirm + self.metadata = metadata + } + + /// Creates params for a US Bank Account Payment Method + /// - Parameters: + /// - usBankAccount: An object containing additional US bank account details + /// - billingDetails: An object containing the user's billing details. Name is required for US Bank Accounts + /// - metadata: Additional information to attach to the PaymentMethod + @objc + public convenience init( + usBankAccount: STPPaymentMethodUSBankAccountParams, + billingDetails: STPPaymentMethodBillingDetails, + metadata: [String: String]? + ) { + self.init() + self.type = .USBankAccount + self.usBankAccount = usBankAccount + self.billingDetails = billingDetails + self.metadata = metadata + } + + /// Creates params from a single-use PaymentMethod. This is useful for recreating a new payment method + /// with similar settings. It will return nil if used with a reusable PaymentMethod. + /// - Parameter paymentMethod: An object containing the original single-use PaymentMethod. + @objc public convenience init?( + singleUsePaymentMethod paymentMethod: STPPaymentMethod + ) { + self.init() + switch paymentMethod.type { + case .EPS: + self.type = .EPS + let eps = STPPaymentMethodEPSParams() + self.eps = eps + self.billingDetails = paymentMethod.billingDetails + case .FPX: + self.type = .FPX + let fpx = STPPaymentMethodFPXParams() + fpx.rawBankString = paymentMethod.fpx?.bankIdentifierCode + self.fpx = fpx + self.billingDetails = paymentMethod.billingDetails + case .iDEAL: + self.type = .iDEAL + let iDEAL = STPPaymentMethodiDEALParams() + self.iDEAL = iDEAL + self.iDEAL?.bankName = paymentMethod.iDEAL?.bankName + self.billingDetails = paymentMethod.billingDetails + case .giropay: + self.type = .giropay + let giropay = STPPaymentMethodGiropayParams() + self.giropay = giropay + self.billingDetails = paymentMethod.billingDetails + case .przelewy24: + self.type = .przelewy24 + let przelewy24 = STPPaymentMethodPrzelewy24Params() + self.przelewy24 = przelewy24 + self.billingDetails = paymentMethod.billingDetails + case .bancontact: + self.type = .bancontact + let bancontact = STPPaymentMethodBancontactParams() + self.bancontact = bancontact + self.billingDetails = paymentMethod.billingDetails + case .netBanking: + self.type = .netBanking + let netBanking = STPPaymentMethodNetBankingParams() + self.netBanking = netBanking + self.billingDetails = paymentMethod.billingDetails + case .OXXO: + self.type = .OXXO + let oxxo = STPPaymentMethodOXXOParams() + self.oxxo = oxxo + self.billingDetails = paymentMethod.billingDetails + case .alipay: + // Careful! In the future, when we add recurring Alipay, we'll need to look at this! + self.type = .alipay + self.billingDetails = paymentMethod.billingDetails + case .sofort: + self.type = .sofort + let sofort = STPPaymentMethodSofortParams() + self.sofort = sofort + self.billingDetails = paymentMethod.billingDetails + case .UPI: + self.type = .UPI + let upi = STPPaymentMethodUPIParams() + self.upi = upi + self.billingDetails = paymentMethod.billingDetails + case .grabPay: + self.type = .grabPay + let grabpay = STPPaymentMethodGrabPayParams() + self.grabPay = grabpay + self.billingDetails = paymentMethod.billingDetails + case .afterpayClearpay: + self.type = .afterpayClearpay + self.afterpayClearpay = STPPaymentMethodAfterpayClearpayParams() + self.billingDetails = paymentMethod.billingDetails + case .boleto: + self.type = .boleto + let boleto = STPPaymentMethodBoletoParams() + self.boleto = boleto + self.billingDetails = paymentMethod.billingDetails + case .klarna: + self.type = .klarna + self.klarna = STPPaymentMethodKlarnaParams() + self.billingDetails = paymentMethod.billingDetails + case .affirm: + self.type = .affirm + self.affirm = STPPaymentMethodAffirmParams() + self.billingDetails = paymentMethod.billingDetails + // All reusable PaymentMethods go below: + case .SEPADebit, + .bacsDebit, + .card, + .cardPresent, + .AUBECSDebit, + .payPal, + .blik, + .weChatPay, + .link, + .linkInstantDebit, + .USBankAccount, + .unknown: + return nil + } + } + + // MARK: - STPFormEncodable + @objc + public class func rootObjectName() -> String? { + return nil + } + + @objc + public class func propertyNamesToFormFieldNamesMapping() -> [String: String] { + return [ + NSStringFromSelector(#selector(getter:rawTypeString)): "type", + NSStringFromSelector(#selector(getter:billingDetails)): "billing_details", + NSStringFromSelector(#selector(getter:card)): "card", + NSStringFromSelector(#selector(getter:iDEAL)): "ideal", + NSStringFromSelector(#selector(getter:eps)): "eps", + NSStringFromSelector(#selector(getter:fpx)): "fpx", + NSStringFromSelector(#selector(getter:sepaDebit)): "sepa_debit", + NSStringFromSelector(#selector(getter:bacsDebit)): "bacs_debit", + NSStringFromSelector(#selector(getter:auBECSDebit)): "au_becs_debit", + NSStringFromSelector(#selector(getter:giropay)): "giropay", + NSStringFromSelector(#selector(getter:grabPay)): "grabpay", + NSStringFromSelector(#selector(getter:przelewy24)): "p24", + NSStringFromSelector(#selector(getter:bancontact)): "bancontact", + NSStringFromSelector(#selector(getter:netBanking)): "netbanking", + NSStringFromSelector(#selector(getter:oxxo)): "oxxo", + NSStringFromSelector(#selector(getter:sofort)): "sofort", + NSStringFromSelector(#selector(getter:upi)): "upi", + NSStringFromSelector(#selector(getter:afterpayClearpay)): "afterpayClearpay", + NSStringFromSelector(#selector(getter:weChatPay)): "wechat_pay", + NSStringFromSelector(#selector(getter:boleto)): "boleto", + NSStringFromSelector(#selector(getter:klarna)): "klarna", + NSStringFromSelector(#selector(getter:affirm)): "affirm", + NSStringFromSelector(#selector(getter:usBankAccount)): "us_bank_account", + NSStringFromSelector(#selector(getter:link)): "link", + NSStringFromSelector(#selector(getter:metadata)): "metadata", + ] + } +} + +// MARK: - Legacy ObjC + +@objc +extension STPPaymentMethodParams { + /// Creates params for a card PaymentMethod. + /// - Parameters: + /// - card: An object containing the user's card details. + /// - billingDetails: An object containing the user's billing details. + /// - metadata: Additional information to attach to the PaymentMethod. + @objc(paramsWithCard:billingDetails:metadata:) + public class func paramsWith( + card: STPPaymentMethodCardParams, + billingDetails: STPPaymentMethodBillingDetails?, + metadata: [String: String]? + ) -> STPPaymentMethodParams { + return STPPaymentMethodParams( + card: card, + billingDetails: billingDetails, + metadata: metadata + ) + } + + /// Creates params for an iDEAL PaymentMethod. + /// - Parameters: + /// - iDEAL: An object containing the user's iDEAL bank details. + /// - billingDetails: An object containing the user's billing details. + /// - metadata: Additional information to attach to the PaymentMethod. + @objc(paramsWithiDEAL:billingDetails:metadata:) + public class func paramsWith( + iDEAL: STPPaymentMethodiDEALParams, + billingDetails: STPPaymentMethodBillingDetails?, + metadata: [String: String]? + ) -> STPPaymentMethodParams { + return STPPaymentMethodParams( + iDEAL: iDEAL, + billingDetails: billingDetails, + metadata: metadata + ) + } + + /// Creates params for an FPX PaymentMethod. + /// - Parameters: + /// - fpx: An object containing the user's FPX bank details. + /// - billingDetails: An object containing the user's billing details. + /// - metadata: Additional information to attach to the PaymentMethod. + @objc(paramsWithFPX:billingDetails:metadata:) + public class func paramsWith( + fpx: STPPaymentMethodFPXParams, + billingDetails: STPPaymentMethodBillingDetails?, + metadata: [String: String]? + ) -> STPPaymentMethodParams { + return STPPaymentMethodParams(fpx: fpx, billingDetails: billingDetails, metadata: metadata) + } + + /// Creates params for a SEPA Debit PaymentMethod; + /// - Parameters: + /// - sepaDebit: An object containing the SEPA bank debit details. + /// - billingDetails: An object containing the user's billing details. Note that `billingDetails.name` is required for SEPA Debit PaymentMethods. + /// - metadata: Additional information to attach to the PaymentMethod. + @objc(paramsWithSEPADebit:billingDetails:metadata:) + public class func paramsWith( + sepaDebit: STPPaymentMethodSEPADebitParams, + billingDetails: STPPaymentMethodBillingDetails, + metadata: [String: String]? + ) -> STPPaymentMethodParams { + return STPPaymentMethodParams( + sepaDebit: sepaDebit, + billingDetails: billingDetails, + metadata: metadata + ) + } + + /// Creates params for a Bacs Debit PaymentMethod; + /// - Parameters: + /// - bacsDebit: An object containing the Bacs bank debit details. + /// - billingDetails: An object containing the user's billing details. Note that name, email, and address are required for Bacs Debit PaymentMethods. + /// - metadata: Additional information to attach to the PaymentMethod. + @objc(paramsWithBacsDebit:billingDetails:metadata:) + public class func paramsWith( + bacsDebit: STPPaymentMethodBacsDebitParams, + billingDetails: STPPaymentMethodBillingDetails, + metadata: [String: String]? + ) -> STPPaymentMethodParams { + return STPPaymentMethodParams( + bacsDebit: bacsDebit, + billingDetails: billingDetails, + metadata: metadata + ) + } + + /// Creates params for an AU BECS Debit PaymentMethod; + /// - Parameters: + /// - auBECSDebit: An object containing the AU BECS bank debit details. + /// - billingDetails: An object containing the user's billing details. Note that `billingDetails.name` and `billingDetails.email` are required for AU BECS Debit PaymentMethods. + /// - metadata: Additional information to attach to the PaymentMethod. + @objc(paramsWithAUBECSDebit:billingDetails:metadata:) + public class func paramsWith( + auBECSDebit: STPPaymentMethodAUBECSDebitParams, + billingDetails: STPPaymentMethodBillingDetails, + metadata: [String: String]? + ) -> STPPaymentMethodParams { + return STPPaymentMethodParams( + aubecsDebit: auBECSDebit, + billingDetails: billingDetails, + metadata: metadata + ) + } + + /// Creates params for a giropay PaymentMethod; + /// - Parameters: + /// - giropay: An object containing additional giropay details. + /// - billingDetails: An object containing the user's billing details. Note that `billingDetails.name` is required for giropay PaymentMethods. + /// - metadata: Additional information to attach to the PaymentMethod. + @objc(paramsWithGiropay:billingDetails:metadata:) + public class func paramsWith( + giropay: STPPaymentMethodGiropayParams, + billingDetails: STPPaymentMethodBillingDetails, + metadata: [String: String]? + ) -> STPPaymentMethodParams { + return STPPaymentMethodParams( + giropay: giropay, + billingDetails: billingDetails, + metadata: metadata + ) + } + + /// Creates params for an EPS PaymentMethod; + /// - Parameters: + /// - eps: An object containing additional EPS details. + /// - billingDetails: An object containing the user's billing details. Note that `billingDetails.name` is required for EPS PaymentMethods. + /// - metadata: Additional information to attach to the PaymentMethod. + @objc(paramsWithEPS:billingDetails:metadata:) + public class func paramsWith( + eps: STPPaymentMethodEPSParams, + billingDetails: STPPaymentMethodBillingDetails, + metadata: [String: String]? + ) -> STPPaymentMethodParams { + return STPPaymentMethodParams(eps: eps, billingDetails: billingDetails, metadata: metadata) + } + + /// Creates params for a Przelewy24 PaymentMethod; + /// - Parameters: + /// - przelewy24: An object containing additional Przelewy24 details. + /// - billingDetails: An object containing the user's billing details. Note that `billingDetails.email` is required for Przelewy24 PaymentMethods. + /// - metadata: Additional information to attach to the PaymentMethod. + @objc(paramsWithPrzelewy24:billingDetails:metadata:) + public class func paramsWith( + przelewy24: STPPaymentMethodPrzelewy24Params, + billingDetails: STPPaymentMethodBillingDetails, + metadata: [String: String]? + ) -> STPPaymentMethodParams { + return STPPaymentMethodParams( + przelewy24: przelewy24, + billingDetails: billingDetails, + metadata: metadata + ) + } + + /// Creates params for a Bancontact PaymentMethod; + /// - Parameters: + /// - bancontact: An object containing additional Bancontact details. + /// - billingDetails: An object containing the user's billing details. Note that `billingDetails.name` is required for Bancontact PaymentMethods. + /// - metadata: Additional information to attach to the PaymentMethod. + @objc(paramsWithBancontact:billingDetails:metadata:) + public class func paramsWith( + bancontact: STPPaymentMethodBancontactParams, + billingDetails: STPPaymentMethodBillingDetails, + metadata: [String: String]? + ) -> STPPaymentMethodParams { + return STPPaymentMethodParams( + bancontact: bancontact, + billingDetails: billingDetails, + metadata: metadata + ) + } + + /// Creates params for a NetBanking PaymentMethod; + /// - Parameters: + /// - netBanking: An object containing additional NetBanking details. + /// - billingDetails: An object containing the user's billing details. Note that `billingDetails.name` is required for Bancontact PaymentMethods. + /// - metadata: Additional information to attach to the PaymentMethod. + @objc(paramsWithNetBanking:billingDetails:metadata:) + public class func paramsWith( + netBanking: STPPaymentMethodNetBankingParams, + billingDetails: STPPaymentMethodBillingDetails, + metadata: [String: String]? + ) -> STPPaymentMethodParams { + return STPPaymentMethodParams( + netBanking: netBanking, + billingDetails: billingDetails, + metadata: metadata + ) + } + + /// Creates params for an OXXO PaymentMethod; + /// - Parameters: + /// - oxxo: An object containing additional OXXO details. + /// - billingDetails: An object containing the user's billing details. Note that `billingDetails.name` is required for OXXO PaymentMethods. + /// - metadata: Additional information to attach to the PaymentMethod. + @objc(paramsWithOXXO:billingDetails:metadata:) + public class func paramsWith( + oxxo: STPPaymentMethodOXXOParams, + billingDetails: STPPaymentMethodBillingDetails, + metadata: [String: String]? + ) -> STPPaymentMethodParams { + return STPPaymentMethodParams( + oxxo: oxxo, + billingDetails: billingDetails, + metadata: metadata + ) + } + + /// Creates params for a GrabPay PaymentMethod; + /// - Parameters: + /// - grabPay: An object containing additional GrabPay details. + /// - billingDetails: An object containing the user's billing details. + /// - metadata: Additional information to attach to the PaymentMethod. + @objc(paramsWithGrabPay:billingDetails:metadata:) + public class func paramsWith( + grabPay: STPPaymentMethodGrabPayParams, + billingDetails: STPPaymentMethodBillingDetails?, + metadata: [String: String]? + ) -> STPPaymentMethodParams { + return STPPaymentMethodParams( + grabPay: grabPay, + billingDetails: billingDetails, + metadata: metadata + ) + } + + /// Creates params for a Sofort PaymentMethod; + /// - Parameters: + /// - sofort: An object containing additional Sofort details. + /// - billingDetails: An object containing the user's billing details. Note that `billingDetails.name` and `billingDetails.email` are required to save bank details from a Sofort payment. + /// - metadata: Additional information to attach to the PaymentMethod. + @objc(paramsWithSofort:billingDetails:metadata:) + public class func paramsWith( + sofort: STPPaymentMethodSofortParams, + billingDetails: STPPaymentMethodBillingDetails?, + metadata: [String: String]? + ) -> STPPaymentMethodParams { + return STPPaymentMethodParams( + sofort: sofort, + billingDetails: billingDetails, + metadata: metadata + ) + } + + /// Creates params for a UPI PaymentMethod; + /// - Parameters: + /// - upi: An object containing additional UPI details. + /// - billingDetails: An object containing the user's billing details. Note that `billingDetails.name` and `billingDetails.email` are required to save bank details from a UPI payment. + /// - metadata: Additional information to attach to the PaymentMethod. + @objc(paramsWithUPI:billingDetails:metadata:) + public class func paramsWith( + upi: STPPaymentMethodUPIParams, + billingDetails: STPPaymentMethodBillingDetails?, + metadata: [String: String]? + ) -> STPPaymentMethodParams { + return STPPaymentMethodParams( + upi: upi, + billingDetails: billingDetails, + metadata: metadata + ) + } + + /// Creates params for an Alipay PaymentMethod. + /// - Parameters: + /// - alipay: An object containing additional Alipay details. + /// - billingDetails: An object containing the user's billing details. + /// - metadata: Additional information to attach to the PaymentMethod. + @objc(paramsWithAlipay:billingDetails:metadata:) + public class func paramsWith( + alipay: STPPaymentMethodAlipayParams, + billingDetails: STPPaymentMethodBillingDetails?, + metadata: [String: String]? + ) -> STPPaymentMethodParams { + return STPPaymentMethodParams( + alipay: alipay, + billingDetails: billingDetails, + metadata: metadata + ) + } + + /// Creates params for a PayPal PaymentMethod. + /// - Parameters: + /// - payPal: An object containing additional PayPal details. + /// - billingDetails: An object containing the user's billing details. + /// - metadata: Additional information to attach to the PaymentMethod. + @objc(paramsWithPayPal:billingDetails:metadata:) + public class func paramsWith( + payPal: STPPaymentMethodPayPalParams, + billingDetails: STPPaymentMethodBillingDetails?, + metadata: [String: String]? + ) -> STPPaymentMethodParams { + return STPPaymentMethodParams( + payPal: payPal, + billingDetails: billingDetails, + metadata: metadata + ) + } + + /// Creates params for an AfterpayClearpay PaymentMethod. + /// - Parameters: + /// - afterpayClearpay: An object containing additional AfterpayClearpay details. + /// - billingDetails: An object containing the user's billing details. + /// - metadata: Additional information to attach to the PaymentMethod. + @objc(paramsWithAfterpayClearpay:billingDetails:metadata:) + public class func paramsWith( + afterpayClearpay: STPPaymentMethodAfterpayClearpayParams, + billingDetails: STPPaymentMethodBillingDetails?, + metadata: [String: String]? + ) -> STPPaymentMethodParams { + return STPPaymentMethodParams( + afterpayClearpay: afterpayClearpay, + billingDetails: billingDetails, + metadata: metadata + ) + } + + /// Creates params for a BLIK PaymentMethod. + /// - Parameters: + /// - blik: An object containing additional BLIK details. + /// - billingDetails: An object containing the user's billing details. + /// - metadata: Additional information to attach to the PaymentMethod. + @objc(paramsWithBLIK:billingDetails:metadata:) + public class func paramsWith( + blik: STPPaymentMethodBLIKParams, + billingDetails: STPPaymentMethodBillingDetails?, + metadata: [String: String]? + ) -> STPPaymentMethodParams { + return STPPaymentMethodParams( + blik: blik, + billingDetails: billingDetails, + metadata: metadata + ) + } + + /// Creates params for a WeChat Pay PaymentMethod. + /// - Parameters: + /// - weChatPay: An object containing additional WeChat Pay details. + /// - billingDetails: An object containing the user's billing details. + /// - metadata: Additional information to attach to the PaymentMethod. + @objc(paramsWithWeChatPay:billingDetails:metadata:) + class func paramsWith( + weChatPay: STPPaymentMethodWeChatPayParams, + billingDetails: STPPaymentMethodBillingDetails?, + metadata: [String: String]? + ) -> STPPaymentMethodParams { + return STPPaymentMethodParams( + weChatPay: weChatPay, + billingDetails: billingDetails, + metadata: metadata + ) + } + + /// Creates params for an Klarna PaymentMethod. + /// - Parameters: + /// - klarna: An object containing additional Klarna details. + /// - billingDetails: An object containing the user's billing details. + /// - metadata: Additional information to attach to the PaymentMethod. + @objc(paramsWithKlarna:billingDetails:metadata:) + public class func paramsWith( + klarna: STPPaymentMethodKlarnaParams, + billingDetails: STPPaymentMethodBillingDetails?, + metadata: [String: String]? + ) -> STPPaymentMethodParams { + return STPPaymentMethodParams( + klarna: klarna, + billingDetails: billingDetails, + metadata: metadata + ) + } + + /// Creates params for an Affirm PaymentMethod. + /// - Parameters: + /// - affirm: An object containing additional Affirm details. + /// - metadata: Additional information to attach to the PaymentMethod. + @objc(paramsWithAffirm:metadata:) + public class func paramsWith( + affirm: STPPaymentMethodAffirmParams, + metadata: [String: String]? + ) -> STPPaymentMethodParams { + return STPPaymentMethodParams( + affirm: affirm, + metadata: metadata + ) + } +} + +extension STPPaymentMethodParams { + @_spi(STP) public convenience init( + type: STPPaymentMethodType + ) { + self.init() + self.type = type + switch type { + case .card: + card = STPPaymentMethodCardParams() + case .alipay: + alipay = STPPaymentMethodAlipayParams() + case .grabPay: + grabPay = STPPaymentMethodGrabPayParams() + case .iDEAL: + iDEAL = STPPaymentMethodiDEALParams() + case .FPX: + fpx = STPPaymentMethodFPXParams() + case .cardPresent: + break + case .SEPADebit: + sepaDebit = STPPaymentMethodSEPADebitParams() + case .AUBECSDebit: + auBECSDebit = STPPaymentMethodAUBECSDebitParams() + case .bacsDebit: + bacsDebit = STPPaymentMethodBacsDebitParams() + case .giropay: + giropay = STPPaymentMethodGiropayParams() + case .przelewy24: + przelewy24 = STPPaymentMethodPrzelewy24Params() + case .EPS: + eps = STPPaymentMethodEPSParams() + case .bancontact: + bancontact = STPPaymentMethodBancontactParams() + case .netBanking: + netBanking = STPPaymentMethodNetBankingParams() + case .OXXO: + oxxo = STPPaymentMethodOXXOParams() + case .sofort: + sofort = STPPaymentMethodSofortParams() + case .UPI: + upi = STPPaymentMethodUPIParams() + case .payPal: + payPal = STPPaymentMethodPayPalParams() + case .afterpayClearpay: + afterpayClearpay = STPPaymentMethodAfterpayClearpayParams() + case .blik: + blik = STPPaymentMethodBLIKParams() + case .weChatPay: + weChatPay = STPPaymentMethodWeChatPayParams() + case .boleto: + boleto = STPPaymentMethodBoletoParams() + case .link: + link = STPPaymentMethodLinkParams() + case .klarna: + klarna = STPPaymentMethodKlarnaParams() + case .affirm: + affirm = STPPaymentMethodAffirmParams() + case .linkInstantDebit: + break + case .USBankAccount: + usBankAccount = STPPaymentMethodUSBankAccountParams() + case .unknown: + break + } + } +} + +extension STPPaymentMethodParams { + @objc public var label: String { + switch type { + case .alipay: + return "Alipay" //? Why aren't these localized? + case .card: + if let card = card { + let brand = STPCardValidator.brand(forNumber: card.number ?? "") + let brandString = STPCardBrandUtilities.stringFrom(brand) + return "\(brandString ?? "") \(card.last4 ?? "")" + } else { + return STPCardBrandUtilities.stringFrom(.unknown) ?? "" + } + case .iDEAL: + return "iDEAL" + case .FPX: + if let fpx = fpx { + return STPFPXBank.stringFrom(fpx.bank) ?? "" + } else { + return "FPX" + } + case .SEPADebit: + return "SEPA Debit" + case .bacsDebit: + return "Bacs Debit" + case .AUBECSDebit: + return "AU BECS Debit" + case .giropay: + return "giropay" + case .przelewy24: + return "Przelewy24" + case .EPS: + return "EPS" + case .bancontact: + return "Bancontact" + case .netBanking: + return "NetBanking" + case .OXXO: + return "OXXO" + case .sofort: + return "Sofort" + case .UPI: + return "UPI" + case .grabPay: + return "GrabPay" + case .payPal: + return "PayPal" + case .afterpayClearpay: + return "Afterpay Clearpay" + case .blik: + return "BLIK" + case .weChatPay: + return "WeChat Pay" + case .boleto: + return "Boleto" + case .link: + return "Link" + case .klarna: + return "Klarna" + case .linkInstantDebit: + return "Bank" + case .affirm: + return "Affirm" + case .USBankAccount: + return "US Bank Account" + case .cardPresent, .unknown: + return STPLocalizedString("Unknown", "Default missing source type label") + @unknown default: + return STPLocalizedString("Unknown", "Default missing source type label") + } + } +} diff --git a/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodAUBECSDebit.swift b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodAUBECSDebit.swift new file mode 100644 index 0000000..c64eef0 --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodAUBECSDebit.swift @@ -0,0 +1,64 @@ +// +// STPPaymentMethodAUBECSDebit.swift +// StripePayments +// +// Created by Cameron Sabol on 3/3/20. +// Copyright © 2020 Stripe, Inc. All rights reserved. +// + +import Foundation + +/// An AU BECS Debit Payment Method. +/// - seealso: https://stripe.com/docs/api/payment_methods/object#payment_method_object-au_becs_debit +public class STPPaymentMethodAUBECSDebit: NSObject, STPAPIResponseDecodable { + /// :nodoc: + private(set) public var allResponseFields: [AnyHashable: Any] = [:] + + /// Six-digit number identifying bank and branch associated with this bank account. + @objc public private(set) var bsbNumber: String + /// Uniquely identifies this particular bank account. You can use this attribute to check whether two bank accounts are the same. + @objc public private(set) var fingerprint: String + /// Last four digits of the bank account number. + @objc public private(set) var last4: String + + // MARK: - Description + /// :nodoc: + @objc public override var description: String { + let props = [ + // Object + String(format: "%@: %p", NSStringFromClass(STPPaymentMethodAUBECSDebit.self), self), + // AU BECS Debit details + "bsbNumber = \(bsbNumber)", + "fingerprint = \(fingerprint)", + "last4 = \(last4)", + ] + + return "<\(props.joined(separator: "; "))>" + } + + // MARK: - STPAPIResponseDecodable + public class func decodedObject(fromAPIResponse response: [AnyHashable: Any]?) -> Self? { + guard let response = response else { + return nil + } + let dict = response.stp_dictionaryByRemovingNulls() + + return self.init(dictionary: dict) + } + + required init?(dictionary dict: [AnyHashable: Any]) { + guard let bsbNumber = dict.stp_string(forKey: "bsb_number"), + let fingerprint = dict.stp_string(forKey: "fingerprint"), + let last4 = dict.stp_string(forKey: "last4") + else { + return nil + } + + self.bsbNumber = bsbNumber + self.fingerprint = fingerprint + self.last4 = last4 + + super.init() + allResponseFields = dict + } +} diff --git a/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodAUBECSDebitParams.swift b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodAUBECSDebitParams.swift new file mode 100644 index 0000000..cae5ae2 --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodAUBECSDebitParams.swift @@ -0,0 +1,31 @@ +// +// STPPaymentMethodAUBECSDebitParams.swift +// StripePayments +// +// Created by Cameron Sabol on 3/3/20. +// Copyright © 2020 Stripe, Inc. All rights reserved. +// + +import Foundation + +/// An object representing parameters used to create an AU BECS Debit Payment Method +public class STPPaymentMethodAUBECSDebitParams: NSObject, STPFormEncodable { + @objc public var additionalAPIParameters: [AnyHashable: Any] = [:] + + /// The account number to debit. + @objc public var accountNumber: String? + /// Six-digit number identifying bank and branch associated with this bank account. + @objc public var bsbNumber: String? + + // MARK: - STPFormEncodable + public class func rootObjectName() -> String? { + return "au_becs_debit" + } + + public class func propertyNamesToFormFieldNamesMapping() -> [String: String] { + return [ + NSStringFromSelector(#selector(getter:accountNumber)): "account_number", + NSStringFromSelector(#selector(getter:bsbNumber)): "bsb_number", + ] + } +} diff --git a/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodAffirm.swift b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodAffirm.swift new file mode 100644 index 0000000..9fc893f --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodAffirm.swift @@ -0,0 +1,44 @@ +// +// STPPaymentMethodAffirm.swift +// StripePayments +// +// Copyright © 2022 Stripe, Inc. All rights reserved. +// + +import Foundation + +/// The Affirm Payment Method. +/// - seealso: +public class STPPaymentMethodAffirm: NSObject, STPAPIResponseDecodable { + /// :nodoc: + @objc private(set) public var allResponseFields: [AnyHashable: Any] = [:] + + // MARK: - Description + /// :nodoc: + @objc public override var description: String { + let props = [ + // Object + String(format: "%@: %p", NSStringFromClass(STPPaymentMethodAffirm.self), self) + ] + + return "<\(props.joined(separator: "; "))>" + } + + // MARK: - STPAPIResponseDecodeable + @objc + /// :nodoc: + public static func decodedObject(fromAPIResponse response: [AnyHashable: Any]?) -> Self? { + guard let response = response else { + return nil + } + + return self.init(dictionary: response) + } + + required init?( + dictionary dict: [AnyHashable: Any] + ) { + super.init() + allResponseFields = dict + } +} diff --git a/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodAffirmParams.swift b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodAffirmParams.swift new file mode 100644 index 0000000..a2f132b --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodAffirmParams.swift @@ -0,0 +1,23 @@ +// +// STPPaymentMethodAffirmParams.swift +// StripePayments +// +// Copyright © 2022 Stripe, Inc. All rights reserved. +// + +import Foundation + +/// An object representing parameters used to create an Affirm Payment Method +public class STPPaymentMethodAffirmParams: NSObject, STPFormEncodable { + @objc public var additionalAPIParameters: [AnyHashable: Any] = [:] + + @objc + public static func rootObjectName() -> String? { + return "affirm" + } + + @objc + public static func propertyNamesToFormFieldNamesMapping() -> [String: String] { + return [:] + } +} diff --git a/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodAfterpayClearpay.swift b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodAfterpayClearpay.swift new file mode 100644 index 0000000..76e3d90 --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodAfterpayClearpay.swift @@ -0,0 +1,43 @@ +// +// STPPaymentMethodAfterpayClearpay.swift +// StripePayments +// +// Created by Ali Riaz on 1/12/21. +// Copyright © 2021 Stripe, Inc. All rights reserved. +// + +import Foundation + +/// An AfterpayClearpay Payment Method. +/// - seealso: https://stripe.com/docs/api/payment_methods/object#payment_method_object-afterpay_clearpay +public class STPPaymentMethodAfterpayClearpay: NSObject, STPAPIResponseDecodable { + @objc private(set) public var allResponseFields: [AnyHashable: Any] = [:] + + // MARK: - Description + /// :nodoc: + @objc public override var description: String { + let props = [ + // Object + String(format: "%@: %p", NSStringFromClass(STPPaymentMethodAfterpayClearpay.self), self) + ] + + return "<\(props.joined(separator: "; "))>" + } + + // MARK: - STPAPIResponseDecodeable + @objc + public class func decodedObject(fromAPIResponse response: [AnyHashable: Any]?) -> Self? { + guard let response = response else { + return nil + } + + return self.init(dictionary: response) + } + + required init?( + dictionary dict: [AnyHashable: Any] + ) { + super.init() + allResponseFields = dict + } +} diff --git a/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodAfterpayClearpayParams.swift b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodAfterpayClearpayParams.swift new file mode 100644 index 0000000..f38c3c3 --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodAfterpayClearpayParams.swift @@ -0,0 +1,24 @@ +// +// STPPaymentMethodAfterpayClearpayParams.swift +// StripePayments +// +// Created by Ali Riaz on 1/12/21. +// Copyright © 2021 Stripe, Inc. All rights reserved. +// + +import Foundation + +/// An object representing parameters used to create an AfterpayClearpay Payment Method +public class STPPaymentMethodAfterpayClearpayParams: NSObject, STPFormEncodable { + @objc public var additionalAPIParameters: [AnyHashable: Any] = [:] + + @objc + public static func rootObjectName() -> String? { + return "afterpay_clearpay" + } + + @objc + public static func propertyNamesToFormFieldNamesMapping() -> [String: String] { + return [:] + } +} diff --git a/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodAlipay.swift b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodAlipay.swift new file mode 100644 index 0000000..95d30fb --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodAlipay.swift @@ -0,0 +1,43 @@ +// +// STPPaymentMethodAlipay.swift +// StripePayments +// +// Copyright © 2020 Stripe, Inc. All rights reserved. +// + +import Foundation + +/// Contains details for an Alipay Payment Method. +/// - seealso: https://stripe.com/docs/api/payment_methods/object#payment_method_object-alipay +public class STPPaymentMethodAlipay: NSObject, STPAPIResponseDecodable { + /// :nodoc: + private(set) public var allResponseFields: [AnyHashable: Any] = [:] + + // MARK: - Description + /// :nodoc: + @objc public override var description: String { + let props = [ + // Object + String(format: "%@: %p", NSStringFromClass(STPPaymentMethodAlipay.self), self) + ] + + return "<\(props.joined(separator: "; "))>" + } + + // MARK: - STPAPIResponseDecodable + /// :nodoc: + public class func decodedObject(fromAPIResponse response: [AnyHashable: Any]?) -> Self? { + guard let dict = response?.stp_dictionaryByRemovingNulls() else { + return nil + } + return self.init(dictionary: dict) + + } + + required init( + dictionary dict: [AnyHashable: Any] + ) { + super.init() + allResponseFields = dict + } +} diff --git a/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodAlipayParams.swift b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodAlipayParams.swift new file mode 100644 index 0000000..967c6e2 --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodAlipayParams.swift @@ -0,0 +1,27 @@ +// +// STPPaymentMethodAlipayParams.swift +// StripePayments +// +// Created by Yuki Tokuhiro on 5/14/20. +// Copyright © 2020 Stripe, Inc. All rights reserved. +// + +import Foundation + +/// An object representing parameters used to create an Alipay Payment Method. +/// There are currently no parameters to pass. +/// - seealso: https://site-admin.stripe.com/docs/api/payment_methods/create#create_payment_method-alipay +public class STPPaymentMethodAlipayParams: NSObject, STPFormEncodable { + @objc public var additionalAPIParameters: [AnyHashable: Any] = [:] + + // MARK: - STPFormEncodable + @objc + public class func rootObjectName() -> String? { + return "alipay" + } + + @objc + public class func propertyNamesToFormFieldNamesMapping() -> [String: String] { + return [:] + } +} diff --git a/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodBLIK.swift b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodBLIK.swift new file mode 100644 index 0000000..eeac067 --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodBLIK.swift @@ -0,0 +1,44 @@ +// +// STPPaymentMethodBLIK.swift +// StripePayments +// +// Created by Yuki Tokuhiro on 3/10/21. +// Copyright © 2021 Stripe, Inc. All rights reserved. +// + +import Foundation + +/// Contains details for a BLIK Payment Method. +/// - seealso: https://stripe.com/docs/api/payment_methods/object#payment_method_object-blik +public class STPPaymentMethodBLIK: NSObject, STPAPIResponseDecodable { + /// :nodoc: + private(set) public var allResponseFields: [AnyHashable: Any] = [:] + + // MARK: - Description + /// :nodoc: + @objc public override var description: String { + let props = [ + // Object + String(format: "%@: %p", NSStringFromClass(STPPaymentMethodBLIK.self), self) + ] + + return "<\(props.joined(separator: "; "))>" + } + + // MARK: - STPAPIResponseDecodable + /// :nodoc: + public class func decodedObject(fromAPIResponse response: [AnyHashable: Any]?) -> Self? { + guard let dict = response?.stp_dictionaryByRemovingNulls() else { + return nil + } + return self.init(dictionary: dict) + + } + + required init( + dictionary dict: [AnyHashable: Any] + ) { + super.init() + allResponseFields = dict + } +} diff --git a/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodBLIKParams.swift b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodBLIKParams.swift new file mode 100644 index 0000000..34574b7 --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodBLIKParams.swift @@ -0,0 +1,27 @@ +// +// STPPaymentMethodBLIKParams.swift +// StripePayments +// +// Created by Yuki Tokuhiro on 3/10/21. +// Copyright © 2021 Stripe, Inc. All rights reserved. +// + +import Foundation + +/// An object representing parameters used to create a BLIK Payment Method +/// There are currently no parameters to pass. +/// - seealso: https://site-admin.stripe.com/docs/api/payment_methods/create#create_payment_method-blik +@objc +public class STPPaymentMethodBLIKParams: NSObject, STPFormEncodable { + @objc public var additionalAPIParameters: [AnyHashable: Any] = [:] + + @objc + public class func rootObjectName() -> String? { + return "blik" + } + + @objc + public class func propertyNamesToFormFieldNamesMapping() -> [String: String] { + return [:] + } +} diff --git a/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodBacsDebit.swift b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodBacsDebit.swift new file mode 100644 index 0000000..77b9a12 --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodBacsDebit.swift @@ -0,0 +1,54 @@ +// +// STPPaymentMethodBacsDebit.swift +// StripePayments +// +// Created by Yuki Tokuhiro on 1/28/20. +// Copyright © 2020 Stripe, Inc. All rights reserved. +// + +import Foundation + +/// A Bacs Debit Payment Method. +/// - seealso: https://stripe.com/docs/api/payment_methods/object#payment_method_object-bacs_debit +public class STPPaymentMethodBacsDebit: NSObject, STPAPIResponseDecodable { + private(set) public var allResponseFields: [AnyHashable: Any] = [:] + + /// This payment method's fingerprint. + @objc public private(set) var fingerprint: String? + /// The last four digits of the bank account. + @objc public private(set) var last4: String? + /// The sort code of the bank account (eg 10-88-00) + @objc public private(set) var sortCode: String? + + // MARK: - Description + /// :nodoc: + @objc public override var description: String { + let props = [ + // Object + String(format: "%@: %p", NSStringFromClass(STPPaymentMethodBacsDebit.self), self), + "fingerprint = \(fingerprint ?? "")", + "last4 = \(last4 ?? "")", + "sortCode = \(sortCode ?? "")", + ] + + return "<\(props.joined(separator: "; "))>" + } + + // MARK: - STPAPIResponseDecodable + public class func decodedObject(fromAPIResponse response: [AnyHashable: Any]?) -> Self? { + guard let response = response else { + return nil + } + return self.init(dictionary: response) + } + + required init( + dictionary dict: [AnyHashable: Any] + ) { + super.init() + fingerprint = dict["fingerprint"] as? String + last4 = dict["last4"] as? String + sortCode = dict["sort_code"] as? String + allResponseFields = dict + } +} diff --git a/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodBacsDebitParams.swift b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodBacsDebitParams.swift new file mode 100644 index 0000000..f592115 --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodBacsDebitParams.swift @@ -0,0 +1,33 @@ +// +// STPPaymentMethodBacsDebitParams.swift +// StripePayments +// +// Created by Yuki Tokuhiro on 1/29/20. +// Copyright © 2020 Stripe, Inc. All rights reserved. +// + +import Foundation + +/// The user's bank account details. +/// - seealso: https://stripe.com/docs/api/payment_methods/create#create_payment_method-bacs_debit +public class STPPaymentMethodBacsDebitParams: NSObject, STPFormEncodable { + @objc public var additionalAPIParameters: [AnyHashable: Any] = [:] + + /// The bank account number (eg 00012345) + @objc public var accountNumber: String? + /// The sort code of the bank account (eg 10-88-00) + @objc public var sortCode: String? + + @objc + public class func rootObjectName() -> String? { + return "bacs_debit" + } + + @objc + public class func propertyNamesToFormFieldNamesMapping() -> [String: String] { + return [ + NSStringFromSelector(#selector(getter:sortCode)): "sort_code", + NSStringFromSelector(#selector(getter:accountNumber)): "account_number", + ] + } +} diff --git a/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodBancontact.swift b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodBancontact.swift new file mode 100644 index 0000000..3d3f8d5 --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodBancontact.swift @@ -0,0 +1,41 @@ +// +// STPPaymentMethodBancontact.swift +// StripePayments +// +// Created by Vineet Shah on 4/29/20. +// Copyright © 2020 Stripe, Inc. All rights reserved. +// + +import Foundation + +/// A Bancontact Payment Method. +/// - seealso: https://stripe.com/docs/payments/bancontact +public class STPPaymentMethodBancontact: NSObject, STPAPIResponseDecodable { + private(set) public var allResponseFields: [AnyHashable: Any] = [:] + + // MARK: - Description + /// :nodoc: + @objc public override var description: String { + let props = [ + // Object + String(format: "%@: %p", NSStringFromClass(STPPaymentMethodBancontact.self), self) + ] + + return "<\(props.joined(separator: "; "))>" + } + + // MARK: - STPAPIResponseDecodable + public class func decodedObject(fromAPIResponse response: [AnyHashable: Any]?) -> Self? { + guard let response = response else { + return nil + } + return self.init(dictionary: response) + } + + required init( + dictionary dict: [AnyHashable: Any] + ) { + super.init() + allResponseFields = dict + } +} diff --git a/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodBancontactParams.swift b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodBancontactParams.swift new file mode 100644 index 0000000..4088671 --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodBancontactParams.swift @@ -0,0 +1,22 @@ +// +// STPPaymentMethodBancontactParams.swift +// StripePayments +// +// Created by Vineet Shah on 4/29/20. +// Copyright © 2020 Stripe, Inc. All rights reserved. +// + +import Foundation + +/// An object representing parameters used to create a Bancontact Payment Method +public class STPPaymentMethodBancontactParams: NSObject, STPFormEncodable { + public var additionalAPIParameters: [AnyHashable: Any] = [:] + + public class func rootObjectName() -> String? { + return "bancontact" + } + + public class func propertyNamesToFormFieldNamesMapping() -> [String: String] { + return [:] + } +} diff --git a/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodBoleto.swift b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodBoleto.swift new file mode 100644 index 0000000..b487cbc --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodBoleto.swift @@ -0,0 +1,56 @@ +// +// STPPaymentMethodBoleto.swift +// StripePayments +// +// Created by Ramon Torres on 9/8/21. +// Copyright © 2021 Stripe, Inc. All rights reserved. +// + +import Foundation + +/// A Boleto Payment Method. +/// - seealso: https://stripe.com/docs/payments/boleto +public class STPPaymentMethodBoleto: NSObject, STPAPIResponseDecodable { + + /// The tax ID of the customer (CPF for individuals or CNPJ for businesses). + @objc public let taxID: String + + /// :nodoc: + @objc public let allResponseFields: [AnyHashable: Any] + + /// :nodoc: + @objc public override var description: String { + let props = [ + // Object + String(format: "%@: %p", NSStringFromClass(STPPaymentMethodBoleto.self), self), + // Properties + "taxID: ", + ] + + return "<\(props.joined(separator: "; "))>" + } + + // MARK: - STPAPIResponseDecodable + + required init?( + dictionary: [AnyHashable: Any] + ) { + guard let taxID = dictionary["tax_id"] as? String else { + return nil + } + + self.taxID = taxID + self.allResponseFields = dictionary + + super.init() + } + + @objc + public class func decodedObject(fromAPIResponse response: [AnyHashable: Any]?) -> Self? { + guard let response = response else { + return nil + } + + return self.init(dictionary: response) + } +} diff --git a/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodBoletoParams.swift b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodBoletoParams.swift new file mode 100644 index 0000000..1abf542 --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodBoletoParams.swift @@ -0,0 +1,49 @@ +// +// STPPaymentMethodBoletoParams.swift +// StripePayments +// +// Created by Ramon Torres on 9/8/21. +// Copyright © 2021 Stripe, Inc. All rights reserved. +// + +import Foundation + +/// An object representing parameters used to create a Boleto Payment Method +public class STPPaymentMethodBoletoParams: NSObject, STPFormEncodable { + + /// The tax ID of the customer (CPF for individuals or CNPJ for businesses). + /// + /// Supported formats: + /// * `XXX.XXX.XXX-XX` or `XXXXXXXXXXX` for CPF + /// * `XX.XXX.XXX/XXXX-XX` or `XXXXXXXXXXXXXX` for CNPJ + @objc public var taxID: String? + + /// :nodoc: + @objc public var additionalAPIParameters: [AnyHashable: Any] = [:] + + /// :nodoc: + @objc public override var description: String { + let props = [ + // Object + String(format: "%@: %p", NSStringFromClass(STPPaymentMethodBoletoParams.self), self), + // Properties + "taxID: \(taxID != nil ? "" : "")", + ] + + return "<\(props.joined(separator: "; "))>" + } + + // MARK: - STPFormEncodable + + @objc + public class func rootObjectName() -> String? { + return "boleto" + } + + @objc + public class func propertyNamesToFormFieldNamesMapping() -> [String: String] { + return [ + NSStringFromSelector(#selector(getter:taxID)): "tax_id" + ] + } +} diff --git a/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodCard.swift b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodCard.swift new file mode 100644 index 0000000..98b0bac --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodCard.swift @@ -0,0 +1,124 @@ +// +// STPPaymentMethodCard.swift +// StripePayments +// +// Created by Yuki Tokuhiro on 3/5/19. +// Copyright © 2019 Stripe, Inc. All rights reserved. +// + +import Foundation + +/// Contains details about a user's credit card. +/// - seealso: https://stripe.com/docs/api/payment_methods/object#payment_method_object-card +public class STPPaymentMethodCard: NSObject, STPAPIResponseDecodable { + /// You cannot directly instantiate an `STPPaymentMethodCard`. You should only use one that is part of an existing `STPPaymentMethod` object. + required internal override init() { + super.init() + } + + /// The issuer of the card. + @objc public private(set) var brand: STPCardBrand = .unknown + /// Checks on Card address and CVC if provided. + @objc public private(set) var checks: STPPaymentMethodCardChecks? + /// Two-letter ISO code representing the country of the card. + @objc public private(set) var country: String? + /// Two-digit number representing the card’s expiration month. + @objc public private(set) var expMonth = 0 + /// Four-digit number representing the card’s expiration year. + @objc public private(set) var expYear = 0 + /// Card funding type. Can be credit, debit, prepaid, or unknown. + @objc public private(set) var funding: String? + /// The last four digits of the card. + @objc public private(set) var last4: String? + /// Uniquely identifies this particular card number. You can use this attribute to check whether two customers who’ve signed up with you are using the same card number, for example. + @objc public private(set) var fingerprint: String? + /// Contains information about card networks that can be used to process the payment. + @objc public private(set) var networks: STPPaymentMethodCardNetworks? + /// Contains details on how this Card maybe be used for 3D Secure authentication. + @objc public private(set) var threeDSecureUsage: STPPaymentMethodThreeDSecureUsage? + /// If this Card is part of a Card Wallet, this contains the details of the Card Wallet. + @objc public private(set) var wallet: STPPaymentMethodCardWallet? + + /// Returns a string representation for the provided card brand; + /// i.e. `STPPaymentMethodCard.string(from brand:.visa) == "Visa"`. + /// - Parameter brand: the brand you want to convert to a string + /// - Returns: A string representing the brand, suitable for displaying to a user. + @objc(stringFromBrand:) public class func string(from brand: STPCardBrand) -> String { + return STPCardBrandUtilities.stringFrom(brand) ?? "" + } + public private(set) var allResponseFields: [AnyHashable: Any] = [:] + + /// :nodoc: + @objc public override var description: String { + let props = [ + // Object + String(format: "%@: %p", NSStringFromClass(STPPaymentMethodCard.self), self), + "brand = \(STPCardBrandUtilities.stringFrom(brand) ?? "")", + "checks = \(checks?.description ?? "")", + "country = \(country ?? "")", + String(format: "expMonth = %lu", UInt(expMonth)), + String(format: "expYear = %lu", UInt(expYear)), + "funding = \(funding ?? "")", + "last4 = \(last4 ?? "")", + "fingerprint = \(fingerprint ?? "")", + "networks = \(networks?.description ?? "")", + "threeDSecureUsage = \(threeDSecureUsage?.description ?? "")", + "wallet = \(wallet?.description ?? "")", + ] + + return "<\(props.joined(separator: "; "))>" + } + + // MARK: - STPAPIResponseDecodable + public class func decodedObject(fromAPIResponse response: [AnyHashable: Any]?) -> Self? { + guard let response = response else { + return nil + } + let dict = response.stp_dictionaryByRemovingNulls() + + let card = self.init() + card.allResponseFields = response + card.brand = self.brand(from: dict.stp_string(forKey: "brand") ?? "") + card.checks = STPPaymentMethodCardChecks.decodedObject( + fromAPIResponse: dict.stp_dictionary(forKey: "checks")) + card.country = dict.stp_string(forKey: "country") + card.expMonth = dict.stp_int(forKey: "exp_month", or: 0) + card.expYear = dict.stp_int(forKey: "exp_year", or: 0) + card.funding = dict.stp_string(forKey: "funding") + card.last4 = dict.stp_string(forKey: "last4") + card.fingerprint = dict.stp_string(forKey: "fingerprint") + card.networks = STPPaymentMethodCardNetworks.decodedObject( + fromAPIResponse: dict["networks"] as? [AnyHashable: Any] + ) + card.threeDSecureUsage = STPPaymentMethodThreeDSecureUsage.decodedObject( + fromAPIResponse: dict.stp_dictionary(forKey: "three_d_secure_usage")) + card.wallet = STPPaymentMethodCardWallet.decodedObject( + fromAPIResponse: dict.stp_dictionary(forKey: "wallet")) + return card + } + + // MARK: - STPCardBrand + + @objc(brandFromString:) @_spi(STP) public class func brand(from string: String) -> STPCardBrand + { + // Documentation: https://stripe.com/docs/api/payment_methods/object#payment_method_object-card-brand + let brand = string.lowercased() + if brand == "visa" { + return .visa + } else if brand == "amex" || brand == "american_express" { + return .amex + } else if brand == "mastercard" { + return .mastercard + } else if brand == "discover" { + return .discover + } else if brand == "jcb" { + return .JCB + } else if brand == "diners" || brand == "diners_club" { + return .dinersClub + } else if brand == "unionpay" { + return .unionPay + } else { + return .unknown + } + } +} diff --git a/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodCardChecks.swift b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodCardChecks.swift new file mode 100644 index 0000000..f0546ab --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodCardChecks.swift @@ -0,0 +1,102 @@ +// +// STPPaymentMethodCardChecks.swift +// StripePayments +// +// Created by Yuki Tokuhiro on 3/5/19. +// Copyright © 2019 Stripe, Inc. All rights reserved. +// + +import Foundation + +/// The result of a check on a Card address or CVC. +@objc +public enum STPPaymentMethodCardCheckResult: Int { + /// The check passed. + case pass + /// The check failed. + case failed + /// The check is unavailable. + case unavailable + /// The value was not checked. + case unchecked + /// Represents an unknown or null value. + case unknown +} + +/// Checks on Card address and CVC. +/// - seealso: https://stripe.com/docs/api/payment_methods/object#payment_method_object-card-checks +public class STPPaymentMethodCardChecks: NSObject, STPAPIResponseDecodable { + override required init() { + super.init() + } + + // MARK: - Deprecated + // TODO(swift): Figure out deprecation strategy + /// If a address line1 was provided, results of the check. + @available( + *, + deprecated, + message: + "Card check values are no longer returned to clients using publishable keys. Retrieve them on your server using your secret key instead." + ) + @objc public private(set) var addressLine1Check: STPPaymentMethodCardCheckResult = .unknown + /// If a address postal code was provided, results of the check. + /// deprecated Card check values are no longer returned to clients using publishable keys. Retrieve them on your server using yoursecret key instead. + @available( + *, + deprecated, + message: + "Card check values are no longer returned to clients using publishable keys. Retrieve them on your server using your secret key instead." + ) + @objc public private(set) var addressPostalCodeCheck: STPPaymentMethodCardCheckResult = .unknown + /// If a CVC was provided, results of the check. + /// deprecated Card check values are no longer returned to clients using publishable keys. Retrieve them on your server using yoursecret key instead. + @available( + *, + deprecated, + message: + "Card check values are no longer returned to clients using publishable keys. Retrieve them on your server using your secret key instead." + ) + @objc public private(set) var cvcCheck: STPPaymentMethodCardCheckResult = .unknown + @objc private(set) public var allResponseFields: [AnyHashable: Any] = [:] + + /// :nodoc: + @objc public override var description: String { + let props = [ + // Object + String(format: "%@: %p", NSStringFromClass(STPPaymentMethodCardChecks.self), self), + // Properties + "addressLine1Check: \(allResponseFields["address_line1_check"] ?? "")", + "addressPostalCodeCheck: \(allResponseFields["address_postal_code_check"] ?? "")", + "cvcCheck: \(allResponseFields["cvc_check"] ?? "")", + ] + + return "<\(props.joined(separator: "; "))>" + } + + @objc(checkResultFromString:) + class func checkResult(from string: String?) -> STPPaymentMethodCardCheckResult { + let check = string?.lowercased() + if check == "pass" { + return .pass + } else if check == "failed" { + return .failed + } else if check == "unavailable" { + return .unavailable + } else if check == "unchecked" { + return .unchecked + } else { + return .unknown + } + } + + // MARK: - STPAPIResponseDecodable + public class func decodedObject(fromAPIResponse response: [AnyHashable: Any]?) -> Self? { + guard let response = response else { + return nil + } + let cardChecks = self.init() + cardChecks.allResponseFields = response + return cardChecks + } +} diff --git a/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodCardNetworks.swift b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodCardNetworks.swift new file mode 100644 index 0000000..9072094 --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodCardNetworks.swift @@ -0,0 +1,53 @@ +// +// STPPaymentMethodCardNetworks.swift +// StripePayments +// +// Created by Cameron Sabol on 7/15/20. +// Copyright © 2020 Stripe, Inc. All rights reserved. +// + +import Foundation + +/// `STPPaymentMethodCardNetworks` contains information about card networks that can be used to process a payment. +public class STPPaymentMethodCardNetworks: NSObject, STPAPIResponseDecodable { + private(set) public var allResponseFields: [AnyHashable: Any] = [:] + + /// All available networks for the card. + @objc public private(set) var available: [String] = [] + /// The preferred network for the card if one exists. + @objc public private(set) var preferred: String? + + /// :nodoc: + @objc public override var description: String { + let props = [ + // Object + String(format: "%@: %p", NSStringFromClass(STPPaymentMethodCardNetworks.self), self), + // Properties + "available: \(available)", + "preferred: \(preferred ?? "")", + ] + + return "<\(props.joined(separator: "; "))>" + } + + // MARK: - STPAPIResponseDecodable + required init?( + withDictionary dict: [AnyHashable: Any] + ) { + super.init() + let dict = dict.stp_dictionaryByRemovingNulls() + guard let available = dict.stp_array(forKey: "available") as? [String] else { + return nil + } + self.available = available + self.preferred = dict.stp_string(forKey: "preferred") + self.allResponseFields = dict + } + + public class func decodedObject(fromAPIResponse response: [AnyHashable: Any]?) -> Self? { + guard let response = response else { + return nil + } + return self.init(withDictionary: response) + } +} diff --git a/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodCardParams.swift b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodCardParams.swift new file mode 100644 index 0000000..bb5edc2 --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodCardParams.swift @@ -0,0 +1,124 @@ +// +// STPPaymentMethodCardParams.swift +// StripePayments +// +// Created by Yuki Tokuhiro on 3/6/19. +// Copyright © 2019 Stripe, Inc. All rights reserved. +// + +import Foundation + +/// The user's card details. +public class STPPaymentMethodCardParams: NSObject, STPFormEncodable { + @objc public var additionalAPIParameters: [AnyHashable: Any] = [:] + + /// A convenience initializer for creating a payment method from a card source. + /// This should be used to help with migrations to Payment Methods from Sources. + @objc public convenience init( + cardSourceParams: STPCardParams + ) { + self.init() + number = cardSourceParams.number + expMonth = NSNumber(value: cardSourceParams.expMonth) + expYear = NSNumber(value: cardSourceParams.expYear) + cvc = cardSourceParams.cvc + } + + /// Initializes an empty STPPaymentMethodCardParams. + public required override init() { + super.init() + } + + /// The card number, as a string without any separators. Ex. @"4242424242424242" + @objc public var number: String? + /// Number representing the card's expiration month. Ex. @1 + @objc public var expMonth: NSNumber? + /// Two- or four-digit number representing the card's expiration year. + @objc public var expYear: NSNumber? + /// For backwards compatibility, you can alternatively set this as a Stripe token (e.g., for apple pay) + @objc public var token: String? + /// Card security code. It is highly recommended to always include this value. + @objc public var cvc: String? + /// The last 4 digits of the card. + + @objc public var last4: String? { + if number != nil && (number?.count ?? 0) >= 4 { + return (number as NSString?)?.substring(from: (number?.count ?? 0) - 4) ?? "" + } else { + return "" + } + } + + // MARK: - Description + /// :nodoc: + @objc public override var description: String { + let props = [ + // Object + String(format: "%@: %p", NSStringFromClass(STPPaymentMethodCardParams.self), self), + // Basic card details + "last4 = \(last4 ?? "")", + "expMonth = \(expMonth ?? 0)", + "expYear = \(expYear ?? 0)", + "cvc = \(((cvc) != nil ? "" : nil) ?? "")", + // Token + "token = \(token ?? "")", + ] + + return "<\(props.joined(separator: "; "))>" + } + + // MARK: - STPFormEncodable + + @objc + public class func rootObjectName() -> String? { + return "card" + } + + @objc + public class func propertyNamesToFormFieldNamesMapping() -> [String: String] { + return [ + NSStringFromSelector(#selector(getter:number)): "number", + NSStringFromSelector(#selector(getter:expMonth)): "exp_month", + NSStringFromSelector(#selector(getter:expYear)): "exp_year", + NSStringFromSelector(#selector(getter:cvc)): "cvc", + NSStringFromSelector(#selector(getter:token)): "token", + ] + } + + // MARK: - NSCopying + @objc(copyWithZone:) func copy(with zone: NSZone? = nil) -> Any { + let copyCardParams = type(of: self).init() + + copyCardParams.number = number + copyCardParams.expMonth = expMonth + copyCardParams.expYear = expYear + copyCardParams.cvc = cvc + return copyCardParams + } + + // MARK: - Equality + /// :nodoc: + @objc + public override func isEqual(_ other: Any?) -> Bool { + return isEqual(to: other as? STPPaymentMethodCardParams) + } + + func isEqual(to other: STPPaymentMethodCardParams?) -> Bool { + if self === other { + return true + } + + if other == nil || !(other != nil) { + return false + } + + if let other = other, + !((additionalAPIParameters as NSDictionary).isEqual(to: other.additionalAPIParameters)) + { + return false + } + + return number == other?.number && expMonth == other?.expMonth && expYear == other?.expYear + && cvc == other?.cvc && token == other?.token + } +} diff --git a/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodCardPresent.swift b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodCardPresent.swift new file mode 100644 index 0000000..a51eb67 --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodCardPresent.swift @@ -0,0 +1,38 @@ +// +// STPPaymentMethodCardPresent.swift +// StripePayments +// +// Created by Yuki Tokuhiro on 3/11/19. +// Copyright © 2019 Stripe, Inc. All rights reserved. +// + +import Foundation + +/// Details about the Card Present payment method + +public class STPPaymentMethodCardPresent: NSObject, STPAPIResponseDecodable { + public private(set) var allResponseFields: [AnyHashable: Any] = [:] + + /// :nodoc: + @objc public override var description: String { + let props = [ + // Object + String(format: "%@: %p", NSStringFromClass(STPPaymentMethodCardPresent.self), self) + ] + return "<\(props.joined(separator: "; "))>" + } + + required override init() { + super.init() + } + + // MARK: - STPAPIResponseDecodable + public class func decodedObject(fromAPIResponse response: [AnyHashable: Any]?) -> Self? { + guard let dict = response?.stp_dictionaryByRemovingNulls() else { + return nil + } + let cardPresent = self.init() + cardPresent.allResponseFields = dict + return cardPresent + } +} diff --git a/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodCardWallet.swift b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodCardWallet.swift new file mode 100644 index 0000000..6ff3d22 --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodCardWallet.swift @@ -0,0 +1,111 @@ +// +// STPPaymentMethodCardWallet.swift +// StripePayments +// +// Created by Yuki Tokuhiro on 3/9/19. +// Copyright © 2019 Stripe, Inc. All rights reserved. +// + +import Foundation + +/// The type of Card Wallet. +@objc +public enum STPPaymentMethodCardWalletType: Int { + /// Amex Express Checkout + case amexExpressCheckout + /// Apple Pay + case applePay + /// Google Pay + case googlePay + /// Masterpass + case masterpass + /// Samsung Pay + case samsungPay + /// Visa Checkout + case visaCheckout + /// An unknown Card Wallet type. + case unknown +} + +/// A Card Wallet. +/// - seealso: https://stripe.com/docs/api/payment_methods/object#payment_method_object-card-wallet +public class STPPaymentMethodCardWallet: NSObject, STPAPIResponseDecodable { + /// The type of the Card Wallet. A matching property is populated if the type is `STPPaymentMethodCardWalletTypeMasterpass` or `STPPaymentMethodCardWalletTypeVisaCheckout` containing additional information specific to the Card Wallet type. + @objc public private(set) var type: STPPaymentMethodCardWalletType = .unknown + /// Contains additional Masterpass information, if the type of the Card Wallet is `STPPaymentMethodCardWalletTypeMasterpass` + @objc public private(set) var masterpass: STPPaymentMethodCardWalletMasterpass? + /// Contains additional Visa Checkout information, if the type of the Card Wallet is `STPPaymentMethodCardWalletTypeVisaCheckout` + @objc public private(set) var visaCheckout: STPPaymentMethodCardWalletVisaCheckout? + @objc public private(set) var allResponseFields: [AnyHashable: Any] = [:] + + /// :nodoc: + @objc public override var description: String { + let props = [ + // Object + String(format: "%@: %p", NSStringFromClass(STPPaymentMethodCardWallet.self), self), + // Properties + "masterpass: \(String(describing: masterpass))", + "visaCheckout: \(String(describing: visaCheckout))", + ] + return "<\(props.joined(separator: "; "))>" + } + + // MARK: - STPPaymentMethodCardWalletType + class func stringToTypeMapping() -> [String: NSNumber] { + return [ + "amex_express_checkout": NSNumber( + value: STPPaymentMethodCardWalletType.amexExpressCheckout.rawValue + ), + "apple_pay": NSNumber(value: STPPaymentMethodCardWalletType.applePay.rawValue), + "google_pay": NSNumber(value: STPPaymentMethodCardWalletType.googlePay.rawValue), + "masterpass": NSNumber(value: STPPaymentMethodCardWalletType.masterpass.rawValue), + "samsung_pay": NSNumber(value: STPPaymentMethodCardWalletType.samsungPay.rawValue), + "visa_checkout": NSNumber(value: STPPaymentMethodCardWalletType.visaCheckout.rawValue), + ] + } + + @objc(typeFromString:) + class func type(from string: String) -> STPPaymentMethodCardWalletType { + let key = string.lowercased() + let typeNumber = self.stringToTypeMapping()[key] + + if let typeNumber = typeNumber { + return (STPPaymentMethodCardWalletType(rawValue: typeNumber.intValue))! + } + + return .unknown + } + + // MARK: - STPAPIResponseDecodable + override required init() { + super.init() + } + + public class func decodedObject(fromAPIResponse response: [AnyHashable: Any]?) -> Self? { + guard let response = response else { + return nil + } + let dict = response.stp_dictionaryByRemovingNulls() + let wallet = self.init() + wallet.allResponseFields = response + wallet.type = self.type(from: dict.stp_string(forKey: "type") ?? "") + wallet.visaCheckout = STPPaymentMethodCardWalletVisaCheckout.decodedObject( + fromAPIResponse: dict.stp_dictionary(forKey: "visa_checkout") + ) + wallet.masterpass = STPPaymentMethodCardWalletMasterpass.decodedObject( + fromAPIResponse: dict.stp_dictionary(forKey: "masterpass") + ) + return wallet + } +} + +// +// STPPaymentMethodCardWallet+Private.h +// StripeiOS +// +// Created by Yuki Tokuhiro on 3/9/19. +// Copyright © 2019 Stripe, Inc. All rights reserved. +// + +extension STPPaymentMethodCardWallet { +} diff --git a/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodCardWalletMasterpass.swift b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodCardWalletMasterpass.swift new file mode 100644 index 0000000..f9114b9 --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodCardWalletMasterpass.swift @@ -0,0 +1,66 @@ +// +// STPPaymentMethodCardWalletMasterpass.swift +// StripePayments +// +// Created by Yuki Tokuhiro on 3/9/19. +// Copyright © 2019 Stripe, Inc. All rights reserved. +// + +import Foundation + +/// A Masterpass Card Wallet +/// - seealso: https://stripe.com/docs/masterpass +public class STPPaymentMethodCardWalletMasterpass: NSObject, STPAPIResponseDecodable { + /// Owner’s verified email. Values are verified or provided by the payment method directly (and if supported) at the time of authorization or settlement. + @objc public private(set) var email: String? + /// Owner’s verified email. Values are verified or provided by the payment method directly (and if supported) at the time of authorization or settlement. + @objc public private(set) var name: String? + /// Owner’s verified billing address. Values are verified or provided by the payment method directly (and if supported) at the time of authorization or settlement. + @objc public private(set) var billingAddress: STPPaymentMethodAddress? + /// Owner’s verified shipping address. Values are verified or provided by the payment method directly (and if supported) at the time of authorization or settlement. + @objc public private(set) var shippingAddress: STPPaymentMethodAddress? + @objc public private(set) var allResponseFields: [AnyHashable: Any] = [:] + + /// :nodoc: + @objc public override var description: String { + let props = [ + // Object + String( + format: "%@: %p", + NSStringFromClass(STPPaymentMethodCardWalletMasterpass.self), + self + ), + // Properties + "email: \(email ?? "")", + "name: \(name ?? "")", + "billingAddress: \(String(describing: billingAddress))", + "shippingAddress: \(String(describing: shippingAddress))", + ] + return "<\(props.joined(separator: "; "))>" + } + + // MARK: - STPAPIResponseDecodable + + override required init() { + super.init() + } + + public class func decodedObject(fromAPIResponse response: [AnyHashable: Any]?) -> Self? { + guard let response = response else { + return nil + } + let dict = response.stp_dictionaryByRemovingNulls() + + let masterpass = self.init() + masterpass.allResponseFields = response + masterpass.billingAddress = STPPaymentMethodAddress.decodedObject( + fromAPIResponse: dict.stp_dictionary(forKey: "billing_address") + ) + masterpass.shippingAddress = STPPaymentMethodAddress.decodedObject( + fromAPIResponse: dict.stp_dictionary(forKey: "shipping_address") + ) + masterpass.email = dict.stp_string(forKey: "email") + masterpass.name = dict.stp_string(forKey: "name") + return masterpass + } +} diff --git a/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodCardWalletVisaCheckout.swift b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodCardWalletVisaCheckout.swift new file mode 100644 index 0000000..9934478 --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodCardWalletVisaCheckout.swift @@ -0,0 +1,47 @@ +// +// STPPaymentMethodCardWalletVisaCheckout.swift +// StripePayments +// +// Created by Yuki Tokuhiro on 3/9/19. +// Copyright © 2019 Stripe, Inc. All rights reserved. +// + +import Foundation + +/// A Visa Checkout Card Wallet +/// - seealso: https://stripe.com/docs/visa-checkout +public class STPPaymentMethodCardWalletVisaCheckout: NSObject, STPAPIResponseDecodable { + /// Owner’s verified email. Values are verified or provided by the payment method directly (and if supported) at the time of authorization or settlement. + @objc public private(set) var email: String? + /// Owner’s verified email. Values are verified or provided by the payment method directly (and if supported) at the time of authorization or settlement. + @objc public private(set) var name: String? + /// Owner’s verified billing address. Values are verified or provided by the payment method directly (and if supported) at the time of authorization or settlement. + @objc public private(set) var billingAddress: STPPaymentMethodAddress? + /// Owner’s verified shipping address. Values are verified or provided by the payment method directly (and if supported) at the time of authorization or settlement. + @objc public private(set) var shippingAddress: STPPaymentMethodAddress? + private(set) public var allResponseFields: [AnyHashable: Any] = [:] + + override required init() { + super.init() + } + + // MARK: - STPAPIResponseDecodable + public class func decodedObject(fromAPIResponse response: [AnyHashable: Any]?) -> Self? { + guard let response = response else { + return nil + } + let dict = response.stp_dictionaryByRemovingNulls() + + let visaCheckout = self.init() + visaCheckout.allResponseFields = response + visaCheckout.billingAddress = STPPaymentMethodAddress.decodedObject( + fromAPIResponse: dict.stp_dictionary(forKey: "billing_address") + ) + visaCheckout.shippingAddress = STPPaymentMethodAddress.decodedObject( + fromAPIResponse: dict.stp_dictionary(forKey: "shipping_address") + ) + visaCheckout.email = dict.stp_string(forKey: "email") + visaCheckout.name = dict.stp_string(forKey: "name") + return visaCheckout + } +} diff --git a/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodEPS.swift b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodEPS.swift new file mode 100644 index 0000000..6954138 --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodEPS.swift @@ -0,0 +1,42 @@ +// +// STPPaymentMethodEPS.swift +// StripePayments +// +// Created by Shengwei Wu on 5/14/20. +// Copyright © 2020 Stripe, Inc. All rights reserved. +// + +import Foundation + +/// An EPS Payment Method. +/// - seealso: https://stripe.com/docs/api/payment_methods/object#payment_method_object-eps +public class STPPaymentMethodEPS: NSObject, STPAPIResponseDecodable { + private(set) public var allResponseFields: [AnyHashable: Any] = [:] + + // MARK: - Description + /// :nodoc: + @objc public override var description: String { + let props = [ + // Object + String(format: "%@: %p", NSStringFromClass(STPPaymentMethodEPS.self), self) + ] + + return "<\(props.joined(separator: "; "))>" + } + + // MARK: - STPAPIResponseDecodable + public class func decodedObject(fromAPIResponse response: [AnyHashable: Any]?) -> Self? { + + guard let response = response else { + return nil + } + return self.init(dictionary: response) + } + + required init( + dictionary dict: [AnyHashable: Any] + ) { + super.init() + allResponseFields = dict + } +} diff --git a/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodEPSParams.swift b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodEPSParams.swift new file mode 100644 index 0000000..c0f78b2 --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodEPSParams.swift @@ -0,0 +1,22 @@ +// +// STPPaymentMethodEPSParams.swift +// StripePayments +// +// Created by Shengwei Wu on 5/14/20. +// Copyright © 2020 Stripe, Inc. All rights reserved. +// + +import Foundation + +/// An object representing parameters used to create a EPS Payment Method +public class STPPaymentMethodEPSParams: NSObject, STPFormEncodable { + public var additionalAPIParameters: [AnyHashable: Any] = [:] + + public class func rootObjectName() -> String? { + return "eps" + } + + public class func propertyNamesToFormFieldNamesMapping() -> [String: String] { + return [:] + } +} diff --git a/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodFPX.swift b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodFPX.swift new file mode 100644 index 0000000..608b303 --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodFPX.swift @@ -0,0 +1,46 @@ +// +// STPPaymentMethodFPX.swift +// StripePayments +// +// Created by David Estes on 7/30/19. +// Copyright © 2019 Stripe, Inc. All rights reserved. +// + +import Foundation + +/// An FPX Payment Method. +/// - seealso: https://stripe.com/docs/api/payment_methods/object#payment_method_object-fpx +public class STPPaymentMethodFPX: NSObject, STPAPIResponseDecodable { + /// The customer’s bank identifier code. + @objc public private(set) var bankIdentifierCode: String? + private(set) public var allResponseFields: [AnyHashable: Any] = [:] + + /// :nodoc: + @objc public override var description: String { + let props = [ + // Object + String(format: "%@: %p", NSStringFromClass(STPPaymentMethodFPX.self), self), + // Properties + "bank: \(bankIdentifierCode ?? "")", + ] + + return "<\(props.joined(separator: "; "))>" + } + + override required init() { + super.init() + } + + // MARK: - STPAPIResponseDecodable + public class func decodedObject(fromAPIResponse response: [AnyHashable: Any]?) -> Self? { + guard let response = response else { + return nil + } + let dict = response.stp_dictionaryByRemovingNulls() + + let fpx = self.init() + fpx.allResponseFields = response + fpx.bankIdentifierCode = dict.stp_string(forKey: "bank") + return fpx + } +} diff --git a/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodFPXParams.swift b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodFPXParams.swift new file mode 100644 index 0000000..6a8bdd8 --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodFPXParams.swift @@ -0,0 +1,47 @@ +// +// STPPaymentMethodFPXParams.swift +// StripePayments +// +// Created by David Estes on 7/30/19. +// Copyright © 2019 Stripe, Inc. All rights reserved. +// + +import Foundation + +/// An object representing parameters used to create an FPX Payment Method +public class STPPaymentMethodFPXParams: NSObject, STPFormEncodable { + @objc public var additionalAPIParameters: [AnyHashable: Any] = [:] + + /// The customer's bank. Required. + + @objc public var bank: STPFPXBankBrand { + get { + return STPFPXBank.brandFrom(rawBankString) + } + set(_bank) { + // If setting unknown and we're already unknown, don't want to override raw value + if _bank != self.bank { + rawBankString = STPFPXBank.identifierFrom(_bank) + } + } + } + /// The raw underlying bank string sent to the server. + /// Generally you should use `bank` instead unless you have a reason not to. + /// You can use this if you want to create a param of a bank not yet supported + /// by the current version of the SDK's `STPFPXBankBrand` enum. + /// Setting this to a value not known by the SDK causes `bank` to + /// return `STPFPXBankBrandUnknown` + @objc public var rawBankString: String? + + // MARK: - STPFormEncodable + + public class func rootObjectName() -> String? { + return "fpx" + } + + public class func propertyNamesToFormFieldNamesMapping() -> [String: String] { + return [ + NSStringFromSelector(#selector(getter:rawBankString)): "bank" + ] + } +} diff --git a/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodGiropay.swift b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodGiropay.swift new file mode 100644 index 0000000..42fbe8a --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodGiropay.swift @@ -0,0 +1,41 @@ +// +// STPPaymentMethodGiropay.swift +// StripePayments +// +// Created by Cameron Sabol on 4/21/20. +// Copyright © 2020 Stripe, Inc. All rights reserved. +// + +import Foundation + +/// A giropay Payment Method. +/// - seealso: https://stripe.com/docs/api/payment_methods/object#payment_method_object-giropay +public class STPPaymentMethodGiropay: NSObject, STPAPIResponseDecodable { + private(set) public var allResponseFields: [AnyHashable: Any] = [:] + + // MARK: - Description + /// :nodoc: + @objc public override var description: String { + let props = [ + // Object + String(format: "%@: %p", NSStringFromClass(STPPaymentMethodGiropay.self), self) + ] + + return "<\(props.joined(separator: "; "))>" + } + + // MARK: - STPAPIResponseDecodable + public class func decodedObject(fromAPIResponse response: [AnyHashable: Any]?) -> Self? { + guard let response = response else { + return nil + } + return self.init(dictionary: response) + } + + required init( + dictionary dict: [AnyHashable: Any] + ) { + super.init() + allResponseFields = dict + } +} diff --git a/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodGiropayParams.swift b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodGiropayParams.swift new file mode 100644 index 0000000..a19c605 --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodGiropayParams.swift @@ -0,0 +1,22 @@ +// +// STPPaymentMethodGiropayParams.swift +// StripePayments +// +// Created by Cameron Sabol on 4/21/20. +// Copyright © 2020 Stripe, Inc. All rights reserved. +// + +import Foundation + +/// An object representing parameters used to create a giropay Payment Method +public class STPPaymentMethodGiropayParams: NSObject, STPFormEncodable { + @objc public var additionalAPIParameters: [AnyHashable: Any] = [:] + + public class func rootObjectName() -> String? { + return "giropay" + } + + public class func propertyNamesToFormFieldNamesMapping() -> [String: String] { + return [:] + } +} diff --git a/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodGrabPay.swift b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodGrabPay.swift new file mode 100644 index 0000000..e16c4c1 --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodGrabPay.swift @@ -0,0 +1,40 @@ +// +// STPPaymentMethodGrabPay.swift +// StripePayments +// +// Copyright © 2020 Stripe, Inc. All rights reserved. +// + +import Foundation + +/// A GrabPay PaymentMethod +/// - seealso: https://stripe.com/docs/api/payment_methods/object#payment_method_object-grabpay +public class STPPaymentMethodGrabPay: NSObject, STPAPIResponseDecodable { + private(set) public var allResponseFields: [AnyHashable: Any] = [:] + + // MARK: - Description + /// :nodoc: + @objc public override var description: String { + let props = [ + // Object + String(format: "%@: %p", NSStringFromClass(STPPaymentMethodGrabPay.self), self) + ] + + return "<\(props.joined(separator: "; "))>" + } + + // MARK: - STPAPIResponseDecodable + public class func decodedObject(fromAPIResponse response: [AnyHashable: Any]?) -> Self? { + guard let response = response else { + return nil + } + return self.init(dictionary: response) + } + + required init( + dictionary dict: [AnyHashable: Any] + ) { + super.init() + allResponseFields = dict + } +} diff --git a/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodGrabPayParams.swift b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodGrabPayParams.swift new file mode 100644 index 0000000..0e049d0 --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodGrabPayParams.swift @@ -0,0 +1,23 @@ +// +// STPPaymentMethodGrabPayParams.swift +// StripePayments +// +// Created by Yuki Tokuhiro on 7/21/20. +// Copyright © 2020 Stripe, Inc. All rights reserved. +// + +import Foundation + +/// An object representing parameters used to create a GrabPay Payment Method +public class STPPaymentMethodGrabPayParams: NSObject, STPFormEncodable { + public var additionalAPIParameters: [AnyHashable: Any] = [:] + + // MARK: - STPFormEncodable + public class func rootObjectName() -> String? { + return "grabpay" + } + + public class func propertyNamesToFormFieldNamesMapping() -> [String: String] { + return [:] + } +} diff --git a/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodKlarna.swift b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodKlarna.swift new file mode 100644 index 0000000..4e7dc44 --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodKlarna.swift @@ -0,0 +1,45 @@ +// +// STPPaymentMethodKlarna.swift +// StripePayments +// +// Created by Nick Porter on 10/19/21. +// Copyright © 2021 Stripe, Inc. All rights reserved. +// + +import Foundation + +/// The Klarna Payment Method. +/// - seealso: https://stripe.com/docs/payments/klarna +public class STPPaymentMethodKlarna: NSObject, STPAPIResponseDecodable { + /// :nodoc: + @objc private(set) public var allResponseFields: [AnyHashable: Any] = [:] + + // MARK: - Description + /// :nodoc: + @objc public override var description: String { + let props = [ + // Object + String(format: "%@: %p", NSStringFromClass(STPPaymentMethodKlarna.self), self) + ] + + return "<\(props.joined(separator: "; "))>" + } + + // MARK: - STPAPIResponseDecodeable + @objc + /// :nodoc: + public class func decodedObject(fromAPIResponse response: [AnyHashable: Any]?) -> Self? { + guard let response = response else { + return nil + } + + return self.init(dictionary: response) + } + + required init?( + dictionary dict: [AnyHashable: Any] + ) { + super.init() + allResponseFields = dict + } +} diff --git a/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodKlarnaParams.swift b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodKlarnaParams.swift new file mode 100644 index 0000000..55ea828 --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodKlarnaParams.swift @@ -0,0 +1,24 @@ +// +// STPPaymentMethodKlarnaParams.swift +// StripePayments +// +// Created by Nick Porter on 10/19/21. +// Copyright © 2021 Stripe, Inc. All rights reserved. +// + +import Foundation + +/// An object representing parameters used to create an Klarna Payment Method +public class STPPaymentMethodKlarnaParams: NSObject, STPFormEncodable { + @objc public var additionalAPIParameters: [AnyHashable: Any] = [:] + + @objc + public static func rootObjectName() -> String? { + return "klarna" + } + + @objc + public static func propertyNamesToFormFieldNamesMapping() -> [String: String] { + return [:] + } +} diff --git a/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodLink.swift b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodLink.swift new file mode 100644 index 0000000..5cd8025 --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodLink.swift @@ -0,0 +1,42 @@ +// +// STPPaymentMethodLink.swift +// StripePayments +// +// Created by Cameron Sabol on 7/6/21. +// Copyright © 2021 Stripe, Inc. All rights reserved. +// + +import Foundation + +/// A Link Payment Method. +public class STPPaymentMethodLink: NSObject, STPAPIResponseDecodable { + + @objc public private(set) var allResponseFields: [AnyHashable: Any] = [:] + + // MARK: - Description + + /// :nodoc: + @objc public override var description: String { + let props = [ + // Object + String(format: "%@: %p", NSStringFromClass(STPPaymentMethodLink.self), self) + ] + + return "<\(props.joined(separator: "; "))>" + } + + // MARK: - STPAPIResponseDecodable + public class func decodedObject(fromAPIResponse response: [AnyHashable: Any]?) -> Self? { + guard let response = response else { + return nil + } + return self.init(dictionary: response) + } + + required init( + dictionary dict: [AnyHashable: Any] + ) { + super.init() + allResponseFields = dict + } +} diff --git a/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodLinkParams.swift b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodLinkParams.swift new file mode 100644 index 0000000..2b322d1 --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodLinkParams.swift @@ -0,0 +1,35 @@ +// +// STPPaymentMethodLinkParams.swift +// StripePayments +// +// Created by Cameron Sabol on 8/26/21. +// Copyright © 2021 Stripe, Inc. All rights reserved. +// + +import UIKit + +/// An object representing parameters used to create an Link Payment Method +public class STPPaymentMethodLinkParams: NSObject, STPFormEncodable { + /// :nodoc: + @objc @_spi(STP) public var paymentDetailsID: String? + + /// :nodoc: + @objc @_spi(STP) public var credentials: [AnyHashable: Any]? + + /// :nodoc: + @objc public var additionalAPIParameters: [AnyHashable: Any] = [:] + + // MARK: - STPFormEncodable + @objc + public class func rootObjectName() -> String? { + return "link" + } + + @objc + public static func propertyNamesToFormFieldNamesMapping() -> [String: String] { + return [ + NSStringFromSelector(#selector(getter:credentials)): "credentials", + NSStringFromSelector(#selector(getter:paymentDetailsID)): "payment_details_id", + ] + } +} diff --git a/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodNetBanking.swift b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodNetBanking.swift new file mode 100644 index 0000000..334a2ea --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodNetBanking.swift @@ -0,0 +1,50 @@ +// +// STPPaymentMethodNetBanking.swift +// StripePayments +// +// Created by Anirudh Bhargava on 11/19/20. +// Copyright © 2020 Stripe, Inc. All rights reserved. +// + +import Foundation + +/// A NetBanking Payment Method. +/// - seealso: https://stripe.com/docs/api/payment_methods/object#payment_method_object-netbanking +public class STPPaymentMethodNetBanking: NSObject, STPAPIResponseDecodable { + @objc private(set) public var allResponseFields: [AnyHashable: Any] = [:] + + /// Customer’s Bank Name + @objc public private(set) var bank: String + + // MARK: - Description + /// :nodoc: + @objc public override var description: String { + let props = [ + // Object + String(format: "%@: %p", NSStringFromClass(STPPaymentMethodNetBanking.self), self), + "bank = \(bank)", + ] + + return "<\(props.joined(separator: "; "))>" + } + + // MARK: - STPAPIResponseDecodable + @objc + public class func decodedObject(fromAPIResponse response: [AnyHashable: Any]?) -> Self? { + guard let response = response else { + return nil + } + return self.init(dictionary: response) + } + + required init?(dictionary dict: [AnyHashable: Any]) { + guard let bank = dict.stp_string(forKey: "bank") else { + return nil + } + + self.bank = bank + + super.init() + allResponseFields = dict + } +} diff --git a/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodNetBankingParams.swift b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodNetBankingParams.swift new file mode 100644 index 0000000..b0e19e5 --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodNetBankingParams.swift @@ -0,0 +1,29 @@ +// +// STPPaymentMethodNetBankingParams.swift +// StripePayments +// +// Created by Anirudh Bhargava on 11/19/20. +// Copyright © 2020 Stripe, Inc. All rights reserved. +// + +import Foundation + +/// An object representing parameters used to create a NetBanking Payment Method +public class STPPaymentMethodNetBankingParams: NSObject, STPFormEncodable { + @objc public var additionalAPIParameters: [AnyHashable: Any] = [:] + + /// Customer’s Bank Name. Required. + @objc public var bank: String? + + @objc + public class func rootObjectName() -> String? { + return "netbanking" + } + + @objc + public class func propertyNamesToFormFieldNamesMapping() -> [String: String] { + return [ + NSStringFromSelector(#selector(getter:bank)): "bank" + ] + } +} diff --git a/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodOXXO.swift b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodOXXO.swift new file mode 100644 index 0000000..91cfead --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodOXXO.swift @@ -0,0 +1,40 @@ +// +// STPPaymentMethodOXXO.swift +// StripePayments +// +// Created by Polo Li on 6/15/20. +// Copyright © 2020 Stripe, Inc. All rights reserved. +// + +import Foundation + +/// An OXXO Payment Method. +/// - seealso: https://stripe.com/docs/payments/oxxo +public class STPPaymentMethodOXXO: NSObject, STPAPIResponseDecodable { + @objc public private(set) var allResponseFields: [AnyHashable: Any] = [:] + + /// :nodoc: + @objc public override var description: String { + let props = [ + // Object + String(format: "%@: %p", NSStringFromClass(STPPaymentMethodOXXO.self), self) + ] + + return "<\(props.joined(separator: "; "))>" + } + + // MARK: - STPAPIResponseDecodable + override required init() { + super.init() + } + + @objc + public class func decodedObject(fromAPIResponse response: [AnyHashable: Any]?) -> Self? { + guard let response = response else { + return nil + } + let oxxo = self.init() + oxxo.allResponseFields = response + return oxxo + } +} diff --git a/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodOXXOParams.swift b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodOXXOParams.swift new file mode 100644 index 0000000..8d0b874 --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodOXXOParams.swift @@ -0,0 +1,25 @@ +// +// STPPaymentMethodOXXOParams.swift +// StripePayments +// +// Created by Polo Li on 6/16/20. +// Copyright © 2020 Stripe, Inc. All rights reserved. +// + +import Foundation + +/// An object representing parameters used to create an OXXO Payment Method +public class STPPaymentMethodOXXOParams: NSObject, STPFormEncodable { + @objc public var additionalAPIParameters: [AnyHashable: Any] = [:] + + // MARK: - STPFormEncodable + @objc + public class func rootObjectName() -> String? { + return "oxxo" + } + + @objc + public class func propertyNamesToFormFieldNamesMapping() -> [String: String] { + return [:] + } +} diff --git a/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodPayPal.swift b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodPayPal.swift new file mode 100644 index 0000000..b8c9922 --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodPayPal.swift @@ -0,0 +1,42 @@ +// +// STPPaymentMethodPayPal.swift +// StripePayments +// +// Created by Cameron Sabol on 10/5/20. +// Copyright © 2020 Stripe, Inc. All rights reserved. +// + +import Foundation + +/// A PayPal Payment Method. :nodoc: +/// - seealso: https://stripe.com/docs/payments/paypal +public class STPPaymentMethodPayPal: NSObject, STPAPIResponseDecodable { + @objc private(set) public var allResponseFields: [AnyHashable: Any] = [:] + + // MARK: - Description + /// :nodoc: + @objc public override var description: String { + let props = [ + // Object + String(format: "%@: %p", NSStringFromClass(STPPaymentMethodPayPal.self), self) + ] + + return "<\(props.joined(separator: "; "))>" + } + + // MARK: - STPAPIResponseDecodable + @objc + public class func decodedObject(fromAPIResponse response: [AnyHashable: Any]?) -> Self? { + guard let response = response else { + return nil + } + return self.init(dictionary: response) + } + + required init( + dictionary dict: [AnyHashable: Any] + ) { + super.init() + allResponseFields = dict + } +} diff --git a/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodPayPalParams.swift b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodPayPalParams.swift new file mode 100644 index 0000000..f1e849c --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodPayPalParams.swift @@ -0,0 +1,24 @@ +// +// STPPaymentMethodPayPalParams.swift +// StripePayments +// +// Created by Cameron Sabol on 10/5/20. +// Copyright © 2020 Stripe, Inc. All rights reserved. +// + +import Foundation + +/// An object representing parameters used to create a PayPal Payment Method :nodoc: +public class STPPaymentMethodPayPalParams: NSObject, STPFormEncodable { + @objc public var additionalAPIParameters: [AnyHashable: Any] = [:] + + @objc + public class func rootObjectName() -> String? { + return "paypal" + } + + @objc + public class func propertyNamesToFormFieldNamesMapping() -> [String: String] { + return [:] + } +} diff --git a/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodPrzelewy24.swift b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodPrzelewy24.swift new file mode 100644 index 0000000..de188c8 --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodPrzelewy24.swift @@ -0,0 +1,42 @@ +// +// STPPaymentMethodPrzelewy24.swift +// StripePayments +// +// Created by Vineet Shah on 4/23/20. +// Copyright © 2020 Stripe, Inc. All rights reserved. +// + +import Foundation + +/// A Przelewy24 Payment Method. +/// - seealso: https://stripe.com/docs/payments/p24 +public class STPPaymentMethodPrzelewy24: NSObject, STPAPIResponseDecodable { + @objc private(set) public var allResponseFields: [AnyHashable: Any] = [:] + + // MARK: - Description + /// :nodoc: + @objc public override var description: String { + let props = [ + // Object + String(format: "%@: %p", NSStringFromClass(STPPaymentMethodPrzelewy24.self), self) + ] + + return "<\(props.joined(separator: "; "))>" + } + + // MARK: - STPAPIResponseDecodable + @objc + public class func decodedObject(fromAPIResponse response: [AnyHashable: Any]?) -> Self? { + guard let response = response else { + return nil + } + return self.init(dictionary: response) + } + + required init( + dictionary dict: [AnyHashable: Any] + ) { + super.init() + allResponseFields = dict + } +} diff --git a/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodPrzelewy24Params.swift b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodPrzelewy24Params.swift new file mode 100644 index 0000000..e64bb71 --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodPrzelewy24Params.swift @@ -0,0 +1,24 @@ +// +// STPPaymentMethodPrzelewy24Params.swift +// StripePayments +// +// Created by Vineet Shah on 4/23/20. +// Copyright © 2020 Stripe, Inc. All rights reserved. +// + +import Foundation + +/// An object representing parameters used to create a Przelewy24 Payment Method +public class STPPaymentMethodPrzelewy24Params: NSObject, STPFormEncodable { + @objc public var additionalAPIParameters: [AnyHashable: Any] = [:] + + @objc + public class func rootObjectName() -> String? { + return "p24" + } + + @objc + public class func propertyNamesToFormFieldNamesMapping() -> [String: String] { + return [:] + } +} diff --git a/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodSEPADebit.swift b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodSEPADebit.swift new file mode 100644 index 0000000..20af997 --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodSEPADebit.swift @@ -0,0 +1,69 @@ +// +// STPPaymentMethodSEPADebit.swift +// StripePayments +// +// Created by Cameron Sabol on 10/7/19. +// Copyright © 2019 Stripe, Inc. All rights reserved. +// + +import Foundation + +/// A SEPA Debit Payment Method. +/// - seealso: https://stripe.com/docs/api/payment_methods/object#payment_method_object-sepa_debit +public class STPPaymentMethodSEPADebit: NSObject, STPAPIResponseDecodable { + @objc private(set) public var allResponseFields: [AnyHashable: Any] = [:] + /// The last 4 digits of the account number. + @objc public private(set) var last4: String? + /// The account's bank code. + @objc public private(set) var bankCode: String? + /// The account's branch code + @objc public private(set) var branchCode: String? + /// Two-letter ISO code representing the country of the bank account. + @objc public private(set) var country: String? + /// The account's fingerprint. + @objc public private(set) var fingerprint: String? + /// The reference of the mandate accepted by your customer. - seealso: https://stripe.com/docs/api/sources/create#create_source-mandate + @objc public private(set) var mandate: String? + + // MARK: - Description + /// :nodoc: + @objc public override var description: String { + let props = [ + // Object + String(format: "%@: %p", NSStringFromClass(STPPaymentMethodSEPADebit.self), self), + // Basic SEPA debit details + "last4 = \(last4 ?? "")", + // Additional SEPA debit details (alphabetical) + "bankCode = \(bankCode ?? "")", + "branchCode = \(branchCode ?? "")", + "country = \(country ?? "")", + "fingerprint = \(fingerprint ?? "")", + "mandate = \(mandate ?? "")", + ] + + return "<\(props.joined(separator: "; "))>" + } + + // MARK: - STPAPIResponseDecodable + @objc + public class func decodedObject(fromAPIResponse response: [AnyHashable: Any]?) -> Self? { + guard let response = response else { + return nil + } + return self.init(dictionary: response) + } + + required init( + dictionary dict: [AnyHashable: Any] + ) { + super.init() + allResponseFields = dict + let dict = dict.stp_dictionaryByRemovingNulls() + last4 = dict.stp_string(forKey: "last4") + bankCode = dict.stp_string(forKey: "bank_code") + branchCode = dict.stp_string(forKey: "branch_code") + country = dict.stp_string(forKey: "country") + fingerprint = dict.stp_string(forKey: "fingerprint") + mandate = dict.stp_string(forKey: "mandate") + } +} diff --git a/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodSEPADebitParams.swift b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodSEPADebitParams.swift new file mode 100644 index 0000000..7f727ff --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodSEPADebitParams.swift @@ -0,0 +1,30 @@ +// +// STPPaymentMethodSEPADebitParams.swift +// StripePayments +// +// Created by Cameron Sabol on 10/7/19. +// Copyright © 2019 Stripe, Inc. All rights reserved. +// + +import Foundation + +/// An object representing parameters used to create a SEPA Debit Payment Method +public class STPPaymentMethodSEPADebitParams: NSObject, STPFormEncodable { + @objc public var additionalAPIParameters: [AnyHashable: Any] = [:] + + /// The IBAN number for the bank account you wish to debit. Required. + @objc public var iban: String? + + // MARK: - STPFormEncodable + @objc + public class func rootObjectName() -> String? { + return "sepa_debit" + } + + @objc + public class func propertyNamesToFormFieldNamesMapping() -> [String: String] { + return [ + NSStringFromSelector(#selector(getter:iban)): "iban" + ] + } +} diff --git a/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodSofort.swift b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodSofort.swift new file mode 100644 index 0000000..bd9cbd2 --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodSofort.swift @@ -0,0 +1,48 @@ +// +// STPPaymentMethodSofort.swift +// StripePayments +// +// Created by David Estes on 8/7/20. +// Copyright © 2020 Stripe, Inc. All rights reserved. +// + +import Foundation + +/// A Sofort Payment Method. +/// - seealso: https://stripe.com/docs/api/payment_methods/object#payment_method_object-Sofort +public class STPPaymentMethodSofort: NSObject, STPAPIResponseDecodable { + @objc private(set) public var allResponseFields: [AnyHashable: Any] = [:] + + /// Two-letter ISO code representing the country the bank account is located in. + @objc public private(set) var country: String? + + // MARK: - Description + /// :nodoc: + @objc public override var description: String { + let props = [ + // Object + String(format: "%@: %p", NSStringFromClass(STPPaymentMethodSofort.self), self), + "country = \(country ?? "")", + ] + + return "<\(props.joined(separator: "; "))>" + } + + // MARK: - STPAPIResponseDecodable + @objc + public class func decodedObject(fromAPIResponse response: [AnyHashable: Any]?) -> Self? { + guard let response = response else { + return nil + } + return self.init(dictionary: response) + } + + required init( + dictionary dict: [AnyHashable: Any] + ) { + super.init() + allResponseFields = dict + let dict = dict.stp_dictionaryByRemovingNulls() + country = dict.stp_string(forKey: "country") + } +} diff --git a/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodSofortParams.swift b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodSofortParams.swift new file mode 100644 index 0000000..051b381 --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodSofortParams.swift @@ -0,0 +1,29 @@ +// +// STPPaymentMethodSofortParams.swift +// StripePayments +// +// Created by David Estes on 8/7/20. +// Copyright © 2020 Stripe, Inc. All rights reserved. +// + +import Foundation + +/// An object representing parameters used to create a Sofort Payment Method +public class STPPaymentMethodSofortParams: NSObject, STPFormEncodable { + @objc public var additionalAPIParameters: [AnyHashable: Any] = [:] + + /// Two-letter ISO code representing the country the bank account is located in. Required. + @objc public var country: String? + + @objc + public class func rootObjectName() -> String? { + return "sofort" + } + + @objc + public class func propertyNamesToFormFieldNamesMapping() -> [String: String] { + return [ + NSStringFromSelector(#selector(getter:country)): "country" + ] + } +} diff --git a/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodThreeDSecureUsage.swift b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodThreeDSecureUsage.swift new file mode 100644 index 0000000..cbda8b8 --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodThreeDSecureUsage.swift @@ -0,0 +1,54 @@ +// +// STPPaymentMethodThreeDSecureUsage.swift +// StripePayments +// +// Created by Yuki Tokuhiro on 3/5/19. +// Copyright © 2019 Stripe, Inc. All rights reserved. +// + +import Foundation + +/// Contains details on how an `STPPaymentMethodCard` maybe be used for 3D Secure authentication. +public class STPPaymentMethodThreeDSecureUsage: NSObject, STPAPIResponseDecodable { + /// `YES` if 3D Secure is supported on this card. + @objc public private(set) var supported = false + private(set) public var allResponseFields: [AnyHashable: Any] = [:] + + /// :nodoc: + @objc public override var description: String { + let props = [ + // Object + String( + format: "%@: %p", + NSStringFromClass(STPPaymentMethodThreeDSecureUsage.self), + self + ), + // Properties + "supported: \(supported ? "YES" : "NO")", + ] + + return "<\(props.joined(separator: "; "))>" + } + + // MARK: - STPAPIResponseDecodable + override required init() { + super.init() + } + + @objc + public class func decodedObject(fromAPIResponse response: [AnyHashable: Any]?) -> Self? { + + guard let response = response else { + return nil + } + let dict = response.stp_dictionaryByRemovingNulls() + if dict["supported"] == nil { + return nil + } + + let usage = self.init() + usage.allResponseFields = response + usage.supported = dict.stp_bool(forKey: "supported", or: false) + return usage + } +} diff --git a/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodUPI.swift b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodUPI.swift new file mode 100644 index 0000000..1fbc058 --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodUPI.swift @@ -0,0 +1,50 @@ +// +// STPPaymentMethodUPI.swift +// StripePayments +// +// Created by Anirudh Bhargava on 11/6/20. +// Copyright © 2020 Stripe, Inc. All rights reserved. +// + +import Foundation + +/// A UPI Payment Method. +/// - seealso: https://stripe.com/docs/api/payment_methods/object#payment_method_object-upi +public class STPPaymentMethodUPI: NSObject, STPAPIResponseDecodable { + @objc private(set) public var allResponseFields: [AnyHashable: Any] = [:] + + /// Customer’s Virtual Payment Address (VPA). + @objc public private(set) var vpa: String + + // MARK: - Description + /// :nodoc: + @objc public override var description: String { + let props = [ + // Object + String(format: "%@: %p", NSStringFromClass(STPPaymentMethodUPI.self), self), + "vpa = \(vpa)", + ] + + return "<\(props.joined(separator: "; "))>" + } + + // MARK: - STPAPIResponseDecodable + @objc + public class func decodedObject(fromAPIResponse response: [AnyHashable: Any]?) -> Self? { + guard let response = response else { + return nil + } + return self.init(dictionary: response) + } + + required init?(dictionary dict: [AnyHashable: Any]) { + guard let vpa = dict.stp_string(forKey: "vpa") else { + return nil + } + + self.vpa = vpa + + super.init() + allResponseFields = dict + } +} diff --git a/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodUPIParams.swift b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodUPIParams.swift new file mode 100644 index 0000000..6fbde8c --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodUPIParams.swift @@ -0,0 +1,29 @@ +// +// STPPaymentMethodUPIParams.swift +// StripePayments +// +// Created by Anirudh Bhargava on 11/6/20. +// Copyright © 2020 Stripe, Inc. All rights reserved. +// + +import Foundation + +/// An object representing parameters used to create a UPI Payment Method +public class STPPaymentMethodUPIParams: NSObject, STPFormEncodable { + @objc public var additionalAPIParameters: [AnyHashable: Any] = [:] + + /// Customer’s Virtual Payment Address (VPA). Required. + @objc public var vpa: String? + + @objc + public class func rootObjectName() -> String? { + return "upi" + } + + @objc + public class func propertyNamesToFormFieldNamesMapping() -> [String: String] { + return [ + NSStringFromSelector(#selector(getter:vpa)): "vpa" + ] + } +} diff --git a/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodUSBankAccount.swift b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodUSBankAccount.swift new file mode 100644 index 0000000..c6c68a9 --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodUSBankAccount.swift @@ -0,0 +1,213 @@ +// +// STPPaymentMethodUSBankAccount.swift +// StripePayments +// +// Created by Cameron Sabol on 2/24/22. +// Copyright © 2022 Stripe, Inc. All rights reserved. +// + +import UIKit + +// MARK: - STPPaymentMethodUSBankAccount +/// A US Bank Account Payment Method (ACH) +/// - seealso: https://stripe.com/docs/api/payment_methods/object#payment_method_object-us_bank_account +public class STPPaymentMethodUSBankAccount: NSObject { + + /// Account holder type + @objc public let accountHolderType: STPPaymentMethodUSBankAccountHolderType + + /// Account type + @objc public let accountType: STPPaymentMethodUSBankAccountType + + /// The name of the bank + @objc public let bankName: String + + /// Uniquely identifies this particular bank account. You can use this attribute to check whether two bank accounts are the same. + @objc public let fingerprint: String + + /// Last four digits of the bank account number + @objc public let last4: String + + /// The token of the Linked Account used to create the payment method + @objc public let linkedAccount: String? + + /// Contains information about US bank account networks that can be used + @objc public let networks: STPPaymentMethodUSBankAccountNetworks? + + /// Routing number of the bank account + @objc public let routingNumber: String + + /// :nodoc: + @objc public let allResponseFields: [AnyHashable: Any] + + internal init( + accountHolderType: STPPaymentMethodUSBankAccountHolderType, + accountType: STPPaymentMethodUSBankAccountType, + bankName: String, + fingerprint: String, + last4: String, + linkedAccount: String?, + networks: STPPaymentMethodUSBankAccountNetworks?, + routingNumber: String, + allResponseFields: [AnyHashable: Any] + ) { + self.accountHolderType = accountHolderType + self.accountType = accountType + self.bankName = bankName + self.fingerprint = fingerprint + self.last4 = last4 + self.linkedAccount = linkedAccount + self.networks = networks + self.routingNumber = routingNumber + self.allResponseFields = allResponseFields + super.init() + } +} + +// MARK: - STPAPIResponseDecodable +/// :nodoc: +extension STPPaymentMethodUSBankAccount: STPAPIResponseDecodable { + public static func decodedObject(fromAPIResponse response: [AnyHashable: Any]?) -> Self? { + guard let response = response, + let accountHolderTypeString = response["account_holder_type"] as? String, + let accountTypeString = response["account_type"] as? String, + let bankName = response["bank_name"] as? String, + let fingerprint = response["fingerprint"] as? String, + let last4 = response["last4"] as? String, + let routingNumber = response["routing_number"] as? String + else { + return nil + } + var networks: STPPaymentMethodUSBankAccountNetworks? = nil + if let networksHash = response["networks"] as? [AnyHashable: Any], + let supported = networksHash["supported"] as? [String] + { + let preferred = networksHash["preferred"] as? String + networks = STPPaymentMethodUSBankAccountNetworks( + preferred: preferred, + supported: supported + ) + } + + return STPPaymentMethodUSBankAccount( + accountHolderType: STPPaymentMethodUSBankAccountHolderType( + string: accountHolderTypeString + ), + accountType: STPPaymentMethodUSBankAccountType(string: accountTypeString), + bankName: bankName, + fingerprint: fingerprint, + last4: last4, + linkedAccount: response["linked_account"] as? String, + networks: networks, + routingNumber: routingNumber, + allResponseFields: response + ) as? Self + + } +} + +// MARK: - STPPaymentMethodUSBankAccountHolderType +/// Account holder type +@objc public enum STPPaymentMethodUSBankAccountHolderType: Int { + /// This is an unknown type that's been added since the SDK + /// was last updated. + /// Update your SDK, or use the `allResponseFields` + /// for custom handling. + case unknown + /// Account belongs to an individual + case individual + /// Account belongs to a company + case company + + internal init( + string: String? + ) { + guard let string = string else { + self = .unknown + return + } + switch string.lowercased() { + case "individual": + self = .individual + case "company": + self = .company + default: + self = .unknown + } + } + + internal var stringValue: String? { + switch self { + case .unknown: + return nil + case .individual: + return "individual" + case .company: + return "company" + } + } + +} + +// MARK: - STPPaymentMethodUSBankAccountType +/// Account type +@objc public enum STPPaymentMethodUSBankAccountType: Int { + /// This is an unknown type that's been added since the SDK + /// was last updated. + /// Update your SDK, or use the `allResponseFields` + /// for custom handling. + case unknown + /// Bank account type is checking + case checking + /// Bank account type is savings + case savings + + internal init( + string: String? + ) { + guard let string = string else { + self = .unknown + return + } + + switch string.lowercased() { + case "checking": + self = .checking + case "savings": + self = .savings + default: + self = .unknown + } + } + + internal var stringValue: String? { + switch self { + case .unknown: + return nil + case .checking: + return "checking" + case .savings: + return "savings" + } + } +} + +// MARK: - STPPaymentMethodUSBankAccountNetworks +/// Contains information about US bank account networks that can be used +public class STPPaymentMethodUSBankAccountNetworks: NSObject { + + /// The preferred network + @objc public let preferred: String? + + /// All supported networks + @objc public let supported: [String] + + internal init( + preferred: String?, + supported: [String] + ) { + self.preferred = preferred + self.supported = supported + super.init() + } +} diff --git a/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodUSBankAccountParams.swift b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodUSBankAccountParams.swift new file mode 100644 index 0000000..3c77f71 --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodUSBankAccountParams.swift @@ -0,0 +1,80 @@ +// +// STPPaymentMethodUSBankAccountParams.swift +// StripePayments +// +// Created by Cameron Sabol on 2/24/22. +// Copyright © 2022 Stripe, Inc. All rights reserved. +// + +import UIKit + +/// An object representing parameters used to create a US Bank Account Payment Method +public class STPPaymentMethodUSBankAccountParams: NSObject { + + /// The raw underlying account holder type string sent to the server. + /// You can use this if you want to create a param of a bank not yet supported + /// by the current version of the SDK's `STPPaymentMethodUSBankAccountHolderType` enum. + /// Setting this to a value not known by the SDK causes `accountHolderType` to + /// return `.unknown` + @objc public var accountHolderTypeString: String? + + /// Account holder type + @objc public var accountHolderType: STPPaymentMethodUSBankAccountHolderType { + get { + return STPPaymentMethodUSBankAccountHolderType(string: accountHolderTypeString) + } + + set { + accountHolderTypeString = newValue.stringValue + } + } + + /// Account number of the bank account + @objc public var accountNumber: String? + + /// The raw underlying account type string sent to the server. + /// You can use this if you want to create a param of a type not yet supported + /// by the current version of the SDK's `STPPaymentMethodUSBankAccountType` enum. + /// Setting this to a value not known by the SDK causes `accountType` to + /// return `.unknown` + @objc public var accountTypeString: String? + + /// Account type + @objc public var accountType: STPPaymentMethodUSBankAccountType { + get { + return STPPaymentMethodUSBankAccountType(string: accountTypeString) + } + + set { + accountTypeString = newValue.stringValue + } + } + + /// Routing number of the bank account + @objc public var routingNumber: String? + + /// :nodoc: + @objc public var additionalAPIParameters: [AnyHashable: Any] = [:] + + /// Internal-only option to create directly from a link_account_session ID + @objc @_spi(STP) public var linkAccountSessionID: String? + +} + +// MARK: - STPFormEncodable +/// :nodoc: +extension STPPaymentMethodUSBankAccountParams: STPFormEncodable { + public static func rootObjectName() -> String? { + return "us_bank_account" + } + + public static func propertyNamesToFormFieldNamesMapping() -> [String: String] { + return [ + NSStringFromSelector(#selector(getter:accountHolderTypeString)): "account_holder_type", + NSStringFromSelector(#selector(getter:accountNumber)): "account_number", + NSStringFromSelector(#selector(getter:accountTypeString)): "account_type", + NSStringFromSelector(#selector(getter:routingNumber)): "routing_number", + NSStringFromSelector(#selector(getter:linkAccountSessionID)): "link_account_session", + ] + } +} diff --git a/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodWeChatPay.swift b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodWeChatPay.swift new file mode 100644 index 0000000..4fb301f --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodWeChatPay.swift @@ -0,0 +1,42 @@ +// +// STPPaymentMethodWeChatPay.swift +// StripePayments +// +// Copyright © 2021 Stripe, Inc. All rights reserved. +// + +import Foundation + +/// A WeChat Pay Payment Method. +/// - seealso: https://stripe.com/docs/api/payment_methods/object#payment_method_object-wechat_pay +/// WeChat Pay is currently unavailable in the iOS SDK. +class STPPaymentMethodWeChatPay: NSObject, STPAPIResponseDecodable { + @objc private(set) public var allResponseFields: [AnyHashable: Any] = [:] + + // MARK: - Description + /// :nodoc: + @objc public override var description: String { + let props = [ + // Object + String(format: "%@: %p", NSStringFromClass(STPPaymentMethodWeChatPay.self), self) + ] + + return "<\(props.joined(separator: "; "))>" + } + + // MARK: - STPAPIResponseDecodable + @objc + public class func decodedObject(fromAPIResponse response: [AnyHashable: Any]?) -> Self? { + guard let response = response else { + return nil + } + return self.init(dictionary: response) + } + + required init?( + dictionary dict: [AnyHashable: Any] + ) { + super.init() + allResponseFields = dict + } +} diff --git a/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodWeChatPayParams.swift b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodWeChatPayParams.swift new file mode 100644 index 0000000..a290ba1 --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodWeChatPayParams.swift @@ -0,0 +1,24 @@ +// +// STPPaymentMethodWeChatPayParams.swift +// StripePayments +// +// Copyright © 2021 Stripe, Inc. All rights reserved. +// + +import Foundation + +/// An object representing parameters used to create a WeChat Pay Payment Method +/// WeChat Pay is currently unavailable in the iOS SDK. +class STPPaymentMethodWeChatPayParams: NSObject, STPFormEncodable { + @objc public var additionalAPIParameters: [AnyHashable: Any] = [:] + + @objc + public class func rootObjectName() -> String? { + return "wechat_pay" + } + + @objc + public class func propertyNamesToFormFieldNamesMapping() -> [String: String] { + return [:] + } +} diff --git a/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodiDEAL.swift b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodiDEAL.swift new file mode 100644 index 0000000..6c80275 --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodiDEAL.swift @@ -0,0 +1,51 @@ +// +// STPPaymentMethodiDEAL.swift +// StripePayments +// +// Created by Yuki Tokuhiro on 3/9/19. +// Copyright © 2019 Stripe, Inc. All rights reserved. +// + +import Foundation + +/// An iDEAL Payment Method. +/// - seealso: https://stripe.com/docs/api/payment_methods/object#payment_method_object-ideal +public class STPPaymentMethodiDEAL: NSObject, STPAPIResponseDecodable { + /// The customer’s bank. + @objc public private(set) var bankName: String? + /// The Bank Identifier Code of the customer’s bank. + @objc public private(set) var bankIdentifierCode: String? + @objc public private(set) var allResponseFields: [AnyHashable: Any] = [:] + + /// :nodoc: + @objc public override var description: String { + let props = [ + // Object + String(format: "%@: %p", NSStringFromClass(STPPaymentMethodiDEAL.self), self), + // Properties + "bank: \(bankName ?? "")", + "bic: \(bankIdentifierCode ?? "")", + ] + + return "<\(props.joined(separator: "; "))>" + } + + // MARK: - STPAPIResponseDecodable + override required init() { + super.init() + } + + @objc + public class func decodedObject(fromAPIResponse response: [AnyHashable: Any]?) -> Self? { + guard let response = response else { + return nil + } + let dict = response.stp_dictionaryByRemovingNulls() + + let ideal = self.init() + ideal.allResponseFields = response + ideal.bankName = dict.stp_string(forKey: "bank") + ideal.bankIdentifierCode = dict.stp_string(forKey: "bic") + return ideal + } +} diff --git a/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodiDEALParams.swift b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodiDEALParams.swift new file mode 100644 index 0000000..b58a9cd --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/PaymentMethods/Types/STPPaymentMethodiDEALParams.swift @@ -0,0 +1,30 @@ +// +// STPPaymentMethodiDEALParams.swift +// StripePayments +// +// Created by Yuki Tokuhiro on 3/9/19. +// Copyright © 2019 Stripe, Inc. All rights reserved. +// + +import Foundation + +/// An object representing parameters used to create an iDEAL Payment Method +public class STPPaymentMethodiDEALParams: NSObject, STPFormEncodable { + @objc public var additionalAPIParameters: [AnyHashable: Any] = [:] + + /// The customer’s bank. + @objc public var bankName: String? + + // MARK: - STPFormEncodable + @objc + public class func rootObjectName() -> String? { + return "ideal" + } + + @objc + public class func propertyNamesToFormFieldNamesMapping() -> [String: String] { + return [ + NSStringFromSelector(#selector(getter:bankName)): "bank" + ] + } +} diff --git a/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/STPAPIResponseDecodable.swift b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/STPAPIResponseDecodable.swift new file mode 100644 index 0000000..1295b16 --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/STPAPIResponseDecodable.swift @@ -0,0 +1,23 @@ +// +// STPAPIResponseDecodable.swift +// StripePayments +// +// Created by Jack Flintermann on 10/14/15. +// Copyright © 2015 Stripe, Inc. All rights reserved. +// + +import Foundation + +/// Objects conforming to STPAPIResponseDecodable can be automatically converted +/// from a JSON dictionary that was returned from the Stripe API. +@objc public protocol STPAPIResponseDecodable: NSObjectProtocol { + /// Parses an response from the Stripe API (in JSON format; represented as + /// an `NSDictionary`) into an instance of the class. + /// - Parameter response: The JSON dictionary that represents an object of this type + /// - Returns: The object represented by the JSON dictionary, or nil if the object + /// could not be decoded (i.e. if one of its `requiredFields` is nil). + static func decodedObject(fromAPIResponse response: [AnyHashable: Any]?) -> Self? + /// The raw JSON response used to create the object. This can be useful for accessing + /// fields that haven't yet been made into native properties in the SDK. + var allResponseFields: [AnyHashable: Any] { get } +} diff --git a/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/STPAddress.swift b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/STPAddress.swift new file mode 100644 index 0000000..5d2a6ef --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/STPAddress.swift @@ -0,0 +1,305 @@ +// +// STPAddress.swift +// StripePayments +// +// Created by Ben Guo on 4/13/16. +// Copyright © 2016 Stripe, Inc. All rights reserved. +// + +import Contacts +import Foundation +import PassKit +@_spi(STP) import StripeCore + +/// STPAddress Contains an address as represented by the Stripe API. +public class STPAddress: NSObject { + /// The user's full name (e.g. "Jane Doe") + @objc public var name: String? + + /// The first line of the user's street address (e.g. "123 Fake St") + @objc public var line1: String? + + /// The apartment, floor number, etc of the user's street address (e.g. "Apartment 1A") + @objc public var line2: String? + + /// The city in which the user resides (e.g. "San Francisco") + @objc public var city: String? + + /// The state in which the user resides (e.g. "CA") + @objc public var state: String? + + /// The postal code in which the user resides (e.g. "90210") + @objc public var postalCode: String? + + /// The ISO country code of the address (e.g. "US") + @objc public var country: String? + + /// The phone number of the address (e.g. "8885551212") + @objc public var phone: String? + + /// The email of the address (e.g. "jane@doe.com") + @objc public var email: String? + + @objc public var additionalAPIParameters: [AnyHashable: Any] = [:] + + /// When creating a charge on your backend, you can attach shipping information + /// to prevent fraud on a physical good. You can use this method to turn your user's + /// shipping address and selected shipping method into a hash suitable for attaching + /// to a charge. You should pass this to your backend, and use it as the `shipping` + /// parameter when creating a charge. + /// - seealso: https://stripe.com/docs/api#create_charge-shipping + /// - Parameters: + /// - address: The user's shipping address. If nil, this method will return nil. + /// - method: The user's selected shipping method. May be nil. + @objc(shippingInfoForChargeWithAddress:shippingMethod:) + public class func shippingInfoForCharge( + with address: STPAddress?, + shippingMethod method: PKShippingMethod? + ) -> [AnyHashable: Any]? { + guard let address = address else { + return nil + } + + var params: [AnyHashable: Any] = [:] + params["name"] = address.name + params["phone"] = address.phone + params["carrier"] = method?.label + // Re-use STPFormEncoder + params["address"] = STPFormEncoder.dictionary(forObject: address) + return params + } + + /// Initializes an empty STPAddress. + @objc + public override init() { + super.init() + } + + /// Initializes a new STPAddress with data from STPPaymentMethodBillingDetails. + /// - Parameter billingDetails: The STPPaymentMethodBillingDetails instance you want to populate the STPAddress from. + /// - Returns: A new STPAddress instance with data copied from the passed in billing details. + @objc + public init( + paymentMethodBillingDetails billingDetails: STPPaymentMethodBillingDetails + ) { + super.init() + name = billingDetails.name + phone = billingDetails.phone + email = billingDetails.email + let pmAddress = billingDetails.address + line1 = pmAddress?.line1 + line2 = pmAddress?.line2 + city = pmAddress?.city + state = pmAddress?.state + postalCode = pmAddress?.postalCode + country = pmAddress?.country + } + + /// Initializes a new STPAddress with data from an PassKit contact. + /// - Parameter contact: The PassKit contact you want to populate the STPAddress from. + /// - Returns: A new STPAddress instance with data copied from the passed in contact. + @objc(initWithPKContact:) + public init( + pkContact contact: PKContact + ) { + super.init() + let nameComponents = contact.name + if let nameComponents = nameComponents { + givenName = stringIfHasContentsElseNil(nameComponents.givenName) + familyName = stringIfHasContentsElseNil(nameComponents.familyName) + + name = stringIfHasContentsElseNil( + PersonNameComponentsFormatter.localizedString(from: nameComponents, style: .default) + ) + } + email = stringIfHasContentsElseNil(contact.emailAddress) + if let phoneNumber = contact.phoneNumber { + phone = sanitizedPhoneString(from: phoneNumber) + } else { + phone = nil + } + setAddressFromCNPostal(contact.postalAddress) + } + + /// Generates a PassKit contact representation of this STPAddress. + /// - Returns: A new PassKit contact with data copied from this STPAddress instance. + @objc(PKContactValue) + public func pkContactValue() -> PKContact { + let contact = PKContact() + var personName = PersonNameComponents() + personName.givenName = firstName() + personName.familyName = lastName() + contact.name = personName + contact.emailAddress = email + let address = CNMutablePostalAddress() + address.street = street() ?? "" + address.city = city ?? "" + address.state = state ?? "" + address.postalCode = postalCode ?? "" + address.country = country ?? "" + contact.postalAddress = address + contact.phoneNumber = CNPhoneNumber(stringValue: phone ?? "") + return contact + } + + /// Initializes a new STPAddress with a contact from the Contacts framework. + /// - Parameter contact: The CNContact you want to populate the STPAddress from. + /// - Returns: A new STPAddress instance with data copied from the passed in contact. + @objc(initWithCNContact:) + public init( + cnContact contact: CNContact + ) { + super.init() + givenName = stringIfHasContentsElseNil(contact.givenName) + familyName = stringIfHasContentsElseNil(contact.familyName) + name = stringIfHasContentsElseNil( + CNContactFormatter.string( + from: contact, + style: .fullName + ) + ) + email = stringIfHasContentsElseNil(contact.emailAddresses.first?.value as String?) + if let value1 = contact.phoneNumbers.first?.value { + phone = sanitizedPhoneString(from: value1) + } + + if let value1 = contact.postalAddresses.first?.value { + setAddressFromCNPostal(value1) + } + } + + @objc public private(set) var allResponseFields: [AnyHashable: Any] = [:] + private var givenName: String? + private var familyName: String? + + private func sanitizedPhoneString(from phoneNumber: CNPhoneNumber) -> String? { + return stringIfHasContentsElseNil( + STPCardValidator.sanitizedNumericString(for: phoneNumber.stringValue) + ) + } + + private func setAddressFromCNPostal(_ address: CNPostalAddress?) { + line1 = stringIfHasContentsElseNil(address?.street) + city = stringIfHasContentsElseNil(address?.city) + state = stringIfHasContentsElseNil(address?.state) + postalCode = stringIfHasContentsElseNil(address?.postalCode) + country = stringIfHasContentsElseNil(address?.isoCountryCode.uppercased()) + } + + private func firstName() -> String? { + if let givenName = givenName { + return givenName + } else { + let components = name?.components(separatedBy: " ") + return components?.first + } + } + + private func lastName() -> String? { + if let familyName = familyName { + return familyName + } else { + if let components = name?.components(separatedBy: " "), + let firstName = components.first, + let lastName = name?.replacingOccurrences(of: firstName, with: "") + .trimmingCharacters( + in: .whitespaces + ) + { + return stringIfHasContentsElseNil(lastName) + } + return nil + } + } + + private func street() -> String? { + var street: String? + if let line1 = line1 { + street = "" + line1 + } + if let line2 = line2 { + street = [street ?? "", line2].joined(separator: " ") + } + return street + } + + /// Does this STPAddress contain any data in the postal address fields? + /// If they are all empty or nil, returns NO. Even a single character in a + /// single field will return YES. + @_spi(STP) public func hasPartialPostalAddress() -> Bool { + return (line1?.count ?? 0) > 0 || (line2?.count ?? 0) > 0 || (city?.count ?? 0) > 0 + || (country?.count ?? 0) > 0 || (state?.count ?? 0) > 0 || (postalCode?.count ?? 0) > 0 + } +} + +extension STPAddress: STPAPIResponseDecodable { + @objc + public class func decodedObject(fromAPIResponse response: [AnyHashable: Any]?) -> Self? { + guard let dict = response else { + return nil + } + + let address = STPAddress() + address.allResponseFields = dict + /// all properties are nullable + address.city = dict["city"] as? String + address.country = dict["country"] as? String + address.line1 = dict["line1"] as? String + address.line2 = dict["line2"] as? String + address.postalCode = dict["postal_code"] as? String + address.state = dict["state"] as? String + return address as? Self + } +} + +extension STPAddress: STPFormEncodable { + + @objc + public class func rootObjectName() -> String? { + return nil + } + + @objc + public class func propertyNamesToFormFieldNamesMapping() -> [String: String] { + // Paralleling `decodedObjectFromAPIResponse:`, *only* the 6 address fields are encoded + // If this changes, shippingInfoForChargeWithAddress:shippingMethod: might break + return [ + NSStringFromSelector(#selector(getter:line1)): "line1", + NSStringFromSelector(#selector(getter:line2)): "line2", + NSStringFromSelector(#selector(getter:city)): "city", + NSStringFromSelector(#selector(getter:state)): "state", + NSStringFromSelector(#selector(getter:CNMutablePostalAddress.postalCode)): + "postal_code", + NSStringFromSelector(#selector(getter:country)): "country", + ] + } + +} + +extension STPAddress: NSCopying { + /// :nodoc: + @objc + public func copy(with zone: NSZone? = nil) -> Any { + let copyAddress = STPAddress() + + // Name might be stored as full name in _name, or split between given/family name + // access ivars directly and explicitly copy the instances. + copyAddress.name = name + copyAddress.givenName = givenName + copyAddress.familyName = familyName + + copyAddress.line1 = line1 + copyAddress.line2 = line2 + copyAddress.city = city + copyAddress.state = state + copyAddress.postalCode = postalCode + copyAddress.country = country + + copyAddress.phone = phone + copyAddress.email = email + + copyAddress.allResponseFields = allResponseFields + + return copyAddress + } +} diff --git a/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/STPCardBrand.swift b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/STPCardBrand.swift new file mode 100644 index 0000000..5635285 --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/STPCardBrand.swift @@ -0,0 +1,67 @@ +// +// STPCardBrand.swift +// StripePayments +// +// Created by Jack Flintermann on 7/24/15. +// Copyright (c) 2015 Stripe, Inc. All rights reserved. +// + +import Foundation + +/// The various card brands to which a payment card can belong. +@objc public enum STPCardBrand: Int { + /// Visa card + case visa + /// American Express card + case amex + /// Mastercard card + case mastercard + /// Discover card + case discover + /// JCB card + case JCB + /// Diners Club card + case dinersClub + /// UnionPay card + case unionPay + /// An unknown card brand type + case unknown +} + +/// :nodoc: +@available( + *, + deprecated, + message: "STPStringFromCardBrand has been replaced with STPCardBrandUtilities.stringFrom(brand)" +) +@objc public class STPStringFromCardBrand: NSObject { +} + +/// Contains `STPStringFromCardBrand` +public class STPCardBrandUtilities: NSObject { + /// Returns a string representation for the provided card brand; + /// i.e. `STPCardBrandUtilities.stringFrom(brand: .visa) == "Visa"`. + /// - Parameter brand: the brand you want to convert to a string + /// - Returns: A string representing the brand, suitable for displaying to a user. + @objc(stringFromCardBrand:) public static func stringFrom(_ brand: STPCardBrand) -> String? { + switch brand { + case .amex: + return "American Express" + case .dinersClub: + return "Diners Club" + case .discover: + return "Discover" + case .JCB: + return "JCB" + case .mastercard: + return "Mastercard" + case .unionPay: + return "UnionPay" + case .visa: + return "Visa" + case .unknown: + return "Unknown" + } + } + +} diff --git a/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/STPConnectAccountAddress.swift b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/STPConnectAccountAddress.swift new file mode 100644 index 0000000..82e3d61 --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/STPConnectAccountAddress.swift @@ -0,0 +1,82 @@ +// +// STPConnectAccountAddress.swift +// StripePayments +// +// Created by Yuki Tokuhiro on 8/2/19. +// Copyright © 2019 Stripe, Inc. All rights reserved. +// + +import Foundation + +/// An address to use with `STPConnectAccountParams`. +public class STPConnectAccountAddress: NSObject { + + /// City, district, suburb, town, or village. + /// For addresses in Japan: City or ward. + @objc public var city: String? + + /// Two-letter country code (ISO 3166-1 alpha-2). + /// - seealso: https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2 + @objc public var country: String? + + /// Address line 1 (e.g., street, PO Box, or company name). + /// For addresses in Japan: Block or building number. + @objc public var line1: String? + + /// Address line 2 (e.g., apartment, suite, unit, or building). + /// For addresses in Japan: Building details. + @objc public var line2: String? + + /// ZIP or postal code. + @objc public var postalCode: String? + + /// State, county, province, or region. + /// For addresses in Japan: Prefecture. + @objc public var state: String? + + /// Town or cho-me. + /// This property only applies to Japanese addresses. + @objc public var town: String? + + /// :nodoc: + @objc public var additionalAPIParameters: [AnyHashable: Any] = [:] + + /// :nodoc: + @objc public override var description: String { + let props = [ + // Object + String(format: "%@: %p", NSStringFromClass(STPConnectAccountAddress.self), self), + // Properties + "line1 = \(String(describing: line1))", + "line2 = \(String(describing: line2))", + "town = \(String(describing: town))", + "city = \(String(describing: city))", + "state = \(String(describing: state))", + "postalCode = \(String(describing: postalCode))", + "country = \(String(describing: country))", + ] + + return "<\(props.joined(separator: "; "))>" + } +} + +// MARK: - STPFormEncodable +extension STPConnectAccountAddress: STPFormEncodable { + @objc + public class func propertyNamesToFormFieldNamesMapping() -> [String: String] { + return [ + NSStringFromSelector(#selector(getter:line1)): "line1", + NSStringFromSelector(#selector(getter:line2)): "line2", + NSStringFromSelector(#selector(getter:town)): "town", + NSStringFromSelector(#selector(getter:city)): "city", + NSStringFromSelector(#selector(getter:country)): "country", + NSStringFromSelector(#selector(getter:state)): "state", + NSStringFromSelector(#selector(getter:postalCode)): "postal_code", + ] + } + + @objc + public class func rootObjectName() -> String? { + return nil + } +} diff --git a/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/STPConnectAccountCompanyParams.swift b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/STPConnectAccountCompanyParams.swift new file mode 100644 index 0000000..7bdfa30 --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/STPConnectAccountCompanyParams.swift @@ -0,0 +1,107 @@ +// +// STPConnectAccountCompanyParams.swift +// StripePayments +// +// Created by Yuki Tokuhiro on 8/2/19. +// Copyright © 2019 Stripe, Inc. All rights reserved. +// + +import Foundation + +/// Information about the company or business to use with `STPConnectAccountParams`. +/// - seealso: https://stripe.com/docs/api/tokens/create_account#create_account_token-account-company +public class STPConnectAccountCompanyParams: NSObject { + + /// The company’s primary address. + @objc public var address: STPConnectAccountAddress! + + /// The Kana variation of the company’s primary address (Japan only). + @objc public var kanaAddress: STPConnectAccountAddress? + + /// The Kanji variation of the company’s primary address (Japan only). + @objc public var kanjiAddress: STPConnectAccountAddress? + + /// Whether the company’s directors have been provided. + /// Set this Boolean to true after creating all the company’s directors with the Persons API (https://stripe.com/docs/api/persons) for accounts with a relationship.director requirement. + /// This value is not automatically set to true after creating directors, so it needs to be updated to indicate all directors have been provided. + @objc public var directorsProvided: NSNumber? + + /// The company’s legal name. + @objc public var name: String? + + /// The Kana variation of the company’s legal name (Japan only). + @objc public var kanaName: String? + + /// The Kanji variation of the company’s legal name (Japan only). + @objc public var kanjiName: String? + + /// Whether the company’s owners have been provided. + /// Set this Boolean to true after creating all the company’s owners with the Persons API (https://stripe.com/docs/api/persons) for accounts with a relationship.owner requirement. + @objc public var ownersProvided: NSNumber? + + /// The company’s phone number (used for verification). + @objc public var phone: String? + + /// The business ID number of the company, as appropriate for the company’s country. + /// (Examples are an Employer ID Number in the U.S., a Business Number in Canada, or a Company Number in the UK.) + @objc public var taxID: String? + + /// The jurisdiction in which the taxID is registered (Germany-based companies only). + @objc public var taxIDRegistrar: String? + + /// The VAT number of the company. + @objc public var vatID: String? + + /// :nodoc: + @objc public var additionalAPIParameters: [AnyHashable: Any] = [:] + + /// :nodoc: + @objc public override var description: String { + let props = [ + // Object + String(format: "%@: %p", NSStringFromClass(STPConnectAccountCompanyParams.self), self), + // Properties omitted b/c they're PII + "address: ", + "kanaAddress: \((kanaAddress != nil ? "" : nil) ?? "")", + "kanjiAddress: \((kanjiAddress != nil ? "" : nil) ?? "")", + "directorsProvided: \(String(describing: directorsProvided))", + "name: \(name != nil ? "" : "")", + "kanaName: \(kanaName != nil ? "" : "")", + "kanjiName: \(kanjiName != nil ? "" : "")", + "ownersProvided: \(String(describing: ownersProvided))", + "phone: \(phone != nil ? "" : "")", + "taxID: \(taxID != nil ? "" : "")", + "taxIDRegistrar: \(taxIDRegistrar != nil ? "" : "")", + "vatID: \(vatID != nil ? "" : "")", + ] + + return "<\(props.joined(separator: "; "))>" + } + +} + +// MARK: - STPFormEncodable +extension STPConnectAccountCompanyParams: STPFormEncodable { + @objc + public class func propertyNamesToFormFieldNamesMapping() -> [String: String] { + return [ + NSStringFromSelector(#selector(getter:address)): "address", + NSStringFromSelector(#selector(getter:kanaAddress)): "address_kana", + NSStringFromSelector(#selector(getter:kanjiAddress)): "address_kanji", + NSStringFromSelector(#selector(getter:directorsProvided)): "directors_provided", + NSStringFromSelector(#selector(getter:name)): "name", + NSStringFromSelector(#selector(getter:kanaName)): "name_kana", + NSStringFromSelector(#selector(getter:kanjiName)): "name_kanji", + NSStringFromSelector(#selector(getter:ownersProvided)): "owners_provided", + NSStringFromSelector(#selector(getter:phone)): "phone", + NSStringFromSelector(#selector(getter:taxID)): "tax_id", + NSStringFromSelector(#selector(getter:taxIDRegistrar)): "tax_id_registrar", + NSStringFromSelector(#selector(getter:vatID)): "vat_id", + ] + } + + @objc + public class func rootObjectName() -> String? { + return nil + } +} diff --git a/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/STPConnectAccountIndividualParams.swift b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/STPConnectAccountIndividualParams.swift new file mode 100644 index 0000000..d7a6e70 --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/STPConnectAccountIndividualParams.swift @@ -0,0 +1,246 @@ +// +// STPConnectAccountIndividualParams.swift +// StripePayments +// +// Created by Yuki Tokuhiro on 8/2/19. +// Copyright © 2019 Stripe, Inc. All rights reserved. +// + +import Foundation + +/// Information about the person represented by the account for use with `STPConnectAccountParams`. +/// - seealso: https://stripe.com/docs/api/tokens/create_account#create_account_token-account-individual +public class STPConnectAccountIndividualParams: NSObject { + + /// The individual’s primary address. + @objc public var address: STPConnectAccountAddress? + + /// The Kana variation of the the individual’s primary address (Japan only). + @objc public var kanaAddress: STPConnectAccountAddress? + + /// The Kanji variation of the the individual’s primary address (Japan only). + @objc public var kanjiAddress: STPConnectAccountAddress? + + /// The individual’s date of birth. + /// Must include `day`, `month`, and `year`, and only those fields are used. + @objc public var dateOfBirth: DateComponents? + + /// The individual's email address. + @objc public var email: String? + + /// The individual’s first name. + @objc public var firstName: String? + + /// The Kana variation of the the individual’s first name (Japan only). + @objc public var kanaFirstName: String? + + /// The Kanji variation of the individual’s first name (Japan only). + @objc public var kanjiFirstName: String? + + /// The individual’s gender + /// International regulations require either “male” or “female”. + @objc public var gender: String? + + /// The government-issued ID number of the individual, as appropriate for the representative’s country. + /// Examples are a Social Security Number in the U.S., or a Social Insurance Number in Canada. + /// Instead of the number itself, you can also provide a PII token (see https://stripe.com/docs/api/tokens/create_pii). + @objc public var idNumber: String? + + /// The individual’s last name. + @objc public var lastName: String? + + /// The Kana varation of the individual’s last name (Japan only). + @objc public var kanaLastName: String? + + /// The Kanji varation of the individual’s last name (Japan only). + @objc public var kanjiLastName: String? + + /// The individual’s maiden name. + @objc public var maidenName: String? + + /// Set of key-value pairs that you can attach to an object. + /// This can be useful for storing additional information about the object in a structured format. + @objc public var metadata: [AnyHashable: Any]? + + /// The individual’s phone number. + @objc public var phone: String? + + /// The last four digits of the individual’s Social Security Number (U.S. only). + @objc public var ssnLast4: String? + + /// The individual’s verification document information. + @objc public var verification: STPConnectAccountIndividualVerification? + + /// :nodoc: + @objc public var additionalAPIParameters: [AnyHashable: Any] = [:] + + /// :nodoc: + @objc public override var description: String { + let props: [String] = [ + // Object + String( + format: "%@: %p", + NSStringFromClass(STPConnectAccountIndividualParams.self), + self + ), + // Properties + "address = \(address != nil ? "" : "")", + "kanaAddress = \(kanaAddress != nil ? "" : "")", + "kanjiAddress = \(kanjiAddress != nil ? "" : "")", + "dateOfBirth = \(dateOfBirth != nil ? "" : "")", + "email = \(email != nil ? "" : "")", + "firstName = \(firstName != nil ? "" : "")", + "kanaFirstName = \(kanaFirstName != nil ? "" : "")", + "kanjiFirstName = \(kanjiFirstName != nil ? "" : "")", + "gender = \(gender != nil ? "" : "")", + "idNumber = \(idNumber != nil ? "" : "")", + "lastName = \(lastName != nil ? "" : "")", + "kanaLastName = \(kanaLastName != nil ? "" : "")", + "kanjiLastNaame = \(kanjiLastName != nil ? "" : "")", + "maidenName = \(maidenName != nil ? "" : "")", + "metadata = \(metadata != nil ? "" : "")", + "phone = \(phone != nil ? "" : "")", + "ssnLast4 = \(ssnLast4 != nil ? "" : "")", + "verification = \(String(describing: verification))", + ] + + return "<\(props.joined(separator: "; "))>" + } + + @objc var _dateOfBirth: STPDateOfBirth? { + guard let dateOfBirth = dateOfBirth else { + return nil + } + + let dob = STPDateOfBirth() + dob.day = dateOfBirth.day ?? 0 + dob.month = dateOfBirth.month ?? 0 + dob.year = dateOfBirth.year ?? 0 + return dob + } +} + +extension STPConnectAccountIndividualParams: STPFormEncodable { + @objc + public class func propertyNamesToFormFieldNamesMapping() -> [String: String] { + return [ + NSStringFromSelector(#selector(getter:address)): "address", + NSStringFromSelector(#selector(getter:kanaAddress)): "address_kana", + NSStringFromSelector(#selector(getter:kanjiAddress)): "address_kanji", + NSStringFromSelector(#selector(getter:_dateOfBirth)): "dob", + NSStringFromSelector(#selector(getter:email)): "email", + NSStringFromSelector(#selector(getter:firstName)): "first_name", + NSStringFromSelector(#selector(getter:kanaFirstName)): "first_name_kana", + NSStringFromSelector(#selector(getter:kanjiFirstName)): "first_name_kanji", + NSStringFromSelector(#selector(getter:gender)): "gender", + NSStringFromSelector(#selector(getter:idNumber)): "id_number", + NSStringFromSelector(#selector(getter:lastName)): "last_name", + NSStringFromSelector(#selector(getter:kanaLastName)): "last_name_kana", + NSStringFromSelector(#selector(getter:kanjiLastName)): "last_name_kanji", + NSStringFromSelector(#selector(getter:maidenName)): "maiden_name", + NSStringFromSelector(#selector(getter:metadata)): "metadata", + NSStringFromSelector(#selector(getter:phone)): "phone", + NSStringFromSelector(#selector(getter:ssnLast4)): "ssn_last_4", + NSStringFromSelector(#selector(getter:verification)): "verification", + ] + } + + @objc + public class func rootObjectName() -> String? { + return nil + } +} + +// MARK: - + +/// The individual’s verification document information for use with `STPConnectAccountIndividualParams`. +public class STPConnectAccountIndividualVerification: NSObject { + + /// An identifying document, either a passport or local ID card. + @objc public var document: STPConnectAccountVerificationDocument? + + /// A document showing address, either a passport, local ID card, or utility bill from a well-known utility company. + @objc public var additionalDocument: STPConnectAccountVerificationDocument? + + @objc public var additionalAPIParameters: [AnyHashable: Any] = [:] +} + +extension STPConnectAccountIndividualVerification: STPFormEncodable { + @objc + public class func propertyNamesToFormFieldNamesMapping() -> [String: String] { + return [ + NSStringFromSelector(#selector(getter:document)): "document", + NSStringFromSelector(#selector(getter:additionalDocument)): "additional_document", + ] + } + + @objc + public class func rootObjectName() -> String? { + return nil + } +} + +// MARK: - + +/// An identifying document, either a passport or local ID card for use with `STPConnectAccountIndividualVerification`. +public class STPConnectAccountVerificationDocument: NSObject { + + /// The back of an ID returned by a file upload with a `purpose` value of `identity_document`. + /// - seealso: https://stripe.com/docs/api/files/create for file uploads + @objc public var back: String? + + /// The front of an ID returned by a file upload with a `purpose` value of `identity_document`. + /// - seealso: https://stripe.com/docs/api/files/create for file uploads + @objc public var front: String? + + @objc public var additionalAPIParameters: [AnyHashable: Any] = [:] +} + +extension STPConnectAccountVerificationDocument: STPFormEncodable { + @objc + public class func propertyNamesToFormFieldNamesMapping() -> [String: String] { + return [ + NSStringFromSelector(#selector(getter:back)): "back", + NSStringFromSelector(#selector(getter:front)): "front", + ] + } + + @objc + public class func rootObjectName() -> String? { + return nil + } +} + +// MARK: - Date of Birth + +/// An individual's date of birth. +/// See https://stripe.com/docs/api/tokens/create_account#create_account_token-account-individual-dob +public class STPDateOfBirth: NSObject { + + /// The day of birth, between 1 and 31. + @objc public var day = 0 + + /// The month of birth, between 1 and 12. + @objc public var month = 0 + + /// The four-digit year of birth. + @objc public var year = 0 + + @objc public var additionalAPIParameters: [AnyHashable: Any] = [:] +} + +extension STPDateOfBirth: STPFormEncodable { + @objc + public class func propertyNamesToFormFieldNamesMapping() -> [String: String] { + return [ + NSStringFromSelector(#selector(getter:day)): "day", + NSStringFromSelector(#selector(getter:month)): "month", + NSStringFromSelector(#selector(getter:year)): "year", + ] + } + + @objc + public class func rootObjectName() -> String? { + return nil + } +} diff --git a/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/STPConnectAccountParams.swift b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/STPConnectAccountParams.swift new file mode 100644 index 0000000..7a3c26b --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/STPConnectAccountParams.swift @@ -0,0 +1,161 @@ +// +// STPConnectAccountParams.swift +// StripePayments +// +// Created by Daniel Jackson on 1/4/18. +// Copyright © 2018 Stripe, Inc. All rights reserved. +// + +import Foundation + +/// The business type of the Connect account. +@objc public enum STPConnectAccountBusinessType: Int { + /// This Connect account represents an individual. + case individual + /// This Connect account represents a company. + case company +} + +/// Parameters for creating a Connect Account token. +/// - seealso: https://stripe.com/docs/api/tokens/create_account +public class STPConnectAccountParams: NSObject { + + /// Boolean indicating that the Terms Of Service were shown to the user & + /// the user accepted them. + @objc public let tosShownAndAccepted: NSNumber? + + /// The business type. + @objc public let businessType: STPConnectAccountBusinessType + + /// Information about the individual represented by the account. + @objc public let individual: STPConnectAccountIndividualParams? + + /// Information about the company or business. + @objc public let company: STPConnectAccountCompanyParams? + + @objc public var additionalAPIParameters: [AnyHashable: Any] = [:] + + /// Initialize `STPConnectAccountParams` with tosShownAndAccepted = YES + /// This method cannot be called with `wasAccepted == NO`, guarded by a `NSParameterAssert()`. + /// Use this init method if you want to set the `tosShownAndAccepted` parameter. If you + /// don't, use the `initWithIndividual:` version instead. + /// - Parameters: + /// - wasAccepted: Must be YES, but only if the user was shown & accepted the ToS + /// - individual: Information about the person represented by the account. See `STPConnectAccountIndividualParams`. + @objc public init?( + tosShownAndAccepted wasAccepted: Bool, + individual: STPConnectAccountIndividualParams + ) { + // It is an error to call this method with wasAccepted == NO + guard wasAccepted == true else { + return nil + } + self.tosShownAndAccepted = wasAccepted as NSNumber + self.individual = individual + self.company = nil + self.businessType = .individual + super.init() + } + + /// Initialize `STPConnectAccountParams` with tosShownAndAccepted = YES + /// This method cannot be called with `wasAccepted == NO`, guarded by a `NSParameterAssert()`. + /// Use this init method if you want to set the `tosShownAndAccepted` parameter. If you + /// don't, use the `initWithCompany:` version instead. + /// - Parameters: + /// - wasAccepted: Must be YES, but only if the user was shown & accepted the ToS + /// - company: Information about the company or business. See `STPConnectAccountCompanyParams`. + @objc public init?( + tosShownAndAccepted wasAccepted: Bool, + company: STPConnectAccountCompanyParams + ) { + // It is an error to call this method with wasAccepted == NO + guard wasAccepted == true else { + return nil + } + self.tosShownAndAccepted = wasAccepted as NSNumber + self.individual = nil + self.company = company + self.businessType = .company + super.init() + } + + /// Initialize `STPConnectAccountParams` with the provided `individual` dictionary. + /// - Parameter individual: Information about the person represented by the account + /// This init method cannot change the `tosShownAndAccepted` parameter. Use + /// `initWithTosShownAndAccepted:individual:` instead if you need to do that. + @objc + public init( + individual: STPConnectAccountIndividualParams + ) { + tosShownAndAccepted = false + self.individual = individual + self.company = nil + businessType = .individual + super.init() + + } + + /// Initialize `STPConnectAccountParams` with the provided `company` dictionary. + /// - Parameter company: Information about the company or business + /// This init method cannot change the `tosShownAndAccepted` parameter. Use + /// `initWithTosShownAndAccepted:company:` instead if you need to do that. + @objc + public init( + company: STPConnectAccountCompanyParams + ) { + tosShownAndAccepted = false + self.individual = nil + self.company = company + businessType = .company + super.init() + } + + // MARK: - description + /// :nodoc: + @objc public override var description: String { + let props: [String] = [ + String(format: "%@: %p", NSStringFromClass(STPConnectAccountParams.self), self), + // We use NSParameterAssert to block this being NO: + "tosShownAndAccepted = \(String(describing: tosShownAndAccepted))", + "individual = \(String(describing: individual))", + "company = \(String(describing: company))", + "business_type = \(STPConnectAccountParams.string(from: businessType))", + ] + return "<\(props.joined(separator: "; "))>" + } + + // MARK: - STPConnectAccountBusinessType + @objc(stringFromBusinessType:) + class func string(from businessType: STPConnectAccountBusinessType) -> String { + switch businessType { + case .individual: + return "individual" + case .company: + return "company" + } + } + +} + +// MARK: - STPFormEncodable +extension STPConnectAccountParams: STPFormEncodable { + + @objc internal var businessTypeString: String { + return STPConnectAccountParams.string(from: businessType) + } + + @objc + public class func rootObjectName() -> String? { + return "account" + } + + @objc + public class func propertyNamesToFormFieldNamesMapping() -> [String: String] { + return [ + NSStringFromSelector(#selector(getter:tosShownAndAccepted)): "tos_shown_and_accepted", + NSStringFromSelector(#selector(getter:individual)): "individual", + NSStringFromSelector(#selector(getter:company)): "company", + NSStringFromSelector(#selector(getter:businessTypeString)): "business_type", + ] + } +} diff --git a/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/STPContactField.swift b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/STPContactField.swift new file mode 100644 index 0000000..6ab9b7a --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/STPContactField.swift @@ -0,0 +1,39 @@ +// +// STPContactField.swift +// StripePayments +// +// Created by Yuki Tokuhiro on 10/6/20. +// Copyright © 2020 Stripe, Inc. All rights reserved. +// + +import Foundation +import PassKit + +/// Contains constants that represent different parts of a users contact/address information. +@objc public class STPContactField: NSObject, RawRepresentable { + public let rawValue: String + + public required init( + rawValue: String + ) { + self.rawValue = rawValue + } + + // We use PKContactField values to handle legacy users who apply XCode's compilable-but-incorrect fix-it to change eg STPContactFieldPostalAddress to PKContactFieldPostalAddress. + /// The contact's full physical address. + @objc public static let postalAddress: STPContactField = STPContactField( + rawValue: PKContactField.postalAddress.rawValue + ) + /// The contact's email address + @objc public static let emailAddress: STPContactField = STPContactField( + rawValue: PKContactField.emailAddress.rawValue + ) + /// The contact's phone number. + @objc public static let phoneNumber: STPContactField = STPContactField( + rawValue: PKContactField.phoneNumber.rawValue + ) + /// The contact's name. + @objc public static let name: STPContactField = STPContactField( + rawValue: PKContactField.name.rawValue + ) +} diff --git a/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/STPCustomer.swift b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/STPCustomer.swift new file mode 100644 index 0000000..39735f4 --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/STPCustomer.swift @@ -0,0 +1,268 @@ +// +// STPCustomer.swift +// StripePayments +// +// Created by Jack Flintermann on 6/9/16. +// Copyright © 2016 Stripe, Inc. All rights reserved. +// + +import Foundation +@_spi(STP) import StripeCore + +/// An `STPCustomer` represents a deserialized Customer object from the Stripe API. +/// You shouldn't need to instantiate an `STPCustomer` – you should instead use +/// `STPCustomerContext` to manage retrieving and updating a customer. +public class STPCustomer: NSObject { + + /// The Stripe ID of the customer, e.g. `cus_1234` + @objc public let stripeID: String + + /// The default source used to charge the customer. + @objc public private(set) var defaultSource: STPSourceProtocol? + + /// The available payment sources the customer has (this may be an empty array). + @objc public private(set) var sources: [STPSourceProtocol] + + /// The customer’s email address. + @objc public private(set) var email: String? + + /// The customer's shipping address. + @objc public var shippingAddress: STPAddress? + + @objc public let allResponseFields: [AnyHashable: Any] + + /// Initialize a customer object with the provided values. + /// - Parameters: + /// - stripeID: The ID of the customer, e.g. `cus_abc` + /// - defaultSource: The default source of the customer, such as an `STPCard` object. Can be nil. + /// - sources: All of the customer's payment sources. This might be an empty array. + /// - Returns: an instance of STPCustomer + @objc + public convenience init( + stripeID: String, + defaultSource: STPSourceProtocol?, + sources: [STPSourceProtocol] + ) { + self.init( + stripeID: stripeID, + defaultSource: defaultSource, + sources: sources, + shippingAddress: nil, + email: nil, + allResponseFields: [:] + ) + } + + internal init( + stripeID: String, + defaultSource: STPSourceProtocol?, + sources: [STPSourceProtocol], + shippingAddress: STPAddress?, + email: String?, + allResponseFields: [AnyHashable: Any] + ) { + self.stripeID = stripeID + self.defaultSource = defaultSource + self.sources = sources + self.shippingAddress = shippingAddress + self.email = email + self.allResponseFields = allResponseFields + super.init() + } + + convenience override init() { + self.init( + stripeID: "", + defaultSource: nil, + sources: [], + shippingAddress: nil, + email: nil, + allResponseFields: [:] + ) + } + + // MARK: - Description + /// :nodoc: + @objc public override var description: String { + let props: [String] = [ + // Object + String(format: "%@: %p", NSStringFromClass(STPCustomer.self), self), + // Identifier + "stripeID = \(stripeID)", + // Sources + "defaultSource = \(String(describing: defaultSource))", + "sources = \(sources)", + ] + + return "<\(props.joined(separator: "; "))>" + } + + /// Replaces the customer's `sources` and `defaultSource` based on whether or not + /// they should include Apple Pay sources. More details on documentation for + /// `STPCustomerContext includeApplePaySources` + /// + /// @param filteringApplePay If YES, Apple Pay sources will be ignored + @objc(updateSourcesFilteringApplePay:) + public func updateSources(filteringApplePay: Bool) { + let (defaultSource, sources) = STPCustomer.sources( + from: allResponseFields, + filterApplePay: filteringApplePay + ) + self.defaultSource = defaultSource + self.sources = sources + } +} + +extension STPCustomer: STPAPIResponseDecodable { + @objc + public class func decodedObject(fromAPIResponse response: [AnyHashable: Any]?) -> Self? { + guard let dict = response, + let stripeID = dict["id"] as? String + else { + return nil + } + + let shippingAddress: STPAddress? + + if let shippingDict = dict["shipping"] as? [AnyHashable: Any], + let addressDict = shippingDict["address"] as? [AnyHashable: Any], + let shipping = STPAddress.decodedObject(fromAPIResponse: addressDict) + { + shipping.name = shippingDict["name"] as? String + shipping.phone = shippingDict["phone"] as? String + shippingAddress = shipping + } else { + shippingAddress = nil + } + let (defaultSource, sources) = STPCustomer.sources(from: dict, filterApplePay: true) + + return STPCustomer( + stripeID: stripeID, + defaultSource: defaultSource, + sources: sources, + shippingAddress: shippingAddress, + email: dict["email"] as? String, + allResponseFields: dict + ) as? Self + + } + + private class func sources( + from response: [AnyHashable: Any], + filterApplePay: Bool + ) -> ( + default: STPSourceProtocol?, sources: [STPSourceProtocol] + ) { + + guard let sourcesDict = response["sources"] as? [AnyHashable: Any], + let data = sourcesDict["data"] as? [[AnyHashable: Any]] + else { + return (nil, []) + } + + var defaultSource: STPSourceProtocol? + let defaultSourceId = response["default_source"] as? String + var sources: [STPSourceProtocol] = [] + + for contents in data { + if let object = contents["object"] as? String { + if object == "card" { + if let card = STPCard.decodedObject(fromAPIResponse: contents), + !filterApplePay || !card.isApplePayCard + { + + sources.append(card) + + if let defaultSourceId = defaultSourceId, + card.stripeID == defaultSourceId + { + defaultSource = card + } + } + } else if object == "source" { + if let source = STPSource.decodedObject(fromAPIResponse: contents), + !filterApplePay || !(source.cardDetails?.isApplePayCard ?? false) + { + sources.append(source) + + if let defaultSourceId = defaultSourceId, + source.stripeID == defaultSourceId + { + defaultSource = source + } + } + } + } else { + continue + } + + } + return (defaultSource, sources) + } +} + +/// Use `STPCustomerDeserializer` to convert a response from the Stripe API into an `STPCustomer` object. `STPCustomerDeserializer` expects the JSON response to be in the exact same format as the Stripe API. +public class STPCustomerDeserializer: NSObject { + + /// If a customer was successfully parsed from the response, it will be set here. Otherwise, this value wil be nil (and the `error` property will explain what went wrong). + @objc public let customer: STPCustomer? + /// If the deserializer failed to parse a customer, this property will explain why (and the `customer` property will be nil). + @objc public let error: Error? + + /// Initialize a customer deserializer. The `data`, `urlResponse`, and `error` + /// parameters are intended to be passed from an `NSURLSessionDataTask` callback. + /// After it has been initialized, you can inspect the `error` and `customer` + /// properties to see if the deserialization was successful. If `error` is nil, + /// `customer` will be non-nil (and vice versa). + /// - Parameters: + /// - data: An `NSData` object representing encoded JSON for a Customer object + /// - urlResponse: The URL response obtained from the `NSURLSessionTask` + /// - error: Any error that occurred from the URL session task (if this + /// is non-nil, the `error` property will be set to this value after initialization). + @objc + public convenience init( + data: Data?, + urlResponse: URLResponse?, + error: Error? + ) { + if let error = error { + self.init(customer: nil, error: error) + } else if let data = data { + var json: Any? + do { + json = try JSONSerialization.jsonObject(with: data, options: []) + } catch let jsonError { + self.init(customer: nil, error: jsonError) + return + } + self.init(jsonResponse: json) + } else { + self.init(customer: nil, error: NSError.stp_genericFailedToParseResponseError()) + } + } + + /// Initializes a customer deserializer with a JSON dictionary. This JSON should be + /// in the exact same format as what the Stripe API returns. If it's successfully + /// parsed, the `customer` parameter will be present after initialization; + /// otherwise `error` will be present. + /// - Parameter json: a JSON dictionary. + @objc + public convenience init( + jsonResponse json: Any? + ) { + if let customer = STPCustomer.decodedObject(fromAPIResponse: json as? [AnyHashable: Any]) { + self.init(customer: customer, error: nil) + } else { + self.init(customer: nil, error: NSError.stp_genericFailedToParseResponseError()) + } + } + + private init( + customer: STPCustomer?, + error: Error? + ) { + self.customer = customer + self.error = error + super.init() + } +} diff --git a/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/STPFPXBankBrand.swift b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/STPFPXBankBrand.swift new file mode 100644 index 0000000..b5d2353 --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/STPFPXBankBrand.swift @@ -0,0 +1,333 @@ +// +// STPFPXBankBrand.swift +// StripePayments +// +// Created by David Estes on 8/8/19. +// Copyright © 2019 Stripe, Inc. All rights reserved. +// + +import Foundation + +/// The various bank brands available for FPX payments. +@objc public enum STPFPXBankBrand: Int { + /// Maybank2U + case maybank2U + /// CIMB Clicks + case CIMB + /// Public Bank + case publicBank + /// RHB Bank + case RHB + /// Hong Leong Bank + case hongLeongBank + /// AmBank + case ambank + /// Affin Bank + case affinBank + /// Alliance Bank + case allianceBank + /// Bank Islam + case bankIslam + /// Bank Muamalat + case bankMuamalat + /// Bank Rakyat + case bankRakyat + /// BSN + case BSN + /// HSBC BANK + case HSBC + /// KFH + case KFH + /// Maybank2E + case maybank2E + /// OCBC Bank + case ocbc + /// Standard Chartered + case standardChartered + /// UOB Bank + case UOB + /// An unknown bank + case unknown +} + +/// Convenience methods for using FPX bank brands. +public class STPFPXBank: NSObject { + /// Returns a string representation for the provided bank brand; + /// i.e. `STPFPXBank.stringFrom(brand:.uob) == "UOB Bank"`. + /// - Parameter brand: The brand you want to convert to a string + /// - Returns: A string representing the brand, suitable for displaying to a user. + @objc public static func stringFrom(_ brand: STPFPXBankBrand) -> String? { + switch brand { + case .affinBank: + return "Affin Bank" + case .allianceBank: + return "Alliance Bank" + case .ambank: + return "AmBank" + case .bankIslam: + return "Bank Islam" + case .bankMuamalat: + return "Bank Muamalat" + case .bankRakyat: + return "Bank Rakyat" + case .BSN: + return "BSN" + case .CIMB: + return "CIMB Clicks" + case .hongLeongBank: + return "Hong Leong Bank" + case .HSBC: + return "HSBC BANK" + case .KFH: + return "KFH" + case .maybank2E: + return "Maybank2E" + case .maybank2U: + return "Maybank2U" + case .ocbc: + return "OCBC Bank" + case .publicBank: + return "Public Bank" + case .RHB: + return "RHB Bank" + case .standardChartered: + return "Standard Chartered" + case .UOB: + return "UOB Bank" + case .unknown: + return "Unknown" + } + } + + /// Returns a bank brand provided a string representation identifying a bank brand; + /// i.e. `STPFPXBankBrandFromIdentifier(@"uob") == STPCardBrandUob`. + /// - Parameter identifier: The identifier for the brand + /// - Returns: The STPFPXBankBrand enum value + @objc public static func brandFrom(_ identifier: String?) -> STPFPXBankBrand { + let brand = identifier?.lowercased() + if brand == "affin_bank" { + return .affinBank + } + if brand == "alliance_bank" { + return .allianceBank + } + if brand == "ambank" { + return .ambank + } + if brand == "bank_islam" { + return .bankIslam + } + if brand == "bank_muamalat" { + return .bankMuamalat + } + if brand == "bank_rakyat" { + return .bankRakyat + } + if brand == "bsn" { + return .BSN + } + if brand == "cimb" { + return .CIMB + } + if brand == "hong_leong_bank" { + return .hongLeongBank + } + if brand == "hsbc" { + return .HSBC + } + if brand == "kfh" { + return .KFH + } + if brand == "maybank2e" { + return .maybank2E + } + if brand == "maybank2u" { + return .maybank2U + } + if brand == "ocbc" { + return .ocbc + } + if brand == "public_bank" { + return .publicBank + } + if brand == "rhb" { + return .RHB + } + if brand == "standard_chartered" { + return .standardChartered + } + if brand == "uob" { + return .UOB + } + return .unknown + } + + /// Returns a string representation identifying the provided bank brand; + /// i.e. `STPIdentifierFromFPXBankBrand(STPCardBrandUob) == @"uob"`. + /// - Parameter brand: The brand you want to convert to a string + /// - Returns: A string representing the brand, suitable for using with the Stripe API. + @objc public static func identifierFrom(_ brand: STPFPXBankBrand) -> String? { + switch brand { + case .affinBank: + return "affin_bank" + case .allianceBank: + return "alliance_bank" + case .ambank: + return "ambank" + case .bankIslam: + return "bank_islam" + case .bankMuamalat: + return "bank_muamalat" + case .bankRakyat: + return "bank_rakyat" + case .BSN: + return "bsn" + case .CIMB: + return "cimb" + case .hongLeongBank: + return "hong_leong_bank" + case .HSBC: + return "hsbc" + case .KFH: + return "kfh" + case .maybank2E: + return "maybank2e" + case .maybank2U: + return "maybank2u" + case .ocbc: + return "ocbc" + case .publicBank: + return "public_bank" + case .RHB: + return "rhb" + case .standardChartered: + return "standard_chartered" + case .UOB: + return "uob" + case .unknown: + return "unknown" + } + } + + /// Returns the code identifying the provided bank brand in the FPX status API; + /// i.e. `STPIdentifierFromFPXBankBrand(STPCardBrandUob) == @"UOB0226"`. + /// - Parameters: + /// - brand: The brand you want to convert to an FPX bank code + /// - isBusiness: Requests the code for the business version of this bank brand, which may be different from the code used for individual accounts + /// - Returns: A string representing the brand, suitable for checking against the FPX status API. + @objc public static func bankCodeFrom(_ brand: STPFPXBankBrand, _ isBusiness: Bool) -> String? { + switch brand { + case .affinBank: + if isBusiness { + return "ABB0232" + } else { + return "ABB0233" + } + case .allianceBank: + if isBusiness { + return "ABMB0213" + } else { + return "ABMB0212" + } + case .ambank: + if isBusiness { + return "AMBB0208" + } else { + return "AMBB0209" + } + case .bankIslam: + if isBusiness { + return nil + } else { + return "BIMB0340" + } + case .bankMuamalat: + if isBusiness { + return "BMMB0342" + } else { + return "BMMB0341" + } + case .bankRakyat: + if isBusiness { + return "BKRM0602" + } else { + return "BKRM0602" + } + case .BSN: + if isBusiness { + return nil + } else { + return "BSN0601" + } + case .CIMB: + if isBusiness { + return "BCBB0235" + } else { + return "BCBB0235" + } + case .hongLeongBank: + if isBusiness { + return "HLB0224" + } else { + return "HLB0224" + } + case .HSBC: + if isBusiness { + return "HSBC0223" + } else { + return "HSBC0223" + } + case .KFH: + if isBusiness { + return "KFH0346" + } else { + return "KFH0346" + } + case .maybank2E: + if isBusiness { + return "MBB0228" + } else { + return "MBB0228" + } + case .maybank2U: + if isBusiness { + return nil + } else { + return "MB2U0227" + } + case .ocbc: + if isBusiness { + return "OCBC0229" + } else { + return "OCBC0229" + } + case .publicBank: + if isBusiness { + return "PBB0233" + } else { + return "PBB0233" + } + case .RHB: + if isBusiness { + return "RHB0218" + } else { + return "RHB0218" + } + case .standardChartered: + if isBusiness { + return "SCB0215" + } else { + return "SCB0216" + } + case .UOB: + if isBusiness { + return "UOB0228" + } else { + return "UOB0226" + } + case .unknown: + return "unknown" + } + } + +} diff --git a/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/STPFile.swift b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/STPFile.swift new file mode 100644 index 0000000..3a1b6e2 --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/STPFile.swift @@ -0,0 +1,139 @@ +// +// STPFile.swift +// StripePayments +// +// Created by Charles Scalesse on 11/30/16. +// Copyright © 2016 Stripe, Inc. All rights reserved. +// + +import Foundation +@_spi(STP) import StripeCore + +/// The purpose of the uploaded file. +/// - seealso: https://stripe.com/docs/file-upload +@objc +public enum STPFilePurpose: Int { + + // NOTE: If adding cases here, also add to `StripeFile.Purpose` or they will + // not be encoded/decoded to/from the server. + + /// Identity document file + case identityDocument + /// Dispute evidence file + case disputeEvidence + /// A file of unknown purpose type + case unknown +} + +/// Representation of a file upload object in the Stripe API. +/// - seealso: https://stripe.com/docs/api#file_uploads +public class STPFile: NSObject, STPAPIResponseDecodable { + + // NOTE: If adding properties here, also add to `StripeFile` or they will + // not be decoded from the API response. + + /// The token for this file. + @objc public private(set) var fileId: String? + /// The date this file was created. + @objc public private(set) var created: Date? + /// The purpose of this file. This can be either an identifing document or an evidence dispute. + /// - seealso: https://stripe.com/docs/file-upload + @objc public private(set) var purpose: STPFilePurpose = .unknown + /// The file size in bytes. + @objc public private(set) var size: NSNumber? + /// The file type. This can be "jpg", "png", or "pdf". + @objc public private(set) var type: String? + + /// Returns the string value for a purpose. + @objc(stringFromPurpose:) + public class func string(from purpose: STPFilePurpose) -> String? { + let purpose = StripeFile.Purpose(from: purpose) + + guard purpose != .unparsable else { + return nil + } + + return purpose.rawValue + } + @objc private(set) public var allResponseFields: [AnyHashable: Any] = [:] + + required internal override init() { + super.init() + } + + convenience init( + fileId: String?, + created: Date?, + purpose: STPFilePurpose, + size: NSNumber?, + type: String? + ) { + self.init() + self.fileId = fileId + self.created = created + self.purpose = purpose + self.size = size + self.type = type + } + + // See STPFile+Private.h + + // MARK: - STPFilePurpose + + @objc(purposeFromString:) + class func purpose(from string: String) -> STPFilePurpose { + return StripeFile.Purpose(rawValue: string.lowercased())?.toSTPFilePurpose ?? .unknown + } + + // MARK: - Equality + /// :nodoc: + @objc + public override func isEqual(_ object: Any?) -> Bool { + return isEqual(to: object as? STPFile) + } + + func isEqual(to file: STPFile?) -> Bool { + if self === file { + return true + } + guard let file = file else { + return false + } + return fileId == file.fileId + } + + /// :nodoc: + @objc public override var hash: Int { + return fileId?.hash ?? 0 + } + + // MARK: - STPAPIResponseDecodable + @objc + public class func decodedObject(fromAPIResponse response: [AnyHashable: Any]?) -> Self? { + guard let response = response else { + return nil + } + let dict = response.stp_dictionaryByRemovingNulls() + + // required fields + let stripeId = dict.stp_string(forKey: "id") + let created = dict.stp_date(forKey: "created") + let size = dict.stp_number(forKey: "size") + let type = dict.stp_string(forKey: "type") + let rawPurpose = dict.stp_string(forKey: "purpose") + if stripeId == nil || created == nil || size == nil || type == nil || rawPurpose == nil { + return nil + } + + let file = self.init() + file.fileId = stripeId + file.created = created + file.size = size + file.type = type + + file.purpose = self.purpose(from: rawPurpose ?? "") + file.allResponseFields = response + + return file + } +} diff --git a/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/STPFormEncodable.swift b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/STPFormEncodable.swift new file mode 100644 index 0000000..d5d4446 --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/STPFormEncodable.swift @@ -0,0 +1,23 @@ +// +// STPFormEncodable.swift +// StripePayments +// +// Created by Jack Flintermann on 10/14/15. +// Copyright © 2015 Stripe, Inc. All rights reserved. +// + +import Foundation + +/// Objects conforming to STPFormEncodable can be automatically converted to a form-encoded string, which can then be used when making requests to the Stripe API. +@objc public protocol STPFormEncodable: NSObjectProtocol { + /// The root object name to be used when converting this object to a form-encoded string. For example, if this returns "card", then the form-encoded output will resemble "card[foo]=bar" (where 'foo' and 'bar' are specified by `propertyNamesToFormFieldNamesMapping` below. + static func rootObjectName() -> String? + /// This maps properties on an object that is being form-encoded into parameter names in the Stripe API. For example, STPCardParams has a field called `expMonth`, but the Stripe API expects a field called `exp_month`. This dictionary represents a mapping from the former to the latter (in other words, STPCardParams.propertyNamesToFormFieldNamesMapping()["expMonth"] == "exp_month".) + static func propertyNamesToFormFieldNamesMapping() -> [String: String] + /// You can use this property to add additional fields to an API request that are not explicitly defined by the object's interface. This can be useful when using beta features that haven't been added to the Stripe SDK yet. For example, if the /v1/tokens API began to accept a beta field called "test_field", you might do the following: + /// var cardParams = STPCardParams() + /// // add card values + /// cardParams.additionalAPIParameters = ["test_field": "example_value"] + /// STPAPIClient.shared.createToken(withParameters: cardParams completion:...); + var additionalAPIParameters: [AnyHashable: Any] { get set } +} diff --git a/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/STPIssuingCardPin.swift b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/STPIssuingCardPin.swift new file mode 100644 index 0000000..631ad2e --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/STPIssuingCardPin.swift @@ -0,0 +1,55 @@ +// +// STPIssuingCardPin.swift +// StripePayments +// +// Created by Arnaud Cavailhez on 4/29/19. +// Copyright © 2019 Stripe, Inc. All rights reserved. +// + +import Foundation + +/// Information related to a Stripe Issuing card, including the PIN +public class STPIssuingCardPin: NSObject { + /// The PIN for the card + @objc public let pin: String? + /// If the PIN failed to be created, this error might be present + @objc public let error: [AnyHashable: Any]? + @objc public let allResponseFields: [AnyHashable: Any] + + convenience override init() { + self.init(pin: nil, error: nil, allResponseFields: [:]) + } + + private init( + pin: String?, + error: [AnyHashable: Any]?, + allResponseFields: [AnyHashable: Any] + ) { + self.pin = pin + self.error = error + self.allResponseFields = allResponseFields + super.init() + } +} + +extension STPIssuingCardPin: STPAPIResponseDecodable { + public class func decodedObject(fromAPIResponse response: [AnyHashable: Any]?) -> Self? { + guard let dict = response else { + return nil + } + + if let error = dict["error"] as? [AnyHashable: Any] { + // Return object to be able to read errors + let pinObject = STPIssuingCardPin(pin: nil, error: error, allResponseFields: dict) + return pinObject as? Self + } + + // required fields + guard let pin = dict["pin"] as? String else { + return nil + } + + let pinObject = STPIssuingCardPin(pin: pin, error: nil, allResponseFields: dict) + return pinObject as? Self + } +} diff --git a/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/STPRadarSession.swift b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/STPRadarSession.swift new file mode 100644 index 0000000..251a67b --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/STPRadarSession.swift @@ -0,0 +1,38 @@ +// +// STPRadarSession.swift +// StripePayments +// +// Created by Yuki Tokuhiro on 5/20/21. +// Copyright © 2021 Stripe, Inc. All rights reserved. +// + +import Foundation + +/// A [Radar Session](https://stripe.com/docs/radar/radar-session). +/// - Note: This API and the guide linked above require special permissions to use. Contact support@stripe.com if you're interested. +public final class STPRadarSession: NSObject, STPAPIResponseDecodable { + /// The Stripe identifier of the RadarSession + @objc public let id: String + @objc public let allResponseFields: [AnyHashable: Any] + + init( + id: String, + allResponseFields: [AnyHashable: Any] + ) { + self.id = id + self.allResponseFields = allResponseFields + super.init() + } + + public static func decodedObject( + fromAPIResponse response: [AnyHashable: Any]? + ) -> STPRadarSession? { + guard let response = response else { return nil } + let dict = response.stp_dictionaryByRemovingNulls() + guard let id = dict.stp_string(forKey: "id") else { + return nil + } + + return STPRadarSession(id: id, allResponseFields: response) + } +} diff --git a/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/STPToken.swift b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/STPToken.swift new file mode 100644 index 0000000..2432ee1 --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/STPToken.swift @@ -0,0 +1,160 @@ +// +// STPToken.swift +// StripePayments +// +// Created by Saikat Chakrabarti on 11/5/12. +// Copyright © 2012 Stripe, Inc. All rights reserved. +// + +import Foundation + +/// Possible Token types +@objc +public enum STPTokenType: Int { + /// Account token type + case account = 0 + /// Bank account token type + case bankAccount + /// Card token type + case card + /// PII token type + case PII + /// CVC update token type + case cvcUpdate +} + +/// A token returned from submitting payment details to the Stripe API. You should not have to instantiate one of these directly. +public class STPToken: NSObject, STPAPIResponseDecodable, STPSourceProtocol { + /// You cannot directly instantiate an `STPToken`. You should only use one that has been returned from an `STPAPIClient` callback. + override init() { + } + + /// The value of the token. You can store this value on your server and use it to make charges and customers. + /// - seealso: https://stripe.com/docs/payments/charges-api + @objc public private(set) var tokenId = "" + /// Whether or not this token was created in livemode. Will be YES if you used your Live Publishable Key, and NO if you used your Test Publishable Key. + @objc public private(set) var livemode = false + /// The type of this token. + @objc public private(set) var type: STPTokenType = .account + /// The credit card details that were used to create the token. Will only be set if the token was created via a credit card or Apple Pay, otherwise it will be + /// nil. + @objc public private(set) var card: STPCard? + /// The bank account details that were used to create the token. Will only be set if the token was created with a bank account, otherwise it will be nil. + @objc public private(set) var bankAccount: STPBankAccount? + /// When the token was created. + @objc public private(set) var created: Date? + @objc public private(set) var allResponseFields: [AnyHashable: Any] = [:] + + // MARK: - Description + /// :nodoc: + @objc public override var description: String { + return tokenId + } + + /// :nodoc: + @objc public override var debugDescription: String { + let token = tokenId + let livemode = self.livemode ? "live mode" : "test mode" + return "\(token) (\(livemode))" + } + + // MARK: - Equality + /// :nodoc: + @objc + public override func isEqual(_ object: Any?) -> Bool { + return isEqual(to: object as? STPToken) + } + + /// :nodoc: + @objc public override var hash: Int { + return tokenId.hash + } + + func isEqual(to object: STPToken?) -> Bool { + if self == object { + return true + } + + guard let object = object else { + return false + } + + if (card != nil || object.card != nil) && (!(card == object.card)) { + return false + } + + if (bankAccount != nil || object.bankAccount != nil) + && (!(bankAccount == object.bankAccount)) + { + return false + } + + if let created1 = object.created { + return livemode == object.livemode && type == object.type && (tokenId == object.tokenId) + && created == created1 && (card == object.card) + } + return false + } + + // MARK: - STPSourceProtocol + @objc public var stripeID: String { + return tokenId + } + + // MARK: - STPAPIResponseDecodable + @objc + public class func decodedObject(fromAPIResponse response: [AnyHashable: Any]?) -> Self? { + guard let response = response else { return nil } + let dict = response.stp_dictionaryByRemovingNulls() + guard let stripeId = dict.stp_string(forKey: "id"), + let created = dict.stp_date(forKey: "created"), + let rawType = dict.stp_string(forKey: "type"), + dict["livemode"] != nil, self._isValidRawTokenType(rawType) + else { + return nil + } + + let token = STPToken.init() + token.tokenId = stripeId + token.livemode = dict.stp_bool(forKey: "livemode", or: true) + token.created = created + token.type = self._tokenType(for: rawType) + + let rawCard = dict.stp_dictionary(forKey: "card") + token.card = STPCard.decodedObject(fromAPIResponse: rawCard) + + let rawBankAccount = dict.stp_dictionary(forKey: "bank_account") + token.bankAccount = STPBankAccount.decodedObject(fromAPIResponse: rawBankAccount) + + token.allResponseFields = dict + + return token as? Self + } + + // MARK: - STPTokenType + class func _isValidRawTokenType(_ rawType: String?) -> Bool { + if (rawType == "account") || (rawType == "bank_account") || (rawType == "card") + || (rawType == "pii") || (rawType == "cvc_update") + { + return true + } + return false + } + + class func _tokenType(for rawType: String?) -> STPTokenType { + if rawType == "account" { + return .account + } else if rawType == "bank_account" { + return .bankAccount + } else if rawType == "card" { + return .card + } else if rawType == "pii" { + return .PII + } else if rawType == "cvc_update" { + return .cvcUpdate + } + + // default return STPTokenTypeAccount (this matches other default enum behavior) + return .account + } +} diff --git a/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/STPiDEALBank.swift b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/STPiDEALBank.swift new file mode 100644 index 0000000..6308058 --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/STPiDEALBank.swift @@ -0,0 +1,59 @@ +// +// STPiDEALBank.swift +// StripePayments +// +// Created by Mel Ludowise on 2/4/21. +// Copyright © 2021 Stripe, Inc. All rights reserved. +// + +import Foundation + +enum STPiDEALBank: String, CaseIterable { + case abnAmro = "abn_amro" + case asnBank = "asn_bank" + case bunq + case handelsbanken + case ing + case knab + case rabobank + case regiobank + case revolut + case snsBank = "sns_bank" + case triodosBank = "triodos_bank" + case vanLanschot = "van_lanschot" + + /// The name of the bank as expected by Stripe's API. + var name: String { + return rawValue + } + + /// The human-readable display name of the bank. + var displayName: String { + switch self { + case .abnAmro: + return "ABN Amro" + case .asnBank: + return "ASN Bank" + case .bunq: + return "bunq B.V." + case .handelsbanken: + return "Handelsbanken" + case .ing: + return "ING Bank" + case .knab: + return "Knab" + case .rabobank: + return "Rabobank" + case .regiobank: + return "RegioBank" + case .revolut: + return "Revolut" + case .snsBank: + return "SNS Bank" + case .triodosBank: + return "Triodos Bank" + case .vanLanschot: + return "Van Lanschot" + } + } +} diff --git a/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/SetupIntents/STPSetupIntent.swift b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/SetupIntents/STPSetupIntent.swift new file mode 100644 index 0000000..8736df0 --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/SetupIntents/STPSetupIntent.swift @@ -0,0 +1,270 @@ +// +// STPSetupIntent.swift +// StripePayments +// +// Created by Yuki Tokuhiro on 6/27/19. +// Copyright © 2019 Stripe, Inc. All rights reserved. +// + +import Foundation + +/// A SetupIntent guides you through the process of setting up a customer's payment credentials for future payments. +/// - seealso: https://stripe.com/docs/api/setup_intents +public class STPSetupIntent: NSObject, STPAPIResponseDecodable { + /// The Stripe ID of the SetupIntent. + @objc public let stripeID: String + /// The client secret of this SetupIntent. Used for client-side retrieval using a publishable key. + @objc public let clientSecret: String + /// Time at which the object was created. + @objc public let created: Date + /// ID of the Customer this SetupIntent belongs to, if one exists. + @objc public let customerID: String? + /// An arbitrary string attached to the object. Often useful for displaying to users. + @objc public let stripeDescription: String? + /// Has the value `YES` if the object exists in live mode or the value `NO` if the object exists in test mode. + @objc public let livemode: Bool + /// If present, this property tells you what actions you need to take in order for your customer to set up this payment method. + @objc public let nextAction: STPIntentAction? + /// ID of the payment method used with this SetupIntent. + @objc public let paymentMethodID: String? + /// The optionally expanded PaymentMethod used in this SetupIntent. + @objc public let paymentMethod: STPPaymentMethod? + /// The list of payment method types (e.g. `[STPPaymentMethodType.card]`) that this SetupIntent is allowed to set up. + @objc public let paymentMethodTypes: [NSNumber] + /// Status of this SetupIntent. + @objc public let status: STPSetupIntentStatus + /// Indicates how the payment method is intended to be used in the future. + @objc public let usage: STPSetupIntentUsage + /// The setup error encountered in the previous SetupIntent confirmation. + @objc public let lastSetupError: STPSetupIntentLastSetupError? + /// The ordered payment method preference for this SetupIntent + @_spi(STP) public let orderedPaymentMethodTypes: [STPPaymentMethodType] + /// A list of payment method types that are not activated in live mode, but activated in test mode + @_spi(STP) public let unactivatedPaymentMethodTypes: [STPPaymentMethodType] + /// Payment-method-specific configuration for this SetupIntent. + @_spi(STP) public let paymentMethodOptions: STPPaymentMethodOptions? + /// Link-specific settings for this SetupIntent. + @_spi(STP) public let linkSettings: LinkSettings? + /// Country code of the user. + @_spi(STP) public let countryCode: String? + // MARK: - Deprecated + + /// Set of key-value pairs that you can attach to an object. This can be useful for storing additional information about the object in a structured format. + /// @deprecated Metadata is not returned to clients using publishable keys. Retrieve them on your server using yoursecret key instead. + /// - seealso: https://stripe.com/docs/api#metadata + @available( + *, + deprecated, + message: + "Metadata is not returned to clients using publishable keys. Retrieve them on your server using your secret key instead." + ) + @objc public private(set) var metadata: [String: String]? + @objc public let allResponseFields: [AnyHashable: Any] + + required init( + stripeID: String, + clientSecret: String, + created: Date, + countryCode: String?, + customerID: String?, + stripeDescription: String?, + linkSettings: LinkSettings?, + livemode: Bool, + nextAction: STPIntentAction?, + orderedPaymentMethodTypes: [STPPaymentMethodType], + paymentMethodID: String?, + paymentMethod: STPPaymentMethod?, + paymentMethodOptions: STPPaymentMethodOptions?, + paymentMethodTypes: [NSNumber], + status: STPSetupIntentStatus, + usage: STPSetupIntentUsage, + lastSetupError: STPSetupIntentLastSetupError?, + allResponseFields: [AnyHashable: Any], + unactivatedPaymentMethodTypes: [STPPaymentMethodType] + ) { + self.stripeID = stripeID + self.clientSecret = clientSecret + self.created = created + self.countryCode = countryCode + self.customerID = customerID + self.stripeDescription = stripeDescription + self.linkSettings = linkSettings + self.livemode = livemode + self.nextAction = nextAction + self.orderedPaymentMethodTypes = orderedPaymentMethodTypes + self.paymentMethodID = paymentMethodID + self.paymentMethod = paymentMethod + self.paymentMethodOptions = paymentMethodOptions + self.paymentMethodTypes = paymentMethodTypes + self.status = status + self.usage = usage + self.lastSetupError = lastSetupError + self.allResponseFields = allResponseFields + self.unactivatedPaymentMethodTypes = unactivatedPaymentMethodTypes + super.init() + } + + /// :nodoc: + @objc override public var description: String { + let props = [ + // Object + String(format: "%@: %p", NSStringFromClass(STPSetupIntent.self), self), + // Identifier + "stripeId = \(stripeID)", + // SetupIntent details (alphabetical) + "clientSecret = ", + "created = \(String(describing: created))", + "countryCode = \(String(describing: countryCode))", + "customerId = \(customerID ?? "")", + "description = \(stripeDescription ?? "")", + "lastSetupError = \(String(describing: lastSetupError))", + "linkSettings = \(String(describing: linkSettings))", + "livemode = \(livemode ? "YES" : "NO")", + "nextAction = \(String(describing: nextAction))", + "paymentMethodId = \(paymentMethodID ?? "")", + "paymentMethod = \(String(describing: paymentMethod))", + "paymentMethodOptions = \(String(describing: paymentMethodOptions))", + "paymentMethodTypes = \(allResponseFields.stp_array(forKey: "payment_method_types") ?? [])", + "status = \(allResponseFields.stp_string(forKey: "status") ?? "")", + "usage = \(allResponseFields.stp_string(forKey: "usage") ?? "")", + "unactivatedPaymentMethodTypes = \(allResponseFields.stp_array(forKey: "unactivated_payment_method_types") ?? [])", + ] + + return "<\(props.joined(separator: "; "))>" + } + + // MARK: - STPSetupIntentEnum support + class func status(from string: String) -> STPSetupIntentStatus { + let map = [ + "requires_payment_method": NSNumber( + value: STPSetupIntentStatus.requiresPaymentMethod.rawValue + ), + "requires_confirmation": NSNumber( + value: STPSetupIntentStatus.requiresConfirmation.rawValue + ), + "requires_action": NSNumber(value: STPSetupIntentStatus.requiresAction.rawValue), + "processing": NSNumber(value: STPSetupIntentStatus.processing.rawValue), + "succeeded": NSNumber(value: STPSetupIntentStatus.succeeded.rawValue), + "canceled": NSNumber(value: STPSetupIntentStatus.canceled.rawValue), + ] + + let key = string.lowercased() + let statusNumber = map[key] ?? NSNumber(value: STPSetupIntentStatus.unknown.rawValue) + return (STPSetupIntentStatus(rawValue: statusNumber.intValue))! + } + + class func usage(from string: String) -> STPSetupIntentUsage { + let map = [ + "off_session": NSNumber(value: STPSetupIntentUsage.offSession.rawValue), + "on_session": NSNumber(value: STPSetupIntentUsage.onSession.rawValue), + ] + + let key = string.lowercased() + let statusNumber = map[key] ?? NSNumber(value: STPSetupIntentUsage.unknown.rawValue) + return (STPSetupIntentUsage(rawValue: statusNumber.intValue))! + } + + @objc @_spi(STP) public class func id(fromClientSecret clientSecret: String) -> String? { + // see parseClientSecret from stripe-js-v3 + let components = clientSecret.components(separatedBy: "_secret_") + if components.count >= 2 && components[0].hasPrefix("seti_") { + return components[0] + } else { + return nil + } + } + + // MARK: - STPAPIResponseDecodable + public class func decodedObject(fromAPIResponse response: [AnyHashable: Any]?) -> Self? { + guard let response = response else { + return nil + } + // Consolidates expanded setup_intent and ordered_payment_method_types into singular dict for decoding + if let paymentMethodPrefDict = response["payment_method_preference"] as? [AnyHashable: Any], + let setupIntentDict = paymentMethodPrefDict["setup_intent"] as? [AnyHashable: Any], + let orderedPaymentMethodTypes = paymentMethodPrefDict["ordered_payment_method_types"] + as? [String] + { + var dict = setupIntentDict + dict["ordered_payment_method_types"] = orderedPaymentMethodTypes + dict["unactivated_payment_method_types"] = response["unactivated_payment_method_types"] + dict["link_settings"] = response["link_settings"] + return decodeSTPSetupIntentObject(fromAPIResponse: dict) + } else { + return decodeSTPSetupIntentObject(fromAPIResponse: response) + } + } + + class func decodeSTPSetupIntentObject(fromAPIResponse response: [AnyHashable: Any]?) -> Self? { + guard let response = response else { + return nil + } + let dict = response.stp_dictionaryByRemovingNulls() + + // required fields + guard + let stripeId = dict.stp_string(forKey: "id"), + let clientSecret = dict.stp_string(forKey: "client_secret"), + let rawStatus = dict.stp_string(forKey: "status"), + let created = dict.stp_date(forKey: "created"), + let paymentMethodTypeStrings = dict["payment_method_types"] as? [String], + dict["livemode"] != nil + else { + return nil + } + + let countryCode = dict.stp_string(forKey: "country_code") + let customerID = dict.stp_string(forKey: "customer") + let stripeDescription = dict.stp_string(forKey: "description") + let linkSettings = LinkSettings.decodedObject( + fromAPIResponse: dict["link_settings"] as? [AnyHashable: Any] + ) + let livemode = dict.stp_bool(forKey: "livemode", or: true) + let nextActionDict = dict.stp_dictionary(forKey: "next_action") + let nextAction = STPIntentAction.decodedObject(fromAPIResponse: nextActionDict) + let orderedPaymentMethodTypes = STPPaymentMethod.paymentMethodTypes( + from: dict["ordered_payment_method_types"] as? [String] ?? paymentMethodTypeStrings + ) + let paymentMethod = STPPaymentMethod.decodedObject( + fromAPIResponse: dict["payment_method"] as? [AnyHashable: Any] + ) + let paymentMethodID = paymentMethod?.stripeId ?? dict.stp_string(forKey: "payment_method") + let paymentMethodOptions = STPPaymentMethodOptions.decodedObject( + fromAPIResponse: dict["payment_method_options"] as? [AnyHashable: Any] + ) + let paymentMethodTypes = STPPaymentMethod.types(from: paymentMethodTypeStrings) + let status = self.status(from: rawStatus) + let rawUsage = dict.stp_string(forKey: "usage") + let usage = rawUsage != nil ? self.usage(from: rawUsage ?? "") : .none + let lastSetupError = STPSetupIntentLastSetupError.decodedObject( + fromAPIResponse: dict.stp_dictionary(forKey: "last_setup_error") + ) + let unactivatedPaymentTypes = STPPaymentMethod.paymentMethodTypes( + from: dict["unactivated_payment_method_types"] as? [String] ?? [] + ) + + let setupIntent = self.init( + stripeID: stripeId, + clientSecret: clientSecret, + created: created, + countryCode: countryCode, + customerID: customerID, + stripeDescription: stripeDescription, + linkSettings: linkSettings, + livemode: livemode, + nextAction: nextAction, + orderedPaymentMethodTypes: orderedPaymentMethodTypes, + paymentMethodID: paymentMethodID, + paymentMethod: paymentMethod, + paymentMethodOptions: paymentMethodOptions, + paymentMethodTypes: paymentMethodTypes, + status: status, + usage: usage, + lastSetupError: lastSetupError, + allResponseFields: response, + unactivatedPaymentMethodTypes: unactivatedPaymentTypes + ) + + return setupIntent + } +} diff --git a/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/SetupIntents/STPSetupIntentConfirmParams.swift b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/SetupIntents/STPSetupIntentConfirmParams.swift new file mode 100644 index 0000000..a09fab3 --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/SetupIntents/STPSetupIntentConfirmParams.swift @@ -0,0 +1,173 @@ +// +// STPSetupIntentConfirmParams.swift +// StripePayments +// +// Created by Yuki Tokuhiro on 6/27/19. +// Copyright © 2019 Stripe, Inc. All rights reserved. +// + +import Foundation + +/// An object representing parameters to confirm a SetupIntent object. +/// For example, you would confirm a SetupIntent when a customer hits the “Save” button on a payment method management view in your app. +/// If the selected payment method does not require any additional steps from the customer, the SetupIntent's status will transition to `STPSetupIntentStatusSucceeded`. Otherwise, it will transition to `STPSetupIntentStatusRequiresAction`, and suggest additional actions via `nextAction`. +/// Instead of passing this to `STPAPIClient.confirmSetupIntent(...)` directly, we recommend using `STPPaymentHandler` to handle any additional steps for you. +/// - seealso: https://stripe.com/docs/api/setup_intents/confirm +public class STPSetupIntentConfirmParams: NSObject, NSCopying, STPFormEncodable { + @objc public var additionalAPIParameters: [AnyHashable: Any] = [:] + + /// Initialize this `STPSetupIntentConfirmParams` with a `clientSecret`. + /// - Parameter clientSecret: the client secret for this SetupIntent + @objc + public init( + clientSecret: String + ) { + self.clientSecret = clientSecret + super.init() + additionalAPIParameters = [:] + } + + /// Initialize this `STPSetupIntentConfirmParams` with a `clientSecret` and `paymentMethodType`. + /// Use this initializer for SetupIntents that already have a PaymentMethod attached. + /// - Parameter clientSecret: the client secret for this SetupIntent + /// - Parameter paymentMethodType: the known type of the SetupIntent's attached PaymentMethod + @objc + public init( + clientSecret: String, + paymentMethodType: STPPaymentMethodType + ) { + self.clientSecret = clientSecret + self._paymentMethodType = paymentMethodType + super.init() + additionalAPIParameters = [:] + } + + /// The client secret of the SetupIntent. Required. + @objc public var clientSecret: String + /// Provide a supported `STPPaymentMethodParams` object, and Stripe will create a + /// PaymentMethod during PaymentIntent confirmation. + /// @note alternative to `paymentMethodId` + @objc public var paymentMethodParams: STPPaymentMethodParams? + /// Provide an already created PaymentMethod's id, and it will be used to confirm the SetupIntent. + /// @note alternative to `paymentMethodParams` + @objc public var paymentMethodID: String? + /// The URL to redirect your customer back to after they authenticate or cancel + /// their payment on the payment method’s app or site. + /// This should probably be a URL that opens your iOS app. + @objc public var returnURL: String? + /// A boolean number to indicate whether you intend to use the Stripe SDK's functionality to handle any SetupIntent next actions. + /// If set to false, STPSetupIntent.nextAction will only ever contain a redirect url that can be opened in a webview or mobile browser. + /// When set to true, the nextAction may contain information that the Stripe SDK can use to perform native authentication within your + /// app. + @objc public var useStripeSDK: NSNumber? + /// Details about the Mandate to create. + /// @note If this value is null and the `(self.paymentMethod.type == STPPaymentMethodTypeSEPADebit | | self.paymentMethodParams.type == STPPaymentMethodTypeAUBECSDebit || self.paymentMethodParams.type == STPPaymentMethodTypeBacsDebit) && self.mandate == nil`, the SDK will set this to an internal value indicating that the mandate data should be inferred from the current context. + @objc public var mandateData: STPMandateDataParams? { + set(newMandateData) { + _mandateData = newMandateData + } + get { + if let _mandateData = _mandateData { + return _mandateData + } + switch paymentMethodType { + case .AUBECSDebit, .bacsDebit, .bancontact, .iDEAL, .SEPADebit, .EPS, .sofort, .link, + .USBankAccount: + // Create default infer from client mandate_data + let onlineParams = STPMandateOnlineParams(ipAddress: "", userAgent: "") + onlineParams.inferFromClient = NSNumber(value: true) + + if let customerAcceptance = STPMandateCustomerAcceptanceParams( + type: .online, + onlineParams: onlineParams + ) { + return STPMandateDataParams(customerAcceptance: customerAcceptance) + } + default: break + } + return nil + } + } + private var _mandateData: STPMandateDataParams? + + internal var _paymentMethodType: STPPaymentMethodType? + internal var paymentMethodType: STPPaymentMethodType? { + if let type = _paymentMethodType { + return type + } + return paymentMethodParams?.type + } + + override convenience init() { + // Not a valid clientSecret, but at least it'll be non-null + self.init(clientSecret: "") + } + + /// :nodoc: + @objc public override var description: String { + let props = [ + // Object + String(format: "%@: %p", NSStringFromClass(STPSetupIntentConfirmParams.self), self), + // SetupIntentParams details (alphabetical) + "clientSecret = \(((clientSecret.count) > 0) ? "" : "")", + "returnURL = \(returnURL ?? "")", + "paymentMethodId = \(paymentMethodID ?? "")", + "paymentMethodParams = \(String(describing: paymentMethodParams))", + "useStripeSDK = \(useStripeSDK ?? 0)", + // Mandate + "mandateData = \(String(describing: mandateData))", + // Additional params set by app + "additionalAPIParameters = \(additionalAPIParameters )", + ] + + return "<\(props.joined(separator: "; "))>" + } + + // MARK: - NSCopying + /// :nodoc: + @objc + public func copy(with zone: NSZone? = nil) -> Any { + let copy = STPSetupIntentConfirmParams() + + copy.clientSecret = clientSecret + copy._paymentMethodType = _paymentMethodType + copy.paymentMethodParams = paymentMethodParams + copy.paymentMethodID = paymentMethodID + copy.returnURL = returnURL + copy.useStripeSDK = useStripeSDK + copy.mandateData = mandateData + copy.additionalAPIParameters = additionalAPIParameters + + return copy + } + + // MARK: - STPFormEncodable + public class func rootObjectName() -> String? { + return nil + } + + public class func propertyNamesToFormFieldNamesMapping() -> [String: String] { + return [ + NSStringFromSelector(#selector(getter:clientSecret)): "client_secret", + NSStringFromSelector(#selector(getter:paymentMethodParams)): "payment_method_data", + NSStringFromSelector(#selector(getter:paymentMethodID)): "payment_method", + NSStringFromSelector(#selector(getter:returnURL)): "return_url", + NSStringFromSelector(#selector(getter:useStripeSDK)): "use_stripe_sdk", + NSStringFromSelector(#selector(getter:mandateData)): "mandate_data", + ] + } + + // MARK: - Utilities + static private let regex = try! NSRegularExpression( + pattern: "^seti_[^_]+_secret_[^_]+$", + options: [] + ) + @_spi(STP) public static func isClientSecretValid(_ clientSecret: String) -> Bool { + return + (regex.numberOfMatches( + in: clientSecret, + options: .anchored, + range: NSRange(location: 0, length: clientSecret.count) + )) == 1 + } +} diff --git a/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/SetupIntents/STPSetupIntentEnums.swift b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/SetupIntents/STPSetupIntentEnums.swift new file mode 100644 index 0000000..012fd06 --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/SetupIntents/STPSetupIntentEnums.swift @@ -0,0 +1,41 @@ +// +// STPSetupIntentEnums.swift +// StripePayments +// +// Created by Yuki Tokuhiro on 6/27/19. +// Copyright © 2019 Stripe, Inc. All rights reserved. +// + +import Foundation + +/// Status types for an STPSetupIntent +@objc public enum STPSetupIntentStatus: Int { + /// Unknown status + case unknown + /// This SetupIntent requires a PaymentMethod + case requiresPaymentMethod + /// This SetupIntent needs to be confirmed + case requiresConfirmation + /// The selected PaymentMethod requires additional authentication steps. + /// Additional actions found via the `nextAction` property of `STPSetupIntent` + case requiresAction + /// Stripe is processing this SetupIntent + case processing + /// The SetupIntent has succeeded + case succeeded + /// This SetupIntent was canceled and cannot be changed. + case canceled +} + +/// Indicates how the payment method is intended to be used in the future. +/// - seealso: https://stripe.com/docs/api/setup_intents/create#create_setup_intent-usage +@objc public enum STPSetupIntentUsage: Int { + /// Unknown value. Update your SDK, or use `allResponseFields` for custom handling. + case unknown + /// No value was provided. + case none + /// Indicates you intend to only reuse the payment method when the customer is in your checkout flow. + case onSession + /// Indicates you intend to reuse the payment method when the customer may or may not be in your checkout flow. + case offSession +} diff --git a/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/SetupIntents/STPSetupIntentLastSetupError.swift b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/SetupIntents/STPSetupIntentLastSetupError.swift new file mode 100644 index 0000000..61fabec --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/SetupIntents/STPSetupIntentLastSetupError.swift @@ -0,0 +1,140 @@ +// +// STPSetupIntentLastSetupError.swift +// StripePayments +// +// Created by Yuki Tokuhiro on 8/9/19. +// Copyright © 2019 Stripe, Inc. All rights reserved. +// + +import Foundation + +/// The type of the error represented by `STPSetupIntentLastSetupError`. +/// Some STPSetupIntentLastError properties are only populated for certain error types. +@objc +public enum STPSetupIntentLastSetupErrorType: UInt { + /// An unknown error type. + case unknown + /// An error connecting to Stripe's API. + @objc(STPSetupIntentLastSetupErrorTypeAPIConnection) + case apiConnection + /// An error with the Stripe API. + case API + /// A failure to authenticate your customer. + case authentication + /// Card errors are the most common type of error you should expect to handle. + /// They result when the user enters a card that can't be charged for some reason. + /// Check the `declineCode` property for the decline code. The `message` property contains a message you can show to your users. + case card + /// Keys for idempotent requests can only be used with the same parameters they were first used with. + case idempotency + /// Invalid request errors. Typically, this is because your request has invalid parameters. + case invalidRequest + /// Too many requests hit the API too quickly. + case rateLimit +} + +// MARK: - Error Codes + +/// A value for `code` indicating the provided payment method failed authentication./// The error encountered in the previous SetupIntent confirmation. +/// - seealso: https://stripe.com/docs/api/setup_intents/object#setup_intent_object-last_setup_error +public class STPSetupIntentLastSetupError: NSObject, STPAPIResponseDecodable { + /// For some errors that could be handled programmatically, a short string indicating the error code reported. + /// - seealso: https://stripe.com/docs/error-codes + @objc public private(set) var code: String? + /// For card (`STPSetupIntentLastSetupErrorTypeCard`) errors resulting from a card issuer decline, + /// a short string indicating the card issuer’s reason for the decline if they provide one. + /// - seealso: https://stripe.com/docs/declines#issuer-declines + @objc public private(set) var declineCode: String? + /// A URL to more information about the error code reported. + /// - seealso: https://stripe.com/docs/error-codes + @objc public private(set) var docURL: String? + /// A human-readable message providing more details about the error. + /// For card (`STPSetupIntentLastSetupErrorTypeCard`) errors, these messages can be shown to your users. + @objc public private(set) var message: String? + /// If the error is parameter-specific, the parameter related to the error. + /// For example, you can use this to display a message near the correct form field. + @objc public private(set) var param: String? + /// The PaymentMethod object for errors returned on a request involving a PaymentMethod. + @objc public private(set) var paymentMethod: STPPaymentMethod? + /// The type of error. + @objc public private(set) var type: STPSetupIntentLastSetupErrorType = .unknown + @objc public private(set) var allResponseFields: [AnyHashable: Any] = [:] + + /// :nodoc: + @objc public override var description: String { + let props = [ + // Object + String(format: "%@: %p", NSStringFromClass(STPSetupIntentLastSetupError.self), self), + // SetupIntentLastError details (alphabetical) + "code = \(code ?? "")", + "declineCode = \(declineCode ?? "")", + "docURL = \(docURL ?? "")", + "message = \(message ?? "")", + "param = \(param ?? "")", + "paymentMethod = \(String(describing: paymentMethod))", + "type = \(String(describing: allResponseFields["type"]))", + ] + + return "<\(props.joined(separator: "; "))>" + } + + @objc(typeFromString:) + class func type(from string: String) -> STPSetupIntentLastSetupErrorType { + let map = [ + "api_connection_error": NSNumber( + value: STPSetupIntentLastSetupErrorType.apiConnection.rawValue + ), + "api_error": NSNumber(value: STPSetupIntentLastSetupErrorType.API.rawValue), + "authentication_error": NSNumber( + value: STPSetupIntentLastSetupErrorType.authentication.rawValue + ), + "card_error": NSNumber(value: STPSetupIntentLastSetupErrorType.card.rawValue), + "idempotency_error": NSNumber( + value: STPSetupIntentLastSetupErrorType.idempotency.rawValue + ), + "invalid_request_error": NSNumber( + value: STPSetupIntentLastSetupErrorType.invalidRequest.rawValue + ), + "rate_limit_error": NSNumber( + value: STPSetupIntentLastSetupErrorType.rateLimit.rawValue + ), + ] + + let key = string.lowercased() + let statusNumber = + map[key] ?? NSNumber(value: STPSetupIntentLastSetupErrorType.unknown.rawValue) + return (STPSetupIntentLastSetupErrorType(rawValue: UInt(statusNumber.intValue)))! + } + + // MARK: - STPAPIResponseDecodable + override required init() { + super.init() + } + + public class func decodedObject(fromAPIResponse response: [AnyHashable: Any]?) -> Self? { + guard let response = response else { + return nil + } + let dict = response.stp_dictionaryByRemovingNulls() + let lastError = self.init() + lastError.code = dict.stp_string(forKey: "code") + lastError.declineCode = dict.stp_string(forKey: "decline_code") + lastError.docURL = dict.stp_string(forKey: "doc_url") + lastError.message = dict.stp_string(forKey: "message") + lastError.param = dict.stp_string(forKey: "param") + lastError.paymentMethod = STPPaymentMethod.decodedObject( + fromAPIResponse: dict.stp_dictionary(forKey: "payment_method") + ) + lastError.type = self.type(from: dict.stp_string(forKey: "type") ?? "") + lastError.allResponseFields = response + + return lastError + } +} + +// MARK: - `code` string values + +@objc extension STPSetupIntentLastSetupError { + /// A possible value for the `error` property. The provided payment method has failed authentication. Provide a new payment method to attempt to fulfill this SetupIntent again. + public static let CodeAuthenticationFailure = "setup_intent_authentication_failure" +} diff --git a/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/Shared/LinkSettings.swift b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/Shared/LinkSettings.swift new file mode 100644 index 0000000..e6375ef --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/Shared/LinkSettings.swift @@ -0,0 +1,50 @@ +// +// LinkSettings.swift +// StripePayments +// +// Created by Ramon Torres on 4/20/22. +// Copyright © 2022 Stripe, Inc. All rights reserved. +// + +import Foundation + +/// For internal SDK use only +@objc(STP_Internal_LinkSettings) +@_spi(STP) public final class LinkSettings: NSObject, STPAPIResponseDecodable { + @_spi(STP) @frozen public enum FundingSource: String { + case card = "CARD" + case bankAccount = "BANK_ACCOUNT" + } + + @_spi(STP) public let fundingSources: Set + + @_spi(STP) public let allResponseFields: [AnyHashable: Any] + + @_spi(STP) public init( + fundingSources: Set, + allResponseFields: [AnyHashable: Any] + ) { + self.fundingSources = fundingSources + self.allResponseFields = allResponseFields + } + + @_spi(STP) public static func decodedObject( + fromAPIResponse response: [AnyHashable: Any]? + ) -> Self? { + guard + let response = response, + let fundingSourcesStrings = response["link_funding_sources"] as? [String] + else { + return nil + } + + // Server may send down funding sources we haven't implemented yet, so we'll just ignore any unknown sources + let validFundingSources = Set(fundingSourcesStrings.compactMap(FundingSource.init)) + + return LinkSettings( + fundingSources: validFundingSources, + allResponseFields: response + ) as? Self + } + +} diff --git a/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/Shared/STPIntentAction.swift b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/Shared/STPIntentAction.swift new file mode 100644 index 0000000..ace1447 --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/Shared/STPIntentAction.swift @@ -0,0 +1,333 @@ +// +// STPIntentAction.swift +// StripePayments +// +// Created by Yuki Tokuhiro on 6/27/19. +// Copyright © 2019 Stripe, Inc. All rights reserved. +// + +// +// STPIntentNextAction.m +// Stripe +// +// Created by Yuki Tokuhiro on 6/27/19. +// Copyright © 2019 Stripe, Inc. All rights reserved. +// + +import Foundation + +/// Types of next actions for `STPPaymentIntent` and `STPSetupIntent`. +/// You shouldn't need to inspect this yourself; `STPPaymentHandler` will handle any next actions for you. +@objc public enum STPIntentActionType: Int { + + /// This is an unknown action that's been added since the SDK + /// was last updated. + /// Update your SDK, or use the `nextAction.allResponseFields` + /// for custom handling. + case unknown + + /// The payment intent needs to be authorized by the user. We provide + /// `STPPaymentHandler` to handle the url redirections necessary. + case redirectToURL + + /// The payment intent requires additional action handled by `STPPaymentHandler`. + case useStripeSDK + + /// The action type is OXXO payment. We provide `STPPaymentHandler` to display + /// the OXXO voucher. + case OXXODisplayDetails + + /// Contains instructions for authenticating a payment by redirecting your customer to Alipay App or website. + case alipayHandleRedirect + + /// The action type for BLIK payment methods. The customer must authorize the transaction in their banking app within 1 minute. + case BLIKAuthorize + + /// Contains instructions for authenticating a payment by redirecting your customer to the WeChat Pay App. + case weChatPayRedirectToApp + + /// The action type is Boleto payment. We provide `STPPaymentHandler` to display the Boleto voucher. + case boletoDisplayDetails + + /// Contains details describing the microdeposits verification flow for US Bank Account payments + case verifyWithMicrodeposits + + /// The action type for UPI payment methods. The customer must complete the transaction in their banking app within 5 minutes. + case upiAwaitNotification + + /// Parse the string and return the correct `STPIntentActionType`, + /// or `STPIntentActionTypeUnknown` if it's unrecognized by this version of the SDK. + /// - Parameter string: the NSString with the `next_action.type` + internal init( + string: String + ) { + switch string.lowercased() { + case "redirect_to_url": + self = .redirectToURL + case "use_stripe_sdk": + self = .useStripeSDK + case "oxxo_display_details": + self = .OXXODisplayDetails + case "alipay_handle_redirect": + self = .alipayHandleRedirect + case "wechat_pay_redirect_to_ios_app": + self = .weChatPayRedirectToApp + case "boleto_display_details": + self = .boletoDisplayDetails + case "blik_authorize": + self = .BLIKAuthorize + case "verify_with_microdeposits": + self = .verifyWithMicrodeposits + case "upi_await_notification": + self = .upiAwaitNotification + default: + self = .unknown + } + } + + /// Return the string representing the provided `STPIntentActionType`. + /// - Parameter actionType: the enum value to convert to a string + /// - Returns: the string, or @"unknown" if this was an unrecognized type + internal var stringValue: String { + switch self { + case .redirectToURL: + return "redirect_to_url" + case .useStripeSDK: + return "use_stripe_sdk" + case .OXXODisplayDetails: + return "oxxo_display_details" + case .alipayHandleRedirect: + return "alipay_handle_redirect" + case .BLIKAuthorize: + return "blik_authorize" + case .weChatPayRedirectToApp: + return "wechat_pay_redirect_to_ios_app" + case .boletoDisplayDetails: + return "boleto_display_details" + case .verifyWithMicrodeposits: + return "verify_with_microdeposits" + case .upiAwaitNotification: + return "upi_await_notification" + case .unknown: + break + } + + // catch any unknown values here + return "unknown" + } +} + +/// Next action details for `STPPaymentIntent` and `STPSetupIntent`. +/// This is a container for the various types that are available. +/// Check the `type` to see which one it is, and then use the related +/// property for the details necessary to handle it. +/// You cannot directly instantiate an `STPIntentAction`. +public class STPIntentAction: NSObject { + + /// The type of action needed. The value of this field determines which + /// property of this object contains further details about the action. + @objc public let type: STPIntentActionType + + /// The details for authorizing via URL, when `type == .redirectToURL` + @objc public let redirectToURL: STPIntentActionRedirectToURL? + + /// The details for displaying OXXO voucher via URL, when `type == .OXXODisplayDetails` + @objc public let oxxoDisplayDetails: STPIntentActionOXXODisplayDetails? + + /// Contains instructions for authenticating a payment by redirecting your customer to Alipay App or website. + @objc public let alipayHandleRedirect: STPIntentActionAlipayHandleRedirect? + + /// Contains instructions for authenticating a payment by redirecting your customer to the WeChat Pay app. + @objc public let weChatPayRedirectToApp: STPIntentActionWechatPayRedirectToApp? + + /// The details for displaying Boleto voucher via URL, when `type == .boleto` + @objc public let boletoDisplayDetails: STPIntentActionBoletoDisplayDetails? + + /// Contains details describing microdeposits verification flow for US bank accounts + @objc public let verifyWithMicrodeposits: STPIntentActionVerifyWithMicrodeposits? + + internal let useStripeSDK: STPIntentActionUseStripeSDK? + + /// :nodoc: + @objc public let allResponseFields: [AnyHashable: Any] + + /// :nodoc: + @objc public override var description: String { + var props = [ + // Object + String(format: "%@: %p", NSStringFromClass(STPIntentAction.self), self), + // Type + "type = \(type.stringValue)", + ] + + // omit properties that don't apply to this type + switch type { + case .redirectToURL: + if let redirectToURL = redirectToURL { + props.append("redirectToURL = \(redirectToURL)") + } + case .useStripeSDK: + if let useStripeSDK = useStripeSDK { + props.append("useStripeSDK = \(useStripeSDK)") + } + case .OXXODisplayDetails: + if let oxxoDisplayDetails = oxxoDisplayDetails { + props.append("oxxoDisplayDetails = \(oxxoDisplayDetails)") + } + case .alipayHandleRedirect: + if let alipayHandleRedirect = alipayHandleRedirect { + props.append("alipayHandleRedirect = \(alipayHandleRedirect)") + } + case .weChatPayRedirectToApp: + if let weChatPayRedirectToApp = weChatPayRedirectToApp { + props.append("weChatPayRedirectToApp = \(weChatPayRedirectToApp)") + } + case .boletoDisplayDetails: + if let boletoDisplayDetails = boletoDisplayDetails { + props.append("boletoDisplayDetails = \(boletoDisplayDetails)") + } + case .BLIKAuthorize: + break // no additional details + case .verifyWithMicrodeposits: + if let verifyWithMicrodeposits = verifyWithMicrodeposits { + props.append("verifyWithMicrodeposits = \(verifyWithMicrodeposits)") + } + case .upiAwaitNotification: + props.append("upiAwaitNotification != nil") + case .unknown: + // unrecognized type, just show the original dictionary for debugging help + props.append("allResponseFields = \(allResponseFields)") + } + + return "<\(props.joined(separator: "; "))>" + } + + internal init( + type: STPIntentActionType, + redirectToURL: STPIntentActionRedirectToURL?, + alipayHandleRedirect: STPIntentActionAlipayHandleRedirect?, + useStripeSDK: STPIntentActionUseStripeSDK?, + oxxoDisplayDetails: STPIntentActionOXXODisplayDetails?, + weChatPayRedirectToApp: STPIntentActionWechatPayRedirectToApp?, + boletoDisplayDetails: STPIntentActionBoletoDisplayDetails?, + verifyWithMicrodeposits: STPIntentActionVerifyWithMicrodeposits?, + allResponseFields: [AnyHashable: Any] + ) { + self.type = type + self.redirectToURL = redirectToURL + self.alipayHandleRedirect = alipayHandleRedirect + self.useStripeSDK = useStripeSDK + self.oxxoDisplayDetails = oxxoDisplayDetails + self.weChatPayRedirectToApp = weChatPayRedirectToApp + self.boletoDisplayDetails = boletoDisplayDetails + self.verifyWithMicrodeposits = verifyWithMicrodeposits + self.allResponseFields = allResponseFields + super.init() + } +} + +// MARK: - STPAPIResponseDecodable +extension STPIntentAction: STPAPIResponseDecodable { + + @objc + public class func decodedObject(fromAPIResponse response: [AnyHashable: Any]?) -> Self? { + guard let dict = response, + let rawType = dict["type"] as? String + else { + return nil + } + + // Only set the type to a recognized value if we *also* have the expected sub-details. + // ex: If the server said it was `.redirectToURL`, but decoding the + // STPIntentActionRedirectToURL object fails, map type to `.unknown` + var type = STPIntentActionType(string: rawType) + var redirectToURL: STPIntentActionRedirectToURL? + var alipayHandleRedirect: STPIntentActionAlipayHandleRedirect? + var useStripeSDK: STPIntentActionUseStripeSDK? + var oxxoDisplayDetails: STPIntentActionOXXODisplayDetails? + var boletoDisplayDetails: STPIntentActionBoletoDisplayDetails? + var weChatPayRedirectToApp: STPIntentActionWechatPayRedirectToApp? + var verifyWithMicrodeposits: STPIntentActionVerifyWithMicrodeposits? + + switch type { + case .unknown: + break + case .redirectToURL: + redirectToURL = STPIntentActionRedirectToURL.decodedObject( + fromAPIResponse: dict["redirect_to_url"] as? [AnyHashable: Any] + ) + if redirectToURL == nil { + type = .unknown + } + case .useStripeSDK: + useStripeSDK = STPIntentActionUseStripeSDK.decodedObject( + fromAPIResponse: dict["use_stripe_sdk"] as? [AnyHashable: Any] + ) + if useStripeSDK == nil { + type = .unknown + } + case .OXXODisplayDetails: + oxxoDisplayDetails = STPIntentActionOXXODisplayDetails.decodedObject( + fromAPIResponse: dict["oxxo_display_details"] as? [AnyHashable: Any] + ) + if oxxoDisplayDetails == nil { + type = .unknown + } + case .alipayHandleRedirect: + alipayHandleRedirect = STPIntentActionAlipayHandleRedirect.decodedObject( + fromAPIResponse: dict["alipay_handle_redirect"] as? [AnyHashable: Any] + ) + if alipayHandleRedirect == nil { + type = .unknown + } + case .weChatPayRedirectToApp: + weChatPayRedirectToApp = STPIntentActionWechatPayRedirectToApp.decodedObject( + fromAPIResponse: dict["wechat_pay_redirect_to_ios_app"] as? [AnyHashable: Any] + ) + if weChatPayRedirectToApp == nil { + type = .unknown + } + case .boletoDisplayDetails: + boletoDisplayDetails = STPIntentActionBoletoDisplayDetails.decodedObject( + fromAPIResponse: dict["boleto_display_details"] as? [AnyHashable: Any] + ) + if boletoDisplayDetails == nil { + type = .unknown + } + case .BLIKAuthorize: + break // no additional details + case .verifyWithMicrodeposits: + verifyWithMicrodeposits = STPIntentActionVerifyWithMicrodeposits.decodedObject( + fromAPIResponse: dict["verify_with_microdeposits"] as? [AnyHashable: Any] + ) + if verifyWithMicrodeposits == nil { + type = .unknown + } + case .upiAwaitNotification: + break // no additional details + } + + return STPIntentAction( + type: type, + redirectToURL: redirectToURL, + alipayHandleRedirect: alipayHandleRedirect, + useStripeSDK: useStripeSDK, + oxxoDisplayDetails: oxxoDisplayDetails, + weChatPayRedirectToApp: weChatPayRedirectToApp, + boletoDisplayDetails: boletoDisplayDetails, + verifyWithMicrodeposits: verifyWithMicrodeposits, + allResponseFields: dict + ) as? Self + } + +} + +// MARK: - Deprecated +extension STPIntentAction { + /// The details for authorizing via URL, when `type == STPIntentActionTypeRedirectToURL` + /// @deprecated Use `redirectToURL` instead. + @available(*, deprecated, message: "Use `redirectToURL` instead.", renamed: "redirectToURL") + @objc public var authorizeWithURL: STPIntentActionRedirectToURL? { + return redirectToURL + } +} diff --git a/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/Shared/STPIntentActionAlipayHandleRedirect.swift b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/Shared/STPIntentActionAlipayHandleRedirect.swift new file mode 100644 index 0000000..4dace45 --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/Shared/STPIntentActionAlipayHandleRedirect.swift @@ -0,0 +1,126 @@ +// +// STPIntentActionAlipayHandleRedirect.swift +// StripePayments +// +// Created by Yuki Tokuhiro on 8/3/20. +// Copyright © 2020 Stripe, Inc. All rights reserved. +// + +import Foundation + +/// Contains instructions for authenticating a payment by redirecting your customer to Alipay App or website. +/// You cannot directly instantiate an `STPPaymentIntentActionAlipayHandleRedirect`. +public class STPIntentActionAlipayHandleRedirect: NSObject { + + /// The native URL you must redirect your customer to in order to authenticate the payment. + @objc public let nativeURL: URL? + + /// If the customer does not exit their browser while authenticating, they will be redirected to this specified URL after completion. + @objc public let returnURL: URL + + /// The URL you must redirect your customer to in order to authenticate the payment. + @objc public let url: URL + + /// :nodoc: + @objc public let allResponseFields: [AnyHashable: Any] + + /// :nodoc: + @objc public override var description: String { + let props: [String] = [ + // Object + String( + format: "%@: %p", + NSStringFromClass(STPIntentActionAlipayHandleRedirect.self), + self + ), + // RedirectToURL details (alphabetical) + "nativeURL = \(String(describing: nativeURL))", + "url = \(url)", + "returnURL = \(returnURL)", + ] + + return "<\(props.joined(separator: "; "))>" + } + + internal init( + nativeURL: URL?, + url: URL, + returnURL: URL, + allResponseFields: [AnyHashable: Any] + ) { + self.nativeURL = nativeURL + self.url = url + self.returnURL = returnURL + self.allResponseFields = allResponseFields + super.init() + } +} + +// MARK: - STPAPIResponseDecodable +extension STPIntentActionAlipayHandleRedirect: STPAPIResponseDecodable { + + @objc + public class func decodedObject(fromAPIResponse response: [AnyHashable: Any]?) -> Self? { + guard let dict = response, + let urlString = dict["url"] as? String, + let url = URL(string: urlString), + let returnURLString = dict["return_url"] as? String, + let returnURL = URL(string: returnURLString) + else { + return nil + } + + let nativeURL: URL? + if let nativeURLString = dict["native_url"] as? String { + nativeURL = URL(string: nativeURLString) + } else { + nativeURL = nil + } + + return STPIntentActionAlipayHandleRedirect( + nativeURL: nativeURL, + url: url, + returnURL: returnURL, + allResponseFields: dict + ) as? Self + } + +} + +// MARK: - Internal +extension STPIntentActionAlipayHandleRedirect { + /// Returns a special url embedded in the native URL that looks like "https://hooks.stripe.com/..." + var marlinReturnURL: URL? { + guard + let escapedNativeURL = nativeURL?.absoluteString.removingPercentEncoding, + let regex = try? NSRegularExpression(pattern: "return_url=([^&]*)", options: []) + else { + return nil + } + var marlinReturnURL: String? + let range = NSRange( + escapedNativeURL.startIndex.." + } + + // MARK: - STPAPIResponseDecodable + + required init?(dictionary: [AnyHashable: Any]) { + guard let number = dictionary.stp_string(forKey: "number"), + let expiresAt = dictionary.stp_date(forKey: "expires_at"), + let hostedVoucherURL = dictionary.stp_url(forKey: "hosted_voucher_url") + else { + return nil + } + + self.number = number + self.expiresAt = expiresAt + self.hostedVoucherURL = hostedVoucherURL + self.allResponseFields = dictionary + + super.init() + } + + public static func decodedObject(fromAPIResponse response: [AnyHashable: Any]?) -> Self? { + guard let response = response else { + return nil + } + + return self.init(dictionary: response) + } +} diff --git a/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/Shared/STPIntentActionOXXODisplayDetails.swift b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/Shared/STPIntentActionOXXODisplayDetails.swift new file mode 100644 index 0000000..ed8b30e --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/Shared/STPIntentActionOXXODisplayDetails.swift @@ -0,0 +1,71 @@ +// +// STPIntentActionOXXODisplayDetails.swift +// StripePayments +// +// Created by Polo Li on 6/23/20. +// Copyright © 2020 Stripe, Inc. All rights reserved. +// + +import Foundation + +/// Contains OXXO details necessary for the customer to complete the payment. +public class STPIntentActionOXXODisplayDetails: NSObject, STPAPIResponseDecodable { + /// The timestamp after which the OXXO voucher expires. + @objc public let expiresAfter: Date + + /// The URL for the hosted OXXO voucher page, which allows customers to view and print an OXXO voucher. + @objc public let hostedVoucherURL: URL + + /// OXXO reference number. + @objc public let number: String + + internal init( + expiresAfter: Date, + hostedVoucherURL: URL, + number: String, + allResponseFields: [AnyHashable: Any] + ) { + self.expiresAfter = expiresAfter + self.hostedVoucherURL = hostedVoucherURL + self.number = number + self.allResponseFields = allResponseFields + super.init() + } + + /// :nodoc: + @objc public override var description: String { + let props: [String] = [ + // Object + String( + format: "%@: %p", + NSStringFromClass(STPIntentActionOXXODisplayDetails.self), + self + ), + // OXXODisplayDetails + "expiresAfter = \(String(describing: expiresAfter))", + "hostedVoucherURL = \(String(describing: hostedVoucherURL))", + "number = \(String(describing: number))", + ] + + return "<\(props.joined(separator: "; "))>" + } + + public static func decodedObject(fromAPIResponse response: [AnyHashable: Any]?) -> Self? { + guard let dict = response, + let expiresAfter = dict.stp_date(forKey: "expires_after"), + let hostedVoucherURL = dict.stp_url(forKey: "hosted_voucher_url"), + let number = dict.stp_string(forKey: "number") + else { + return nil + } + + return STPIntentActionOXXODisplayDetails( + expiresAfter: expiresAfter, + hostedVoucherURL: hostedVoucherURL, + number: number, + allResponseFields: dict + ) as? Self + } + + public private(set) var allResponseFields: [AnyHashable: Any] +} diff --git a/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/Shared/STPIntentActionRedirectToURL.swift b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/Shared/STPIntentActionRedirectToURL.swift new file mode 100644 index 0000000..202e3e9 --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/Shared/STPIntentActionRedirectToURL.swift @@ -0,0 +1,79 @@ +// +// STPIntentActionRedirectToURL.swift +// StripePayments +// +// Created by Yuki Tokuhiro on 6/27/19. +// Copyright © 2019 Stripe, Inc. All rights reserved. +// + +import Foundation + +/// Contains instructions for authenticating a payment by redirecting your customer to another page or application. +/// You cannot directly instantiate an `STPIntentActionRedirectToURL`. +/// - seealso: https://stripe.com/docs/api/payment_intents/object#payment_intent_object-next_action +public class STPIntentActionRedirectToURL: NSObject { + + /// The URL you must redirect your customer to in order to authenticate the payment. + @objc public let url: URL + /// The return URL that'll be redirected back to when the user is done + /// authenticating. + @objc public let returnURL: URL? + + @objc public let allResponseFields: [AnyHashable: Any] + + let threeDSSourceID: String? + + /// :nodoc: + @objc public override var description: String { + let props: [String] = [ + // Object + String(format: "%@: %p", NSStringFromClass(STPIntentActionRedirectToURL.self), self), + // RedirectToURL details (alphabetical) + "returnURL = \(String(describing: returnURL))", + "url = \(url)", + ] + + return "<\(props.joined(separator: "; "))>" + } + + init( + url: URL, + returnURL: URL?, + threeDSSourceID: String?, + allResponseFields: [AnyHashable: Any] + ) { + self.url = url + self.returnURL = returnURL + self.threeDSSourceID = threeDSSourceID + self.allResponseFields = allResponseFields + super.init() + } + +} + +// MARK: - STPAPIResponseDecodable +extension STPIntentActionRedirectToURL: STPAPIResponseDecodable { + @objc + public class func decodedObject(fromAPIResponse response: [AnyHashable: Any]?) -> Self? { + guard let dict = response, + let urlString = dict["url"] as? String, + let url = URL(string: urlString) + else { + return nil + } + + let returnURL: URL? + if let returnURLString = dict["return_url"] as? String { + returnURL = URL(string: returnURLString) + } else { + returnURL = nil + } + + return STPIntentActionRedirectToURL( + url: url, + returnURL: returnURL, + threeDSSourceID: url.lastPathComponent.hasPrefix("src_") ? url.lastPathComponent : nil, + allResponseFields: dict + ) as? Self + } +} diff --git a/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/Shared/STPIntentActionVerifyWithMicrodeposits.swift b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/Shared/STPIntentActionVerifyWithMicrodeposits.swift new file mode 100644 index 0000000..5b5ce40 --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/Shared/STPIntentActionVerifyWithMicrodeposits.swift @@ -0,0 +1,88 @@ +// +// STPIntentActionVerifyWithMicrodeposits.swift +// StripePayments +// +// Created by Cameron Sabol on 2/23/22. +// Copyright © 2022 Stripe, Inc. All rights reserved. +// + +import UIKit + +@objc public enum STPMicrodepositType: Int { + + /// This is an unknown type that's been added since the SDK + /// was last updated. + /// Update your SDK, or use the `allResponseFields` + /// for custom handling. + case unknown + + /// Two non-unique micro-deposits to the customer's bank account + case amounts + + /// A single micro-deposit sent to the customer's bank account with a unique descriptor code + case descriptorCode + + internal init( + string: String + ) { + switch string.lowercased() { + case "amounts": + self = .amounts + case "descriptor_code": + self = .descriptorCode + default: + self = .unknown + } + } +} + +/// Contains details describing microdeposits verification flow for US Bank Accounts. +public class STPIntentActionVerifyWithMicrodeposits: NSObject { + + /// The timestamp when the microdeposits are expected to land + @objc public let arrivalDate: Date + + /// The URL for the hosted verification page, which allows customers to verify their bank account + @objc public let hostedVerificationURL: URL + + /// The type of the microdeposit sent to the customer. Used to distinguish between different verificaion methods. + @objc public let microdepositType: STPMicrodepositType + + /// :nodoc: + @objc public let allResponseFields: [AnyHashable: Any] + + internal init( + arrivalDate: Date, + hostedVerificationURL: URL, + microdepositType: STPMicrodepositType, + allResponseFields: [AnyHashable: Any] + ) { + self.arrivalDate = arrivalDate + self.hostedVerificationURL = hostedVerificationURL + self.microdepositType = microdepositType + self.allResponseFields = allResponseFields + super.init() + } +} + +// MARK: - STPAPIResponseDecodable +/// :nodoc: +extension STPIntentActionVerifyWithMicrodeposits: STPAPIResponseDecodable { + public static func decodedObject(fromAPIResponse response: [AnyHashable : Any]?) -> Self? { + guard let response = response, + let arrivalDate = response.stp_date(forKey: "arrival_date"), + let hostedVerificationURL = response.stp_url(forKey: "hosted_verification_url"), + let microdepositTypeString = response.stp_string(forKey: "microdeposit_type") + else { + return nil + } + + return STPIntentActionVerifyWithMicrodeposits( + arrivalDate: arrivalDate, + hostedVerificationURL: hostedVerificationURL, + microdepositType: STPMicrodepositType(string: microdepositTypeString), + allResponseFields: response + ) as? Self + } + +} diff --git a/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/Shared/STPIntentActionWeChatPayRedirectToApp.swift b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/Shared/STPIntentActionWeChatPayRedirectToApp.swift new file mode 100644 index 0000000..c9055f7 --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/Shared/STPIntentActionWeChatPayRedirectToApp.swift @@ -0,0 +1,64 @@ +// +// STPIntentActionWeChatPayRedirectToApp.swift +// StripePayments +// +// Copyright © 2021 Stripe, Inc. All rights reserved. +// + +import Foundation + +/// Contains instructions for authenticating a payment by redirecting your customer to WeChat Pay app. +/// You cannot directly instantiate an `STPIntentActionWechatPayRedirectToApp`. +public class STPIntentActionWechatPayRedirectToApp: NSObject { + + /// The native URL you must redirect your customer to in order to authenticate the payment. + @objc public let nativeURL: URL? + + /// :nodoc: + @objc public let allResponseFields: [AnyHashable: Any] + + /// :nodoc: + @objc public override var description: String { + let props: [String] = [ + // Object + String( + format: "%@: %p", + NSStringFromClass(STPIntentActionAlipayHandleRedirect.self), + self + ), + // RedirectToURL details (alphabetical) + "nativeURL = \(String(describing: nativeURL))", + ] + + return "<\(props.joined(separator: "; "))>" + } + + internal init( + nativeURL: URL, + allResponseFields: [AnyHashable: Any] + ) { + self.nativeURL = nativeURL + self.allResponseFields = allResponseFields + super.init() + } +} + +// MARK: - STPAPIResponseDecodable +extension STPIntentActionWechatPayRedirectToApp: STPAPIResponseDecodable { + + @objc + public class func decodedObject(fromAPIResponse response: [AnyHashable: Any]?) -> Self? { + guard let dict = response, + let nativeURLString = dict["native_url"] as? String, + let nativeURL = URL(string: nativeURLString) + else { + return nil + } + + return STPIntentActionWechatPayRedirectToApp( + nativeURL: nativeURL, + allResponseFields: dict + ) as? Self + } + +} diff --git a/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/Shared/STPMandateCustomerAcceptanceParams.swift b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/Shared/STPMandateCustomerAcceptanceParams.swift new file mode 100644 index 0000000..5865a99 --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/Shared/STPMandateCustomerAcceptanceParams.swift @@ -0,0 +1,70 @@ +// +// STPMandateCustomerAcceptanceParams.swift +// StripePayments +// +// Created by Cameron Sabol on 10/17/19. +// Copyright © 2019 Stripe, Inc. All rights reserved. +// + +import Foundation + +/// The type of customer acceptance information included with the Mandate. +@objc public enum STPMandateCustomerAcceptanceType: Int { + /// A Mandate that was accepted online. + case online + /// A Mandate that was accepted offline. + case offline +} + +/// An object that contains details about the customer acceptance of the Mandate. - seealso: https://stripe.com/docs/api/payment_intents/confirm#confirm_payment_intent-mandate_data-customer_acceptance +public class STPMandateCustomerAcceptanceParams: NSObject, STPFormEncodable { + + /// The type of customer acceptance information included with the Mandate. + @objc public var type: STPMandateCustomerAcceptanceType = .offline + + /// If this is a Mandate accepted online, this object contains details about the online acceptance. + /// @note If `type == STPMandateCustomerAcceptanceTypeOnline`, this value must be non-nil. + @objc public var onlineParams: STPMandateOnlineParams? + + @objc public var additionalAPIParameters: [AnyHashable: Any] = [:] + + /// Initializes an empty STPMandateCustomerAcceptanceParams. + @objc public required override init() { + super.init() + } + + @objc convenience init?( + type: STPMandateCustomerAcceptanceType, + onlineParams: STPMandateOnlineParams? + ) { + guard type == .offline || onlineParams != nil else { + return nil + } + self.init() + self.type = type + self.onlineParams = onlineParams + } + + // MARK: - STPFormEncodable + @objc internal var typeString: String { + switch type { + case .online: + return "online" + case .offline: + return "offline" + } + } + + @objc + public class func propertyNamesToFormFieldNamesMapping() -> [String: String] { + return [ + NSStringFromSelector(#selector(getter:typeString)): "type", + NSStringFromSelector(#selector(getter:onlineParams)): "online", + ] + } + + @objc + public class func rootObjectName() -> String? { + return "customer_acceptance" + } +} diff --git a/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/Shared/STPMandateDataParams.swift b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/Shared/STPMandateDataParams.swift new file mode 100644 index 0000000..4246692 --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/Shared/STPMandateDataParams.swift @@ -0,0 +1,40 @@ +// +// STPMandateDataParams.swift +// StripePayments +// +// Created by Cameron Sabol on 10/17/19. +// Copyright © 2019 Stripe, Inc. All rights reserved. +// + +import Foundation + +/// This object contains details about the Mandate to create. - seealso: https://stripe.com/docs/api/payment_intents/confirm#confirm_payment_intent-mandate_data +public class STPMandateDataParams: NSObject { + + /// Details about the customer acceptance of the Mandate. + @objc public let customerAcceptance: STPMandateCustomerAcceptanceParams + + @objc public var additionalAPIParameters: [AnyHashable: Any] = [:] + + /// Initializes an STPMandateDataParams from an STPMandateCustomerAcceptanceParams. + @objc public init( + customerAcceptance: STPMandateCustomerAcceptanceParams + ) { + self.customerAcceptance = customerAcceptance + super.init() + } +} + +extension STPMandateDataParams: STPFormEncodable { + @objc + public class func propertyNamesToFormFieldNamesMapping() -> [String: String] { + return [ + NSStringFromSelector(#selector(getter:customerAcceptance)): "customer_acceptance" + ] + } + + @objc + public class func rootObjectName() -> String? { + return "mandate_data" + } +} diff --git a/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/Shared/STPMandateOnlineParams.swift b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/Shared/STPMandateOnlineParams.swift new file mode 100644 index 0000000..85ad781 --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/Shared/STPMandateOnlineParams.swift @@ -0,0 +1,68 @@ +// +// STPMandateOnlineParams.swift +// StripePayments +// +// Created by Cameron Sabol on 10/17/19. +// Copyright © 2019 Stripe, Inc. All rights reserved. +// + +import Foundation + +/// Contains details about a Mandate accepted online. - seealso: https://stripe.com/docs/api/payment_intents/confirm#confirm_payment_intent-mandate_data-customer_acceptance-online +public class STPMandateOnlineParams: NSObject { + + /// The IP address from which the Mandate was accepted by the customer. + @objc public let ipAddress: String + + /// The user agent of the browser from which the Mandate was accepted by the customer. + @objc public let userAgent: String + + @objc public var additionalAPIParameters: [AnyHashable: Any] = [:] + + @objc internal var inferFromClient: NSNumber? + + /// Initializes an STPMandateOnlineParams. + /// - Parameter ipAddress: The IP address from which the Mandate was accepted by the customer. + /// - Parameter userAgent: The user agent of the browser from which the Mandate was accepted by the customer. + /// - Returns: A new STPMandateOnlineParams instance with the specified parameters. + @objc(initWithIPAddress:userAgent:) + public init( + ipAddress: String, + userAgent: String + ) { + self.ipAddress = ipAddress + self.userAgent = userAgent + super.init() + } +} + +extension STPMandateOnlineParams: STPFormEncodable { + + @objc internal var ipAddressField: String? { + guard inferFromClient == nil || !(inferFromClient?.boolValue ?? false) else { + return nil + } + return ipAddress + } + + @objc internal var userAgentField: String? { + guard inferFromClient == nil || !(inferFromClient?.boolValue ?? false) else { + return nil + } + return userAgent + } + + @objc + public class func propertyNamesToFormFieldNamesMapping() -> [String: String] { + return [ + NSStringFromSelector(#selector(getter:ipAddressField)): "ip_address", + NSStringFromSelector(#selector(getter:userAgentField)): "user_agent", + NSStringFromSelector(#selector(getter:inferFromClient)): "infer_from_client", + ] + } + + @objc + public class func rootObjectName() -> String? { + return "online" + } +} diff --git a/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/Shared/STPPaymentMethodOptions.swift b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/Shared/STPPaymentMethodOptions.swift new file mode 100644 index 0000000..be078f7 --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/Shared/STPPaymentMethodOptions.swift @@ -0,0 +1,120 @@ +// +// STPPaymentMethodOptions.swift +// StripePayments +// +// Created by Cameron Sabol on 4/8/22. +// Copyright © 2022 Stripe, Inc. All rights reserved. +// + +import UIKit + +@_spi(STP) public class STPPaymentMethodOptions: NSObject, STPAPIResponseDecodable { + + @_spi(STP) public let usBankAccount: USBankAccount? + @_spi(STP) public let allResponseFields: [AnyHashable: Any] + + @_spi(STP) public init( + usBankAccount: USBankAccount?, + allResponseFields: [AnyHashable: Any] + ) { + self.usBankAccount = usBankAccount + self.allResponseFields = allResponseFields + } + + @_spi(STP) public static func decodedObject( + fromAPIResponse response: [AnyHashable: Any]? + ) -> Self? { + guard let response = response else { + return nil + } + + return STPPaymentMethodOptions( + usBankAccount: USBankAccount.decodedObject( + fromAPIResponse: response["us_bank_account"] as? [AnyHashable: Any] + ), + allResponseFields: response + ) as? Self + } + +} + +// MARK: - us_bank_account + +extension STPPaymentMethodOptions { + @_spi(STP) public class USBankAccount: NSObject, STPAPIResponseDecodable { + + /// Bank account verification method. + @_spi(STP) @frozen public enum VerificationMethod: String, CaseIterable { + /// Allows skipping the bank account verification step. + case skip + /// Instant verification with fallback to microdeposits. + case automatic + /// Instant verification only. + case instant + /// Verification using microdeposits. + case microdeposits + /// Instant verification with fallback to verification skip. + case instantOrSkip = "instant_or_skip" + case unknown + } + + @_spi(STP) public let setupFutureUsage: STPPaymentIntentSetupFutureUsage? + @_spi(STP) public let verificationMethod: VerificationMethod + @_spi(STP) public let allResponseFields: [AnyHashable: Any] + + @_spi(STP) public init( + setupFutureUsage: STPPaymentIntentSetupFutureUsage?, + verificationMethod: VerificationMethod, + allResponseFields: [AnyHashable: Any] + ) { + self.setupFutureUsage = setupFutureUsage + self.verificationMethod = verificationMethod + self.allResponseFields = allResponseFields + } + + @_spi(STP) public static func decodedObject( + fromAPIResponse response: [AnyHashable: Any]? + ) -> Self? { + guard let response = response, + let verificationMethodString = response["verification_method"] as? String + else { + return nil + } + + let setupFutureUsageString = response["setup_future_usage"] as? String + + return USBankAccount( + setupFutureUsage: setupFutureUsageString != nil + ? STPPaymentIntentSetupFutureUsage.init(string: setupFutureUsageString!) : nil, + verificationMethod: VerificationMethod(rawValue: verificationMethodString) + ?? .unknown, + allResponseFields: response + ) as? Self + } + } +} + +// MARK: - Test Helpers +extension STPPaymentMethodOptions { + var dictionaryValue: [AnyHashable: Any] { + var dictionaryValue = [AnyHashable: Any]() + if let usBankAccount = usBankAccount { + dictionaryValue["us_bank_account"] = usBankAccount.dictionaryValue + } + return dictionaryValue.merging(allResponseFields) { a, b in + a + } + } +} +extension STPPaymentMethodOptions.USBankAccount { + var dictionaryValue: [AnyHashable: Any] { + var dictionaryValue = [AnyHashable: Any]() + dictionaryValue["verification_method"] = verificationMethod.rawValue + if let setupFutureUsage = setupFutureUsage { + dictionaryValue["setup_future_usage"] = setupFutureUsage.stringValue + } + return dictionaryValue.merging(allResponseFields) { a, b in + a + } + } +} diff --git a/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/Sources/STPSource.swift b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/Sources/STPSource.swift new file mode 100644 index 0000000..df47970 --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/Sources/STPSource.swift @@ -0,0 +1,331 @@ +// +// STPSource.swift +// StripePayments +// +// Created by Ben Guo on 1/23/17. +// Copyright © 2017 Stripe, Inc. All rights reserved. +// + +import Foundation +import UIKit + +/// Representation of a customer's payment instrument created with the Stripe API. - seealso: https://stripe.com/docs/api#sources +public class STPSource: NSObject, STPAPIResponseDecodable, STPSourceProtocol { + + /// You cannot directly instantiate an `STPSource`. You should only use one that + /// has been returned from an `STPAPIClient` callback. + override required init() { + super.init() + } + + /// The amount associated with the source. + @objc public private(set) var amount: NSNumber? + /// The client secret of the source. Used for client-side fetching of a source + /// using a publishable key. + @objc public private(set) var clientSecret: String? + /// When the source was created. + @objc public private(set) var created: Date? + /// The currency associated with the source. + @objc public private(set) var currency: String? + /// The authentication flow of the source. + @objc public private(set) var flow: STPSourceFlow = .none + /// Whether or not this source was created in livemode. + @objc public private(set) var livemode = false + /// Information about the owner of the payment instrument. + @objc public private(set) var owner: STPSourceOwner? + /// Information related to the receiver flow. Present if the source's flow + /// is receiver. + @objc public private(set) var receiver: STPSourceReceiver? + /// Information related to the redirect flow. Present if the source's flow + /// is redirect. + @objc public private(set) var redirect: STPSourceRedirect? + /// The status of the source. + @objc public private(set) var status: STPSourceStatus = .unknown + /// The type of the source. + @objc public private(set) var type: STPSourceType = .unknown + /// Whether this source should be reusable or not. + @objc public private(set) var usage: STPSourceUsage = .unknown + /// Information related to the verification flow. Present if the source's flow + /// is verification. + @objc public private(set) var verification: STPSourceVerification? + /// Information about the source specific to its type + @objc public private(set) var details: [AnyHashable: Any]? + /// If this is a card source, this property provides typed access to the + /// contents of the `details` dictionary. + @objc public private(set) var cardDetails: STPSourceCardDetails? + /// If this is a Klarna source, this property provides typed access to the + /// contents of the `details` dictionary. + @objc public private(set) var klarnaDetails: STPSourceKlarnaDetails? + /// If this is a SEPA Debit source, this property provides typed access to the + /// contents of the `details` dictionary. + @objc public private(set) var sepaDebitDetails: STPSourceSEPADebitDetails? + /// If this is a WeChat Pay source, this property provides typed access to the + /// contents of the `details` dictionary. + @objc public private(set) var weChatPayDetails: STPSourceWeChatPayDetails? + // MARK: - Deprecated + + /// A set of key/value pairs associated with the source object. + /// @deprecated Metadata is no longer returned to clients using publishable keys. Retrieve them on your server using yoursecret key instead. + /// - seealso: https://stripe.com/docs/api#metadata + @available( + *, + deprecated, + message: + "Metadata is no longer returned to clients using publishable keys. Retrieve them on your server using yoursecret key instead." + ) + @objc public private(set) var metadata: [String: String]? + @objc public var stripeID = "" + @objc private(set) public var allResponseFields: [AnyHashable: Any] = [:] + + // MARK: - STPSourceType + class func stringToTypeMapping() -> [String: NSNumber] { + return [ + "bancontact": NSNumber(value: STPSourceType.bancontact.rawValue), + "card": NSNumber(value: STPSourceType.card.rawValue), + "giropay": NSNumber(value: STPSourceType.giropay.rawValue), + "ideal": NSNumber(value: STPSourceType.iDEAL.rawValue), + "sepa_debit": NSNumber(value: STPSourceType.SEPADebit.rawValue), + "sofort": NSNumber(value: STPSourceType.sofort.rawValue), + "three_d_secure": NSNumber(value: STPSourceType.threeDSecure.rawValue), + "alipay": NSNumber(value: STPSourceType.alipay.rawValue), + "p24": NSNumber(value: STPSourceType.P24.rawValue), + "eps": NSNumber(value: STPSourceType.EPS.rawValue), + "multibanco": NSNumber(value: STPSourceType.multibanco.rawValue), + "wechat": NSNumber(value: STPSourceType.weChatPay.rawValue), + "klarna": NSNumber(value: STPSourceType.klarna.rawValue), + ] + } + + @objc(typeFromString:) + class func type(from string: String) -> STPSourceType { + let key = string.lowercased() + let typeNumber = self.stringToTypeMapping()[key] + + if let typeNumber = typeNumber { + return (STPSourceType(rawValue: typeNumber.intValue))! + } + + return .unknown + } + + @objc(stringFromType:) + class func string(from type: STPSourceType) -> String? { + return + (self.stringToTypeMapping() as NSDictionary).allKeys( + for: NSNumber(value: type.rawValue) + ) + .first as? String + } + + // MARK: - STPSourceFlow + class func stringToFlowMapping() -> [String: NSNumber] { + return [ + "redirect": NSNumber(value: STPSourceFlow.redirect.rawValue), + "receiver": NSNumber(value: STPSourceFlow.receiver.rawValue), + "code_verification": NSNumber(value: STPSourceFlow.codeVerification.rawValue), + "none": NSNumber(value: STPSourceFlow.none.rawValue), + ] + } + + @objc(flowFromString:) + class func flow(from string: String) -> STPSourceFlow { + let key = string.lowercased() + let flowNumber = self.stringToFlowMapping()[key] + + if let flowNumber = flowNumber { + return (STPSourceFlow(rawValue: flowNumber.intValue))! + } + + return .unknown + } + + @objc(stringFromFlow:) + class func string(from flow: STPSourceFlow) -> String? { + return + (self.stringToFlowMapping() as NSDictionary).allKeys( + for: NSNumber(value: flow.rawValue) + ) + .first as? String + } + + // MARK: - STPSourceStatus + class func stringToStatusMapping() -> [String: NSNumber] { + return [ + "pending": NSNumber(value: STPSourceStatus.pending.rawValue), + "chargeable": NSNumber(value: STPSourceStatus.chargeable.rawValue), + "consumed": NSNumber(value: STPSourceStatus.consumed.rawValue), + "canceled": NSNumber(value: STPSourceStatus.canceled.rawValue), + "failed": NSNumber(value: STPSourceStatus.failed.rawValue), + ] + } + + @objc(statusFromString:) + class func status(from string: String) -> STPSourceStatus { + let key = string.lowercased() + let statusNumber = self.stringToStatusMapping()[key] + + if let statusNumber = statusNumber { + return (STPSourceStatus(rawValue: statusNumber.intValue))! + } + + return .unknown + } + + @objc(stringFromStatus:) + class func string(from status: STPSourceStatus) -> String? { + return + (self.stringToStatusMapping() as NSDictionary).allKeys( + for: NSNumber(value: status.rawValue) + ) + .first as? String + } + + // MARK: - STPSourceUsage + class func stringToUsageMapping() -> [String: NSNumber] { + return [ + "reusable": NSNumber(value: STPSourceUsage.reusable.rawValue), + "single_use": NSNumber(value: STPSourceUsage.singleUse.rawValue), + ] + } + + @objc(usageFromString:) + class func usage(from string: String) -> STPSourceUsage { + let key = string.lowercased() + let usageNumber = self.stringToUsageMapping()[key] + + if let usageNumber = usageNumber { + return (STPSourceUsage(rawValue: usageNumber.intValue))! + } + + return .unknown + } + + @objc(stringFromUsage:) + class func string(from usage: STPSourceUsage) -> String? { + return + (self.stringToUsageMapping() as NSDictionary).allKeys( + for: NSNumber(value: usage.rawValue) + ) + .first as? String + } + + // MARK: - Equality + /// :nodoc: + @objc + public override func isEqual(_ object: Any?) -> Bool { + return isEqual(to: object as? STPSource) + } + + /// :nodoc: + @objc public override var hash: Int { + return stripeID.hash + } + + func isEqual(to source: STPSource?) -> Bool { + if self === source { + return true + } + + guard let source = source else { + return false + } + + return stripeID == source.stripeID + } + + // MARK: - Description + /// :nodoc: + @objc public override var description: String { + let props = [ + // Object + String(format: "%@: %p", NSStringFromClass(STPSource.self), self), + // Identifier + "stripeID = \(stripeID)", + // Source details (alphabetical) + "amount = \(amount ?? 0)", + "clientSecret = \(((clientSecret) != nil ? "" : nil) ?? "")", + "created = \(String(describing: created))", + "currency = \(currency ?? "")", + "flow = \((STPSource.string(from: flow)) ?? "unknown")", + "livemode = \((livemode) ? "YES" : "NO")", + "owner = \(((owner) != nil ? "" : nil) ?? "")", + "receiver = \(String(describing: receiver))", + "redirect = \(String(describing: redirect))", + "status = \((STPSource.string(from: status)) ?? "unknown")", + "type = \((STPSource.string(from: type)) ?? "unknown")", + "usage = \((STPSource.string(from: usage)) ?? "unknown")", + "verification = \(String(describing: verification))", + ] + + return "<\(props.joined(separator: "; "))>" + } + + // MARK: - STPAPIResponseDecodable + @objc func stripeObject() -> String { + return "source" + } + + @objc + public class func decodedObject(fromAPIResponse response: [AnyHashable: Any]?) -> Self? { + guard let response = response else { + return nil + } + let dict = response.stp_dictionaryByRemovingNulls() + + // required fields + let stripeId = dict.stp_string(forKey: "id") + let rawStatus = dict.stp_string(forKey: "status") + let rawType = dict.stp_string(forKey: "type") + if stripeId == nil || rawStatus == nil || rawType == nil || dict["livemode"] == nil { + return nil + } + + let source = self.init() + source.stripeID = stripeId ?? "" + source.amount = dict.stp_number(forKey: "amount") + source.clientSecret = dict.stp_string(forKey: "client_secret") + source.created = dict.stp_date(forKey: "created") + source.currency = dict.stp_string(forKey: "currency") + let rawFlow = dict.stp_string(forKey: "flow") + source.flow = self.flow(from: rawFlow ?? "") + source.livemode = dict.stp_bool(forKey: "livemode", or: true) + let rawOwner = dict.stp_dictionary(forKey: "owner") + source.owner = STPSourceOwner.decodedObject(fromAPIResponse: rawOwner) + let rawReceiver = dict.stp_dictionary(forKey: "receiver") + source.receiver = STPSourceReceiver.decodedObject(fromAPIResponse: rawReceiver) + let rawRedirect = dict.stp_dictionary(forKey: "redirect") + source.redirect = STPSourceRedirect.decodedObject(fromAPIResponse: rawRedirect) + source.status = self.status(from: rawStatus ?? "") + source.type = self.type(from: rawType ?? "") + let rawUsage = dict.stp_string(forKey: "usage") + source.usage = self.usage(from: rawUsage ?? "") + let rawVerification = dict.stp_dictionary(forKey: "verification") + if let rawVerification = rawVerification { + source.verification = STPSourceVerification.decodedObject( + fromAPIResponse: rawVerification + ) + } + source.details = dict.stp_dictionary(forKey: rawType ?? "") + source.allResponseFields = dict + + if source.type == .card { + if let details1 = source.details { + source.cardDetails = STPSourceCardDetails.decodedObject(fromAPIResponse: details1) + } + } else if source.type == .SEPADebit { + source.sepaDebitDetails = STPSourceSEPADebitDetails.decodedObject( + fromAPIResponse: source.details + ) + } else if source.type == .weChatPay { + source.weChatPayDetails = STPSourceWeChatPayDetails.decodedObject( + fromAPIResponse: source.details + ) + } else if source.type == .klarna { + source.klarnaDetails = STPSourceKlarnaDetails.decodedObject( + fromAPIResponse: source.details + ) + } + + return source + } +} diff --git a/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/Sources/STPSourceEnums.swift b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/Sources/STPSourceEnums.swift new file mode 100644 index 0000000..0855439 --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/Sources/STPSourceEnums.swift @@ -0,0 +1,100 @@ +// +// STPSourceEnums.swift +// StripePayments +// +// Created by Brian Dorfman on 8/4/17. +// Copyright © 2017 Stripe, Inc. All rights reserved. +// + +import Foundation + +/// Authentication flows for a Source +@objc public enum STPSourceFlow: Int { + /// No action is required from your customer. + /// @note WeChat Pay Sources also have this flow type. + case none + /// Your customer must be redirected to their online banking service (either a website or mobile banking app) to approve the payment. + case redirect + /// Your customer must verify ownership of their account by providing a code that you post to the Stripe API for authentication. + case codeVerification + /// Your customer must push funds to the account information provided. + case receiver + /// The source's flow is unknown. + case unknown +} + +/// Usage types for a Source +@objc public enum STPSourceUsage: Int { + /// The source can be reused. + case reusable + /// The source can only be used once. + case singleUse + /// The source's usage is unknown. + case unknown +} + +/// Status types for a Source +@objc public enum STPSourceStatus: Int { + /// The source has been created and is awaiting customer action. + case pending + /// The source is ready to use. The customer action has been completed or the + /// payment method requires no customer action. + case chargeable + /// The source has been used. This status only applies to single-use sources. + case consumed + /// The source, which was chargeable, has expired because it was not used to + /// make a charge request within a specified amount of time. + case canceled + /// Your customer has not taken the required action or revoked your access + /// (e.g., did not authorize the payment with their bank or canceled their + /// mandate acceptance for SEPA direct debits). + case failed + /// The source status is unknown. + case unknown +} + +/// Types for a Source +/// - seealso: https://stripe.com/docs/sources +@objc public enum STPSourceType: Int { + /// A Bancontact source. - seealso: https://stripe.com/docs/sources/bancontact + case bancontact + /// A card source. - seealso: https://stripe.com/docs/sources/cards + case card + /// A Giropay source. - seealso: https://stripe.com/docs/sources/giropay + case giropay + /// An iDEAL source. - seealso: https://stripe.com/docs/sources/ideal + @objc(STPSourceTypeiDEAL) case iDEAL + /// A SEPA Direct Debit source. - seealso: https://stripe.com/docs/sources/sepa-debit + case SEPADebit + /// A Sofort source. - seealso: https://stripe.com/docs/sources/sofort + case sofort + /// A 3DS card source. - seealso: https://stripe.com/docs/sources/three-d-secure + case threeDSecure + /// An Alipay source. - seealso: https://stripe.com/docs/sources/alipay + case alipay + /// A P24 source. - seealso: https://stripe.com/docs/sources/p24 + case P24 + /// An EPS source. - seealso: https://stripe.com/docs/sources/eps + case EPS + /// A Multibanco source. - seealso: https://stripe.com/docs/sources/multibanco + case multibanco + /// A WeChat Pay source. - seealso: https://stripe.com/docs/sources/wechat-pay + case weChatPay + /// A Klarna source. - seealso: https://stripe.com/docs/sources/klarna + case klarna + /// An unknown type of source. + case unknown +} + +/// Custom payment methods for Klarna +/// - seealso: https://stripe.com/docs/sources/klarna#create-source +@objc public enum STPKlarnaPaymentMethods: Int { + /// Don't specify any custom payment methods. + case none + /// Offer payments over 4 installments. (a.k.a. Pay Later in 4) + case payIn4 + /// Offer payments over an arbitrary number of installments. (a.k.a. Slice It) + case installments + /// Offer payments over 4 or an arbitrary number of installments. + case payIn4OrInstallments +} diff --git a/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/Sources/STPSourceOwner.swift b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/Sources/STPSourceOwner.swift new file mode 100644 index 0000000..2332753 --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/Sources/STPSourceOwner.swift @@ -0,0 +1,61 @@ +// +// STPSourceOwner.swift +// StripePayments +// +// Created by Ben Guo on 1/25/17. +// Copyright © 2017 Stripe, Inc. All rights reserved. +// + +import Foundation + +/// Information about a source's owner. +public class STPSourceOwner: NSObject, STPAPIResponseDecodable { + override required init() { + super.init() + } + + /// Owner's address. + @objc public private(set) var address: STPAddress? + /// Owner's email address. + @objc public private(set) var email: String? + /// Owner's full name. + @objc public private(set) var name: String? + /// Owner's phone number. + @objc public private(set) var phone: String? + /// Verified owner's address. + @objc public private(set) var verifiedAddress: STPAddress? + /// Verified owner's email address. + @objc public private(set) var verifiedEmail: String? + /// Verified owner's full name. + @objc public private(set) var verifiedName: String? + /// Verified owner's phone number. + @objc public private(set) var verifiedPhone: String? + @objc private(set) public var allResponseFields: [AnyHashable: Any] = [:] + + // MARK: - STPAPIResponseDecodable + @objc + public class func decodedObject(fromAPIResponse response: [AnyHashable: Any]?) -> Self? { + guard let response = response else { + return nil + } + let dict = response.stp_dictionaryByRemovingNulls() + + let owner = self.init() + owner.allResponseFields = response + let rawAddress = dict.stp_dictionary(forKey: "address") + if let rawAddress = rawAddress { + owner.address = STPAddress.decodedObject(fromAPIResponse: rawAddress) + } + owner.email = dict.stp_string(forKey: "email") + owner.name = dict.stp_string(forKey: "name") + owner.phone = dict.stp_string(forKey: "phone") + let rawVerifiedAddress = dict.stp_dictionary(forKey: "verified_address") + if let rawVerifiedAddress = rawVerifiedAddress { + owner.verifiedAddress = STPAddress.decodedObject(fromAPIResponse: rawVerifiedAddress) + } + owner.verifiedEmail = dict.stp_string(forKey: "verified_email") + owner.verifiedName = dict.stp_string(forKey: "verified_name") + owner.verifiedPhone = dict.stp_string(forKey: "verified_phone") + return owner + } +} diff --git a/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/Sources/STPSourceParams.swift b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/Sources/STPSourceParams.swift new file mode 100644 index 0000000..4eb7d22 --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/Sources/STPSourceParams.swift @@ -0,0 +1,975 @@ +// +// STPSourceParams.swift +// StripePayments +// +// Created by Ben Guo on 1/23/17. +// Copyright © 2017 Stripe, Inc. All rights reserved. +// + +import Foundation +@_spi(STP) import StripeCore + +/// An object representing parameters used to create a Source object. +/// - seealso: https://stripe.com/docs/api#create_source +public class STPSourceParams: NSObject, STPFormEncodable, NSCopying { + @objc public var additionalAPIParameters: [AnyHashable: Any] = [:] + var redirectMerchantName: String? + + /// The type of the source to create. Required. + + @objc public var type: STPSourceType { + get { + return STPSource.type(from: rawTypeString ?? "") + } + set(type) { + // If setting unknown and we're already unknown, don't want to override raw value + if type != self.type { + rawTypeString = STPSource.string(from: type) + } + } + } + /// The raw underlying type string sent to the server. + /// Generally you should use `type` instead unless you have a reason not to. + /// You can use this if you want to create a param of a type not yet supported + /// by the current version of the SDK's `STPSourceType` enum. + /// Setting this to a value not known by the SDK causes `type` to + /// return `STPSourceTypeUnknown` + @objc public var rawTypeString: String? + /// A positive integer in the smallest currency unit representing the + /// amount to charge the customer (e.g., @1099 for a €10.99 payment). + /// Required for `single_use` sources. + @objc public var amount: NSNumber? + /// The currency associated with the source. This is the currency for which the source + /// will be chargeable once ready. + @objc public var currency: String? + /// The authentication flow of the source to create. `flow` may be "redirect", + /// "receiver", "verification", or "none". It is generally inferred unless a type + /// supports multiple flows. + @objc public var flow: STPSourceFlow + /// A set of key/value pairs that you can attach to a source object. + @objc public var metadata: [AnyHashable: Any]? + /// Information about the owner of the payment instrument. May be used or required + /// by particular source types. + @objc public var owner: [AnyHashable: Any]? + /// Parameters required for the redirect flow. Required if the source is + /// authenticated by a redirect (`flow` is "redirect"). + @objc public var redirect: [AnyHashable: Any]? + /// An optional token used to create the source. When passed, token properties will + /// override source parameters. + @objc public var token: String? + /// Whether this source should be reusable or not. `usage` may be "reusable" or + /// "single_use". Some source types may or may not be reusable by construction, + /// while other may leave the option at creation. + @objc public var usage: STPSourceUsage + + /// Initializes an empty STPSourceParams. + override public required init() { + rawTypeString = "" + flow = .unknown + usage = .unknown + additionalAPIParameters = [:] + super.init() + } +} + +// MARK: - Constructors +extension STPSourceParams { + /// Creates params for a Bancontact source. + /// - seealso: https://stripe.com/docs/payments/bancontact#create-source + /// - Parameters: + /// - amount: The amount to charge the customer in EUR. + /// - name: The full name of the account holder. + /// - returnURL: The URL the customer should be redirected to after + /// they have successfully verified the payment. + /// - statementDescriptor: (Optional) A custom statement descriptor for + /// the payment. + /// @note The currency for Bancontact must be "eur". This will be set automatically + /// for you. + /// - Returns: an STPSourceParams object populated with the provided values. + @objc + public class func bancontactParams( + withAmount amount: Int, + name: String, + returnURL: String, + statementDescriptor: String? + ) -> STPSourceParams { + let params = self.init() + params.type = .bancontact + params.amount = NSNumber(value: amount) + params.currency = "eur" // Bancontact must always use eur + params.owner = [ + "name": name + ] + params.redirect = [ + "return_url": returnURL + ] + if let statementDescriptor = statementDescriptor { + params.additionalAPIParameters = [ + "bancontact": [ + "statement_descriptor": statementDescriptor + ] + ] + } + return params + } + + /// Creates params for a Card source. + /// - seealso: https://stripe.com/docs/sources/cards#create-source + /// - Parameter card: An object containing the user's card details + /// - Returns: an STPSourceParams object populated with the provided card details. + @objc + public class func cardParams(withCard card: STPCardParams) -> STPSourceParams { + let params = self.init() + params.type = .card + let keyPairs = STPFormEncoder.dictionary(forObject: card)["card"] as? [AnyHashable: Any] + var cardDict: [AnyHashable: Any] = [:] + let cardKeys = ["number", "cvc", "exp_month", "exp_year"] + for key in cardKeys { + if let keyPair = keyPairs?[key] { + cardDict[key] = keyPair + } + } + params.additionalAPIParameters = [ + "card": cardDict + ] + var addressDict: [AnyHashable: Any] = [:] + let addressKeyMapping = [ + "address_line1": "line1", + "address_line2": "line2", + "address_city": "city", + "address_state": "state", + "address_zip": "postal_code", + "address_country": "country", + ] + for key in addressKeyMapping.keys { + if let newKey = addressKeyMapping[key], + let keyPair = keyPairs?[key] + { + addressDict[newKey] = keyPair + } + } + var ownerDict: [AnyHashable: Any] = [:] + ownerDict["address"] = addressDict + ownerDict["name"] = card.name + params.owner = ownerDict + return params + } + + /// Creates params for a Giropay source. + /// - seealso: https://stripe.com/docs/sources/giropay#create-source + /// - Parameters: + /// - amount: The amount to charge the customer in EUR. + /// - name: The full name of the account holder. + /// - returnURL: The URL the customer should be redirected to after + /// they have successfully verified the payment. + /// - statementDescriptor: (Optional) A custom statement descriptor for + /// the payment. + /// @note The currency for Giropay must be "eur". This will be set automatically + /// for you. + /// - Returns: an STPSourceParams object populated with the provided values. + @objc + public class func giropayParams( + withAmount amount: Int, + name: String, + returnURL: String, + statementDescriptor: String? + ) -> STPSourceParams { + let params = self.init() + params.type = .giropay + params.amount = NSNumber(value: amount) + params.currency = "eur" // Giropay must always use eur + params.owner = [ + "name": name + ] + params.redirect = [ + "return_url": returnURL + ] + if let statementDescriptor = statementDescriptor { + params.additionalAPIParameters = [ + "giropay": [ + "statement_descriptor": statementDescriptor + ] + ] + } + return params + } + + /// Creates params for an iDEAL source. + /// - seealso: https://stripe.com/docs/sources/ideal#create-source + /// - Parameters: + /// - amount: The amount to charge the customer in EUR. + /// - name: (Optional) The full name of the account holder. + /// - returnURL: The URL the customer should be redirected to after + /// they have successfully verified the payment. + /// - statementDescriptor: (Optional) A custom statement descriptor for t + /// he payment. + /// - bank: (Optional) The customer's bank. + /// @note The currency for iDEAL must be "eur". This will be set automatically + /// for you. + /// - Returns: an STPSourceParams object populated with the provided values. + @objc + public class func idealParams( + withAmount amount: Int, + name: String?, + returnURL: String, + statementDescriptor: String?, + bank: String? + ) -> STPSourceParams { + let params = self.init() + params.type = .iDEAL + params.amount = NSNumber(value: amount) + params.currency = "eur" // iDEAL must always use eur + if (name?.count ?? 0) > 0 { + params.owner = [ + "name": name ?? "" + ] + } + params.redirect = [ + "return_url": returnURL + ] + if (statementDescriptor?.count ?? 0) > 0 || (bank?.count ?? 0) > 0 { + var idealDict: [AnyHashable: Any] = [:] + if let statementDescriptor = statementDescriptor, statementDescriptor.count > 0 { + idealDict["statement_descriptor"] = + statementDescriptor + } + if let bank = bank, bank.count > 0 { + idealDict["bank"] = bank + } + params.additionalAPIParameters = [ + "ideal": idealDict + ] + } + return params + } + + /// Creates params for a SEPA Debit source. + /// - seealso: https://stripe.com/docs/sources/sepa-debit#create-source + /// - Parameters: + /// - name: The full name of the account holder. + /// - iban: The IBAN number for the bank account you wish to debit. + /// - addressLine1: (Optional) The bank account holder's first address line. + /// - city: (Optional) The bank account holder's city. + /// - postalCode: (Optional) The bank account holder's postal code. + /// - country: (Optional) The bank account holder's two-letter + /// country code. + /// @note The currency for SEPA Debit must be "eur". This will be set automatically + /// for you. + /// - Returns: an STPSourceParams object populated with the provided values. + @objc + public class func sepaDebitParams( + withName name: String, + iban: String, + addressLine1: String?, + city: String?, + postalCode: String?, + country: String? + ) -> STPSourceParams { + let params = self.init() + params.type = .SEPADebit + params.currency = "eur" // SEPA Debit must always use eur + + var owner: [AnyHashable: Any] = [:] + owner["name"] = name + + var address: [String: String]? = [:] + address?["city"] = city + address?["postal_code"] = postalCode + address?["country"] = country + address?["line1"] = addressLine1 + + if (address?.count ?? 0) > 0 { + if let address = address { + owner["address"] = address + } + } + + params.owner = owner + params.additionalAPIParameters = [ + "sepa_debit": [ + "iban": iban + ] + ] + return params + } + + /// Creates params for a Sofort source. + /// - seealso: https://stripe.com/docs/sources/sofort#create-source + /// - Parameters: + /// - amount: The amount to charge the customer in EUR. + /// - returnURL: The URL the customer should be redirected to after + /// they have successfully verified the payment. + /// - country: The country code of the customer's bank. + /// - statementDescriptor: (Optional) A custom statement descriptor for + /// the payment. + /// @note The currency for Sofort must be "eur". This will be set automatically + /// for you. + /// - Returns: an STPSourceParams object populated with the provided values. + @objc + public class func sofortParams( + withAmount amount: Int, + returnURL: String, + country: String, + statementDescriptor: String? + ) -> STPSourceParams { + let params = self.init() + params.type = .sofort + params.amount = NSNumber(value: amount) + params.currency = "eur" // sofort must always use eur + params.redirect = [ + "return_url": returnURL + ] + var sofortDict: [AnyHashable: Any] = [:] + sofortDict["country"] = country + if let statementDescriptor = statementDescriptor { + sofortDict["statement_descriptor"] = statementDescriptor + } + params.additionalAPIParameters = [ + "sofort": sofortDict + ] + return params + } + + /// Creates params for a Klarna source. + /// - seealso: https://stripe.com/docs/sources/klarna#create-source + /// - Parameters: + /// - returnURL: The URL the customer should be redirected to after + /// they have successfully verified the payment. + /// - currency: The currency the payment is being created in. + /// - purchaseCountry: The ISO-3166 2-letter country code of the customer's location. + /// - items: An array of STPKlarnaLineItems. Klarna will present these on the confirmation + /// page. The total amount charged will be a sum of the `totalAmount` of each of these items. + /// - customPaymentMethods: Required for customers located in the US. This determines whether Pay Later and/or Slice It + /// is offered to a US customer. + /// - address: An STPAddress for the customer. At a minimum, an `email`, `line1`, `postalCode`, `city`, and `country` must be provided. + /// The address' `name` will be ignored in favor of the `firstName and `lastName` parameters. + /// - firstName: The customer's first name. + /// - lastName: The customer's last name. + /// If the provided information is missing a line1, postal code, city, email, or first/last name, or if the country code is + /// outside the specified country, no address information will be sent to Klarna, and Klarna will prompt the customer to provide their address. + /// - dateOfBirth: The customer's date of birth. This will be used by Klarna for a credit check in some EU countries. + /// The optional fields (address, firstName, lastName, and dateOfBirth) can be provided to skip Klarna's customer information form. + /// If this information is missing, Klarna will prompt the customer for these values during checkout. + /// Be careful with this option: If the provided information is invalid, + /// Klarna may reject the transaction without giving the customer a chance to correct it. + /// - Returns: an STPSourceParams object populated with the provided values. + @available(swift, obsoleted: 1.0) + @objc( + klarnaParamsWithReturnURL: + currency: + purchaseCountry: + items: + customPaymentMethods: + billingAddress: + billingFirstName: + billingLastName: + billingDOB: + ) + public class func objc_klarnaParams( + withReturnURL returnURL: String, + currency: String, + purchaseCountry: String, + items: [STPKlarnaLineItem], + customPaymentMethods: [NSNumber], + billingAddress address: STPAddress?, + billingFirstName firstName: String?, + billingLastName lastName: String?, + billingDOB dateOfBirth: STPDateOfBirth? + ) -> STPSourceParams { + let customPaymentMethods: [STPKlarnaPaymentMethods] = customPaymentMethods.map { + STPKlarnaPaymentMethods(rawValue: $0.intValue) ?? STPKlarnaPaymentMethods.none + } + return klarnaParams( + withReturnURL: returnURL, + currency: currency, + purchaseCountry: purchaseCountry, + items: items, + customPaymentMethods: customPaymentMethods, + billingAddress: address, + billingFirstName: firstName, + billingLastName: lastName, + billingDOB: dateOfBirth + ) + } + + /// Creates params for a Klarna source. + /// - seealso: https://stripe.com/docs/sources/klarna#create-source + /// - Parameters: + /// - returnURL: The URL the customer should be redirected to after + /// they have successfully verified the payment. + /// - currency: The currency the payment is being created in. + /// - purchaseCountry: The ISO-3166 2-letter country code of the customer's location. + /// - items: An array of STPKlarnaLineItems. Klarna will present these on the confirmation + /// page. The total amount charged will be a sum of the `totalAmount` of each of these items. + /// - customPaymentMethods: Required for customers located in the US. This determines whether Pay Later and/or Slice It + /// is offered to a US customer. + /// - address: An STPAddress for the customer. At a minimum, an `email`, `line1`, `postalCode`, `city`, and `country` must be provided. + /// The address' `name` will be ignored in favor of the `firstName and `lastName` parameters. + /// - firstName: The customer's first name. + /// - lastName: The customer's last name. + /// If the provided information is missing a line1, postal code, city, email, or first/last name, or if the country code is + /// outside the specified country, no address information will be sent to Klarna, and Klarna will prompt the customer to provide their address. + /// - dateOfBirth: The customer's date of birth. This will be used by Klarna for a credit check in some EU countries. + /// The optional fields (address, firstName, lastName, and dateOfBirth) can be provided to skip Klarna's customer information form. + /// If this information is missing, Klarna will prompt the customer for these values during checkout. + /// Be careful with this option: If the provided information is invalid, + /// Klarna may reject the transaction without giving the customer a chance to correct it. + /// - Returns: an STPSourceParams object populated with the provided values. + public class func klarnaParams( + withReturnURL returnURL: String, + currency: String, + purchaseCountry: String, + items: [STPKlarnaLineItem], + customPaymentMethods: [STPKlarnaPaymentMethods], + billingAddress address: STPAddress? = nil, + billingFirstName firstName: String? = nil, + billingLastName lastName: String? = nil, + billingDOB dateOfBirth: STPDateOfBirth? = nil + ) -> STPSourceParams { + let params = self.init() + params.type = .klarna + params.currency = currency + params.redirect = [ + "return_url": returnURL + ] + var additionalAPIParameters: [AnyHashable: Any] = [:] + + var klarnaDict: [AnyHashable: Any] = [:] + klarnaDict["product"] = "payment" + klarnaDict["purchase_country"] = purchaseCountry + + if let address = address, address.country == purchaseCountry, let line1 = address.line1, + let postalCode = address.postalCode, + let city = address.city, let email = address.email, let firstName = firstName, + let lastName = lastName + { + klarnaDict["first_name"] = firstName + klarnaDict["last_name"] = lastName + + var ownerDict: [AnyHashable: Any] = [:] + var addressDict: [AnyHashable: Any] = [:] + + addressDict["line1"] = line1 + addressDict["line2"] = address.line2 + addressDict["city"] = city + addressDict["state"] = address.state + addressDict["postal_code"] = postalCode + addressDict["country"] = address.country + + ownerDict["address"] = addressDict + ownerDict["phone"] = address.phone + ownerDict["email"] = email + additionalAPIParameters["owner"] = ownerDict + } + + if let dateOfBirth = dateOfBirth { + klarnaDict["owner_dob_day"] = String(format: "%02ld", dateOfBirth.day) + klarnaDict["owner_dob_month"] = String(format: "%02ld", dateOfBirth.month) + klarnaDict["owner_dob_year"] = String(format: "%li", dateOfBirth.year) + } + + var amount = 0 + let sourceOrderItems = NSMutableArray() + for item in items { + let itemType: String = { + switch item.itemType { + case .SKU: + return "sku" + case .tax: + return "tax" + case .shipping: + return "shipping" + } + }() + sourceOrderItems.add([ + "type": itemType, + "description": item.itemDescription, + "quantity": item.quantity, + "amount": item.totalAmount, + "currency": currency, + ]) + amount = Int(item.totalAmount.uint32Value) + amount + } + params.amount = NSNumber(value: amount) + + if !customPaymentMethods.isEmpty { + let customPaymentMethodsArray = NSMutableArray() + if customPaymentMethods.contains(.payIn4) + || customPaymentMethods.contains(.payIn4OrInstallments) + { + customPaymentMethodsArray.add("payin4") + } + if customPaymentMethods.contains(.installments) + || customPaymentMethods.contains(.payIn4OrInstallments) + { + customPaymentMethodsArray.add("installments") + } + klarnaDict["custom_payment_methods"] = customPaymentMethodsArray.componentsJoined( + by: "," + ) + } + + additionalAPIParameters["source_order"] = [ + "items": sourceOrderItems + ] + additionalAPIParameters["klarna"] = klarnaDict + additionalAPIParameters["flow"] = "redirect" + + params.additionalAPIParameters = additionalAPIParameters + return params + } + + /// Creates params for a Klarna source. + /// - seealso: https://stripe.com/docs/sources/klarna#create-source + /// - Parameters: + /// - returnURL: The URL the customer should be redirected to after + /// they have successfully verified the payment. + /// - currency: The currency the payment is being created in. + /// - purchaseCountry: The ISO-3166 2-letter country code of the customer's location. + /// - items: An array of STPKlarnaLineItems. Klarna will present these in the confirmation + /// dialog. The total amount charged will be a sum of the `totalAmount` of each of these items. + /// - customPaymentMethods: Required for customers located in the US. This determines whether Pay Later and/or Slice It + /// is offered to a US customer. + /// - Returns: an STPSourceParams object populated with the provided values. + @available(swift, obsoleted: 1.0) + @objc(klarnaParamsWithReturnURL:currency:purchaseCountry:items:customPaymentMethods:) + public class func objc_klarnaParams( + withReturnURL returnURL: String, + currency: String, + purchaseCountry: String, + items: [STPKlarnaLineItem], + customPaymentMethods: [NSNumber] + ) -> STPSourceParams { + return self.klarnaParams( + withReturnURL: returnURL, + currency: currency, + purchaseCountry: purchaseCountry, + items: items, + customPaymentMethods: customPaymentMethods.map({ + STPKlarnaPaymentMethods(rawValue: $0.intValue) ?? .none + }), + billingAddress: nil, + billingFirstName: "", + billingLastName: "", + billingDOB: nil + ) + } + + /// Creates params for a Klarna source. + /// - seealso: https://stripe.com/docs/sources/klarna#create-source + /// - Parameters: + /// - returnURL: The URL the customer should be redirected to after + /// they have successfully verified the payment. + /// - currency: The currency the payment is being created in. + /// - purchaseCountry: The ISO-3166 2-letter country code of the customer's location. + /// - items: An array of STPKlarnaLineItems. Klarna will present these in the confirmation + /// dialog. The total amount charged will be a sum of the `totalAmount` of each of these items. + /// - customPaymentMethods: Required for customers located in the US. This determines whether Pay Later and/or Slice It + /// is offered to a US customer. + /// - Returns: an STPSourceParams object populated with the provided values. + public class func klarnaParams( + withReturnURL returnURL: String, + currency: String, + purchaseCountry: String, + items: [STPKlarnaLineItem], + customPaymentMethods: [STPKlarnaPaymentMethods] + ) -> STPSourceParams { + return self.klarnaParams( + withReturnURL: returnURL, + currency: currency, + purchaseCountry: purchaseCountry, + items: items, + customPaymentMethods: customPaymentMethods, + billingAddress: nil, + billingFirstName: "", + billingLastName: "", + billingDOB: nil + ) + } + + /// Creates params for a 3DS source. + /// - seealso: https://stripe.com/docs/sources/three-d-secure#create-3ds-source + /// - Parameters: + /// - amount: The amount to charge the customer. + /// - currency: The currency the payment is being created in. + /// - returnURL: The URL the customer should be redirected to after they have + /// successfully verified the payment. + /// - card: The ID of the card source. + /// - Returns: an STPSourceParams object populated with the provided card details. + @objc + public class func threeDSecureParams( + withAmount amount: Int, + currency: String, + returnURL: String, + card: String + ) -> STPSourceParams { + let params = self.init() + params.type = .threeDSecure + params.amount = NSNumber(value: amount) + params.currency = currency + params.additionalAPIParameters = [ + "three_d_secure": [ + "card": card + ] + ] + params.redirect = [ + "return_url": returnURL + ] + return params + } + + /// Creates params for a single-use Alipay source + /// - seealso: https://stripe.com/docs/sources/alipay#create-source + /// - Parameters: + /// - amount: The amount to charge the customer. + /// - currency: The currency the payment is being created in. + /// - returnURL: The URL the customer should be redirected to after they have + /// successfully verified the payment. + /// - Returns: An STPSourceParams object populated with the provided values + @objc + public class func alipayParams( + withAmount amount: Int, + currency: String, + returnURL: String + ) -> STPSourceParams { + let params = self.init() + params.type = .alipay + params.amount = NSNumber(value: amount) + params.currency = currency + params.redirect = [ + "return_url": returnURL + ] + + let bundleID = Bundle.main.bundleIdentifier + let versionKey = Bundle.stp_applicationVersion() + if bundleID != nil && versionKey != nil { + params.additionalAPIParameters = [ + "alipay": [ + "app_bundle_id": bundleID ?? "", + "app_version_key": versionKey ?? "", + ] + ] + } + return params + } + + /// Creates params for a reusable Alipay source + /// - seealso: https://stripe.com/docs/sources/alipay#create-source + /// - Parameters: + /// - currency: The currency the payment is being created in. + /// - returnURL: The URL the customer should be redirected to after they have + /// successfully verified the payment. + /// - Returns: An STPSourceParams object populated with the provided values + @objc + public class func alipayReusableParams( + withCurrency currency: String, + returnURL: String + ) -> STPSourceParams { + let params = self.init() + params.type = .alipay + params.currency = currency + params.redirect = [ + "return_url": returnURL + ] + params.usage = .reusable + + return params + } + + /// Creates params for a P24 source + /// - seealso: https://stripe.com/docs/sources/p24#create-source + /// - Parameters: + /// - amount: The amount to charge the customer. + /// - currency: The currency the payment is being created in (this must be + /// EUR or PLN) + /// - email: The email address of the account holder. + /// - name: The full name of the account holder (optional). + /// - returnURL: The URL the customer should be redirected to after they have + /// - Returns: An STPSourceParams object populated with the provided values. + @objc + public class func p24Params( + withAmount amount: Int, + currency: String, + email: String, + name: String?, + returnURL: String + ) -> STPSourceParams { + let params = self.init() + params.type = .P24 + params.amount = NSNumber(value: amount) + params.currency = currency + + var ownerDict = [ + "email": email + ] + if let name = name { + ownerDict["name"] = name + } + params.owner = ownerDict + params.redirect = [ + "return_url": returnURL + ] + return params + } + + /// Creates params for a card source created from Visa Checkout. + /// - seealso: https://stripe.com/docs/visa-checkout + /// @note Creating an STPSource with these params will give you a + /// source with type == STPSourceTypeCard + /// - Parameter callId: The callId property from a `VisaCheckoutResult` object. + /// - Returns: An STPSourceParams object populated with the provided values. + @objc + public class func visaCheckoutParams(withCallId callId: String) -> STPSourceParams { + let params = self.init() + params.type = .card + params.additionalAPIParameters = [ + "card": [ + "visa_checkout": [ + "callid": callId + ] + ] + ] + return params + } + + /// Creates params for a card source created from Masterpass. + /// - seealso: https://stripe.com/docs/masterpass + /// @note Creating an STPSource with these params will give you a + /// source with type == STPSourceTypeCard + /// - Parameters: + /// - cartId: The cartId from a `MCCCheckoutResponse` object. + /// - transactionId: The transactionid from a `MCCCheckoutResponse` object. + /// - Returns: An STPSourceParams object populated with the provided values. + @objc + public class func masterpassParams( + withCartId cartId: String, + transactionId: String + ) -> STPSourceParams { + let params = self.init() + params.type = .card + params.additionalAPIParameters = [ + "card": [ + "masterpass": [ + "cart_id": cartId, + "transaction_id": transactionId, + ] + ] + ] + return params + } + + /// Create params for an EPS source + /// - seealso: https://stripe.com/docs/sources/eps + /// - Parameters: + /// - amount: The amount to charge the customer. + /// - name: The full name of the account holder. + /// - returnURL: The URL the customer should be redirected to + /// after the authorization process. + /// - statementDescriptor: A custom statement descriptor for the + /// payment (optional). + /// - Returns: An STPSourceParams object populated with the provided values. + @objc + public class func epsParams( + withAmount amount: Int, + name: String, + returnURL: String, + statementDescriptor: String? + ) -> STPSourceParams { + let params = self.init() + params.type = .EPS + params.amount = NSNumber(value: amount) + params.currency = "eur" // EPS must always use eur + params.owner = [ + "name": name + ] + params.redirect = [ + "return_url": returnURL + ] + + if (statementDescriptor?.count ?? 0) > 0 { + params.additionalAPIParameters = [ + "statement_descriptor": statementDescriptor ?? "" + ] + } + + return params + } + + /// Create params for a Multibanco source + /// - seealso: https://stripe.com/docs/sources/multibanco + /// - Parameters: + /// - amount: The amount to charge the customer. + /// - returnURL: The URL the customer should be redirected to after the + /// authorization process. + /// - email: The full email address of the customer. + /// - Returns: An STPSourceParams object populated with the provided values. + @objc + public class func multibancoParams( + withAmount amount: Int, + returnURL: String, + email: String + ) -> STPSourceParams { + let params = self.init() + params.type = .multibanco + params.currency = "eur" // Multibanco must always use eur + params.amount = NSNumber(value: amount) + params.redirect = [ + "return_url": returnURL + ] + params.owner = [ + "email": email + ] + return params + } + + /// Create params for a WeChat Pay native app redirect source + /// @note This feature is in private beta. + /// - Parameters: + /// - amount: The amount to charge the customer. + /// - currency: The currency of the payment + /// - appId: Your WeChat-provided application id. WeChat Pay uses + /// this as the redirect URL scheme + /// - statementDescriptor: A custom statement descriptor for the payment (optional). + /// - Returns: An STPSourceParams object populated with the provided values. + @objc(wechatPayParamsWithAmount:currency:appId:statementDescriptor:) + public class func wechatPay( + withAmount amount: Int, + currency: String, + appId: String, + statementDescriptor: String? + ) -> STPSourceParams { + let params = self.init() + + params.type = .weChatPay + params.amount = NSNumber(value: amount) + params.currency = currency + + var wechat: [AnyHashable: Any] = [:] + wechat["appid"] = appId + if (statementDescriptor?.count ?? 0) > 0 { + wechat["statement_descriptor"] = statementDescriptor ?? "" + } + params.additionalAPIParameters = [ + "wechat": wechat + ] + return params + } + + @objc func flowString() -> String? { + return STPSource.string(from: flow) + } + + @objc func usageString() -> String? { + return STPSource.string(from: usage) + } + + // MARK: - Description + /// :nodoc: + @objc public override var description: String { + let props = [ + // Object + String(format: "%@: %p", NSStringFromClass(STPSourceParams.self), self), + // Basic source details + "type = \((STPSource.string(from: type)) ?? "unknown")", + "rawTypeString = \(rawTypeString ?? "")", + // Additional source details (alphabetical) + "amount = \(amount ?? 0)", + "currency = \(currency ?? "")", + "flow = \((STPSource.string(from: flow)) ?? "unknown")", + "metadata = \(((metadata) != nil ? "" : nil) ?? "")", + "owner = \(((owner) != nil ? "" : nil) ?? "")", + "redirect = \(redirect ?? [:])", + "token = \(token ?? "")", + "usage = \((STPSource.string(from: usage)) ?? "unknown")", + ] + + return "<\(props.joined(separator: "; "))>" + } + + // MARK: - Redirect Dictionary + + /// Private setter allows for setting the name of the app in the returnURL so + /// that it can be displayed on hooks.stripe.com if the automatic redirect back + /// to the app fails. + /// We intercept the reading of redirect dictionary from STPFormEncoder and replace + /// the value of return_url if necessary + @objc + public func redirectDictionaryWithMerchantNameIfNecessary() -> [AnyHashable: Any] { + if (redirectMerchantName != nil) && redirect?["return_url"] != nil { + + let url = URL(string: redirect?["return_url"] as? String ?? "") + if let url = url { + let urlComponents = NSURLComponents( + url: url, + resolvingAgainstBaseURL: false + ) + + if let urlComponents = urlComponents { + + for item in urlComponents.queryItems ?? [] { + if item.name == "redirect_merchant_name" { + // Just return, don't replace their value + return redirect ?? [:] + } + } + + // If we get here, there was no existing redirect name + + var queryItems: [URLQueryItem] = urlComponents.queryItems ?? [URLQueryItem]() + + queryItems.append( + URLQueryItem( + name: "redirect_merchant_name", + value: redirectMerchantName + ) + ) + urlComponents.queryItems = queryItems as [URLQueryItem]? + + var redirectCopy = redirect + redirectCopy?["return_url"] = urlComponents.url?.absoluteString + + return redirectCopy ?? [:] + } + } + } + + return redirect ?? [:] + + } + + // MARK: - STPFormEncodable + public class func rootObjectName() -> String? { + return nil + } + + public class func propertyNamesToFormFieldNamesMapping() -> [String: String] { + return [ + NSStringFromSelector(#selector(getter:rawTypeString)): "type", + NSStringFromSelector(#selector(getter:amount)): "amount", + NSStringFromSelector(#selector(getter:currency)): "currency", + NSStringFromSelector(#selector(flowString)): "flow", + NSStringFromSelector(#selector(getter:metadata)): "metadata", + NSStringFromSelector(#selector(getter:owner)): "owner", + NSStringFromSelector(#selector(redirectDictionaryWithMerchantNameIfNecessary)): + "redirect", + NSStringFromSelector(#selector(getter:token)): "token", + NSStringFromSelector(#selector(usageString)): "usage", + ] + } + + // MARK: - NSCopying + /// :nodoc: + public func copy(with zone: NSZone? = nil) -> Any { + let copy = Swift.type(of: self).init() + copy.type = type + copy.amount = amount + copy.currency = currency + copy.flow = flow + copy.metadata = metadata + copy.owner = owner + copy.redirect = redirect + copy.token = token + copy.usage = usage + return copy + } +} diff --git a/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/Sources/STPSourceProtocol.swift b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/Sources/STPSourceProtocol.swift new file mode 100644 index 0000000..d3f307f --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/Sources/STPSourceProtocol.swift @@ -0,0 +1,18 @@ +// +// STPSourceProtocol.swift +// StripePayments +// +// Created by Jack Flintermann on 1/15/16. +// Copyright © 2016 Stripe, Inc. All rights reserved. +// + +import Foundation +import UIKit + +/// Objects conforming to this protocol can be attached to a Stripe Customer object +/// as a payment source. +/// - seealso: https://stripe.com/docs/api#customer_object-sources +@objc public protocol STPSourceProtocol: NSObjectProtocol { + /// The Stripe ID of the source. + var stripeID: String { get } +} diff --git a/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/Sources/STPSourceReceiver.swift b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/Sources/STPSourceReceiver.swift new file mode 100644 index 0000000..45ae3ee --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/Sources/STPSourceReceiver.swift @@ -0,0 +1,64 @@ +// +// STPSourceReceiver.swift +// StripePayments +// +// Created by Ben Guo on 1/25/17. +// Copyright © 2017 Stripe, Inc. All rights reserved. +// + +import Foundation + +/// Information related to a source's receiver flow. +public class STPSourceReceiver: NSObject, STPAPIResponseDecodable { + /// The address of the receiver source. This is the value that should be communicated to the customer to send their funds to. + @objc public private(set) var address: String? + /// The total amount charged by you. + @objc public private(set) var amountCharged: NSNumber? + /// The total amount received by the receiver source. + @objc public private(set) var amountReceived: NSNumber? + /// The total amount that was returned to the customer. + @objc public private(set) var amountReturned: NSNumber? + @objc public private(set) var allResponseFields: [AnyHashable: Any] = [:] + + // MARK: - Description + /// :nodoc: + @objc public override var description: String { + let props = [ + // Object + String(format: "%@: %p", NSStringFromClass(STPSourceReceiver.self), self), + // Details (alphabetical) + "address = \(((address) != nil ? "" : nil) ?? "")", + "amountCharged = \(amountCharged ?? 0)", + "amountReceived = \(amountReceived ?? 0)", + "amountReturned = \(amountReturned ?? 0)", + ] + + return "<\(props.joined(separator: "; "))>" + } + + // MARK: - STPAPIResponseDecodable + public class func decodedObject(fromAPIResponse response: [AnyHashable: Any]?) -> Self? { + guard let response = response else { + return nil + } + let dict = response.stp_dictionaryByRemovingNulls() + + // required fields + let address = dict.stp_string(forKey: "address") + if address == nil { + return nil + } + + let receiver = self.init() + receiver.allResponseFields = response + receiver.address = address + receiver.amountCharged = dict.stp_number(forKey: "amount_charged") + receiver.amountReceived = dict.stp_number(forKey: "amount_received") + receiver.amountReturned = dict.stp_number(forKey: "amount_returned") + return receiver + } + + override required init() { + super.init() + } +} diff --git a/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/Sources/STPSourceRedirect.swift b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/Sources/STPSourceRedirect.swift new file mode 100644 index 0000000..84620e8 --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/Sources/STPSourceRedirect.swift @@ -0,0 +1,113 @@ +// +// STPSourceRedirect.swift +// StripePayments +// +// Created by Ben Guo on 1/25/17. +// Copyright © 2017 Stripe, Inc. All rights reserved. +// + +import Foundation + +/// Redirect status types for a Source. +@objc +public enum STPSourceRedirectStatus: Int { + /// The redirect is pending. + case pending + /// The redirect has succeeded. + case succeeded + /// The redirect has failed. + case failed + /// The redirect should not be used. + case notRequired + /// The state of the redirect is unknown. + case unknown +} + +/// Information related to a source's redirect flow. +public class STPSourceRedirect: NSObject, STPAPIResponseDecodable { + /// The URL you provide to redirect the customer to after they authenticated their payment. + @objc public private(set) var returnURL: URL + /// The status of the redirect. + @objc public private(set) var status: STPSourceRedirectStatus = .unknown + /// The URL provided to you to redirect a customer to as part of a redirect authentication flow. + @objc public private(set) var url: URL + @objc public private(set) var allResponseFields: [AnyHashable: Any] = [:] + + // MARK: - STPSourceRedirectStatus + class func stringToStatusMapping() -> [String: NSNumber] { + return [ + "pending": NSNumber(value: STPSourceRedirectStatus.pending.rawValue), + "succeeded": NSNumber(value: STPSourceRedirectStatus.succeeded.rawValue), + "failed": NSNumber(value: STPSourceRedirectStatus.failed.rawValue), + "not_required": NSNumber(value: STPSourceRedirectStatus.notRequired.rawValue), + ] + } + + @objc(statusFromString:) + class func status(from string: String) -> STPSourceRedirectStatus { + let key = string.lowercased() + let statusNumber = self.stringToStatusMapping()[key] + + if let statusNumber = statusNumber { + return (STPSourceRedirectStatus(rawValue: statusNumber.intValue))! + } + + return .unknown + } + + @objc(stringFromStatus:) + class func string(from status: STPSourceRedirectStatus) -> String? { + return + (self.stringToStatusMapping() as NSDictionary).allKeys( + for: NSNumber(value: status.rawValue) + ) + .first as? String + } + + // MARK: - Description + /// :nodoc: + @objc public override var description: String { + let props = [ + // Object + String(format: "%@: %p", NSStringFromClass(STPSourceRedirect.self), self), + // Details (alphabetical) + "returnURL = \(String(describing: returnURL))", + "status = \((STPSourceRedirect.string(from: status)) ?? "unknown")", + "url = \(String(describing: url))", + ] + + return "<\(props.joined(separator: "; "))>" + } + + // MARK: - STPAPIResponseDecodable + required init( + returnURL: URL, + url: URL + ) { + self.returnURL = returnURL + self.url = url + super.init() + } + + public class func decodedObject(fromAPIResponse response: [AnyHashable: Any]?) -> Self? { + guard let response = response else { + return nil + } + let dict = response.stp_dictionaryByRemovingNulls() + + // required fields + guard let returnURL = dict.stp_url(forKey: "return_url"), + let rawStatus = dict.stp_string(forKey: "status"), + let url = dict.stp_url(forKey: "url") + else { + return nil + } + + let redirect = self.init(returnURL: returnURL, url: url) + redirect.allResponseFields = response + redirect.returnURL = returnURL + redirect.status = self.status(from: rawStatus) + redirect.url = url + return redirect + } +} diff --git a/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/Sources/STPSourceVerification.swift b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/Sources/STPSourceVerification.swift new file mode 100644 index 0000000..f079aae --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/Sources/STPSourceVerification.swift @@ -0,0 +1,100 @@ +// +// STPSourceVerification.swift +// StripePayments +// +// Created by Ben Guo on 1/25/17. +// Copyright © 2017 Stripe, Inc. All rights reserved. +// + +import Foundation + +/// Verification status types for a Source. +@objc +public enum STPSourceVerificationStatus: Int { + /// The verification is pending. + case pending + /// The verification has succeeeded. + case succeeded + /// The verification has failed. + case failed + /// The state of the verification is unknown. + case unknown +} + +/// Information related to a source's verification flow. +public class STPSourceVerification: NSObject, STPAPIResponseDecodable { + /// The number of attempts remaining to authenticate the source object with a + /// verification code. + @objc public private(set) var attemptsRemaining: NSNumber? + /// The status of the verification. + @objc public private(set) var status: STPSourceVerificationStatus = .unknown + @objc public private(set) var allResponseFields: [AnyHashable: Any] = [:] + + // MARK: - STPSourceVerificationStatus + class func stringToStatusMapping() -> [String: NSNumber] { + return [ + "pending": NSNumber(value: STPSourceVerificationStatus.pending.rawValue), + "succeeded": NSNumber(value: STPSourceVerificationStatus.succeeded.rawValue), + "failed": NSNumber(value: STPSourceVerificationStatus.failed.rawValue), + ] + } + + @objc(statusFromString:) + class func status(from string: String) -> STPSourceVerificationStatus { + let key = string.lowercased() + let statusNumber = self.stringToStatusMapping()[key] + + if let statusNumber = statusNumber { + return (STPSourceVerificationStatus(rawValue: statusNumber.intValue))! + } + + return .unknown + } + + @objc(stringFromStatus:) + class func string(from status: STPSourceVerificationStatus) -> String? { + return + (self.stringToStatusMapping() as NSDictionary).allKeys( + for: NSNumber(value: status.rawValue) + ) + .first as? String + } + + // MARK: - Description + /// :nodoc: + @objc public override var description: String { + let props = [ + // Object + String(format: "%@: %p", NSStringFromClass(STPSourceVerification.self), self), + // Details (alphabetical) + "attemptsRemaining = \(attemptsRemaining ?? 0)", + "status = \((STPSourceVerification.string(from: status)) ?? "unknown")", + ] + + return "<\(props.joined(separator: "; "))>" + } + + // MARK: - STPAPIResponseDecodable + override required init() { + super.init() + } + + public class func decodedObject(fromAPIResponse response: [AnyHashable: Any]?) -> Self? { + guard let response = response else { + return nil + } + let dict = response.stp_dictionaryByRemovingNulls() + + // required fields + let rawStatus = dict.stp_string(forKey: "status") + if rawStatus == nil { + return nil + } + + let verification = self.init() + verification.attemptsRemaining = dict.stp_number(forKey: "attempts_remaining") + verification.status = self.status(from: rawStatus ?? "") + verification.allResponseFields = response + return verification + } +} diff --git a/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/Sources/Types/STPBankAccount.swift b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/Sources/Types/STPBankAccount.swift new file mode 100644 index 0000000..89ead4f --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/Sources/Types/STPBankAccount.swift @@ -0,0 +1,202 @@ +// +// STPBankAccount.swift +// StripePayments +// +// Created by Charles Scalesse on 10/1/14. +// Copyright © 2014 Stripe, Inc. All rights reserved. +// + +import Foundation + +/// Possible validation states for a bank account. +@objc public enum STPBankAccountStatus: Int { + /// The account has had no activity or validation performed + case new + /// Stripe has determined this bank account exists. + case validated + /// Bank account verification has succeeded. + case verified + /// Verification for this bank account has failed. + case verificationFailed + /// A transfer sent to this bank account has failed. + case errored +} + +/// Representation of a user's bank account details that have been tokenized with +/// the Stripe API. +/// - seealso: https://stripe.com/docs/api#bank_accounts +public class STPBankAccount: NSObject, STPAPIResponseDecodable, STPSourceProtocol { + /// You cannot directly instantiate an `STPBankAccount`. You should only use one + /// that has been returned from an `STPAPIClient` callback. + required override init() { + } + + /// The routing number for the bank account. This should be the ACH routing number, + /// not the wire routing number. + @objc public private(set) var routingNumber: String? + /// Two-letter ISO code representing the country the bank account is located in. + @objc public private(set) var country: String? + /// The default currency for the bank account. + @objc public private(set) var currency: String? + /// The last 4 digits of the account number. + @objc public private(set) var last4: String? + /// The name of the bank that owns the account. + @objc public private(set) var bankName: String? + /// The name of the person or business that owns the bank account. + @objc public private(set) var accountHolderName: String? + /// The type of entity that holds the account. + @objc public private(set) var accountHolderType: STPBankAccountHolderType = .individual + /// A proxy for the account number, this uniquely identifies the account and can be + /// used to compare equality of different bank accounts. + @objc public private(set) var fingerprint: String? + /// The validation status of the bank account. - seealso: STPBankAccountStatus + @objc public private(set) var status: STPBankAccountStatus = .new + + // MARK: - Deprecated methods + + /// A set of key/value pairs associated with the bank account object. + /// @deprecated Metadata is no longer returned to clients using publishable keys. Retrieve them on your server using yoursecret key instead. + /// - seealso: https://stripe.com/docs/api#metadata + @available( + *, + deprecated, + message: + "Metadata is no longer returned to clients using publishable keys. Retrieve them on your server using yoursecret key instead." + ) + private(set) var metadata: [String: String]? + /// The Stripe ID for the bank account. + @available( + *, + deprecated, + message: "Use stripeID (defined in STPSourceProtocol)" + ) + @objc public var bankAccountId: String? { + return stripeID + } + @objc public private(set) var stripeID: String = "" + @objc public private(set) var allResponseFields: [AnyHashable: Any] = [:] + + // MARK: - STPBankAccountStatus + class func stringToStatusMapping() -> [String: NSNumber] { + return [ + "new": NSNumber(value: STPBankAccountStatus.new.rawValue), + "validated": NSNumber(value: STPBankAccountStatus.validated.rawValue), + "verified": NSNumber(value: STPBankAccountStatus.verified.rawValue), + "verification_failed": NSNumber( + value: STPBankAccountStatus.verificationFailed.rawValue + ), + "errored": NSNumber(value: STPBankAccountStatus.errored.rawValue), + ] + } + + @objc(statusFromString:) class func status(from string: String) -> STPBankAccountStatus { + let key = string.lowercased() + let statusNumber = self.stringToStatusMapping()[key] + + if let statusNumber = statusNumber { + return (STPBankAccountStatus(rawValue: statusNumber.intValue))! + } + + return .new + } + + @objc(stringFromStatus:) class func string(from status: STPBankAccountStatus) -> String? { + return + (self.stringToStatusMapping() as NSDictionary).allKeys( + for: NSNumber(value: status.rawValue) + ) + .first as? String + } + + // MARK: - Equality + /// :nodoc: + @objc + public override func isEqual(_ bankAccount: Any?) -> Bool { + return isEqual(to: bankAccount as? STPBankAccount) + } + + /// :nodoc: + @objc public override var hash: Int { + return stripeID.hash + } + + func isEqual(to bankAccount: STPBankAccount?) -> Bool { + guard let bankAccount = bankAccount else { + return false + } + + return stripeID == bankAccount.stripeID + } + + // MARK: - Description + /// :nodoc: + @objc public override var description: String { + let props = [ + // Object + String(format: "%@: %p", NSStringFromClass(STPBankAccount.self), self), + // Identifier + "stripeID = \(stripeID)", + // Basic account details + "routingNumber = \(routingNumber ?? "")", + "last4 = \(last4 ?? "")", + // Additional account details (alphabetical) + "bankName = \(bankName ?? "")", + "country = \(country ?? "")", + "currency = \(currency ?? "")", + "fingerprint = \(fingerprint ?? "")", + "status = \(STPBankAccount.string(from: status) ?? "")", + // Owner details + "accountHolderName = \(((accountHolderName) != nil ? "" : nil) ?? "")", + "accountHolderType = \(STPBankAccountParams.string(from: accountHolderType))", + ] + + return "<\(props.joined(separator: "; "))>" + } + + // MARK: - STPAPIResponseDecodable + @objc + public class func decodedObject(fromAPIResponse response: [AnyHashable: Any]?) -> Self? { + guard let response = response else { + return nil + } + let dict = response.stp_dictionaryByRemovingNulls() + + // required fields + guard let stripeId = dict.stp_string(forKey: "id"), + let last4 = dict.stp_string(forKey: "last4"), + let bankName = dict.stp_string(forKey: "bank_name"), + let country = dict.stp_string(forKey: "country"), + let currency = dict.stp_string(forKey: "currency"), + let rawStatus = dict.stp_string(forKey: "status") + else { + return nil + } + + let bankAccount = self.init() + + // Identifier + bankAccount.stripeID = stripeId + + // Basic account details + bankAccount.routingNumber = dict.stp_string(forKey: "routing_number") + bankAccount.last4 = last4 + + // Additional account details (alphabetical) + bankAccount.bankName = bankName + bankAccount.country = country + bankAccount.currency = currency + bankAccount.fingerprint = dict.stp_string(forKey: "fingerprint") + bankAccount.status = self.status(from: rawStatus) + + // Owner details + bankAccount.accountHolderName = dict.stp_string(forKey: "account_holder_name") + let rawAccountHolderType = dict.stp_string(forKey: "account_holder_type") + bankAccount.accountHolderType = STPBankAccountParams.accountHolderType( + from: rawAccountHolderType ?? "" + ) + + bankAccount.allResponseFields = dict + + return bankAccount + } +} diff --git a/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/Sources/Types/STPBankAccountParams.swift b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/Sources/Types/STPBankAccountParams.swift new file mode 100644 index 0000000..c34109f --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/Sources/Types/STPBankAccountParams.swift @@ -0,0 +1,128 @@ +// +// STPBankAccountParams.swift +// StripePayments +// +// Created by Jack Flintermann on 10/4/15. +// Copyright © 2015 Stripe, Inc. All rights reserved. +// + +import Foundation + +/// The type of entity that holds a bank account. +@objc public enum STPBankAccountHolderType: Int { + /// An individual holds this bank account. + case individual + /// A company holds this bank account. + case company +} + +/// Representation of a user's bank account details. You can assemble these with +/// information that your user enters and then create Stripe tokens with them using +/// an STPAPIClient. +/// - seealso: https://stripe.com/docs/api#create_bank_account_token +public class STPBankAccountParams: NSObject, STPFormEncodable { + /// The account number for the bank account. Currently must be a checking account. + @objc public var accountNumber: String? + /// The last 4 digits of the bank account's account number, if it's been set, + /// otherwise nil. + + @objc public var last4: String? { + if accountNumber != nil && (accountNumber?.count ?? 0) >= 4 { + return (accountNumber as NSString?)?.substring(from: (accountNumber?.count ?? 0) - 4) + ?? "" + } else { + return nil + } + } + /// The routing number for the bank account. This should be the ACH routing number, + /// not the wire routing number. + @objc public var routingNumber: String? + /// Two-letter ISO code representing the country the bank account is located in. + @objc public var country: String? + /// The default currency for the bank account. + @objc public var currency: String? + /// The name of the person or business that owns the bank account. + @objc public var accountHolderName: String? + /// The type of entity that holds the account. + /// Defaults to STPBankAccountHolderTypeIndividual. + @objc public var accountHolderType: STPBankAccountHolderType = .individual + + @objc public var additionalAPIParameters: [AnyHashable: Any] = [:] + + /// Initializes an empty STPBankAccountParams. + public override init() { + super.init() + additionalAPIParameters = [:] + accountHolderType = .individual + } + + // MARK: - STPBankAccountHolderType + static var stringToAccountHolderTypeMapping: [String: STPBankAccountHolderType] = [ + "individual": .individual, + "company": .company, + ] + + @objc(accountHolderTypeFromString:) class func accountHolderType( + from string: String + ) + -> STPBankAccountHolderType + { + let key = string.lowercased() + return self.stringToAccountHolderTypeMapping[key] ?? .individual + } + + @objc(stringFromAccountHolderType:) class func string( + from accountHolderType: STPBankAccountHolderType + ) -> String { + guard + let stringTuple = self.stringToAccountHolderTypeMapping.filter({ + return $0.1 == accountHolderType + }).first?.0 + else { + return "individual" + } + return stringTuple + } + + // MARK: - Description + /// :nodoc: + @objc public override var description: String { + let props = [ + // Object + String(format: "%@: %p", NSStringFromClass(STPBankAccountParams.self), self), + // Basic account details + "routingNumber = \(routingNumber ?? "")", + "last4 = \(last4 ?? "")", + // Additional account details (alphabetical) + "country = \(country ?? "")", + "currency = \(currency ?? "")", + // Owner details + "accountHolderName = \(((accountHolderName) != nil ? "" : nil) ?? "")", + "accountHolderType = \(STPBankAccountParams.string(from: accountHolderType))", + ] + + return "<\(props.joined(separator: "; "))>" + } + + // MARK: - STPFormEncodable + @objc + public class func rootObjectName() -> String? { + return "bank_account" + } + + @objc + public class func propertyNamesToFormFieldNamesMapping() -> [String: String] { + return [ + NSStringFromSelector(#selector(getter:accountNumber)): "account_number", + NSStringFromSelector(#selector(getter:routingNumber)): "routing_number", + NSStringFromSelector(#selector(getter:country)): "country", + NSStringFromSelector(#selector(getter:currency)): "currency", + NSStringFromSelector(#selector(getter:accountHolderName)): "account_holder_name", + NSStringFromSelector(#selector(accountHolderTypeString)): "account_holder_type", + ] + } + + @objc func accountHolderTypeString() -> String { + return STPBankAccountParams.string(from: accountHolderType) + } +} diff --git a/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/Sources/Types/STPCard.swift b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/Sources/Types/STPCard.swift new file mode 100644 index 0000000..2936583 --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/Sources/Types/STPCard.swift @@ -0,0 +1,338 @@ +// +// STPCard.swift +// StripePayments +// +// Created by Saikat Chakrabarti on 11/2/12. +// Copyright © 2012 Stripe, Inc. All rights reserved. +// + +import Foundation +import UIKit + +/// The various funding sources for a payment card. +@objc +public enum STPCardFundingType: Int { + /// Debit card funding + case debit + /// Credit card funding + case credit + /// Prepaid card funding + case prepaid + /// An other or unknown type of funding source. + case other +} + +/// Representation of a user's credit card details that have been tokenized with +/// the Stripe API +/// - seealso: https://stripe.com/docs/api#cards +public class STPCard: NSObject, STPAPIResponseDecodable, STPSourceProtocol { + /// The last 4 digits of the card. + @objc public internal(set) var last4: String + /// For cards made with Apple Pay, this refers to the last 4 digits of the + /// "Device Account Number" for the tokenized card. For regular cards, it will + /// be nil. + @objc public internal(set) var dynamicLast4: String? + /// Whether or not the card originated from Apple Pay. + + @objc public var isApplePayCard: Bool { + return (allResponseFields["tokenization_method"] as? String) == "apple_pay" + } + /// The card's expiration month. 1-indexed (i.e. 1 == January) + @objc public internal(set) var expMonth = 0 + /// The card's expiration year. + @objc public internal(set) var expYear = 0 + /// The cardholder's name. + @objc public internal(set) var name: String? + /// The cardholder's address. + @objc public internal(set) var address: STPAddress? + /// The issuer of the card. + @objc public internal(set) var brand: STPCardBrand = .unknown + /// The funding source for the card (credit, debit, prepaid, or other) + @objc public internal(set) var funding: STPCardFundingType = .other + /// Two-letter ISO code representing the issuing country of the card. + @objc public internal(set) var country: String? + /// This is only applicable when tokenizing debit cards to issue payouts to managed + /// accounts. You should not set it otherwise. The card can then be used as a + /// transfer destination for funds in this currency. + @objc public internal(set) var currency: String? + + /// Returns a string representation for the provided card brand; + /// i.e. `STPCard.string(from brand: .visa) == "Visa"`. + /// - Parameter brand: the brand you want to convert to a string + /// - Returns: A string representing the brand, suitable for displaying to a user. + @objc(stringFromBrand:) + public class func string(from brand: STPCardBrand) -> String { + return STPCardBrandUtilities.stringFrom(brand) ?? "" + } + + /// This parses a string representing a card's brand into the appropriate + /// STPCardBrand enum value, + /// i.e. `STPCard.brand(from string: "American Express") == .amex`. + /// The string values themselves are specific to Stripe as listed in the Stripe API + /// documentation. + /// - seealso: https://stripe.com/docs/api#card_object-brand + /// - Parameter string: a string representing the card's brand as returned from + /// the Stripe API + /// - Returns: an enum value mapped to that string. If the string is unrecognized, + /// returns STPCardBrandUnknown. + @objc(brandFromString:) + public class func brand(from string: String) -> STPCardBrand { + // Documentation: https://stripe.com/docs/api#card_object-brand + let brand = string.lowercased() + if brand == "visa" { + return .visa + } else if (brand == "american express") || (brand == "american_express") { + return .amex + } else if brand == "mastercard" { + return .mastercard + } else if brand == "discover" { + return .discover + } else if brand == "jcb" { + return .JCB + } else if (brand == "diners club") || (brand == "diners_club") { + return .dinersClub + } else if brand == "unionpay" { + return .unionPay + } else { + return .unknown + } + } + + /// Create an STPCard from a Stripe API response. + /// - Parameters: + /// - cardID: The Stripe ID of the card, e.g. `card_185iQx4JYtv6MPZKfcuXwkOx` + /// - brand: The brand of the card (e.g. "Visa". To obtain this enum value + /// from a string, use `STPCardBrand.brand(from string:string)`; + /// - last4: The last 4 digits of the card, e.g. 4242 + /// - expMonth: The card's expiration month, 1-indexed (i.e. 1 = January) + /// - expYear: The card's expiration year + /// - funding: The card's funding type (credit, debit, or prepaid). To obtain + /// this enum value from a string, use `STPCardBrand.funding(from string:)`. + /// - Returns: an STPCard instance populated with the provided values. + @available( + *, + deprecated, + message: + "You cannot directly instantiate an STPCard. You should only use one that has been returned from an STPAPIClient callback." + ) + @objc(initWithID:brand:last4:expMonth:expYear:funding:) + public init( + id cardID: String, + brand: STPCardBrand, + last4: String, + expMonth: Int, + expYear: Int, + funding: STPCardFundingType + ) { + self.stripeID = cardID + self.brand = brand + self.last4 = last4 + super.init() + self.expMonth = expMonth + self.expYear = expYear + self.funding = funding + address = STPAddress() + } + + /// This parses a string representing a card's funding type into the appropriate + /// `STPCardFundingType` enum value, + /// i.e. `STPCard.funding(from string:"prepaid") == .prepaid`. + /// - Parameter string: a string representing the card's funding type as returned from + /// the Stripe API + /// - Returns: an enum value mapped to that string. If the string is unrecognized, + /// returns `STPCardFundingTypeOther`. + @objc(fundingFromString:) + public class func funding(from string: String) -> STPCardFundingType { + let key = string.lowercased() + let fundingNumber = self.stringToFundingMapping()[key] + + if let fundingNumber = fundingNumber { + return (STPCardFundingType(rawValue: fundingNumber.intValue))! + } + + return .other + } + + @objc public var stripeID: String + internal(set) public var allResponseFields: [AnyHashable: Any] = [:] + + // See STPCard+Private.h + + // MARK: - STPCardBrand + + // MARK: - STPCardFundingType + class func stringToFundingMapping() -> [String: NSNumber] { + return [ + "credit": NSNumber(value: STPCardFundingType.credit.rawValue), + "debit": NSNumber(value: STPCardFundingType.debit.rawValue), + "prepaid": NSNumber(value: STPCardFundingType.prepaid.rawValue), + ] + } + + class func string(fromFunding funding: STPCardFundingType) -> String? { + return + (self.stringToFundingMapping() as NSDictionary).allKeys( + for: NSNumber(value: funding.rawValue) + ).first as? String + } + + // MARK: - + + // MARK: - Equality + /// :nodoc: + @objc + public override func isEqual(_ other: Any?) -> Bool { + return isEqual(to: other as? STPCard) + } + + /// :nodoc: + @objc public override var hash: Int { + return stripeID.hash + } + + func isEqual(to other: STPCard?) -> Bool { + if self === other { + return true + } + + if other == nil || !(other != nil) { + return false + } + + return stripeID == other?.stripeID + } + + // MARK: - Description + /// :nodoc: + @objc public override var description: String { + let props = [ + // Object + String(format: "%@: %p", NSStringFromClass(STPCard.self), self), + // Identifier + "stripeID = \(stripeID )", + // Basic card details + "brand = \(STPCard.string(from: brand))", + "last4 = \(last4 )", + String(format: "expMonth = %lu", UInt(expMonth)), + String(format: "expYear = %lu", UInt(expYear)), + "funding = \((STPCard.string(fromFunding: funding)) ?? "unknown")", + // Additional card details (alphabetical) + "country = \(country ?? "")", + "currency = \(currency ?? "")", + "dynamicLast4 = \(dynamicLast4 ?? "")", + "isApplePayCard = \((isApplePayCard) ? "YES" : "NO")", + // Cardholder details + "name = \(((name) != nil ? "" : nil) ?? "")", + "address = \(((address) != nil ? "" : nil) ?? "")", + ] + + return "<\(props.joined(separator: "; "))>" + } + + // MARK: - STPAPIResponseDecodable + @objc func stripeObject() -> String { + return "card" + } + + required init( + stripeID: String, + last4: String + ) { + self.stripeID = stripeID + self.last4 = last4 + super.init() + } + + @objc + public class func decodedObject(fromAPIResponse response: [AnyHashable: Any]?) -> Self? { + guard let response = response else { + return nil + } + let dict = response.stp_dictionaryByRemovingNulls() + + // required fields + guard let stripeId = dict.stp_string(forKey: "id"), + let last4 = dict.stp_string(forKey: "last4"), + let rawBrand = dict.stp_string(forKey: "brand"), + dict.stp_number(forKey: "exp_month") != nil, + dict.stp_number(forKey: "exp_year") != nil + else { + return nil + } + + let card = self.init(stripeID: stripeId, last4: last4) + card.address = STPAddress() + + card.stripeID = stripeId + card.name = dict.stp_string(forKey: "name") + card.last4 = last4 + card.dynamicLast4 = dict.stp_string(forKey: "dynamic_last4") + card.brand = self.brand(from: rawBrand) + let rawFunding = dict.stp_string(forKey: "funding") + card.funding = self.funding(from: rawFunding ?? "") + + card.country = dict.stp_string(forKey: "country") + card.currency = dict.stp_string(forKey: "currency") + card.expMonth = dict.stp_int(forKey: "exp_month", or: 0) + card.expYear = dict.stp_int(forKey: "exp_year", or: 0) + + card.address?.name = card.name + card.address?.line1 = dict.stp_string(forKey: "address_line1") + card.address?.line2 = dict.stp_string(forKey: "address_line2") + card.address?.city = dict.stp_string(forKey: "address_city") + card.address?.state = dict.stp_string(forKey: "address_state") + card.address?.postalCode = dict.stp_string(forKey: "address_zip") + card.address?.country = dict.stp_string(forKey: "address_country") + + card.allResponseFields = response + return card + } + + // MARK: - Deprecated methods + + /// A set of key/value pairs associated with the card object. + /// @deprecated Metadata is no longer returned to clients using publishable keys. Retrieve them on your server using yoursecret key instead. + /// - seealso: https://stripe.com/docs/api#metadata + @available( + *, + deprecated, + message: + "Metadata is no longer returned to clients using publishable keys. Retrieve them on your server using yoursecret key instead." + ) + @objc public private(set) var metadata: [String: String]? + /// The Stripe ID for the card. + @available(*, deprecated, message: "Use stripeID (defined in STPSourceProtocol)") + @objc public var cardId: String? { + return stripeID + } + /// The first line of the cardholder's address + @available(*, deprecated, message: "Use address.line1") + @objc public var addressLine1: String? { + return address?.line1 + } + /// The second line of the cardholder's address + @available(*, deprecated, message: "Use address.line2") + @objc public var addressLine2: String? { + return address?.line2 + } + /// The city of the cardholder's address + @available(*, deprecated, message: "Use address.city") + @objc public var addressCity: String? { + return address?.city + } + /// The state of the cardholder's address + @available(*, deprecated, message: "Use address.state") + @objc public var addressState: String? { + return address?.state + } + /// The zip code of the cardholder's address + @available(*, deprecated, message: "Use address.postalCode") + @objc public var addressZip: String? { + return address?.postalCode + } + /// The country of the cardholder's address + @available(*, deprecated, message: "Use address.country") + @objc public var addressCountry: String? { + return address?.country + } +} diff --git a/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/Sources/Types/STPCardParams.swift b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/Sources/Types/STPCardParams.swift new file mode 100644 index 0000000..f5a6cb8 --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/Sources/Types/STPCardParams.swift @@ -0,0 +1,212 @@ +// +// STPCardParams.swift +// StripePayments +// +// Created by Jack Flintermann on 10/4/15. +// Copyright © 2015 Stripe, Inc. All rights reserved. +// + +import Foundation + +/// Representation of a user's credit card details. You can assemble these with +/// information that your user enters and then create Stripe tokens with them using +/// an STPAPIClient. +/// - seealso: https://stripe.com/docs/api#cards +public class STPCardParams: NSObject, STPFormEncodable, NSCopying { + public var additionalAPIParameters: [AnyHashable: Any] = [:] + + /// A convenience initializer for creating a card params from a card payment method params. + @objc public convenience init( + paymentMethodParams: STPPaymentMethodParams + ) { + self.init() + number = paymentMethodParams.card?.number + expMonth = paymentMethodParams.card?.expMonth as? UInt ?? 0 + expYear = paymentMethodParams.card?.expYear as? UInt ?? 0 + cvc = paymentMethodParams.card?.cvc + name = paymentMethodParams.billingDetails?.name + addressLine1 = paymentMethodParams.billingDetails?.address?.line1 + addressLine2 = paymentMethodParams.billingDetails?.address?.line2 + addressZip = paymentMethodParams.billingDetails?.address?.postalCode + addressCity = paymentMethodParams.billingDetails?.address?.city + addressState = paymentMethodParams.billingDetails?.address?.state + addressCountry = paymentMethodParams.billingDetails?.address?.country + } + + /// The card's number. + @objc public var number: String? + + /// The last 4 digits of the card's number, if it's been set, otherwise nil. + @objc + public func last4() -> String? { + if number != nil && (number?.count ?? 0) >= 4 { + return (number as NSString?)?.substring(from: (number?.count ?? 0) - 4) + } else { + return nil + } + } + + /// The card's expiration month. + @objc public var expMonth: UInt = 0 + /// The card's expiration year. + @objc public var expYear: UInt = 0 + /// The card's security code, found on the back. + @objc public var cvc: String? + + /// The cardholder's name. + /// @note Changing this property will also changing the name of the + /// param's `address` property. + @objc public var name: String? { + didSet { + address.name = name + } + } + + /// The cardholder's address. + /// @note Setting `address` to a new value will also change the `name` property to + /// be the value of `address.name`. However, changing `address.name` directly will + ///not* change `name`. + @objc public var address: STPAddress { + didSet { + name = address.name + } + } + /// Three-letter ISO currency code representing the currency paid out to the bank + /// account. This is only applicable when tokenizing debit cards to issue payouts + /// to managed accounts. You should not set it otherwise. The card can then be + /// used as a transfer destination for funds in this currency. + @objc public var currency: String? + + // MARK: - Deprecated methods + + /// The first line of the cardholder's address + @objc public var addressLine1: String? { + get { + return address.line1 + } + set(addressLine1) { + address.line1 = addressLine1 + } + } + + /// The second line of the cardholder's address + @objc public var addressLine2: String? { + get { + return address.line2 + } + set(addressLine2) { + address.line2 = addressLine2 + } + } + + /// The city of the cardholder's address + @objc public var addressCity: String? { + get { + return address.city + } + set(addressCity) { + address.city = addressCity + } + } + + /// The state of the cardholder's address + @objc public var addressState: String? { + get { + return address.state + } + set(addressState) { + address.state = addressState + } + } + + /// The zip code of the cardholder's address + @objc public var addressZip: String? { + get { + return address.postalCode + } + set(addressZip) { + address.postalCode = addressZip + } + } + + /// The country of the cardholder's address + @objc public var addressCountry: String? { + get { + return address.country + } + set(addressCountry) { + address.country = addressCountry + } + } + + /// Initializes an empty STPCardParams. + public override init() { + address = STPAddress() + super.init() + additionalAPIParameters = [:] + } + + // MARK: - Description + /// :nodoc: + @objc public override var description: String { + let props = [ + // Object + String(format: "%@: %p", NSStringFromClass(STPCardParams.self), self), + // Basic card details + "last4 = \(last4() ?? "")", + String(format: "expMonth = %lu", UInt(expMonth)), + String(format: "expYear = %lu", UInt(expYear)), + "cvc = \(((cvc) != nil ? "" : nil) ?? "")", + // Additional card details (alphabetical) + "currency = \(currency ?? "")", + // Cardholder details + "name = \(((name) != nil ? "" : nil) ?? "")", + "address = ", + ] + + return "<\(props.joined(separator: "; "))>" + } + + // MARK: - STPFormEncodable + public class func rootObjectName() -> String? { + return "card" + } + + public class func propertyNamesToFormFieldNamesMapping() -> [String: String] { + return [ + NSStringFromSelector(#selector(getter:number)): "number", + NSStringFromSelector(#selector(getter:cvc)): "cvc", + NSStringFromSelector(#selector(getter:name)): "name", + NSStringFromSelector(#selector(getter:addressLine1)): "address_line1", + NSStringFromSelector(#selector(getter:addressLine2)): "address_line2", + NSStringFromSelector(#selector(getter:addressCity)): "address_city", + NSStringFromSelector(#selector(getter:addressState)): "address_state", + NSStringFromSelector(#selector(getter:addressZip)): "address_zip", + NSStringFromSelector(#selector(getter:addressCountry)): "address_country", + NSStringFromSelector(#selector(getter:expMonth)): "exp_month", + NSStringFromSelector(#selector(getter:expYear)): "exp_year", + NSStringFromSelector(#selector(getter:currency)): "currency", + ] + } + + // MARK: - NSCopying + /// :nodoc: + @objc + public func copy(with zone: NSZone? = nil) -> Any { + let copyCardParams = STPCardParams() + + copyCardParams.number = number + copyCardParams.expMonth = expMonth + copyCardParams.expYear = expYear + copyCardParams.cvc = cvc + + // Use ivar to avoid setName:/setAddress: behavior that'd possibly overwrite name/address.name + copyCardParams.name = name + copyCardParams.address = address.copy() as! STPAddress + + copyCardParams.currency = currency + copyCardParams.additionalAPIParameters = additionalAPIParameters + + return copyCardParams + } +} diff --git a/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/Sources/Types/STPKlarnaLineItem.swift b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/Sources/Types/STPKlarnaLineItem.swift new file mode 100644 index 0000000..ac688e3 --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/Sources/Types/STPKlarnaLineItem.swift @@ -0,0 +1,54 @@ +// +// STPKlarnaLineItem.swift +// StripePayments +// +// Created by David Estes on 11/19/19. +// Copyright © 2019 Stripe, Inc. All rights reserved. +// + +import Foundation + +/// The type of the Klarna line item. +@objc public enum STPKlarnaLineItemType: Int { + /// The line item for a product + case SKU + /// The line item for taxes + case tax + /// The line item for shipping costs + case shipping +} + +/// An object representing a line item in a Klarna source. +/// - seealso: https://stripe.com/docs/sources/klarna#create-source +public class STPKlarnaLineItem: NSObject { + /// The line item's type. One of `sku` (for a product), `tax` (for taxes), or `shipping` (for shipping costs). + @objc public var itemType: STPKlarnaLineItemType + /// The human-readable description for the line item. + @objc public var itemDescription: String + /// The quantity to display for this line item. + @objc public var quantity: NSNumber + /// The total price of this line item. + /// Note: This is the total price after multiplying by the quantity, not + /// the price of an individual item. It is denominated in the currency + /// of the STPSourceParams which contains it. + @objc public var totalAmount: NSNumber + + /// Initialize this `STPKlarnaLineItem` with a set of parameters. + /// - Parameters: + /// - itemType: The line item's type. + /// - itemDescription: The human-readable description for the line item. + /// - quantity: The quantity to display for this line item. + /// - totalAmount: The total price of this line item. + @objc + public init( + itemType: STPKlarnaLineItemType, + itemDescription: String, + quantity: NSNumber, + totalAmount: NSNumber + ) { + self.itemType = itemType + self.itemDescription = itemDescription + self.quantity = quantity + self.totalAmount = totalAmount + } +} diff --git a/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/Sources/Types/STPSourceCardDetails.swift b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/Sources/Types/STPSourceCardDetails.swift new file mode 100644 index 0000000..f506419 --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/Sources/Types/STPSourceCardDetails.swift @@ -0,0 +1,135 @@ +// +// STPSourceCardDetails.swift +// StripePayments +// +// Created by Brian Dorfman on 2/23/17. +// Copyright © 2017 Stripe, Inc. All rights reserved. +// + +import Foundation + +/// The status of this card's 3D Secure support. +/// - seealso: https://stripe.com/docs/sources/three-d-secure#check-requirement +@objc +public enum STPSourceCard3DSecureStatus: Int { + /// 3D Secure is required. This card must be converted into a 3D Secure + /// source for a charge on it to be successful. + case `required` + /// 3D Secure is optional. It is not required nor recommended for successful charging, + /// but can be performed to help reduce the likelihood of fraud. + case `optional` + /// 3D Secure is not supported on this card. + case notSupported + /// 3D Secure is recommended. The process is not required, but it is highly recommended + /// and has minimal impact to your conversion rate. + case recommended + /// The status of 3D Secure support on this card is unknown. + case unknown +} + +/// This class provides typed access to the contents of an STPSource `details` +/// dictionary for card sources. +public class STPSourceCardDetails: NSObject, STPAPIResponseDecodable { + /// The last 4 digits of the card. + @objc public private(set) var last4: String? + /// The card's expiration month. 1-indexed (i.e. 1 == January) + @objc public private(set) var expMonth: UInt = 0 + /// The card's expiration year. + @objc public private(set) var expYear: UInt = 0 + /// The issuer of the card. + @objc public private(set) var brand: STPCardBrand = .unknown + /// The funding source for the card (credit, debit, prepaid, or other) + @objc public private(set) var funding: STPCardFundingType = .other + /// Two-letter ISO code representing the issuing country of the card. + @objc public private(set) var country: String? + /// Whether 3D Secure is supported or required by the card. + @objc public private(set) var threeDSecure: STPSourceCard3DSecureStatus = .unknown + /// True if this card was created through Apple Pay, false otherwise. + @objc public private(set) var isApplePayCard = false + @objc public private(set) var allResponseFields: [AnyHashable: Any] = [:] + + // See STPSourceCardDetails+Private.h + + // MARK: - STPAPIResponseDecodable + public class func decodedObject(fromAPIResponse response: [AnyHashable: Any]?) -> Self? { + guard let response = response else { + return nil + } + return self.init(dictionary: response) + } + + required init( + dictionary dict: [AnyHashable: Any] + ) { + allResponseFields = dict + let dict = dict.stp_dictionaryByRemovingNulls() + last4 = dict.stp_string(forKey: "last4") + brand = STPCard.brand(from: dict.stp_string(forKey: "brand") ?? "") + //#pragma clang diagnostic push + //#pragma clang diagnostic ignored "-Wdeprecated" + // This is only intended to be deprecated publicly. + // When removed from public header, can remove these pragmas + funding = STPCard.funding(from: dict.stp_string(forKey: "funding") ?? "") + //#pragma clang diagnostic pop + country = dict.stp_string(forKey: "country") + expMonth = UInt(dict.stp_int(forKey: "exp_month", or: 0)) + expYear = UInt(dict.stp_int(forKey: "exp_year", or: 0)) + threeDSecure = STPSourceCardDetails.threeDSecureStatus( + from: dict.stp_string(forKey: "three_d_secure") ?? "" + ) + isApplePayCard = dict.stp_string(forKey: "tokenization_method") == "apple_pay" + super.init() + } + + // MARK: - STPSourceCard3DSecureStatus + class func stringToThreeDSecureStatusMapping() -> [String: NSNumber] { + return [ + "required": NSNumber(value: STPSourceCard3DSecureStatus.`required`.rawValue), + "optional": NSNumber(value: STPSourceCard3DSecureStatus.`optional`.rawValue), + "not_supported": NSNumber(value: STPSourceCard3DSecureStatus.notSupported.rawValue), + "recommended": NSNumber(value: STPSourceCard3DSecureStatus.recommended.rawValue), + ] + } + + class func threeDSecureStatus(from string: String) -> STPSourceCard3DSecureStatus { + let key = string.lowercased() + let threeDSecureStatusNumber = self.stringToThreeDSecureStatusMapping()[key] + + if let threeDSecureStatusNumber = threeDSecureStatusNumber { + return (STPSourceCard3DSecureStatus(rawValue: threeDSecureStatusNumber.intValue))! + } + + return .unknown + } + + class func string( + fromThreeDSecureStatus threeDSecureStatus: STPSourceCard3DSecureStatus + ) + -> String? + { + return + (self.stringToThreeDSecureStatusMapping() as NSDictionary).allKeys( + for: NSNumber(value: threeDSecureStatus.rawValue) + ).first as? String + } + + // MARK: - Description + /// :nodoc: + @objc public override var description: String { + let props = [ + // Object + String(format: "%@: %p", NSStringFromClass(STPSourceCardDetails.self), self), + // Basic card details + "brand = \(STPCard.string(from: brand))", + "last4 = \(last4 ?? "")", + String(format: "expMonth = %lu", UInt(expMonth)), + String(format: "expYear = %lu", UInt(expYear)), + "funding = \((STPCard.string(fromFunding: funding)) ?? "unknown")", + // Additional card details (alphabetical) + "country = \(country ?? "")", + "threeDSecure = \((STPSourceCardDetails.string(fromThreeDSecureStatus: threeDSecure)) ?? "unknown")", + ] + + return "<\(props.joined(separator: "; "))>" + } +} diff --git a/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/Sources/Types/STPSourceKlarnaDetails.swift b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/Sources/Types/STPSourceKlarnaDetails.swift new file mode 100644 index 0000000..c92eed1 --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/Sources/Types/STPSourceKlarnaDetails.swift @@ -0,0 +1,50 @@ +// +// STPSourceKlarnaDetails.swift +// StripePayments +// +// Created by David Estes on 11/19/19. +// Copyright © 2019 Stripe, Inc. All rights reserved. +// + +import Foundation + +/// Details of a Klarna source. +public class STPSourceKlarnaDetails: NSObject, STPAPIResponseDecodable { + /// The Klarna-specific client token. This may be used with the Klarna SDK. + /// - seealso: https://developers.klarna.com/documentation/in-app/ios/steps-klarna-payments-native/#initialization + @objc public private(set) var clientToken: String? + /// The ISO-3166 2-letter country code of the customer's location. + @objc public private(set) var purchaseCountry: String? + private(set) public var allResponseFields: [AnyHashable: Any] = [:] + + // MARK: - Description + /// :nodoc: + @objc public override var description: String { + let props = [ + String(format: "%@: %p", NSStringFromClass(STPSourceKlarnaDetails.self), self), + "clientToken = \(clientToken ?? "")", + "purchaseCountry = \(purchaseCountry ?? "")", + ] + + return "<\(props.joined(separator: "; "))>" + } + + // MARK: - STPAPIResponseDecodable + override required init() { + super.init() + } + + @objc + public class func decodedObject(fromAPIResponse response: [AnyHashable: Any]?) -> Self? { + guard let response = response else { + return nil + } + let dict = response.stp_dictionaryByRemovingNulls() + + let details = self.init() + details.clientToken = dict.stp_string(forKey: "client_token") + details.purchaseCountry = dict.stp_string(forKey: "purchase_country") + details.allResponseFields = response + return details + } +} diff --git a/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/Sources/Types/STPSourceSEPADebitDetails.swift b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/Sources/Types/STPSourceSEPADebitDetails.swift new file mode 100644 index 0000000..ec0037d --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/Sources/Types/STPSourceSEPADebitDetails.swift @@ -0,0 +1,74 @@ +// +// STPSourceSEPADebitDetails.swift +// StripePayments +// +// Created by Brian Dorfman on 2/24/17. +// Copyright © 2017 Stripe, Inc. All rights reserved. +// + +import Foundation + +/// This class provides typed access to the contents of an STPSource `details` +/// dictionary for SEPA Debit sources. +public class STPSourceSEPADebitDetails: NSObject, STPAPIResponseDecodable { + /// You cannot directly instantiate an `STPSourceSEPADebitDetails`. + /// You should only use one that is part of an existing `STPSource` object. + override init() { + } + + /// The last 4 digits of the account number. + @objc public private(set) var last4: String? + /// The account's bank code. + @objc public private(set) var bankCode: String? + /// Two-letter ISO code representing the country of the bank account. + @objc public private(set) var country: String? + /// The account's fingerprint. + @objc public private(set) var fingerprint: String? + /// The reference of the mandate accepted by your customer. + @objc public private(set) var mandateReference: String? + /// The details of the mandate accepted by your customer. + @objc public private(set) var mandateURL: URL? + @objc public private(set) var allResponseFields: [AnyHashable: Any] = [:] + + // MARK: - Description + /// :nodoc: + @objc public override var description: String { + let props = [ + // Object + String(format: "%@: %p", NSStringFromClass(STPSourceSEPADebitDetails.self), self), + // Basic SEPA debit details + "last4 = \(last4 ?? "")", + // Additional SEPA debit details (alphabetical) + "bankCode = \(bankCode ?? "")", + "country = \(country ?? "")", + "fingerprint = \(fingerprint ?? "")", + "mandateReference = \(mandateReference ?? "")", + "mandateURL = \(String(describing: mandateURL))", + ] + + return "<\(props.joined(separator: "; "))>" + } + + // MARK: - STPAPIResponseDecodable + public class func decodedObject(fromAPIResponse response: [AnyHashable: Any]?) -> Self? { + guard let response = response else { + return nil + } + return self.init(dictionary: response) + } + + required init( + dictionary dict: [AnyHashable: Any] + ) { + super.init() + allResponseFields = dict + let dict = dict.stp_dictionaryByRemovingNulls() + last4 = dict.stp_string(forKey: "last4") + bankCode = dict.stp_string(forKey: "bank_code") + country = dict.stp_string(forKey: "country") + fingerprint = dict.stp_string(forKey: "fingerprint") + mandateReference = dict.stp_string(forKey: "mandate_reference") + mandateURL = dict.stp_url(forKey: "mandate_url") + + } +} diff --git a/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/Sources/Types/STPSourceWeChatPayDetails.swift b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/Sources/Types/STPSourceWeChatPayDetails.swift new file mode 100644 index 0000000..da7b8f3 --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/Models/Sources/Types/STPSourceWeChatPayDetails.swift @@ -0,0 +1,44 @@ +// +// STPSourceWeChatPayDetails.swift +// StripePayments +// +// Created by Yuki Tokuhiro on 6/4/19. +// Copyright © 2019 Stripe, Inc. All rights reserved. +// + +import Foundation + +/// Details of a WeChat Pay Source. +public class STPSourceWeChatPayDetails: NSObject, STPAPIResponseDecodable { + /// A URL to the WeChat App. + /// Use `STPRedirectContext` instead of redirecting users yourself. + @objc public private(set) var weChatAppURL: String? + @objc public private(set) var allResponseFields: [AnyHashable: Any] = [:] + + // MARK: - Description + /// :nodoc: + @objc public override var description: String { + let props = [ + String(format: "%@: %p", NSStringFromClass(STPSourceWeChatPayDetails.self), self), + "weChatAppURL = \(weChatAppURL ?? "")", + ] + + return "<\(props.joined(separator: "; "))>" + } + + // MARK: - STPAPIResponseDecodable + public class func decodedObject(fromAPIResponse response: [AnyHashable: Any]?) -> Self? { + guard let response = response else { + return nil + } + let dict = response.stp_dictionaryByRemovingNulls() + let details = self.init() + details.weChatAppURL = dict.stp_string(forKey: "ios_native_url") + details.allResponseFields = response + return details + } + + override required init() { + super.init() + } +} diff --git a/Pods/StripePayments/StripePayments/StripePayments/API Bindings/STPAPIClient+ApplePay.swift b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/STPAPIClient+ApplePay.swift new file mode 100644 index 0000000..0116572 --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/STPAPIClient+ApplePay.swift @@ -0,0 +1,198 @@ +// +// STPAPIClient+ApplePay.swift +// StripePayments +// +// Created by Jack Flintermann on 12/19/14. +// Copyright © 2014 Stripe, Inc. All rights reserved. +// + +import Foundation +import PassKit +@_spi(STP) import StripeCore + +/// STPAPIClient extensions to create Stripe Tokens, Sources, or PaymentMethods from Apple Pay PKPayment objects. +extension STPAPIClient { + /// Converts a PKPayment object into a Stripe token using the Stripe API. + /// - Parameters: + /// - payment: The user's encrypted payment information as returned from a PKPaymentAuthorizationController. Cannot be nil. + /// - completion: The callback to run with the returned Stripe token (and any errors that may have occurred). + @objc(createTokenWithPayment:completion:) + public func createToken(with payment: PKPayment, completion: @escaping STPTokenCompletionBlock) + { + var params = payment.stp_tokenParameters(apiClient: self) + STPTelemetryClient.shared.addTelemetryFields(toParams: ¶ms) + createToken( + withParameters: params, + completion: completion + ) + STPTelemetryClient.shared.sendTelemetryData() + } + + /// Converts a PKPayment object into a Stripe source using the Stripe API. + /// - Parameters: + /// - payment: The user's encrypted payment information as returned from a PKPaymentAuthorizationController. Cannot be nil. + /// - completion: The callback to run with the returned Stripe source (and any errors that may have occurred). + @objc(createSourceWithPayment:completion:) + public func createSource( + with payment: PKPayment, + completion: @escaping STPSourceCompletionBlock + ) { + createToken(with: payment) { token, error in + if token?.tokenId == nil || error != nil { + completion(nil, error ?? NSError.stp_genericConnectionError()) + } else { + let params = STPSourceParams() + params.type = .card + params.token = token?.tokenId + self.createSource(with: params, completion: completion) + } + } + } + + /// Converts a PKPayment object into a Stripe Payment Method using the Stripe API. + /// - Parameters: + /// - payment: The user's encrypted payment information as returned from a PKPaymentAuthorizationController. Cannot be nil. + /// - completion: The callback to run with the returned Stripe source (and any errors that may have occurred). + @objc(createPaymentMethodWithPayment:completion:) + public func createPaymentMethod( + with payment: PKPayment, + completion: @escaping STPPaymentMethodCompletionBlock + ) { + createToken(with: payment) { token, error in + if token?.tokenId == nil || error != nil { + completion(nil, error ?? NSError.stp_genericConnectionError()) + } else { + let cardParams = STPPaymentMethodCardParams() + cardParams.token = token?.tokenId + let billingDetails = STPAPIClient.billingDetails(from: payment) + let paymentMethodParams = STPPaymentMethodParams( + card: cardParams, + billingDetails: billingDetails, + metadata: nil + ) + self.createPaymentMethod(with: paymentMethodParams, completion: completion) + } + } + + } + + class func billingDetails(from payment: PKPayment) -> STPPaymentMethodBillingDetails? { + var billingDetails: STPPaymentMethodBillingDetails? + if payment.billingContact != nil { + billingDetails = STPPaymentMethodBillingDetails() + var billingAddress: STPAddress? + if let billingContact = payment.billingContact { + billingAddress = STPAddress(pkContact: billingContact) + } + billingDetails?.name = billingAddress?.name + billingDetails?.email = billingAddress?.email + billingDetails?.phone = billingAddress?.phone + if payment.billingContact?.postalAddress != nil { + if let billingAddress = billingAddress { + billingDetails?.address = STPPaymentMethodAddress(address: billingAddress) + } + } + } + + // The phone number and email in the "Contact" panel in the Apple Pay dialog go into the shippingContact, + // not the billingContact. To work around this, we should fill the billingDetails' email and phone + // number from the shippingDetails. + if payment.shippingContact != nil { + var shippingAddress: STPAddress? + if let shippingContact = payment.shippingContact { + shippingAddress = STPAddress(pkContact: shippingContact) + } + if billingDetails?.email == nil && shippingAddress?.email != nil { + if billingDetails == nil { + billingDetails = STPPaymentMethodBillingDetails() + } + billingDetails?.email = shippingAddress?.email + } + if billingDetails?.phone == nil && shippingAddress?.phone != nil { + if billingDetails == nil { + billingDetails = STPPaymentMethodBillingDetails() + } + billingDetails?.phone = shippingAddress?.phone + } + } + + return billingDetails + } +} + +extension PKPayment { + func stp_tokenParameters(apiClient: STPAPIClient) -> [String: Any] { + let paymentString = String(data: self.token.paymentData, encoding: .utf8) + var payload: [String: Any] = [:] + payload["pk_token"] = paymentString + if let billingContact = self.billingContact { + payload["card"] = billingContact.addressParams + } + + assert( + !((paymentString?.count ?? 0) == 0 + && apiClient.publishableKey?.hasPrefix("pk_live") ?? false), + "The pk_token is empty. Using Apple Pay with an iOS Simulator while not in Stripe Test Mode will always fail." + ) + + let paymentInstrumentName = self.token.paymentMethod.displayName + if let paymentInstrumentName = paymentInstrumentName { + payload["pk_token_instrument_name"] = paymentInstrumentName + } + + let paymentNetwork = self.token.paymentMethod.network + if let paymentNetwork = paymentNetwork { + // Note: As of SDK 20.0.0, this will return `PKPaymentNetwork(_rawValue: MasterCard)`. + // We're intentionally leaving it this way: See RUN_MOBILESDK-125. + payload["pk_token_payment_network"] = paymentNetwork + } + + var transactionIdentifier = self.token.transactionIdentifier + if transactionIdentifier != "" { + if self.stp_isSimulated() { + transactionIdentifier = PKPayment.stp_testTransactionIdentifier() + } + payload["pk_token_transaction_id"] = transactionIdentifier + } + + return payload + } +} +extension PKContact { + @_spi(STP) public var addressParams: [AnyHashable: Any] { + var params: [AnyHashable: Any] = [:] + let stpAddress = STPAddress(pkContact: self) + + params["name"] = stpAddress.name + params["address_line1"] = stpAddress.line1 + params["address_city"] = stpAddress.city + params["address_state"] = stpAddress.state + params["address_zip"] = stpAddress.postalCode + params["address_country"] = stpAddress.country + + return params + } +} + +extension PKPayment { + /// Returns true if the instance is a payment from the simulator. + @_spi(STP) public func stp_isSimulated() -> Bool { + return token.transactionIdentifier == "Simulated Identifier" + } + + /// Returns a fake transaction identifier with the expected ~-separated format. + @_spi(STP) public class func stp_testTransactionIdentifier() -> String { + var uuid = UUID().uuidString + uuid = uuid.replacingOccurrences(of: "~", with: "") + + // Simulated cards don't have enough info yet. For now, use a fake Visa number + let number = "4242424242424242" + + // Without the original PKPaymentRequest, we'll need to use fake data here. + let amount = NSDecimalNumber(string: "0") + let cents = NSNumber(value: amount.multiplying(byPowerOf10: 2).intValue).stringValue + let currency = "USD" + let identifier = ["ApplePayStubs", number, cents, currency, uuid].joined(separator: "~") + return identifier + } +} diff --git a/Pods/StripePayments/StripePayments/StripePayments/API Bindings/STPAPIClient+LinkAccountSession.swift b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/STPAPIClient+LinkAccountSession.swift new file mode 100644 index 0000000..7ded227 --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/STPAPIClient+LinkAccountSession.swift @@ -0,0 +1,128 @@ +// +// STPAPIClient+LinkAccountSession.swift +// StripePayments +// +// Copyright © 2022 Stripe, Inc. All rights reserved. +// + +import Foundation +@_spi(STP) import StripeCore + +typealias STPLinkAccountSessionBlock = (LinkAccountSession?, Error?) -> Void +typealias STPLinkAccountSessionsAttachPaymentIntentBlock = (STPPaymentIntent?, Error?) -> Void +typealias STPLinkAccountSessionsAttachSetupIntentBlock = (STPSetupIntent?, Error?) -> Void + +extension STPAPIClient { + func createLinkAccountSession( + setupIntentID: String, + clientSecret: String, + paymentMethodType: STPPaymentMethodType, + customerName: String?, + customerEmailAddress: String?, + completion: @escaping STPLinkAccountSessionBlock + ) { + let endpoint: String = "setup_intents/\(setupIntentID)/link_account_sessions" + linkAccountSessions( + endpoint: endpoint, + clientSecret: clientSecret, + paymentMethodType: paymentMethodType, + customerName: customerName, + customerEmailAddress: customerEmailAddress, + completion: completion + ) + } + + func createLinkAccountSession( + paymentIntentID: String, + clientSecret: String, + paymentMethodType: STPPaymentMethodType, + customerName: String?, + customerEmailAddress: String?, + completion: @escaping STPLinkAccountSessionBlock + ) { + let endpoint: String = "payment_intents/\(paymentIntentID)/link_account_sessions" + linkAccountSessions( + endpoint: endpoint, + clientSecret: clientSecret, + paymentMethodType: paymentMethodType, + customerName: customerName, + customerEmailAddress: customerEmailAddress, + completion: completion + ) + + } + + // MARK: - Helper + private func linkAccountSessions( + endpoint: String, + clientSecret: String, + paymentMethodType: STPPaymentMethodType, + customerName: String?, + customerEmailAddress: String?, + completion: @escaping STPLinkAccountSessionBlock + ) { + var parameters: [String: Any] = [ + "client_secret": clientSecret + ] + if let paymentMethodType = STPPaymentMethod.string(from: paymentMethodType) { + parameters["payment_method_data[type]"] = paymentMethodType + } + if let customerName = customerName { + parameters["payment_method_data[billing_details][name]"] = customerName + } + if let customerEmailAddress = customerEmailAddress { + parameters["payment_method_data[billing_details][email]"] = customerEmailAddress + } + + APIRequest.post( + with: self, + endpoint: endpoint, + parameters: parameters + ) { linkAccountSession, _, error in + completion(linkAccountSession, error) + } + } + + func attachLinkAccountSession( + setupIntentID: String, + linkAccountSessionID: String, + clientSecret: String, + completion: @escaping STPLinkAccountSessionsAttachSetupIntentBlock + ) { + let endpoint: String = + "setup_intents/\(setupIntentID)/link_account_sessions/\(linkAccountSessionID)/attach" + let parameters: [String: Any] = [ + "client_secret": clientSecret, + "expand": ["payment_method"], + ] + APIRequest.post( + with: self, + endpoint: endpoint, + parameters: parameters + ) { setupIntent, _, error in + completion(setupIntent, error) + } + } + + func attachLinkAccountSession( + paymentIntentID: String, + linkAccountSessionID: String, + clientSecret: String, + completion: @escaping STPLinkAccountSessionsAttachPaymentIntentBlock + ) { + let endpoint: String = + "payment_intents/\(paymentIntentID)/link_account_sessions/\(linkAccountSessionID)/attach" + let parameters: [String: Any] = [ + "client_secret": clientSecret, + "expand": ["payment_method"], + ] + APIRequest.post( + with: self, + endpoint: endpoint, + parameters: parameters + ) { paymentIntent, _, error in + completion(paymentIntent, error) + } + } + +} diff --git a/Pods/StripePayments/StripePayments/StripePayments/API Bindings/STPAPIClient+Payments.swift b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/STPAPIClient+Payments.swift new file mode 100644 index 0000000..56cabc7 --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/STPAPIClient+Payments.swift @@ -0,0 +1,935 @@ +// +// STPAPIClient+Payments.swift +// StripePayments +// +// Created by Jack Flintermann on 12/18/14. +// Copyright (c) 2014 Stripe, Inc. All rights reserved. +// + +import Foundation +import PassKit +@_spi(STP) import StripeCore +import UIKit + +#if canImport(Stripe3DS2) + import Stripe3DS2 +#endif + +extension STPAPIClient { + // MARK: Tokens + + func createToken( + withParameters parameters: [String: Any], + completion: @escaping STPTokenCompletionBlock + ) { + let tokenType = STPAnalyticsClient.tokenType(fromParameters: parameters) + STPAnalyticsClient.sharedClient.logTokenCreationAttempt( + with: _stored_configuration, + tokenType: tokenType + ) + let preparedParameters = Self.paramsAddingPaymentUserAgent(parameters) + APIRequest.post( + with: self, + endpoint: APIEndpointToken, + parameters: preparedParameters + ) { object, _, error in + completion(object, error) + } + } +} + +// MARK: Bank Accounts + +/// STPAPIClient extensions to create Stripe tokens from bank accounts. +extension STPAPIClient { + /// Converts an STPBankAccount object into a Stripe token using the Stripe API. + /// - Parameters: + /// - bankAccount: The user's bank account details. Cannot be nil. - seealso: https://stripe.com/docs/api#create_bank_account_token + /// - completion: The callback to run with the returned Stripe token (and any errors that may have occurred). + @objc(createTokenWithBankAccount:completion:) + public func createToken( + withBankAccount bankAccount: STPBankAccountParams, + completion: @escaping STPTokenCompletionBlock + ) { + var params = STPFormEncoder.dictionary(forObject: bankAccount) + STPTelemetryClient.shared.addTelemetryFields(toParams: ¶ms) + createToken(withParameters: params, completion: completion) + STPTelemetryClient.shared.sendTelemetryData() + } +} + +// MARK: Personally Identifiable Information + +/// STPAPIClient extensions to create Stripe tokens from a personal identification number. +extension STPAPIClient { + /// Converts a personal identification number into a Stripe token using the Stripe API. + /// - Parameters: + /// - pii: The user's personal identification number. Cannot be nil. - seealso: https://stripe.com/docs/api#create_pii_token + /// - completion: The callback to run with the returned Stripe token (and any errors that may have occurred). + @objc(createTokenWithPersonalIDNumber:completion:) + public func createToken( + withPersonalIDNumber pii: String, + completion: STPTokenCompletionBlock? + ) { + var params: [String: Any] = [ + "pii": [ + "personal_id_number": pii + ] + ] + STPTelemetryClient.shared.addTelemetryFields(toParams: ¶ms) + if let completion = completion { + createToken(withParameters: params, completion: completion) + } + STPTelemetryClient.shared.sendTelemetryData() + } + + /// Converts the last 4 SSN digits into a Stripe token using the Stripe API. + /// - Parameters: + /// - ssnLast4: The last 4 digits of the user's SSN. Cannot be nil. + /// - completion: The callback to run with the returned Stripe token (and any errors that may have occurred). + @objc(createTokenWithSSNLast4:completion:) + public func createToken( + withSSNLast4 ssnLast4: String, + completion: @escaping STPTokenCompletionBlock + ) { + var params: [String: Any] = [ + "pii": [ + "ssn_last_4": ssnLast4 + ] + ] + STPTelemetryClient.shared.addTelemetryFields(toParams: ¶ms) + createToken(withParameters: params, completion: completion) + STPTelemetryClient.shared.sendTelemetryData() + } +} + +// MARK: Connect Accounts + +/// STPAPIClient extensions for working with Connect Accounts +extension STPAPIClient { + /// Converts an `STPConnectAccountParams` object into a Stripe token using the Stripe API. + /// This allows the connected account to accept the Terms of Service, and/or send Legal Entity information. + /// - Parameters: + /// - account: The Connect Account parameters. Cannot be nil. + /// - completion: The callback to run with the returned Stripe token (and any errors that may have occurred). + @objc(createTokenWithConnectAccount:completion:) + public func createToken( + withConnectAccount account: STPConnectAccountParams, + completion: STPTokenCompletionBlock? + ) { + var params = STPFormEncoder.dictionary(forObject: account) + STPTelemetryClient.shared.addTelemetryFields(toParams: ¶ms) + if let completion = completion { + createToken(withParameters: params, completion: completion) + } + STPTelemetryClient.shared.sendTelemetryData() + } +} + +// MARK: Upload + +/// STPAPIClient extensions to upload files. +extension STPAPIClient { + + /// Uses the Stripe file upload API to upload an image. This can be used for + /// identity verification and evidence disputes. + /// - Parameters: + /// - image: The image to be uploaded. The maximum allowed file size is 16MB + /// for identity documents and 5MB for evidence disputes. Cannot be nil. + /// Your image will be automatically resized down if you pass in one that + /// is too large + /// - purpose: The purpose of this file. This can be either an identifying + /// document or an evidence dispute. + /// - completion: The callback to run with the returned Stripe file + /// (and any errors that may have occurred). + /// - seealso: https://stripe.com/docs/file-upload + @objc(uploadImage:purpose:completion:) + public func uploadImage( + _ image: UIImage, + purpose: STPFilePurpose, + completion: STPFileCompletionBlock? + ) { + uploadImage(image, purpose: StripeFile.Purpose(from: purpose).rawValue) { result in + switch result { + case .success(let file): + completion?(file.toSTPFile, nil) + case .failure(let error): + completion?(nil, error) + } + } + } +} + +extension StripeFile.Purpose { + // NOTE: Avoid adding `default` to these switch statements. Instead, + // explicitly check each case. This helps compile-time enforce that we + // don't leave any cases out when more are added. + + init( + from purpose: STPFilePurpose + ) { + switch purpose { + case .identityDocument: + self = .identityDocument + case .disputeEvidence: + self = .disputeEvidence + case .unknown: + self = .unparsable + } + } + + var toSTPFilePurpose: STPFilePurpose { + switch self { + case .identityDocument: + return .identityDocument + case .disputeEvidence: + return .disputeEvidence + case .identityPrivate, + .unparsable: + return .unknown + } + } +} + +extension StripeFile { + var toSTPFile: STPFile { + return STPFile( + fileId: id, + created: created, + purpose: purpose.toSTPFilePurpose, + size: NSNumber(integerLiteral: size), + type: type + ) + } +} + +// MARK: Credit Cards + +/// STPAPIClient extensions to create Stripe tokens from credit or debit cards. +extension STPAPIClient { + /// Converts an STPCardParams object into a Stripe token using the Stripe API. + /// - Parameters: + /// - cardParams: The user's card details. Cannot be nil. - seealso: https://stripe.com/docs/api#create_card_token + /// - completion: The callback to run with the returned Stripe token (and any errors that may have occurred). + @objc(createTokenWithCard:completion:) + public func createToken( + withCard cardParams: STPCardParams, + completion: @escaping STPTokenCompletionBlock + ) { + var params = STPFormEncoder.dictionary(forObject: cardParams) + STPTelemetryClient.shared.addTelemetryFields(toParams: ¶ms) + createToken(withParameters: params, completion: completion) + STPTelemetryClient.shared.sendTelemetryData() + } + + /// Converts a CVC string into a Stripe token using the Stripe API. + /// - Parameters: + /// - cvc: The CVC/CVV number used to create the token. Cannot be nil. + /// - completion: The callback to run with the returned Stripe token (and any errors that may have occurred). + @objc(createTokenForCVCUpdate:completion:) + public func createToken(forCVCUpdate cvc: String, completion: STPTokenCompletionBlock? = nil) { + var params: [String: Any] = [ + "cvc_update": [ + "cvc": cvc + ] + ] + STPTelemetryClient.shared.addTelemetryFields(toParams: ¶ms) + if let completion = completion { + createToken(withParameters: params, completion: completion) + } + STPTelemetryClient.shared.sendTelemetryData() + } +} + +// MARK: Sources + +/// STPAPIClient extensions for working with Source objects +extension STPAPIClient { + /// Creates a Source object using the provided details. + /// Note: in order to create a source on a connected account, you can set your + /// API client's `stripeAccount` property to the ID of the account. + /// - seealso: https://stripe.com/docs/sources/connect#creating-direct-charges + /// - Parameters: + /// - sourceParams: The details of the source to create. Cannot be nil. - seealso: https://stripe.com/docs/api#create_source + /// - completion: The callback to run with the returned Source object, or an error. + @objc(createSourceWithParams:completion:) + public func createSource( + with sourceParams: STPSourceParams, + completion: @escaping STPSourceCompletionBlock + ) { + let sourceType = STPSource.string(from: sourceParams.type) + STPAnalyticsClient.sharedClient.logSourceCreationAttempt( + with: _stored_configuration, + sourceType: sourceType + ) + sourceParams.redirectMerchantName = Bundle.stp_applicationName() ?? "" + var params = STPFormEncoder.dictionary(forObject: sourceParams) + STPTelemetryClient.shared.addTelemetryFields(toParams: ¶ms) + params = Self.paramsAddingPaymentUserAgent(params) + APIRequest.post( + with: self, + endpoint: APIEndpointSources, + parameters: params + ) { object, _, error in + completion(object, error) + } + STPTelemetryClient.shared.sendTelemetryData() + } + + /// Retrieves the Source object with the given ID. - seealso: https://stripe.com/docs/api#retrieve_source + /// - Parameters: + /// - identifier: The identifier of the source to be retrieved. Cannot be nil. + /// - secret: The client secret of the source. Cannot be nil. + /// - completion: The callback to run with the returned Source object, or an error. + @objc(retrieveSourceWithId:clientSecret:completion:) + public func retrieveSource( + withId identifier: String, + clientSecret secret: String, + completion: @escaping STPSourceCompletionBlock + ) { + retrieveSource( + withId: identifier, + clientSecret: secret, + responseCompletion: { object, _, error in + completion(object, error) + } + ) + } + + func retrieveSource( + withId identifier: String, + clientSecret secret: String, + responseCompletion completion: @escaping (STPSource?, HTTPURLResponse?, Error?) -> Void + ) { + let endpoint = "\(APIEndpointSources)/\(identifier)" + let parameters = [ + "client_secret": secret + ] + APIRequest.getWith( + self, + endpoint: endpoint, + parameters: parameters, + completion: completion + ) + } + + /// Starts polling the Source object with the given ID. For payment methods that require + /// additional customer action (e.g. authorizing a payment with their bank), polling + /// allows you to determine if the action was successful. Polling will stop and the + /// provided callback will be called once the source's status is no longer `pending`, + /// or if the given timeout is reached and the source is still `pending`. If polling + /// stops due to an error, the callback will be fired with the latest retrieved + /// source and the error. + /// Note that if a poll is already running for a source, subsequent calls to `startPolling` + /// with the same source ID will do nothing. + /// - Parameters: + /// - identifier: The identifier of the source to be retrieved. Cannot be nil. + /// - secret: The client secret of the source. Cannot be nil. + /// - timeout: The timeout for the polling operation, in seconds. Timeouts are capped at 5 minutes. + /// - completion: The callback to run with the returned Source object, or an error. + @available(iOSApplicationExtension, unavailable) + @available(macCatalystApplicationExtension, unavailable) + @objc(startPollingSourceWithId:clientSecret:timeout:completion:) + public func startPollingSource( + withId identifier: String, + clientSecret secret: String, + timeout: TimeInterval, + completion: @escaping STPSourceCompletionBlock + ) { + stopPollingSource(withId: identifier) + let poller = STPSourcePoller( + apiClient: self, + clientSecret: secret, + sourceID: identifier, + timeout: timeout, + completion: completion + ) + sourcePollersQueue?.async(execute: { + self.sourcePollers?[identifier] = poller + }) + } + + /// Stops polling the Source object with the given ID. Note that the completion block passed to + /// `startPolling` will not be fired when `stopPolling` is called. + /// - Parameter identifier: The identifier of the source to be retrieved. Cannot be nil. + @objc(stopPollingSourceWithId:) + @available(iOSApplicationExtension, unavailable) + @available(macCatalystApplicationExtension, unavailable) + public func stopPollingSource(withId identifier: String) { + sourcePollersQueue?.async(execute: { + let poller = self.sourcePollers?[identifier] as? STPSourcePoller + if let poller = poller { + poller.stopPolling() + self.sourcePollers?[identifier] = nil + } + }) + } +} + +// MARK: Payment Intents + +/// STPAPIClient extensions for working with PaymentIntent objects. +extension STPAPIClient { + + internal func paymentIntentEndpoint(from secret: String) -> String { + if publishableKeyIsUserKey { + assert( + secret.hasPrefix("pi_"), + "`secret` format does not match expected identifer formatting." + ) + return "\(APIEndpointPaymentIntents)/\(secret)" + } else { + assert( + STPPaymentIntentParams.isClientSecretValid(secret), + "`secret` format does not match expected client secret formatting." + ) + let identifier = STPPaymentIntent.id(fromClientSecret: secret) ?? "" + return "\(APIEndpointPaymentIntents)/\(identifier)" + } + } + + /// Retrieves the PaymentIntent object using the given secret. - seealso: https://stripe.com/docs/api#retrieve_payment_intent + /// - Parameters: + /// - secret: The client secret of the payment intent to be retrieved. Cannot be nil. + /// - completion: The callback to run with the returned PaymentIntent object, or an error. + @objc(retrievePaymentIntentWithClientSecret:completion:) + public func retrievePaymentIntent( + withClientSecret secret: String, + completion: @escaping STPPaymentIntentCompletionBlock + ) { + retrievePaymentIntent( + withClientSecret: secret, + expand: nil, + completion: completion + ) + } + + /// Retrieves the PaymentIntent object using the given secret. - seealso: https://stripe.com/docs/api#retrieve_payment_intent + /// - Parameters: + /// - secret: The client secret of the payment intent to be retrieved. Cannot be nil. + /// - expand: An array of string keys to expand on the returned PaymentIntent object. These strings should match one or more of the parameter names that are marked as expandable. - seealso: https://stripe.com/docs/api/payment_intents/object + /// - completion: The callback to run with the returned PaymentIntent object, or an error. + @objc(retrievePaymentIntentWithClientSecret:expand:completion:) + public func retrievePaymentIntent( + withClientSecret secret: String, + expand: [String]?, + completion: @escaping STPPaymentIntentCompletionBlock + ) { + let endpoint: String = paymentIntentEndpoint(from: secret) + var parameters: [String: Any] = [:] + + if !publishableKeyIsUserKey { + parameters["client_secret"] = secret + } + + if (expand?.count ?? 0) > 0 { + parameters["expand"] = expand + } + + APIRequest.getWith( + self, + endpoint: endpoint, + parameters: parameters + ) { paymentIntent, _, error in + completion(paymentIntent, error) + } + } + + /// Confirms the PaymentIntent object with the provided params object. + /// At a minimum, the params object must include the `clientSecret`. + /// - seealso: https://stripe.com/docs/api#confirm_payment_intent + /// @note Use the `confirmPayment:withAuthenticationContext:completion:` method on `STPPaymentHandler` instead + /// of calling this method directly. It handles any authentication necessary for you. - seealso: https://stripe.com/docs/payments/3d-secure + /// - Parameters: + /// - paymentIntentParams: The `STPPaymentIntentParams` to pass to `/confirm` + /// - completion: The callback to run with the returned PaymentIntent object, or an error. + @objc(confirmPaymentIntentWithParams:completion:) + public func confirmPaymentIntent( + with paymentIntentParams: STPPaymentIntentParams, + completion: @escaping STPPaymentIntentCompletionBlock + ) { + confirmPaymentIntent( + with: paymentIntentParams, + expand: nil, + completion: completion + ) + } + + /// Confirms the PaymentIntent object with the provided params object. + /// At a minimum, the params object must include the `clientSecret`. + /// - seealso: https://stripe.com/docs/api#confirm_payment_intent + /// @note Use the `confirmPayment:withAuthenticationContext:completion:` method on `STPPaymentHandler` instead + /// of calling this method directly. It handles any authentication necessary for you. - seealso: https://stripe.com/docs/payments/3d-secure + /// - Parameters: + /// - paymentIntentParams: The `STPPaymentIntentParams` to pass to `/confirm` + /// - expand: An array of string keys to expand on the returned PaymentIntent object. These strings should match one or more of the parameter names that are marked as expandable. - seealso: https://stripe.com/docs/api/payment_intents/object + /// - completion: The callback to run with the returned PaymentIntent object, or an error. + public func confirmPaymentIntent( + with paymentIntentParams: STPPaymentIntentParams, + expand: [String]?, + completion: @escaping STPPaymentIntentCompletionBlock + ) { + assert( + STPPaymentIntentParams.isClientSecretValid(paymentIntentParams.clientSecret), + "`paymentIntentParams.clientSecret` format does not match expected client secret formatting." + ) + + let identifier = paymentIntentParams.stripeId ?? "" + let type = + paymentIntentParams.paymentMethodParams?.rawTypeString + ?? paymentIntentParams.sourceParams?.rawTypeString + STPAnalyticsClient.sharedClient.logPaymentIntentConfirmationAttempt( + with: _stored_configuration, + paymentMethodType: type + ) + + let endpoint = "\(APIEndpointPaymentIntents)/\(identifier)/confirm" + + var params = STPFormEncoder.dictionary(forObject: paymentIntentParams) + if var sourceParamsDict = params[SourceDataHash] as? [String: Any] { + STPTelemetryClient.shared.addTelemetryFields(toParams: &sourceParamsDict) + sourceParamsDict = Self.paramsAddingPaymentUserAgent(sourceParamsDict) + params[SourceDataHash] = sourceParamsDict + } + if var paymentMethodParamsDict = params[PaymentMethodDataHash] as? [String: Any] { + paymentMethodParamsDict = Self.paramsAddingPaymentUserAgent(paymentMethodParamsDict) + params[PaymentMethodDataHash] = paymentMethodParamsDict + } + if (expand?.count ?? 0) > 0 { + if let expand = expand { + params["expand"] = expand + } + } + if publishableKeyIsUserKey { + params["client_secret"] = nil + } + + APIRequest.post( + with: self, + endpoint: endpoint, + parameters: params + ) { paymentIntent, _, error in + completion(paymentIntent, error) + } + } + + /// Endpoint to call to indicate that the web-based challenge flow for 3DS authentication was canceled. + func cancel3DSAuthentication( + forPaymentIntent paymentIntentID: String, + withSource sourceID: String, + publishableKeyOverride: String?, + completion: @escaping STPPaymentIntentCompletionBlock + ) { + APIRequest.post( + with: self, + endpoint: "\(APIEndpointPaymentIntents)/\(paymentIntentID)/source_cancel", + additionalHeaders: authorizationHeader(using: publishableKeyOverride), + parameters: [ + "source": sourceID + ] + ) { paymentIntent, _, responseError in + completion(paymentIntent, responseError) + } + } +} + +// MARK: Setup Intents + +/// STPAPIClient extensions for working with SetupIntent objects. +extension STPAPIClient { + + func setupIntentEndpoint(from secret: String) -> String { + assert( + STPSetupIntentConfirmParams.isClientSecretValid(secret), + "`secret` format does not match expected client secret formatting." + ) + let identifier = STPSetupIntent.id(fromClientSecret: secret) ?? "" + + return "\(APIEndpointSetupIntents)/\(identifier)" + } + + /// Retrieves the SetupIntent object using the given secret. - seealso: https://stripe.com/docs/api/setup_intents/retrieve + /// - Parameters: + /// - secret: The client secret of the SetupIntent to be retrieved. Cannot be nil. + /// - completion: The callback to run with the returned SetupIntent object, or an error. + @objc(retrieveSetupIntentWithClientSecret:completion:) + public func retrieveSetupIntent( + withClientSecret secret: String, + completion: @escaping STPSetupIntentCompletionBlock + ) { + retrieveSetupIntent( + withClientSecret: secret, + expand: nil, + completion: completion + ) + } + + /// Retrieves the SetupIntent object using the given secret. - seealso: https://stripe.com/docs/api/setup_intents/retrieve + /// - Parameters: + /// - secret: The client secret of the SetupIntent to be retrieved. Cannot be nil. + /// - expand: An array of string keys to expand on the returned SetupIntent object. These strings should match one or more of the parameter names that are marked as expandable. - seealso: https://stripe.com/docs/api/setup_intents/object + /// - completion: The callback to run with the returned SetupIntent object, or an error. + @objc(retrieveSetupIntentWithClientSecret:expand:completion:) + public func retrieveSetupIntent( + withClientSecret secret: String, + expand: [String]?, + completion: @escaping STPSetupIntentCompletionBlock + ) { + + let endpoint = setupIntentEndpoint(from: secret) + var parameters: [String: Any] = ["client_secret": secret] + if let expand = expand, + !expand.isEmpty + { + parameters["expand"] = expand + } + + APIRequest.getWith( + self, + endpoint: endpoint, + parameters: parameters + ) { setupIntent, _, error in + completion(setupIntent, error) + } + } + + /// Confirms the SetupIntent object with the provided params object. + /// At a minimum, the params object must include the `clientSecret`. + /// - seealso: https://stripe.com/docs/api/setup_intents/confirm + /// @note Use the `confirmSetupIntent:withAuthenticationContext:completion:` method on `STPPaymentHandler` instead + /// of calling this method directly. It handles any authentication necessary for you. - seealso: https://stripe.com/docs/payments/3d-secure + /// - Parameters: + /// - setupIntentParams: The `STPSetupIntentConfirmParams` to pass to `/confirm` + /// - completion: The callback to run with the returned PaymentIntent object, or an error. + @objc(confirmSetupIntentWithParams:completion:) + public func confirmSetupIntent( + with setupIntentParams: STPSetupIntentConfirmParams, + completion: @escaping STPSetupIntentCompletionBlock + ) { + confirmSetupIntent( + with: setupIntentParams, + expand: nil, + completion: completion + ) + } + + /// Confirms the SetupIntent object with the provided params object. + /// At a minimum, the params object must include the `clientSecret`. + /// - seealso: https://stripe.com/docs/api/setup_intents/confirm + /// @note Use the `confirmSetupIntent:withAuthenticationContext:completion:` method on `STPPaymentHandler` instead + /// of calling this method directly. It handles any authentication necessary for you. - seealso: https://stripe.com/docs/mobile/ios/authentication + /// - Parameters: + /// - setupIntentParams: The `STPSetupIntentConfirmParams` to pass to `/confirm` + /// - expand: An array of string keys to expand on the returned SetupIntent object. These strings should match one or more of the parameter names that are marked as expandable. - seealso: https://stripe.com/docs/api/setup_intents/object + /// - completion: The callback to run with the returned PaymentIntent object, or an error. + @objc(confirmSetupIntentWithParams:expand:completion:) + public func confirmSetupIntent( + with setupIntentParams: STPSetupIntentConfirmParams, + expand: [String]?, + completion: @escaping STPSetupIntentCompletionBlock + ) { + assert( + STPSetupIntentConfirmParams.isClientSecretValid(setupIntentParams.clientSecret), + "`setupIntentParams.clientSecret` format does not match expected client secret formatting." + ) + + STPAnalyticsClient.sharedClient.logSetupIntentConfirmationAttempt( + with: _stored_configuration, + paymentMethodType: setupIntentParams.paymentMethodParams?.rawTypeString + ) + + let endpoint = setupIntentEndpoint(from: setupIntentParams.clientSecret) + "/confirm" + var params = STPFormEncoder.dictionary(forObject: setupIntentParams) + if var sourceParamsDict = params[SourceDataHash] as? [String: Any] { + STPTelemetryClient.shared.addTelemetryFields(toParams: &sourceParamsDict) + sourceParamsDict = Self.paramsAddingPaymentUserAgent(sourceParamsDict) + params[SourceDataHash] = sourceParamsDict + } + if var paymentMethodParamsDict = params[PaymentMethodDataHash] as? [String: Any] { + paymentMethodParamsDict = Self.paramsAddingPaymentUserAgent(paymentMethodParamsDict) + params[PaymentMethodDataHash] = paymentMethodParamsDict + } + if let expand = expand, + !expand.isEmpty + { + params["expand"] = expand + } + + APIRequest.post( + with: self, + endpoint: endpoint, + parameters: params + ) { setupIntent, _, error in + completion(setupIntent, error) + } + } + + func cancel3DSAuthentication( + forSetupIntent setupIntentID: String, + withSource sourceID: String, + publishableKeyOverride: String?, + completion: @escaping STPSetupIntentCompletionBlock + ) { + APIRequest.post( + with: self, + endpoint: "\(APIEndpointSetupIntents)/\(setupIntentID)/source_cancel", + additionalHeaders: authorizationHeader(using: publishableKeyOverride), + parameters: [ + "source": sourceID + ] + ) { setupIntent, _, responseError in + completion(setupIntent, responseError) + } + } +} + +// MARK: Payment Methods + +/// STPAPIClient extensions for working with PaymentMethod objects. +extension STPAPIClient { + /// Creates a PaymentMethod object with the provided params object. + /// - seealso: https://stripe.com/docs/api/payment_methods/create + /// - Parameters: + /// - paymentMethodParams: The `STPPaymentMethodParams` to pass to `/v1/payment_methods`. Cannot be nil. + /// - completion: The callback to run with the returned PaymentMethod object, or an error. + @objc(createPaymentMethodWithParams:completion:) + public func createPaymentMethod( + with paymentMethodParams: STPPaymentMethodParams, + completion: @escaping STPPaymentMethodCompletionBlock + ) { + STPAnalyticsClient.sharedClient.logPaymentMethodCreationAttempt( + with: _stored_configuration, + paymentMethodType: paymentMethodParams.rawTypeString + ) + var parameters = STPFormEncoder.dictionary(forObject: paymentMethodParams) + parameters = Self.paramsAddingPaymentUserAgent(parameters) + APIRequest.post( + with: self, + endpoint: APIEndpointPaymentMethods, + parameters: parameters + ) { paymentMethod, _, error in + completion(paymentMethod, error) + } + + } +} + +// MARK: - ThreeDS2 +extension STPAPIClient { + /// Kicks off 3DS2 authentication. + func authenticate3DS2( + _ authRequestParams: STDSAuthenticationRequestParameters, + sourceIdentifier sourceID: String, + returnURL returnURLString: String?, + maxTimeout: Int, + publishableKeyOverride: String?, + completion: @escaping STP3DS2AuthenticateCompletionBlock + ) { + let endpoint = "\(APIEndpoint3DS2)/authenticate" + + var appParams = STDSJSONEncoder.dictionary(forObject: authRequestParams) + appParams["deviceRenderOptions"] = [ + "sdkInterface": "03", + "sdkUiType": ["01", "02", "03", "04", "05"], + ] + appParams["sdkMaxTimeout"] = String(format: "%02ld", maxTimeout) + let appData = try? JSONSerialization.data( + withJSONObject: appParams, + options: .prettyPrinted + ) + + var params = [ + "app": String(data: appData ?? Data(), encoding: .utf8) ?? "", + "source": sourceID, + ] + if let returnURLString = returnURLString { + params["fallback_return_url"] = returnURLString + } + + APIRequest.post( + with: self, + endpoint: endpoint, + additionalHeaders: authorizationHeader(using: publishableKeyOverride), + parameters: params + ) { authenticateResponse, _, error in + completion(authenticateResponse, error) + } + } + + /// Endpoint to call to indicate that the challenge flow for a 3DS2 authentication has finished. + func complete3DS2Authentication( + forSource sourceID: String, + publishableKeyOverride: String?, + completion: @escaping STPBooleanSuccessBlock + ) { + APIRequest.post( + with: self, + endpoint: "\(APIEndpoint3DS2)/challenge_complete", + additionalHeaders: authorizationHeader(using: publishableKeyOverride), + parameters: [ + "source": sourceID + ] + ) { _, response, responseError in + completion(response?.statusCode == 200, responseError) + } + } +} + +// MARK: - US Bank Account +extension STPAPIClient { + + /// Verify a customer's bank account with micro-deposits + /// This function should only be called when the PaymentIntent is in the `requires_action` + /// state and `next_action.type` equals `verify_with_microdeposits` + /// - Parameters: + /// - clientSecret: The client secret of the PaymentIntent. + /// - firstAmount: The amount, in cents of USD, equal to the value of the first micro-deposit sent to the bank account. + /// - secondAmount: The amount, in cents of USD, equal to the value of the second micro-deposit sent to the bank account. + /// - completion: The callback to run with the returned PaymentIntent object, or an error. + public func verifyPaymentIntentWithMicrodeposits( + clientSecret: String, + firstAmount: Int, + secondAmount: Int, + completion: @escaping STPPaymentIntentCompletionBlock + ) { + verifyIntentWithMicrodeposits( + clientSecret: clientSecret, + firstAmount: firstAmount, + secondAmount: secondAmount, + completion: completion + ) + } + + /// Verify a customer's bank account with micro-deposits + /// This function should only be called when the PaymentIntent is in the `requires_action` + /// state and `next_action.type` equals `verify_with_microdeposits` + /// - Parameters: + /// - clientSecret: The client secret of the PaymentIntent. + /// - descriptorCode: a unique, 6-digit descriptor code that starts with SM that was sent as statement descriptor to the bank account. + /// - completion: The callback to run with the returned PaymentIntent object, or an error. + public func verifyPaymentIntentWithMicrodeposits( + clientSecret: String, + descriptorCode: String, + completion: @escaping STPPaymentIntentCompletionBlock + ) { + + verifyIntentWithMicrodeposits( + clientSecret: clientSecret, + descriptorCode: descriptorCode, + completion: completion + ) + } + + /// Verify a customer's bank account with micro-deposits + /// This function should only be called when the SetupIntent is in the `requires_action` + /// state and `next_action.type` equals `verify_with_microdeposits` + /// - Parameters: + /// - clientSecret: The client secret of the SetupIntent. + /// - firstAmount: The amount, in cents of USD, equal to the value of the first micro-deposit sent to the bank account. + /// - secondAmount: The amount, in cents of USD, equal to the value of the second micro-deposit sent to the bank account. + /// - completion: The callback to run with the returned SetupIntent object, or an error. + public func verifySetupIntentWithMicrodeposits( + clientSecret: String, + firstAmount: Int, + secondAmount: Int, + completion: @escaping STPSetupIntentCompletionBlock + ) { + + verifyIntentWithMicrodeposits( + clientSecret: clientSecret, + firstAmount: firstAmount, + secondAmount: secondAmount, + completion: completion + ) + } + + /// Verify a customer's bank account with micro-deposits + /// This function should only be called when the PaymentIntent is in the `requires_action` + /// state and `next_action.type` equals `verify_with_microdeposits` + /// - Parameters: + /// - clientSecret: The client secret of the SetupIntent. + /// - descriptorCode: a unique, 6-digit descriptor code that starts with SM that was sent as statement descriptor to the bank account. + /// - completion: The callback to run with the returned SetupIntent object, or an error. + public func verifySetupIntentWithMicrodeposits( + clientSecret: String, + descriptorCode: String, + completion: @escaping STPSetupIntentCompletionBlock + ) { + verifyIntentWithMicrodeposits( + clientSecret: clientSecret, + descriptorCode: descriptorCode, + completion: completion + ) + } + + // Internal helpers + + func verifyIntentWithMicrodeposits( + clientSecret: String, + firstAmount: Int, + secondAmount: Int, + completion: @escaping (T?, Error?) -> Void + ) { + verifyIntentWithMicrodeposits( + clientSecret: clientSecret, + verificationKey: "amounts", + verificationData: [firstAmount, secondAmount], + completion: completion + ) + } + + func verifyIntentWithMicrodeposits( + clientSecret: String, + descriptorCode: String, + completion: @escaping (T?, Error?) -> Void + ) { + verifyIntentWithMicrodeposits( + clientSecret: clientSecret, + verificationKey: "descriptor_code", + verificationData: descriptorCode, + completion: completion + ) + } + + func verifyIntentWithMicrodeposits( + clientSecret: String, + verificationKey: String, + verificationData: Any, + completion: @escaping (T?, Error?) -> Void + ) { + var endpoint: String + if T.self is STPPaymentIntent.Type { + endpoint = paymentIntentEndpoint(from: clientSecret) + } else if T.self is STPSetupIntent.Type { + endpoint = setupIntentEndpoint(from: clientSecret) + } else { + assertionFailure("Don't call verifyIntentWithMicrodeposits for a non Intent object") + return + } + + endpoint += "/verify_microdeposits" + + let parameters: [String: Any] = [ + "client_secret": clientSecret, + verificationKey: verificationData, + ] + + APIRequest.post( + with: self, + endpoint: endpoint, + parameters: parameters + ) { intent, _, error in + completion(intent, error) + } + } +} + +private let APIEndpointToken = "tokens" +private let APIEndpointSources = "sources" +@_spi(STP) public let APIEndpointCustomers = "customers" +private let APIEndpointPaymentIntents = "payment_intents" +private let APIEndpointSetupIntents = "setup_intents" +@_spi(STP) public let APIEndpointPaymentMethods = "payment_methods" +private let APIEndpoint3DS2 = "3ds2" +private let PaymentMethodDataHash = "payment_method_data" +private let SourceDataHash = "source_data" diff --git a/Pods/StripePayments/StripePayments/StripePayments/API Bindings/STPAPIClient+Radar.swift b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/STPAPIClient+Radar.swift new file mode 100644 index 0000000..62a7ce4 --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/STPAPIClient+Radar.swift @@ -0,0 +1,52 @@ +// +// STPAPIClient+Radar.swift +// StripePayments +// +// Created by Yuki Tokuhiro on 5/20/21. +// Copyright © 2021 Stripe, Inc. All rights reserved. +// + +import Foundation +@_spi(STP) import StripeCore + +private let APIEndpointRadarSession = "radar/session" + +extension STPAPIClient { + + /// Creates a Radar Session. + /// + /// - Note: See https://stripe.com/docs/radar/radar-session + /// - Note: This API and the guide linked above require special permissions to use. Contact support@stripe.com. + /// - Note: `StripeAPI.advancedFraudSignalsEnabled` must be `true` to use this method. + /// - Note: See `STPRadarSession` + /// + /// - Parameters: + /// - completion: The callback to run with the returned `STPRadarSession` (and any errors that may have occurred). + @objc(createRadarSessionWithCompletion:) + public func createRadarSession( + completion: @escaping STPRadarSessionCompletionBlock + ) { + STPTelemetryClient.shared.updateFraudDetectionIfNecessary { result in + switch result { + case .failure(let error): + completion(nil, error) + return + case .success(let fraudDetectionDataData): + let paymentUserAgent = PaymentsSDKVariant.paymentUserAgent + let parameters = [ + "muid": fraudDetectionDataData.muid ?? "", + "sid": fraudDetectionDataData.sid ?? "", + "guid": fraudDetectionDataData.guid ?? "", + "payment_user_agent": paymentUserAgent, + ] + APIRequest.post( + with: self, + endpoint: APIEndpointRadarSession, + parameters: parameters + ) { (radarSession, _, error) in + completion(radarSession, error) + } + } + } + } +} diff --git a/Pods/StripePayments/StripePayments/StripePayments/API Bindings/STPRedirectContext.swift b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/STPRedirectContext.swift new file mode 100644 index 0000000..9072604 --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/API Bindings/STPRedirectContext.swift @@ -0,0 +1,602 @@ +// +// STPRedirectContext.swift +// StripePayments +// +// Created by Brian Dorfman on 3/29/17. +// Copyright © 2017 Stripe, Inc. All rights reserved. +// + +import Foundation +import SafariServices +@_spi(STP) import StripeCore + +/// Error codes specific to `STPRedirectContext` +@objc public enum STPRedirectContextError: Int { + /// `STPRedirectContext` failed to redirect to the app to complete the payment. + /// This could be because the app is not installed on the user's device. + @objc(STPRedirectContextAppRedirectError) case appRedirectError +} + +/// Possible states for the redirect context to be in +@objc public enum STPRedirectContextState: Int { + /// Initialized, but redirect not started. + case notStarted + /// Redirect is in progress. + case inProgress + /// Redirect has been cancelled programmatically before completing. + case cancelled + /// Redirect has completed. + case completed +} + +/// A callback that is executed when the context believes the redirect action has been completed. +/// - Parameters: +/// - sourceID: The stripe id of the source. +/// - clientSecret: The client secret of the source. +/// - error: An error if one occured. Note that a lack of an error does not +/// mean that the action was completed successfully, the presence of one confirms +/// that it was not. Currently the only possible error the context can know about +/// is if SFSafariViewController fails its initial load (e.g. the user has no +/// internet connection, or servers are down). +public typealias STPRedirectContextSourceCompletionBlock = (String, String?, Error?) -> Void +/// A callback that is executed when the context believes the redirect action has been completed. +/// This type has been renamed to `STPRedirectContextSourceCompletionBlock` and deprecated. +public typealias STPRedirectContextCompletionBlock = STPRedirectContextSourceCompletionBlock +/// A callback that is executed when the context believes the redirect action has been completed. +/// @note The STPPaymentIntent originally provided to this class may be out of date, +/// so you should re-fetch it using the clientSecret. +/// - Parameters: +/// - clientSecret: The client secret of the PaymentIntent. +/// - error: An error if one occured. Note that a lack of an error does not +/// mean that the action was completed successfully, the presence of one confirms +/// that it was not. Currently the only possible error the context can know about +/// is if SFSafariViewController fails its initial load (e.g. the user has no +/// internet connection, or servers are down). +public typealias STPRedirectContextPaymentIntentCompletionBlock = (String, Error?) -> Void + +// swift-format-ignore: DontRepeatTypeInStaticProperties +/// This is a helper class for handling redirects associated with STPSource and +/// STPPaymentIntents. +/// Init and retain an instance with the Source or PaymentIntent you want to handle, +/// then choose a redirect method. The context will fire the completion handler +/// when the redirect completes. +/// Due to the nature of iOS, very little concrete information can be gained +/// during this process, as all actions take place in either the Safari app +/// or the sandboxed SFSafariViewController class. The context attempts to +/// detect when the user has completed the necessary redirect action by listening +/// for both app foregrounds and url callbacks received in the app delegate. +/// However, it is possible the when the redirect is "completed", the user may +/// have not actually completed the necessary actions to authorize the charge. +/// You should not use either this class, nor `STPAPIClient`, as a way +/// to determine when you should charge the Source or to determine if the redirect +/// was successful. Use Stripe webhooks on your backend server to listen for Source +/// state changes and to make the charge. +/// @note You must retain this instance for the duration of the redirect flow. +/// This class dismisses any presented view controller upon deallocation. +/// See https://stripe.com/docs/sources/best-practices +@available(iOSApplicationExtension, unavailable) +@available(macCatalystApplicationExtension, unavailable) +public class STPRedirectContext: NSObject, SFSafariViewControllerDelegate, + UIViewControllerTransitioningDelegate, STPSafariViewControllerDismissalDelegate +{ + + /// The domain for NSErrors specific to `STPRedirectContext` + @objc public static let STPRedirectContextErrorDomain = "STPRedirectContextErrorDomain" + + /// The current state of the context. + @objc public internal(set) var state: STPRedirectContextState = .notStarted + + /// Optional URL for a native app. This is passed directly to `UIApplication openURL:`, and if it fails this class falls back to `redirectURL` + @objc internal var nativeRedirectURL: URL? + /// The URL to redirect to, assuming `nativeRedirectURL` is nil or fails to open. Cannot be nil if `nativeRedirectURL` is. + @objc internal var redirectURL: URL? + /// The expected `returnURL`, passed to STPURLCallbackHandler + @objc internal var returnURL: URL? + /// Completion block to execute when finished redirecting, with optional error parameter. + @objc internal var completion: STPErrorBlock + /// Error parameter for completion block. + @objc internal var completionError: Error? + + /// Initializer for context from an `STPSource`. + /// @note You must ensure that the returnURL set up in the created source + /// correctly goes to your app so that users can be returned once + /// they complete the redirect in the web broswer. + /// - Parameters: + /// - source: The source that needs user redirect action to be taken. + /// - completion: A block to fire when the action is believed to have + /// been completed. + /// - Returns: nil if the specified source is not a redirect-flow source. Otherwise + /// a new context object. + /// @note Execution of the completion block does not necessarily mean the user + /// successfully performed the redirect action. You should listen for source status + /// change webhooks on your backend to determine the result of a redirect. + @objc public convenience init?( + source: STPSource, + completion: @escaping STPRedirectContextSourceCompletionBlock + ) { + + if (source.flow != .redirect && source.type != .weChatPay) + || !(source.status == .pending || source.status == .chargeable) + { + return nil + } + + let nativeRedirectURL = Self.nativeRedirectURL(for: source) + var returnURL = source.redirect?.returnURL + + if source.type == .weChatPay { + // Construct the returnURL for WeChat Pay: + // - nativeRedirectURL looks like "weixin://app/MERCHANT_APP_ID/pay/?..." + // - the WeChat app will redirect back using a URL like "MERCHANT_APP_ID://pay/?..." + let merchantAppID = nativeRedirectURL?.pathComponents[1] + returnURL = URL(string: "\(merchantAppID ?? "")://pay/") + } + + self.init( + nativeRedirectURL: nativeRedirectURL, + redirectURL: source.redirect?.url, + return: returnURL + ) { error in + completion(source.stripeID, source.clientSecret, error) + } + self.source = source + } + + /// Initializer for context from an `STPPaymentIntent`. + /// This should be used when the `status` is `STPPaymentIntentStatusRequiresAction`. + /// If the next action involves a redirect, this init method will return a non-nil object. + /// - Parameters: + /// - paymentIntent: The STPPaymentIntent that needs a redirect. + /// - completion: A block to fire when the action is believed to have + /// been completed. + /// - Returns: nil if the provided PaymentIntent does not need a redirect. Otherwise + /// a new context object. + /// @note Execution of the completion block does not necessarily mean the user + /// successfully performed the redirect action. + @objc public convenience init?( + paymentIntent: STPPaymentIntent, + completion: @escaping STPRedirectContextPaymentIntentCompletionBlock + ) { + guard let redirectURL = paymentIntent.nextAction?.redirectToURL?.url, + let returnURL = paymentIntent.nextAction?.redirectToURL?.returnURL, + paymentIntent.status == .requiresAction, + paymentIntent.nextAction?.type == .redirectToURL + else { + return nil + } + + self.init( + nativeRedirectURL: nil, + redirectURL: redirectURL, + return: returnURL + ) { error in + completion(paymentIntent.clientSecret, error) + } + } + + /// Starts a redirect flow. + /// You must ensure that your app delegate listens for the `returnURL` that you + /// set on the Stripe object, and forwards it to the Stripe SDK so that the + /// context can be notified when the redirect is completed and dismiss the + /// view controller. See `StripeAPI.handleURLCallback(with url:)` + /// The context will listen for both received URLs and app open notifications + /// and fire its completion block when either the URL is received, or the next + /// time the app is foregrounded. + /// The context will initiate the flow by presenting a SFSafariViewController + /// instance from the passsed in view controller. If you want more manual control + /// over the redirect method, you can use `startSafariViewControllerRedirectFlowFromViewController` + /// or `startSafariAppRedirectFlow` + /// If the redirect supports a native app, and that app is is installed on the user's + /// device, this call will do a direct app-to-app redirect instead of showing + /// a web url. + /// @note This method does nothing if the context is not in the + /// `STPRedirectContextStateNotStarted` state. + /// - Parameter presentingViewController: The view controller to present the Safari + /// view controller from. + @objc(startRedirectFlowFromViewController:) public func startRedirectFlow( + from presentingViewController: UIViewController + ) { + + if state == .notStarted { + state = .inProgress + subscribeToURLAndAppActiveNotifications() + + weak var weakSelf = self + performAppRedirectIfPossible(withCompletion: { success in + if success { + return + } + + let strongSelf = weakSelf + if strongSelf == nil { + return + } + // Redirect failed... + if strongSelf?.source?.type == .weChatPay { + // ...and this Source doesn't support web-based redirect — finish with an error. + let error = NSError( + domain: STPRedirectContext.STPRedirectContextErrorDomain, + code: STPRedirectContextError.appRedirectError.rawValue, + userInfo: [ + NSLocalizedDescriptionKey: NSError.stp_unexpectedErrorMessage(), + STPError.errorMessageKey: + "Redirecting to WeChat failed. Only offer WeChat Pay if the WeChat app is installed.", + ] + ) + stpDispatchToMainThreadIfNecessary({ + strongSelf?.handleRedirectCompletionWithError( + error, + shouldDismissViewController: false + ) + }) + } else { + // ...reset our state and try a web redirect + strongSelf?.state = .notStarted + strongSelf?.unsubscribeFromNotifications() + strongSelf?.startSafariViewControllerRedirectFlow( + from: presentingViewController + ) + } + }) + } + } + + /// Starts a redirect flow by presenting an SFSafariViewController in your app + /// from the passed in view controller. + /// You must ensure that your app delegate listens for the `returnURL` that you + /// set on the Stripe object, and forwards it to the Stripe SDK so that the + /// context can be notified when the redirect is completed and dismiss the + /// view controller. See `StripeAPI.handleStripeURLCallback(with url:)]` + /// The context will listen for both received URLs and app open notifications + /// and fire its completion block when either the URL is received, or the next + /// time the app is foregrounded. + /// @note This method does nothing if the context is not in the + /// `STPRedirectContextStateNotStarted` state. + /// - Parameter presentingViewController: The view controller to present the Safari + /// view controller from. + @objc(startSafariViewControllerRedirectFlowFromViewController:) + public dynamic func startSafariViewControllerRedirectFlow( + from presentingViewController: UIViewController + ) { + guard let redirectURL = redirectURL else { + return + } + if state == .notStarted { + state = .inProgress + subscribeToURLNotifications() + lastKnownSafariVCURL = redirectURL + let safariVC = SFSafariViewController(url: lastKnownSafariVCURL!) + safariVC.transitioningDelegate = self + safariVC.delegate = self + safariVC.modalPresentationStyle = .custom + self.safariVC = safariVC + presentingViewController.present( + safariVC, + animated: true + ) + } + } + + /// Starts a redirect flow by calling `openURL` to bounce the user out to + /// the Safari app. + /// The context will listen for app open notifications and fire its completion + /// block the next time the user re-opens the app (either manually or via url) + /// @note This method does nothing if the context is not in the + /// `STPRedirectContextStateNotStarted` state. + @objc + public func startSafariAppRedirectFlow() { + guard let redirectURL = redirectURL else { + return + } + if state == .notStarted { + state = .inProgress + subscribeToURLAndAppActiveNotifications() + UIApplication.shared.open(redirectURL, options: [:], completionHandler: nil) + } + } + + /// Dismisses any presented views and stops listening for any + /// app opens or callbacks. The completion block will not be fired. + @objc + public func cancel() { + if state == .inProgress { + state = .cancelled + unsubscribeFromNotificationsAndDismissPresentedViewControllers() + } + } + + private var safariVC: SFSafariViewController? + /// If we're on iOS 11+ and in the SafariVC flow, this tracks the latest URL loaded/redirected to during the initial load + private var lastKnownSafariVCURL: URL? + private var source: STPSource? + private var subscribedToURLNotifications = false + private var subscribedToAppActiveNotifications = false + + /// Failable initializer for the general case of STPRedirectContext, some URLs and a completion block. + init?( + nativeRedirectURL: URL?, + redirectURL: URL?, + return returnURL: URL?, + completion: @escaping STPErrorBlock + ) { + if nativeRedirectURL == nil && redirectURL == nil { + return nil + } + + self.nativeRedirectURL = nativeRedirectURL + self.redirectURL = redirectURL + self.returnURL = returnURL + self.completion = completion + super.init() + + subscribedToURLNotifications = false + subscribedToAppActiveNotifications = false + } + + deinit { + unsubscribeFromNotificationsAndDismissPresentedViewControllers() + } + + // MARK: - SFSafariViewControllerDelegate - + /// :nodoc: + @objc + public func safariViewControllerDidFinish(_ controller: SFSafariViewController) { + var manuallyClosedError: Error? + if returnURL != nil && state == .inProgress && completionError == nil { + manuallyClosedError = NSError( + domain: STPError.stripeDomain, + code: STPErrorCode.cancellationError.rawValue, + userInfo: [ + STPError.errorMessageKey: + "User manually closed SFSafariViewController before redirect was completed." + ] + ) + } + stpDispatchToMainThreadIfNecessary({ + self.handleRedirectCompletionWithError( + manuallyClosedError, + shouldDismissViewController: false + ) + }) + } + + /// :nodoc: + @objc + public func safariViewController( + _ controller: SFSafariViewController, + didCompleteInitialLoad didLoadSuccessfully: Bool + ) { + // SafariVC is, imo, over-eager to report errors. The way that (for example) girogate.de redirects + // can cause SafariVC to report that the initial load failed, even though it completes successfully. + // + // So, only report failures to complete the initial load if the host was a Stripe domain. + // Stripe uses 302 redirects, and this should catch local connection problems as well as + // server-side failures from Stripe. + if didLoadSuccessfully == false { + stpDispatchToMainThreadIfNecessary({ + if self.lastKnownSafariVCURL?.host?.contains("stripe.com") ?? false { + self.handleRedirectCompletionWithError( + NSError.stp_genericConnectionError(), + shouldDismissViewController: true + ) + } + }) + } + } + + /// :nodoc: + @objc + public func safariViewController( + _ controller: SFSafariViewController, + initialLoadDidRedirectTo URL: URL + ) { + stpDispatchToMainThreadIfNecessary({ + // This is only kept up to date during the "initial load", but we only need the value in + // `safariViewController:didCompleteInitialLoad:`, so that's fine. + self.lastKnownSafariVCURL = URL + }) + } + + // MARK: - STPSafariViewControllerDismissalDelegate - + func safariViewControllerDidCompleteDismissal(_ controller: SFSafariViewController) { + completion(completionError) + completionError = nil + } + + // MARK: - UIViewControllerTransitioningDelegate + /// :nodoc: + @objc + public func presentationController( + forPresented presented: UIViewController, + presenting: UIViewController?, + source: UIViewController + ) -> UIPresentationController? { + let controller = STPSafariViewControllerPresentationController( + presentedViewController: presented, + presenting: presenting + ) + controller.dismissalDelegate = self + return controller + } + + // MARK: - Private methods - + func performAppRedirectIfPossible(withCompletion onCompletion: @escaping STPBoolCompletionBlock) + { + + let nativeURL = nativeRedirectURL + if nativeURL == nil { + onCompletion(false) + return + } + + let application = UIApplication.shared + if let nativeURL = nativeURL { + application.open( + nativeURL, + options: [:], + completionHandler: { success in + onCompletion(success) + } + ) + } + } + + @objc func handleDidBecomeActiveNotification() { + // Always `dispatch_async` the `handleDidBecomeActiveNotification` function + // call to re-queue the task at the end of the run loop. This is so that the + // `handleURLCallback` gets handled first. + // + // Verified this works even if `handleURLCallback` performs `dispatch_async` + // but not completely sure why :) + // + // When returning from a `startSafariAppRedirectFlow` call, the + // `UIApplicationDidBecomeActiveNotification` handler and + // `STPURLCallbackHandler` compete. The problem is the + // `UIApplicationDidBecomeActiveNotification` handler is always queued + // first causing the `STPURLCallbackHandler` to always fail because the + // registered callback was already unregistered by the + // `UIApplicationDidBecomeActiveNotification` handler. We are patching + // this so that the`STPURLCallbackHandler` can succeed and the + // `UIApplicationDidBecomeActiveNotification` handler can silently fail. + DispatchQueue.main.async(execute: { + self.handleRedirectCompletionWithError( + nil, + shouldDismissViewController: true + ) + }) + } + + @objc dynamic func handleRedirectCompletionWithError( + _ error: Error?, + shouldDismissViewController: Bool + ) { + if state != .inProgress { + return + } + + state = .completed + + unsubscribeFromNotifications() + + if isSafariVCPresented() { + // SafariVC dismissal delegate will manage calling completion handler + completionError = error + } else { + completion(error) + } + + if shouldDismissViewController { + dismissPresentedViewController() + } + } + + func subscribeToURLNotifications() { + guard let returnURL = returnURL else { + return + } + if !subscribedToURLNotifications { + subscribedToURLNotifications = true + STPURLCallbackHandler.shared().register( + self, + for: returnURL + ) + } + } + + func subscribeToURLAndAppActiveNotifications() { + subscribeToURLNotifications() + if !subscribedToAppActiveNotifications { + subscribedToAppActiveNotifications = true + NotificationCenter.default.addObserver( + self, + selector: #selector(handleDidBecomeActiveNotification), + name: UIApplication.didBecomeActiveNotification, + object: nil + ) + } + } + + func unsubscribeFromNotificationsAndDismissPresentedViewControllers() { + unsubscribeFromNotifications() + dismissPresentedViewController() + } + + @objc dynamic func unsubscribeFromNotifications() { + NotificationCenter.default.removeObserver( + self, + name: UIApplication.didBecomeActiveNotification, + object: nil + ) + STPURLCallbackHandler.shared().unregisterListener(self) + subscribedToURLNotifications = false + subscribedToAppActiveNotifications = false + } + + @objc dynamic func dismissPresentedViewController() { + if isSafariVCPresented() { + safariVC?.presentingViewController?.dismiss( + animated: true + ) + safariVC = nil + } + } + + func isSafariVCPresented() -> Bool { + return safariVC != nil + } + + class func nativeRedirectURL(for source: STPSource) -> URL? { + var nativeURLString: String? + switch source.type { + case .alipay: + nativeURLString = source.details?["native_url"] as? String + case .weChatPay: + nativeURLString = source.weChatPayDetails?.weChatAppURL + default: + // All other sources currently have no native url support + break + } + + let nativeURL = nativeURLString != nil ? URL(string: nativeURLString ?? "") : nil + return nativeURL + } +} + +@available(iOSApplicationExtension, unavailable) +@available(macCatalystApplicationExtension, unavailable) +/// :nodoc: +@_spi(STP) extension STPRedirectContext: STPURLCallbackListener { + /// :nodoc: + @_spi(STP) public func handleURLCallback(_ url: URL) -> Bool { + stpDispatchToMainThreadIfNecessary({ + self.handleRedirectCompletionWithError( + nil, + shouldDismissViewController: true + ) + }) + // We handle all returned urls that match what we registered for + return true + } +} + +@objc protocol STPSafariViewControllerDismissalDelegate: NSObjectProtocol { + func safariViewControllerDidCompleteDismissal(_ controller: SFSafariViewController) +} + +typealias STPBoolCompletionBlock = (Bool) -> Void +// SFSafariViewController sometimes manages its own dismissal and does not currently provide +// any easier API hooks to detect when the dismissal has completed. This machinery exists to +// insert ourselves into the View Controller transitioning process and detect when a dismissal +// transition has completed. +class STPSafariViewControllerPresentationController: UIPresentationController { + weak var dismissalDelegate: STPSafariViewControllerDismissalDelegate? + + override func dismissalTransitionDidEnd(_ completed: Bool) { + if presentedViewController is SFSafariViewController { + if let presentedViewController = presentedViewController as? SFSafariViewController { + dismissalDelegate?.safariViewControllerDidCompleteDismissal(presentedViewController) + } + } + return super.dismissalTransitionDidEnd(completed) + } +} diff --git a/Pods/StripePayments/StripePayments/StripePayments/Categories/Enums+CustomStringConvertible.swift b/Pods/StripePayments/StripePayments/StripePayments/Categories/Enums+CustomStringConvertible.swift new file mode 100644 index 0000000..807c7c7 --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/Categories/Enums+CustomStringConvertible.swift @@ -0,0 +1,879 @@ +// +// Enums+CustomStringConvertible.swift +// Stripe +// +// Autogenerated by generate_objc_enum_string_values.rb +// Copyright © 2021 Stripe, Inc. All rights reserved. +// + +/// :nodoc: +extension STPBankAccountHolderType: CustomStringConvertible { + public var description: String { + switch self { + case .company: + return "company" + case .individual: + return "individual" + } + } +} + +/// :nodoc: +extension STPBankAccountStatus: CustomStringConvertible { + public var description: String { + switch self { + case .errored: + return "errored" + case .new: + return "new" + case .validated: + return "validated" + case .verificationFailed: + return "verificationFailed" + case .verified: + return "verified" + } + } +} + +/// :nodoc: +extension STPCardBrand: CustomStringConvertible { + public var description: String { + switch self { + case .JCB: + return "JCB" + case .amex: + return "amex" + case .dinersClub: + return "dinersClub" + case .discover: + return "discover" + case .mastercard: + return "mastercard" + case .unionPay: + return "unionPay" + case .unknown: + return "unknown" + case .visa: + return "visa" + } + } +} + +/// :nodoc: +extension STPCardFundingType: CustomStringConvertible { + public var description: String { + switch self { + case .credit: + return "credit" + case .debit: + return "debit" + case .other: + return "other" + case .prepaid: + return "prepaid" + } + } +} + +/// :nodoc: +extension STPCollectBankAccountError: CustomStringConvertible { + public var description: String { + switch self { + case .financialConnectionsSDKNotLinked: + return "financialConnectionsSDKNotLinked" + case .invalidClientSecret: + return "invalidClientSecret" + case .unexpectedError: + return "unexpectedError" + } + } +} + +/// :nodoc: +extension STPConnectAccountBusinessType: CustomStringConvertible { + public var description: String { + switch self { + case .company: + return "company" + case .individual: + return "individual" + } + } +} + +/// :nodoc: +extension STPFPXBankBrand: CustomStringConvertible { + public var description: String { + switch self { + case .BSN: + return "BSN" + case .CIMB: + return "CIMB" + case .HSBC: + return "HSBC" + case .KFH: + return "KFH" + case .RHB: + return "RHB" + case .UOB: + return "UOB" + case .affinBank: + return "affinBank" + case .allianceBank: + return "allianceBank" + case .ambank: + return "ambank" + case .bankIslam: + return "bankIslam" + case .bankMuamalat: + return "bankMuamalat" + case .bankRakyat: + return "bankRakyat" + case .hongLeongBank: + return "hongLeongBank" + case .maybank2E: + return "maybank2E" + case .maybank2U: + return "maybank2U" + case .ocbc: + return "ocbc" + case .publicBank: + return "publicBank" + case .standardChartered: + return "standardChartered" + case .unknown: + return "unknown" + } + } +} + +/// :nodoc: +extension STPFilePurpose: CustomStringConvertible { + public var description: String { + switch self { + case .disputeEvidence: + return "disputeEvidence" + case .identityDocument: + return "identityDocument" + case .unknown: + return "unknown" + } + } +} + +/// :nodoc: +extension STPIntentActionType: CustomStringConvertible { + public var description: String { + switch self { + case .BLIKAuthorize: + return "BLIKAuthorize" + case .OXXODisplayDetails: + return "OXXODisplayDetails" + case .alipayHandleRedirect: + return "alipayHandleRedirect" + case .boletoDisplayDetails: + return "boletoDisplayDetails" + case .redirectToURL: + return "redirectToURL" + case .unknown: + return "unknown" + case .upiAwaitNotification: + return "upiAwaitNotification" + case .useStripeSDK: + return "useStripeSDK" + case .verifyWithMicrodeposits: + return "verifyWithMicrodeposits" + case .weChatPayRedirectToApp: + return "weChatPayRedirectToApp" + } + } +} + +/// :nodoc: +extension STPIntentActionUseStripeSDKType: CustomStringConvertible { + public var description: String { + switch self { + case .threeDS2Fingerprint: + return "threeDS2Fingerprint" + case .threeDS2Redirect: + return "threeDS2Redirect" + case .unknown: + return "unknown" + } + } +} + +/// :nodoc: +extension STPKlarnaLineItemType: CustomStringConvertible { + public var description: String { + switch self { + case .SKU: + return "SKU" + case .shipping: + return "shipping" + case .tax: + return "tax" + } + } +} + +/// :nodoc: +extension STPKlarnaPaymentMethods: CustomStringConvertible { + public var description: String { + switch self { + case .installments: + return "installments" + case .none: + return "none" + case .payIn4: + return "payIn4" + case .payIn4OrInstallments: + return "payIn4OrInstallments" + } + } +} + +/// :nodoc: +extension STPMandateCustomerAcceptanceType: CustomStringConvertible { + public var description: String { + switch self { + case .offline: + return "offline" + case .online: + return "online" + } + } +} + +/// :nodoc: +extension STPMicrodepositType: CustomStringConvertible { + public var description: String { + switch self { + case .amounts: + return "amounts" + case .descriptorCode: + return "descriptorCode" + case .unknown: + return "unknown" + } + } +} + +/// :nodoc: +extension STPPaymentHandlerActionStatus: CustomStringConvertible { + public var description: String { + switch self { + case .canceled: + return "canceled" + case .failed: + return "failed" + case .succeeded: + return "succeeded" + } + } +} + +/// :nodoc: +extension STPPaymentHandlerErrorCode: CustomStringConvertible { + public var description: String { + switch self { + case .intentStatusErrorCode: + return "intentStatusErrorCode" + case .invalidClientSecret: + return "invalidClientSecret" + case .noConcurrentActionsErrorCode: + return "noConcurrentActionsErrorCode" + case .notAuthenticatedErrorCode: + return "notAuthenticatedErrorCode" + case .paymentErrorCode: + return "paymentErrorCode" + case .requiredAppNotAvailable: + return "requiredAppNotAvailable" + case .requiresAuthenticationContextErrorCode: + return "requiresAuthenticationContextErrorCode" + case .requiresPaymentMethodErrorCode: + return "requiresPaymentMethodErrorCode" + case .stripe3DS2ErrorCode: + return "stripe3DS2ErrorCode" + case .timedOutErrorCode: + return "timedOutErrorCode" + case .unsupportedAuthenticationErrorCode: + return "unsupportedAuthenticationErrorCode" + } + } +} + +/// :nodoc: +extension STPPaymentIntentActionType: CustomStringConvertible { + public var description: String { + switch self { + case .redirectToURL: + return "redirectToURL" + case .unknown: + return "unknown" + } + } +} + +/// :nodoc: +extension STPPaymentIntentCaptureMethod: CustomStringConvertible { + public var description: String { + switch self { + case .automatic: + return "automatic" + case .manual: + return "manual" + case .unknown: + return "unknown" + } + } +} + +/// :nodoc: +extension STPPaymentIntentConfirmationMethod: CustomStringConvertible { + public var description: String { + switch self { + case .automatic: + return "automatic" + case .manual: + return "manual" + case .unknown: + return "unknown" + } + } +} + +/// :nodoc: +extension STPPaymentIntentLastPaymentErrorType: CustomStringConvertible { + public var description: String { + switch self { + case .api: + return "api" + case .apiConnection: + return "apiConnection" + case .authentication: + return "authentication" + case .card: + return "card" + case .idempotency: + return "idempotency" + case .invalidRequest: + return "invalidRequest" + case .rateLimit: + return "rateLimit" + case .unknown: + return "unknown" + } + } +} + +/// :nodoc: +extension STPPaymentIntentSetupFutureUsage: CustomStringConvertible { + public var description: String { + switch self { + case .none: + return "none" + case .offSession: + return "offSession" + case .onSession: + return "onSession" + case .unknown: + return "unknown" + } + } +} + +/// :nodoc: +@available( + *, + deprecated, + message: "Use STPIntentActionType instead", + renamed: "STPIntentActionType" +) +extension STPPaymentIntentSourceActionType: CustomStringConvertible { + public var description: String { + switch self { + case .authorizeWithURL: + return "authorizeWithURL" + case .unknown: + return "unknown" + } + } +} + +/// :nodoc: +extension STPPaymentIntentStatus: CustomStringConvertible { + public var description: String { + switch self { + case .canceled: + return "canceled" + case .processing: + return "processing" + case .requiresAction: + return "requiresAction" + case .requiresCapture: + return "requiresCapture" + case .requiresConfirmation: + return "requiresConfirmation" + case .requiresPaymentMethod: + return "requiresPaymentMethod" + case .requiresSource: + return "requiresSource" + case .requiresSourceAction: + return "requiresSourceAction" + case .succeeded: + return "succeeded" + case .unknown: + return "unknown" + } + } +} + +/// :nodoc: +extension STPPaymentMethodCardCheckResult: CustomStringConvertible { + public var description: String { + switch self { + case .failed: + return "failed" + case .pass: + return "pass" + case .unavailable: + return "unavailable" + case .unchecked: + return "unchecked" + case .unknown: + return "unknown" + } + } +} + +/// :nodoc: +extension STPPaymentMethodCardWalletType: CustomStringConvertible { + public var description: String { + switch self { + case .amexExpressCheckout: + return "amexExpressCheckout" + case .applePay: + return "applePay" + case .googlePay: + return "googlePay" + case .masterpass: + return "masterpass" + case .samsungPay: + return "samsungPay" + case .unknown: + return "unknown" + case .visaCheckout: + return "visaCheckout" + } + } +} + +/// :nodoc: +extension STPPaymentMethodType: CustomStringConvertible { + public var description: String { + switch self { + case .AUBECSDebit: + return "AUBECSDebit" + case .EPS: + return "EPS" + case .FPX: + return "FPX" + case .OXXO: + return "OXXO" + case .SEPADebit: + return "SEPADebit" + case .UPI: + return "UPI" + case .USBankAccount: + return "USBankAccount" + case .affirm: + return "affirm" + case .afterpayClearpay: + return "afterpayClearpay" + case .alipay: + return "alipay" + case .bacsDebit: + return "bacsDebit" + case .bancontact: + return "bancontact" + case .blik: + return "blik" + case .boleto: + return "boleto" + case .card: + return "card" + case .cardPresent: + return "cardPresent" + case .giropay: + return "giropay" + case .grabPay: + return "grabPay" + case .iDEAL: + return "iDEAL" + case .klarna: + return "klarna" + case .link: + return "link" + case .linkInstantDebit: + return "linkInstantDebit" + case .netBanking: + return "netBanking" + case .payPal: + return "payPal" + case .przelewy24: + return "przelewy24" + case .sofort: + return "sofort" + case .unknown: + return "unknown" + case .weChatPay: + return "weChatPay" + } + } +} + +/// :nodoc: +extension STPPaymentMethodUSBankAccountHolderType: CustomStringConvertible { + public var description: String { + switch self { + case .company: + return "company" + case .individual: + return "individual" + case .unknown: + return "unknown" + } + } +} + +/// :nodoc: +extension STPPaymentMethodUSBankAccountType: CustomStringConvertible { + public var description: String { + switch self { + case .checking: + return "checking" + case .savings: + return "savings" + case .unknown: + return "unknown" + } + } +} + +/// :nodoc: +extension STPPaymentStatus: CustomStringConvertible { + public var description: String { + switch self { + case .error: + return "error" + case .success: + return "success" + case .userCancellation: + return "userCancellation" + } + } +} + +/// :nodoc: +extension STPPinStatus: CustomStringConvertible { + public var description: String { + switch self { + case .ephemeralKeyError: + return "ephemeralKeyError" + case .errorVerificationAlreadyRedeemed: + return "errorVerificationAlreadyRedeemed" + case .errorVerificationCodeIncorrect: + return "errorVerificationCodeIncorrect" + case .errorVerificationExpired: + return "errorVerificationExpired" + case .errorVerificationTooManyAttempts: + return "errorVerificationTooManyAttempts" + case .success: + return "success" + case .unknownError: + return "unknownError" + } + } +} + +/// :nodoc: +extension STPRedirectContextError: CustomStringConvertible { + public var description: String { + switch self { + case .appRedirectError: + return "appRedirectError" + } + } +} + +/// :nodoc: +extension STPRedirectContextState: CustomStringConvertible { + public var description: String { + switch self { + case .cancelled: + return "cancelled" + case .completed: + return "completed" + case .inProgress: + return "inProgress" + case .notStarted: + return "notStarted" + } + } +} + +/// :nodoc: +extension STPSetupIntentLastSetupErrorType: CustomStringConvertible { + public var description: String { + switch self { + case .API: + return "API" + case .apiConnection: + return "apiConnection" + case .authentication: + return "authentication" + case .card: + return "card" + case .idempotency: + return "idempotency" + case .invalidRequest: + return "invalidRequest" + case .rateLimit: + return "rateLimit" + case .unknown: + return "unknown" + } + } +} + +/// :nodoc: +extension STPSetupIntentStatus: CustomStringConvertible { + public var description: String { + switch self { + case .canceled: + return "canceled" + case .processing: + return "processing" + case .requiresAction: + return "requiresAction" + case .requiresConfirmation: + return "requiresConfirmation" + case .requiresPaymentMethod: + return "requiresPaymentMethod" + case .succeeded: + return "succeeded" + case .unknown: + return "unknown" + } + } +} + +/// :nodoc: +extension STPSetupIntentUsage: CustomStringConvertible { + public var description: String { + switch self { + case .none: + return "none" + case .offSession: + return "offSession" + case .onSession: + return "onSession" + case .unknown: + return "unknown" + } + } +} + +/// :nodoc: +extension STPSourceCard3DSecureStatus: CustomStringConvertible { + public var description: String { + switch self { + case .`optional`: + return "`optional`" + case .`required`: + return "`required`" + case .notSupported: + return "notSupported" + case .recommended: + return "recommended" + case .unknown: + return "unknown" + } + } +} + +/// :nodoc: +extension STPSourceFlow: CustomStringConvertible { + public var description: String { + switch self { + case .codeVerification: + return "codeVerification" + case .none: + return "none" + case .receiver: + return "receiver" + case .redirect: + return "redirect" + case .unknown: + return "unknown" + } + } +} + +/// :nodoc: +extension STPSourceRedirectStatus: CustomStringConvertible { + public var description: String { + switch self { + case .failed: + return "failed" + case .notRequired: + return "notRequired" + case .pending: + return "pending" + case .succeeded: + return "succeeded" + case .unknown: + return "unknown" + } + } +} + +/// :nodoc: +extension STPSourceStatus: CustomStringConvertible { + public var description: String { + switch self { + case .canceled: + return "canceled" + case .chargeable: + return "chargeable" + case .consumed: + return "consumed" + case .failed: + return "failed" + case .pending: + return "pending" + case .unknown: + return "unknown" + } + } +} + +/// :nodoc: +extension STPSourceType: CustomStringConvertible { + public var description: String { + switch self { + case .EPS: + return "EPS" + case .P24: + return "P24" + case .SEPADebit: + return "SEPADebit" + case .alipay: + return "alipay" + case .bancontact: + return "bancontact" + case .card: + return "card" + case .giropay: + return "giropay" + case .iDEAL: + return "iDEAL" + case .klarna: + return "klarna" + case .multibanco: + return "multibanco" + case .sofort: + return "sofort" + case .threeDSecure: + return "threeDSecure" + case .unknown: + return "unknown" + case .weChatPay: + return "weChatPay" + } + } +} + +/// :nodoc: +extension STPSourceUsage: CustomStringConvertible { + public var description: String { + switch self { + case .reusable: + return "reusable" + case .singleUse: + return "singleUse" + case .unknown: + return "unknown" + } + } +} + +/// :nodoc: +extension STPSourceVerificationStatus: CustomStringConvertible { + public var description: String { + switch self { + case .failed: + return "failed" + case .pending: + return "pending" + case .succeeded: + return "succeeded" + case .unknown: + return "unknown" + } + } +} + +/// :nodoc: +extension STPThreeDSButtonTitleStyle: CustomStringConvertible { + public var description: String { + switch self { + case .`default`: + return "`default`" + case .lowercase: + return "lowercase" + case .sentenceCapitalized: + return "sentenceCapitalized" + case .uppercase: + return "uppercase" + } + } +} + +/// :nodoc: +extension STPThreeDSCustomizationButtonType: CustomStringConvertible { + public var description: String { + switch self { + case .`continue`: + return "`continue`" + case .cancel: + return "cancel" + case .next: + return "next" + case .resend: + return "resend" + case .submit: + return "submit" + } + } +} + +/// :nodoc: +extension STPTokenType: CustomStringConvertible { + public var description: String { + switch self { + case .PII: + return "PII" + case .account: + return "account" + case .bankAccount: + return "bankAccount" + case .card: + return "card" + case .cvcUpdate: + return "cvcUpdate" + } + } +} diff --git a/Pods/StripePayments/StripePayments/StripePayments/Helpers/STPBINController.swift b/Pods/StripePayments/StripePayments/StripePayments/Helpers/STPBINController.swift new file mode 100644 index 0000000..4ce80e7 --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/Helpers/STPBINController.swift @@ -0,0 +1,409 @@ +// +// STPBINController.swift +// StripePayments +// +// Created by Jack Flintermann on 5/24/16. +// Copyright © 2016 Stripe, Inc. All rights reserved. +// + +import Foundation +@_spi(STP) import StripeCore + +@_spi(STP) public struct STPBINRange: Decodable, Equatable { + @_spi(STP) public let panLength: UInt + @_spi(STP) public let brand: STPCardBrand + @_spi(STP) public let accountRangeLow: String + @_spi(STP) public let accountRangeHigh: String + @_spi(STP) public let country: String? + + private enum CodingKeys: String, CodingKey { + case panLength = "pan_length" + case brand = "brand" + case accountRangeLow = "account_range_low" + case accountRangeHigh = "account_range_high" + case country = "country" + } + + @_spi(STP) public init( + from decoder: Decoder + ) throws { + let container = try decoder.container(keyedBy: CodingKeys.self) + self.panLength = try container.decode(UInt.self, forKey: .panLength) + let brandString = try container.decode(String.self, forKey: .brand) + self.brand = STPCard.brand(from: brandString) + self.accountRangeLow = try container.decode(String.self, forKey: .accountRangeLow) + self.accountRangeHigh = try container.decode(String.self, forKey: .accountRangeHigh) + self.country = try? container.decode(String.self, forKey: .country) + self.isHardcoded = false + } + + @_spi(STP) public init( + panLength: UInt, + brand: STPCardBrand, + accountRangeLow: String, + accountRangeHigh: String, + country: String? + ) { + self.panLength = panLength + self.brand = brand + self.accountRangeLow = accountRangeLow + self.accountRangeHigh = accountRangeHigh + self.country = country + self.isHardcoded = true + } + + /// indicates bin range was included in the SDK (rather than downloaded from edge service) + @_spi(STP) public var isHardcoded: Bool +} + +extension STPBINRange { + /// Number matching strategy: Truncate the longer of the two numbers (theirs and our + /// bounds) to match the length of the shorter one, then do numerical compare. + func matchesNumber(_ number: String) -> Bool { + + var withinLowRange = false + var withinHighRange = false + + if number.count < (accountRangeLow.count) { + withinLowRange = + Int(number) ?? 0 >= Int( + (accountRangeLow as NSString?)?.substring(to: number.count) ?? "" + ) + ?? 0 + } else { + withinLowRange = + Int((number as NSString).substring(to: accountRangeLow.count)) ?? 0 >= Int( + accountRangeLow + ) + ?? 0 + } + + if number.count < (accountRangeHigh.count) { + withinHighRange = + Int(number) ?? 0 <= Int( + (accountRangeHigh as NSString?)?.substring(to: number.count) ?? "" + ) ?? 0 + } else { + withinHighRange = + Int((number as NSString).substring(to: accountRangeHigh.count)) ?? 0 <= Int( + accountRangeHigh + ) ?? 0 + } + + return withinLowRange && withinHighRange + } + + func compare(_ other: STPBINRange) -> ComparisonResult { + return NSNumber(value: accountRangeLow.count).compare( + NSNumber(value: other.accountRangeLow.count) + ) + } +} + +private let CardMetadataURL = URL(string: "https://api.stripe.com/edge-internal/card-metadata")! + +extension STPBINRange { + struct STPBINRangeResponse: Decodable { + var data: [STPBINRange] + } + + typealias BINRangeCompletionBlock = (Result) -> Void + + /// Converts a PKPayment object into a Stripe token using the Stripe API. + /// - Parameters: + /// - payment: The user's encrypted payment information as returned from a PKPaymentAuthorizationController. Cannot be nil. + /// - completion: The callback to run with the returned Stripe token (and any errors that may have occurred). + static func retrieve( + apiClient: STPAPIClient = .shared, + forPrefix binPrefix: String, + completion: @escaping BINRangeCompletionBlock + ) { + assert(binPrefix.count == 6, "Requests can only be made with 6-digit binPrefixes.") + // not adding explicit handling for above assert as endpoint will error anyway + let params = [ + "bin_prefix": binPrefix + ] + + apiClient.get(url: CardMetadataURL, parameters: params, completion: completion) + } +} + +@_spi(STP) public typealias STPRetrieveBINRangesCompletionBlock = (Result<[STPBINRange], Error>) -> + Void + +@_spi(STP) public class STPBINController { + @_spi(STP) public static let shared = STPBINController() + + @_spi(STP) public func isLoadingCardMetadata(forPrefix binPrefix: String) -> Bool { + var isLoading = false + self._retrievalQueue.sync(execute: { + let binPrefixKey = binPrefix.stp_safeSubstring(to: kPrefixLengthForMetadataRequest) + isLoading = sPendingRequests[binPrefixKey] != nil + }) + return isLoading + } + + @_spi(STP) public func allRanges() -> [STPBINRange] { + var ret: [STPBINRange]? + self._performSync(withAllRangesLock: { + ret = sAllRanges + }) + + return ret ?? [] + } + + @_spi(STP) public func binRanges(forNumber number: String) -> [STPBINRange] { + return self.allRanges().filter { (binRange) -> Bool in + binRange.matchesNumber(number) + } + } + + @_spi(STP) public func binRanges(for brand: STPCardBrand) -> [STPBINRange] { + return self.allRanges().filter { (binRange) -> Bool in + binRange.brand == brand + } + } + + @_spi(STP) public func mostSpecificBINRange(forNumber number: String) -> STPBINRange { + let validRanges = self.allRanges().filter { (range) -> Bool in + range.matchesNumber(number) + } + return validRanges.sorted { (r1, r2) -> Bool in + if number.isEmpty { + // empty numbers should always best match to unknown brand + if r1.brand == .unknown && r2.brand != .unknown { + return true + } else if r1.brand != .unknown && r2.brand == .unknown { + return false + } + } + return r1.compare(r2) == .orderedAscending + }.last! + } + + @_spi(STP) public func maxCardNumberLength() -> Int { + return kMaxCardNumberLength + } + + /// Returns the shortest possible card number length for the brand + @_spi(STP) public func minCardNumberLength(for brand: STPCardBrand) -> Int { + switch brand { + case .visa, .amex, .mastercard, .discover, .JCB, .dinersClub: + return allRanges().reduce(Int.max) { currentMinimum, range in + if range.brand == brand { + return min(currentMinimum, Int(range.panLength)) + } else { + return currentMinimum + } + } + case .unionPay: + return 16 + case .unknown: + return 13 + } + } + + @_spi(STP) public func minLengthForFullBINRange() -> Int { + return kPrefixLengthForMetadataRequest + } + + /// This is basically a wrapper around: + /// + /// 1. Does BIN have variable length pans, i.e. do we need to call the metadata service + /// 2. If yes, have we already gotten a response from the metadata service + @_spi(STP) public func hasBINRanges(forPrefix binPrefix: String) -> Bool { + if self.isInvalidBINPrefix(binPrefix) { + return true // we won't fetch any more info for this prefix + } + // if we know a card has a static length, we don't need to ask the BIN service + if !self.isVariableLengthBINPrefix(binPrefix) { + return true + } + var hasBINRanges = false + self._retrievalQueue.sync(execute: { + let binPrefixKey = binPrefix.stp_safeSubstring(to: kPrefixLengthForMetadataRequest) + hasBINRanges = + (binPrefixKey.count) == kPrefixLengthForMetadataRequest + && sRetrievedRanges[binPrefixKey] != nil + }) + return hasBINRanges + } + + func isInvalidBINPrefix(_ binPrefix: String) -> Bool { + let firstFive = binPrefix.stp_safeSubstring(to: kPrefixLengthForMetadataRequest - 1) + return (self.mostSpecificBINRange(forNumber: firstFive)).brand == .unknown + } + + /// This will asynchronously check if we have already fetched metadata for this prefix and if we have not will + /// issue a network request to retrieve it if possible. + /// - Parameter recordErrorsAsSuccess: An unfortunate toggle for behavior that STPCardFormView/STPPaymentCardTextField depends on. See https://jira.corp.stripe.com/browse/MOBILESDK-724 + @_spi(STP) public func retrieveBINRanges( + forPrefix binPrefix: String, + recordErrorsAsSuccess: Bool = true, + completion: @escaping STPRetrieveBINRangesCompletionBlock + ) { + self._retrievalQueue.async(execute: { + let binPrefixKey = binPrefix.stp_safeSubstring(to: kPrefixLengthForMetadataRequest) + if self.sRetrievedRanges[binPrefixKey] != nil + || (binPrefixKey.count) < kPrefixLengthForMetadataRequest + || self.isInvalidBINPrefix(binPrefixKey) + || !self.isVariableLengthBINPrefix(binPrefix) + { + // if we already have a metadata response or the binPrefix isn't long enough to make a request, + // or we know that this is not a valid BIN prefix + // or we know this isn't a BIN prefix that could contain variable length BINs + // return the bin ranges we already have on device + DispatchQueue.main.async(execute: { + completion(.success(self.binRanges(forNumber: binPrefix))) + }) + } else if self.sPendingRequests[binPrefixKey] != nil { + // A request for this prefix is already in flight, add the completion block to sPendingRequests + if let sPendingRequest = self.sPendingRequests[binPrefixKey] { + self.sPendingRequests[binPrefixKey] = sPendingRequest + [completion] + } + } else { + + self.sPendingRequests[binPrefixKey] = [completion] + + STPBINRange.retrieve( + forPrefix: binPrefixKey, + completion: { result in + self._retrievalQueue.async(execute: { + let ranges = result.map { $0.data } + let completionBlocks = self.sPendingRequests[binPrefixKey] + + self.sPendingRequests.removeValue(forKey: binPrefixKey) + + if recordErrorsAsSuccess { + // The following is a comment for STPCardFormView/STPPaymentCardTextField: + // we'll record this response even if there was an error + // this will prevent our validation from getting stuck thinking we don't + // have enough info if the metadata service is down or unreachable + // Could improve this in the future with "smart" retries + self.sRetrievedRanges[binPrefixKey] = (try? ranges.get()) ?? [] + } else if let ranges = try? ranges.get(), !ranges.isEmpty { + self.sRetrievedRanges[binPrefixKey] = ranges + } + self._performSync(withAllRangesLock: { + self.sAllRanges = + self.sAllRanges + ((try? ranges.get()) ?? []) + }) + + if case .failure(_) = ranges { + STPAnalyticsClient.sharedClient.logCardMetadataResponseFailure() + } + + DispatchQueue.main.async(execute: { + for block in completionBlocks ?? [] { + block(ranges) + } + }) + }) + } + ) + } + }) + + } + + // MARK: - Class Utilities + + static let STPBINRangeInitialRanges: [STPBINRange] = { + let ranges: [(String, String, UInt, STPCardBrand)] = [ + // Unknown + ("", "", 19, .unknown), + // American Express + ("34", "34", 15, .amex), + ("37", "37", 15, .amex), + // Diners Club + ("30", "30", 16, .dinersClub), + ("36", "36", 14, .dinersClub), + ("38", "39", 16, .dinersClub), + // Discover + ("60", "60", 16, .discover), + ("64", "65", 16, .discover), + // JCB + ("35", "35", 16, .JCB), + // Mastercard + ("50", "59", 16, .mastercard), + ("22", "27", 16, .mastercard), + ("67", "67", 16, .mastercard), // Maestro + // UnionPay + ("62", "62", 16, .unionPay), + ("81", "81", 16, .unionPay), + // Include at least one known 19-digit BIN for maxLength + ("621598", "621598", 19, .unionPay), + // Visa + ("40", "49", 16, .visa), + ("413600", "413600", 13, .visa), + ("444509", "444509", 13, .visa), + ("444509", "444509", 13, .visa), + ("444550", "444550", 13, .visa), + ("450603", "450603", 13, .visa), + ("450617", "450617", 13, .visa), + ("450628", "450629", 13, .visa), + ("450636", "450636", 13, .visa), + ("450640", "450641", 13, .visa), + ("450662", "450662", 13, .visa), + ("463100", "463100", 13, .visa), + ("476142", "476142", 13, .visa), + ("476143", "476143", 13, .visa), + ("492901", "492902", 13, .visa), + ("492920", "492920", 13, .visa), + ("492923", "492923", 13, .visa), + ("492928", "492930", 13, .visa), + ("492937", "492937", 13, .visa), + ("492939", "492939", 13, .visa), + ("492960", "492960", 13, .visa), + ] + var binRanges: [STPBINRange] = [] + for range in ranges { + let binRange = STPBINRange.init( + panLength: range.2, + brand: range.3, + accountRangeLow: range.0, + accountRangeHigh: range.1, + country: nil + ) + binRanges.append(binRange) + } + return binRanges + }() + + private var sAllRanges: [STPBINRange] = { + return STPBINRangeInitialRanges + }() + + let sAllRangesLockQueue: DispatchQueue = { + DispatchQueue(label: "com.stripe.STPBINRange.allRanges") + }() + + func _performSync(withAllRangesLock block: () -> Void) { + sAllRangesLockQueue.sync(execute: { + block() + }) + } + + // sPendingRequests contains the completion blocks for a given metadata request that we have not yet gotten a response for + var sPendingRequests: [String: [STPRetrieveBINRangesCompletionBlock]] = [:] + + // sRetrievedRanges tracks the bin prefixes for which we've already received metadata responses + var sRetrievedRanges: [String: [STPBINRange]] = [:] + + // _retrievalQueue protects access to the two above dictionaries, sSpendingRequests and sRetrievedRanges + let _retrievalQueue: DispatchQueue = { + return DispatchQueue(label: "com.stripe.retrieveBINRangesForPrefix") + }() + + func isVariableLengthBINPrefix(_ binPrefix: String) -> Bool { + guard !binPrefix.isEmpty else { + return false + } + let firstFive = binPrefix.stp_safeSubstring(to: kPrefixLengthForMetadataRequest - 1) + // Only UnionPay has variable-length cards at the moment. + return (self.mostSpecificBINRange(forNumber: firstFive)).brand == .unionPay + } +} + +private let kMaxCardNumberLength: Int = 19 +private let kPrefixLengthForMetadataRequest: Int = 6 diff --git a/Pods/StripePayments/StripePayments/StripePayments/Helpers/STPBankAccountCollector.swift b/Pods/StripePayments/StripePayments/StripePayments/Helpers/STPBankAccountCollector.swift new file mode 100644 index 0000000..1672a0c --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/Helpers/STPBankAccountCollector.swift @@ -0,0 +1,462 @@ +// +// STPBankAccountCollector.swift +// StripePayments +// +// Copyright © 2022 Stripe, Inc. All rights reserved. +// + +import Foundation +@_spi(STP) import StripeCore +import UIKit + +/// Error codes generated by STPBankAccountCollector +@objc public enum STPCollectBankAccountError: Int { + + /// Error when using APIs that require the linking the StripeFinancialConnections SDK + @objc(STPCollectBankAccountErrorFinancialConnectionsSDKNotLinked) + case financialConnectionsSDKNotLinked + + /// Error when a secret can not be parsed to retrieve the ID + @objc(STPCollectBankAccountErrorInvalidClientSecret) + case invalidClientSecret + + /// Unexpected behavior in calling the API + @objc(STPCollectBankAccountErrorUnexpectedError) + case unexpectedError +} + +/// A class responsible for collecting bank account information +public class STPBankAccountCollector: NSObject { + + /// By default `sharedHandler` initializes with STPAPIClient.shared. + public var apiClient: STPAPIClient + + @objc(`init`) + @available(swift, deprecated: 0.0.1, obsoleted: 0.0.1, renamed: "init()") + public convenience override init() { + self.init(apiClient: STPAPIClient.shared) + } + + public init( + apiClient: STPAPIClient = .shared + ) { + self.apiClient = apiClient + } + + // MARK: Collect Bank Account - Payment Intent + public typealias STPCollectBankAccountForPaymentCompletionBlock = (STPPaymentIntent?, NSError?) + -> Void + + func error( + for errorCode: STPCollectBankAccountError, + userInfo additionalUserInfo: [AnyHashable: Any]? = nil + ) -> NSError { + var userInfo: [AnyHashable: Any] = additionalUserInfo ?? [:] + switch errorCode { + case .financialConnectionsSDKNotLinked: + userInfo[STPError.errorMessageKey] = + "StripeFinancialConnections SDK has not been linked into your project" + case .invalidClientSecret: + userInfo[STPError.errorMessageKey] = "Unable to parse client secret" + case .unexpectedError: + userInfo[STPError.errorMessageKey] = NSError.stp_unexpectedErrorMessage() + } + return NSError( + domain: STPPaymentHandler.errorDomain, + code: errorCode.rawValue, + userInfo: userInfo as? [String: Any] + ) + } + + /// Presents a modal from the viewController to collect bank account + /// and if completed successfully, link your bank account to a PaymentIntent + /// - Parameters: + /// - clientSecret: Client secret of the payment intent + /// - params: Parameters for this call + /// - viewController: Presenting view controller that will present the modal + /// - completion: Completion block to be called on completion of the operation. + /// Upon success, the `STPPaymentIntent` instance will have an + /// expanded `paymentMethod` containing detailed payment method information + @available(iOS 12, *) + @objc(collectBankAccountForPaymentWithClientSecret:params:from:completion:) + public func collectBankAccountForPayment( + clientSecret: String, + params: STPCollectBankAccountParams, + from viewController: UIViewController, + completion: @escaping STPCollectBankAccountForPaymentCompletionBlock + ) { + collectBankAccountForPayment( + clientSecret: clientSecret, + returnURL: nil, + params: params, + from: viewController, + completion: completion + ) + } + + /// Presents a modal from the viewController to collect bank account + /// and if completed successfully, link your bank account to a PaymentIntent + /// - Parameters: + /// - clientSecret: Client secret of the payment intent + /// - returnURL: A URL that redirects back to your app to be used to return after completing authentication in another app (such as bank app or Safari). + /// - params: Parameters for this call + /// - viewController: Presenting view controller that will present the modal + /// - completion: Completion block to be called on completion of the operation. + /// Upon success, the `STPPaymentIntent` instance will have an + /// expanded `paymentMethod` containing detailed payment method information + @available(iOS 12, *) + @objc(collectBankAccountForPaymentWithClientSecret:returnURL:params:from:completion:) + public func collectBankAccountForPayment( + clientSecret: String, + returnURL: String?, + params: STPCollectBankAccountParams, + from viewController: UIViewController, + completion: @escaping STPCollectBankAccountForPaymentCompletionBlock + ) { + guard let paymentIntentID = STPPaymentIntent.id(fromClientSecret: clientSecret) else { + completion(nil, error(for: .invalidClientSecret)) + return + } + let financialConnectionsCompletion: + (FinancialConnectionsSDKResult?, LinkAccountSession?, NSError?) -> Void = { + result, + linkAccountSession, + error in + if let error = error { + completion( + nil, + self.error(for: .unexpectedError, userInfo: [NSUnderlyingErrorKey: error]) + ) + return + } + guard let linkAccountSession = linkAccountSession, + let result = result + else { + completion(nil, NSError.stp_genericFailedToParseResponseError()) + return + } + + switch result { + case .completed: + self.attachLinkAccountSessionToPaymentIntent( + paymentIntentID: paymentIntentID, + clientSecret: clientSecret, + linkAccountSession: linkAccountSession, + completion: completion + ) + case .cancelled: + self.apiClient.retrievePaymentIntent(withClientSecret: clientSecret) { + intent, + error in + if let intent = intent { + completion(intent, nil) + } else if let error = error { + completion( + nil, + self.error( + for: .unexpectedError, + userInfo: [NSUnderlyingErrorKey: error] + ) + ) + } else { + completion(nil, self.error(for: .unexpectedError)) + } + } + case .failed(let error): + completion( + nil, + self.error(for: .unexpectedError, userInfo: [NSUnderlyingErrorKey: error]) + ) + } + } + collectBankAccountForPayment( + clientSecret: clientSecret, + returnURL: returnURL, + params: params, + from: viewController, + financialConnectionsCompletion: financialConnectionsCompletion + ) + } + + @_spi(STP) public func collectBankAccountForPayment( + clientSecret: String, + returnURL: String?, + params: STPCollectBankAccountParams, + from viewController: UIViewController, + financialConnectionsCompletion: @escaping ( + FinancialConnectionsSDKResult?, LinkAccountSession?, NSError? + ) -> Void + ) { + guard + let financialConnectionsAPI = FinancialConnectionsSDKAvailability.financialConnections() + else { + assertionFailure("FinancialConnections SDK has not been linked into your project") + financialConnectionsCompletion(nil, nil, error(for: .financialConnectionsSDKNotLinked)) + return + } + + guard let paymentIntentID = STPPaymentIntent.id(fromClientSecret: clientSecret) else { + financialConnectionsCompletion(nil, nil, error(for: .invalidClientSecret)) + return + } + + let linkAccountSessionCallback: STPLinkAccountSessionBlock = { linkAccountSession, error in + if let error = error { + financialConnectionsCompletion( + nil, + nil, + self.error(for: .unexpectedError, userInfo: [NSUnderlyingErrorKey: error]) + ) + return + } + guard let linkAccountSession = linkAccountSession else { + financialConnectionsCompletion( + nil, + nil, + NSError.stp_genericFailedToParseResponseError() + ) + return + } + financialConnectionsAPI.presentFinancialConnectionsSheet( + apiClient: self.apiClient, + clientSecret: linkAccountSession.clientSecret, + returnURL: returnURL, + from: viewController + ) { result in + financialConnectionsCompletion(result, linkAccountSession, nil) + } + } + + apiClient.createLinkAccountSession( + paymentIntentID: paymentIntentID, + clientSecret: clientSecret, + paymentMethodType: params.paymentMethodParams.type, + customerName: params.paymentMethodParams.billingDetails?.name, + customerEmailAddress: params.paymentMethodParams.billingDetails?.email, + completion: linkAccountSessionCallback + ) + } + + // MARK: Helper + private func attachLinkAccountSessionToPaymentIntent( + paymentIntentID: String, + clientSecret: String, + linkAccountSession: LinkAccountSession, + completion: @escaping STPCollectBankAccountForPaymentCompletionBlock + ) { + STPAPIClient.shared.attachLinkAccountSession( + paymentIntentID: paymentIntentID, + linkAccountSessionID: linkAccountSession.stripeID, + clientSecret: clientSecret + ) { paymentIntent, error in + if let error = error { + completion( + nil, + self.error(for: .unexpectedError, userInfo: [NSUnderlyingErrorKey: error]) + ) + return + } + guard let paymentIntent = paymentIntent else { + completion(nil, NSError.stp_genericFailedToParseResponseError()) + return + } + completion(paymentIntent, nil) + } + } + + // MARK: Collect Bank Account - Setup Intent + public typealias STPCollectBankAccountForSetupCompletionBlock = (STPSetupIntent?, NSError?) -> + Void + + /// Presents a modal from the viewController to collect bank account + /// and if completed successfully, link your bank account to a SetupIntent + /// - Parameters: + /// - clientSecret: Client secret of the setup intent + /// - params: Parameters for this call + /// - viewController: Presenting view controller that will present the modal + /// - completion: Completion block to be called on completion of the operation. + /// Upon success, the `STPSetupIntent` instance will have an + /// expanded `paymentMethod` containing detailed payment method information + @available(iOS 12, *) + @objc(collectBankAccountForSetupWithClientSecret:params:from:completion:) + public func collectBankAccountForSetup( + clientSecret: String, + params: STPCollectBankAccountParams, + from viewController: UIViewController, + completion: @escaping STPCollectBankAccountForSetupCompletionBlock + ) { + collectBankAccountForSetup( + clientSecret: clientSecret, + returnURL: nil, + params: params, + from: viewController, + completion: completion + ) + } + + /// Presents a modal from the viewController to collect bank account + /// and if completed successfully, link your bank account to a SetupIntent + /// - Parameters: + /// - clientSecret: Client secret of the setup intent + /// - returnURL: A URL that redirects back to your app to be used to return after completing authentication in another app (such as bank app or Safari). + /// - params: Parameters for this call + /// - viewController: Presenting view controller that will present the modal + /// - completion: Completion block to be called on completion of the operation. + /// Upon success, the `STPSetupIntent` instance will have an + /// expanded `paymentMethod` containing detailed payment method information + @available(iOS 12, *) + @objc(collectBankAccountForSetupWithClientSecret:returnURL:params:from:completion:) + public func collectBankAccountForSetup( + clientSecret: String, + returnURL: String?, + params: STPCollectBankAccountParams, + from viewController: UIViewController, + completion: @escaping STPCollectBankAccountForSetupCompletionBlock + ) { + guard let setupIntentID = STPSetupIntent.id(fromClientSecret: clientSecret) else { + completion(nil, error(for: .invalidClientSecret)) + return + } + let financialConnectionsCompletion: + (FinancialConnectionsSDKResult?, LinkAccountSession?, NSError?) -> Void = { + result, + linkAccountSession, + error in + if let error = error { + completion( + nil, + self.error(for: .unexpectedError, userInfo: [NSUnderlyingErrorKey: error]) + ) + return + } + guard let linkAccountSession = linkAccountSession, + let result = result + else { + completion(nil, NSError.stp_genericFailedToParseResponseError()) + return + } + switch result { + case .completed: + self.attachLinkAccountSessionToSetupIntent( + setupIntentID: setupIntentID, + clientSecret: clientSecret, + linkAccountSession: linkAccountSession, + completion: completion + ) + case .cancelled: + self.apiClient.retrieveSetupIntent(withClientSecret: clientSecret) { + intent, + error in + if let intent = intent { + completion(intent, nil) + } else if let error = error { + completion( + nil, + self.error( + for: .unexpectedError, + userInfo: [NSUnderlyingErrorKey: error] + ) + ) + } else { + completion(nil, self.error(for: .unexpectedError)) + } + } + case .failed(let error): + completion( + nil, + self.error(for: .unexpectedError, userInfo: [NSUnderlyingErrorKey: error]) + ) + } + } + collectBankAccountForSetup( + clientSecret: clientSecret, + returnURL: returnURL, + params: params, + from: viewController, + financialConnectionsCompletion: financialConnectionsCompletion + ) + } + + @_spi(STP) public func collectBankAccountForSetup( + clientSecret: String, + returnURL: String?, + params: STPCollectBankAccountParams, + from viewController: UIViewController, + financialConnectionsCompletion: @escaping ( + FinancialConnectionsSDKResult?, LinkAccountSession?, NSError? + ) -> Void + ) { + guard + let financialConnectionsAPI = FinancialConnectionsSDKAvailability.financialConnections() + else { + assertionFailure("FinancialConnections SDK has not been linked into your project") + financialConnectionsCompletion(nil, nil, error(for: .financialConnectionsSDKNotLinked)) + return + } + guard let setupIntentID = STPSetupIntent.id(fromClientSecret: clientSecret) else { + financialConnectionsCompletion(nil, nil, error(for: .invalidClientSecret)) + return + } + let linkAccountSessionCallback: STPLinkAccountSessionBlock = { linkAccountSession, error in + if let error = error { + financialConnectionsCompletion( + nil, + nil, + self.error(for: .unexpectedError, userInfo: [NSUnderlyingErrorKey: error]) + ) + return + } + guard let linkAccountSession = linkAccountSession else { + financialConnectionsCompletion( + nil, + nil, + NSError.stp_genericFailedToParseResponseError() + ) + return + } + financialConnectionsAPI.presentFinancialConnectionsSheet( + apiClient: self.apiClient, + clientSecret: linkAccountSession.clientSecret, + returnURL: returnURL, + from: viewController + ) { result in + financialConnectionsCompletion(result, linkAccountSession, nil) + } + } + apiClient.createLinkAccountSession( + setupIntentID: setupIntentID, + clientSecret: clientSecret, + paymentMethodType: params.paymentMethodParams.type, + customerName: params.paymentMethodParams.billingDetails?.name, + customerEmailAddress: params.paymentMethodParams.billingDetails?.email, + completion: linkAccountSessionCallback + ) + } + + // MARK: Helper + private func attachLinkAccountSessionToSetupIntent( + setupIntentID: String, + clientSecret: String, + linkAccountSession: LinkAccountSession, + completion: @escaping STPCollectBankAccountForSetupCompletionBlock + ) { + STPAPIClient.shared.attachLinkAccountSession( + setupIntentID: setupIntentID, + linkAccountSessionID: linkAccountSession.stripeID, + clientSecret: clientSecret + ) { setupIntent, error in + if let error = error { + completion( + nil, + self.error(for: .unexpectedError, userInfo: [NSUnderlyingErrorKey: error]) + ) + return + } + guard let setupIntent = setupIntent else { + completion(nil, NSError.stp_genericFailedToParseResponseError()) + return + } + completion(setupIntent, nil) + } + } +} diff --git a/Pods/StripePayments/StripePayments/StripePayments/Helpers/STPBlocks.swift b/Pods/StripePayments/StripePayments/StripePayments/Helpers/STPBlocks.swift new file mode 100644 index 0000000..2212701 --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/Helpers/STPBlocks.swift @@ -0,0 +1,122 @@ +// +// STPBlocks.swift +// StripePayments +// +// Created by Jack Flintermann on 3/23/16. +// Copyright © 2016 Stripe, Inc. All rights reserved. +// + +import Foundation +import PassKit + +/// An enum representing the status of a payment requested from the user. +@objc public enum STPPaymentStatus: Int { + /// The payment succeeded. + case success + /// The payment failed due to an unforeseen error, such as the user's Internet connection being offline. + case error + /// The user cancelled the payment (for example, by hitting "cancel" in the Apple Pay dialog). + case userCancellation +} + +/// A block that may optionally be called with an error. +/// - Parameter error: The error that occurred, if any. +public typealias STPErrorBlock = (Error?) -> Void +/// A block that contains a boolean success param and may optionally be called with an error. +/// - Parameters: +/// - success: Whether the task succeeded. +/// - error: The error that occurred, if any. +public typealias STPBooleanSuccessBlock = (Bool, Error?) -> Void +/// A callback to be run with a JSON response. +/// - Parameters: +/// - jsonResponse: The JSON response, or nil if an error occured. +/// - error: The error that occurred, if any. +public typealias STPJSONResponseCompletionBlock = ([AnyHashable: Any]?, Error?) -> Void +/// A callback to be run with a token response from the Stripe API. +/// - Parameters: +/// - token: The Stripe token from the response. Will be nil if an error occurs. - seealso: STPToken +/// - error: The error returned from the response, or nil if none occurs. - seealso: StripeError.h for possible values. +public typealias STPTokenCompletionBlock = (STPToken?, Error?) -> Void +/// A callback to be run with a source response from the Stripe API. +/// - Parameters: +/// - source: The Stripe source from the response. Will be nil if an error occurs. - seealso: STPSource +/// - error: The error returned from the response, or nil if none occurs. - seealso: StripeError.h for possible values. +public typealias STPSourceCompletionBlock = (STPSource?, Error?) -> Void +/// A callback to be run with a source or card response from the Stripe API. +/// - Parameters: +/// - source: The Stripe source from the response. Will be nil if an error occurs. - seealso: STPSourceProtocol +/// - error: The error returned from the response, or nil if none occurs. - seealso: StripeError.h for possible values. +public typealias STPSourceProtocolCompletionBlock = (STPSourceProtocol?, Error?) -> Void +/// A callback to be run with a PaymentIntent response from the Stripe API. +/// - Parameters: +/// - paymentIntent: The Stripe PaymentIntent from the response. Will be nil if an error occurs. - seealso: STPPaymentIntent +/// - error: The error returned from the response, or nil if none occurs. - seealso: StripeError.h for possible values. +public typealias STPPaymentIntentCompletionBlock = (STPPaymentIntent?, Error?) -> Void +/// A callback to be run with a PaymentIntent response from the Stripe API. +/// - Parameters: +/// - setupIntent: The Stripe SetupIntent from the response. Will be nil if an error occurs. - seealso: STPSetupIntent +/// - error: The error returned from the response, or nil if none occurs. - seealso: StripeError.h for possible values. +public typealias STPSetupIntentCompletionBlock = (STPSetupIntent?, Error?) -> Void +/// A callback to be run with a PaymentMethod response from the Stripe API. +/// - Parameters: +/// - paymentMethod: The Stripe PaymentMethod from the response. Will be nil if an error occurs. - seealso: STPPaymentMethod +/// - error: The error returned from the response, or nil if none occurs. - seealso: StripeError.h for possible values. +public typealias STPPaymentMethodCompletionBlock = (STPPaymentMethod?, Error?) -> Void +/// A callback to be run with an array of PaymentMethods response from the Stripe API. +/// - Parameters: +/// - paymentMethods: An array of PaymentMethod from the response. Will be nil if an error occurs. - seealso: STPPaymentMethod +/// - error: The error returned from the response, or nil if none occurs. - seealso: StripeError.h for possible values. +public typealias STPPaymentMethodsCompletionBlock = ([STPPaymentMethod]?, Error?) -> Void + +/// A callback to be run with a file response from the Stripe API. +/// - Parameters: +/// - file: The Stripe file from the response. Will be nil if an error occurs. - seealso: STPFile +/// - error: The error returned from the response, or nil if none occurs. - seealso: StripeError.h for possible values. +public typealias STPFileCompletionBlock = (STPFile?, Error?) -> Void +/// A callback to be run with a customer response from the Stripe API. +/// - Parameters: +/// - customer: The Stripe customer from the response, or nil if an error occurred. - seealso: STPCustomer +/// - error: The error returned from the response, or nil if none occurs. +public typealias STPCustomerCompletionBlock = (STPCustomer?, Error?) -> Void +/// An enum representing the success and error states of PIN management +@objc public enum STPPinStatus: Int { + /// The verification object was already redeemed + case success + /// The verification object was already redeemed + case errorVerificationAlreadyRedeemed + /// The one-time code was incorrect + case errorVerificationCodeIncorrect + /// The verification object was expired + case errorVerificationExpired + /// The verification object has been attempted too many times + case errorVerificationTooManyAttempts + /// An error occured while retrieving the ephemeral key + case ephemeralKeyError + /// An unknown error occured + case unknownError +} + +/// A callback to be run with a card PIN response from the Stripe API. +/// - Parameters: +/// - cardPin: The Stripe card PIN from the response. Will be nil if an error occurs. - seealso: STPIssuingCardPin +/// - status: The status to help you sort between different error state, or STPPinSuccess when succesful. - seealso: STPPinStatus for possible values. +/// - error: The error returned from the response, or nil if none occurs. - seealso: StripeError.h for possible values. +public typealias STPPinCompletionBlock = (STPIssuingCardPin?, STPPinStatus, Error?) -> Void +/// A callback to be run with a 3DS2 authenticate response from the Stripe API. +/// - Parameters: +/// - authenticateResponse: The Stripe AuthenticateResponse. Will be nil if an error occurs. - seealso: STP3DS2AuthenticateResponse +/// - error: The error returned from the response, or nil if none occurs. +typealias STP3DS2AuthenticateCompletionBlock = (STP3DS2AuthenticateResponse?, Error?) -> Void +/// A block called with a payment status and an optional error. +/// - Parameter error: The error that occurred, if any. +public typealias STPPaymentStatusBlock = (STPPaymentStatus, Error?) -> Void + +/// A callback to be run with an STPRadarSession +/// +/// - Parameters: +/// - radarSession: The RadarSession object. +/// - error: The error that occured, if any. +public typealias STPRadarSessionCompletionBlock = (STPRadarSession?, Error?) -> Void + +/// An empty block, called with no arguments, returning nothing. +public typealias STPVoidBlock = () -> Void diff --git a/Pods/StripePayments/StripePayments/StripePayments/Helpers/STPCardValidator.swift b/Pods/StripePayments/StripePayments/StripePayments/Helpers/STPCardValidator.swift new file mode 100644 index 0000000..59d1124 --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/Helpers/STPCardValidator.swift @@ -0,0 +1,470 @@ +// +// STPCardValidator.swift +// StripePayments +// +// Created by Jack Flintermann on 7/15/15. +// Copyright (c) 2015 Stripe, Inc. All rights reserved. +// + +import Foundation +@_spi(STP) import StripeCore + +/// These fields indicate whether a card field represents a valid value, invalid +/// value, or incomplete value. +@objc @frozen public enum STPCardValidationState: Int { + /// The field's contents are valid. For example, a valid, 16-digit card number. + /// Note that valid values may not be complete. For example: a US Zip code can + /// be 5 or 9 digits. A 5-digit code is Valid, but more text could be entered + /// to transition to incomplete again. American Express CVC codes can be 3 or + /// 4 digits and both will be treated as Valid. + case valid + /// The field's contents are invalid. For example, an expiration date + /// of "13/42". + case invalid + /// The field's contents are not currently valid, but could be by typing + /// additional characters. For example, a CVC of "1". + case incomplete +} + +/// This class contains static methods to validate card numbers, expiration dates, +/// and CVCs. For a list of test card numbers to use with this code, +/// see https://stripe.com/docs/testing +@objc(STPCardValidator) +public class STPCardValidator: NSObject { + /// Returns a copy of the passed string with all non-numeric characters removed. + @objc(sanitizedNumericStringForString:) + public class func sanitizedNumericString( + for string: String + ) + -> String + { + return stringByRemovingCharactersFromSet(string, CharacterSet.stp_invertedAsciiDigit) + } + + /// Returns a copy of the passed string with all characters removed that do not exist within a postal code. + @objc(sanitizedPostalStringForString:) + public class func sanitizedPostalString( + for string: String + ) + -> String + { + let sanitizedString = stringByRemovingCharactersFromSet( + string, + CharacterSet.stp_invertedPostalCode + ) + let sanitizedStringWithoutPunctuation = stringByRemovingCharactersFromSet( + sanitizedString, + CharacterSet(charactersIn: " -") + ) + if sanitizedStringWithoutPunctuation == "" { + // No postal codes begin with a space or -. If the user has only entered these characters, it was probably a typo. + return "" + } + return sanitizedString + } + + /// Whether or not the target string contains only numeric characters. + @objc(stringIsNumeric:) + public class func stringIsNumeric(_ string: String) -> Bool { + return + (string as NSString).rangeOfCharacter(from: CharacterSet.stp_invertedAsciiDigit) + .location + == NSNotFound + } + + /// Validates a card number, passed as a string. This will return + /// STPCardValidationStateInvalid for numbers that are too short or long, contain + /// invalid characters, do not pass Luhn validation, or (optionally) do not match + /// a number format issued by a major card brand. + /// - Parameters: + /// - cardNumber: The card number to validate. Ex. @"4242424242424242" + /// - validatingCardBrand: Whether or not to enforce that the number appears to + /// be issued by a major card brand (or could be). For example, no issuing card + /// network currently issues card numbers beginning with the digit 9; if an + /// otherwise correct-length and luhn-valid card number beginning with 9 + /// (example: 9999999999999995) were passed to this method, it would return + /// STPCardValidationStateInvalid if this parameter were YES and + /// STPCardValidationStateValid if this parameter were NO. If unsure, you should + /// use YES for this value. + /// - Returns: STPCardValidationStateValid if the number is valid, + /// STPCardValidationStateInvalid if the number is invalid, or + /// STPCardValidationStateIncomplete if the number is a substring of a valid + /// card (e.g. @"4242"). + @objc(validationStateForNumber:validatingCardBrand:) + public class func validationState( + forNumber cardNumber: String?, + validatingCardBrand: Bool + ) -> STPCardValidationState { + guard let cardNumber = cardNumber else { + return .incomplete + } + let sanitizedNumber = self.stringByRemovingSpaces(from: cardNumber) + if sanitizedNumber.count == 0 { + return .incomplete + } + if !self.stringIsNumeric(sanitizedNumber) { + return .invalid + } + let binRange = STPBINController.shared.mostSpecificBINRange(forNumber: sanitizedNumber) + if binRange.brand == .unknown && validatingCardBrand { + return .invalid + } + if sanitizedNumber.count == binRange.panLength { + let isValidLuhn = self.stringIsValidLuhn(sanitizedNumber) + if isValidLuhn { + if binRange.isHardcoded + && STPBINController.shared.isVariableLengthBINPrefix(sanitizedNumber) + { + // log that we didn't get a match in the metadata response so fell back to a hard coded response + STPAnalyticsClient.sharedClient.logCardMetadataMissingRange() + } + return .valid + } else { + return .invalid + } + } else if sanitizedNumber.count > binRange.panLength { + return .invalid + } else { + return .incomplete + } + } + + /// The card brand for a card number or substring thereof. + /// - Parameter cardNumber: A card number, or partial card number. For + /// example, @"4242", @"5555555555554444", or @"123". + /// - Returns: The brand for that card number. The example parameters would + /// return STPCardBrandVisa, STPCardBrandMasterCard, and + /// STPCardBrandUnknown, respectively. + @objc(brandForNumber:) + public class func brand(forNumber cardNumber: String) -> STPCardBrand { + let sanitizedNumber = self.sanitizedNumericString(for: cardNumber) + let brands = self.possibleBrands(forNumber: sanitizedNumber) + if brands.count == 1 { + return brands.first! + } + return .unknown + } + + /// The possible number lengths for cards associated with a card brand. For + /// example, Discover card numbers contain 16 characters, while American Express + /// cards contain 15 characters. + /// - Parameter brand: The brand to return lengths for. + /// - Returns: The set of possible lengths cards associated with that brand can be. + @objc(lengthsForCardBrand:) + public class func lengths(for brand: STPCardBrand) -> Set { + var set: Set = [] + let binRanges = STPBINController.shared.binRanges(for: brand) + for binRange in binRanges { + _ = set.insert(binRange.panLength) + } + return set + } + + /// The maximum possible length the number of a card associated with the specified + /// brand could be. + /// For example, Visa cards could be either 13 or 16 characters, so this method + /// would return 16 for the that card brand. + /// - Parameter brand: The brand to return the max length for. + /// - Returns: The maximum length card numbers associated with that brand could be. + @objc(maxLengthForCardBrand:) + public class func maxLength(for brand: STPCardBrand) -> Int { + var maxLength = -1 + for length in self.lengths(for: brand) { + if length > maxLength { + maxLength = Int(length) + } + } + return maxLength + } + + /// The length of the final grouping of digits to use when formatting a card number + /// for display. + /// For example, Visa cards display their final 4 numbers, e.g. "4242", while + /// American Express cards display their final 5 digits, e.g. "10005". + /// - Parameter brand: The brand to return the fragment length for. + /// - Returns: The final fragment length card numbers associated with that brand use. + @objc(fragmentLengthForCardBrand:) + public class func fragmentLength(for brand: STPCardBrand) -> Int { + return Int(self.cardNumberFormat(for: brand).last?.uintValue ?? 0) + } + + /// Validates an expiration month, passed as an (optionally 0-padded) string. + /// Example valid values are "3", "12", and "08". Example invalid values are "99", + /// "a", and "00". Incomplete values include "0" and "1". + /// - Parameter expirationMonth: A string representing a 2-digit expiration month for a + /// payment card. + /// - Returns: STPCardValidationStateValid if the month is valid, + /// STPCardValidationStateInvalid if the month is invalid, or + /// STPCardValidationStateIncomplete if the month is a substring of a valid + /// month (e.g. @"0" or @"1"). + @objc(validationStateForExpirationMonth:) + public class func validationState( + forExpirationMonth expirationMonth: String + ) + -> STPCardValidationState + { + + let sanitizedExpiration = self.stringByRemovingSpaces(from: expirationMonth) + + if !self.stringIsNumeric(sanitizedExpiration) { + return .invalid + } + + switch sanitizedExpiration.count { + case 0: + return .incomplete + case 1: + return ((sanitizedExpiration == "0") || (sanitizedExpiration == "1")) + ? .incomplete : .valid + case 2: + return (0 < Int(sanitizedExpiration) ?? 0 && Int(sanitizedExpiration) ?? 0 <= 12) + ? .valid : .invalid + default: + return .invalid + } + } + + /// Validates an expiration year, passed as a string representing the final + /// 2 digits of the year. + /// This considers the period between the current year until 2099 as valid times. + /// An example valid year value would be "16" (assuming the current year, as + /// determined by NSDate.date, is 2015). + /// Will return STPCardValidationStateInvalid for a month/year combination that + /// is earlier than the current date (i.e. @"15" and @"04" in October 2015). + /// Example invalid year values are "00", "a", and "13". Any 1-digit year string + /// will return STPCardValidationStateIncomplete. + /// - Parameters: + /// - expirationYear: A string representing a 2-digit expiration year for a + /// payment card. + /// - expirationMonth: A string representing a valid 2-digit expiration month + /// for a payment card. If the month is invalid + /// (see `validationStateForExpirationMonth`), this will + /// return STPCardValidationStateInvalid. + /// - Returns: STPCardValidationStateValid if the year is valid, + /// STPCardValidationStateInvalid if the year is invalid, or + /// STPCardValidationStateIncomplete if the year is a substring of a valid + /// year (e.g. @"1" or @"2"). + @objc(validationStateForExpirationYear:inMonth:) + public class func validationState( + forExpirationYear expirationYear: String, + inMonth expirationMonth: String + ) -> STPCardValidationState { + return self.validationState( + forExpirationYear: expirationYear, + inMonth: expirationMonth, + inCurrentYear: self.currentYear(), + currentMonth: self.currentMonth() + ) + } + + /// The max CVC length for a card brand (for example, American Express CVCs are + /// 4 digits, while all others are 3). + /// - Parameter brand: The brand to return the max CVC length for. + /// - Returns: The maximum length of CVC numbers for cards associated with that brand. + @objc(maxCVCLengthForCardBrand:) + public class func maxCVCLength(for brand: STPCardBrand) -> UInt { + switch brand { + case .amex, .unknown: + return 4 + default: + return 3 + } + } + + /// Validates a card's CVC, passed as a numeric string, for the given card brand. + /// - Parameters: + /// - cvc: the CVC to validate + /// - brand: the card brand (can be determined from the card's number + /// using `brandForNumber`) + /// - Returns: Whether the CVC represents a valid CVC for that card brand. For + /// example, would return STPCardValidationStateValid for @"123" and + /// STPCardBrandVisa, STPCardValidationStateValid for @"1234" and + /// STPCardBrandAmericanExpress, STPCardValidationStateIncomplete for @"12" and + /// STPCardBrandVisa, and STPCardValidationStateInvalid for @"12345" and any brand. + @objc(validationStateForCVC:cardBrand:) + public class func validationState( + forCVC cvc: String, + cardBrand brand: STPCardBrand + ) + -> STPCardValidationState + { + + if !self.stringIsNumeric(cvc) { + return .invalid + } + + let sanitizedCvc = self.sanitizedNumericString(for: cvc) + + let minLength = self.minCVCLength() + let maxLength = self.maxCVCLength(for: brand) + if sanitizedCvc.count < minLength { + return .incomplete + } else if sanitizedCvc.count > maxLength { + return .invalid + } else { + return .valid + } + } + + /// Validates the given card details. + /// - Parameter card: The card details to validate. + /// - Returns: STPCardValidationStateValid if all fields are valid, + /// STPCardValidationStateInvalid if any field is invalid, or + /// STPCardValidationStateIncomplete if all fields are either incomplete or valid. + @objc(validationStateForCard:) + public class func validationState(forCard card: STPCardParams) -> STPCardValidationState { + return self.validationState( + forCard: card, + inCurrentYear: self.currentYear(), + currentMonth: self.currentMonth() + ) + } + + class func stringByRemovingSpaces(from string: String) -> String { + let set = CharacterSet.whitespaces + return stringByRemovingCharactersFromSet(string, set) + } + + static func stringByRemovingCharactersFromSet(_ string: String, _ cs: CharacterSet) -> String { + let filtered = string.unicodeScalars.filter { !cs.contains($0) } + return String(String.UnicodeScalarView(filtered)) + } + + class func validationState( + forExpirationYear expirationYear: String, + inMonth expirationMonth: String, + inCurrentYear currentYear: Int, + currentMonth: Int + ) -> STPCardValidationState { + + let moddedYear = currentYear % 100 + + if !self.stringIsNumeric(expirationMonth) || !self.stringIsNumeric(expirationYear) { + return .invalid + } + + let sanitizedMonth = self.sanitizedNumericString(for: expirationMonth) + let sanitizedYear = self.sanitizedNumericString(for: expirationYear) + + switch sanitizedYear.count { + case 0, 1: + return .incomplete + case 2: + if self.validationState(forExpirationMonth: sanitizedMonth) == .invalid { + return .invalid + } else { + if Int(sanitizedYear) ?? 0 == moddedYear { + return Int(sanitizedMonth) ?? 0 >= currentMonth ? .valid : .invalid + } else { + return Int(sanitizedYear) ?? 0 > moddedYear ? .valid : .invalid + } + } + default: + return .invalid + } + } + + class func validationState( + forCard card: STPCardParams, + inCurrentYear currentYear: Int, + currentMonth: Int + ) -> STPCardValidationState { + let numberValidation = self.validationState( + forNumber: card.number ?? "", + validatingCardBrand: true + ) + let expMonthString = String(format: "%02lu", UInt(card.expMonth)) + let expMonthValidation = self.validationState(forExpirationMonth: expMonthString) + let expYearString = String(format: "%02lu", UInt(card.expYear) % 100) + let expYearValidation = self.validationState( + forExpirationYear: expYearString, + inMonth: expMonthString, + inCurrentYear: currentYear, + currentMonth: currentMonth + ) + let brand = self.brand(forNumber: card.number ?? "") + let cvcValidation = self.validationState(forCVC: card.cvc ?? "", cardBrand: brand) + + let states = [ + NSNumber(value: numberValidation.rawValue), + NSNumber(value: expMonthValidation.rawValue), + NSNumber(value: expYearValidation.rawValue), + NSNumber(value: cvcValidation.rawValue), + ] + var incomplete = false + for boxedState in states { + let state = STPCardValidationState(rawValue: boxedState.intValue) + if state == .invalid { + return state! + } else if state == .incomplete { + incomplete = true + } + } + return incomplete ? .incomplete : .valid + } + + @_spi(STP) public class func minCVCLength() -> Int { + return 3 + } + + class func possibleBrands(forNumber cardNumber: String) -> Set { + let binRanges = STPBINController.shared.binRanges(forNumber: cardNumber) + var brands = binRanges.map { $0.brand } + brands.removeAll { $0 == .unknown } + return Set(brands) + } + + class func currentYear() -> Int { + let calendar = Calendar(identifier: .gregorian) + return (calendar.component(.year, from: Date())) % 100 + } + + class func currentMonth() -> Int { + let calendar = Calendar(identifier: .gregorian) + return calendar.component(.month, from: Date()) + } +} + +extension STPCardValidator { + class func cardNumberFormat(for brand: STPCardBrand) -> [NSNumber] { + switch brand { + case .amex: + return [NSNumber(value: 4), NSNumber(value: 6), NSNumber(value: 5)] + default: + return [NSNumber(value: 4), NSNumber(value: 4), NSNumber(value: 4), NSNumber(value: 4)] + } + } + + @_spi(STP) public class func cardNumberFormat(forCardNumber cardNumber: String) -> [NSNumber] { + let binRange = STPBINController.shared.mostSpecificBINRange(forNumber: cardNumber) + if binRange.brand == .dinersClub && binRange.panLength == 14 { + return [NSNumber(value: 4), NSNumber(value: 6), NSNumber(value: 4)] + } + + return self.cardNumberFormat(for: binRange.brand) + } + + @_spi(STP) public class func stringIsValidLuhn(_ number: String) -> Bool { + var odd = true + var sum = 0 + var digits: [String] = [] + + for i in 0.. 9 { + digit -= 9 + } + sum += digit + } + + return sum % 10 == 0 + } +} diff --git a/Pods/StripePayments/StripePayments/StripePayments/Helpers/STPLocalizedString.swift b/Pods/StripePayments/StripePayments/StripePayments/Helpers/STPLocalizedString.swift new file mode 100644 index 0000000..24ce47a --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/Helpers/STPLocalizedString.swift @@ -0,0 +1,16 @@ +// +// STPLocalizedString.swift +// StripePayments +// +// Copyright © 2022 Stripe, Inc. All rights reserved. +// + +import Foundation +@_spi(STP) import StripeCore + +@inline(__always) func STPLocalizedString(_ key: String, _ comment: String?) -> String { + return STPLocalizationUtils.localizedStripeString( + forKey: key, + bundleLocator: StripePaymentsBundleLocator.self + ) +} diff --git a/Pods/StripePayments/StripePayments/StripePayments/Helpers/STPPaymentConfirmation+SwiftUI.swift b/Pods/StripePayments/StripePayments/StripePayments/Helpers/STPPaymentConfirmation+SwiftUI.swift new file mode 100644 index 0000000..7d8eb12 --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/Helpers/STPPaymentConfirmation+SwiftUI.swift @@ -0,0 +1,155 @@ +// +// STPPaymentConfirmation+SwiftUI.swift +// StripePayments +// +// Created by David Estes on 2/1/21. +// Copyright © 2021 Stripe, Inc. All rights reserved. +// + +import SafariServices +import SwiftUI + +@available(iOS 13.0, *) +@available(iOSApplicationExtension, unavailable) +@available(macCatalystApplicationExtension, unavailable) +struct ConfirmPaymentPresenter: UIViewControllerRepresentable { + @Binding var presented: Bool + let intentParams: ParamsType + let onCompletion: CompletionBlockType + + func makeCoordinator() -> Coordinator { + return Coordinator(parent: self) + } + + func makeUIViewController(context: Context) -> UIViewController { + return context.coordinator.uiViewController + } + + func updateUIViewController(_ uiViewController: UIViewController, context: Context) { + context.coordinator.parent = self + context.coordinator.presented = presented + } + + class Coordinator: NSObject, STPAuthenticationContext { + func authenticationPresentingViewController() -> UIViewController { + // This is a bit of a hack: We traverse the view hierarchy looking for the most reasonable VC to present from. + // A VC hosted within a SwiftUI cell, for example, doesn't have a parent, so we need to find the UIWindow. + var presentingViewController = uiViewController.view.window?.rootViewController + presentingViewController = + presentingViewController?.presentedViewController ?? presentingViewController + ?? uiViewController + return presentingViewController ?? UIViewController() + } + + var parent: ConfirmPaymentPresenter + init( + parent: ConfirmPaymentPresenter + ) { + self.parent = parent + } + + let uiViewController = UIViewController() + + var presented: Bool = false { + didSet { + if oldValue != presented { + presented ? presentConfirmationSheet() : forciblyDismissConfirmationSheet() + } + } + } + + private func presentConfirmationSheet() { + if let params = self.parent.intentParams as? STPPaymentIntentParams, + let completion = self.parent.onCompletion + as? STPPaymentHandlerActionPaymentIntentCompletionBlock + { + STPPaymentHandler.sharedHandler.confirmPayment(params, with: self) { + (status, pi, error) in + self.parent.presented = false + completion(status, pi, error) + } + } else if let params = self.parent.intentParams as? STPSetupIntentConfirmParams, + let completion = self.parent.onCompletion + as? STPPaymentHandlerActionSetupIntentCompletionBlock + { + STPPaymentHandler.sharedHandler.confirmSetupIntent(params, with: self) { + (status, si, error) in + self.parent.presented = false + completion(status, si, error) + } + } else { + assert(false, "ConfirmPaymentPresenter was passed an invalid type.") + } + + } + + private func forciblyDismissConfirmationSheet() { + if let sfvc = self.authenticationPresentingViewController().presentedViewController + as? SFSafariViewController, + !sfvc.isBeingDismissed + { + self.authenticationPresentingViewController().dismiss(animated: true) + } + } + } +} + +@available(iOS 13.0, *) +@available(iOSApplicationExtension, unavailable) +@available(macCatalystApplicationExtension, unavailable) +extension View { + /// Confirm the payment, presenting a sheet for the user to confirm their payment if needed. + /// - Parameter isConfirmingPayment: A binding to whether the payment is being confirmed. This will present a sheet if needed. It will be updated to `false` after performing the payment confirmation. + /// - Parameter paymentIntentParams: A PaymentIntentParams to confirm. + /// - Parameter onCompletion: Called with the result of the payment after the payment confirmation is done and the sheet (if any) is dismissed. + public func paymentConfirmationSheet( + isConfirmingPayment: Binding, + paymentIntentParams: STPPaymentIntentParams, + onCompletion: @escaping STPPaymentHandlerActionPaymentIntentCompletionBlock + ) -> some View { + self.modifier( + ConfirmPaymentPresentationModifier( + isPresented: isConfirmingPayment, + intentParams: paymentIntentParams, + onCompletion: onCompletion + ) + ) + } + + /// Confirm the SetupIntent, presenting a sheet for the user to confirm if needed. + /// - Parameter isConfirmingSetupIntent: A binding to whether the SetupIntent is being confirmed. This will present a sheet if needed. It will be updated to `false` after performing the SetupIntent confirmation. + /// - Parameter paymentIntentParams: A SetupIntentParams to confirm. + /// - Parameter onCompletion: Called with the result of the SetupIntent confirmation after the confirmation is done and the sheet (if any) is dismissed. + public func setupIntentConfirmationSheet( + isConfirmingSetupIntent: Binding, + setupIntentParams: STPSetupIntentConfirmParams, + onCompletion: @escaping STPPaymentHandlerActionSetupIntentCompletionBlock + ) -> some View { + self.modifier( + ConfirmPaymentPresentationModifier( + isPresented: isConfirmingSetupIntent, + intentParams: setupIntentParams, + onCompletion: onCompletion + ) + ) + } +} + +@available(iOS 13.0, *) +@available(iOSApplicationExtension, unavailable) +@available(macCatalystApplicationExtension, unavailable) +struct ConfirmPaymentPresentationModifier: ViewModifier { + @Binding var isPresented: Bool + let intentParams: ParamsType + let onCompletion: CompletionBlockType + + func body(content: Content) -> some View { + content.background( + ConfirmPaymentPresenter( + presented: $isPresented, + intentParams: intentParams, + onCompletion: onCompletion + ) + ) + } +} diff --git a/Pods/StripePayments/StripePayments/StripePayments/Helpers/StripePayments+Export.swift b/Pods/StripePayments/StripePayments/StripePayments/Helpers/StripePayments+Export.swift new file mode 100644 index 0000000..2e67edd --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/Helpers/StripePayments+Export.swift @@ -0,0 +1,10 @@ +// +// StripePayments+Export.swift +// StripePayments +// +// Created by David Estes on 7/6/22. +// Copyright © 2022 Stripe, Inc. All rights reserved. +// + +import Foundation +@_exported import StripeCore diff --git a/Pods/StripePayments/StripePayments/StripePayments/Helpers/StripePaymentsBundleLocator.swift b/Pods/StripePayments/StripePayments/StripePayments/Helpers/StripePaymentsBundleLocator.swift new file mode 100644 index 0000000..10a9d9c --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/Helpers/StripePaymentsBundleLocator.swift @@ -0,0 +1,19 @@ +// +// StripePaymentsBundleLocator.swift +// StripePayments +// +// Copyright © 2022 Stripe, Inc. All rights reserved. +// + +import Foundation +@_spi(STP) import StripeCore + +/// :nodoc: +@_spi(STP) public final class StripePaymentsBundleLocator: BundleLocatorProtocol { + public static let internalClass: AnyClass = StripePaymentsBundleLocator.self + public static let bundleName = "StripePayments" + #if SWIFT_PACKAGE + public static let spmResourcesBundle = Bundle.module + #endif + public static let resourcesBundle = StripePaymentsBundleLocator.computeResourcesBundle() +} diff --git a/Pods/StripePayments/StripePayments/StripePayments/Internal/API Bindings/APIRequest.swift b/Pods/StripePayments/StripePayments/StripePayments/Internal/API Bindings/APIRequest.swift new file mode 100644 index 0000000..08b9096 --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/Internal/API Bindings/APIRequest.swift @@ -0,0 +1,197 @@ +// +// APIRequest.swift +// StripePayments +// +// Created by Jack Flintermann on 10/14/15. +// Copyright © 2015 Stripe, Inc. All rights reserved. +// + +import Foundation +@_spi(STP) import StripeCore + +let HTTPMethodPOST = "POST" +let HTTPMethodGET = "GET" +let HTTPMethodDELETE = "DELETE" +let JSONKeyObject = "object" + +/// The shape of this class is only for backwards compatibility with the rest of the codebase. +/// +/// Ideally, we should do something like: +/// 1) Use Codable +/// 2) Define every Stripe API resource explicitly as a Resource { URL, HTTPMethod, ReturnType } +/// 3) Make this class generic on the Resource +@_spi(STP) public class APIRequest: NSObject { + @_spi(STP) public typealias STPAPIResponseBlock = (ResponseType?, HTTPURLResponse?, Error?) -> + Void + + @_spi(STP) public class func post( + with apiClient: STPAPIClient, + endpoint: String, + additionalHeaders: [String: String] = [:], + parameters: [String: Any], + completion: @escaping STPAPIResponseBlock + ) { + // Build url + let url = apiClient.apiURL.appendingPathComponent(endpoint) + + // Setup request + var request = apiClient.configuredRequest(for: url, additionalHeaders: additionalHeaders) + request.httpMethod = HTTPMethodPOST + request.stp_setFormPayload(parameters) + + // Perform request + apiClient.urlSession.stp_performDataTask( + with: request as URLRequest, + completionHandler: { body, response, error in + self.parseResponse(response, body: body, error: error, completion: completion) + } + ) + } + + @_spi(STP) public class func getWith( + _ apiClient: STPAPIClient, + endpoint: String, + parameters: [String: Any], + completion: @escaping STPAPIResponseBlock + ) { + self.getWith( + apiClient, + endpoint: endpoint, + additionalHeaders: [:], + parameters: parameters, + completion: completion + ) + } + + @_spi(STP) public class func getWith( + _ apiClient: STPAPIClient, + endpoint: String, + additionalHeaders: [String: String], + parameters: [String: Any], + completion: @escaping STPAPIResponseBlock + ) { + // Build url + let url = apiClient.apiURL.appendingPathComponent(endpoint) + + // Setup request + var request = apiClient.configuredRequest(for: url, additionalHeaders: additionalHeaders) + request.stp_addParameters(toURL: parameters) + request.httpMethod = HTTPMethodGET + + // Perform request + apiClient.urlSession.stp_performDataTask( + with: request as URLRequest, + completionHandler: { body, response, error in + self.parseResponse(response, body: body, error: error, completion: completion) + } + ) + } + + @_spi(STP) public class func delete( + with apiClient: STPAPIClient, + endpoint: String, + parameters: [String: Any], + completion: @escaping STPAPIResponseBlock + ) { + self.delete( + with: apiClient, + endpoint: endpoint, + additionalHeaders: [:], + parameters: parameters, + completion: completion + ) + } + + @_spi(STP) public class func delete( + with apiClient: STPAPIClient, + endpoint: String, + additionalHeaders: [String: String], + parameters: [String: Any], + completion: @escaping STPAPIResponseBlock + ) { + // Build url + let url = apiClient.apiURL.appendingPathComponent(endpoint) + + // Setup request + var request = apiClient.configuredRequest(for: url, additionalHeaders: additionalHeaders) + request.stp_addParameters(toURL: parameters) + request.httpMethod = HTTPMethodDELETE + + // Perform request + apiClient.urlSession.stp_performDataTask( + with: request as URLRequest, + completionHandler: { body, response, error in + self.parseResponse(response, body: body, error: error, completion: completion) + } + ) + } + + class func parseResponse( + _ response: URLResponse?, + body: Data?, + error: Error?, + completion: @escaping (ResponseType?, HTTPURLResponse?, Error?) -> Void + ) { + // Derive HTTP URL response + var httpResponse: HTTPURLResponse? + if response is HTTPURLResponse { + httpResponse = response as? HTTPURLResponse + } + + // Wrap completion block with main thread dispatch + let safeCompletion: ((ResponseType?, Error?) -> Void) = { responseObject, responseError in + stpDispatchToMainThreadIfNecessary({ + completion(responseObject, httpResponse, responseError) + }) + } + + if error != nil { + // Forward NSURLSession error + return safeCompletion(nil, error) + } + + // Parse JSON response body + var jsonDictionary: [AnyHashable: Any]? + if let body = body { + do { + jsonDictionary = + try JSONSerialization.jsonObject(with: body, options: []) as? [AnyHashable: Any] + } catch { + + } + } + + // HACK: + // STPEmptyStripeResponse will always parse successfully and never return an error, as we're + // not looking at the HTTP error code or the error dictionary. + // I'm afraid this will cause issues if anyone is depending on the old behavior, so let's treat + // STPEmptyStripeResponse as special. + // We probably always want errors to override object deserialization: re-evaluate + // this hack when building the new API client. + if ResponseType.self == STPEmptyStripeResponse.self { + if let error: Error = + NSError.stp_error(fromStripeResponse: jsonDictionary, httpResponse: httpResponse) + { + safeCompletion(nil, error) + } else if let responseObject = ResponseType.decodedObject( + fromAPIResponse: jsonDictionary + ) { + safeCompletion(responseObject, nil) + } else { + safeCompletion(nil, NSError.stp_genericFailedToParseResponseError()) + } + return + } + // END OF STPEmptyStripeResponse HACK + + if let responseObject = ResponseType.decodedObject(fromAPIResponse: jsonDictionary) { + safeCompletion(responseObject, nil) + } else { + let error: Error = + NSError.stp_error(fromStripeResponse: jsonDictionary, httpResponse: httpResponse) + ?? NSError.stp_genericFailedToParseResponseError() + safeCompletion(nil, error) + } + } + +} diff --git a/Pods/StripePayments/StripePayments/StripePayments/Internal/API Bindings/STP3DS2AuthenticateResponse.swift b/Pods/StripePayments/StripePayments/StripePayments/Internal/API Bindings/STP3DS2AuthenticateResponse.swift new file mode 100644 index 0000000..7c81409 --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/Internal/API Bindings/STP3DS2AuthenticateResponse.swift @@ -0,0 +1,81 @@ +// +// STP3DS2AuthenticateResponse.swift +// StripePayments +// +// Created by Cameron Sabol on 5/22/19. +// Copyright © 2019 Stripe, Inc. All rights reserved. +// + +import Foundation + +#if canImport(Stripe3DS2) + import Stripe3DS2 +#endif + +enum STP3DS2AuthenticateResponseState: Int { + /// Unknown Authenticate Response state + case unknown = 0 + /// State indicating that a challenge flow needs to be applied + case challengeRequired + /// State indicating that the authentication succeeded + case succeeded +} + +class STP3DS2AuthenticateResponse: NSObject, STPAPIResponseDecodable { + private(set) var allResponseFields: [AnyHashable: Any] = [:] + /// The Authentication Response received from the Access Control Server + private(set) var authenticationResponse: STDSAuthenticationResponse? + /// When the 3DS2 Authenticate Response was created. + private(set) var created: Date? + /// Whether or not this Authenticate Response was created in livemode. + private(set) var livemode = false + /// The identifier for the Source associated with this Authenticate Response + private(set) var sourceID: String? + /// A fallback URL to redirect to instead of running native 3DS2 + private(set) var fallbackURL: URL? + /// The state of the authentication + private(set) var state: STP3DS2AuthenticateResponseState = .unknown + + override required init() { + super.init() + } + + class func decodedObject(fromAPIResponse response: [AnyHashable: Any]?) -> Self? { + guard let response = response else { + return nil + } + let dict = response.stp_dictionaryByRemovingNulls() + + let fallbackURL = dict.stp_url(forKey: "fallback_redirect_url") + + let authenticationResponseJSON = dict.stp_dictionary(forKey: "ares") + + var authenticationResponse: STDSAuthenticationResponse? + if let authenticationResponseJSON = authenticationResponseJSON { + authenticationResponse = STDSAuthenticationResponseFromJSON(authenticationResponseJSON) + } + if authenticationResponse == nil && fallbackURL == nil { + // we need at least one of ares or fallback_redirect_url + return nil + } + + let stateString = dict.stp_string(forKey: "state") + var state: STP3DS2AuthenticateResponseState = .unknown + if stateString == "succeeded" { + state = .succeeded + } else if stateString == "challenge_required" { + state = .challengeRequired + } + + let authResponse = self.init() + authResponse.authenticationResponse = authenticationResponse + authResponse.state = state + authResponse.created = dict.stp_date(forKey: "created") + authResponse.livemode = dict.stp_bool(forKey: "livemode", or: true) + authResponse.sourceID = dict.stp_string(forKey: "source") + authResponse.fallbackURL = fallbackURL + authResponse.allResponseFields = response + + return authResponse + } +} diff --git a/Pods/StripePayments/StripePayments/StripePayments/Internal/API Bindings/STPEmptyStripeResponse.swift b/Pods/StripePayments/StripePayments/StripePayments/Internal/API Bindings/STPEmptyStripeResponse.swift new file mode 100644 index 0000000..a503e7e --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/Internal/API Bindings/STPEmptyStripeResponse.swift @@ -0,0 +1,30 @@ +// +// STPEmptyStripeResponse.swift +// StripePayments +// +// Created by Cameron Sabol on 6/11/19. +// Copyright © 2019 Stripe, Inc. All rights reserved. +// + +import Foundation + +/// An STPAPIResponseDecodable implementation to use for endpoints that don't +/// actually return objects, like /v1/3ds2/challenge_completed +@_spi(STP) public class STPEmptyStripeResponse: NSObject, STPAPIResponseDecodable { + @_spi(STP) public private(set) var allResponseFields: [AnyHashable: Any] = [:] + + required internal override init() { + super.init() + } + + @_spi(STP) public class func decodedObject( + fromAPIResponse response: [AnyHashable: Any]? + ) -> Self? { + let emptyResponse = self.init() + if let response = response { + emptyResponse.allResponseFields = response + } + + return emptyResponse + } +} diff --git a/Pods/StripePayments/StripePayments/StripePayments/Internal/API Bindings/STPFormEncoder.swift b/Pods/StripePayments/StripePayments/StripePayments/Internal/API Bindings/STPFormEncoder.swift new file mode 100644 index 0000000..84783b6 --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/Internal/API Bindings/STPFormEncoder.swift @@ -0,0 +1,97 @@ +// +// STPFormEncoder.swift +// StripePayments +// +// Created by Jack Flintermann on 1/8/15. +// Copyright (c) 2015 Stripe, Inc. All rights reserved. +// + +import Foundation + +@_spi(STP) public class STPFormEncoder: NSObject { + @objc @_spi(STP) public class func dictionary( + forObject object: (NSObject & STPFormEncodable) + ) -> [String: Any] { + // returns [object root name : object.coded (eg [property name strings: property values)] + let keyPairs = self.keyPairDictionary(forObject: object) + let rootObjectName = type(of: object).rootObjectName() + if let rootObjectName = rootObjectName { + return [rootObjectName: keyPairs] + } else { + return keyPairs + } + } + + // MARK: - Internal + + /// Returns [Property name : Property's form encodable value] + private class func keyPairDictionary( + forObject object: (NSObject & STPFormEncodable) + ) + -> [String: + Any] + { + var keyPairs: [String: Any] = [:] + for (propertyName, formFieldName) in type(of: object).propertyNamesToFormFieldNamesMapping() + { + if let propertyValue = object.value(forKeyPath: propertyName) { + guard let propertyValue = propertyValue as? NSObject else { + assertionFailure() + continue + } + keyPairs[formFieldName] = formEncodableValue(for: propertyValue) + } + } + for (additionalFieldName, additionalFieldValue) in object.additionalAPIParameters { + guard let additionalFieldName = additionalFieldName as? String, + let additionalFieldValue = additionalFieldValue as? NSObject + else { + assertionFailure() + continue + } + keyPairs[additionalFieldName] = formEncodableValue(for: additionalFieldValue) + } + return keyPairs + } + + /// Expands object, and any subobjects, into key pair dictionaries if they are STPFormEncodable + private class func formEncodableValue(for object: NSObject) -> NSObject { + switch object { + case let object as NSObject & STPFormEncodable: + return self.keyPairDictionary(forObject: object) as NSObject + case let dict as NSDictionary: + let result = NSMutableDictionary(capacity: dict.count) + dict.enumerateKeysAndObjects({ key, value, _ in + if let key = key as? NSObject, // Don't all keys need to be Strings? + let value = value as? NSObject + { + result[formEncodableValue(for: key)] = formEncodableValue(for: value) + } else { + assertionFailure() // TODO remove + } + }) + return result + case let array as NSArray: + let result = NSMutableArray() + for element in array { + guard let element = element as? NSObject else { + assertionFailure() // TODO remove + continue + } + result.add(formEncodableValue(for: element)) + } + return result + case let set as NSSet: + let result = NSMutableSet() + for element in set { + guard let element = element as? NSObject else { + continue + } + result.add(self.formEncodableValue(for: element)) + } + return result + default: + return object + } + } +} diff --git a/Pods/StripePayments/StripePayments/StripePayments/Internal/API Bindings/STPIntentActionUseStripeSDK.swift b/Pods/StripePayments/StripePayments/StripePayments/Internal/API Bindings/STPIntentActionUseStripeSDK.swift new file mode 100644 index 0000000..79ac9ac --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/Internal/API Bindings/STPIntentActionUseStripeSDK.swift @@ -0,0 +1,224 @@ +// +// STPIntentActionUseStripeSDK.swift +// StripePayments +// +// Created by Cameron Sabol on 5/15/19. +// Copyright © 2019 Stripe, Inc. All rights reserved. +// + +import Foundation + +@objc +enum STPIntentActionUseStripeSDKType: Int { + case unknown = 0 + case threeDS2Fingerprint + case threeDS2Redirect +} + +class STPIntentActionUseStripeSDK: NSObject { + + let allResponseFields: [AnyHashable: Any] + + let type: STPIntentActionUseStripeSDKType + + // MARK: - 3DS2 Fingerprint + let directoryServerName: String? + let directoryServerID: String? + + /// PEM encoded DS certificate + let directoryServerCertificate: String? + let rootCertificateStrings: [String]? + + /// A Visa-specific field + let directoryServerKeyID: String? + let serverTransactionID: String? + let threeDSSourceID: String? + + /// Publishable key to use for making authentication API calls (Link-specific) + let publishableKeyOverride: String? + let threeDS2IntentOverride: String? + + // MARK: - 3DS2 Redirect + let redirectURL: URL? + + private init( + type: STPIntentActionUseStripeSDKType, + directoryServerName: String?, + directoryServerID: String?, + directoryServerCertificate: String?, + rootCertificateStrings: [String]?, + directoryServerKeyID: String?, + serverTransactionID: String?, + threeDSSourceID: String?, + publishableKeyOverride: String?, + threeDS2IntentOverride: String?, + redirectURL: URL?, + allResponseFields: [AnyHashable: Any] + ) { + self.type = type + self.directoryServerName = directoryServerName + self.directoryServerID = directoryServerID + self.directoryServerCertificate = directoryServerCertificate + self.rootCertificateStrings = rootCertificateStrings + self.directoryServerKeyID = directoryServerKeyID + self.serverTransactionID = serverTransactionID + self.threeDSSourceID = threeDSSourceID + self.publishableKeyOverride = publishableKeyOverride + self.threeDS2IntentOverride = threeDS2IntentOverride + self.redirectURL = redirectURL + self.allResponseFields = allResponseFields + super.init() + } + + convenience init?( + encryptionInfo: [AnyHashable: Any], + directoryServerName: String?, + directoryServerKeyID: String?, + serverTransactionID: String?, + threeDSSourceID: String?, + publishableKeyOverride: String?, + threeDS2IntentOverride: String?, + allResponseFields: [AnyHashable: Any] + ) { + guard let certificate = encryptionInfo["certificate"] as? String, + !certificate.isEmpty, + let directoryServerID = encryptionInfo["directory_server_id"] as? String, + !directoryServerID.isEmpty, + let rootCertificates = encryptionInfo["root_certificate_authorities"] as? [String], + !rootCertificates.isEmpty + else { + return nil + } + self.init( + type: .threeDS2Fingerprint, + directoryServerName: directoryServerName, + directoryServerID: directoryServerID, + directoryServerCertificate: certificate, + rootCertificateStrings: rootCertificates, + directoryServerKeyID: directoryServerKeyID, + serverTransactionID: serverTransactionID, + threeDSSourceID: threeDSSourceID, + publishableKeyOverride: publishableKeyOverride, + threeDS2IntentOverride: threeDS2IntentOverride, + redirectURL: nil, + allResponseFields: allResponseFields + ) + } + + convenience init( + redirectURL: URL, + allResponseFields: [AnyHashable: Any] + ) { + var threeDSSourceID: String? + if redirectURL.lastPathComponent.hasPrefix("src_") { + threeDSSourceID = redirectURL.lastPathComponent + } + self.init( + type: .threeDS2Redirect, + directoryServerName: nil, + directoryServerID: nil, + directoryServerCertificate: nil, + rootCertificateStrings: nil, + directoryServerKeyID: nil, + serverTransactionID: nil, + threeDSSourceID: threeDSSourceID, + publishableKeyOverride: nil, + threeDS2IntentOverride: nil, + redirectURL: redirectURL, + allResponseFields: allResponseFields + ) + } + + convenience override init() { + self.init( + type: .unknown, + directoryServerName: nil, + directoryServerID: nil, + directoryServerCertificate: nil, + rootCertificateStrings: nil, + directoryServerKeyID: nil, + serverTransactionID: nil, + threeDSSourceID: nil, + publishableKeyOverride: nil, + threeDS2IntentOverride: nil, + redirectURL: nil, + allResponseFields: [:] + ) + } + + @objc override var description: String { + let props: [String] = [ + // Object + String(format: "%@: %p", String(describing: STPIntentActionUseStripeSDK.self), self), + // IntentActionUseStripeSDK details (alphabetical) + "directoryServer = \(String(describing: directoryServerName))", + "directoryServerID = \(String(describing: directoryServerID))", + "directoryServerKeyID = \(String(describing: directoryServerKeyID))", + "serverTransactionID = \(String(describing: serverTransactionID))", + "directoryServerCertificate = \(String(describing: (directoryServerCertificate?.count ?? 0 > 0 ? "" : nil)))", + "rootCertificateStrings = \(String(describing: (rootCertificateStrings?.count ?? 0 > 0 ? "" : nil)))", + "threeDSSourceID = \(String(describing: threeDSSourceID))", + "type = \(String(describing: allResponseFields["type"]))", + "redirectURL = \(String(describing: redirectURL))", + ] + + return "<\(props.joined(separator: "; "))>" + } +} + +/// :nodoc: +extension STPIntentActionUseStripeSDK: STPAPIResponseDecodable { + class func decodedObject(fromAPIResponse response: [AnyHashable: Any]?) -> Self? { + guard let dict = response, + let typeString = dict["type"] as? String + else { + return nil + } + + switch typeString { + case "stripe_3ds2_fingerprint": + if let encryptionInfo = dict["directory_server_encryption"] as? [AnyHashable: Any] { + return STPIntentActionUseStripeSDK( + encryptionInfo: encryptionInfo, + directoryServerName: dict["directory_server_name"] as? String, + directoryServerKeyID: encryptionInfo["key_id"] as? String, + serverTransactionID: dict["server_transaction_id"] as? String, + threeDSSourceID: dict["three_d_secure_2_source"] as? String, + publishableKeyOverride: dict["publishable_key"] as? String, + threeDS2IntentOverride: dict["three_d_secure_2_intent"] as? String, + allResponseFields: dict + ) as? Self + } else { + return nil + } + case "three_d_secure_redirect": + if let redirectURLString = dict["stripe_js"] as? String, + let redirectURL = URL(string: redirectURLString) + { + return STPIntentActionUseStripeSDK( + redirectURL: redirectURL, + allResponseFields: dict + ) + as? Self + } else { + return nil + } + + default: + return STPIntentActionUseStripeSDK( + type: .unknown, + directoryServerName: nil, + directoryServerID: nil, + directoryServerCertificate: nil, + rootCertificateStrings: nil, + directoryServerKeyID: nil, + serverTransactionID: nil, + threeDSSourceID: nil, + publishableKeyOverride: nil, + threeDS2IntentOverride: nil, + redirectURL: nil, + allResponseFields: dict + ) as? Self + } + } +} diff --git a/Pods/StripePayments/StripePayments/StripePayments/Internal/API Bindings/STPInternalAPIResponseDecodable.swift b/Pods/StripePayments/StripePayments/StripePayments/Internal/API Bindings/STPInternalAPIResponseDecodable.swift new file mode 100644 index 0000000..822b689 --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/Internal/API Bindings/STPInternalAPIResponseDecodable.swift @@ -0,0 +1,16 @@ +// +// STPInternalAPIResponseDecodable.swift +// StripePayments +// +// Created by Ben Guo on 5/23/17. +// Copyright © 2017 Stripe, Inc. All rights reserved. +// + +import Foundation + +/// Objects that can be returned as part of a heterogenous API response +/// (e.g. cards and sources) should implement this protocol. +@objc protocol STPInternalAPIResponseDecodable: STPAPIResponseDecodable { + /// The object's type. This should match the `object` field in the API response. + func stripeObject() -> String +} diff --git a/Pods/StripePayments/StripePayments/StripePayments/Internal/API Bindings/STPPaymentMethodListDeserializer.swift b/Pods/StripePayments/StripePayments/StripePayments/Internal/API Bindings/STPPaymentMethodListDeserializer.swift new file mode 100644 index 0000000..431782d --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/Internal/API Bindings/STPPaymentMethodListDeserializer.swift @@ -0,0 +1,44 @@ +// +// STPPaymentMethodListDeserializer.swift +// StripePayments +// +// Created by Yuki Tokuhiro on 5/16/19. +// Copyright © 2019 Stripe, Inc. All rights reserved. +// + +import Foundation + +/// Deserializes the response returned from https://stripe.com/docs/api/payment_methods/list +@_spi(STP) public class STPPaymentMethodListDeserializer: NSObject, STPAPIResponseDecodable { + @_spi(STP) public var paymentMethods: [STPPaymentMethod]? + @_spi(STP) public private(set) var allResponseFields: [AnyHashable: Any] = [:] + + // MARK: STPAPIResponseDecodable + override required init() { + super.init() + } + + @_spi(STP) public class func decodedObject( + fromAPIResponse response: [AnyHashable: Any]? + ) -> Self? { + guard let response = response else { + return nil + } + let dict = response.stp_dictionaryByRemovingNulls() + // Required fields + guard let data = dict.stp_array(forKey: "data") as? [[AnyHashable: Any]] else { + return nil + } + + let paymentMethodsDeserializer = self.init() + var paymentMethods: [STPPaymentMethod] = [] + for paymentMethodJSON in data { + let paymentMethod = STPPaymentMethod.decodedObject(fromAPIResponse: paymentMethodJSON) + if let paymentMethod = paymentMethod { + paymentMethods.append(paymentMethod) + } + } + paymentMethodsDeserializer.paymentMethods = paymentMethods + return paymentMethodsDeserializer + } +} diff --git a/Pods/StripePayments/StripePayments/StripePayments/Internal/API Bindings/STPSourcePoller.swift b/Pods/StripePayments/StripePayments/StripePayments/Internal/API Bindings/STPSourcePoller.swift new file mode 100644 index 0000000..9f00b67 --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/Internal/API Bindings/STPSourcePoller.swift @@ -0,0 +1,234 @@ +// +// STPSourcePoller.swift +// StripePayments +// +// Created by Ben Guo on 1/26/17. +// Copyright © 2017 Stripe, Inc. All rights reserved. +// + +import Foundation +@_spi(STP) import StripeCore +import UIKit + +@available(iOSApplicationExtension, unavailable) +@available(macCatalystApplicationExtension, unavailable) +class STPSourcePoller: NSObject { + required init( + apiClient: STPAPIClient, + clientSecret: String, + sourceID: String, + timeout: TimeInterval, + completion: @escaping STPSourceCompletionBlock + ) { + self.apiClient = apiClient + self.sourceID = sourceID + self.clientSecret = clientSecret + self.completion = completion + pollInterval = DefaultPollInterval + self.timeout = timeout + startTime = Date() + retryCount = 0 + requestCount = 0 + pollingPaused = false + pollingStopped = false + super.init() + poll(after: 0, lastError: nil) + let notificationCenter = NotificationCenter.default + notificationCenter.addObserver( + self, + selector: #selector(restartPolling), + name: UIApplication.didBecomeActiveNotification, + object: nil + ) + notificationCenter.addObserver( + self, + selector: #selector(restartPolling), + name: UIApplication.willEnterForegroundNotification, + object: nil + ) + notificationCenter.addObserver( + self, + selector: #selector(pausePolling), + name: UIApplication.willResignActiveNotification, + object: nil + ) + notificationCenter.addObserver( + self, + selector: #selector(pausePolling), + name: UIApplication.didEnterBackgroundNotification, + object: nil + ) + } + + // Stops polling and cancels the request in progress. + func stopPolling() { + pollingStopped = true + if let timer = timer { + timer.invalidate() + self.timer = nil + } + } + + private weak var apiClient: STPAPIClient? + private var sourceID: String + private var clientSecret: String + private var completion: STPSourceCompletionBlock + private var latestSource: STPSource? + private var pollInterval: TimeInterval = 0.0 + private var timeout: TimeInterval = 0.0 + private var timer: Timer? + private var startTime: Date + private var retryCount = 0 + private var requestCount = 0 + private var pollingPaused = false + private var pollingStopped = false + + deinit { + NotificationCenter.default.removeObserver(self) + } + + func poll(after interval: TimeInterval, lastError error: Error?) { + let totalTime: TimeInterval = Date().timeIntervalSince(startTime) + let shouldTimeout = + requestCount > 0 + && ((totalTime) >= TimeInterval(min(timeout, MaxTimeout)) || retryCount >= MaxRetries) + if apiClient == nil || shouldTimeout { + cleanupAndFireCompletion( + with: latestSource, + error: error + ) + return + } + if pollingPaused || pollingStopped { + return + } + timer = Timer.scheduledTimer( + timeInterval: interval, + target: self, + selector: #selector(_poll), + userInfo: nil, + repeats: false + ) + } + + @objc func _poll() { + timer = nil + let application = UIApplication.shared + var bgTaskID: UIBackgroundTaskIdentifier = .invalid + bgTaskID = application.beginBackgroundTask(expirationHandler: { + application.endBackgroundTask(bgTaskID) + bgTaskID = .invalid + }) + apiClient?.retrieveSource( + withId: sourceID, + clientSecret: clientSecret, + responseCompletion: { source, response, error in + self._continue(with: source, response: response, error: error as NSError?) + self.requestCount += 1 + application.endBackgroundTask(bgTaskID) + bgTaskID = .invalid + } + ) + } + + func _continue( + with source: STPSource?, + response: HTTPURLResponse?, + error: NSError? + ) { + if let response = response { + let status = response.statusCode + if status >= 400 && status < 500 { + // Don't retry requests that 4xx + cleanupAndFireCompletion( + with: latestSource, + error: error + ) + } else if status == 200 { + pollInterval = DefaultPollInterval + retryCount = 0 + latestSource = source + if shouldContinuePollingSource(source) { + poll(after: pollInterval, lastError: nil) + } else { + cleanupAndFireCompletion( + with: latestSource, + error: nil + ) + } + } else { + // Backoff and increment retry count + pollInterval = TimeInterval(min(pollInterval * 2, MaxPollInterval)) + retryCount += 1 + poll(after: pollInterval, lastError: error) + } + } else { + // Retry if there's a connectivity error + if let error = error, + error.code == CFNetworkErrors.cfurlErrorNotConnectedToInternet.rawValue + || error.code == CFNetworkErrors.cfurlErrorNetworkConnectionLost.rawValue + { + retryCount += 1 + poll(after: pollInterval, lastError: error) + } else { + // Don't call completion if the request was cancelled + if let error = error, error.code != CFNetworkErrors.cfurlErrorCancelled.rawValue { + cleanupAndFireCompletion( + with: latestSource, + error: error + ) + } + stopPolling() + } + } + } + + func shouldContinuePollingSource(_ source: STPSource?) -> Bool { + if source == nil { + return false + } + return source?.status == .pending + } + + @objc func restartPolling() { + if pollingStopped { + return + } + pollingPaused = false + if timer == nil { + poll(after: 0, lastError: nil) + } + } + + // Pauses polling, without canceling the request in progress. + @objc func pausePolling() { + pollingPaused = true + if let timer = timer { + timer.invalidate() + self.timer = nil + } + } + + func cleanupAndFireCompletion( + with source: STPSource?, + error: Error? + ) { + if !pollingStopped { + DispatchQueue.main.async(execute: { + if error == nil && source == nil { + self.completion(nil, NSError.stp_genericConnectionError()) + } else { + self.completion(source, error) + } + }) + stopPolling() + } + } +} + +private let DefaultPollInterval: TimeInterval = 1.5 +private let MaxPollInterval: TimeInterval = 24 +// Stop polling after 5 minutes +private let MaxTimeout: TimeInterval = 60 * 5 +// Stop polling after 5 consecutive non-200 responses +private let MaxRetries: Int = 5 diff --git a/Pods/StripePayments/StripePayments/StripePayments/Internal/Analytics/Analytic+Payments.swift b/Pods/StripePayments/StripePayments/StripePayments/Internal/Analytics/Analytic+Payments.swift new file mode 100644 index 0000000..e197905 --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/Internal/Analytics/Analytic+Payments.swift @@ -0,0 +1,59 @@ +// +// Analytic+Payments.swift +// StripePayments +// +// Created by Mel Ludowise on 5/26/21. +// Copyright © 2021 Stripe, Inc. All rights reserved. +// + +import Foundation +@_spi(STP) import StripeCore + +/// A generic analytic type. +/// - NOTE: This should only be used to support legacy analytics. +/// Any new analytic events should create a new type and conform to `PaymentAnalytic`. +struct GenericPaymentAnalytic: PaymentAnalytic { + let event: STPAnalyticEvent + let paymentConfiguration: NSObject? + let productUsage: Set + let additionalParams: [String: Any] +} + +/// Represents a generic payment error analytic +struct GenericPaymentErrorAnalytic: PaymentAnalytic, ErrorAnalytic { + let event: STPAnalyticEvent + let paymentConfiguration: NSObject? + let productUsage: Set + let additionalParams: [String: Any] + let error: Error +} + +extension GenericPaymentAnalytic { + var params: [String: Any] { + var params = additionalParams + + params["company_name"] = Bundle.stp_applicationName() ?? "" + params["apple_pay_enabled"] = NSNumber(value: StripeAPI.deviceSupportsApplePay()) + params["ocr_type"] = PaymentsSDKVariant.ocrTypeString + params["pay_var"] = PaymentsSDKVariant.variant + + if let paymentConfiguration = paymentConfiguration, + let analyticsSerializerClass = GenericPaymentAnalytic.STPBasicUIAnalyticsSerializerClass + { + let configurationDictionary = analyticsSerializerClass.serializeConfiguration( + paymentConfiguration + ) + params = params.merging(configurationDictionary) { (_, new) in new } + } + + return params + } + + static let STPBasicUIAnalyticsSerializerClass: STPAnalyticsSerializer.Type? = + NSClassFromString("Stripe.STPBasicUIAnalyticsSerializer") as? STPAnalyticsSerializer.Type + +} + +@_spi(STP) public protocol STPAnalyticsSerializer { + static func serializeConfiguration(_ configuration: NSObject) -> [String: String] +} diff --git a/Pods/StripePayments/StripePayments/StripePayments/Internal/Analytics/STPAnalyticsClient+Payments.swift b/Pods/StripePayments/StripePayments/StripePayments/Internal/Analytics/STPAnalyticsClient+Payments.swift new file mode 100644 index 0000000..5ff3b92 --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/Internal/Analytics/STPAnalyticsClient+Payments.swift @@ -0,0 +1,350 @@ +// +// STPAnalyticsClient+Payments.swift +// StripePayments +// +// Created by Mel Ludowise on 5/26/21. +// Copyright © 2021 Stripe, Inc. All rights reserved. +// + +import Foundation +@_spi(STP) import StripeCore + +// MARK: - Creation +extension STPAnalyticsClient { + func logTokenCreationAttempt( + with configuration: NSObject?, + tokenType: String? + ) { + log( + analytic: GenericPaymentAnalytic( + event: .tokenCreation, + paymentConfiguration: configuration, + productUsage: productUsage, + additionalParams: [ + "token_type": tokenType ?? "unknown" + ] + ) + ) + } + + func logSourceCreationAttempt( + with configuration: NSObject?, + sourceType: String? + ) { + log( + analytic: GenericPaymentAnalytic( + event: .sourceCreation, + paymentConfiguration: configuration, + productUsage: productUsage, + additionalParams: [ + "source_type": sourceType ?? "unknown" + ] + ) + ) + } + + func logPaymentMethodCreationAttempt( + with configuration: NSObject?, + paymentMethodType: String? + ) { + log( + analytic: GenericPaymentAnalytic( + event: .paymentMethodCreation, + paymentConfiguration: configuration, + productUsage: productUsage, + additionalParams: [ + "source_type": paymentMethodType ?? "unknown" + ] + ) + ) + } +} + +// MARK: - Confirmation +extension STPAnalyticsClient { + func logPaymentIntentConfirmationAttempt( + with configuration: NSObject?, + paymentMethodType: String? + ) { + log( + analytic: GenericPaymentAnalytic( + event: .paymentMethodIntentCreation, + paymentConfiguration: configuration, + productUsage: productUsage, + additionalParams: [ + "source_type": paymentMethodType ?? "unknown" + ] + ) + ) + } + + func logSetupIntentConfirmationAttempt( + with configuration: NSObject?, + paymentMethodType: String? + ) { + log( + analytic: GenericPaymentAnalytic( + event: .setupIntentConfirmationAttempt, + paymentConfiguration: configuration, + productUsage: productUsage, + additionalParams: [ + "source_type": paymentMethodType ?? "unknown" + ] + ) + ) + } +} + +// MARK: - 3DS2 Flow +extension STPAnalyticsClient { + func log3DS2AuthenticationRequestParamsFailed( + with configuration: NSObject?, + intentID: String, + error: NSError + ) { + log( + analytic: GenericPaymentErrorAnalytic( + event: ._3DS2AuthenticationRequestParamsFailed, + paymentConfiguration: configuration, + productUsage: productUsage, + additionalParams: [ + "intent_id": intentID + ], + error: error + ) + ) + } + + func log3DS2AuthenticateAttempt( + with configuration: NSObject?, + intentID: String + ) { + log( + analytic: GenericPaymentAnalytic( + event: ._3DS2AuthenticationAttempt, + paymentConfiguration: configuration, + productUsage: productUsage, + additionalParams: [ + "intent_id": intentID + ] + ) + ) + } + + func log3DS2FrictionlessFlow( + with configuration: NSObject?, + intentID: String + ) { + log( + analytic: GenericPaymentAnalytic( + event: ._3DS2FrictionlessFlow, + paymentConfiguration: configuration, + productUsage: productUsage, + additionalParams: [ + "intent_id": intentID + ] + ) + ) + } + + func logURLRedirectNextAction( + with configuration: NSObject?, + intentID: String + ) { + log( + analytic: GenericPaymentAnalytic( + event: .urlRedirectNextAction, + paymentConfiguration: configuration, + productUsage: productUsage, + additionalParams: [ + "intent_id": intentID + ] + ) + ) + } + + func log3DS2ChallengeFlowPresented( + with configuration: NSObject?, + intentID: String, + uiType: String + ) { + log( + analytic: GenericPaymentAnalytic( + event: ._3DS2ChallengeFlowPresented, + paymentConfiguration: configuration, + productUsage: productUsage, + additionalParams: [ + "intent_id": intentID, + "3ds2_ui_type": uiType, + ] + ) + ) + } + + func log3DS2ChallengeFlowTimedOut( + with configuration: NSObject?, + intentID: String, + uiType: String + ) { + log( + analytic: GenericPaymentAnalytic( + event: ._3DS2ChallengeFlowTimedOut, + paymentConfiguration: configuration, + productUsage: productUsage, + additionalParams: [ + "intent_id": intentID, + "3ds2_ui_type": uiType, + ] + ) + ) + } + + func log3DS2ChallengeFlowUserCanceled( + with configuration: NSObject?, + intentID: String, + uiType: String + ) { + log( + analytic: GenericPaymentAnalytic( + event: ._3DS2ChallengeFlowUserCanceled, + paymentConfiguration: configuration, + productUsage: productUsage, + additionalParams: [ + "intent_id": intentID, + "3ds2_ui_type": uiType, + ] + ) + ) + } + + func log3DS2RedirectUserCanceled( + with configuration: NSObject?, + intentID: String + ) { + log( + analytic: GenericPaymentAnalytic( + event: ._3DS2RedirectUserCanceled, + paymentConfiguration: configuration, + productUsage: productUsage, + additionalParams: [ + "intent_id": intentID + ] + ) + ) + } + + func log3DS2ChallengeFlowCompleted( + with configuration: NSObject?, + intentID: String, + uiType: String + ) { + log( + analytic: GenericPaymentAnalytic( + event: ._3DS2ChallengeFlowCompleted, + paymentConfiguration: configuration, + productUsage: productUsage, + additionalParams: [ + "intent_id": intentID, + "3ds2_ui_type": uiType, + ] + ) + ) + } + + func log3DS2ChallengeFlowErrored( + with configuration: NSObject?, + intentID: String, + error: NSError + ) { + log( + analytic: GenericPaymentErrorAnalytic( + event: ._3DS2ChallengeFlowErrored, + paymentConfiguration: configuration, + productUsage: productUsage, + additionalParams: [ + "intent_id": intentID + ], + error: error + ) + ) + } +} + +// MARK: - Card Metadata +extension STPAnalyticsClient { + @_spi(STP) public func logUserEnteredCompletePANBeforeMetadataLoaded() { + log( + analytic: GenericPaymentAnalytic( + event: .cardMetadataLoadedTooSlow, + paymentConfiguration: nil, + productUsage: productUsage, + additionalParams: [:] + ) + ) + } + + func logCardMetadataResponseFailure() { + log( + analytic: GenericPaymentAnalytic( + event: .cardMetadataResponseFailure, + paymentConfiguration: nil, + productUsage: productUsage, + additionalParams: [:] + ) + ) + } + + func logCardMetadataMissingRange() { + log( + analytic: GenericPaymentAnalytic( + event: .cardMetadataMissingRange, + paymentConfiguration: nil, + productUsage: productUsage, + additionalParams: [:] + ) + ) + } +} + +// MARK: - Card Scanning +extension STPAnalyticsClient { + @_spi(STP) public func logCardScanSucceeded(withDuration duration: TimeInterval) { + log( + analytic: GenericAnalytic( + event: .cardScanSucceeded, + params: [ + "duration": NSNumber(value: round(duration)) + ] + ) + ) + } + + @_spi(STP) public func logCardScanCancelled(withDuration duration: TimeInterval) { + log( + analytic: GenericAnalytic( + event: .cardScanCancelled, + params: [ + "duration": NSNumber(value: round(duration)) + ] + ) + ) + } +} + +/// An analytic specific to payments that serializes payment-specific +/// information into its params. +@_spi(STP) public protocol PaymentAnalytic: Analytic { + var productUsage: Set { get } + var additionalParams: [String: Any] { get } +} + +@_spi(STP) extension PaymentAnalytic { + public var params: [String: Any] { + var params = additionalParams + + params["apple_pay_enabled"] = NSNumber(value: StripeAPI.deviceSupportsApplePay()) + params["ocr_type"] = PaymentsSDKVariant.ocrTypeString + params["pay_var"] = PaymentsSDKVariant.variant + return params + } +} diff --git a/Pods/StripePayments/StripePayments/StripePayments/Internal/Categories/NSArray+Stripe.swift b/Pods/StripePayments/StripePayments/StripePayments/Internal/Categories/NSArray+Stripe.swift new file mode 100644 index 0000000..7686f07 --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/Internal/Categories/NSArray+Stripe.swift @@ -0,0 +1,38 @@ +// +// NSArray+Stripe.swift +// StripePayments +// +// Created by Jack Flintermann on 1/19/16. +// Copyright © 2016 Stripe, Inc. All rights reserved. +// + +import Foundation + +extension Array { + func stp_arrayByRemovingNulls() -> [Any] { + var result: [Any] = [] + + for obj in self { + switch obj { + case let obj as Array: + // Save array after removing any null values + result.append(obj.stp_arrayByRemovingNulls()) + case let obj as [AnyHashable: Any]: + // Save dictionary after removing any null values + let dict = obj.stp_dictionaryByRemovingNulls() + result.append(dict) + case let obj as Any: + if obj is NSNull { + // Skip null value + continue + } + // Save other value + result.append(obj) + default: + continue + } + } + + return result + } +} diff --git a/Pods/StripePayments/StripePayments/StripePayments/Internal/Categories/NSDecimalNumber+Stripe_Currency.swift b/Pods/StripePayments/StripePayments/StripePayments/Internal/Categories/NSDecimalNumber+Stripe_Currency.swift new file mode 100644 index 0000000..db627db --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/Internal/Categories/NSDecimalNumber+Stripe_Currency.swift @@ -0,0 +1,53 @@ +// +// NSDecimalNumber+Stripe_Currency.swift +// StripePayments +// +// Created by Jack Flintermann on 4/20/16. +// Copyright © 2016 Stripe, Inc. All rights reserved. +// + +import Foundation + +extension NSDecimalNumber { + @objc @_spi(STP) public class func stp_decimalNumber( + withAmount amount: Int, + currency: String? + ) -> NSDecimalNumber { + let noDecimalCurrencies = self.stp_currenciesWithNoDecimal() + let number = self.init(mantissa: UInt64(amount), exponent: 0, isNegative: false) + if noDecimalCurrencies.contains(currency?.lowercased() ?? "") { + return number + } + return number.multiplying(byPowerOf10: -2) + } + + @objc @_spi(STP) public func stp_amount(withCurrency currency: String?) -> Int { + let noDecimalCurrencies = NSDecimalNumber.stp_currenciesWithNoDecimal() + + var ourNumber = self + if !(noDecimalCurrencies.contains(currency?.lowercased() ?? "")) { + ourNumber = multiplying(byPowerOf10: 2) + } + return Int(ourNumber.doubleValue) + } + + class func stp_currenciesWithNoDecimal() -> [String] { + return [ + "bif", + "clp", + "djf", + "gnf", + "jpy", + "kmf", + "krw", + "mga", + "pyg", + "rwf", + "vnd", + "vuv", + "xaf", + "xof", + "xpf", + ] + } +} diff --git a/Pods/StripePayments/StripePayments/StripePayments/Internal/Categories/NSDictionary+Stripe.swift b/Pods/StripePayments/StripePayments/StripePayments/Internal/Categories/NSDictionary+Stripe.swift new file mode 100644 index 0000000..cc95598 --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/Internal/Categories/NSDictionary+Stripe.swift @@ -0,0 +1,131 @@ +// +// NSDictionary+Stripe.swift +// StripePayments +// +// Created by Jack Flintermann on 10/15/15. +// Copyright © 2015 Stripe, Inc. All rights reserved. +// + +import Foundation + +extension Dictionary where Key == AnyHashable, Value: Any { + @_spi(STP) public func stp_dictionaryByRemovingNulls() -> [AnyHashable: Any] { + var result = [AnyHashable: Any]() + + (self as NSDictionary).enumerateKeysAndObjects({ key, obj, _ in + guard let key = key as? AnyHashable else { + assertionFailure() + return + } + if let obj = obj as? [Any] { + // Save array after removing any null values + let stp = obj.stp_arrayByRemovingNulls() + result[key] = stp + } else if let obj = obj as? [AnyHashable: Any] { + // Save dictionary after removing any null values + let stp = obj.stp_dictionaryByRemovingNulls() + result[key] = stp + } else if obj is NSNull { + // Skip null value + } else { + // Save other value + result[key] = obj + } + }) + + // Make immutable copy + return result + } + + func stp_dictionaryByRemovingNonStrings() -> [String: String] { + var result: [String: String] = [:] + + (self as NSDictionary).enumerateKeysAndObjects({ key, obj, _ in + if let key = key as? String, let obj = obj as? String { + // Save valid key/value pair + result[key] = obj + } + }) + + // Make immutable copy + return result + } + + // Getters + @_spi(STP) public func stp_array(forKey key: String) -> [Any]? { + let value = self[key] + if value != nil { + return value as? [Any] + } + return nil + } + + @_spi(STP) public func stp_bool(forKey key: String, or defaultValue: Bool) -> Bool { + let value = self[key] + if value != nil { + if let value = value as? NSNumber { + return value.boolValue + } + if value is NSString { + let string = (value as? String)?.lowercased() + // boolValue on NSString is true for "Y", "y", "T", "t", or 1-9 + if (string == "true") || (string as NSString?)?.boolValue ?? false { + return true + } else { + return false + } + } + } + return defaultValue + } + + @_spi(STP) public func stp_date(forKey key: String) -> Date? { + let value = self[key] + if let value = value as? NSNumber { + let timeInterval = value.doubleValue + return Date(timeIntervalSince1970: TimeInterval(timeInterval)) + } else if let value = value as? NSString { + let timeInterval = value.doubleValue + return Date(timeIntervalSince1970: TimeInterval(timeInterval)) + } + return nil + } + + @_spi(STP) public func stp_dictionary(forKey key: String) -> [AnyHashable: Any]? { + let value = self[key] + if value != nil && (value is [AnyHashable: Any]) { + return value as? [AnyHashable: Any] + } + return nil + } + + func stp_int(forKey key: String, or defaultValue: Int) -> Int { + let value = self[key] + if let value = value as? NSNumber { + return value.intValue + } else if let value = value as? NSString { + return Int(value.intValue) + } + return defaultValue + } + + func stp_number(forKey key: String) -> NSNumber? { + return self[key] as? NSNumber + } + + @_spi(STP) public func stp_string(forKey key: String) -> String? { + let value = self[key] + if value != nil && (value is NSString) { + return value as? String + } + return nil + } + + func stp_url(forKey key: String) -> URL? { + let value = self[key] + if value != nil && (value is NSString) && ((value as? String)?.count ?? 0) > 0 { + return URL(string: value as? String ?? "") + } + return nil + } +} diff --git a/Pods/StripePayments/StripePayments/StripePayments/Internal/Categories/NSString+Stripe.swift b/Pods/StripePayments/StripePayments/StripePayments/Internal/Categories/NSString+Stripe.swift new file mode 100644 index 0000000..461b1f0 --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/Internal/Categories/NSString+Stripe.swift @@ -0,0 +1,73 @@ +// +// NSString+Stripe.swift +// StripePayments +// +// Created by Jack Flintermann on 10/16/15. +// Copyright © 2015 Stripe, Inc. All rights reserved. +// + +import Foundation + +extension String { + + /// A Boolean value indicating whether the string contains only whitespace. + @_spi(STP) public var isBlank: Bool { + return allSatisfy({ $0.isWhitespace }) + } + + /// Returns a substring up to the specified index. + /// + /// This method clamps out-of-bound indexes and always returns a valid (non-nil) string. + /// + /// - Parameter index: Index of last character to include in the substring. + /// - Returns: Substring. + @_spi(STP) public func stp_safeSubstring(to index: Int) -> String { + let maxLength = max(min(index, count), 0) + return String(prefix(maxLength)) + } + + /// Returns the substring starting from the specified index. + /// + /// This method clamps out-of-bound indexes and always returns a valid (non-nil) string. + /// + /// - Parameter index: Index of starting point of substring. + /// - Returns: Substring. + @_spi(STP) public func stp_safeSubstring(from index: Int) -> String { + let maxLength = max(min(count - index, count), 0) + return String(suffix(maxLength)) + } + + @_spi(STP) public func stp_string(byRemovingSuffix suffix: String?) -> String { + if let suffix = suffix, self.hasSuffix(suffix) { + return String(dropLast(suffix.count)) + } else { + return self + } + } + + // e.g. localizedAmountDisplayString(for: 1099, "USD") -> "$10.99" in en_US, "10,99 $" in fr_FR + @_spi(STP) public static func localizedAmountDisplayString( + for amount: Int, + currency: String, + locale: Locale = NSLocale.autoupdatingCurrent + ) -> String { + let decimalizedAmount = NSDecimalNumber.stp_decimalNumber( + withAmount: amount, + currency: currency + ) + let formatter = NumberFormatter() + formatter.numberStyle = .currency + formatter.usesGroupingSeparator = true + formatter.locale = locale + formatter.currencyCode = currency + let failsafeString = "\(formatter.currencySymbol ?? "")\(decimalizedAmount)" + return formatter.string(from: decimalizedAmount) ?? failsafeString + } + + /// Function to determine if this string is the country code of the United State + ///@param caseSensitive - Whether this string should only be considered the US country code if it matches the expected capitalization + @_spi(STP) public func isUSCountryCode(_ caseSensitive: Bool = false) -> Bool { + return caseSensitive ? self == "US" : self.caseInsensitiveCompare("US") == .orderedSame + } + +} diff --git a/Pods/StripePayments/StripePayments/StripePayments/Internal/Categories/STPAPIClient+PaymentsCore.swift b/Pods/StripePayments/StripePayments/StripePayments/Internal/Categories/STPAPIClient+PaymentsCore.swift new file mode 100644 index 0000000..c8598c2 --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/Internal/Categories/STPAPIClient+PaymentsCore.swift @@ -0,0 +1,20 @@ +// +// STPAPIClient+PaymentsCore.swift +// StripePayments +// +// Created by David Estes on 1/25/22. +// Copyright © 2022 Stripe, Inc. All rights reserved. +// + +import Foundation +@_spi(STP) import StripeCore + +extension STPAPIClient { + @_spi(STP) public class func paramsAddingPaymentUserAgent( + _ params: [String: Any] + ) -> [String: Any] { + var newParams = params + newParams["payment_user_agent"] = PaymentsSDKVariant.paymentUserAgent + return newParams + } +} diff --git a/Pods/StripePayments/StripePayments/StripePayments/Internal/Helpers/ConnectionsSDKAvailability.swift b/Pods/StripePayments/StripePayments/StripePayments/Internal/Helpers/ConnectionsSDKAvailability.swift new file mode 100644 index 0000000..79c00d3 --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/Internal/Helpers/ConnectionsSDKAvailability.swift @@ -0,0 +1,76 @@ +// +// ConnectionsSDKAvailability.swift +// StripePayments +// +// Created by Vardges Avetisyan on 2/24/22. +// Copyright © 2022 Stripe, Inc. All rights reserved. +// + +import Foundation +@_spi(STP) import StripeCore +import SwiftUI +import UIKit + +@available(iOS 12, *) +@_spi(STP) public struct FinancialConnectionsSDKAvailability { + static let FinancialConnectionsSDKClass: FinancialConnectionsSDKInterface.Type? = + NSClassFromString("StripeFinancialConnections.FinancialConnectionsSDKImplementation") + as? FinancialConnectionsSDKInterface.Type + + static let isUnitOrUITest: Bool = { + #if targetEnvironment(simulator) + return NSClassFromString("XCTest") != nil + || ProcessInfo.processInfo.environment["UITesting"] != nil + #else + return false + #endif + }() + + @_spi(STP) public static var isFinancialConnectionsSDKAvailable: Bool { + // return true for tests + if isUnitOrUITest { + return true + } + return FinancialConnectionsSDKClass != nil + } + + static func financialConnections() -> FinancialConnectionsSDKInterface? { + if isUnitOrUITest { + return StubbedConnectionsSDKInterface() + } + + guard let klass = FinancialConnectionsSDKClass else { + return nil + } + + return klass.init() + } +} + +final class StubbedConnectionsSDKInterface: FinancialConnectionsSDKInterface { + func presentFinancialConnectionsSheet( + apiClient: STPAPIClient, + clientSecret: String, + returnURL: String?, + from presentingViewController: UIViewController, + completion: @escaping (FinancialConnectionsSDKResult) -> Void + ) { + DispatchQueue.main.async { + completion(FinancialConnectionsSDKResult.completed(linkedBank: StubbedLinkedBank())) + } + } +} + +struct StubbedLinkedBank: LinkedBank { + var sessionId: String = "las_123" + + var accountId: String = "fca_123" + + var displayName: String? = "Test Bank" + + var bankName: String? = "Test Bank" + + var last4: String? = "1234" + + var instantlyVerified: Bool = true +} diff --git a/Pods/StripePayments/StripePayments/StripePayments/Internal/STPPaymentHandlerActionParams.swift b/Pods/StripePayments/StripePayments/StripePayments/Internal/STPPaymentHandlerActionParams.swift new file mode 100644 index 0000000..ac3a58f --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/Internal/STPPaymentHandlerActionParams.swift @@ -0,0 +1,180 @@ +// +// STPPaymentHandlerActionParams.swift +// StripePayments +// +// Created by Yuki Tokuhiro on 6/28/19. +// Copyright © 2019 Stripe, Inc. All rights reserved. +// + +import Foundation +@_spi(STP) import StripeCore + +#if canImport(Stripe3DS2) + import Stripe3DS2 +#endif + +@_spi(STP) public protocol STPPaymentHandlerActionParams: NSObject { + var threeDS2Service: STDSThreeDS2Service? { get } + var threeDS2Transaction: STDSTransaction? { get set } + var authenticationContext: STPAuthenticationContext { get } + var apiClient: STPAPIClient { get } + var threeDSCustomizationSettings: STPThreeDSCustomizationSettings { get } + var returnURLString: String? { get } + var intentStripeID: String? { get } + /// Returns the payment or setup intent's next action + func nextAction() -> STPIntentAction? + func complete(with status: STPPaymentHandlerActionStatus, error: NSError?) +} + +@_spi(STP) +public class STPPaymentHandlerPaymentIntentActionParams: NSObject, STPPaymentHandlerActionParams { + + private var serviceInitialized = false + + @_spi(STP) public let authenticationContext: STPAuthenticationContext + @_spi(STP) public let apiClient: STPAPIClient + @_spi(STP) public let threeDSCustomizationSettings: STPThreeDSCustomizationSettings + @_spi(STP) public let paymentIntentCompletion: + STPPaymentHandlerActionPaymentIntentCompletionBlock + @_spi(STP) public let returnURLString: String? + @_spi(STP) public var paymentIntent: STPPaymentIntent? + @_spi(STP) public var threeDS2Transaction: STDSTransaction? + + @_spi(STP) public var intentStripeID: String? { + return paymentIntent?.stripeId + } + + private var _threeDS2Service: STDSThreeDS2Service? + + @_spi(STP) public var threeDS2Service: STDSThreeDS2Service? { + if !serviceInitialized { + serviceInitialized = true + _threeDS2Service = STDSThreeDS2Service() + + STDSSwiftTryCatch.try( + { + let configParams = STDSConfigParameters() + if !(self.paymentIntent?.livemode ?? true) { + configParams.addParameterNamed( + "kInternalStripeTestingConfigParam", + withValue: "Y" + ) + } + self._threeDS2Service?.initialize( + withConfig: configParams, + locale: Locale.autoupdatingCurrent, + uiSettings: self.threeDSCustomizationSettings.uiCustomization + .uiCustomization + ) + }, + catch: { _ in + self._threeDS2Service = nil + }, + finallyBlock: { + } + ) + } + + return _threeDS2Service + } + + init( + apiClient: STPAPIClient, + authenticationContext: STPAuthenticationContext, + threeDSCustomizationSettings: STPThreeDSCustomizationSettings, + paymentIntent: STPPaymentIntent, + returnURL returnURLString: String?, + completion: @escaping STPPaymentHandlerActionPaymentIntentCompletionBlock + ) { + self.apiClient = apiClient + self.authenticationContext = authenticationContext + self.threeDSCustomizationSettings = threeDSCustomizationSettings + self.returnURLString = returnURLString + self.paymentIntent = paymentIntent + self.paymentIntentCompletion = completion + super.init() + } + + @_spi(STP) public func nextAction() -> STPIntentAction? { + return paymentIntent?.nextAction + } + + @_spi(STP) public func complete(with status: STPPaymentHandlerActionStatus, error: NSError?) { + paymentIntentCompletion(status, paymentIntent, error) + } +} + +internal class STPPaymentHandlerSetupIntentActionParams: NSObject, STPPaymentHandlerActionParams { + private var serviceInitialized = false + + let authenticationContext: STPAuthenticationContext + let apiClient: STPAPIClient + let threeDSCustomizationSettings: STPThreeDSCustomizationSettings + let setupIntentCompletion: STPPaymentHandlerActionSetupIntentCompletionBlock + let returnURLString: String? + var setupIntent: STPSetupIntent? + var threeDS2Transaction: STDSTransaction? + + var intentStripeID: String? { + return setupIntent?.stripeID + } + + private var _threeDS2Service: STDSThreeDS2Service? + + var threeDS2Service: STDSThreeDS2Service? { + if !serviceInitialized { + serviceInitialized = true + _threeDS2Service = STDSThreeDS2Service() + + STDSSwiftTryCatch.try( + { + let configParams = STDSConfigParameters() + if !(self.setupIntent?.livemode ?? true) { + configParams.addParameterNamed( + "kInternalStripeTestingConfigParam", + withValue: "Y" + ) + } + self._threeDS2Service?.initialize( + withConfig: configParams, + locale: Locale.autoupdatingCurrent, + uiSettings: self.threeDSCustomizationSettings.uiCustomization + .uiCustomization + ) + }, + catch: { _ in + self._threeDS2Service = nil + }, + finallyBlock: { + } + ) + } + + return _threeDS2Service + } + + init( + apiClient: STPAPIClient, + authenticationContext: STPAuthenticationContext, + threeDSCustomizationSettings: STPThreeDSCustomizationSettings, + setupIntent: STPSetupIntent, + returnURL returnURLString: String?, + completion: @escaping STPPaymentHandlerActionSetupIntentCompletionBlock + ) { + self.apiClient = apiClient + self.authenticationContext = authenticationContext + self.threeDSCustomizationSettings = threeDSCustomizationSettings + self.returnURLString = returnURLString + self.setupIntent = setupIntent + self.setupIntentCompletion = completion + super.init() + } + + func nextAction() -> STPIntentAction? { + return setupIntent?.nextAction + } + + func complete(with status: STPPaymentHandlerActionStatus, error: NSError?) { + setupIntentCompletion(status, setupIntent, error) + } +} diff --git a/Pods/StripePayments/StripePayments/StripePayments/PaymentHandler/STPAuthenticationContext.swift b/Pods/StripePayments/StripePayments/StripePayments/PaymentHandler/STPAuthenticationContext.swift new file mode 100644 index 0000000..0e5d1f1 --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/PaymentHandler/STPAuthenticationContext.swift @@ -0,0 +1,36 @@ +// +// STPAuthenticationContext.swift +// StripePayments +// +// Created by Cameron Sabol on 5/10/19. +// Copyright © 2019 Stripe, Inc. All rights reserved. +// + +import Foundation +import SafariServices +import UIKit + +/// `STPAuthenticationContext` provides information required to present authentication challenges +/// to a user. +@objc public protocol STPAuthenticationContext: NSObjectProtocol { + /// The Stripe SDK will modally present additional view controllers on top + /// of the `authenticationPresentingViewController` when required for user + /// authentication, like in the Challenge Flow for 3DS2 transactions. + func authenticationPresentingViewController() -> UIViewController + + /// This method is called before presenting a UIViewController for authentication. + /// @note `STPPaymentHandler` will not proceed until `completion` is called. + @objc(prepareAuthenticationContextForPresentation:) optional func prepare( + forPresentation completion: @escaping STPVoidBlock + ) + /// This method is called before presenting an SFSafariViewController for web-based authentication. + /// Implement this method to configure the `SFSafariViewController` instance, e.g. `viewController.preferredBarTintColor = MyBarTintColor` + /// @note Setting the `delegate` property has no effect. + @objc optional func configureSafariViewController(_ viewController: SFSafariViewController) + /// This method is called when an authentication UIViewController is about to be dismissed. + /// Implement this method to prepare your UI for the authentication view controller to be dismissed. For example, + /// if you requested authentication while displaying an STPBankSelectionViewController, you may want to hide + /// it to return the user to your desired view controller. + @objc(authenticationContextWillDismissViewController:) + optional func authenticationContextWillDismiss(_ viewController: UIViewController) +} diff --git a/Pods/StripePayments/StripePayments/StripePayments/PaymentHandler/STPPaymentHandler.swift b/Pods/StripePayments/StripePayments/StripePayments/PaymentHandler/STPPaymentHandler.swift new file mode 100644 index 0000000..f7b601a --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/PaymentHandler/STPPaymentHandler.swift @@ -0,0 +1,2200 @@ +// +// STPPaymentHandler.swift +// StripePayments +// +// Created by Cameron Sabol on 5/10/19. +// Copyright © 2019 Stripe, Inc. All rights reserved. +// + +import Foundation +import PassKit +import SafariServices +@_spi(STP) import StripeCore + +#if canImport(Stripe3DS2) + import Stripe3DS2 +#endif + +/// `STPPaymentHandlerActionStatus` represents the possible outcomes of requesting an action by `STPPaymentHandler`. An action could be confirming and/or handling the next action for a PaymentIntent. +@objc public enum STPPaymentHandlerActionStatus: Int { + /// The action succeeded. + case succeeded + /// The action was cancelled by the cardholder/user. + case canceled + /// The action failed. See the error code for more details. + case failed +} + +/// Error codes generated by `STPPaymentHandler` +@objc public enum STPPaymentHandlerErrorCode: Int { + /// Indicates that the action requires an authentication method not recognized or supported by the SDK. + @objc(STPPaymentHandlerUnsupportedAuthenticationErrorCode) + case unsupportedAuthenticationErrorCode + + /// Indicates that the action requires an authentication app, but either the app is not installed or the request to switch to the app was denied. + @objc(STPPaymentHandlerRequiredAppNotAvailableErrorCode) + case requiredAppNotAvailable + + /// Attach a payment method to the PaymentIntent or SetupIntent before using `STPPaymentHandler`. + @objc(STPPaymentHandlerRequiresPaymentMethodErrorCode) + case requiresPaymentMethodErrorCode + + /// The PaymentIntent or SetupIntent status cannot be resolved by `STPPaymentHandler`. + @objc(STPPaymentHandlerIntentStatusErrorCode) + case intentStatusErrorCode + + /// The action timed out. + @objc(STPPaymentHandlerTimedOutErrorCode) + case timedOutErrorCode + + /// There was an error in the Stripe3DS2 SDK. + @objc(STPPaymentHandlerStripe3DS2ErrorCode) + case stripe3DS2ErrorCode + + /// The transaction did not authenticate (e.g. user entered the wrong code). + @objc(STPPaymentHandlerNotAuthenticatedErrorCode) + case notAuthenticatedErrorCode + + /// `STPPaymentHandler` does not support concurrent actions. + @objc(STPPaymentHandlerNoConcurrentActionsErrorCode) + case noConcurrentActionsErrorCode + + /// Payment requires a valid `STPAuthenticationContext`. Make sure your presentingViewController isn't already presenting. + @objc(STPPaymentHandlerRequiresAuthenticationContextErrorCode) + case requiresAuthenticationContextErrorCode + + /// There was an error confirming the Intent. + /// Inspect the `paymentIntent.lastPaymentError` or `setupIntent.lastSetupError` property. + @objc(STPPaymentHandlerPaymentErrorCode) + case paymentErrorCode + + /// The provided PaymentIntent of SetupIntent client secret does not match the expected pattern for client secrets. + /// Make sure that your server is returning the correct value and that is being passed to `STPPaymentHandler`. + @objc(STPPaymentHandlerInvalidClientSecret) + case invalidClientSecret +} + +/// Completion block typedef for use in `STPPaymentHandler` methods for Payment Intents. +public typealias STPPaymentHandlerActionPaymentIntentCompletionBlock = ( + STPPaymentHandlerActionStatus, STPPaymentIntent?, NSError? +) -> Void +/// Completion block typedef for use in `STPPaymentHandler` methods for Setup Intents. +public typealias STPPaymentHandlerActionSetupIntentCompletionBlock = ( + STPPaymentHandlerActionStatus, STPSetupIntent?, NSError? +) -> Void + +/// `STPPaymentHandler` is a utility class that confirms PaymentIntents/SetupIntents and handles any authentication required, such as 3DS1/3DS2 for Strong Customer Authentication. +/// It can present authentication UI on top of your app or redirect users out of your app (to e.g. their banking app). +/// - seealso: https://stripe.com/docs/payments/3d-secure +public class STPPaymentHandler: NSObject { + + /// The error domain for errors in `STPPaymentHandler`. + @objc public static let errorDomain = "STPPaymentHandlerErrorDomain" + + private var currentAction: STPPaymentHandlerActionParams? + /// YES from when a public method is first called until its associated completion handler is called. + /// This property guards against simultaneous usage of this class; only one "next action" can be handled at a time. + private static var inProgress = false + private var safariViewController: SFSafariViewController? + + /// Set this to true if you want a specific test to run the _canPresent code + /// it will automatically toggle back to false after running the code once + internal var checkCanPresentInTest: Bool = false + + /// The globally shared instance of `STPPaymentHandler`. + @objc public static let sharedHandler: STPPaymentHandler = STPPaymentHandler() + + /// The globally shared instance of `STPPaymentHandler`. + @objc + public class func shared() -> STPPaymentHandler { + return STPPaymentHandler.sharedHandler + } + + @_spi(STP) public init( + apiClient: STPAPIClient = .shared, + threeDSCustomizationSettings: STPThreeDSCustomizationSettings = + STPThreeDSCustomizationSettings(), + formSpecPaymentHandler: FormSpecPaymentHandler? = nil + ) { + self.apiClient = apiClient + self.threeDSCustomizationSettings = threeDSCustomizationSettings + self.formSpecPaymentHandler = formSpecPaymentHandler + super.init() + } + + /// By default `sharedHandler` initializes with STPAPIClient.shared. + public var apiClient: STPAPIClient + + /// Customizable settings to use when performing 3DS2 authentication. + /// Note: Configure this before calling any methods. + /// Defaults to `STPThreeDSCustomizationSettings()`. + @objc public var threeDSCustomizationSettings: STPThreeDSCustomizationSettings + + internal var _simulateAppToAppRedirect: Bool = false + + /// When this flag is enabled, STPPaymentHandler will confirm certain PaymentMethods using + /// Safari instead of SFSafariViewController. If you'd like to use this in your own + /// testing or Continuous Integration platform, please see the IntegrationTester app + /// for usage examples. + /// + /// Note: This flag is only intended for development, and only impacts payments made with testmode keys. + /// Setting this to `true` with a livemode key will fail. + @objc public var simulateAppToAppRedirect: Bool + { + get { + _simulateAppToAppRedirect && STPAPIClient.shared.isTestmode + } + set { + _simulateAppToAppRedirect = newValue + } + } + + private var formSpecPaymentHandler: FormSpecPaymentHandler? + + internal var _redirectShim: ((URL, URL?) -> Void)? = nil + + /// Confirms the PaymentIntent with the provided parameters and handles any `nextAction` required + /// to authenticate the PaymentIntent. + /// Call this method if you are using automatic confirmation. - seealso:https://stripe.com/docs/payments/accept-a-payment?platform=ios&ui=custom + /// - Parameters: + /// - paymentParams: The params used to confirm the PaymentIntent. Note that this method overrides the value of `paymentParams.useStripeSDK` to `@YES`. + /// - authenticationContext: The authentication context used to authenticate the payment. + /// - completion: The completion block. If the status returned is `STPPaymentHandlerActionStatusSucceeded`, the PaymentIntent status is not necessarily STPPaymentIntentStatusSucceeded (e.g. some bank payment methods take days before the PaymentIntent succeeds). + @available(iOSApplicationExtension, unavailable) + @available(macCatalystApplicationExtension, unavailable) + @objc(confirmPayment:withAuthenticationContext:completion:) + public func confirmPayment( + _ paymentParams: STPPaymentIntentParams, + with authenticationContext: STPAuthenticationContext, + completion: @escaping STPPaymentHandlerActionPaymentIntentCompletionBlock + ) { + if Self.inProgress { + completion(.failed, nil, _error(for: .noConcurrentActionsErrorCode)) + return + } else if !STPPaymentIntentParams.isClientSecretValid(paymentParams.clientSecret) { + completion(.failed, nil, _error(for: .invalidClientSecret)) + return + } + Self.inProgress = true + weak var weakSelf = self + // wrappedCompletion ensures we perform some final logic before calling the completion block. + let wrappedCompletion: STPPaymentHandlerActionPaymentIntentCompletionBlock = { + status, + paymentIntent, + error in + guard let strongSelf = weakSelf else { + return + } + // Reset our internal state + Self.inProgress = false + + // Use spec first to determine if we are in a terminal state + if status == .succeeded, + self.formSpecPaymentHandler?.isPIStatusSpecFinishedForPostConfirmPIStatus( + paymentIntent: paymentIntent, + paymentHandler: self + ) ?? false + { + completion(.succeeded, paymentIntent, nil) + return + // Else ensure the .succeeded case returns a PaymentIntent in the expected state. + } else if let paymentIntent = paymentIntent, status == .succeeded { + let successIntentState = + paymentIntent.status == .succeeded || paymentIntent.status == .requiresCapture + || (paymentIntent.status == .processing + && STPPaymentHandler._isProcessingIntentSuccess( + for: paymentIntent.paymentMethod?.type ?? .unknown + ) + || (paymentIntent.status == .requiresAction + && strongSelf.isNextActionSuccessState( + nextAction: paymentIntent.nextAction + ))) + + if error == nil && successIntentState { + completion(.succeeded, paymentIntent, nil) + } else { + assert(false, "Calling completion with invalid state") + completion( + .failed, + paymentIntent, + error ?? strongSelf._error(for: .intentStatusErrorCode) + ) + } + return + } + completion(status, paymentIntent, error) + } + + let confirmCompletionBlock: STPPaymentIntentCompletionBlock = { paymentIntent, error in + guard let strongSelf = weakSelf else { + return + } + if let paymentIntent = paymentIntent, + error == nil + { + strongSelf._handleNextAction( + forPayment: paymentIntent, + with: authenticationContext, + returnURL: paymentParams.returnURL + ) { status, completedPaymentIntent, completedError in + wrappedCompletion(status, completedPaymentIntent, completedError) + } + } else { + wrappedCompletion(.failed, paymentIntent, error as NSError?) + } + } + + var params = paymentParams + // We always set useStripeSDK = @YES in STPPaymentHandler + if !(params.useStripeSDK?.boolValue ?? false) { + params = paymentParams.copy() as! STPPaymentIntentParams + params.useStripeSDK = NSNumber(value: true) + } + apiClient.confirmPaymentIntent( + with: params, + expand: ["payment_method"], + completion: confirmCompletionBlock + ) + } + + /// :nodoc: + @available( + *, + deprecated, + message: "Use confirmPayment(_:with:completion:) instead", + renamed: "confirmPayment(_:with:completion:)" + ) + @available(iOSApplicationExtension, unavailable) + @available(macCatalystApplicationExtension, unavailable) + public func confirmPayment( + withParams: STPPaymentIntentParams, + authenticationContext: STPAuthenticationContext, + completion: @escaping STPPaymentHandlerActionPaymentIntentCompletionBlock + ) { + self.confirmPayment(withParams, with: authenticationContext, completion: completion) + } + + /// Handles any `nextAction` required to authenticate the PaymentIntent. + /// Call this method if you are using manual confirmation. - seealso: https://stripe.com/docs/payments/accept-a-payment?platform=ios&ui=custom + /// - Parameters: + /// - paymentIntentClientSecret: The client secret of the PaymentIntent to handle next actions for. + /// - authenticationContext: The authentication context used to authenticate the payment. + /// - returnURL: An optional URL to redirect your customer back to after they authenticate or cancel in a webview. This should match the returnURL you specified during PaymentIntent confirmation. + /// - completion: The completion block. If the status returned is `STPPaymentHandlerActionStatusSucceeded`, the PaymentIntent status will always be either STPPaymentIntentStatusSucceeded, or STPPaymentIntentStatusRequiresConfirmation, or STPPaymentIntentStatusRequiresCapture if you are using manual capture. In the latter two cases, confirm or capture the PaymentIntent on your backend to complete the payment. + @objc(handleNextActionForPayment:withAuthenticationContext:returnURL:completion:) + @available(iOSApplicationExtension, unavailable) + @available(macCatalystApplicationExtension, unavailable) + public func handleNextAction( + forPayment paymentIntentClientSecret: String, + with authenticationContext: STPAuthenticationContext, + returnURL: String?, + completion: @escaping STPPaymentHandlerActionPaymentIntentCompletionBlock + ) { + if Self.inProgress { + assert(false, "Should not handle multiple payments at once.") + completion(.failed, nil, _error(for: .noConcurrentActionsErrorCode)) + return + } else if !STPPaymentIntentParams.isClientSecretValid(paymentIntentClientSecret) { + completion(.failed, nil, _error(for: .invalidClientSecret)) + return + } + + Self.inProgress = true + weak var weakSelf = self + // wrappedCompletion ensures we perform some final logic before calling the completion block. + let wrappedCompletion: STPPaymentHandlerActionPaymentIntentCompletionBlock = { + status, + paymentIntent, + error in + guard let strongSelf = weakSelf else { + return + } + // Reset our internal state + Self.inProgress = false + // Ensure the .succeeded case returns a PaymentIntent in the expected state. + if let paymentIntent = paymentIntent, + status == .succeeded + { + let successIntentState = + paymentIntent.status == .succeeded || paymentIntent.status == .requiresCapture + || paymentIntent.status == .requiresConfirmation + + if error == nil && successIntentState { + completion(.succeeded, paymentIntent, nil) + } else { + assert(false, "Calling completion with invalid state") + completion( + .failed, + paymentIntent, + error ?? strongSelf._error(for: .intentStatusErrorCode) + ) + } + return + } + completion(status, paymentIntent, error) + } + + let retrieveCompletionBlock: STPPaymentIntentCompletionBlock = { paymentIntent, error in + guard let strongSelf = weakSelf else { + return + } + if let paymentIntent = paymentIntent, + error == nil + { + if paymentIntent.status == .requiresConfirmation { + // The caller forgot to confirm the paymentIntent on the backend before calling this method + wrappedCompletion( + .failed, + paymentIntent, + strongSelf._error( + for: .intentStatusErrorCode, + userInfo: [ + STPError.errorMessageKey: + "Confirm the PaymentIntent on the backend before calling handleNextActionForPayment:withAuthenticationContext:completion." + ] + ) + ) + } else { + strongSelf._handleNextAction( + forPayment: paymentIntent, + with: authenticationContext, + returnURL: returnURL + ) { status, completedPaymentIntent, completedError in + wrappedCompletion(status, completedPaymentIntent, completedError) + } + } + } else { + wrappedCompletion(.failed, paymentIntent, error as NSError?) + } + } + + apiClient.retrievePaymentIntent( + withClientSecret: paymentIntentClientSecret, + expand: ["payment_method"], + completion: retrieveCompletionBlock + ) + } + + /// Confirms the SetupIntent with the provided parameters and handles any `nextAction` required + /// to authenticate the SetupIntent. + /// - seealso: https://stripe.com/docs/payments/save-during-payment?platform=ios + /// - Parameters: + /// - setupIntentConfirmParams: The params used to confirm the SetupIntent. Note that this method overrides the value of `setupIntentConfirmParams.useStripeSDK` to `@YES`. + /// - authenticationContext: The authentication context used to authenticate the SetupIntent. + /// - completion: The completion block. If the status returned is `STPPaymentHandlerActionStatusSucceeded`, the SetupIntent status will always be STPSetupIntentStatusSucceeded. + @available(iOSApplicationExtension, unavailable) + @available(macCatalystApplicationExtension, unavailable) + @objc(confirmSetupIntent:withAuthenticationContext:completion:) + public func confirmSetupIntent( + _ setupIntentConfirmParams: STPSetupIntentConfirmParams, + with authenticationContext: STPAuthenticationContext, + completion: @escaping STPPaymentHandlerActionSetupIntentCompletionBlock + ) { + if Self.inProgress { + assert(false, "Should not handle multiple payments at once.") + completion(.failed, nil, _error(for: .noConcurrentActionsErrorCode)) + return + } else if !STPSetupIntentConfirmParams.isClientSecretValid( + setupIntentConfirmParams.clientSecret + ) { + completion(.failed, nil, _error(for: .invalidClientSecret)) + return + } + + Self.inProgress = true + weak var weakSelf = self + // wrappedCompletion ensures we perform some final logic before calling the completion block. + let wrappedCompletion: STPPaymentHandlerActionSetupIntentCompletionBlock = { + status, + setupIntent, + error in + guard let strongSelf = weakSelf else { + return + } + // Reset our internal state + Self.inProgress = false + + if status == .succeeded { + // Ensure the .succeeded case returns a PaymentIntent in the expected state. + if let setupIntent = setupIntent, + error == nil, + setupIntent.status == .succeeded + || (setupIntent.status == .requiresAction + && self.isNextActionSuccessState(nextAction: setupIntent.nextAction)) + { + completion(.succeeded, setupIntent, nil) + } else { + assert(false, "Calling completion with invalid state") + completion( + .failed, + setupIntent, + error ?? strongSelf._error(for: .intentStatusErrorCode) + ) + } + + } else { + completion(status, setupIntent, error) + } + } + + let confirmCompletionBlock: STPSetupIntentCompletionBlock = { setupIntent, error in + guard let strongSelf = weakSelf else { + return + } + + if let setupIntent = setupIntent, + error == nil + { + let action = STPPaymentHandlerSetupIntentActionParams( + apiClient: self.apiClient, + authenticationContext: authenticationContext, + threeDSCustomizationSettings: self.threeDSCustomizationSettings, + setupIntent: setupIntent, + returnURL: setupIntentConfirmParams.returnURL + ) { status, resultSetupIntent, resultError in + guard let strongSelf2 = weakSelf else { + return + } + strongSelf2.currentAction = nil + + wrappedCompletion(status, resultSetupIntent, resultError) + } + strongSelf.currentAction = action + let requiresAction = strongSelf._handleSetupIntentStatus(forAction: action) + if requiresAction { + strongSelf._handleAuthenticationForCurrentAction() + } + } else { + wrappedCompletion(.failed, setupIntent, error as NSError?) + } + } + var params = setupIntentConfirmParams + if !(params.useStripeSDK?.boolValue ?? false) { + params = setupIntentConfirmParams.copy() as! STPSetupIntentConfirmParams + params.useStripeSDK = NSNumber(value: true) + } + apiClient.confirmSetupIntent(with: params, completion: confirmCompletionBlock) + } + + /// Handles any `nextAction` required to authenticate the SetupIntent. + /// Call this method if you are confirming the SetupIntent on your backend and get a status of requires_action. + /// - Parameters: + /// - setupIntentClientSecret: The client secret of the SetupIntent to handle next actions for. + /// - authenticationContext: The authentication context used to authenticate the SetupIntent. + /// - returnURL: An optional URL to redirect your customer back to after they authenticate or cancel in a webview. This should match the returnURL you specified during SetupIntent confirmation. + /// - completion: The completion block. If the status returned is `STPPaymentHandlerActionStatusSucceeded`, the SetupIntent status will always be STPSetupIntentStatusSucceeded. + @objc(handleNextActionForSetupIntent:withAuthenticationContext:returnURL:completion:) + @available(iOSApplicationExtension, unavailable) + @available(macCatalystApplicationExtension, unavailable) + public func handleNextAction( + forSetupIntent setupIntentClientSecret: String, + with authenticationContext: STPAuthenticationContext, + returnURL: String?, + completion: @escaping STPPaymentHandlerActionSetupIntentCompletionBlock + ) { + if Self.inProgress { + assert(false, "Should not handle multiple payments at once.") + completion(.failed, nil, _error(for: .noConcurrentActionsErrorCode)) + return + } else if !STPSetupIntentConfirmParams.isClientSecretValid(setupIntentClientSecret) { + completion(.failed, nil, _error(for: .invalidClientSecret)) + return + } + + Self.inProgress = true + weak var weakSelf = self + // wrappedCompletion ensures we perform some final logic before calling the completion block. + let wrappedCompletion: STPPaymentHandlerActionSetupIntentCompletionBlock = { + status, + setupIntent, + error in + guard let strongSelf = weakSelf else { + return + } + // Reset our internal state + Self.inProgress = false + + if status == .succeeded { + // Ensure the .succeeded case returns a PaymentIntent in the expected state. + if let setupIntent = setupIntent, + error == nil, + setupIntent.status == .succeeded + { + completion(.succeeded, setupIntent, nil) + } else { + assert(false, "Calling completion with invalid state") + completion( + .failed, + setupIntent, + error ?? strongSelf._error(for: .intentStatusErrorCode) + ) + } + + } else { + completion(status, setupIntent, error) + } + } + + let retrieveCompletionBlock: STPSetupIntentCompletionBlock = { setupIntent, error in + guard let strongSelf = weakSelf else { + return + } + if let setupIntent = setupIntent, + error == nil + { + if setupIntent.status == .requiresConfirmation { + // The caller forgot to confirm the setupIntent on the backend before calling this method + wrappedCompletion( + .failed, + setupIntent, + strongSelf._error( + for: .intentStatusErrorCode, + userInfo: [ + STPError.errorMessageKey: + "Confirm the SetupIntent on the backend before calling handleNextActionForSetupIntent:withAuthenticationContext:completion." + ] + ) + ) + } else { + strongSelf._handleNextAction( + for: setupIntent, + with: authenticationContext, + returnURL: returnURL + ) { status, completedSetupIntent, completedError in + wrappedCompletion(status, completedSetupIntent, completedError) + } + } + } else { + wrappedCompletion(.failed, setupIntent, error as NSError?) + } + } + + apiClient.retrieveSetupIntent( + withClientSecret: setupIntentClientSecret, + completion: retrieveCompletionBlock + ) + } + + // MARK: - Private Helpers + + /// Depending on the PaymentMethod Type, after handling next action and confirming, + /// we should either expect a success state on the PaymentIntent, or for certain asynchronous + /// PaymentMethods like SEPA Debit, processing is considered a completed PaymentIntent flow + /// because the funds can take up to 14 days to transfer from the customer's bank. + class func _isProcessingIntentSuccess(for type: STPPaymentMethodType) -> Bool { + switch type { + // Asynchronous + case .SEPADebit, + .bacsDebit, // Bacs Debit takes 2-3 business days + .AUBECSDebit, + .sofort, + .USBankAccount: + return true + + // Synchronous + case .alipay, + .card, + .UPI, + .iDEAL, + .FPX, + .cardPresent, + .giropay, + .EPS, + .payPal, + .przelewy24, + .bancontact, + .netBanking, + .OXXO, + .grabPay, + .afterpayClearpay, + .blik, + .weChatPay, + .boleto, + .link, + .klarna, + .affirm, + .linkInstantDebit: + return false + + case .unknown: + return false + + @unknown default: + return false + } + } + + @available(iOSApplicationExtension, unavailable) + @available(macCatalystApplicationExtension, unavailable) + func _handleNextAction( + forPayment paymentIntent: STPPaymentIntent, + with authenticationContext: STPAuthenticationContext, + returnURL returnURLString: String?, + completion: @escaping STPPaymentHandlerActionPaymentIntentCompletionBlock + ) { + guard paymentIntent.status != .requiresPaymentMethod else { + // The caller forgot to attach a paymentMethod. + completion( + .failed, + paymentIntent, + _error(for: .requiresPaymentMethodErrorCode) + ) + return + } + + weak var weakSelf = self + let action = STPPaymentHandlerPaymentIntentActionParams( + apiClient: apiClient, + authenticationContext: authenticationContext, + threeDSCustomizationSettings: threeDSCustomizationSettings, + paymentIntent: paymentIntent, + returnURL: returnURLString + ) { status, resultPaymentIntent, error in + guard let strongSelf = weakSelf else { + return + } + strongSelf.currentAction = nil + completion(status, resultPaymentIntent, error) + } + currentAction = action + let specHandledNextAction = + self.formSpecPaymentHandler?.handleNextActionSpec( + for: paymentIntent, + action: action, + paymentHandler: self + ) ?? false + if !specHandledNextAction { + let requiresAction = _handlePaymentIntentStatus(forAction: action) + if requiresAction { + _handleAuthenticationForCurrentAction() + } + } + } + + @available(iOSApplicationExtension, unavailable) + @available(macCatalystApplicationExtension, unavailable) + func _handleNextAction( + for setupIntent: STPSetupIntent, + with authenticationContext: STPAuthenticationContext, + returnURL returnURLString: String?, + completion: @escaping STPPaymentHandlerActionSetupIntentCompletionBlock + ) { + guard setupIntent.status != .requiresPaymentMethod else { + // The caller forgot to attach a paymentMethod. + completion( + .failed, + setupIntent, + _error(for: .requiresPaymentMethodErrorCode) + ) + return + } + + weak var weakSelf = self + let action = STPPaymentHandlerSetupIntentActionParams( + apiClient: apiClient, + authenticationContext: authenticationContext, + threeDSCustomizationSettings: threeDSCustomizationSettings, + setupIntent: setupIntent, + returnURL: returnURLString + ) { status, resultSetupIntent, resultError in + guard let strongSelf = weakSelf else { + return + } + strongSelf.currentAction = nil + completion(status, resultSetupIntent, resultError) + } + currentAction = action + let requiresAction = _handleSetupIntentStatus(forAction: action) + if requiresAction { + _handleAuthenticationForCurrentAction() + } + } + + /// Calls the current action's completion handler for the SetupIntent status, or returns YES if the status is ...RequiresAction. + func _handleSetupIntentStatus( + forAction action: STPPaymentHandlerSetupIntentActionParams + ) + -> Bool + { + guard let setupIntent = action.setupIntent else { + assert(false, "Calling _handleSetupIntentStatus without a setupIntent") + return false + } + + switch setupIntent.status { + case .unknown: + action.complete( + with: STPPaymentHandlerActionStatus.failed, + error: _error( + for: .intentStatusErrorCode, + userInfo: [ + "STPSetupIntent": setupIntent.description + ] + ) + ) + + case .requiresPaymentMethod: + // If the user forgot to attach a PaymentMethod, they get an error before this point. + // If confirmation fails (eg not authenticated, card declined) the SetupIntent transitions to this state. + if let lastSetupError = setupIntent.lastSetupError { + if lastSetupError.code == STPSetupIntentLastSetupError.CodeAuthenticationFailure { + action.complete( + with: STPPaymentHandlerActionStatus.failed, + error: _error(for: .notAuthenticatedErrorCode) + ) + } else if lastSetupError.type == .card { + action.complete( + with: STPPaymentHandlerActionStatus.failed, + error: _error( + for: .paymentErrorCode, + apiErrorCode: lastSetupError.code, + userInfo: [ + NSLocalizedDescriptionKey: lastSetupError.message ?? "" + ] + ) + ) + } else { + action.complete( + with: STPPaymentHandlerActionStatus.failed, + error: _error(for: .paymentErrorCode, apiErrorCode: lastSetupError.code) + ) + } + } else { + action.complete( + with: STPPaymentHandlerActionStatus.failed, + error: _error(for: .paymentErrorCode) + ) + } + + case .requiresConfirmation: + action.complete(with: STPPaymentHandlerActionStatus.succeeded, error: nil) + + case .requiresAction: + return true + + case .processing: + action.complete( + with: STPPaymentHandlerActionStatus.failed, + error: _error(for: .intentStatusErrorCode) + ) + + case .succeeded: + action.complete(with: STPPaymentHandlerActionStatus.succeeded, error: nil) + + case .canceled: + action.complete(with: STPPaymentHandlerActionStatus.canceled, error: nil) + + @unknown default: + fatalError() + } + return false + } + + /// Calls the current action's completion handler for the PaymentIntent status, or returns YES if the status is ...RequiresAction. + func _handlePaymentIntentStatus( + forAction action: STPPaymentHandlerPaymentIntentActionParams + ) + -> Bool + { + guard let paymentIntent = action.paymentIntent else { + assert(false, "Calling _handlePaymentIntentStatus without a paymentIntent") + return false + } + + switch paymentIntent.status { + case .unknown: + action.complete( + with: STPPaymentHandlerActionStatus.failed, + error: _error( + for: .intentStatusErrorCode, + userInfo: [ + "STPPaymentIntent": paymentIntent.description + ] + ) + ) + + case .requiresPaymentMethod: + // If the user forgot to attach a PaymentMethod, they get an error before this point. + // If confirmation fails (eg not authenticated, card declined) the PaymentIntent transitions to this state. + if let lastPaymentError = paymentIntent.lastPaymentError { + if lastPaymentError.code + == STPPaymentIntentLastPaymentError.ErrorCodeAuthenticationFailure + { + action.complete( + with: STPPaymentHandlerActionStatus.failed, + error: _error(for: .notAuthenticatedErrorCode) + ) + } else if lastPaymentError.type == .card { + + action.complete( + with: STPPaymentHandlerActionStatus.failed, + error: _error( + for: .paymentErrorCode, + apiErrorCode: lastPaymentError.code, + userInfo: [ + NSLocalizedDescriptionKey: lastPaymentError.message ?? "" + ] + ) + ) + } else { + action.complete( + with: STPPaymentHandlerActionStatus.failed, + error: _error(for: .paymentErrorCode, apiErrorCode: lastPaymentError.code) + ) + } + } else { + action.complete( + with: STPPaymentHandlerActionStatus.failed, + error: _error(for: .paymentErrorCode) + ) + } + + case .requiresConfirmation: + action.complete(with: STPPaymentHandlerActionStatus.succeeded, error: nil) + + case .requiresAction: + return true + + case .processing: + if let type = paymentIntent.paymentMethod?.type, + STPPaymentHandler._isProcessingIntentSuccess(for: type) + { + action.complete(with: STPPaymentHandlerActionStatus.succeeded, error: nil) + } else { + action.complete( + with: STPPaymentHandlerActionStatus.failed, + error: _error(for: .intentStatusErrorCode) + ) + } + + case .succeeded: + action.complete(with: STPPaymentHandlerActionStatus.succeeded, error: nil) + + case .requiresCapture: + action.complete(with: STPPaymentHandlerActionStatus.succeeded, error: nil) + + case .canceled: + action.complete(with: STPPaymentHandlerActionStatus.canceled, error: nil) + + case .requiresSource: + fatalError() + case .requiresSourceAction: + fatalError() + } + return false + } + + @available(iOSApplicationExtension, unavailable) + @available(macCatalystApplicationExtension, unavailable) + func _handleAuthenticationForCurrentAction() { + guard let currentAction = currentAction, + let authenticationAction = currentAction.nextAction() + else { + return + } + + switch authenticationAction.type { + case .unknown: + currentAction.complete( + with: STPPaymentHandlerActionStatus.failed, + error: _error( + for: .unsupportedAuthenticationErrorCode, + userInfo: [ + "STPIntentAction": authenticationAction.description + ] + ) + ) + + case .redirectToURL: + if let redirectToURL = authenticationAction.redirectToURL { + _handleRedirect(to: redirectToURL.url, withReturn: redirectToURL.returnURL) + } else { + currentAction.complete( + with: STPPaymentHandlerActionStatus.failed, + error: _error( + for: .unsupportedAuthenticationErrorCode, + userInfo: [ + "STPIntentAction": authenticationAction.description + ] + ) + ) + } + + case .alipayHandleRedirect: + if let alipayHandleRedirect = authenticationAction.alipayHandleRedirect { + _handleRedirect( + to: alipayHandleRedirect.nativeURL, + fallbackURL: alipayHandleRedirect.url, + return: alipayHandleRedirect.returnURL + ) + } else { + currentAction.complete( + with: STPPaymentHandlerActionStatus.failed, + error: _error( + for: .unsupportedAuthenticationErrorCode, + userInfo: [ + "STPIntentAction": authenticationAction.description + ] + ) + ) + } + + case .weChatPayRedirectToApp: + if let weChatPayRedirectToApp = authenticationAction.weChatPayRedirectToApp { + _handleRedirect( + to: weChatPayRedirectToApp.nativeURL, + fallbackURL: nil, + return: nil + ) + } else { + currentAction.complete( + with: STPPaymentHandlerActionStatus.failed, + error: _error( + for: .unsupportedAuthenticationErrorCode, + userInfo: [ + "STPIntentAction": authenticationAction.description + ] + ) + ) + } + + case .OXXODisplayDetails: + if let hostedVoucherURL = authenticationAction.oxxoDisplayDetails?.hostedVoucherURL { + self._handleRedirect(to: hostedVoucherURL, withReturn: nil) + } else { + currentAction.complete( + with: STPPaymentHandlerActionStatus.failed, + error: _error( + for: .unsupportedAuthenticationErrorCode, + userInfo: [ + "STPIntentAction": authenticationAction.description + ] + ) + ) + } + + case .boletoDisplayDetails: + if let hostedVoucherURL = authenticationAction.boletoDisplayDetails?.hostedVoucherURL { + self._handleRedirect(to: hostedVoucherURL, withReturn: nil) + } else { + currentAction.complete( + with: STPPaymentHandlerActionStatus.failed, + error: _error( + for: .unsupportedAuthenticationErrorCode, + userInfo: [ + "STPIntentAction": authenticationAction.description + ] + ) + ) + } + + case .useStripeSDK: + if let useStripeSDK = authenticationAction.useStripeSDK { + switch useStripeSDK.type { + case .unknown: + currentAction.complete( + with: STPPaymentHandlerActionStatus.failed, + error: _error( + for: .unsupportedAuthenticationErrorCode, + userInfo: [ + "STPIntentAction": authenticationAction.description + ] + ) + ) + + case .threeDS2Fingerprint: + guard let threeDSService = currentAction.threeDS2Service else { + currentAction.complete( + with: STPPaymentHandlerActionStatus.failed, + error: _error( + for: .stripe3DS2ErrorCode, + userInfo: [ + "description": "Failed to initialize STDSThreeDS2Service." + ] + ) + ) + return + } + var transaction: STDSTransaction? + var authRequestParams: STDSAuthenticationRequestParameters? + + STDSSwiftTryCatch.try( + { + transaction = threeDSService.createTransaction( + forDirectoryServer: useStripeSDK.directoryServerID ?? "", + serverKeyID: useStripeSDK.directoryServerKeyID, + certificateString: useStripeSDK.directoryServerCertificate ?? "", + rootCertificateStrings: useStripeSDK.rootCertificateStrings ?? [], + withProtocolVersion: "2.1.0" + ) + + authRequestParams = transaction?.createAuthenticationRequestParameters() + + }, + catch: { exception in + + STPAnalyticsClient.sharedClient + .log3DS2AuthenticationRequestParamsFailed( + with: currentAction.apiClient._stored_configuration, + intentID: currentAction.intentStripeID ?? "", + error: self._error( + for: .stripe3DS2ErrorCode, + userInfo: [ + "exception": exception.description + ] + ) + ) + + currentAction.complete( + with: STPPaymentHandlerActionStatus.failed, + error: self._error( + for: .stripe3DS2ErrorCode, + userInfo: [ + "exception": exception.description + ] + ) + ) + }, + finallyBlock: { + } + ) + + STPAnalyticsClient.sharedClient.log3DS2AuthenticateAttempt( + with: currentAction.apiClient._stored_configuration, + intentID: currentAction.intentStripeID ?? "" + ) + + if let authParams = authRequestParams, + let transaction = transaction + { + currentAction.threeDS2Transaction = transaction + currentAction.apiClient.authenticate3DS2( + authParams, + sourceIdentifier: useStripeSDK.threeDSSourceID ?? "", + returnURL: currentAction.returnURLString, + maxTimeout: currentAction.threeDSCustomizationSettings + .authenticationTimeout, + publishableKeyOverride: useStripeSDK.publishableKeyOverride + ) { (authenticateResponse, error) in + if let authenticateResponse = authenticateResponse, + error == nil + { + + if let aRes = authenticateResponse.authenticationResponse { + + if aRes.isChallengeRequired { + let challengeParameters = STDSChallengeParameters( + authenticationResponse: aRes + ) + + let doChallenge: STPVoidBlock = { + var presentationError: NSError? + + if !self._canPresent( + with: currentAction.authenticationContext, + error: &presentationError + ) { + currentAction.complete( + with: STPPaymentHandlerActionStatus.failed, + error: presentationError + ) + } else { + STDSSwiftTryCatch.try( + { + let presentingViewController = currentAction + .authenticationContext + .authenticationPresentingViewController() + + if let paymentSheet = + presentingViewController + as? PaymentSheetAuthenticationContext + { + transaction.doChallenge( + with: challengeParameters, + challengeStatusReceiver: self, + timeout: TimeInterval( + currentAction + .threeDSCustomizationSettings + .authenticationTimeout + * 60 + ) + ) { + ( + threeDSChallengeViewController, + completion + ) in + paymentSheet.present( + threeDSChallengeViewController, + completion: completion + ) + } + } else { + transaction.doChallenge( + with: presentingViewController, + challengeParameters: + challengeParameters, + challengeStatusReceiver: self, + timeout: TimeInterval( + currentAction + .threeDSCustomizationSettings + .authenticationTimeout + * 60 + ) + ) + } + + }, + catch: { exception in + self.currentAction?.complete( + with: STPPaymentHandlerActionStatus + .failed, + error: self._error( + for: .stripe3DS2ErrorCode, + userInfo: [ + "exception": exception + ] + ) + ) + }, + finallyBlock: { + } + ) + } + } + + if currentAction.authenticationContext.responds( + to: #selector( + STPAuthenticationContext.prepare(forPresentation:)) + ) { + currentAction.authenticationContext.prepare?( + forPresentation: doChallenge + ) + } else { + doChallenge() + } + + } else { + // Challenge not required, finish the flow. + transaction.close() + currentAction.threeDS2Transaction = nil + STPAnalyticsClient.sharedClient.log3DS2FrictionlessFlow( + with: currentAction.apiClient._stored_configuration, + intentID: currentAction.intentStripeID ?? "" + ) + + self._retrieveAndCheckIntentForCurrentAction() + } + + } else if let fallbackURL = authenticateResponse.fallbackURL { + self._handleRedirect( + to: fallbackURL, + withReturn: URL(string: currentAction.returnURLString ?? "") + ) + } else { + currentAction.complete( + with: STPPaymentHandlerActionStatus.failed, + error: self._error( + for: .unsupportedAuthenticationErrorCode, + userInfo: [ + "STPIntentAction": authenticationAction.description + ] + ) + ) + } + + } else { + currentAction.complete( + with: STPPaymentHandlerActionStatus.failed, + error: (error as NSError?) + ) + } + } + + } else { + currentAction.complete( + with: STPPaymentHandlerActionStatus.failed, + error: self._error( + for: .unsupportedAuthenticationErrorCode, + userInfo: [ + "STPIntentAction": authenticationAction.description + ] + ) + ) + } + + case .threeDS2Redirect: + if let redirectURL = useStripeSDK.redirectURL { + let returnURL: URL? + if let returnURLString = currentAction.returnURLString { + returnURL = URL(string: returnURLString) + } else { + returnURL = nil + } + _handleRedirect(to: redirectURL, withReturn: returnURL) + } else { + // TOOD : Error + } + + @unknown default: + fatalError() + } + } else { + currentAction.complete( + with: STPPaymentHandlerActionStatus.failed, + error: _error( + for: .unsupportedAuthenticationErrorCode, + userInfo: [ + "STPIntentAction": authenticationAction.description + ] + ) + ) + } + + case .BLIKAuthorize: + // The customer must authorize the transaction in their banking app within 1 minute + // The merchant integration should spin and poll their backend or Stripe to determine success + guard + let currentAction = self.currentAction + as? STPPaymentHandlerPaymentIntentActionParams + else { + fatalError() + } + currentAction.complete(with: .succeeded, error: nil) + + case .verifyWithMicrodeposits: + // The customer must authorize after the microdeposits appear in their bank account + // which may take 1-2 business days + currentAction.complete(with: .succeeded, error: nil) + + case .upiAwaitNotification: + guard + let presentingVC = currentAction.authenticationContext + as? PaymentSheetAuthenticationContext + else { + return + } + presentingVC.presentPollingVCForAction(currentAction) + break + @unknown default: + fatalError() + } + } + + func _retryWithExponentialDelay(retryCount: Int, block: @escaping STPVoidBlock) { + // Add some backoff time: + let delayTime = TimeInterval( + pow(Double(1 + Self.maxChallengeRetries - retryCount), Double(2)) + ) + + DispatchQueue.main.asyncAfter(deadline: .now() + delayTime) { + block() + } + } + + func _retrieveAndCheckIntentForCurrentAction(retryCount: Int = maxChallengeRetries) { + // Alipay requires us to hit an endpoint before retrieving the PI, to ensure the status is up to date. + let pingMarlinIfNecessary: + ((STPPaymentHandlerPaymentIntentActionParams, @escaping STPVoidBlock) -> Void) = { + currentAction, + completionBlock in + if let paymentMethod = currentAction.paymentIntent?.paymentMethod, + paymentMethod.type == .alipay, + let alipayHandleRedirect = currentAction.nextAction()?.alipayHandleRedirect, + let alipayReturnURL = alipayHandleRedirect.marlinReturnURL + { + + // Make a request to the return URL + let request: URLRequest = URLRequest(url: alipayReturnURL) + let task: URLSessionDataTask = URLSession.shared.dataTask( + with: request, + completionHandler: { _, _, _ in + completionBlock() + } + ) + task.resume() + } else { + completionBlock() + } + } + + if let currentAction = self.currentAction as? STPPaymentHandlerPaymentIntentActionParams, + let paymentIntent = currentAction.paymentIntent + { + pingMarlinIfNecessary( + currentAction, + { + currentAction.apiClient.retrievePaymentIntent( + withClientSecret: paymentIntent.clientSecret, + expand: ["payment_method"] + ) { retrievedPaymentIntent, error in + currentAction.paymentIntent = retrievedPaymentIntent + if let error = error { + currentAction.complete( + with: STPPaymentHandlerActionStatus.failed, + error: error as NSError? + ) + } else { + // If the transaction is still unexpectedly processing, refresh the PaymentIntent + // This could happen if, for example, a payment is approved in an SFSafariViewController, the user closes the sheet, and the approval races with this fetch. + if let type = retrievedPaymentIntent?.paymentMethod?.type, + !STPPaymentHandler._isProcessingIntentSuccess(for: type), + retrievedPaymentIntent?.status == .processing && retryCount > 0 + { + self._retryWithExponentialDelay(retryCount: retryCount) { + self._retrieveAndCheckIntentForCurrentAction( + retryCount: retryCount - 1 + ) + } + } else { + if self.formSpecPaymentHandler?.handlePostConfirmPIStatusSpec( + for: currentAction.paymentIntent, + action: currentAction, + paymentHandler: self + ) ?? false { + return + } + let requiresAction: Bool = self._handlePaymentIntentStatus( + forAction: currentAction + ) + if requiresAction { + // If the status is still RequiresAction, the user exited from the redirect before the + // payment intent was updated. Consider it a cancel, unless it's a valid terminal next action + if self.isNextActionSuccessState( + nextAction: retrievedPaymentIntent?.nextAction + ) { + currentAction.complete(with: .succeeded, error: nil) + } else { + // If this is a web-based 3DS2 transaction that is still in requires_action, we may just need to refresh the PI a few more times. + if retryCount > 0 + && retrievedPaymentIntent?.paymentMethod?.type == .card + && retrievedPaymentIntent?.nextAction?.type + == .useStripeSDK + { + self._retryWithExponentialDelay(retryCount: retryCount) + { + self._retrieveAndCheckIntentForCurrentAction( + retryCount: retryCount - 1 + ) + } + } else { + self._markChallengeCanceled(withCompletion: { _, _ in + // We don't forward cancelation errors + currentAction.complete( + with: STPPaymentHandlerActionStatus.canceled, + error: nil + ) + }) + } + } + } + } + } + } + } + ) + } else if let currentAction = self.currentAction + as? STPPaymentHandlerSetupIntentActionParams, + let setupIntent = currentAction.setupIntent + { + + currentAction.apiClient.retrieveSetupIntent( + withClientSecret: setupIntent.clientSecret, + expand: ["payment_method"] + ) { retrievedSetupIntent, error in + currentAction.setupIntent = retrievedSetupIntent + if let error = error { + currentAction.complete( + with: STPPaymentHandlerActionStatus.failed, + error: error as NSError? + ) + } else { + if let type = retrievedSetupIntent?.paymentMethod?.type, + !STPPaymentHandler._isProcessingIntentSuccess(for: type), + retrievedSetupIntent?.status == .processing && retryCount > 0 + { + self._retryWithExponentialDelay(retryCount: retryCount) { + self._retrieveAndCheckIntentForCurrentAction(retryCount: retryCount - 1) + } + } else { + let requiresAction: Bool = self._handleSetupIntentStatus( + forAction: currentAction + ) + + if requiresAction { + // If the status is still RequiresAction, the user exited from the redirect before the + // payment intent was updated. Consider it a cancel, unless it's a valid terminal next action + if self.isNextActionSuccessState( + nextAction: retrievedSetupIntent?.nextAction + ) { + currentAction.complete(with: .succeeded, error: nil) + } else { + // If this is a web-based 3DS2 transaction that is still in requires_action, we may just need to refresh the SI a few more times. + if retryCount > 0 + && retrievedSetupIntent?.paymentMethod?.type == .card + && retrievedSetupIntent?.nextAction?.type == .useStripeSDK + { + self._retryWithExponentialDelay(retryCount: retryCount) { + self._retrieveAndCheckIntentForCurrentAction( + retryCount: retryCount - 1 + ) + } + } else { + // If the status is still RequiresAction, the user exited from the redirect before the + // setup intent was updated. Consider it a cancel + self._markChallengeCanceled(withCompletion: { _, _ in + // We don't forward cancelation errors + currentAction.complete( + with: STPPaymentHandlerActionStatus.canceled, + error: nil + ) + }) + } + } + } + } + } + + } + } else { + assert(false, "currentAction is an unknown type or nil intent.") + } + } + + @available(iOSApplicationExtension, unavailable) + @available(macCatalystApplicationExtension, unavailable) + @objc func _handleWillForegroundNotification() { + NotificationCenter.default.removeObserver( + self, + name: UIApplication.willEnterForegroundNotification, + object: nil + ) + STPURLCallbackHandler.shared().unregisterListener(self) + _retrieveAndCheckIntentForCurrentAction() + } + + @available(iOSApplicationExtension, unavailable) + @available(macCatalystApplicationExtension, unavailable) + @_spi(STP) public func _handleRedirect(to url: URL, withReturn returnURL: URL?) { + if let redirectShim = _redirectShim { + redirectShim(url, returnURL) + } + _handleRedirect(to: url, fallbackURL: url, return: returnURL) + } + + /// This method: + /// 1. Redirects to an app using url + /// 2. Open fallbackURL in a webview if 1) fails + @available(iOSApplicationExtension, unavailable) + @available(macCatalystApplicationExtension, unavailable) + /// + func _handleRedirect(to nativeURL: URL?, fallbackURL: URL?, return returnURL: URL?) { + var url = nativeURL + guard let currentAction = currentAction else { + assert(false, "Calling _handleRedirect without a currentAction") + return + } + + if let returnURL = returnURL { + STPURLCallbackHandler.shared().register(self, for: returnURL) + } + + STPAnalyticsClient.sharedClient.logURLRedirectNextAction( + with: currentAction.apiClient._stored_configuration, + intentID: currentAction.intentStripeID ?? "" + ) + + // Open the link in SafariVC + let presentSFViewControllerBlock: (() -> Void) = { + let context = currentAction.authenticationContext + + let presentingViewController = context.authenticationPresentingViewController() + + let doChallenge: STPVoidBlock = { + var presentationError: NSError? + guard self._canPresent(with: context, error: &presentationError) else { + currentAction.complete( + with: STPPaymentHandlerActionStatus.failed, + error: presentationError + ) + return + } + + if let fallbackURL = fallbackURL { + let safariViewController = SFSafariViewController(url: fallbackURL) + safariViewController.modalPresentationStyle = .overFullScreen + safariViewController.dismissButtonStyle = .close + if context.responds( + to: #selector(STPAuthenticationContext.configureSafariViewController(_:)) + ) { + context.configureSafariViewController?(safariViewController) + } + safariViewController.delegate = self + self.safariViewController = safariViewController + presentingViewController.present(safariViewController, animated: true) + } else { + currentAction.complete( + with: STPPaymentHandlerActionStatus.failed, + error: self._error( + for: .requiredAppNotAvailable, + userInfo: [ + "STPIntentAction": currentAction.description + ] + ) + ) + } + } + if context.responds(to: #selector(STPAuthenticationContext.prepare(forPresentation:))) { + context.prepare?(forPresentation: doChallenge) + } else { + doChallenge() + } + } + + // Redirect to an app + // We don't want universal links to open up Safari, but we do want to allow custom URL schemes + var options: [UIApplication.OpenExternalURLOptionsKey: Any] = [:] + #if !targetEnvironment(macCatalyst) + if let scheme = url?.scheme, scheme == "http" || scheme == "https" { + options[UIApplication.OpenExternalURLOptionsKey.universalLinksOnly] = true + } + #endif + + // If we're simulating app-to-app redirects, we always want to open the URL in Safari instead of an in-app web view. + // We'll tell Safari to open all URLs, not just universal links. + // If we don't have a nativeURL, we should open the fallbackURL in Safari instead. + if simulateAppToAppRedirect { + options[UIApplication.OpenExternalURLOptionsKey.universalLinksOnly] = false + url = nativeURL ?? fallbackURL + } + + // We don't check canOpenURL before opening the URL because that requires users to pre-register the custom URL schemes + if let url = url { + UIApplication.shared.open( + url, + options: options, + completionHandler: { success in + if !success { + // no app installed, launch safari view controller + presentSFViewControllerBlock() + } else { + NotificationCenter.default.addObserver( + self, + selector: #selector(self._handleWillForegroundNotification), + name: UIApplication.willEnterForegroundNotification, + object: nil + ) + } + } + ) + } else { + presentSFViewControllerBlock() + } + } + + /// Checks if authenticationContext.authenticationPresentingViewController can be presented on. + /// @note Call this method after `prepareAuthenticationContextForPresentation:` + func _canPresent( + with authenticationContext: STPAuthenticationContext, + error: inout NSError? + ) + -> Bool + { + // Always allow in tests: + if NSClassFromString("XCTest") != nil { + if checkCanPresentInTest { + checkCanPresentInTest.toggle() + } else { + return true + } + } + + let presentingViewController = + authenticationContext.authenticationPresentingViewController() + var canPresent = true + var errorMessage: String? + + // Is it in the window hierarchy? + if presentingViewController.viewIfLoaded?.window == nil { + canPresent = false + errorMessage = + "authenticationPresentingViewController is not in the window hierarchy. You should probably return the top-most view controller instead." + } + + // Is it already presenting something? + if presentingViewController.presentedViewController != nil { + canPresent = false + errorMessage = + "authenticationPresentingViewController is already presenting. You should probably dismiss the presented view controller in `prepareAuthenticationContextForPresentation`." + } + + if !canPresent { + error = _error( + for: .requiresAuthenticationContextErrorCode, + userInfo: errorMessage != nil + ? [ + STPError.errorMessageKey: errorMessage ?? "" + ] : nil + ) + } + return canPresent + } + + /// Check if the intent.nextAction is expected state after a successful on-session transaction + /// e.g. for voucher-based payment methods like OXXO that require out-of-band payment + func isNextActionSuccessState(nextAction: STPIntentAction?) -> Bool { + if let nextAction = nextAction { + switch nextAction.type { + case .unknown, + .redirectToURL, + .useStripeSDK, + .alipayHandleRedirect, + .BLIKAuthorize, + .weChatPayRedirectToApp: + return false + case .OXXODisplayDetails, + .boletoDisplayDetails, + .verifyWithMicrodeposits, + .upiAwaitNotification: + return true + } + } + return false + } + + // This is only called after web-redirects because native 3DS2 cancels go directly + // to the ACS + func _markChallengeCanceled(withCompletion completion: @escaping STPBooleanSuccessBlock) { + guard let currentAction = currentAction, + let nextAction = currentAction.nextAction() + else { + assert(false, "Calling _markChallengeCanceled without currentAction or nextAction.") + return + } + + var threeDSSourceID: String? + switch nextAction.type { + case .redirectToURL: + threeDSSourceID = nextAction.redirectToURL?.threeDSSourceID + case .useStripeSDK: + threeDSSourceID = nextAction.useStripeSDK?.threeDSSourceID + case .OXXODisplayDetails, .alipayHandleRedirect, .unknown, .BLIKAuthorize, + .weChatPayRedirectToApp, .boletoDisplayDetails, .verifyWithMicrodeposits, + .upiAwaitNotification: + break + @unknown default: + fatalError() + } + + guard let cancelSourceID = threeDSSourceID else { + // If there's no threeDSSourceID, there's nothing for us to cancel + completion(true, nil) + return + } + + if let currentAction = self.currentAction as? STPPaymentHandlerPaymentIntentActionParams, + let paymentIntent = currentAction.paymentIntent + { + guard + paymentIntent.paymentMethod?.card != nil || paymentIntent.paymentMethod?.link != nil + else { + // Only cancel 3DS auth on payment method types that support 3DS. + completion(true, nil) + return + } + + STPAnalyticsClient.sharedClient.log3DS2RedirectUserCanceled( + with: currentAction.apiClient._stored_configuration, + intentID: currentAction.intentStripeID ?? "" + ) + + let intentID = nextAction.useStripeSDK?.threeDS2IntentOverride ?? paymentIntent.stripeId + + currentAction.apiClient.cancel3DSAuthentication( + forPaymentIntent: intentID, + withSource: cancelSourceID, + publishableKeyOverride: nextAction.useStripeSDK?.publishableKeyOverride + ) { retrievedPaymentIntent, error in + currentAction.paymentIntent = retrievedPaymentIntent + completion(retrievedPaymentIntent != nil, error) + } + } else if let currentAction = self.currentAction + as? STPPaymentHandlerSetupIntentActionParams, + let setupIntent = currentAction.setupIntent + { + guard setupIntent.paymentMethod?.card != nil || setupIntent.paymentMethod?.link != nil + else { + // Only cancel 3DS auth on payment method types that support 3DS. + completion(true, nil) + return + } + + STPAnalyticsClient.sharedClient.log3DS2RedirectUserCanceled( + with: currentAction.apiClient._stored_configuration, + intentID: currentAction.intentStripeID ?? "" + ) + + let intentID = nextAction.useStripeSDK?.threeDS2IntentOverride ?? setupIntent.stripeID + + currentAction.apiClient.cancel3DSAuthentication( + forSetupIntent: intentID, + withSource: cancelSourceID, + publishableKeyOverride: nextAction.useStripeSDK?.publishableKeyOverride + ) { retrievedSetupIntent, error in + currentAction.setupIntent = retrievedSetupIntent + completion(retrievedSetupIntent != nil, error) + } + } else { + assert(false, "currentAction is an unknown type or nil intent.") + } + } + + static let maxChallengeRetries = 2 + func _markChallengeCompleted( + withCompletion completion: @escaping STPBooleanSuccessBlock, + retryCount: Int = maxChallengeRetries + ) { + guard let currentAction = currentAction, + let useStripeSDK = currentAction.nextAction()?.useStripeSDK, + let threeDSSourceID = useStripeSDK.threeDSSourceID + else { + completion(false, nil) + return + } + + currentAction.apiClient.complete3DS2Authentication( + forSource: threeDSSourceID, + publishableKeyOverride: useStripeSDK.publishableKeyOverride + ) { + success, + error in + if success { + if let paymentIntentAction = currentAction + as? STPPaymentHandlerPaymentIntentActionParams, + let paymentIntent = paymentIntentAction.paymentIntent + { + + currentAction.apiClient.retrievePaymentIntent( + withClientSecret: paymentIntent.clientSecret, + expand: ["payment_method"] + ) { retrievedPaymentIntent, retrieveError in + paymentIntentAction.paymentIntent = retrievedPaymentIntent + completion(retrievedPaymentIntent != nil, retrieveError) + } + } else if let setupIntentAction = currentAction + as? STPPaymentHandlerSetupIntentActionParams, + let setupIntent = setupIntentAction.setupIntent + { + currentAction.apiClient.retrieveSetupIntent( + withClientSecret: setupIntent.clientSecret + ) { retrievedSetupIntent, retrieveError in + setupIntentAction.setupIntent = retrievedSetupIntent + completion(retrievedSetupIntent != nil, retrieveError) + } + } else { + assert(false, "currentAction is an unknown type or nil intent.") + } + } else { + // This isn't guaranteed to succeed if the ACS isn't ready yet. + // Try it a few more times if it fails with a 400. (RUN_MOBILESDK-126) + if retryCount > 0 + && (error as NSError?)?.code == STPErrorCode.invalidRequestError.rawValue + { + self._retryWithExponentialDelay( + retryCount: retryCount, + block: { + self._markChallengeCompleted( + withCompletion: completion, + retryCount: retryCount - 1 + ) + } + ) + } else { + completion(success, error) + } + } + } + } + + // MARK: - Errors + @_spi(STP) public func _error( + for errorCode: STPPaymentHandlerErrorCode, + apiErrorCode: String? = nil, + userInfo additionalUserInfo: [AnyHashable: Any]? = nil + ) -> NSError { + var userInfo: [AnyHashable: Any] = additionalUserInfo ?? [:] + switch errorCode { + // 3DS(2) flow expected user errors + case .notAuthenticatedErrorCode: + userInfo[NSLocalizedDescriptionKey] = STPLocalizedString( + "We are unable to authenticate your payment method. Please choose a different payment method and try again.", + "Error when 3DS2 authentication failed (e.g. customer entered the wrong code)" + ) + + case .timedOutErrorCode: + userInfo[NSLocalizedDescriptionKey] = STPLocalizedString( + "Timed out authenticating your payment method -- try again", + "Error when 3DS2 authentication timed out." + ) + + // PaymentIntent has an unexpected/unknown status + case .intentStatusErrorCode: + // The PI's status is processing or unknown + userInfo[STPError.errorMessageKey] = + userInfo[STPError.errorMessageKey] ?? "The PaymentIntent status cannot be handled." + userInfo[NSLocalizedDescriptionKey] = NSError.stp_unexpectedErrorMessage() + + case .unsupportedAuthenticationErrorCode: + userInfo[STPError.errorMessageKey] = + userInfo[STPError.errorMessageKey] + ?? "The SDK doesn't recognize the PaymentIntent action type." + userInfo[NSLocalizedDescriptionKey] = NSError.stp_unexpectedErrorMessage() + + case .requiredAppNotAvailable: + userInfo[STPError.errorMessageKey] = + userInfo[STPError.errorMessageKey] + ?? "This PaymentIntent action requires an app, but the app is not installed or the request to open the app was denied." + userInfo[NSLocalizedDescriptionKey] = NSError.stp_unexpectedErrorMessage() + + // Programming errors + case .requiresPaymentMethodErrorCode: + userInfo[STPError.errorMessageKey] = + userInfo[STPError.errorMessageKey] + ?? "The PaymentIntent requires a PaymentMethod or Source to be attached before using STPPaymentHandler." + userInfo[NSLocalizedDescriptionKey] = NSError.stp_unexpectedErrorMessage() + + case .noConcurrentActionsErrorCode: + userInfo[STPError.errorMessageKey] = + userInfo[STPError.errorMessageKey] + ?? "The current action is not yet completed. STPPaymentHandler does not support concurrent calls to its API." + userInfo[NSLocalizedDescriptionKey] = NSError.stp_unexpectedErrorMessage() + + case .requiresAuthenticationContextErrorCode: + userInfo[NSLocalizedDescriptionKey] = NSError.stp_unexpectedErrorMessage() + + // Exceptions thrown from the Stripe3DS2 SDK. Other errors are reported via STPChallengeStatusReceiver. + case .stripe3DS2ErrorCode: + userInfo[STPError.errorMessageKey] = + userInfo[STPError.errorMessageKey] ?? "There was an error in the Stripe3DS2 SDK." + userInfo[NSLocalizedDescriptionKey] = NSError.stp_unexpectedErrorMessage() + + // Confirmation errors (eg card was declined) + case .paymentErrorCode: + userInfo[STPError.errorMessageKey] = + userInfo[STPError.errorMessageKey] + ?? "There was an error confirming the Intent. Inspect the `paymentIntent.lastPaymentError` or `setupIntent.lastSetupError` property." + + userInfo[NSLocalizedDescriptionKey] = + apiErrorCode.flatMap({ NSError.Utils.localizedMessage(fromAPIErrorCode: $0) }) + ?? userInfo[NSLocalizedDescriptionKey] + ?? NSError.stp_unexpectedErrorMessage() + + // Client secret format error + case .invalidClientSecret: + userInfo[STPError.errorMessageKey] = + userInfo[STPError.errorMessageKey] + ?? "The provided Intent client secret does not match the expected client secret format. Make sure your server is returning the correct value and that is passed to `STPPaymentHandler`." + userInfo[NSLocalizedDescriptionKey] = + userInfo[NSLocalizedDescriptionKey] ?? NSError.stp_unexpectedErrorMessage() + } + return NSError( + domain: STPPaymentHandler.errorDomain, + code: errorCode.rawValue, + userInfo: userInfo as? [String: Any] + ) + } +} + +@available(iOSApplicationExtension, unavailable) +@available(macCatalystApplicationExtension, unavailable) +extension STPPaymentHandler: SFSafariViewControllerDelegate { + // MARK: - SFSafariViewControllerDelegate + /// :nodoc: + @objc + public func safariViewControllerDidFinish(_ controller: SFSafariViewController) { + let context = currentAction?.authenticationContext + if context?.responds( + to: #selector(STPAuthenticationContext.authenticationContextWillDismiss(_:)) + ) ?? false { + context?.authenticationContextWillDismiss?(controller) + } + safariViewController = nil + STPURLCallbackHandler.shared().unregisterListener(self) + _retrieveAndCheckIntentForCurrentAction() + } +} + +@available(iOSApplicationExtension, unavailable) +@available(macCatalystApplicationExtension, unavailable) +/// :nodoc: +@_spi(STP) extension STPPaymentHandler: STPURLCallbackListener { + /// :nodoc: + @_spi(STP) public func handleURLCallback(_ url: URL) -> Bool { + // Note: At least my iOS 15 device, willEnterForegroundNotification is triggered before this method when returning from another app, which means this method isn't called because it unregisters from STPURLCallbackHandler. + let context = currentAction?.authenticationContext + if context?.responds( + to: #selector(STPAuthenticationContext.authenticationContextWillDismiss(_:)) + ) ?? false, + let safariViewController = safariViewController + { + context?.authenticationContextWillDismiss?(safariViewController) + } + + NotificationCenter.default.removeObserver( + self, + name: UIApplication.willEnterForegroundNotification, + object: nil + ) + STPURLCallbackHandler.shared().unregisterListener(self) + safariViewController?.dismiss(animated: true) { + self.safariViewController = nil + } + _retrieveAndCheckIntentForCurrentAction() + return true + } +} + +extension STPPaymentHandler { + // MARK: - STPChallengeStatusReceiver + /// :nodoc: + @objc(transaction:didCompleteChallengeWithCompletionEvent:) + dynamic func transaction( + _ transaction: STDSTransaction, + didCompleteChallengeWith completionEvent: STDSCompletionEvent + ) { + guard let currentAction = currentAction else { + assert(false, "Calling didCompleteChallengeWith without currentAction.") + return + } + let transactionStatus = completionEvent.transactionStatus + STPAnalyticsClient.sharedClient.log3DS2ChallengeFlowCompleted( + with: currentAction.apiClient._stored_configuration, + intentID: currentAction.intentStripeID ?? "", + uiType: transaction.presentedChallengeUIType + ) + if transactionStatus == "Y" { + _markChallengeCompleted(withCompletion: { markedCompleted, error in + if let currentAction = self.currentAction + as? STPPaymentHandlerPaymentIntentActionParams + { + let requiresAction = self._handlePaymentIntentStatus(forAction: currentAction) + if requiresAction { + assert( + false, + "3DS2 challenge completed, but the PaymentIntent is still requiresAction" + ) + currentAction.complete( + with: STPPaymentHandlerActionStatus.failed, + error: self._error(for: .intentStatusErrorCode) + ) + } + } else if let currentAction = self.currentAction + as? STPPaymentHandlerSetupIntentActionParams + { + let requiresAction = self._handleSetupIntentStatus(forAction: currentAction) + if requiresAction { + assert( + false, + "3DS2 challenge completed, but the SetupIntent is still requiresAction" + ) + currentAction.complete( + with: STPPaymentHandlerActionStatus.failed, + error: self._error(for: .intentStatusErrorCode) + ) + } + } + }) + } else { + // going to ignore the rest of the status types because they provide more detail than we require + _markChallengeCompleted(withCompletion: { _, error in + currentAction.complete( + with: STPPaymentHandlerActionStatus.failed, + error: self._error( + for: .notAuthenticatedErrorCode, + userInfo: [ + "transaction_status": transactionStatus + ] + ) + ) + }) + } + } + + /// :nodoc: + @objc(transactionDidCancel:) + dynamic func transactionDidCancel(_ transaction: STDSTransaction) { + guard let currentAction = currentAction else { + assert(false, "Calling transactionDidCancel without currentAction.") + return + } + + STPAnalyticsClient.sharedClient.log3DS2ChallengeFlowUserCanceled( + with: currentAction.apiClient._stored_configuration, + intentID: currentAction.intentStripeID ?? "", + uiType: transaction.presentedChallengeUIType + ) + _markChallengeCompleted(withCompletion: { _, error in + // we don't forward cancelation errors + currentAction.complete(with: STPPaymentHandlerActionStatus.canceled, error: nil) + }) + } + + /// :nodoc: + @objc(transactionDidTimeOut:) + dynamic func transactionDidTimeOut(_ transaction: STDSTransaction) { + guard let currentAction = currentAction else { + assert(false, "Calling transactionDidTimeOut without currentAction.") + return + } + + STPAnalyticsClient.sharedClient.log3DS2ChallengeFlowTimedOut( + with: currentAction.apiClient._stored_configuration, + intentID: currentAction.intentStripeID ?? "", + uiType: transaction.presentedChallengeUIType + ) + _markChallengeCompleted(withCompletion: { _, error in + currentAction.complete( + with: STPPaymentHandlerActionStatus.failed, + error: self._error(for: .timedOutErrorCode) + ) + }) + + } + + /// :nodoc: + @objc(transaction:didErrorWithProtocolErrorEvent:) + dynamic func transaction( + _ transaction: STDSTransaction, + didErrorWith protocolErrorEvent: STDSProtocolErrorEvent + ) { + + guard let currentAction = currentAction else { + assert(false, "Calling didErrorWith protocolErrorEvent without currentAction.") + return + } + + _markChallengeCompleted(withCompletion: { _, error in + // Add localizedError to the 3DS2 SDK error + let threeDSError = protocolErrorEvent.errorMessage.nsErrorValue() as NSError + var userInfo = threeDSError.userInfo + userInfo[NSLocalizedDescriptionKey] = NSError.stp_unexpectedErrorMessage() + + let localizedError = NSError( + domain: threeDSError.domain, + code: threeDSError.code, + userInfo: userInfo + ) + STPAnalyticsClient.sharedClient.log3DS2ChallengeFlowErrored( + with: currentAction.apiClient._stored_configuration, + intentID: currentAction.intentStripeID ?? "", + error: localizedError + ) + currentAction.complete( + with: STPPaymentHandlerActionStatus.failed, + error: localizedError + ) + }) + } + + /// :nodoc: + @objc(transaction:didErrorWithRuntimeErrorEvent:) + dynamic func transaction( + _ transaction: STDSTransaction, + didErrorWith runtimeErrorEvent: STDSRuntimeErrorEvent + ) { + + guard let currentAction = currentAction else { + assert(false, "Calling didErrorWith runtimeErrorEvent without currentAction.") + return + } + + _markChallengeCompleted(withCompletion: { _, error in + // Add localizedError to the 3DS2 SDK error + let threeDSError = runtimeErrorEvent.nsErrorValue() as NSError + var userInfo = threeDSError.userInfo + userInfo[NSLocalizedDescriptionKey] = NSError.stp_unexpectedErrorMessage() + + let localizedError = NSError( + domain: threeDSError.domain, + code: threeDSError.code, + userInfo: userInfo + ) + + STPAnalyticsClient.sharedClient.log3DS2ChallengeFlowErrored( + with: currentAction.apiClient._stored_configuration, + intentID: currentAction.intentStripeID ?? "", + error: localizedError + ) + currentAction.complete( + with: STPPaymentHandlerActionStatus.failed, + error: localizedError + ) + }) + } + + /// :nodoc: + @objc(transactionDidPresentChallengeScreen:) + dynamic func transactionDidPresentChallengeScreen(_ transaction: STDSTransaction) { + + guard let currentAction = currentAction else { + assert(false, "Calling didErrorWith runtimeErrorEvent without currentAction.") + return + } + + STPAnalyticsClient.sharedClient.log3DS2ChallengeFlowPresented( + with: currentAction.apiClient._stored_configuration, + intentID: currentAction.intentStripeID ?? "", + uiType: transaction.presentedChallengeUIType + ) + } + + /// :nodoc: + @objc(dismissChallengeViewController:forTransaction:) + dynamic func dismiss( + _ challengeViewController: UIViewController, + for transaction: STDSTransaction + ) { + guard let currentAction = currentAction else { + assert(false, "Calling didErrorWith runtimeErrorEvent without currentAction.") + return + } + if let paymentSheet = currentAction.authenticationContext + .authenticationPresentingViewController() as? PaymentSheetAuthenticationContext + { + paymentSheet.dismiss(challengeViewController) + } else { + challengeViewController.dismiss(animated: true, completion: nil) + } + } + + @_spi(STP) public func cancel3DS2ChallengeFlow() { + guard let transaction = currentAction?.threeDS2Transaction else { + assertionFailure() + return + } + transaction.cancelChallengeFlow() + } +} + +/// Internal authentication context for PaymentSheet magic +@_spi(STP) public protocol PaymentSheetAuthenticationContext: STPAuthenticationContext { + func present(_ authenticationViewController: UIViewController, completion: @escaping () -> Void) + func dismiss(_ authenticationViewController: UIViewController) + func presentPollingVCForAction(_ action: STPPaymentHandlerActionParams) +} + +@_spi(STP) public protocol FormSpecPaymentHandler { + func isPIStatusSpecFinishedForPostConfirmPIStatus( + paymentIntent: STPPaymentIntent?, + paymentHandler: STPPaymentHandler + ) -> Bool + func handleNextActionSpec( + for paymentIntent: STPPaymentIntent, + action: STPPaymentHandlerPaymentIntentActionParams, + paymentHandler: STPPaymentHandler + ) -> Bool + func handlePostConfirmPIStatusSpec( + for paymentIntent: STPPaymentIntent?, + action: STPPaymentHandlerPaymentIntentActionParams, + paymentHandler: STPPaymentHandler + ) -> Bool +} diff --git a/Pods/StripePayments/StripePayments/StripePayments/PaymentHandler/STPThreeDSButtonCustomization.swift b/Pods/StripePayments/StripePayments/StripePayments/PaymentHandler/STPThreeDSButtonCustomization.swift new file mode 100644 index 0000000..a32d78e --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/PaymentHandler/STPThreeDSButtonCustomization.swift @@ -0,0 +1,126 @@ +// +// STPThreeDSButtonCustomization.swift +// StripePayments +// +// Created by Yuki Tokuhiro on 6/17/19. +// Copyright © 2019 Stripe, Inc. All rights reserved. +// + +import Foundation +import UIKit + +#if canImport(Stripe3DS2) + import Stripe3DS2 +#endif + +/// An enum that defines the different types of buttons that are able to be customized. +@objc public enum STPThreeDSCustomizationButtonType: Int { + /// The submit button type. + case submit = 0 + /// The continue button type. + case `continue` = 1 + /// The next button type. + case next = 2 + /// The cancel button type. + case cancel = 3 + /// The resend button type. + case resend = 4 +} + +/// An enumeration of the case transformations that can be applied to the button's title +@objc public enum STPThreeDSButtonTitleStyle: Int { + /// Default style, doesn't modify the title + case `default` + /// Applies localizedUppercaseString to the title + case uppercase + /// Applies localizedLowercaseString to the title + case lowercase + /// Applies localizedCapitalizedString to the title + case sentenceCapitalized +} + +/// A customization object to use to configure the UI of a button. +public class STPThreeDSButtonCustomization: NSObject { + /// The default settings for the provided button type. + @objc(defaultSettingsForButtonType:) public class func defaultSettings( + for type: STPThreeDSCustomizationButtonType + ) -> STPThreeDSButtonCustomization { + let stdsButtonCustomization = STDSButtonCustomization.defaultSettings( + for: STDSUICustomizationButtonType(rawValue: type.rawValue)! + ) + let buttonCustomization = STPThreeDSButtonCustomization.init( + backgroundColor: stdsButtonCustomization.backgroundColor, + cornerRadius: stdsButtonCustomization.cornerRadius + ) + buttonCustomization.buttonCustomization = stdsButtonCustomization + return buttonCustomization + } + + internal var buttonCustomization: STDSButtonCustomization + + /// Initializes an instance of STDSButtonCustomization with the given backgroundColor and colorRadius. + @objc + public init( + backgroundColor: UIColor, + cornerRadius: CGFloat + ) { + buttonCustomization = STDSButtonCustomization( + backgroundColor: backgroundColor, + cornerRadius: cornerRadius + ) + super.init() + } + + /// The background color of the button. + /// The default for .resend and .cancel is clear. + /// The default for .submit, .continue, and .next is blue. + + @objc public var backgroundColor: UIColor { + get { + return buttonCustomization.backgroundColor + } + set { + buttonCustomization.backgroundColor = newValue + } + } + /// The corner radius of the button. Defaults to 8. + + @objc public var cornerRadius: CGFloat { + get { + return buttonCustomization.cornerRadius + } + set { + buttonCustomization.cornerRadius = newValue + } + } + /// The capitalization style of the button title. + + @objc public var titleStyle: STPThreeDSButtonTitleStyle { + get { + return STPThreeDSButtonTitleStyle(rawValue: buttonCustomization.titleStyle.rawValue)! + } + set { + buttonCustomization.titleStyle = STDSButtonTitleStyle(rawValue: newValue.rawValue)! + } + } + /// The font of the title. + + @objc public var font: UIFont? { + get { + return buttonCustomization.font + } + set(font) { + buttonCustomization.font = font + } + } + /// The text color of the title. + + @objc public var textColor: UIColor? { + get { + return buttonCustomization.textColor + } + set { + buttonCustomization.textColor = newValue + } + } +} diff --git a/Pods/StripePayments/StripePayments/StripePayments/PaymentHandler/STPThreeDSCustomizationSettings.swift b/Pods/StripePayments/StripePayments/StripePayments/PaymentHandler/STPThreeDSCustomizationSettings.swift new file mode 100644 index 0000000..bcea5f6 --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/PaymentHandler/STPThreeDSCustomizationSettings.swift @@ -0,0 +1,44 @@ +// +// STPThreeDSCustomizationSettings.swift +// StripePayments +// +// Created by Cameron Sabol on 5/30/19. +// Copyright © 2019 Stripe, Inc. All rights reserved. +// + +import Foundation +import UIKit + +#if canImport(Stripe3DS2) + import Stripe3DS2 +#endif + +/// `STPThreeDSCustomizationSettings` provides customization options for 3DS2 authentication flows in your app. +public class STPThreeDSCustomizationSettings: NSObject { + /// Returns an `STPThreeDSCustomizationSettings` preconfigured with the default + /// Stripe UI settings and a 10 minute `authenticationTimeout`. + /// @deprecated Use STPThreeDSCustomizationSettings() instead. The default settings are the same. + @available( + *, + deprecated, + message: + "Use STPThreeDSCustomizationSettings() instead of STPThreeDSCustomizationSettings.defaultSettings()." + ) + @objc + public class func defaultSettings() -> STPThreeDSCustomizationSettings { + return STPThreeDSCustomizationSettings() + } + + /// `uiCustomization` can be used to provide custom UI settings for the authentication + /// challenge screens presented during a Three Domain Secure authentication. For more information see + /// our guide on supporting 3DS2 in your iOS application. + /// Note: It's important to configure this object appropriately before calling any `STPPaymentHandler` APIs. + /// The API makes a copy of the customization settings you provide; it ignores any subsequent changes you + /// make to your `STPThreeDSUICustomization` instance. + /// Defaults to `STPThreeDSUICustomization.defaultSettings()`. + @objc public var uiCustomization = STPThreeDSUICustomization.defaultSettings() + /// `authenticationTimeout` is the total time allowed for a user to complete a 3DS2 authentication + /// interaction, in minutes. This value *must* be at least 5 minutes. + /// Defaults to 10 minutes. + @objc public var authenticationTimeout = 10 +} diff --git a/Pods/StripePayments/StripePayments/StripePayments/PaymentHandler/STPThreeDSFooterCustomization.swift b/Pods/StripePayments/StripePayments/StripePayments/PaymentHandler/STPThreeDSFooterCustomization.swift new file mode 100644 index 0000000..3578b46 --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/PaymentHandler/STPThreeDSFooterCustomization.swift @@ -0,0 +1,88 @@ +// +// STPThreeDSFooterCustomization.swift +// StripePayments +// +// Created by Yuki Tokuhiro on 6/17/19. +// Copyright © 2019 Stripe, Inc. All rights reserved. +// + +import Foundation +import UIKit + +#if canImport(Stripe3DS2) + import Stripe3DS2 +#endif + +/// The Challenge view displays a footer with additional details that +/// expand when tapped. This object configures the appearance of that view. +public class STPThreeDSFooterCustomization: NSObject { + /// The default settings. + @objc + public class func defaultSettings() -> STPThreeDSFooterCustomization { + return STPThreeDSFooterCustomization() + } + + internal var footerCustomization = STDSFooterCustomization.defaultSettings() + /// The background color of the footer. + /// Defaults to gray. + + @objc public var backgroundColor: UIColor { + get { + return footerCustomization.backgroundColor + } + set { + footerCustomization.backgroundColor = newValue + } + } + + /// The color of the chevron. Defaults to a dark gray. + @objc public var chevronColor: UIColor { + get { + return footerCustomization.chevronColor + } + set { + footerCustomization.chevronColor = newValue + } + } + + /// The color of the heading text. Defaults to black. + @objc public var headingTextColor: UIColor { + get { + return footerCustomization.headingTextColor + } + set { + footerCustomization.headingTextColor = newValue + } + } + /// The font to use for the heading text. + + @objc public var headingFont: UIFont { + get { + return footerCustomization.headingFont + } + set { + footerCustomization.headingFont = newValue + } + } + + /// The font of the text. + @objc public var font: UIFont? { + get { + return footerCustomization.font + } + set { + footerCustomization.font = newValue + } + } + + /// The color of the text. + @objc public var textColor: UIColor? { + get { + return footerCustomization.textColor + } + set { + footerCustomization.textColor = newValue + } + } + +} diff --git a/Pods/StripePayments/StripePayments/StripePayments/PaymentHandler/STPThreeDSLabelCustomization.swift b/Pods/StripePayments/StripePayments/StripePayments/PaymentHandler/STPThreeDSLabelCustomization.swift new file mode 100644 index 0000000..302013b --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/PaymentHandler/STPThreeDSLabelCustomization.swift @@ -0,0 +1,67 @@ +// +// STPThreeDSLabelCustomization.swift +// StripePayments +// +// Created by Yuki Tokuhiro on 6/17/19. +// Copyright © 2019 Stripe, Inc. All rights reserved. +// + +import Foundation +import UIKit + +#if canImport(Stripe3DS2) + import Stripe3DS2 +#endif + +/// A customization object to use to configure the UI of a text label. +public class STPThreeDSLabelCustomization: NSObject { + /// The default settings. + @objc + public class func defaultSettings() -> STPThreeDSLabelCustomization { + return STPThreeDSLabelCustomization() + } + + internal var labelCustomization = STDSLabelCustomization.defaultSettings() + + /// The font to use for heading text. + + @objc public var headingFont: UIFont { + get { + return labelCustomization.headingFont + } + set(headingFont) { + labelCustomization.headingFont = headingFont + } + } + /// The color of heading text. Defaults to black. + + @objc public var headingTextColor: UIColor { + get { + return labelCustomization.headingTextColor + } + set(headingTextColor) { + labelCustomization.headingTextColor = headingTextColor + } + } + + /// The font to use for non-heading text. + @objc public var font: UIFont? { + get { + return labelCustomization.font + } + set(font) { + labelCustomization.font = font + } + } + + /// The color to use for non-heading text. Defaults to black. + @objc public var textColor: UIColor? { + get { + return labelCustomization.textColor + } + set(textColor) { + labelCustomization.textColor = textColor + } + } + +} diff --git a/Pods/StripePayments/StripePayments/StripePayments/PaymentHandler/STPThreeDSNavigationBarCustomization.swift b/Pods/StripePayments/StripePayments/StripePayments/PaymentHandler/STPThreeDSNavigationBarCustomization.swift new file mode 100644 index 0000000..8d89702 --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/PaymentHandler/STPThreeDSNavigationBarCustomization.swift @@ -0,0 +1,101 @@ +// +// STPThreeDSNavigationBarCustomization.swift +// StripePayments +// +// Created by Yuki Tokuhiro on 6/17/19. +// Copyright © 2019 Stripe, Inc. All rights reserved. +// + +import Foundation +import UIKit + +#if canImport(Stripe3DS2) + import Stripe3DS2 +#endif + +/// A customization object to use to configure a UINavigationBar. +public class STPThreeDSNavigationBarCustomization: NSObject { + /// The default settings. + @objc + public class func defaultSettings() -> STPThreeDSNavigationBarCustomization { + return STPThreeDSNavigationBarCustomization() + } + + @_spi(STP) public var navigationBarCustomization = + STDSNavigationBarCustomization.defaultSettings() + + /// The tint color of the navigation bar background. + /// Defaults to nil. + + @objc public var barTintColor: UIColor? { + get { + return navigationBarCustomization.barTintColor + } + set(barTintColor) { + navigationBarCustomization.barTintColor = barTintColor + } + } + /// The navigation bar style. + /// Defaults to UIBarStyleDefault. + /// @note This property controls the `UIStatusBarStyle`. Set this to `UIBarStyleBlack` + /// to change the `statusBarStyle` to `UIStatusBarStyleLightContent` - even if you also set + /// `barTintColor` to change the actual color of the navigation bar. + + @objc public var barStyle: UIBarStyle { + get { + return navigationBarCustomization.barStyle + } + set(barStyle) { + navigationBarCustomization.barStyle = barStyle + } + } + /// A Boolean value indicating whether the navigation bar is translucent or not. + /// Defaults to YES. + @objc public var translucent: Bool { + get { + return navigationBarCustomization.translucent + } + set(translucent) { + navigationBarCustomization.translucent = translucent + } + } + /// The text to display in the title of the navigation bar. + /// Defaults to "Secure checkout". + + @objc public var headerText: String { + get { + return navigationBarCustomization.headerText + } + set(headerText) { + navigationBarCustomization.headerText = headerText + } + } + /// The text to display for the button in the navigation bar. + /// Defaults to "Cancel". + @objc public var buttonText: String { + get { + return navigationBarCustomization.buttonText + } + set(buttonText) { + navigationBarCustomization.buttonText = buttonText + } + } + /// The font to use for the title. Defaults to nil. + @objc public var font: UIFont? { + get { + return navigationBarCustomization.font + } + set(font) { + navigationBarCustomization.font = font + } + } + /// The color to use for the title. Defaults to nil. + @objc public var textColor: UIColor? { + get { + return navigationBarCustomization.textColor + } + set(textColor) { + navigationBarCustomization.textColor = textColor + } + } +} diff --git a/Pods/StripePayments/StripePayments/StripePayments/PaymentHandler/STPThreeDSSelectionCustomization.swift b/Pods/StripePayments/StripePayments/StripePayments/PaymentHandler/STPThreeDSSelectionCustomization.swift new file mode 100644 index 0000000..d791de4 --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/PaymentHandler/STPThreeDSSelectionCustomization.swift @@ -0,0 +1,72 @@ +// +// STPThreeDSSelectionCustomization.swift +// StripePayments +// +// Created by Yuki Tokuhiro on 6/18/19. +// Copyright © 2019 Stripe, Inc. All rights reserved. +// + +import Foundation +import UIKit + +#if canImport(Stripe3DS2) + import Stripe3DS2 +#endif + +/// A customization object that configures the appearance of +/// radio buttons and checkboxes. +public class STPThreeDSSelectionCustomization: NSObject { + /// The default settings. + @objc + public class func defaultSettings() -> STPThreeDSSelectionCustomization { + return STPThreeDSSelectionCustomization() + } + + internal var selectionCustomization = STDSSelectionCustomization.defaultSettings() + + /// The primary color of the selected state. + /// Defaults to blue. + + @objc public var primarySelectedColor: UIColor { + get { + return selectionCustomization.primarySelectedColor + } + set(primarySelectedColor) { + selectionCustomization.primarySelectedColor = primarySelectedColor + } + } + /// The secondary color of the selected state (e.g. the checkmark color). + /// Defaults to white. + + @objc public var secondarySelectedColor: UIColor { + get { + return selectionCustomization.secondarySelectedColor + } + set(secondarySelectedColor) { + selectionCustomization.secondarySelectedColor = secondarySelectedColor + } + } + /// The background color displayed in the unselected state. + /// Defaults to light blue. + + @objc public var unselectedBackgroundColor: UIColor { + get { + return selectionCustomization.unselectedBackgroundColor + } + set(unselectedBackgroundColor) { + selectionCustomization.unselectedBackgroundColor = unselectedBackgroundColor + } + } + /// The color of the border drawn around the view in the unselected state. + /// Defaults to blue. + + @objc public var unselectedBorderColor: UIColor { + get { + return selectionCustomization.unselectedBorderColor + } + set(unselectedBorderColor) { + selectionCustomization.unselectedBorderColor = unselectedBorderColor + } + } + +} diff --git a/Pods/StripePayments/StripePayments/StripePayments/PaymentHandler/STPThreeDSTextFieldCustomization.swift b/Pods/StripePayments/StripePayments/StripePayments/PaymentHandler/STPThreeDSTextFieldCustomization.swift new file mode 100644 index 0000000..ebdc64c --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/PaymentHandler/STPThreeDSTextFieldCustomization.swift @@ -0,0 +1,94 @@ +// +// STPThreeDSTextFieldCustomization.swift +// StripePayments +// +// Created by Yuki Tokuhiro on 6/18/19. +// Copyright © 2019 Stripe, Inc. All rights reserved. +// + +import Foundation +import UIKit + +#if canImport(Stripe3DS2) + import Stripe3DS2 +#endif + +/// A customization object to use to configure the UI of a text field. +public class STPThreeDSTextFieldCustomization: NSObject { + /// The default settings. + @objc + public class func defaultSettings() -> STPThreeDSTextFieldCustomization { + return STPThreeDSTextFieldCustomization() + } + + internal var textFieldCustomization = STDSTextFieldCustomization.defaultSettings() + + /// The border width of the text field. Defaults to 2. + @objc public var borderWidth: CGFloat { + get { + return textFieldCustomization.borderWidth + } + set(borderWidth) { + textFieldCustomization.borderWidth = borderWidth + } + } + + /// The color of the border of the text field. Defaults to clear. + @objc public var borderColor: UIColor { + get { + return textFieldCustomization.borderColor + } + set(borderColor) { + textFieldCustomization.borderColor = borderColor + } + } + + /// The corner radius of the edges of the text field. Defaults to 8. + @objc public var cornerRadius: CGFloat { + get { + return textFieldCustomization.cornerRadius + } + set(cornerRadius) { + textFieldCustomization.cornerRadius = cornerRadius + } + } + /// The appearance of the keyboard. Defaults to UIKeyboardAppearanceDefault. + + @objc public var keyboardAppearance: UIKeyboardAppearance { + get { + return textFieldCustomization.keyboardAppearance + } + set(keyboardAppearance) { + textFieldCustomization.keyboardAppearance = keyboardAppearance + } + } + /// The color of the placeholder text. Defaults to light gray. + + @objc public var placeholderTextColor: UIColor { + get { + return textFieldCustomization.placeholderTextColor + } + set(placeholderTextColor) { + textFieldCustomization.placeholderTextColor = placeholderTextColor + } + } + + /// The font to use for text. + @objc public var font: UIFont? { + get { + return textFieldCustomization.font + } + set(font) { + textFieldCustomization.font = font + } + } + /// The color to use for the text. Defaults to black. + @objc public var textColor: UIColor? { + get { + return textFieldCustomization.textColor + } + set(textColor) { + textFieldCustomization.textColor = textColor + } + } +} diff --git a/Pods/StripePayments/StripePayments/StripePayments/PaymentHandler/STPThreeDSUICustomization.swift b/Pods/StripePayments/StripePayments/StripePayments/PaymentHandler/STPThreeDSUICustomization.swift new file mode 100644 index 0000000..148bcc3 --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/PaymentHandler/STPThreeDSUICustomization.swift @@ -0,0 +1,193 @@ +// +// STPThreeDSUICustomization.swift +// StripePayments +// +// Created by Yuki Tokuhiro on 6/17/19. +// Copyright © 2019 Stripe, Inc. All rights reserved. +// + +import Foundation +import UIKit + +#if canImport(Stripe3DS2) + import Stripe3DS2 +#endif + +/// The `STPThreeDSUICustomization` provides configuration for UI elements displayed during 3D Secure authentication. +/// Note: It's important to configure this object appropriately before calling any `STPPaymentHandler` APIs. +/// The API makes a copy of the customization settings you provide; it ignores any subsequent changes you +/// make to your `STPThreeDSUICustomization` instance. +/// - seealso: https://stripe.com/docs/payments/3d-secure +public class STPThreeDSUICustomization: NSObject { + /// The default settings. See individual properties for their default values. + @objc + public class func defaultSettings() -> STPThreeDSUICustomization { + return STPThreeDSUICustomization() + } + + internal var uiCustomization = STDSUICustomization.defaultSettings() + + private var _navigationBarCustomization = STPThreeDSNavigationBarCustomization.defaultSettings() + /// Provides custom settings for the UINavigationBar of all UIViewControllers displayed during 3D Secure authentication. + /// The default is `STPThreeDSNavigationBarCustomization.defaultSettings()`. + @objc public var navigationBarCustomization: STPThreeDSNavigationBarCustomization { + get { + _navigationBarCustomization + } + set(navigationBarCustomization) { + _navigationBarCustomization = navigationBarCustomization + uiCustomization.navigationBarCustomization = + navigationBarCustomization.navigationBarCustomization + } + } + + private var _labelCustomization = STPThreeDSLabelCustomization.defaultSettings() + /// Provides custom settings for labels. + /// The default is `STPThreeDSLabelCustomization.defaultSettings()`. + @objc public var labelCustomization: STPThreeDSLabelCustomization { + get { + _labelCustomization + } + set(labelCustomization) { + _labelCustomization = labelCustomization + uiCustomization.labelCustomization = labelCustomization.labelCustomization + } + } + + private var _textFieldCustomization = STPThreeDSTextFieldCustomization.defaultSettings() + /// Provides custom settings for text fields. + /// The default is `STPThreeDSTextFieldCustomization.defaultSettings()`. + @objc public var textFieldCustomization: STPThreeDSTextFieldCustomization { + get { + _textFieldCustomization + } + set(textFieldCustomization) { + _textFieldCustomization = textFieldCustomization + uiCustomization.textFieldCustomization = textFieldCustomization.textFieldCustomization + } + } + + /// The primary background color of all UIViewControllers displayed during 3D Secure authentication. + /// Defaults to white. + @objc public var backgroundColor: UIColor { + get { + return uiCustomization.backgroundColor + } + set(backgroundColor) { + uiCustomization.backgroundColor = backgroundColor + } + } + + private var _footerCustomization = STPThreeDSFooterCustomization.defaultSettings() + /// Provides custom settings for the footer the challenge view can display containing additional details. + /// The default is `STPThreeDSFooterCustomization.defaultSettings()`. + @objc public var footerCustomization: STPThreeDSFooterCustomization { + get { + _footerCustomization + } + set(footerCustomization) { + _footerCustomization = footerCustomization + uiCustomization.footerCustomization = footerCustomization.footerCustomization + } + } + + /// Sets a given button customization for the specified type. + /// - Parameters: + /// - buttonCustomization: The buttom customization to use. + /// - buttonType: The type of button to use the customization for. + @objc(setButtonCustomization:forType:) public func setButtonCustomization( + _ buttonCustomization: STPThreeDSButtonCustomization, + for buttonType: STPThreeDSCustomizationButtonType + ) { + buttonCustomizationDictionary[NSNumber(value: buttonType.rawValue)] = buttonCustomization + self.uiCustomization.setButton( + buttonCustomization.buttonCustomization, + for: STDSUICustomizationButtonType(rawValue: buttonType.rawValue)! + ) + } + + /// Retrieves a button customization object for the given button type. + /// - Parameter buttonType: The button type to retrieve a customization object for. + /// - Returns: A button customization object, or the default if none was set. + /// - seealso: STPThreeDSButtonCustomization + @objc(buttonCustomizationForButtonType:) public func buttonCustomization( + for buttonType: STPThreeDSCustomizationButtonType + ) -> STPThreeDSButtonCustomization { + return (buttonCustomizationDictionary[NSNumber(value: buttonType.rawValue)])! + } + + private var _selectionCustomization = STPThreeDSSelectionCustomization.defaultSettings() + /// Provides custom settings for radio buttons and checkboxes. + /// The default is `STPThreeDSSelectionCustomization.defaultSettings()`. + @objc public var selectionCustomization: STPThreeDSSelectionCustomization { + get { + _selectionCustomization + } + set(selectionCustomization) { + _selectionCustomization = selectionCustomization + uiCustomization.selectionCustomization = selectionCustomization.selectionCustomization + } + } + // MARK: - Progress View + + /// The style of `UIActivityIndicatorView`s displayed. + /// This should contrast with `backgroundColor`. Defaults to gray. + + @objc public var activityIndicatorViewStyle: UIActivityIndicatorView.Style { + get { + return uiCustomization.activityIndicatorViewStyle + } + set(activityIndicatorViewStyle) { + uiCustomization.activityIndicatorViewStyle = activityIndicatorViewStyle + } + } + + /// The style of the `UIBlurEffect` displayed underneath the `UIActivityIndicatorView`. + /// Defaults to `UIBlurEffectStyleLight`. + @objc public var blurStyle: UIBlurEffect.Style { + get { + return uiCustomization.blurStyle + } + set(blurStyle) { + uiCustomization.blurStyle = blurStyle + } + } + + private var buttonCustomizationDictionary: [NSNumber: STPThreeDSButtonCustomization] + + /// :nodoc: + @objc + public override init() { + // Initialize defaults for all properties + let nextButton = STPThreeDSButtonCustomization.defaultSettings(for: .next) + let cancelButton = STPThreeDSButtonCustomization.defaultSettings(for: .cancel) + let resendButton = STPThreeDSButtonCustomization.defaultSettings(for: .resend) + let submitButton = STPThreeDSButtonCustomization.defaultSettings(for: .submit) + let continueButton = STPThreeDSButtonCustomization.defaultSettings(for: .continue) + buttonCustomizationDictionary = [ + NSNumber(value: STPThreeDSCustomizationButtonType.next.rawValue): nextButton, + NSNumber(value: STPThreeDSCustomizationButtonType.cancel.rawValue): cancelButton, + NSNumber(value: STPThreeDSCustomizationButtonType.resend.rawValue): resendButton, + NSNumber(value: STPThreeDSCustomizationButtonType.submit.rawValue): submitButton, + NSNumber(value: STPThreeDSCustomizationButtonType.continue.rawValue): continueButton, + ] + + // Initialize the underlying STDS class we are wrapping + uiCustomization = STDSUICustomization() + uiCustomization.setButton(nextButton.buttonCustomization, for: .next) + uiCustomization.setButton(cancelButton.buttonCustomization, for: .cancel) + uiCustomization.setButton(resendButton.buttonCustomization, for: .resend) + uiCustomization.setButton(submitButton.buttonCustomization, for: .submit) + uiCustomization.setButton(continueButton.buttonCustomization, for: .continue) + + super.init() + + uiCustomization.footerCustomization = footerCustomization.footerCustomization + uiCustomization.labelCustomization = labelCustomization.labelCustomization + uiCustomization.navigationBarCustomization = + navigationBarCustomization.navigationBarCustomization + uiCustomization.selectionCustomization = selectionCustomization.selectionCustomization + uiCustomization.textFieldCustomization = textFieldCustomization.textFieldCustomization + + } +} diff --git a/Pods/StripePayments/StripePayments/StripePayments/Resources/Localizations/bg-BG.lproj/Localizable.strings b/Pods/StripePayments/StripePayments/StripePayments/Resources/Localizations/bg-BG.lproj/Localizable.strings new file mode 100644 index 0000000..fdbe820 --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/Resources/Localizations/bg-BG.lproj/Localizable.strings @@ -0,0 +1,57 @@ +"AU BECS Direct Debit" = "AU BECS директно дебитиране"; + +"Affirm" = "Affirm"; + +"Afterpay" = "Afterpay"; + +"Alipay" = "Alipay"; + +"BLIK" = "BLIK"; + +"Bancontact" = "Bancontact"; + +"Bank" = "Банка"; + +"Boleto" = "Boleto"; + +"Card" = "Карта"; + +"Clearpay" = "Clearpay"; + +"EPS" = "EPS"; + +"FPX" = "FPX"; + +"GrabPay" = "GrabPay"; + +"Klarna" = "Klarna"; + +"Link" = "Link"; + +"NetBanking" = "Netbanking"; + +"OXXO" = "OXXO"; + +"PayPal" = "PayPal"; + +"Przelewy24" = "Przelewy24"; + +"SEPA Debit" = "SEPA дебит"; + +"Sofort" = "Sofort"; + +"Timed out authenticating your payment method -- try again" = "Времето на изчакване на удостоверяването на Вашия метод на плащане изтече -- опитайте отново"; + +"UPI" = "UPI"; + +"US Bank Account" = "Банкова сметка в САЩ"; + +"Unknown" = "Непознат"; + +"We are unable to authenticate your payment method. Please choose a different payment method and try again." = "Не можем да удостоверим Вашия метод на плащане. Моля, изберете различен метод на плащане и опитайте отново."; + +"WeChat Pay" = "WeChat Pay"; + +"giropay" = "giropay"; + +"iDEAL" = "iDEAL"; diff --git a/Pods/StripePayments/StripePayments/StripePayments/Resources/Localizations/ca-ES.lproj/Localizable.strings b/Pods/StripePayments/StripePayments/StripePayments/Resources/Localizations/ca-ES.lproj/Localizable.strings new file mode 100644 index 0000000..26c9f8d --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/Resources/Localizations/ca-ES.lproj/Localizable.strings @@ -0,0 +1,57 @@ +"AU BECS Direct Debit" = "Domiciliació bancària AU BECS"; + +"Affirm" = "Affirm"; + +"Afterpay" = "Afterpay"; + +"Alipay" = "Alipay"; + +"BLIK" = "BLIK"; + +"Bancontact" = "Bancontact"; + +"Bank" = "Banc"; + +"Boleto" = "Boleto"; + +"Card" = "Targeta"; + +"Clearpay" = "Clearpay"; + +"EPS" = "EPS"; + +"FPX" = "FPX"; + +"GrabPay" = "GrabPay"; + +"Klarna" = "Klarna"; + +"Link" = "Link"; + +"NetBanking" = "NetBanking"; + +"OXXO" = "OXXO"; + +"PayPal" = "PayPal"; + +"Przelewy24" = "Przelewy24"; + +"SEPA Debit" = "Domiciliació SEPA"; + +"Sofort" = "Sofort"; + +"Timed out authenticating your payment method -- try again" = "S'ha esgotat el temps d'autenticació del teu mètode de pagament - intenta-ho un altre cop"; + +"UPI" = "UPI"; + +"US Bank Account" = "Compte bancari dels EUA"; + +"Unknown" = "Desconegut"; + +"We are unable to authenticate your payment method. Please choose a different payment method and try again." = "No podem autenticar el teu mètode de pagament. Si us plau, escull un mètode de pagament diferent."; + +"WeChat Pay" = "WeChat Pay"; + +"giropay" = "giropay"; + +"iDEAL" = "iDEAL"; diff --git a/Pods/StripePayments/StripePayments/StripePayments/Resources/Localizations/cs-CZ.lproj/Localizable.strings b/Pods/StripePayments/StripePayments/StripePayments/Resources/Localizations/cs-CZ.lproj/Localizable.strings new file mode 100644 index 0000000..c9c013d --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/Resources/Localizations/cs-CZ.lproj/Localizable.strings @@ -0,0 +1,57 @@ +"AU BECS Direct Debit" = "Přímé inkasa AU BECS"; + +"Affirm" = "Affirm"; + +"Afterpay" = "Afterpay"; + +"Alipay" = "Alipay"; + +"BLIK" = "BLIK"; + +"Bancontact" = "Bancontact"; + +"Bank" = "Banka"; + +"Boleto" = "Boleto"; + +"Card" = "Karta"; + +"Clearpay" = "Clearpay"; + +"EPS" = "EPS"; + +"FPX" = "FPX"; + +"GrabPay" = "GrabPay"; + +"Klarna" = "Klarna"; + +"Link" = "Link"; + +"NetBanking" = "NetBanking"; + +"OXXO" = "OXXO"; + +"PayPal" = "PayPal"; + +"Przelewy24" = "Przelewy24"; + +"SEPA Debit" = "Debet SEPA"; + +"Sofort" = "Sofort"; + +"Timed out authenticating your payment method -- try again" = "Časový limit ověření Vašeho způsobu platby uplynul -- zkuste to znovu"; + +"UPI" = "UPI"; + +"US Bank Account" = "Bankovní účet v USA"; + +"Unknown" = "Neznámé"; + +"We are unable to authenticate your payment method. Please choose a different payment method and try again." = "Nemůžeme ověřit Váš způsob platby. Vyberte si jiný způsob platby a zkuste to znovu."; + +"WeChat Pay" = "WeChat Pay"; + +"giropay" = "giropay"; + +"iDEAL" = "iDEAL"; diff --git a/Pods/StripePayments/StripePayments/StripePayments/Resources/Localizations/da.lproj/Localizable.strings b/Pods/StripePayments/StripePayments/StripePayments/Resources/Localizations/da.lproj/Localizable.strings new file mode 100644 index 0000000..dfc4a68 --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/Resources/Localizations/da.lproj/Localizable.strings @@ -0,0 +1,57 @@ +"AU BECS Direct Debit" = "AU BECS direkte debitering"; + +"Affirm" = "Affirm"; + +"Afterpay" = "Afterpay"; + +"Alipay" = "Alipay"; + +"BLIK" = "BLIK"; + +"Bancontact" = "Bancontact"; + +"Bank" = "Bank"; + +"Boleto" = "Boleto"; + +"Card" = "Kort"; + +"Clearpay" = "Clearpay"; + +"EPS" = "EPS"; + +"FPX" = "FPX"; + +"GrabPay" = "GrabPay"; + +"Klarna" = "Klarna"; + +"Link" = "Link"; + +"NetBanking" = "Onlinebanking"; + +"OXXO" = "OXXO"; + +"PayPal" = "PayPal"; + +"Przelewy24" = "Przelewy24"; + +"SEPA Debit" = "SEPA Debit"; + +"Sofort" = "Sofort"; + +"Timed out authenticating your payment method -- try again" = "Bekræftelsen af din betalingsmetode udløb -- prøv igen."; + +"UPI" = "UPI"; + +"US Bank Account" = "Bankkonto i USA"; + +"Unknown" = "Ukendt"; + +"We are unable to authenticate your payment method. Please choose a different payment method and try again." = "Vi kunne ikke bekræfte din betalingsmetode. Vælg venligst en anden betalingsmetode, og prøv igen."; + +"WeChat Pay" = "WeChat Pay"; + +"giropay" = "giropay"; + +"iDEAL" = "iDEAL"; diff --git a/Pods/StripePayments/StripePayments/StripePayments/Resources/Localizations/de.lproj/Localizable.strings b/Pods/StripePayments/StripePayments/StripePayments/Resources/Localizations/de.lproj/Localizable.strings new file mode 100644 index 0000000..b0c97e4 --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/Resources/Localizations/de.lproj/Localizable.strings @@ -0,0 +1,57 @@ +"AU BECS Direct Debit" = "AU BECS-Lastschriftverfahren"; + +"Affirm" = "Affirm"; + +"Afterpay" = "Afterpay"; + +"Alipay" = "Alipay"; + +"BLIK" = "BLIK"; + +"Bancontact" = "Bancontact"; + +"Bank" = "Bank"; + +"Boleto" = "Boleto"; + +"Card" = "Karte"; + +"Clearpay" = "Clearpay"; + +"EPS" = "EPS"; + +"FPX" = "FPX"; + +"GrabPay" = "GrabPay"; + +"Klarna" = "Klarna"; + +"Link" = "Link"; + +"NetBanking" = "NetBanking"; + +"OXXO" = "OXXO"; + +"PayPal" = "PayPal"; + +"Przelewy24" = "Przelewy24"; + +"SEPA Debit" = "SEPA-Lastschrift"; + +"Sofort" = "Sofort"; + +"Timed out authenticating your payment method -- try again" = "Zeitüberschreitung bei der Authentifizierung Ihrer Zahlungsmethode – versuchen Sie es noch einmal."; + +"UPI" = "UPI"; + +"US Bank Account" = "US-Bankkonto"; + +"Unknown" = "Unbekannt"; + +"We are unable to authenticate your payment method. Please choose a different payment method and try again." = "Wir können Ihre Zahlungsmethode nicht authentifizieren. Bitte wählen Sie eine andere Zahlungsmethode und versuchen Sie es noch einmal."; + +"WeChat Pay" = "WeChat Pay"; + +"giropay" = "Giropay"; + +"iDEAL" = "iDEAL"; diff --git a/Pods/StripePayments/StripePayments/StripePayments/Resources/Localizations/el-GR.lproj/Localizable.strings b/Pods/StripePayments/StripePayments/StripePayments/Resources/Localizations/el-GR.lproj/Localizable.strings new file mode 100644 index 0000000..55f9f40 --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/Resources/Localizations/el-GR.lproj/Localizable.strings @@ -0,0 +1,57 @@ +"AU BECS Direct Debit" = "Άμεση χρέωση AU BECS"; + +"Affirm" = "Affirm"; + +"Afterpay" = "Afterpay"; + +"Alipay" = "Alipay"; + +"BLIK" = "BLIK"; + +"Bancontact" = "Bancontact"; + +"Bank" = "Τράπεζα"; + +"Boleto" = "Boleto"; + +"Card" = "Κάρτα"; + +"Clearpay" = "Clearpay"; + +"EPS" = "EPS"; + +"FPX" = "FPX"; + +"GrabPay" = "GrabPay"; + +"Klarna" = "Klarna"; + +"Link" = "Link"; + +"NetBanking" = "NetBanking"; + +"OXXO" = "OXXO"; + +"PayPal" = "PayPal"; + +"Przelewy24" = "Przelewy24"; + +"SEPA Debit" = "Χρέωση SEPA"; + +"Sofort" = "Sofort"; + +"Timed out authenticating your payment method -- try again" = "Έληξε το χρονικό όριο επαλήθευσης της μεθόδου πληρωμής σας -- δοκιμάστε ξανά"; + +"UPI" = "UPI"; + +"US Bank Account" = "Τραπεζικός λογαριασμός στις Η.Π.Α."; + +"Unknown" = "Άγνωστο"; + +"We are unable to authenticate your payment method. Please choose a different payment method and try again." = "Δεν μπορούμε να επαληθεύσουμε τη μέθοδο πληρωμής σας. Επιλέξτε διαφορετική μέθοδο πληρωμής και προσπαθήστε ξανά."; + +"WeChat Pay" = "WeChat Pay"; + +"giropay" = "giropay"; + +"iDEAL" = "iDEAL"; diff --git a/Pods/StripePayments/StripePayments/StripePayments/Resources/Localizations/en-GB.lproj/Localizable.strings b/Pods/StripePayments/StripePayments/StripePayments/Resources/Localizations/en-GB.lproj/Localizable.strings new file mode 100644 index 0000000..f92b0ea --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/Resources/Localizations/en-GB.lproj/Localizable.strings @@ -0,0 +1,57 @@ +"AU BECS Direct Debit" = "AU BECS Direct Debit"; + +"Affirm" = "Affirm"; + +"Afterpay" = "Afterpay"; + +"Alipay" = "Alipay"; + +"BLIK" = "BLIK"; + +"Bancontact" = "Bancontact"; + +"Bank" = "Bank"; + +"Boleto" = "Boleto"; + +"Card" = "Card"; + +"Clearpay" = "Clearpay"; + +"EPS" = "EPS"; + +"FPX" = "FPX"; + +"GrabPay" = "GrabPay"; + +"Klarna" = "Klarna"; + +"Link" = "Link"; + +"NetBanking" = "NetBanking"; + +"OXXO" = "OXXO"; + +"PayPal" = "PayPal"; + +"Przelewy24" = "Przelewy24"; + +"SEPA Debit" = "SEPA Debit"; + +"Sofort" = "Sofort"; + +"Timed out authenticating your payment method -- try again" = "Timed out authenticating your payment method - please try again"; + +"UPI" = "UPI"; + +"US Bank Account" = "US Bank Account"; + +"Unknown" = "Unknown"; + +"We are unable to authenticate your payment method. Please choose a different payment method and try again." = "We are unable to authenticate your payment method. Please choose a different payment method and try again."; + +"WeChat Pay" = "WeChat Pay"; + +"giropay" = "giropay"; + +"iDEAL" = "iDEAL"; diff --git a/Pods/StripePayments/StripePayments/StripePayments/Resources/Localizations/en.lproj/Localizable.strings b/Pods/StripePayments/StripePayments/StripePayments/Resources/Localizations/en.lproj/Localizable.strings new file mode 100644 index 0000000..4a02f62 --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/Resources/Localizations/en.lproj/Localizable.strings @@ -0,0 +1,87 @@ +/* Payment Method type brand name */ +"Affirm" = "Affirm"; + +/* Payment Method type brand name */ +"Afterpay" = "Afterpay"; + +/* Payment Method type brand name */ +"Alipay" = "Alipay"; + +/* Payment Method type brand name. */ +"AU BECS Direct Debit" = "AU BECS Direct Debit"; + +/* Payment Method type brand name */ +"Bancontact" = "Bancontact"; + +/* Link Instant Debit payment method display name */ +"Bank" = "Bank"; + +/* Payment Method type brand name */ +"BLIK" = "BLIK"; + +/* Payment Method type brand name */ +"Boleto" = "Boleto"; + +/* Payment Method for credit card */ +"Card" = "Card"; + +/* Payment Method type brand name */ +"Clearpay" = "Clearpay"; + +/* Payment Method type brand name. */ +"EPS" = "EPS"; + +/* Payment Method type brand name */ +"FPX" = "FPX"; + +/* Payment Method type brand name. */ +"giropay" = "giropay"; + +/* Payment Method type brand name. */ +"GrabPay" = "GrabPay"; + +/* Source type brand name */ +"iDEAL" = "iDEAL"; + +/* Payment Method type brand name */ +"Klarna" = "Klarna"; + +/* Link Payment Method type brand name */ +"Link" = "Link"; + +/* Payment Method type brand name */ +"NetBanking" = "NetBanking"; + +/* Payment Method type brand name */ +"OXXO" = "OXXO"; + +/* Payment Method type brand name */ +"PayPal" = "PayPal"; + +/* Payment Method type brand name. */ +"Przelewy24" = "Przelewy24"; + +/* Payment method brand name */ +"SEPA Debit" = "SEPA Debit"; + +/* Payment Method type brand name */ +"Sofort" = "Sofort"; + +/* Error when 3DS2 authentication timed out. */ +"Timed out authenticating your payment method -- try again" = "Timed out authenticating your payment method -- try again"; + +/* Default missing source type label */ +"Unknown" = "Unknown"; + +/* Payment Method type brand name */ +"UPI" = "UPI"; + +/* Payment Method type name for US Bank Account payments. */ +"US Bank Account" = "US Bank Account"; + +/* Error when 3DS2 authentication failed (e.g. customer entered the wrong code) */ +"We are unable to authenticate your payment method. Please choose a different payment method and try again." = "We are unable to authenticate your payment method. Please choose a different payment method and try again."; + +/* Payment Method type brand name */ +"WeChat Pay" = "WeChat Pay"; + diff --git a/Pods/StripePayments/StripePayments/StripePayments/Resources/Localizations/es-419.lproj/Localizable.strings b/Pods/StripePayments/StripePayments/StripePayments/Resources/Localizations/es-419.lproj/Localizable.strings new file mode 100644 index 0000000..d641538 --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/Resources/Localizations/es-419.lproj/Localizable.strings @@ -0,0 +1,57 @@ +"AU BECS Direct Debit" = "Débito directo BECS (Australia)"; + +"Affirm" = "Affirm"; + +"Afterpay" = "Afterpay"; + +"Alipay" = "Alipay"; + +"BLIK" = "BLIK"; + +"Bancontact" = "Bancontact"; + +"Bank" = "Banco"; + +"Boleto" = "Boleto"; + +"Card" = "Tarjeta"; + +"Clearpay" = "Clearpay"; + +"EPS" = "EPS"; + +"FPX" = "FPX"; + +"GrabPay" = "GrabPay"; + +"Klarna" = "Klarna"; + +"Link" = "Link"; + +"NetBanking" = "NetBanking"; + +"OXXO" = "OXXO"; + +"PayPal" = "PayPal"; + +"Przelewy24" = "Przelewy24"; + +"SEPA Debit" = "Débito SEPA"; + +"Sofort" = "Sofort"; + +"Timed out authenticating your payment method -- try again" = "Se agotó el tiempo para autenticar el método de pago. Vuelve a intentarlo."; + +"UPI" = "UPI"; + +"US Bank Account" = "Cuenta bancaria de EE. UU."; + +"Unknown" = "Desconocido"; + +"We are unable to authenticate your payment method. Please choose a different payment method and try again." = "No pudimos autenticar tu método de pago. Elige otro método y vuelve a intentarlo."; + +"WeChat Pay" = "WeChat Pay"; + +"giropay" = "giropay"; + +"iDEAL" = "iDEAL"; diff --git a/Pods/StripePayments/StripePayments/StripePayments/Resources/Localizations/es.lproj/Localizable.strings b/Pods/StripePayments/StripePayments/StripePayments/Resources/Localizations/es.lproj/Localizable.strings new file mode 100644 index 0000000..8c6293e --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/Resources/Localizations/es.lproj/Localizable.strings @@ -0,0 +1,57 @@ +"AU BECS Direct Debit" = "Adeudo directo BECS (Australia)"; + +"Affirm" = "Affirm"; + +"Afterpay" = "Afterpay"; + +"Alipay" = "Alipay"; + +"BLIK" = "BLIK"; + +"Bancontact" = "Bancontact"; + +"Bank" = "Banco"; + +"Boleto" = "Boleto"; + +"Card" = "Tarjeta"; + +"Clearpay" = "Clearpay"; + +"EPS" = "EPS"; + +"FPX" = "FPX"; + +"GrabPay" = "GrabPay"; + +"Klarna" = "Klarna"; + +"Link" = "Link"; + +"NetBanking" = "NetBanking"; + +"OXXO" = "OXXO"; + +"PayPal" = "PayPal"; + +"Przelewy24" = "Przelewy24"; + +"SEPA Debit" = "Adeudo SEPA"; + +"Sofort" = "Sofort"; + +"Timed out authenticating your payment method -- try again" = "Se agotó el tiempo de espera para autenticar el método de pago. Vuelve a intentarlo."; + +"UPI" = "UPI"; + +"US Bank Account" = "Cuenta bancaria de EE. UU."; + +"Unknown" = "Desconocido"; + +"We are unable to authenticate your payment method. Please choose a different payment method and try again." = "No pudimos autenticar el método de pago. Elige otro método y vuelve a intentarlo."; + +"WeChat Pay" = "WeChat Pay"; + +"giropay" = "giropay"; + +"iDEAL" = "iDEAL"; diff --git a/Pods/StripePayments/StripePayments/StripePayments/Resources/Localizations/et-EE.lproj/Localizable.strings b/Pods/StripePayments/StripePayments/StripePayments/Resources/Localizations/et-EE.lproj/Localizable.strings new file mode 100644 index 0000000..84dfaf3 --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/Resources/Localizations/et-EE.lproj/Localizable.strings @@ -0,0 +1,57 @@ +"AU BECS Direct Debit" = "AU BECS-i otsekorraldus"; + +"Affirm" = "Affirm"; + +"Afterpay" = "Afterpay"; + +"Alipay" = "Alipay"; + +"BLIK" = "BLIK"; + +"Bancontact" = "Bancontact"; + +"Bank" = "Pank"; + +"Boleto" = "Boleto"; + +"Card" = "Kaart"; + +"Clearpay" = "Clearpay"; + +"EPS" = "EPS"; + +"FPX" = "FPX"; + +"GrabPay" = "GrabPay"; + +"Klarna" = "Klarna"; + +"Link" = "Link"; + +"NetBanking" = "NetBanking"; + +"OXXO" = "OXXO"; + +"PayPal" = "PayPal"; + +"Przelewy24" = "Przelewy24"; + +"SEPA Debit" = "SEPA deebet"; + +"Sofort" = "Sofort"; + +"Timed out authenticating your payment method -- try again" = "Makseviisi autentimise toiming aegus – proovige uuesti"; + +"UPI" = "UPI"; + +"US Bank Account" = "USA pangakonto"; + +"Unknown" = "Tundmatu"; + +"We are unable to authenticate your payment method. Please choose a different payment method and try again." = "Makseviisi ei õnnestunud autentida. Palun valige muu makseviis ja proovige uuesti."; + +"WeChat Pay" = "WeChat Pay"; + +"giropay" = "Giropay"; + +"iDEAL" = "iDEAL"; diff --git a/Pods/StripePayments/StripePayments/StripePayments/Resources/Localizations/fi.lproj/Localizable.strings b/Pods/StripePayments/StripePayments/StripePayments/Resources/Localizations/fi.lproj/Localizable.strings new file mode 100644 index 0000000..2fc32af --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/Resources/Localizations/fi.lproj/Localizable.strings @@ -0,0 +1,57 @@ +"AU BECS Direct Debit" = "AU BECS -suoraveloitus"; + +"Affirm" = "Affirm"; + +"Afterpay" = "Afterpay"; + +"Alipay" = "Alipay"; + +"BLIK" = "BLIK"; + +"Bancontact" = "Bancontact"; + +"Bank" = "Pankki"; + +"Boleto" = "Boleto"; + +"Card" = "Kortti"; + +"Clearpay" = "Clearpay"; + +"EPS" = "EPS"; + +"FPX" = "FPX"; + +"GrabPay" = "GrabPay"; + +"Klarna" = "Klarna"; + +"Link" = "Linkki"; + +"NetBanking" = "NetBanking"; + +"OXXO" = "OXXO"; + +"PayPal" = "PayPal"; + +"Przelewy24" = "Przelewy24"; + +"SEPA Debit" = "SEPA Debit"; + +"Sofort" = "Sofort"; + +"Timed out authenticating your payment method -- try again" = "Maksutapasi todennus aikakatkaistiin – yritä uudelleen."; + +"UPI" = "UPI"; + +"US Bank Account" = "Yhdysvaltalainen pankkitili"; + +"Unknown" = "Tuntematon"; + +"We are unable to authenticate your payment method. Please choose a different payment method and try again." = "Emme pystyneet todentamaan maksutapaasi. Valitse toinen maksutapa ja yritä uudelleen."; + +"WeChat Pay" = "WeChat Pay"; + +"giropay" = "giropay"; + +"iDEAL" = "iDEAL"; diff --git a/Pods/StripePayments/StripePayments/StripePayments/Resources/Localizations/fil.lproj/Localizable.strings b/Pods/StripePayments/StripePayments/StripePayments/Resources/Localizations/fil.lproj/Localizable.strings new file mode 100644 index 0000000..fdf031d --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/Resources/Localizations/fil.lproj/Localizable.strings @@ -0,0 +1,57 @@ +"AU BECS Direct Debit" = "AU BECS Direct Debit"; + +"Affirm" = "Affirm"; + +"Afterpay" = "Afterpay"; + +"Alipay" = "Alipay"; + +"BLIK" = "BLIK"; + +"Bancontact" = "Bancontact"; + +"Bank" = "Bangko"; + +"Boleto" = "Boleto"; + +"Card" = "Kard"; + +"Clearpay" = "Clearpay"; + +"EPS" = "EPS"; + +"FPX" = "FPX"; + +"GrabPay" = "GrabPay"; + +"Klarna" = "Klarna"; + +"Link" = "Link"; + +"NetBanking" = "NetBanking"; + +"OXXO" = "OXXO"; + +"PayPal" = "PayPal"; + +"Przelewy24" = "Przelewy24"; + +"SEPA Debit" = "SEPA Debit"; + +"Sofort" = "Sofort"; + +"Timed out authenticating your payment method -- try again" = "Nag- time out sa pagpapatunay ng iyong paraan ng pagbabayad --- subukin muli"; + +"UPI" = "UPI"; + +"US Bank Account" = "Account sa Bangko sa US"; + +"Unknown" = "Di kilala"; + +"We are unable to authenticate your payment method. Please choose a different payment method and try again." = "Hindi namin mapatunayan ang paraan ng iyong pagbabayad. Mangyaring pumili ng ibang paraan ng pagbabayad at subukin muli."; + +"WeChat Pay" = "WeChat Pay"; + +"giropay" = "giropay"; + +"iDEAL" = "iDEAL"; diff --git a/Pods/StripePayments/StripePayments/StripePayments/Resources/Localizations/fr-CA.lproj/Localizable.strings b/Pods/StripePayments/StripePayments/StripePayments/Resources/Localizations/fr-CA.lproj/Localizable.strings new file mode 100644 index 0000000..4ad3484 --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/Resources/Localizations/fr-CA.lproj/Localizable.strings @@ -0,0 +1,57 @@ +"AU BECS Direct Debit" = "Prélèvement automatique BECS (Australie)"; + +"Affirm" = "Affirm"; + +"Afterpay" = "Afterpay"; + +"Alipay" = "Alipay"; + +"BLIK" = "BLIK"; + +"Bancontact" = "Bancontact"; + +"Bank" = "Institution financière"; + +"Boleto" = "Boleto"; + +"Card" = "Carte"; + +"Clearpay" = "Clearpay"; + +"EPS" = "EPS"; + +"FPX" = "FPX"; + +"GrabPay" = "GrabPay"; + +"Klarna" = "Klarna"; + +"Link" = "Link"; + +"NetBanking" = "Netbanking"; + +"OXXO" = "OXXO"; + +"PayPal" = "PayPal"; + +"Przelewy24" = "Przelewy24"; + +"SEPA Debit" = "Prélèvement SEPA"; + +"Sofort" = "Sofort"; + +"Timed out authenticating your payment method -- try again" = "Le délai d'authentification de votre moyen de paiement est dépassé, veuillez réessayer."; + +"UPI" = "UPI"; + +"US Bank Account" = "Compte bancaire aux États-Unis"; + +"Unknown" = "Inconnu"; + +"We are unable to authenticate your payment method. Please choose a different payment method and try again." = "Nous ne sommes pas en mesure d'identifier votre moyen de paiement. Veuillez sélectionner un autre moyen de paiement et réessayer."; + +"WeChat Pay" = "WeChat Pay"; + +"giropay" = "Giropay"; + +"iDEAL" = "iDEAL"; diff --git a/Pods/StripePayments/StripePayments/StripePayments/Resources/Localizations/fr.lproj/Localizable.strings b/Pods/StripePayments/StripePayments/StripePayments/Resources/Localizations/fr.lproj/Localizable.strings new file mode 100644 index 0000000..4eb0dec --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/Resources/Localizations/fr.lproj/Localizable.strings @@ -0,0 +1,57 @@ +"AU BECS Direct Debit" = "Prélèvement automatique BECS (Australie)"; + +"Affirm" = "Affirm"; + +"Afterpay" = "Afterpay"; + +"Alipay" = "Alipay"; + +"BLIK" = "BLIK"; + +"Bancontact" = "Bancontact"; + +"Bank" = "Bancaire"; + +"Boleto" = "Boleto"; + +"Card" = "Carte"; + +"Clearpay" = "Clearpay"; + +"EPS" = "EPS"; + +"FPX" = "FPX"; + +"GrabPay" = "GrabPay"; + +"Klarna" = "Klarna"; + +"Link" = "Link"; + +"NetBanking" = "Netbanking"; + +"OXXO" = "OXXO"; + +"PayPal" = "PayPal"; + +"Przelewy24" = "Przelewy24"; + +"SEPA Debit" = "Prélèvement SEPA"; + +"Sofort" = "Sofort"; + +"Timed out authenticating your payment method -- try again" = "La tentative d'identification de votre moyen de paiement a été interrompue, veuillez réessayer."; + +"UPI" = "UPI"; + +"US Bank Account" = "Compte bancaire aux États-Unis"; + +"Unknown" = "Inconnu"; + +"We are unable to authenticate your payment method. Please choose a different payment method and try again." = "Nous ne sommes pas en mesure d'identifier votre moyen de paiement. Veuillez sélectionner un autre moyen de paiement et réessayer."; + +"WeChat Pay" = "WeChat Pay"; + +"giropay" = "Giropay"; + +"iDEAL" = "iDEAL"; diff --git a/Pods/StripePayments/StripePayments/StripePayments/Resources/Localizations/hr.lproj/Localizable.strings b/Pods/StripePayments/StripePayments/StripePayments/Resources/Localizations/hr.lproj/Localizable.strings new file mode 100644 index 0000000..d2d93ba --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/Resources/Localizations/hr.lproj/Localizable.strings @@ -0,0 +1,57 @@ +"AU BECS Direct Debit" = "AU BECS Izravno terećenje"; + +"Affirm" = "Affirm"; + +"Afterpay" = "Afterpay"; + +"Alipay" = "Alipay"; + +"BLIK" = "BLIK"; + +"Bancontact" = "Bancontact"; + +"Bank" = "Banka"; + +"Boleto" = "Boleto"; + +"Card" = "Kartica"; + +"Clearpay" = "Clearpay"; + +"EPS" = "EPS"; + +"FPX" = "FPX"; + +"GrabPay" = "GrabPay"; + +"Klarna" = "Klarna"; + +"Link" = "Link"; + +"NetBanking" = "NetBanking"; + +"OXXO" = "OXXO"; + +"PayPal" = "PayPal"; + +"Przelewy24" = "Przelewy24"; + +"SEPA Debit" = "SEPA Debit"; + +"Sofort" = "Sofort"; + +"Timed out authenticating your payment method -- try again" = "Istek vremena pri provjeri načina plaćanja -- pokušajte ponovno"; + +"UPI" = "UPI"; + +"US Bank Account" = "Američki bankovni račun"; + +"Unknown" = "Nepoznato"; + +"We are unable to authenticate your payment method. Please choose a different payment method and try again." = "Nismo mogli potvrditi vaš način plaćanja. Odaberite drugi način plaćanja i pokušajte ponovno."; + +"WeChat Pay" = "WeChat Pay"; + +"giropay" = "giropay"; + +"iDEAL" = "iDEAL"; diff --git a/Pods/StripePayments/StripePayments/StripePayments/Resources/Localizations/hu.lproj/Localizable.strings b/Pods/StripePayments/StripePayments/StripePayments/Resources/Localizations/hu.lproj/Localizable.strings new file mode 100644 index 0000000..8263ec1 --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/Resources/Localizations/hu.lproj/Localizable.strings @@ -0,0 +1,57 @@ +"AU BECS Direct Debit" = "AU BECS-beszedés"; + +"Affirm" = "Affirm"; + +"Afterpay" = "Afterpay"; + +"Alipay" = "Alipay"; + +"BLIK" = "BLIK"; + +"Bancontact" = "Bancontact"; + +"Bank" = "Bank"; + +"Boleto" = "Boleto"; + +"Card" = "Kártya"; + +"Clearpay" = "Clearpay"; + +"EPS" = "EPS"; + +"FPX" = "FPX"; + +"GrabPay" = "GrabPay"; + +"Klarna" = "Klarna"; + +"Link" = "Link"; + +"NetBanking" = "NetBanking"; + +"OXXO" = "OXXO"; + +"PayPal" = "PayPal"; + +"Przelewy24" = "Przelewy24"; + +"SEPA Debit" = "SEPA beszedés"; + +"Sofort" = "Sofort"; + +"Timed out authenticating your payment method -- try again" = "Fizetési módjának hitelesítésénél időtúllépés történt, próbálja újra."; + +"UPI" = "UPI"; + +"US Bank Account" = "USA bankszámla"; + +"Unknown" = "Ismeretlen"; + +"We are unable to authenticate your payment method. Please choose a different payment method and try again." = "Nem tudjuk hitelesíteni a fizetési módját. Kérjük, válasszon másik fizetési módot, és próbálkozzon újból."; + +"WeChat Pay" = "WeChat Pay"; + +"giropay" = "giropay"; + +"iDEAL" = "iDEAL"; diff --git a/Pods/StripePayments/StripePayments/StripePayments/Resources/Localizations/id.lproj/Localizable.strings b/Pods/StripePayments/StripePayments/StripePayments/Resources/Localizations/id.lproj/Localizable.strings new file mode 100644 index 0000000..78a7473 --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/Resources/Localizations/id.lproj/Localizable.strings @@ -0,0 +1,57 @@ +"AU BECS Direct Debit" = "Debit Langsung BECS AU"; + +"Affirm" = "Affirm"; + +"Afterpay" = "Afterpay"; + +"Alipay" = "Alipay"; + +"BLIK" = "BLIK"; + +"Bancontact" = "Bancontact"; + +"Bank" = "Bank"; + +"Boleto" = "Boleto"; + +"Card" = "Kartu"; + +"Clearpay" = "Clearpay"; + +"EPS" = "EPS"; + +"FPX" = "FPX"; + +"GrabPay" = "GrabPay"; + +"Klarna" = "Klarna"; + +"Link" = "Link"; + +"NetBanking" = "Internet Banking"; + +"OXXO" = "OXXO"; + +"PayPal" = "PayPal"; + +"Przelewy24" = "Przelewy24"; + +"SEPA Debit" = "SEPA Debit"; + +"Sofort" = "Sofort"; + +"Timed out authenticating your payment method -- try again" = "Waktu autentikasi metode pembayaran Anda habis -- coba lagi"; + +"UPI" = "UPI"; + +"US Bank Account" = "Rekening Bank AS"; + +"Unknown" = "Tak dikenal"; + +"We are unable to authenticate your payment method. Please choose a different payment method and try again." = "Kami tidak dapat mengautentikasi metode pembayaran Anda. Pilih metode pembayaran yang berbeda dan coba lagi."; + +"WeChat Pay" = "WeChat Pay"; + +"giropay" = "giropay"; + +"iDEAL" = "iDEAL"; diff --git a/Pods/StripePayments/StripePayments/StripePayments/Resources/Localizations/it.lproj/Localizable.strings b/Pods/StripePayments/StripePayments/StripePayments/Resources/Localizations/it.lproj/Localizable.strings new file mode 100644 index 0000000..ed98314 --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/Resources/Localizations/it.lproj/Localizable.strings @@ -0,0 +1,57 @@ +"AU BECS Direct Debit" = "Addebito diretto AU BECS"; + +"Affirm" = "Affirm"; + +"Afterpay" = "Afterpay"; + +"Alipay" = "Alipay"; + +"BLIK" = "BLIK"; + +"Bancontact" = "Bancontact"; + +"Bank" = "Banca"; + +"Boleto" = "Boleto"; + +"Card" = "Carta"; + +"Clearpay" = "Clearpay"; + +"EPS" = "EPS"; + +"FPX" = "FPX"; + +"GrabPay" = "GrabPay"; + +"Klarna" = "Klarna"; + +"Link" = "Link"; + +"NetBanking" = "Banca online"; + +"OXXO" = "OXXO"; + +"PayPal" = "PayPal"; + +"Przelewy24" = "Przelewy24"; + +"SEPA Debit" = "Addebito SEPA"; + +"Sofort" = "Sofort"; + +"Timed out authenticating your payment method -- try again" = "Timeout durante l'autenticazione della modalità di pagamento. Riprova."; + +"UPI" = "UPI"; + +"US Bank Account" = "Conto bancario Stati Uniti"; + +"Unknown" = "Sconosciuto"; + +"We are unable to authenticate your payment method. Please choose a different payment method and try again." = "Impossibile autenticare la modalità di pagamento. Scegline un'altra e riprova."; + +"WeChat Pay" = "WeChat Pay"; + +"giropay" = "giropay"; + +"iDEAL" = "iDEAL"; diff --git a/Pods/StripePayments/StripePayments/StripePayments/Resources/Localizations/ja.lproj/Localizable.strings b/Pods/StripePayments/StripePayments/StripePayments/Resources/Localizations/ja.lproj/Localizable.strings new file mode 100644 index 0000000..8b78981 --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/Resources/Localizations/ja.lproj/Localizable.strings @@ -0,0 +1,57 @@ +"AU BECS Direct Debit" = "BECS ダイレクトデビット (オーストラリア)"; + +"Affirm" = "Affirm"; + +"Afterpay" = "Afterpay"; + +"Alipay" = "Alipay"; + +"BLIK" = "BLIK"; + +"Bancontact" = "Bancontact"; + +"Bank" = "銀行"; + +"Boleto" = "Boleto"; + +"Card" = "クレジットカード番号"; + +"Clearpay" = "Clearpay"; + +"EPS" = "EPS"; + +"FPX" = "FPX"; + +"GrabPay" = "GrabPay"; + +"Klarna" = "Klarna"; + +"Link" = "Link"; + +"NetBanking" = "ネットバンキング"; + +"OXXO" = "OXXO"; + +"PayPal" = "PayPal"; + +"Przelewy24" = "Przelewy24"; + +"SEPA Debit" = "SEPA デビット"; + +"Sofort" = "Sofort"; + +"Timed out authenticating your payment method -- try again" = "支払い方法の認証がタイムアウトしました。もう一度お試しください"; + +"UPI" = "UPI"; + +"US Bank Account" = "アメリカの銀行口座"; + +"Unknown" = "不明"; + +"We are unable to authenticate your payment method. Please choose a different payment method and try again." = "お客様の支払い方法を認証できませんでした。別の支払い方法を選択してもう一度お試しください。"; + +"WeChat Pay" = "WeChat Pay"; + +"giropay" = "giropay"; + +"iDEAL" = "iDEAL"; diff --git a/Pods/StripePayments/StripePayments/StripePayments/Resources/Localizations/ko.lproj/Localizable.strings b/Pods/StripePayments/StripePayments/StripePayments/Resources/Localizations/ko.lproj/Localizable.strings new file mode 100644 index 0000000..c5a238b --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/Resources/Localizations/ko.lproj/Localizable.strings @@ -0,0 +1,57 @@ +"AU BECS Direct Debit" = "AU BECS 자동 이체"; + +"Affirm" = "Affirm"; + +"Afterpay" = "Afterpay"; + +"Alipay" = "Alipay"; + +"BLIK" = "BLIK"; + +"Bancontact" = "Bancontact"; + +"Bank" = "은행"; + +"Boleto" = "Boleto"; + +"Card" = "카드"; + +"Clearpay" = "Clearpay"; + +"EPS" = "EPS"; + +"FPX" = "FPX"; + +"GrabPay" = "GrabPay"; + +"Klarna" = "Klarna"; + +"Link" = "Link"; + +"NetBanking" = "NetBanking"; + +"OXXO" = "OXXO"; + +"PayPal" = "PayPal"; + +"Przelewy24" = "Przelewy24"; + +"SEPA Debit" = "SEPA Debit"; + +"Sofort" = "Sofort"; + +"Timed out authenticating your payment method -- try again" = "결제 수단 인증 시간이 초과되었습니다. 다시 시도하십시오."; + +"UPI" = "UPI"; + +"US Bank Account" = "미국 은행 계좌"; + +"Unknown" = "알 수 없음"; + +"We are unable to authenticate your payment method. Please choose a different payment method and try again." = "결제 수단을 인증할 수 없습니다. 다른 결제 수단을 선택하고 다시 시도하십시오."; + +"WeChat Pay" = "WeChat Pay"; + +"giropay" = "giropay"; + +"iDEAL" = "iDEAL"; diff --git a/Pods/StripePayments/StripePayments/StripePayments/Resources/Localizations/lt-LT.lproj/Localizable.strings b/Pods/StripePayments/StripePayments/StripePayments/Resources/Localizations/lt-LT.lproj/Localizable.strings new file mode 100644 index 0000000..dcd548e --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/Resources/Localizations/lt-LT.lproj/Localizable.strings @@ -0,0 +1,57 @@ +"AU BECS Direct Debit" = "AU BECS tiesioginis debetas"; + +"Affirm" = "Affirm"; + +"Afterpay" = "Afterpay"; + +"Alipay" = "„Alipay“"; + +"BLIK" = "BLIK"; + +"Bancontact" = "„Bancontact“"; + +"Bank" = "Bankas"; + +"Boleto" = "Boleto"; + +"Card" = "Kortelė"; + +"Clearpay" = "Clearpay"; + +"EPS" = "EPS"; + +"FPX" = "FPX"; + +"GrabPay" = "GrabPay"; + +"Klarna" = "Klarna"; + +"Link" = "\"Link\""; + +"NetBanking" = "NetBanking"; + +"OXXO" = "OXXO"; + +"PayPal" = "PayPal"; + +"Przelewy24" = "Przelewy24"; + +"SEPA Debit" = "SEPA debetas"; + +"Sofort" = "Sofort"; + +"Timed out authenticating your payment method -- try again" = "Baigėsi mokėjimo būdui autentifikuoti skirtas laikas, bandykite dar kartą"; + +"UPI" = "UPI"; + +"US Bank Account" = "JAV banko sąskaita"; + +"Unknown" = "Nežinoma"; + +"We are unable to authenticate your payment method. Please choose a different payment method and try again." = "Nepavyko autentifikuoti mokėjimo būdo. Pasirinkite kitą mokėjimo būdą ir bandykite dar kartą."; + +"WeChat Pay" = "„WeChat“ mokėjimas"; + +"giropay" = "giropay"; + +"iDEAL" = "iDEAL"; diff --git a/Pods/StripePayments/StripePayments/StripePayments/Resources/Localizations/lv-LV.lproj/Localizable.strings b/Pods/StripePayments/StripePayments/StripePayments/Resources/Localizations/lv-LV.lproj/Localizable.strings new file mode 100644 index 0000000..acb1a77 --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/Resources/Localizations/lv-LV.lproj/Localizable.strings @@ -0,0 +1,57 @@ +"AU BECS Direct Debit" = "AU BECS tiešais debets"; + +"Affirm" = "Affirm"; + +"Afterpay" = "Afterpay"; + +"Alipay" = "Alipay"; + +"BLIK" = "BLIK"; + +"Bancontact" = "Bancontact"; + +"Bank" = "Banka"; + +"Boleto" = "Boleto"; + +"Card" = "Karte"; + +"Clearpay" = "Clearpay"; + +"EPS" = "EPS"; + +"FPX" = "FPX"; + +"GrabPay" = "GrabPay"; + +"Klarna" = "Klarna"; + +"Link" = "Link"; + +"NetBanking" = "Tiešsaistes banku pakalpojumi"; + +"OXXO" = "OXXO"; + +"PayPal" = "PayPal"; + +"Przelewy24" = "Przelewy24"; + +"SEPA Debit" = "SEPA debets"; + +"Sofort" = "Sofort"; + +"Timed out authenticating your payment method -- try again" = "Autentificējot jūsu maksājuma metodi, iestājās noildze — mēģiniet vēlreiz"; + +"UPI" = "UPI"; + +"US Bank Account" = "ASV bankas konts"; + +"Unknown" = "Nav zināms"; + +"We are unable to authenticate your payment method. Please choose a different payment method and try again." = "Nevaram autentificēt jūsu maksājuma metodi. Lūdzu, izvēlieties citu maksājuma metodi un mēģiniet vēlreiz."; + +"WeChat Pay" = "WeChat Pay"; + +"giropay" = "giropay"; + +"iDEAL" = "iDEAL"; diff --git a/Pods/StripePayments/StripePayments/StripePayments/Resources/Localizations/ms-MY.lproj/Localizable.strings b/Pods/StripePayments/StripePayments/StripePayments/Resources/Localizations/ms-MY.lproj/Localizable.strings new file mode 100644 index 0000000..d33d222 --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/Resources/Localizations/ms-MY.lproj/Localizable.strings @@ -0,0 +1,57 @@ +"AU BECS Direct Debit" = "Debit Terus BECS AU"; + +"Affirm" = "Affirm"; + +"Afterpay" = "Afterpay"; + +"Alipay" = "Alipay"; + +"BLIK" = "BLIK"; + +"Bancontact" = "Bancontact"; + +"Bank" = "Bank"; + +"Boleto" = "Boleto"; + +"Card" = "Kad"; + +"Clearpay" = "Clearpay"; + +"EPS" = "EPS"; + +"FPX" = "FPX"; + +"GrabPay" = "GrabPay"; + +"Klarna" = "Klarna"; + +"Link" = "Link"; + +"NetBanking" = "NetBanking"; + +"OXXO" = "OXXO"; + +"PayPal" = "PayPal"; + +"Przelewy24" = "Przelewy24"; + +"SEPA Debit" = "Debit SEPA"; + +"Sofort" = "Sofort"; + +"Timed out authenticating your payment method -- try again" = "Masa tamat ketika mensahihkan kaedah pembayaran anda -- cuba lagi"; + +"UPI" = "UPI"; + +"US Bank Account" = "Akaun Bank AS"; + +"Unknown" = "Tidak diketahui"; + +"We are unable to authenticate your payment method. Please choose a different payment method and try again." = "Kami tidak dapat mensahihkan kaedah pembayaran anda. Sila pilih kaedah pembayaran yang berbeza dan cuba lagi."; + +"WeChat Pay" = "WeChat Pay"; + +"giropay" = "giropay"; + +"iDEAL" = "iDEAL"; diff --git a/Pods/StripePayments/StripePayments/StripePayments/Resources/Localizations/mt.lproj/Localizable.strings b/Pods/StripePayments/StripePayments/StripePayments/Resources/Localizations/mt.lproj/Localizable.strings new file mode 100644 index 0000000..c4cce0e --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/Resources/Localizations/mt.lproj/Localizable.strings @@ -0,0 +1,57 @@ +"AU BECS Direct Debit" = "Debitu Dirett BECS AU"; + +"Affirm" = "Affirm"; + +"Afterpay" = "Afterpay"; + +"Alipay" = "Alipay"; + +"BLIK" = "BLIK"; + +"Bancontact" = "Bancontact"; + +"Bank" = "Bank"; + +"Boleto" = "Boleto"; + +"Card" = "Kard"; + +"Clearpay" = "Clearpay"; + +"EPS" = "EPS"; + +"FPX" = "FPX"; + +"GrabPay" = "GrabPay"; + +"Klarna" = "Klarna"; + +"Link" = "Link"; + +"NetBanking" = "NetBanking"; + +"OXXO" = "OXXO"; + +"PayPal" = "PayPal"; + +"Przelewy24" = "Przelewy24"; + +"SEPA Debit" = "Debitu SEPA"; + +"Sofort" = "Sofort"; + +"Timed out authenticating your payment method -- try again" = "Skada l-ħin tal-awtentikazzjoni tal-metodu tal-ħlas tiegħek -- erġa' pprova"; + +"UPI" = "UPI"; + +"US Bank Account" = "Kont tal-bank tal-Istati Uniti tal-Amerka"; + +"Unknown" = "Mhux magħruf"; + +"We are unable to authenticate your payment method. Please choose a different payment method and try again." = "Ma nistgħux nawtentikaw il-metodu tal-ħlas tiegħek. Jekk jogħġbok agħżel metodu tal-ħlas differenti u erġa' pprova."; + +"WeChat Pay" = "WeChat Pay"; + +"giropay" = "Giropay"; + +"iDEAL" = "iDEAL"; diff --git a/Pods/StripePayments/StripePayments/StripePayments/Resources/Localizations/nb.lproj/Localizable.strings b/Pods/StripePayments/StripePayments/StripePayments/Resources/Localizations/nb.lproj/Localizable.strings new file mode 100644 index 0000000..eeed758 --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/Resources/Localizations/nb.lproj/Localizable.strings @@ -0,0 +1,57 @@ +"AU BECS Direct Debit" = "AU BECS-direktedebitering"; + +"Affirm" = "Affirm"; + +"Afterpay" = "Afterpay"; + +"Alipay" = "Alipay"; + +"BLIK" = "BLIK"; + +"Bancontact" = "Bancontact"; + +"Bank" = "Bank"; + +"Boleto" = "Boleto"; + +"Card" = "Kort"; + +"Clearpay" = "Clearpay"; + +"EPS" = "EPS"; + +"FPX" = "FPX"; + +"GrabPay" = "GrabPay"; + +"Klarna" = "Klarna"; + +"Link" = "Link"; + +"NetBanking" = "NetBanking"; + +"OXXO" = "OXXO"; + +"PayPal" = "PayPal"; + +"Przelewy24" = "Przelewy24"; + +"SEPA Debit" = "SEPA Debit"; + +"Sofort" = "Sofort"; + +"Timed out authenticating your payment method -- try again" = "Tidsavbrudd ved godkjennelse av betalingsmåten din - prøv igjen"; + +"UPI" = "UPI"; + +"US Bank Account" = "Bankkonto i USA"; + +"Unknown" = "Ukjent"; + +"We are unable to authenticate your payment method. Please choose a different payment method and try again." = "Vi kan ikke godkjenne betalingsmåten din. Vennligst velg en annen betalingsmetode og prøv igjen."; + +"WeChat Pay" = "WeChat Pay"; + +"giropay" = "giropay"; + +"iDEAL" = "iDEAL"; diff --git a/Pods/StripePayments/StripePayments/StripePayments/Resources/Localizations/nl.lproj/Localizable.strings b/Pods/StripePayments/StripePayments/StripePayments/Resources/Localizations/nl.lproj/Localizable.strings new file mode 100644 index 0000000..59f95ca --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/Resources/Localizations/nl.lproj/Localizable.strings @@ -0,0 +1,57 @@ +"AU BECS Direct Debit" = "AU BECS Direct Debit"; + +"Affirm" = "Affirm"; + +"Afterpay" = "Afterpay"; + +"Alipay" = "Alipay"; + +"BLIK" = "BLIK"; + +"Bancontact" = "Bancontact"; + +"Bank" = "Bank"; + +"Boleto" = "Boleto"; + +"Card" = "Kaart"; + +"Clearpay" = "Clearpay"; + +"EPS" = "EPS"; + +"FPX" = "FPX"; + +"GrabPay" = "GrabPay"; + +"Klarna" = "Klarna"; + +"Link" = "Link"; + +"NetBanking" = "NetBanking"; + +"OXXO" = "OXXO"; + +"PayPal" = "PayPal"; + +"Przelewy24" = "Przelewy24"; + +"SEPA Debit" = "SEPA-incasso"; + +"Sofort" = "Sofort"; + +"Timed out authenticating your payment method -- try again" = "Time-out bij authenticatie van de betaalmethode. Probeer het nogmaals"; + +"UPI" = "UPI"; + +"US Bank Account" = "Amerikaanse bankrekening"; + +"Unknown" = "Onbekend"; + +"We are unable to authenticate your payment method. Please choose a different payment method and try again." = "We kunnen de betaalmethode niet authenticeren. Kies een andere betaalmethode en probeer het nogmaals."; + +"WeChat Pay" = "WeChat Pay"; + +"giropay" = "Giropay"; + +"iDEAL" = "iDEAL"; diff --git a/Pods/StripePayments/StripePayments/StripePayments/Resources/Localizations/nn-NO.lproj/Localizable.strings b/Pods/StripePayments/StripePayments/StripePayments/Resources/Localizations/nn-NO.lproj/Localizable.strings new file mode 100644 index 0000000..6b2b566 --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/Resources/Localizations/nn-NO.lproj/Localizable.strings @@ -0,0 +1,57 @@ +"AU BECS Direct Debit" = "AU BECS Direct Debit"; + +"Affirm" = "Affirm"; + +"Afterpay" = "Afterpay"; + +"Alipay" = "Alipay"; + +"BLIK" = "BLIK"; + +"Bancontact" = "Bancontact"; + +"Bank" = "Bank"; + +"Boleto" = "Boleto"; + +"Card" = "Kort"; + +"Clearpay" = "Clearpay"; + +"EPS" = "EPS"; + +"FPX" = "FPX"; + +"GrabPay" = "GrabPay"; + +"Klarna" = "Klarna"; + +"Link" = "Link"; + +"NetBanking" = "NetBanking"; + +"OXXO" = "OXXO"; + +"PayPal" = "PayPal"; + +"Przelewy24" = "Przelewy24"; + +"SEPA Debit" = "SEPA-betaling"; + +"Sofort" = "Sofort"; + +"Timed out authenticating your payment method -- try again" = "Tidsavbrot ved godkjenning av betalingsmåten - prøv igjen"; + +"UPI" = "UPI"; + +"US Bank Account" = "Bankkonto i USA"; + +"Unknown" = "Ukjend"; + +"We are unable to authenticate your payment method. Please choose a different payment method and try again." = "Vi kan ikkje godkjenne betalingsmåten. Ver vennleg å velje ein annan betalingsmetode og prøv igjen."; + +"WeChat Pay" = "WeChat Pay"; + +"giropay" = "giropay"; + +"iDEAL" = "iDEAL"; diff --git a/Pods/StripePayments/StripePayments/StripePayments/Resources/Localizations/pl-PL.lproj/Localizable.strings b/Pods/StripePayments/StripePayments/StripePayments/Resources/Localizations/pl-PL.lproj/Localizable.strings new file mode 100644 index 0000000..9b3a68f --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/Resources/Localizations/pl-PL.lproj/Localizable.strings @@ -0,0 +1,57 @@ +"AU BECS Direct Debit" = "Polecenie zapłaty AU BECS"; + +"Affirm" = "Affirm"; + +"Afterpay" = "Afterpay"; + +"Alipay" = "Alipay"; + +"BLIK" = "BLIK"; + +"Bancontact" = "Bancontact"; + +"Bank" = "Bank"; + +"Boleto" = "Boleto"; + +"Card" = "Karta"; + +"Clearpay" = "Clearpay"; + +"EPS" = "EPS"; + +"FPX" = "FPX"; + +"GrabPay" = "GrabPay"; + +"Klarna" = "Klarna"; + +"Link" = "Link"; + +"NetBanking" = "NetBanking"; + +"OXXO" = "OXXO"; + +"PayPal" = "PayPal"; + +"Przelewy24" = "Przelewy24"; + +"SEPA Debit" = "Polecenie zapłaty SEPA"; + +"Sofort" = "Sofort"; + +"Timed out authenticating your payment method -- try again" = "Przekroczono czas uwierzytelnienia metody płatności – spróbuj ponownie"; + +"UPI" = "UPI"; + +"US Bank Account" = "Konto bankowe w Stanach Zjednoczonych"; + +"Unknown" = "Nieznany"; + +"We are unable to authenticate your payment method. Please choose a different payment method and try again." = "Nie możemy wykonać uwierzytelnienia Twojej metody płatności. Wybierz inną metodę i spróbuj ponownie."; + +"WeChat Pay" = "WeChat Pay"; + +"giropay" = "giropay"; + +"iDEAL" = "iDEAL"; diff --git a/Pods/StripePayments/StripePayments/StripePayments/Resources/Localizations/pt-BR.lproj/Localizable.strings b/Pods/StripePayments/StripePayments/StripePayments/Resources/Localizations/pt-BR.lproj/Localizable.strings new file mode 100644 index 0000000..c7a1345 --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/Resources/Localizations/pt-BR.lproj/Localizable.strings @@ -0,0 +1,57 @@ +"AU BECS Direct Debit" = "Débito automático AU BECS"; + +"Affirm" = "Affirm"; + +"Afterpay" = "Afterpay"; + +"Alipay" = "Alipay"; + +"BLIK" = "BLIK"; + +"Bancontact" = "Bancontact"; + +"Bank" = "Banco"; + +"Boleto" = "Boleto"; + +"Card" = "Cartão"; + +"Clearpay" = "Clearpay"; + +"EPS" = "EPS"; + +"FPX" = "FPX"; + +"GrabPay" = "GrabPay"; + +"Klarna" = "Klarna"; + +"Link" = "Link"; + +"NetBanking" = "NetBanking"; + +"OXXO" = "OXXO"; + +"PayPal" = "PayPal"; + +"Przelewy24" = "Przelewy24"; + +"SEPA Debit" = "Débito SEPA"; + +"Sofort" = "Sofort"; + +"Timed out authenticating your payment method -- try again" = "Tempo limite esgotado para autenticar sua forma de pagamento – tente novamente"; + +"UPI" = "UPI"; + +"US Bank Account" = "Conta bancária dos EUA"; + +"Unknown" = "Desconhecido"; + +"We are unable to authenticate your payment method. Please choose a different payment method and try again." = "Não é possível autenticar sua forma de pagamento. Escolha outra forma de pagamento e tente de novo."; + +"WeChat Pay" = "WeChat Pay"; + +"giropay" = "giropay"; + +"iDEAL" = "iDEAL"; diff --git a/Pods/StripePayments/StripePayments/StripePayments/Resources/Localizations/pt-PT.lproj/Localizable.strings b/Pods/StripePayments/StripePayments/StripePayments/Resources/Localizations/pt-PT.lproj/Localizable.strings new file mode 100644 index 0000000..dded8dd --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/Resources/Localizations/pt-PT.lproj/Localizable.strings @@ -0,0 +1,57 @@ +"AU BECS Direct Debit" = "Débito Direto AU BECS"; + +"Affirm" = "Affirm"; + +"Afterpay" = "Afterpay"; + +"Alipay" = "Alipay"; + +"BLIK" = "BLIK"; + +"Bancontact" = "Bancontact"; + +"Bank" = "Banco"; + +"Boleto" = "Boleto"; + +"Card" = "Cartão"; + +"Clearpay" = "Clearpay"; + +"EPS" = "EPS"; + +"FPX" = "FPX"; + +"GrabPay" = "GrabPay"; + +"Klarna" = "Klarna"; + +"Link" = "Link"; + +"NetBanking" = "NetBanking"; + +"OXXO" = "OXXO"; + +"PayPal" = "PayPal"; + +"Przelewy24" = "Przelewy24"; + +"SEPA Debit" = "Débito SEPA"; + +"Sofort" = "Sofort"; + +"Timed out authenticating your payment method -- try again" = "A autenticação do seu método de pagamento atingiu o tempo limite -- tente novamente"; + +"UPI" = "UPI"; + +"US Bank Account" = "Conta bancária dos EUA"; + +"Unknown" = "Desconhecido"; + +"We are unable to authenticate your payment method. Please choose a different payment method and try again." = "Não conseguimos autenticar o seu método de pagamento. Selecione outro método de pagamento e tente novamente."; + +"WeChat Pay" = "WeChat Pay"; + +"giropay" = "giropay"; + +"iDEAL" = "iDEAL"; diff --git a/Pods/StripePayments/StripePayments/StripePayments/Resources/Localizations/ro-RO.lproj/Localizable.strings b/Pods/StripePayments/StripePayments/StripePayments/Resources/Localizations/ro-RO.lproj/Localizable.strings new file mode 100644 index 0000000..7e81249 --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/Resources/Localizations/ro-RO.lproj/Localizable.strings @@ -0,0 +1,57 @@ +"AU BECS Direct Debit" = "AU BECS Direct Debit"; + +"Affirm" = "Affirm"; + +"Afterpay" = "Afterpay"; + +"Alipay" = "Alipay"; + +"BLIK" = "BLIK"; + +"Bancontact" = "Bancontact"; + +"Bank" = "Bancă"; + +"Boleto" = "Boleto"; + +"Card" = "Număr card"; + +"Clearpay" = "Clearpay"; + +"EPS" = "EPS"; + +"FPX" = "FPX"; + +"GrabPay" = "GrabPay"; + +"Klarna" = "Klarna"; + +"Link" = "Link"; + +"NetBanking" = "Netbanking"; + +"OXXO" = "OXXO"; + +"PayPal" = "PayPal"; + +"Przelewy24" = "Przelewy24"; + +"SEPA Debit" = "SEPA Debit"; + +"Sofort" = "Sofort"; + +"Timed out authenticating your payment method -- try again" = "Timpul de autentificare a metodei dvs. de plată a expirat -- încercați din nou"; + +"UPI" = "UPI"; + +"US Bank Account" = "Cont bancar SUA"; + +"Unknown" = "Necunoscut"; + +"We are unable to authenticate your payment method. Please choose a different payment method and try again." = "Nu vă putem autentifica metoda de plată. Alegeți o altă metodă de plată și încercați din nou."; + +"WeChat Pay" = "WeChat Pay"; + +"giropay" = "giropay"; + +"iDEAL" = "iDEAL"; diff --git a/Pods/StripePayments/StripePayments/StripePayments/Resources/Localizations/ru.lproj/Localizable.strings b/Pods/StripePayments/StripePayments/StripePayments/Resources/Localizations/ru.lproj/Localizable.strings new file mode 100644 index 0000000..4abda0e --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/Resources/Localizations/ru.lproj/Localizable.strings @@ -0,0 +1,57 @@ +"AU BECS Direct Debit" = "Австралийская система прямого списания средств BECS"; + +"Affirm" = "Affirm"; + +"Afterpay" = "Afterpay"; + +"Alipay" = "Alipay"; + +"BLIK" = "BLIK"; + +"Bancontact" = "Bancontact"; + +"Bank" = "Банк"; + +"Boleto" = "Boleto"; + +"Card" = "Карта"; + +"Clearpay" = "Clearpay"; + +"EPS" = "EPS"; + +"FPX" = "FPX"; + +"GrabPay" = "GrabPay"; + +"Klarna" = "Klarna"; + +"Link" = "Link"; + +"NetBanking" = "NetBanking"; + +"OXXO" = "OXXO"; + +"PayPal" = "PayPal"; + +"Przelewy24" = "Przelewy24"; + +"SEPA Debit" = "Списание средств SEPA"; + +"Sofort" = "Sofort"; + +"Timed out authenticating your payment method -- try again" = "Лимит времени для аутентификации метода оплаты истек. Попробуйте еще раз"; + +"UPI" = "UPI"; + +"US Bank Account" = "Банковский счет в США"; + +"Unknown" = "Неизвестно"; + +"We are unable to authenticate your payment method. Please choose a different payment method and try again." = "Не удалось верифицировать метод оплаты. Выберите другой метод оплаты и повторите попытку."; + +"WeChat Pay" = "WeChat Pay"; + +"giropay" = "giropay"; + +"iDEAL" = "iDEAL"; diff --git a/Pods/StripePayments/StripePayments/StripePayments/Resources/Localizations/sk-SK.lproj/Localizable.strings b/Pods/StripePayments/StripePayments/StripePayments/Resources/Localizations/sk-SK.lproj/Localizable.strings new file mode 100644 index 0000000..6fbf42c --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/Resources/Localizations/sk-SK.lproj/Localizable.strings @@ -0,0 +1,57 @@ +"AU BECS Direct Debit" = "AU BECS inkaso"; + +"Affirm" = "Affirm"; + +"Afterpay" = "Afterpay"; + +"Alipay" = "Alipay"; + +"BLIK" = "BLIK"; + +"Bancontact" = "Bancontact"; + +"Bank" = "Banka"; + +"Boleto" = "Boleto"; + +"Card" = "Karta"; + +"Clearpay" = "Clearpay"; + +"EPS" = "EPS"; + +"FPX" = "FPX"; + +"GrabPay" = "GrabPay"; + +"Klarna" = "Klarna"; + +"Link" = "Link"; + +"NetBanking" = "NetBanking"; + +"OXXO" = "OXXO"; + +"PayPal" = "PayPal"; + +"Przelewy24" = "Przelewy24"; + +"SEPA Debit" = "SEPA inkaso"; + +"Sofort" = "Sofort"; + +"Timed out authenticating your payment method -- try again" = "Vypršal čas autentifikácie vášho spôsobu platby -- skúste znova"; + +"UPI" = "UPI"; + +"US Bank Account" = "Americký bankový účet"; + +"Unknown" = "Neznáme"; + +"We are unable to authenticate your payment method. Please choose a different payment method and try again." = "Nemôžeme overiť váš spôsob platby. Vyberte iný spôsob platby a skúste to znova."; + +"WeChat Pay" = "WeChat Pay"; + +"giropay" = "giropay"; + +"iDEAL" = "iDEAL"; diff --git a/Pods/StripePayments/StripePayments/StripePayments/Resources/Localizations/sl-SI.lproj/Localizable.strings b/Pods/StripePayments/StripePayments/StripePayments/Resources/Localizations/sl-SI.lproj/Localizable.strings new file mode 100644 index 0000000..4ee5197 --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/Resources/Localizations/sl-SI.lproj/Localizable.strings @@ -0,0 +1,57 @@ +"AU BECS Direct Debit" = "Direktna obremenitev AU BECS"; + +"Affirm" = "Affirm"; + +"Afterpay" = "Afterpay"; + +"Alipay" = "Alipay"; + +"BLIK" = "BLIK"; + +"Bancontact" = "Bancontact"; + +"Bank" = "Banka"; + +"Boleto" = "Boleto"; + +"Card" = "Kartica"; + +"Clearpay" = "Clearpay"; + +"EPS" = "EPS"; + +"FPX" = "FPX"; + +"GrabPay" = "GrabPay"; + +"Klarna" = "Klarna"; + +"Link" = "Link"; + +"NetBanking" = "NetBanking"; + +"OXXO" = "OXXO"; + +"PayPal" = "PayPal"; + +"Przelewy24" = "Przelewy24"; + +"SEPA Debit" = "Obremenitev SEPA"; + +"Sofort" = "Sofort"; + +"Timed out authenticating your payment method -- try again" = "Pri preverjanju pristnosti vašega načina plačila je potekla časovna omejitev. Poskusite znova."; + +"UPI" = "UPI"; + +"US Bank Account" = "Bančni račun v ZDA"; + +"Unknown" = "Neznano"; + +"We are unable to authenticate your payment method. Please choose a different payment method and try again." = "Pristnosti vašega načina plačila ni mogoče preveriti. Izberite drugačen način plačila in poskusite znova."; + +"WeChat Pay" = "WeChat Pay"; + +"giropay" = "giropay"; + +"iDEAL" = "iDEAL"; diff --git a/Pods/StripePayments/StripePayments/StripePayments/Resources/Localizations/sv.lproj/Localizable.strings b/Pods/StripePayments/StripePayments/StripePayments/Resources/Localizations/sv.lproj/Localizable.strings new file mode 100644 index 0000000..c298579 --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/Resources/Localizations/sv.lproj/Localizable.strings @@ -0,0 +1,57 @@ +"AU BECS Direct Debit" = "AU BECS Direct Debit"; + +"Affirm" = "Affirm"; + +"Afterpay" = "Afterpay"; + +"Alipay" = "Alipay"; + +"BLIK" = "BLIK"; + +"Bancontact" = "Bancontact"; + +"Bank" = "Bank"; + +"Boleto" = "Boleto"; + +"Card" = "Kort"; + +"Clearpay" = "Clearpay"; + +"EPS" = "EPS"; + +"FPX" = "FPX"; + +"GrabPay" = "GrabPay"; + +"Klarna" = "Klarna"; + +"Link" = "Link"; + +"NetBanking" = "NetBanking"; + +"OXXO" = "OXXO"; + +"PayPal" = "PayPal"; + +"Przelewy24" = "Przelewy24"; + +"SEPA Debit" = "SEPA Debit"; + +"Sofort" = "Sofort"; + +"Timed out authenticating your payment method -- try again" = "Tidsgränsen överskreds vid autentisering av betalningsmetoden – försök igen"; + +"UPI" = "UPI"; + +"US Bank Account" = "Amerikanskt bankkonto"; + +"Unknown" = "Okänd"; + +"We are unable to authenticate your payment method. Please choose a different payment method and try again." = "Vi kan inte verifiera din betalningsmetod. Välj en annan betalningsmetod och försök igen."; + +"WeChat Pay" = "WeChat Pay"; + +"giropay" = "giropay"; + +"iDEAL" = "iDEAL"; diff --git a/Pods/StripePayments/StripePayments/StripePayments/Resources/Localizations/tk.lproj/Localizable.strings b/Pods/StripePayments/StripePayments/StripePayments/Resources/Localizations/tk.lproj/Localizable.strings new file mode 100644 index 0000000..e69de29 diff --git a/Pods/StripePayments/StripePayments/StripePayments/Resources/Localizations/tr.lproj/Localizable.strings b/Pods/StripePayments/StripePayments/StripePayments/Resources/Localizations/tr.lproj/Localizable.strings new file mode 100644 index 0000000..3e2a8bb --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/Resources/Localizations/tr.lproj/Localizable.strings @@ -0,0 +1,57 @@ +"AU BECS Direct Debit" = "AU BECS Otomatik Ödeme"; + +"Affirm" = "Affirm"; + +"Afterpay" = "Afterpay"; + +"Alipay" = "Alipay"; + +"BLIK" = "BLIK"; + +"Bancontact" = "Bancontact"; + +"Bank" = "Banka"; + +"Boleto" = "Boleto"; + +"Card" = "Kart"; + +"Clearpay" = "Clearpay"; + +"EPS" = "EPS"; + +"FPX" = "FPX"; + +"GrabPay" = "GrabPay"; + +"Klarna" = "Klarna"; + +"Link" = "Link"; + +"NetBanking" = "NetBanking"; + +"OXXO" = "OXXO"; + +"PayPal" = "PayPal"; + +"Przelewy24" = "Przelewy24"; + +"SEPA Debit" = "SEPA Bankamatik"; + +"Sofort" = "Sofort"; + +"Timed out authenticating your payment method -- try again" = "Ödeme metodunuz doğrulanırken zaman aşımına uğradı -- tekrar deneyin"; + +"UPI" = "UPI"; + +"US Bank Account" = "Banka Hesabı"; + +"Unknown" = "Bilinmeyen"; + +"We are unable to authenticate your payment method. Please choose a different payment method and try again." = "Ödeme metodunuzu doğrulayamadık. Lütfen farklı bir ödeme metodu seçin ve tekrar deneyin."; + +"WeChat Pay" = "WeChat Pay"; + +"giropay" = "giropay"; + +"iDEAL" = "iDEAL"; diff --git a/Pods/StripePayments/StripePayments/StripePayments/Resources/Localizations/vi.lproj/Localizable.strings b/Pods/StripePayments/StripePayments/StripePayments/Resources/Localizations/vi.lproj/Localizable.strings new file mode 100644 index 0000000..7c58e2e --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/Resources/Localizations/vi.lproj/Localizable.strings @@ -0,0 +1,57 @@ +"AU BECS Direct Debit" = "Ghi nợ trực tiếp AU Becs"; + +"Affirm" = "Affirm"; + +"Afterpay" = "Afterpay"; + +"Alipay" = "Alipay"; + +"BLIK" = "BLIK"; + +"Bancontact" = "Bancontact"; + +"Bank" = "Ngân hàng"; + +"Boleto" = "Boleto"; + +"Card" = "Thẻ"; + +"Clearpay" = "Clearpay"; + +"EPS" = "EPS"; + +"FPX" = "FPX"; + +"GrabPay" = "GrabPay"; + +"Klarna" = "Klarna"; + +"Link" = "Link"; + +"NetBanking" = "Ngân hàng trực tuyến"; + +"OXXO" = "OXXO"; + +"PayPal" = "PayPal"; + +"Przelewy24" = "Przelewy24"; + +"SEPA Debit" = "Ghi nợ SEPA"; + +"Sofort" = "Sofort"; + +"Timed out authenticating your payment method -- try again" = "Đã hết thời gian xác thực phương thức thanh toán -- hãy thử lại sau"; + +"UPI" = "UPI"; + +"US Bank Account" = "Tài khoản ngân hàng Mỹ"; + +"Unknown" = "Không biết"; + +"We are unable to authenticate your payment method. Please choose a different payment method and try again." = "Chúng tôi không thể xác thực phương thức thanh toán của bạn. Vui lòng chọn phương thức thanh toán khác và thử lại."; + +"WeChat Pay" = "WeChat Pay"; + +"giropay" = "giropay"; + +"iDEAL" = "iDEAL"; diff --git a/Pods/StripePayments/StripePayments/StripePayments/Resources/Localizations/zh-HK.lproj/Localizable.strings b/Pods/StripePayments/StripePayments/StripePayments/Resources/Localizations/zh-HK.lproj/Localizable.strings new file mode 100644 index 0000000..d835f10 --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/Resources/Localizations/zh-HK.lproj/Localizable.strings @@ -0,0 +1,57 @@ +"AU BECS Direct Debit" = "AU BECS 直接借記"; + +"Affirm" = "Affirm"; + +"Afterpay" = "Afterpay"; + +"Alipay" = "支付寶"; + +"BLIK" = "BLIK"; + +"Bancontact" = "Bancontact"; + +"Bank" = "銀行"; + +"Boleto" = "Boleto"; + +"Card" = "卡"; + +"Clearpay" = "Clearpay"; + +"EPS" = "EPS"; + +"FPX" = "FPX"; + +"GrabPay" = "GrabPay"; + +"Klarna" = "Klarna"; + +"Link" = "Link"; + +"NetBanking" = "NetBanking"; + +"OXXO" = "OXXO"; + +"PayPal" = "PayPal"; + +"Przelewy24" = "Przelewy24"; + +"SEPA Debit" = "SEPA Debit"; + +"Sofort" = "Sofort"; + +"Timed out authenticating your payment method -- try again" = "驗證您的付款方式時超時 -- 請重試"; + +"UPI" = "UPI"; + +"US Bank Account" = "美國銀行帳戶"; + +"Unknown" = "未知"; + +"We are unable to authenticate your payment method. Please choose a different payment method and try again." = "我們無法驗證您的付款方式。請選擇另一付款方式並重試。"; + +"WeChat Pay" = "WeChat Pay"; + +"giropay" = "Giropay"; + +"iDEAL" = "iDEAL"; diff --git a/Pods/StripePayments/StripePayments/StripePayments/Resources/Localizations/zh-Hans.lproj/Localizable.strings b/Pods/StripePayments/StripePayments/StripePayments/Resources/Localizations/zh-Hans.lproj/Localizable.strings new file mode 100644 index 0000000..240ccd3 --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/Resources/Localizations/zh-Hans.lproj/Localizable.strings @@ -0,0 +1,57 @@ +"AU BECS Direct Debit" = "AU BECS 直接借记"; + +"Affirm" = "Affirm"; + +"Afterpay" = "Afterpay"; + +"Alipay" = "支付宝"; + +"BLIK" = "BLIK"; + +"Bancontact" = "Bancontact"; + +"Bank" = "银行"; + +"Boleto" = "Boleto"; + +"Card" = "银行卡"; + +"Clearpay" = "Clearpay"; + +"EPS" = "EPS"; + +"FPX" = "FPX"; + +"GrabPay" = "GrabPay"; + +"Klarna" = "Klarna"; + +"Link" = "Link"; + +"NetBanking" = "NetBanking"; + +"OXXO" = "OXXO"; + +"PayPal" = "PayPal"; + +"Przelewy24" = "Przelewy24"; + +"SEPA Debit" = "SEPA 借记"; + +"Sofort" = "Sofort"; + +"Timed out authenticating your payment method -- try again" = "验证您的支付方式时失败——请重试"; + +"UPI" = "UPI"; + +"US Bank Account" = "美国银行账户"; + +"Unknown" = "未知"; + +"We are unable to authenticate your payment method. Please choose a different payment method and try again." = "我们未能验证您的支付方式。请选择另一支付方式并重试。"; + +"WeChat Pay" = "WeChat Pay"; + +"giropay" = "Giropay"; + +"iDEAL" = "iDEAL"; diff --git a/Pods/StripePayments/StripePayments/StripePayments/Resources/Localizations/zh-Hant.lproj/Localizable.strings b/Pods/StripePayments/StripePayments/StripePayments/Resources/Localizations/zh-Hant.lproj/Localizable.strings new file mode 100644 index 0000000..b7ac690 --- /dev/null +++ b/Pods/StripePayments/StripePayments/StripePayments/Resources/Localizations/zh-Hant.lproj/Localizable.strings @@ -0,0 +1,57 @@ +"AU BECS Direct Debit" = "AU BECS 直接借記 "; + +"Affirm" = "Affirm"; + +"Afterpay" = "Afterpay"; + +"Alipay" = "支付寶"; + +"BLIK" = "BLIK"; + +"Bancontact" = "Bancontact"; + +"Bank" = "銀行"; + +"Boleto" = "Boleto"; + +"Card" = "卡"; + +"Clearpay" = "Clearpay"; + +"EPS" = "EPS"; + +"FPX" = "FPX"; + +"GrabPay" = "GrabPay"; + +"Klarna" = "Klarna"; + +"Link" = "Link"; + +"NetBanking" = "NetBanking"; + +"OXXO" = "OXXO"; + +"PayPal" = "PayPal"; + +"Przelewy24" = "Przelewy24"; + +"SEPA Debit" = "SEPA Debit"; + +"Sofort" = "Sofort"; + +"Timed out authenticating your payment method -- try again" = "驗證您的付款方式時逾時 -- 請重試"; + +"UPI" = "UPI"; + +"US Bank Account" = "美國銀行帳戶"; + +"Unknown" = "未知"; + +"We are unable to authenticate your payment method. Please choose a different payment method and try again." = "我們無法驗證您的付款方式。請選擇其他付款方式,然後再試一次。"; + +"WeChat Pay" = "WeChat Pay"; + +"giropay" = "Giropay"; + +"iDEAL" = "iDEAL"; diff --git a/Pods/Target Support Files/Pods-OSPaymentsLib-OSPaymentsLibTests/Pods-OSPaymentsLib-OSPaymentsLibTests-acknowledgements.markdown b/Pods/Target Support Files/Pods-OSPaymentsLib-OSPaymentsLibTests/Pods-OSPaymentsLib-OSPaymentsLibTests-acknowledgements.markdown index c2cb63e..40b5ee6 100644 --- a/Pods/Target Support Files/Pods-OSPaymentsLib-OSPaymentsLibTests/Pods-OSPaymentsLib-OSPaymentsLibTests-acknowledgements.markdown +++ b/Pods/Target Support Files/Pods-OSPaymentsLib-OSPaymentsLibTests/Pods-OSPaymentsLib-OSPaymentsLibTests-acknowledgements.markdown @@ -1,6 +1,56 @@ # Acknowledgements This application makes use of the following third party libraries: +## StripeCore + +The MIT License + +Copyright (c) 2011- Stripe, Inc. (https://stripe.com) + +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. + + +## StripePayments + +The MIT License + +Copyright (c) 2011- Stripe, Inc. (https://stripe.com) + +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. + + ## Nimble Apache License diff --git a/Pods/Target Support Files/Pods-OSPaymentsLib-OSPaymentsLibTests/Pods-OSPaymentsLib-OSPaymentsLibTests-acknowledgements.plist b/Pods/Target Support Files/Pods-OSPaymentsLib-OSPaymentsLibTests/Pods-OSPaymentsLib-OSPaymentsLibTests-acknowledgements.plist index 252bf55..b2a5f69 100644 --- a/Pods/Target Support Files/Pods-OSPaymentsLib-OSPaymentsLibTests/Pods-OSPaymentsLib-OSPaymentsLibTests-acknowledgements.plist +++ b/Pods/Target Support Files/Pods-OSPaymentsLib-OSPaymentsLibTests/Pods-OSPaymentsLib-OSPaymentsLibTests-acknowledgements.plist @@ -12,6 +12,68 @@ Type PSGroupSpecifier + + FooterText + The MIT License + +Copyright (c) 2011- Stripe, Inc. (https://stripe.com) + +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. + + License + MIT + Title + StripeCore + Type + PSGroupSpecifier + + + FooterText + The MIT License + +Copyright (c) 2011- Stripe, Inc. (https://stripe.com) + +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. + + License + MIT + Title + StripePayments + Type + PSGroupSpecifier + FooterText Apache License diff --git a/Pods/Target Support Files/Pods-OSPaymentsLib-OSPaymentsLibTests/Pods-OSPaymentsLib-OSPaymentsLibTests-frameworks-Debug-input-files.xcfilelist b/Pods/Target Support Files/Pods-OSPaymentsLib-OSPaymentsLibTests/Pods-OSPaymentsLib-OSPaymentsLibTests-frameworks-Debug-input-files.xcfilelist index 6323d70..f80ebad 100644 --- a/Pods/Target Support Files/Pods-OSPaymentsLib-OSPaymentsLibTests/Pods-OSPaymentsLib-OSPaymentsLibTests-frameworks-Debug-input-files.xcfilelist +++ b/Pods/Target Support Files/Pods-OSPaymentsLib-OSPaymentsLibTests/Pods-OSPaymentsLib-OSPaymentsLibTests-frameworks-Debug-input-files.xcfilelist @@ -1,3 +1,5 @@ ${PODS_ROOT}/Target Support Files/Pods-OSPaymentsLib-OSPaymentsLibTests/Pods-OSPaymentsLib-OSPaymentsLibTests-frameworks.sh +${BUILT_PRODUCTS_DIR}/StripeCore/StripeCore.framework +${BUILT_PRODUCTS_DIR}/StripePayments/StripePayments.framework ${BUILT_PRODUCTS_DIR}/Nimble/Nimble.framework ${BUILT_PRODUCTS_DIR}/Quick/Quick.framework \ No newline at end of file diff --git a/Pods/Target Support Files/Pods-OSPaymentsLib-OSPaymentsLibTests/Pods-OSPaymentsLib-OSPaymentsLibTests-frameworks-Debug-output-files.xcfilelist b/Pods/Target Support Files/Pods-OSPaymentsLib-OSPaymentsLibTests/Pods-OSPaymentsLib-OSPaymentsLibTests-frameworks-Debug-output-files.xcfilelist index 26331d0..9200f92 100644 --- a/Pods/Target Support Files/Pods-OSPaymentsLib-OSPaymentsLibTests/Pods-OSPaymentsLib-OSPaymentsLibTests-frameworks-Debug-output-files.xcfilelist +++ b/Pods/Target Support Files/Pods-OSPaymentsLib-OSPaymentsLibTests/Pods-OSPaymentsLib-OSPaymentsLibTests-frameworks-Debug-output-files.xcfilelist @@ -1,2 +1,4 @@ +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/StripeCore.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/StripePayments.framework ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Nimble.framework ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Quick.framework \ No newline at end of file diff --git a/Pods/Target Support Files/Pods-OSPaymentsLib-OSPaymentsLibTests/Pods-OSPaymentsLib-OSPaymentsLibTests-frameworks-Release-input-files.xcfilelist b/Pods/Target Support Files/Pods-OSPaymentsLib-OSPaymentsLibTests/Pods-OSPaymentsLib-OSPaymentsLibTests-frameworks-Release-input-files.xcfilelist index 6323d70..f80ebad 100644 --- a/Pods/Target Support Files/Pods-OSPaymentsLib-OSPaymentsLibTests/Pods-OSPaymentsLib-OSPaymentsLibTests-frameworks-Release-input-files.xcfilelist +++ b/Pods/Target Support Files/Pods-OSPaymentsLib-OSPaymentsLibTests/Pods-OSPaymentsLib-OSPaymentsLibTests-frameworks-Release-input-files.xcfilelist @@ -1,3 +1,5 @@ ${PODS_ROOT}/Target Support Files/Pods-OSPaymentsLib-OSPaymentsLibTests/Pods-OSPaymentsLib-OSPaymentsLibTests-frameworks.sh +${BUILT_PRODUCTS_DIR}/StripeCore/StripeCore.framework +${BUILT_PRODUCTS_DIR}/StripePayments/StripePayments.framework ${BUILT_PRODUCTS_DIR}/Nimble/Nimble.framework ${BUILT_PRODUCTS_DIR}/Quick/Quick.framework \ No newline at end of file diff --git a/Pods/Target Support Files/Pods-OSPaymentsLib-OSPaymentsLibTests/Pods-OSPaymentsLib-OSPaymentsLibTests-frameworks-Release-output-files.xcfilelist b/Pods/Target Support Files/Pods-OSPaymentsLib-OSPaymentsLibTests/Pods-OSPaymentsLib-OSPaymentsLibTests-frameworks-Release-output-files.xcfilelist index 26331d0..9200f92 100644 --- a/Pods/Target Support Files/Pods-OSPaymentsLib-OSPaymentsLibTests/Pods-OSPaymentsLib-OSPaymentsLibTests-frameworks-Release-output-files.xcfilelist +++ b/Pods/Target Support Files/Pods-OSPaymentsLib-OSPaymentsLibTests/Pods-OSPaymentsLib-OSPaymentsLibTests-frameworks-Release-output-files.xcfilelist @@ -1,2 +1,4 @@ +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/StripeCore.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/StripePayments.framework ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Nimble.framework ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Quick.framework \ No newline at end of file diff --git a/Pods/Target Support Files/Pods-OSPaymentsLib-OSPaymentsLibTests/Pods-OSPaymentsLib-OSPaymentsLibTests-frameworks.sh b/Pods/Target Support Files/Pods-OSPaymentsLib-OSPaymentsLibTests/Pods-OSPaymentsLib-OSPaymentsLibTests-frameworks.sh index 0420a86..5e7b4da 100755 --- a/Pods/Target Support Files/Pods-OSPaymentsLib-OSPaymentsLibTests/Pods-OSPaymentsLib-OSPaymentsLibTests-frameworks.sh +++ b/Pods/Target Support Files/Pods-OSPaymentsLib-OSPaymentsLibTests/Pods-OSPaymentsLib-OSPaymentsLibTests-frameworks.sh @@ -176,10 +176,14 @@ code_sign_if_enabled() { } if [[ "$CONFIGURATION" == "Debug" ]]; then + install_framework "${BUILT_PRODUCTS_DIR}/StripeCore/StripeCore.framework" + install_framework "${BUILT_PRODUCTS_DIR}/StripePayments/StripePayments.framework" install_framework "${BUILT_PRODUCTS_DIR}/Nimble/Nimble.framework" install_framework "${BUILT_PRODUCTS_DIR}/Quick/Quick.framework" fi if [[ "$CONFIGURATION" == "Release" ]]; then + install_framework "${BUILT_PRODUCTS_DIR}/StripeCore/StripeCore.framework" + install_framework "${BUILT_PRODUCTS_DIR}/StripePayments/StripePayments.framework" install_framework "${BUILT_PRODUCTS_DIR}/Nimble/Nimble.framework" install_framework "${BUILT_PRODUCTS_DIR}/Quick/Quick.framework" fi diff --git a/Pods/Target Support Files/Pods-OSPaymentsLib-OSPaymentsLibTests/Pods-OSPaymentsLib-OSPaymentsLibTests.debug.xcconfig b/Pods/Target Support Files/Pods-OSPaymentsLib-OSPaymentsLibTests/Pods-OSPaymentsLib-OSPaymentsLibTests.debug.xcconfig index ad26395..674ba59 100644 --- a/Pods/Target Support Files/Pods-OSPaymentsLib-OSPaymentsLibTests/Pods-OSPaymentsLib-OSPaymentsLibTests.debug.xcconfig +++ b/Pods/Target Support Files/Pods-OSPaymentsLib-OSPaymentsLibTests/Pods-OSPaymentsLib-OSPaymentsLibTests.debug.xcconfig @@ -1,11 +1,11 @@ ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO -FRAMEWORK_SEARCH_PATHS = $(inherited) "$(PLATFORM_DIR)/Developer/Library/Frameworks" "${PODS_CONFIGURATION_BUILD_DIR}/Nimble" "${PODS_CONFIGURATION_BUILD_DIR}/Quick" +FRAMEWORK_SEARCH_PATHS = $(inherited) "$(PLATFORM_DIR)/Developer/Library/Frameworks" "${PODS_CONFIGURATION_BUILD_DIR}/Nimble" "${PODS_CONFIGURATION_BUILD_DIR}/Quick" "${PODS_CONFIGURATION_BUILD_DIR}/StripeCore" "${PODS_CONFIGURATION_BUILD_DIR}/StripePayments" GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 -HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/Nimble/Nimble.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/Quick/Quick.framework/Headers" +HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/Nimble/Nimble.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/Quick/Quick.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/StripeCore/StripeCore.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/StripePayments/StripePayments.framework/Headers" LD_RUNPATH_SEARCH_PATHS = $(inherited) /usr/lib/swift "$(PLATFORM_DIR)/Developer/Library/Frameworks" '@executable_path/Frameworks' '@loader_path/Frameworks' LIBRARY_SEARCH_PATHS = $(inherited) "${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift -OTHER_LDFLAGS = $(inherited) -framework "Nimble" -framework "Quick" -framework "XCTest" -weak_framework "XCTest" +OTHER_LDFLAGS = $(inherited) -framework "Foundation" -framework "Nimble" -framework "Quick" -framework "StripeCore" -framework "StripePayments" -framework "UIKit" -framework "XCTest" -weak_framework "SwiftUI" -weak_framework "XCTest" OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS PODS_BUILD_DIR = ${BUILD_DIR} PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) diff --git a/Pods/Target Support Files/Pods-OSPaymentsLib-OSPaymentsLibTests/Pods-OSPaymentsLib-OSPaymentsLibTests.release.xcconfig b/Pods/Target Support Files/Pods-OSPaymentsLib-OSPaymentsLibTests/Pods-OSPaymentsLib-OSPaymentsLibTests.release.xcconfig index ad26395..674ba59 100644 --- a/Pods/Target Support Files/Pods-OSPaymentsLib-OSPaymentsLibTests/Pods-OSPaymentsLib-OSPaymentsLibTests.release.xcconfig +++ b/Pods/Target Support Files/Pods-OSPaymentsLib-OSPaymentsLibTests/Pods-OSPaymentsLib-OSPaymentsLibTests.release.xcconfig @@ -1,11 +1,11 @@ ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO -FRAMEWORK_SEARCH_PATHS = $(inherited) "$(PLATFORM_DIR)/Developer/Library/Frameworks" "${PODS_CONFIGURATION_BUILD_DIR}/Nimble" "${PODS_CONFIGURATION_BUILD_DIR}/Quick" +FRAMEWORK_SEARCH_PATHS = $(inherited) "$(PLATFORM_DIR)/Developer/Library/Frameworks" "${PODS_CONFIGURATION_BUILD_DIR}/Nimble" "${PODS_CONFIGURATION_BUILD_DIR}/Quick" "${PODS_CONFIGURATION_BUILD_DIR}/StripeCore" "${PODS_CONFIGURATION_BUILD_DIR}/StripePayments" GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 -HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/Nimble/Nimble.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/Quick/Quick.framework/Headers" +HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/Nimble/Nimble.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/Quick/Quick.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/StripeCore/StripeCore.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/StripePayments/StripePayments.framework/Headers" LD_RUNPATH_SEARCH_PATHS = $(inherited) /usr/lib/swift "$(PLATFORM_DIR)/Developer/Library/Frameworks" '@executable_path/Frameworks' '@loader_path/Frameworks' LIBRARY_SEARCH_PATHS = $(inherited) "${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift -OTHER_LDFLAGS = $(inherited) -framework "Nimble" -framework "Quick" -framework "XCTest" -weak_framework "XCTest" +OTHER_LDFLAGS = $(inherited) -framework "Foundation" -framework "Nimble" -framework "Quick" -framework "StripeCore" -framework "StripePayments" -framework "UIKit" -framework "XCTest" -weak_framework "SwiftUI" -weak_framework "XCTest" OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS PODS_BUILD_DIR = ${BUILD_DIR} PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) diff --git a/Pods/Target Support Files/Pods-OSPaymentsLib/Pods-OSPaymentsLib-acknowledgements.markdown b/Pods/Target Support Files/Pods-OSPaymentsLib/Pods-OSPaymentsLib-acknowledgements.markdown index 102af75..0b7322a 100644 --- a/Pods/Target Support Files/Pods-OSPaymentsLib/Pods-OSPaymentsLib-acknowledgements.markdown +++ b/Pods/Target Support Files/Pods-OSPaymentsLib/Pods-OSPaymentsLib-acknowledgements.markdown @@ -1,3 +1,53 @@ # Acknowledgements This application makes use of the following third party libraries: + +## StripeCore + +The MIT License + +Copyright (c) 2011- Stripe, Inc. (https://stripe.com) + +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. + + +## StripePayments + +The MIT License + +Copyright (c) 2011- Stripe, Inc. (https://stripe.com) + +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. + Generated by CocoaPods - https://cocoapods.org diff --git a/Pods/Target Support Files/Pods-OSPaymentsLib/Pods-OSPaymentsLib-acknowledgements.plist b/Pods/Target Support Files/Pods-OSPaymentsLib/Pods-OSPaymentsLib-acknowledgements.plist index 7acbad1..8f41d38 100644 --- a/Pods/Target Support Files/Pods-OSPaymentsLib/Pods-OSPaymentsLib-acknowledgements.plist +++ b/Pods/Target Support Files/Pods-OSPaymentsLib/Pods-OSPaymentsLib-acknowledgements.plist @@ -12,6 +12,68 @@ Type PSGroupSpecifier + + FooterText + The MIT License + +Copyright (c) 2011- Stripe, Inc. (https://stripe.com) + +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. + + License + MIT + Title + StripeCore + Type + PSGroupSpecifier + + + FooterText + The MIT License + +Copyright (c) 2011- Stripe, Inc. (https://stripe.com) + +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. + + License + MIT + Title + StripePayments + Type + PSGroupSpecifier + FooterText Generated by CocoaPods - https://cocoapods.org diff --git a/Pods/Target Support Files/Pods-OSPaymentsLib/Pods-OSPaymentsLib.debug.xcconfig b/Pods/Target Support Files/Pods-OSPaymentsLib/Pods-OSPaymentsLib.debug.xcconfig index 26f2c77..68d268c 100644 --- a/Pods/Target Support Files/Pods-OSPaymentsLib/Pods-OSPaymentsLib.debug.xcconfig +++ b/Pods/Target Support Files/Pods-OSPaymentsLib/Pods-OSPaymentsLib.debug.xcconfig @@ -1,5 +1,11 @@ CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO +FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/StripeCore" "${PODS_CONFIGURATION_BUILD_DIR}/StripePayments" GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/StripeCore/StripeCore.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/StripePayments/StripePayments.framework/Headers" +LD_RUNPATH_SEARCH_PATHS = $(inherited) /usr/lib/swift '@executable_path/Frameworks' '@loader_path/Frameworks' '@executable_path/../../Frameworks' +LIBRARY_SEARCH_PATHS = $(inherited) "${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift +OTHER_LDFLAGS = $(inherited) -framework "Foundation" -framework "StripeCore" -framework "StripePayments" -framework "UIKit" -weak_framework "SwiftUI" +OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS PODS_BUILD_DIR = ${BUILD_DIR} PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) PODS_PODFILE_DIR_PATH = ${SRCROOT}/. diff --git a/Pods/Target Support Files/Pods-OSPaymentsLib/Pods-OSPaymentsLib.release.xcconfig b/Pods/Target Support Files/Pods-OSPaymentsLib/Pods-OSPaymentsLib.release.xcconfig index 26f2c77..68d268c 100644 --- a/Pods/Target Support Files/Pods-OSPaymentsLib/Pods-OSPaymentsLib.release.xcconfig +++ b/Pods/Target Support Files/Pods-OSPaymentsLib/Pods-OSPaymentsLib.release.xcconfig @@ -1,5 +1,11 @@ CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO +FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/StripeCore" "${PODS_CONFIGURATION_BUILD_DIR}/StripePayments" GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/StripeCore/StripeCore.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/StripePayments/StripePayments.framework/Headers" +LD_RUNPATH_SEARCH_PATHS = $(inherited) /usr/lib/swift '@executable_path/Frameworks' '@loader_path/Frameworks' '@executable_path/../../Frameworks' +LIBRARY_SEARCH_PATHS = $(inherited) "${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift +OTHER_LDFLAGS = $(inherited) -framework "Foundation" -framework "StripeCore" -framework "StripePayments" -framework "UIKit" -weak_framework "SwiftUI" +OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS PODS_BUILD_DIR = ${BUILD_DIR} PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) PODS_PODFILE_DIR_PATH = ${SRCROOT}/. diff --git a/Pods/Target Support Files/StripeCore/ResourceBundle-StripeCore-StripeCore-Info.plist b/Pods/Target Support Files/StripeCore/ResourceBundle-StripeCore-StripeCore-Info.plist new file mode 100644 index 0000000..db7b866 --- /dev/null +++ b/Pods/Target Support Files/StripeCore/ResourceBundle-StripeCore-StripeCore-Info.plist @@ -0,0 +1,24 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleIdentifier + ${PRODUCT_BUNDLE_IDENTIFIER} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + BNDL + CFBundleShortVersionString + 23.2.0 + CFBundleSignature + ???? + CFBundleVersion + 1 + NSPrincipalClass + + + diff --git a/Pods/Target Support Files/StripeCore/StripeCore-Info.plist b/Pods/Target Support Files/StripeCore/StripeCore-Info.plist new file mode 100644 index 0000000..920b3cf --- /dev/null +++ b/Pods/Target Support Files/StripeCore/StripeCore-Info.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIdentifier + ${PRODUCT_BUNDLE_IDENTIFIER} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + FMWK + CFBundleShortVersionString + 23.2.0 + CFBundleSignature + ???? + CFBundleVersion + ${CURRENT_PROJECT_VERSION} + NSPrincipalClass + + + diff --git a/Pods/Target Support Files/StripeCore/StripeCore-dummy.m b/Pods/Target Support Files/StripeCore/StripeCore-dummy.m new file mode 100644 index 0000000..3c29c90 --- /dev/null +++ b/Pods/Target Support Files/StripeCore/StripeCore-dummy.m @@ -0,0 +1,5 @@ +#import +@interface PodsDummy_StripeCore : NSObject +@end +@implementation PodsDummy_StripeCore +@end diff --git a/Pods/Target Support Files/StripeCore/StripeCore-prefix.pch b/Pods/Target Support Files/StripeCore/StripeCore-prefix.pch new file mode 100644 index 0000000..beb2a24 --- /dev/null +++ b/Pods/Target Support Files/StripeCore/StripeCore-prefix.pch @@ -0,0 +1,12 @@ +#ifdef __OBJC__ +#import +#else +#ifndef FOUNDATION_EXPORT +#if defined(__cplusplus) +#define FOUNDATION_EXPORT extern "C" +#else +#define FOUNDATION_EXPORT extern +#endif +#endif +#endif + diff --git a/Pods/Target Support Files/StripeCore/StripeCore-umbrella.h b/Pods/Target Support Files/StripeCore/StripeCore-umbrella.h new file mode 100644 index 0000000..63def25 --- /dev/null +++ b/Pods/Target Support Files/StripeCore/StripeCore-umbrella.h @@ -0,0 +1,16 @@ +#ifdef __OBJC__ +#import +#else +#ifndef FOUNDATION_EXPORT +#if defined(__cplusplus) +#define FOUNDATION_EXPORT extern "C" +#else +#define FOUNDATION_EXPORT extern +#endif +#endif +#endif + + +FOUNDATION_EXPORT double StripeCoreVersionNumber; +FOUNDATION_EXPORT const unsigned char StripeCoreVersionString[]; + diff --git a/Pods/Target Support Files/StripeCore/StripeCore.debug.xcconfig b/Pods/Target Support Files/StripeCore/StripeCore.debug.xcconfig new file mode 100644 index 0000000..893397c --- /dev/null +++ b/Pods/Target Support Files/StripeCore/StripeCore.debug.xcconfig @@ -0,0 +1,15 @@ +BUILD_LIBRARY_FOR_DISTRIBUTION = YES +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO +CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/StripeCore +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +LIBRARY_SEARCH_PATHS = $(inherited) "${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift +OTHER_LDFLAGS = $(inherited) -framework "Foundation" -framework "UIKit" +OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_ROOT = ${SRCROOT} +PODS_TARGET_SRCROOT = ${PODS_ROOT}/StripeCore +PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates +PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} +SKIP_INSTALL = YES +USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/Pods/Target Support Files/StripeCore/StripeCore.modulemap b/Pods/Target Support Files/StripeCore/StripeCore.modulemap new file mode 100644 index 0000000..407a56c --- /dev/null +++ b/Pods/Target Support Files/StripeCore/StripeCore.modulemap @@ -0,0 +1,6 @@ +framework module StripeCore { + umbrella header "StripeCore-umbrella.h" + + export * + module * { export * } +} diff --git a/Pods/Target Support Files/StripeCore/StripeCore.release.xcconfig b/Pods/Target Support Files/StripeCore/StripeCore.release.xcconfig new file mode 100644 index 0000000..893397c --- /dev/null +++ b/Pods/Target Support Files/StripeCore/StripeCore.release.xcconfig @@ -0,0 +1,15 @@ +BUILD_LIBRARY_FOR_DISTRIBUTION = YES +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO +CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/StripeCore +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +LIBRARY_SEARCH_PATHS = $(inherited) "${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift +OTHER_LDFLAGS = $(inherited) -framework "Foundation" -framework "UIKit" +OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_ROOT = ${SRCROOT} +PODS_TARGET_SRCROOT = ${PODS_ROOT}/StripeCore +PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates +PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} +SKIP_INSTALL = YES +USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/Pods/Target Support Files/StripePayments/ResourceBundle-Stripe3DS2-StripePayments-Info.plist b/Pods/Target Support Files/StripePayments/ResourceBundle-Stripe3DS2-StripePayments-Info.plist new file mode 100644 index 0000000..db7b866 --- /dev/null +++ b/Pods/Target Support Files/StripePayments/ResourceBundle-Stripe3DS2-StripePayments-Info.plist @@ -0,0 +1,24 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleIdentifier + ${PRODUCT_BUNDLE_IDENTIFIER} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + BNDL + CFBundleShortVersionString + 23.2.0 + CFBundleSignature + ???? + CFBundleVersion + 1 + NSPrincipalClass + + + diff --git a/Pods/Target Support Files/StripePayments/ResourceBundle-StripePayments-StripePayments-Info.plist b/Pods/Target Support Files/StripePayments/ResourceBundle-StripePayments-StripePayments-Info.plist new file mode 100644 index 0000000..db7b866 --- /dev/null +++ b/Pods/Target Support Files/StripePayments/ResourceBundle-StripePayments-StripePayments-Info.plist @@ -0,0 +1,24 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleIdentifier + ${PRODUCT_BUNDLE_IDENTIFIER} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + BNDL + CFBundleShortVersionString + 23.2.0 + CFBundleSignature + ???? + CFBundleVersion + 1 + NSPrincipalClass + + + diff --git a/Pods/Target Support Files/StripePayments/StripePayments-Info.plist b/Pods/Target Support Files/StripePayments/StripePayments-Info.plist new file mode 100644 index 0000000..920b3cf --- /dev/null +++ b/Pods/Target Support Files/StripePayments/StripePayments-Info.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIdentifier + ${PRODUCT_BUNDLE_IDENTIFIER} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + FMWK + CFBundleShortVersionString + 23.2.0 + CFBundleSignature + ???? + CFBundleVersion + ${CURRENT_PROJECT_VERSION} + NSPrincipalClass + + + diff --git a/Pods/Target Support Files/StripePayments/StripePayments-dummy.m b/Pods/Target Support Files/StripePayments/StripePayments-dummy.m new file mode 100644 index 0000000..7d6ef5b --- /dev/null +++ b/Pods/Target Support Files/StripePayments/StripePayments-dummy.m @@ -0,0 +1,5 @@ +#import +@interface PodsDummy_StripePayments : NSObject +@end +@implementation PodsDummy_StripePayments +@end diff --git a/Pods/Target Support Files/StripePayments/StripePayments-prefix.pch b/Pods/Target Support Files/StripePayments/StripePayments-prefix.pch new file mode 100644 index 0000000..beb2a24 --- /dev/null +++ b/Pods/Target Support Files/StripePayments/StripePayments-prefix.pch @@ -0,0 +1,12 @@ +#ifdef __OBJC__ +#import +#else +#ifndef FOUNDATION_EXPORT +#if defined(__cplusplus) +#define FOUNDATION_EXPORT extern "C" +#else +#define FOUNDATION_EXPORT extern +#endif +#endif +#endif + diff --git a/Pods/Target Support Files/StripePayments/StripePayments-umbrella.h b/Pods/Target Support Files/StripePayments/StripePayments-umbrella.h new file mode 100644 index 0000000..688a704 --- /dev/null +++ b/Pods/Target Support Files/StripePayments/StripePayments-umbrella.h @@ -0,0 +1,113 @@ +#ifdef __OBJC__ +#import +#else +#ifndef FOUNDATION_EXPORT +#if defined(__cplusplus) +#define FOUNDATION_EXPORT extern "C" +#else +#define FOUNDATION_EXPORT extern +#endif +#endif +#endif + +#import "STDSAlreadyInitializedException.h" +#import "STDSAuthenticationRequestParameters.h" +#import "STDSAuthenticationResponse.h" +#import "STDSButtonCustomization.h" +#import "STDSChallengeParameters.h" +#import "STDSChallengeStatusReceiver.h" +#import "STDSCompletionEvent.h" +#import "STDSConfigParameters.h" +#import "STDSCustomization.h" +#import "STDSErrorMessage.h" +#import "STDSException.h" +#import "STDSFooterCustomization.h" +#import "STDSInvalidInputException.h" +#import "STDSJSONDecodable.h" +#import "STDSJSONEncodable.h" +#import "STDSJSONEncoder.h" +#import "STDSLabelCustomization.h" +#import "STDSNavigationBarCustomization.h" +#import "STDSNotInitializedException.h" +#import "STDSProtocolErrorEvent.h" +#import "STDSRuntimeErrorEvent.h" +#import "STDSRuntimeException.h" +#import "STDSSelectionCustomization.h" +#import "STDSStripe3DS2Error.h" +#import "STDSSwiftTryCatch.h" +#import "STDSTextFieldCustomization.h" +#import "STDSThreeDS2Service.h" +#import "STDSThreeDSProtocolVersion.h" +#import "STDSTransaction.h" +#import "STDSUICustomization.h" +#import "STDSWarning.h" +#import "Stripe3DS2.h" +#import "NSData+JWEHelpers.h" +#import "NSDictionary+DecodingHelpers.h" +#import "NSError+Stripe3DS2.h" +#import "NSLayoutConstraint+LayoutSupport.h" +#import "NSString+EmptyChecking.h" +#import "NSString+JWEHelpers.h" +#import "STDSACSNetworkingManager.h" +#import "STDSAuthenticationResponseObject.h" +#import "STDSBrandingView.h" +#import "STDSBundleLocator.h" +#import "STDSCategoryLinker.h" +#import "STDSChallengeInformationView.h" +#import "STDSChallengeRequestParameters.h" +#import "STDSChallengeResponse.h" +#import "STDSChallengeResponseImage.h" +#import "STDSChallengeResponseImageObject.h" +#import "STDSChallengeResponseMessageExtension.h" +#import "STDSChallengeResponseMessageExtensionObject.h" +#import "STDSChallengeResponseObject.h" +#import "STDSChallengeResponseSelectionInfo.h" +#import "STDSChallengeResponseSelectionInfoObject.h" +#import "STDSChallengeResponseViewController.h" +#import "STDSChallengeSelectionView.h" +#import "STDSDebuggerChecker.h" +#import "STDSDeviceInformation.h" +#import "STDSDeviceInformationManager.h" +#import "STDSDeviceInformationParameter+Private.h" +#import "STDSDeviceInformationParameter.h" +#import "STDSDirectoryServer.h" +#import "STDSDirectoryServerCertificate+Internal.h" +#import "STDSDirectoryServerCertificate.h" +#import "STDSEllipticCurvePoint.h" +#import "STDSEphemeralKeyPair+Testing.h" +#import "STDSEphemeralKeyPair.h" +#import "STDSErrorMessage+Internal.h" +#import "STDSException+Internal.h" +#import "STDSExpandableInformationView.h" +#import "STDSImageLoader.h" +#import "STDSIntegrityChecker.h" +#import "STDSIPAddress.h" +#import "STDSJailbreakChecker.h" +#import "STDSJSONWebEncryption.h" +#import "STDSJSONWebSignature.h" +#import "STDSLocalizedString.h" +#import "STDSOSVersionChecker.h" +#import "STDSProcessingView.h" +#import "STDSProgressViewController.h" +#import "STDSSecTypeUtilities.h" +#import "STDSSelectionButton.h" +#import "STDSSimulatorChecker.h" +#import "STDSSpacerView.h" +#import "STDSStackView.h" +#import "STDSSynchronousLocationManager.h" +#import "STDSTextChallengeView.h" +#import "STDSThreeDSProtocolVersion+Private.h" +#import "STDSTransaction+Private.h" +#import "STDSWebView.h" +#import "STDSWhitelistView.h" +#import "Stripe3DS2-Bridging-Header.h" +#import "UIButton+CustomInitialization.h" +#import "UIColor+DefaultColors.h" +#import "UIColor+ThirteenSupport.h" +#import "UIFont+DefaultFonts.h" +#import "UIView+LayoutSupport.h" +#import "UIViewController+Stripe3DS2.h" + +FOUNDATION_EXPORT double StripePaymentsVersionNumber; +FOUNDATION_EXPORT const unsigned char StripePaymentsVersionString[]; + diff --git a/Pods/Target Support Files/StripePayments/StripePayments.debug.xcconfig b/Pods/Target Support Files/StripePayments/StripePayments.debug.xcconfig new file mode 100644 index 0000000..7f07acd --- /dev/null +++ b/Pods/Target Support Files/StripePayments/StripePayments.debug.xcconfig @@ -0,0 +1,16 @@ +BUILD_LIBRARY_FOR_DISTRIBUTION = YES +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO +CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/StripePayments +FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/StripeCore" +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +LIBRARY_SEARCH_PATHS = $(inherited) "${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift +OTHER_LDFLAGS = $(inherited) -framework "Foundation" -framework "StripeCore" -framework "UIKit" -weak_framework "SwiftUI" +OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_ROOT = ${SRCROOT} +PODS_TARGET_SRCROOT = ${PODS_ROOT}/StripePayments +PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates +PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} +SKIP_INSTALL = YES +USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/Pods/Target Support Files/StripePayments/StripePayments.modulemap b/Pods/Target Support Files/StripePayments/StripePayments.modulemap new file mode 100644 index 0000000..c4849d7 --- /dev/null +++ b/Pods/Target Support Files/StripePayments/StripePayments.modulemap @@ -0,0 +1,6 @@ +framework module StripePayments { + umbrella header "StripePayments-umbrella.h" + + export * + module * { export * } +} diff --git a/Pods/Target Support Files/StripePayments/StripePayments.release.xcconfig b/Pods/Target Support Files/StripePayments/StripePayments.release.xcconfig new file mode 100644 index 0000000..7f07acd --- /dev/null +++ b/Pods/Target Support Files/StripePayments/StripePayments.release.xcconfig @@ -0,0 +1,16 @@ +BUILD_LIBRARY_FOR_DISTRIBUTION = YES +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO +CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/StripePayments +FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/StripeCore" +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +LIBRARY_SEARCH_PATHS = $(inherited) "${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift +OTHER_LDFLAGS = $(inherited) -framework "Foundation" -framework "StripeCore" -framework "UIKit" -weak_framework "SwiftUI" +OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_ROOT = ${SRCROOT} +PODS_TARGET_SRCROOT = ${PODS_ROOT}/StripePayments +PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates +PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} +SKIP_INSTALL = YES +USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index 142e323..ba549f7 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -6,6 +6,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### 2022-12-02 +- Feat: Add Stripe as Payment Service Provider (https://outsystemsrd.atlassian.net/browse/RMET-2078). + ### 2022-11-14 - Add `podspec` file.