iOS Integration Guide

This page describes how to integrate Vesta’s iOS SDK into your iOS app project. During the integration, you will perform the following actions:

Download the Libraries

Click here to download the iOS SDK. If the download does not start automatically, on Windows, right click the link, or on Mac, hold the Control key and click the link. Then, select Save link as… from the menu that opens.

Import the Library

Import the library into your project in order to begin using the Vesta methods.

The steps below describe how to add the library files to your project:

  1. Add the library file, vNext.xcframework, to the project target where you want to use it. Be sure to select the “Copy items if needed” option.

  2. Confirm that the framework was properly added to your project as shown in the image below:

  3. Unzip the FingerprintPro.xcframework.zip file, and add it to you project as in step 1.

Now that the SDK is included in your project, you must complete the set up to initialize when your app launches.

Initialize the Data Collector

Initialize the Data Collector at the beginning of your app flow so that it can report the data that it tracks to Vesta.

At the beginning of your app flow, call the authenticateUser function to initialize the service. The function requires the following parameters:

Parameter Name Type Description
UserName String Your Vesta account user name provided by Vesta Customer Success.
SecretKey String You secret key, obtained from the Vesta Console.
CustomerName String The customer name.
SandboxEnabled Boolean Set this value to true to use the sandbox environment.
Region Enum The region in which your business operates: US or APAC.

The sample code below shows how to call the authenticateUser function:

import vNext

func initializeDataCollectorService() {

  DataCollectorService.default.authenticateUser(withUserName: "[email protected]", secretKey: "'c&D906L*4-3oBa", customerName: "Dharmbir Singh", sandboxEnabled: true, region: .US, completion: {
    transactionId in
    if !transactionId.isEmpty {
      print("Customer TransactionID==", transactionId)

    }

  })
}

Note: The user name and password are specific to the application environment. For development, use your sandbox credentials, then swap them with your production credentials when your app goes live.

The completion handler will return a transactionId which will be used in subsequent function calls. If the completion handler returns an empty transactionId field, the service did not initialize properly, and you should handle the error. If the problem persists, contact Vesta Customer Success.

Provide Location Data

If you choose to track your customer’s location, use the DataCollectorService.sendLocationData() method to send the latitude and longitude values from your user’s device to Vesta. Vesta uses the location data to augment our fraud detection and risk analysis. Tracking location data is optional. If you choose not to track location, proceed to the Implement Data Collector section.

The table below defines the parameters that you must pass to the DataCollectorService.sendLocationData() method:

Parameter Name Description Type
latitude The latitude value obtained from your customer’s device. Double
longitude The longitude value obtained from your customer’s device. Double

The code below provides an example of how to call the sendLocationData() method:

import vNext

func sendLocationToDataCollectorService() {
	// Previously obtained latitude<Double> from CoreLocation
	// Previously obtained latitude<Double> from CoreLocation

	DataCollectorService.default.sendLocationData(latitude: latitude, longitude: longitude) { (success) in
		if success {
            print("Location sent successfully")
		}
	}
}

Implement Data Collector

Our iOS integration supports different ways to implement tracking depending on the type of UI element:

  • Text Fields - Track the text entered and time spent in text field elements in your app.
  • Buttons - Track button taps for different events in your app.
  • Pickers - Track the start and end time for when pickers are displayed.
  • Active Screens - Track the time that your users enter and leave screens of your app.

In general, you can add tracked UI elements using Interface Builder or in your code by subclassing the standard UI components. The SDK provides an additional, unique class for tracking text fields, VestaTextWatcher.

Field Tags - When subclassing one of Vesta’s tracking elements from a standard element, you must use a tag value from the enums defined in the FieldTags.swift file. Any other tag values will cause a runtime error.

Text Fields

Text field tracking sends information to Vesta about how users interact with text fields in your app, which improves our fraud detection.

Implement text field tracking in your application using Interface Builder, directly in your code by setting the fieldTag property of your TrackingTextField objects or using the VestaTextWatcher class.

Interface Builder

