ForageSDK
The ForageSDK processes Electronic Benefits Transfer (EBT) payments in your e-commerce application. It provides secure user interfaces for collecting and tokenizing an EBT cardholder’s PAN and accepting an EBT cardholder’s PIN to execute a balance check and process a payment.
Table of contents
Integration
CocoaPods
CocoaPods is a dependency manager for Cocoa projects. For usage and installation instructions, visit their website. To integrate ForageSDK into your Xcode project using CocoaPods, specify it in your Podfile
:
pod 'ForageSDK', '~> 0.1.1'
Swift Package Manager
The Swift Package Manager is a tool for managing the distribution of Swift code. It’s integrated with the Swift build system to automate the process of downloading, compiling, and linking dependencies.
We recommend using Xcode with Swift tools version 5.3 or higher. Earlier Xcode versions don’t support Swift packages with resources. To check your current Swift tools version run in your terminal:
xcrun swift -version
Follow the official Apple SPM guide instructions for more details.
Step-by-step
Add package:
To use Swift Package Manager, in Xcode add the https://github.com/teamforage/forage-ios-sdk dependency and choose the Dependency Rule
as Branch and the branch enter main
.
Click on Add Package
button. And, on the next screen, select the package ForageSDK
, and finish by clicking on Add Package
.
Usage
Import SDK into your file
import ForageSDK
Create ForageSDK instance
To initialize a ForageSDK instance, you need to provide the merchantID and sessionToken.
ForageSDK.setup(
ForageSDK.Config(
merchantID: "1234567",
sessionToken: "sandbox_eyJ0eXAiOiJKV1Qi..."
)
)
Forage UI Elements
ForageSDK provides two UI Elements to securely communicate with the Forage API.
ForagePANTextField
A component that securely accepts the PAN number. This field validates the PAN number based on the StateIIN list
private let foragePanTextField: ForagePANTextField = {
let tf = ForagePANTextField()
tf.borderColor = .black
tf.placeholder = "EBT Card Number"
return tf
}()
ForagePANTextField uses a delegate ForageElementDelegate
to communicate the updates to the client side.
foragePanTextField.delegate = self
public protocol ForageElementDelegate: AnyObject {
func focusDidChange(_ state: ObservableState)
func textFieldDidChange(_ state: ObservableState)
}
The ObservableState object has the values:
public protocol ObservableState {
/// isFirstResponder is true if the input is focused, false otherwise.
var isFirstResponder: Bool { get }
/// isEmpty is true if the input is empty, false otherwise.
var isEmpty: Bool { get }
/// isValid is true when the input text does not fail any validation checks with the exception of target length;
/// false if any of the validation checks other than target length fail.
var isValid: Bool { get }
/// isComplete is true when all validation checks pass and the input is ready to be submitted.
var isComplete: Bool { get }
}
The ForagePINTextField exposes a function to programmatically gain focus:
func becomeFirstResponder() -> Bool
To send the PAN number, we can use ForageSDK to perform the request.
Tokenize card number
// Signature
func tokenizeEBTCard(
foragePanTextField: ForagePANTextField,
customerID: String,
reusable: Bool?,
completion: @escaping (Result<PaymentMethodModel, Error>) -> Void
)
// Usage
ForageSDK.shared.tokenizeEBTCard(
foragePanTextField: foragePanTextField,
// NOTE: The following line is for testing purposes only and should not be used in production.
// Please replace this line with a real hashed customer ID value.
customerID: UUID.init().uuidString,
reusable: true
) { result in
// Handle result and error here
}
ForagePINTextField
A component the securely accepts an EBT PIN for balance requests and payment capture. It only accepts 4 digit numbers.
private let foragePinTextField: ForagePINTextField = {
let tf = ForagePINTextField()
tf.borderRadius = 10
tf.backgroundColor = .systemGray6
tf.pinType = .balance
return tf
}()
To identify the type of pin we are handling in the component, you can use the pinType
property. We have support for these types:
public enum PinType: String {
case snap
case nonSnap
case balance
}
ForagePINTextField uses a delegate ForageElementDelegate
to communicate the updates to the client side.
foragePinTextField.delegate = self
public protocol ForageElementDelegate: AnyObject {
func focusDidChange(_ state: ObservableState)
func textFieldDidChange(_ state: ObservableState)
}
The ObservableState object has the values:
public protocol ObservableState {
/// isFirstResponder is true if the input is focused, false otherwise.
var isFirstResponder: Bool { get }
/// isEmpty is true if the input is empty, false otherwise.
var isEmpty: Bool { get }
/// isValid is true when the input text does not fail any validation checks with the exception of target length;
/// false if any of the validation checks other than target length fail.
var isValid: Bool { get }
/// isComplete is true when all validation checks pass and the input is ready to be submitted.
var isComplete: Bool { get }
}
The ForagePINTextField exposes a function to programmatically gain focus:
func becomeFirstResponder() -> Bool
To send the PIN number, we can use the ForageSDK to perform the request.
Balance
// Signature
func checkBalance(
foragePinTextField: ForagePINTextField,
paymentMethodReference: String,
completion: @escaping (Result<BalanceModel, Error>) -> Void
)
// Usage
ForageSDK.shared.checkBalance(
foragePinTextField: foragePinTextField,
paymentMethodReference: paymentMethodReference
) { result in
// Handle result and error here
}
Capture payment
// Signature
func capturePayment(
foragePinTextField: ForagePINTextField,
paymentReference: String,
completion: @escaping (Result<PaymentModel, Error>) -> Void
)
// Usage
ForageSDK.shared.capturePayment(
foragePinTextField: foragePinTextField,
paymentReference: paymentReference
) { result in
// Handle result and error here
}
Demo Application
Demo application for using our components on iOS is here.
To get the application running,
- Clone this repo and open the Sample Project in the Sample folder.
- Ensure that you have a valid Merchant ID for the Forage API, which can be found on the dashboard (sandbox | prod).
- Create an authentication token with
pinpad_only
scope. - Create a session token.
- Run the Sample app project and provide your Merchant ID and session token on the first screen.
- These credentials will be passed through to all the SDK calls inside the sample app.
Dependencies
- iOS 10+
- Swift 5
- 3rd party libraries: