How Strong Customer Authentication (SCA) rules affect developers?
Updated: April 25, 2023
6 min read
New legislation changes, referred to as Strong Customer Authentication (SCA) requirements, are coming to the EU, affecting all online purchases. Back in December, Apple released news about how in-app transactions will work with it.
SCA is a set of requirements designed to make online payments safer, maximize the security of user’s funds, and limit any fraud in online transactions. The EU issued these requirements with the second Payment Services Directive (PSD2), a legal document regulating payment services in Europe. PSD2 requires identifying payment verification introduced by your bank or payment service provider.
In other words, some of your customers in the EU will have to be taken out of the app purchase flow and redirected to a webpage of their bank in order to complete the payment.
All users in the EEA countries must confirm their online purchases by authenticating a bank card for every transaction greater than €30 starting 31 December 2020. For auto-renewable subscriptions, SCA is required only for the first transaction. Note that purchases made with Apple Pay won’t need additional authentication, as it already meets SCA requirements—as well as purchases made with phone billing, other payment services, or an Apple ID balance.
What we understand for SCA authentication EEA countries
Selling something in-app with a price greater than €30, such as a yearly subscription, may be tricky as there’s one more step in your sales funnel. Instead of just confirming the transaction with Face/Touch ID, the user must confirm it with the bank.
This slight change may affect your entire economy in EEA, and conversions may drop with expensive purchases.
The countries affected include the EU + a couple of countries in the EEA zone. Here’s the complete list: Austria, Belgium, Bulgaria, Croatia, Cyprus, Czech Republic, Denmark, Estonia, Finland, France, Germany, Greece, Hungary, Ireland, Italy, Latvia, Lithuania, Luxembourg, Malta, Netherlands, Poland, Portugal, Romania, Slovakia, Slovenia, Spain, Norway, Liechtenstein, Iceland, and Sweden.
Note that neither the UK nor Switzerland is included.
What can you do to be compliant?
- Reduce the price for yearly subscriptions.
- Show different options for users from EEA countries.
- Use Adapty A/B testing solution for targeting; exclude EEA countries for expensive purchases
Enhancing user experience with PurchaseInfo listener
Flow experience for purchases that are eligible for SCA will provide more barriers for users to complete the transaction. Fortunately, SCA-eligible purchase can be regarded as a ‘deferred’ purchase, and there are ways to make the experience smoother.
Let’s explore the two following steps:
- Listen for subscription status changes and broadcast those changes to the app;
- Handle the notification from the previous step to update the content screen, or paywall UI.
First, listen for didReceiveUpdatedPurchaserInfo delegate method and send a related notification when needed.
import Adapty
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
Adapty.activate("YOUR_ADAPTY_APP_TOKEN")
Adapty.delegate = self
return true
}
}
extension AppDelegate: AdaptyDelegate {
func didReceiveUpdatedPurchaserInfo(_ purchaserInfo: PurchaserInfoModel) {
// broadcast purchaserInfo changes
NotificationCenter.default.post(name: NSNotification.Name(rawValue: "PurchaserInfoUpdated"), object: purchaserInfo)
}
}
Here, we’re configuring Adapty and setting the delegate. In didReceiveUpdatedPurchaserInfo method we’re posting a notification with updated purchaserInfo.
Next, we’ll respond to this listener in two places: first is on our paywall, so we can close the paywall when the purchase is completed; second is on our main view controller, if the customer dismisses the paywall on their own before the listener fires, the main view will refresh to show the “premium” state.
We’ll add a notification observer which fires configureContent method to update the view based on the current user’s purchase status.
import UIKit
import Adapty
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// add an observer for `PurchaserInfoUpdated` notification that triggers an update content function
NotificationCenter.default.addObserver(forName: NSNotification.Name(rawValue: "PurchaserInfoUpdated"), object: nil, queue: OperationQueue.main) { (notification) in
self.configureContent(for: notification.object as? PurchaserInfoModel)
}
// get initial user's purchaser info
Adapty.getPurchaserInfo { (purchaserInfo, error) in
self.configureContent(for: purchaserInfo)
}
}
func configureContent(for purchaserInfo: PurchaserInfoModel?) {
// update the content based on subscription status
}
// remove the observer when the view is deallocated
deinit {
NotificationCenter.default.removeObserver(self)
}
}
Let’s walk through the above code:
- We set up an observer to receive notifications from didReceiveUpdatedPurchaserInfo delegate method.
- The observer fires UI updates, based on the current user’s purchaserInfo.
- Remove the observer when the view is deallocated.
We can also handle those pending errors in some way, or even show a dismissible banner indicating a pending payment is happening. But the extra development and testing may not be worth it, as the small changes we’ve already made are a huge improvement.
The whole thing mostly depends on your app business logic, so keep that in mind.