Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations biv343 on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Payment method

Status
Not open for further replies.

RitwickGupta

Programmer
Aug 21, 2014
96
CA
Hi,

I am making a program which allows you to open a new screen for payment when my payment option is clicked on tender screen. This interface for payment will be opened by a DLL function which will be called by my ISL code and I was hoping to return back values like Status and Payment_reference_code to ISL function to tell if the payment was a pass of a fail. After that I will close the current Check if the payment was a Pass.

What I want to know is do I need to use TxMsg for my method? I am unclear about when to use TxMsg and How do I send that TxMsg to my third party system.

Also, how do I close a Check on POS through ISL code?

Thanks
 
You only need to use TxMsg when communicating with a TCP/IP connection to your interface. If you are using a DLL, you use references to set the value of variables. I never made it very far with DLL's, given I have no idea how to compile one for the WinCE micros system, and have only ever gotten to work for my Win32 systems. So I don't do it very often.

To close the check just use a loadkybdmacro to ring in your tender and close the check. They will have to setup a tender in their system, and then link it to your system so that it can ring it in.
 
Hello,

Thanks for the reply. I guess I am going to try the DLL thing first, as my friend is an expert in windows and .NET programming.

What do you mean by ring in the tender? I am not aware of it and can't find it in Micros 3700 SIM manual. Can you point me in the right direction?

What I have done as of now is crated a button on tender screen for my tender type "PaymentXXX" and when the operator hits that button, I am planning to fire a SIM event, which will call the DLL function, which will do the payment and if it's a success, I will close that ticket and if possible, assign a reference number to it.
 

and here is a sample SIM you can look at:

Code:
RETAINGLOBALVAR
VAR SQL_H   : N12
VAR SQL_FF  : N1
VAR I       : N10
VAR LINE    : A200

VAR CHARGE_TIP : N9
VAR REDEEM_TND : N9
VAR PRINT_CONT : N9

VAR CARD_TRACK  : N2
VAR CARD_START  : N2
VAR CARD_LENGTH : N2

VAR PRINT_SIG : N1
VAR PRINT_CCN : N100
VAR PRINT_AMT : $12
VAR PRINT_VAL : $12

////
// EVENTS
////

EVENT INQ : 1

	IF @INSTANDALONEMODE = 1 OR @INBACKUPMODE = 1
		EXITWITHERROR "FUNCTION NOT AVAILABLE", "Cannot Talk to MICROS Database"
	ENDIF
	CALL READ_CFG( CHARGE_TIP, REDEEM_TND, PRINT_CONT )
	//Open SQL connection
	CALL SQL_LOAD
	
	//Load information about GSS Gift Card setup
	CALL GET_CARD_SETUP( CARD_TRACK, CARD_START, CARD_LENGTH )
	
	//Read Card Swipe
	VAR CARD_DATA : N(CARD_LENGTH)
	CALL SWIPE_CARD( CARD_TRACK, CARD_START, CARD_LENGTH, CARD_DATA )
	//Attempt to read Card Balance
	VAR BALANCE : $12
	CALL GET_BALANCE( CARD_DATA, BALANCE )
	IF BALANCE < 0
		EXITWITHERROR "Card Not Found"
	ENDIF
	IF BALANCE = 0
		EXITWITHERROR "Card Balance is Zero"
	ENDIF
	
	//Get Current Authorizations
	VAR CARD_NUMS[ 8 ] : N(CARD_LENGTH)
	VAR CARD_VALS[ 8 ] : $12
	VAR NUM_CARDS : N1
	CALL GET_AUTHS( CARD_NUMS[], CARD_VALS[], NUM_CARDS )
	IF NUM_CARDS >= 8
		EXITWITHERROR "Maximum of eight authorizations reached"
	ENDIF
	
	//Check how much they are trying to auth the card for
	VAR AUTH_AMT : $12
	//If there is a user entry, we only need to compare it to the current balance and @Ttldue
	IF @USERENTRY <> 0
		AUTH_AMT = @USERENTRY
		IF AUTH_AMT > BALANCE
			FORMAT LINE AS "Insufficient Funds", CHR(10), "Balance: $", BALANCE
			EXITWITHERROR LINE
		ENDIF
		IF AUTH_AMT > @TTLDUE
			EXITWITHERROR "Cannot Over-tender Check"
		ENDIF
	ELSE
		IF AUTH_AMT > BALANCE
			FORMAT LINE AS "Insufficient Funds", CHR(10), "Balance: $", BALANCE
			EXITWITHERROR LINE
		ENDIF
		AUTH_AMT = 0
		FOR I = 1 TO NUM_CARDS
			IF CARD_DATA <> CARD_NUMS[ I ]
				AUTH_AMT = AUTH_AMT + CARD_VALS[ I ]
			ENDIF
		ENDFOR
		AUTH_AMT = @TTLDUE - AUTH_AMT
	ENDIF
	IF AUTH_AMT <= 0
		EXITWITHERROR "Cannot Authorize Card for $0"
	ENDIF
	
	//Ok - So we are ready to authorize the card. Determine if we are re-authorizing a card
	VAR CARD_POS : N1 = 0
	FOR I = 1 TO NUM_CARDS
		IF CARD_NUMS[I] = CARD_DATA
			CARD_POS = I
			BREAK
		ENDIF
	ENDFOR
	IF CARD_POS = 0
		CARD_POS = NUM_CARDS + 1
		NUM_CARDS = NUM_CARDS + 1
	ENDIF
	CARD_NUMS[ CARD_POS ] = CARD_DATA
	CARD_VALS[ CARD_POS ] = AUTH_AMT
	
	CALL SAVE( CARD_NUMS[], CARD_VALS[], NUM_CARDS )
	PRINT_SIG = 1
	PRINT_CCN = TRIM(CARD_DATA)
	PRINT_AMT = AUTH_AMT
	PRINT_VAL = BALANCE - AUTH_AMT
	LOADKYBDMACRO KEY(9, PRINT_CONT)
	//Close SQL Connection
	CALL SQL_CLOSE
ENDEVENT

EVENT INQ : 2
	IF @INSTANDALONEMODE = 1 OR @INBACKUPMODE = 1
		EXITWITHERROR "FUNCTION NOT AVAILABLE", "Cannot Talk to MICROS Database"
	ENDIF
	CALL READ_CFG( CHARGE_TIP, REDEEM_TND, PRINT_CONT )
	CALL SQL_LOAD
	
	CALL GET_CARD_SETUP( CARD_TRACK, CARD_START, CARD_LENGTH )
	VAR CARD_NUMS[ 8 ] : A(CARD_LENGTH)
	VAR CARD_VALS[ 8 ] : $12
	VAR NUM_CARDS : N1
	CALL GET_AUTHS( CARD_NUMS[], CARD_VALS[], NUM_CARDS )
	
	VAR CLOSE_FOR : $12 = @USERENTRY
	VAR TIP_AMT : $12
	VAR RESULT : N10
	VAR MESSAGE : A100
	VAR CARD_TO_CLOSE : N1
	IF NUM_CARDS < 1
		EXITWITHERROR "No Gift Card Authorizations Exist"
	ENDIF
	IF NUM_CARDS = 1
		CARD_TO_CLOSE = 1
	ELSE
		CALL GET_CARD_CHOICE(RESULT, CARD_NUMS[], CARD_VALS[], NUM_CARDS)
		IF RESULT < 0 OR RESULT > NUM_CARDS
			EXITWITHERROR "Invalid Choice"
		ENDIF
		CARD_TO_CLOSE = RESULT
	ENDIF
	
	IF CLOSE_FOR = 0
		CLOSE_FOR = CARD_VALS[ CARD_TO_CLOSE ]
	ENDIF
	IF CARD_VALS[ CARD_TO_CLOSE ] >= @TTLDUE AND CLOSE_FOR >= CARD_VALS[ CARD_TO_CLOSE ]
		TIP_AMT = CLOSE_FOR - @TTLDUE
		FORMAT MESSAGE AS "Charge Tip Amount is ", TIP_AMT, "?"
		CALL GET_YES_NO( RESULT, MESSAGE )
		IF RESULT <> 1
			EXITCONTINUE
		ENDIF
	ELSE
		CALL GET_TIP_AMT( TIP_AMT )
	ENDIF
	IF TIP_AMT < 0
		EXITCONTINUE
	ENDIF
	IF TIP_AMT > 0
		IF @CCAUTH_COUNT > 0
			LOADKYBDMACRO MAKEKEYS(TIP_AMT), KEY(7, CHARGE_TIP), MAKEKEYS(CLOSE_FOR), KEY(9, REDEEM_TND), @KEY_CLEAR, MAKEKEYS(CARD_NUMS[ CARD_TO_CLOSE ]), @KEY_ENTER
		ELSE
			LOADKYBDMACRO MAKEKEYS(TIP_AMT), KEY(7, CHARGE_TIP), MAKEKEYS(CLOSE_FOR), KEY(9, REDEEM_TND), MAKEKEYS(CARD_NUMS[ CARD_TO_CLOSE ]), @KEY_ENTER
		ENDIF
	ELSE
		IF @CCAUTH_COUNT > 0
			LOADKYBDMACRO MAKEKEYS(CLOSE_FOR), KEY(9, REDEEM_TND), @KEY_CLEAR, MAKEKEYS(CARD_NUMS[ CARD_TO_CLOSE ] ), @KEY_ENTER
		ELSE
			LOADKYBDMACRO MAKEKEYS(CLOSE_FOR), KEY(9, REDEEM_TND), MAKEKEYS(CARD_NUMS[ CARD_TO_CLOSE ]), @KEY_ENTER
		ENDIF
	ENDIF
	
	CALL SQL_CLOSE
