POS Omnichannel SDK

The main goal is to have an easy to integrate SDK, that allows you to create a transaction from your point-of-sale software using a POS terminal.

      1. The point-of-sale software sends a request payment to the Omnichannel SDK.
      2. SDK initialize the payment on the POS Terminal e.g the amount is displayed on the screen and the customer should process the payment.
      3. POS Terminal sends the result payment to the Omnichannel SDK in its format.
      4. Omnichannel SDK sends the result to the point-of-sale software with a custom object.
      5. Transaction request is sent to HiPay’s server
      6. Result of the transaction request

Requirements

    • iOS >= 9
    • XCode 11 or later
    • Cocoapods
    • POS terminal with Concert protocol version 3
    • Android >= 5.0 Lollipop (API 21)
    • POS terminal with Concert protocol version 3
    • Android Studio 3.5 or later

Installation

You have to use CocoaPods to install the HiPay Omnichannel SDK for iOS. CocoaPods is a dependency manager for Swift and Objective-C Cocoa projects.

CocoaPods is built with Ruby and it will be installable with the default Ruby available on macOS. Install it with this command if you haven’t done before :

sudo gem install cocoapods

Then, execute this command at the root of your project to initialize the required files :

pod init

Add this line to your project’s Podfile:

pod 'HiPayOmnichannelConcertV3'

Then, run the following command in the same directory as your Podfile.

pod install

Open the Xcode workspace (*.xcworkspace) instead of the project file.

HiPay’s Android Omnichannel SDK is hosted on hipay.com. In order to install it, you have to add these lines to your Build.gradle Projet file :

allprojects {
    repositories {
        maven {
            url "https://artifactory.hipay.com/repository/maven-public/"
        }
    }
}

Then, add this line in your build.gradle file of the module app :

dependencies {
    implementation 'com.hipay:hipay-omnichannel-concertv3:1.2.0'
}

Initialization

First of all, to use the SDK, you have to set the Configuration object. An exception is thrown if your configuration is not set correctly.

Variable name Description Type Values Char. limit
ipAddress* Terminal IPv4 address String e.g. “192.168.1.10” 12
apiUsername* Public HiPay API username used by authentication String e.g. “123456789.stage-secure-gateway.hipay-tpp[.]com” 60
apiPassword* Public HiPay API password used by authentication String e.g. “Test_AB1234578903bd5eg” 60
environment Environment in which the transaction is going to be created Enum

Default: Production

Stage

2
authorizationThreshold When the amount is above this threshold, the authorization is set to true value Float e.g. 100.00 8
rank Terminal rank used to reconcile the transaction String Default: “001” 3
debug Enable debug mode (display all prints) Boolean Default: False  

* Mandatory parameters

import HiPayOmnichannelConcertV3
 
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
    // Override point for customization after application launch.
 
    do {
        try Configuration.shared.setConfiguration(ipAddress: "192.168.1.1",
                                                  apiUsername: "username",
                                                  apiPassword: "password",
                                                  environment: .Production,
                                                  authorizationThreshold: 10.0,
                                                  rank: "003",
                                                  debug: false)
 
    } catch ConfigurationError.invalidIpAddress {
        // Invalid IP Adress
    } catch ConfigurationError.invalidUsernamePasswordAPI { 
        // Invalid API password or API Username
    } catch {
        // Others
    }
    return true
}
public class MainActivity extends AppCompatActivity {
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
 
        try {
            Configuration.getInstance().setConfiguration(
                    "192.168.1.1",
                    "username",
                    "password",
                    Environment.STAGE,
                    10.0f,
                    false);                    
        } catch (InvalidIpAddressException e) {
            // Handle invalidIpAddressException
        } catch (InvalidUsernamePasswordAPIException e) {
            // Handle InvalidUsernamePasswordAPIException
        }
    }
}

Request Payment

For each payment, you have to create a RequestPayment object with theses variables below. When your RequestPayment is created, you execute it with the corresponding iOS method execute() or Android method execute(this). Your class has to conform to the RequestPaymentDelegate delegate to receive a response.

Variable name

Description

Type

Values

Char. limit

amount*

Total order amount, calculated as the sum of purchased items, plus shipping fees (if present), plus tax fees (if present).

Float

e.g. 9.99

8

transactionType

Type of transaction to be processed

Enum

Default: Debit

Credit

Cancellation

Duplicata

Authorization

2

forceAuthorization

Whether the authorization should be forced or not. Overwrites the authorizationThreshold parameter to enable authorization

Boolean

Default: False

 

currency

ISO 4217 alpha currency code (More information)

Enum

Default: EUR

3

orderId

Order number of your request payment. If you don’t send an identifier, we will generated it for you

String

e.g. “Order_12345”

32

cart**

Cart object (More information)

Cart

 

customer

Customer’s information object (id, firstName, lastName, email)

Customer

 

customData

Custom data (only value type Bool / Int / Float / String are accepted)

Dictionary

 

* Mandatory parameters

** If the cart content is not correctly fulfilled or doesn’t match the total amount of the order, the order will be created with an empty cart.

