⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 posls.c

📁 界面库
💻 C
📖 第 1 页 / 共 4 页
字号:

/*============================================================================
功能: 		对交易流水表的处理	
作者:
最后修改日期:	2001/3/25
最后修改者:	王永忠
2001/03/31:wyz:修改原流水表中tran_ls_no为trace_no, void_tran_ls_no
	为void_trace_no; 改程序以适应现在PUBLIC结构中没有
	Old_tran_sys_time域。
2001/04/11:wyz:修改adjust_update()函数; 删除offline_update()函数。
2001/07/07:wyz:modified all #ifndef wyz_mod_0625 to
	#ifdef wyz_mod_0625 for not be modified completely last
	time.
2001/07/07:wyz:将所有的根据trace_no为依据改为invoice_no.
2001/07/10:wyz:将ADJUST交易对原交易金额的修改去掉.
2001/07/13:wyz:将CONFIRM交易对原交易查询时使用的terminal_id去掉.
2001/08/18:wyz:增加撤消交易金额为0时, 查找原交易时不使用交易金额
	作为判断条件.
2001/08/21:wyz:在记录交易流水的同时记录交易的实时统计(包括成功交易
	和不成功交易).
2001/08/21:wyz:将AUTH_PUR交易从卡段交易路由移到交易路由
2001/09/18:wyz:修改撤销交易原票据号为0时, 原使用TRACE_NO作为查找原交易的依据, 
	为使用AUTH_NO作为查找原交易的依据.
2001/10/16:wyz:修改adjust_update()函数,更新数据库的对流水查找方法。
2001/10/16:wyz:修改check_ls()函数,更新数据库的对流水查找方法。
2001/10/19:wyz:添加支持调整交易没有上送原交易金额
2001/11/09:wyz:添加交易处理成功但数据库操作失败交易自动产生冲正交易
	使用事务
2001/11/19:wyz:添加再Add_data中对原交易主机流水号的保存
2001/11/30:wyz:添加对冲正交易未找到原交易的处理
2002/01/16:wyz:调整数据库操作中列顺序符合索引顺序
2002/01/16:wyz:添加数据库操作不成功后,如果为成功交易自动发冲正
2002/04/15:wyz:修改update_pre_flag1()函数,将原来在进行CONFIRM交易冲正时,改
PRE_AUTH流水为已冲正为改原预授权交易流水中tran_flag改为'0', 即由已确认'2'
改为正常'0'。从而正常进行预授权的再确认(在确认被冲正情况下)
============================================================================*/

#include <stdio.h>
#include <math.h>
#include "all.h"
#include "macro_def.h"
#include "db_struct_c.h"

extern	S_sys_param G_sys_param;

PUBLIC	pcs;
int	G_special_flag = 0;		//
int	G_reversal_flag = 0;
char	sqlstr[1024];