ENDEVENT

EVENT PRINT_TRAILER : GssAuthTrailer

	IF PRINT_SIG = 0
		EXITCONTINUE
	ENDIF

	VAR LINE : A200
	FORMAT LINE AS "Card: ", PRINT_CCN
	@TRAILER[ 1 ] = LINE

	FORMAT LINE AS "Authed For: ", PRINT_AMT
	@trailer[ 2 ] = line
	
	FORMAT LINE AS "New Balance: ", PRINT_VAL
	@TRAILER[ 3 ] = line
	@TRAILER[ 4 ] = " "
	@TRAILER[ 5 ] = " "

	@TRAILER[ 6 ] = "Tip:____________________________"
	@TRAILER[ 7 ] = " "
	@TRAILER[ 8 ] = " "
	@TRAILER[ 9 ] = "Total:__________________________"
	@TRAILER[ 10 ] = " "
	@TRAILER[ 11 ] = " "
	@TRAILER[ 12 ] = " "
	@TRAILER[ 13 ] = "________________________________"
	@TRAILER[ 14 ] = "Signature"

	PRINT_SIG = 0

ENDEVENT

////
// GSS SUBROUTINES
////

SUB SAVE( REF CARD_NUMS[], REF CARD_VALS[], REF NUM_CARDS )
	VAR LINE : A500
	FOR I = 1 TO NUM_CARDS
		FORMAT LINE AS "CARD: ", CARD_NUMS[I]
		SAVECHKINFO LINE
		FORMAT LINE AS "AUTH AMT: ", CARD_VALS[I]
		SAVECHKINFO LINE
	ENDFOR
ENDSUB

SUB GET_BALANCE( REF CARD_DATA, REF BALANCE )
	VAR SQL_CMD : A2000
	FORMAT SQL_CMD AS "SELECT current_value FROM MICROS.gss_gift_certificate_dtl WHERE card_data = '", CARD_DATA, "'"
	CALL SQL_QUERY( SQL_CMD )
	CALL SQL_FETCH( SQL_CMD )
	IF SQL_CMD = ""
		BALANCE = -1
	ELSE
		BALANCE = SQL_CMD
	ENDIF
ENDSUB

SUB SWIPE_CARD( VAR CARD_TRACK : N2, VAR CARD_START : N2, VAR CARD_LENGTH : N2, REF RESULT )
	VAR DATA : A200
	IF CARD_TRACK = 1
		INPUT DATA{M1,*}, "Swipe Gift Card"
	ELSE
		INPUT DATA{M2,*}, "Swipe Gift Card"
	ENDIF
	IF @MAGSTATUS = "Y"
		RESULT = MID(DATA,1,CARD_LENGTH)
	ELSE
		IF LEN(DATA) > CARD_LENGTH
			EXITWITHERROR "Invalid Card Number"
		ENDIF
		RESULT = MID(DATA,1,CARD_LENGTH)
	ENDIF