To use Interface Builder to implement field tagging, follow the steps below for each of the UITextField objects in your application that you intend to track.

  1. Open the Identity Inspector for the UITextField object that you want to tag.

  2. Set the class of the UITextField to TrackingTextField, and set the Module to vNext as shown in the image below.

  3. Open the Attributes Inspector for the UITextField object. You will see Identifier and Field Tag properties, which are defined by the TrackingTextField subclass.

    Known Issues: Occasionally, Interface Builder will not display the custom properties of the TrackingTextField in the Attributes Inspector. If this happens, define any necessary information in the Connections Inspector first. If you do not define the connections first, setting the class in the Identity Inspector may cause the connections to disappear from the list and you will not be able to set them. Once you have set the connections manually, you can assign the values in the Identity Inspector as described in the next step.

  4. Set the fieldTag value in the Attributes Inspector, as shown in the image above. The value that you set for fieldTag must correspond to one of the values provided by Vesta in the list of tracked fields.

Code

The information in this section describes how to set the fieldTag property on your TrackingTextField classes using code. Using code to implement field tagging is easier and less likely to cause bugs than using the Interface Builder. Follow the steps below for each of your TrackingTextField objects to implement field tagging in your code:

  1. Set the fieldTag property of the TrackingTextField object.
  2. Access the enum values of the TrackingTextField object and cast them to string rawValue.

The code below shows an example of tagging the user name and password fields as LoginID and Password:

import vNext 

// You can use any default or convenience initializer
 
let emailTextField = TrackingTextField()
let passwordTextField = TrackingTextField()
         
emailTextField.fieldTag = FieldTags.LoginID.rawValue
passwordTextField.fieldTag = FieldTags.Password.rawValue

VestaTextWatcher

The VestaTextWatcher class makes it possible to track all UITextField elements, including UISearchBar, UITextView, and other UI elements that use any of these components, without having to subclass from TrackingTextField. The steps below describe how to use VestaTextWatcher:

  1. Make sure your UI subclasses conform to the FieldTrackingProtocol by setting a FieldTags variable for each of them.
  2. Create an instance of VestaTextWatcher and call startTracking() when you want to begin tracking user interaction. We recommend calling startTracking() in viewWillAppear.
  3. Call stopTracking() on your VestaTextWatcher instance when you want to end user tracking, for example, when a screen is being dismissed or the customer is leaving your app. We recommend ending tracking in viewDidDisappear.

Note: We recommend creating an instance of VestaTextWatcher on each screen for better handling of tracking. Having a single instance for the entire application lifecycle may cause unexpected behavior.

Warning: Do not combine VestaTextWatcher with TrackingTextField subclassing in the same screen.

The code below provides an example of implementing VestaTextWatcher:

import vNext

class MyTextField: UITextField, FieldTrackingProtocol {
	// You can initialize it to None and change it to something trackable if needed
    var fieldTag: FieldTags = .None
}

class MySearchBar: UISearchBar, FieldTrackingProtocol {
	// You can initialize it to None and change it to something trackable if needed
    var fieldTag: FieldTags = .None
}

class MyOwnTextView: AnotherTextViewUIComponent, FieldTrackingProtocol {
	// You can initialize it to None and change it to something trackable if needed
    var fieldTag: FieldTags = .None
}

class ViewController: UIViewController {
    // VestaTextWatcher instance for this screen
    let vestaTextWatcher = VestaTextWatcher()
    
    @IBOutlet private weak var emailTextField: MyTextField!
    @IBOutlet private weak var passwordTextField: MyTextField!
    
    @IBOutlet private weak var mySearchBar: MySearchBar!
    
    @IBOutlet private weak var myTextView: MyOwnTextView!

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
        
		// Setting the fieldTag property on the elements before startTracking so it works
        emailTextField.fieldTag = FieldTags.LoginID
        passwordTextField.fieldTag = FieldTags.Password
        
        mySearchBar.fieldTag = FieldTags.ProductSearch
        
        myTextView.fieldTag = FieldTags.BillingAddressLine1
    }
    
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        
		// We recommend having the startTracking function in the viewWillAppear function for better results
        vestaTextWatcher.startTracking()
    }
    
    override func viewDidDisappear(_ animated: Bool) {
        super.viewDidDisappear(animated)
        
		// We recommend having the stopTracking function in the viewDidDisappear function for better results
        vestaTextWatcher.stopTracking()
    }
}

