diff --git a/Example/Non-Card Payment Examples.xcodeproj/project.pbxproj b/Example/Non-Card Payment Examples.xcodeproj/project.pbxproj index 690e7dbea75..b6813962af0 100644 --- a/Example/Non-Card Payment Examples.xcodeproj/project.pbxproj +++ b/Example/Non-Card Payment Examples.xcodeproj/project.pbxproj @@ -27,6 +27,7 @@ 36B6CB64234FD9AA00331C38 /* iDEALExampleViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 36B6CB63234FD9AA00331C38 /* iDEALExampleViewController.m */; }; 448895B424526C6B00F7D0C2 /* Przelewy24ExampleViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 448895B324526C6B00F7D0C2 /* Przelewy24ExampleViewController.m */; }; 44BDCFE4245A4CAE007EE6D5 /* BancontactExampleViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 44BDCFE3245A4CAE007EE6D5 /* BancontactExampleViewController.m */; }; + 45DB454B249BD97B00DE45DE /* OXXOExampleViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 45DB454A249BD97B00DE45DE /* OXXOExampleViewController.m */; }; 69A6C306246E63A2005FF304 /* EPSExampleViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 69A6C305246E63A2005FF304 /* EPSExampleViewController.m */; }; 8BBD79C6207FD2F900F85BED /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 8BBD79C8207FD2F900F85BED /* Localizable.strings */; }; B607FFBD2321DA99004203E0 /* MyAPIClient.m in Sources */ = {isa = PBXBuildFile; fileRef = B607FFBC2321DA99004203E0 /* MyAPIClient.m */; }; @@ -87,6 +88,8 @@ 448895B324526C6B00F7D0C2 /* Przelewy24ExampleViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = Przelewy24ExampleViewController.m; sourceTree = ""; }; 44BDCFE2245A4CAE007EE6D5 /* BancontactExampleViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = BancontactExampleViewController.h; sourceTree = ""; }; 44BDCFE3245A4CAE007EE6D5 /* BancontactExampleViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = BancontactExampleViewController.m; sourceTree = ""; }; + 45DB4549249BD97B00DE45DE /* OXXOExampleViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = OXXOExampleViewController.h; sourceTree = ""; }; + 45DB454A249BD97B00DE45DE /* OXXOExampleViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = OXXOExampleViewController.m; sourceTree = ""; }; 69A6C304246E6225005FF304 /* EPSExampleViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = EPSExampleViewController.h; sourceTree = ""; }; 69A6C305246E63A2005FF304 /* EPSExampleViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = EPSExampleViewController.m; sourceTree = ""; }; 8BBD79C7207FD2F900F85BED /* en */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Localizable.strings; sourceTree = ""; }; @@ -194,6 +197,10 @@ 04533E8A1A687F5D00C7E52E /* Supporting Files */, B65E8FCA22FA078A0057E64A /* WeChatPayExampleViewController.h */, B65E8FCB22FA078A0057E64A /* WeChatPayExampleViewController.m */, + 69A6C304246E6225005FF304 /* EPSExampleViewController.h */, + 69A6C305246E63A2005FF304 /* EPSExampleViewController.m */, + 45DB4549249BD97B00DE45DE /* OXXOExampleViewController.h */, + 45DB454A249BD97B00DE45DE /* OXXOExampleViewController.m */, ); path = "Non-Card Payment Examples"; sourceTree = ""; @@ -319,6 +326,7 @@ 36B6CB5D234BEB8400331C38 /* SEPADebitExampleViewController.m in Sources */, 69A6C306246E63A2005FF304 /* EPSExampleViewController.m in Sources */, C12C50DD1E57B3C800EC6D58 /* BrowseExamplesViewController.m in Sources */, + 45DB454B249BD97B00DE45DE /* OXXOExampleViewController.m in Sources */, 3171D89A24DDECD80038A218 /* SofortExampleViewController.m in Sources */, 364FC2D024201F62002879EB /* AUBECSDebitExampleViewController.m in Sources */, 448895B424526C6B00F7D0C2 /* Przelewy24ExampleViewController.m in Sources */, diff --git a/Example/Non-Card Payment Examples/BrowseExamplesViewController.m b/Example/Non-Card Payment Examples/BrowseExamplesViewController.m index 3584c354bc8..5646fda172c 100644 --- a/Example/Non-Card Payment Examples/BrowseExamplesViewController.m +++ b/Example/Non-Card Payment Examples/BrowseExamplesViewController.m @@ -17,6 +17,7 @@ #import "FPXExampleViewController.h" #import "GiropayExampleViewController.h" #import "iDEALExampleViewController.h" +#import "OXXOExampleViewController.h" #import "Przelewy24ExampleViewController.h" #import "SEPADebitExampleViewController.h" #import "SofortSourcesExampleViewController.h" @@ -44,7 +45,7 @@ - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { } - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { - return 16; + return 17; } - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { @@ -93,9 +94,12 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N cell.textLabel.text = @"EPS"; break; case 14: - cell.textLabel.text = @"Sofort (PaymentMethods)"; + cell.textLabel.text = @"OXXO"; break; case 15: + cell.textLabel.text = @"Sofort (PaymentMethods)"; + break; + case 16: cell.textLabel.text = @"GrabPay"; break; } @@ -197,12 +201,18 @@ - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath break; } case 14: { - SofortExampleViewController *exampleVC = [SofortExampleViewController new]; + OXXOExampleViewController *exampleVC = [OXXOExampleViewController new]; exampleVC.delegate = self; viewController = exampleVC; break; } case 15: { + SofortExampleViewController *exampleVC = [SofortExampleViewController new]; + exampleVC.delegate = self; + viewController = exampleVC; + break; + } + case 16: { GrabPayExampleViewController *exampleVC = [GrabPayExampleViewController new]; exampleVC.delegate = self; viewController = exampleVC; diff --git a/Example/Non-Card Payment Examples/OXXOExampleViewController.h b/Example/Non-Card Payment Examples/OXXOExampleViewController.h new file mode 100644 index 00000000000..7dd39428816 --- /dev/null +++ b/Example/Non-Card Payment Examples/OXXOExampleViewController.h @@ -0,0 +1,17 @@ +// +// OXXOExampleViewController.h +// Non-Card Payment Examples +// +// Created by Polo Li on 6/18/20. +// Copyright © 2020 Stripe. All rights reserved. +// + +#import "PaymentExampleViewController.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface OXXOExampleViewController : PaymentExampleViewController + +@end + +NS_ASSUME_NONNULL_END diff --git a/Example/Non-Card Payment Examples/OXXOExampleViewController.m b/Example/Non-Card Payment Examples/OXXOExampleViewController.m new file mode 100644 index 00000000000..478243e83a4 --- /dev/null +++ b/Example/Non-Card Payment Examples/OXXOExampleViewController.m @@ -0,0 +1,98 @@ +// +// OXXOExampleViewController.m +// Non-Card Payment Examples +// +// Created by Polo Li on 6/18/20. +// Copyright © 2020 Stripe. All rights reserved. +// + +#import "OXXOExampleViewController.h" + +#import "MyAPIClient.h" + +@interface OXXOExampleViewController () + +@end + +@implementation OXXOExampleViewController { + UITextField *_nameField; + UITextField *_emailField; +} + +- (void)viewDidLoad { + [super viewDidLoad]; + // Do any additional setup after loading the view. + + self.title = @"OXXO"; + + _nameField = [[UITextField alloc] init]; + _nameField.borderStyle = UITextBorderStyleRoundedRect; + _nameField.textContentType = UITextContentTypeName; + _nameField.placeholder = @"Full name"; + _nameField.translatesAutoresizingMaskIntoConstraints = NO; + [self.view addSubview:_nameField]; + + _emailField = [[UITextField alloc] init]; + _emailField.borderStyle = UITextBorderStyleRoundedRect; + _emailField.textContentType = UITextContentTypeEmailAddress; + _emailField.placeholder = @"Email address"; + _emailField.translatesAutoresizingMaskIntoConstraints = NO; + [self.view addSubview:_emailField]; + + [self.payButton setTitle:@"Pay with OXXO" forState:UIControlStateNormal]; + [self.payButton sizeToFit]; + + [NSLayoutConstraint activateConstraints:@[ + [_emailField.centerXAnchor constraintEqualToAnchor:self.payButton.centerXAnchor], + [_emailField.widthAnchor constraintEqualToConstant:240.f], + [_emailField.bottomAnchor constraintEqualToAnchor:self.payButton.topAnchor constant:-12.f], + [_nameField.centerXAnchor constraintEqualToAnchor:self.payButton.centerXAnchor], + [_nameField.bottomAnchor constraintEqualToAnchor:self->_emailField.topAnchor constant:-12.f], + [_nameField.widthAnchor constraintEqualToConstant:240.f], + ]]; +} + +- (void)payButtonSelected { + [super payButtonSelected]; + [self updateUIForPaymentInProgress:YES]; + + [[MyAPIClient sharedClient] createPaymentIntentWithCompletion:^(MyAPIClientResult status, NSString *clientSecret, NSError *error) { + if (status == MyAPIClientResultFailure || clientSecret == nil) { + [self.delegate exampleViewController:self didFinishWithError:error]; + return; + } + + STPPaymentIntentParams *paymentIntentParams = [[STPPaymentIntentParams alloc] initWithClientSecret:clientSecret]; + + STPPaymentMethodBillingDetails *billingDetails = [[STPPaymentMethodBillingDetails alloc] init]; + billingDetails.name = self->_nameField.text; + billingDetails.email = self->_emailField.text; + + + STPPaymentMethodOXXOParams *oxxo = [[STPPaymentMethodOXXOParams alloc] init]; + + // OXXO does not require additional parameters so we only need to pass the init-ed + // STPPaymentMethodOXXOParams instance to STPPaymentMethodParams + paymentIntentParams.paymentMethodParams = [STPPaymentMethodParams paramsWithOXXO:oxxo + billingDetails:billingDetails + metadata:nil]; + + [[STPPaymentHandler sharedHandler] confirmPayment:paymentIntentParams + withAuthenticationContext:self.delegate + completion:^(STPPaymentHandlerActionStatus handlerStatus, STPPaymentIntent * handledIntent, NSError * _Nullable handlerError) { + switch (handlerStatus) { + case STPPaymentHandlerActionStatusFailed: + [self.delegate exampleViewController:self didFinishWithError:handlerError]; + break; + case STPPaymentHandlerActionStatusCanceled: + [self.delegate exampleViewController:self didFinishWithMessage:@"Canceled"]; + break; + case STPPaymentHandlerActionStatusSucceeded: + [self.delegate exampleViewController:self didFinishWithMessage:@"Payment successfully created"]; + break; + } + }]; + } additionalParameters:@"country=mx"]; +} + +@end diff --git a/Stripe.xcodeproj/project.pbxproj b/Stripe.xcodeproj/project.pbxproj index f05057f1cf1..58cb1b84b22 100644 --- a/Stripe.xcodeproj/project.pbxproj +++ b/Stripe.xcodeproj/project.pbxproj @@ -313,9 +313,7 @@ 3680BFD023A9967100DB54AA /* STPSetupIntentConfirmParams+Utilities.h in Headers */ = {isa = PBXBuildFile; fileRef = 3680BFCF23A9967100DB54AA /* STPSetupIntentConfirmParams+Utilities.h */; settings = {ATTRIBUTES = (Public, ); }; }; 3680BFD123A9967100DB54AA /* STPSetupIntentConfirmParams+Utilities.h in Headers */ = {isa = PBXBuildFile; fileRef = 3680BFCF23A9967100DB54AA /* STPSetupIntentConfirmParams+Utilities.h */; }; 3687D23524C2244D00724C3D /* STPCardBINMetadata.h in Headers */ = {isa = PBXBuildFile; fileRef = 3687D23324C2244D00724C3D /* STPCardBINMetadata.h */; }; - 3687D23624C2244D00724C3D /* STPCardBINMetadata.h in Headers */ = {isa = PBXBuildFile; fileRef = 3687D23324C2244D00724C3D /* STPCardBINMetadata.h */; }; 3687D23724C2244D00724C3D /* STPCardBINMetadata.m in Sources */ = {isa = PBXBuildFile; fileRef = 3687D23424C2244D00724C3D /* STPCardBINMetadata.m */; }; - 3687D23824C2244D00724C3D /* STPCardBINMetadata.m in Sources */ = {isa = PBXBuildFile; fileRef = 3687D23424C2244D00724C3D /* STPCardBINMetadata.m */; }; 3687D23A24C6396200724C3D /* STPCardBINMetadataTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 3687D23924C6396200724C3D /* STPCardBINMetadataTests.m */; }; 3691EB712119111A008C49E1 /* STPCardValidator+Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 3691EB6F2119111A008C49E1 /* STPCardValidator+Private.h */; }; 3691EB722119111A008C49E1 /* STPCardValidator+Private.m in Sources */ = {isa = PBXBuildFile; fileRef = 3691EB702119111A008C49E1 /* STPCardValidator+Private.m */; }; @@ -365,6 +363,14 @@ 44BDCFDB245A2C38007EE6D5 /* STPPaymentMethodBancontactParams.h in Headers */ = {isa = PBXBuildFile; fileRef = 44BDCFDA245A2C38007EE6D5 /* STPPaymentMethodBancontactParams.h */; settings = {ATTRIBUTES = (Public, ); }; }; 44BDCFDF245A46CC007EE6D5 /* STPPaymentMethodBancontactParamsTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 44BDCFDE245A46CC007EE6D5 /* STPPaymentMethodBancontactParamsTests.m */; }; 44BDCFE1245A4841007EE6D5 /* STPPaymentMethodBancontactTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 44BDCFE0245A4841007EE6D5 /* STPPaymentMethodBancontactTests.m */; }; + 45211F1F24A2A6C6004ABF00 /* STPIntentActionOXXODisplayDetails.h in Headers */ = {isa = PBXBuildFile; fileRef = 45211F1D24A2A6C6004ABF00 /* STPIntentActionOXXODisplayDetails.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 45211F2124A2A6C6004ABF00 /* STPIntentActionOXXODisplayDetails.m in Sources */ = {isa = PBXBuildFile; fileRef = 45211F1E24A2A6C6004ABF00 /* STPIntentActionOXXODisplayDetails.m */; }; + 4521D385249896F40042700B /* STPPaymentMethodOXXO.m in Sources */ = {isa = PBXBuildFile; fileRef = 4521D384249896F40042700B /* STPPaymentMethodOXXO.m */; }; + 4521D38B249985160042700B /* STPPaymentMethodOXXO.h in Headers */ = {isa = PBXBuildFile; fileRef = 4521D383249896C70042700B /* STPPaymentMethodOXXO.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 4521D38D249986A40042700B /* STPPaymentMethodOXXOParams.h in Headers */ = {isa = PBXBuildFile; fileRef = 4521D38C249986A40042700B /* STPPaymentMethodOXXOParams.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 4521D390249988340042700B /* STPPaymentMethodOXXOParams.m in Sources */ = {isa = PBXBuildFile; fileRef = 4521D38F249988340042700B /* STPPaymentMethodOXXOParams.m */; }; + 4521D395249999C10042700B /* STPPaymentMethodOXXOParamsTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 4521D394249999C10042700B /* STPPaymentMethodOXXOParamsTests.m */; }; + 4521D3972499E85E0042700B /* STPPaymentMethodOXXOTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 4521D3962499E85E0042700B /* STPPaymentMethodOXXOTests.m */; }; 69A6C2FA246D4AA0005FF304 /* STPPaymentMethodEPS.m in Sources */ = {isa = PBXBuildFile; fileRef = 69A6C2F9246D4AA0005FF304 /* STPPaymentMethodEPS.m */; }; 69A6C2FE246D788D005FF304 /* STPPaymentMethodEPSParams.m in Sources */ = {isa = PBXBuildFile; fileRef = 69A6C2FD246D788D005FF304 /* STPPaymentMethodEPSParams.m */; }; 69A6C2FF246D8834005FF304 /* STPPaymentMethodEPS.m in Headers */ = {isa = PBXBuildFile; fileRef = 69A6C2F9246D4AA0005FF304 /* STPPaymentMethodEPS.m */; }; @@ -544,7 +550,7 @@ B6D6C933223076600092AFC8 /* STPPaymentMethodAddressTest.m in Sources */ = {isa = PBXBuildFile; fileRef = B6D6C932223076600092AFC8 /* STPPaymentMethodAddressTest.m */; }; B6D6C935223078840092AFC8 /* STPPaymentMethodBillingDetailsTest.m in Sources */ = {isa = PBXBuildFile; fileRef = B6D6C934223078840092AFC8 /* STPPaymentMethodBillingDetailsTest.m */; }; B6DB0CA6223817A300AEF640 /* STPPaymentMethodEnums.h in Headers */ = {isa = PBXBuildFile; fileRef = B6DB0CA5223817A300AEF640 /* STPPaymentMethodEnums.h */; settings = {ATTRIBUTES = (Public, ); }; }; - B6DB0CA922381B4900AEF640 /* STPPaymentMethod+Private.h in Headers */ = {isa = PBXBuildFile; fileRef = B6DB0CA822381B4900AEF640 /* STPPaymentMethod+Private.h */; }; + B6DB0CA922381B4900AEF640 /* STPPaymentMethod+Private.h in Headers */ = {isa = PBXBuildFile; fileRef = B6DB0CA822381B4900AEF640 /* STPPaymentMethod+Private.h */; settings = {ATTRIBUTES = (Private, ); }; }; B6DE52DB2230981200B70A66 /* STPPaymentMethodParams.h in Headers */ = {isa = PBXBuildFile; fileRef = B6DE52D92230981200B70A66 /* STPPaymentMethodParams.h */; settings = {ATTRIBUTES = (Public, ); }; }; B6DE52DD2230981200B70A66 /* STPPaymentMethodParams.m in Sources */ = {isa = PBXBuildFile; fileRef = B6DE52DA2230981200B70A66 /* STPPaymentMethodParams.m */; }; B6DF4C972411BE4D005C1AE0 /* STPApplePayContextFunctionalTest.m in Sources */ = {isa = PBXBuildFile; fileRef = B6DF4C962411BE4D005C1AE0 /* STPApplePayContextFunctionalTest.m */; }; @@ -1113,11 +1119,11 @@ 3674EADB232AEE5B008ADA25 /* tr */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.strings; name = tr; path = Localizations/tr.lproj/Localizable.strings; sourceTree = ""; }; 3676777B237CC8A800B8FA4F /* STPIntentActionRedirectToURL+Private.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "STPIntentActionRedirectToURL+Private.h"; sourceTree = ""; }; 367B46D522A0969000730BE0 /* STPThreeDSCustomizationSettings.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = STPThreeDSCustomizationSettings.m; sourceTree = ""; }; + 3680BFCB23A9926500DB54AA /* STPPaymentIntentParams+Utilities.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "STPPaymentIntentParams+Utilities.h"; path = "PublicHeaders/Stripe/STPPaymentIntentParams+Utilities.h"; sourceTree = ""; }; + 3680BFCF23A9967100DB54AA /* STPSetupIntentConfirmParams+Utilities.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "STPSetupIntentConfirmParams+Utilities.h"; path = "PublicHeaders/Stripe/STPSetupIntentConfirmParams+Utilities.h"; sourceTree = ""; }; 3687D23324C2244D00724C3D /* STPCardBINMetadata.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = STPCardBINMetadata.h; sourceTree = ""; }; 3687D23424C2244D00724C3D /* STPCardBINMetadata.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = STPCardBINMetadata.m; sourceTree = ""; }; 3687D23924C6396200724C3D /* STPCardBINMetadataTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = STPCardBINMetadataTests.m; sourceTree = ""; }; - 3680BFCB23A9926500DB54AA /* STPPaymentIntentParams+Utilities.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "STPPaymentIntentParams+Utilities.h"; path = "PublicHeaders/Stripe/STPPaymentIntentParams+Utilities.h"; sourceTree = ""; }; - 3680BFCF23A9967100DB54AA /* STPSetupIntentConfirmParams+Utilities.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "STPSetupIntentConfirmParams+Utilities.h"; path = "PublicHeaders/Stripe/STPSetupIntentConfirmParams+Utilities.h"; sourceTree = ""; }; 3691EB6F2119111A008C49E1 /* STPCardValidator+Private.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "STPCardValidator+Private.h"; sourceTree = ""; }; 3691EB702119111A008C49E1 /* STPCardValidator+Private.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "STPCardValidator+Private.m"; sourceTree = ""; }; 3691EB73211A4F31008C49E1 /* STPShippingAddressViewControllerTest.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = STPShippingAddressViewControllerTest.m; sourceTree = ""; }; @@ -1191,6 +1197,14 @@ 44BDCFDA245A2C38007EE6D5 /* STPPaymentMethodBancontactParams.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = STPPaymentMethodBancontactParams.h; path = PublicHeaders/Stripe/STPPaymentMethodBancontactParams.h; sourceTree = ""; }; 44BDCFDE245A46CC007EE6D5 /* STPPaymentMethodBancontactParamsTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = STPPaymentMethodBancontactParamsTests.m; sourceTree = ""; }; 44BDCFE0245A4841007EE6D5 /* STPPaymentMethodBancontactTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = STPPaymentMethodBancontactTests.m; sourceTree = ""; }; + 45211F1D24A2A6C6004ABF00 /* STPIntentActionOXXODisplayDetails.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = STPIntentActionOXXODisplayDetails.h; path = PublicHeaders/Stripe/STPIntentActionOXXODisplayDetails.h; sourceTree = ""; }; + 45211F1E24A2A6C6004ABF00 /* STPIntentActionOXXODisplayDetails.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = STPIntentActionOXXODisplayDetails.m; sourceTree = ""; }; + 4521D383249896C70042700B /* STPPaymentMethodOXXO.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = STPPaymentMethodOXXO.h; path = PublicHeaders/Stripe/STPPaymentMethodOXXO.h; sourceTree = ""; }; + 4521D384249896F40042700B /* STPPaymentMethodOXXO.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = STPPaymentMethodOXXO.m; sourceTree = ""; }; + 4521D38C249986A40042700B /* STPPaymentMethodOXXOParams.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = STPPaymentMethodOXXOParams.h; path = PublicHeaders/Stripe/STPPaymentMethodOXXOParams.h; sourceTree = ""; }; + 4521D38F249988340042700B /* STPPaymentMethodOXXOParams.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = STPPaymentMethodOXXOParams.m; sourceTree = ""; }; + 4521D394249999C10042700B /* STPPaymentMethodOXXOParamsTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = STPPaymentMethodOXXOParamsTests.m; sourceTree = ""; }; + 4521D3962499E85E0042700B /* STPPaymentMethodOXXOTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = STPPaymentMethodOXXOTests.m; sourceTree = ""; }; 4A0D74F918F6106100966D7B /* Security.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Security.framework; path = System/Library/Frameworks/Security.framework; sourceTree = SDKROOT; }; 69A6C2F9246D4AA0005FF304 /* STPPaymentMethodEPS.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = STPPaymentMethodEPS.m; sourceTree = ""; }; 69A6C2FD246D788D005FF304 /* STPPaymentMethodEPSParams.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = STPPaymentMethodEPSParams.m; sourceTree = ""; }; @@ -1891,6 +1905,8 @@ 36B6CB9A235A3CF200331C38 /* STPMandateOnlineParams.h */, 36B6CB842359063200331C38 /* STPMandateOnlineParams.m */, 36B6CB892359194F00331C38 /* STPMandateOnlineParams+Private.h */, + 45211F1D24A2A6C6004ABF00 /* STPIntentActionOXXODisplayDetails.h */, + 45211F1E24A2A6C6004ABF00 /* STPIntentActionOXXODisplayDetails.m */, ); name = "Intents (Shared)"; sourceTree = ""; @@ -1910,6 +1926,7 @@ 36196240244FA5C80025D60B /* giropay */, B67F503824C760DC00CF4A9D /* GrabPay */, 3626616923C904B400B13AE0 /* iDEAL */, + 4521D3732498904B0042700B /* OXXO */, 4488959924523D6900F7D0C2 /* Przelewy24 */, 3626616A23C904C200B13AE0 /* SEPA Debit */, 31C8644224DDEEFB0015F7DF /* Sofort */, @@ -2160,6 +2177,17 @@ name = Bancontact; sourceTree = ""; }; + 4521D3732498904B0042700B /* OXXO */ = { + isa = PBXGroup; + children = ( + 4521D383249896C70042700B /* STPPaymentMethodOXXO.h */, + 4521D384249896F40042700B /* STPPaymentMethodOXXO.m */, + 4521D38C249986A40042700B /* STPPaymentMethodOXXOParams.h */, + 4521D38F249988340042700B /* STPPaymentMethodOXXOParams.m */, + ); + name = OXXO; + sourceTree = ""; + }; 69A6C301246D8BD2005FF304 /* EPS */ = { isa = PBXGroup; children = ( @@ -2397,6 +2425,8 @@ C15B02721EA176090026E606 /* StripeErrorTest.m */, F1D3A25E1EB015B30095BFA9 /* UIImage+StripeTests.m */, F1122A7D1DFB84E000A8B1AF /* UINavigationBar+StripeTest.m */, + 4521D394249999C10042700B /* STPPaymentMethodOXXOParamsTests.m */, + 4521D3962499E85E0042700B /* STPPaymentMethodOXXOTests.m */, ); name = Unit; sourceTree = ""; @@ -3074,6 +3104,7 @@ 311A476224EB27D000576D92 /* STPCardScannerTableViewCell.h in Headers */, 3626617F23C908BA00B13AE0 /* STPConfirmPaymentMethodOptions.h in Headers */, 315CB8D822E7D96100E612A3 /* STDSChallengeParameters.h in Headers */, + 45211F1F24A2A6C6004ABF00 /* STPIntentActionOXXODisplayDetails.h in Headers */, 315CB8D922E7D96100E612A3 /* STDSJSONDecodable.h in Headers */, 315CB8DA22E7D96100E612A3 /* STDSJSONEncodable.h in Headers */, 315CB8DB22E7D96100E612A3 /* STDSInvalidInputException.h in Headers */, @@ -3173,6 +3204,7 @@ 314B6A592384ABF9001FE708 /* STPSourceKlarnaDetails.h in Headers */, B6794A4922F4B5CC00E3AB41 /* STPConnectAccountCompanyParams.h in Headers */, 04793F561D1D8DDD00B3C551 /* STPSourceProtocol.h in Headers */, + 4521D38D249986A40042700B /* STPPaymentMethodOXXOParams.h in Headers */, 3656EF2F246F135400DA11CF /* STPPaymentMethodEPSParams.h in Headers */, 0451CC441C49AE1C003B2CA6 /* STPPaymentResult.h in Headers */, B690DDF2222F0211000B902D /* STPPaymentMethodAddress.h in Headers */, @@ -3194,6 +3226,7 @@ 045D712C1CF4ED7600F6CD65 /* STPBINRange.h in Headers */, C1D7B51A1E36B8B9002181F5 /* STPSourceParams.h in Headers */, 3604007322C18C78004CF80B /* STPThreeDSButtonCustomization.h in Headers */, + 4521D38B249985160042700B /* STPPaymentMethodOXXO.h in Headers */, 04827D101D2575C6002DB3E8 /* STPImageLibrary.h in Headers */, B6B41F79223484280020BA7F /* STPPaymentMethodiDEAL.h in Headers */, F152322A1EA9306100D65C67 /* NSURLComponents+Stripe.h in Headers */, @@ -3484,6 +3517,7 @@ C1054F911FE197AE0033C87E /* STPPaymentContextSnapshotTests.m in Sources */, C127110A1DBA7E490087840D /* STPAddressViewModelTest.m in Sources */, C17D24EE1E37DBAC005CB188 /* STPSourceTest.m in Sources */, + 4521D3972499E85E0042700B /* STPPaymentMethodOXXOTests.m in Sources */, B69CABB9246DCB620081B1EF /* STPPaymentHandlerFunctionalTest.m in Sources */, 3691EB74211A4F31008C49E1 /* STPShippingAddressViewControllerTest.m in Sources */, C1E4F8061EBBEB0F00E611F5 /* STPCustomerContextTest.m in Sources */, @@ -3512,6 +3546,7 @@ F1D777C01D81DD520076FA19 /* STPStringUtilsTest.m in Sources */, C1FEE5991CBFF24000A7632B /* STPPostalCodeValidatorTest.m in Sources */, 8BD87B8B1EFB136F00269C2B /* STPSourceCardDetailsTest.m in Sources */, + 4521D395249999C10042700B /* STPPaymentMethodOXXOParamsTests.m in Sources */, 31C8644A24DDF2560015F7DF /* STPPaymentMethodSofortTests.m in Sources */, 073132982277A72D0019CE3F /* STPIssuingCardPin.m in Sources */, C13538081D2C2186003F6157 /* STPAddCardViewControllerTest.m in Sources */, @@ -3641,6 +3676,7 @@ 049A3F7F1CC1920A00F57DE7 /* UIViewController+Stripe_KeyboardAvoiding.m in Sources */, B664D65D22B839DD00E6354B /* STPThreeDSLabelCustomization.m in Sources */, 36239BAF2295EA23004FB1A5 /* STP3DS2AuthenticateResponse.m in Sources */, + 45211F2124A2A6C6004ABF00 /* STPIntentActionOXXODisplayDetails.m in Sources */, 04F416271CA3639500486FB5 /* STPAddCardViewController.m in Sources */, B6472185246CB5180098DE24 /* STPPaymentMethodAlipay.m in Sources */, B6794A5722F4CF6500E3AB41 /* STPConnectAccountAddress.m in Sources */, @@ -3651,6 +3687,7 @@ 314B6A5B2384ABF9001FE708 /* STPSourceKlarnaDetails.m in Sources */, 311A475E24EB21AE00576D92 /* STPCameraView.m in Sources */, F1DEB88C1E2047CA0066B8E8 /* STPCoreTableViewController.m in Sources */, + 4521D390249988340042700B /* STPPaymentMethodOXXOParams.m in Sources */, 44BDCFD3245A278F007EE6D5 /* STPPaymentMethodBancontact.m in Sources */, 04E39F6B1CED48D500AF3B96 /* UIBarButtonItem+Stripe.m in Sources */, 365BE89E2285F6080068D824 /* STPPaymentHandler.m in Sources */, @@ -3747,6 +3784,7 @@ C124A17E1CCAA0C2007D42EE /* NSMutableURLRequest+Stripe.m in Sources */, 36E8B98E2413159B007546C1 /* STPNumericStringValidator.m in Sources */, 04695ADA1C77F9EF00E08063 /* STPDelegateProxy.m in Sources */, + 4521D385249896F40042700B /* STPPaymentMethodOXXO.m in Sources */, 69A6C2FA246D4AA0005FF304 /* STPPaymentMethodEPS.m in Sources */, B664D65722B817C800E6354B /* STPThreeDSFooterCustomization.m in Sources */, 36B6CB55234BD59F00331C38 /* STPPaymentMethodSEPADebitParams.m in Sources */, diff --git a/Stripe/PublicHeaders/Stripe/STPIntentAction.h b/Stripe/PublicHeaders/Stripe/STPIntentAction.h index 48a95aaaec5..42979a09209 100644 --- a/Stripe/PublicHeaders/Stripe/STPIntentAction.h +++ b/Stripe/PublicHeaders/Stripe/STPIntentAction.h @@ -10,7 +10,7 @@ #import "STPAPIResponseDecodable.h" -@class STPIntentActionRedirectToURL, STPIntentActionRedirectToURL, STPIntentActionAlipayHandleRedirect; +@class STPIntentActionRedirectToURL, STPIntentActionOXXODisplayDetails, STPIntentActionAlipayHandleRedirect; NS_ASSUME_NONNULL_BEGIN @@ -39,6 +39,12 @@ typedef NS_ENUM(NSUInteger, STPIntentActionType) { The payment intent requires additional action handled by `STPPaymentHandler`. */ STPIntentActionTypeUseStripeSDK, + + /** + The action type is OXXO payment. We provide `STPPaymentHandler` to display + the OXXO voucher. + */ + STPIntentActionTypeOXXODisplayDetails, /** Contains instructions for authenticating a payment by redirecting your customer to Alipay App or website. @@ -71,6 +77,11 @@ typedef NS_ENUM(NSUInteger, STPIntentActionType) { */ @property (nonatomic, strong, nullable, readonly) STPIntentActionRedirectToURL *redirectToURL; +/** + The details for displaying OXXO voucher via URL, when `type ==STPIntentActionTypeOXXODisplayDetails ` + */ +@property (nonatomic, strong, nullable, readonly) STPIntentActionOXXODisplayDetails *oxxoDisplayDetails; + /** Contains instructions for authenticating a payment by redirecting your customer to Alipay App or website. */ diff --git a/Stripe/PublicHeaders/Stripe/STPIntentActionOXXODisplayDetails.h b/Stripe/PublicHeaders/Stripe/STPIntentActionOXXODisplayDetails.h new file mode 100644 index 00000000000..8eb84bea28e --- /dev/null +++ b/Stripe/PublicHeaders/Stripe/STPIntentActionOXXODisplayDetails.h @@ -0,0 +1,42 @@ +// +// STPIntentActionOXXODisplayDetails.h +// Stripe +// +// Created by Polo Li on 6/23/20. +// Copyright © 2020 Stripe, Inc. All rights reserved. +// + +#import + +#import "STPAPIResponseDecodable.h" + +NS_ASSUME_NONNULL_BEGIN + +/** + Contains OXXO details necessary for the customer to complete the payment. + */ +@interface STPIntentActionOXXODisplayDetails : NSObject + +/** + You cannot directly instantiate an `STPIntentActionOXXODisplayDetails`. + */ +- (instancetype)init __attribute__((unavailable("You cannot directly instantiate an STPIntentActionOXXODisplayDetails."))); + +/** + The timestamp after which the OXXO voucher expires. + */ +@property (nonatomic, readonly) NSDate *expiresAfter; + +/** + The URL for the hosted OXXO voucher page, which allows customers to view and print an OXXO voucher. + */ +@property (nonatomic, readonly) NSURL *hostedVoucherURL; + +/** + OXXO reference number. + */ +@property (nonatomic, readonly) NSString *number; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Stripe/PublicHeaders/Stripe/STPPaymentMethod.h b/Stripe/PublicHeaders/Stripe/STPPaymentMethod.h index 92abc8ded47..89c5c40f6a1 100644 --- a/Stripe/PublicHeaders/Stripe/STPPaymentMethod.h +++ b/Stripe/PublicHeaders/Stripe/STPPaymentMethod.h @@ -24,6 +24,7 @@ STPPaymentMethodFPX, STPPaymentMethodGiropay, STPPaymentMethodGrabPay, STPPaymentMethodiDEAL, +STPPaymentMethodOXXO, STPPaymentMethodPrzelewy24, STPPaymentMethodSEPADebit, STPPaymentMethodSofort; @@ -128,6 +129,11 @@ NS_ASSUME_NONNULL_BEGIN */ @property (nonatomic, nullable, readonly) STPPaymentMethodBancontact *bancontact; +/** + If this is a OXXO PaymentMethod (i.e. `self.type == STPPaymentMethodTypeOXXO`), this contains additional details. +*/ +@property (nonatomic, nullable, readonly) STPPaymentMethodOXXO *oxxo; + /** If this is a Sofort PaymentMethod (i.e. `self.type == STPPaymentMethodTypeSofort`), this contains additional details. */ diff --git a/Stripe/PublicHeaders/Stripe/STPPaymentMethodEnums.h b/Stripe/PublicHeaders/Stripe/STPPaymentMethodEnums.h index d9258ce70d4..ac250995871 100644 --- a/Stripe/PublicHeaders/Stripe/STPPaymentMethodEnums.h +++ b/Stripe/PublicHeaders/Stripe/STPPaymentMethodEnums.h @@ -75,6 +75,11 @@ typedef NS_ENUM(NSUInteger, STPPaymentMethodType) { */ STPPaymentMethodTypeBancontact, + /** + A OXXO payment method. + */ + STPPaymentMethodTypeOXXO, + /** A Sofort payment method. */ diff --git a/Stripe/PublicHeaders/Stripe/STPPaymentMethodOXXO.h b/Stripe/PublicHeaders/Stripe/STPPaymentMethodOXXO.h new file mode 100644 index 00000000000..c82c72bfbfb --- /dev/null +++ b/Stripe/PublicHeaders/Stripe/STPPaymentMethodOXXO.h @@ -0,0 +1,35 @@ +// +// STPPaymentMethodOXXO.h +// Stripe +// +// Created by Polo Li on 6/15/20. +// Copyright © 2020 Stripe, Inc. All rights reserved. +// + +#import + +#import "STPAPIResponseDecodable.h" + +NS_ASSUME_NONNULL_BEGIN + +/** +A OXXO Payment Method. +@see https://stripe.com/docs/payments/oxxo +*/ +@interface STPPaymentMethodOXXO : NSObject + +/** +You cannot directly instantiate an `STPPaymentMethodOXXO. +You should only use one that is part of an existing `STPPaymentMethod` object. +*/ +- (instancetype)init NS_UNAVAILABLE; + +/** +You cannot directly instantiate an `STPPaymentMethodOXXO`. +You should only use one that is part of an existing `STPPaymentMethod` object. +*/ ++ (instancetype)new NS_UNAVAILABLE; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Stripe/PublicHeaders/Stripe/STPPaymentMethodOXXOParams.h b/Stripe/PublicHeaders/Stripe/STPPaymentMethodOXXOParams.h new file mode 100644 index 00000000000..afc3a518aff --- /dev/null +++ b/Stripe/PublicHeaders/Stripe/STPPaymentMethodOXXOParams.h @@ -0,0 +1,22 @@ +// +// STPPaymentMethodOXXOParams.h +// StripeiOS +// +// Created by Polo Li on 6/16/20. +// Copyright © 2020 Stripe, Inc. All rights reserved. +// + +#import + +#import "STPFormEncodable.h" + +NS_ASSUME_NONNULL_BEGIN + +/** +An object representing parameters used to create a OXXO Payment Method +*/ +@interface STPPaymentMethodOXXOParams : NSObject + +@end + +NS_ASSUME_NONNULL_END diff --git a/Stripe/PublicHeaders/Stripe/STPPaymentMethodParams.h b/Stripe/PublicHeaders/Stripe/STPPaymentMethodParams.h index 61f0c8a654b..a557e8bbe7f 100644 --- a/Stripe/PublicHeaders/Stripe/STPPaymentMethodParams.h +++ b/Stripe/PublicHeaders/Stripe/STPPaymentMethodParams.h @@ -24,6 +24,7 @@ STPPaymentMethodFPXParams, STPPaymentMethodGiropayParams, STPPaymentMethodGrabPayParams, STPPaymentMethodiDEALParams, +STPPaymentMethodOXXOParams, STPPaymentMethodPrzelewy24Params, STPPaymentMethodSofortParams, STPPaymentMethodSEPADebitParams; @@ -116,6 +117,11 @@ NS_ASSUME_NONNULL_BEGIN */ @property (nonatomic, nullable) STPPaymentMethodBancontactParams *bancontact; +/** + If this is a OXXO PaymentMethod, this contains additional details. + */ +@property (nonatomic, nullable) STPPaymentMethodOXXOParams *oxxo; + /** If this is a Sofort PaymentMethod, this contains additional details. */ @@ -273,6 +279,17 @@ NS_ASSUME_NONNULL_BEGIN billingDetails:(nullable STPPaymentMethodBillingDetails *)billingDetails metadata:(nullable NSDictionary *)metadata; +/** + Creates params for a OXXO PaymentMethod; + + @param oxxo An object containing additional OXXO details. + @param billingDetails An object containing the user's billing details. Note that `billingDetails.name` is required for OXXO PaymentMethods. + @param metadata Additional information to attach to the PaymentMethod. + */ ++ (nullable STPPaymentMethodParams *)paramsWithOXXO:(STPPaymentMethodOXXOParams *)oxxo + billingDetails:(STPPaymentMethodBillingDetails *)billingDetails + metadata:(nullable NSDictionary *)metadata; + /** Creates params from a single-use PaymentMethod. This is useful for recreating a new payment method with similar settings. It will return nil if used with a reusable PaymentMethod. diff --git a/Stripe/PublicHeaders/Stripe/Stripe.h b/Stripe/PublicHeaders/Stripe/Stripe.h index 10ed435cf56..af6b9ca0eca 100644 --- a/Stripe/PublicHeaders/Stripe/Stripe.h +++ b/Stripe/PublicHeaders/Stripe/Stripe.h @@ -49,6 +49,7 @@ #import "STPFPXBankBrand.h" #import "STPImageLibrary.h" #import "STPIntentAction.h" +#import "STPIntentActionOXXODisplayDetails.h" #import "STPIntentActionRedirectToURL.h" #import "STPIntentActionAlipayHandleRedirect.h" #import "STPKlarnaLineItem.h" @@ -103,6 +104,8 @@ #import "STPPaymentMethodGrabPayParams.h" #import "STPPaymentMethodGiropay.h" #import "STPPaymentMethodGiropayParams.h" +#import "STPPaymentMethodOXXO.h" +#import "STPPaymentMethodOXXOParams.h" #import "STPPaymentMethodParams.h" #import "STPPaymentMethodPrzelewy24.h" #import "STPPaymentMethodPrzelewy24Params.h" diff --git a/Stripe/Resources/Localizations/en.lproj/Localizable.strings b/Stripe/Resources/Localizations/en.lproj/Localizable.strings index afc0af9f997..48d17086507 100644 --- a/Stripe/Resources/Localizations/en.lproj/Localizable.strings +++ b/Stripe/Resources/Localizations/en.lproj/Localizable.strings @@ -139,6 +139,9 @@ /* Button to pay with a Bank Account (using FPX). */ "Online Banking (FPX)" = "Online Banking (FPX)"; +/* Payment Method type brand name */ +"OXXO" = "OXXO"; + /* Source type brand name */ "P24" = "P24"; diff --git a/Stripe/STPIntentAction.m b/Stripe/STPIntentAction.m index 1814d2c8f5e..e3bf16af02a 100644 --- a/Stripe/STPIntentAction.m +++ b/Stripe/STPIntentAction.m @@ -10,6 +10,7 @@ #import "STPIntentActionRedirectToURL.h" #import "STPIntentActionUseStripeSDK.h" +#import "STPIntentActionOXXODisplayDetails.h" #import "STPIntentActionAlipayHandleRedirect.h" #import "NSDictionary+Stripe.h" @@ -19,6 +20,7 @@ @interface STPIntentAction() @property (nonatomic) STPIntentActionType type; @property (nonatomic, strong, nullable) STPIntentActionRedirectToURL *redirectToURL; @property (nonatomic, strong, nullable) STPIntentActionUseStripeSDK *useStripeSDK; +@property (nonatomic, strong, nullable) STPIntentActionOXXODisplayDetails *oxxoDisplayDetails; @property (nonatomic, nullable) STPIntentActionAlipayHandleRedirect *alipayHandleRedirect; @property (nonatomic, copy, nonnull, readwrite) NSDictionary *allResponseFields; @@ -43,6 +45,8 @@ - (NSString *)description { case STPIntentActionTypeUseStripeSDK: [props addObject:[NSString stringWithFormat:@"useStripeSDK = %@", self.useStripeSDK]]; break; + case STPIntentActionTypeOXXODisplayDetails: + [props addObject:[NSString stringWithFormat:@"oxxoDisplayDetails = %@", self.oxxoDisplayDetails]]; case STPIntentActionTypeAlipayHandleRedirect: [props addObject:[NSString stringWithFormat:@"alipayHandleRedirect = %@", self.alipayHandleRedirect]]; break; @@ -58,6 +62,7 @@ + (STPIntentActionType)actionTypeFromString:(NSString *)string { NSDictionary *map = @{ @"redirect_to_url": @(STPIntentActionTypeRedirectToURL), @"use_stripe_sdk": @(STPIntentActionTypeUseStripeSDK), + @"oxxo_display_details": @(STPIntentActionTypeOXXODisplayDetails), @"alipay_handle_redirect": @(STPIntentActionTypeAlipayHandleRedirect), }; @@ -72,6 +77,8 @@ + (NSString *)stringFromActionType:(STPIntentActionType)actionType { return @"redirect_to_url"; case STPIntentActionTypeUseStripeSDK: return @"use_stripe_sdk"; + case STPIntentActionTypeOXXODisplayDetails: + return @"oxxo_display_details"; case STPIntentActionTypeAlipayHandleRedirect: return @"alipay_handle_redirection"; case STPIntentActionTypeUnknown: @@ -97,6 +104,9 @@ + (nullable instancetype)decodedObjectFromAPIResponse:(nullable NSDictionary *)r NSDictionary *useStripeSDKDict = [dict stp_dictionaryForKey:@"use_stripe_sdk"]; STPIntentActionUseStripeSDK *useStripeSDK = [STPIntentActionUseStripeSDK decodedObjectFromAPIResponse:useStripeSDKDict]; + + NSDictionary *oxxoDisplayDetailsDict = [dict stp_dictionaryForKey:@"oxxo_display_details"]; + STPIntentActionOXXODisplayDetails *oxxoDisplayDetails = [STPIntentActionOXXODisplayDetails decodedObjectFromAPIResponse:oxxoDisplayDetailsDict]; NSDictionary *alipayHandleRedirectDict = [dict stp_dictionaryForKey:@"alipay_handle_redirect"]; STPIntentActionAlipayHandleRedirect *alipayHandleRedirect = [STPIntentActionAlipayHandleRedirect decodedObjectFromAPIResponse:alipayHandleRedirectDict]; @@ -112,6 +122,9 @@ + (nullable instancetype)decodedObjectFromAPIResponse:(nullable NSDictionary *)r } else if (type == STPIntentActionTypeUseStripeSDK && useStripeSDK != nil) { action.type = type; action.useStripeSDK = useStripeSDK; + } else if (type == STPIntentActionTypeOXXODisplayDetails && oxxoDisplayDetails != nil) { + action.type = type; + action.oxxoDisplayDetails = oxxoDisplayDetails; } else if (type == STPIntentActionTypeAlipayHandleRedirect && alipayHandleRedirect != nil) { action.type = type; action.alipayHandleRedirect = alipayHandleRedirect; diff --git a/Stripe/STPIntentActionOXXODisplayDetails.m b/Stripe/STPIntentActionOXXODisplayDetails.m new file mode 100644 index 00000000000..e185927b8cc --- /dev/null +++ b/Stripe/STPIntentActionOXXODisplayDetails.m @@ -0,0 +1,64 @@ +// +// STPIntentActionOXXODisplayDetails.m +// Stripe +// +// Created by Polo Li on 6/23/20. +// Copyright © 2020 Stripe, Inc. All rights reserved. +// + +#import "STPIntentActionOXXODisplayDetails.h" + +#import "NSDictionary+Stripe.h" +#import "NSURLComponents+Stripe.h" + +@interface STPIntentActionOXXODisplayDetails() + +@property (nonatomic, nonnull) NSDate *expiresAfter; +@property (nonatomic, nonnull) NSURL *hostedVoucherURL; +@property (nonatomic, nonnull) NSString *number; +@property (nonatomic, nonnull, copy) NSDictionary *allResponseFields; + +@end + +@implementation STPIntentActionOXXODisplayDetails + +- (NSString *)description { + NSArray *props = @[ + // Object + [NSString stringWithFormat:@"%@: %p", NSStringFromClass([self class]), self], + + // OXXODisplayDetails + [NSString stringWithFormat:@"expiresAfter = %@", self.expiresAfter], + [NSString stringWithFormat:@"hostedVoucherURL = %@", self.hostedVoucherURL], + [NSString stringWithFormat:@"number = %@", self.number], + ]; + + return [NSString stringWithFormat:@"<%@>", [props componentsJoinedByString:@"; "]]; +} + +#pragma mark - STPAPIResponseDecodable + ++ (nullable instancetype)decodedObjectFromAPIResponse:(nullable NSDictionary*)response { + NSDictionary *dict = [response stp_dictionaryByRemovingNulls]; + if(!dict) { + return nil; + } + + NSDate *expiresAfter = [dict stp_dateForKey:@"expires_after"]; + NSURL *hostedVoucherURL = [dict stp_urlForKey:@"hosted_voucher_url"]; + NSString *number = [dict stp_stringForKey:@"number"]; + + if(!expiresAfter || !hostedVoucherURL || !number) { + return nil; + } + + STPIntentActionOXXODisplayDetails *oxxoDisplayDetails = [self new]; + oxxoDisplayDetails.expiresAfter = expiresAfter; + oxxoDisplayDetails.hostedVoucherURL = hostedVoucherURL; + oxxoDisplayDetails.number = number; + oxxoDisplayDetails.allResponseFields = dict; + + return oxxoDisplayDetails; +} + +@end diff --git a/Stripe/STPPaymentHandler.m b/Stripe/STPPaymentHandler.m index 858ed1ecfb9..2cb07a329e1 100644 --- a/Stripe/STPPaymentHandler.m +++ b/Stripe/STPPaymentHandler.m @@ -27,6 +27,7 @@ #import "STPIntentAction+Private.h" #import "STPIntentActionRedirectToURL+Private.h" #import "STPIntentActionUseStripeSDK.h" +#import "STPIntentActionOXXODisplayDetails.h" #import "STPIntentActionAlipayHandleRedirect.h" #import "STPSetupIntent.h" #import "STPSetupIntentConfirmParams.h" @@ -86,7 +87,7 @@ - (void)confirmPayment:(STPPaymentIntentParams *)paymentParams if (status == STPPaymentHandlerActionStatusSucceeded) { BOOL successIntentState = paymentIntent.status == STPPaymentIntentStatusSucceeded || paymentIntent.status == STPPaymentIntentStatusRequiresCapture || - (paymentIntent.status == STPPaymentIntentStatusProcessing && [[self class] _isProcessingIntentSuccessForType:paymentIntent.paymentMethod.type]); + (paymentIntent.status == STPPaymentIntentStatusProcessing && [[self class] _isProcessingIntentSuccessForType:paymentIntent.paymentMethod.type]) || (paymentIntent.status == STPPaymentIntentStatusRequiresAction && [self _isPaymentIntentNextActionVoucherBased:paymentIntent.nextAction]); if (error == nil && paymentIntent != nil && successIntentState) { completion(STPPaymentHandlerActionStatusSucceeded, paymentIntent, nil); @@ -322,6 +323,7 @@ + (BOOL)_isProcessingIntentSuccessForType:(STPPaymentMethodType)type { case STPPaymentMethodTypeEPS: case STPPaymentMethodTypePrzelewy24: case STPPaymentMethodTypeBancontact: + case STPPaymentMethodTypeOXXO: // fall through case STPPaymentMethodTypeUnknown: return NO; @@ -506,6 +508,11 @@ - (void)_handleAuthenticationForCurrentAction { break; } + case STPIntentActionTypeOXXODisplayDetails: { + NSURL *hostedVoucherURL = authenticationAction.oxxoDisplayDetails.hostedVoucherURL; + [self _handleRedirectToURL:hostedVoucherURL withReturnURL:nil]; + break; + } case STPIntentActionTypeUseStripeSDK: switch (authenticationAction.useStripeSDK.type) { case STPIntentActionUseStripeSDKTypeUnknown: @@ -638,7 +645,7 @@ - (void)_retrieveAndCheckIntentForCurrentAction { if ([_currentAction isKindOfClass:[STPPaymentHandlerPaymentIntentActionParams class]]) { STPPaymentHandlerPaymentIntentActionParams *currentAction = (STPPaymentHandlerPaymentIntentActionParams *)_currentAction; - + pingMarlinIfNecessary(currentAction, ^{ [currentAction.apiClient retrievePaymentIntentWithClientSecret:currentAction.paymentIntent.clientSecret expand:@[@"payment_method"] @@ -799,6 +806,20 @@ - (BOOL)_canPresentWithAuthenticationContext:(id)authe return canPresent; } +/** + Check paymentIntent.nextAction is voucher-based payment method. + Currently only OXXO payment is voucher-based. + If it's voucher-based, the paymentIntent status stays in requiresAction until the voucher is paid or expired. + */ + +- (BOOL)_isPaymentIntentNextActionVoucherBased:(STPIntentAction *)nextAction { + if (STPIntentActionTypeOXXODisplayDetails == nextAction.type) { + return YES; + } + + return NO; +} + #pragma mark - SFSafariViewControllerDelegate - (void)safariViewControllerDidFinish:(SFSafariViewController * __unused)controller { @@ -924,6 +945,7 @@ - (void)_markChallengeCanceledWithCompletion:(STPBooleanSuccessBlock)completion case STPIntentActionTypeUseStripeSDK: threeDSSourceID = _currentAction.nextAction.useStripeSDK.threeDSSourceID; break; + case STPIntentActionTypeOXXODisplayDetails: case STPIntentActionTypeAlipayHandleRedirect: case STPIntentActionTypeUnknown: break; diff --git a/Stripe/STPPaymentMethod.m b/Stripe/STPPaymentMethod.m index cc12cd991b5..237145a938d 100644 --- a/Stripe/STPPaymentMethod.m +++ b/Stripe/STPPaymentMethod.m @@ -23,6 +23,7 @@ #import "STPPaymentMethodGiropay.h" #import "STPPaymentMethodGrabPay.h" #import "STPPaymentMethodiDEAL.h" +#import "STPPaymentMethodOXXO.h" #import "STPPaymentMethodPrzelewy24.h" #import "STPPaymentMethodSEPADebit.h" #import "STPPaymentMethodSofort.h" @@ -43,6 +44,7 @@ @interface STPPaymentMethod () @property (nonatomic, strong, nullable, readwrite) STPPaymentMethodAUBECSDebit *auBECSDebit; @property (nonatomic, strong, nullable, readwrite) STPPaymentMethodGiropay *giropay; @property (nonatomic, strong, nullable, readwrite) STPPaymentMethodEPS *eps; +@property (nonatomic, strong, nullable, readwrite) STPPaymentMethodOXXO *oxxo; @property (nonatomic, strong, nullable, readwrite) STPPaymentMethodPrzelewy24 *przelewy24; @property (nonatomic, strong, nullable, readwrite) STPPaymentMethodBancontact *bancontact; @property (nonatomic, strong, nullable, readwrite) STPPaymentMethodSofort *sofort; @@ -79,6 +81,7 @@ - (NSString *)description { [NSString stringWithFormat:@"eps = %@", self.eps], [NSString stringWithFormat:@"fpx = %@", self.fpx], [NSString stringWithFormat:@"giropay = %@", self.giropay], + [NSString stringWithFormat:@"oxxo = %@", self.oxxo], [NSString stringWithFormat:@"grabPay = %@", self.bacsDebit], [NSString stringWithFormat:@"przelewy24 = %@", self.przelewy24], [NSString stringWithFormat:@"sepaDebit = %@", self.sepaDebit], @@ -106,6 +109,7 @@ - (NSString *)description { @"p24": @(STPPaymentMethodTypePrzelewy24), @"eps": @(STPPaymentMethodTypeEPS), @"bancontact": @(STPPaymentMethodTypeBancontact), + @"oxxo": @(STPPaymentMethodTypeOXXO), @"sofort": @(STPPaymentMethodTypeSofort), @"alipay": @(STPPaymentMethodTypeAlipay), }; @@ -166,6 +170,7 @@ + (nullable instancetype)decodedObjectFromAPIResponse:(nullable NSDictionary *)r paymentMethod.eps = [STPPaymentMethodEPS decodedObjectFromAPIResponse:[dict stp_dictionaryForKey:@"eps"]]; paymentMethod.przelewy24 = [STPPaymentMethodPrzelewy24 decodedObjectFromAPIResponse:[dict stp_dictionaryForKey:@"p24"]]; paymentMethod.bancontact = [STPPaymentMethodBancontact decodedObjectFromAPIResponse:[dict stp_dictionaryForKey:@"bancontact"]]; + paymentMethod.oxxo = [STPPaymentMethodOXXO decodedObjectFromAPIResponse:[dict stp_dictionaryForKey:@"oxxo"]]; paymentMethod.sofort = [STPPaymentMethodSofort decodedObjectFromAPIResponse:[dict stp_dictionaryForKey:@"sofort"]]; paymentMethod.customerId = [dict stp_stringForKey:@"customer"]; paymentMethod.metadata = [[dict stp_dictionaryForKey:@"metadata"] stp_dictionaryByRemovingNonStrings]; @@ -225,6 +230,8 @@ - (NSString *)label { return STPLocalizedString(@"Przelewy24", @"Payment Method type brand name."); case STPPaymentMethodTypeBancontact: return STPLocalizedString(@"Bancontact", @"Payment Method type brand name"); + case STPPaymentMethodTypeOXXO: + return STPLocalizedString(@"OXXO", @"Payment Method type brand name"); case STPPaymentMethodTypeSofort: return STPLocalizedString(@"Sofort", @"Payment Method type brand name"); case STPPaymentMethodTypeBacsDebit: @@ -251,6 +258,7 @@ - (BOOL)isReusable { case STPPaymentMethodTypeEPS: case STPPaymentMethodTypePrzelewy24: case STPPaymentMethodTypeBancontact: + case STPPaymentMethodTypeOXXO: case STPPaymentMethodTypeSofort: case STPPaymentMethodTypeGrabPay: // fall through diff --git a/Stripe/STPPaymentMethodOXXO.m b/Stripe/STPPaymentMethodOXXO.m new file mode 100644 index 00000000000..6524aca8055 --- /dev/null +++ b/Stripe/STPPaymentMethodOXXO.m @@ -0,0 +1,50 @@ +// +// STPPaymentMethodOXXO.m +// StripeiOS +// +// Created by Polo Li on 6/15/20. +// Copyright © 2020 Stripe, Inc. All rights reserved. +// + +#import "STPPaymentMethodOXXO.h" + +#import "NSDictionary+Stripe.h" + +NS_ASSUME_NONNULL_BEGIN + +@implementation STPPaymentMethodOXXO + +@synthesize allResponseFields = _allResponseFields; + +#pragma mark - Description + +- (NSString *)description { + NSArray *props = @[ + // Object + [NSString stringWithFormat:@"%@: %p", NSStringFromClass([self class]), self], + ]; + + return [NSString stringWithFormat:@"<%@>", [props componentsJoinedByString:@"; "]]; +} + +#pragma mark - STPAPIResponseDecodable + ++ (nullable instancetype)decodedObjectFromAPIResponse:(nullable NSDictionary *)response { + NSDictionary *dict = [response stp_dictionaryByRemovingNulls]; + if (!dict) { + return nil; + } + return [[self alloc] initWithDictionary:dict]; +} + +- (nullable instancetype)initWithDictionary:(NSDictionary *)dict { + self = [super init]; + if (self) { + _allResponseFields = dict.copy; + } + return self; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/Stripe/STPPaymentMethodOXXOParams.m b/Stripe/STPPaymentMethodOXXOParams.m new file mode 100644 index 00000000000..932b2b384e7 --- /dev/null +++ b/Stripe/STPPaymentMethodOXXOParams.m @@ -0,0 +1,28 @@ +// +// STPPaymentMethodOXXOParams.m +// StripeiOS +// +// Created by Polo Li on 6/16/20. +// Copyright © 2020 Stripe, Inc. All rights reserved. +// + +#import "STPPaymentMethodOXXOParams.h" + +NS_ASSUME_NONNULL_BEGIN + +@implementation STPPaymentMethodOXXOParams + +@synthesize additionalAPIParameters = _additionalAPIParameters; + ++ (nullable NSString *)rootObjectName { + return @"oxxo"; +} + ++ (NSDictionary *)propertyNamesToFormFieldNamesMapping { + return @{ + }; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/Stripe/STPPaymentMethodParams.m b/Stripe/STPPaymentMethodParams.m index 24f4ed28bbe..1138a33da51 100644 --- a/Stripe/STPPaymentMethodParams.m +++ b/Stripe/STPPaymentMethodParams.m @@ -25,6 +25,7 @@ #import "STPPaymentMethodGrabPayParams.h" #import "STPPaymentMethodiDEAL.h" #import "STPPaymentMethodiDEALParams.h" +#import "STPPaymentMethodOXXOParams.h" #import "STPPaymentMethodPrzelewy24Params.h" #import "STPPaymentMethodSEPADebitParams.h" #import "STPPaymentMethodSofortParams.h" @@ -135,6 +136,17 @@ + (nullable STPPaymentMethodParams *)paramsWithBancontact:(STPPaymentMethodBanco return params; } ++ (nullable STPPaymentMethodParams *)paramsWithOXXO:(STPPaymentMethodOXXOParams *)oxxo + billingDetails:(STPPaymentMethodBillingDetails *)billingDetails + metadata:(NSDictionary *)metadata { + STPPaymentMethodParams *params = [self new]; + params.type = STPPaymentMethodTypeOXXO; + params.oxxo = oxxo; + params.billingDetails = billingDetails; + params.metadata = metadata; + return params; +} + + (nullable STPPaymentMethodParams *)paramsWithSofort:(STPPaymentMethodSofortParams *)sofort billingDetails:(nullable STPPaymentMethodBillingDetails *)billingDetails metadata:(nullable NSDictionary *)metadata { @@ -217,6 +229,14 @@ + (nullable STPPaymentMethodParams *)paramsWithSingleUsePaymentMethod:(STPPaymen params.billingDetails = paymentMethod.billingDetails; break; } + case STPPaymentMethodTypeOXXO: + { + params.type = STPPaymentMethodTypeOXXO; + STPPaymentMethodOXXOParams *oxxo = [[STPPaymentMethodOXXOParams alloc] init]; + params.oxxo = oxxo; + params.billingDetails = paymentMethod.billingDetails; + break; + } case STPPaymentMethodTypeAlipay: { // Careful! In the future, when we add recurring Alipay, we'll need to look at this! @@ -283,6 +303,7 @@ + (nonnull NSDictionary *)propertyNamesToFormFieldNamesMapping { NSStringFromSelector(@selector(grabPay)): @"grabpay", NSStringFromSelector(@selector(przelewy24)): @"p24", NSStringFromSelector(@selector(bancontact)): @"bancontact", + NSStringFromSelector(@selector(oxxo)): @"oxxo", NSStringFromSelector(@selector(sofort)): @"sofort", NSStringFromSelector(@selector(metadata)): @"metadata", }; @@ -343,6 +364,8 @@ - (NSString *)label { return @"EPS"; case STPPaymentMethodTypeBancontact: return @"Bancontact"; + case STPPaymentMethodTypeOXXO: + return @"OXXO"; case STPPaymentMethodTypeSofort: return @"Sofort"; case STPPaymentMethodTypeGrabPay: @@ -370,6 +393,7 @@ - (BOOL)isReusable { case STPPaymentMethodTypeEPS: case STPPaymentMethodTypePrzelewy24: case STPPaymentMethodTypeBancontact: + case STPPaymentMethodTypeOXXO: case STPPaymentMethodTypeSofort: // fall through case STPPaymentMethodTypeUnknown: diff --git a/Tests/Tests/STPPaymentIntentFunctionalTest.m b/Tests/Tests/STPPaymentIntentFunctionalTest.m index 5f2c47bc2ca..585cd5594d8 100644 --- a/Tests/Tests/STPPaymentIntentFunctionalTest.m +++ b/Tests/Tests/STPPaymentIntentFunctionalTest.m @@ -655,6 +655,59 @@ - (void)testConfirmPaymentIntentWithBancontact { [self waitForExpectationsWithTimeout:STPTestingNetworkRequestTimeout handler:nil]; } +#pragma mark - OXXO + +- (void)testConfirmPaymentIntentWithOXXO { + __block NSString *clientSecret = nil; + XCTestExpectation *createExpectation = [self expectationWithDescription:@"Create PaymentIntent."]; + [[STPTestingAPIClient sharedClient] createPaymentIntentWithParams:@{ + @"payment_method_types": @[@"oxxo"], + @"amount": @(2000), + @"currency": @"mxn", + } + account:@"mex" + completion:^(NSString * _Nullable createdClientSecret, NSError * _Nullable creationError) { + XCTAssertNotNil(createdClientSecret); + XCTAssertNil(creationError); + [createExpectation fulfill]; + clientSecret = [createdClientSecret copy]; + }]; + [self waitForExpectationsWithTimeout:STPTestingNetworkRequestTimeout handler:nil]; + XCTAssertNotNil(clientSecret); + + STPAPIClient *client = [[STPAPIClient alloc] initWithPublishableKey:STPTestingMEXPublishableKey]; + XCTestExpectation *expectation = [self expectationWithDescription:@"Payment Intent confirm"]; + + STPPaymentIntentParams *paymentIntentParams = [[STPPaymentIntentParams alloc] initWithClientSecret:clientSecret]; + STPPaymentMethodOXXOParams *oxxo = [STPPaymentMethodOXXOParams new]; + + STPPaymentMethodBillingDetails *billingDetails = [STPPaymentMethodBillingDetails new]; + billingDetails.name = @"Jane Doe"; + billingDetails.email = @"email@email.com"; + + paymentIntentParams.paymentMethodParams = [STPPaymentMethodParams paramsWithOXXO:oxxo + billingDetails:billingDetails + metadata:@{@"test_key": @"test_value"}]; + [client confirmPaymentIntentWithParams:paymentIntentParams + completion:^(STPPaymentIntent * _Nullable paymentIntent, NSError * _Nullable error) { + XCTAssertNil(error, @"With valid key + secret, should be able to confirm the intent"); + + XCTAssertNotNil(paymentIntent); + XCTAssertEqualObjects(paymentIntent.stripeId, paymentIntentParams.stripeId); + XCTAssertFalse(paymentIntent.livemode); + XCTAssertNotNil(paymentIntent.paymentMethodId); + + // OXXO requires display the voucher as next step + NSDictionary *oxxoDisplayDetails = [paymentIntent.nextAction.allResponseFields objectForKey:@"oxxo_display_details"]; + XCTAssertNotNil([oxxoDisplayDetails objectForKey:@"expires_after"]); + XCTAssertNotNil([oxxoDisplayDetails objectForKey:@"number"]); + XCTAssertEqual(paymentIntent.status, STPPaymentIntentStatusRequiresAction); + [expectation fulfill]; + }]; + + [self waitForExpectationsWithTimeout:STPTestingNetworkRequestTimeout handler:nil]; +} + #pragma mark - EPS - (void)testConfirmPaymentIntentWithEPS { diff --git a/Tests/Tests/STPPaymentMethodOXXOParamsTests.m b/Tests/Tests/STPPaymentMethodOXXOParamsTests.m new file mode 100644 index 00000000000..dcec8e99517 --- /dev/null +++ b/Tests/Tests/STPPaymentMethodOXXOParamsTests.m @@ -0,0 +1,60 @@ +// +// STPPaymentMethodOXXOParamsTests.m +// StripeiOS Tests +// +// Created by Polo Li on 6/16/20. +// Copyright © 2020 Stripe, Inc. All rights reserved. +// + +#import + +#import "STPAPIClient.h" +#import "STPPaymentMethod.h" +#import "STPPaymentMethodOXXOParams.h" +#import "STPPaymentMethodBillingDetails.h" +#import "STPPaymentMethodParams.h" +#import "STPTestingAPIClient.h" + +@interface STPPaymentMethodOXXOParamsTests : XCTestCase + +@end + +@implementation STPPaymentMethodOXXOParamsTests + +- (void)testCreateOXXOPaymentMethod { + STPAPIClient *client = [[STPAPIClient alloc] initWithPublishableKey:STPTestingDefaultPublishableKey]; + STPPaymentMethodOXXOParams *oxxoParams = [STPPaymentMethodOXXOParams new]; + + STPPaymentMethodBillingDetails *billingDetails = [STPPaymentMethodBillingDetails new]; + billingDetails.name = @"Jane Doe"; + billingDetails.email = @"test@test.com"; + + STPPaymentMethodParams *params = [STPPaymentMethodParams paramsWithOXXO:oxxoParams + billingDetails:billingDetails + metadata:@{@"test_key": @"test_value"}]; + + XCTestExpectation *expectation = [self expectationWithDescription:@"Payment Method OXXO create"]; + + [client createPaymentMethodWithParams:params + completion:^(STPPaymentMethod * _Nullable paymentMethod, NSError * _Nullable error) { + [expectation fulfill]; + + XCTAssertNil(error, @"Unexpected error creating OXXO PaymentMethod: %@", error); + XCTAssertNotNil(paymentMethod, @"Failed to create OXXO PaymentMethod"); + XCTAssertNotNil(paymentMethod.stripeId, @"Missing stripeId"); + XCTAssertNotNil(paymentMethod.created, @"Missing created"); + XCTAssertFalse(paymentMethod.liveMode, @"Incorrect livemode"); + XCTAssertEqual(paymentMethod.type, STPPaymentMethodTypeOXXO, @"Incorrect PaymentMethod type"); + + // Billing Details + XCTAssertEqualObjects(paymentMethod.billingDetails.name, @"Jane Doe", @"Incorrect name"); + XCTAssertEqualObjects(paymentMethod.billingDetails.email, @"test@test.com", @"Incorrect email"); + + // OXXO Details + XCTAssertNotNil(paymentMethod.oxxo, @"Missing OXXO"); + }]; + + [self waitForExpectationsWithTimeout:STPTestingNetworkRequestTimeout handler:nil]; +} + +@end diff --git a/Tests/Tests/STPPaymentMethodOXXOTests.m b/Tests/Tests/STPPaymentMethodOXXOTests.m new file mode 100644 index 00000000000..2a9361cb9c3 --- /dev/null +++ b/Tests/Tests/STPPaymentMethodOXXOTests.m @@ -0,0 +1,49 @@ +// +// STPPaymentMethodOXXOTests.m +// StripeiOS Tests +// +// Created by Polo Li on 6/16/20. +// Copyright © 2020 Stripe, Inc. All rights reserved. +// + +#import + +#import "STPAPIClient+Private.h" +#import "STPPaymentIntent+Private.h" +#import "STPPaymentMethod.h" +#import "STPPaymentMethodOXXO.h" +#import "STPTestingAPIClient.h" + +@interface STPPaymentMethodOXXOTests : XCTestCase + +@property (nonatomic, readonly) NSDictionary *oxxoJSON; + +@end + +@implementation STPPaymentMethodOXXOTests + +- (void)_retrieveOXXOJSON:(void (^)(NSDictionary *))completion { + if (self.oxxoJSON) { + completion(self.oxxoJSON); + } else { + STPAPIClient *client = [[STPAPIClient alloc] initWithPublishableKey:STPTestingMEXPublishableKey]; + [client retrievePaymentIntentWithClientSecret:@"pi_1GvAdyHNG4o8pO5l0dr078gf_secret_h0tJE5mSX9BPEkmpKSh93jBXi" + expand:@[@"payment_method"] + completion:^(STPPaymentIntent * _Nullable paymentIntent, __unused NSError * _Nullable error) { + self->_oxxoJSON = paymentIntent.paymentMethod.oxxo.allResponseFields; + completion(self.oxxoJSON); + }]; + } +} + +- (void)testCorrectParsing { + XCTestExpectation *expectation = [self expectationWithDescription:@"Retrieve payment intent"]; + [self _retrieveOXXOJSON:^(NSDictionary *json) { + STPPaymentMethodOXXO *oxxo = [STPPaymentMethodOXXO decodedObjectFromAPIResponse:json]; + XCTAssertNotNil(oxxo, @"Failed to decode JSON"); + [expectation fulfill]; + }]; + [self waitForExpectationsWithTimeout:STPTestingNetworkRequestTimeout handler:nil]; +} + +@end diff --git a/Tests/Tests/STPPaymentMethodTest.m b/Tests/Tests/STPPaymentMethodTest.m index 6a2090c5d49..d26c347c70d 100644 --- a/Tests/Tests/STPPaymentMethodTest.m +++ b/Tests/Tests/STPPaymentMethodTest.m @@ -95,6 +95,9 @@ - (void)testStringFromType { case STPPaymentMethodTypeEPS: XCTAssertEqualObjects(string, @"eps"); break; + case STPPaymentMethodTypeOXXO: + XCTAssertEqualObjects(string, @"oxxo"); + break; case STPPaymentMethodTypeSofort: XCTAssertEqualObjects(string, @"sofort"); break; diff --git a/Tests/Tests/STPTestingAPIClient.h b/Tests/Tests/STPTestingAPIClient.h index 42b43323db5..d4da6579371 100644 --- a/Tests/Tests/STPTestingAPIClient.h +++ b/Tests/Tests/STPTestingAPIClient.h @@ -19,6 +19,8 @@ NS_ASSUME_NONNULL_BEGIN static NSString * const STPTestingDefaultPublishableKey = @"pk_test_ErsyMEOTudSjQR8hh0VrQr5X008sBXGOu6"; // Test account in Australia static NSString * const STPTestingAUPublishableKey = @"pk_test_GNmlCJ6AFgWXm4mJYiyWSOWN00KIIiri7F"; +// Test account in Mexico +static NSString * const STPTestingMEXPublishableKey = @"pk_test_51GvAY5HNG4o8pO5lDEegY72rkF1TMiMyuTxSFJsmsH7U0KjTwmEf2VuXHVHecil64QA8za8Um2uSsFsfrG0BkzFo00sb1uhblF"; // Test account in SG static NSString * const STPTestingSGPublishableKey = @"pk_test_51H7oXMAOnZToJom1hqiSvNGsUVTrG1SaXRSBon9xcEp0yDFAxEh5biA4n0ty6paEsD5Mo5ps1b7Taj9WAHQzjup800m8A8Nc3u"; @@ -32,14 +34,14 @@ static const NSTimeInterval STPTestingNetworkRequestTimeout = 8; completion:(void (^)(NSString * _Nullable, NSError * _Nullable))completion; - (void)createPaymentIntentWithParams:(nullable NSDictionary *)params - account:(nullable NSString *)account // nil for default or "au" for Australia test account + account:(nullable NSString *)account // nil for default or "au" for Australia test account or "mex" for Mexico test account completion:(void (^)(NSString * _Nullable, NSError * _Nullable))completion; - (void)createSetupIntentWithParams:(nullable NSDictionary *)params completion:(void (^)(NSString *_Nullable, NSError * _Nullable))completion; - (void)createSetupIntentWithParams:(nullable NSDictionary *)params - account:(nullable NSString *)account // nil for default or "au" for Australia test account + account:(nullable NSString *)account // nil for default or "au" for Australia test account or "mex" for Mexico test account completion:(void (^)(NSString *_Nullable, NSError * _Nullable))completion; @end