📄 posls.c
字号:
/*============================================================================
功能: 对交易流水表的处理
作者:
最后修改日期: 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 + -