Smart COMM .Net
To integrate your POS with NetPay's Smart PinPad follow the next steps:
1. Driver installation.
The terminals are connected to POS through USB port, it is necessary to install the corresponding drivers since Windows needs them to detect the device. To install these drivers it is necessary to unzip the file USBDriver_V2.22_20180726.zip, run the installer USBDriver.exe and follow the instructions on the screen.
Once the drivers installation are done, Windows will detect our Smart Pin Pad device and assign it to a working serial port. To watch the assigned serial port, it can be viewed on Control Panel, in the Hardware Devices section, under the Ports (COMM & LPT) menu.
2. POS demo.
We count with a POS Demo to simulate the transactions of Sale, Cancellation and Reprint.
To run the COMM Demo you must first download the smartPinPadTester from Drive, unzip the file, run and make references to the . dll depending on the architecture x64 or x86 as indicated in point 3. Installation of components.
3. Installation of components.
To integrate with the terminal, the following files are included. These must be imported into the POS project. The DLLs have as Target .NET 3.5 Framework or higher.
NetPayConnect.dll (Connector for Smart PinPad terminal).
Newtonsoft.Json.dll (Auxiliary library for managing JSON objects).
Currently the NetPayConnect.dll has several versions available for download:
- NetPayConnect.dll_v1.3
- NetPayConnect.dll_v1.4
- NetPayConnect.dll_v1.5
- NetPayConnect.dll_v1.5.5
- NetPayConnect.dll_v1.6
Version 1.5 has a Timer that is enabled when the request is sent to the PinPad and it keeps waiting until it receives a response. This version improves performance related issues of the POS and inhibition, which is why this is considered a much more stable version than its predecessors.
It is important to point out that version 1.5 is implemented in a different way than 1.3 or 1.4, therefore additional configurations are needed, and will be explained throughout the documentation.
The dll files can be downloaded by this link Versions .dll
Note.
Depending on the type of development, it is necessary to verify if it is in x64 or x86 architecture since the corresponding dll must be added.
Example of adding dll reference that correspondos to the architecture of your POS.
Enter the Project menu->right click on the References option.
Add references->
Press the Browse button and select the corresponding x64 or x86 file and press Add.
Enter the folder where the dll is located according to the architecture.
Select the dll file and press OK.
After adding the reference compile the project.
Menu Build-> Build Solution.
4. Library integration.
The NetPayConnect.dll component is a library that can be integrated into any Windows-based development language that supports this type of library. It contains a class called Operator which is used to call the methods.
4.1 Creation of the object.
We create an Operator type object to be able to access its methods.
NetPayConnect.Operator connectorPAX = new NetPayConnect.Operator();
4.2 Sending a sale request to Smart PinPad.
Once the object is instantiated we can access the following methods:
Method. | Description. |
---|---|
SetAmount | The amount to be collected is assigned. Receives a value of type Double (only accepts 2 decimal places). |
setMSI | The number of months without interest is assigned at the time of processing the transaction. By default, the value 0 (without months) is sent. Possible values that it accepts: 3, 6, 9, 12, 18. |
setFolio | The personalized folio to be used in the Ticket is assigned. |
sendData | Once the minimum amount has been assigned, this method is called to process the transaction on the PinPad. |
ReceiveData(version 1.5.dll) | It receives information from the PinPad and stores it in a "response" object within the Connector class. |
getResponse | You can retrieve the information stored in the "response" object by calling this method. |
setTip | A designated amount is assigned to tip. Receives values of type Double. (only accepts 2 decimals). |
findPortByDescription | Returns the port to which the PinPad is connected. |
Version() | Returns version of dll. |
SetCustomeCOMM (version 1.6.dll) | Sets the custome COMM port that the terminal will be using. |
Note.
To perform a test transaction we must use at least the setAmount() method to place the amount to be charged and process the transaction with the sendData() method.
These are examples of how to use these methods in existing libraries.
- Version 1.5 of NetPayConnect.dll requires a _Timer _to be implemented at your POS for it to function properly. A code example will be presented later.
Note
In version 1.5 of the NetPayConnect.dll it is recommended to implement the Timer by setting its value between 500-1000 ms. This setting is simply a recommendation, however we suggest setting it to less than 2000 ms as some Smart PinPad processes end quickly and the response may not be catched.
- On the other hand, version 1.4 of NetPayConnect.dll does not require said Timer, but it may show problems related to inhibition.
To avoid any inconvenience, it is recommended to implement version 1.5 of NetPayConnect.dll.
Example sale button in the most recent bookstores:
private void Venta_Click(object sender, EventArgs e){
//pressing the button enables the timer that will be waiting for a response from the PinPad
timer1.Enabled = true;
//It is RECOMMENDED to block the button until the sale is satisfactorily completed to avoid
//double instances and is enabled when information is received.
button1.Enabled = false;
string result = "";
string msiValue = ((KeyValuePair<string, string>)comboBox1.SelectedItem).Value;
try
{
//we do set to the value Amount (required field to call sendData())
connectorPAX.SetAmount(Convert.ToDouble(textBox1.Text));
//we set the Tip value (not mandatory)
if (textBox5.Text == "")
{
connectorPAX.SetTip(0.0);
}
else
{
connectorPAX.SetTip(Convert.ToDouble(textBox5.Text));
}
//we set the folio value (not mandatory)
connectorPAX.SetFolio(textBox2.Text);
//we set the MSI value (not mandatory)
connectorPAX.SetMSI(Convert.ToInt32(msiValue));
//we validate the checkbox to print or not the ticket
connectorPAX.setDisablePrintAnimation(checkBox1.Checked);
//we send the transaction to the PinPad
connectorPAX.sendData();
}
catch (Exception ec)
{
Console.WriteLine(ec.Message);
}
}
private void Venta_Click(object sender, EventArgs e){
//se RECOMIENDA bloquear el boton para evitar temas de dobles instancias
button1.Enabled = false;
String result= "";
string msiValue = ((KeyValuePair<string, string>)comboBox1.SelectedItem).Value;
try {
//hacemos set al valor Amount (campo obligatorio para llamar el sendData())
connectorPAX.SetAmount(Convert.ToDouble(textBox1.Text));
//hacemos set al valor folio (no obligatorio)
connectorPAX.SetFolio(textBox2.Text);
//hacemos set al valor MSI (no obligatorio)
connectorPAX.SetMSI(Convert.ToInt32(msiValue));
//validamos la checkbox para imprimir o no el ticket
connectorPAX.setDisablePrintAnimation(checkBox1.Checked);
//enviamos la informacion a la PinPad para realizar la venta
connectorPAX.sendData();
}
catch (Exception ec){
Console.WriteLine(ec.Message);
}
//...
//CODIGO PARA RECIBIR RESPUESTA
//...
}
Note.
As you can see in the example above, some buttons are disabled or hidden during the response process, it is recommended to do this as well on your Sell button to avoid problems with duplicate instances or thread related problems.
In the same way it is recommended to do this on Cancel and Reprint buttons.
4.3 Receiving the response.
We can get the response in JSON format after sending a transaction.
In version 1.5 of the .dll, the Timer calls another method called getResponseData(), both are outside the sale button, this implementation improves the point of sale performance.
In version 1.4 of the .dll, the getResponse() method is called just after sending a sale.
Example of how to receive the response from the PinPad:
//The timer is enabled and calls the getResponseData method to wait for the return data.
private void Timer_Tick(object sender, EventArgs e)
{
getResponseData();
}
//The getResponseData method is activated which will be waiting for values
private void getResponseData()
{
//The ReceiveData method will be waiting for data from the port to save them in getResponse()
connectorPAX.ReceiveData();
//If getResponse is not empty, the obtained information is retrieved
if (connectorPAX.getResponse() != null)
{
//RECOVERED VALUES
textBox.Text += System.Environment.NewLine + "Amount: " + connectorPAX.getAmount();
textBox.Text += System.Environment.NewLine + "Message: " + connectorPAX.getMessage();
textBox.Text += System.Environment.NewLine + "OrderId: " + connectorPAX.getOrderId();
//...RECOVERED VALUES
//The timer is turned off once the information has arrived
timer1.Enabled = false;
//the button is enabled once the information has been received
button1.Enabled = true;
}
}
private void Venta_Click(object sender, EventArgs e){
//...
//CODIGO PARA ENVIAR VENTA
//...
//Si getResponse no esta vacio, se recupera la informacion obtenida
if (connectorPAX.getResponse() != null)
{
//VALORES RECUPERADOS
textBox.Text += System.Environment.NewLine + "Amount: " + connectorPAX.getAmount();
textBox.Text += System.Environment.NewLine + "Message: " + connectorPAX.getMessage();
textBox.Text += System.Environment.NewLine + "OrderId: " + connectorPAX.getOrderId();
//...VALORES RECUPERADOS
//Se habilita el boton de venta despues de recibir informacion.
button1.Enabled = false;
}
}
Obervation
Sell button is activated after receiving the response, this can be implemented also in the cancel and reprint button. We highly recommend this, in order to avoid any instance or thread problems.
Example 1 to receive the response: Using the getResponse() object, the following will be obtained:
{
"data": {
"affiliation": "7389108",
"applicationLabel": "Debit MasterCard",
"arqc": "44F30DA9ED36D1D3",
"aid": "A0000000032010",
"amount": "100.0",
"authCode": "TEST00",
"bankName": "SANTANDER",
"cardExpDate": "01/26",
"cardType": "D",
"cardTypeName": "MASTERCARD",
"cityName": "Guadalupe NUEVO LEON",
"responseCode": "00",
"folioNumber": "",
"hasPin": true,
"hexSign": "",
"isQPS": 0,
"message": "Transacción exitosa",
"moduleCharge": "1",
"moduleLote": "1",
"customerName": "NOMBRE CLIENTE /",
"terminalId": "1310000001",
"orderId": "211018115515-1490293212",
"preAuth": "0",
"preStatus": 0,
"promotion": "00",
"rePrintDate": "1.3.1_20211018",
"rePrintMark": "MASTER",
"reprintModule": "C",
"cardNumber": "1234",
"storeId": "9194",
"storeName": "CICAP",
"streetName": "AVE PABLO LIVAS 7200",
"ticketDate": "OCT. 18, 21 11:55:18 ",
"tipAmount": "0.0",
"tipLessAmount": "100.0",
"transDate": "2021-10-18 11:55:16.CDT",
"transType": "A",
"transactionCertificate": "411D6DCB7F34B45C"
},
"idReport": 1
}
{
"data": {
"affiliation": "7389108",
"applicationLabel": "Debit MasterCard",
"arqc": "44F30DA9ED36D1D3",
"aid": "A0000000032010",
"amount": "100",
"authCode": "TEST00",
"bankName": "SANTANDER",
"cardExpDate": "01/26",
"cardType": "D",
"cardTypeName": "MASTERCARD",
"cityName": "Guadalupe,NUEVO LEON",
"responseCode": "00",
"folioNumber": "",
"hasPin": false,
"hexSign": "null",
"isQPS": 0,
"message": "Transaccion Valida",
"moduleCharge": "1",
"moduleLote": "1",
"customerName": "NOMBRE CLIENTE /",
"terminalId": "1310000001",
"orderId": "211018115515-1490293212",
"preAuth": "0",
"preStatus": 0,
"promotion": "0",
"rePrintDate": "1.3.1_20211018",
"rePrintMark": "MASTER",
"reprintModule": "C",
"cardNumber": "1234",
"storeId": "9194",
"storeName": "CICAP",
"streetName": "AVE PABLO LIVAS 7200",
"ticketDate": "OCT. 18, 21 11:55:18",
"tipAmount": "0",
"tipLessAmount": "0",
"transDate": "2021-10-18 11:55:15.0",
"transType": "A",
"transactionCertificate": "79835BDB5404064F"
},
"idReport": 1
}
{
"data": {
"affiliation": "7389108",
"applicationLabel": "Debit MasterCard",
"arqc": "79835BDB5404064F",
"aid": "A0000000032010",
"amount": "100.0",
"authCode": "TEST00",
"bankName": "SANTANDER",
"cardExpDate": "01/06",
"cardType": "D",
"cardTypeName": "MASTERCARD",
"cityName": "Guadalupe NUEVO LEON",
"responseCode": "00",
"folioNumber": "",
"hasPin": false,
"hexSign": "",
"isQPS": 0,
"message": "Transacción exitosa",
"moduleCharge": "2",
"moduleLote": "1",
"customerName": "NOMBRE CLIENTE /",
"terminalId": "1310000001",
"orderId": "211018115515-1490293212",
"preAuth": "0",
"preStatus": 0,
"promotion": "00",
"rePrintDate": "1.3.1_20211018",
"rePrintMark": "MASTERCARD",
"reprintModule": "C",
"cardNumber": "1234",
"storeId": "9194",
"storeName": "CICAP",
"streetName": "AVE PABLO LIVAS 7200",
"ticketDate": "OCT. 18, 21 11:55:18",
"tipAmount": "null",
"tipLessAmount": "100.0",
"transDate": "2021-10-18 12:00:22.CDT",
"transType": "V",
"transactionCertificate": null
},
"idReport": 1
}
Example 2 to receive the response: Extract information from the object manually.
Note: For cases where JSON objects cannot be used, the object can be extracted
directly from its properties as shown in the following example:
textBox4.Text += System.Environment.NewLine + "Afiliacion: " +
connectorPAX.getAffiliation();
textBox4.Text += System.Environment.NewLine + "ApplicationLabel: " +
connectorPAX.getApplicationLabel();
textBox4.Text += System.Environment.NewLine + "ARQC: " +
connectorPAX.getARQC();
textBox4.Text += System.Environment.NewLine + "AID: " +
connectorPAX.getAID();
textBox4.Text += System.Environment.NewLine + "Amount: " +
connectorPAX.getAmount();
textBox4.Text += System.Environment.NewLine + "AuthCode: " +
connectorPAX.getAuthCode();
textBox4.Text += System.Environment.NewLine + "BankName: " +
connectorPAX.getBankName();
textBox4.Text += System.Environment.NewLine + "CardExpDate: " +
connectorPAX.getCardExpDate();
textBox4.Text += System.Environment.NewLine + "CardType: " +
connectorPAX.getCardType();
textBox4.Text += System.Environment.NewLine + "CardTypeName: " +
connectorPAX.getCardTypeName();
textBox4.Text += System.Environment.NewLine + "CityName: " +
connectorPAX.getCityName();
textBox4.Text += System.Environment.NewLine + "ResponseCode: " +
connectorPAX.getResponseCode();
textBox4.Text += System.Environment.NewLine + "HasPin: " +
connectorPAX.getHasPin();
textBox4.Text += System.Environment.NewLine + "HexSign: " +
connectorPAX.getHexSign();
textBox4.Text += System.Environment.NewLine + "IsQps: " +
connectorPAX.getIsQPS();
textBox4.Text += System.Environment.NewLine + "Message: " +
connectorPAX.getMessage();
textBox4.Text += System.Environment.NewLine + "ModuleCharge: " +
connectorPAX.getModuleCharge();
textBox4.Text += System.Environment.NewLine + "ModuleLote: " +
connectorPAX.getModuleLote();
textBox4.Text += System.Environment.NewLine + "CustomerName: " +
connectorPAX.getCustomerName();
textBox4.Text += System.Environment.NewLine + "TerminalId: " +
connectorPAX.getTerminalId();
textBox4.Text += System.Environment.NewLine + "OrderId: " +
connectorPAX.getOrderId();
textBox4.Text += System.Environment.NewLine + "PreAuth: " +
connectorPAX.getPreAuth();
textBox4.Text += System.Environment.NewLine + "PreStatus: " +
connectorPAX.getPreStatus();
textBox4.Text += System.Environment.NewLine + "Promotion: " +
connectorPAX.getPromotion();
textBox4.Text += System.Environment.NewLine + "RePrintDate: " +
connectorPAX.getRePrintDate();
textBox4.Text += System.Environment.NewLine + "RePrintMark: " +
connectorPAX.getRePrintMark();
textBox4.Text += System.Environment.NewLine + "ReprintModule: " +
connectorPAX.getReprintModule();
textBox4.Text += System.Environment.NewLine + "CardNumber: " +
connectorPAX.getCardNumber();
textBox4.Text += System.Environment.NewLine + "StoreName: " +
connectorPAX.getStoreName();
textBox4.Text += System.Environment.NewLine + "StreetName: " +
connectorPAX.getStreetName();
textBox4.Text += System.Environment.NewLine + "TicketDate: " +
connectorPAX.getTicketDate();
textBox4.Text += System.Environment.NewLine + "TipAmount: " +
connectorPAX.getTipAmount();
textBox4.Text += System.Environment.NewLine + "TipLessAmount: " +
connectorPAX.getTipLessAmount();
textBox4.Text += System.Environment.NewLine + "TransDate: " +
connectorPAX.getTransDate();
textBox4.Text += System.Environment.NewLine + "TransType: " +
connectorPAX.getTransType();
textBox4.Text += System.Environment.NewLine +
"TransactionCertificate: " + connectorPAX.getTransactionCertificate();
textBox4.Text += System.Environment.NewLine + "FolioId: " +
connectorPAX.getFolioNumber();
Response receipt example.
Afiliacion: 7389108
ApplicationLabel: VISA
ARQC: B3815181F196389B
AID: A0000000032010
Amount: 123.0
AuthCode: TEST00
BankName: AZTECA
CardExpDate: 01/26
CardType: D
CardTypeName: VISA
ResponseCode: 00
HasPin: False
HexSign:
00000100000001DA0000009E000000040800031CFF02
FF02D300A76532632F7F2F2B74EB3DDE4A08C3C534AE
000B6AFA5F6B44A912EBB0A60C4206C0FF02039D9FEE
15B843DC3722399D609DDCD17026DAE3D358E02E47E6
BE965B8EBA5D0E56967C9D64FF026D3E9E6F1C9D0F88
13D50C4E83764CD71B623485A8E50EDB9E3F1330B2BA
FF02FF02FF02FF02FF02FF029467FF02E0FF02EB0CA6
DEB49F60FF02BCA8BC803614E03B177B828428A2F888
E8BE8A19F85E54C680E630E5F33D3F491E42EDA3F484
F54B482FF4FF02358A7F1DCB544BB50792E1573048C4
40607F927A353AC4B1AEF28981ABFF023C00198F1E04
BFD7692BDDAE884B00EFD5DA18D5915F7B659ED8A453
0E992072533170E0976C78FF02A22091C9C30EFB3108
FF0239AD4B3B65B0FCC379CEC0552BE507CA00DA2484
69604B8BFF0207E346CFDE54EC186DB3CBCDD76540FF
0215B619E5CEDC2A4B92FF024CB17A2B7FB1C6B5A3FF
0220352633D35B827F62FF02356DF5C051BAC080FF02
D3A7674F8AA2E4A022E0FF02E3679A3F34E0CD2EF155
99064160320B96E2A10BF9ADB389D5D1BE99E5B08DD9
C2E4B988614A29B6777F939A29E0DDCE3BE1F4ADDB50
22E3A412FF02371FEDFC71431D91BEC0979E97442C71
E53B71FA1633A1760839FBBAC354B82461D80980FF02
3ABF11E4B19CEB9EFA9242BFC3860DB64ED210CC5FC0
327DB08CBFEA60FF0211A7BC314499B24224E9C221FF
233C2579FE2E4A17CFF02F8FF02F2C0FF02BCB4FF02F
0FF02FAEAE0FF02FF02FF0084DE67F5E39C9E9D77428
1E182EA3C5191E18B63A983B74FF5AA2A60EA604498D
1F5A4A47F4CE5406B885554A401E6C68699F6B3F7C47
BBC5C425C5480FF0271C4A0054CFE278E48375D13848
F4F1741FF000236F5EC1DB423323A478F4EF65920A48
0FF02360CEDB743D40280FF02FF02FF02
IsQps: 0
Message: Transacción exitosa
ModuleCharge: 3
ModuleLote: 1
CustomerName:
TerminalId: 1310000001
OrderId: 211018122312-1490293212
PreAuth: 0
PreStatus: 0
Promotion: 00
RePrintDate: 1.3.1_20211018
RePrintMark: VISA
ReprintModule: C
CardNumber: 5678
StoreName: CICAP
StreetName: AVE PABLO LIVAS 7200
TicketDate: OCT. 18, 21 12:23:14
TipAmount: 0.0
TipLessAmount: 123.0
TransDate: 2021-10-18 12:23:12.CDT
TransType: A
TransactionCertificate: 0C9DD851CECB2E3F
FolioId:
StoreId: 9194
4.4 Request to cancel a transaction
Message to cancel a sale (Auth) made on the same day. Only the orderId parameter is used
and the sendCancel() method is called:
connectorPAX.sendCancel(orderId);
4.5 Ticket reprint of a previous transaction.
To reprint an already generated ticket, use the sendPrint() method. receive by
parameter the orderId of the transaction to reprint.
connectorPAX.sendPrint(orderId);
Note.
Error Handling.
When using the getResponse() object library, if it is null, it means that there is no communication with the PinPad, this may happen because it is not connected or the drivers are not installed correctly.
Optional Disable the animation and printing of the ticket in the terminal
This following implementation is optional and aimed to those business that have their integration with a kiosks and may find unecessary the ticket that the terminal print . You can disable the terminal's ticket print and animation functions with the following example.
connectorPAX. setDisablePrintAnimation(true);
connectorPAX.SetAmount(Convert.ToDouble(textBox1.Text));
connectorPAX.SetFolio(textBox2.Text);
connectorPAX.setDisablePrintAnimation (checkBox1.Checked);
Updated 9 months ago
El siguiente paso es continuar en el apartado de Certificación en el cual se detalla las pruebas a realizar para validar el correcto funcionamiento de la integración.