iOS SDK
Getting started with iOS SDK for Number
The EasyPay iOS SDK offers access to the Number API for effortless integration with any iOS application. For Android integration, refer to the Android SDK integration guide.
Installation
Requirements
Xcode 15 or above
Compatible with iOS 13.0 or above
Configuration
Setup with Swift Package Manager
.package(url: "https://github.com/Easy-Pay-Solutions/Mobile-SDK-IOS.git", from: "1.0.6")
Setup with Cocoapods
pod 'EasyPay'
Get started
Integration
Prerequisites - get HMAC secret, API key and optional Sentry DSN from Number.
During the initialization, the process of downloading the certificate is starting. Proceeding with any call before downloading has finished will result in an error RsaCertificateError.failedToLoadCertificateData
.
You can check the status of downloading by accessing the following enum:
EasyPay.shared.certificateStatus
To enable jailbreak detection, please set isProduction = true
when initializing the library and add the following URL schemes to main Info.plist
.
<key>LSApplicationQueriesSchemes</key>
<array>
<string>undecimus</string>
<string>sileo</string>
<string>zbra</string>
<string>filza</string>
<string>activator</string>
</array>
Using widgets
Number's prebuilt payment UI components allow you to collect and process credit card information and payments in a secure way.
Managing cards
For managing saved cards without paying, the following initializer should be used:
CardSelectionViewController(selectionDelegate: AnyObject, preselectedCardId: Int?, paymentDetails: AddAnnualConsentWidgetModel) throws
preselectedCardId
is an optional parameter that allows to mark a card as selected by passing the ConsentId
of this card. If nil or incorrect, the selection will be ignored.
paymentDetails
parameter is used for passing additional payment details not visible for the end user. Either customerReferenceId
or rpguid
must be provided to get the list of consents of a specific customer. In case of of incorrect initialization data, CardSelectionViewControllerInitError
will be thrown.
If you would like to receive callbacks, conform to CardSelectionDelegate
with following methods:
func didSelectCard(consentId: String) {}
func didDeleteCard(consentId: Int, success: Bool) {}
func didSaveCard(consentId: Int?,
expMonth: Int?,
expYear: Int?,
last4digits: String?,
success: Bool) {}
Managing cards and payment
For managing saved cards and paying, following initializer should be used:
CardSelectionViewController(amount: String, paymentDelegate: AnyObject, preselectedCardId: Int?, paymentDetails: AddAnnualConsentWidgetModel) throws
amount
should be higher than 0 and it is required parameter.
preselectedCardId
is an optional parameter that allows to mark a card as selected by passing the ConsentId
of this card. If nil or incorrect, the selection will be ignored.
paymentDetails
parameter is used for passing additional payment details not visible for the end user. Either customerReferenceId
or rpguid
must be provided to get the list of consents of a specific customer. In case of of incorrect initialization data, CardSelectionViewControllerInitError
will be thrown.
If you would like to receive callbacks, conform to CardPaymentDelegate
with following methods:
func didPayWithCard(consentId: Int?, paymentData: PaymentData?, success: Bool) {}
func didDeleteCard(consentId: Int, success: Bool) {}
Screenshots
Save Card


Manage Cards


Store and Pay