Buttons

To track button taps in your app, subclass TrackingButton from the UIButton class in Interface Builder or directly in your code.

Interface Builder

To use Interface Builder to implement field tagging, follow the steps below for each of the UIButton objects in your application that you intend to track.

  1. Open the Identity Inspector for the UIButton object that you want to tag.

  2. Set the class of the UIButton to TrackingButton, and set the Module to vNext, as shown in the image below.

  3. In your code, set the trackingAction property to one of the values defined in the ButtonTrackingAction.swift file. If you do not set the property to one of the specified values, it will cause a runtime error.

Code

To implement data collector for buttons using code, you must set the trackingAction property to one of the values defined in the ButtonTrackingAction.swift enum.

The code below shows an example of setting trackingAction property on a login button:

import vNext 

class LoginViewController: UIViewController {
    
    @IBOutlet private weak var loginButton: TrackingButton!

    override func viewDidLoad() {
        super.viewDidLoad()

		loginButton.trackingAction = .LoginAttempt

		// You can also create the button with code using any default or convenience initializer

		let signUpButton = TrackingButton()
		signUpButton.trackingAction = .SignUp
    }
}

Note: If you do not want a button to be tracked but it still overrides from TrackingButton for some reason, you can use the ButtonTrackingAction value of None which will prevent the button from being tracked.

Pickers

To track the time a UIPickerView element is present on a screen of your app, subclass TrackingPickerView from the UIPickerView class in Interface Builder or in your code.

Interface Builder

To use Interface Builder to implement picker tracking, follow the steps below for each of the UIPickerView objects in your application that you intend to track.

  1. Open the Identity Inspector for the UIPickerView object that you want to tag.

  2. Set the class of the UIPickerView element to TrackingPickerView, and set the Module to vNext as shown in the image below.

  3. In your code, set the fieldTag property to one of the values defined in the FieldTags.swift file. If you do not set the property to one of the specified values, it will cause a runtime error.

Code

To implement data collector for pickers using code, you must set the fieldTags property to one of the values defined in the FieldTags.swift enum.

The code below shows an example of setting the fieldTags property on an expiration date picker:

import vNext 

class YourViewController: UIViewController {
    
    @IBOutlet private weak var pickerView: TrackingPickerView!

    override func viewDidLoad() {
        super.viewDidLoad()

		pickerView.fieldTag = FieldTags.PurchaseCardExpirationDateMonth.rawValue

		// You can also create the button with code using any default or convenience initializer

		let anotherPickerView = TrackingPickerView()
		anotherPickerView.fieldTag = FieldTags.PurchaseCardExpirationDateYear.rawValue
    }
}

Active Screens

Active screen tracking tracks user navigation in your app, including the time a user enters and leaves each screen. Follow the steps below to implement screen tracking:

  1. Subclass your UIViewController from the EventsTrackerViewController class.
  2. Override the screenTag property and return a value defined in the ScreenTags.swift enum.

The code below provides an example of how to implement screen tracking:

import vNext 

class LoginViewController: EventsTrackerViewController {
    
    @IBOutlet private weak var loginButton: TrackingButton!

	override var screenTag: ScreenTags {
        return .Login
    }

    override func viewDidLoad() {
        super.viewDidLoad()

		loginButton.trackingAction = .LoginAttempt
	}
}

Track Shopping Cart Actions

Use the transactionEvent method to notify Vesta when your customer adds, updates, or removes items from the shopping cart. The trasactionEvent method takes product details, event type, and a completion handler as inputs and returns a transaction ID if the operation was successful.

The eventType parameter defines the cart action and takes one of the following values: add, update, or remove.

The code below shows adding an item to the cart:

let vestaManager = VestaManager()
vestaManager.transactionEvent(productCode: product.id, quantity: Cart.cartItem.count, normalAmount: product.productPrice, normalCurrencyCode: "USD", discountAmount: 0.0, discountCurrencyCode: "USD", giftCard: false, productType: "Virtual", uniqueCartID: "AIV90687S980SV", productDescription: product.productDescription, eventType: "add", completionHandler: {
  result in
  if !result.isEmpty {
    DispatchQueue.main.async {
      print("Transaction event == ", result)
    }
  }
})

