Полуинтегрированное решение Moneris не работает - PullRequest
1 голос
/ 03 июля 2019

Я очень расстроен этим моментом и думал, что опубликую это как последнее средство.

Я нахожусь в процессе разработки приложения на C # .NET 4.5, которое будет связываться через USB с платежным устройством Moneris. Это Moneris ICT-250, а Moneris называет это «полуинтегрированным» приложением. Я пытался отправить тестовый платеж, чтобы заставить устройство работать с использованием класса Serial Port, но, похоже, ничего не работает.

Для начала, Moneris предоставляет симулятор для запуска и запуска. Я могу подтвердить, что могу пойти дальше, настроить тестовый платеж - скажем, 100,00 долларов - отправить его ... и устройство загорится. Он также выводит подробный журнал как запроса, так и ответа.

Каждый запрос должен быть специально отформатированной строкой, которая идентифицирует тип платежа, сумму и т. Д .... Я взял строку, найденную в журнале, и отправил ее, но, похоже, ничего не работает. Устройство не регистрирует сбой или успех.

Я знаю, что устройство подключено правильно. Если я изменю номер порта или отключу устройство, моя ловушка справится с этим (ниже).

Ниже приведено простое консольное приложение. Что-то не так в моем коде? Кто-нибудь еще имел опыт подключения к полуинтегрированному решению Moneris? Я открыт для любых идей. Moneris не может предоставить какую-либо поддержку или фрагменты кода. Очень расстраивает, если не сказать больше ...

Спасибо всем! Код ниже:)

using System;
using System.IO.Ports;

class Moneris_Integration
{
    public static void Main()
    {
        SerialPort port = new SerialPort("COM8");

        // These properties are required by the device         
        port.BaudRate = 19200;
        port.Parity = Parity.Even;
        port.StopBits = StopBits.One;
        port.DataBits = 8;

        port.Open();

        // This is the request that is sent by the simulator to the device
        port.Write("<STX>02<FS>0011000<FS>0020<ETX><LRC>");

        port.DataReceived += new SerialDataReceivedEventHandler(DataReceivedHandler);

        Console.WriteLine("===| Moneris Test |===");
        Console.ReadKey();
    }

    private static void DataReceivedHandler(
                        object sender,
                        SerialDataReceivedEventArgs e)
    {
        SerialPort sp = (SerialPort)sender;
        string incomingData = sp.ReadExisting();
        Console.WriteLine("Response:");
        Console.Write(incomingData);
    }
}

Ответы [ 2 ]

2 голосов
/ 04 июля 2019

Как подсказывает кто-то еще в комментариях к вашему вопросу, это, безусловно, похоже на то, что вы пишете в порт:

port.Write("<STX>02<FS>0011000<FS>0020<ETX><LRC>");

необходимо полностью перевести на ASCII.

Сначала определите управляющие символы ASCII :

private byte[] STX = new byte[] { 0x02 };
private byte[] EXT = new byte[] { 0x03 };
private byte[] FS = new byte[] { 0x1C };

Вам также нужна функция для расчета LRC, основанная на остальной части сообщения. Я взял этот :

public static byte calculateLRC(byte[] bytes)
{
    byte LRC = 0;
    for (int i = 0; i < bytes.Length; i++)
    {
        LRC ^= bytes[i];
    }
    return LRC;
}

Затем преобразуйте числовые строки в сообщении в байты, используя кодировку ASCII:

byte[] bytes1 = System.Text.Encoding.ASCII.GetBytes("02");
byte[] bytes2 = System.Text.Encoding.ASCII.GetBytes("0011000");
byte[] bytes3 = System.Text.Encoding.ASCII.GetBytes("0011000");

Создаем новый блок памяти для хранения сообщения:

var message = new MemoryStream();

Добавьте байты, которые мы хотим отправить к нашему сообщению, кусками:

message.Write(STX, 0 , 1);
message.Write(bytes1, 0, bytes1.Length);
message.Write(FS, 0 , 1);
message.Write(bytes2, 0, bytes2.Length);
message.Write(FS, 0 , 1);
message.Write(bytes3, 0, bytes3.Length);
message.Write(EXT, 0 , 1);

Рассчитать LRC:

var LRC_msg = calculateLRC(message)

Добавить к сообщению:

message.Write(LRC_msg, 0, LRC_msg.Length);

И, наконец, запишите это в порт:

port.Write(message, 0, message.Length);

Вам также следует учитывать, что журнал, который вы видите, может вводить вас в заблуждение цифровой частью сообщения. Если вы все еще не получили ответ, возможно, пришло время взглянуть на реальные данные о порте. Для этого вы можете открыть терминал типа Termite или RealTerm . Я не уверен, как работает упомянутый вами симулятор, но я предполагаю, что это программное обеспечение и ему нужен последовательный порт, к которому он подключается для отправки данных. Если это так, вы можете попробовать перенаправить два реальных или виртуальных последовательных порта на вашем компьютере, как я объяснил здесь .

Было также предложено , что вам может потребоваться прервать вашу команду с помощью CR или LF.

1 голос
/ 08 июля 2019

ОК - у меня это работает.Я хочу опубликовать свое решение здесь на случай, если кто-то застрянет при попытке связаться с платежным устройством Moneris через то, что они называют «полуинтегрированным» решением.

Все предложения заставили меня задуматься ... так что послеЕще некоторые исследования и тестирование позволили мне заставить устройство работать.

ПРИМЕЧАНИЕ: В этом примере передаваемый гекс является жестко закодированным (на данный момент), и у меня сложныйзакодировал LRC.Двигаясь вперед, необходимо рассчитать шестнадцатеричные запросы + LRC на лету.Также установите биты данных на 7, а не на 8 !!

using System;
using System.IO.Ports;

class Moneris_Integration
{
    public static void Main()
    {
        SerialPort port = new SerialPort("COM4");

        port.BaudRate = 19200;
        port.Parity = Parity.Even;
        port.StopBits = StopBits.One;
        port.DataBits = 7;      // Changed to 7. Was incorrectly told it was 8.

        port.Open();

        // You'll need to change this to be whatever your app is trying to send at the time
        // Last array item is the LRC. In my case, it was 0x31
        var bytesToSend = new byte[] { 0x02, 0x30, 0x30, 0x1c, 0x30, 0x30, 0x31, 0x31, 0x30, 0x30, 0x30, 0x1c, 0x30, 0x30, 0x32, 0x30, 0x03, 0x31 };

        port.Write(bytesToSend, 0, bytesToSend.Length);

        port.DataReceived += new SerialDataReceivedEventHandler(DataReceivedHandler);

        Console.ReadKey();
    }

    public static byte calculateLRC(byte[] bytes)
    {
        byte LRC = 0;
        for (int i = 0; i < bytes.Length; i++)
        {
            if (i == 0)
            {
                LRC = bytes[i];
            }
            else
            {
                LRC ^= bytes[i];
            }

        }
        return LRC;
    }

    private static void DataReceivedHandler(
    object sender,
    SerialDataReceivedEventArgs e)
    {
        SerialPort sp = (SerialPort)sender;
        string incomingData = sp.ReadExisting();
        Console.WriteLine("Response:");
        Console.Write(incomingData);
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...