Amadis

Skip to end of metadata
Go to start of metadata

You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 34 Next »

  • That series of tutorials use Kizis as the squeleton to build from scratch a basic payment application.

  • Use ACE to trace and monitor behaviors (open ‘'Console Log’' to see traces).

  • These examples have been built using a Visa configuration (Ipaywave213_ICC/CONF_01)

Tutorial #1: set communication and traces using ACE

The very step to avoid difficult integration times: unit test the external communication with ACE.

int main(int argc, char** argv)
{
  // Communication
  int port, length;
  char address[50]="";

  // Get communication parameters from ini file
  xgpiIniSetFilename("agnos.ini");
  xgpiIniGetString("COM", "Address", 50, address, &length);
  xgpiIniGetNumeric("COM", "Port", &port);

  // Initialize ACE
  // Initialize generic communication interface
  assert(tcpInit(0) == TCP_NO_ERROR);

  // Device side is server fro ACE
  assert(comtcpOpen(&gACEServerCOMTCP, TCP_SERVER, 0, port) == COM_NO_ERROR);
  // Device side is also an ACE client
  assert(comtcpOpen(&gACEClientCOMTCP, TCP_CLIENT, address, 1979) == COM_NO_ERROR);

  aceInitializeCommunication(&gACEServerCOMTCP.com,&gACEClientCOMTCP.com);

  // Initialize running mode
  aceSetMode(pmSDK);
	
  // Set ACE option
  aceSetUIDisplay(bTRUE);

  // Tutorial
  aceOut("Training Session - BEGIN\n");
  aceOut("Hello World!\n");
  aceOut("Training Session - END\n");

	return 0;
}

Tutorial #2: initialize language and payment context

int main(int argc, char** argv)
{
	// Trace for debugging
	char tmp[100]="";

	// Communication
	int port, length;
	char address[50]="";

	// System's language
	tByte availableLanguage=0;
	tByte currentLanguage = 0;

	tPaymentContext* pay = &gPaymentCtx;
	tOutComeParameter* out = &gOutcome;

	// Get Communication parameters from ini file
	xgpiIniSetFilename("agnos.ini");
	xgpiIniGetString("COM", "Address", 50, address, &length);
	xgpiIniGetNumeric("COM", "Port", &port);

	// Initialize ACE
	// Initialize generic communication interface
	assert(tcpInit(0) == TCP_NO_ERROR);

	assert(comtcpOpen(&gACEServerCOMTCP, TCP_SERVER, 0, port) == COM_NO_ERROR);
	assert(comtcpOpen(&gACEClientCOMTCP, TCP_CLIENT, address, 1979) == COM_NO_ERROR);

	aceInitializeCommunication(&gACEServerCOMTCP.com,&gACEClientCOMTCP.com);

	// Initialize running mode
	aceSetMode(pmSDK);

	// Set up ACE's options
	aceSetUIDisplay(bTRUE);

	// Tutorial
	aceOut("Training Session - BEGIN\n");
	aceOut("Hello World!\n");// set default language (merchant language indeed)

	// Initialize lines, columns and set string table from lang.ini
	gpiInitializeDisplay("lang.ini",&availableLanguage,NULL); // Assuming that lan.ini supports at least 2 languages
	sprintf(tmp,"Available lang.: %i\n",availableLanguage);
	aceOut(tmp);

	// Initialize payment context and outcome
	pmwInitializePaymentContext(pay);
	pmwSetLanguage(pay,currentLanguage); // Don't forget to propagate language in payment context for further processing
	currentLanguage = pmwGetLanguage(pay);
	pmwInitializeOutComeParameter(out);

	// Important to perform these initializations after pmwInitializePaymentContext
	pay->mAmount = &gAmount;
	pay->mCashBack = &gCashBack;
	pay->mTransactionType = (tTransactionType)0x00;
	gAmount = gCashBack = 0;

	gpiDisplayMessageByID(gpi_true,currentLanguage,WELCOME);
	gpiDisplayMessageByID(gpi_true,currentLanguage+1,THANKS); // Using the next language

	aceOut("Training Session - END\n");

	return 0;
}

Tutorial #3: manage ACE requests

