From 505e54963162d2d574b95d4b0b5f2280a1fe4985 Mon Sep 17 00:00:00 2001 From: Dan Jackson Date: Wed, 16 May 2018 16:25:43 -0700 Subject: [PATCH 1/4] Workaround for SafariVC reporting failure while redirecting to iDEAL Ignores reported errors from SafariVC unless we know the error was for a `stripe.com` domain. SafariVC is basically a black box: give it a URL and ask it to load. It'll report via the delegate method when the initial load finishes, and whether it was successful or not. Prior to this commit, iDEAL (and others?) would fail and close SafariVC. However, it hadn't actually failed, and just leaving the SafariVC open would allow the user to finish the redirect workflow. It's strange to me that SafariVC behaves this way. It's also a little strange how the redirects are being handled by girogate.de. This works around the interaction between the two, while still attempting to report legitimate errors, so the host application can tell the user and allow them to retry. --- Stripe/STPRedirectContext.m | 36 +++++++++++++++++++++++++++++++----- 1 file changed, 31 insertions(+), 5 deletions(-) diff --git a/Stripe/STPRedirectContext.m b/Stripe/STPRedirectContext.m index 5146802dd54..b21417e230d 100644 --- a/Stripe/STPRedirectContext.m +++ b/Stripe/STPRedirectContext.m @@ -25,6 +25,8 @@ @interface STPRedirectContext () Date: Wed, 16 May 2018 16:33:45 -0700 Subject: [PATCH 2/4] Add error handling to `STPRedirectContext` completion block errors in example code The example code was ignoring the error parameter, instead of reporting on it. --- .../SofortExampleViewController.m | 52 ++++++++++--------- .../ThreeDSExampleViewController.m | 52 ++++++++++--------- 2 files changed, 56 insertions(+), 48 deletions(-) diff --git a/Example/Custom Integration (ObjC)/SofortExampleViewController.m b/Example/Custom Integration (ObjC)/SofortExampleViewController.m index 24d1eb5d1cb..7578ab53615 100644 --- a/Example/Custom Integration (ObjC)/SofortExampleViewController.m +++ b/Example/Custom Integration (ObjC)/SofortExampleViewController.m @@ -100,31 +100,35 @@ - (void)pay { // your app delegate to forward URLs to the Stripe SDK. // See `[Stripe handleStripeURLCallback:]` self.redirectContext = [[STPRedirectContext alloc] initWithSource:source completion:^(NSString *sourceID, NSString *clientSecret, NSError *error) { - [[STPAPIClient sharedClient] startPollingSourceWithId:sourceID - clientSecret:clientSecret - timeout:10 - completion:^(STPSource *source, NSError *error) { - [self updateUIForPaymentInProgress:NO]; - if (error) { - [self.delegate exampleViewController:self didFinishWithError:error]; - } else { - switch (source.status) { - case STPSourceStatusChargeable: - case STPSourceStatusConsumed: - [self.delegate exampleViewController:self didFinishWithMessage:@"Payment successfully created"]; - break; - case STPSourceStatusCanceled: - [self.delegate exampleViewController:self didFinishWithMessage:@"Payment failed"]; - break; - case STPSourceStatusPending: - case STPSourceStatusFailed: - case STPSourceStatusUnknown: - [self.delegate exampleViewController:self didFinishWithMessage:@"Order received"]; - break; + if (error) { + [self.delegate exampleViewController:self didFinishWithError:error]; + } else { + [[STPAPIClient sharedClient] startPollingSourceWithId:sourceID + clientSecret:clientSecret + timeout:10 + completion:^(STPSource *source, NSError *error) { + [self updateUIForPaymentInProgress:NO]; + if (error) { + [self.delegate exampleViewController:self didFinishWithError:error]; + } else { + switch (source.status) { + case STPSourceStatusChargeable: + case STPSourceStatusConsumed: + [self.delegate exampleViewController:self didFinishWithMessage:@"Payment successfully created"]; + break; + case STPSourceStatusCanceled: + [self.delegate exampleViewController:self didFinishWithMessage:@"Payment failed"]; + break; + case STPSourceStatusPending: + case STPSourceStatusFailed: + case STPSourceStatusUnknown: + [self.delegate exampleViewController:self didFinishWithMessage:@"Order received"]; + break; + } } - } - self.redirectContext = nil; - }]; + self.redirectContext = nil; + }]; + } }]; [self.redirectContext startRedirectFlowFromViewController:self]; } diff --git a/Example/Custom Integration (ObjC)/ThreeDSExampleViewController.m b/Example/Custom Integration (ObjC)/ThreeDSExampleViewController.m index 605ab6caca5..3fc44e6603d 100644 --- a/Example/Custom Integration (ObjC)/ThreeDSExampleViewController.m +++ b/Example/Custom Integration (ObjC)/ThreeDSExampleViewController.m @@ -129,31 +129,35 @@ - (void)pay { // your app delegate to forwards URLs to the Stripe SDK. // See `[Stripe handleStripeURLCallback:]` self.redirectContext = [[STPRedirectContext alloc] initWithSource:source completion:^(NSString *sourceID, NSString *clientSecret, NSError *error) { - [[STPAPIClient sharedClient] startPollingSourceWithId:sourceID - clientSecret:clientSecret - timeout:10 - completion:^(STPSource *source, NSError *error) { - [self updateUIForPaymentInProgress:NO]; - if (error) { - [self.delegate exampleViewController:self didFinishWithError:error]; - } else { - switch (source.status) { - case STPSourceStatusChargeable: - case STPSourceStatusConsumed: - [self.delegate exampleViewController:self didFinishWithMessage:@"Payment successfully created"]; - break; - case STPSourceStatusCanceled: - [self.delegate exampleViewController:self didFinishWithMessage:@"Payment failed"]; - break; - case STPSourceStatusPending: - case STPSourceStatusFailed: - case STPSourceStatusUnknown: - [self.delegate exampleViewController:self didFinishWithMessage:@"Order received"]; - break; + if (error) { + [self.delegate exampleViewController:self didFinishWithError:error]; + } else { + [[STPAPIClient sharedClient] startPollingSourceWithId:sourceID + clientSecret:clientSecret + timeout:10 + completion:^(STPSource *source, NSError *error) { + [self updateUIForPaymentInProgress:NO]; + if (error) { + [self.delegate exampleViewController:self didFinishWithError:error]; + } else { + switch (source.status) { + case STPSourceStatusChargeable: + case STPSourceStatusConsumed: + [self.delegate exampleViewController:self didFinishWithMessage:@"Payment successfully created"]; + break; + case STPSourceStatusCanceled: + [self.delegate exampleViewController:self didFinishWithMessage:@"Payment failed"]; + break; + case STPSourceStatusPending: + case STPSourceStatusFailed: + case STPSourceStatusUnknown: + [self.delegate exampleViewController:self didFinishWithMessage:@"Order received"]; + break; + } } - } - self.redirectContext = nil; - }]; + self.redirectContext = nil; + }]; + } }]; [self.redirectContext startRedirectFlowFromViewController:self]; } From 3d897c33a9acbd28d2a1153a42983206f3f2207b Mon Sep 17 00:00:00 2001 From: Dan Jackson Date: Thu, 17 May 2018 11:44:06 -0700 Subject: [PATCH 3/4] Rename property and move comment for code review feedback --- Stripe/STPRedirectContext.m | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/Stripe/STPRedirectContext.m b/Stripe/STPRedirectContext.m index b21417e230d..77641af18d7 100644 --- a/Stripe/STPRedirectContext.m +++ b/Stripe/STPRedirectContext.m @@ -26,7 +26,7 @@ @interface STPRedirectContext () Date: Thu, 17 May 2018 11:47:55 -0700 Subject: [PATCH 4/4] Add changelog entry --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index d8de4966158..2940691c9b6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,6 @@ +## 13.0.1 2018-05-17 +* Fixes bug in `STPRedirectContext` that'd close the `SFSafariViewController` during the initial redirects, but only in livemode. [#937](https://github.com/stripe/stripe-ios/pull/937) + ## 13.0.0 2018-04-26 * Removes Bitcoin source support. See MIGRATING.md. [#931](https://github.com/stripe/stripe-ios/pull/931) * Adds Masterpass support to `STPSourceParams` [#928](https://github.com/stripe/stripe-ios/pull/928)