- Notifications
You must be signed in to change notification settings - Fork37
A .NET Zvt Library for Payment Terminals (C#)
License
Portalum/Portalum.Zvt
Folders and files
Name | Name | Last commit message | Last commit date | |
---|---|---|---|---|
Repository files navigation
Portalum.Zvt is a library designed to simplify communication with payment terminals via theZVT Protocol used in (Germany, Austria, Switzerland). The library is based on Microsoft .NET.
Communication via Network (TCP) and communication via a serial connection is supported. The most important commands for processing a payment transaction with an electronic POS system are also already integrated.
The aim of this project is to achieve uncomplicated acceptance by payment service providers. The more often this project is referred to, the better it should work. Please help us to achieve this.
The package is available viaNuGet
PM> install-package Portalum.Zvt
In theIReceiveHandler
interface the received data is now included in theCompletionReceived
event. Normally, the update should not lead to any difficulties.event Action CompletionReceived;
change toevent Action<byte[]> CompletionReceived;
The following features of the ZVT protocol were implemented.
Commands sent from the cash register to the payment terminal
- Registration
- Log-Off
- Authorization
- Reversal
- Refund
- End-of-Day
- Send Turnover Totals
- Repeat Receipt
- Diagnosis
- Abort
- Software-Update
Information sent from the payment terminal to the cash register
- Status-Information
- Intermediate StatusInformation
- Print Line
- Print Text-Block
- BMP Processing
- TLV Processing
Before sending a payment to the terminal, you should consider how to configure the terminal. For example, it can be set that a manual start of a payment at the terminal is no longer possible. You must also set where the receipts are printed directly via the terminal or via an external printer. For the configuration use theRegistration
command.
Here you can find some code examples how to use this library
vardeviceCommunication=newTcpNetworkDeviceCommunication("192.168.0.10");if(!awaitdeviceCommunication.ConnectAsync()){return;}usingvarzvtClient=newZvtClient(deviceCommunication);zvtClient.StatusInformationReceived+=(statusInformation)=>Console.WriteLine(statusInformation.ErrorMessage);awaitzvtClient.PaymentAsync(10.5M);
vardeviceCommunication=newTcpNetworkDeviceCommunication("192.168.0.10");if(!awaitdeviceCommunication.ConnectAsync()){return;}usingvarzvtClient=newZvtClient(deviceCommunication);zvtClient.StatusInformationReceived+=(statusInformation)=>Console.WriteLine(statusInformation.ErrorMessage);awaitzvtClient.EndOfDayAsync();
vardeviceCommunication=newTcpNetworkDeviceCommunication("192.168.0.10");if(!awaitdeviceCommunication.ConnectAsync()){return;}varclientConfig=newZvtClientConfig{Encoding=ZvtEncoding.CodePage437,Language=Language.German,Password=000000};varzvtClient=newZvtClient(deviceCommunication,clientConfig:clientConfig);
This library uses theMicrosoft.Extensions.Logging
package so you can easily decide where to write the log files, to a file or directly to the console output for example.To write the logging output directly to the console output, this nuget packages is neededMicrosoft.Extensions.Logging.Console
.
usingvarloggerFactory=LoggerFactory.Create(builder=>{builder.AddConsole().SetMinimumLevel(LogLevel.Debug);});vardeviceCommunicationLogger=loggerFactory.CreateLogger<TcpNetworkDeviceCommunication>();varzvtClientLogger=loggerFactory.CreateLogger<ZvtClient>();vardeviceCommunication=newTcpNetworkDeviceCommunication("192.168.0.10",logger:deviceCommunicationLogger);if(!awaitdeviceCommunication.ConnectAsync()){return;}varzvtClient=newZvtClient(deviceCommunication,logger:zvtClientLogger);
var deviceCommunication = new TcpNetworkDeviceCommunication("192.168.0.10", port: 20007);
When using asynchronous completion, the payment process is split into two steps. First the payment is authorized. Then a callback is firedwhich allows the electronic cash register to dispense it's goods. After the goods have been dispensed successfully, the payment is completed.If something fails during the dispensing process, the payment is automatically reversed by the payment terminal. This ensures that a customeris not charged for goods that have not been dispensed or when something fails.
In order to use asynchronous completion:
- register the
CompletionStartReceived
callback in theZvtClient
. This callback is fired when the payment is authorized. - register the
CompletionDecisionRequested
callback in theZvtClient
. This callback must return the status of the asynchronous completion process.
Please note when using asynchronous completion theStatusInformationReceived
callback is fired multiple times as the payment terminal isquerying the electronic cash register for the completion status.
vardeviceCommunication=newTcpNetworkDeviceCommunication("192.168.0.10");if(!awaitdeviceCommunication.ConnectAsync()){return;}varcompletionInfo=newCompletionInfo();usingvarzvtClient=newZvtClient(deviceCommunication);zvtClient.CompletionStartReceived+=(statusInformation)=>{completionInfo.State=CompletionInfoState.Wait;// here you would start your asynchronous completion process, i.e. start dispensing a water bottleConsole.WriteLine("Start asynchronous completion");Task.Delay(5000).ContinueWith((_)=>{// After the goods have been dispensed successfully, set the completion status to successcompletionInfo.State=CompletionInfoState.Successful;Console.WriteLine("Asynchronous completion finished");});};// this callback is fired about every 2-4 seconds (depending on the payment terminal) to query the status of the asynchronous completion processzvtClient.CompletionDecisionRequested+=()=>completionInfo;awaitzvtClient.PaymentAsync(10.5M);// this task will only return when the asynchronous completion process has finished
The payment terminal can be configured to stop the asynchronous completion after a certain number of queries. By default library setsthe number of tries to 10. This can be changed by setting theGetAsyncCompletionInfoLimit
property on theZvtClientConfig
objectwhen constructing theZvtClient
, seeSet a custom configuration.
With the Portalum.Zvt.ControlPanel you can test the different ZVT functions.
To use the tool, the following steps must be performed
- Install at least.NET Desktop Runtime 6.0.16
- Download and extract the ControlPanel (download)
When you only want to transmit an amount to the payment terminal.
Then you can still look at our small tool.Portalum.Zvt.EasyPay
We have already been able to test the terminals of these payment service providers.
Provider | Country | Terminal |
---|---|---|
CardComplete | Austria | ingenico iWL250 |
CardComplete | Austria | Worldline VALINA |
Hobex | Austria | ingenico Desk/3500 |
Wordline/PAYONE (SIX) | Austria | yomani touch family |
Global Payments | Austria | PAX A80 |
- Encoding is fixed to
ISO-8859-1/ISO-8859-2/ISO-8859-15
instead of default character setCP437
. There is no way to configure this Print Line
contains TLV data at the end of the package, afterTLV-activation
. According to official documentation, there should be no TLV data here- The maximum number of retries for asynchronous completion is 3 when no other value is transmitted. According to the ZVT it should be infinite.
- Authorization - Partial issue for Vending machine (Change Amount for asynchronous completion is not supported)
- No
Print Line
support - Sends TLV data even without
TLV-activation
- Authorization - Partial issue for Vending machine (Change Amount for asynchronous completion is not supported)
- Abort from ECR not possible
CommonPorts
of the device are 20007, 20008
CommonBaudRates
is9600 or115200, defaultParity
isNone, defaultDataBits
is8, defaultStopBits
is2
The official documentation of the ZVT protocol is available here
About
A .NET Zvt Library for Payment Terminals (C#)