void createFile(char* fileName, tByte* buffer, tWord len)
{
	tFileHandler ifp = 0;

	if (fileName)
	{
		gpiFileDelete(fileName);
		if(gpiFileOpen(fileName,&ifp,CREATE|BINARY)==filNO_ERROR)
		{
			gpiFileWrite(ifp,buffer,len);
			gpiFileClose(ifp);
		}
	}
}

//---------------------------------------------------------
//            Main
//---------------------------------------------------------
//  Main function:
//		- Initialize the platform
//		- Wait for payment trigger
//		- Initialize the data model
//		- Perform a payment
//
//  Visibility: Public
//  Hypothesis: --
//  Reference: --
//
int main(int argc, char** argv)
{
	// Trace for debugging
	char tmp[100]="";

	// Communication
	int port, length;
	char address[50]="";

	// System's language
	tByte availableLanguage=0, currentLanguage = 0;

	tPaymentContext* pay = &gPaymentCtx;
	tOutComeParameter* out = &gOutcome;

	// Get Communication parameters from ini file
	xgpiIniSetFilename("agnos.ini");
	xgpiIniGetString("COM", "Address", 50, address, &length);
	xgpiIniGetNumeric("COM", "Port", &port);

	// Initialize ACE
	// Initialize generic communication interface
	assert(tcpInit(0) == TCP_NO_ERROR);

	assert(comtcpOpen(&gACEServerCOMTCP, TCP_SERVER, 0, port) == COM_NO_ERROR);
	assert(comtcpOpen(&gACEClientCOMTCP, TCP_CLIENT, address, 1979) == COM_NO_ERROR);

	aceInitializeCommunication(&gACEServerCOMTCP.com,&gACEClientCOMTCP.com);

	// Initialize running mode
	aceSetMode(pmSDK);

	// Set up ACE's options
	aceSetUIDisplay(bTRUE);

	// Tutorial
	aceOut("Training Session - BEGIN\n");
	aceOut("Hello World!\n");// set default language (merchant language indeed)

	// Initialize lines, columns and set string table from lang.ini
	gpiInitializeDisplay("lang.ini",&availableLanguage,NULL);
	sprintf(tmp,"Available lang.: %i\n",availableLanguage);
	aceOut(tmp);

	// Initialize payment context and outcome
	pmwInitializePaymentContext(pay);
	pmwSetLanguage(pay,currentLanguage); // Don't forget to propagate language in payment context for further processing
	currentLanguage = pmwGetLanguage(pay);
	pmwInitializeOutComeParameter(out);

	// Important to perform these initializations after pmwInitializePaymentContext
	pay->mAmount = &gAmount;
	pay->mCashBack = &gCashBack;
	pay->mTransactionType = (tTransactionType)0x00;
	gAmount = gCashBack = 0;

	tByte *buffer = NULL;
	tDataFileSize size=0;
	tWord len=0;
	char c, workingString[1000]="";

	gpiGetTotalRAM(&buffer,&size);
	if (!buffer)
		return 0;

	len=0;
	gpiMemSet(buffer,0x00,size);
	gpiMemSet(workingString,0x00,sizeof(workingString));

	// Wait for inbound sale request
	do
	{
		gpiDisplayMessageByID(gpi_true,currentLanguage,WELCOME);
		c = aceGetRequest(buffer,&len);

		if (INIT == c)
		{
			sprintf(workingString,"%sTERMINAL","./AGNOS/");
			createFile(workingString,buffer+1,len-1);
			gpiDisplayMessage(gpi_true,"TERMINAL Updated" );
		}
		else if (CONFIG == c)
		{
			sprintf(workingString,"%sPROCESSING","./AGNOS/");
			createFile(workingString,buffer+1,len-1);
			gpiDisplayMessage(gpi_true,"PROCESSING Updated" );
		}
		else if ( CL_ENTRY_POINT == c)
		{
			sprintf(workingString,"%sENTRY_POINT","./AGNOS/");
			createFile(workingString,buffer+1,len-1);
			gpiDisplayMessage(gpi_true,"ENTRY_POINT Updated" );
		}
		else if ((CAPK == c) && (len >= 21))
		{
			sprintf(workingString,"%sCAKeys","./AGNOS/");
			createFile(workingString,buffer+1,len-1-20);
			gpiDisplayMessage(gpi_true,"CAPK Updated" );
		}
		aceSendResponse((unsigned char*)"\x30\x30",2);
	} while (c != PAYMENT);


	gpiDisplayMessageByID(gpi_true,currentLanguage+1,THANKS);

	aceOut("Training Session - END\n");

	return 0;
}