/*====================================================
功能:
交易成功后, 对 cur_tran_ls 表的处理(UPDATE, INSERT)
涉及多记录操作的交易, 事务处理统一在此模块进行
 
输入: 
输出:		0	SUCC
		-1	FAIL, NEED addvoid()
=====================================================*/
int posls_handle()
{
S_tran_ls	tran_ls;
int		i, j;

	if (!strcmp(pcs.Card_no + 5, "00000000000"))
		return 0;
	
	switch(pcs.Tran_type) {
	//这些交易现在暂不记流水
		case	INQUERY:
		case	MUL_QUY:
			//记录EDC终端所有的查询交易
			upd_edc_tran_stat( &pcs );
			if (strcmp(pcs.Resp_code, SUCCESS))
				inc_fail_edc_tran_stat(pcs.Merchant_id, pcs.Terminal_id);
			return 0;

		case 	POS_LOGIN:
		case	POS_LOGOUT:
		case 	POS_SETTLE:
		case	POS_BATCH_UP:
		case	POS_SETTLE_2:
		case 	NET_LOGIN:
		case 	NET_LOGOUT:
		case 	NET_SETTLE:
		case	TEST_TRAN:
		case	CUT_START:
		case	CUT_END:
		case	CHECK_WB:
		case	CHG_PWD:
		case	EXPIRE:
		case	ISS_CARD:
		case	DISUSE_CARD:
		case	OPEN_ACC:
		case	DISUSE_ACC:
		case	ACQ_ADVICE:
		case	ACQ_REV_ADVICE:
		case	OFFLINE:
		case	AUTH_PUR:
			return 0;
		default:
			break;
	}
	
	if (pcs.Card_no[0]=='\0') 
		return 0;
	
	i = 0;

	begin_tran(); /* 开始事务 */

	if( !strcmp(pcs.Resp_code, SUCCESS))
	{/* 成功交易 */ 

		//自动发送收单行通知
		addadv_acq(&pcs);

		/*
		*发卡行通知交易成功返回后,修改原交易的相关标志位
		*/
		if ( pcs.Tran_type == ISS_ADVICE ){

		    //判断发卡行通知交易的原交易
		    switch (pcs.Void_tran_type) {

			//是否需要增加ADJUST交易处理部分?????
			case  CONFIRM:

				i = update_pre_flag2();
				if( i < 0 ) {
					rollback_tran();
					strcpy(pcs.Resp_code, SYS_FAIL);
					strcpy(pcs.Resp_bank_id, G_sys_param.bank_id);
					strcpy(pcs.Resp_host_id, G_sys_param.host_id);
					return -1;
				}

				//不是收单行,需进一步记流水
				if(strcmp(pcs.Acq_bank_id, G_sys_param.bank_id) ||
				   strcmp(pcs.Acq_host_id, G_sys_param.host_id))
					break;
				else { 
					commit_tran();
					return 0;
				}

			case  POS_VOID:

				i = iss_void_update();
				if( i< 0 ) {
					rollback_tran();
					strcpy(pcs.Resp_code, SYS_FAIL);
					strcpy(pcs.Resp_bank_id, G_sys_param.bank_id);
					strcpy(pcs.Resp_host_id, G_sys_param.host_id);
					return -1;
				}

#ifndef wyz_mod_010713
				break;
#else
				if(strcmp(pcs.Acq_bank_id, G_sys_param.bank_id) ||
				   strcmp(pcs.Acq_host_id, G_sys_param.host_id))
				   //不是收单行,需进一步记流水
					break;
				else { 
					commit_tran();
					return 0;
				}
#endif

			default:
				break;
			
		    }
		}//发卡行通知结束

		//根据各种特殊交易类型做相应的处理
		switch(pcs.Tran_type) {

			case	REFUND:

				i = refund_update();
				break;

			case	CONFIRM:

				i = update_pre_flag2();
#ifdef wyz_mod_020220
				//?????
				if (pcs.Msg_id[2] > '1') i = 0;
#else
#endif
				break;

			case	POS_VOID:

				i = void_update();
				break;

			case	REVERSAL:

				i = recovery_update();
				if (i < 0) {
					rollback_tran();

					inc_edc_rev_cnt(pcs.Merchant_id, pcs.Terminal_id);

					errcall(DEBUG, "REVERSAL: reversal_update() failed");
					strcpy(pcs.Resp_code, SYS_FAIL);
					strcpy(pcs.Resp_bank_id, G_sys_param.bank_id);
					strcpy(pcs.Resp_host_id, G_sys_param.host_id);
					return -1;
				}

				if (i == 0) 
					upd_edc_tran_stat(&pcs);
				else
					inc_edc_rev_cnt(pcs.Merchant_id, pcs.Terminal_id);

				commit_tran();
				return 0;
				
			case	ADJUST:

				i = adjust_update();
				break;
		}
	}//成功交易结束

	else {//非成功交易
		//统计非成功交易笔数
		inc_fail_edc_tran_stat(pcs.Merchant_id, pcs.Terminal_id);

		switch(pcs.Tran_type) {
			case	REVERSAL:
			case	ISS_ADVICE:
			case	ISS_REV_ADVICE:
				if (pcs.Saf_flag == 2) {
					addsaf(&pcs);
				}
				commit_tran ();
				return 0;
		}
	}

	if (i < 0) {//如果成功交易数据库处理失败,则自动发起一个冲正交易。

		rollback_tran();

		begin_tran();

		//统计非成功交易笔数
		inc_fail_edc_tran_stat(pcs.Merchant_id, pcs.Terminal_id);

		errcall(ERROR, "交易成功但数据库操作失败!");
		strcpy(pcs.Resp_code, SYS_FAIL);
		strcpy(pcs.Resp_bank_id, G_sys_param.bank_id);
		strcpy(pcs.Resp_host_id, G_sys_param.host_id);

		//由SAF模块发出的交易不重新发冲正
		if (pcs.Saf_flag == 1) {
			commit_tran();
			return -1;
		}

		//发送自动冲正交易
		i = pcs.Void_tran_type;
		j = pcs.Void_old_tran_type;

		pcs.Void_old_tran_type = pcs.Void_tran_type;
		pcs.Void_tran_type = pcs.Tran_type;
		pcs.Tran_type = REVERSAL;

		addsaf(&pcs);

		pcs.Tran_type = pcs.Void_tran_type;
		pcs.Void_tran_type = i;
		pcs.Void_old_tran_type = j;

		commit_tran();

		return -1;
	}

	//成功和失败交易均向交易流水中插入一条记录。
	pcs2posls(&tran_ls, &pcs);

	if (insert_posls(&tran_ls) < 0) {
		rollback_tran();

		begin_tran();

		if (strcmp(pcs.Resp_code, SUCCESS)==0) {
			//发送自动冲正交易
			i = pcs.Void_tran_type;
			j = pcs.Void_old_tran_type;
	
			pcs.Void_old_tran_type = pcs.Void_tran_type;
			pcs.Void_tran_type = pcs.Tran_type;
			pcs.Tran_type = REVERSAL;
	
			addsaf(&pcs);
	
			pcs.Tran_type = pcs.Void_tran_type;
			pcs.Void_tran_type = i;
			pcs.Void_old_tran_type = j;
		}

		//统计非成功交易笔数
		inc_fail_edc_tran_stat(pcs.Merchant_id, pcs.Terminal_id);

		commit_tran();

		strcpy(pcs.Resp_code, SYS_FAIL);
		strcpy(pcs.Resp_bank_id, G_sys_param.bank_id);
		strcpy(pcs.Resp_host_id, G_sys_param.host_id);
		return -1;
	}

	if (upd_edc_tran_stat(&pcs) < 0) {
		rollback_tran();

		begin_tran();

		if (strcmp(pcs.Resp_code, SUCCESS)==0) {
			//发送自动冲正交易
			i = pcs.Void_tran_type;
			j = pcs.Void_old_tran_type;
	
			pcs.Void_old_tran_type = pcs.Void_tran_type;
			pcs.Void_tran_type = pcs.Tran_type;
			pcs.Tran_type = REVERSAL;
	
			addsaf(&pcs);
	
			pcs.Tran_type = pcs.Void_tran_type;
			pcs.Void_tran_type = i;
			pcs.Void_old_tran_type = j;
		}

		//统计非成功交易笔数
		inc_fail_edc_tran_stat(pcs.Merchant_id, pcs.Terminal_id);

		commit_tran();

		strcpy(pcs.Resp_code, SYS_FAIL);
		strcpy(pcs.Resp_bank_id, G_sys_param.bank_id);
		strcpy(pcs.Resp_host_id, G_sys_param.host_id);
		return -1;
	}

	commit_tran();

	return 0;
}

