ECP - iOS Framework

iOS Models/Methods/Delegates

Models

ECPDevice

PropertyTypeDescription
id_numberNSStringId (serial) number of device.
manufacturerNSStringManufacturer/brand of device.
modelNSStringModel of device.
battery_percentageNSStringBattery percentage of device between 0-100%.

ECPPaymentParameters

PropertyTypeDescription
amountNSNumberRequired. Amount to charge. Must be a positive number.
paymentDescriptionNSStringOptional. A string to be displayed on your customer’s credit card statement. This may be up to 22 characters. The statement descriptor must contain at least one letter, may not include <>"' characters, and will appear on your customer’s statement in capital letters. Non-ASCII characters are automatically stripped. While most banks and card issuers display this information consistently, some may display it incorrectly or not at all.
paymentDescriptionSuffixNSStringOptional. A string to specify details about the transaction so your customer can understand it clearly on their statement. The suffix is concatenated with the statementDescriptor, the * symbol, and a space to form the complete statement descriptor that your customer sees. Maximum 22 characters for the final concatenated descriptor.
currencyNSStringOptional. Default: "usd". Type of currency to be collected. Only USD supported at this time (default).
external_idNSStringOptional. <= 50 characters. Unique identifier for the payment in merchant or partner's system.
duplicate_checkNSStringWORLDPAY/EXPRESS ONLY Optional. Default:"enabled" Valid values: "enabled", "disabled". Indicates the duplicate check mode.
captureNSStringIDYNAMO ONLY Optional. Possible values: "completed_sale" "auth_until_capture" "tip_adjustment". 'completed_sale' (default) will authorize and capture the sale at the specified amount. 'auth_until_capture' requires the capture endpoint for the payment to be added to a settlement batch. 'tip_adjustment' allows for the tip_adjustment endpoint to be called up until just prior to the batch close time.
allow_partial_approvalsBOOLWORLDPAY/EXPRESS ONLY Optional. Default: FALSE. If true, allows partial approvals. Most useful for gift cards with limited funds.

ECPSdkEventConstants

Constants to be used to help consumers specify which events they would like to listen to when calling Initalize Sdk.

PropertyTypeValue
ALLNSString"ALL"
ECPConnectionChangedEventNSString"ECPConnectionChangedEvent"
ECPDeviceBatteryEventNSString"ECPDeviceBatteryEvent"
ECPDeviceCardEventNSString"ECPDeviceCardEvent"
ECPDeviceMessageEventNSString"ECPDeviceMessageEvent"
ECPDeviceConfigStatusEventNSString"ECPDeviceConfigStatusEvent"
ECPDeviceConfigProgressEventNSString"ECPDeviceConfigProgressEvent"

These string values will be accessible through the ECPSdkEventsConstants class. An example below shows creating a sample set of Events utilizing ECPSdkEventConstants.

 NSSet *events = [NSSet setWithObjects: ECPSdkEventConstants.ECPDeviceConfigStatusEvent, ECPSdkEventConstants.ECPDeviceConfigProgressEvent, ECPSdkEventConstants.ECPConnectionChangedEvent, ECPSdkEventConstants.ECPDeviceMessageEvent,
                                 ECPSdkEventConstants.ECPDeviceCardEvent, ECPSdkEventConstants.ECPDeviceBatteryEvent, nil];

ECPSaleResponse

PropertyTypeDescription
transaction_idNSStringUnique Id of transaction.
acqurier_messageNSStringAcquirer message returned. Do not base application logic on this message as it may change without notice.
authorization_codeNSStringAcquirer Authorization code.
approved_amountNSDecimalNumberAmount approved.
batch_idNSNumberSettlement batch id (card only). Value will be nil for Stripe processed payments.
cardECPCardDataCard response
outcomeECPSaleOutcomeSale outcome
emvECPEmvDataEMV response data if present
entry_modeNSStringEntry mode of transaction

ECPSaleOutcome

PropertyTypeDescription
resultNSStringResult of transaction request. Valid values "success", "failed", "declined"
codeNSString4-digit PaySimple result code.
outcome_descriptionNSDecimalNumberDescription of decline, failure or success.

