SmartPin SDK - Android
Prerequisites:
- You need to have a SmartPin account.
- You can download android 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:
SmartPinManager.init(sandbox, token, object : SPInitListener { override fun onReady() { //SDK successfully initiated } override fun onNotReady(error: SPError) { // Error while initializing SDK. See the error object. } })
sandbox: Boolean When true , the SDK will communicate with the sandbox server. Use this for development. Dont't forget to set this to false when releasing the final version of your app.
accesstoken: String
listener : SPInitListener
In the init 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 recieve an SPError.
Get orders
Get orders in a range
You can retrieve orders for your contract within a range of two dates. You can get the orders by calling:
SmartPinManager.getOrders(startDate, null, object : SPOrdersListener { override fun onOrdersReceived(orderList: List) { // Retrieved the orders } override fun onOrdersFailed(error: SPError) { // 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.
Get single order based on id
You can get a single order bases on a id by calling:
SmartPinManager.getOrder(orderId, object : SPOrderListener { override fun onOrderReceived(order: SPOrder) { // Retrieved the order } override fun onOrderFailed(error: SPError) { // Error retrieving the order, see the error object } })
id: Long The id of the order you want to retrieve
listener : SPOrderListener
Get sites
You can retrieve all the sites within the contract by calling:
SmartPinManager.getSites(object : SPSitesListener { override fun onSitesReceived(sites: List) { // Retrieved the sites within the contract } override fun onSitesFailed(error: SPError) { // Error while retrieving the sites, see the error object } })
sites : List The ID of the order you want to retrieve
listener : SPSitesListener
Get terminals
To retrieve all terminals within the SmartPin contract you call:
SmartPinManager.getTerminals(object : SPTerminalsListener { override fun onTerminalsReceived(terminalsList: List) { // Retrieved the terminals } override fun onTerminalsFailed(error: SPError) { // Error while retrieving the terminals, see the error object } }, siteId)
siteId: String (Optional) The external id of the site. Leave empty if you want to retrieve all the
terminals in the contract.
listener : SPTerminalsListener
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:
SmartPinManager.testConnection(object : SPTestListener { override fun onTestSuccessful() { // Terminal connected and valid } override fun onTestFailed(error: SPError) { // Terminal not connected or not valid, see the error object. } })
listener : SPTestListener
Check terminal availability
You can check if there is an available terminal:
val terminalConnected = SmartPinManager.isExternalDeviceAvailable()
Transactions
SPPaymentListener
interface SPPaymentListener { fun onPaymentSuccess(order: SPOrder) fun onPaymentUnknown(error: SPError) fun onPaymentDeclined() fun onPaymentError(error: SPError) }
Assign this listener to SmartPinManager.paymentListener to receive callback events.
order : SPOrder
error : SPError
fun onPaymentError(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.
fun onPaymentSuccess(order: SPOrder)
This function is called when the payment is approved. You'll retrieve the SPOrder back.
fun onPaymentDeclined(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
fun onPaymentUnknown(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 3. Get orders call.
Cash transactions
You can start a cash payment by providing the payment type CASH [SPPaymentType] and an amount
SmartPinManager.startPayment( SPPaymentType.CASH, amount, reference )
type : SPPaymentType
amount: BigDecimal
reference: String (Optional)
Once then transaction is successfully stored, onPaymentSuccess() will be called. When there is an error, onPaymentError(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
You can start a cash payment by providing the payment type PIN [SPPaymentType] and an amount
SmartPinManager.startPayment( SPPaymentType.PIN, amount, reference )
type : SPPaymentType
amount: BigDecimal
reference: String (Optional)
Once the payment is finished one of the delegate functions described in SPPaymentListener will be called.
Retour transaction
When you want to do a retour/refund transactions, make the amount send in the startPayment() call negative.
Listeners
SPInitListener
interface SPInitListener { fun onReady() fun onNotReady(error: SPError) }
error: SPError
SPOrdersListener
interface SPOrdersListener { fun onOrdersReceived(orders: List) fun onOrdersFailed(error: SPError) }
orders : List A list with order objects
error : SPError
SPOrderListener
interface SPOrderListener { fun onOrderReceived(order: SPOrder) fun onOrderFailed(error: SPError) }
order : SPOrder
error : SPError
SPSitesListener
interface SPSitesListener { fun onSitesReceived(orders: List) fun onSitesFailed(error: SPError) }
order : List A list with site objects
error : SPError
SPSiteListener
interface SPSiteListener { fun onSiteReceived(site: SPSite) fun onSiteFailed(error: SPError) }
order : SPSite
error : SPError
SPTerminalsListener
interface SPTerminalsListener { fun onTerminalsReceived(terminals: List) fun onTerminalsFailed(error: SPError) }
terminals : List A list with terminal objects
error : SPError
SPTerminalListener
interface SPTerminalListener { fun onTerminalReceived(terminal: SPTerminal) fun onTerminalFailed(error: SPError) }
terminal : SPTerminal
error : SPError
SPDeviceListener
interface SPDeviceListener { fun onConnecting() fun onConnected() fun onDisconnected() }
SPTestListener
interface SPTestListener { fun onTestSuccessful() fun onTestFailed(error: SPError) }
error : SPError
Objects
SPError
data class SPError( var code: ErrorCode = ErrorCode.GENERIC, var message: String = "" // The description of the error if available )
For now there are 9 cases the ErrorCode can contain. Keep in mind that in update of the SDK, new codes can be added.
SPOrder
class SPOrder( var id: Long? //The ID of the order var date: String? //The date and time of the transaction var terminalDate: String? //The date and time of when transaction reached the terminal var siteId: String? //The id of the site where this transaction was done var terminalId: String? //The id of the terminal that handled the transaction var type: SPPaymentType //An enum containing pin or cash var paymentMethod: String? //The payment method of this transaction (e.g. maestro) var amount: BigDecimal //The amount of the transaction in cents var transactionId: String? //The unique transaction id if this order var aid: String? //The AID of the pin transaction var pan: String? //The truncated pan of the card holder var authCode: String? //The authorizationcode of the transaction var status: SPPaymentStatus //The status of the transaction, (Pending, failed or success) var responseCode: Int? //The responsecode of the transaction var externalId: String? //The unique external id of this transaction var reference: String? //The reference of the order )
SPSite
class SPSite ( var id: Long? var externalId: String //The external id of the site var name: String //The external id of the site var terminals: List //A list of terminals belonging to this site )
SPTerminal
class SPTerminal ( var externalId: String )
SPPaymentType
enum class SPPaymentType { PIN, CASH }
ErrorCode
enum class ErrorCode { GENERIC, //A generic ErrorCode, see the message what the error is. BACKEND_OFFLINE, //The backend of SmartPin (Or internet conncetion) is offline AMOUNT_INVALID, //The amount send in the payment is invalid REFUND_DISABLED, //You are doing a refund transaction, but refund payments are disabled in your SmartPin contract CONNECTION_ERROR, //There is a connection error with the terminal SDK_BLOCKED, //This SDK version is blocked, please update your SDK INVALID_TOKEN, //The token submitted is invalid PAYMENT_NOT_STORED, //The payment was successful, but could not be stored in the backend. It will be synced later BACKEND_OFFLINE, //There was a error in the backend, or with the internet connection. You can see the statuscode of the network call. }