Remove remember me

This commit is contained in:
Brian Dorfman 2017-06-28 17:05:59 -07:00
parent 693ca110ed
commit f86c7fa767
33 changed files with 26 additions and 2340 deletions

View File

@ -245,24 +245,8 @@
04BC29A11CD8412000318357 /* STPPaymentContext.m in Sources */ = {isa = PBXBuildFile; fileRef = 049A3F881CC73C7100F57DE7 /* STPPaymentContext.m */; };
04BC29A41CD8697900318357 /* STPTheme.h in Headers */ = {isa = PBXBuildFile; fileRef = 04BC29A21CD8697900318357 /* STPTheme.h */; settings = {ATTRIBUTES = (Public, ); }; };
04BC29A51CD8697900318357 /* STPTheme.m in Sources */ = {isa = PBXBuildFile; fileRef = 04BC29A31CD8697900318357 /* STPTheme.m */; };
04BC29A91CD9A83600318357 /* STPCheckoutAPIClient.h in Headers */ = {isa = PBXBuildFile; fileRef = 04BC29A71CD9A83600318357 /* STPCheckoutAPIClient.h */; };
04BC29AA1CD9A83600318357 /* STPCheckoutAPIClient.m in Sources */ = {isa = PBXBuildFile; fileRef = 04BC29A81CD9A83600318357 /* STPCheckoutAPIClient.m */; };
04BC29AD1CD9A88600318357 /* STPCheckoutAPIVerification.h in Headers */ = {isa = PBXBuildFile; fileRef = 04BC29AB1CD9A88600318357 /* STPCheckoutAPIVerification.h */; };
04BC29AE1CD9A88600318357 /* STPCheckoutAPIVerification.m in Sources */ = {isa = PBXBuildFile; fileRef = 04BC29AC1CD9A88600318357 /* STPCheckoutAPIVerification.m */; };
04BC29B11CD9AAA800318357 /* STPCheckoutAccount.h in Headers */ = {isa = PBXBuildFile; fileRef = 04BC29AF1CD9AAA800318357 /* STPCheckoutAccount.h */; };
04BC29B21CD9AAA800318357 /* STPCheckoutAccount.m in Sources */ = {isa = PBXBuildFile; fileRef = 04BC29B01CD9AAA800318357 /* STPCheckoutAccount.m */; };
04BC29B51CD9AE0000318357 /* STPCheckoutBootstrapResponse.h in Headers */ = {isa = PBXBuildFile; fileRef = 04BC29B31CD9AE0000318357 /* STPCheckoutBootstrapResponse.h */; };
04BC29B61CD9AE0000318357 /* STPCheckoutBootstrapResponse.m in Sources */ = {isa = PBXBuildFile; fileRef = 04BC29B41CD9AE0000318357 /* STPCheckoutBootstrapResponse.m */; };
04BC29B91CDA995000318357 /* STPCheckoutAccountLookup.h in Headers */ = {isa = PBXBuildFile; fileRef = 04BC29B71CDA995000318357 /* STPCheckoutAccountLookup.h */; };
04BC29BA1CDA995000318357 /* STPCheckoutAccountLookup.m in Sources */ = {isa = PBXBuildFile; fileRef = 04BC29B81CDA995000318357 /* STPCheckoutAccountLookup.m */; };
04BC29BD1CDD535700318357 /* STPSwitchTableViewCell.h in Headers */ = {isa = PBXBuildFile; fileRef = 04BC29BB1CDD535700318357 /* STPSwitchTableViewCell.h */; };
04BC29BE1CDD535700318357 /* STPSwitchTableViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 04BC29BC1CDD535700318357 /* STPSwitchTableViewCell.m */; };
04BC29C21CE2A48000318357 /* STPSMSCodeViewController.h in Headers */ = {isa = PBXBuildFile; fileRef = 04BC29C01CE2A48000318357 /* STPSMSCodeViewController.h */; };
04BC29C31CE2A48000318357 /* STPSMSCodeViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 04BC29C11CE2A48000318357 /* STPSMSCodeViewController.m */; };
04BC29C61CE2A82300318357 /* STPSMSCodeTextField.h in Headers */ = {isa = PBXBuildFile; fileRef = 04BC29C41CE2A82300318357 /* STPSMSCodeTextField.h */; };
04BC29C71CE2A82300318357 /* STPSMSCodeTextField.m in Sources */ = {isa = PBXBuildFile; fileRef = 04BC29C51CE2A82300318357 /* STPSMSCodeTextField.m */; };
04BC29CA1CE40F7500318357 /* STPObscuredCardView.h in Headers */ = {isa = PBXBuildFile; fileRef = 04BC29C81CE40F7500318357 /* STPObscuredCardView.h */; };
04BC29CB1CE40F7500318357 /* STPObscuredCardView.m in Sources */ = {isa = PBXBuildFile; fileRef = 04BC29C91CE40F7500318357 /* STPObscuredCardView.m */; };
04BFFFD91D240B13005F2340 /* STPAddCardViewController+Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 04BFFFD81D240B13005F2340 /* STPAddCardViewController+Private.h */; };
04BFFFDA1D240B13005F2340 /* STPAddCardViewController+Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 04BFFFD81D240B13005F2340 /* STPAddCardViewController+Private.h */; };
04CB86BA1BA89CE100E4F61E /* PKPayment+StripeTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 04CB86B81BA89CD400E4F61E /* PKPayment+StripeTest.m */; };
@ -295,8 +279,6 @@
04E39F551CECF7A100AF3B96 /* STPPaymentMethodTuple.m in Sources */ = {isa = PBXBuildFile; fileRef = 04E39F511CECF7A100AF3B96 /* STPPaymentMethodTuple.m */; };
04E39F581CECF9A800AF3B96 /* STPPaymentMethodsViewController+Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 04E39F561CECF9A800AF3B96 /* STPPaymentMethodsViewController+Private.h */; };
04E39F5C1CECFAFD00AF3B96 /* STPPaymentContext+Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 04E39F5A1CECFAFD00AF3B96 /* STPPaymentContext+Private.h */; };
04E39F601CED2C3900AF3B96 /* STPRememberMeTermsView.h in Headers */ = {isa = PBXBuildFile; fileRef = 04E39F5E1CED2C3900AF3B96 /* STPRememberMeTermsView.h */; };
04E39F611CED2C3900AF3B96 /* STPRememberMeTermsView.m in Sources */ = {isa = PBXBuildFile; fileRef = 04E39F5F1CED2C3900AF3B96 /* STPRememberMeTermsView.m */; };
04E39F661CED3B0100AF3B96 /* stp_icon_chevron_right_small@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 04E39F631CED3B0100AF3B96 /* stp_icon_chevron_right_small@2x.png */; };
04E39F671CED3B0100AF3B96 /* stp_icon_chevron_right_small@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 04E39F641CED3B0100AF3B96 /* stp_icon_chevron_right_small@3x.png */; };
04E39F6A1CED48D500AF3B96 /* UIBarButtonItem+Stripe.h in Headers */ = {isa = PBXBuildFile; fileRef = 04E39F681CED48D500AF3B96 /* UIBarButtonItem+Stripe.h */; };
@ -336,31 +318,13 @@
04F94DAD1D229F4E004FC826 /* STPColorUtils.h in Headers */ = {isa = PBXBuildFile; fileRef = 0426B96C1CEADC98006AC8DD /* STPColorUtils.h */; };
04F94DAE1D229F54004FC826 /* STPColorUtils.m in Sources */ = {isa = PBXBuildFile; fileRef = 0426B96D1CEADC98006AC8DD /* STPColorUtils.m */; };
04F94DAF1D229F59004FC826 /* STPPaymentMethodsViewController+Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 04E39F561CECF9A800AF3B96 /* STPPaymentMethodsViewController+Private.h */; };
04F94DB01D229F60004FC826 /* STPRememberMeTermsView.h in Headers */ = {isa = PBXBuildFile; fileRef = 04E39F5E1CED2C3900AF3B96 /* STPRememberMeTermsView.h */; };
04F94DB11D229F64004FC826 /* STPRememberMeTermsView.m in Sources */ = {isa = PBXBuildFile; fileRef = 04E39F5F1CED2C3900AF3B96 /* STPRememberMeTermsView.m */; };
04F94DB21D229F69004FC826 /* STPSMSCodeViewController.h in Headers */ = {isa = PBXBuildFile; fileRef = 04BC29C01CE2A48000318357 /* STPSMSCodeViewController.h */; };
04F94DB31D229F6D004FC826 /* STPSMSCodeViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 04BC29C11CE2A48000318357 /* STPSMSCodeViewController.m */; };
04F94DB41D229F71004FC826 /* STPPaymentActivityIndicatorView.m in Sources */ = {isa = PBXBuildFile; fileRef = 046FE9A01CE55D1D00DA6A7B /* STPPaymentActivityIndicatorView.m */; };
04F94DB51D229F74004FC826 /* STPSMSCodeTextField.h in Headers */ = {isa = PBXBuildFile; fileRef = 04BC29C41CE2A82300318357 /* STPSMSCodeTextField.h */; };
04F94DB61D229F77004FC826 /* STPSMSCodeTextField.m in Sources */ = {isa = PBXBuildFile; fileRef = 04BC29C51CE2A82300318357 /* STPSMSCodeTextField.m */; };
04F94DB71D229F7C004FC826 /* STPObscuredCardView.h in Headers */ = {isa = PBXBuildFile; fileRef = 04BC29C81CE40F7500318357 /* STPObscuredCardView.h */; };
04F94DB81D229F7F004FC826 /* STPObscuredCardView.m in Sources */ = {isa = PBXBuildFile; fileRef = 04BC29C91CE40F7500318357 /* STPObscuredCardView.m */; };
04F94DB91D229F86004FC826 /* STPApplePayPaymentMethod.m in Sources */ = {isa = PBXBuildFile; fileRef = C11810881CC6B00D0022FB55 /* STPApplePayPaymentMethod.m */; };
04F94DBA1D229F8A004FC826 /* PKPaymentAuthorizationViewController+Stripe_Blocks.h in Headers */ = {isa = PBXBuildFile; fileRef = C11810931CC6C4700022FB55 /* PKPaymentAuthorizationViewController+Stripe_Blocks.h */; };
04F94DBB1D229F8D004FC826 /* PKPaymentAuthorizationViewController+Stripe_Blocks.m in Sources */ = {isa = PBXBuildFile; fileRef = C11810941CC6C4700022FB55 /* PKPaymentAuthorizationViewController+Stripe_Blocks.m */; };
04F94DBC1D229F92004FC826 /* UIToolbar+Stripe_InputAccessory.m in Sources */ = {isa = PBXBuildFile; fileRef = 049A3FB11CC9FEFC00F57DE7 /* UIToolbar+Stripe_InputAccessory.m */; };
04F94DBD1D229F95004FC826 /* UITableViewCell+Stripe_Borders.h in Headers */ = {isa = PBXBuildFile; fileRef = 0426B9701CEAE3EB006AC8DD /* UITableViewCell+Stripe_Borders.h */; };
04F94DBE1D229F98004FC826 /* UITableViewCell+Stripe_Borders.m in Sources */ = {isa = PBXBuildFile; fileRef = 0426B9711CEAE3EB006AC8DD /* UITableViewCell+Stripe_Borders.m */; };
04F94DBF1D22A0AA004FC826 /* STPCheckoutAPIClient.h in Headers */ = {isa = PBXBuildFile; fileRef = 04BC29A71CD9A83600318357 /* STPCheckoutAPIClient.h */; };
04F94DC01D22A0AD004FC826 /* STPCheckoutAPIClient.m in Sources */ = {isa = PBXBuildFile; fileRef = 04BC29A81CD9A83600318357 /* STPCheckoutAPIClient.m */; };
04F94DC11D22A0B0004FC826 /* STPCheckoutAPIVerification.h in Headers */ = {isa = PBXBuildFile; fileRef = 04BC29AB1CD9A88600318357 /* STPCheckoutAPIVerification.h */; };
04F94DC21D22A0B8004FC826 /* STPCheckoutAPIVerification.m in Sources */ = {isa = PBXBuildFile; fileRef = 04BC29AC1CD9A88600318357 /* STPCheckoutAPIVerification.m */; };
04F94DC31D22A1F7004FC826 /* STPCheckoutAccount.h in Headers */ = {isa = PBXBuildFile; fileRef = 04BC29AF1CD9AAA800318357 /* STPCheckoutAccount.h */; };
04F94DC41D22A1F9004FC826 /* STPCheckoutAccount.m in Sources */ = {isa = PBXBuildFile; fileRef = 04BC29B01CD9AAA800318357 /* STPCheckoutAccount.m */; };
04F94DC51D22A1FD004FC826 /* STPCheckoutAccountLookup.h in Headers */ = {isa = PBXBuildFile; fileRef = 04BC29B71CDA995000318357 /* STPCheckoutAccountLookup.h */; };
04F94DC61D22A1FF004FC826 /* STPCheckoutAccountLookup.m in Sources */ = {isa = PBXBuildFile; fileRef = 04BC29B81CDA995000318357 /* STPCheckoutAccountLookup.m */; };
04F94DC71D22A204004FC826 /* STPCheckoutBootstrapResponse.h in Headers */ = {isa = PBXBuildFile; fileRef = 04BC29B31CD9AE0000318357 /* STPCheckoutBootstrapResponse.h */; };
04F94DC81D22A207004FC826 /* STPCheckoutBootstrapResponse.m in Sources */ = {isa = PBXBuildFile; fileRef = 04BC29B41CD9AE0000318357 /* STPCheckoutBootstrapResponse.m */; };
04F94DC91D22A20A004FC826 /* STPSwitchTableViewCell.h in Headers */ = {isa = PBXBuildFile; fileRef = 04BC29BB1CDD535700318357 /* STPSwitchTableViewCell.h */; };
04F94DCA1D22A20D004FC826 /* STPSwitchTableViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 04BC29BC1CDD535700318357 /* STPSwitchTableViewCell.m */; };
04F94DCB1D22A229004FC826 /* UIView+Stripe_FirstResponder.h in Headers */ = {isa = PBXBuildFile; fileRef = 049A3F781CC18D5300F57DE7 /* UIView+Stripe_FirstResponder.h */; };
@ -726,10 +690,6 @@
F1D3A25F1EB015B30095BFA9 /* UIImage+StripeTests.m in Sources */ = {isa = PBXBuildFile; fileRef = F1D3A25E1EB015B30095BFA9 /* UIImage+StripeTests.m */; };
F1D3A2651EBA5BAE0095BFA9 /* STPPaymentCardTextField+Private.h in Headers */ = {isa = PBXBuildFile; fileRef = F1D3A2631EBA5BAE0095BFA9 /* STPPaymentCardTextField+Private.h */; };
F1D3A2661EBA5BAE0095BFA9 /* STPPaymentCardTextField+Private.h in Headers */ = {isa = PBXBuildFile; fileRef = F1D3A2631EBA5BAE0095BFA9 /* STPPaymentCardTextField+Private.h */; };
F1D64B291D8767FC001CDB7C /* STPWebViewController.h in Headers */ = {isa = PBXBuildFile; fileRef = F1D64B271D8767FC001CDB7C /* STPWebViewController.h */; };
F1D64B2A1D8767FC001CDB7C /* STPWebViewController.h in Headers */ = {isa = PBXBuildFile; fileRef = F1D64B271D8767FC001CDB7C /* STPWebViewController.h */; };
F1D64B2B1D8767FC001CDB7C /* STPWebViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = F1D64B281D8767FC001CDB7C /* STPWebViewController.m */; };
F1D64B2C1D8767FC001CDB7C /* STPWebViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = F1D64B281D8767FC001CDB7C /* STPWebViewController.m */; };
F1D64B2E1D87686E001CDB7C /* WebKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F1D64B2D1D87686E001CDB7C /* WebKit.framework */; };
F1D765CE1EDE331500F37005 /* CoreLocation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F1D765CD1EDE331500F37005 /* CoreLocation.framework */; settings = {ATTRIBUTES = (Required, ); }; };
F1D777C01D81DD520076FA19 /* STPStringUtilsTest.m in Sources */ = {isa = PBXBuildFile; fileRef = F1D777BF1D81DD520076FA19 /* STPStringUtilsTest.m */; };
@ -950,24 +910,8 @@
04B94BC71A47B78A00092C46 /* AddressBook.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AddressBook.framework; path = System/Library/Frameworks/AddressBook.framework; sourceTree = SDKROOT; };
04BC29A21CD8697900318357 /* STPTheme.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = STPTheme.h; path = PublicHeaders/STPTheme.h; sourceTree = "<group>"; };
04BC29A31CD8697900318357 /* STPTheme.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = STPTheme.m; sourceTree = "<group>"; };
04BC29A71CD9A83600318357 /* STPCheckoutAPIClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = STPCheckoutAPIClient.h; sourceTree = "<group>"; };
04BC29A81CD9A83600318357 /* STPCheckoutAPIClient.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = STPCheckoutAPIClient.m; sourceTree = "<group>"; };
04BC29AB1CD9A88600318357 /* STPCheckoutAPIVerification.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = STPCheckoutAPIVerification.h; sourceTree = "<group>"; };
04BC29AC1CD9A88600318357 /* STPCheckoutAPIVerification.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = STPCheckoutAPIVerification.m; sourceTree = "<group>"; };
04BC29AF1CD9AAA800318357 /* STPCheckoutAccount.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = STPCheckoutAccount.h; sourceTree = "<group>"; };
04BC29B01CD9AAA800318357 /* STPCheckoutAccount.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = STPCheckoutAccount.m; sourceTree = "<group>"; };
04BC29B31CD9AE0000318357 /* STPCheckoutBootstrapResponse.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = STPCheckoutBootstrapResponse.h; sourceTree = "<group>"; };
04BC29B41CD9AE0000318357 /* STPCheckoutBootstrapResponse.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = STPCheckoutBootstrapResponse.m; sourceTree = "<group>"; };
04BC29B71CDA995000318357 /* STPCheckoutAccountLookup.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = STPCheckoutAccountLookup.h; sourceTree = "<group>"; };
04BC29B81CDA995000318357 /* STPCheckoutAccountLookup.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = STPCheckoutAccountLookup.m; sourceTree = "<group>"; };
04BC29BB1CDD535700318357 /* STPSwitchTableViewCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = STPSwitchTableViewCell.h; sourceTree = "<group>"; };
04BC29BC1CDD535700318357 /* STPSwitchTableViewCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = STPSwitchTableViewCell.m; sourceTree = "<group>"; };
04BC29C01CE2A48000318357 /* STPSMSCodeViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = STPSMSCodeViewController.h; sourceTree = "<group>"; };
04BC29C11CE2A48000318357 /* STPSMSCodeViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = STPSMSCodeViewController.m; sourceTree = "<group>"; };
04BC29C41CE2A82300318357 /* STPSMSCodeTextField.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = STPSMSCodeTextField.h; sourceTree = "<group>"; };
04BC29C51CE2A82300318357 /* STPSMSCodeTextField.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = STPSMSCodeTextField.m; sourceTree = "<group>"; };
04BC29C81CE40F7500318357 /* STPObscuredCardView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = STPObscuredCardView.h; sourceTree = "<group>"; };
04BC29C91CE40F7500318357 /* STPObscuredCardView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = STPObscuredCardView.m; sourceTree = "<group>"; };
04BFFFD81D240B13005F2340 /* STPAddCardViewController+Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "STPAddCardViewController+Private.h"; sourceTree = "<group>"; };
04CB86B81BA89CD400E4F61E /* PKPayment+StripeTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "PKPayment+StripeTest.m"; sourceTree = "<group>"; };
04CDB4421A5F2E1800B854EE /* Stripe.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Stripe.framework; sourceTree = BUILT_PRODUCTS_DIR; };
@ -1005,8 +949,6 @@
04E39F511CECF7A100AF3B96 /* STPPaymentMethodTuple.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = STPPaymentMethodTuple.m; sourceTree = "<group>"; };
04E39F561CECF9A800AF3B96 /* STPPaymentMethodsViewController+Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "STPPaymentMethodsViewController+Private.h"; sourceTree = "<group>"; };
04E39F5A1CECFAFD00AF3B96 /* STPPaymentContext+Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "STPPaymentContext+Private.h"; sourceTree = "<group>"; };
04E39F5E1CED2C3900AF3B96 /* STPRememberMeTermsView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = STPRememberMeTermsView.h; sourceTree = "<group>"; };
04E39F5F1CED2C3900AF3B96 /* STPRememberMeTermsView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = STPRememberMeTermsView.m; sourceTree = "<group>"; };
04E39F621CED3B0100AF3B96 /* stp_icon_chevron_right_small.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = stp_icon_chevron_right_small.png; sourceTree = "<group>"; };
04E39F631CED3B0100AF3B96 /* stp_icon_chevron_right_small@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "stp_icon_chevron_right_small@2x.png"; sourceTree = "<group>"; };
04E39F641CED3B0100AF3B96 /* stp_icon_chevron_right_small@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "stp_icon_chevron_right_small@3x.png"; sourceTree = "<group>"; };
@ -1103,9 +1045,9 @@
C15993321D8808680047950D /* STPShippingMethodTableViewCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = STPShippingMethodTableViewCell.m; sourceTree = "<group>"; };
C15B02721EA176090026E606 /* StripeErrorTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = StripeErrorTest.m; sourceTree = "<group>"; };
C16F66AA1CA21BAC006A21B5 /* STPFormTextFieldTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = STPFormTextFieldTest.m; sourceTree = "<group>"; };
C16FC79C1EEB39C3001CBD3A /* STPCustomerContext+Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "STPCustomerContext+Private.h"; sourceTree = "<group>"; };
C1785F5A1EC60B5E00E9CFAC /* STPCardIOProxy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = STPCardIOProxy.h; sourceTree = "<group>"; };
C1785F5B1EC60B5E00E9CFAC /* STPCardIOProxy.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = STPCardIOProxy.m; sourceTree = "<group>"; };
C16FC79C1EEB39C3001CBD3A /* STPCustomerContext+Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "STPCustomerContext+Private.h"; sourceTree = "<group>"; };
C17A030B1CBEE7A2006C819F /* STPAddressFieldTableViewCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = STPAddressFieldTableViewCell.h; sourceTree = "<group>"; };
C17A030C1CBEE7A2006C819F /* STPAddressFieldTableViewCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = STPAddressFieldTableViewCell.m; sourceTree = "<group>"; };
C17D24ED1E37DBAC005CB188 /* STPSourceTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = STPSourceTest.m; sourceTree = "<group>"; };
@ -1233,8 +1175,6 @@
F1D3A2591EB014BD0095BFA9 /* UIImage+Stripe.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIImage+Stripe.m"; sourceTree = "<group>"; };
F1D3A25E1EB015B30095BFA9 /* UIImage+StripeTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIImage+StripeTests.m"; sourceTree = "<group>"; };
F1D3A2631EBA5BAE0095BFA9 /* STPPaymentCardTextField+Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "STPPaymentCardTextField+Private.h"; sourceTree = "<group>"; };
F1D64B271D8767FC001CDB7C /* STPWebViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = STPWebViewController.h; sourceTree = "<group>"; };
F1D64B281D8767FC001CDB7C /* STPWebViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = STPWebViewController.m; sourceTree = "<group>"; };
F1D64B2D1D87686E001CDB7C /* WebKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = WebKit.framework; path = System/Library/Frameworks/WebKit.framework; sourceTree = SDKROOT; };
F1D765CD1EDE331500F37005 /* CoreLocation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreLocation.framework; path = System/Library/Frameworks/CoreLocation.framework; sourceTree = SDKROOT; };
F1D777BF1D81DD520076FA19 /* STPStringUtilsTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = STPStringUtilsTest.m; sourceTree = "<group>"; };
@ -1689,7 +1629,6 @@
045D711E1CEFA57000F6CD65 /* UIViewController+Stripe_Promises.h */,
045D711F1CEFA57000F6CD65 /* UIViewController+Stripe_Promises.m */,
C1A5E5F31ED3A71C00C79B0F /* StripeError+Private.h */,
C1C1B6E71EFC05F800BD1A36 /* StripeError+Private.m */,
);
name = Categories;
sourceTree = "<group>";
@ -1833,16 +1772,6 @@
049A3FAD1CC9AA9900F57DE7 /* STPAddressViewModel.m */,
04E39F4E1CECF7A100AF3B96 /* STPCardTuple.h */,
04E39F4F1CECF7A100AF3B96 /* STPCardTuple.m */,
04BC29AF1CD9AAA800318357 /* STPCheckoutAccount.h */,
04BC29B01CD9AAA800318357 /* STPCheckoutAccount.m */,
04BC29B71CDA995000318357 /* STPCheckoutAccountLookup.h */,
04BC29B81CDA995000318357 /* STPCheckoutAccountLookup.m */,
04BC29A71CD9A83600318357 /* STPCheckoutAPIClient.h */,
04BC29A81CD9A83600318357 /* STPCheckoutAPIClient.m */,
04BC29AB1CD9A88600318357 /* STPCheckoutAPIVerification.h */,
04BC29AC1CD9A88600318357 /* STPCheckoutAPIVerification.m */,
04BC29B31CD9AE0000318357 /* STPCheckoutBootstrapResponse.h */,
04BC29B41CD9AE0000318357 /* STPCheckoutBootstrapResponse.m */,
F1D3A2631EBA5BAE0095BFA9 /* STPPaymentCardTextField+Private.h */,
04B31DD81D09A4DC00EF1631 /* STPPaymentConfiguration+Private.h */,
F12C8DBE1D63DE9F00ADA0D7 /* STPPaymentContextAmountModel.h */,
@ -1939,10 +1868,6 @@
04E39F561CECF9A800AF3B96 /* STPPaymentMethodsViewController+Private.h */,
C159932F1D8808680047950D /* STPShippingMethodsViewController.h */,
C15993301D8808680047950D /* STPShippingMethodsViewController.m */,
04BC29C01CE2A48000318357 /* STPSMSCodeViewController.h */,
04BC29C11CE2A48000318357 /* STPSMSCodeViewController.m */,
F1D64B271D8767FC001CDB7C /* STPWebViewController.h */,
F1D64B281D8767FC001CDB7C /* STPWebViewController.m */,
);
name = "View Controllers";
sourceTree = "<group>";
@ -1963,16 +1888,10 @@
children = (
0438EF261B7416BB00D506CC /* STPFormTextField.h */,
0438EF271B7416BB00D506CC /* STPFormTextField.m */,
04BC29C81CE40F7500318357 /* STPObscuredCardView.h */,
04BC29C91CE40F7500318357 /* STPObscuredCardView.m */,
0438EF2A1B7416BB00D506CC /* STPPaymentCardTextFieldViewModel.h */,
0438EF2B1B7416BB00D506CC /* STPPaymentCardTextFieldViewModel.m */,
04E39F5E1CED2C3900AF3B96 /* STPRememberMeTermsView.h */,
04E39F5F1CED2C3900AF3B96 /* STPRememberMeTermsView.m */,
C158AB3D1E1EE98900348D01 /* STPSectionHeaderView.h */,
C158AB3E1E1EE98900348D01 /* STPSectionHeaderView.m */,
04BC29C41CE2A82300318357 /* STPSMSCodeTextField.h */,
04BC29C51CE2A82300318357 /* STPSMSCodeTextField.m */,
);
name = Views;
sourceTree = "<group>";
@ -2060,7 +1979,6 @@
F1D3A2661EBA5BAE0095BFA9 /* STPPaymentCardTextField+Private.h in Headers */,
F1DEB8911E2052150066B8E8 /* STPCoreScrollViewController.h in Headers */,
C1785F5D1EC60B5E00E9CFAC /* STPCardIOProxy.h in Headers */,
04F94DB51D229F74004FC826 /* STPSMSCodeTextField.h in Headers */,
C1363BB81D7633D800EB82B4 /* STPPaymentMethodTableViewCell.h in Headers */,
C1271A3F1E3FA4EB00F25DFE /* STPSectionHeaderView.h in Headers */,
049E84D91A605EF0000B66CD /* Stripe.h in Headers */,
@ -2094,7 +2012,6 @@
04F94DD31D22A23F004FC826 /* NSBundle+Stripe_AppName.h in Headers */,
C1A5E5F51ED3A71C00C79B0F /* StripeError+Private.h in Headers */,
F1D3A25B1EB014BD0095BFA9 /* UIImage+Stripe.h in Headers */,
04F94DC31D22A1F7004FC826 /* STPCheckoutAccount.h in Headers */,
F1852F941D80B6EC00367C86 /* STPStringUtils.h in Headers */,
049E84EA1A605EF0000B66CD /* STPCard.h in Headers */,
049E84EB1A605EF0000B66CD /* STPToken.h in Headers */,
@ -2102,12 +2019,9 @@
F1FA6F991E25970F00EB444D /* STPCoreTableViewController+Private.h in Headers */,
C1BD9B2F1E3940A200CEE925 /* STPSourceRedirect.h in Headers */,
8B429AD91EF9D4B500F95F34 /* STPBankAccountParams+Private.h in Headers */,
04F94DB01D229F60004FC826 /* STPRememberMeTermsView.h in Headers */,
04F94DBF1D22A0AA004FC826 /* STPCheckoutAPIClient.h in Headers */,
04E32AA01B7A9490009C9E35 /* STPPaymentCardTextField.h in Headers */,
04F94DA81D229F2F004FC826 /* STPPaymentMethodTuple.h in Headers */,
0438EF491B74183100D506CC /* STPCardBrand.h in Headers */,
04F94DB71D229F7C004FC826 /* STPObscuredCardView.h in Headers */,
F12C8DC21D63DE9F00ADA0D7 /* STPPaymentContextAmountModel.h in Headers */,
F1D96F971DC7D82400477E64 /* STPLocalizationUtils.h in Headers */,
049A3FA91CC96B3B00F57DE7 /* STPBackendAPIAdapter.h in Headers */,
@ -2135,11 +2049,7 @@
046FE9A31CE5608000DA6A7B /* STPPaymentActivityIndicatorView.h in Headers */,
F1DEB88B1E2047CA0066B8E8 /* STPCoreTableViewController.h in Headers */,
F1FA6F931E258F6800EB444D /* STPCoreViewController+Private.h in Headers */,
04F94DC71D22A204004FC826 /* STPCheckoutBootstrapResponse.h in Headers */,
04793F571D1D9C0200B3C551 /* STPSourceProtocol.h in Headers */,
F1D64B2A1D8767FC001CDB7C /* STPWebViewController.h in Headers */,
04F94DB21D229F69004FC826 /* STPSMSCodeViewController.h in Headers */,
04F94DC51D22A1FD004FC826 /* STPCheckoutAccountLookup.h in Headers */,
04A4883E1CA3568800506E53 /* STPBlocks.h in Headers */,
045D71211CEFA57000F6CD65 /* UIViewController+Stripe_Promises.h in Headers */,
C159932A1D88084D0047950D /* STPShippingAddressViewController.h in Headers */,
@ -2175,7 +2085,6 @@
045D712D1CF4ED7600F6CD65 /* STPBINRange.h in Headers */,
049E84E71A605EF0000B66CD /* STPFormEncoder.h in Headers */,
C1D7B51B1E36B8B9002181F5 /* STPSourceParams.h in Headers */,
04F94DC11D22A0B0004FC826 /* STPCheckoutAPIVerification.h in Headers */,
04B31DFA1D11AC6400EF1631 /* STPUserInformation.h in Headers */,
C1CFCB681ED4E38900BE45DF /* STPInternalAPIResponseDecodable.h in Headers */,
045D71081CEED3AA00F6CD65 /* STPRememberMeEmailCell.h in Headers */,
@ -2190,7 +2099,6 @@
buildActionMask = 2147483647;
files = (
C15993361D8808680047950D /* STPShippingMethodsViewController.h in Headers */,
04BC29A91CD9A83600318357 /* STPCheckoutAPIClient.h in Headers */,
F1D3A24E1EB012010095BFA9 /* STPMultipartFormDataPart.h in Headers */,
C11810A71CC6EE840022FB55 /* STPBackendAPIAdapter.h in Headers */,
F12C8DC01D63DE9F00ADA0D7 /* STPPaymentContextAmountModel.h in Headers */,
@ -2201,7 +2109,6 @@
045D710E1CEEE30500F6CD65 /* STPAspects.h in Headers */,
C158AB3F1E1EE98900348D01 /* STPSectionHeaderView.h in Headers */,
04EBC7571B7533C300A0E6AE /* STPCardValidator.h in Headers */,
04BC29B91CDA995000318357 /* STPCheckoutAccountLookup.h in Headers */,
046FE9A11CE55D1D00DA6A7B /* STPPaymentActivityIndicatorView.h in Headers */,
C11810861CC6AF4C0022FB55 /* STPPaymentMethod.h in Headers */,
04695AD91C77F9EF00E08063 /* STPDelegateProxy.h in Headers */,
@ -2230,7 +2137,6 @@
C17A030D1CBEE7A2006C819F /* STPAddressFieldTableViewCell.h in Headers */,
C1C1012D1E57A26F00C7BFAE /* STPSource+Private.h in Headers */,
04A4C3891C4F25F900B3B290 /* NSArray+Stripe_BoundSafe.h in Headers */,
04BC29B11CD9AAA800318357 /* STPCheckoutAccount.h in Headers */,
04827D151D257764002DB3E8 /* STPImageLibrary+Private.h in Headers */,
049952D21BCF13DD0088C703 /* STPAPIClient+Private.h in Headers */,
8B429AD81EF9D4B400F95F34 /* STPBankAccountParams+Private.h in Headers */,
@ -2264,9 +2170,7 @@
04695ADB1C77F9EF00E08063 /* STPPhoneNumberValidator.h in Headers */,
F1C7B8D51DBECF2400D9F6F0 /* STPDispatchFunctions.h in Headers */,
0426B9761CEBD001006AC8DD /* UINavigationBar+Stripe_Theme.h in Headers */,
04BC29CA1CE40F7500318357 /* STPObscuredCardView.h in Headers */,
04E39F581CECF9A800AF3B96 /* STPPaymentMethodsViewController+Private.h in Headers */,
04BC29C21CE2A48000318357 /* STPSMSCodeViewController.h in Headers */,
C11810891CC6B00D0022FB55 /* STPApplePayPaymentMethod.h in Headers */,
0426B9721CEAE3EB006AC8DD /* UITableViewCell+Stripe_Borders.h in Headers */,
C1A5E5F41ED3A71C00C79B0F /* StripeError+Private.h in Headers */,
@ -2276,7 +2180,6 @@
F15232241EA9303800D65C67 /* STPURLCallbackHandler.h in Headers */,
C18410761EC2529400178149 /* STPEphemeralKeyManager.h in Headers */,
04F416261CA3639500486FB5 /* STPAddCardViewController.h in Headers */,
F1D64B291D8767FC001CDB7C /* STPWebViewController.h in Headers */,
049880FC1CED5A2300EA4FFD /* STPPaymentConfiguration.h in Headers */,
F1852F931D80B6EC00367C86 /* STPStringUtils.h in Headers */,
049A3FAE1CC9AA9900F57DE7 /* STPAddressViewModel.h in Headers */,
@ -2296,8 +2199,6 @@
8BD87B881EFB131700269C2B /* STPSourceCardDetails+Private.h in Headers */,
8BD87B8D1EFB152B00269C2B /* STPSourceRedirect+Private.h in Headers */,
04CDB4D31A5F30A700B854EE /* Stripe.h in Headers */,
04BC29C61CE2A82300318357 /* STPSMSCodeTextField.h in Headers */,
04E39F601CED2C3900AF3B96 /* STPRememberMeTermsView.h in Headers */,
F1A0197C1EA5733200354301 /* STPSourceParams+Private.h in Headers */,
F19491E71E60DD9C001E1FC2 /* STPSourceSEPADebitDetails.h in Headers */,
F15232201EA92FCF00D65C67 /* STPRedirectContext.h in Headers */,
@ -2307,12 +2208,10 @@
04A4883C1CA3568800506E53 /* STPBlocks.h in Headers */,
F1D3A2511EB0120F0095BFA9 /* STPFile.h in Headers */,
F1FA6F921E258F6800EB444D /* STPCoreViewController+Private.h in Headers */,
04BC29B51CD9AE0000318357 /* STPCheckoutBootstrapResponse.h in Headers */,
045D71201CEFA57000F6CD65 /* UIViewController+Stripe_Promises.h in Headers */,
04793F561D1D8DDD00B3C551 /* STPSourceProtocol.h in Headers */,
0451CC441C49AE1C003B2CA6 /* STPPaymentResult.h in Headers */,
049A3F951CC75B2E00F57DE7 /* STPPromise.h in Headers */,
04BC29AD1CD9A88600318357 /* STPCheckoutAPIVerification.h in Headers */,
049A3F7E1CC1920A00F57DE7 /* UIViewController+Stripe_KeyboardAvoiding.h in Headers */,
04BFFFD91D240B13005F2340 /* STPAddCardViewController+Private.h in Headers */,
C1363BB71D7633D800EB82B4 /* STPPaymentMethodTableViewCell.h in Headers */,
@ -2772,8 +2671,6 @@
C1271A3E1E3FA4E800F25DFE /* STPSectionHeaderView.m in Sources */,
F12829DD1D7747E4008B10D6 /* STPBundleLocator.m in Sources */,
04F94DA91D229F32004FC826 /* STPPaymentMethodTuple.m in Sources */,
04F94DC41D22A1F9004FC826 /* STPCheckoutAccount.m in Sources */,
04F94DB61D229F77004FC826 /* STPSMSCodeTextField.m in Sources */,
F19491E51E60DD72001E1FC2 /* STPSourceSEPADebitDetails.m in Sources */,
C1785F5F1EC60B5E00E9CFAC /* STPCardIOProxy.m in Sources */,
0438EF311B7416BB00D506CC /* STPFormTextField.m in Sources */,
@ -2785,7 +2682,6 @@
04F94DAC1D229F42004FC826 /* UIBarButtonItem+Stripe.m in Sources */,
F1DEB88D1E2047CA0066B8E8 /* STPCoreTableViewController.m in Sources */,
F1C7B8D41DBECF2400D9F6F0 /* STPDispatchFunctions.m in Sources */,
04F94DB11D229F64004FC826 /* STPRememberMeTermsView.m in Sources */,
04633B141CD45215009D4FB5 /* PKPayment+Stripe.m in Sources */,
04633AFF1CD129C0009D4FB5 /* NSString+Stripe.m in Sources */,
04633B021CD129D0009D4FB5 /* STPDelegateProxy.m in Sources */,
@ -2795,7 +2691,6 @@
04F94DCE1D22A232004FC826 /* UIViewController+Stripe_KeyboardAvoiding.m in Sources */,
04B31E021D131D9000EF1631 /* STPRememberMePaymentCell.m in Sources */,
C1D7B5231E36C32F002181F5 /* STPSource.m in Sources */,
04F94DC21D22A0B8004FC826 /* STPCheckoutAPIVerification.m in Sources */,
04A4C3901C4F25F900B3B290 /* UIViewController+Stripe_ParentViewController.m in Sources */,
04F94DA01D229F0B004FC826 /* STPPostalCodeValidator.m in Sources */,
C124A17F1CCAA0C2007D42EE /* NSMutableURLRequest+Stripe.m in Sources */,
@ -2806,14 +2701,11 @@
C113D21C1EBB9A36006FACC2 /* STPEphemeralKey.m in Sources */,
04F94DAE1D229F54004FC826 /* STPColorUtils.m in Sources */,
C1D7B51D1E36B8B9002181F5 /* STPSourceParams.m in Sources */,
04F94DC01D22A0AD004FC826 /* STPCheckoutAPIClient.m in Sources */,
C124A1731CCA968B007D42EE /* STPAnalyticsClient.m in Sources */,
04F94DCC1D22A22C004FC826 /* UIView+Stripe_FirstResponder.m in Sources */,
F1D3A2571EB012350095BFA9 /* STPMultipartFormDataPart.m in Sources */,
F1DEB8931E2052150066B8E8 /* STPCoreScrollViewController.m in Sources */,
04F94DC81D22A207004FC826 /* STPCheckoutBootstrapResponse.m in Sources */,
04F94D9E1D229F05004FC826 /* STPEmailAddressValidator.m in Sources */,
04F94DC61D22A1FF004FC826 /* STPCheckoutAccountLookup.m in Sources */,
04F94DD21D22A23C004FC826 /* STPPromise.m in Sources */,
0438EF371B7416BB00D506CC /* STPPaymentCardTextField.m in Sources */,
049E84CC1A605DE0000B66CD /* STPAPIClient.m in Sources */,
@ -2836,7 +2728,6 @@
04F94DA21D229F14004FC826 /* STPAddressFieldTableViewCell.m in Sources */,
049A3FB71CCA6B8900F57DE7 /* STPAddress.m in Sources */,
04F94DD41D22A242004FC826 /* NSBundle+Stripe_AppName.m in Sources */,
C1C1B6E91EFC05F800BD1A36 /* StripeError+Private.m in Sources */,
F152321E1EA92FC100D65C67 /* STPRedirectContext.m in Sources */,
C126553A1CAA2392006F7265 /* STPAddCardViewController.m in Sources */,
04633B151CD4521F009D4FB5 /* STPAPIClient+ApplePay.m in Sources */,
@ -2845,9 +2736,7 @@
04F94DD01D22A236004FC826 /* NSDecimalNumber+Stripe_Currency.m in Sources */,
F1852F961D80B6EC00367C86 /* STPStringUtils.m in Sources */,
04F94DBC1D229F92004FC826 /* UIToolbar+Stripe_InputAccessory.m in Sources */,
04F94DB81D229F7F004FC826 /* STPObscuredCardView.m in Sources */,
F15232271EA9303800D65C67 /* STPURLCallbackHandler.m in Sources */,
04F94DB31D229F6D004FC826 /* STPSMSCodeViewController.m in Sources */,
C18410791EC2529400178149 /* STPEphemeralKeyManager.m in Sources */,
04F94DB41D229F71004FC826 /* STPPaymentActivityIndicatorView.m in Sources */,
C1BD9B251E393FFE00CEE925 /* STPSourceReceiver.m in Sources */,
@ -2871,7 +2760,6 @@
C192268A1EBA228900BED563 /* STPTelemetryClient.m in Sources */,
045D71231CEFA57000F6CD65 /* UIViewController+Stripe_Promises.m in Sources */,
04BC29A11CD8412000318357 /* STPPaymentContext.m in Sources */,
F1D64B2C1D8767FC001CDB7C /* STPWebViewController.m in Sources */,
04CDE5C71BC20AF800548833 /* STPBankAccountParams.m in Sources */,
C1363BBA1D7633D800EB82B4 /* STPPaymentMethodTableViewCell.m in Sources */,
);
@ -2883,9 +2771,7 @@
files = (
0438EF431B74170D00D506CC /* STPCardValidator.m in Sources */,
F19491DB1E5F606F001E1FC2 /* STPSourceCardDetails.m in Sources */,
04BC29AE1CD9A88600318357 /* STPCheckoutAPIVerification.m in Sources */,
0426B9781CEBD001006AC8DD /* UINavigationBar+Stripe_Theme.m in Sources */,
04BC29C31CE2A48000318357 /* STPSMSCodeViewController.m in Sources */,
C180211C1E3A58710089D712 /* STPSourcePoller.m in Sources */,
C17A030E1CBEE7A2006C819F /* STPAddressFieldTableViewCell.m in Sources */,
049A3F921CC740FF00F57DE7 /* NSDecimalNumber+Stripe_Currency.m in Sources */,
@ -2904,7 +2790,6 @@
04CDB5001A5F30A700B854EE /* STPAPIClient.m in Sources */,
C18410781EC2529400178149 /* STPEphemeralKeyManager.m in Sources */,
04CDB50C1A5F30A700B854EE /* STPBankAccount.m in Sources */,
04E39F611CED2C3900AF3B96 /* STPRememberMeTermsView.m in Sources */,
049A3F7F1CC1920A00F57DE7 /* UIViewController+Stripe_KeyboardAvoiding.m in Sources */,
04F416271CA3639500486FB5 /* STPAddCardViewController.m in Sources */,
C1FEE5971CBFF11400A7632B /* STPPostalCodeValidator.m in Sources */,
@ -2930,14 +2815,11 @@
C192269F1EBA9A0800BED563 /* STPCustomerContext.m in Sources */,
0426B9731CEAE3EB006AC8DD /* UITableViewCell+Stripe_Borders.m in Sources */,
C1BD9B241E393FFE00CEE925 /* STPSourceReceiver.m in Sources */,
04BC29B21CD9AAA800318357 /* STPCheckoutAccount.m in Sources */,
04BC29CB1CE40F7500318357 /* STPObscuredCardView.m in Sources */,
04B31DD61D08E6E200EF1631 /* STPCustomer.m in Sources */,
0438EF351B7416BB00D506CC /* STPPaymentCardTextField.m in Sources */,
045D71091CEED3AA00F6CD65 /* STPRememberMeEmailCell.m in Sources */,
F1D3A24F1EB012010095BFA9 /* STPMultipartFormDataPart.m in Sources */,
04827D121D2575C6002DB3E8 /* STPImageLibrary.m in Sources */,
F1D64B2B1D8767FC001CDB7C /* STPWebViewController.m in Sources */,
04CDB5041A5F30A700B854EE /* STPFormEncoder.m in Sources */,
0426B96F1CEADC98006AC8DD /* STPColorUtils.m in Sources */,
04E39F531CECF7A100AF3B96 /* STPCardTuple.m in Sources */,
@ -2951,7 +2833,6 @@
04A4C38B1C4F25F900B3B290 /* NSArray+Stripe_BoundSafe.m in Sources */,
F19491E41E60DD72001E1FC2 /* STPSourceSEPADebitDetails.m in Sources */,
04A4C38F1C4F25F900B3B290 /* UIViewController+Stripe_ParentViewController.m in Sources */,
04BC29AA1CD9A83600318357 /* STPCheckoutAPIClient.m in Sources */,
049A3FAF1CC9AA9900F57DE7 /* STPAddressViewModel.m in Sources */,
04695ADC1C77F9EF00E08063 /* STPPhoneNumberValidator.m in Sources */,
C1785F5E1EC60B5E00E9CFAC /* STPCardIOProxy.m in Sources */,
@ -2972,17 +2853,13 @@
0451CC461C49AE1C003B2CA6 /* STPPaymentResult.m in Sources */,
04E39F551CECF7A100AF3B96 /* STPPaymentMethodTuple.m in Sources */,
C11810961CC6C4700022FB55 /* PKPaymentAuthorizationViewController+Stripe_Blocks.m in Sources */,
04BC29B61CD9AE0000318357 /* STPCheckoutBootstrapResponse.m in Sources */,
04BC29C71CE2A82300318357 /* STPSMSCodeTextField.m in Sources */,
0439B9891C454F97005A1ED5 /* STPPaymentMethodsViewController.m in Sources */,
04A488441CA3580700506E53 /* UINavigationController+Stripe_Completion.m in Sources */,
049A3F961CC75B2E00F57DE7 /* STPPromise.m in Sources */,
04695AD41C77F9DB00E08063 /* NSString+Stripe.m in Sources */,
04BC29BA1CDA995000318357 /* STPCheckoutAccountLookup.m in Sources */,
F15232261EA9303800D65C67 /* STPURLCallbackHandler.m in Sources */,
049952D01BCF13510088C703 /* STPAPIRequest.m in Sources */,
F1D3A24B1EB012010095BFA9 /* STPFile.m in Sources */,
C1C1B6E81EFC05F800BD1A36 /* StripeError+Private.m in Sources */,
049A3F9A1CC76A2400F57DE7 /* NSBundle+Stripe_AppName.m in Sources */,
049A3F7B1CC18D5300F57DE7 /* UIView+Stripe_FirstResponder.m in Sources */,
04CDE5C51BC20AF800548833 /* STPBankAccountParams.m in Sources */,

View File

@ -70,12 +70,6 @@ NS_ASSUME_NONNULL_BEGIN
* The Apple Merchant Identifier to use during Apple Pay transactions. To create one of these, see our guide at https://stripe.com/docs/mobile/apple-pay . You must set this to a valid identifier in order to automatically enable Apple Pay.
*/
@property(nonatomic, nullable, copy)NSString *appleMerchantIdentifier;
/**
* When entering their payment information, users who have a saved card with Stripe will be prompted to autofill it by entering an SMS code. Set this property to `YES` to disable this feature. The user won't receive an SMS code even if they have their payment information stored with Stripe, and won't be prompted to save it if they don't.
*/
@property(nonatomic)BOOL smsAutofillDisabled;
@end
NS_ASSUME_NONNULL_END

View File

@ -13,7 +13,6 @@
#import "STPAddressViewModel.h"
#import "STPAnalyticsClient.h"
#import "STPCardIOProxy.h"
#import "STPCheckoutAPIClient.h"
#import "STPColorUtils.h"
#import "STPCoreTableViewController+Private.h"
#import "STPDispatchFunctions.h"
@ -21,17 +20,13 @@
#import "STPImageLibrary+Private.h"
#import "STPImageLibrary.h"
#import "STPLocalizationUtils.h"
#import "STPObscuredCardView.h"
#import "STPPaymentActivityIndicatorView.h"
#import "STPPaymentCardTextField.h"
#import "STPPaymentConfiguration+Private.h"
#import "STPPhoneNumberValidator.h"
#import "STPRememberMeEmailCell.h"
#import "STPRememberMePaymentCell.h"
#import "STPRememberMeTermsView.h"
#import "STPSectionHeaderView.h"
#import "STPSMSCodeViewController.h"
#import "STPSwitchTableViewCell.h"
#import "STPToken.h"
#import "STPWeakStrongMacros.h"
#import "StripeError.h"
@ -47,14 +42,10 @@
@interface STPAddCardViewController ()<
STPAddressViewModelDelegate,
STPAddressFieldTableViewCellDelegate,
STPCardIOProxyDelegate,
STPPaymentCardTextFieldDelegate,
STPSwitchTableViewCellDelegate,
UITableViewDelegate,
UITableViewDataSource,
STPSMSCodeViewControllerDelegate,
STPRememberMePaymentCellDelegate>
UITableViewDataSource>
@property(nonatomic)STPPaymentConfiguration *configuration;
@property(nonatomic)STPAddress *shippingAddress;
@ -65,34 +56,21 @@
@property(nonatomic)STPSectionHeaderView *cardHeaderView;
@property(nonatomic)STPCardIOProxy *cardIOProxy;
@property(nonatomic)STPSectionHeaderView *addressHeaderView;
@property(nonatomic)STPRememberMeEmailCell *emailCell;
@property(nonatomic)STPSwitchTableViewCell *rememberMeCell;
@property(nonatomic)STPAddressFieldTableViewCell *rememberMePhoneCell;
@property(nonatomic)STPRememberMePaymentCell *paymentCell;
@property(nonatomic)BOOL loading;
@property(nonatomic)STPPaymentActivityIndicatorView *activityIndicator;
@property(nonatomic, weak)STPPaymentActivityIndicatorView *lookupActivityIndicator;
@property(nonatomic)STPAddressViewModel *addressViewModel;
@property(nonatomic)UIToolbar *inputAccessoryToolbar;
@property(nonatomic)STPCheckoutAPIClient *checkoutAPIClient;
@property(nonatomic)STPCheckoutAccount *checkoutAccount;
@property(nonatomic)STPCheckoutAccountLookup *checkoutLookup;
@property(nonatomic)STPCard *checkoutAccountCard;
@property(nonatomic)BOOL lookupSucceeded;
@property(nonatomic)STPRememberMeTermsView *rememberMeTermsView;
@property(nonatomic)BOOL showingRememberMePhoneAndTerms;
#ifdef STRIPE_UNIT_TESTS_ENABLED
@property(nonatomic)BOOL forceEnableRememberMeForTesting;
#endif
@end
static NSString *const STPPaymentCardCellReuseIdentifier = @"STPPaymentCardCellReuseIdentifier";
typedef NS_ENUM(NSUInteger, STPPaymentCardSection) {
STPPaymentCardEmailSection = 0,
STPPaymentCardNumberSection = 1,
STPPaymentCardBillingAddressSection = 2,
STPPaymentCardRememberMeSection = 3
STPPaymentCardNumberSection = 0,
STPPaymentCardBillingAddressSection = 1,
};
@implementation STPAddCardViewController
@ -116,7 +94,6 @@ typedef NS_ENUM(NSUInteger, STPPaymentCardSection) {
_apiClient = [[STPAPIClient alloc] initWithConfiguration:configuration];
_addressViewModel = [[STPAddressViewModel alloc] initWithRequiredBillingFields:configuration.requiredBillingAddressFields];
_addressViewModel.delegate = self;
_checkoutAPIClient = [[STPCheckoutAPIClient alloc] initWithPublishableKey:configuration.publishableKey];
self.title = STPLocalizedString(@"Add a Card", @"Title for Add a Card view");
}
@ -134,7 +111,6 @@ typedef NS_ENUM(NSUInteger, STPPaymentCardSection) {
cardImageView.frame = CGRectMake(0, 0, self.view.bounds.size.width, cardImageView.bounds.size.height + (57 * 2));
self.cardImageView = cardImageView;
self.tableView.tableHeaderView = cardImageView;
self.emailCell = [[STPRememberMeEmailCell alloc] initWithDelegate:self];
STPRememberMePaymentCell *paymentCell = [[STPRememberMePaymentCell alloc] init];
paymentCell.paymentField.delegate = self;
@ -145,21 +121,6 @@ typedef NS_ENUM(NSUInteger, STPPaymentCardSection) {
}
self.addressViewModel.previousField = paymentCell;
self.rememberMeCell = [[STPSwitchTableViewCell alloc] init];
[self.rememberMeCell configureWithLabel:STPLocalizedString(@"Save for use in other apps", @"Label for the switch to enable Remember Me") delegate:self];
[self reloadRememberMeCellAnimated:NO];
self.rememberMePhoneCell = [[STPAddressFieldTableViewCell alloc] initWithType:STPAddressFieldTypePhone contents:nil lastInList:YES delegate:self];
self.rememberMePhoneCell.caption = STPLocalizedString(@"Phone", nil);
self.rememberMeTermsView = [STPRememberMeTermsView new];
self.rememberMeTermsView.textView.alpha = 0;
WEAK(self);
self.rememberMeTermsView.pushViewControllerBlock = ^(UIViewController *vc) {
STRONG(self);
[self.navigationController pushViewController:vc animated:YES];
};
self.activityIndicator = [[STPPaymentActivityIndicatorView alloc] initWithFrame:CGRectMake(0, 0, 20.0f, 20.0f)];
self.inputAccessoryToolbar = [UIToolbar stp_inputAccessoryToolbarWithTarget:self action:@selector(paymentFieldNextTapped)];
@ -198,11 +159,6 @@ typedef NS_ENUM(NSUInteger, STPPaymentCardSection) {
[self.view addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(endEditing)]];
[self.checkoutAPIClient.bootstrapPromise onCompletion:^(__unused id value, __unused NSError *error) {
STRONG(self);
[self reloadRememberMeCellAnimated:YES];
}];
[self setUpCardScanningIfAvailable];
[[STPAnalyticsClient sharedClient] clearAdditionalInfo];
@ -243,39 +199,15 @@ typedef NS_ENUM(NSUInteger, STPPaymentCardSection) {
self.cardImageView.tintColor = self.theme.accentColor;
self.activityIndicator.tintColor = self.theme.accentColor;
self.emailCell.theme = self.theme;
self.paymentCell.theme = self.theme;
for (STPAddressFieldTableViewCell *cell in self.addressViewModel.addressCells) {
cell.theme = self.theme;
}
self.rememberMeCell.theme = self.theme;
self.rememberMePhoneCell.theme = self.theme;
self.rememberMeTermsView.theme = self.theme;
[self reloadRememberMeSectionForFooterSizeChangeIfNecessary];
[self setNeedsStatusBarAppearanceUpdate];
}
- (void)viewDidLayoutSubviews {
[super viewDidLayoutSubviews];
[self reloadRememberMeSectionForFooterSizeChangeIfNecessary];
}
- (void)reloadRememberMeSectionForFooterSizeChangeIfNecessary {
if (self.showingRememberMePhoneAndTerms
&& self.rememberMeTermsView.superview != nil) {
// This should force the table to recalc all of its heights
// And therefore render the footer appropriately if its height changed
[self.tableView beginUpdates];
[self.tableView endUpdates];
}
}
- (void)setLoading:(BOOL)loading {
if (loading == _loading) {
return;
@ -292,7 +224,7 @@ typedef NS_ENUM(NSUInteger, STPPaymentCardSection) {
[self.stp_navigationItemProxy setRightBarButtonItem:self.doneItem animated:YES];
}
NSArray *cells = self.addressViewModel.addressCells;
for (UITableViewCell *cell in [cells arrayByAddingObjectsFromArray:@[self.emailCell, self.paymentCell, self.rememberMeCell, self.rememberMePhoneCell]] ) {
for (UITableViewCell *cell in [cells arrayByAddingObject:self.paymentCell]) {
cell.userInteractionEnabled = !loading;
[UIView animateWithDuration:0.1f animations:^{
cell.alpha = loading ? 0.7f : 1.0f;
@ -300,11 +232,6 @@ typedef NS_ENUM(NSUInteger, STPPaymentCardSection) {
}
}
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[self reloadRememberMeCellAnimated:NO];
}
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
[self stp_beginObservingKeyboardAndInsettingScrollView:self.tableView
@ -313,9 +240,7 @@ typedef NS_ENUM(NSUInteger, STPPaymentCardSection) {
}
- (UIResponder *)firstEmptyField {
if (!self.emailCell.contents && !self.configuration.smsAutofillDisabled) {
return self.emailCell;
}
if (self.paymentCell.isEmpty) {
return self.paymentCell;
}
@ -336,68 +261,12 @@ typedef NS_ENUM(NSUInteger, STPPaymentCardSection) {
STPCardParams *cardParams = self.paymentCell.paymentField.cardParams;
cardParams.address = self.addressViewModel.address;
cardParams.currency = self.managedAccountCurrency;
if (self.checkoutAccountCard) {
WEAK(self);
[[[self.checkoutAPIClient createTokenWithAccount:self.checkoutAccount] onSuccess:^(STPToken *token) {
STRONG(self);
[[STPAnalyticsClient sharedClient] logRememberMeConversion:STPAddCardRememberMeUsageAddedFromSMS];
[self.delegate addCardViewController:self didCreateToken:token completion:^(NSError * _Nullable error) {
stpDispatchToMainThreadIfNecessary(^{
if (error) {
[self handleCheckoutTokenError:error];
}
else {
self.loading = NO;
}
});
}];
}] onFailure:^(NSError *error) {
STRONG(self);
[self handleCardTokenError:error];
}];
} else if (cardParams) {
if (cardParams) {
[self.apiClient createTokenWithCard:cardParams completion:^(STPToken *token, NSError *tokenError) {
if (tokenError) {
[self handleCardTokenError:tokenError];
} else {
NSString *phone = self.rememberMePhoneCell.contents;
NSString *email = self.emailCell.contents;
/**
Remember me button usage segmented into following categories:
1. User saw the toggle, selected it, and entered valid email/phone details
2. User saw the toggle, and did not select it or entered invalid details
3. User did not see the toggle because the developer disabled it
4. User did not see the toggle because the developer enabled it but they were otherwise ineligible
(eg payment context flow disables if you already have >0 payment methods,
or you had a cancelled SMS fill)
5. User saw the email field and added card by SMS code from a previous Remember Me save
*/
STPAddCardRememberMeUsage rememberMeUsage;
if (![self rememberMeCellIsDisabled]) {
if (self.showingRememberMePhoneAndTerms
&& [STPEmailAddressValidator stringIsValidEmailAddress:email]
&& [STPPhoneNumberValidator stringIsValidPhoneNumber:phone]) {
rememberMeUsage = STPAddCardRememberMeUsageSelected;
}
else {
rememberMeUsage = STPAddCardRememberMeUsageNotSelected;
}
}
else {
if (self.configuration.smsAutofillDisabled
&& !self.configuration.ineligibleForSmsAutofill) {
rememberMeUsage = STPAddCardRememberMeUsageDeveloperDisabled;
}
else {
rememberMeUsage = STPAddCardRememberMeUsageIneligible;
}
}
[[STPAnalyticsClient sharedClient] logRememberMeConversion:rememberMeUsage];
if (rememberMeUsage == STPAddCardRememberMeUsageSelected) {
[self.checkoutAPIClient createAccountWithCardParams:cardParams email:email phone:phone];
}
}
else {
[self.delegate addCardViewController:self didCreateToken:token completion:^(NSError * _Nullable error) {
stpDispatchToMainThreadIfNecessary(^{
if (error) {
@ -413,22 +282,6 @@ typedef NS_ENUM(NSUInteger, STPPaymentCardSection) {
}
}
- (void)handleCheckoutTokenError:(__unused NSError *)error {
self.loading = NO;
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:STPLocalizedString(@"There was an error submitting your autofilled card details.", nil)
message:nil
preferredStyle:UIAlertControllerStyleAlert];
[alertController addAction:[UIAlertAction actionWithTitle:STPLocalizedString(@"Enter card details manually", nil)
style:UIAlertActionStyleDefault
handler:^(UIAlertAction * _Nonnull __unused action) {
[self.paymentCell clear];
}]];
[self presentViewController:alertController animated:YES completion:nil];
}
- (void)handleCardTokenError:(NSError *)error {
self.loading = NO;
[[self firstEmptyField] becomeFirstResponder];
@ -444,33 +297,10 @@ typedef NS_ENUM(NSUInteger, STPPaymentCardSection) {
[self presentViewController:alertController animated:YES completion:nil];
}
- (void)setCheckoutAccountCard:(STPCard *)checkoutAccountCard {
_checkoutAccountCard = checkoutAccountCard;
[self updateDoneButton];
}
- (void)updateDoneButton {
self.stp_navigationItemProxy.rightBarButtonItem.enabled = (self.paymentCell.paymentField.isValid || self.checkoutAccountCard) &&
self.addressViewModel.isValid &&
(self.configuration.smsAutofillDisabled || [STPEmailAddressValidator stringIsValidEmailAddress:self.emailCell.contents]);
}
- (void)smsCodeViewControllerDidCancel:(__unused STPSMSCodeViewController *)smsCodeViewController {
[self reloadRememberMeCellAnimated:NO];
[self dismissViewControllerAnimated:YES completion:nil];
}
- (void)smsCodeViewController:(__unused STPSMSCodeViewController *)smsCodeViewController didAuthenticateAccount:(STPCheckoutAccount *)account {
self.checkoutAccount = account;
self.checkoutAccountCard = account.card;
[self reloadRememberMeCellAnimated:NO];
[self.paymentCell configureWithCard:account.card];
self.addressViewModel.address = account.card.address;
[self dismissViewControllerAnimated:YES completion:nil];
}
- (void)paymentCellDidClear:(__unused STPRememberMePaymentCell *)cell {
self.checkoutAccountCard = nil;
self.stp_navigationItemProxy.rightBarButtonItem.enabled = (self.paymentCell.paymentField.isValid
&& self.addressViewModel.isValid
);
}
#pragma mark - STPPaymentCardTextField
@ -518,149 +348,18 @@ typedef NS_ENUM(NSUInteger, STPPaymentCardSection) {
[self updateDoneButton];
}
- (void)addressFieldTableViewCellDidReturn:(STPAddressFieldTableViewCell *)cell {
if (cell == self.emailCell) {
[self.paymentCell becomeFirstResponder];
}
}
- (void)addressFieldTableViewCellDidUpdateText:(STPAddressFieldTableViewCell *)cell {
if (cell == self.emailCell) {
[self lookupAndSendSMS:cell.contents];
[self updateDoneButton];
}
}
- (void)lookupAndSendSMS:(NSString *)email {
if (self.checkoutAccount || self.configuration.smsAutofillDisabled || self.lookupSucceeded) {
return;
}
WEAK(self);
if ([STPEmailAddressValidator stringIsValidEmailAddress:email]) {
[self.emailCell.activityIndicator setAnimating:YES animated:YES];
[[[[self.stp_didAppearPromise voidFlatMap:^STPPromise * _Nonnull{
STRONG(self);
return [self.checkoutAPIClient lookupEmail:email];
}] flatMap:^STPPromise * _Nonnull(STPCheckoutAccountLookup *lookup) {
STRONG(self);
self.lookupSucceeded = YES;
self.checkoutLookup = lookup;
return [self.checkoutAPIClient sendSMSToAccountWithEmail:lookup.email];
}] onSuccess:^(STPCheckoutAPIVerification *verification) {
STRONG(self);
STPSMSCodeViewController *codeViewController = [[STPSMSCodeViewController alloc] initWithCheckoutAPIClient:self.checkoutAPIClient
verification:verification
redactedPhone:self.checkoutLookup.redactedPhone];
codeViewController.theme = self.theme;
codeViewController.delegate = self;
UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:codeViewController];
nav.navigationBar.stp_theme = self.theme;
nav.modalPresentationStyle = UIModalPresentationFormSheet;
[self presentViewController:nav animated:YES completion:nil];
}] onCompletion:^(__unused id value, NSError *error) {
STRONG(self);
if (![error stp_isURLSessionCancellationError]) {
[self.emailCell.activityIndicator setAnimating:NO animated:YES];
}
}];
}
}
- (void)addressFieldTableViewCellDidBackspaceOnEmpty:(__unused STPAddressFieldTableViewCell *)cell {
// this is the email cell; do nothing.
}
- (void)switchTableViewCell:(STPSwitchTableViewCell *)cell didToggleSwitch:(BOOL)on {
self.showingRememberMePhoneAndTerms = on;
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:1
inSection:STPPaymentCardRememberMeSection];
[self.tableView beginUpdates];
if (on) {
[self.tableView insertRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationTop];
} else {
[self.tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationTop];
}
[self.tableView endUpdates];
[UIView animateWithDuration:0.1 animations:^{
self.rememberMeTermsView.textView.alpha = on ? 1.0f : 0.0f;
}];
// This updates the section borders so they're not drawn in both cells.
NSIndexPath *switchIndexPath = [self.tableView indexPathForCell:cell];
[self tableView:self.tableView willDisplayCell:cell forRowAtIndexPath:switchIndexPath];
if (on) {
[self.rememberMePhoneCell becomeFirstResponder];
}
}
#pragma mark - UITableView
#ifdef STRIPE_UNIT_TESTS_ENABLED
/**
This method/property is used by unit tests to force the view into having remember me
being enabled for snapshot testing purposes.
It also bypasses the checks for seeing if the remember me switch
can be show below in `reloadRememberMeCellAnimated`
*/
- (void)setForceEnableRememberMeForTesting:(BOOL)forceEnableRememberMeForTesting {
// force view load
__unused UIView *view = self.view;
[self.tableView setNeedsLayout];
[self.tableView layoutIfNeeded];
_forceEnableRememberMeForTesting = forceEnableRememberMeForTesting;
[self reloadRememberMeCellAnimated:NO];
self.rememberMeCell.on = forceEnableRememberMeForTesting;
[self switchTableViewCell:self.rememberMeCell didToggleSwitch:forceEnableRememberMeForTesting];
}
#endif
- (BOOL)rememberMeCellIsDisabled {
return ((!self.checkoutAPIClient.readyForLookups
|| self.checkoutAccount
|| self.configuration.smsAutofillDisabled
|| self.lookupSucceeded
|| self.managedAccountCurrency)
&& (self.rememberMePhoneCell.contentView.alpha < FLT_EPSILON
|| self.rememberMePhoneCell.superview == nil));
}
- (void)reloadRememberMeCellAnimated:(BOOL)animated {
BOOL disabled = [self rememberMeCellIsDisabled];
#ifdef STRIPE_UNIT_TESTS_ENABLED
if (self.forceEnableRememberMeForTesting) {
disabled = NO;
}
#endif
[UIView animateWithDuration:(0.2f * animated) animations:^{
self.rememberMeCell.contentView.alpha = disabled ? 0 : 1;
} completion:^(__unused BOOL finished) {
[self tableView:self.tableView willDisplayCell:self.rememberMeCell forRowAtIndexPath:[self.tableView indexPathForCell:self.rememberMeCell]];
}];
}
- (NSInteger)numberOfSectionsInTableView:(__unused UITableView *)tableView {
return 4;
return 2;
}
- (NSInteger)tableView:(__unused UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
if (section == STPPaymentCardEmailSection) {
if (self.configuration.smsAutofillDisabled) {
return 0;
}
if (section == STPPaymentCardNumberSection) {
return 1;
}
else if (section == STPPaymentCardNumberSection) {
return 1;
} else if (section == STPPaymentCardBillingAddressSection) {
else if (section == STPPaymentCardBillingAddressSection) {
return self.addressViewModel.addressCells.count;
} else if (section == STPPaymentCardRememberMeSection) {
return self.showingRememberMePhoneAndTerms ? 2 : 1;
}
return 0;
}
@ -669,21 +368,12 @@ typedef NS_ENUM(NSUInteger, STPPaymentCardSection) {
cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell;
switch (indexPath.section) {
case STPPaymentCardEmailSection:
return self.emailCell;
case STPPaymentCardNumberSection:
cell = self.paymentCell;
break;
case STPPaymentCardBillingAddressSection:
cell = [self.addressViewModel.addressCells stp_boundSafeObjectAtIndex:indexPath.row];
break;
case STPPaymentCardRememberMeSection:
if (indexPath.row == 0) {
cell = self.rememberMeCell;
} else {
cell = self.rememberMePhoneCell;
}
break;
default:
return [UITableViewCell new]; // won't be called; exists to make the static analyzer happy
}
@ -703,10 +393,7 @@ typedef NS_ENUM(NSUInteger, STPPaymentCardSection) {
}
- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section {
if (section == STPPaymentCardRememberMeSection
&& self.showingRememberMePhoneAndTerms) {
return [self.rememberMeTermsView heightForWidth:CGRectGetWidth(self.tableView.frame)];
} else if ([self tableView:tableView numberOfRowsInSection:section] == 0) {
if ([self tableView:tableView numberOfRowsInSection:section] == 0) {
return 0.01f;
}
return 27.0f;
@ -715,22 +402,18 @@ typedef NS_ENUM(NSUInteger, STPPaymentCardSection) {
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
CGSize fittingSize = CGSizeMake(self.view.bounds.size.width, CGFLOAT_MAX);
NSInteger numberOfRows = [self tableView:tableView numberOfRowsInSection:section];
if (section == STPPaymentCardEmailSection) {
return 0.01f;
} else if (section == STPPaymentCardNumberSection) {
if (section == STPPaymentCardNumberSection) {
return [self.cardHeaderView sizeThatFits:fittingSize].height;
} else if (section == STPPaymentCardBillingAddressSection && numberOfRows != 0) {
return [self.addressHeaderView sizeThatFits:fittingSize].height;
} else if (section == STPPaymentCardRememberMeSection || numberOfRows != 0) {
} else if (numberOfRows != 0) {
return tableView.sectionHeaderHeight;
}
return 0.01f;
}
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
if (section == STPPaymentCardEmailSection || section == STPPaymentCardRememberMeSection) {
return [UIView new];
} else if ([self tableView:tableView numberOfRowsInSection:section] == 0) {
if ([self tableView:tableView numberOfRowsInSection:section] == 0) {
return [UIView new];
} else {
if (section == STPPaymentCardNumberSection) {
@ -742,13 +425,8 @@ typedef NS_ENUM(NSUInteger, STPPaymentCardSection) {
return nil;
}
- (UIView *)tableView:(__unused UITableView *)tableView viewForFooterInSection:(NSInteger)section {
if (section == STPPaymentCardRememberMeSection) {
return self.rememberMeTermsView;
}
else {
return [UIView new];
}
- (UIView *)tableView:(__unused UITableView *)tableView viewForFooterInSection:(__unused NSInteger)section {
return [UIView new];
}
- (void)useShippingAddress:(__unused UIButton *)sender {

View File

@ -11,14 +11,6 @@
@class STPPaymentConfiguration, STPToken;
@protocol STPFormEncodable;
typedef NS_ENUM(NSUInteger, STPAddCardRememberMeUsage) {
STPAddCardRememberMeUsageNotSelected = 0,
STPAddCardRememberMeUsageSelected = 1,
STPAddCardRememberMeUsageDeveloperDisabled = 2,
STPAddCardRememberMeUsageIneligible = 3,
STPAddCardRememberMeUsageAddedFromSMS = 4,
};
@interface STPAnalyticsClient : NSObject
+ (instancetype)sharedClient;
@ -31,8 +23,6 @@ typedef NS_ENUM(NSUInteger, STPAddCardRememberMeUsage) {
- (void)clearAdditionalInfo;
- (void)logRememberMeConversion:(STPAddCardRememberMeUsage)selected;
- (void)logTokenCreationAttemptWithConfiguration:(STPPaymentConfiguration *)configuration
tokenType:(NSString *)tokenType;

View File

@ -158,15 +158,6 @@
return additionalInfo ?: @[];
}
- (void)logRememberMeConversion:(STPAddCardRememberMeUsage)selected {
NSMutableDictionary *payload = [self.class commonPayload];
[payload addEntriesFromDictionary:@{
@"event": @"stripeios.remember_me",
@"selected": @(selected),
}];
[self logPayload:payload];
}
- (NSArray *)productUsage {
NSSortDescriptor *sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:NSStringFromSelector(@selector(description)) ascending:YES];
NSArray *productUsage = [self.apiUsage sortedArrayUsingDescriptors:@[sortDescriptor]];
@ -318,7 +309,6 @@
}
dictionary[@"company_name"] = configuration.companyName ?: @"unknown";
dictionary[@"apple_merchant_identifier"] = configuration.appleMerchantIdentifier ?: @"unknown";
dictionary[@"sms_autofill_disabled"] = @(configuration.smsAutofillDisabled);
return [dictionary copy];
}

View File

@ -1,43 +0,0 @@
//
// STPCheckoutAPIClient.h
// Stripe
//
// Created by Jack Flintermann on 5/3/16.
// Copyright © 2016 Stripe, Inc. All rights reserved.
//
#import <Foundation/Foundation.h>
#import "STPBlocks.h"
#import "STPCheckoutAPIVerification.h"
#import "STPCheckoutAccount.h"
#import "STPCheckoutAccountLookup.h"
#import "STPPromise.h"
#import "STPToken.h"
NS_ASSUME_NONNULL_BEGIN
@interface STPCheckoutAPIClient : NSObject
@property(nonatomic, copy)NSString *merchantName;
@property(nonatomic)STPVoidPromise *bootstrapPromise;
@property(nonatomic, readonly)BOOL readyForLookups;
- (instancetype)initWithPublishableKey:(NSString *)publishableKey;
- (STPPromise<STPCheckoutAccountLookup *> *)lookupEmail:(NSString *)email;
- (STPPromise<STPCheckoutAPIVerification *> *)sendSMSToAccountWithEmail:(NSString *)email;
- (STPPromise<STPCheckoutAccount *> *)submitSMSCode:(NSString *)code
forVerification:(STPCheckoutAPIVerification *)verification;
- (STPPromise<STPToken *> *)createTokenWithAccount:(STPCheckoutAccount *)account;
- (STPPromise<STPCheckoutAccount *> *)createAccountWithCardParams:(STPCardParams *)cardParams
email:(NSString *)email
phone:(NSString *)phone;
@end
NS_ASSUME_NONNULL_END

View File

@ -1,303 +0,0 @@
//
// STPCheckoutAPIClient.m
// Stripe
//
// Created by Jack Flintermann on 5/3/16.
// Copyright © 2016 Stripe, Inc. All rights reserved.
//
#import "STPCheckoutAPIClient.h"
#import "NSBundle+Stripe_AppName.h"
#import "NSMutableURLRequest+Stripe.h"
#import "STPAPIClient.h"
#import "STPCardValidator.h"
#import "STPCheckoutBootstrapResponse.h"
#import "STPLocalizationUtils.h"
#import "STPWeakStrongMacros.h"
#import "StripeError.h"
@interface STPCheckoutAPIClient()
@property(nonatomic, copy)NSString *publishableKey;
@property(nonatomic)NSURLSession *accountSession;
@property(nonatomic)NSURLSessionTask *lookupTask;
@property(nonatomic)STPAPIClient *tokenClient;
@end
static NSString *CheckoutBaseURLString = @"https://checkout.stripe.com/api";
@implementation STPCheckoutAPIClient
- (instancetype)initWithPublishableKey:(NSString *)publishableKey {
self = [super init];
if (self) {
_publishableKey = publishableKey;
_merchantName = [NSBundle stp_applicationName];
_bootstrapPromise = [STPVoidPromise new];
NSURLSession *urlSession = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]];
NSURL *baseURL = [NSURL URLWithString:CheckoutBaseURLString];
NSURL *url = [baseURL URLByAppendingPathComponent:@"bootstrap"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
NSDictionary *payload = @{
@"key": _publishableKey
};
WEAK(self);
[request stp_addParametersToURL:payload];
[[urlSession dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse * response, NSError *error) {
STRONG(self);
if (error) {
[self.bootstrapPromise fail:error];
} else {
STPCheckoutBootstrapResponse *bootstrap = [STPCheckoutBootstrapResponse bootstrapResponseWithData:data URLResponse:response];
if (bootstrap && !bootstrap.accountsDisabled) {
NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response;
NSArray<NSHTTPCookie *> *cookies = [NSHTTPCookie cookiesWithResponseHeaderFields:httpResponse.allHeaderFields forURL:baseURL];
NSMutableDictionary *cookieHeaders = [[NSHTTPCookie requestHeaderFieldsWithCookies:cookies] mutableCopy];
[cookieHeaders addEntriesFromDictionary:@{
@"X-Stripe-Client": @"iossdk",
@"X-Stripe-Client-Version": STPSDKVersion,
@"X-CSRF-Token": bootstrap.csrfToken,
}];
configuration.HTTPAdditionalHeaders = cookieHeaders;
self.accountSession = [NSURLSession sessionWithConfiguration:configuration];
self.tokenClient = bootstrap.tokenClient;
[self.bootstrapPromise succeed];
} else {
[self.bootstrapPromise fail:[self.class genericRememberMeErrorWithResponseData:data message:@"Bootstrap failed."]];
}
}
}] resume];
}
return self;
}
- (BOOL)readyForLookups {
if (self.bootstrapPromise.completed) {
return !self.bootstrapPromise.error;
}
return NO;
}
- (STPPromise *)lookupEmail:(NSString *)email {
WEAK(self);
Class selfClass = self.class;
return [self.bootstrapPromise voidFlatMap:^STPPromise*() {
STRONG(self);
if (!self) {
return [STPPromise promiseWithError:[selfClass cancellationError]];
}
STPPromise<STPCheckoutAccountLookup *> *lookupPromise = [STPPromise<STPCheckoutAccountLookup *> new];
NSURL *url = [[NSURL URLWithString:CheckoutBaseURLString] URLByAppendingPathComponent:@"account/lookup"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
NSDictionary *payload = @{
@"key": self.publishableKey,
@"email": email,
};
[request stp_addParametersToURL:payload];
[self.lookupTask cancel];
self.lookupTask = [self.accountSession dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
STPCheckoutAccountLookup *lookup = [STPCheckoutAccountLookup lookupWithData:data URLResponse:response];
if (lookup) {
[lookupPromise succeed:lookup];
} else {
[lookupPromise fail:error ?: [self.class genericRememberMeErrorWithResponseData:data message:@"Failed to parse account lookup response"]];
}
}];
[self.lookupTask resume];
return lookupPromise;
}];
}
- (STPPromise *)sendSMSToAccountWithEmail:(NSString *)email {
WEAK(self);
Class selfClass = self.class;
return [self.bootstrapPromise voidFlatMap:^STPPromise *{
STRONG(self);
STPPromise *smsPromise = [STPPromise new];
if (!self) {
return [STPPromise promiseWithError:[selfClass cancellationError]];
}
NSURL *url = [[NSURL URLWithString:CheckoutBaseURLString] URLByAppendingPathComponent:@"account/verifications"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
request.HTTPMethod = @"POST";
NSDictionary *payload = @{
@"key": self.publishableKey,
@"email": email,
@"locale": @"en",
};
NSDictionary *formPayload = @{
@"merchant_name": self.merchantName,
};
[request stp_addParametersToURL:payload];
[request stp_setFormPayload:formPayload];
[[self.accountSession dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
STPCheckoutAPIVerification *verification = [STPCheckoutAPIVerification verificationWithData:data URLResponse:response];
if (verification) {
[smsPromise succeed:verification];
} else {
[smsPromise fail:error ?: [self.class genericRememberMeErrorWithResponseData:data message:@"Failed to parse SMS verification"]];
}
}] resume];
return smsPromise;
}];
}
- (STPPromise *)submitSMSCode:(NSString *)code
forVerification:(STPCheckoutAPIVerification *)verification {
WEAK(self);
Class selfClass = self.class;
return [self.bootstrapPromise voidFlatMap:^STPPromise *{
STRONG(self);
STPPromise<STPCheckoutAccount*> *accountPromise = [STPPromise<STPCheckoutAccount *> new];
if (!self) {
return [STPPromise promiseWithError:[selfClass cancellationError]];
}
NSString *pathComponent = [@"account/verifications" stringByAppendingPathComponent:verification.verificationID];
NSURL *url = [[NSURL URLWithString:CheckoutBaseURLString] URLByAppendingPathComponent:pathComponent];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
request.HTTPMethod = @"PUT";
NSDictionary *formPayload = @{
@"code": code,
@"key": self.publishableKey,
@"locale": @"en",
};
[request stp_setFormPayload:formPayload];
[[self.accountSession dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
STPCheckoutAccount *account = [STPCheckoutAccount accountWithData:data URLResponse:response];
if (account) {
[accountPromise succeed:account];
} else {
[accountPromise fail:error ?: [self.class genericRememberMeErrorWithResponseData:data message:@"Failed to parse checkout account response"]];
}
}] resume];
return accountPromise;
}];
}
- (STPPromise *)createTokenWithAccount:(STPCheckoutAccount *)account {
WEAK(self);
Class selfClass = self.class;
return [self.bootstrapPromise voidFlatMap:^STPPromise *{
STRONG(self);
STPPromise<STPToken *> *tokenPromise = [STPPromise new];
if (!self) {
return [STPPromise promiseWithError:[selfClass cancellationError]];
}
NSURL *url = [[NSURL URLWithString:CheckoutBaseURLString] URLByAppendingPathComponent:@"account/tokens"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
request.HTTPMethod = @"POST";
NSDictionary *payload = @{
@"key": self.publishableKey,
};
[request stp_addParametersToURL:payload];
[request setValue:account.sessionID forHTTPHeaderField:@"X-Rack-Session"];
[request setValue:account.sessionID forHTTPHeaderField:@"Stripe-Checkout-Test-Session"];
[request setValue:account.csrfToken forHTTPHeaderField:@"X-CSRF-Token"];
[[self.accountSession dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
STPToken *token = [self parseTokenFromResponse:response data:data];
if (token) {
[tokenPromise succeed:token];
} else {
[tokenPromise fail:error ?: [self.class genericRememberMeErrorWithResponseData:data message:@"Failed to parse token from checkout response"]];
}
}] resume];
return tokenPromise;
}];
}
- (STPPromise *)createAccountWithCardParams:(STPCardParams *)cardParams
email:(NSString *)email
phone:(NSString *)phone {
WEAK(self);
Class selfClass = self.class;
return [[self.bootstrapPromise voidFlatMap:^STPPromise * _Nonnull{
STRONG(self);
STPPromise *tokenPromise = [STPPromise new];
[self.tokenClient createTokenWithCard:cardParams completion:^(STPToken *token, NSError *error) {
if (error) {
[tokenPromise fail:error];
} else {
[tokenPromise succeed:token];
}
}];
return tokenPromise;
}] flatMap:^STPPromise *(STPToken *token) {
STRONG(self);
if (!self) {
return [STPPromise promiseWithError:[selfClass cancellationError]];
}
STPPromise<STPCheckoutAccount*> *accountPromise = [STPPromise<STPCheckoutAccount *> new];
NSURL *url = [[NSURL URLWithString:CheckoutBaseURLString] URLByAppendingPathComponent:@"account"];
NSString *internationalizedPhone = [STPCardValidator sanitizedNumericStringForString:phone];
if ([[[NSLocale autoupdatingCurrentLocale] localeIdentifier] isEqualToString:@"en_US"] && ![internationalizedPhone hasPrefix:@"1"]) {
internationalizedPhone = [@"1" stringByAppendingString:internationalizedPhone];
}
if (![internationalizedPhone hasPrefix:@"+"]) {
internationalizedPhone = [@"+" stringByAppendingString:internationalizedPhone];
}
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
request.HTTPMethod = @"POST";
NSDictionary *formPayload = @{
@"token": token.tokenId,
@"key": self.publishableKey,
@"phone": internationalizedPhone,
@"email": email,
@"merchant_name": self.merchantName,
};
[request stp_setFormPayload:formPayload];
[[self.accountSession dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
STPCheckoutAccount *account = [STPCheckoutAccount accountWithData:data URLResponse:response];
if (account) {
[accountPromise succeed:account];
} else {
[accountPromise fail:error ?: [self.class genericRememberMeErrorWithResponseData:data
message:STPLocalizedString(@"Failed to parse account response",
@"Error message for checkout account api call")]];
}
}] resume];
return accountPromise;
}];
}
- (nullable STPToken *)parseTokenFromResponse:(NSURLResponse *)response
data:(NSData *)data {
if (![response isKindOfClass:[NSHTTPURLResponse class]]) {
return nil;
}
if (((NSHTTPURLResponse *)response).statusCode != 200) {
return nil;
}
NSDictionary *json = [NSJSONSerialization JSONObjectWithData:data options:(NSJSONReadingOptions)kNilOptions error:nil];
return [STPToken decodedObjectFromAPIResponse:json[@"token"]];
}
+ (NSError *)cancellationError {
return [NSError errorWithDomain:StripeDomain code:STPCancellationError userInfo:@{
NSLocalizedDescriptionKey: STPLocalizedString(@"The operation was cancelled",
@"Error message for network request being cancelled.")
}];
}
+ (NSError *)genericRememberMeErrorWithResponseData:(NSData *)responseData
message:(NSString *)message {
NSInteger code = STPCheckoutUnknownError;
NSDictionary *json;
id object = [NSJSONSerialization JSONObjectWithData:responseData options:(NSJSONReadingOptions)kNilOptions error:nil];
if ([object isKindOfClass:[NSDictionary class]]) {
json = object;
if ([json[@"reason"] isEqualToString:@"too_many_attempts"]) {
code = STPCheckoutTooManyAttemptsError;
}
}
return [NSError errorWithDomain:StripeDomain code:code userInfo:@{
NSLocalizedDescriptionKey: [NSString stringWithFormat:STPLocalizedString(@"Something went wrong with Remember Me: %@",
@"Error message for Remember Me network error. More detailed cause of the error will be filled into the substitution."),
message]
}];
}
@end

View File

@ -1,23 +0,0 @@
//
// STPCheckoutAPIVerification.h
// Stripe
//
// Created by Jack Flintermann on 5/3/16.
// Copyright © 2016 Stripe, Inc. All rights reserved.
//
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
@interface STPCheckoutAPIVerification : NSObject
+ (nullable instancetype)verificationWithData:(nullable NSData *)data
URLResponse:(nullable NSURLResponse *)response;
@property(nonatomic, readonly)NSString *verificationID;
@property(nonatomic, readonly)NSString *statusURLString;
@end
NS_ASSUME_NONNULL_END

View File

@ -1,47 +0,0 @@
//
// STPCheckoutAPIVerification.m
// Stripe
//
// Created by Jack Flintermann on 5/3/16.
// Copyright © 2016 Stripe, Inc. All rights reserved.
//
#import "STPCheckoutAPIVerification.h"
@interface STPCheckoutAPIVerification()
@property(nonatomic)NSString *verificationID;
@property(nonatomic)NSString *statusURLString;
@end
@implementation STPCheckoutAPIVerification
+ (nullable instancetype)verificationWithData:(nullable NSData *)data
URLResponse:(nullable NSURLResponse *)response {
if (![response isKindOfClass:[NSHTTPURLResponse class]]) {
return nil;
}
NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response;
if (httpResponse.statusCode != 201) {
return nil;
}
NSDictionary *object = [NSJSONSerialization JSONObjectWithData:data options:(NSJSONReadingOptions)kNilOptions error:nil];
if (![object isKindOfClass:[NSDictionary class]]) {
return nil;
}
NSString *verificationID = object[@"id"];
if (![verificationID isKindOfClass:[NSString class]]) {
return nil;
}
NSString *statusURLString = object[@"status_url"];
if (![statusURLString isKindOfClass:[NSString class]]) {
return nil;
}
STPCheckoutAPIVerification *verification = [self new];
verification.verificationID = verificationID;
verification.statusURLString = statusURLString;
return verification;
}
@end

View File

@ -1,23 +0,0 @@
//
// STPCheckoutAccount.h
// Stripe
//
// Created by Jack Flintermann on 5/3/16.
// Copyright © 2016 Stripe, Inc. All rights reserved.
//
#import <Foundation/Foundation.h>
#import "STPCard.h"
@interface STPCheckoutAccount : NSObject
+ (nullable instancetype)accountWithData:(nullable NSData *)data
URLResponse:(nullable NSURLResponse *)response;
@property(nonatomic, nonnull, readonly)NSString *email;
@property(nonatomic, nonnull, readonly)NSString *phone;
@property(nonatomic, nonnull, readonly)NSString *csrfToken;
@property(nonatomic, nonnull, readonly)NSString *sessionID;
@property(nonatomic, nonnull, readonly)STPCard *card;
@end

View File

@ -1,86 +0,0 @@
//
// STPCheckoutAccount.m
// Stripe
//
// Created by Jack Flintermann on 5/3/16.
// Copyright © 2016 Stripe, Inc. All rights reserved.
//
#import "STPCheckoutAccount.h"
@interface STPCheckoutAccount()
@property(nonatomic, nonnull)NSString *email;
@property(nonatomic, nonnull)NSString *phone;
@property(nonatomic, nonnull)NSString *csrfToken;
@property(nonatomic, nonnull)NSString *sessionID;
@property(nonatomic, nonnull)STPCard *card;
@end
@implementation STPCheckoutAccount
+ (nullable instancetype)accountWithData:(nullable NSData *)data
URLResponse:(nullable NSURLResponse *)response {
if (![response isKindOfClass:[NSHTTPURLResponse class]]) {
return nil;
}
NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response;
if (httpResponse.statusCode != 200 && httpResponse.statusCode != 201) {
return nil;
}
NSDictionary *object = [NSJSONSerialization JSONObjectWithData:data options:(NSJSONReadingOptions)kNilOptions error:nil];
if (![object isKindOfClass:[NSDictionary class]]) {
return nil;
}
NSDictionary *accountHash = object[@"account"];
if (![accountHash isKindOfClass:[NSDictionary class]]) {
return nil;
}
NSString *email = accountHash[@"email"];
if (![email isKindOfClass:[NSString class]]) {
return nil;
}
NSString *phone = accountHash[@"phone"];
if (![phone isKindOfClass:[NSString class]]) {
return nil;
}
NSString *csrfToken = object[@"securityToken"];
if (![csrfToken isKindOfClass:[NSString class]]) {
return nil;
}
NSString *sessionID = object[@"sessionID"];
if (![sessionID isKindOfClass:[NSString class]]) {
return nil;
}
NSDictionary *cardHash = accountHash[@"card"];
if (![cardHash isKindOfClass:[NSDictionary class]]) {
return nil;
}
NSString *last4 = cardHash[@"last4"];
if (![last4 isKindOfClass:[NSString class]]) {
return nil;
}
NSString *brandString = cardHash[@"brand"];
if (![brandString isKindOfClass:[NSString class]]) {
return nil;
}
NSNumber *expMonthNumber = cardHash[@"exp_month"];
if (![expMonthNumber isKindOfClass:[NSNumber class]]) {
return nil;
}
NSNumber *expYearNumber = cardHash[@"exp_year"];
if (![expYearNumber isKindOfClass:[NSNumber class]]) {
return nil;
}
STPCheckoutAccount *account = [self new];
account.email = email;
account.phone = phone;
account.csrfToken = csrfToken;
account.sessionID = sessionID;
account.card = [[STPCard alloc] initWithID:@"" brand:[STPCard brandFromString:brandString] last4:last4 expMonth:expMonthNumber.unsignedIntegerValue expYear:expYearNumber.unsignedIntegerValue funding:STPCardFundingTypeOther];
return account;
}
@end

View File

@ -1,23 +0,0 @@
//
// STPCheckoutAccountLookup.h
// Stripe
//
// Created by Jack Flintermann on 5/4/16.
// Copyright © 2016 Stripe, Inc. All rights reserved.
//
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
@interface STPCheckoutAccountLookup : NSObject
+ (nullable instancetype)lookupWithData:(nullable NSData *)data
URLResponse:(nullable NSURLResponse *)response;
@property(nonatomic, readonly)NSString *email;
@property(nonatomic, readonly)NSString *redactedPhone;
@end
NS_ASSUME_NONNULL_END

View File

@ -1,51 +0,0 @@
//
// STPCheckoutAccountLookup.m
// Stripe
//
// Created by Jack Flintermann on 5/4/16.
// Copyright © 2016 Stripe, Inc. All rights reserved.
//
#import "STPCheckoutAccountLookup.h"
@interface STPCheckoutAccountLookup()
@property(nonatomic)NSString *email;
@property(nonatomic)NSString *redactedPhone;
@end
@implementation STPCheckoutAccountLookup
+ (nullable instancetype)lookupWithData:(nullable NSData *)data
URLResponse:(nullable NSURLResponse *)response {
if (![response isKindOfClass:[NSHTTPURLResponse class]]) {
return nil;
}
NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response;
if (httpResponse.statusCode != 200) {
return nil;
}
NSDictionary *object = [NSJSONSerialization JSONObjectWithData:data options:(NSJSONReadingOptions)kNilOptions error:nil];
if (![object isKindOfClass:[NSDictionary class]]) {
return nil;
}
NSDictionary *account = object[@"account"];
if (![account isKindOfClass:[NSDictionary class]]) {
return nil;
}
NSString *email = account[@"email"];
if (![email isKindOfClass:[NSString class]]) {
return nil;
}
NSString *redactedPhone = account[@"phone"];
if (![redactedPhone isKindOfClass:[NSString class]]) {
return nil;
}
STPCheckoutAccountLookup *lookup = [self new];
lookup.email = email;
lookup.redactedPhone = redactedPhone;
return lookup;
}
@end

View File

@ -1,24 +0,0 @@
//
// STPCheckoutBootstrapResponse.h
// Stripe
//
// Created by Jack Flintermann on 5/4/16.
// Copyright © 2016 Stripe, Inc. All rights reserved.
//
#import <Foundation/Foundation.h>
@class STPAPIClient;
@interface STPCheckoutBootstrapResponse : NSObject
+ (nullable instancetype)bootstrapResponseWithData:(nullable NSData *)data
URLResponse:(nullable NSURLResponse *)response;
@property(nonatomic, readonly)BOOL liveMode;
@property(nonatomic, readonly)BOOL accountsDisabled;
@property(nonatomic, readonly, nonnull)NSString *sessionID;
@property(nonatomic, readonly, nonnull)NSString *csrfToken;
@property(nonatomic, readonly, nonnull)STPAPIClient *tokenClient;
@end

View File

@ -1,74 +0,0 @@
//
// STPCheckoutBootstrapResponse.m
// Stripe
//
// Created by Jack Flintermann on 5/4/16.
// Copyright © 2016 Stripe, Inc. All rights reserved.
//
#import "STPCheckoutBootstrapResponse.h"
#import "STPAPIClient.h"
#import "STPAPIClient+Private.h"
@interface STPCheckoutBootstrapResponse()
@property(nonatomic)BOOL liveMode;
@property(nonatomic)BOOL accountsDisabled;
@property(nonatomic, nonnull)NSString *sessionID;
@property(nonatomic, nonnull)NSString *csrfToken;
@property(nonatomic, nonnull)STPAPIClient *tokenClient;
@end
@implementation STPCheckoutBootstrapResponse
+ (nullable instancetype)bootstrapResponseWithData:(NSData *)data
URLResponse:( NSURLResponse *)response {
if (![response isKindOfClass:[NSHTTPURLResponse class]]) {
return nil;
}
NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response;
if (httpResponse.statusCode != 200) {
return nil;
}
NSDictionary *object = [NSJSONSerialization JSONObjectWithData:data options:(NSJSONReadingOptions)kNilOptions error:nil];
if (![object isKindOfClass:[NSDictionary class]]) {
return nil;
}
NSString *checkoutPublishableKey = object[@"checkoutPublishableKey"];
if (![checkoutPublishableKey isKindOfClass:[NSString class]]) {
return nil;
}
NSString *sessionID = object[@"sessionID"];
if (![sessionID isKindOfClass:[NSString class]]) {
return nil;
}
NSString *csrfToken = object[@"securityToken"];
if (![csrfToken isKindOfClass:[NSString class]]) {
return nil;
}
NSNumber *accountsDisabled = object[@"accountsDisabled"];
if (![accountsDisabled isKindOfClass:[NSNumber class]]) {
return nil;
}
NSString *apiURL = object[@"apiEndpoint"];
if (![apiURL isKindOfClass:[NSString class]]) {
return nil;
}
NSNumber *liveMode = object[@"livemode"];
if (![liveMode isKindOfClass:[NSNumber class]]) {
return nil;
}
STPCheckoutBootstrapResponse *bootstrap = [self new];
bootstrap.accountsDisabled = [accountsDisabled boolValue];
bootstrap.sessionID = sessionID;
bootstrap.liveMode = [liveMode boolValue];
bootstrap.csrfToken = csrfToken;
bootstrap.tokenClient = [[STPAPIClient alloc] initWithPublishableKey:checkoutPublishableKey
baseURL:apiURL];
return bootstrap;
}
@end

View File

@ -1,34 +0,0 @@
//
// STPObscuredCardView.h
// Stripe
//
// Created by Jack Flintermann on 5/11/16.
// Copyright © 2016 Stripe, Inc. All rights reserved.
//
#import <UIKit/UIKit.h>
#import "STPCard.h"
#import "STPTheme.h"
NS_ASSUME_NONNULL_BEGIN
@class STPObscuredCardView;
@protocol STPObscuredCardViewDelegate <NSObject>
- (void)obscuredCardViewDidClear:(STPObscuredCardView *)cardView;
@end
@interface STPObscuredCardView : UIView
@property(nonatomic)STPTheme *theme;
@property(nonatomic, weak)id<STPObscuredCardViewDelegate>delegate;
@property(nonatomic, weak)UIView *inputAccessoryView;
- (void)configureWithCard:(STPCard *)card;
- (void)clear;
- (BOOL)isEmpty;
@end
NS_ASSUME_NONNULL_END

View File

@ -1,148 +0,0 @@
//
// STPObscuredCardView.m
// Stripe
//
// Created by Jack Flintermann on 5/11/16.
// Copyright © 2016 Stripe, Inc. All rights reserved.
//
#import "STPObscuredCardView.h"
#import "STPImageLibrary+Private.h"
#import "STPImageLibrary.h"
#import "STPLocalizationUtils.h"
@interface STPObscuredCardView()<UITextFieldDelegate>
@property(nonatomic, weak) UIImageView *brandImageView;
@property(nonatomic, weak) UITextField *last4Field;
@property(nonatomic, weak) UITextField *expField;
@property(nonatomic, weak) UITextField *cvcField;
@end
@implementation STPObscuredCardView
- (instancetype)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
UIImage *cardImage = [STPImageLibrary unknownCardCardImage];
UIImageView *brandImageView = [[UIImageView alloc] initWithImage:cardImage];
brandImageView.contentMode = UIViewContentModeCenter;
[self addSubview:brandImageView];
_brandImageView = brandImageView;
UITextField *last4Field = [UITextField new];
last4Field.delegate = self;
last4Field.keyboardType = UIKeyboardTypePhonePad;
[self addSubview:last4Field];
_last4Field = last4Field;
UITextField *expField = [UITextField new];
expField.delegate = self;
expField.keyboardType = UIKeyboardTypePhonePad;
[self addSubview:expField];
_expField = expField;
UITextField *cvcField = [UITextField new];
cvcField.delegate = self;
cvcField.keyboardType = UIKeyboardTypePhonePad;
cvcField.secureTextEntry = YES;
[self addSubview:cvcField];
_cvcField = cvcField;
_theme = [STPTheme new];
[self updateAppearance];
}
return self;
}
- (void)layoutSubviews {
[super layoutSubviews];
self.brandImageView.frame = CGRectMake(10, 2, self.brandImageView.image.size.width, self.bounds.size.height - 2);
[self.last4Field sizeToFit];
self.last4Field.frame = CGRectMake(CGRectGetMaxX(self.brandImageView.frame) + 8, 0, self.last4Field.frame.size.width + 20, self.bounds.size.height);
[self.cvcField sizeToFit];
CGRect cvcFrame = self.cvcField.frame;
cvcFrame.size.width += 20;
cvcFrame.origin.y = 0;
cvcFrame.origin.x = CGRectGetMaxX(self.bounds) - cvcFrame.size.width;
cvcFrame.size.height = CGRectGetHeight(self.bounds);
self.cvcField.frame = cvcFrame;
[self.expField sizeToFit];
CGRect expFrame = self.expField.frame;
expFrame.size.width += 20;
self.expField.frame = expFrame;
self.expField.center = CGPointMake(
(CGRectGetMinX(cvcFrame) + CGRectGetMaxX(self.last4Field.frame)) / 2,
self.bounds.size.height / 2
);
}
- (void)setTheme:(STPTheme *)theme {
_theme = theme;
[self updateAppearance];
}
- (void)updateAppearance {
self.backgroundColor = self.theme.secondaryBackgroundColor;
self.last4Field.backgroundColor = [UIColor clearColor];
self.last4Field.font = self.theme.font;
self.last4Field.textColor = self.theme.primaryForegroundColor;
self.expField.backgroundColor = [UIColor clearColor];
self.expField.font = self.theme.font;
self.expField.textColor = self.theme.primaryForegroundColor;
self.cvcField.backgroundColor = [UIColor clearColor];
self.cvcField.font = self.theme.font;
self.cvcField.textColor = self.theme.primaryForegroundColor;
}
- (void)configureWithCard:(STPCard *)card {
UIImage *image = [STPImageLibrary brandImageForCardBrand:card.brand];
self.brandImageView.image = image;
self.last4Field.text = card.last4;
self.expField.text = [NSString stringWithFormat:@"%lu/%lu", (unsigned long)card.expMonth, (unsigned long)(card.expYear % 100)];
if (card.brand == STPCardBrandAmex) {
self.cvcField.text = STPLocalizedString(@"XXXX", @"Placeholder text for Amex CVC field (4 digits)");
} else {
self.cvcField.text = STPLocalizedString(@"XXX", @"Placeholder text for non-Amex CVC field (3 digits)");
}
[self setNeedsLayout];
}
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
BOOL deleting = (range.location == textField.text.length - 1 && range.length == 1 && [string isEqualToString:@""]);
if (deleting) {
[self clear];
}
return NO;
}
- (void)clear {
self.last4Field.text = @"";
self.expField.text = @"";
[self.delegate obscuredCardViewDidClear:self];
}
- (BOOL)isEmpty {
return self.last4Field.text.length == 0;
}
- (void)setInputAccessoryView:(UIView *)inputAccessoryView {
_inputAccessoryView = inputAccessoryView;
self.last4Field.inputAccessoryView = inputAccessoryView;
self.expField.inputAccessoryView = inputAccessoryView;
self.cvcField.inputAccessoryView = inputAccessoryView;
}
- (BOOL)becomeFirstResponder {
return [self.cvcField becomeFirstResponder];
}
@end

View File

@ -11,7 +11,6 @@
@interface STPPaymentConfiguration ()
@property(nonatomic, readonly)BOOL applePayEnabled;
@property(nonatomic, readwrite) BOOL ineligibleForSmsAutofill;
@end

View File

@ -16,8 +16,6 @@
@implementation STPPaymentConfiguration
@synthesize ineligibleForSmsAutofill = _ineligibleForSmsAutofill;
+ (void)initialize {
[STPAnalyticsClient initializeIfNeeded];
[STPTelemetryClient sharedInstance];
@ -40,7 +38,6 @@
_requiredShippingAddressFields = PKAddressFieldNone;
_verifyPrefilledShippingAddress = YES;
_companyName = [NSBundle stp_applicationName];
_smsAutofillDisabled = NO;
_shippingType = STPShippingTypeShipping;
}
return self;
@ -56,7 +53,6 @@
copy.shippingType = self.shippingType;
copy.companyName = self.companyName;
copy.appleMerchantIdentifier = self.appleMerchantIdentifier;
copy.smsAutofillDisabled = self.smsAutofillDisabled;
return copy;
}
@ -66,11 +62,6 @@
[Stripe deviceSupportsApplePay];
}
- (void)setIneligibleForSmsAutofill:(BOOL)ineligibleForSmsAutofill {
_ineligibleForSmsAutofill = ineligibleForSmsAutofill;
self.smsAutofillDisabled = (self.smsAutofillDisabled || ineligibleForSmsAutofill);
}
@end

View File

@ -113,14 +113,7 @@ static NSInteger STPPaymentMethodAddCardSection = 1;
[tableView reloadSections:[NSIndexSet indexSetWithIndex:STPPaymentMethodCardListSection] withRowAnimation:UITableViewRowAnimationFade];
[self.delegate internalViewControllerDidSelectPaymentMethod:paymentMethod];
} else if (indexPath.section == STPPaymentMethodAddCardSection) {
STPPaymentConfiguration *config = [self.configuration copy];
NSArray *cardPaymentMethods = [self.paymentMethods filteredArrayUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(id<STPPaymentMethod> paymentMethod, __unused NSDictionary<NSString *,id> * _Nullable bindings) {
return [paymentMethod isKindOfClass:[STPCard class]];
}]];
// Disable SMS autofill if we already have a card on file
config.ineligibleForSmsAutofill = (cardPaymentMethods.count > 0);
STPAddCardViewController *paymentCardViewController = [[STPAddCardViewController alloc] initWithConfiguration:config theme:self.theme];
STPAddCardViewController *paymentCardViewController = [[STPAddCardViewController alloc] initWithConfiguration:self.configuration theme:self.theme];
paymentCardViewController.delegate = self;
paymentCardViewController.prefilledInformation = self.prefilledInformation;
paymentCardViewController.shippingAddress = self.shippingAddress;

View File

@ -8,31 +8,18 @@
#import <UIKit/UIKit.h>
#import "STPObscuredCardView.h"
#import "STPPaymentCardTextField.h"
#import "STPTheme.h"
NS_ASSUME_NONNULL_BEGIN
@class STPRememberMePaymentCell;
@protocol STPRememberMePaymentCellDelegate <NSObject>
- (void)paymentCellDidClear:(STPRememberMePaymentCell *)cell;
@end
@interface STPRememberMePaymentCell : UITableViewCell
@property(nonatomic, weak)id<STPRememberMePaymentCellDelegate>delegate;
@property(nonatomic, weak, readonly)STPPaymentCardTextField *paymentField;
@property(nonatomic, weak, readonly)STPObscuredCardView *obscuredCardView;
@property(nonatomic, copy)STPTheme *theme;
@property(nonatomic, weak)UIView *inputAccessoryView;
- (void)configureWithCard:(STPCard *)card;
- (BOOL)isEmpty;
- (void)clear;
@end

View File

@ -8,10 +8,9 @@
#import "STPRememberMePaymentCell.h"
@interface STPRememberMePaymentCell()<STPObscuredCardViewDelegate>
@interface STPRememberMePaymentCell()
@property(nonatomic, weak)STPPaymentCardTextField *paymentField;
@property(nonatomic, weak)STPObscuredCardView *obscuredCardView;
@end
@ -23,12 +22,7 @@
STPPaymentCardTextField *paymentField = [[STPPaymentCardTextField alloc] initWithFrame:self.bounds];
[self.contentView addSubview:paymentField];
_paymentField = paymentField;
STPObscuredCardView *obscuredView = [[STPObscuredCardView alloc] initWithFrame:self.bounds];
obscuredView.hidden = YES;
obscuredView.delegate = self;
[self.contentView addSubview:obscuredView];
_obscuredCardView = obscuredView;
_theme = [STPTheme defaultTheme];
[self updateAppearance];
}
@ -38,7 +32,6 @@
- (void)layoutSubviews {
[super layoutSubviews];
self.paymentField.frame = self.bounds;
self.obscuredCardView.frame = self.bounds;
}
- (void)setTheme:(STPTheme *)theme {
@ -53,42 +46,21 @@
self.paymentField.textColor = self.theme.primaryForegroundColor;
self.paymentField.textErrorColor = self.theme.errorColor;
self.paymentField.font = self.theme.font;
self.obscuredCardView.theme = self.theme;
self.backgroundColor = self.theme.secondaryBackgroundColor;
}
- (void)setInputAccessoryView:(UIView *)inputAccessoryView {
_inputAccessoryView = inputAccessoryView;
self.paymentField.inputAccessoryView = inputAccessoryView;
self.obscuredCardView.inputAccessoryView = inputAccessoryView;
}
- (BOOL)isEmpty {
return self.paymentField.cardNumber.length == 0 && self.obscuredCardView.isEmpty;
}
- (void)configureWithCard:(STPCard *)card {
[self.paymentField clear];
self.obscuredCardView.hidden = NO;
[self.obscuredCardView configureWithCard:card];
return self.paymentField.cardNumber.length == 0;
}
- (BOOL)becomeFirstResponder {
if (self.obscuredCardView.hidden) {
return [self.paymentField becomeFirstResponder];
} else {
return [self.obscuredCardView becomeFirstResponder];
}
return [self.paymentField becomeFirstResponder];
}
- (void)obscuredCardViewDidClear:(__unused STPObscuredCardView *)cardView {
self.obscuredCardView.hidden = YES;
[self.paymentField becomeFirstResponder];
[self.delegate paymentCellDidClear:self];
}
- (void)clear {
[self.obscuredCardView clear];
}
@end

View File

@ -1,26 +0,0 @@
//
// STPRememberMeTermsView.h
// Stripe
//
// Created by Jack Flintermann on 5/18/16.
// Copyright © 2016 Stripe, Inc. All rights reserved.
//
#import <UIKit/UIKit.h>
#import "STPTheme.h"
NS_ASSUME_NONNULL_BEGIN
typedef void(^STPRememberMeTermsPushVCBlock)(UIViewController *vc);
@interface STPRememberMeTermsView : UIView
@property(nonatomic, weak, readonly)UITextView *textView;
@property(nonatomic)STPTheme *theme;
@property(nonatomic)UIEdgeInsets insets;
@property (nonatomic, copy)STPRememberMeTermsPushVCBlock pushViewControllerBlock;
- (CGFloat)heightForWidth:(CGFloat)maxWidth;
@end
NS_ASSUME_NONNULL_END

View File

@ -1,148 +0,0 @@
//
// STPRememberMeTermsView.m
// Stripe
//
// Created by Jack Flintermann on 5/18/16.
// Copyright © 2016 Stripe, Inc. All rights reserved.
//
#import "STPRememberMeTermsView.h"
#import "STPImageLibrary+Private.h"
#import "STPImageLibrary.h"
#import "STPLocalizationUtils.h"
#import "STPStringUtils.h"
#import "STPWebViewController.h"
@interface STPRememberMeTermsView()<UITextViewDelegate>
@property(nonatomic, weak)UITextView *textView;
@end
@implementation STPRememberMeTermsView
- (instancetype)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
self.backgroundColor = [UIColor clearColor];
UITextView *textView = [[UITextView alloc] initWithFrame:self.bounds];
textView.backgroundColor = [UIColor clearColor];
[self addSubview:textView];
textView.editable = NO;
textView.dataDetectorTypes = UIDataDetectorTypeLink;
textView.scrollEnabled = NO;
textView.delegate = self;
// This disables 3D touch previews in the text view.
for (UIGestureRecognizer *recognizer in textView.gestureRecognizers) {
if ([[NSStringFromClass([recognizer class]) lowercaseString] containsString:@"preview"] ||
[[NSStringFromClass([recognizer class]) lowercaseString] containsString:@"reveal"]) {
recognizer.enabled = NO;
}
}
_textView = textView;
_theme = [STPTheme new];
_insets = UIEdgeInsetsMake(10, 15, 0, 15);
[self updateAppearance];
}
return self;
}
static NSString *const FooterLinkTagPrivacyPolicy = @"pplink";
static NSString *const FooterLinkTagTermsOfService = @"termslink";
static NSString *const FooterLinkTagMoreInfo = @"infolink";
- (NSAttributedString *)buildAttributedString {
__block NSString *contents = STPLocalizedString(@"Stripe may store my payment info and phone number for use in this app and other apps, and use my number for verification, subject to Stripe's <pplink>Privacy Policy</pplink> and <termslink>Terms</termslink>. <infolink>More Info</infolink>",
@"Footer shown when the user enables Remember Me that shows additional info. The html-style tags control which parts of the text link to the Stripe Privacy Policy, Terms of Service, and Remember Me More Info pages, and can be moved around as needed in the translation (although they CANNOT overlap).");
__block NSRange privacyRange;
__block NSRange termsRange;
__block NSRange learnMoreRange;
[STPStringUtils parseRangesFromString:contents
withTags:[NSSet setWithArray:@[FooterLinkTagPrivacyPolicy, FooterLinkTagTermsOfService, FooterLinkTagMoreInfo]]
completion:^(NSString *string, NSDictionary<NSString *,NSValue *> *tagMap) {
contents = string;
privacyRange = tagMap[FooterLinkTagPrivacyPolicy].rangeValue;
termsRange = tagMap[FooterLinkTagTermsOfService].rangeValue;
learnMoreRange = tagMap[FooterLinkTagMoreInfo].rangeValue;
}];
NSURL *privacyURL = [NSURL URLWithString:@"https://checkout.stripe.com/-/privacy"];
NSURL *termsURL = [NSURL URLWithString:@"https://checkout.stripe.com/-/terms"];
NSURL *learnMoreURL = [NSURL URLWithString:@"https://checkout.stripe.com/-/remember-me"];
NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init];
paragraphStyle.alignment = NSTextAlignmentLeft;
NSDictionary *attributes = @{
NSFontAttributeName: self.theme.smallFont,
NSForegroundColorAttributeName: self.theme.secondaryForegroundColor,
NSParagraphStyleAttributeName: paragraphStyle,
};
NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:contents
attributes:attributes];
if (privacyRange.location != NSNotFound && privacyURL) {
[attributedString addAttribute:NSLinkAttributeName value:privacyURL range:privacyRange];
}
if (termsRange.location != NSNotFound && termsURL) {
[attributedString addAttribute:NSLinkAttributeName value:termsURL range:termsRange];
}
if (learnMoreRange.location != NSNotFound && learnMoreURL) {
[attributedString addAttribute:NSLinkAttributeName value:learnMoreURL range:learnMoreRange];
}
if (learnMoreURL) {
NSTextAttachment *attachment = [[NSTextAttachment alloc] init];
attachment.image = [STPImageLibrary smallRightChevronIcon];
NSMutableAttributedString *chevron = [[NSMutableAttributedString alloc] initWithString:@" " attributes:@{}];
[chevron appendAttributedString:[NSMutableAttributedString attributedStringWithAttachment:attachment]];
NSRange chevronRange = NSMakeRange(0, chevron.length);
[chevron addAttribute:NSLinkAttributeName value:learnMoreURL range:chevronRange];
[chevron addAttribute:NSBaselineOffsetAttributeName value:@(-1) range:chevronRange];
[attributedString appendAttributedString:chevron];
}
return attributedString;
}
- (void)setTheme:(STPTheme *)theme {
_theme = theme;
[self updateAppearance];
}
- (void)updateAppearance {
self.textView.attributedText = [self buildAttributedString];
self.textView.linkTextAttributes = @{
NSFontAttributeName: self.theme.smallFont,
NSForegroundColorAttributeName: self.theme.primaryForegroundColor
};
}
- (CGFloat)heightForWidth:(CGFloat)maxWidth {
CGFloat availableWidth = maxWidth - (self.insets.left + self.insets.right);
return ([self.textView sizeThatFits:CGSizeMake(availableWidth, CGFLOAT_MAX)].height
+ self.insets.top
+ self.insets.bottom);
}
- (void)layoutSubviews {
[super layoutSubviews];
self.textView.frame = UIEdgeInsetsInsetRect(self.bounds, self.insets);
}
- (void)setInsets:(UIEdgeInsets)insets {
_insets = insets;
[self setNeedsLayout];
}
- (BOOL)textView:(UITextView *)textView shouldInteractWithURL:(NSURL *)URL inRange:(NSRange)characterRange {
if (self.pushViewControllerBlock) {
STPWebViewController *webViewController = [[STPWebViewController alloc] initWithURL:URL
title:[textView.text substringWithRange:characterRange]];
self.pushViewControllerBlock(webViewController);
}
return NO;
}
@end

View File

@ -1,31 +0,0 @@
//
// STPSMSCodeTextField.h
// Stripe
//
// Created by Jack Flintermann on 5/10/16.
// Copyright © 2016 Stripe, Inc. All rights reserved.
//
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
@class STPSMSCodeTextField, STPTheme;
@protocol STPSMSCodeTextFieldDelegate <NSObject>
- (void)codeTextField:(STPSMSCodeTextField *)codeField didEnterCode:(NSString *)code;
@end
@interface STPSMSCodeTextField : UIView
@property(nonatomic, weak)id<STPSMSCodeTextFieldDelegate>delegate;
@property(nonatomic)STPTheme *theme;
@property(nonatomic, copy)NSString *code;
- (void)shakeAndClear;
@end
NS_ASSUME_NONNULL_END

View File

@ -1,273 +0,0 @@
//
// STPSMSCodeTextField.m
// Stripe
//
// Created by Jack Flintermann on 5/10/16.
// Copyright © 2016 Stripe, Inc. All rights reserved.
//
#import "STPSMSCodeTextField.h"
#import "NSArray+Stripe_BoundSafe.h"
#import "NSString+Stripe.h"
#import "STPCardValidator.h"
#import "STPTheme.h"
@class STPCodeInternalTextField;
@protocol STPCodeInternalTextFieldDelegate <NSObject>
- (void)internalTextFieldDidBackspaceOnEmpty:(STPCodeInternalTextField *)textField;
@end
@interface STPCodeInternalTextField : UITextField
@property(nonatomic, weak)id<STPCodeInternalTextFieldDelegate>internalDelegate;
@end
@implementation STPCodeInternalTextField
- (void)deleteBackward {
[super deleteBackward];
if (self.text.length == 0) {
[self.internalDelegate internalTextFieldDidBackspaceOnEmpty:self];
}
}
@end
@interface STPSMSCodeTextField()<UITextFieldDelegate, STPCodeInternalTextFieldDelegate>
@property(nonatomic, weak)UIView *leftContainerView;
@property(nonatomic, weak)UILabel *centerLabel;
@property(nonatomic, weak)UIView *rightContainerView;
@property(nonatomic)NSArray *textFields;
@property(nonatomic)NSArray *separators;
@property(nonatomic, weak)UIView *coveringView;
@end
@implementation STPSMSCodeTextField
- (instancetype)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
_theme = [STPTheme new];
UIView *leftContainerView = [UIView new];
[self addSubview:leftContainerView];
_leftContainerView = leftContainerView;
UILabel *centerLabel = [UILabel new];
centerLabel.text = @"-";
centerLabel.textAlignment = NSTextAlignmentCenter;
[self addSubview:centerLabel];
_centerLabel = centerLabel;
UIView *rightContainerView = [UIView new];
[self addSubview:rightContainerView];
_rightContainerView = rightContainerView;
NSMutableArray *textFields = [NSMutableArray array];
NSMutableArray *separators = [NSMutableArray array];
for (UIView *containerView in @[leftContainerView, rightContainerView]) {
for (NSInteger i=0; i < 3; i++) {
STPCodeInternalTextField *textField = [STPCodeInternalTextField new];
textField.delegate = self;
textField.keyboardType = UIKeyboardTypePhonePad;
textField.internalDelegate = self;
textField.textAlignment = NSTextAlignmentCenter;
[textFields addObject:textField];
[containerView addSubview:textField];
UIView *separator = [UIView new];
[separators addObject:separator];
[containerView addSubview:separator];
}
}
_textFields = [textFields copy];
_separators = [separators copy];
UIView *coveringView = [UIView new];
UITapGestureRecognizer *gestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(becomeFirstResponder)];
[coveringView addGestureRecognizer:gestureRecognizer];
[self addSubview:coveringView];
_coveringView = coveringView;
[self updateAppearance];
}
return self;
}
- (void)layoutSubviews {
[super layoutSubviews];
[self.centerLabel sizeToFit];
self.centerLabel.center = CGPointMake((CGFloat)round(self.bounds.size.width / 2), (CGFloat)round(self.bounds.size.height / 2));
self.leftContainerView.frame = CGRectMake(0, 0, CGRectGetMinX(self.centerLabel.frame) - 8, self.bounds.size.height);
CGFloat rightContainerX = CGRectGetMaxX(self.centerLabel.frame) + 8;
self.rightContainerView.frame = CGRectMake(rightContainerX, 0, self.bounds.size.width - rightContainerX, self.bounds.size.height);
CGFloat fieldWidth = (CGFloat)round(self.leftContainerView.bounds.size.width / 3.0f);
CGFloat fieldHeight = self.leftContainerView.bounds.size.height;
for (NSInteger i=0; i < 6; i++) {
NSInteger j = i % 3;
UITextField *textField = self.textFields[i];
textField.frame = CGRectMake(j * fieldWidth, 0, fieldWidth, fieldHeight);
UIView *separator = self.separators[i];
separator.frame = CGRectMake(((j+1) * fieldWidth), 0, 0.5, fieldHeight);
separator.hidden = j == 2;
}
self.coveringView.frame = self.bounds;
}
- (BOOL)becomeFirstResponder {
UITextField *emptyField;
for (UITextField *textField in self.textFields) {
if (textField.text.length == 0) {
emptyField = textField;
break;
}
}
if (!emptyField) {
emptyField = self.textFields.lastObject;
}
return [emptyField becomeFirstResponder];
}
- (BOOL)resignFirstResponder {
[super resignFirstResponder];
for (UITextField *textField in self.textFields) {
if ([textField isFirstResponder]) {
return [textField resignFirstResponder];
}
}
return NO;
}
- (void)shakeAndClear {
for (UIView *containerView in @[self.leftContainerView, self.rightContainerView]) {
CABasicAnimation *colorAnimation = [CABasicAnimation animationWithKeyPath:@"borderColor"];
colorAnimation.fromValue = (id)containerView.layer.borderColor;
colorAnimation.toValue = (id)self.theme.errorColor.CGColor;
containerView.layer.borderColor = self.theme.errorColor.CGColor;
colorAnimation.duration = 0.1f;
colorAnimation.timingFunction = [CATransaction animationTimingFunction];
[containerView.layer addAnimation:colorAnimation forKey:nil];
CABasicAnimation *widthAnimation = [CABasicAnimation animationWithKeyPath:@"borderWidth"];
widthAnimation.fromValue = @(containerView.layer.borderWidth);
widthAnimation.toValue = @(1.0f);
containerView.layer.borderWidth = 1.0f;
widthAnimation.duration = 0.1f;
widthAnimation.timingFunction = [CATransaction animationTimingFunction];
[containerView.layer addAnimation:widthAnimation forKey:nil];
}
self.transform = CGAffineTransformMakeTranslation(20, 0);
[UIView animateWithDuration:0.3f
delay:0.0f
usingSpringWithDamping:0.3f
initialSpringVelocity:1.0f
options:UIViewAnimationOptionCurveEaseInOut
animations:^{
self.transform = CGAffineTransformIdentity;
} completion:^(__unused BOOL finished) {
for (UITextField *textField in self.textFields) {
textField.text = nil;
}
for (UIView *containerView in @[self.leftContainerView, self.rightContainerView]) {
CABasicAnimation *colorAnimation = [CABasicAnimation animationWithKeyPath:@"borderColor"];
colorAnimation.fromValue = (id)containerView.layer.borderColor;
colorAnimation.toValue = (id)self.theme.secondaryForegroundColor.CGColor;
containerView.layer.borderColor = self.theme.secondaryForegroundColor.CGColor;
colorAnimation.duration = 0.1f;
colorAnimation.timingFunction = [CATransaction animationTimingFunction];
[containerView.layer addAnimation:colorAnimation forKey:nil];
CABasicAnimation *widthAnimation = [CABasicAnimation animationWithKeyPath:@"borderWidth"];
widthAnimation.fromValue = @(containerView.layer.borderWidth);
widthAnimation.toValue = @(0.5f);
containerView.layer.borderWidth = 0.5f;
widthAnimation.duration = 0.15f;
widthAnimation.timingFunction = [CATransaction animationTimingFunction];
[containerView.layer addAnimation:widthAnimation forKey:nil];
}
[self becomeFirstResponder];
}];
}
- (void)setTheme:(STPTheme *)theme {
_theme = theme;
[self updateAppearance];
}
- (void)updateAppearance {
self.backgroundColor = [UIColor clearColor];
self.coveringView.backgroundColor = [UIColor clearColor];
for (UIView *containerView in @[self.leftContainerView, self.rightContainerView]) {
containerView.layer.cornerRadius = 6;
containerView.layer.borderWidth = 0.5f;
containerView.layer.borderColor = self.theme.tertiaryBackgroundColor.CGColor;
containerView.backgroundColor = self.theme.secondaryBackgroundColor;
}
self.centerLabel.textColor = self.theme.secondaryForegroundColor;
self.centerLabel.font = self.theme.largeFont;
for (UIView *separator in self.separators) {
separator.backgroundColor = self.theme.quaternaryBackgroundColor;
}
for (UITextField *textField in self.textFields) {
textField.textColor = self.theme.primaryForegroundColor;
textField.tintColor = self.theme.accentColor;
textField.font = self.theme.largeFont;
}
}
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
if (![STPCardValidator stringIsNumeric:string]) {
return NO;
}
NSString *destination = [[textField.text stringByReplacingCharactersInRange:range withString:string] stp_safeSubstringToIndex:1];
textField.text = destination;
UITextField *nextField = [self fieldAfter:textField];
if (nextField) {
[nextField becomeFirstResponder];
} else {
[textField resignFirstResponder];
[self.delegate codeTextField:self didEnterCode:self.code];
}
return NO;
}
- (void)internalTextFieldDidBackspaceOnEmpty:(STPCodeInternalTextField *)textField {
UITextField *previousField = [self fieldBefore:textField];
previousField.text = @"";
[previousField becomeFirstResponder];
}
- (UITextField *)fieldBefore:(UITextField *)field {
NSInteger index = [self.textFields indexOfObject:field];
return [self.textFields stp_boundSafeObjectAtIndex:index-1];
}
- (UITextField *)fieldAfter:(UITextField *)field {
NSInteger index = [self.textFields indexOfObject:field];
return [self.textFields stp_boundSafeObjectAtIndex:index+1];
}
- (NSString *)code {
NSMutableString *code = [NSMutableString string];
for (UITextField *aTextField in self.textFields) {
[code appendString:aTextField.text];
}
return code.copy;
}
- (void)setCode:(NSString *)code {
[self.textFields enumerateObjectsUsingBlock:^(UITextField *_Nonnull aTextField, NSUInteger idx, __unused BOOL * _Nonnull stop) {
if (idx < code.length) {
aTextField.text = [code substringWithRange:NSMakeRange(idx, 1)];
}
else {
aTextField.text = @"";
}
}];
}
@end

View File

@ -1,31 +0,0 @@
//
// STPSMSCodeViewController.h
// Stripe
//
// Created by Jack Flintermann on 5/10/16.
// Copyright © 2016 Stripe, Inc. All rights reserved.
//
#import <UIKit/UIKit.h>
#import "STPCoreScrollViewController.h"
@class STPSMSCodeViewController, STPCheckoutAccount, STPCheckoutAPIClient, STPAPIClient,STPCheckoutAPIVerification, STPTheme;
@protocol STPSMSCodeViewControllerDelegate <NSObject>
- (void)smsCodeViewControllerDidCancel:(STPSMSCodeViewController *)smsCodeViewController;
- (void)smsCodeViewController:(STPSMSCodeViewController *)smsCodeViewController
didAuthenticateAccount:(STPCheckoutAccount *)account;
@end
@interface STPSMSCodeViewController : STPCoreScrollViewController
- (instancetype)initWithCheckoutAPIClient:(STPCheckoutAPIClient *)checkoutAPIClient
verification:(STPCheckoutAPIVerification *)verification
redactedPhone:(NSString *)redactedPhone;
@property(nonatomic, weak)id<STPSMSCodeViewControllerDelegate>delegate;
@end

View File

@ -1,327 +0,0 @@
//
// STPSMSCodeViewController.m
// Stripe
//
// Created by Jack Flintermann on 5/10/16.
// Copyright © 2016 Stripe, Inc. All rights reserved.
//
#import "STPSMSCodeViewController.h"
#import "STPCheckoutAPIClient.h"
#import "STPColorUtils.h"
#import "STPCoreScrollViewController+Private.h"
#import "STPLocalizationUtils.h"
#import "STPPaymentActivityIndicatorView.h"
#import "STPPhoneNumberValidator.h"
#import "STPSMSCodeTextField.h"
#import "STPTheme.h"
#import "STPWeakStrongMacros.h"
#import "StripeError.h"
#import "UIBarButtonItem+Stripe.h"
#import "UINavigationBar+Stripe_Theme.h"
#import "UIViewController+Stripe_KeyboardAvoiding.h"
@interface STPSMSCodeViewController()<STPSMSCodeTextFieldDelegate>
@property(nonatomic)STPCheckoutAPIClient *checkoutAPIClient;
@property(nonatomic)STPCheckoutAPIVerification *verification;
@property(nonatomic)NSString *redactedPhone;
@property(nonatomic)NSTimer *hideSMSSentLabelTimer;
@property(nonatomic, weak)UILabel *topLabel;
@property(nonatomic, weak)STPSMSCodeTextField *codeField;
@property(nonatomic, weak)UILabel *bottomLabel;
@property(nonatomic, weak)UIButton *cancelButton;
@property(nonatomic, weak)UILabel *errorLabel;
@property(nonatomic, weak)UILabel *smsSentLabel;
@property(nonatomic, weak)UIButton *pasteFromClipboardButton;
@property(nonatomic, weak)STPPaymentActivityIndicatorView *activityIndicator;
@property(nonatomic)BOOL loading;
@end
@implementation STPSMSCodeViewController
- (instancetype)initWithCheckoutAPIClient:(STPCheckoutAPIClient *)checkoutAPIClient
verification:(STPCheckoutAPIVerification *)verification
redactedPhone:(NSString *)redactedPhone {
self = [super init];
if (self) {
_checkoutAPIClient = checkoutAPIClient;
_verification = verification;
_redactedPhone = redactedPhone;
}
return self;
}
- (void)dealloc {
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
- (void)createAndSetupViews {
[super createAndSetupViews];
self.navigationItem.title = STPLocalizedString(@"Verification Code",
@"Title for SMS verification code screen");
UILabel *topLabel = [UILabel new];
topLabel.text = STPLocalizedString(@"Enter the verification code to use the payment info you stored with Stripe.", nil);
topLabel.textAlignment = NSTextAlignmentCenter;
topLabel.numberOfLines = 0;
[self.scrollView addSubview:topLabel];
self.topLabel = topLabel;
STPSMSCodeTextField *codeField = [STPSMSCodeTextField new];
[self.scrollView addSubview:codeField];
codeField.delegate = self;
self.codeField = codeField;
UILabel *bottomLabel = [UILabel new];
bottomLabel.textAlignment = NSTextAlignmentCenter;
bottomLabel.text = STPLocalizedString(@"Didn't receive the code?",
@"Button on SMS verification screen if the user did not receive the SMS code.");
bottomLabel.alpha = 0;
[self.scrollView addSubview:bottomLabel];
self.bottomLabel = bottomLabel;
UIButton *cancelButton = [UIButton buttonWithType:UIButtonTypeSystem];
cancelButton.titleLabel.textAlignment = NSTextAlignmentCenter;
[cancelButton setTitle:STPLocalizedString(@"Fill in your card details manually",
@"Cancel button for Remember Me SMS verification screen.")
forState:UIControlStateNormal];
[cancelButton addTarget:self action:@selector(cancel) forControlEvents:UIControlEventTouchUpInside];
cancelButton.alpha = 0;
[self.scrollView addSubview:cancelButton];
self.cancelButton = cancelButton;
UILabel *errorLabel = [UILabel new];
errorLabel.textAlignment = NSTextAlignmentCenter;
errorLabel.alpha = 0;
errorLabel.text = STPLocalizedString(@"Invalid Code",
@"Message shown when the user enters an incorrect SMS verification code.");
[self.scrollView addSubview:errorLabel];
self.errorLabel = errorLabel;
UILabel *smsSentLabel = [UILabel new];
smsSentLabel.textAlignment = NSTextAlignmentCenter;
smsSentLabel.numberOfLines = 2;
NSString *sentString = STPLocalizedString(@"We just sent a text message to: %@",
@"Message shown after sending SMS verification code. The substitution is a phone number.");
smsSentLabel.text = [NSString stringWithFormat:sentString,
[STPPhoneNumberValidator formattedRedactedPhoneNumberForString:self.redactedPhone]];
[self.scrollView addSubview:smsSentLabel];
self.smsSentLabel = smsSentLabel;
UIButton *pasteFromClipboardButton = [UIButton buttonWithType:UIButtonTypeSystem];
pasteFromClipboardButton.titleLabel.textAlignment = NSTextAlignmentCenter;
[pasteFromClipboardButton setTitle:STPLocalizedString(@"Paste copied code?",
@"Button to paste a copied SMS code into the verification field.")
forState:UIControlStateNormal];
[pasteFromClipboardButton addTarget:self action:@selector(pasteCodeFromClipboard) forControlEvents:UIControlEventTouchUpInside];
pasteFromClipboardButton.alpha = 0;
pasteFromClipboardButton.hidden = YES;
[self.scrollView addSubview:pasteFromClipboardButton];
self.pasteFromClipboardButton = pasteFromClipboardButton;
STPPaymentActivityIndicatorView *activityIndicator = [STPPaymentActivityIndicatorView new];
[self.scrollView addSubview:activityIndicator];
_activityIndicator = activityIndicator;
[self updateAppearance];
NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter];
[notificationCenter addObserver:self
selector:@selector(applicationDidBecomeActive)
name:UIApplicationDidBecomeActiveNotification
object:nil];
}
- (void)applicationDidBecomeActive {
if (self.view.superview != nil) {
NSString *pasteboardString = [UIPasteboard generalPasteboard].string;
BOOL clipboardIsCode = NO;
if (pasteboardString.length == 6) {
NSCharacterSet *invalidCharacterset = [NSCharacterSet characterSetWithCharactersInString:@"0123456789"].invertedSet;
clipboardIsCode = [pasteboardString rangeOfCharacterFromSet:invalidCharacterset].location == NSNotFound;
}
[self setPasteFromClipboardButtonVisible:clipboardIsCode];
}
}
- (void)updateAppearance {
[super updateAppearance];
self.topLabel.font = self.theme.smallFont;
self.topLabel.textColor = self.theme.secondaryForegroundColor;
self.codeField.theme = self.theme;
self.bottomLabel.font = self.theme.smallFont;
self.bottomLabel.textColor = self.theme.secondaryForegroundColor;
self.cancelButton.tintColor = self.theme.accentColor;
self.cancelButton.titleLabel.font = self.theme.smallFont;
self.errorLabel.font = self.theme.smallFont;
self.errorLabel.textColor = self.theme.errorColor;
self.smsSentLabel.font = self.theme.smallFont;
self.smsSentLabel.textColor = self.theme.secondaryForegroundColor;
self.pasteFromClipboardButton.tintColor = self.theme.accentColor;
self.pasteFromClipboardButton.titleLabel.font = self.theme.smallFont;
self.activityIndicator.tintColor = self.theme.accentColor;
}
- (void)viewDidLayoutSubviews {
[super viewDidLayoutSubviews];
CGFloat padding = 20.0f;
CGFloat contentWidth = self.view.bounds.size.width - (padding * 2);
CGSize topLabelSize = [self.topLabel sizeThatFits:CGSizeMake(contentWidth, CGFLOAT_MAX)];
self.topLabel.frame = CGRectMake(padding, 40, contentWidth, topLabelSize.height);
self.codeField.frame = CGRectMake(padding, CGRectGetMaxY(self.topLabel.frame) + padding, contentWidth, 76);
CGSize pasteFromClipboardButtonSize = [self.pasteFromClipboardButton sizeThatFits:CGSizeMake(contentWidth, CGFLOAT_MAX)];
self.pasteFromClipboardButton.frame = CGRectMake(padding, CGRectGetMaxY(self.codeField.frame) + padding, contentWidth, pasteFromClipboardButtonSize.height);
CGFloat bottomLabelTop = (CGRectGetMaxY(self.pasteFromClipboardButton.hidden
? self.codeField.frame
: self.pasteFromClipboardButton.frame)
+ padding);
CGSize bottomLabelSize = [self.bottomLabel sizeThatFits:CGSizeMake(contentWidth, CGFLOAT_MAX)];
self.bottomLabel.frame = CGRectMake(padding,
bottomLabelTop,
contentWidth,
bottomLabelSize.height);
self.errorLabel.frame = self.bottomLabel.frame;
self.cancelButton.frame = CGRectOffset(self.errorLabel.frame, 0, self.errorLabel.frame.size.height + 2);
CGSize smsSentLabelSize = [self.smsSentLabel sizeThatFits:CGSizeMake(contentWidth, CGFLOAT_MAX)];
self.smsSentLabel.frame = CGRectMake(padding, self.bottomLabel.frame.origin.y, contentWidth, smsSentLabelSize.height);
CGFloat activityIndicatorWidth = 30.0f;
self.activityIndicator.frame = CGRectMake((self.view.bounds.size.width - activityIndicatorWidth) / 2, CGRectGetMaxY(self.cancelButton.frame) + 20, activityIndicatorWidth, activityIndicatorWidth);
self.scrollView.contentSize = CGSizeMake(CGRectGetWidth(self.scrollView.frame),
[self contentMaxY]);
}
- (CGFloat)contentMaxY {
return ((self.activityIndicator.animating
? CGRectGetMaxY(self.activityIndicator.frame)
: CGRectGetMaxY(self.cancelButton.frame))
+ 2);
}
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
WEAK(self);
[self stp_beginObservingKeyboardAndInsettingScrollView:self.scrollView
onChangeBlock:^(__unused CGRect keyboardFrame, __unused UIView * _Nullable currentlyEditedField) {
STRONG(self);
CGFloat scrollOffsetY = self.scrollView.contentOffset.y + self.scrollView.contentInset.top;
CGFloat topLabelDistanceFromOffset = CGRectGetMinY(self.topLabel.frame) - scrollOffsetY;
if (topLabelDistanceFromOffset > 0
&& [self contentMaxY] > self.scrollView.contentOffset.y + CGRectGetHeight(self.scrollView.bounds) - self.scrollView.contentInset.bottom) {
// We have extra whitespace on top but the bottom of our content is cut off, so scroll a bit
CGPoint contentOffset = self.scrollView.contentOffset;
contentOffset.y += (topLabelDistanceFromOffset - 2);
self.scrollView.contentOffset = contentOffset;
}
}];
[self.codeField becomeFirstResponder];
self.hideSMSSentLabelTimer = [NSTimer scheduledTimerWithTimeInterval:10.0f target:self selector:@selector(hideSMSSentLabel) userInfo:nil repeats:NO];
}
- (void)hideSMSSentLabel {
[UIView animateWithDuration:0.2f delay:0 options:0 animations:^{
self.bottomLabel.alpha = 1.0f;
self.cancelButton.alpha = 1.0f;
self.smsSentLabel.alpha = 0;
} completion:nil];
}
- (void)codeTextField:(STPSMSCodeTextField *)codeField
didEnterCode:(NSString *)code {
WEAK(self);
self.loading = YES;
[self.codeField resignFirstResponder];
STPCheckoutAPIClient *client = self.checkoutAPIClient;
[[[client submitSMSCode:code forVerification:self.verification] onSuccess:^(STPCheckoutAccount *account) {
STRONG(self);
[self.delegate smsCodeViewController:self didAuthenticateAccount:account];
}] onFailure:^(NSError *error) {
STRONG(self);
if (!self) {
return;
}
self.loading = NO;
BOOL tooManyTries = error.code == STPCheckoutTooManyAttemptsError;
if (tooManyTries) {
self.errorLabel.text = STPLocalizedString(@"Too many incorrect attempts",
@"Error message when failing to type in SMS code for Remember me too many times.");
}
[codeField shakeAndClear];
[self.hideSMSSentLabelTimer invalidate];
[UIView animateWithDuration:0.2f animations:^{
self.smsSentLabel.alpha = 0;
self.bottomLabel.alpha = 0;
self.cancelButton.alpha = 0;
self.errorLabel.alpha = 1.0f;
}];
[UIView animateWithDuration:0.2f delay:0.3f options:0 animations:^{
self.bottomLabel.alpha = 1.0f;
self.cancelButton.alpha = 1.0f;
self.errorLabel.alpha = 0;
} completion:^(__unused BOOL finished) {
[self.codeField becomeFirstResponder];
if (tooManyTries) {
[self.delegate smsCodeViewControllerDidCancel:self];
}
}];
}];
}
- (void)setLoading:(BOOL)loading {
if (loading == _loading) {
return;
}
_loading = loading;
[self.activityIndicator setAnimating:loading animated:YES];
self.scrollView.contentSize = CGSizeMake(CGRectGetWidth(self.scrollView.frame),
[self contentMaxY]);
self.navigationItem.leftBarButtonItem.enabled = !loading;
self.cancelButton.enabled = !loading;
}
- (void)handleBackOrCancelTapped:(__unused id)sender {
[self cancel];
}
- (void)cancel {
[self.codeField resignFirstResponder];
[self.delegate smsCodeViewControllerDidCancel:self];
}
- (void)setPasteFromClipboardButtonVisible:(BOOL)isVisible {
if (isVisible == self.pasteFromClipboardButton.hidden) {
[UIView animateWithDuration:0.2f delay:0 options:0 animations:^{
self.pasteFromClipboardButton.hidden = !isVisible;
self.pasteFromClipboardButton.alpha = isVisible ? 1 : 0;
[self.view setNeedsLayout];
[self.view layoutIfNeeded];
} completion:nil];
}
}
- (void)pasteCodeFromClipboard {
self.codeField.code = [UIPasteboard generalPasteboard].string;
[UIPasteboard generalPasteboard].string = @"";
[self setPasteFromClipboardButtonVisible:NO];
[self codeTextField:self.codeField
didEnterCode:self.codeField.code];
}
@end

View File

@ -1,19 +0,0 @@
//
// STPWebViewController.h
// Stripe
//
// Created by Brian Dorfman on 9/12/16.
// Copyright © 2016 Stripe, Inc. All rights reserved.
//
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
@interface STPWebViewController : UIViewController
- (instancetype)initWithURL:(NSURL *)url title:(NSString *)title;
@end
NS_ASSUME_NONNULL_END

View File

@ -1,46 +0,0 @@
//
// STPWebViewController.m
// Stripe
//
// Created by Brian Dorfman on 9/12/16.
// Copyright © 2016 Stripe, Inc. All rights reserved.
//
#import "STPWebViewController.h"
#import <WebKit/WKWebView.h>
NS_ASSUME_NONNULL_BEGIN
@interface STPWebViewController ()
@property (nonatomic, strong) NSURL *url;
@end
@implementation STPWebViewController
- (instancetype)initWithURL:(NSURL *)url title:(nonnull NSString *)title {
self = [super init];
if (self) {
_url = url;
self.navigationItem.title = title;
}
return self;
}
- (void)viewDidLoad {
[super viewDidLoad];
CGRect frame = CGRectMake(0,
self.topLayoutGuide.length,
CGRectGetWidth(self.view.frame),
CGRectGetHeight(self.view.frame) - self.topLayoutGuide.length - self.bottomLayoutGuide.length);
WKWebView *webView = [[WKWebView alloc] initWithFrame:frame];
[self.view addSubview:webView];
webView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
[webView loadRequest:[NSURLRequest requestWithURL:self.url]];
}
@end
NS_ASSUME_NONNULL_END

View File

@ -25,7 +25,6 @@
@interface STPAddCardViewController (TestsPrivate)
@property(nonatomic) UITableView *tableView;
@property(nonatomic) BOOL forceEnableRememberMeForTesting;
@property(nonatomic) STPAddressViewModel<STPAddressFieldTableViewCellDelegate> *addressViewModel;
@end
@ -45,7 +44,6 @@
config.companyName = @"Test Company";
config.requiredBillingAddressFields = STPBillingAddressFieldsFull;
config.additionalPaymentMethods = STPPaymentMethodTypeAll;
config.smsAutofillDisabled = NO;
config.shippingType = (delivery) ? STPShippingTypeDelivery : STPShippingTypeShipping;
[STPLocalizationUtils overrideLanguageTo:language];
@ -57,7 +55,6 @@
UINavigationController *navController = [UINavigationController new];
navController.view.frame = CGRectMake(0, 0, 320, 750);
[navController pushViewController:addCardVC animated:NO];
addCardVC.forceEnableRememberMeForTesting = YES;
[navController.view layoutIfNeeded];
navController.view.frame = CGRectMake(0, 0, 320, addCardVC.tableView.contentSize.height);

View File

@ -10,7 +10,6 @@
#import <OCMock/OCMock.h>
#import <Stripe/Stripe.h>
#import "STPCard.h"
#import "STPCheckoutAccount.h"
#import "STPFixtures.h"
#import "STPRememberMePaymentCell.h"

View File

@ -30,7 +30,6 @@
config.companyName = @"Test Company";
config.requiredBillingAddressFields = STPBillingAddressFieldsFull;
config.additionalPaymentMethods = STPPaymentMethodTypeAll;
config.smsAutofillDisabled = NO;
STPTheme *theme = [STPTheme defaultTheme];
id customerContext = [STPMocks staticCustomerContext];
id delegate = OCMProtocolMock(@protocol(STPPaymentMethodsViewControllerDelegate));