📄 atmtrx.cpp
字号:
///////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// IT24 Sistemas S.A.
// Process ATM Transaction Method
//
// Metodo de Procesamiento de Transaccion ATM, con conexion y desconexion a base de
// datos para cada transaccion entrante, con manejo local de parsing del mensaje ISO
// y seteo del codigo de respuesta en el mensaje saliente.
//
// Tarea Fecha Autor Observaciones
// (Inicial) 2001.12.31 mdc Base
// (Inicial) 2002.01.30 mdc Base
// (Inicial) 2002.02.18 mdc Nuevos queries
// (Alfa) 2002.03.12 mdc RED LINK pide "DESTINO O AUTORIZADOR NO DISPONIBLE" para Ult.Mov.
// (Alfa) 2002.05.27 mdc SetOnOffLine( isoMsg.IsValid220() || isoMsg.IsValid221() );
// (Alfa) 2002.05.30 mdc STATEMENT PRINT RESPONSE para un FINANCIAL REQUEST. RED LINK S.A.
// (Alfa) 2002.07.23 mdc if( isoMsg.IsReversalOrAdviceRepeat() )....
// (Beta) 2002.10.10 mdc En vez de "AUTORIZADOR NO DISPONIBLE", se responde "NO SOPORTADA" cuando es reversa
// (Beta) 2003.01.21 mdc 'Extract and Verify RefNum validity'
//
///////////////////////////////////////////////////////////////////////////////////////////////////////////
// Headers ANSI C/C++
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
#include <time.h>
#include <string.h>
#ifndef _SYSTEM_ATM_
#define _SYSTEM_ATM_DEFINED_
#define _SYSTEM_ATM_
#endif // _SYSTEM_ATM_DEFINED_
// Header Transaction Resolution
#include <qusrinc/trxres.h>
// Header ISO Msg Redefinition
#include <qusrinc/isoredef.h>
#ifdef _SYSTEM_ATM_DEFINED_
#undef _SYSTEM_ATM_
#endif // _SYSTEM_ATM_DEFINED_
// Libreria criptografica
#include <qusrinc/crypto.h>
// Libreria de utilidades estandards
#include <qusrinc/stdiol.h>
//////////////////////////////////////////////////////////////////////////
// Toma el valor de la clave de encripcion
// char *=(input) buffer de 24 caracteres + NULL
// retorno=direccion del buffer de entrada
//////////////////////////////////////////////////////////////////////////
extern "C" char *get_encryption_key(char *);
///////////////////////////////////////////////////////////////////////////
// Macro de invocacion de copia de valores campo a campo
#define COPYVALUE(destiny,source) \
if(source && destiny) \
{ \
memset(destiny,' ',sizeof(destiny)); \
memcpy(destiny,source,min(strlen(source),sizeof(destiny))); \
}
///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
// Macro de invocacion de copia de valores exacta campo a campo
#define COPYVALUEEXACT(destiny,source) \
if(source && destiny) \
{ \
memset(destiny,' ',sizeof(destiny)); \
memcpy(destiny,source,min(sizeof(source),sizeof(destiny))); \
}
///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
// Macro de actualizacion de valor en cero
#define SETVALUEZEROE(destiny) \
if(destiny) \
{ \
memset(destiny,'0',sizeof(destiny)); \
}
///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
// Macro de asignacion de causal segun sea OFF y ONLINE
#define ISONOFFLINECAUSE(on,off) (boolOnlineMode == is_true) ? on : off
///////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////
// Implementacion
/////////////////////////////////////////////////////////////////////////////////////
// Constructor
TrxResATM::TrxResATM(void)
{
// CodRta comunes a toda transaccion
rtRespCdeTxt.Insert("99","ERROR INTERNO");
rtRespCdeTxt.Insert("00","OPERACION APROBADA");
// Sin cargar campos ISO en estructuras parseadas
isoFields.bLoaded = is_false;
}
////////////////////////////////////////////////////////////////////////////////////////////////
// Procesamiento de Transacciones ATM.
// Retorna is_true por procesamiento aprobado o no,
// y is_false al hallar algun Error en el Sistema o en el Mensaje ISO-8583.
// Verifica tambien si la respuesta es solicitada (OnLine) o no
// (OffLine) para la copia de datos en el mensaje de retorno.
////////////////////////////////////////////////////////////////////////////////////////////////
boolean_t TrxResATM::ProcessTransaction(void)
{
// Estructuras locales de parsing de Datos desde el Mensaje o BDatos
// Variables para extraccion de Campos del Mensaje ISO-8583/POS/...
BYTE szRespCode[8] = {0},// Resp Code
szTranTyp[8] = {0};// Trx Type (para ATMTRX)
WORD wRespCode = 0,
wTranTypLen = 0,
wRspCdeLen = 0;
CONST WORD cwDefaultCause = 0;
// Ok o Error?
boolean_t bProcResult = is_false;// Procesamiento OK?
boolean_t bIsReversal = is_false;// Es reverso?
const boolean_t bStmtPrint_forced = is_false; // No forzar STATEMENT PRINT
const boolean_t bIgnoreAdvRepeat = is_false; // No ignorar ADVICE REEPAT (0221)
///////////////////////////////////////////////////////////////
BYTE szRefNum[sizeof(FIELD37)+1] = {0}; // Reference Number
WORD wLen = 0; // Reference Number length
///////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////
// Antes de modificar el requerimiento como respuesta,
// guardar un backup original para no perder los datos !
isoMsgBkp = isoMsg;
///////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////
// Extract TranTyp
wTranTypLen = sizeof(szTranTyp)-1;
if(!isoMsg.GetMsgTypeId( (PBYTE)&szTranTyp, wTranTypLen ))
{
// On error, set Message Type Response
if(!isoMsg.SetMsgTypeIdResponse())
return (is_false);
// Codigo de Respuesta erroneo
isoMsg.InsertField(39, &(wRspCdeLen=2), (PBYTE)CISO_INVALID_FORMAT, 2 );
// Ok por procesado, aunque no por aprobado
return (is_true);
};//end-if-trantype
////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////
// Extract and Verify RefNum validity
wLen = sizeof(szRefNum)-1;
if(isoMsg.GetField(37, &wLen, szRefNum, wLen ))
{
// Verify NUMERIC content
if( strnumlenpad( (char *)szRefNum, sizeof(FIELD37), ' ') != sizeof(FIELD37) )
{
// On error, set Message Type Response
isoMsg.SetMsgTypeIdResponse();
// Codigo de Respuesta erroneo, segun sea SAF o no
if( isoMsg.IsFinancialAdvice() || isoMsg.IsReversalOrAdviceRepeat() )
isoMsg.InsertField(39, &(wRspCdeLen=2), (PBYTE)CISO_EXTERNAL_DECLINE, 2 );
else
isoMsg.InsertField(39, &(wRspCdeLen=2), (PBYTE)CISO_INVALID_FORMAT, 2 );
// Ok por procesado, aunque no por aprobado
return (is_true);
}
};//end-if-refnum
////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////
// Conexion y desconexion a Base de Datos por cada Transaccion,
// accediendo con usuario-odbc y contrasena respectiva
// OBSERVACIONES : EN ESTA CASO NO CORRESPONDE YA QUE EXISTE SESION RPC PREVIA
////////////////////////////////////////////////////////////////////////////////////
// Procesar toda otra transaccion de ATM
if( isoMsg.IsATMTransaction() )
{
// Por default e inicialmente, el codigo de respuesta es ERROR,
// para la transaccion en curso
wRespCode = CISO_DESTINY_NOT_AVAILABLE_I;
// Es reverso? Verificar en el mensaje ISO y pasar luego un booleano
bIsReversal = ( isoMsg.IsValidReversal() )
? is_true
: is_false; // Reversal or Rvsl.Repeat?
// Si es FORZADO (Fin.Adv.0220 o 0221), habilitar el MODO OFFLINE del HOST-DPC
// SetOnOffLine(TRUE : ONLINE, FALSE : OFFLINE)
if(!SetOnOffLine( isoMsg.IsFinancialAdvice() ? is_false : is_true ))
///////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////
{
isoMsg.SetMsgTypeIdResponse();
isoMsg.InsertField(39, &(wRspCdeLen=2), (PBYTE)CISO_INVALID_TRANSACTION, 2 );
return (is_true);
};
///////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////
// Segun el tipo de transaccion, procesar...
// Repeticion de Forzado, siempre y cuando no deba ignorarse....
///////////////////////////////////////////////////////////////////////////////////
if( is_true == bIgnoreAdvRepeat && isoMsg.IsReversalOrAdviceRepeat() )
{
// No soportada
wRespCode = CISO_INVALID_TRANSACTION_I;
}
///////////////////////////////////////////////////////////////////////////////////
else if(is_true == bIsReversal) // Es reversa generica para cualquier transaccion?
{
//////////////////////////////////////////////////////////////
// No procesar reversos de consultas
if( isoMsg.IsATMLastMovInquiry() ||
isoMsg.IsATMBalanceInquiry() ||
isoMsg.IsATMOthersMsgs() )
{
// Completar campos de respuesta en BLANCOS y RECHAZAR TRX.
// Formatear campo ISO #44, RESP_DATA, saldo y disponible
FormatField44_RESP_DATA( NULL,NULL );
// Formatear campo ISO #122, SECNDRY_RSRVD3_PRVT
FormatField122_SECNDRY_RSRVD3_PRVT();
// Formatear campo ISO #123, SECNDRY_RSRVD4_PRVT, "DEPOSIT AMMOUNT"
FormatField123_SECNDRY_RSRVD4_PRVT();
// No soportada
wRespCode = CISO_INVALID_TRANSACTION_I;
}
else
wRespCode = ProcessReversal(cwDefaultCause);
//////////////////////////////////////////////////////////////
}
else if(isoMsg.IsATMBalanceInquiry()) // Consulta de saldos
wRespCode = ProcessBalanceInquiry(cwDefaultCause,bIsReversal);
else if(isoMsg.IsATMTransfer()) // Transferencia cuentas relacionadas
wRespCode = ProcessTransfer(cwDefaultCause,bIsReversal);
else if(isoMsg.IsATMTransferInterbank()) // Transferencia interbancaria
wRespCode = ProcessTransferInterbank(cwDefaultCause,bIsReversal);
else if(isoMsg.IsATMTransferCBU()) // Transferencia minorista x CBU
wRespCode = ProcessIndividualTransfer(cwDefaultCause,bIsReversal);
else if(isoMsg.IsATMWithdrawal()) // Extraccion
wRespCode = ProcessWithdrawal(cwDefaultCause,bIsReversal);
else if(isoMsg.IsATMDeposit()) // Deposito
wRespCode = ProcessDeposit(cwDefaultCause,bIsReversal);
else if(isoMsg.IsATMFastCash()) // FastCash o compra
wRespCode = ProcessFastCash(cwDefaultCause,bIsReversal);
else if(isoMsg.IsATMAccountVerification()) // Verificacion cuenta destino
wRespCode = ProcessAccountVerification(cwDefaultCause,bIsReversal);
else if(isoMsg.IsATMPayment()) // Pagos
wRespCode = ProcessPayment(cwDefaultCause,bIsReversal);
else if(isoMsg.IsATMBuying()) // Compras y relacionados
wRespCode = ProcessBuying(cwDefaultCause,bIsReversal);
else if(isoMsg.IsATMAutServicePayment()) // Pagos Automatico de Servs.
wRespCode = ProcessAutServicePayment(cwDefaultCause,bIsReversal);
else if(isoMsg.IsATMOthersMsgs()) // Otros mensajes al banco
wRespCode = ProcessOtherMsgs(cwDefaultCause,bIsReversal);
else if(isoMsg.IsATMLastMovInquiry()) // Consulta ultimos movimientos
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -