Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Release 4.0.0 #332

Merged
merged 1 commit into from
Oct 31, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
54 changes: 53 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,60 @@ of each release can be found in the [Support Lifecycle](SUPPORT.md).

If you are using CocoaPods, update your Podfile:
```
pod 'StripeTerminal', '~> 3.0'
pod 'StripeTerminal', '~> 4.0'
```

# 4.0.0 2024-10-31
4.0.0 includes breaking changes in both symbols and behavior. See the [migration guide](https://stripe.com/docs/terminal/references/sdk-migration-guide) for more details.

* Built with Xcode 16.0, Swift version 6.0.
* Update: Minimum deployment target updated from iOS 13.0 to iOS 14.0.

### New Features
* [Mail order / telephone order (MOTO)](https://docs.stripe.com/terminal/features/mail-telephone-orders/overview) payment support for smart readers.
- Contact Stripe support to enable this feature on your account.

* Global [card saving after payment](https://docs.stripe.com/terminal/features/saving-cards/save-after-payment) support by updating customer consent capture. The following breaking changes are required:
- A valid `allowRedisplay` value is now required to be set in `collectConfiguration` when using `setupFutureUsage` for `SCPTerminal`'s `collectPaymentMethod`.
- Removed the `customerConsentCollected` parameter from `SCPTerminal`'s `collectSetupIntentPaymentMethod` and replaced it with `allowRedisplay`.

## ⚠️ Breaking changes required

### Reader discovery
* New: Added a new enum value `discovering` to [`SCPConnectionStatus`](https://stripe.dev/stripe-terminal-ios/docs/Enums/SCPConnectionStatus.html) to represent when discovery is running.
* Update: Subsequent calls to `SCPTerminal`'s `discoverReaders:delegate:completion:` cancel all previously queued discovery operations. Only one discovery operation can run at any given time; all other discovery attempts will fail with `SCPErrorCanceledDueToIntegrationError`.
* Update: Internet and Tap to Pay discovery will now call the [`discoverReaders`](https://stripe.dev/stripe-terminal-ios/docs/Classes/SCPTerminal.html#/c:objc(cs)SCPTerminal(im)discoverReaders:delegate:completion:) completion block when the operation completes since these are not long running discovery operations.

### Reader connection
* Update: There is now a single [`connectReader`](https://stripe.dev/stripe-terminal-ios/docs/Classes/SCPTerminal.html#/c:objc(cs)SCPTerminal(im)connectReader:delegate:connectionConfig:completion:) call used for all connection methods. This replaces the previous methods: `connectBluetoothReader`, `connectInternetReader`, and `connectLocalMobileReader`.
- For mobile readers and Tap to Pay readers, the `ReaderDelegate` has been removed from the `connectReader` method as a parameter, and moved into the `connectionConfig`, replacing `autoReconnectionDelegate`. - For smart readers, the `InternetConnectionConfiguration` now also expects an `InternetReaderDelegate` to be passed in, which will alert your integration of reader disconnects.

* Update: [Auto reconnect on unexpected disconnect](https://docs.stripe.com/terminal/payments/connect-reader?terminal-sdk-platform=ios&reader-type=tap-to-pay#2.-automatically-attempt-reconnection) is now enabled by default for mobile and Tap to Pay readers.
* The `SCPReconnectionDelegate` has been removed and the methods have been moved to the common [`ReaderDelegate`](https://stripe.dev/stripe-terminal-ios/docs/Protocols/SCPReaderDelegate.html).
* Update: The method for handling reader disconnects has changed.
* Removed `terminal:didReportUnexpectedReaderDisconnect:` from the `SCPTerminalDelegate`. Use [`reader:didDisconnect:`](https://stripe.dev/stripe-terminal-ios/docs/Protocols/SCPReaderDelegate.html#/c:objc(pl)SCPReaderDelegate(im)reader:didDisconnect:) to be informed of reader disconnects.
* When auto-reconnect on unexpected disconnect is enabled, both [`-readerDidFailReconnect:`](https://stripe.dev/stripe-terminal-ios/docs/4.0.0/Protocols/SCPReaderDelegate.html#/c:objc(pl)SCPReaderDelegate(im)readerDidFailReconnect:) and [`reader:didDisconnect:`](https://stripe.dev/stripe-terminal-ios/docs/4.0.0/Protocols/SCPReaderDelegate.html#/c:objc(pl)SCPReaderDelegate(im)reader:didDisconnect:) methods will be called if the SDK fails to reconnect to the reader and it becomes disconnected.

### Payment acceptance
* New: Added a new enum value `SCPCardPresentCaptureMethodManual` to [`SCPCardPresentCaptureMethod`](https://stripe.dev/stripe-terminal-ios/docs/Enums/SCPCardPresentCaptureMethod.html) for simplifying manual card capture without affecting automatic non-card payment capture.
* If you are interested in joining this private preview, please email [stripe-terminal-betas@stripe.com](mailto:stripe-terminal-betas@stripe.com).
* Update: `SCPTerminal`'s `confirmPaymentIntent:completion`, `confirmSetupIntent:completion`, and `confirmRefund:completion` operations now return `SCPCancelable`'s that allow you to cancel the operation in certain scenarios.
* Update: Calls to `SCPTerminal`'s `cancelPaymentIntent:completion` or `cancelSetupIntent:completion` will now cancel ongoing operations related to the specified intent.
* Update: [`SCPOfflineDelegate`](https://stripe.dev/stripe-terminal-ios/docs/Protocols/SCPOfflineDelegate.html) now conforms to `NSObject`.
* Update: `SCPPaymentIntentParameters` and `SCPSetupIntentParameters` now keep payment method types as values of the `SCPPaymentMethodType` enum rather than strings.
* Update: [`SCPSetupIntent.stripeId`](https://stripe.dev/stripe-terminal-ios/docs/Classes/SCPSetupIntent.html#/c:objc(cs)SCPSetupIntent(py)stripeId) is now `nullable` to be consistent with `SCPPaymentintent.stripeId`. The `SCPSetupIntent.stripeId` will continue to be present.

### Renaming
* Update: [`BluetoothReaderDelegate`](https://stripe.dev/stripe-terminal-ios/3.9.0/Protocols/SCPBluetoothReaderDelegate.html) has been renamed to [`MobileReaderDelegate`](https://stripe.dev/stripe-terminal-ios/Protocols/SCPMobileReaderDelegate.html).
* Update: In `SCPReaderSoftwareUpdate`, renamed `estimatedUpdateTime` to `durationEstimate`.
* Update: Renamed `SCPUpdateTimeEstimate` to `SCPUpdateDurationEstimate`.
* Update: Renamed "local mobile" and "apple built in" to "Tap To Pay" in all SDK types, function names, and error codes to align with Stripe branding for this functionality.

## Non-breaking changes
* Update: The [`SCPInternetDiscoveryConfiguration`](https://stripe.dev/stripe-terminal-ios/docs/Classes/SCPInternetDiscoveryConfiguration.html) now supports an optional `timeout` value, specifying the timeout in seconds for the discover readers request. If the online discovery attempt fails, the operation will automatically fall back to offline discovery if [offline mode](https://docs.stripe.com/terminal/features/operate-offline/overview?reader-type=internet) is enabled.
* Update: Improved accuracy of smart reader errors that are reported as `SCPError`. Errors that were previously reported as a `SCPErrorGenericReaderError` are now mapped to a more specific `SCPError` type.


# 3.9.1 2024-09-05
* Built with Xcode 15.2, Swift version 5.9.
* Fix [#325](https://github.com/stripe/stripe-terminal-ios/issues/325): Corrects the status of `Terminal.shared.paymentStatus` and `Terminal.shared.connectionStatus` after [automatically reconnecting](https://docs.stripe.com/terminal/payments/connect-reader?terminal-sdk-platform=ios&reader-type=bluetooth#handle-disconnects) to mobile readers during unexpected disconnects.
Expand Down
40 changes: 20 additions & 20 deletions Example/Example.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
50225C402B4DACB300757FC6 /* StartReaderSettingsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50225C3F2B4DACB300757FC6 /* StartReaderSettingsViewController.swift */; };
50225C5E2B508DFB00757FC6 /* Error+StripeTerminal.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50225C5D2B508DFB00757FC6 /* Error+StripeTerminal.swift */; };
6F8BE0922177B403009511E5 /* DiscoveryMethodViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6F8BE0912177B403009511E5 /* DiscoveryMethodViewController.swift */; };
7BCA0C6739FF6C2E1B3AE86F /* Pods_Example.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F933CA536E7BD443088E6702 /* Pods_Example.framework */; };
A40E7CF027F64191005879C7 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = C16F40A72094F07C009CE87C /* Assets.xcassets */; };
A63E8431260D073B006CB90C /* CreateLocationViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = A63E8430260D073B006CB90C /* CreateLocationViewController.swift */; };
A63E8435260D0A0D006CB90C /* SelectLocationViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = A63E8434260D0A0D006CB90C /* SelectLocationViewController.swift */; };
Expand All @@ -58,7 +59,6 @@
C1DE30D721438E9900A3026F /* UIViewController+UIAlertController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1DE30D121438E9800A3026F /* UIViewController+UIAlertController.swift */; };
C1DE30D821438E9900A3026F /* UIView+Layout.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1DE30D221438E9800A3026F /* UIView+Layout.swift */; };
C1F78BDB2144F0830094BE37 /* CustomViews.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1F78BDA2144F0830094BE37 /* CustomViews.swift */; };
D1823934E4A82B04B4DB9896 /* Pods_Example.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B6C5EBEE90C4E3204BD10FFF /* Pods_Example.framework */; };
/* End PBXBuildFile section */

/* Begin PBXCopyFilesBuildPhase section */
Expand Down Expand Up @@ -100,17 +100,17 @@
390B937A2BED7C1800557850 /* CollectDataViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CollectDataViewController.swift; sourceTree = "<group>"; };
3936853D28860BDE0026A906 /* CaptureMethod+String.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "CaptureMethod+String.swift"; sourceTree = "<group>"; };
3959705F2A8D85830015F0F3 /* LocationStub.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LocationStub.swift; sourceTree = "<group>"; };
4FD82F87B0169B182DE08E4B /* Pods-Example.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Example.release.xcconfig"; path = "Target Support Files/Pods-Example/Pods-Example.release.xcconfig"; sourceTree = "<group>"; };
50225C3F2B4DACB300757FC6 /* StartReaderSettingsViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StartReaderSettingsViewController.swift; sourceTree = "<group>"; };
50225C5D2B508DFB00757FC6 /* Error+StripeTerminal.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Error+StripeTerminal.swift"; sourceTree = "<group>"; };
5F298C7CAAC76F0FE28E79E3 /* Pods-Example.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Example.release.xcconfig"; path = "Target Support Files/Pods-Example/Pods-Example.release.xcconfig"; sourceTree = "<group>"; };
68331A81F431D3EB50C6D085 /* Pods-Example.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Example.debug.xcconfig"; path = "Target Support Files/Pods-Example/Pods-Example.debug.xcconfig"; sourceTree = "<group>"; };
6F8BE0912177B403009511E5 /* DiscoveryMethodViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DiscoveryMethodViewController.swift; sourceTree = "<group>"; };
A63E8430260D073B006CB90C /* CreateLocationViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CreateLocationViewController.swift; sourceTree = "<group>"; };
A63E8434260D0A0D006CB90C /* SelectLocationViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SelectLocationViewController.swift; sourceTree = "<group>"; };
A63E8456260D23C9006CB90C /* StripeCountries.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StripeCountries.swift; sourceTree = "<group>"; };
AA568CD02A9D413900B9605C /* StartSetupIntentViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StartSetupIntentViewController.swift; sourceTree = "<group>"; };
B3C24C6B23285BF6003271BD /* ifaddrs.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ifaddrs.swift; sourceTree = "<group>"; };
B3C53B8B23286DA9003A707B /* Example-Bridging-Header.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "Example-Bridging-Header.h"; sourceTree = "<group>"; };
B6C5EBEE90C4E3204BD10FFF /* Pods_Example.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Example.framework; sourceTree = BUILT_PRODUCTS_DIR; };
C151C7A521605B6200FC206F /* UpdateReaderViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UpdateReaderViewController.swift; sourceTree = "<group>"; };
C152F77B214A18C00078BD07 /* StripeCurrencies.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StripeCurrencies.swift; sourceTree = "<group>"; };
C16651B621963C51006EFACF /* APIClient.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = APIClient.swift; sourceTree = "<group>"; };
Expand All @@ -130,7 +130,7 @@
C1DE30D121438E9800A3026F /* UIViewController+UIAlertController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIViewController+UIAlertController.swift"; sourceTree = "<group>"; };
C1DE30D221438E9800A3026F /* UIView+Layout.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIView+Layout.swift"; sourceTree = "<group>"; };
C1F78BDA2144F0830094BE37 /* CustomViews.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CustomViews.swift; sourceTree = "<group>"; };
D0BA0AF20D590A047F38D5AE /* Pods-Example.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Example.debug.xcconfig"; path = "Target Support Files/Pods-Example/Pods-Example.debug.xcconfig"; sourceTree = "<group>"; };
F933CA536E7BD443088E6702 /* Pods_Example.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Example.framework; sourceTree = BUILT_PRODUCTS_DIR; };
/* End PBXFileReference section */

/* Begin PBXFrameworksBuildPhase section */
Expand All @@ -139,18 +139,18 @@
buildActionMask = 2147483647;
files = (
022FB25B245868EF00F4C321 /* StripeTerminal.xcframework in Frameworks */,
D1823934E4A82B04B4DB9896 /* Pods_Example.framework in Frameworks */,
7BCA0C6739FF6C2E1B3AE86F /* Pods_Example.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */

/* Begin PBXGroup section */
1F9017D3F9880088EE567B8C /* Pods */ = {
9AB770F8BEE42F0193407BF9 /* Pods */ = {
isa = PBXGroup;
children = (
D0BA0AF20D590A047F38D5AE /* Pods-Example.debug.xcconfig */,
4FD82F87B0169B182DE08E4B /* Pods-Example.release.xcconfig */,
68331A81F431D3EB50C6D085 /* Pods-Example.debug.xcconfig */,
5F298C7CAAC76F0FE28E79E3 /* Pods-Example.release.xcconfig */,
);
name = Pods;
path = Pods;
Expand All @@ -162,7 +162,7 @@
C16F409F2094F07B009CE87C /* Example */,
EE087B524FD387212EBE036B /* Frameworks */,
C16F409E2094F07B009CE87C /* Products */,
1F9017D3F9880088EE567B8C /* Pods */,
9AB770F8BEE42F0193407BF9 /* Pods */,
);
sourceTree = "<group>";
};
Expand Down Expand Up @@ -236,7 +236,7 @@
isa = PBXGroup;
children = (
022FB25A245868EF00F4C321 /* StripeTerminal.xcframework */,
B6C5EBEE90C4E3204BD10FFF /* Pods_Example.framework */,
F933CA536E7BD443088E6702 /* Pods_Example.framework */,
);
name = Frameworks;
sourceTree = "<group>";
Expand All @@ -248,12 +248,12 @@
isa = PBXNativeTarget;
buildConfigurationList = C16F40AF2094F07C009CE87C /* Build configuration list for PBXNativeTarget "Example" */;
buildPhases = (
FDB3870A5F628D73748E5225 /* [CP] Check Pods Manifest.lock */,
7C8C6C314F349CEDD997FF26 /* [CP] Check Pods Manifest.lock */,
C16F40992094F07B009CE87C /* Sources */,
C16F409B2094F07B009CE87C /* Resources */,
0DE2ACED4D7F3843500B5F14 /* Frameworks */,
02A6BF5524CB1C3D0054ADFF /* CopyFiles */,
2114A53FB23FDBBFB2C0A4D1 /* [CP] Embed Pods Frameworks */,
3C492C1B82E7C01036C8C956 /* [CP] Embed Pods Frameworks */,
);
buildRules = (
);
Expand Down Expand Up @@ -314,7 +314,7 @@
/* End PBXResourcesBuildPhase section */

/* Begin PBXShellScriptBuildPhase section */
2114A53FB23FDBBFB2C0A4D1 /* [CP] Embed Pods Frameworks */ = {
3C492C1B82E7C01036C8C956 /* [CP] Embed Pods Frameworks */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
Expand All @@ -334,7 +334,7 @@
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Example/Pods-Example-frameworks.sh\"\n";
showEnvVarsInLog = 0;
};
FDB3870A5F628D73748E5225 /* [CP] Check Pods Manifest.lock */ = {
7C8C6C314F349CEDD997FF26 /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
Expand Down Expand Up @@ -486,7 +486,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
IPHONEOS_DEPLOYMENT_TARGET = 14.0;
MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES;
SAMPLE_CODE_DISAMBIGUATOR = "$(DEVELOPMENT_TEAM)";
Expand Down Expand Up @@ -542,7 +542,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
IPHONEOS_DEPLOYMENT_TARGET = 14.0;
MTL_ENABLE_DEBUG_INFO = NO;
SAMPLE_CODE_DISAMBIGUATOR = "$(DEVELOPMENT_TEAM)";
SDKROOT = iphoneos;
Expand All @@ -554,7 +554,7 @@
};
C16F40B02094F07C009CE87C /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = D0BA0AF20D590A047F38D5AE /* Pods-Example.debug.xcconfig */;
baseConfigurationReference = 68331A81F431D3EB50C6D085 /* Pods-Example.debug.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CODE_SIGN_IDENTITY = "Apple Development";
Expand All @@ -571,7 +571,7 @@
);
GCC_TREAT_WARNINGS_AS_ERRORS = YES;
INFOPLIST_FILE = Example/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
IPHONEOS_DEPLOYMENT_TARGET = 14.0;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
Expand All @@ -587,7 +587,7 @@
};
C16F40B12094F07C009CE87C /* Release */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 4FD82F87B0169B182DE08E4B /* Pods-Example.release.xcconfig */;
baseConfigurationReference = 5F298C7CAAC76F0FE28E79E3 /* Pods-Example.release.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CODE_SIGN_IDENTITY = "Apple Development";
Expand All @@ -604,7 +604,7 @@
);
GCC_TREAT_WARNINGS_AS_ERRORS = YES;
INFOPLIST_FILE = Example/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
IPHONEOS_DEPLOYMENT_TARGET = 14.0;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
Expand Down
5 changes: 1 addition & 4 deletions Example/Example/CollectDataViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,12 @@ import Static
import StripeTerminal

class CollectDataViewController: EventDisplayingViewController {
override var cancelLogMethod: LogEvent.Method {
return .cancelCollectData
}

private let collectDataConfig: CollectDataConfiguration

init(collectDataConfiguration: CollectDataConfiguration) {
self.collectDataConfig = collectDataConfiguration
super.init()
self.currentCancelLogMethod = .cancelCollectData
}

required init?(coder aDecoder: NSCoder) {
Expand Down
Loading