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.

Get it on the App Store

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:

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.