@IBAction func payTapped(_ sender: Any) {
  do {
        let requestPayment = try RequestPayment(amount: 98.80,
                                                transactionType: .Debit,
                                                forceAuthorization: false,
                                                currency: .EUR,
                                                orderId: "order_12345",
                                                cart: nil,
                                                customer: nil,
                                                customData: nil)
 
        requestPayment.delegate = self
        requestPayment.execute() // Request execution
      } catch RequestPaymentError.invalidAmount {
          // handle invalid amount
      } catch {
          // Others
      }
}
@Override
public void onClick(View view) {
    try {
        RequestPayment requestPayment = new RequestPayment(
                98.80f,
                TransactionType.TRANSACTION_TYPE_DEBIT,
                false,
                Currency.EUR,
                "order_12345",
                null,
                null,
                null);

        requestPayment.execute(this);
    } catch (InvalidAmountException e) {
        // Handle InvalidAmountException
    }
}

Cart

You can add the cart of the transaction, creating an Item for each article ( More informations about cart ).

/// Cart
var cart = Cart()
var table = Item(productReference: "A2343SSS",
               type: .Good,
               name: "Table",
               quantity: 2,
               unitPrice: 30.50,
               taxRate: 0.0,
               totalAmount: 58.00)
table.discount = 3.00
table.productCategory = .HomeAppliances
table.europeanArticleNumbering = "4711892728946"
table.imageUrl = "https://www.hipay.com/yourImage"

var chair = Item(productReference: "B7762NN",
               type: .Good,
               name: "Chair",
               quantity: 4,
               unitPrice: 10.20,
               taxRate: 0.0,
               totalAmount: 40.80)
chair.productCategory = .HomeAppliances
chair.productDescription = "A wooden chair"
chair.europeanArticleNumbering = "4713716322385"
chair.imageUrl = "https://www.hipay.com/yourImage"

cart.items.append(table)
cart.items.append(chair)
Item table = new Item("A2343SSS",
        ItemType.GOOD,
        "Table",
        2,
        30.50f,
        0.0f,
        58.00f);
table.setDiscount(-3.00f);
table.setProductCategory(ItemProductCategory.HOME_APPLIANCES);
table.setEuropeanArticleNumbering("4711892728946");
table.setImageUrl("https://wwww.hipay.com");

Item chair = new Item("B7762NN",
        ItemType.GOOD,
        "Chair",
        4,
        10.20f,
        0.0f,
        40.80f
);
chair.setProductCategory(ItemProductCategory.HOME_APPLIANCES);
chair.setProductDescription("A wooden chair");
chair.setEuropeanArticleNumbering("4713716322385");
chair.setImageUrl("https://wwww.hipay.com");

ArrayList itemArrayList = new ArrayList();
itemArrayList.add(table);
itemArrayList.add(chair);

Cart cart = new Cart(itemArrayList);

Customer

You can set all personal information such as his email, first name, last name and a unique identifier.

/// Customer
let customer = Customer(id: "1234",
                        firstName: "John",
                        lastName: "Doe",
                        email: "[email protected]")
// Customer
Customer customer = new Customer("99",
        "John",
        "Doe",
        "[email protected]"
);

Custom data

In the custom data parameter, you can set all the values of you want to retrieve in HiPay’s backoffice.

/// Custom data
var customData = [String:Any]()
customData["foo1"] = "foo2"
customData["price"] = 12.30
customData["event"] = 34
customData["newCustomer"] = true
HashMap customData = new HashMap();
customData.put("foo1", "foo2");
customData.put("price", 12.30);
customData.put("event", 34);
customData.put("newCustomer", true);

Payment Response

After the transaction has been processed through the HiPay’s servers, you will receive a response from the Omnichannel SDK.

class ViewControlller: UIViewController, RequestPaymentDelegate {
 
  // ... code example above
 
  // Mandatory function from RequestPaymentDelegate delegate
  func requestDidEnd(_ response: ResponsePayment) {
        print(response)
 
        if (response.paymentStatus == .Success) {
            // Handle Success
        }
        else {
            // Handle Failure
        }
  }
}
@Override
public void onFinish(ResponsePayment responsePayment) {
    if (responsePayment.getPaymentStatus() == PaymentStatus.SUCCESS) {
        // Handle success response
    }
    else {
        // Handle failed response
    }
}

The below table describes the ResponsePayment object properties, notice that all these properties are in read-only :

Variable name

Description

Type

Values

paymentStatus

Status received from the TPE regarding the payment.

Enum

Success

Failure

errorDescription

Error description

String

e.g. : “The network is unavailable”

errorCode

Error code

String

e.g. : “1003”

amount

Amount of the transaction

Float

e.g. : 98.80

currency

ISO 4217 alpha currency code

Enum

e.g. : .EUR

orderId

Order number

String

e.g. : “order_12345”

notificationHipaySent

Indicates whether Hipay has been notified of the transaction

Boolean

e.g. false

Payment Example

Here you have a complete example of the code needed to request a payment and handle its response.

import UIKit
import HiPayOmnichannelConcertV3
 
