From 78ca92a85d243cfbe2ff848bf19c447a383ddd5d Mon Sep 17 00:00:00 2001 From: Yuki Tokuhiro Date: Fri, 31 Jan 2020 17:02:16 -0800 Subject: [PATCH 1/3] GrabPay --- .../project.pbxproj | 14 ++- .../BrowseExamplesViewController.m | 10 +- .../EPSExampleViewController.m | 2 +- .../GrabPayExampleViewController.swift | 101 ++++++++++++++++++ Stripe.xcodeproj/project.pbxproj | 42 +++++++- Stripe/Payments/STPPaymentHandler.m | 1 + Stripe/PublicHeaders/STPPaymentMethod.h | 6 ++ Stripe/PublicHeaders/STPPaymentMethodEnums.h | 5 + .../PublicHeaders/STPPaymentMethodGrabPay.h | 34 ++++++ Stripe/PublicHeaders/STPPaymentMethodParams.h | 18 ++++ Stripe/PublicHeaders/Stripe.h | 2 + Stripe/STPPaymentMethod.m | 8 ++ Stripe/STPPaymentMethodGrabPay.m | 45 ++++++++ Stripe/STPPaymentMethodGrabPayParams.h | 22 ++++ Stripe/STPPaymentMethodGrabPayParams.m | 25 +++++ Stripe/STPPaymentMethodParams.m | 26 ++++- Tests/Tests/STPFixtures.h | 1 + Tests/Tests/STPFixtures.m | 1 + Tests/Tests/STPPaymentIntentFunctionalTest.m | 55 ++++++++++ .../Tests/STPPaymentMethodGrabPayParamsTest.m | 60 +++++++++++ Tests/Tests/STPPaymentMethodTest.m | 3 + Tests/Tests/STPTestingAPIClient.h | 2 + 22 files changed, 471 insertions(+), 12 deletions(-) create mode 100644 Example/Non-Card Payment Examples/GrabPayExampleViewController.swift create mode 100644 Stripe/PublicHeaders/STPPaymentMethodGrabPay.h create mode 100644 Stripe/STPPaymentMethodGrabPay.m create mode 100644 Stripe/STPPaymentMethodGrabPayParams.h create mode 100644 Stripe/STPPaymentMethodGrabPayParams.m create mode 100644 Tests/Tests/STPPaymentMethodGrabPayParamsTest.m diff --git a/Example/Non-Card Payment Examples.xcodeproj/project.pbxproj b/Example/Non-Card Payment Examples.xcodeproj/project.pbxproj index 28e64f42c7d..e2c606d54e1 100644 --- a/Example/Non-Card Payment Examples.xcodeproj/project.pbxproj +++ b/Example/Non-Card Payment Examples.xcodeproj/project.pbxproj @@ -25,12 +25,13 @@ 36B6CB5D234BEB8400331C38 /* SEPADebitExampleViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 36B6CB5C234BEB8400331C38 /* SEPADebitExampleViewController.m */; }; 36B6CB64234FD9AA00331C38 /* iDEALExampleViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 36B6CB63234FD9AA00331C38 /* iDEALExampleViewController.m */; }; 448895B424526C6B00F7D0C2 /* Przelewy24ExampleViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 448895B324526C6B00F7D0C2 /* Przelewy24ExampleViewController.m */; }; - 69A6C306246E63A2005FF304 /* EPSExampleViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 69A6C305246E63A2005FF304 /* EPSExampleViewController.m */; }; 44BDCFE4245A4CAE007EE6D5 /* BancontactExampleViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 44BDCFE3245A4CAE007EE6D5 /* BancontactExampleViewController.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 */; }; B65E8FCC22FA078A0057E64A /* WeChatPayExampleViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = B65E8FCB22FA078A0057E64A /* WeChatPayExampleViewController.m */; }; B68882D323FC5BD30057C5AD /* BacsDebitViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B68882D223FC5BD30057C5AD /* BacsDebitViewController.swift */; }; + B6B0BB2E24C8A21A0000998E /* GrabPayExampleViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6B0BB2D24C8A21A0000998E /* GrabPayExampleViewController.swift */; }; B6C1FC832330432E0097FC4C /* AlipayExampleViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6C1FC822330432E0097FC4C /* AlipayExampleViewController.swift */; }; C12C50DD1E57B3C800EC6D58 /* BrowseExamplesViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = C12C50DC1E57B3C800EC6D58 /* BrowseExamplesViewController.m */; }; C1CACE891E5DF7A9002D0821 /* ApplePayExampleViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = C1CACE881E5DF7A9002D0821 /* ApplePayExampleViewController.m */; }; @@ -81,10 +82,10 @@ 36B6CB63234FD9AA00331C38 /* iDEALExampleViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = iDEALExampleViewController.m; sourceTree = ""; }; 448895B224526C6B00F7D0C2 /* Przelewy24ExampleViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Przelewy24ExampleViewController.h; sourceTree = ""; }; 448895B324526C6B00F7D0C2 /* Przelewy24ExampleViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = Przelewy24ExampleViewController.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 = ""; }; 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 = ""; }; + 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 = ""; }; 8BBD79C9207FD31A00F85BED /* zh-Hans */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/Localizable.strings"; sourceTree = ""; }; 8BBD79CA207FD32100F85BED /* nl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.strings; name = nl; path = nl.lproj/Localizable.strings; sourceTree = ""; }; @@ -100,6 +101,7 @@ B65E8FCA22FA078A0057E64A /* WeChatPayExampleViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WeChatPayExampleViewController.h; sourceTree = ""; }; B65E8FCB22FA078A0057E64A /* WeChatPayExampleViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = WeChatPayExampleViewController.m; sourceTree = ""; }; B68882D223FC5BD30057C5AD /* BacsDebitViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BacsDebitViewController.swift; sourceTree = ""; }; + B6B0BB2D24C8A21A0000998E /* GrabPayExampleViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GrabPayExampleViewController.swift; sourceTree = ""; }; B6C1FC812330432E0097FC4C /* Non-Card Payment Examples-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Non-Card Payment Examples-Bridging-Header.h"; sourceTree = ""; }; B6C1FC822330432E0097FC4C /* AlipayExampleViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AlipayExampleViewController.swift; sourceTree = ""; }; C12C50DB1E57B3C800EC6D58 /* BrowseExamplesViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BrowseExamplesViewController.h; sourceTree = ""; }; @@ -159,10 +161,13 @@ C12C50DC1E57B3C800EC6D58 /* BrowseExamplesViewController.m */, 04533F171A688A0A00C7E52E /* Constants.h */, 04533F181A688A0A00C7E52E /* Constants.m */, + 69A6C304246E6225005FF304 /* EPSExampleViewController.h */, + 69A6C305246E63A2005FF304 /* EPSExampleViewController.m */, 31A8934B230F6ABD007ABE37 /* FPXExampleViewController.h */, 31A8934C230F6ABD007ABE37 /* FPXExampleViewController.m */, 361962572450DA280025D60B /* GiropayExampleViewController.h */, 361962582450DA280025D60B /* GiropayExampleViewController.m */, + B6B0BB2D24C8A21A0000998E /* GrabPayExampleViewController.swift */, 36B6CB62234FD9AA00331C38 /* iDEALExampleViewController.h */, 36B6CB63234FD9AA00331C38 /* iDEALExampleViewController.m */, 04533E971A687F5D00C7E52E /* Images.xcassets */, @@ -184,8 +189,6 @@ 04533E8A1A687F5D00C7E52E /* Supporting Files */, B65E8FCA22FA078A0057E64A /* WeChatPayExampleViewController.h */, B65E8FCB22FA078A0057E64A /* WeChatPayExampleViewController.m */, - 69A6C304246E6225005FF304 /* EPSExampleViewController.h */, - 69A6C305246E63A2005FF304 /* EPSExampleViewController.m */, ); path = "Non-Card Payment Examples"; sourceTree = ""; @@ -319,6 +322,7 @@ 04533EB21A68802E00C7E52E /* ShippingManager.m in Sources */, 361962592450DA280025D60B /* GiropayExampleViewController.m in Sources */, 31C108D823677C0100FE91B7 /* KlarnaExampleViewController.swift in Sources */, + B6B0BB2E24C8A21A0000998E /* GrabPayExampleViewController.swift in Sources */, 04533E901A687F5D00C7E52E /* AppDelegate.m in Sources */, 44BDCFE4245A4CAE007EE6D5 /* BancontactExampleViewController.m in Sources */, B65E8FCC22FA078A0057E64A /* WeChatPayExampleViewController.m in Sources */, diff --git a/Example/Non-Card Payment Examples/BrowseExamplesViewController.m b/Example/Non-Card Payment Examples/BrowseExamplesViewController.m index 6032ddad4f0..61d81b1e0dc 100644 --- a/Example/Non-Card Payment Examples/BrowseExamplesViewController.m +++ b/Example/Non-Card Payment Examples/BrowseExamplesViewController.m @@ -43,7 +43,7 @@ - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { } - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { - return 14; + return 15; } - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { @@ -91,6 +91,8 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N case 13: cell.textLabel.text = @"EPS"; break; + case 14: + cell.textLabel.text = @"GrabPay"; } return cell; } @@ -189,6 +191,12 @@ - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath viewController = exampleVC; break; } + case 14: { + GrabPayExampleViewController *exampleVC = [GrabPayExampleViewController new]; + exampleVC.delegate = self; + viewController = exampleVC; + break; + } } [self.navigationController pushViewController:viewController animated:YES]; } diff --git a/Example/Non-Card Payment Examples/EPSExampleViewController.m b/Example/Non-Card Payment Examples/EPSExampleViewController.m index c6d52accfec..2e8a2d2197f 100644 --- a/Example/Non-Card Payment Examples/EPSExampleViewController.m +++ b/Example/Non-Card Payment Examples/EPSExampleViewController.m @@ -26,7 +26,7 @@ - (void)viewDidLoad { [super viewDidLoad]; self.title = @"EPS"; - + _nameField = [[UITextField alloc] init]; _nameField.borderStyle = UITextBorderStyleRoundedRect; _nameField.textContentType = UITextContentTypeName; diff --git a/Example/Non-Card Payment Examples/GrabPayExampleViewController.swift b/Example/Non-Card Payment Examples/GrabPayExampleViewController.swift new file mode 100644 index 00000000000..6bfa5693db7 --- /dev/null +++ b/Example/Non-Card Payment Examples/GrabPayExampleViewController.swift @@ -0,0 +1,101 @@ +// +// GrabPayExampleViewController.swift +// Non-Card Payment Examples +// +// Created by Yuki Tokuhiro on 7/22/20. +// Copyright © 2020 Stripe. All rights reserved. +// + +import UIKit +import Stripe + +/** + An example of accepting GrabPay payments. + + See https://stripe.com/docs/payments/grabpay/accept-a-payment + */ +class GrabPayExampleViewController: UIViewController { + @objc weak var delegate: ExampleViewControllerDelegate? + var inProgress: Bool = false { + didSet { + navigationController?.navigationBar.isUserInteractionEnabled = !inProgress + payButton.isEnabled = !inProgress + inProgress ? activityIndicatorView.startAnimating() : activityIndicatorView.stopAnimating() + } + } + + // UI + lazy var activityIndicatorView = { + return UIActivityIndicatorView(style: .gray) + }() + lazy var payButton: UIButton = { + let button = UIButton(type: .roundedRect) + button.setTitle("Pay with GrabPay", for: .normal) + button.addTarget(self, action: #selector(didTapPayButton), for: .touchUpInside) + return button + }() + + override func viewDidLoad() { + super.viewDidLoad() + view.backgroundColor = .white + title = "GrabPay" + [payButton, activityIndicatorView].forEach { subview in + view.addSubview(subview) + subview.translatesAutoresizingMaskIntoConstraints = false + } + + let constraints = [ + payButton.centerXAnchor.constraint(equalTo: view.centerXAnchor), + payButton.centerYAnchor.constraint(equalTo: view.centerYAnchor), + + activityIndicatorView.centerXAnchor.constraint(equalTo: view.centerXAnchor), + activityIndicatorView.centerYAnchor.constraint(equalTo: view.centerYAnchor), + ] + NSLayoutConstraint.activate(constraints) + } + + @objc func didTapPayButton(sender: UIButton) { + inProgress = true + + let grabPayParams = STPPaymentMethodGrabPayParams() + + let billingDetails = STPPaymentMethodBillingDetails() + billingDetails.name = "Chiaki" + billingDetails.email = "email@email.com" + + let paymentMethodParams = STPPaymentMethodParams(grabPay: grabPayParams, billingDetails: billingDetails, metadata: nil) + + MyAPIClient.shared().createPaymentIntent(completion: { (result, clientSecret, error) in + guard let clientSecret = clientSecret else { + self.delegate?.exampleViewController(self, didFinishWithError: error) + return + } + + let paymentIntentParams = STPPaymentIntentParams(clientSecret: clientSecret) + paymentIntentParams.paymentMethodParams = paymentMethodParams + paymentIntentParams.returnURL = "payments-example://stripe-redirect" + + STPPaymentHandler.shared().confirmPayment(withParams: paymentIntentParams, authenticationContext: self) { (status, intent, error) in + switch (status) { + case .canceled: + self.delegate?.exampleViewController(self, didFinishWithMessage: "Canceled.") + return + case .failed: + self.delegate?.exampleViewController(self, didFinishWithMessage: "Payment failed. \(String(describing: error?.localizedDescription))") + return + case .succeeded: + self.delegate?.exampleViewController(self, didFinishWithMessage: "Your order was received and is awaiting payment confirmation.") + @unknown default: + fatalError() + } + } + }, additionalParameters: "country=sg") + } +} + +// MARK: - +extension GrabPayExampleViewController: STPAuthenticationContext { + func authenticationPresentingViewController() -> UIViewController { + self + } +} diff --git a/Stripe.xcodeproj/project.pbxproj b/Stripe.xcodeproj/project.pbxproj index fcf6383699b..57c63f3b68a 100644 --- a/Stripe.xcodeproj/project.pbxproj +++ b/Stripe.xcodeproj/project.pbxproj @@ -1000,6 +1000,15 @@ B67AAC5A24D885EB0012FCEB /* STPIntentActionAlipayHandleRedirect.m in Sources */ = {isa = PBXBuildFile; fileRef = B67AAC5624D885EB0012FCEB /* STPIntentActionAlipayHandleRedirect.m */; }; B67D7D4B2294A081000FBA12 /* STPPaymentMethodListDeserializer.h in Headers */ = {isa = PBXBuildFile; fileRef = B665CE45228DE4C4008B546F /* STPPaymentMethodListDeserializer.h */; }; B67D7D4D2294A0FD000FBA12 /* STPPaymentMethodListDeserializer.m in Sources */ = {isa = PBXBuildFile; fileRef = B665CE46228DE4C4008B546F /* STPPaymentMethodListDeserializer.m */; }; + B67F503A24C760EE00CF4A9D /* STPPaymentMethodGrabPay.m in Sources */ = {isa = PBXBuildFile; fileRef = B67F503924C760EE00CF4A9D /* STPPaymentMethodGrabPay.m */; }; + B67F503B24C760EE00CF4A9D /* STPPaymentMethodGrabPay.m in Sources */ = {isa = PBXBuildFile; fileRef = B67F503924C760EE00CF4A9D /* STPPaymentMethodGrabPay.m */; }; + B67F503D24C760F700CF4A9D /* STPPaymentMethodGrabPay.h in Headers */ = {isa = PBXBuildFile; fileRef = B67F503C24C760F700CF4A9D /* STPPaymentMethodGrabPay.h */; settings = {ATTRIBUTES = (Public, ); }; }; + B67F503E24C760F700CF4A9D /* STPPaymentMethodGrabPay.h in Headers */ = {isa = PBXBuildFile; fileRef = B67F503C24C760F700CF4A9D /* STPPaymentMethodGrabPay.h */; settings = {ATTRIBUTES = (Public, ); }; }; + B67F504124C764CF00CF4A9D /* STPPaymentMethodGrabPayParams.h in Headers */ = {isa = PBXBuildFile; fileRef = B67F503F24C764CF00CF4A9D /* STPPaymentMethodGrabPayParams.h */; settings = {ATTRIBUTES = (Public, ); }; }; + B67F504224C764CF00CF4A9D /* STPPaymentMethodGrabPayParams.h in Headers */ = {isa = PBXBuildFile; fileRef = B67F503F24C764CF00CF4A9D /* STPPaymentMethodGrabPayParams.h */; settings = {ATTRIBUTES = (Public, ); }; }; + B67F504324C764CF00CF4A9D /* STPPaymentMethodGrabPayParams.m in Sources */ = {isa = PBXBuildFile; fileRef = B67F504024C764CF00CF4A9D /* STPPaymentMethodGrabPayParams.m */; }; + B67F504424C764CF00CF4A9D /* STPPaymentMethodGrabPayParams.m in Sources */ = {isa = PBXBuildFile; fileRef = B67F504024C764CF00CF4A9D /* STPPaymentMethodGrabPayParams.m */; }; + B67F504824C794EF00CF4A9D /* STPPaymentMethodGrabPayParamsTest.m in Sources */ = {isa = PBXBuildFile; fileRef = B67F504724C794EF00CF4A9D /* STPPaymentMethodGrabPayParamsTest.m */; }; B68882DC23FF15250057C5AD /* STPApplePayContext.h in Headers */ = {isa = PBXBuildFile; fileRef = B68882DA23FF15250057C5AD /* STPApplePayContext.h */; settings = {ATTRIBUTES = (Public, ); }; }; B68882DD23FF15250057C5AD /* STPApplePayContext.h in Headers */ = {isa = PBXBuildFile; fileRef = B68882DA23FF15250057C5AD /* STPApplePayContext.h */; settings = {ATTRIBUTES = (Public, ); }; }; B68882DE23FF15250057C5AD /* STPApplePayContext.m in Sources */ = {isa = PBXBuildFile; fileRef = B68882DB23FF15250057C5AD /* STPApplePayContext.m */; }; @@ -2202,6 +2211,11 @@ B6794A5422F4CF6500E3AB41 /* STPConnectAccountAddress.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = STPConnectAccountAddress.m; sourceTree = ""; }; B67AAC5524D885EB0012FCEB /* STPIntentActionAlipayHandleRedirect.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = STPIntentActionAlipayHandleRedirect.h; path = Stripe/PublicHeaders/STPIntentActionAlipayHandleRedirect.h; sourceTree = SOURCE_ROOT; }; B67AAC5624D885EB0012FCEB /* STPIntentActionAlipayHandleRedirect.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = STPIntentActionAlipayHandleRedirect.m; path = Stripe/STPIntentActionAlipayHandleRedirect.m; sourceTree = SOURCE_ROOT; }; + B67F503924C760EE00CF4A9D /* STPPaymentMethodGrabPay.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = STPPaymentMethodGrabPay.m; sourceTree = ""; }; + B67F503C24C760F700CF4A9D /* STPPaymentMethodGrabPay.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = STPPaymentMethodGrabPay.h; path = PublicHeaders/STPPaymentMethodGrabPay.h; sourceTree = ""; }; + B67F503F24C764CF00CF4A9D /* STPPaymentMethodGrabPayParams.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = STPPaymentMethodGrabPayParams.h; sourceTree = ""; }; + B67F504024C764CF00CF4A9D /* STPPaymentMethodGrabPayParams.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = STPPaymentMethodGrabPayParams.m; sourceTree = ""; }; + B67F504724C794EF00CF4A9D /* STPPaymentMethodGrabPayParamsTest.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = STPPaymentMethodGrabPayParamsTest.m; sourceTree = ""; }; B68882DA23FF15250057C5AD /* STPApplePayContext.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = STPApplePayContext.h; path = PublicHeaders/STPApplePayContext.h; sourceTree = ""; }; B68882DB23FF15250057C5AD /* STPApplePayContext.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = STPApplePayContext.m; sourceTree = ""; }; B68882E4240453E30057C5AD /* STPApplePayContextTest.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = STPApplePayContextTest.m; sourceTree = ""; }; @@ -2813,7 +2827,6 @@ 3626615F23C8F9CA00B13AE0 /* PaymentMethods */ = { isa = PBXGroup; children = ( - 69A6C301246D8BD2005FF304 /* EPS */, B6472180246CB4CC0098DE24 /* Alipay */, 3666589F240F177400D00354 /* AU BECS Debit */, B656293023E10F6300458A8E /* Bacs Debit */, @@ -2821,8 +2834,10 @@ 3626616523C9048500B13AE0 /* Card */, 3626616623C9049000B13AE0 /* Card Present */, 3626616723C9049D00B13AE0 /* Card Wallet */, + 69A6C301246D8BD2005FF304 /* EPS */, 3626616823C904AB00B13AE0 /* FPX */, 36196240244FA5C80025D60B /* giropay */, + B67F503824C760DC00CF4A9D /* GrabPay */, 3626616923C904B400B13AE0 /* iDEAL */, 4488959924523D6900F7D0C2 /* Przelewy24 */, 3626616A23C904C200B13AE0 /* SEPA Debit */, @@ -3328,6 +3343,17 @@ name = Payments; sourceTree = ""; }; + B67F503824C760DC00CF4A9D /* GrabPay */ = { + isa = PBXGroup; + children = ( + B67F503C24C760F700CF4A9D /* STPPaymentMethodGrabPay.h */, + B67F503924C760EE00CF4A9D /* STPPaymentMethodGrabPay.m */, + B67F503F24C764CF00CF4A9D /* STPPaymentMethodGrabPayParams.h */, + B67F504024C764CF00CF4A9D /* STPPaymentMethodGrabPayParams.m */, + ); + name = GrabPay; + sourceTree = ""; + }; C18867D61E8B069E00A77634 /* Snapshot */ = { isa = PBXGroup; children = ( @@ -3437,16 +3463,17 @@ B6B41F70223476AE0020BA7F /* STPPaymentMethodCardWalletMasterpassTest.m */, B68F1C782234740B0030B438 /* STPPaymentMethodCardWalletTest.m */, B6B41F72223476B90020BA7F /* STPPaymentMethodCardWalletVisaCheckoutTest.m */, + 69A6C309246EA195005FF304 /* STPPaymentMethodEPSParamsTests.m */, + 69A6C307246EA03E005FF304 /* STPPaymentMethodEPSTests.m */, 3194CF5B2314869400E1940F /* STPPaymentMethodFPXTest.m */, 3619624D244FB2AE0025D60B /* STPPaymentMethodGiropayParamsTests.m */, 36196255244FBEB80025D60B /* STPPaymentMethodGiropayTests.m */, + B67F504724C794EF00CF4A9D /* STPPaymentMethodGrabPayParamsTest.m */, B6EC63C922348D4600E4C0FB /* STPPaymentMethodiDEALTest.m */, B63E42782231F8FE007B5B95 /* STPPaymentMethodParamsTest.m */, 448895AE245255D800F7D0C2 /* STPPaymentMethodPrzelewy24ParamsTests.m */, 448895B0245262E500F7D0C2 /* STPPaymentMethodPrzelewy24Tests.m */, 36B6CB56234BDC4400331C38 /* STPPaymentMethodSEPADebitTest.m */, - 69A6C307246EA03E005FF304 /* STPPaymentMethodEPSTests.m */, - 69A6C309246EA195005FF304 /* STPPaymentMethodEPSParamsTests.m */, B66B39B3223044A2006D1CAD /* STPPaymentMethodTest.m */, B66D5023222F5A27004A9210 /* STPPaymentMethodThreeDSecureUsageTest.m */, F1DE87FF1F8D410D00602F4C /* STPPaymentOptionsViewControllerTest.m */, @@ -4168,6 +4195,7 @@ F1DEB88B1E2047CA0066B8E8 /* STPCoreTableViewController.h in Headers */, F1FA6F931E258F6800EB444D /* STPCoreViewController+Private.h in Headers */, 31B9609922FE20DF00DC6FD9 /* STPBankSelectionTableViewCell.h in Headers */, + B67F503E24C760F700CF4A9D /* STPPaymentMethodGrabPay.h in Headers */, 04793F571D1D9C0200B3C551 /* STPSourceProtocol.h in Headers */, 04A4883E1CA3568800506E53 /* STPBlocks.h in Headers */, B64763B522FE193800C01BC0 /* STPSetupIntentLastSetupError.h in Headers */, @@ -4245,6 +4273,7 @@ B621F05A22346243002141B7 /* STPPaymentMethodCardWalletMasterpass.h in Headers */, B6472183246CB4EA0098DE24 /* STPPaymentMethodAlipay.h in Headers */, 04B31DFA1D11AC6400EF1631 /* STPUserInformation.h in Headers */, + B67F504224C764CF00CF4A9D /* STPPaymentMethodGrabPayParams.h in Headers */, C1CFCB681ED4E38900BE45DF /* STPInternalAPIResponseDecodable.h in Headers */, C113D21A1EBB9A36006FACC2 /* STPEphemeralKey.h in Headers */, 04A4C38E1C4F25F900B3B290 /* UIViewController+Stripe_ParentViewController.h in Headers */, @@ -4354,6 +4383,7 @@ C1785F5C1EC60B5E00E9CFAC /* STPCardIOProxy.h in Headers */, 049952CF1BCF13510088C703 /* STPAPIRequest.h in Headers */, C15993381D8808680047950D /* STPShippingMethodTableViewCell.h in Headers */, + B67F504124C764CF00CF4A9D /* STPPaymentMethodGrabPayParams.h in Headers */, 049A3FB21CC9FEFC00F57DE7 /* UIToolbar+Stripe_InputAccessory.h in Headers */, F1FA6F981E25970F00EB444D /* STPCoreTableViewController+Private.h in Headers */, F1DEB8901E2052150066B8E8 /* STPCoreScrollViewController.h in Headers */, @@ -4506,6 +4536,7 @@ 04A4883C1CA3568800506E53 /* STPBlocks.h in Headers */, F1D3A2511EB0120F0095BFA9 /* STPFile.h in Headers */, F1BEB2F91F34F2250043F48C /* STPSourceEnums.h in Headers */, + B67F503D24C760F700CF4A9D /* STPPaymentMethodGrabPay.h in Headers */, F1FA6F921E258F6800EB444D /* STPCoreViewController+Private.h in Headers */, 045D71201CEFA57000F6CD65 /* UIViewController+Stripe_Promises.h in Headers */, B6794A5522F4CF6500E3AB41 /* STPConnectAccountAddress.h in Headers */, @@ -5275,6 +5306,7 @@ F1D3A25F1EB015B30095BFA9 /* UIImage+StripeTests.m in Sources */, 04415C6B1A6605B5001225ED /* STPBankAccountFunctionalTest.m in Sources */, 8B6DC9751F0171D20025E811 /* STPSourceReceiverTest.m in Sources */, + B67F504824C794EF00CF4A9D /* STPPaymentMethodGrabPayParamsTest.m in Sources */, F1DE88011F8D410D00602F4C /* STPPaymentOptionsViewControllerTest.m in Sources */, 8B6DC9771F0172640025E811 /* STPSourceSEPADebitDetailsTest.m in Sources */, 69A6C30A246EA195005FF304 /* STPPaymentMethodEPSParamsTests.m in Sources */, @@ -5366,6 +5398,7 @@ C1D7B5231E36C32F002181F5 /* STPSource.m in Sources */, 04A4C3901C4F25F900B3B290 /* UIViewController+Stripe_ParentViewController.m in Sources */, 04F94DA01D229F0B004FC826 /* STPPostalCodeValidator.m in Sources */, + B67F504424C764CF00CF4A9D /* STPPaymentMethodGrabPayParams.m in Sources */, C124A17F1CCAA0C2007D42EE /* NSMutableURLRequest+Stripe.m in Sources */, 448895AA2452455C00F7D0C2 /* STPPaymentMethodPrzelewy24.m in Sources */, 0413CB31233FECD5006429EA /* STPAPIClient+PushProvisioning.m in Sources */, @@ -5457,6 +5490,7 @@ B699BC9024577D50009107F9 /* STPPaymentIntentShippingDetailsParams.m in Sources */, 045D71111CEEE30500F6CD65 /* STPAspects.m in Sources */, B64763B722FE193900C01BC0 /* STPSetupIntentLastSetupError.m in Sources */, + B67F503B24C760EE00CF4A9D /* STPPaymentMethodGrabPay.m in Sources */, 04F94DCA1D22A20D004FC826 /* STPSwitchTableViewCell.m in Sources */, 04CDE5BA1BC1F1F100548833 /* STPCardParams.m in Sources */, 0451CC471C49AE1C003B2CA6 /* STPPaymentResult.m in Sources */, @@ -5606,6 +5640,7 @@ 04CDB5041A5F30A700B854EE /* STPFormEncoder.m in Sources */, 0426B96F1CEADC98006AC8DD /* STPColorUtils.m in Sources */, C1D7B51C1E36B8B9002181F5 /* STPSourceParams.m in Sources */, + B67F503A24C760EE00CF4A9D /* STPPaymentMethodGrabPay.m in Sources */, 049880FE1CED5A2300EA4FFD /* STPPaymentConfiguration.m in Sources */, 046FE9A21CE55D1D00DA6A7B /* STPPaymentActivityIndicatorView.m in Sources */, 31B9609622FE20DF00DC6FD9 /* STPBankSelectionTableViewCell.m in Sources */, @@ -5671,6 +5706,7 @@ B3BDCAD320EEF5E10034F7F5 /* STPPaymentIntentParams.m in Sources */, 04695AD41C77F9DB00E08063 /* NSString+Stripe.m in Sources */, F15232261EA9303800D65C67 /* STPURLCallbackHandler.m in Sources */, + B67F504324C764CF00CF4A9D /* STPPaymentMethodGrabPayParams.m in Sources */, B68D52E422A739AA00D4E8BA /* STPSourceWeChatPayDetails.m in Sources */, F1BEB2FF1F3508BB0043F48C /* NSError+Stripe.m in Sources */, B699BC9524577FED009107F9 /* STPPaymentIntentShippingDetailsAddressParams.m in Sources */, diff --git a/Stripe/Payments/STPPaymentHandler.m b/Stripe/Payments/STPPaymentHandler.m index 1dcc058f912..69e316d8b27 100644 --- a/Stripe/Payments/STPPaymentHandler.m +++ b/Stripe/Payments/STPPaymentHandler.m @@ -311,6 +311,7 @@ + (BOOL)_isProcessingIntentSuccessForType:(STPPaymentMethodType)type { case STPPaymentMethodTypeBacsDebit: // Bacs Debit takes 2-3 business days // fall through case STPPaymentMethodTypeAUBECSDebit: + case STPPaymentMethodTypeGrabPay: // Asynchronous return YES; case STPPaymentMethodTypeAlipay: case STPPaymentMethodTypeCard: diff --git a/Stripe/PublicHeaders/STPPaymentMethod.h b/Stripe/PublicHeaders/STPPaymentMethod.h index f239f183481..7de41b34e25 100644 --- a/Stripe/PublicHeaders/STPPaymentMethod.h +++ b/Stripe/PublicHeaders/STPPaymentMethod.h @@ -22,6 +22,7 @@ STPPaymentMethodCardPresent, STPPaymentMethodEPS, STPPaymentMethodFPX, STPPaymentMethodGiropay, +STPPaymentMethodGrabPay, STPPaymentMethodiDEAL, STPPaymentMethodPrzelewy24, STPPaymentMethodSEPADebit; @@ -66,6 +67,11 @@ NS_ASSUME_NONNULL_BEGIN */ @property (nonatomic, nullable, readonly) STPPaymentMethodAlipay *alipay; +/** + If this is a GrabPay PaymentMethod (ie `self.type == STPPaymentMethodTypeGrabPay`), this contains additional details. + */ +@property (nonatomic, nullable, readonly) STPPaymentMethodGrabPay *grabPay; + /** If this is a card PaymentMethod (ie `self.type == STPPaymentMethodTypeCard`), this contains additional details. */ diff --git a/Stripe/PublicHeaders/STPPaymentMethodEnums.h b/Stripe/PublicHeaders/STPPaymentMethodEnums.h index 2719055809b..85c6b6a395c 100644 --- a/Stripe/PublicHeaders/STPPaymentMethodEnums.h +++ b/Stripe/PublicHeaders/STPPaymentMethodEnums.h @@ -20,6 +20,11 @@ typedef NS_ENUM(NSUInteger, STPPaymentMethodType) { */ STPPaymentMethodTypeAlipay, + /** + A GrabPay payment method. + */ + STPPaymentMethodTypeGrabPay, + /** An iDEAL payment method. */ diff --git a/Stripe/PublicHeaders/STPPaymentMethodGrabPay.h b/Stripe/PublicHeaders/STPPaymentMethodGrabPay.h new file mode 100644 index 00000000000..79572de886d --- /dev/null +++ b/Stripe/PublicHeaders/STPPaymentMethodGrabPay.h @@ -0,0 +1,34 @@ +// +// STPPaymentMethodGrabPay.h +// StripeiOS +// +// Copyright © 2020 Stripe, Inc. All rights reserved. +// + +#import +#import "STPAPIResponseDecodable.h" + +NS_ASSUME_NONNULL_BEGIN + +/** + A GrabPay PaymentMethod + + @see https://stripe.com/docs/api/payment_methods/object#payment_method_object-grabpay + */ +@interface STPPaymentMethodGrabPay : NSObject + +/** +You cannot directly instantiate an `STPPaymentMethodGrabPay`. +You should only use one that is part of an existing `STPPaymentMethod` object. +*/ +- (instancetype)init NS_UNAVAILABLE; + +/** +You cannot directly instantiate an `STPPaymentMethodGrabPay`. +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/STPPaymentMethodParams.h b/Stripe/PublicHeaders/STPPaymentMethodParams.h index e4e7d3ae5bf..695a4873791 100644 --- a/Stripe/PublicHeaders/STPPaymentMethodParams.h +++ b/Stripe/PublicHeaders/STPPaymentMethodParams.h @@ -22,6 +22,7 @@ STPPaymentMethodCardParams, STPPaymentMethodEPSParams, STPPaymentMethodFPXParams, STPPaymentMethodGiropayParams, +STPPaymentMethodGrabPayParams, STPPaymentMethodiDEALParams, STPPaymentMethodPrzelewy24Params, STPPaymentMethodSEPADebitParams; @@ -114,6 +115,11 @@ NS_ASSUME_NONNULL_BEGIN */ @property (nonatomic, nullable) STPPaymentMethodBancontactParams *bancontact; +/** + If this is a GrabPay PaymentMethod, this contains additional details. +*/ +@property (nonatomic, nullable) STPPaymentMethodGrabPayParams *grabPay; + /** Set of key-value pairs that you can attach to the PaymentMethod. This can be useful for storing additional information about the PaymentMethod in a structured format. */ @@ -228,6 +234,18 @@ NS_ASSUME_NONNULL_BEGIN billingDetails:(STPPaymentMethodBillingDetails *)billingDetails metadata:(nullable NSDictionary *)metadata; + +/** + Creates params for a GrabPay PaymentMethod; + + @param grabPay An object containing additional GrabPay details. + @param billingDetails An object containing the user's billing details. + @param metadata Additional information to attach to the PaymentMethod. + */ ++ (nullable STPPaymentMethodParams *)paramsWithGrabPay:(STPPaymentMethodGrabPayParams *)grabPay + billingDetails:(nullable STPPaymentMethodBillingDetails *)billingDetails + metadata:(nullable NSDictionary *)metadata; + /** Creates params for an Alipay PaymentMethod. diff --git a/Stripe/PublicHeaders/Stripe.h b/Stripe/PublicHeaders/Stripe.h index 3076e9981c4..1614133787f 100644 --- a/Stripe/PublicHeaders/Stripe.h +++ b/Stripe/PublicHeaders/Stripe.h @@ -99,6 +99,8 @@ #import "STPPaymentMethodEPSParams.h" #import "STPPaymentMethodFPX.h" #import "STPPaymentMethodFPXParams.h" +#import "STPPaymentMethodGrabPay.h" +#import "STPPaymentMethodGrabPayParams.h" #import "STPPaymentMethodGiropay.h" #import "STPPaymentMethodGiropayParams.h" #import "STPPaymentMethodParams.h" diff --git a/Stripe/STPPaymentMethod.m b/Stripe/STPPaymentMethod.m index b9c20c5304f..2551f542d52 100644 --- a/Stripe/STPPaymentMethod.m +++ b/Stripe/STPPaymentMethod.m @@ -21,6 +21,7 @@ #import "STPPaymentMethodEPS.h" #import "STPPaymentMethodFPX.h" #import "STPPaymentMethodGiropay.h" +#import "STPPaymentMethodGrabPay.h" #import "STPPaymentMethodiDEAL.h" #import "STPPaymentMethodPrzelewy24.h" #import "STPPaymentMethodSEPADebit.h" @@ -44,6 +45,7 @@ @interface STPPaymentMethod () @property (nonatomic, strong, nullable, readwrite) STPPaymentMethodPrzelewy24 *przelewy24; @property (nonatomic, strong, nullable, readwrite) STPPaymentMethodBancontact *bancontact; @property (nonatomic, strong, nullable, readwrite) STPPaymentMethodAlipay *alipay; +@property (nonatomic, strong, nullable, readwrite) STPPaymentMethodGrabPay *grabPay; @property (nonatomic, copy, nullable, readwrite) NSString *customerId; @property (nonatomic, copy, nullable, readwrite) NSDictionary *metadata; @property (nonatomic, copy, nonnull, readwrite) NSDictionary *allResponseFields; @@ -75,6 +77,7 @@ - (NSString *)description { [NSString stringWithFormat:@"eps = %@", self.eps], [NSString stringWithFormat:@"fpx = %@", self.fpx], [NSString stringWithFormat:@"giropay = %@", self.giropay], + [NSString stringWithFormat:@"grabPay = %@", self.bacsDebit], [NSString stringWithFormat:@"przelewy24 = %@", self.przelewy24], [NSString stringWithFormat:@"sepaDebit = %@", self.sepaDebit], [NSString stringWithFormat:@"liveMode = %@", self.liveMode ? @"YES" : @"NO"], @@ -95,6 +98,7 @@ - (NSString *)description { @"sepa_debit": @(STPPaymentMethodTypeSEPADebit), @"bacs_debit": @(STPPaymentMethodTypeBacsDebit), @"au_becs_debit": @(STPPaymentMethodTypeAUBECSDebit), + @"grabpay": @(STPPaymentMethodTypeGrabPay), @"giropay": @(STPPaymentMethodTypeGiropay), @"p24": @(STPPaymentMethodTypePrzelewy24), @"eps": @(STPPaymentMethodTypeEPS), @@ -161,6 +165,7 @@ + (nullable instancetype)decodedObjectFromAPIResponse:(nullable NSDictionary *)r paymentMethod.customerId = [dict stp_stringForKey:@"customer"]; paymentMethod.metadata = [[dict stp_dictionaryForKey:@"metadata"] stp_dictionaryByRemovingNonStrings]; paymentMethod.alipay = [STPPaymentMethodAlipay decodedObjectFromAPIResponse:[dict stp_dictionaryForKey:@"alipay"]]; + paymentMethod.grabPay = [STPPaymentMethodGrabPay decodedObjectFromAPIResponse:[dict stp_dictionaryForKey:@"grabpay"]]; return paymentMethod; } @@ -205,6 +210,8 @@ - (NSString *)label { return STPLocalizedString(@"SEPA Debit", @"Payment method brand name"); case STPPaymentMethodTypeAUBECSDebit: return STPLocalizedString(@"AU BECS Debit", @"Payment Method type brand name."); + case STPPaymentMethodTypeGrabPay: + return STPLocalizedString(@"GrabPay", @"Payment Method type brand name."); case STPPaymentMethodTypeGiropay: return STPLocalizedString(@"giropay", @"Payment Method type brand name."); case STPPaymentMethodTypeEPS: @@ -237,6 +244,7 @@ - (BOOL)isReusable { case STPPaymentMethodTypeEPS: case STPPaymentMethodTypePrzelewy24: case STPPaymentMethodTypeBancontact: + case STPPaymentMethodTypeGrabPay: // fall through case STPPaymentMethodTypeUnknown: return NO; diff --git a/Stripe/STPPaymentMethodGrabPay.m b/Stripe/STPPaymentMethodGrabPay.m new file mode 100644 index 00000000000..37b68d69bf2 --- /dev/null +++ b/Stripe/STPPaymentMethodGrabPay.m @@ -0,0 +1,45 @@ +// +// STPPaymentMethodGrabPay.m +// StripeiOS +// +// Copyright © 2020 Stripe, Inc. All rights reserved. +// + +#import "STPPaymentMethodGrabPay.h" + +#import "NSDictionary+Stripe.h" + +@implementation STPPaymentMethodGrabPay + +@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]; +} + +- (instancetype)initWithDictionary:(NSDictionary *)dict { + self = [super init]; + if (self) { + _allResponseFields = dict.copy; + } + return self; +} + +@end diff --git a/Stripe/STPPaymentMethodGrabPayParams.h b/Stripe/STPPaymentMethodGrabPayParams.h new file mode 100644 index 00000000000..d7b2412fc6e --- /dev/null +++ b/Stripe/STPPaymentMethodGrabPayParams.h @@ -0,0 +1,22 @@ +// +// STPPaymentMethodGrabPayParams.h +// Stripe +// +// Created by Yuki Tokuhiro on 7/21/20. +// Copyright © 2020 Stripe, Inc. All rights reserved. +// + +#import + +#import "STPFormEncodable.h" + +NS_ASSUME_NONNULL_BEGIN + +/** + An object representing parameters used to create a GrabPay Payment Method + */ +@interface STPPaymentMethodGrabPayParams : NSObject + +@end + +NS_ASSUME_NONNULL_END diff --git a/Stripe/STPPaymentMethodGrabPayParams.m b/Stripe/STPPaymentMethodGrabPayParams.m new file mode 100644 index 00000000000..2f6dcea2911 --- /dev/null +++ b/Stripe/STPPaymentMethodGrabPayParams.m @@ -0,0 +1,25 @@ +// +// STPPaymentMethodGrabPayParams.m +// Stripe +// +// Created by Yuki Tokuhiro on 7/21/20. +// Copyright © 2020 Stripe, Inc. All rights reserved. +// + +#import "STPPaymentMethodGrabPayParams.h" + +@implementation STPPaymentMethodGrabPayParams + +@synthesize additionalAPIParameters = _additionalAPIParameters; + +#pragma mark - STPFormEncodable + ++ (NSString *)rootObjectName { + return @"grabpay"; +} + ++ (NSDictionary *)propertyNamesToFormFieldNamesMapping { + return @{}; +} + +@end diff --git a/Stripe/STPPaymentMethodParams.m b/Stripe/STPPaymentMethodParams.m index 6900dc4649c..c86d7ef4520 100644 --- a/Stripe/STPPaymentMethodParams.m +++ b/Stripe/STPPaymentMethodParams.m @@ -22,6 +22,7 @@ #import "STPPaymentMethodFPX.h" #import "STPPaymentMethodFPXParams.h" #import "STPPaymentMethodGiropayParams.h" +#import "STPPaymentMethodGrabPayParams.h" #import "STPPaymentMethodiDEAL.h" #import "STPPaymentMethodiDEALParams.h" #import "STPPaymentMethodPrzelewy24Params.h" @@ -138,7 +139,16 @@ + (STPPaymentMethodParams *)paramsWithAlipay:(STPPaymentMethodAlipayParams *)ali params.type = STPPaymentMethodTypeAlipay; params.alipay = alipay; params.billingDetails = billingDetails; - params.metadata = metadata; + return params; +} + ++ (STPPaymentMethodParams *)paramsWithGrabPay:(STPPaymentMethodGrabPayParams *)grabPay + billingDetails:(STPPaymentMethodBillingDetails *)billingDetails + metadata:(nullable NSDictionary *)metadata { + STPPaymentMethodParams *params = [self new]; + params.type = STPPaymentMethodTypeGrabPay; + params.grabPay = grabPay; + params.billingDetails = billingDetails; return params; } @@ -202,6 +212,14 @@ + (nullable STPPaymentMethodParams *)paramsWithSingleUsePaymentMethod:(STPPaymen params.billingDetails = paymentMethod.billingDetails; break; } + case STPPaymentMethodTypeGrabPay: + { + params.type = STPPaymentMethodTypeGrabPay; + STPPaymentMethodGrabPayParams *grabpay = [STPPaymentMethodGrabPayParams new]; + params.grabPay = grabpay; + params.billingDetails = paymentMethod.billingDetails; + } + // All reusable PaymentMethods go below: case STPPaymentMethodTypeSEPADebit: case STPPaymentMethodTypeBacsDebit: case STPPaymentMethodTypeCard: @@ -242,6 +260,7 @@ + (nonnull NSDictionary *)propertyNamesToFormFieldNamesMapping { NSStringFromSelector(@selector(bacsDebit)): @"bacs_debit", NSStringFromSelector(@selector(auBECSDebit)): @"au_becs_debit", NSStringFromSelector(@selector(giropay)): @"giropay", + NSStringFromSelector(@selector(grabPay)): @"grabpay", NSStringFromSelector(@selector(przelewy24)): @"p24", NSStringFromSelector(@selector(bancontact)): @"bancontact", NSStringFromSelector(@selector(metadata)): @"metadata", @@ -303,10 +322,12 @@ - (NSString *)label { return @"EPS"; case STPPaymentMethodTypeBancontact: return @"Bancontact"; + case STPPaymentMethodTypeGrabPay: + return @"GrabPay"; + break; case STPPaymentMethodTypeCardPresent: case STPPaymentMethodTypeUnknown: return STPLocalizedString(@"Unknown", @"Default missing source type label"); - } } @@ -323,6 +344,7 @@ - (BOOL)isReusable { case STPPaymentMethodTypeFPX: case STPPaymentMethodTypeCardPresent: case STPPaymentMethodTypeGiropay: + case STPPaymentMethodTypeGrabPay: case STPPaymentMethodTypeEPS: case STPPaymentMethodTypePrzelewy24: case STPPaymentMethodTypeBancontact: diff --git a/Tests/Tests/STPFixtures.h b/Tests/Tests/STPFixtures.h index a93ee7c2fdc..bb3af9c439e 100644 --- a/Tests/Tests/STPFixtures.h +++ b/Tests/Tests/STPFixtures.h @@ -20,6 +20,7 @@ extern NSString *const STPTestJSONSetupIntent; extern NSString *const STPTestJSONPaymentMethodCard; extern NSString *const STPTestJSONPaymentMethodApplePay; extern NSString *const STPTestJSONPaymentMethodBacsDebit; +extern NSString *const STPTestJSONPaymentMethodGrabPay; extern NSString *const STPTestJSONSource3DS; extern NSString *const STPTestJSONSourceAlipay; diff --git a/Tests/Tests/STPFixtures.m b/Tests/Tests/STPFixtures.m index 6c46e0430b1..3857594ad28 100644 --- a/Tests/Tests/STPFixtures.m +++ b/Tests/Tests/STPFixtures.m @@ -20,6 +20,7 @@ NSString *const STPTestJSONPaymentMethodCard = @"CardPaymentMethod"; NSString *const STPTestJSONPaymentMethodApplePay = @"ApplePayPaymentMethod"; NSString *const STPTestJSONPaymentMethodBacsDebit = @"BacsDebitPaymentMethod"; +NSString *const STPTestJSONPaymentMethodGrabPay = @"GrabPayPaymentMethod"; NSString *const STPTestJSONSource3DS = @"3DSSource"; NSString *const STPTestJSONSourceAlipay = @"AlipaySource"; diff --git a/Tests/Tests/STPPaymentIntentFunctionalTest.m b/Tests/Tests/STPPaymentIntentFunctionalTest.m index e442ba5e983..5f2c47bc2ca 100644 --- a/Tests/Tests/STPPaymentIntentFunctionalTest.m +++ b/Tests/Tests/STPPaymentIntentFunctionalTest.m @@ -756,6 +756,61 @@ - (void)testConfirmAlipayPaymentIntent { [self waitForExpectationsWithTimeout:STPTestingNetworkRequestTimeout handler:nil]; } +#pragma mark - GrabPay + +- (void)testConfirmPaymentIntentWithGrabPay { + __block NSString *clientSecret = nil; + XCTestExpectation *createExpectation = [self expectationWithDescription:@"Create PaymentIntent."]; + [[STPTestingAPIClient sharedClient] createPaymentIntentWithParams:@{ + @"payment_method_types": @[@"grabpay"], + @"currency": @"sgd", + } + account:@"sg" + 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:STPTestingSGPublishableKey]; + XCTestExpectation *expectation = [self expectationWithDescription:@"Payment Intent confirm"]; + + STPPaymentIntentParams *paymentIntentParams = [[STPPaymentIntentParams alloc] initWithClientSecret:clientSecret]; + STPPaymentMethodGrabPayParams *grabpay = [STPPaymentMethodGrabPayParams new]; + + STPPaymentMethodBillingDetails *billingDetails = [STPPaymentMethodBillingDetails new]; + billingDetails.name = @"Jenny Rosen"; + + paymentIntentParams.paymentMethodParams = [STPPaymentMethodParams paramsWithGrabPay:grabpay + billingDetails:billingDetails + metadata:nil]; + paymentIntentParams.returnURL = @"example-app-scheme://authorized"; + + [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); + + // GrabPay requires a redirect + XCTAssertEqual(paymentIntent.status, STPPaymentIntentStatusRequiresAction); + XCTAssertNotNil(paymentIntent.nextAction.redirectToURL.returnURL); + XCTAssertEqualObjects(paymentIntent.nextAction.redirectToURL.returnURL, + [NSURL URLWithString:@"example-app-scheme://authorized"]); + + [expectation fulfill]; + }]; + + [self waitForExpectationsWithTimeout:STPTestingNetworkRequestTimeout handler:nil]; +} + #pragma mark - Helpers - (STPSourceParams *)cardSourceParams { diff --git a/Tests/Tests/STPPaymentMethodGrabPayParamsTest.m b/Tests/Tests/STPPaymentMethodGrabPayParamsTest.m new file mode 100644 index 00000000000..bf9608ca0b3 --- /dev/null +++ b/Tests/Tests/STPPaymentMethodGrabPayParamsTest.m @@ -0,0 +1,60 @@ +// +// STPPaymentMethodGrabPayParamsTest.m +// StripeiOS Tests +// +// Created by Yuki Tokuhiro on 7/21/20. +// Copyright © 2020 Stripe, Inc. All rights reserved. +// + +#import + +#import "STPAPIClient.h" +#import "STPPaymentMethod.h" +#import "STPPaymentMethodBillingDetails.h" +#import "STPPaymentMethodGrabPay.h" +#import "STPPaymentMethodGrabPayParams.h" +#import "STPPaymentMethodParams.h" +#import "STPTestingAPIClient.h" + +@interface STPPaymentMethodGrabPayParamsTest : XCTestCase + +@end + +@implementation STPPaymentMethodGrabPayParamsTest + + +- (void)testCreateGrabPayPaymentMethod { + STPAPIClient *client = [[STPAPIClient alloc] initWithPublishableKey:STPTestingSGPublishableKey]; + STPPaymentMethodGrabPayParams *grabPayParams = [STPPaymentMethodGrabPayParams new]; + + STPPaymentMethodBillingDetails *billingDetails = [STPPaymentMethodBillingDetails new]; + billingDetails.name = @"Jenny Rosen"; + + STPPaymentMethodParams *params = [STPPaymentMethodParams paramsWithGrabPay:grabPayParams + billingDetails:billingDetails + metadata:@{@"test_key": @"test_value"}]; + + XCTestExpectation *expectation = [self expectationWithDescription:@"Payment Method GrabPay create"]; + + [client createPaymentMethodWithParams:params + completion:^(STPPaymentMethod * _Nullable paymentMethod, NSError * _Nullable error) { + [expectation fulfill]; + + XCTAssertNil(error, @"Unexpected error creating GrabPay PaymentMethod: %@", error); + XCTAssertNotNil(paymentMethod, @"Failed to create GrabPay PaymentMethod"); + XCTAssertNotNil(paymentMethod.stripeId, @"Missing stripeId"); + XCTAssertNotNil(paymentMethod.created, @"Missing created"); + XCTAssertFalse(paymentMethod.liveMode, @"Incorrect livemode"); + XCTAssertEqual(paymentMethod.type, STPPaymentMethodTypeGrabPay, @"Incorrect PaymentMethod type"); + + // Billing Details + XCTAssertEqualObjects(paymentMethod.billingDetails.name, @"Jenny Rosen", @"Incorrect name"); + + // GrabPay Details + XCTAssertNotNil(paymentMethod.grabPay, @"Missing grabPay"); + }]; + + [self waitForExpectationsWithTimeout:STPTestingNetworkRequestTimeout handler:nil]; +} + +@end diff --git a/Tests/Tests/STPPaymentMethodTest.m b/Tests/Tests/STPPaymentMethodTest.m index 2afc0ec123a..12f40c20fd0 100644 --- a/Tests/Tests/STPPaymentMethodTest.m +++ b/Tests/Tests/STPPaymentMethodTest.m @@ -100,6 +100,9 @@ - (void)testStringFromType { case STPPaymentMethodTypeUnknown: XCTAssertNil(string); break; + case STPPaymentMethodTypeGrabPay: + XCTAssertEqualObjects(string, @"grabpay"); + break; } } } diff --git a/Tests/Tests/STPTestingAPIClient.h b/Tests/Tests/STPTestingAPIClient.h index 17d2fd5e133..42b43323db5 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 SG +static NSString * const STPTestingSGPublishableKey = @"pk_test_51H7oXMAOnZToJom1hqiSvNGsUVTrG1SaXRSBon9xcEp0yDFAxEh5biA4n0ty6paEsD5Mo5ps1b7Taj9WAHQzjup800m8A8Nc3u"; static const NSTimeInterval STPTestingNetworkRequestTimeout = 8; From 6ddf383a237497237365ec56fa9a62b0ad5c84bd Mon Sep 17 00:00:00 2001 From: Yuki Tokuhiro Date: Wed, 19 Aug 2020 09:48:29 -0700 Subject: [PATCH 2/3] Fix ci scripts --- Stripe/{ => PublicHeaders}/STPPaymentMethodGrabPayParams.h | 0 Stripe/Resources/Localizations/en.lproj/Localizable.strings | 3 +++ 2 files changed, 3 insertions(+) rename Stripe/{ => PublicHeaders}/STPPaymentMethodGrabPayParams.h (100%) diff --git a/Stripe/STPPaymentMethodGrabPayParams.h b/Stripe/PublicHeaders/STPPaymentMethodGrabPayParams.h similarity index 100% rename from Stripe/STPPaymentMethodGrabPayParams.h rename to Stripe/PublicHeaders/STPPaymentMethodGrabPayParams.h diff --git a/Stripe/Resources/Localizations/en.lproj/Localizable.strings b/Stripe/Resources/Localizations/en.lproj/Localizable.strings index 4982e97c727..9d804cc0ddc 100644 --- a/Stripe/Resources/Localizations/en.lproj/Localizable.strings +++ b/Stripe/Resources/Localizations/en.lproj/Localizable.strings @@ -103,6 +103,9 @@ /* Payment Method type brand name. */ "giropay" = "giropay"; +/* Payment Method type brand name. */ +"GrabPay" = "GrabPay"; + /* Source type brand name */ "iDEAL" = "iDEAL"; From 555918b6664ed32d65bba9efd3cf691dbabffe24 Mon Sep 17 00:00:00 2001 From: Yuki Tokuhiro Date: Wed, 19 Aug 2020 09:51:01 -0700 Subject: [PATCH 3/3] PR feedback --- Stripe.xcodeproj/project.pbxproj | 2 +- Stripe/STPPaymentMethodParams.m | 1 - Tests/Tests/STPFixtures.h | 1 - Tests/Tests/STPFixtures.m | 1 - 4 files changed, 1 insertion(+), 4 deletions(-) diff --git a/Stripe.xcodeproj/project.pbxproj b/Stripe.xcodeproj/project.pbxproj index 57c63f3b68a..d822f3a50cd 100644 --- a/Stripe.xcodeproj/project.pbxproj +++ b/Stripe.xcodeproj/project.pbxproj @@ -2213,7 +2213,7 @@ B67AAC5624D885EB0012FCEB /* STPIntentActionAlipayHandleRedirect.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = STPIntentActionAlipayHandleRedirect.m; path = Stripe/STPIntentActionAlipayHandleRedirect.m; sourceTree = SOURCE_ROOT; }; B67F503924C760EE00CF4A9D /* STPPaymentMethodGrabPay.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = STPPaymentMethodGrabPay.m; sourceTree = ""; }; B67F503C24C760F700CF4A9D /* STPPaymentMethodGrabPay.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = STPPaymentMethodGrabPay.h; path = PublicHeaders/STPPaymentMethodGrabPay.h; sourceTree = ""; }; - B67F503F24C764CF00CF4A9D /* STPPaymentMethodGrabPayParams.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = STPPaymentMethodGrabPayParams.h; sourceTree = ""; }; + B67F503F24C764CF00CF4A9D /* STPPaymentMethodGrabPayParams.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = STPPaymentMethodGrabPayParams.h; path = PublicHeaders/STPPaymentMethodGrabPayParams.h; sourceTree = ""; }; B67F504024C764CF00CF4A9D /* STPPaymentMethodGrabPayParams.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = STPPaymentMethodGrabPayParams.m; sourceTree = ""; }; B67F504724C794EF00CF4A9D /* STPPaymentMethodGrabPayParamsTest.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = STPPaymentMethodGrabPayParamsTest.m; sourceTree = ""; }; B68882DA23FF15250057C5AD /* STPApplePayContext.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = STPApplePayContext.h; path = PublicHeaders/STPApplePayContext.h; sourceTree = ""; }; diff --git a/Stripe/STPPaymentMethodParams.m b/Stripe/STPPaymentMethodParams.m index c86d7ef4520..00d3dbd8fd1 100644 --- a/Stripe/STPPaymentMethodParams.m +++ b/Stripe/STPPaymentMethodParams.m @@ -324,7 +324,6 @@ - (NSString *)label { return @"Bancontact"; case STPPaymentMethodTypeGrabPay: return @"GrabPay"; - break; case STPPaymentMethodTypeCardPresent: case STPPaymentMethodTypeUnknown: return STPLocalizedString(@"Unknown", @"Default missing source type label"); diff --git a/Tests/Tests/STPFixtures.h b/Tests/Tests/STPFixtures.h index bb3af9c439e..a93ee7c2fdc 100644 --- a/Tests/Tests/STPFixtures.h +++ b/Tests/Tests/STPFixtures.h @@ -20,7 +20,6 @@ extern NSString *const STPTestJSONSetupIntent; extern NSString *const STPTestJSONPaymentMethodCard; extern NSString *const STPTestJSONPaymentMethodApplePay; extern NSString *const STPTestJSONPaymentMethodBacsDebit; -extern NSString *const STPTestJSONPaymentMethodGrabPay; extern NSString *const STPTestJSONSource3DS; extern NSString *const STPTestJSONSourceAlipay; diff --git a/Tests/Tests/STPFixtures.m b/Tests/Tests/STPFixtures.m index 3857594ad28..6c46e0430b1 100644 --- a/Tests/Tests/STPFixtures.m +++ b/Tests/Tests/STPFixtures.m @@ -20,7 +20,6 @@ NSString *const STPTestJSONPaymentMethodCard = @"CardPaymentMethod"; NSString *const STPTestJSONPaymentMethodApplePay = @"ApplePayPaymentMethod"; NSString *const STPTestJSONPaymentMethodBacsDebit = @"BacsDebitPaymentMethod"; -NSString *const STPTestJSONPaymentMethodGrabPay = @"GrabPayPaymentMethod"; NSString *const STPTestJSONSource3DS = @"3DSSource"; NSString *const STPTestJSONSourceAlipay = @"AlipaySource";