iOS—OAuth on mobile

United States

Interconnects

The Clover app ties the merchant to the mobile app, and provides authorization from Clover to operate your app on Clover systems. The Clover app is installed on the merchant. The Clover app's ID and Secret are provided to the mobile app.

The merchant provides authorization to their employee(s), the Clover app, and your mobile app. Employees are configured on the merchant. The Clover app is installed on the merchant.

The site URL is validated against a redirect URI provided by your mobile app during OAuth. The redirect URI must have the same base as the site URL configured for your Clover app. The site URL is configured on the Clover app. The redirect URI is configured in the mobile app.

📘

NOTE

If using app site association on iPhone Operating System (iOS®), the apple-app-site-association file must also be installed at the base of the same site URL and will be used by iOS and Apple for further validation. The apple-app-site-association validates the redirect URI against the mobile app using the Mobile App's ID and your developer credentials.

OAuth flow

  1. When the app launches, add a token change callback using CloverPaymentSDK.shared.addOnTokenChangeCallback.
  2. Initialize the SDK:
    • Call CloverPaymentSDK.shared.setup.
    • Pass in your configuration object.
    • In the configuration object, include a CloverPaymentSDK.FullOAuth object for full OAuth Support.
  3. CloverPaymentSDK attempts to recover a valid token stored securely in Keychain. If it finds a valid token, it completes initialization and calls your success callback registered in Step 2.
  4. If a valid token is not found, CloverPaymentSDK initiates OAuth login using the default browser on the device. This opens the login page in your configured environment for the user to log in. Identifying information from your configuration is passed in to ensure your app is authorized to log in for the merchant and employee.
  5. After logging in, the user receives a code to your registered associated domain using a callback. This enters back into your app using the scene delegate or other appropriate path. Refer to Apple documentation for options. In your handler, pass the full URL containing the code back using CloverPaymentSDK.shared.receivedOAuthCodeOrToken.
  6. CloverPaymentSDK exchanges the code for a token, stores the token back into Keychain for the next launch, and then calls your token change callback registered in Step 1. In your callback, call the CloverPaymentSDK.shared.setup to retry initialization this time with a valid token stored.

📘

NOTE

You may bypass the use of the in-built OAuth flow by implementing your own flow before calling CloverPaymentSDK.shared.setup. Use CloverPaymentSDK.isLoggedIn to determine if the SDK has a valid token before calling CloverPaymentSDK.shared.setup. Use the in-built token storage by passing the code received from the OAuth flow in a CloverPaymentSDK.PartialOAuth object. The PartialOAuth object's OAuthCodeResponse should only be populated once per code received. On subsequent launches pass in nil for the OAuthCodeResponse in the PartialOAuth object to maintain and use the token already acquired.

public class CloverPaymentSDK

                /// Initialize the Clover Payment SDK
                /// - Throws: A ``CloverGenericError`` in the event of an issue during setup
                /// - Parameters:
                ///   - configuration: Provide the necessary ``Configuration`` parameters used to communicate with Clover.
    public func setup(configuration: Configuration) async throws

                /// Provides configuration parameters to the SDK, specifying how to communicate with Clover's servers
    public struct Configuration {

                /// The server environment that we will send all server calls to.
        public let environment: CloverEnvironment.EnvironmentType

                /// App ID registered on your Clover Developer Portal, used by the OAuth Flow to match permissions to your app when your merchant logs in.
        public let appID:String

                /// App Secret obtained from your Clover Developer Portal.  This is the secret associated with your App ID.
        public let appSecret:String

                /// API Key for server access.  Contact your Developer Relations representative for a valid Key and Secret.
        public let apiKey: String

                /// API Secret for server access.  Contact your Developer Relations representative for a valid Key and Secret.
        public let apiSecret: String

                /// Specifier for how the SDK should handle OAuth within your application. 
                /// Provide a FullOAuth object to enable the SDK to provide login capabilities automatically. 
                /// Provide a PartialOAuth object to enable the SDK to only maintain the OAuthToken that you have aquired outside of the SDK.
        public var oauthFlowType : OAuthFlowType

   }

                /// Specifies that the SDK should provide full OAuth login capabilities for your application. 
                /// If specified, when needed the SDK will kick out to the default browser for user authentication, and return via the redirectURI.
    public struct FullOAuth : OAuthFlowType {

                /// The redirectURI to provide to the OAuth server.  This URI will be called containing the code or token after the user logs in.
                /// - Precondition: The redirectURI must be configured in your app using either Associated Domains or Custom URL Scheme.
                /// - Precondition: The redirectURI must be entered into your associated Clover App on Developer Home
        public var redirectURI : String

    }

                /// Specifies that the SDK should provide partial OAuth login capabilities for your application.
                /// If specified, the SDK will not attempt to authenticate the user, and instead expects that the host app will provide the authentication mechanism.
                /// - Remark: `codeResponse` is optional, and should only be provided if you received a new code response.  The eventual token will be stored securely by the SDK between instances.
    public struct PartialOAuth : OAuthFlowType {

        /// The response you received from the OAuth flow implemented in your app.
        /// - Remark: This value is optional, and should only be provided if you received a new code response.  The eventual token will be stored securely by the SDK between instances.
        public var codeResponse : OAuthCodeResponse?

    }

                /// True if we have valid OAuth credentials, signifying the User is logged in
    public var isLoggedIn:Bool

                /// Deletes the OAuth credentials and triggers an onTokenChangeCallback
    public func logout()

                /// The onTokenChangeCallbacks will be executed whenever a token changes (new token, refreshed token, deleted token, invalidated token)
                /// - Parameter callback: The callback to execute when the token changes
                /// - Returns: A unique identifier to be used for removing a callback when no longer needed.
    public func addOnTokenChangeCallback(_ callback:@escaping ()->()) -> String

                /// Removes an onTokenChangeCallback from the call list
                /// - Parameter identifier: The unique identifier returned when adding the callback to the call list
                /// - Returns: True if the passed in identifier was found to be associated with a callback in the call list, and therefore the callback was removed from the call list
    public func removeOnTokenChangeCallback(identifier:String) -> Bool

Implementation

When your app launches, any stored tokens are loaded from Keychain. If there is a token, it initializes the SDK. If there is no token, it redirects to the default web browser for the user to log in. When authentication succeeds, the app reopens, passing in the code, which Clover passes to the SDK. The SDK exchanges it for a token, stores it securely in Keychain, and finishes initializing the SDK.

Refer to the iOS—Clover Go quick SDK start guide OAuth section for OAuth implementation instructions.