class ViewController: UIViewController, RequestPaymentDelegate {
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
    }
 
    @IBAction func payTapped(_ sender: Any) {
 
        /// Cart
        var cart = Cart()
        var table = Item(productReference: "A2343SSS",
                         type: .Good,
                         name: "Table",
                         quantity: 2,
                         unitPrice: 30.50,
                         taxRate: 0.0,
                         totalAmount: 58.00)
        table.discount = 3.00
        table.productCategory = .HomeAppliances
        table.europeanArticleNumbering = "4711892728946"
        table.imageUrl = "https://www.hipay.com/yourImage"

 
        var chair = Item(productReference: "B7762NN",
                         type: .Good,
                         name: "Chair",
                         quantity: 4,
                         unitPrice: 10.20,
                         taxRate: 0.0,
                         totalAmount: 40.80)
        chair.productCategory = .HomeAppliances
        chair.productDescription = "A wooden chair"
        chair.europeanArticleNumbering = "4713716322385"
 
        cart.items.append(table)
        cart.items.append(chair)
 
        /// Customer
        let customer = Customer(id: "1234",
                                firstName: "John",
                                lastName: "Doe",
                                email: "[email protected]")
 
        /// Custom data
        var customData = [String:Any]()
        customData["foo1"] = "foo2"
        customData["price"] = 12.30
        customData["event"] = 34
        customData["newCustomer"] = true
 
        do {
            let requestPayment = try RequestPayment(amount: 98.80,
                                                    transactionType: .Debit,
                                                    forceAuthorization: true,
                                                    currency: .EUR,
                                                    orderId: "order_12345",
                                                    cart: cart,
                                                    customer: customer,
                                                    customData: customData)
 
            requestPayment.delegate = self
            requestPayment.execute() // Request execution
        } catch RequestPaymentError.invalidAmount {
            // handle invalid amount
        } catch {
            // Others
        }
    }
 
    func requestDidEnd(_ response: ResponsePayment) {
        // Handle the reponsePayment object
        print(response)
 
        if (response.paymentStatus == .Success) {
            // Handle Success
        }
        else {
            // Handle Failure
        }
    }   
}
// All your imports
public class MainActivity extends AppCompatActivity implements View.OnClickListener, RequestPaymentDelegate {
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
 
        try {
            Configuration.getInstance().setConfiguration(
                    "192.168.1.1",
                    "username",
                    "password",
                    Environment.STAGE,
                    10.0f,
                    false);                    
        } catch (InvalidIpAddressException e) {
            // Handle invalidIpAddressException
        } catch (InvalidUsernamePasswordAPIException e) {
            // Handle InvalidUsernamePasswordAPIException
        }
    }
 
 
    @Override
    public void onClick(View view) {
 
        // Cart
        Item table = new Item("A2343SSS",
                ItemType.GOOD,
                "Table",
                2,
                30.50f,
                0.0f,
                58.00f);
        table.setDiscount(-3.00f);
        table.setProductCategory(ItemProductCategory.HOME_APPLIANCES);
        table.setEuropeanArticleNumbering("4711892728946");
        table.setImageUrl("https://wwww.hipay.com");

 
        Item chair = new Item("B7762NN",
                ItemType.GOOD,
                "Chair",
                4,
                10.20f,
                0.0f,
                40.80f
        );
        chair.setProductCategory(ItemProductCategory.HOME_APPLIANCES);
        chair.setProductDescription("A wooden chair");
        chair.setEuropeanArticleNumbering("4713716322385");
 
        ArrayList itemArrayList = new ArrayList();
        itemArrayList.add(table);
        itemArrayList.add(chair);
 
        Cart cart = new Cart(itemArrayList);
 
        // Customer
        Customer customer = new Customer("99",
                                        "John",
                                        "Doe",
                                        "[email protected]"
        );
 
        // CustomData
        HashMap customData = new HashMap();
        customData.put("foo1", "foo2");
        customData.put("price", 12.30);
        customData.put("event", 34);
        customData.put("newCustomer", true);
 
        try {
            RequestPayment requestPayment = new RequestPayment(TransactionType.TRANSACTION_TYPE_DEBIT,
                    false,
                    98.80f,
                    Currency.EUR,
                    "order_12345",
                    "1234567",
                    cart,
                    customer,
                    customData
            );
            requestPayment.execute(this);
        } catch (InvalidAmountException e) {
            // Handle InvalidAmountException
        }
    }
 
    @Override
    public void onFinish(ResponsePayment responsePayment) {
        if (responsePayment.getPaymentStatus() == PaymentStatus.SUCCESS) {
            // Handle success response
        }
        else {
            // Handle failed response
        }
    }
}

Error Codes

Should an error occur, here is a list of all the possible related codes and descriptions.

CodeDescription
1000An unknown error occurred
1001Timeout expired
1002Authentication failed with HiPay
1003The network is unavailable
1004POS terminal Not Connected
1005Parsing transaction status failed
1006Cancelled transaction (REASON)
1007Parsing received frame failed
1008Parsing created frame from POS terminal failed
1009Unknown MID