// Executa a captura de dado solicitada pela biblioteca private int ShowCorrespondingWindow(PW_GetData[] expectedData, ref FormDisplayQRcode fdqr) { int ret = 0; ushort index = 0; FormDisplayMessage fdm; foreach (PW_GetData item in expectedData) { // Caso exista uma mensagem a ser exibida ao usuário antes da captura do dado if (item.szMsgPrevia.Length > 0) { fdm = new FormDisplayMessage(); fdm.ShowDialog(item.szMsgPrevia, 3000); fdm.Dispose(); } ret = 0; switch (item.bTipoDeDado) { case 0: Debug.Print(string.Format("ERRO!!! Item com valor zerado.")); return(ret); // Caso a automação trabalhe com captura de código de barras, necessário // implementar os casos que serão aceitos (digitado, leitor...), bem como // as validações necessárias por tipo de código case (int)E_PWDAT.PWDAT_BARCODE: ret = GetTypedDataFromUser(item); return(ret); // Menu de opções case (int)E_PWDAT.PWDAT_MENU: return(GetMenuFromUser(item)); // Captura de dado digitado case (int)E_PWDAT.PWDAT_TYPED: ret = GetTypedDataFromUser(item); return(ret); // Autenticação de permissão de usuário case (int)E_PWDAT.PWDAT_USERAUTH: ret = GetTypedDataFromUser(item); return(ret); // Captura de dados do cartão case (int)E_PWDAT.PWDAT_CARDINF: // Caso só seja aceito o modo de entrada de cartão digitado if (item.ulTipoEntradaCartao == 1) { PW_GetData temp = item; temp.wIdentificador = (ushort)E_PWINFO.PWINFO_CARDFULLPAN; ret = GetTypedDataFromUser(temp); } // Caso seja aceito cartão lido pelo PIN-pad else { ret = Interop.PW_iPPGetCard(index); Debug.Print(string.Format("PW_iPPGetCard={0}", ret.ToString())); if (ret == (int)E_PWRET.PWRET_OK) { ret = LoopPP(); } } return(ret); // Processamento offline do cartão case (int)E_PWDAT.PWDAT_CARDOFF: ret = Interop.PW_iPPGoOnChip(index); Debug.Print(string.Format("PW_iPPGoOnChip={0}", ret.ToString())); if (ret == (int)E_PWRET.PWRET_OK) { ret = LoopPP(); } return(ret); // Processamento online do cartão case (int)E_PWDAT.PWDAT_CARDONL: ret = Interop.PW_iPPFinishChip(index); Debug.Print(string.Format("PW_iPPFinishChip={0}", ret.ToString())); if (ret == (int)E_PWRET.PWRET_OK) { ret = LoopPP(); } return(ret); // Confirmação de dado no PIN-pad case (int)E_PWDAT.PWDAT_PPCONF: ret = Interop.PW_iPPConfirmData(index); Debug.Print(string.Format("PW_iPPConfirmData={0}", ret.ToString())); if (ret == (int)E_PWRET.PWRET_OK) { ret = LoopPP(); } return(ret); // Confirmação positiva PIN-pad case (int)E_PWDAT.PWDAT_PPDATAPOSCNF: ret = Interop.PW_iPPPositiveConfirmation(index); Debug.Print(string.Format("PW_iPPPositiveConfirmation={0}", ret.ToString())); if (ret == (int)E_PWRET.PWRET_OK) { ret = LoopPP(); } return(ret); // Comando genérico no PIN-pad case (int)E_PWDAT.PWDAT_PPGENCMD: ret = Interop.PW_iPPGenericCMD(index); Debug.Print(string.Format("PW_iPPGenericCMD={0}", ret.ToString())); if (ret == (int)E_PWRET.PWRET_OK) { ret = LoopPP(); } return(ret); // Senha do portador case (int)E_PWDAT.PWDAT_PPENCPIN: ret = Interop.PW_iPPGetPIN(index); Debug.Print(string.Format("PW_iPPGetPIN={0}", ret.ToString())); if (ret == (int)E_PWRET.PWRET_OK) { ret = LoopPP(); } return(ret); // Entrada digitada no PIN-pad case (int)E_PWDAT.PWDAT_PPENTRY: ret = Interop.PW_iPPGetData(index); Debug.Print(string.Format("PW_iPPGetData={0}", ret.ToString())); if (ret == (int)E_PWRET.PWRET_OK) { ret = LoopPP(); } return(ret); // Remoção de cartão do PIN-pad case (int)E_PWDAT.PWDAT_PPREMCRD: ret = Interop.PW_iPPRemoveCard(); Debug.Print(string.Format("PW_iPPRemoveCard={0}", ret.ToString())); if (ret == (int)E_PWRET.PWRET_OK) { ret = LoopPP(); } return(ret); // Exibição de mensagem de interface no display da automação case (int)E_PWDAT.PWDAT_DSPCHECKOUT: fdm = new FormDisplayMessage(); fdm.Start(); fdm.ChangeText(item.szPrompt); Thread.Sleep(1000); // Caso o operador tenha apertado a tecla ESC, cancela a operação e aborta o comando do PINpad if (fdm.isAborted()) { // Aborta a operação em curso no PIN-pad Interop.PW_iPPAbort(); // Atribui o retorno de aoperação cancelada ret = (int)E_PWRET.PWRET_CANCEL; } fdm.Stop(); if (ret != (int)E_PWRET.PWRET_OK) { return(ret); } // Sinaliza a exibição da mensagem para a biblioteca ret = Interop.PW_iAddParam(item.wIdentificador, ""); return((int)E_PWRET.PWRET_OK); // Exibição de QRcode no display da automação case (int)E_PWDAT.PWDAT_DSPQRCODE: // Exemplo 2: A string com o QR Code é recebida e um QRcode é gerado utilizando uma biblioteca // de terceiros, para compilar essa opção é necessário descomentar a função AtualizaQRCode na classe FormDisplayQRcode // e instalar a biblioteca MessagingToolkit.QRCode em seu Visual studio através do gerenciador de pacotes // com o comando "Install-Package MessagingToolkit.QRCode -ProjectName PGWLib" StringBuilder stringQRcode = new StringBuilder(5001); // Tenta obter o valor do QRcode a ser exibido, caso não ache retorna operação cancelada if (Interop.PW_iGetResult((short)E_PWINFO.PWINFO_AUTHPOSQRCODE, stringQRcode, 5001) != (int)E_PWRET.PWRET_OK) { return((int)E_PWRET.PWRET_CANCEL); } // Exibe o QRcode e o prompt fdqr.Start(); // Para esse caso em específico o QR code é muito grande para exibir no display "padrão" // Somente para esse exemplo, liga o autoSize da janela fdqr.ChangeText(item.szPrompt, stringQRcode.ToString()); // Caso o operador tenha apertado a tecla ESC, cancela a operação e aborta o comando do PINpad if (fdqr.isAborted()) { // Aborta a operação em curso no PIN-pad Interop.PW_iPPAbort(); fdqr.Stop(); // Atribui o retorno de aoperação cancelada return((int)E_PWRET.PWRET_CANCEL); } // Sinaliza a exibição do QRcode para a biblioteca ret = Interop.PW_iAddParam(item.wIdentificador, ""); return((int)E_PWRET.PWRET_OK); default: break; } index++; } return(ret); }
// Executa o loop da transação até que ela seja aprovada ou ocorra algum erro private int ExecuteTransaction() { int ret; FormDisplayQRcode fdqr = new FormDisplayQRcode(); // Loop que só será interrompido em caso da finalização da transação, seja ela por algum // tipo de erro ou com o sucesso for (; ;) { // Cria a estrutura necessária para executar a função PW_iExecTransac, caso seja // necessário capturar algum dado, essa estrutura terá detalhes de como deverá ser feita // essa captura PW_GetData[] structParam = new PW_GetData[10]; // Parâmetro que, na entrada, indica quantos registros possui a estrutura PW_GetData e // na saída indica quantos dados precisam ser capturados short numDados = 10; // Desmarca o desfazimento marcado por segurança, pois a transação irá para // controle pela biblioteca PendencyDelete(); // Chama a função que executa um passo da transação ret = (int)Interop.PW_iExecTransac(structParam, ref numDados); // Marca um desfazimento por segurança, caso a automação seja fechada abruptamente // durante qualquer passo abaixo, o desfazimento já estará armazenado em disco para // ser executado por PendencyResolve antes da próxima transação // Esse desfazimento será desmarcado em duas situações: // 1-) O loop foi executado novamente e PW_iExecTransac será chamada // 2-) Algum erro ocorreu durante o loop // 3-) A transação foi finalizada com sucesso, nesse caso o desfazimento permanecerá // gravado até a execução da resolução de pendência da transação em // "ConfirmUndoNormalTransaction" PendencyWrite(E_PWCNF.PWCNF_REV_PWR_AUT); // Registra na janela de debug o resultado da execução Debug.Print(string.Format("PW_iExecTransac={0}", ret.ToString())); // Faz o tratamento correto de acordo com o retorno recebido em PW_iExecTransac switch (ret) { // Caso a biblioteca tenha solicitado a captura de mais dados, chama a função que // faz a captura de acordo com as informações contidas em structParam case (int)E_PWRET.PWRET_MOREDATA: int ret2 = ShowCorrespondingWindow(structParam, ref fdqr); if (ret2 != (int)E_PWRET.PWRET_OK) { if (ret2 == (int)E_PWRET.PWRET_CANCEL) { // Apaga o status de desfazimento anterior por desligamento abrupto da // automação PendencyDelete(); // Escreve o novo desfazimento a ser executado por transação abortada // pela automação durante uma captura de dados PendencyWrite(E_PWCNF.PWCNF_REV_ABORT); } return(ret2); } break; // Caso a biblioteca tenha retornado que existe uma transação pendente. // Esse retorno só irá acontecer em caso de alguma falha de tratamento da resolução // de pendência da transação por parte da automação, ou alguma falha de sistema // do Pay&Go WEB, caso um ponto de captura fique com uma transação pendente ele não // irá poder realizar novas transações até que essa pendência seja resolvida case (int)E_PWRET.PWRET_FROMHOSTPENDTRN: // Desmarca o desfazimento marcado por segurança, pois a transação não foi // finalizada com sucesso PendencyDelete(); return(ret); // Esse retorno indica que nada deve ser feito e PW_iExecTransac deve ser chamada // novamente para prosseguir o fluxo case (int)E_PWRET.PWRET_NOTHING: break; // Esse retorno indica que a transação foi executada com sucesso case (int)E_PWRET.PWRET_OK: // Para de exibir o QRcode, caso exista um sendo exibido fdqr.Stop(); return(ret); // Qualquer outro código de retorno representa um erro default: // Para de exibir o QRcode, caso exista um sendo exibido fdqr.Stop(); // Desmarca o desfazimento marcado por segurança, pois a transação não foi // finalizada com sucesso PendencyDelete(); return(ret); } } }