ENDSUB

SUB GET_CARD_SETUP( REF TRACK, REF START, REF LENGTH )
	VAR SQL_CMD : A2000
	
	FORMAT SQL_CMD AS "SELECT card_number_track, card_number_start, card_number_len FROM MICROS.gss_restaurant_def"
	CALL SQL_QUERY( SQL_CMD )
	CALL SQL_FETCH( SQL_CMD )
	
	IF SQL_CMD = ""
		EXITWITHERROR "GSS Card Setup Not Found"
	ENDIF
	
	SPLIT SQL_CMD, ";", TRACK, START, LENGTH
ENDSUB

SUB GET_AUTHS( REF CARD_NUMBERS[], REF CARD_BALANCES[], REF NUM_CARDS )
	VAR I : N2
	VAR SQL_CMD : A2000

	FORMAT SQL_CMD AS "SELECT line_01, line_02, line_03, line_04, line_05, line_06, line_07, line_08, line_09, line_10, line_11, line_12, line_13, line_14, line_15, line_16 FROM MICROS.chk_info_dtl WHERE chk_seq = ", @CkSeqNum
	
	CALL SQL_QUERY( SQL_CMD )
	CALL SQL_FETCH( SQL_CMD )
	IF SQL_CMD = ""
		NUM_CARDS = 0
		RETURN
	ENDIF
	VAR LINES[ 16 ] : A500
	SPLIT SQL_CMD, ";", LINES[1], LINES[2], LINES[3], LINES[4], LINES[5], LINES[6], LINES[7], LINES[8], LINES[9], LINES[10], LINES[11], LINES[12], LINES[13], LINES[14], LINES[15], LINES[16]
	FOR I = 1 TO 16 STEP 2
		LINES[I] = TRIM(LINES[I])
		IF MID(LINES[I], 1, 5) = "CARD:"
			IF MID(LINES[I+1], 1, 9) = "AUTH AMT:"
				NUM_CARDS = NUM_CARDS + 1
				CARD_NUMBERS[ NUM_CARDS ] = MID(LINES[I], 7, CARD_LENGTH)
				CARD_BALANCES[ NUM_CARDS ] = MID(LINES[I+1], 11, LEN(LINES[I+1])-9)
			ENDIF
		ENDIF
	ENDFOR
ENDSUB

////
// HELPERS
////

SUB READ_CFG( REF CHARGE_TIP, REF REDEEM_TND, REF PRINT_CONT )
	VAR FILE : A200 = "gss_auth.cfg"
	VAR FN : N9
	VAR I : N2
	VAR LINE : A100
	FOPEN FN,FILE, READ
	IF FN = 0
		FOPEN FN, "\cf\micros\etc\gss_auth.cfg", READ
	ENDIF
	IF FN = 0 OR @FILE_ERRNO <> 0
		EXITWITHERROR @FILE_ERRSTR
	ENDIF
	VAR PARM : A10
	WHILE NOT FEOF(FN)
		FREADLN FN, LINE
		IF LEN(LINE) > 11
			PARM = MID(LINE,1,10)
			IF PARM = "CHARGE_TIP"
				CHARGE_TIP = MID(LINE,12,LEN(LINE)-11)
			ENDIF
			IF PARM = "REDEEM_TND"
				REDEEM_TND = MID(LINE,12,LEN(LINE)-11)
			ENDIF
			IF PARM = "PRINT_CONT"
				PRINT_CONT = MID(LINE,12,LEN(LINE)-11)
			ENDIF
		ENDIF
	ENDWHILE
	FCLOSE FN
ENDSUB