Common components
SecureTextField component
The SDK's widgets use a component called SecureTextField
which ensures a safe input of credit card numbers. It is a subclass of UITextField
which enables freedom of styling as needed.
Setting up requires configuring the certificate once it was downloaded to encrypt credit card data.
nameOfYourTextField.setupConfig(EasyPay.shared.config)
To receive the encrypted card string required to send to the API, you can use the following method:
nameOfYourTextField.encryptCardData()
Common objects
Below you'll find code describing some of the objects that are commonly used in requests or responses. You can use it as a reference. The code includes parameter names and types.
CreditCardInfo
CreditCardInfo
The object consists of the following fields:
let accountNumber: String //credit card number encoded in base 64
let expirationMonth: Int?
let expirationYear: Int?
let cvv: String
AccountHolder
AccountHolder
The object consists of the following fields:
let firstName: String
let lastName: String
let company: String?
let billingAddress: BillingAddress
let email: String?
let phone: String?
BillingAddress
BillingAddress
The object consists of the following fields:
let address1: String
let address2: String?
let city: String?
let state: String?
let zip: String
let country: String?
EndCustomer
EndCustomer
The object consists of the following fields:
let firstName: String?
let lastName: String?
let company: String?
let billingAddress: EndCustomerBillingAddress?
let email: String?
let phone: String?
EndCustomerBillingAddress
EndCustomerBillingAddress
The object consists of the following fields:
let address1: String?
let address2: String?
let city: String?
let state: String?
let zip: String?
let country: String?
Amounts
Amounts
The object consists of the following fields:
let totalAmount: String
let salesAmount: String?
let surcharge: String?
PurchItems
PurchItems
The object consists of the following fields:
let serviceDescription: String?
let clientRefId: String?
let rpguid: String?
CreateConsentAnnual
CreateConsentAnnual
The object consists of the following fields:
let merchID: Int?
let customerRefID: String?
let serviceDescrip: String?
let rpguid: String?
let startDate: String //Timestamp in milliseconds in format \/Date(1710936735853)\/
let limitPerCharge: String
let limitLifeTime: String
AnnualEndCustomer
AnnualEndCustomer
The object consists of the following fields:
let firstName: String?
let lastName: String?
let company: String?
let billingAddress: AnnualEndCustomerBillingAddress?
let email: String?
let phone: String?
AnnualEndCustomerBillingAddress
AnnualEndCustomerBillingAddress
The object consists of the following fields:
let address1: String?
let address2: String?
let city: String?
let state: String?
let zip: String?
let country: String?
Publics methods in the SDK
Configuration
These methods allow you to configure the SDK secrets and load the certificate.
EasyPay.shared.configureSecrets(apiKey: String, hmacSecret: String)
EasyPay.shared.loadCertificate(_ completion: @escaping (Result<Data, Error>) -> Void)
1. Charge credit card
This method processes a credit card card sale when the credit card details are entered manually. Details include the card number, expiration date, CVV, card holder name and address.
EasyPay.apiClient.chargeCreditCard(request: CardSaleManualRequest,
completion: @escaping (Result<CreditCardSaleResponse, Error>) -> Void)
REST API equivalent: Process a Card Sale
Request parameters
TransactionRequest
creditCardInfo
: CreditCardInfoaccountHolder
: AccountHolderendCustomer
: EndCustomer?amounts
: AmountspurchItems
: PurchItemsmerchantId
: Int
Response body
The response will be serialized to CardSaleManualResponseModel
and include:
public let avsResult: String
public let acquirerResponseEMV: String?
public let cvvResult: String
public let errorCode: Int
public let errorMessage: String
public let functionOk: Bool
public let isPartialApproval: Bool
public let requiresVoiceAuth: Bool
public let responseMessage: String
public let responseApprovedAmount: Double
public let responseAuthorizedAmount: Double
public let responseBalanceAmount: Double
public let txApproved: Bool
public let txId: Int
public let txnCode: String
2. List annual consents
A query that returns annual consent details. Depending on the query sent, a single consent or multiple consents may be returned.
EasyPay.apiClient.listAnnualConsents(request: ConsentAnnualListingRequest,
completion: @escaping (Result<ListingConsentAnnualResponse, Error>) -> Void)
REST API equivalent: Query
Request body
AnnualQueryHelper
merchantId
: StringcustomerReferenceId
: String?rpguid
: String?endDate
: Date?
Either
customerReferenceId
orrpguid
must be provided to get the list of consents of a specific customer.
Response body
The response will be serialized to ConsentAnnualListingResponseModel
and include:
public let functionOk: Bool?
public var responseMessage: String?
public let errorMessage: String?
public let errorCode: Int?
public let numberOfRecords: Int?
public let consents: [ConsentAnnual]?
And the ConsentAnnual
consists of the following fields:
public let id: Int?
public let accountHolderId: Int?
public let customerId: Int?
public let merchantId: Int?
public let customerRefId: String?
public let rpguid: String?
public let serviceDescription: String?
public let accountHolderLastName: String?
public let accountHolderFirstName: String?
public let isEnabled: Bool?
public let startDate: String?
public let endDate: String?
public let numberOfDays: Int?
public let limitPerCharge: Double?
public let limitLifeTime: Double?
public let authTxID: Int?
public let createdOn: String?
public let createdBy: String?
public let accountNumber: String?
3. Create annual consent
This method creates an annual consent by sending the credit card details, which include: card number, expiration date, CVV, and card holder contact data. It is not created by swiping the card through a reader device.
EasyPay.apiClient.createAnnualConsent(request: CreateConsentAnnualRequest,
completion: @escaping (Result<CreateConsentAnnualResponse, Error>) -> Void)
REST API equivalent: Create Annual Consent
Request body
CreateConsentAnnualManualRequestModel
creditCardInfo
: CreditCardInfoconsentAnnualCreate
: CreateConsentAnnualaccountHolder
: AccountHolderendCustomer
: AnnualEndCustomer?
Response body
The response will be serialized to CreateConsentAnnualResponseModel
and include:
public let functionOk: Bool
public let responseMessage: String
public let errorMessage: String
public let errorCode: Int
public let creationSuccess: Bool
public let preConsentAuthSuccess: Bool
public let preConsentAuthMessage: String
public let preConsentAuthTxId: Int
public let consentId: Int
4. Cancel annual consent
Cancels an annual consent. Credit card data is removed from the system after the cancellation is complete.
EasyPay.apiClient.cancelAnnualConsent(request: CancelConsentAnnualRequest,
completion: @escaping (Result<CancelConsentAnnualResponse, Error>) -> Void)
REST API equivalent: Consent Annual
Request parameters
CancelConsentAnnualManualRequestModel
consentId
: Int
Response body
The response will be serialized to CancelConsentAnnualResponseModel
and include:
public let functionOk: Bool?
public let responseMessage: String?
public let errorMessage: String?
public let errorCode: Int?
public let cancelledConsentId: Int?
public let cancelSuccess: Bool?
5. Process payment for an annual consent
This method uses the credit card stored on file to process a payment for an existing consent.
EasyPay.apiClient.processPaymentAnnualConsent(request: ProcessPaymentAnnualRequest,
completion: @escaping (Result<ProcessPaymentAnnualResponse, Error>) -> Void)
REST API equivalent: Consent Annual
Request body
ProcessPaymentAnnualRequestModel
consentId
: IntprocessAmount
: String
Response body
The response will be serialized to ProcessPaymentAnnualResponseModel
and include:
public let functionOk: Bool?
public let txApproved: Bool?
public let responseMessage: String?
public let errorMessage: String?
public let errorCode: Int?
public let txnCode: String?
public let avsResult: String?
public let cvvResult: String?
public let acquirerResponseEMV: String?
public let txId: Int?
public let requiresVoiceAuth: Bool?
public let isPartialApproval: Bool?
public let responseAuthorizedAmount: Double?
public let responseBalanceAmount: Double?
public let responseApprovedAmount: Double?
How to properly consume the API response
The response must be consumed in the intended order and format. Clients who deviate from this can experience unwanted behavior.
if response.data.errorMessage != "" && response.data.errorCode != 0 {
//This indicates an error which was handled on the Number servers, consume the ErrCode and the ErrMsg
return
} else if response.data.functionOk == true && response.data.txApproved == false {
//This indicates a declined authorization, display the TXID, RspMsg (friendly decline message), also the decline Code (TxnCode)
} else {
//Transaction has been approved, display the TXID, and approval code (also in TXNCODE)
}
If there is no TxApproved
flag, then you can omit the last evaluation. More information about consuming the API response can be found in Consuming the API response section.
Possible errors
RsaCertificateError
failedToLoadCertificateData
Check certificate status, wait until the full download before proceeding with calls, try to download it again manually.
failedToCreateCertificate
Contact Number.
failedToExtractPublicKey
Contact Number.
AuthenticationError
missingSessionKeyOrExpired
Check if you have provided the correct apiKey
and hmacSecret
, contact Number to receive updated secrets.
NetworkingError
unsuccesfulRequest
Check HTTP status code.
noDataReceived
Data from backend was empty, contact Number.
dataDecodingFailure
Data from backend was not decoded properly, contact Number.
invalidCertificatePathURL
Contact Number.
Semantic versioning
The SDK follows semantic versioning with a three-part version number: MAJOR
.MINOR
.PATCH
.
MAJOR
version is incremented when there are incompatible API changes,MINOR
version is incremented when functionality is added in a backwards-compatible manner,PATCH
version is incremented when there are backwards-compatible bug fixes.
Last updated
Was this helpful?