/*==================================================
功能:
撤销交易数据库处理函数, 修改cur_tran_ls或his_tran_ls
中原交易的tran_flag标志为已撤销, 如果原交易为退货交易

ENTRY:
RETURN:		0	SUCC
		-1	FAIL
		1	NOTFOUND
===================================================*/
int void_update()
{
S_tran_ls	po;
int		i;

	switch(pcs.Void_tran_type) {
	case	ADJUST:
	//case	CONFIRM:
	case	REFUND:
		i = update_refund_void(pcs.Void_invoice_no);
		if( i < 0 )
			return -1;
		break;
	default:
		break;
	}

	//根据交易的原票据号,将原交易改为已撤销。
	sprintf(sqlstr, "				\
		UPDATE	cur_tran_ls			\
		SET 	tran_flag 	= \'1\'		\
		WHERE	acq_bank_id	= \'%s\'	\
		AND	acq_host_id	= \'%s\'	\
		AND	card_no 	= \'%s\' 	\
		AND	merchant_id	= \'%s\' 	\
		AND	terminal_id	= \'%s\' 	\
		AND	invoice_no	= %ld 		\
		AND	tran_type	= %d 		\
		AND 	resp_code	= \'00\'",
		pcs.Acq_bank_id,
		pcs.Acq_host_id,
		pcs.Card_no,
		pcs.Merchant_id,
		pcs.Terminal_id,
		pcs.Void_invoice_no,	
		pcs.Void_tran_type);

	i = update_table(sqlstr);

	return i;
}

