iOS Loans SDK Integration

Integrate smallcase Gateway Loans iOS SDK to allow your users to apply for loans, pay, withdraw, and much more

🙌

Hey, before you read further

Must read: LAMF: Integration overview , Loans SDK integration guide

Step 1 - Install and Configure

smallcase Gateway iOS Loans SDK is distributed as SCLoans, a standalone CocoaPod. It requires iOS 14.0+.

To install:

  1. Add the following to your Podfile
  2. Run pod install
target '${CLIENT_PROJECT_NAME}' do
  use_frameworks!

  # Replace ${FRAMEWORK_VERSION} with the latest version (eg. 7.2.0)
  pod 'SCLoans', '~> ${FRAMEWORK_VERSION}'
end
  • Check the changelog for the latest version.
  • Replace ${CLIENT_PROJECT_NAME} with your Xcode target name.
  • use_frameworks! is required — the SDK is distributed as a dynamic xcframework.
  • Credentials are provided to all integration partners by smallcase.
📘

Import the Loans module

The CocoaPod is named SCLoans, but the Swift module it vendors is Loans. In every file that uses the SDK, import it as:

import Loans

Step 2 - Environment Setup

Initialise the Loans SDK by calling setup on the ScLoan singleton before calling any other method.

import Loans

ScLoan.instance.setup(
    config: ScLoanConfig(gatewayName: "your_gateway_name")
) { result in
    switch result {
    case .success(let response):
        // Setup succeeded — proceed to trigger interactions
    case .failure(let error):
        // Handle error
    }
}

Here's a look at ScLoanConfig:

public class ScLoanConfig: NSObject {
    public init(gatewayName: String, environment: SCLoanEnvironment? = .production)
}

Params:

  1. gatewayName (required): The unique name given to your gateway integration.
    Eg: "moneycontrol"
  2. environment (optional, default: .production): The API environment to target.
    Possible values: .production | .staging | .development
📘

Note

Call setup every time there is any change in configuration.
setup must be the first method called. All other SDK methods will not work if setup hasn't completed successfully.


Step 3 - Trigger a loan interaction

All loan flows are triggered through a single method: triggerInteraction. The SDK determines the correct flow (application, repayment, withdrawal, servicing) from the interactionToken you pass in.

Interaction Token must be created before calling any Loans SDK method

All Loans SDK methods require an interaction token passed as an argument. The JWT token holds the context of user action in the form of an Interaction ID — a unique, one-time-use ID created each time a borrower wants to interact with their loan via the SDK. Learn more in the Glossary & API documentation.

triggerInteraction: unified loan interaction

ScLoan.instance.triggerInteraction(
    presentingController: self,
    loanInfo: ScLoanInfo(interactionToken: interactionToken)
) { result in
    switch result {
    case .success(let response):
        // Handle success
    case .failure(let error):
        // Handle error
    }
}

Params:

  1. presentingController (required): The UIViewController from which the SDK will be presented modally.
  2. loanInfo — ScLoanInfo (required):
    • interactionToken (required): The unique string received from your backend.

The completion closure receives a ScLoanResult<ScLoanSuccess>, which is a typealias for Swift's Result<ScLoanSuccess, ScLoanError>.


Step 4 - Handle response or error

Success response

On a successful interaction, the result resolves to .success(let response) where response is a ScLoanSuccess instance.

public class ScLoanSuccess: NSObject {
    public let isSuccess: Bool  // always true
    public let data: String?    // serialised JSON — parse to get intent-specific payload
}

Parse response.data to read the intent-specific result. The structure of the parsed JSON depends on the interaction:

{
  "intent": "LOAN_APPLICATION",
  "userId": "string",
  "loanApplication": {
    "status": "<ApplicationStatus>"
  }
}
{
  "intent": "PAYMENT",
  "userId": "string",
  "payment": {
    "status": "<PaymentStatus>"
  }
}
{
  "intent": "WITHDRAW",
  "userId": "string",
  "withdraw": {
    "status": "<WithdrawStatus>"
  }
}
📘

Note

The servicing dashboard (SERVICE intent) will always call the .failure case with error code 1012 when the user closes the dashboard. This is by design — there is no specific user action that constitutes a success for the servicing flow.

See the full list of loan application statuses and their meanings here: Loan application statuses.

Error response

On an incomplete or failed interaction, the result resolves to .failure(let error) where error is a ScLoanError instance.

public class ScLoanError: NSError {
    public let isSuccess: Bool     // always false
    public let errorCode: Int
    public let errorMessage: String
    public let data: String?       // serialised JSON — parse to get intent-specific data
}

ScLoanError also exposes asDictionary and toJsonString() which serialise the error as:

{
  "isSuccess": false,
  "code": <Int>,
  "message": "<String>",
  "data": "<serialised JSON string>"
}

Example error responses (parsed from error.data):

// error.errorCode == 1012, error.errorMessage == "user_cancelled"
{
  "intent": "LOAN_APPLICATION",
  "loanApplication": {
    "lid": "648c66ffc3488a97c9931a2d",
    "status": "SIGN_AGREEMENT"
  },
  "userId": "648c6705ee286538f7bebbbb"
}
// error.errorCode == 3001, error.errorMessage == "existing_loan_found"
{
  "intent": "LOAN_APPLICATION",
  "userId": "64ad01ba0241316d036519c6"
}

For the full list of SDK error codes and their meanings, see SDK error codes.


Deprecated methods

The following methods are deprecated as of the current SDK version. Use triggerInteraction() for all new integrations — the interaction token carries the intent, so a single method handles all flows.

// All share the same signature:
// (presentingController: UIViewController, loanInfo: ScLoanInfo, completion: (ScLoanResult<ScLoanSuccess>) -> Void)

@available(*, deprecated, message: "Use triggerInteraction() instead.")
ScLoan.instance.apply(presentingController: self, loanInfo: ...) { result in }    // loan origination

@available(*, deprecated, message: "Use triggerInteraction() instead.")
ScLoan.instance.pay(presentingController: self, loanInfo: ...) { result in }      // repayment

@available(*, deprecated, message: "Use triggerInteraction() instead.")
ScLoan.instance.withdraw(presentingController: self, loanInfo: ...) { result in } // withdrawal

@available(*, deprecated, message: "Use triggerInteraction() instead.")
ScLoan.instance.service(presentingController: self, loanInfo: ...) { result in }  // servicing dashboard

👋

Got queries? Ask our AM for an integrations support email. If an email thread exists, post queries as a reply to that.



Did this page help you?