ECPCardData

PropertyTypeDescription
card_brandNSStringCard brand type.
last4NSStringLast 4 digits of card number.
card_holder_nameNSStringName of cardholder
expiration_monthNSNumberMonth of card expiration
expiration_yearNSNumberYear of card expiration in 4 digit format.

ECPEmvData

PropertyTypeDescription
application_identifierNSStringApplication Identifier.
application_preferred_nameNSStringApplication Preferred Name.
application_labelNSStringApplication Label. Value will be nil for Stripe payments.
application_cryptogramNSStringCryptogram value.
authorization_response_codeNSStringAuthorization Response Code.
authorization_response_messageNSStringAuthorization Response Message.
is_pin_verifiedBOOLWhether or not the result is pin verified.

Client Token Block

Authorization via Client Token is required to use this SDK. In this SDK, we have introduced the concept of a Client Token Block which consumers will pass in to the Initialize Sdk method in order to ensure the SDK is able to associate and authenticate with the proper merchant/client.

Before integrating to our SDK, you should create an endpoint on your secure backend server which returns the proper PaySimple client token for a particular PaySimple user that you are trying to use this SDK with. How you map your application's users to a PaySimple user is up to you in your backend - you just need to be sure to use this Client Token Block to get a proper PaySimple token tied to the user you would like to utilize the SDK for each time you initialize. The type of authorization token currently supported will be https://documentation.paysimple.com/v2019/docs/authorization#client-token-authorization-rarely-used .

❗️

The client token code block you provide will then be called by our SDK as needed during various actions which require PaySimple authorization.

Here is a mock implementation of a Client Token Block to help get you started. Notice how in the failure flows for getting the token, completion handler is called with nil and an error. When you successfully fetch the token, the completion handler should be called with the token and a nil error.

Client Token Authorization Example

@property (nonatomic, copy) void (^userClientTokenBlock)(void (^completionHandler)(NSString *clientToken, NSError *error));

self.userClientTokenBlock = ^(void (^completionHandler)(NSString *clientToken, NSError *error)) {
        NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration];
        NSURLSession *session = [NSURLSession sessionWithConfiguration:config];
        
  			// When using Client Token Authorization strategy, your backend server should be using 
  			// https://api.paysimple.com/ps/auth/reseller_client_token endpoint to help generate
  			// the token. See https://documentation.paysimple.com/v2019/docs/authorization#client-token-authorization-rarely-used
        NSURL *url =  [ NSURL URLWithString:@"{CALL TO YOUR BACKEND URL FOR RESELLER AUTH ENDPOINT}"];
        
        NSMutableURLRequest *sampleRequest = [[NSMutableURLRequest alloc]initWithURL:url];
        
        sampleRequest.HTTPMethod = @"GET";
        
       // Make sure to add any authorization headers or any other authentication needed for your server prior to sending request
        
        NSURLSessionDataTask *task = [session dataTaskWithRequest:sampleRequest completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
            id jsonObject = nil;
            NSError *jsonSerializationError;
            if (data) {
                jsonObject = [NSJSONSerialization JSONObjectWithData:data options:(NSJSONReadingOptions)kNilOptions error:&jsonSerializationError];
            }
            else {
                NSError *error = [NSError errorWithDomain:@"com.test-app-ios.test"
                                                     code:1000
                                                 userInfo:@{NSLocalizedDescriptionKey: @"No data in response from API endpoint"}];
                completionHandler(nil, error);
                return;
            }
            if (!(jsonObject && [jsonObject isKindOfClass:[NSDictionary class]])) {
                completionHandler(nil, jsonSerializationError);
                return;
            }
            NSDictionary *json = (NSDictionary *)jsonObject;
            id token = json[@"token"];
            if (!(token && [token isKindOfClass:[NSString class]])) {
                NSError *error = [NSError errorWithDomain:@"com.test-app-ios.test"
                                                     code:2000
                                                 userInfo:@{NSLocalizedDescriptionKey: @"Missing `token` in JSON response"}];
                completionHandler(nil, error);
                return;
            }
            completionHandler((NSString *)token, nil);
        }];
        [task resume];
    };