SUB GET_YES_NO( REF ANSWER, VAR MESSAGE : A78 )
	CLEARISLTS
		SETISLTSKEYX 2, 10, 4, 4, 2, @KEY_ENTER, 10059, "LEFT", 10, "YES"
		SETISLTSKEYX 2, 16, 4, 4, 2, @KEY_CLEAR, 10058, "LEFT", 10, "NO"
		SETISLTSKEYX 11, 12, 2, 6, 2, @KEY_CANCEL, 10392, "LEFT", 10, "CANCEL"
	DISPLAYISLTS
	
	VAR CENTER : N3 = (78-LEN(MESSAGE))/2
	WINDOW 3,78
	DISPLAY 2, CENTER, MESSAGE
	
	VAR KEY_PRESS : KEY
	VAR DATA : A20
	INPUTKEY KEY_PRESS, DATA, MESSAGE
	
	IF KEY_PRESS = @KEY_ENTER
		ANSWER = 1
	ELSEIF KEY_PRESS = @KEY_CANCEL
		EXITCONTINUE
	ELSE
		ANSWER = 0
	ENDIF
	WINDOWCLOSE
ENDSUB

SUB GET_CARD_CHOICE( REF ANSWER, REF CARD_NUMS[], REF CARD_VALS[], VAR NUM_CARDS : N1 )
	VAR MESSAGE : A80 = "Choose Gift Card to Close"
	VAR SQL_CMD : A2000
	SQL_CMD = "SELECT obj_num FROM MICROS.ts_scrn_def WHERE ts_scrn_seq = (SELECT FIRST numeric_ts_scrn_seq FROM MICROS.rvc_add_def WHERE numeric_ts_scrn_seq is not null ORDER BY numeric_ts_scrn_seq)"
	CALL SQL_QUERY( SQL_CMD )
	CALL SQL_FETCH( SQL_CMD )
	
	VAR NUMERIC_TS : N9 = SQL_CMD
	IF NUMERIC_TS > 0
		TOUCHSCREEN NUMERIC_TS
	ENDIF
	
	VAR CENTER : N3 = (78-LEN(MESSAGE))/2
	WINDOW NUM_CARDS+2,78
	DISPLAY 1, CENTER, MESSAGE
	VAR I : N1
	VAR ROW : N1 = 3
	FOR I = 1 TO NUM_CARDS
		FORMAT MESSAGE AS I, ".    ", CARD_NUMS[I], " ($", CARD_VALS[I], ")"
		DISPLAY ROW, 3, MESSAGE
		ROW = ROW + 1
	ENDFOR
	
	VAR KEY_PRESS : KEY
	VAR DATA : A20
	INPUTKEY KEY_PRESS, DATA, MESSAGE
	
	IF KEY_PRESS = @KEY_ENTER
		ANSWER = DATA
	ELSEIF KEY_PRESS = @KEY_CANCEL
		EXITCONTINUE
	ELSE
		EXITCONTINUE
	ENDIF
	WINDOWCLOSE
ENDSUB

SUB GET_TIP_AMT( REF TIP_AMT )
	VAR MESSAGE : A80 = "Enter Charge Tip Amount"
	VAR SQL_CMD : A2000
	SQL_CMD = "SELECT obj_num FROM MICROS.ts_scrn_def WHERE ts_scrn_seq = (SELECT FIRST numeric_ts_scrn_seq FROM MICROS.rvc_add_def WHERE numeric_ts_scrn_seq is not null ORDER BY numeric_ts_scrn_seq)"
	CALL SQL_QUERY( SQL_CMD )
	CALL SQL_FETCH( SQL_CMD )
	
	VAR NUMERIC_TS : N9 = SQL_CMD
	IF NUMERIC_TS > 0
		TOUCHSCREEN NUMERIC_TS
	ENDIF
	
	VAR CENTER : N3 = (78-LEN(MESSAGE))/2
	WINDOW 3,78
	DISPLAY 2, CENTER, MESSAGE
	
	VAR KEY_PRESS : KEY
	VAR DATA : A20
	INPUTKEY KEY_PRESS, DATA, MESSAGE
	IF KEY_PRESS <> @KEY_ENTER
		TIP_AMT = -1
		RETURN
	ENDIF
	TIP_AMT = DATA
	WINDOWCLOSE
ENDSUB

////
// SQL SUBROUTINES
////