Tutorial #4: manage a payment request

For this tutorial, code examples rely on previous tutorial. Let’s focus on payment. A comprehensive example is provided below.

  void processRequest(tByte* request, tWord requestLen, tPaymentContext* ctx)
{
	tByte date[4], time[3], datetime[6];
	cursor_t cursorRequest;
	byte_t *value;

	static tByte TRD[500] = "";
	static tWord TRDLength = 0;

	if(!requestLen || !request)
		return;

	gpiMemCpy(TRD,request,requestLen);
	TRDLength = requestLen;


	// Parse TLV stream
	if(tlvInitCursor(request,requestLen,requestLen,&cursorRequest)==TLV_NO_ERROR)
	{
		// Map tags to tPaymentContext structure
		tlvResetCursor(&cursorRequest);
		if(tlvFindTag(0x9C,1,&cursorRequest)==TLV_NO_ERROR)
		{
			value = tlvGetValue(&cursorRequest);
			if(value)
			{
				if(*value==0x00)		ctx->mTransactionType = ttPURCHASE;
				else if(*value==0x01)	ctx->mTransactionType = ttCASH;
				else if(*value==0x09)	ctx->mTransactionType = ttWITH_CASHBACK;
				else					ctx->mTransactionType = ttUNDEFINED;
			}
			else
				ctx->mTransactionType = ttUNDEFINED;
		}
		// as per new GTBI as of december 2014: ctx->mTransactionType is set at initialization time from agnos.ini
		//else
			//ctx->mTransactionType = ttPURCHASE;

		if(ctx->mTransactionType == ttWITH_CASHBACK)
		{
			tlvResetCursor(&cursorRequest);
			if(tlvFindTag(0x9F02,1,&cursorRequest)==TLV_ERR_TAG_NOT_FOUND)
			{
				ctx->mAmount = NULL;
				ctx->mCashBack = NULL;
			}
			else
			{
				if(tlvGetLength(&cursorRequest))
					convertBCDToAmount(ctx->mAmount,tlvGetValue(&cursorRequest),6);
				else
					ctx->mAmount = NULL;

				if(tlvFindTag(0x9F03,1,&cursorRequest)==TLV_ERR_TAG_NOT_FOUND)
					ctx->mCashBack = NULL;
				else
				{
					if(tlvGetLength(&cursorRequest))
						convertBCDToAmount(ctx->mCashBack,tlvGetValue(&cursorRequest),6);
					else
						ctx->mCashBack = NULL;
				}
			}
		}
		else
		{	// ttPURCHASE or ttCASH or ttMANUALCASH or ttREFUND or ttDEPOSIT or dummy value
			tlvResetCursor(&cursorRequest);
			if(tlvFindTag(0x9F02,1,&cursorRequest)==TLV_ERR_TAG_NOT_FOUND)
			{
				ctx->mAmount = NULL;
				ctx->mCashBack = NULL;
			}
			else
			{
				if(tlvGetLength(&cursorRequest))
				{
					convertBCDToAmount(ctx->mAmount,tlvGetValue(&cursorRequest),6);

					tlvResetCursor(&cursorRequest);
					if(tlvFindTag(0x9F03,1,&cursorRequest)==TLV_ERR_TAG_NOT_FOUND)
						ctx->mCashBack = NULL;
					else
					{
						if(tlvGetLength(&cursorRequest))
							convertBCDToAmount(ctx->mCashBack,tlvGetValue(&cursorRequest),6);
						else
							ctx->mCashBack = NULL;
					}
				}
				else
				{
					ctx->mAmount = NULL;
					ctx->mCashBack = NULL;
				}
			}
		}

		tlvResetCursor(&cursorRequest);
		if(tlvFindTag(0x9A,1,&cursorRequest)==TLV_NO_ERROR)
		{
			if(tlvGetValue(&cursorRequest))
			{
				gpiMemCpy(ctx->mTransactionDate,tlvGetValue(&cursorRequest),3);

				// Mantis 0000142: Set date and time from ACE
				// Synchronize system's date from ACE
				datetime[0] = bcdToDecimal(ctx->mTransactionDate[0]);
				datetime[1] = bcdToDecimal(ctx->mTransactionDate[1]);
				datetime[2] = bcdToDecimal(ctx->mTransactionDate[2]);
				gpiGetTime(time);
				gpiMemCpy(datetime+3,time,3);
				gpiSetDateTime(datetime);
			}
			else
			{
				gpiGetDate(date);
				ctx->mTransactionDate[0] = toNumeric(date[1]);
				ctx->mTransactionDate[1] = toNumeric(date[2]);
				ctx->mTransactionDate[2] = toNumeric(date[3]);
			}
		}
		else
		{
			gpiGetDate(date);
			ctx->mTransactionDate[0] = toNumeric(date[1]);
			ctx->mTransactionDate[1] = toNumeric(date[2]);
			ctx->mTransactionDate[2] = toNumeric(date[3]);
		}

		tlvResetCursor(&cursorRequest);
		if(tlvFindTag(0x9F21,1,&cursorRequest)==TLV_NO_ERROR)
		{
			if(tlvGetValue(&cursorRequest))
			{
				gpiMemCpy(ctx->mTransactionTime,tlvGetValue(&cursorRequest),3);

				// Mantis 0000142: Set date and tiem from ACE
				// Synchronize system's time from ACE
				gpiGetDate(date);
				gpiMemCpy(datetime,date+1,3);
				datetime[3] = bcdToDecimal(ctx->mTransactionTime[0]);
				datetime[4] = bcdToDecimal(ctx->mTransactionTime[1]);
				datetime[5] = bcdToDecimal(ctx->mTransactionTime[2]);
				gpiSetDateTime(datetime);
			}
			else
			{
				gpiGetTime(time);
				ctx->mTransactionTime[0] = toNumeric(time[0]);
				ctx->mTransactionTime[1] = toNumeric(time[1]);
				ctx->mTransactionTime[2] = toNumeric(time[2]);
			}
		}
		else
		{
			gpiGetTime(time);
			ctx->mTransactionTime[0] = toNumeric(time[0]);
			ctx->mTransactionTime[1] = toNumeric(time[1]);
			ctx->mTransactionTime[2] = toNumeric(time[2]);
		}

		tlvResetCursor(&cursorRequest);
		if(tlvFindTag(0x5F2A,1,&cursorRequest)==TLV_NO_ERROR)
		{
			if(tlvGetValue(&cursorRequest))
				gpiMemCpy(ctx->mTransactionCurrencyCode,tlvGetValue(&cursorRequest),2);
		}

		tlvResetCursor(&cursorRequest);
		if(tlvFindTag(0x5F36,1,&cursorRequest)==TLV_NO_ERROR)
		{
			if(tlvGetValue(&cursorRequest))
					ctx->mTransactionCurrencyExponent = *(tlvGetValue(&cursorRequest));
		}
	}
}

//---------------------------------------------------------
//            Main
//---------------------------------------------------------
//  Main function:
//		- Initialize the platform
//		- Wait for payment trigger
//		- Initialize the data model
//		- Perform a payment
//
//  Visibility: Public
//  Hypothesis: --
//  Reference: --
//
int main(int argc, char** argv)
{
  // Do all initializations    
  // Wait for inbound sale request
  // See previous tutorials

  // Contexts are empty
  outPaymentContext(pay);
  outOutcomeParameter(out);

  // Fill-up contextes from ACE request
  processRequest(buffer+1,len-1,pay);

  // Contexts are ready
  outPaymentContext(pay);
  outOutcomeParameter(out);

  // Acknomledge payment request
  aceSendResponse((unsigned char*)"\x30\x30",2);

  gpiDisplayMessageByID(gpi_true,currentLanguage+1,THANKS);

  aceOut("Training Session - END\n");

	return 0;
}

Tutorial #5: perform a transaction

  • No labels