SmartPin SDK - iOS
Prerequisites:
- You need to have a SmartPin account.
- You can download iOS sdk from below link:
To initialize you need to have a client secret and a one time password. This one-time password can only be used once to create a access token. In the SmartPin app, you can also revoke tokens, when you revoke a token the access token will become invalid.
Get an access token
Retrieve client secret and One Time Password
- Login in the SmartPin app as the contract owner
- Go to settings
- Go to 'Options for developers'
- Enable 'Allow API access'
- Copy the client secret
- Go to Manage access tokens Create a new One Time Password
Retrieve an access token
In Postman (https://getpostman.com) or Paw (https://paw.cloud) create a new POST request with the following content:
The token_inactivity_timeout is a double, you can enter a number of days the token is valid when there is no activity on this token. The minimum 1 day, maximum 90 days. This field is optional, the default value is 7 days.
Create a basic authorization header, the username is your contract number, the password is your client_secret.
POST https://production.rspin.nl/api/v1/oauth/token Content-Type: application/json Accept: application/json Authorizaton: [Basic authorization with contract and client_secret] Content: { "grant_type":"client_credentials", "otp":"[One Time Password]", "access_token_validity":7 }
Initialize the SDK
To initialize the SDK you need to call:
Swift
SmartPinSDK(environment: .sandbox(loggingEnabled: true), accesstoken: access_token, completion: { (success, error) in if (success) { // SDK successfully intiated } else { // Error while initializing SDK. See the error object. } })
environment: SPEnvironment
accesstoken: String
completion: Completion block containing a success boolean and an optional SPError object.
In the initialize call the SDK validates the SDK and access token. When the SDK is invalid (e.g. there is a newer version, and older versions are blocked) or the access token is invalid, you'll retrieve an error.
Get orders
Get orders in a range
You can retrieve orders for your contract within a range of two dates. On the instance of the SDK you created in 1. Initialize the sdk, you can get the orders by calling:
Swift
sdk.getOrders(startDate: Date, endDate: Date) { (success, error, orders) in if (success) { // Retrieved the orders } else { // Error retrieving the orders, see the error object } }
startDate : Date
endDate : Optional, also a Date. If endDate is not present, you'll retrieve the orders up to and including today.
completion: Completion block containing a success boolean, optional SPError object when it failed and optional orders when successful. The orders is an Array containing SPOrder objects.
Get single order based on id
You can get a single order bases on a id by calling:
Swift
sdk.getOrder(id: Int) { (success, error, order) in if (success) { // Retrieved the order } else { // Error retrieving the order, see the error object } }
id : The ID of the order you want to retrieve
In the completion block you'll retrieve a success boolean, an optional SPError and when successful an SPOrder
Get sites
You can retrieve all the sites within the contract by calling:
Swift
sdk.getSites { (success, error, sites) in if (success) { // Retrieved the sites within the contract } else { // Error while retrieving the sites, see the error object } }
The only parameter needed in this call is a completion block, this completion block contains a success boolean, an optional SPError and an optional Array with SPSite objects.
Get terminals
To retrieve all terminals within the SmartPin contract you call:
Swift
sdk.getTerminals(site: "siteId") { (success, error, terminals) in if (success) { // Successfully retrieved the terminals } else { // Error while retrieving terminals. See the error object. } }
The site is optional, when there is no site provided, you'll retrieve all the terminals in the contract. In the completion block you'll get a success boolean, an optional SPError object, and an Array with SPTerminal objects.
Do a connection test with the terminal
You can do a connection test with the terminal to make sure the terminal is connected to the right environments. You can do this by calling:
Swift
sdk.testConnection { (success, error) in if (success) { // Terminal connected and valid } else { // Terminal not connected or not valid, see the error object. } }
In the completion block of this call you see a success boolean and an optional SPError object.
Check if device is connected
You can check if the terminal is connected by calling:
Swift
let terminalConnected = sdk.isTerminalConnected()
Transactions
When you are doing transactions, you must listen to the SPDelegate protocol. Just set the delegate of the sdk.
SPDelegate
Tere are four functions implemented in the SPDelegate
func paymentError(error: SPError)
This function is called when the payment has errored. This could be for several reasons:
- The SDK is blocked
- The amount is too high or too low. (Max = 9999999, Min = -9999999)
- The payment type is invalid
- There is no terminal connected when performing an pin payment
- The connected terminal is invalid, or it does not belong to your contract.
- There can be more errors, these will be explained in the SPError.
func paymentApproved()
This function is called when the payment is approved. You'll retrieve the SPPayment back.
func paymentDeclined(error: SPError?)
This function is called when a payment is declined. This can happen for several reasons, for example:
- Transaction cancelled on the terminal
- Connection error halfway through the transaction
func paymentUnknown(error: SPError?)
Called when we don't know the status of the payment. This happens mostly when we retrieve a unknown status from the terminal.
When this happens, the payment will be synced in the backend. After a while you'll get the correct status of this payment in the 2. Get orders cal
Cash transactions
If you want to start a cash payment, you need to create a SPPayment object with a cash payment type. After creating the payment object, you can start a payment by calling:
sdk.startPayment(type: .cash, amount: amount, reference: "Referentie")
Once then transaction is successfully stored, the delegate function paymentApproved() will be called.
When there is an error the delegate function paymentError(error: SPError) will be called. This can happen when there is a network issue. In this case the payment is not stored in the SmartPin backend. It could be that the payment was successful, but the transaction was not stored. You'll retrieve the error paymentNotStored . The customer has succesfully paid, and the transaction will be stored in the SmartPin backend later.
Pin transactions
If you want to start a pin payment, set the payment type of the SPPayment object to pin. Then you can call:
sdk.startPayment(type: .pin, amount: amount, reference: "Referentie")
Once the epayment is finished one of the delegate functions described in 8.1 SPDelegate will be called.
Retour transaction
When you want to do a retour/refund transactions, make the amount send in the startPayment() call negative.
Objects
SPEnvironment
Enum with cases:
- dev(loggingEnabeld: Bool) : Only used by the developers of the SDK
- sandbox(loggingEnabled: Bool) : Used for for testing the API on the sandbox environment
- production : Production environment of the sdk. Logging will always be disabled
SPError
code : ErrorCode
message : Optional String The description (if available of the error)
ErrorCode
For now there are 9 cases the ErrorCode can contain:
- backendOffline : The backend of SmartPin (Or internet conncetion) is offline
- amountInvalid : The amount send in the payment is invalid
- refundDisabled : You are doing a refund transaction, but refund payments are disabled in your
SmartPin contract
- generic : A generic ErrorCode, see the message what the error is.
- connectionError : There is a connection error with the terminal
- sdkBlocked : This SDK version is blocked, please update your SDK.
- invalidToken : The token submitted is invalid
- paymentNotStored : The payment was successful, but could not be stored in the backend. It will be synced later
- backendError(statusCode: Int) : There was a error in the backend, or with the internetconnection. You can see the statuscode of the network call.
Keep in mind that in updates of the SDK, new codes can be added.
SPOrder
The SPOrder contains the following values:
id : Int, the ID of the order
date : Date, the date of the transaction
terminalDate : Date?, the date the transaction reached the terminal.
type : SPPaymentType, this is a enum, containing pin or cash.
paymentMethod : String?, the payment method of this transaction (e.g. maestro)
siteId : String?, The id of the site where this transaction was done
status : SPPaymentStatus, The status of the transaction, (Pending, failed or success)
amount : Double, the amount of the transaction // TODO!
responseCode : Int?, the responsecode of the transaction
transactionId : String? The unique transaction id if this order.
externalId : String? The unique external id of this transaction
aid : String? The AID of the pin transaction
pan : String? The truncated pan of the card holder
authCode: String? The authorizationcode of the transaction
terminalId: String? The id of the terminal of a pin transaction.
reference : String? The reference of the order
SPSite
The SPSite contains the following:
externalId : String, the external id of the site
name : String? The name of the site
terminals: [SPTerminal], the terminals of the site
SPTerminal
The SPTerminal contains only a externalId (string).