Skip to content

Commit

Permalink
Release 6.0.0
Browse files Browse the repository at this point in the history
* [ADDED] New payment method: Tap to Pay on iPhone
* [ADDED] New `paymentMethod` property on `SMPCheckoutRequest`. This defaults to `cardReader` but may be set to `tapToPay`.
* [REMOVED] `SMPPaymentOptions` was deleted. This was previously deprecated and is no longer used.
* [IMPROVEMENTS] Minor fixes for unified Black and White theme
  • Loading branch information
jadeburton-sumup committed Jun 28, 2024
1 parent 36af1d7 commit 5f4265c
Show file tree
Hide file tree
Showing 185 changed files with 22,859 additions and 47 deletions.
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
# SumUp iOS SDK Changelog

## Version 6.0.0

* [ADDED] New payment method: Tap to Pay on iPhone
* [ADDED] New `paymentMethod` property on `SMPCheckoutRequest`. This defaults to `cardReader` but may be set to `tapToPay`.
* [REMOVED] `SMPPaymentOptions` was deleted. This was previously deprecated and is no longer used.
* [IMPROVEMENTS] Minor fixes for unified Black and White theme

## Version 5.0.0

* [ADDED] Support for the Solo Lite card reader
Expand Down
131 changes: 131 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ Before calling SMPSumUpSDK checkoutWithRequest:fromViewController:completion:, c
* [Login](#login)
* [Accept card payments](#accept-card-payments)
* [Update checkout preferences](#update-checkout-preferences)
* [Tap to Pay on iPhone](#tap-to-pay-on-iphone)
* [Out of Scope](#out-of-scope)
* [Community](#community)
* [Changelog](#changelog)
Expand Down Expand Up @@ -318,6 +319,136 @@ respective account settings.
}];
```

## Tap to Pay on iPhone

With Tap to Pay on iPhone merchants can accept contactless card payments on their iPhone without needing a card reader.

To add Tap to Pay on iPhone to your app:

* Request the Tap to Pay on iPhone entitlement from Apple, receive approval, and then add the `com.apple.developer.proximity-reader.payment.acceptance` entitlement to your app. [Setting up the entitlement](https://developer.apple.com/documentation/proximityreader/setting-up-the-entitlement-for-tap-to-pay-on-iphone?language=objc).
* This feature requires an iPhone XS or later, running iOS 16.4 (iOS 16.7 starting July 8th) or later (ideally 17.5 or later.) The feature does not work on iPad.
* For debugging and testing you will need to be logged into an iPhone with a non-Sandbox Apple ID. Using a Sandbox Apple ID requires both Apple and SumUp implementations to connect to their respective non-production (test) backends, which the SDK does not support.
* During testing, to avoid transactions going to the acquirer and transferring real money, use a SumUp test account. To create a test account, please log in [here](https://auth.sumup.com/flows/login?client_id=developer_portal&login_challenge=fd21867fbc224ee985c0e206ef7f7549). Hover over "Account" on the top right corner of the page and click on “Test Profile” in the drop-down menu.

In your code:

* Make a call to check feature availability: is the Tap to Pay on iPhone payment method available for the current merchant?
* Trigger activation if needed. Activation sets up the iPhone to receive payments, shows the merchant how to use the feature, and links the SumUp account and Apple ID.
* Start the checkout.

### Check feature availability

* Call `checkTapToPayAvailability` on `SMPSumUpSDK` to check the availability of the Tap to Pay on iPhone payment method. This call, which requires the SDK to be in a logged-in state, may internally perform one or more network calls.
* If the feature is not available, your app could, as an example, hide or disable a button or menu item representing the Tap to Pay on iPhone payment method.
* The feature is generally available when the following criteria are fulfilled:
* the iPhone model and iOS version requirements are met
* the user logs in with a SumUp account registered in one of the countries where SumUp supports Tap to Pay on iPhone (temporarily with exception of Brazil)

### Perform activation if needed

* Activation must be completed before the first transaction can be performed. Activation means:
* the merchant links their Apple ID with their SumUp account
* the iPhone is prepared, which can take 45 seconds or longer
* This needs to be done once per merchant account, per device.
* In addition to determining feature availability, `checkTapToPayAvailability` also indicates whether Tap to Pay on iPhone has been activated yet for the current merchant.
* If it has not yet been activated then you should trigger activation by calling `presentTapToPayActivation` at a convenient time. Calling it more than once will still show the user education screens each time. Independently, the activation from the initial setup will remain valid.

Code example: checking availability and activation status

Objective-C

```obj-c
[SMPSumUpSDK checkTapToPayAvailability:^(BOOL isAvailable, BOOL isActivated, NSError * _Nullable error) {
if (error == nil) {
if (!isAvailable) {
// Tap to Pay on iPhone is not available for the merchant
return;
}

if (!isActivated) {
// Tap to Pay on iPhone needs activation - call presentTapToPayActivation
return;
}

// The app is ready to take Tap to Pay on iPhone payments!

} else {
// An error occurred
}
}];
```
Swift
```swift
SumUpSDK.checkTapToPayAvailability { isAvailable, isActivated, error in
if let error {
// An error occurred
return
}
if !isAvailable {
// Tap to Pay on iPhone is not available for the merchant
return
}
if !isActivated {
// Tap to Pay on iPhone needs activation - call presentTapToPayActivation
return
}
// The app is ready to take Tap to Pay on iPhone payments!
}
```

### Do the checkout

* Use the initializer of `SMPCheckoutRequest`/`CheckoutRequest` that takes a `paymentMethod` parameter, and specify `SMPPaymentMethodTapToPay`/`tapToPay`:

Objective-C

```objc
SMPCheckoutRequest request = [SMPCheckoutRequest requestWithTotal:total
title:itemDescription
currencyCode:SMPSumUpSDK.currentMerchant.currencyCode
paymentMethod:SMPPaymentMethodTapToPay];
```
Swift
```swift
let request = CheckoutRequest(total: total,
title: itemDescription,
currencyCode: SumUpSDK.currentMerchant?.currencyCode,
paymentMethod: .tapToPay)
```

* The rest of the checkout process is the same as when using a card reader.

### Background initialization

When `SMPSumUpSDK` initializes, it triggers a background initialization process. This can take about 10-15 seconds and must be completed before the first Tap to Pay on iPhone card-read can occur. If the user quickly initiates a transaction after your app launches, it may take longer than usual as it first waits for the initialization to complete. For subsequent transactions, however, (until the app is relaunched) this delay should not happen.

### Card Verification Method

Tap to Pay on iPhone supports contactless payments with physical cards or wallets (eg. Apple or Google Pay).
When accepting payments with physical cards, additional card holder verification in a form of PIN may be required. In the majority of such cases, the UI will display a PIN pad where the customer can enter and confirm the digits.
However, not every physical card allows this type of PIN processing. Some can only be processed by inserting the card into a physical card reader, which is not possible in the case of Tap to Pay on iPhone.
In such an instance, the merchant should ask the customer to try a different card or payment method.

### Best practices

* Follow the [Human Interface Guidelines](https://developer.apple.com/design/human-interface-guidelines/tap-to-pay-on-iphone) to save time when Apple reviews your app.
* Also consider [Apple’s marketing guidelines](https://developer.apple.com/tap-to-pay/marketing-guidelines/) and use standard assets where possible.

### Known issues

* If entitlements are not correctly set up in your app, `presentTapToPayActivation` may show an error Alert with "Failed to show Terms of Service".
* Bluetooth permissions will be requested even if the merchant does not plan to use any of the SumUp Bluetooth card readers. This will be fixed in an upcoming release.
* Businesses using SumUp sub-accounts must first activate the feature on their main account before using it on devices logged in with sub-accounts, otherwise an error message will appear during activation for the sub-account user.
* The `title` field in `SMPCheckoutRequest` does not currently appear on receipts.

## Out of Scope
The following functions are handled by the [SumUp APIs](http://docs.sumup.com/rest-api/):
* [Refunds](https://docs.sumup.com/rest-api/#tag/Refunds)
Expand Down
2 changes: 1 addition & 1 deletion SampleApp/SumUpSDKSampleApp/project.xcconfig
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
// Configuration file containging common settings for the sample apps
IPHONEOS_DEPLOYMENT_TARGET = 14.0
MARKETING_VERSION = 5.0.0
MARKETING_VERSION = 6.0.0
2 changes: 1 addition & 1 deletion SumUpSDK.podspec
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ Pod::Spec.new do |s|
s.cocoapods_version = '>= 1.9'

s.name = 'SumUpSDK'
s.version = '5.0.0'
s.version = '6.0.0'
s.summary = "This SDK enables you to integrate SumUp's proprietary card terminal(s) and its payment platform to accept credit and debit card payments."

s.description = <<-DESC
Expand Down
10 changes: 5 additions & 5 deletions SumUpSDK.xcframework/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -8,32 +8,32 @@
<key>BinaryPath</key>
<string>SumUpSDK.framework/SumUpSDK</string>
<key>LibraryIdentifier</key>
<string>ios-arm64_x86_64-simulator</string>
<string>ios-arm64</string>
<key>LibraryPath</key>
<string>SumUpSDK.framework</string>
<key>SupportedArchitectures</key>
<array>
<string>arm64</string>
<string>x86_64</string>
</array>
<key>SupportedPlatform</key>
<string>ios</string>
<key>SupportedPlatformVariant</key>
<string>simulator</string>
</dict>
<dict>
<key>BinaryPath</key>
<string>SumUpSDK.framework/SumUpSDK</string>
<key>LibraryIdentifier</key>
<string>ios-arm64</string>
<string>ios-arm64_x86_64-simulator</string>
<key>LibraryPath</key>
<string>SumUpSDK.framework</string>
<key>SupportedArchitectures</key>
<array>
<string>arm64</string>
<string>x86_64</string>
</array>
<key>SupportedPlatform</key>
<string>ios</string>
<key>SupportedPlatformVariant</key>
<string>simulator</string>
</dict>
</array>
<key>CFBundlePackageType</key>
Expand Down
Binary file not shown.
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,10 @@

NS_ASSUME_NONNULL_BEGIN

typedef NS_OPTIONS (NSUInteger, SMPPaymentOptions) {
SMPPaymentOptionAny = 0,
SMPPaymentOptionCardReader = 1 << 0,
SMPPaymentOptionMobilePayment = 1 << 1,
} NS_SWIFT_NAME(PaymentOptions);
typedef NS_ENUM(NSInteger, SMPPaymentMethod) {
SMPPaymentMethodCardReader = 0,
SMPPaymentMethodTapToPay = 1,
} NS_SWIFT_NAME(PaymentMethod);

/// Encapsulates all information that is necessary during a checkout with the SumUp SDK.
NS_SWIFT_NAME(CheckoutRequest)
Expand All @@ -24,27 +23,23 @@ NS_SWIFT_NAME(CheckoutRequest)
/**
* Creates a new checkout request.
*
* Be careful when creating the NSDecimalNumber to not
* falsely use the NSNumber class creator methods.
* Use SMPPaymentOptionAny to not put restrictions on the desired payment types.
* Be careful when creating the NSDecimalNumber to not falsely use the NSNumber class creator methods.
*
* @param totalAmount The total amount to be charged to a customer. Cannot be nil.
* @param title An optional title to be displayed in the merchant's history and on customer receipts.
* @param currencyCode Currency Code in which the total should be charged (ISO 4217 code, see SMPCurrencyCode). Cannot be nil, has to match the currency of the merchant logged in. Use [[[SMPSumUpSDK currentMerchant] currencyCode] and ensure its length is not 0.
* @param paymentOptions Payment options to choose a payment type(card reader, mobile payment...)
*
* @return A new request object or nil if totalAmount or currencyCode are nil.
*/
+ (SMPCheckoutRequest *)requestWithTotal:(NSDecimalNumber *)totalAmount
title:(nullable NSString *)title
currencyCode:(NSString *)currencyCode
paymentOptions:(SMPPaymentOptions)paymentOptions __deprecated_msg("Payment options will be ignored and default to .any. Options presented will be governed by merchant settings. Please use requestWithTotal:title:currencyCode: instead.");
paymentMethod:(SMPPaymentMethod)paymentMethod;

/**
* Creates a new checkout request.
* Creates a new checkout request using a card reader as the method of payment.
*
* Be careful when creating the NSDecimalNumber to not
* falsely use the NSNumber class creator methods.
* Be careful when creating the NSDecimalNumber to not falsely use the NSNumber class creator methods.
*
* @param totalAmount The total amount to be charged to a customer. Cannot be nil.
* @param title An optional title to be displayed in the merchant's history and on customer receipts.
Expand Down Expand Up @@ -77,9 +72,6 @@ NS_SWIFT_NAME(CheckoutRequest)
*/
@property (nonatomic, readonly, nullable) NSString *currencyCode;

/// Payment options to choose a payment type
@property (nonatomic, readonly) SMPPaymentOptions paymentOptions __deprecated_msg("Payment options will be ignored and default to .any");

/**
* An (optional) ID to be associated with this transaction.
* See https://docs.sumup.com/rest-api/#tag/Transactions
Expand Down Expand Up @@ -134,14 +126,20 @@ NS_SWIFT_NAME(CheckoutRequest)
*/
@property (nonatomic) NSUInteger saleItemsCount;


/**
* An optional flag to skip the confirmation screen in checkout.
* If set, the checkout will be dismissed w/o user interaction.
* Default is SMPSkipScreenOptionNone.
*/
@property (nonatomic) SMPSkipScreenOptions skipScreenOptions;

/**
* The method of payment to use during checkout; for example, a bluetooth-connected card reader, or Tap to Pay on iPhone.
*
* Defaults to `SMPPaymentMethodCardReader`.
*/
@property (nonatomic) SMPPaymentMethod paymentMethod;

@end

NS_ASSUME_NONNULL_END
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,55 @@ NS_SWIFT_NAME(SumUpSDK)
animated:(BOOL)animated
completion:(nullable SMPCompletionBlock)block;

#pragma mark - Tap to Pay on iPhone

/**
* Checks whether the Tap to Pay on iPhone payment method is available for the current merchant and whether or
* not it requires activation to be performed via a call to
* `presentTapToPayActivationFromViewController:animated:completionBlock:`.
*
* For the merchant to be able to use this payment method the following must be true:
*
* - The feature must be available in the merchant's country
*
* - It must be activated. This is where the merchant's Apple ID is linked with their SumUp account and the
* iPhone is prepared to work as a card reader. As this can take a minute or so the first time, the
* merchant is shown a UI that introduces them to the feature as it initializes in the background.
*
* The merchant must be logged in before you call this method.
*
* @param availability YES if the feature is available for the current merchant and it's OK to start activation.
* @param isActivated YES if activation has already been done for this device and merchant account
*/
+ (void)checkTapToPayAvailability:(void (^ _Nonnull)(BOOL isAvailable, BOOL isActivated, NSError * _Nullable error))block NS_SWIFT_NAME(checkTapToPayAvailability(completion:));

/**
* Performs activation for Tap to Pay on iPhone. This prepares the device, introduces the merchant to the
* feature and links their Apple ID to their SumUp account (which will require confirmation from the merchant.)
*
* Call `checkTapToPayAvailability:` before calling this method to find out if this payment method is available
* and if activation is needed.
*
* The merchant must be logged in before you call this method.
*
* Tap to Pay on iPhone requirements:
*
* - The hosting app must have the `com.apple.developer.proximity-reader.payment.acceptance`
* entitlement.
*
* - The merchant must have an iPhone XS or later with iOS 16.4 or later (iOS 17 or later recommended.)
* The feature does not work with iPads.
*
* @param fromViewController The UIViewController instance from which the UI should be presented modally.
* @param animated Pass YES to animate the transition.
* @param block The completion block is called after the view controller has been dismissed.
*/
+ (void)presentTapToPayActivationFromViewController:(UIViewController *)fromViewController
animated:(BOOL)animated
completionBlock:(nullable SMPCompletionBlock)block;

#pragma mark - Misc

/**
* This method does not do anything. It will be removed in a future release.
*/
Expand Down Expand Up @@ -170,11 +219,25 @@ typedef NS_ENUM(NSInteger, SMPSumUpSDKError) {
/// The currency code specified in the checkout request does not match that of the current merchant.
SMPSumUpSDKErrorCheckoutCurrencyCodeMismatch = 52,
/// The foreign transaction ID specified in the checkout request has already been used.
SMPSumUpSDKErrorDuplicateForeignID = 53,
SMPSumUpSDKErrorDuplicateForeignID = 53,
/// The access token is invalid. Login to get a valid access token.
SMPSumUpSDKErrorInvalidAccessToken = 54,
SMPSumUpSDKErrorInvalidAccessToken = 54,
/// The amount entered contains invalid number of decimals.
SMPSumUpSDKErrorInvalidAmountDecimals = 55,
SMPSumUpSDKErrorInvalidAmountDecimals = 55,
/// Tap to Pay on iPhone payment method is not available for the current merchant. This may be
/// because the payment method is not available in their country.
SMPSumUpSDKErrorTapToPayNotAvailable = 100,
/// Tap to Pay on iPhone: activation is required. Call `presentTapToPayActivationFromViewController:animated:completionBlock:`.
SMPSumUpSDKErrorTapToPayActivationNeeded = 101,
/// Tap to Pay on iPhone: an unspecified error occurred
SMPSumUpSDKErrorTapToPayInternalError = 102,
/// Tap to Pay on iPhone requires an iPhone XS or later and does not work on iPads.
SMPSumUpSDKErrorTapToPayMinHardwareNotMet = 103,
/// Tap to Pay on iPhone requires a newer version of iOS; please check the documentation for the
/// minimum supported version.
SMPSumUpSDKErrorTapToPayiOSVersionTooOld = 104,
/// Tap to Pay on iPhone has some other (unspecified) requirement(s) that are not met.
SMPSumUpSDKErrorTapToPayRequirementsNotMet = 105,
} NS_SWIFT_NAME(SumUpSDKError);

#pragma mark - Features
Expand Down
Loading

0 comments on commit 5f4265c

Please sign in to comment.