iOS 13+ POS SDK updated implementation

Tyro now provides a production ready, integration library for iOS. The library is essentially a thin wrapper around our iClient JavaScript library for Web based POSs

The original Tyro iOS SDK is based on UIWebViews which are no longer supported by iOS, new application submissions to the iOS app store are no longer accepted and application updates were blocked in December 2020.

The new implementation uses WKWebviews, to implement the changes a new Tyro ios framework will need to be added to the POS application. There are no changes to how a transaction is initiated or the underlining Javascript library/API.

Before you begin the development work, please have a look at the certification criteria, which provide a checklist of the minimum requirements for this certification with Tyro.

Certification Criteria Document

The example project in the zip file below contains a demo of how to implement the new framework.

POS-Simulator

For just the frame work download this zip file:

TyroClientuniversal Framework

The below Zip file contains API docs. Unzip it, and inside the doc folder there is an index.html file. Open it and on the left side is TYRO.IClientEmbedded which is the doc for iOS integration. iClient API docs

Before you begin, please take a look at the certification criteria, which provide a checklist of the minimum requirements for the certification of Integrated EFTPOS features with Tyro.

Certification Criteria Document

Objective-C purchase example:

The main changes that will be need to be made are how to initiate the webView.

WKWebView SDK:

Copy
Copied
#import <TyroClientUniversal/TyroClient.h>
#import "PaymentsViewController.h"
#import "PosConfiguration.h"

@interface PaymentsViewController ()

@property(weak, nonatomic) IBOutlet UITextField *amountField;
@property(weak, nonatomic) IBOutlet UITextField *cashoutAmountField;
@property(weak, nonatomic) IBOutlet UITextField *refundAmountField;
@property(weak, nonatomic) IBOutlet UITextField *openTabAmountField;
@property(weak, nonatomic) IBOutlet UITextField *closeTabAmountField;
@property(weak, nonatomic) IBOutlet UITextField *closeTabCompletionReferenceField;
@property(weak, nonatomic) IBOutlet UITextField *voidTabCompletionReferenceField;

@property(strong, nonatomic) IBOutlet WKWebView *mainWebView;
@property(weak, nonatomic) IBOutlet UITextView *merchantReceiptTextView;
@property(weak, nonatomic) IBOutlet UITextView *customerReceiptTextView;

@property(nonatomic, strong) PosConfiguration *posConfiguration;
@property(nonatomic, strong) TyroClient *client;
@property (weak, nonatomic) IBOutlet UISwitch *enableSurcharge;

@end

@implementation PaymentsViewController

- (void) viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    self.posConfiguration = [PosConfiguration sharedInstance];
    
    WKPreferences * preferences = [[WKPreferences alloc] init];
    preferences.javaScriptEnabled = true;
    WKWebViewConfiguration* configuration = [[WKWebViewConfiguration alloc] init];
    configuration.preferences = preferences;
    self.mainWebView = [[WKWebView alloc] initWithFrame:self.mainWebView.frame configuration:configuration];
    
    [self.view addSubview:self.mainWebView];

    self.client = [[TyroClient alloc] initWithWebView:self.mainWebView
                                      webViewDelegate:self
                                               apiKey:self.posConfiguration.apiKey
                                     posProductVendor:self.posConfiguration.posProductVendor
                                       posProductName:self.posConfiguration.posProductName
                                    posProductVersion:self.posConfiguration.posProductVersion];
    
    self.client.baseUrl = self.posConfiguration.iclientBaseUrl;
}

UIWebView SDK:

Copy
Copied
#import <TyroClientUniversal/TyroClient.h>
#import "PaymentsViewController.h"
#import "PosConfiguration.h"

@interface PaymentsViewController ()

@property(weak, nonatomic) IBOutlet UITextField *amountField;
@property(weak, nonatomic) IBOutlet UITextField *cashoutAmountField;
@property(weak, nonatomic) IBOutlet UITextField *refundAmountField;
@property(weak, nonatomic) IBOutlet UITextField *openTabAmountField;
@property(weak, nonatomic) IBOutlet UITextField *closeTabAmountField;
@property(weak, nonatomic) IBOutlet UITextField *closeTabCompletionReferenceField;
@property(weak, nonatomic) IBOutlet UITextField *voidTabCompletionReferenceField;

@property(strong, nonatomic) IBOutlet UIWebView *mainWebView;
@property(weak, nonatomic) IBOutlet UITextView *merchantReceiptTextView;
@property(weak, nonatomic) IBOutlet UITextView *customerReceiptTextView;

@property(nonatomic, strong) PosConfiguration *posConfiguration;
@property(nonatomic, strong) TyroClient *client;

@end

@implementation PaymentsViewController

- (void) viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    self.posConfiguration = [PosConfiguration sharedInstance];
    self.mainWebView = [[UIWebView alloc] initWithFrame:self.mainWebView.frame];
    [self.view addSubview:self.mainWebView];

    self.client = [[TyroClient alloc] initWithWebView:self.mainWebView
                                      webViewDelegate:self
                                               apiKey:self.posConfiguration.apiKey
                                     posProductVendor:self.posConfiguration.posProductVendor
                                       posProductName:self.posConfiguration.posProductName
                                    posProductVersion:self.posConfiguration.posProductVersion];
    
    self.client.baseUrl = self.posConfiguration.iclientBaseUrl;
}

Initiating a transaction remains the same:

Copy
Copied
- (IBAction)initiatePurchase {
    [self.amountField resignFirstResponder];
    [self clearReceipts];

    NSDictionary *parameters = @{
            @"amount" : self.amountField.text,
            @"cashout" : self.cashoutAmountField.text,
            @"integratedReceipt" : self.posConfiguration.integratedReceipt ? @"true" : @"false"};

    if ([self.amountField.text isEqualToString:@"error"]) {
        [self.client performOperation:@"invalid-operation"
                           parameters:parameters
              receiptReceivedCallback:[self receiptReceivedCallback]
          transactionCompleteCallback:[self transactionCompleteCallback]];
    } else {
        [self.client performOperation:@"purchase"
                           parameters:parameters
              receiptReceivedCallback:[self receiptReceivedCallback]
          transactionCompleteCallback:[self transactionCompleteCallback]];
    }
}

Headless Pairing

Using the pairTerminal(mid, tid) function is compulsory when implementing the iOS SDK with your POS. This function will establish the connection with the terminal where you will be able to receive the integration key and store it in memory.

Parameters:

  • mid (type String) - Tyro Merchant ID (MID)
  • tid (type String) - Tyro Terminal ID (TID)

Example:

Copy
Copied
[self.client performOperation: @"pairTerminal" parameters: @{@"mid" : @"22323", @"tid": @"3" } receiptReceivedCallback: nil transactionCompleteCallback: ^(NSDictionary *result) {NSLog(@"Paired terminal: %@", result);}];
important

The POS must display the "status" and "message" fields on the POS UI gracefully. The POS must store the MID number, TID number, and integration key in the database of their POS app and pass them when processing a transaction.

info

For further information on WKWebView functionality please see apple documentation

Copyright © Tyro Payments 2019-2022. All right reserved.