iOS
The Viva Wallet Card Terminal App for iOS can receive requests for initiating transactions from third-party apps installed on the same iOS mobile device. Communication with the Card Terminal App is done through the use of URL schemes and by implementing UIApplicationDelegate’s instance method application(_:open:options:) on the AppDelegate file of the client’s app project. The client app should create an URL scheme using specific parameters that will initiate the Card Terminal App’s pay activity. When the Card Terminal App’s pay activity finishes it returns the transaction result to the caller app.
A sample app is also available for download from our public GitHub account. It demonstrates the inter-app communication ability and contains all necessary info.
Messages
The client app must implement a mechanism to send messages using iOS intents and URI calls and to receive the result in a custom URI callback. Overall the following messages are available:
- Sale request originating from the client app to initiate a request for a new Sale transaction.
- Sale response originating from the Card terminal app to return the result of a Sale transaction.
- Cancel request originating from the client app to initiate a request for a Cancel transaction.
- Cancel response originating from the Card terminal app to return the result of a Cancel transaction.
Callback activity
The card terminal app will deliver the URL to your app by calling your app delegate’s application(_:open:options:) method. The following code should be added to the method in order to parse the contents of the URL and take the appropriate actions. To ensure the URL is parsed correctly, use NSURLComponents APIs to extract the components.
func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
guard let components = NSURLComponents(url: url, resolvingAgainstBaseURL: true),
let path = components.path,
let params = components.queryItems else {
print("Invalid URL or path missing")
return false
}
print("Path: \(path)\nComponents: \(params)")
//MARK: - Do any additional actions after parsing the data
return true
}
Sale request
For a typical sale request the client app must provide the following information:
Field | Description | Example |
---|---|---|
scheme |
The Viva custom URL scheme, the host and the version | 'vivapayclient://pay/v1' |
merchantKey |
The merchant's key | 'SG23323424EXS3' |
appId |
The client app id | 'com.example.myapp' |
action |
Sale transaction | 'sale' |
clientTransactionId |
A unique transaction ID transmitted to the host for storage with the transaction. Note that this value will be provided in the Merchant Reference field provided in the sales export response. |
'12345678901234567890123456789012' |
amount |
Amount in cents without any decimal digits. | '1200' = 12 euro |
tipAmount |
How much of the amount in cents is considered as tip without any decimal digits. | '200' = 2 euro |
withInstallments |
Enable installments. | 'true' |
preferredInstallments |
Number of preferred installments. If the number is between the allowed range and the card supports installments then the flow complete without any prompt for installments. If the number is 0 or > max allowed number of installments then the user will be prompt to enter the number in the app. If the card does not support installments then the app will request from the user how to proceed with the flow. | '10' |
callback |
The URI callback that will handle the result. | 'mycallbackscheme://result' |
Using the information above, our custom URI should be created like this.
static let schemeURL = "vivapayclient://pay/v1" // The Viva's custom URL scheme, the host and the version.
static let callback = "?callback=interapp-callback" // The URI callback that will handle the result.
static let merchantKey = "&merchantKey=SG23323424EXS3" // The merchant's key.
static let clientAppID = "&appId=com.vivawallet.InterAppDemo" // The client app id.
static let saleAction = "&action=sale" // Sale transaction
func createSaleRequest(amount: Decimal, tipAmount: Decimal?, numberOfInstallments: Int?, clientTransactionId: String?) -> String {
// construct sale action url
var saleActionURL = schemeURL + callback + merchantKey + clientAppID + saleAction
saleActionURL += "&amount=\(((amount * 100) as NSDecimalNumber).intValue)" // The amount in cents without any decimal digits.
if let tip = tipAmount {
saleActionURL += "&tipAmount=\(((tip * 100) as NSDecimalNumber).intValue)" // The tip amount in cents without any decimal digits.
}
// append clientTransactionId parameter (if any)
if let transactionId = clientTransactionId {
saleActionURL += "&clientTransactionId=\(transactionId)"
}
// append number of installments parameter (if any)
if let preferredInstallments = numberOfInstallments, preferredInstallments > 1 {
saleActionURL += "&withInstallments=true" // enable installments parameter
saleActionURL += "&preferredInstallments=\(preferredInstallments)"
}
else {
saleActionURL += "&withInstallments=false" // no installments parameter (should be used)
}
return saleActionURL
}
func performInterAppRequest(request: String){
guard let url = URL(string: request) else { return } // url with constructed parameters
UIApplication.shared.open(url) { (result) in
if result {
// The URL was delivered successfully!
}
}
}
//USE LIKE THIS
let saleRequestStringURL: String = createSaleRequest(amount: 12.00, tipAmount: 2.00, numberOfInstallments: nil, clientTransactionId: nil)
performInterAppRequest(request: saleRequestStringURL)
Sale response
After executing a Sale transaction the card terminal app responds with a Sale Response result to indicate if the transaction has been approved or not.
The result is received as a URI in the callback activity.
The table below summarises the contents of an approved response.
Field | Description | Example |
---|---|---|
callback |
The URI callback that will handle the result. | 'mycallbackscheme://result' |
status |
The status of the transaction | 'success' |
message |
A string containing information about the transaction status. | 'Transaction successful' |
action |
Sale transaction | 'sale' |
clientTransactionId |
The client transaction ID. | '12345678901234567890123456789012' |
amount |
The amount in cents without any decimal digits. | '1200' = 12 euro |
tipAmount |
How much of the amount in cents is considered as tip without any decimal digits. | '200' = 2 euro |
verificationMethod |
The verification method used | 'CHIP-PIN' |
rrn |
The retrieval reference number of the transaction RRN. | '123456833121' |
cardType |
The card type. | 'VISA' |
accountNumber |
The card number masked. Note that only the 6 first and the 4 last digits are provided. All other digits are masked with stars. | '479275\*\*\*\*\*\*9999' |
referenceNumber |
A 6-digit number indicating the transaction's STAN number. | '833121' |
authorisationCode |
A 6-digit number indicating the transaction's Authorisation code provided by the host. | '690882' |
tid |
A 12 character string indicating the terminal's TID number. | ' 16016684' |
orderCode |
The order code. | ' 9256110059000200' |
installments |
Number of installments. | ' 10' |
transactionDate |
The transaction date in ISO 8601 format. | '2019-09-13T12:14:19.8703452+03:00' |
transactionId |
A unique identifier for the transaction. | 'a78e045c-49c3-4743-9071-f1e0ed71810c' |
A Sale response result for an approved transaction looks as follows:
mycallbackscheme://result?status=success&message=Transaction%20successful.&action=sale&clientTransactionId=12345678901234567890123456789012&amount=1200&tipAmount=200&verificationMethod=CHIP-PIN&rrn=123456833121&cardType=VISA&accountNumber=479275******9999&referenceNumber=833121&authorisationCode=690882&tid=16016684&orderCode=9256110059000200&installments=10&transactionDate=2019-09-13T12:14:19.8703452+03:00&transactionId=a78e045c-49c3-4743-9071-f1e0ed71810c
It is expected that certain transactions will fail for various reasons. A Sale response result for a failed transaction looks as follows:
mycallbackscheme://result?status=failed&message=Transaction%20declined%20by%20host.&action=sale&clientTransactionId=12345678901234567890123456789012&amount=1200&tipAmount=200&verificationMethod=CHIP-PIN&rrn=123456833121&cardType=VISA& accountNumber=479275******9999&referenceNumber=&authorisationCode=&tid=16016684&orderCode=9256110059000200&transactionDate=2019-09-13T12:14:19.8703452+03:00
The structure of the message is the same as in the case of an approved transaction. Fields such as referenceNumber
and authorisationCode
may not have values since there is no STAN code available, nor an authorisation code.
Cancel request
For a typical cancel request the client app must provide the following information:
Field | Description | Example |
---|---|---|
scheme |
The Viva's custom URL scheme, the host and the version. | 'vivapayclient://pay/v1' |
merchantKey |
The merchant's key. | 'SG23323424EXS3' |
appId |
The client app id. | 'com.example.myapp' |
action |
Cancel transaction. | 'cancel' |
referenceNumber |
The STAN number of the transaction to be cancelled. If empty, after card presentment, the app will provide a list of the last 3 transactions made with the presented card, allowing the user to select the transaction to be canceled. | |
callback |
The URI callback that will handle the result. | 'mycallbackscheme://result' |
The above information elements must create a URI call, i.e.
let cancelAction = "&action=cancel"
func createCancelRequest(reference: String?) -> String {
// construct sale action url
var cancelActionURL = schemeURL + callback + merchantKey + clientAppID + cancelAction
if let unwrappedReference = reference, unwrappedReference != "" {
cancelActionURL += "&referenceNumber=\(unwrappedReference)" // transaction reference number
}
return cancelActionURL
}
//USE LIKE THIS
let canceRequestStringURL: String = createCancelRequest(reference: "60646")
performInterAppRequest(request: canceRequestStringURL)
Cancel response
After executing a Cancel transaction the card terminal app responds with a Cancel response result to indicate if the transaction has been approved or not.
The result is received as a URI in the callback activity.
The table below summarises the contents of an approved response:
Field | Description | Example |
---|---|---|
callback |
The URI callback that will handle the result. | 'mycallbackscheme://result' |
status |
The status of the transaction | 'success' |
message |
A string containing information about the transaction status. | 'Transaction successful' |
action |
Cancel transaction. | 'cancel' |
amount |
The amount in cents without any decimal digits. | '1200' = 12 euro |
cardType |
The card type. | 'VISA' |
accountNumber |
The card number. Note that only the 6 first and the 4 last digits are provided. All other digits are masked with stars. | '479275\*\*\*\*\*\*9999' |
tid |
A 12 character string indicating the terminal's TID number. | ' 16016684' |
transactionDate |
The transaction date in ISO 8601 format. | ' 2019-09-13T12:14:19.8703452+03:00' |
transactionId |
A unique identifier for the transaction. | 'a78e045c-49c3-4743-9071-f1e0ed71810c' |
A Cancel response result for an approved transaction looks as follows:
mycallbackscheme://result?status=success&message=Transaction%20successful.&action=cancel&amount=1200 &cardType=VISA&accountNumber=479275******9999&tid=16016684&transactionDate=2019-09-13T12:14:19.8703452+03:00&transactionId=a78e045c-49c3-4743-9071-f1e0ed71810c
It is expected that certain transactions will fail for various reasons. A Cancel response result for a failed transaction looks as follows:
mycallbackscheme://result?status=success&message=Transaction%20successful.&action=cancel&amount=1200& cardType=VISA&accountNumber=479275******9999&tid=16016684&transactionDate=2019-09-13T12:14:19.8703452+03:00
The structure of the message is the same as in the case of an approved transaction.