Evaluate the Transaction

When your customer is ready to check out, use one of the transaction evaluation methods to obtain fraud analysis from Vesta. The results of the analysis depend on whether you are using Payment Guarantee or Payment Protect.

You can run one-step or two-step transaction evaluations.

One-step

For one-step transaction flows, send the transaction to your payment gateway for authorization, then use the completeTransactionPostAuth method to send transaction information to Vesta, as shown below:

if (authType == .OneStepPostAut) {
  let vesta = VestaManager()
  vesta.completeTransactionPostAuth(customData: [customData], uniqueCartID: "AIV90687S980SV", orderNumber: "70001", customerOrderStatus: "COMPLETE", totalAmount: totalAmout, discountAmount: discountAmount, payment: payments, shiping: [shiping], authType: authType, completionHandler: {
    result in

    self.showPostAuthResponse(result, authType: "OneStepPostAuth")
  })
}

func showPostAuthResponse(_ response: Result < vNext.CompleteTransactionResponse, vNext.ErrorModel > ) {

  switch response {
    case.success(let response):

      print("Post Auth EvaluationDecision = \(response.data?.evaluationDecision ?? "
        ")")
    print("Post Auth TransactionID = \(response.data?.transactionID ?? "
      ")")

    break

    case.failure(let error):
      print("Error Code =\(error.errorMessage ?? "
        ")")
    print("Error Message =\(error.errorMessage ?? "
      ")")
    break
  }
}

You will include the response from your payment gateway in the payment object in the parameters. Set the value of authType to OneStepPostAuth.

See the /transactions/evaluate/{transaction_id} definition in the API Reference for definitions of the values each parameter takes.

The result of the method depends on the Vesta product you are using:

  • Payment Guarantee - You will receive a Guaranteed or Not Guaranteed decision in the result. You can choose whether to submit the transaction to your gateway for payment. If you submit a transaction that is Not Guaranteed for payment, Vesta will not cover the cost of any associated chargeback.
  • Payment Protect - You will receive a score, insights, and a risk band, which you can use to determine whether to submit the transaction to your gateway for payment or cancel the transaction because it is too risky.

Two-step

For two-step transaction flows, submit the transaction to Vesta for analysis before submitting it to your gateway for authorization. Based on Vesta’s response, you can choose whether to submit the transaction for authorization. Once you have obtained an authorization decision from your gateway, submit the transaction to Vesta for analysis a second time, with the auth response included in the data. Vesta will return an updated decision that you can use to decide whether to submit the transaction for payment.

For the initial transaction analysis, use the completeTransactionPostAuthFallowedByPreAuth method, as shown below:

if authType == .PreAndPostAuth {
  let vesta = VestaManager()
  vesta.completeTransactionPostAuthFallowedByPreAuth(customData: [customData], uniqueCartID: "AIV90687S980SV", orderNumber: "90003", customerOrderStatus: "COMPLETE", totalAmount: totalAmout, discountAmount: discountAmount, payment: payments, shiping: [shiping], completionHandler: {
    (response) in

    switch response {
      case.success(let response):

        print("EvaluationDecision = \(response.data?.evaluationDecision ?? "
          ")")
      print("TransactionID = \(response.data?.transactionID ?? "
        ")")

      break

      case.failure(let error):
        print("Error Code =\(error.errorCode ?? "
          ")")
      print("Error Message =\(error.errorMessage ?? "
        ")")
            
      break
    }
  })
}

Set the authType to PreAndPostAuth.

See the /transactions/evaluate/{transaction_id} definition in the API Reference for definitions of the values each parameter takes.

The response depends on your subscription:

  • Payment Guarantee - You will receive a Guaranteeable or Not Guaranteed decision in the result. You can choose whether to submit the transaction to your gateway for authorization.
  • Payment Protect - You will receive a score, insights, and a risk band, which you can use to determine whether to submit the transaction to your gateway for authorization or cancel the transaction because it is too risky.

If you submit the transaction for authorization, call the completeTransactionPostAuthFallowedByPreAuth again and include the authorization response in the parameters to obtain an updated fraud analysis. Include the auth result in the payment object in the parameters.

