Ingenico Desk/5000 over TCP/IP returns 300 Invalid ECR Request or 950 Invalid Message Format when sending sale request from PHP

22 hours ago 2
ARTICLE AD BOX

Body

I am trying to integrate an Ingenico Desk/5000 payment terminal with a custom PHP POS system over local TCP/IP.

The terminal is on my local network:

Terminal IP: 192.168.2.78 Port: 9000

My PHP POS can successfully open a socket to the terminal and write data to it, so this does not appear to be an IP/firewall/connectivity problem.

Example connection test:

$sock = fsockopen('192.168.2.78', 9000, $errno, $errstr, 10); if (!$sock) { die("Connect failed: $errno $errstr"); } fwrite($sock, $payload); $response = fread($sock, 4096); echo bin2hex($response);

The terminal accepts the TCP connection, but it rejects the request format.

What I have tested

1. STX/ETX/LRC framed message

I tried sending a $1.00 CAD sale request like this:

01|000000000100|000000000000|123456|124|0|0

Framed as:

STX + body + ETX + LRC

Hex example:

0230317c3030303030303030303130307c3030303030303030303030307c3132333435367c3132347c307c300333

If I send this with no handshake, I usually get no response.

If I send an ACK byte first, then the framed message, the terminal responds:

950

The terminal does not show the payment screen.

2. 4-digit length-prefixed message

I also tried sending length-prefixed messages like:

004300|000000000100|000000000000|123456|124|0|0

The terminal responds:

300

The terminal screen shows:

Invalid ECR Request

I also tested very simple length-prefixed values like:

0000 0001X 0004TEST 0006STATUS

All of them return:

300

So 300 appears to be a generic invalid ECR request/parameter response.

3. Other body formats tested

I also tested variants using:

SALE|... PURCHASE|... JSON XML-like body key=value CSV semicolon-delimited fields fixed-width numeric fields

They all either return:

300

or:

950

or no response.

Port scan

I scanned common ports on the terminal. Only port 9000 is open:

23 closed 80 closed 443 closed 8080 closed 8443 closed 9000 open 9100 closed 12000 closed

So I believe 9000 is the correct ECR/POS listener.

What I am trying to understand

Is the Ingenico Desk/5000 expecting a specific protocol such as:

Elavon TSI Commerce SDK / CSDK INGENICO_RBA_UPP RBA NEXO POSXML Telium

or another format?

I found Elavon Commerce SDK documentation mentioning INGENICO_RBA_UPP, IP connection criteria, and possible TLS 1.2, but customer support told me the terminal should work directly and does not require extra software.

Question

What is the correct request format for sending a simple $1.00 CAD sale request to an Ingenico Desk/5000 over TCP/IP on port 9000?

Specifically:

Does this terminal expect plain TCP or TLS?

Does it require STX/ETX/LRC, length-prefixed packets, or another envelope?

Is 300 definitely “Invalid ECR Request / Invalid ECR Parameter”?

Is 950 “Invalid Message Format”?

Does PHP need to communicate through Elavon Commerce SDK/CWS instead of raw TCP?

Can anyone provide a minimal example of a valid sale request packet?

I am not looking for approval/settlement logic yet. I only want to get the terminal to display the payment prompt for a test $1.00 CAD sale.

Minimal PHP test

<?php $ip = '192.168.2.78'; $port = 9000; function lrc($body) { $lrc = 0; for ($i = 0; $i < strlen($body); $i++) { $lrc ^= ord($body[$i]); } $lrc ^= 0x03; return chr($lrc); } $body = '01|000000000100|000000000000|123456|124|0|0'; $payload = chr(0x02) . $body . chr(0x03) . lrc($body); $sock = fsockopen($ip, $port, $errno, $errstr, 10); if (!$sock) { die("Connection failed: $errno $errstr"); } stream_set_timeout($sock, 15); // Sending ACK first makes the terminal return 950. // Without this, I usually get no response. fwrite($sock, chr(0x06)); usleep(300000); fwrite($sock, $payload); $response = fread($sock, 4096); fclose($sock); echo "Sent body: $body\n"; echo "Sent hex: " . bin2hex($payload) . "\n"; echo "Response text: " . $response . "\n"; echo "Response hex: " . bin2hex($response) . "\n";

Output:

Response text: 950 Response hex: 393530

Length-prefixed test:

<?php $ip = '192.168.2.78'; $port = 9000; $body = '00|000000000100|000000000000|123456|124|0|0'; $payload = str_pad(strlen($body), 4, '0', STR_PAD_LEFT) . $body; $sock = fsockopen($ip, $port, $errno, $errstr, 10); if (!$sock) { die("Connection failed: $errno $errstr"); } stream_set_timeout($sock, 15); fwrite($sock, $payload); $response = fread($sock, 4096); fclose($sock); echo "Sent: $payload\n"; echo "Response text: $response\n"; echo "Response hex: " . bin2hex($response) . "\n";

Output:

Response text: 300 Response hex: 333030

Any guidance on the correct Ingenico/Elavon ECR message format would be appreciated.

Read Entire Article