After defining this client token block, you can then pass it into the Initialize SDK method. See below a sample call, on how we access this userClientTokenBlock variable which was created.

               [self.sharedECPSdk initializeSdk:env
									subscribedEvents:events
                  clientTokenBlock:self.userClientTokenBlock
                  completionHandler:^(BOOL isSdkInitialized, NSError *error) {}

Class Methods

Shared Instance

Returns a shared instance of the ECPSdk service. If you would like, you can store this in a variable to later be accessed by your class.

+ (ECPSdk *)sharedInstance;

Example Implementation:

@property (nonatomic, strong) ECPSdk *sharedECPSdk;

@implementation HomePageViewController


- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    self.sharedECPSdk = [ECPSdk sharedInstance];
}

// later on in another method, use this shared instance
- (void) callInitialized {

NSString *env = @"PROD";
self.userClientTokenBlock = [self codeToDefineAndSetUserClientTokenBlock];

NSSet *events = [NSSet setWithObjects: ECPSdkEventConstants.ECPDeviceConfigStatusEvent, ECPSdkEventConstants.ECPDeviceConfigProgressEvent, ECPSdkEventConstants.ECPConnectionChangedEvent, ECPSdkEventConstants.ECPDeviceMessageEvent,
                                 ECPSdkEventConstants.ECPDeviceCardEvent, ECPSdkEventConstants.ECPDeviceBatteryEvent, nil];


[self.sharedECPSdk initializeSdk:env
									 subscribedEvents:events
                    clientTokenBlock:self.userClientTokenBlock
                    completionHandler:^(BOOL isSdkInitialized, NSError *error) {
                          if(!isSdkInitialized {
                          //  SDK failed to initialize and report on error
                          } else {
                          // SDK is now officially initialized
                          }];.

}

Instance Methods

🚧

Important

As best practice, make sure the completion handler of one operation within the ECPSdk is called prior to attempting to execute an additional operation, to avoid unintended behavior.

Initialize SDK

Initializes the SDK. Provides a completion handler to determine the result of the SDK initialization. Returns YES if initialization occurred without error. Consumers must initialize the SDK prior to any other SDK actions. User must pass in environment, list of events they would like to subscribe to, and a Client Token Block

- (void) initializeSdk:(NSString *)environment
                subscribedEvents:(NSSet *)events
                clientTokenBlock:(void (^)(void (^)(NSString *clientToken, NSError *error)))fetchClientTokenBlock
                completionHandler:(void(^)(BOOL isSdkInitialized, NSError *error))handler;
PropertyTypeDescription
environmentNSStringRequired. Environment to use. Possible values: "SBX" for sandbox or "PROD" for production
subscribedEventsNSSetSet of events consumer would like to listen to. If a nil or empty set is passed in, by default user will subscribe to all events. ECPSdkEventConstants.ALL will also subscribe to all events, if it is present in the NSSet. If you only want to listen to specific events, please specify those events using ECPSdkEventConstants. For example, if you only wanted to listen to ECPDeviceMessageEvent and ECPConnectionChangedEvent, you would pass in a set as that has been initialized as follows:

NSSet *events = [NSSet setWithObjects: ECPSdkEventConstants.ECPDeviceMessageEvent, ECPSdkEventConstants.ECPConnectionChangedEvent, nil];
clientTokenBlockCode BlockRequired. Code block which returns a PaySimple client token and an error so the SDK can hook into your client/merchant. For more info and sample code block implementations, see the Client Token Block section.
completionHandlerCode BlockRequired. Upon execution passes back isSdkInitialized to provide information on the result of initialization. Also passes NSError reference to pass back error information in case of initialization issue.

Example Implementation:

@interface HomePageViewController()
@property (nonatomic, copy) void (^userClientTokenBlock)(void (^completionHandler)(NSString *clientToken, NSError *error));                

@implementation HomePageViewController()

// class methods here.....

(void)method1 {
 // ...
}

(void)method2 {
  // ...
}

(void) initializeECPSdk {
  
NSString *env = @"PROD";
self.userClientTokenBlock = [self methodToDefineAndSetUserClientTokenBlock];

NSSet *events = [NSSet setWithObjects: ECPSdkEventConstants.ECPDeviceConfigStatusEvent, ECPSdkEventConstants.ECPDeviceConfigProgressEvent, ECPSdkEventConstants.ECPConnectionChangedEvent, ECPSdkEventConstants.ECPDeviceMessageEvent,
                                 ECPSdkEventConstants.ECPDeviceCardEvent, ECPSdkEventConstants.ECPDeviceBatteryEvent, nil];

[self.sharedECPSdk initializeSdk:env
									 subscribedEvents:events
                    clientTokenBlock:self.userClientTokenBlock
                    completionHandler:^(BOOL isSdkInitialized, NSError *error) {
                          if(!isSdkInitialized) {
                          //  SDK failed to initialize and report on error
                          } else {
                          // SDK is now officially initialized
                          }];
                             
 }

Is Initialized

Returns BOOL to indicate if the SDK has been initialized.

- (BOOL)isInitialized

Example Implementation:

// somewhere in your class you have stored the sdk, accessing it via sharedECPSdk variable

if([self.sharedECPSdk isInitialized] {
	// follow up logic here
}

Reset SDK

Clears out SDK data. Clears processor data, client token block data, event initialization data, any data that was setup in Initialize SDK. Disconnects device. Allows consumer to start fresh with a reset instance of the SDK to help with changing users, clearing config.

- (void) resetSdk:(void(^)(BOOL isSdkReset, NSError *error))handler
PropertyTypeDescription
handlerCode BlockRequired. Upon execution passed back isSdkReset to provide information on the result of reset. Also passes NSError reference to pass back error information in case of initialization issue.

Example Implementation:

    [self.sharedECPSdk resetSdk:^(BOOL isSdkReset, NSError *error) {
        if(isSdkReset) {
	  	// SDK successfully reset, follow up code here
        }
        } else {
      // SDK not reset, follow up code here
        }
    }];

Discover Devices

Discovers devices powered on and within range of the iOS device to be used with the SDK. Currently only officially supported for Stripe M2 Reader device. If you have another brand of bluetooth reader turned on and in range, the discover devices may show the device. However, only Stripe M2 will currently work with Connect Device.

❗️

Mobile device settings warning (Stripe M2)

For the Stripe M2 Reader, do not use your own mobile device settings when pairing with an M2 reader using the SDK. Pairing the reader through your mobile device settings may make the reader unavailable to connect through our SDK. Please rely on our ECPSdk to help guide the connection process.

- (void) discoverDevices:(NSUInteger)scanTime completionHandler:(void(^)(NSArray<ECPDevice *> *, NSError *error))handler
PropertyTypeDescription
scanTimeNSUIntegerRequired. Amount of time in seconds you would like to attempt to scan to discover devices. If 0 is passed in, the scanTime will default to a value of 5.
completionHandlerCode BlockRequired. Indicates the discover process has finished. Upon execution passes back an array of ECPDevice to indicate devices that were successfully discovered. Also takes NSError to pass back any error information that occurs during the discover process.

Example Implementation:

    [self.sharedECPSdk discoverDevices:5 completionHandler:^(NSArray<ECPDevice *> *devices, NSError *error) {
        if ( devices.count > 0){
           // devices found. If you would like, you can continue and handle connection logic
          //  within here. Device info can be accessed on the devices array
        }
        else{
           // Handle error or no devices found here
        }
    }];

Connect Device

Currently only officially supported for Stripe M2 Reader device. Connects to the card reader device and prepares the device to take payments, fire off events, report information. A reader can only connect to one instance of the SDK at a time. Note - a reader may need to update on the connect process. If a reader needs to update, the reader will not finish the connect process until the update process completes. When trying to update, ensure your reader is charged greater than 50 percent. Monitor ECPDeviceConfigStatusEvent and ECPDeviceConfigProgressEvent to track update status. If an update fails upon connection to a reader, disconnect from the reader and try to connect again.

- (void) connectDevice:(ECPDevice *)device
        connectTimeout:(NSUInteger)timeout
completionHandler:(void(^)(BOOL isDeviceConnected, ECPDevice* device, NSError *error))handler
PropertyTypeDescription
ECPDeviceECPDeviceDevice object which you would like to attempt to connect to. This should be a recently discovered device from the Discover Devices method. Note - this device must be charged and turned on in order to connect.
connectTimeoutNSUIntegerRequired. Amount of time in approximate seconds that you would like to attempt the connect process. After this amount of time if the connect fails, the completion handler will be called with an error. If 0 is passed in, the connectTimeout will default to a value of 15 seconds.
completionHandlerCode BlockRequired. Indicates the connect process has finished. Upon execution passes back isDeviceConnected to indicate if a device connection was successful. Passes back ECPDevice object that was used for the connect process. Also takes NSError to pass back any error information that occurs during the discover process.

Example Implementation: See the example below. This example uses discover devices to discover available devices to use, and then as an example selects the first device in the devices array. The first device from the devices array is then passed into the connectDevice method. We then attempt to connect to the device.

    [self.sharedECPSdk discoverDevices:5 completionHandler:^(NSArray<ECPDevice *> *devices, NSError *error) {
        if ( devices.count > 0){
          // could use some sort of logic to determine which device to connect to.
          // for simplicity, here is an example selecting the first device that was
          // populated in the devices NSArray.
           ECPDevice * device = devices[0];
            [self.sharedECPSdk connectDevice:device connectTimeout:10 completionHandler:^(BOOL isDeviceConnected, ECPDevice *device, NSError *error) {
                    if (isDeviceConnected){
             	       // logic after device connected
                    }
                    else{
                     // logic after failed device connect
                    }
                }];
        }
        else{
           // Handle error or no devices found here
        }
    }];

Disconnect Device

Disconnects the currently connected device.

- (void) disconnectDevice:(void(^)(BOOL didDisconnect, NSError *error)) handler
PropertyTypeDescription
handlerCode BlockRequired. Upon execution passed back didDisconnect to provide information on result of disconnect. Also passes NSError reference to pass back error information in case of disconnect issue.

Example Implementation:

    [self.sharedECPSdk disconnectDevice:^(BOOL didDisconnect, NSError *error) {
        if(didDisconnect) {
				// device disconnected, perform disconnect logic
        } else {
				// disconnect failed, perform error handling logic for this scenario 
        }
    }];

Make Sale

Makes a sale for the amount specified. This requires that the SDK is initialized and that the Client Token Block above is set up correctly in order to retrieve a current client token for communication with PaySimple.

- (void) makeSale:(ECPPaymentParameters*) parameters completionHandler:(void(^)(ECPSaleResponse *saleResponse, NSError *error))handler
PropertyTypeDescription
parametersECPPaymentParametersRequired. The parameters used to create the payment.
completionHandlerCode BlockRequired. Upon execution passed back ECPSaleResponse to provide information about the payment including whether it was successful or failed. Also passes NSError reference to pass back error information in case of payment failure.

Example implementation:

ECPPaymentParameters* params = [[ECPPaymentParameters alloc]initWithAmount:amount];
    [params setPaymentDescription:@"test stmt descript"];
    [params setPaymentDescriptionSuffix:@"test suffix"];
    
    NSString *externalId = self.ExternalIdTextBox.text;
    [params setExternalId:externalId];
        
    [self.sharedECPSDK makeSale:params completionHandler:^(ECPSaleResponse *saleResponse, NSError *error) {
      if ([saleResponse.outcome.result isEqual: @"success"]){
            dispatch_async(dispatch_get_main_queue(), ^{
                [self.NotificationsLabel setText:@"payment succeeded"];
                NSLog(@"success");
                
            });
        }
        else{
            dispatch_async(dispatch_get_main_queue(), ^{
                [self.NotificationsLabel setText:@"payment declined/failed"];
                NSLog(@"payment failed: %@", error);
             
            });
        }
    }];

Stop Current Flow

Stops a payment from completing. This can be done before the payment method is collected. Once the payment method is collected, the payment flow will run to completion.

- (void)stopCurrentFlow: (void(^)(BOOL didCancel, NSError *error)) handler;
PropertyTypeDescription
handlerCode BlockRequired. Upon execution passes back didCancel to confirm that the flow was cancelled successfully. Also passes NSError reference to pass back error information in case of failure.

Example implementation:

- (IBAction)cancelPaymentButtonPressed:(id)sender
{
    [self.sharedECPSDK stopCurrentFlow:^(BOOL didCancel, NSError *error) {
        if (didCancel)
        {
            dispatch_async(dispatch_get_main_queue(), ^{
                [self.NotificationsLabel setText:@"payment cancelled successfully."];             
            });
        }
        else
        {
            dispatch_async(dispatch_get_main_queue(), ^{
                [self.NotificationsLabel setText:@"payment could not be cancelled."];
                NSLog(@"error cancelling payment: %@", error);
            });
        }
    }];
}

Get Device Info

Returns information about the connected device.

- (void)getDeviceInfo:(void(^)(BOOL isDeviceConnected, ECPDevice *device, NSError *error))handler
PropertyTypeDescription
handlerCode BlockRequired. Upon execution passed back isDeviceConnected to provide information on if a device is currently connected to the SDK. Passed back an ECPDevice object with up to date properties for the specific device. Also passes NSError reference to pass back error information in case of Get Device Info issue.

Example Implementation:

    [self.sharedECPSdk getDeviceInfo:^(BOOL isDeviceConnected, ECPDevice *device, NSError *error) {
            if(isDeviceConnected && device) {
               // Display device information using a UI label of your choosing.
               // you can access device properties on the device object. See example below:
                dispatch_async(dispatch_get_main_queue(), ^{
                    NSString *deviceInfo = [NSString stringWithFormat:@"GetDeviceInfo - id:%@, manufacturer:%@, model:%@, battery:%@, isDeviceConnected:%d", device.id_number, device.manufacturer, device.model, device.battery_percentage, isDeviceConnected];
                    [self.NotificationsLabel setText:deviceInfo];
                });
            } else {
                dispatch_async(dispatch_get_main_queue(), ^{
                    NSString *errorMessage = [NSString stringWithFormat:@"GetDeviceInfoError - %@", error.localizedFailureReason];
                    [self.NotificationsLabel setText:errorMessage];
                });
            }
        }];

Delegates / Events

The SDK provides an ECPSdkDelegate protocol to help expose delegate methods to report on SDK Events. Currently, the ECPSdkDelegate provides one optional method -(void)onDeviceEvent:(ECPSdkEvent *)event; . In order to use this protocol within your application and listen to delegates, please mark the class you would like to use the protocol/delegate in as implementing the interface. For example, if you would like to use the protocol/delegate on the home page view controller of your application, your class declaration may look as follows:

In HomePageViewController.h file:

	#import <UIKit/UIKit.h>
	#import <EverCommercePaymentsIosSdk/EverCommercePaymentsIosSdk.h>
	@interface HomePageViewController : UIViewController<ECPSdkDelegate>
  // continue class definition below ...

In HomePageViewController.m file, include the following delegate method:

	-(void)onDeviceEvent:(ECPSdkEvent *)event {
}

The SDK also has an id type accessible through sharedECPSdk.delegate which needs to be wired up for use, to make everything work properly. You can wire up the delegate for use by attaching and wiring up to the delegate through a line of code like or similar to below in the class(es) which utilize the ECPSdkDelegate protocol:

self.sharedECPSdk.delegate = self; 

ECPSdkEvent Types

A generic type of event will be used as the base class for SDK events. This type is represented by a base class of ECPSdkEvent.

ECPSdkEvent

PropertyTypeDescription
errorNSErrorIndicates any sort of error with ECPSdkEvent. If this property is not nil, there is an error on the ECPSdkEvent object, and error handling logic should be utilized, as the SDK will not have proper information on the SDK event objects.

👍

Different subclasses of ECPSdkEvent will be utilized to represent different events. These classes are represented in the charts below.

ECPConnectionChangedEvent

Event that fires when a device connection status change is reported.

PropertyTypeDescription
connection_statusNS_ENUM (ECPConnectionChangeStatus)Indicates connection status of device. This enum can have the following potential enumvalues. These enum values are accessible to you as part of the ECPSdk:
ECP_CONNECTION_STATUS_NOT_CONNECTED, ECP_CONNECTION_STATUS_CONNECTED,
ECP_CONNECTION_STATUS_CONNECTING .

ECPDeviceBatteryEvent

Event that fires when a battery event is reported.

PropertyTypeDescription
battery_statusNS_ENUM (ECPBatteryEventStatus)Indicates the type of battery status event that took place. These enum values are accessible to you as part of the ECPSdk:
ECP_BATTERY_EVENT_LOW

ECPDeviceCardEvent

Event that fires when a card is inserted or removed.

PropertyTypeDescription
event_statusNS_ENUM (ECPCardEventStatus)Indicates the type of device card event that took place. This enum can have the following potential values. These enum values are accessible to you as part of the ECPSdk:
ECP_CARD_EVENT_INSERTED,
ECP_CARD_EVENT_REMOVED

ECPDeviceMessageEvent

Event that fires when a device attempts to prompt a user.

PropertyTypeDescription
promptMessageNSStringIndicates that a message should be displayed to the user. (I.e. Insert Card, Remove Card, Try Again, Retry Card, etc.)
inputMessageNSStringIndicated that the reader is waiting for input. Your app should prompt the customer to present a payment method using one of the given input options.

ECPDeviceConfigStatusEvent

Event that fires when a config event takes place from a device. Note - on a config update event some readers may be unusable until required updates are completed.

PropertyTypeDescription
event_statusNS_ENUM (ECPDeviceConfigEventStatus)Indicates the type of config event that took place. This enum can have the following potential values. These enum values are accessible to you as part of the ECPSdk:
ECP_CONFIG_EVENT_UPDATE_STARTED,
ECP_CONFIG_EVENT_UPDATE_FINISHED

ECPDeviceConfigProgressEvent

Event that fires to report on config event progress.

PropertyTypeDescription
progressfloatIndicates the progress of a config event in the range of 0-100.

onDeviceEvent - Optional Delegate

Delegate fires when one of the subclasses of ECPSdkEvent is reported from the SDK and the SDK consumer has chosen to subscribe to the particular event. See ECPSdkEventConstants and the subscribedEvents parameter in Initialize Sdk for how to specify which events you would like to subscribe to.

-(void)onDeviceEvent:(ECPSdkEvent *)event
PropertyTypeDescription
eventECPSdkEventGeneric type of event which will have a specific subclass type which one can use to handle events.

Example Implementation: See the below code block for sample implementation of listening and reporting on device events. This particular example uses if else statements and class type to determine the type of ECPSdkEvent that came through. Consumers are free to determine their own best practice for their particular use case to determine the type of ECPSdkEvent, below is just one example. Consumers can then utilize the specific event type that is known to exist and access event specific information to utilize in their application.

🚧

Important: If you are utilizing information in delegates to update UI, please follow best practices and dispatch UI changes to the main thread.

-(void)onDeviceEvent:(ECPSdkEvent *)event {
    __weak typeof(self) weakSelf = self;
    __strong typeof(self) strongSelf = weakSelf;
    if([event isKindOfClass:[ECPDeviceConfigStatusEvent class]]) {
        ECPDeviceConfigStatusEvent *statusEvent = (ECPDeviceConfigStatusEvent*)event;
        if(statusEvent.error) {
            NSString *error = [NSString stringWithFormat:@"Logging error: %@", [statusEvent.error localizedDescription]];
            dispatch_async(dispatch_get_main_queue(), ^{
                [strongSelf.DelegatesLabel setText:error];
            });
        } else {
            NSString *configStatus = [NSString stringWithFormat:@"Reporting config event enum: %lu", (unsigned long)statusEvent.event_status];
            dispatch_async(dispatch_get_main_queue(), ^{
                [strongSelf.DelegatesLabel setText:configStatus];
            });
        }
    } else if([event isKindOfClass:[ECPDeviceConfigProgressEvent class]]) {
        ECPDeviceConfigProgressEvent *progressEvent = (ECPDeviceConfigProgressEvent*)event;
        NSString *configProgress = [NSString stringWithFormat:@"Reporting config progress event %f", progressEvent.progress];
        dispatch_async(dispatch_get_main_queue(), ^{
            [strongSelf.DelegatesLabel setText:configProgress];
        });
    } else if([event isKindOfClass:[ECPConnectionChangedEvent class]]) {
        ECPConnectionChangedEvent *connectionEvent = (ECPConnectionChangedEvent*)event;
        switch(connectionEvent.connection_status) {
            case ECP_CONNECTION_STATUS_CONNECTED: {
                dispatch_async(dispatch_get_main_queue(), ^{
                    [strongSelf.DelegatesLabel setText:@"ConnectionChangedEvent - CONNECTED!"];
                });
                break;
            }
            case ECP_CONNECTION_STATUS_CONNECTING: {
                dispatch_async(dispatch_get_main_queue(), ^{
                    [strongSelf.DelegatesLabel setText:@"ConnectionChangedEvent - CONNECTING!"];
                });
                break;
            }
            case ECP_CONNECTION_STATUS_NOT_CONNECTED: {
                dispatch_async(dispatch_get_main_queue(), ^{
                    [strongSelf.DelegatesLabel setText:@"ConnectionChangedEvent - NOT_CONNECTED!"];
                });
                break;
            }
            default:
                break;
        }
    } else if([event isKindOfClass:[ECPDeviceBatteryEvent class]]) {
        ECPDeviceBatteryEvent *batteryEvent = (ECPDeviceBatteryEvent*)event;
        NSMutableString *batteryInfo;
        if(batteryEvent.battery_status == ECP_BATTERY_EVENT_LOW) {
            batteryInfo = [NSMutableString stringWithString:@"DeviceBatteryEvent - Low"];
            dispatch_async(dispatch_get_main_queue(), ^{
                [strongSelf.DelegatesLabel setText:batteryInfo];
            });
        }
    }  else if([event isKindOfClass:[ECPDeviceMessageEvent class]]) {
        ECPDeviceMessageEvent *promptEvent = (ECPDeviceMessageEvent*)event;
        if ([promptEvent.inputMessage length] != 0)
        {
            NSString *message = [NSString stringWithFormat:@"Display: %@", promptEvent.inputMessage];
            dispatch_async(dispatch_get_main_queue(), ^{
                [strongSelf.InputMessage setText:message];
            });
        }
        
        if ([promptEvent.promptMessage length] != 0)
        {
            NSString *message = [NSString stringWithFormat:@"Display: %@", promptEvent.promptMessage];
            dispatch_async(dispatch_get_main_queue(), ^{
                [strongSelf.delegatesLabel setText:message];
            });
        }
    } else if([event isKindOfClass:[ECPDeviceCardEvent class]]) {
        ECPDeviceCardEvent *deviceCardEvent = (ECPDeviceCardEvent*)event;
        NSMutableString *message;
        if(deviceCardEvent.event_status == ECP_CARD_EVENT_REMOVED) {
            message =  [NSMutableString stringWithString:@"DeviceCardEvent - REMOVED"];
            dispatch_async(dispatch_get_main_queue(), ^{
                [strongSelf.cardDelegateLabel setText:message];
            });
        }else if(deviceCardEvent.event_status == ECP_CARD_EVENT_INSERTED) {
            message = [NSMutableString stringWithString:@"DeviceCardEvent - INSERTED"];
            dispatch_async(dispatch_get_main_queue(), ^{
                [strongSelf.cardDelegateLabel setText:message];
            });
        }
    }
}