The method will return an updated analysis result based on your subscription:

  • Payment Guarantee - You will receive a Guaranteed or Not Guaranteed decision in the result. You can choose whether to submit the transaction to your gateway for payment. If you submit a transaction that is Not Guaranteed for payment, Vesta will not cover the cost of any associated chargeback.
  • Payment Protect - You will receive an updated score, insights, and a risk band, which you can use to determine whether to submit the transaction to your gateway for payment or cancel the transaction because it is too risky.

Logs

When working with the Data Collector framework, logs are disabled by default. You can enable logs for each of the objects described in the sections above by setting the showLogs static variable to true. For TrackingTextField objects, you can enable and disable logs on a per object basis. The code below shows how to enable logs using the different approaches:

import DataCollector

// Enables logs for DataCollectorService
DataCollectorService.showLogs = true

// Enables logs for this TrackingTextField
let trackingTextField = TrackingTextField()
trackingTextField.showLogs = true

// Enables logs for ALL TrackingTextField instances (bypasses instance showLogs var)
TrackingTextField.showLogs = true

Tag reference

Field Tags

Field Tag Description
None (v1.4.0) Used to tag a field that should not be tracked, but that has been subclassed from the Vesta tracking class.
LoginID The user name field of your login form.
Password The password field of your login form.
ProductSearch The text field used to search for products.
AddToCart The button used to add a product to the shopping cart.
RemoveFromCart The button used to remove a product from the shopping cart.
TransferRecipient The text field used to identify the recipient of a transfer payment.
TransferSender The text field used to identify the sender of a transfer payment.
TransferToAccount The text field used to identify the account that will receive the funds from a transfer payment.
TransferAmount The text field used to define the amount of a transfer payment.
TransferDate The text field used to define the date that a transfer payment should be made.
BillingFirstName The text field used to collect the first name of the cardholder.
BillingLastName The text field used to collect the last name of the cardholder.
BillingAddressLine1 The text field used to collect the first line of the cardholder’s billing address.
BilllingAddressLine2 The text field used to collect the second line of the cardholder’s billing address.
BillingCity The text field used to collect the city portion of the cardholder’s billing address.
BillingRegion The text field used to collect the region of the cardholder’s billing address.
BillingPostalCode The text field used to collect the postal code of the cardholder’s billing address.
BillingCountryCode The text field used to collect the country code of the cardholder’s billing address.
PurchaseCardNumber The text field used to collect the customer’s payment card number.
PurchaseCardExpirationDateFull The text field used to collect the expiration date of the customer’s payment card.
PurchaseCardExpirationDateMonth The text field used to collect the month portion of the expiration date of the customer’s payment card.
PurchaseCardExpirationDateYear The text field used to collect the year portion of the expiration date of the customer’s payment card.
PurchaseCardCVV The text field used to collect the CVV number associated with the customer’s payment card.
PurchaseAlternateAccount The text field used to define an alternate payment method for the purchase.
DeliveryMethod The UI element used to select the shipping method.
DeliveryRecipient The text field used to collect the name of the person who will receive the shipment.

Tracking Actions

Tracking Action Description
None (v1.4.0) Used to tag a button that should not be tracked, but that has been subclassed from the Vesta tracking class.
LoginAttempt Start this event when your customer clicks the login button.
ForgotPassword Start this event when your customer clicks a button to attempt a password reset.
SignUp Start this event when your customer clicks the button for creating a new account.
SignUpAttempt Start this event when your customer clicks the button for creating a new account, but the credentials have not yet been validated.
Search Start this event when your customer activates the search field or clicks the button to perform a search.
AddToCart Start this event when your customer clicks the button to add a product to the shopping cart.
RemoveFromCart Start this event when your customer clicks the button to remove a product from the shopping card.
ShowCart Start this event when your customer clicks the button to view the contents of the shopping cart.
ProceedToCheckout Start this event when your customer clicks the button to begin the checkout process.
ConfirmPaymentMethod Start this event when your customer clicks the button to confirm the payment method.
ConfirmShippingMethod Start this event when your customer clicks the button to confirm the shipping method.
CompleteOrder Start this event when your customer clicks the button to complete the order.