Skip to main content

iOS SDK

The iOS SDK enables you to capture credit card data, additional personal data, and process them to create a Hellgate® Token. This token can then be used to process payments with the Hellgate® API.

The SDK is written in Swift and is available as an iOS dependency. It aims to provide a set of UI components and helpers that can be used to collect payment method data from the user with ease.

Installation

Installation can be done in a number of ways. Pick the distribution method that best suits your project:

Cocoapods

The SDK is available on Cocoapods. Add the following line to your Podfile:

pod 'Hellgate-iOS-SDK'

Carthage

  1. Add the following line to your Cartfile:
github "starfish-codes/hgate2-ios-headless-sdk"
  1. Run in same directory as your Cartfile:
$ carthage update --use-xcframeworks
  1. Add the built XCFrameworks to your project under "Frameworks and Libraries"

Swift Package Manager

The SDK is available on Swift Package Index. Add the package via Xcode from https://github.com/starfish-codes/hgate2-ios-headless-sdk.git

Usage

The SDK provides a set of UI components that can be used to collect payment method data from the user.

The components are composed of the following separate fields:

  • CardNumberView - A View that collects card details from the user.
  • ExpiryDateView - A View that collects the expiry date of the card from the user.
  • CvcView- A View that collects the CVC of the card from the user.

First you'll need to import the project:

import Hellgate-iOS-SDK

User Interface

Initialization of the UI Components

These components are intended to be used in a SwiftUI project. The validity of the users entered data can be listened in on by creating a @State property on your parent view.

form

ViewState

Each view below requires a binding to a ViewState property. The ViewState of each component is updated as soon as their related component changes.

SDK Interface
public enum ComponentState: String {
case complete
case incomplete
case blank
case invalid
}

public struct ViewState {
public let state: ComponentState
}
Code Sample
struct ContentView: View {

@State var cardNumberViewState = ViewState(state: .blank)
@State var expiryViewState = ViewState(state: .blank)
@State var cvcViewState = ViewState(state: .blank)

// ...
}

CardNumberView

The CardNumberView view is used to collect the card number from the user. It can be initialized with the card brand image either on the leading or trailing side of the input or hidden.

CardNumberView

Code Sample
CardNumberView(viewState: $cardNumberViewState, image: .leading)
.border()

struct ContentView: View {
@State var cardNumberViewState = ViewState(state: .blank)

var body: some View {
CardNumberView(viewState: $cardNumberViewState, image: .leading)
.border()
}
}

ExpiryDateView

The ExpiryDateView view is used to collect the expiry date of the card from the user.

ExpirtyDateView

Code Sample
struct ContentView: View {
@State var expiryViewState = ViewState(state: .blank)

var body: some View {
ExpiryDateView(viewState: $expiryViewState)
.border()
}
}

CvcView

The CvcView view is used to collect the CVC or CVV number of the card from the user.

Code Sample
struct ContentView: View {
@State var cvcViewState = ViewState(state: .blank)

var body: some View {
CvcView(viewState: $cvcViewState, length: .cvc)
.border()
}
}

Additional Fields

The AdditionalFieldsView is used to capture additional information about the card holder. The view is initialized with a type of the field and can be used to collect the following types of data:

  • CARDHOLDER_NAME - to collect the cardholder name from the user. In the future, the following fields will be added:

  • EMAIL - to collect the email from the user.

  • BILLING_ADDRESS_LINE_1 - to collect the address details from the user.

  • BILLING_ADDRESS_LINE_2 - to collect the address details from the user.

  • BILLING_ADDRESS_LINE_3 - to collect the address details from the user.

  • BILLING_ADDRESS_POSTAL_CODE - to collect the address details from the user.

  • BILLING_ADDRESS_CITY - to collect the address details from the user.

Code Sample

struct ContentView: View {
var body: some View {
AdditionalFieldsView(type: .CARDHOLDER_NAME)
.border()
}
}

Tokenization

Once the user has filled in the fields, the data can be tokenized using the tokenizeCard() function of the CardHandler interface. To create an instance of the CardHandler interface, you can use the cardHandler() function of the Hellgate® SDK object. This section is followed by the SDK-interface for reference.

Please make sure to provide the base URL of the Hellgate® API as a parameter according to your Hellgate® usage scenario. As a second parameter, you will need to provide the session_id that you received from the Hellgate® API when you initialized the session on the server side. See the section Tokenize on the Web for more information.

Once created, you can initialize a Hellgate® Object which helps you to handle a session.

SDK Interface
func initHellgate(baseUrl: URL, sessionId: String) async -> Hellgate

protocol Hellgate {
func fetchSessionStatus() async -> SessionState
func cardHandler() async -> Result<CardHandler, InvalidSessionState>
}

enum SessionState: String {
case REQUIRE_TOKENIZATION
case WAITING
case COMPLETED
case UNKNOWN
}
Code Sample
import Hellgate_iOS_SDK

class ContentViewViewModel: ObservableObject {

private var hellgate: Hellgate?

@Published var secretKey = ""
@Published var sessionId = ""
@Published var sessionState: SessionState?

@MainActor
func initSession() async {
// Retrieve the session id from your backend services
self.sessionId = await fetchSessionId()

// Initialise Hellgate with the session id
self.hellgate = await initHellgate(baseUrl: HELLGATE_URL, sessionId: sessionId)
}

@MainActor
func sessionStatus() async {
guard let hellgate = self.hellgate else { return }
self.sessionState = await hellgate.fetchSessionStatus()
}
}

After acquiring a Hellgate® object, you can fetch the session status and create a card handler object to tokenize the card data. Fetching the session status will return a SessionState enum which can be used to determine the state of the session. If the session is in the state REQUIRE_TOKENIZATION you can proceed with tokenizing the card data. After the card data was handed in successfully, the session state will change to COMPLETE. To hand in card data please create a cardhandler object by calling the cardHandler() function of the Hellgate® object. Now the tokenizeCard() function can be used to tokenize the card data by handing over the classes of the card number, expiry date and CVC number fields.

Also, in case you collected additional data, you can hand over a list of DataField objects to the function. The function will return a TokenizeCardResponse object. In case the tokenization was successful, the response will be of type TokenizeCardResponse.Success and contain the ID of the token. In case the tokenization failed, the response will be of type TokenizeCardResponse.Failure and contain a message.

SDK Interface
protocol CardHandler {
func tokenizeCard(
_ cardNumberView: ViewState,
_ cvcView: ViewState,
_ expiryView: ViewState,
_ additional: [AdditionalFieldType: ViewState]
) async -> Result<TokenizeCardResponse.Success, TokenizeCardResponse.Failure>
}

enum TokenizeCardResponse {
public struct Success: Decodable {
public let id: String
}

public struct Failure: Error, Decodable {
let message: String

var localizedDescription: String {
message
}
}
}
Code Sample
@MainActor
func tokenize() async {
guard let hellgate = self.hellgate else { return }

let result = await hellgate.cardHandler()

if case let .success(handler) = result {

let response = await handler.tokenizeCard(
cardNumberViewState,
cvcViewState,
expiryViewState,
[:]
)

switch response {
case let .success(result):
print("Token: \(result.id)")
case let .failure(err):
print(err.localizedDescription)
}
}
}