SUB SQL_LOAD
	SQL_FF = 0
	IF SQL_H = 0
		DLLLOAD SQL_H, "MDSSysUtilsProxy.dll"
	ENDIF
	IF SQL_H = 0
		EXITWITHERROR "Unable to load SQL DLL"
	ENDIF

	VAR CON_STATUS : N1 = 0
	DLLCALL_CDECL SQL_H, sqlIsConnectionOpen(ref CON_STATUS)
	IF CON_STATUS = 0
		DLLCALL_CDECL SQL_H, sqlInitConnection("micros", "ODBC;UID=custom;PWD=custom", "")
	ENDIF
	DLLCALL_CDECL SQL_H, sqlIsConnectionOpen(ref CON_STATUS)
	IF CON_STATUS = 0
		EXITWITHERROR "Can’t Connect to MICROS Database"
	ENDIF
ENDSUB

SUB SQL_CLOSE
	SQL_FF = 0
	IF SQL_H <> 0
		DLLCALL_CDECL SQL_H, sqlCloseConnection()
		SQL_H = 0
	ENDIF
ENDSUB

SUB SQL_FETCH( REF RESULT )
	IF SQL_H = 0
		EXITWITHERROR "Not Connected to Database"
	ENDIF

	IF SQL_FF > 0
		DLLCALL_CDECL SQL_H, sqlGetNext( REF RESULT )
	ELSE
		DLLCALL_CDECL SQL_H, sqlGetFirst( REF RESULT )
	ENDIF
	SQL_FF = 1
ENDSUB

SUB SQL_QUERY( REF QUERY )
	SQL_FF = 0
	IF SQL_H = 0
		EXITWITHERROR "Not Connected to Database"
	ENDIF

	DLLCALL_CDECL SQL_H, sqlGetRecordSet( REF QUERY )
	IF QUERY = ""
		DLLCALL_CDECL SQL_H, sqlGetLastErrorString( REF QUERY )
		ERRORMESSAGE "SQL Error - See Log"
		RETURN
	ENDIF
ENDSUB
 
So here is what I have understood till now. Loadkybmacros command simulates pressing of some button on the POS. I guess I will have to use Key type 9 (Tender media sequence) to close the ticket. But how do I know what sequence number to use? Where can I find a list of sequence number on the POS?

Also, I don't think I will be able to associate a ref number with cash at tender type.

Thanks for all the help
 
You don't use the sequence number, you use the object number. Your software will have to allow the end user to configure which tender to use, much like SVC does.
 
Before you go pulling your hair out, I don't know if SIM can use dll's compiled in .NET. I haven't tried on Res5.x systems, but as of about 4.6 they didn't work.
 
I know for sure it can't. RES only supports unmanaged DLL's - ie: DLL's compiled in C++ (NOT Visual C++, they must be unmanaged).
 
You can compile it with the Visual Studio compiler, but you have to be very, very careful with how you setup your environment or it starts putting managed libraries in and then Micros won't import it correctly.
 
Honestly, I had more success writing stored procedures and calling them from a SIM than with dlls. On the rare occasion that I couldn't I wrote a port listener and used a TxMsg to get the data back and forth. That takes the unmanaged code issue out of the equation. Whichever way you want to go, try getting your hands on an 8700 or 9700 SIM manual. The dll and TxMsg sections are pretty much the same as the 3700, but the documentation is much, much better for those products.
 
Thanks a lot guys. this is immensely helpful. I will try some things and ask if I have more doubts. Highly appreciate this.
 
It sounds almost like you are trying to write a PMS. If that is the case, there really isn't any need for you to use a DLL. You can use the TxMsg functions to communication with a service running on the server, which can then do the work for you.
 
We are trying not to write a PMS. Best case condition for us would be if we can manage it using a dll. Will make our life easier
 
Writing a DLL will just make things harder. Do you know how many devices there are in Micros world?

Eclispse
WS4
WS4LX
WS5
WS5A
DT430
DT360 (think thats the right name for that one)
mTablet R-Series
mTablet E-Series
PCWS2015

And more that you might find in other places. All of these have different version of CE or POS Ready running on them. You will need to test your DLL on ALL of them to ensure it works. But if you used the built in TxMsg, you need only make sure your interface works on the server - Micros handles making sure the communication back to your interface is compatible with them all.
 
oh ok. That sounds like a good argument. How do I go about making a PMS then? Is there a code/documentation for it.? It's not very clear in 3700 documentation that I used.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top