/*====================================================
功能:
通知交易成功之后修改cur_tran_ls或his_tran_ls中原交易的
tran_flag标志为'1',已确认

ENTRY:
RETURN:		0	SUCC
		-1	FAIL
		1	NOTFOUND
====================================================*/
int iss_void_update( )
{

S_tran_ls	po;
int		i=0;

	switch(pcs.Void_old_tran_type) {
	case	REFUND:
		i = iss_update_refund_void(pcs.Invoice_no);
		if( i < 0 )
			return -1;
		break;
	default:
		break;
	}

	sprintf(sqlstr, "				\
		UPDATE	cur_tran_ls			\
		SET 	tran_flag 	= \'1\'		\
		WHERE	acq_bank_id	= \'%s\'	\
		AND	acq_host_id	= \'%s\'	\
		AND	card_no 	= \'%s\'	\
		AND	merchant_id	= \'%s \'	\
		AND	terminal_id	= \'%s \'	\
		AND	invoice_no	= %ld 		\
		AND 	resp_code	= \'00\'",
		pcs.Acq_bank_id,
		pcs.Acq_host_id,
		pcs.Card_no,
		pcs.Merchant_id,
		pcs.Terminal_id,
		pcs.Invoice_no);

	i = update_table(sqlstr);

	return i;
}

/*==================================================
功能:
ADJUST交易修改cur_tran_ls中原交易的tran_flag为'3',已调整
tran_amount 为调整后的金额,void_amount为原金额
RETURN:		0	SUCC
		-1	FAIL
		1	NOTFOUND
===================================================*/
int adjust_update()
{
S_tran_ls	po;
double		adjust_amount=0.;
double		amt=0.;
double		void_amt=0.;
int		i=0;
int		len;

	pack_sqlstr_new(sqlstr, "cur_tran_ls");

	//取原交易流水
	if (select_tran_ls(sqlstr, &po, &pcs) != 0) {
		errcall(DEBUG, "ADJUST select_tran_ls() not found!!");
		strcpy(pcs.Resp_code, INVALID_TRANS);
		strcpy(pcs.Resp_bank_id, G_sys_param.bank_id);
		strcpy(pcs.Resp_host_id, G_sys_param.host_id);
		return -1; 
	}

	//现在按照ADJUST交易的Tran_amount为调整后的金额,
	//Void_amount存放的是原交易金额。
	amt = atol(pcs.Tran_amount) / 100.;
	void_amt = atol(pcs.Void_amount) / 100.;

	adjust_amount = fabs(amt - void_amt);

	//调整交易的原交易金额不等于交易流水中交易金额
	if (fabs(void_amt - po.tran_amt) >= 0.01){
		errcall(DEBUG, "调整交易的原交易金额[%f]不等于交易流水中交易金额[%f]",
			void_amt, po.tran_amt);
		strcpy(pcs.Resp_code, UNACCEPT_AMOUNT);
		strcpy(pcs.Resp_bank_id, G_sys_param.bank_id);
		strcpy(pcs.Resp_host_id, G_sys_param.host_id);
		return -1;
	}

	if (adjust_amount > po.tran_amt * G_sys_param.adjust_rate) {
		//调整金额的比率大于系统参数表规定的比率
		errcall(DEBUG, "调整金额的比率大于系统参数表规定的比率");
		strcpy(pcs.Resp_code, UNACCEPT_AMOUNT);
		strcpy(pcs.Resp_bank_id, G_sys_param.bank_id);
		strcpy(pcs.Resp_host_id, G_sys_param.host_id);
		return -1;
	}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -