# Workflow

## Overview

{% tabs %}
{% tab title="In Scope" %}

* [Swift - SwiftUI](#swift-swiftui)
* [Swift - Storyboard](#swift-storyboard)
* [Objective C - Storyboard](#objective-c-storyboard)
  {% endtab %}

{% tab title="Out of Scope" %}

* [Swift - SwiftUI](#swift-swiftui-2)
* [Swift - Storyboard](#swift-storyboard-2)
* [Objective C - Storyboard](#objective-c-storyboard-2)
  {% endtab %}

{% tab title="Custom UI" %}
Coming soon.
{% endtab %}
{% endtabs %}

## Workflow Examples

{% tabs %}
{% tab title="In Scope Examples" %}
Example 1: [Swift, Storyboard, cc:sale](#in-scope-example-1)

Example 2: [Objective C, Storyboard, cc:refund](#in-scope-example-2)
{% endtab %}

{% tab title="Out of Scope Examples" %}
Example 1: [Swift, Storyboard, cc:sale](#out-of-scope-example-1)

Example 2: [Objective C, Storyboard, cc:sale](#out-of-scope-example-2)
{% endtab %}
{% endtabs %}

## In Scope

### Swift - SwiftUI

To submit a <mark style="color:red;">**\<xCommand>**</mark> request, first configure the SDK with:

* an xKey value obtained from Cardknox
* a software name value; a short name for your application
* a software version value; the current version of your software
* a version value; the current Cardknox Gateway version 4.5.9

{% code overflow="wrap" lineNumbers="true" %}

```
CardknoxSDK.setPrincipalKey("Your xKey value");
CardknoxSDK.setxSoftwareName("Your app name", xSoftwareVersion: "1.0.0", xVersion: "4.5.9");
```

{% endcode %}

Create a Cardknox SDK object. A good place is the “view appear” method. This object will be used to create “request” objects.

{% code overflow="wrap" lineNumbers="true" %}

```
func viewDidAppear()
{
  // Example of a "view appear" method in a SwiftUI View
  // Store the object instance as a @State in the View for later use
  let cardknoxSDKDirect = CardknoxSDKDirect.create() as? CardknoxSDKDirect;
}
```

{% endcode %}

Register the “view appear” method with the “body” parameter

```
struct InScopeView : View
{
  var body: some View
  {
    // Using NavigationView as a View example
    NavigationView{}
    .onAppear(perform: viewDidAppear)
  }
}
```

Destroy the Cardknox SDK object to free resources when SDK will no longer be used:

{% code lineNumbers="true" %}

```
cardknoxSDKDirect.destroy();
```

{% endcode %}

Next, create a transaction parameters object:

{% code overflow="wrap" lineNumbers="true" %}

```
let prms : TransactionParameters = TransactionParameters.init()
```

{% endcode %}

Specify the required parameters:

{% code lineNumbers="true" %}

```
prms.xCommand = "<xCommand>";
prms.xAmount = 1.23;
```

{% endcode %}

<mark style="color:red;">**CHANGE \<xCommand>**</mark>

Specify the additional parameters for the <mark style="color:red;">**\<xCommand>**</mark> transaction type:

**If selected Transaction type is&#x20;**<mark style="color:red;">**cc:sale, cc:credit, cc:authonly**</mark>

{% code lineNumbers="true" %}

```
prms.xCardNum = "4444333322221111";
prms.xExpDate = "1225"; // MMYY
```

{% endcode %}

**If selected Transaction type is&#x20;**<mark style="color:red;">**cc:capture**</mark>

{% code overflow="wrap" lineNumbers="true" %}

```
prms.xRefNum = "123456789";
```

{% endcode %}

Specify optional parameters, if any:

{% code overflow="wrap" lineNumbers="true" %}

```
prms.xInvoice = "123456";
prms.xBillFirstName = "Billing first name";
// ... etc. 
```

{% endcode %}

Create a request object, check if the request object is valid, initiate a transaction & process the response:

{% code overflow="wrap" lineNumbers="true" %}

```
let request = cardknoxSDKDirect.createRequest(withParameters: prms) as! PaymentTransactionRequestDirect;

if(request.isValid)
{
  let respone = request.process() as! PaymentTransactionResponse
  
  if(response.isSuccess())
  {
    let refNum = respone.xRefNum();
    let status = respone.xStatus();
    let avs = respone.xAvsResult();
  }
  else
  {
    let refNum = response.xRefNum();
    let error = response.xError()!
    let errorCode = response.xErrorCode()!;
  }
}
else
{
  // Request could not be processed due to these errors
  let errors = request.validationErrors!
}
```

{% endcode %}

### Swift - Storyboard

To submit a <mark style="color:red;">**\<xCommand>**</mark> request, first configure the SDK with:

* an xKey value obtained from Cardknox
* a software name value; a short name for your application
* a software version value; the current version of your software
* a version value; the current Cardknox Gateway version 4.5.9

{% code overflow="wrap" lineNumbers="true" %}

```
CardknoxSDK.setPrincipalKey("Your xKey value");
CardknoxSDK.setxSoftwareName("Your app name", xSoftwareVersion: "1.0.0", xVersion: "4.5.9");
```

{% endcode %}

Create a Cardknox SDK object. A good place is the “view appear” method. This object will be used to create “request” objects.

{% code overflow="wrap" lineNumbers="true" %}

```
override func viewDidAppear(_ animated: Bool) 
{
  super.viewDidAppear(animated)
  let cardknoxSDKDirect = CardknoxSDKDirect.create() as? CardknoxSDKDirect
}
```

{% endcode %}

Destroy the Cardknox SDK object to free resources when SDK will no longer be used:

{% code lineNumbers="true" %}

```
cardknoxSDKDirect.destroy();
```

{% endcode %}

Next, create a transaction parameters object:

{% code lineNumbers="true" %}

```
let prms = TransactionParameters();
```

{% endcode %}

Specify the required parameters:

{% code lineNumbers="true" %}

```
prms.xCommand = "<xCommand>";
prms.xAmount = 1.23;
```

{% endcode %}

<mark style="color:red;">**CHANGE \<xCommand>**</mark>

Specify the additional parameters for the <mark style="color:red;">**\<xCommand>**</mark> transaction type:

**If selected Transaction type is&#x20;**<mark style="color:red;">**cc:sale, cc:credit, cc:authonly**</mark>

{% code lineNumbers="true" %}

```
prms.xCardNum = "4444333322221111";
prms.xExpDate = "1225"; // MMYY
```

{% endcode %}

**If selected Transaction type is&#x20;**<mark style="color:red;">**cc:capture**</mark>

{% code overflow="wrap" lineNumbers="true" %}

```
prms.xRefNum = "123456789";
```

{% endcode %}

Specify optional parameters, if any:

{% code overflow="wrap" lineNumbers="true" %}

```
prms.xInvoice = "123456";
prms.xBillFirstName = "Billing first name";
// ... etc. 
```

{% endcode %}

Create a request object, check if the request object is valid, initiate a transaction & process the response:

{% code overflow="wrap" lineNumbers="true" %}

```
let request = cardknoxSDKDirect.createRequest(withParameters: prms) as! PaymentTransactionRequestDirect;

if(request.isValid)
{
  let respone = request.process() as! PaymentTransactionResponse
  
  if(response.isSuccess())
  {
    let refNum = respone.xRefNum();
    let status = respone.xStatus();
    let avs = respone.xAvsResult();
  }
  else
  {
    let refNum = response.xRefNum();
    let error = response.xError()!
    let errorCode = response.xErrorCode()!;
  }
}
else
{
  // Request could not be processed due to these errors
  let errors = request.validationErrors!
}
```

{% endcode %}

### Objective C - Storyboard

To submit a <mark style="color:red;">**\<xCommand>**</mark> request, first configure the SDK with:

* an xKey value obtained from Cardknox
* a software name value; a short name for your application
* a software version value; the current version of your software
* a version value; the current Cardknox Gateway version 4.5.9

{% code overflow="wrap" lineNumbers="true" %}

```
[CardknoxSDK setPrincipalKey:@"Your xKey"];
[CardknoxSDK setxSoftwareName:@"Your app name" xSoftwareVersion:@"1.0.0" xVersion:@"4.5.9"];
```

{% endcode %}

Create a Cardknox SDK object. A good place is the “view appear” method. This object will be used to create “request” objects.

{% code overflow="wrap" lineNumbers="true" %}

```
- (void)viewDidAppear:(BOOL)animated
{
  [super viewDidAppear:animated];
  CardknoxSDKDirect* cardknoxSDKDirect = [CardknoxSDKDirect create];
}
```

{% endcode %}

Destroy the Cardknox SDK object to free resources when SDK will no longer be used:

{% code lineNumbers="true" %}

```
[cardknoxSDKDirect destroy];
```

{% endcode %}

Next, create a transaction parameters object:

{% code overflow="wrap" lineNumbers="true" %}

```
TransactionParameters *prms =[[TransactionParameters alloc] init];
```

{% endcode %}

Specify the required parameters:

{% code lineNumbers="true" %}

```
prms.xCommand = @"<xCommand>";
prms.xAmount = 1.23;
```

{% endcode %}

<mark style="color:red;">**CHANGE \<xCommand>**</mark>

Specify the additional parameters for the <mark style="color:red;">**\<xCommand>**</mark> transaction type:

**If selected Transaction type is&#x20;**<mark style="color:red;">**cc:sale, cc:credit, cc:authonly**</mark>

{% code lineNumbers="true" %}

```
prms.xCardNum = @"4444333322221111";
prms.xExpDate = @"1225"; // MMYY
```

{% endcode %}

**If selected Transaction type is&#x20;**<mark style="color:red;">**cc:capture**</mark>

{% code overflow="wrap" lineNumbers="true" %}

```
prms.xRefNum = @"123456789";
```

{% endcode %}

Specify optional parameters, if any:

{% code overflow="wrap" lineNumbers="true" %}

```
prms.xInvoice = @"123456";
prms.xBillFirstName = @"Billing first name";
// ... etc. 
```

{% endcode %}

Create a request object, check if the request object is valid, initiate a transaction & process the response:

{% code overflow="wrap" lineNumbers="true" %}

```
PaymentTransactionRequestDirect *request = [cardknoxSDKDirect createRequestWithParameters:prms];

if([request IsValid])
{
  PaymentTransactionResponse * response = [request process];
 
  if(response.isSuccess)
  {
    NSString* refNum = response.xRefNum;
    NSString* status = response.xStatus;
    NSString* avs = response.xAvsResult; 
  }
  else
  {
    NSString* refNum = response.xRefNum;
    NSString* error = response.xError;
    NSString* errorCode = response.xErrorCode;
  } 
}
else
{
  // Request could not be processed due to these errors
  NSArray* errors = request.ValidationErrors;
}
```

{% endcode %}

## Out of Scope

### Swift - SwiftUI 2

To submit a <mark style="color:red;">**\<xCommand>**</mark> request, first configure the SDK with:

* an xKey value obtained from Cardknox
* a software name value; a short name for your application
* a software version value; the current version of your software
* a version value; the current Cardknox Gateway version 4.5.9

{% code overflow="wrap" lineNumbers="true" %}

```
CardknoxSDK.setPrincipalKey("Your xKey value");
CardknoxSDK.setxSoftwareName("Your app name", xSoftwareVersion: "1.0.0", xVersion: "4.5.9");
```

{% endcode %}

Create a Cardknox SDK object. A good place is the “view appear” method. This object will be used to create “request” objects.

{% code overflow="wrap" lineNumbers="true" %}

```
func viewDidAppear()
{
  // Example of a "view appear" method in a SwiftUI View
  // Store the object instance as a @State in the View for later use
  let cardknoxSDKUI = CardknoxSDKUI.create() as? CardknoxSDKUI
}
```

{% endcode %}

Register the “view appear” method with the “body” parameterde

{% code overflow="wrap" lineNumbers="true" %}

```
struct OutOfScopeView : View
{
  var body: some View
  {
    // Using NavigationView as a View example
    NavigationView{}
    .onAppear(perform: viewDidAppear)
  }
}
```

{% endcode %}

Destroy the Cardknox SDK object to free resources when SDK will no longer be used:

{% code lineNumbers="true" %}

```
cardknoxSDKDirect.destroy();
```

{% endcode %}

Define a Publisher object that will deliver processed Transaction results in a Notification:

{% code overflow="wrap" lineNumbers="true" %}

```
let transactionResultSubscription =
NotificationCenter.default.publisher(for: NSNotification.Name(CardknoxSDK.transactionResultSubscription_NSNotificationCenterName()))
```

{% endcode %}

Define a Publisher object that will deliver Notifications about various card reader event taking place in the SDK:

{% code overflow="wrap" lineNumbers="true" %}

```
let cardreaderEventSubscription =
    NotificationCenter.default.publisher(for: NSNotification.Name(CardknoxSDK.cardreaderEventSubscription_NSNotificationCenterName()))
```

{% endcode %}

Define a method to run when the SDK processes a transaction and sends the processing results back:

{% code overflow="wrap" lineNumbers="true" %}

```
func transactionResultSubscription(aNotification: Notification)
{
    let response = PaymentTransactionResponse.unwrap(aNotification) as! PaymentTransactionResponse
    
    var message = ""
    if(response.isSuccess())
    {
        let refNum = response.xRefNum()!
        message = "Transaction success response! Ref num: " + refNum
    }
    else
    {
        let error = response.errorMessage()!
        message = "Transaction error response - " + error
    }
}
```

{% endcode %}

Afterwards, subscribe the method to receive results back from the SDK:

{% code overflow="wrap" lineNumbers="true" %}

```
struct OutOfScopeView : View
{
  var body: some View
  {
    // Using NavigationView as a View example
    NavigationView{}
    .onReceive(transactionResultSubscriptionPublisher, perform:  transactionResultSubscription(aNotification:))
  }
}
```

{% endcode %}

SDK works with a card reader to accept a card. Various card reader events can happen during processing. Define a method to run whenever a new card reader event happens:

{% code overflow="wrap" lineNumbers="true" %}

```
func cardreaderEventSubscription(aNotification: Notification)
{
  let callback = CardknoxCardReaderCallback.unwrap(aNotification) as? CardknoxCardReaderCallback
  
  let code = callback?.code()
  let name = callback?.name()
  
  var errorMessage : String?;
  if(code == CardknoxCardReaderCallbackType.error()){
      errorMessage = callback?.message();
  }
}
```

{% endcode %}

Afterwards, subscribe the method to be notified about card reader events:

{% code overflow="wrap" lineNumbers="true" %}

```
struct OutOfScopeView : View
{
  var body: some View
  {
    // Using NavigationView as a View example
    NavigationView{}
    .onReceive(cardreaderEventSubscriptionPublisher, perform: cardreaderEventSubscription(aNotification:))
  }
}
```

{% endcode %}

Next, create a transaction parameters object:

{% code lineNumbers="true" %}

```
let prms = TransactionParameters();
```

{% endcode %}

Specify the required parameters:

{% code overflow="wrap" lineNumbers="true" %}

```
prms.xCommand = "<xCommand>";
prms.xAmount = 1.23;
```

{% endcode %}

<mark style="color:red;">**CHANGE \<xCommand> to value from Transaction Type dropdown**</mark>

Specify optional parameters, if any:

{% code overflow="wrap" lineNumbers="true" %}

```
prms.xInvoice = "123456";
prms.xBillFirstName = "Billing first name";
// ... etc. 
```

{% endcode %}

Create a request object, check if the request object is valid, initiate a transaction & process the response:

{% code overflow="wrap" lineNumbers="true" %}

```
// Define if a 'keyed' screen is available
CardknoxSDKUI.setEnableKeyedEntry(true);
// Define if a 'swipe' screen is available
CardknoxSDKUI.setEnableDeviceInsertSwipeTap(true);
// Define if the UI should auto close
CardknoxSDKUI.setCloseOnProcessedTransaction(true);

let request = cardknoxSDKUI.createRequest(withParameters: prms) as! PaymentTransactionRequestUI
if(request.isValid)
{
  // Show the Cardknox UI
  request.process()
}
else
{
  // Request could not be processed due to these errors
  let errors = request.validationErrors!
}
```

{% endcode %}

### Swift - Storyboard 2

To submit a <mark style="color:red;">**\<xCommand>**</mark> request, first configure the SDK with:

* an xKey value obtained from Cardknox
* a software name value; a short name for your application
* a software version value; the current version of your software
* a version value; the current Cardknox Gateway version 4.5.9

{% code overflow="wrap" lineNumbers="true" %}

```
CardknoxSDK.setPrincipalKey("Your xKey value");
CardknoxSDK.setxSoftwareName("Your app name", xSoftwareVersion: "1.0.0", xVersion: "4.5.9");
```

{% endcode %}

Create a Cardknox SDK object. A good place is the “view appear” method. This object will be used to create “request” objects.

{% code overflow="wrap" lineNumbers="true" %}

```
override func viewDidAppear(_ animated: Bool) 
{
  super.viewDidAppear(animated)
  let cardknoxSDKUI = CardknoxSDKUI.create() as? CardknoxSDKUI
}
```

{% endcode %}

Destroy the Cardknox SDK object to free resources when SDK will no longer be used:

{% code lineNumbers="true" %}

```
cardknoxSDKDirect.destroy();
```

{% endcode %}

Define a method to run when the SDK processes a transaction and sends the processing results back:

{% code overflow="wrap" lineNumbers="true" %}

```
@objc func transactionResultSubscription(aNotification: Notification)
{
    let response = PaymentTransactionResponse.unwrap(aNotification) as! PaymentTransactionResponse
    
    var message = ""
    if(response.isSuccess())
    {
        let refNum = response.xRefNum()!
        message = "Transaction success response! Ref num: " + refNum
    }
    else
    {
        let error = response.errorMessage()!
        message = "Transaction error response - " + error
    }
}
```

{% endcode %}

Afterwards, subscribe the method to receive results back from the SDK:

{% code overflow="wrap" lineNumbers="true" %}

```
NotificationCenter.default.addObserver(self,
                                       selector: #selector(transactionResultSubscription(aNotification:)),
                                       name: Notification.Name( CardknoxSDK.transactionResultSubscription_NSNotificationCenterName()),
                                       object: nil)
```

{% endcode %}

SDK works with a card reader to accept a card. Various card reader events can happen during processing. Define a method to run whenever a new card reader event happens:

{% code overflow="wrap" lineNumbers="true" %}

```
@objc func cardreaderEventSubscription(aNotification: Notification)
{
  let callback = CardknoxCardReaderCallback.unwrap(aNotification) as? CardknoxCardReaderCallback
  
  let code = callback?.code()
  let name = callback?.name()
  
  var errorMessage : String?;
  if(code == CardknoxCardReaderCallbackType.error()){
      errorMessage = callback?.message();
  }
}
```

{% endcode %}

Afterwards, subscribe the method to be notified about card reader events:

{% code overflow="wrap" lineNumbers="true" %}

```
NotificationCenter.default.addObserver(self,
                                       selector: #selector(cardreaderEventSubscription(aNotification:)),
                                       name: Notification.Name( CardknoxSDK.cardreaderEventSubscription_NSNotificationCenterName()),
                                       object: nil)
```

{% endcode %}

Next, create a transaction parameters object:

{% code lineNumbers="true" %}

```
let prms = TransactionParameters();
```

{% endcode %}

Specify the required parameters:

{% code overflow="wrap" lineNumbers="true" %}

```
prms.xCommand = "<xCommand>";
prms.xAmount = 1.23;
```

{% endcode %}

<mark style="color:red;">**CHANGE \<xCommand> to value from Transaction Type dropdown**</mark>

Specify optional parameters, if any:

{% code overflow="wrap" lineNumbers="true" %}

```
prms.xInvoice = "123456";
prms.xBillFirstName = "Billing first name";
// ... etc. 
```

{% endcode %}

Create a request object, check if the request object is valid, initiate a transaction & process the response:

{% code overflow="wrap" lineNumbers="true" %}

```
// Define if a 'keyed' screen is available
CardknoxSDKUI.setEnableKeyedEntry(true);
// Define if a 'swipe' screen is available
CardknoxSDKUI.setEnableDeviceInsertSwipeTap(true);
// Define if the UI should auto close
CardknoxSDKUI.setCloseOnProcessedTransaction(true);

let request = cardknoxSDKUI.createRequest(withParameters: prms) as! PaymentTransactionRequestUI
if(request.isValid)
{
  // Show the Cardknox UI
  request.process()
}
else
{
  // Request could not be processed due to these errors
  let errors = request.validationErrors!
}
```

{% endcode %}

### Objective C - Storyboard 2

To submit a <mark style="color:red;">**\<xCommand>**</mark> request, first configure the SDK with:

* an xKey value obtained from Cardknox
* a software name value; a short name for your application
* a software version value; the current version of your software
* a version value; the current Cardknox Gateway version 4.5.9

{% code overflow="wrap" lineNumbers="true" %}

```
[CardknoxSDK setPrincipalKey:@"Your xKey"];
[CardknoxSDK setxSoftwareName:@"Your app name" xSoftwareVersion:@"1.0.0" xVersion:@"4.5.9"];
```

{% endcode %}

Create a Cardknox SDK object. A good place is the “view appear” method. This object will be used to create “request” objects.

{% code overflow="wrap" lineNumbers="true" %}

```
- (void)viewDidAppear:(BOOL)animated
{
  [super viewDidAppear:animated];
  CardknoxSDKUI* cardknoxSDKUI = [CardknoxSDKUI create];
}
```

{% endcode %}

Destroy the Cardknox SDK object to free resources when SDK will no longer be used:

{% code lineNumbers="true" %}

```
[cardknoxSDKUI destroy];
```

{% endcode %}

Define a method to run when the SDK processes a transaction and sends the processing results back:

{% code overflow="wrap" lineNumbers="true" %}

```
-(void)transactionResultSubscription:(NSNotification*)aNotification
{
    PaymentTransactionResponse * response = [PaymentTransactionResponse unwrap:aNotification];
    
    NSString *message;
    if(response.isSuccess)
    {
        NSString * refNum = response.xRefNum;
        message = [NSString stringWithFormat:@"Transaction success response! Ref num: %@", refNum];
    }
    else
    {
        NSString * error = response.errorMessage;
        message = [NSString stringWithFormat:@"Transaction error response - %@", error];
    }
}
```

{% endcode %}

Afterwards, subscribe the method to receive results back from the SDK:

{% code overflow="wrap" lineNumbers="true" %}

```
[[NSNotificationCenter defaultCenter] addObserver:self
                       selector:@selector(transactionResultSubscription:)
                           name:[CardknoxSDK transactionResultSubscription_NSNotificationCenterName]
                         object:nil];
```

{% endcode %}

SDK works with a card reader to accept a card. Various card reader events can happen during processing. Define a method to run whenever a new card reader event happens:

{% code overflow="wrap" lineNumbers="true" %}

```
-(void)cardreaderEventSubscription:(NSNotification*)callbackNotification
{
    CardknoxCardReaderCallback* callback = [CardknoxCardReaderCallback unwrap:callbackNotification];
    
    int code = callback.code;
    NSString* name = callback.name;
    
    NSString* errorMessage;
    if(code == CardknoxCardReaderCallbackType.error){
        errorMessage = callback.message;
    }
}
```

{% endcode %}

Afterwards, subscribe the method to be notified about card reader events:

{% code overflow="wrap" lineNumbers="true" %}

```
NotificationCenter.default.addObserver(self,
                                       selector: #selector(cardreaderEventSubscription(aNotification:)),
                                       name: Notification.Name( CardknoxSDK.cardreaderEventSubscription_NSNotificationCenterName()),
                                       object: nil)
```

{% endcode %}

Next, create a transaction parameters object:

{% code overflow="wrap" lineNumbers="true" %}

```
TransactionParameters *prms =[[TransactionParameters alloc] init];
```

{% endcode %}

Specify the required parameters:

{% code overflow="wrap" lineNumbers="true" %}

```
prms.xCommand = @"<xCommand>";
prms.xAmount = 1.23;
```

{% endcode %}

<mark style="color:red;">**CHANGE \<xCommand> to value from Transaction Type dropdown**</mark>

Specify optional parameters, if any:

{% code overflow="wrap" lineNumbers="true" %}

```
prms.xInvoice = @"123456";
prms.xBillFirstName = @"Billing first name";
// ... etc. 
```

{% endcode %}

Create a request object, check if the request object is valid, initiate a transaction & process the response:

{% code overflow="wrap" lineNumbers="true" %}

```
// Define if a 'keyed' screen is available
CardknoxSDKUI.EnableKeyedEntry = true;
// Define if a 'swipe' screen is available
CardknoxSDKUI.EnableDeviceInsertSwipeTap = true;
// Define if the UI should auto close
CardknoxSDKUI.CloseSDKUIOnProcessedTransaction = true;

PaymentTransactionRequestUI *request = [cardknoxSDKUI createRequestWithParameters:prms];
if(request.IsValid)
{
  // Show the Cardknox UI
  [request process];
}
else
{
  // Request could not be processed due to these errors
  NSArray* errors = request.ValidationErrors;
}
```

{% endcode %}

## Examples

### In Scope Example Processes

| Selections       | Example 1                               | Example 2                               |
| ---------------- | --------------------------------------- | --------------------------------------- |
| Integration      | In Scope                                | In Scope                                |
| Language         | Swift                                   | Objective C                             |
| UI Toolkit       | Storyboard                              | Storyboard                              |
| Transaction Type | cc:sale                                 | cc:refund                               |
|                  | [View the Example](#in-scope-example-1) | [View the Example](#in-scope-example-2) |

#### In Scope Example 1

<table data-header-hidden><thead><tr><th width="180">Role</th><th>Capabilities</th></tr></thead><tbody><tr><td>Integration</td><td>In Scope</td></tr><tr><td>Language</td><td>Swift</td></tr><tr><td>UI Toolkit</td><td>Storyboard</td></tr><tr><td>Transaction</td><td>cc:sale</td></tr></tbody></table>

Example 1 sets `xCardNum` & `xExpDate` into the parameters object as those 2 are required by the `cc:sale` command. Therefor example 1 has the `Specify the additional parameters for the "cc:sale" transaction type:` sample code

```
prms.xCardNum = "4444333322221111";
2prms.xExpDate = "1225"; // MMYY
```

To submit a **cc:sale** request, first configure the SDK with:

* an xKey value obtained from Cardknox
* a software name value; a short name for your application
* a software version value; the current version of your software, if any
* a version value; the current Cardknox Gateway version 4.5.9

{% code overflow="wrap" lineNumbers="true" %}

```
CardknoxSDK.setPrincipalKey("Your xKey value");
CardknoxSDK.setxSoftwareName("Your app name", xSoftwareVersion: "1.0.0", xVersion: "4.5.9")
```

{% endcode %}

Create a Cardknox SDK object. A good place is the “view appear” method. This object will be used to create “request” objects.

{% code overflow="wrap" lineNumbers="true" %}

```
override func viewDidAppear(_ animated: Bool) 
{
  super.viewDidAppear(animated)
  let cardknoxSDKDirect = CardknoxSDKDirect.create() as? CardknoxSDKDirect
}
```

{% endcode %}

Destroy the Cardknox SDK object to free resources when SDK will no longer be used:

{% code overflow="wrap" lineNumbers="true" %}

```
cardknoxSDKDirect.destroy();
```

{% endcode %}

Next, create a transaction parameters object:

{% code overflow="wrap" lineNumbers="true" %}

```
let prms = TransactionParameters();
```

{% endcode %}

Specify the required parameters:

{% code overflow="wrap" lineNumbers="true" %}

```
prms.xCommand = "cc:sale";
prms.xAmount = 1.23;
```

{% endcode %}

<mark style="color:red;">**\[VARIES]**</mark> <mark style="color:red;">**REQUIRED FOR IN SCOPE CC:SALE**</mark>

Specify the additional parameters for the **“cc:sale”** transaction type:

{% code overflow="wrap" lineNumbers="true" %}

```
prms.xCardNum = "4444333322221111";
prms.xExpDate = "1225"; // MMYY
```

{% endcode %}

Specify optional parameters, if any:

{% code overflow="wrap" lineNumbers="true" %}

```
prms.xInvoice = "123456";
prms.xBillFirstName = "Billing first name";
// ... etc. 
```

{% endcode %}

Create a request object, check if the request object is valid, initiate a transaction & process the response:

{% code overflow="wrap" lineNumbers="true" %}

```
let request = cardknoxSDKDirect.createRequest(withParameters: prms) as! PaymentTransactionRequestDirect;
if(request.isValid)
{
  let respone = request.process() as! PaymentTransactionResponse
  
  if(response.isSuccess())
  {
    let refNum = respone.xRefNum();
    let status = respone.xStatus();
    let avs = respone.xAvsResult();
  }
  else
  {
    let refNum = response.xRefNum();
    let error = response.xError()!
    let errorCode = response.xErrorCode()!;
  }
}
else
{
  // Request could not be processed due to these errors
  let errors = request.validationErrors!
}
```

{% endcode %}

#### In Scope Example 2

| Integration      | In Scope    |
| ---------------- | ----------- |
| Language         | Objective C |
| UI Toolkit       | Storyboard  |
| Transaction Type | cc:refund   |

Example 2 sets the xRefNum value required by the `cc:refund` command. Therefor example 2 has `Specify the additional parameters for the "cc:refund" transaction type:`

{% code overflow="wrap" lineNumbers="true" %}

```
prms.xRefNum = @"123456789";
```

{% endcode %}

To submit a **cc:sale** request, first configure the SDK with:

* an xKey value obtained from Cardknox
* a software name value; a short name for your application
* a software version value; the current version of your software, if any
* a version value; the current Cardknox Gateway version 4.5.9

{% code overflow="wrap" lineNumbers="true" %}

```
[CardknoxSDK setPrincipalKey:@"Your xKey"];
[CardknoxSDK setxSoftwareName:@"Your app name" xSoftwareVersion:@"1.0.0" xVersion:@"4.5.9"];
```

{% endcode %}

Create a Cardknox SDK object. A good place is the “view appear” method. This object will be used to create “request” objects.

{% code overflow="wrap" lineNumbers="true" %}

```
- (void)viewDidAppear:(BOOL)animated
{
  [super viewDidAppear:animated];
  CardknoxSDKDirect* cardknoxSDKDirect = [CardknoxSDKDirect create];
}
```

{% endcode %}

Destroy the Cardknox SDK object to free resources when SDK will no longer be used:

{% code overflow="wrap" lineNumbers="true" %}

```
[cardknoxSDKDirect destroy];
```

{% endcode %}

Next, create a transaction parameters object:

{% code overflow="wrap" lineNumbers="true" %}

```
TransactionParameters *prms =[[TransactionParameters alloc] init];
```

{% endcode %}

Specify the required parameters:

{% code overflow="wrap" lineNumbers="true" %}

```
prms.xCommand = @"cc:refund";
prms.xAmount = 1.23;
```

{% endcode %}

<mark style="color:red;">**\[VARIES]**</mark> <mark style="color:red;">**REQUIRED FOR IN SCOPE CC:REFUND**</mark>

Specify the additional parameters for the **“cc:refund”** transaction type:

{% code overflow="wrap" lineNumbers="true" %}

```
prms.xRefNum = @"123456789";
```

{% endcode %}

Specify optional parameters, if any:

{% code overflow="wrap" lineNumbers="true" %}

```
prms.xInvoice = @"123456";
prms.xBillFirstName = @"Billing first name";
// ... etc. 
```

{% endcode %}

Create a request object, check if the request object is valid, initiate a transaction & process the response:

{% code overflow="wrap" lineNumbers="true" %}

```
PaymentTransactionRequestDirect *request = [cardknoxSDKDirect createRequestWithParameters:prms];

if([request IsValid])
{
  PaymentTransactionResponse * response = [request process];
 
  if(response.isSuccess)
  {
    NSString* refNum = response.xRefNum;
    NSString* status = response.xStatus;
    NSString* avs = response.xAvsResult; 
  }
  else
  {
    NSString* refNum = response.xRefNum;
    NSString* error = response.xError;
    NSString* errorCode = response.xErrorCode;
  } 
}
else
{
  // Request could not be processed due to these errors
  NSArray* errors = request.ValidationErrors;
}
```

{% endcode %}

### Out of Scope Example Processes

| Selections       | Example 1                                   | Example 2                                   |
| ---------------- | ------------------------------------------- | ------------------------------------------- |
| Integration      | Out of Scope                                | Out of Scope                                |
| Language         | Swift                                       | Objective C                                 |
| UI Toolkit       | Storyboard                                  | Storyboard                                  |
| Transaction Type | cc:sale                                     | cc:sale                                     |
|                  | [View the Example](#out-of-scopr-example-1) | [View the Example](#out-of-scope-example-2) |

#### Out of Scope Example 1

<table data-header-hidden><thead><tr><th width="180">Role</th><th>Capabilities</th></tr></thead><tbody><tr><td>Integration</td><td>Out of Scope</td></tr><tr><td>Language</td><td>Swift</td></tr><tr><td>UI Toolkit</td><td>Storyboard</td></tr><tr><td>Transaction</td><td>cc:sale</td></tr></tbody></table>

To submit a **cc:sale** request, first configure the SDK with:

* an xKey value obtained from Cardknox
* a software name value; a short name for your application
* a software version value; the current version of your software, if any
* a version value; the current Cardknox Gateway version 4.5.9

{% code overflow="wrap" lineNumbers="true" %}

```
CardknoxSDK.setPrincipalKey("Your xKey value");
CardknoxSDK.setxSoftwareName("Your app name", xSoftwareVersion: "1.0.0", xVersion: "4.5.9")
```

{% endcode %}

Create a Cardknox SDK object. A good place is the “view appear” method. This object will be used to create “request” objects.

{% code overflow="wrap" lineNumbers="true" %}

```
override func viewDidAppear(_ animated: Bool) 
{
  super.viewDidAppear(animated)
  let cardknoxSDKUI = CardknoxSDKUI.create() as? CardknoxSDKUI
}
```

{% endcode %}

Destroy the Cardknox SDK object to free resources when SDK will no longer be used:

{% code overflow="wrap" lineNumbers="true" %}

```
cardknoxSDKDirect.destroy();
```

{% endcode %}

Define a method to run when the SDK processes a transaction and sends the processing results back:

{% code overflow="wrap" lineNumbers="true" %}

```
@objc func transactionResultSubscription(aNotification: Notification)
{
    let response = PaymentTransactionResponse.unwrap(aNotification) as? PaymentTransactionResponse
    
    var message = ""
    if((response?.isSuccess()) != nil)
    {
        let refNum = (response?.xRefNum())! as String
        message = "Transaction success response! Ref num: " + refNum
    }
    else
    {
        let error = (response?.errorMessage())! as String
        message = "Transaction error response - " + error            
    }
}
```

{% endcode %}

Afterwards, subscribe the method to receive results back from the SDK:

{% code overflow="wrap" lineNumbers="true" %}

```
NotificationCenter.default.addObserver(self,
                                       selector: #selector(transactionResultSubscription(aNotification:)),
                                       name: Notification.Name( CardknoxSDK.transactionResultSubscription_NSNotificationCenterName()),
                                       object: nil)
```

{% endcode %}

SDK works with a card reader to accept a card. Various card reader events can happen during processing. Define a method to run whenever a new card reader event happens:

{% code overflow="wrap" lineNumbers="true" %}

```
@objc func cardreaderEventSubscription(aNotification: Notification)
{
  let callback = CardknoxCardReaderCallback.unwrap(aNotification) as? CardknoxCardReaderCallback
  
  let code = callback?.code()
  let name = callback?.name()
  
  var errorMessage : String?;
  if(code == CardknoxCardReaderCallbackType.error()){
      errorMessage = callback?.message();
  }
}
```

{% endcode %}

Afterwards, subscribe the method to be notified about card reader events:

{% code overflow="wrap" lineNumbers="true" %}

```
NotificationCenter.default.addObserver(self,
                                       selector: #selector(cardreaderEventSubscription(aNotification:)),
                                       name: Notification.Name( CardknoxSDK.cardreaderEventSubscription_NSNotificationCenterName()),
                                       object: nil)
```

{% endcode %}

Next, create a transaction parameters object:

{% code overflow="wrap" lineNumbers="true" %}

```
let prms = TransactionParameters();
```

{% endcode %}

Specify the required parameters:

{% code overflow="wrap" lineNumbers="true" %}

```
prms?.xCommand = "cc:sale";
2prms?.xAmount = 1.23;
```

{% endcode %}

Specify optional parameters, if any:

{% code overflow="wrap" lineNumbers="true" %}

```
prms?.xInvoice = "123456";
prms?.xBillFirstName = "Billing first name";
// ... etc. 
```

{% endcode %}

Create a request object, check if the request object is valid, initiate a transaction & process the response:

{% code overflow="wrap" lineNumbers="true" %}

```
// Define if a 'keyed' screen is available
CardknoxSDKUI.setEnableKeyedEntry(true);
// Define if a 'swipe' screen is available
CardknoxSDKUI.setEnableDeviceInsertSwipeTap(true);
// Define if the UI should auto close
CardknoxSDKUI.setCloseOnProcessedTransaction(true);

let request = cardknoxSDKUI.createRequest(withParameters: prms) as! PaymentTransactionRequestUI
if(request.isValid)
{
  // Show the Cardknox UI
  request.process()
}
else
{
  // Request could not be processed due to these errors
  let errors = request.validationErrors!
}
```

{% endcode %}

#### Out of Scope Example 2

| Integration      | Out of Scope |
| ---------------- | ------------ |
| Language         | Objective C  |
| UI Toolkit       | Storyboard   |
| Transaction Type | cc:sale      |

To submit a **cc:sale** request, first configure the SDK with:

* an xKey value obtained from Cardknox
* a software name value; a short name for your application
* a software version value; the current version of your software, if any
* a version value; the current Cardknox Gateway version 4.5.9

{% code overflow="wrap" lineNumbers="true" %}

```
[CardknoxSDK setPrincipalKey:@"Your xKey"];
[CardknoxSDK setxSoftwareName:@"Your app name" xSoftwareVersion:@"1.0.0" xVersion:@"4.5.9"];
```

{% endcode %}

Create a Cardknox SDK object. A good place is the “view appear” method. This object will be used to create “request” objects.

{% code overflow="wrap" lineNumbers="true" %}

```
- (void)viewDidAppear:(BOOL)animated
{
  [super viewDidAppear:animated];
  CardknoxSDKUI* cardknoxSDKUI = [CardknoxSDKUI create];
}
```

{% endcode %}

Destroy the Cardknox SDK object to free resources when SDK will no longer be used:

{% code overflow="wrap" lineNumbers="true" %}

```
[cardknoxSDKUI destroy];
```

{% endcode %}

Define a method to run when the SDK processes a transaction and sends the processing results back:

{% code overflow="wrap" lineNumbers="true" %}

```
-(void)transactionResultSubscription:(NSNotification*)aNotification
{
    PaymentTransactionResponse * response = [PaymentTransactionResponse unwrap:aNotification];
    
    NSString *message;
    if(response.isSuccess)
    {
        NSString * refNum = response.xRefNum;
        message = [NSString stringWithFormat:@"Transaction success response! Ref num: %@", refNum];
    }
    else
    {
        NSString * error = response.errorMessage;
        message = [NSString stringWithFormat:@"Transaction error response - %@", error];
    }
}
```

{% endcode %}

Afterwards, subscribe the method to receive results back from the SDK:

{% code overflow="wrap" lineNumbers="true" %}

```
[[NSNotificationCenter defaultCenter] addObserver:self
                       selector:@selector(transactionResultSubscription:)
                           name:[CardknoxSDK transactionResultSubscription_NSNotificationCenterName]
                         object:nil];
```

{% endcode %}

SDK works with a card reader to accept a card. Various card reader events can happen during processing. Define a method to run whenever a new card reader event happens:

{% code overflow="wrap" lineNumbers="true" %}

```
-(void)cardreaderEventSubscription:(NSNotification*)callbackNotification
{
    CardknoxCardReaderCallback* callback = [CardknoxCardReaderCallback unwrap:callbackNotification];
    
    int code = callback.code;
    NSString* name = callback.name;
    
    NSString* errorMessage;
    if(code == CardknoxCardReaderCallbackType.error){
        errorMessage = callback.message;
    }
}
```

{% endcode %}

Afterwards, subscribe the method to be notified about card reader events:

{% code overflow="wrap" lineNumbers="true" %}

```
NotificationCenter.default.addObserver(self,
                                       selector: #selector(cardreaderEventSubscription(aNotification:)),
                                       name: Notification.Name( CardknoxSDK.cardreaderEventSubscription_NSNotificationCenterName()),
                                       object: nil)
```

{% endcode %}

Next, create a transaction parameters object:

{% code overflow="wrap" lineNumbers="true" %}

```
TransactionParameters *prms = [[TransactionParameters alloc] init];
```

{% endcode %}

Specify the required parameters:

{% code overflow="wrap" lineNumbers="true" %}

```
prms.xCommand = @"cc:sale";
prms.xAmount = 1.23;
```

{% endcode %}

Specify optional parameters, if any:

{% code overflow="wrap" lineNumbers="true" %}

```
prms.xInvoice = @"123456";
prms.xBillFirstName = @"Billing first name";
// ... etc.
```

{% endcode %}

Create a request object, check if the request object is valid, initiate a transaction & process the response:

{% code overflow="wrap" lineNumbers="true" %}

```
// Define if a 'keyed' screen is available
CardknoxSDKUI.EnableKeyedEntry = true;
// Define if a 'swipe' screen is available
CardknoxSDKUI.EnableDeviceInsertSwipeTap = true;
// Define if the UI should auto close
CardknoxSDKUI.CloseSDKUIOnProcessedTransaction = true;

PaymentTransactionRequestUI *request = [cardknoxSDKUI createRequestWithParameters:prms];
if(request.IsValid)
{
  // Show the Cardknox UI
  [request process];
}
else
{
  // Request could not be processed due to these errors
  NSArray* errors = request.ValidationErrors;
}
```

{% endcode %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.solapayments.com/sdk/ios-sdk/workflow.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
