- 浏览: 56740 次
文章分类
- 全部博客 (46)
- java邮件组件 (1)
- java excel上传 (3)
- java 导出excel (1)
- java文件上传 (1)
- java文件上传、下载 (1)
- mytatis插件 (1)
- jquery.validate.min.js 非空验证 (1)
- 常用js工具 (2)
- 编程规范 (1)
- art.dialog页面 (1)
- java常量配置 (1)
- 框架知识 (2)
- web页面前段技术 (3)
- Method方法反射机制 (1)
- 数据库 (5)
- java解析excel数据 (1)
- java 反射 (1)
- spring 注解 (2)
- mybatis (4)
- Eclipse 模板 (1)
- web页面前端技术 (3)
- java 1.8 (1)
- 111111 (0)
- EL (1)
- mysql 分页 (1)
- excel导出 (1)
- 页面通用查询保存方法 (1)
- 自动创建数据库脚本 (1)
- 重复提交后台校验 (1)
- maven (1)
最新评论
/*
* Copyright (c) 2016, S.F. Express Inc. All rights reserved.
*/
package com.sf.novatar.tpl.task;
import java.math.BigDecimal;
import java.util.List;
import java.util.Map;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import javax.xml.datatype.XMLGregorianCalendar;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.sf.novatar.tpl.base.TaskBase;
import com.sf.novatar.tpl.bean.PayBusiness;
import com.sf.novatar.tpl.dao.IPayBusinessDao;
import com.sf.novatar.tpl.dao.ISysConfigurationsDao;
import com.sf.novatar.tpl.dto.PayBusinessDto;
import com.sf.novatar.tpl.enums.PayBusinessCallbackStatusEnum;
import com.sf.novatar.tpl.enums.PayBusinessStatusEnum;
import com.sf.novatar.tpl.enums.PayTypeEnum;
import com.sf.novatar.tpl.util.B2EUtil;
import com.sf.novatar.tpl.util.CurrencyUtil;
import com.sf.novatar.tpl.util.TaskThreadPoolUtil;
import com.sf.novatar.tpl.ws.client.cbe.PaymentInServiceClient;
import com.sf.novatar.tpl.ws.client.cbe.pay.DTPaymentReq;
import com.sf.novatar.tpl.ws.client.cbe.pay.DTPaymentResp;
import com.sf.novatar.tpl.ws.client.cbe.pay.DTPaymentSBodyReq;
import com.sf.novatar.tpl.ws.client.cbe.pay.DTPaymentSBodyReq.CstmrCdtTrfInitn;
import com.sf.novatar.tpl.ws.client.cbe.pay.DTPaymentSBodyReq.CstmrCdtTrfInitn.GrpHdr;
import com.sf.novatar.tpl.ws.client.cbe.pay.DTPaymentSBodyReq.CstmrCdtTrfInitn.PmtInf;
import com.sf.novatar.tpl.ws.client.cbe.pay.DTPaymentSBodyReq.CstmrCdtTrfInitn.PmtInf.CdtTrfTxInf;
import com.sf.novatar.tpl.ws.client.cbe.pay.DTPaymentSBodyReq.CstmrCdtTrfInitn.PmtInf.CdtTrfTxInf.Amt;
import com.sf.novatar.tpl.ws.client.cbe.pay.DTPaymentSBodyReq.CstmrCdtTrfInitn.PmtInf.CdtTrfTxInf.Amt.InstdAmt;
import com.sf.novatar.tpl.ws.client.cbe.pay.DTPaymentSBodyReq.CstmrCdtTrfInitn.PmtInf.CdtTrfTxInf.Cdtr;
import com.sf.novatar.tpl.ws.client.cbe.pay.DTPaymentSBodyReq.CstmrCdtTrfInitn.PmtInf.CdtTrfTxInf.CdtrAcct;
import com.sf.novatar.tpl.ws.client.cbe.pay.DTPaymentSBodyReq.CstmrCdtTrfInitn.PmtInf.CdtTrfTxInf.CdtrAgt;
import com.sf.novatar.tpl.ws.client.cbe.pay.DTPaymentSBodyReq.CstmrCdtTrfInitn.PmtInf.CdtTrfTxInf.CdtrAgt.FinInstnId;
import com.sf.novatar.tpl.ws.client.cbe.pay.DTPaymentSBodyReq.CstmrCdtTrfInitn.PmtInf.CdtTrfTxInf.CdtrAgt.FinInstnId.ClrSysMmbId;
import com.sf.novatar.tpl.ws.client.cbe.pay.DTPaymentSBodyReq.CstmrCdtTrfInitn.PmtInf.CdtTrfTxInf.PmtId;
import com.sf.novatar.tpl.ws.client.cbe.pay.DTPaymentSBodyReq.CstmrCdtTrfInitn.PmtInf.CdtTrfTxInf.Purp;
import com.sf.novatar.tpl.ws.client.cbe.pay.DTPaymentSBodyReq.CstmrCdtTrfInitn.PmtInf.CdtTrfTxInf.RmtInf;
import com.sf.novatar.tpl.ws.client.cbe.pay.DTPaymentSBodyReq.CstmrCdtTrfInitn.PmtInf.DbtrAcct;
import com.sf.novatar.tpl.ws.client.cbe.pay.DTPaymentSBodyReq.CstmrCdtTrfInitn.PmtInf.DbtrAcct.Id;
import com.sf.novatar.tpl.ws.client.cbe.pay.DTPaymentSBodyReq.CstmrCdtTrfInitn.PmtInf.DbtrAcct.Id.Othr;
import com.sf.novatar.tpl.ws.client.cbe.pay.DTPaymentSBodyReq.CstmrCdtTrfInitn.PmtInf.PmtTpInf;
import com.sf.novatar.tpl.ws.client.cbe.pay.DTPaymentSBodyResp;
import com.sf.novatar.tpl.ws.client.cbe.pay.DTPaymentSBodyResp.CstmrPmtStsRpt.OrgnlPmtInfAndSts;
import com.sf.novatar.tpl.ws.client.cbe.pay.DTPaymentSBodyResp.CstmrPmtStsRpt.OrgnlPmtInfAndSts.TxInfAndSts;
import com.sfpay.framework.base.exception.ServiceException;
/**
* 描述:
*
* <pre>
* HISTORY
* ****************************************************************************
* ID DATE PERSON REASON
* 1 2016年3月7日 601008 Create
* ****************************************************************************
* </pre>
*
* @author 601008
* @since 1.0
*/
@Service("payTask")
public class PayTask extends TaskBase {
@Autowired
private ISysConfigurationsDao sysConfigurationsDao;
@Override
public void processor() throws Exception {
boolean ok = lock.tryLock();
if (ok) {
try {
this.logger.info("================开始向银行提交支付指令===============");
List<Map<String, Object>> paybusinesses = null;
// 同步查询定义
Sync<Map<String, Object>> sync = sync();
do {
try {
// 多线程同步查询
paybusinesses = sync.execute();
} catch (Exception ex) {
String errorMsg = "查询支付结果失败,定时任务退出:" + ex.getMessage();
this.logger.error(errorMsg, ex);
throw new ServiceException(ex.getMessage());
}
// 多个线程支付
threadsPay(paybusinesses);
} while (paybusinesses != null && paybusinesses.size() > 0);
this.logger
.info("=================向银行提交支付指令结束======================");
} finally {
lock.unlock();
}
}
}
/**
* 方法说明:<br>
* 多线程支付
*
* @param paybusinesses
* 支付指令
* @param banksProperties
* @return
*/
private void threadsPay(final List<Map<String, Object>> paybusinessesList) {
int size = null == paybusinessesList ? 0 : paybusinessesList.size();
for (int i = 0; i < size; i++) {
final Map<String, Object> vo = paybusinessesList.get(i);
if (null == vo) {
continue;
}
// 多线程执行
TaskThreadPoolUtil.PAY_BUSINESS_TASK_THREAD.excute(
new Runnable<Integer>(i) {
@Override
public void run() {
try {
// 支付业务
executePay(vo);
} catch (Exception e) {
logger.error("向银行提交支付指令失败:" + e.getMessage());
} finally {
// 释放集合对对象的引用,此处index = i
paybusinessesList.set(index, null);
}
}
}, 20);
}
}
public void executePay(Map<String, Object> vo) {
if(!validate(vo)){//验证不通过
return;
}
//初始化支付数据
DTPaymentReq req = init(vo);
//付款流水号
String tradeOutNo = String.valueOf(vo.get("trade_out_no"));;
//修改支付开始时间
long id = Long.parseLong(String.valueOf(vo.get("id")));
PayBusinessDto payBusinessDto = new PayBusinessDto();
payBusinessDto.setId(id);
payBusinessDto.setPayType(PayTypeEnum.TRANSFER.getValue());
int count = payBusinessDao.updatePayBeginTime(payBusinessDto);
if (count < 1) {
logger.info("付款id[{}],流水号[{}]更新付款开始时间失败", new Object[]{String.valueOf(id), tradeOutNo});
return;
} else {
logger.info("付款id[{}],流水号[{}]更新付款开始时间成功", new Object[]{String.valueOf(id), tradeOutNo});
}
DTPaymentResp dTPaymentResp = null;
try {
dTPaymentResp = paymentInServiceClient.getClient().siPaymentIn(req);
} catch (Exception e) {
throw new ServiceException(e.getMessage());
}finally{
updatePayEndTime(dTPaymentResp);
}
}
/**
* 修改支付结束时间
* @param dTPaymentResp
* void
*/
private void updatePayEndTime(DTPaymentResp dTPaymentResp) {
if (dTPaymentResp != null) {
dTPaymentResp.getSBody().getCstmrPmtStsRpt().getOrgnlGrpInfAndSts();
List<DTPaymentSBodyResp.CstmrPmtStsRpt.OrgnlPmtInfAndSts> orgnlPmtInfAndStses = dTPaymentResp.getSBody().getCstmrPmtStsRpt().getOrgnlPmtInfAndSts();
for (OrgnlPmtInfAndSts orgnlPmtInfAndSts : orgnlPmtInfAndStses) {
List<DTPaymentSBodyResp.CstmrPmtStsRpt.OrgnlPmtInfAndSts.TxInfAndSts> txInfAndStses = orgnlPmtInfAndSts.getTxInfAndSts();
for (TxInfAndSts txInfAndSts : txInfAndStses) {
String orgnlEndToEndId = txInfAndSts.getOrgnlEndToEndId();
String txSts = txInfAndSts.getTxSts();
//失败
if (PayBusinessStatusEnum.RJCT.getValue().equals(txSts)) {
//wait to rjct and updateEndTime
PayBusinessDto payBusinessDto = new PayBusinessDto();
payBusinessDto.setTransSerialNo(orgnlEndToEndId);
payBusinessDto.setOldStatus(PayBusinessStatusEnum.WAIT);
payBusinessDto.setStatus(PayBusinessStatusEnum.RJCT.getValue());
//payBusinessDto.setPayEndTime(payEndTime);
payBusinessDto.setPayType(PayTypeEnum.TRANSFER.getValue());
int count = payBusinessDao.updatePayEndTime(payBusinessDto);
if (count < 1) {
logger.info(
"支付明细transSerialNo:{},状态status[{}]->[{}],回调状态callBack[{}]->[{}]失败。",
new Object[] {
orgnlEndToEndId,
PayBusinessStatusEnum.WAIT.name(),
PayBusinessStatusEnum.RJCT.name(),
PayBusinessCallbackStatusEnum.INITIAL
.getValue(),
PayBusinessCallbackStatusEnum.NOTBACK
.getValue() });
} else {
logger.info(
"支付明细transSerialNo:{},状态status[{}]->[{}],回调状态callBack[{}]->[{}]成功。",
new Object[] {
orgnlEndToEndId,
PayBusinessStatusEnum.WAIT.name(),
PayBusinessStatusEnum.RJCT.name(),
PayBusinessCallbackStatusEnum.INITIAL
.getValue(),
PayBusinessCallbackStatusEnum.NOTBACK
.getValue() });
}
} else if (PayBusinessStatusEnum.PDNG.getValue().equals(txSts)) {
//updateEndTime
PayBusinessDto payBusinessDto = new PayBusinessDto();
payBusinessDto.setTransSerialNo(orgnlEndToEndId);
payBusinessDto.setOldStatus(PayBusinessStatusEnum.WAIT);
payBusinessDto.setStatus(PayBusinessStatusEnum.WAIT.getValue());
//payBusinessDto.setPayEndTime(payEndTime);
payBusinessDto.setPayType(PayTypeEnum.TRANSFER.getValue());
int count = payBusinessDao.updatePayEndTime(payBusinessDto);
if (count < 1) {
logger.info("支付明细transSerialNo:{},修改支付结束时间失败。", new Object[]{orgnlEndToEndId});
} else {
logger.info("支付明细transSerialNo:{},修改支付结束时间成功。", new Object[]{orgnlEndToEndId});
}
}
}
}
}
}
/**
* 2016年3月7日 601008方法说明: 初始支付数据
*
* @param vo
* @return DTPaymentReq
*/
private DTPaymentReq init(Map<String, Object> vo) {
DTPaymentReq dTPaymentReq = new DTPaymentReq();
GrpHdr grpHdr = new GrpHdr();
grpHdr.setMsgId(String.valueOf(vo.get("trans_serial_no")) + "XEPIC"); //trans_serial_no
XMLGregorianCalendar XMLGregorianCalendar = null;
String mhAcctNo = String.valueOf(vo.get("payer_acct_no"));
String objAcctNo = String.valueOf(vo.get("payee_acct_no"));
String amount = String.valueOf(vo.get("amt"));
String bisId = String.valueOf(vo.get("trans_serial_no"));
String key= sysConfigurationsDao.getParamValue("PAY_KEY");
amount = CurrencyUtil.fen2Yuan(Long.valueOf(amount));
String passStr = mhAcctNo + objAcctNo + bisId + amount + key;
String md5Str = B2EUtil.toMD5(passStr);
if(logger.isInfoEnabled()){
logger.info("付款账号: [" + mhAcctNo + "] , 收款账号:[" + objAcctNo
+ "] , 唯一交易号:[" + bisId + "] , 交易金额:[" + amount
+ "] , UUID :[" + md5Str + "] , KEY:" +key);
}
grpHdr.setUUId(md5Str); //付款方账号+收款方账号+trans_serial_no+金额+ key
grpHdr.setCreDtTm(XMLGregorianCalendar);
CstmrCdtTrfInitn cstmrCdtTrfInitn = new CstmrCdtTrfInitn();
cstmrCdtTrfInitn.setGrpHdr(grpHdr);
DTPaymentSBodyReq dTPaymentSBodyReq = new DTPaymentSBodyReq();
dTPaymentSBodyReq.setCstmrCdtTrfInitn(cstmrCdtTrfInitn);
List<PmtInf> pmtInfList = cstmrCdtTrfInitn.getPmtInf();
PmtInf pmtInf = new PmtInf();
pmtInfList.add(pmtInf);
pmtInf.setPmtInfId(String.valueOf(vo.get("trans_serial_no"))); //trans_serial_no
PmtTpInf pmtTpInf = new PmtTpInf();
// 指令优先级(指令优先级: HIGH-加急, NORM-普通)
pmtTpInf.setInstrPrty(String.valueOf(vo.get("remit_type"))); //remit_type
// 交易类别(对公,对私)
pmtTpInf.setCtgyPurp(String.valueOf(vo.get("instruction_code"))); //instruction_code
pmtInf.setPmtTpInf(pmtTpInf);
DbtrAcct dbtrAcct = new DbtrAcct();
dbtrAcct.setCcy((String)vo.get("currencies"));
pmtInf.setDbtrAcct(dbtrAcct);
Id payerId = new Id();
dbtrAcct.setId(payerId);
Othr payerOthr = new Othr();
// 付款账号
payerOthr.setId((String)vo.get("payer_acct_no"));
payerId.setOthr(payerOthr);
List<CdtTrfTxInf> cdtTrfTxInfList = pmtInf.getCdtTrfTxInf();
PmtId pmtId = new PmtId();
// 银行支行名称
pmtId.setInstrId(""); //空===
// 交易指令唯一标识
pmtId.setEndToEndId(String.valueOf(vo.get("trans_serial_no")));//trans_serial_no
// 联行号
ClrSysMmbId clrSysMmbId = new ClrSysMmbId();
clrSysMmbId.setMmbId((String)vo.get("relation_no"));
FinInstnId finInstnId = new FinInstnId();
finInstnId.setClrSysMmbId(clrSysMmbId);
// 省份
finInstnId.setRegion(String.valueOf(vo.get("payee_province"))); //payee_province
// 银行编码
finInstnId.setBankId(String.valueOf(vo.get("payee_bank_code"))); //payee_bank_code
// 银行支行名称
finInstnId.setNm(String.valueOf(vo.get("payee_open_bank_name"))); //==payee_open_bank_name
// 城市
finInstnId.setCity(String.valueOf(vo.get("payee_city"))); //payee_city
CdtrAgt cdtrAgt = new CdtrAgt();
cdtrAgt.setFinInstnId(finInstnId);
// ----------
Cdtr cdtr = new Cdtr();
// // 收款相关信息
// 收款公司名
cdtr.setNm(String.valueOf(vo.get("payee_name"))); //==payee_name
// ----------------
com.sf.novatar.tpl.ws.client.cbe.pay.DTPaymentSBodyReq.CstmrCdtTrfInitn.PmtInf
.CdtTrfTxInf.CdtrAcct.Id.Othr payeeOthr = new com.sf.novatar.tpl.ws.client.cbe
.pay.DTPaymentSBodyReq.CstmrCdtTrfInitn.PmtInf.CdtTrfTxInf.CdtrAcct.Id.Othr();
//收款账号
payeeOthr.setId((String)vo.get("payee_acct_no"));
com.sf.novatar.tpl.ws.client.cbe.pay.DTPaymentSBodyReq.CstmrCdtTrfInitn.PmtInf
.CdtTrfTxInf.CdtrAcct.Id payeeId = new com.sf.novatar.tpl.ws.client.cbe.pay
.DTPaymentSBodyReq.CstmrCdtTrfInitn.PmtInf.CdtTrfTxInf.CdtrAcct.Id();
payeeId.setOthr(payeeOthr);
CdtrAcct cdtrAcct = new CdtrAcct();
cdtrAcct.setId(payeeId);
//----------------------
//付款金额
BigDecimal bdAmt = new BigDecimal(amount);
InstdAmt instdAmt = new InstdAmt();
instdAmt.setValue(bdAmt);
Amt amt = new Amt();
amt.setInstdAmt(instdAmt);
//---------------------
Purp purp = new Purp();
purp.setCd((String)vo.get("use_desc"));//用途
//----------------
RmtInf rmtInf = new RmtInf();
rmtInf.getUstrd().add((String)vo.get("use_desc"));//摘要
//---------------
CdtTrfTxInf cdtTrfTxInf = new CdtTrfTxInf();
cdtTrfTxInf.setCdtrAgt(cdtrAgt);
cdtTrfTxInf.setPmtId(pmtId);
cdtTrfTxInf.setCdtr(cdtr);
cdtTrfTxInf.setCdtrAcct(cdtrAcct);
cdtTrfTxInf.setAmt(amt);
cdtTrfTxInf.setPurp(purp);
cdtTrfTxInf.setRmtInf(rmtInf);
cdtTrfTxInfList.add(cdtTrfTxInf);
dTPaymentReq.setSBody(dTPaymentSBodyReq);
return dTPaymentReq;
}
/**
* 方法说明:<br>
* 同步查询定义
*
* @return 同步对象
*/
private Sync<Map<String, Object>> sync() {
return new Sync<Map<String, Object>>() {
private final PayBusiness param = new PayBusiness();
{
// 未发送支付指令
param.setStatus(PayBusinessStatusEnum.APRD.getValue());
param.setPayType(PayTypeEnum.TRANSFER.getValue());
}
@Override
protected List<Map<String, Object>> callBack() {
// 查询需要支付的支付明细
List<Map<String, Object>> paybusinessesList = payBusinessDao
.queryPayBusinessWaitToPay(param, 0, 100);
int size = 0;
if (paybusinessesList != null
&& (size = paybusinessesList.size()) > 0) {
// 修改明细状态“支付中”
for (int i = 0; i < size; i++) {
int count = 0;
Map<String, Object> vo = paybusinessesList.get(i);
long id = Long
.valueOf(String.valueOf(vo.get("id")));
PayBusinessDto updatePayBusinessDto = new PayBusinessDto();
updatePayBusinessDto.setId(id);
updatePayBusinessDto
.setOldStatus(PayBusinessStatusEnum.APRD);
updatePayBusinessDto
.setStatus(PayBusinessStatusEnum.WAIT.getValue());
updatePayBusinessDto.setBankRetCode("");
updatePayBusinessDto.setBankRetMsg("");
updatePayBusinessDto.setPayType(PayTypeEnum.TRANSFER.getValue());
try {
// 修改状态返回影响到的条数
count = payBusinessDao
.updateStatusToWait(updatePayBusinessDto);
} catch (Exception ex) {
String errorMsg = "付款id:{},指令唯一标识:{}修改状态status[{}]->status[{}]出错。";
logger.error(
errorMsg,
new Object[] { String.valueOf(id), String.valueOf(vo.get("trans_serial_no")),
PayBusinessStatusEnum.APRD.name(),
PayBusinessStatusEnum.WAIT.name() },
ex);
}
if (count == 0) {
// 影响条数为0,说明这条支付明细不能提交,从list中剔除
paybusinessesList.set(i, null);
String errorMsg = "付款id:{},指令唯一标识:{}修改状态status[{}]->status[{}]失败。";
logger.error(
errorMsg,
new Object[] { String.valueOf(id), String.valueOf(vo.get("trans_serial_no")),
PayBusinessStatusEnum.APRD.name(),
PayBusinessStatusEnum.WAIT.name() });
} else {
String errorMsg = "付款id:{},指令唯一标识:{}修改状态status[{}]->status[{}]成功。";
logger.info(
errorMsg,
new Object[] { String.valueOf(id), String.valueOf(vo.get("trans_serial_no")),
PayBusinessStatusEnum.APRD.name(),
PayBusinessStatusEnum.WAIT.name() });
}
}
}
return paybusinessesList;
}
};
}
private final Logger logger = LoggerFactory.getLogger(this.getClass());
private static final Lock lock = new ReentrantLock();
@Autowired
private IPayBusinessDao payBusinessDao;
@Autowired
private PaymentInServiceClient paymentInServiceClient;
public abstract class Runnable<V> implements java.lang.Runnable {
protected V index;
public Runnable(V index) {
this.index = index;
}
}
/**
* 2016年3月12日 601008方法说明:
* 支付数据验证
* @param payBusiness
* @return
* boolean
*/
private boolean validate(Map<String, Object> payBusiness) {
long id = Long.parseLong(String.valueOf(payBusiness.get("id")));
// 银行编码
String bankCode = String.valueOf(payBusiness.get("id"));
// 收款人账号
String payeeAcctCode = String.valueOf(payBusiness.get("payee_acct_no"));
// 收款人账户名
// 收款人省份
String provinceName = String.valueOf(payBusiness.get("payee_province"));
// 收款人城市
String city = String.valueOf(payBusiness.get("payee_city"));
// 付款金额
long amt = Long.parseLong(String.valueOf(payBusiness.get("amt")));
//收款开户行
String branchName = String.valueOf(payBusiness.get("payee_open_bank_name"));
//用途
String useDesc = String.valueOf(payBusiness.get("use_desc"));
//付款流水号
String tradeOutNo = String.valueOf(payBusiness.get("trade_out_no"));;
String errorMsg = "";
if(amt <= 0 ) {
errorMsg = "金额错误,小于或者等于0";
}else if (StringUtils.isBlank(bankCode)) {
errorMsg = "收款银行编号为空";
}else if( StringUtils.isBlank(payeeAcctCode)) {
errorMsg = "收款账号为空";
}else if(StringUtils.isBlank(provinceName)) {
errorMsg = "收款省份为空";
}else if(StringUtils.isBlank(useDesc)) {
errorMsg = "收款用途为空";
}else if( StringUtils.isBlank(branchName)) {
errorMsg = "收款人开户行为空";
}else if( StringUtils.isBlank(city)) {
errorMsg = "收款人城市为空";
}else if(StringUtils.isBlank(tradeOutNo)){
errorMsg = "交易流水号为空";
}
if(StringUtils.isNotBlank(errorMsg)){
updateAuthRjct(payBusiness, errorMsg);
logger.error("支付明细id["+id+"],"+errorMsg);
return false;
}
logger.info("支付明细id["+id+"],验证通过");
return true;
}
/**
* 方法说明:<br>
* 支付条件不满足,直接更新状态为支付失败
* @param vo
* 支付明细
* @param msg
* 错误消息
* @return
*/
private int updateAuthRjct(Map<String, Object> payBusiness, String msg) {
long id = Long
.valueOf(String.valueOf(payBusiness.get("id")));
PayBusinessDto updatePayBusinessDto = new PayBusinessDto();
updatePayBusinessDto.setId(id);
updatePayBusinessDto
.setOldStatus(PayBusinessStatusEnum.WAIT);
updatePayBusinessDto
.setStatus(PayBusinessStatusEnum.RJCT.getValue());
updatePayBusinessDto.setBankRetCode("cbe_error_0030");
updatePayBusinessDto.setBankRetMsg(msg);
updatePayBusinessDto.setPayType(PayTypeEnum.TRANSFER.getValue());
// 修改状态返回影响到的条数
int count = payBusinessDao
.updateStatusToWait(updatePayBusinessDto);
if (count < 1) {
logger.info("付款id:{}修改status[{}]->[{}]失败",
new Object[] { String.valueOf(id),
PayBusinessStatusEnum.WAIT.getValue(),
PayBusinessStatusEnum.RJCT.getValue() });
} else {
logger.info("付款id:{}修改status[{}]->[{}]成功",
new Object[] { String.valueOf(id),
PayBusinessStatusEnum.WAIT.getValue(),
PayBusinessStatusEnum.RJCT.getValue() });
}
return count;
}
}
* Copyright (c) 2016, S.F. Express Inc. All rights reserved.
*/
package com.sf.novatar.tpl.task;
import java.math.BigDecimal;
import java.util.List;
import java.util.Map;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import javax.xml.datatype.XMLGregorianCalendar;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.sf.novatar.tpl.base.TaskBase;
import com.sf.novatar.tpl.bean.PayBusiness;
import com.sf.novatar.tpl.dao.IPayBusinessDao;
import com.sf.novatar.tpl.dao.ISysConfigurationsDao;
import com.sf.novatar.tpl.dto.PayBusinessDto;
import com.sf.novatar.tpl.enums.PayBusinessCallbackStatusEnum;
import com.sf.novatar.tpl.enums.PayBusinessStatusEnum;
import com.sf.novatar.tpl.enums.PayTypeEnum;
import com.sf.novatar.tpl.util.B2EUtil;
import com.sf.novatar.tpl.util.CurrencyUtil;
import com.sf.novatar.tpl.util.TaskThreadPoolUtil;
import com.sf.novatar.tpl.ws.client.cbe.PaymentInServiceClient;
import com.sf.novatar.tpl.ws.client.cbe.pay.DTPaymentReq;
import com.sf.novatar.tpl.ws.client.cbe.pay.DTPaymentResp;
import com.sf.novatar.tpl.ws.client.cbe.pay.DTPaymentSBodyReq;
import com.sf.novatar.tpl.ws.client.cbe.pay.DTPaymentSBodyReq.CstmrCdtTrfInitn;
import com.sf.novatar.tpl.ws.client.cbe.pay.DTPaymentSBodyReq.CstmrCdtTrfInitn.GrpHdr;
import com.sf.novatar.tpl.ws.client.cbe.pay.DTPaymentSBodyReq.CstmrCdtTrfInitn.PmtInf;
import com.sf.novatar.tpl.ws.client.cbe.pay.DTPaymentSBodyReq.CstmrCdtTrfInitn.PmtInf.CdtTrfTxInf;
import com.sf.novatar.tpl.ws.client.cbe.pay.DTPaymentSBodyReq.CstmrCdtTrfInitn.PmtInf.CdtTrfTxInf.Amt;
import com.sf.novatar.tpl.ws.client.cbe.pay.DTPaymentSBodyReq.CstmrCdtTrfInitn.PmtInf.CdtTrfTxInf.Amt.InstdAmt;
import com.sf.novatar.tpl.ws.client.cbe.pay.DTPaymentSBodyReq.CstmrCdtTrfInitn.PmtInf.CdtTrfTxInf.Cdtr;
import com.sf.novatar.tpl.ws.client.cbe.pay.DTPaymentSBodyReq.CstmrCdtTrfInitn.PmtInf.CdtTrfTxInf.CdtrAcct;
import com.sf.novatar.tpl.ws.client.cbe.pay.DTPaymentSBodyReq.CstmrCdtTrfInitn.PmtInf.CdtTrfTxInf.CdtrAgt;
import com.sf.novatar.tpl.ws.client.cbe.pay.DTPaymentSBodyReq.CstmrCdtTrfInitn.PmtInf.CdtTrfTxInf.CdtrAgt.FinInstnId;
import com.sf.novatar.tpl.ws.client.cbe.pay.DTPaymentSBodyReq.CstmrCdtTrfInitn.PmtInf.CdtTrfTxInf.CdtrAgt.FinInstnId.ClrSysMmbId;
import com.sf.novatar.tpl.ws.client.cbe.pay.DTPaymentSBodyReq.CstmrCdtTrfInitn.PmtInf.CdtTrfTxInf.PmtId;
import com.sf.novatar.tpl.ws.client.cbe.pay.DTPaymentSBodyReq.CstmrCdtTrfInitn.PmtInf.CdtTrfTxInf.Purp;
import com.sf.novatar.tpl.ws.client.cbe.pay.DTPaymentSBodyReq.CstmrCdtTrfInitn.PmtInf.CdtTrfTxInf.RmtInf;
import com.sf.novatar.tpl.ws.client.cbe.pay.DTPaymentSBodyReq.CstmrCdtTrfInitn.PmtInf.DbtrAcct;
import com.sf.novatar.tpl.ws.client.cbe.pay.DTPaymentSBodyReq.CstmrCdtTrfInitn.PmtInf.DbtrAcct.Id;
import com.sf.novatar.tpl.ws.client.cbe.pay.DTPaymentSBodyReq.CstmrCdtTrfInitn.PmtInf.DbtrAcct.Id.Othr;
import com.sf.novatar.tpl.ws.client.cbe.pay.DTPaymentSBodyReq.CstmrCdtTrfInitn.PmtInf.PmtTpInf;
import com.sf.novatar.tpl.ws.client.cbe.pay.DTPaymentSBodyResp;
import com.sf.novatar.tpl.ws.client.cbe.pay.DTPaymentSBodyResp.CstmrPmtStsRpt.OrgnlPmtInfAndSts;
import com.sf.novatar.tpl.ws.client.cbe.pay.DTPaymentSBodyResp.CstmrPmtStsRpt.OrgnlPmtInfAndSts.TxInfAndSts;
import com.sfpay.framework.base.exception.ServiceException;
/**
* 描述:
*
* <pre>
* HISTORY
* ****************************************************************************
* ID DATE PERSON REASON
* 1 2016年3月7日 601008 Create
* ****************************************************************************
* </pre>
*
* @author 601008
* @since 1.0
*/
@Service("payTask")
public class PayTask extends TaskBase {
@Autowired
private ISysConfigurationsDao sysConfigurationsDao;
@Override
public void processor() throws Exception {
boolean ok = lock.tryLock();
if (ok) {
try {
this.logger.info("================开始向银行提交支付指令===============");
List<Map<String, Object>> paybusinesses = null;
// 同步查询定义
Sync<Map<String, Object>> sync = sync();
do {
try {
// 多线程同步查询
paybusinesses = sync.execute();
} catch (Exception ex) {
String errorMsg = "查询支付结果失败,定时任务退出:" + ex.getMessage();
this.logger.error(errorMsg, ex);
throw new ServiceException(ex.getMessage());
}
// 多个线程支付
threadsPay(paybusinesses);
} while (paybusinesses != null && paybusinesses.size() > 0);
this.logger
.info("=================向银行提交支付指令结束======================");
} finally {
lock.unlock();
}
}
}
/**
* 方法说明:<br>
* 多线程支付
*
* @param paybusinesses
* 支付指令
* @param banksProperties
* @return
*/
private void threadsPay(final List<Map<String, Object>> paybusinessesList) {
int size = null == paybusinessesList ? 0 : paybusinessesList.size();
for (int i = 0; i < size; i++) {
final Map<String, Object> vo = paybusinessesList.get(i);
if (null == vo) {
continue;
}
// 多线程执行
TaskThreadPoolUtil.PAY_BUSINESS_TASK_THREAD.excute(
new Runnable<Integer>(i) {
@Override
public void run() {
try {
// 支付业务
executePay(vo);
} catch (Exception e) {
logger.error("向银行提交支付指令失败:" + e.getMessage());
} finally {
// 释放集合对对象的引用,此处index = i
paybusinessesList.set(index, null);
}
}
}, 20);
}
}
public void executePay(Map<String, Object> vo) {
if(!validate(vo)){//验证不通过
return;
}
//初始化支付数据
DTPaymentReq req = init(vo);
//付款流水号
String tradeOutNo = String.valueOf(vo.get("trade_out_no"));;
//修改支付开始时间
long id = Long.parseLong(String.valueOf(vo.get("id")));
PayBusinessDto payBusinessDto = new PayBusinessDto();
payBusinessDto.setId(id);
payBusinessDto.setPayType(PayTypeEnum.TRANSFER.getValue());
int count = payBusinessDao.updatePayBeginTime(payBusinessDto);
if (count < 1) {
logger.info("付款id[{}],流水号[{}]更新付款开始时间失败", new Object[]{String.valueOf(id), tradeOutNo});
return;
} else {
logger.info("付款id[{}],流水号[{}]更新付款开始时间成功", new Object[]{String.valueOf(id), tradeOutNo});
}
DTPaymentResp dTPaymentResp = null;
try {
dTPaymentResp = paymentInServiceClient.getClient().siPaymentIn(req);
} catch (Exception e) {
throw new ServiceException(e.getMessage());
}finally{
updatePayEndTime(dTPaymentResp);
}
}
/**
* 修改支付结束时间
* @param dTPaymentResp
* void
*/
private void updatePayEndTime(DTPaymentResp dTPaymentResp) {
if (dTPaymentResp != null) {
dTPaymentResp.getSBody().getCstmrPmtStsRpt().getOrgnlGrpInfAndSts();
List<DTPaymentSBodyResp.CstmrPmtStsRpt.OrgnlPmtInfAndSts> orgnlPmtInfAndStses = dTPaymentResp.getSBody().getCstmrPmtStsRpt().getOrgnlPmtInfAndSts();
for (OrgnlPmtInfAndSts orgnlPmtInfAndSts : orgnlPmtInfAndStses) {
List<DTPaymentSBodyResp.CstmrPmtStsRpt.OrgnlPmtInfAndSts.TxInfAndSts> txInfAndStses = orgnlPmtInfAndSts.getTxInfAndSts();
for (TxInfAndSts txInfAndSts : txInfAndStses) {
String orgnlEndToEndId = txInfAndSts.getOrgnlEndToEndId();
String txSts = txInfAndSts.getTxSts();
//失败
if (PayBusinessStatusEnum.RJCT.getValue().equals(txSts)) {
//wait to rjct and updateEndTime
PayBusinessDto payBusinessDto = new PayBusinessDto();
payBusinessDto.setTransSerialNo(orgnlEndToEndId);
payBusinessDto.setOldStatus(PayBusinessStatusEnum.WAIT);
payBusinessDto.setStatus(PayBusinessStatusEnum.RJCT.getValue());
//payBusinessDto.setPayEndTime(payEndTime);
payBusinessDto.setPayType(PayTypeEnum.TRANSFER.getValue());
int count = payBusinessDao.updatePayEndTime(payBusinessDto);
if (count < 1) {
logger.info(
"支付明细transSerialNo:{},状态status[{}]->[{}],回调状态callBack[{}]->[{}]失败。",
new Object[] {
orgnlEndToEndId,
PayBusinessStatusEnum.WAIT.name(),
PayBusinessStatusEnum.RJCT.name(),
PayBusinessCallbackStatusEnum.INITIAL
.getValue(),
PayBusinessCallbackStatusEnum.NOTBACK
.getValue() });
} else {
logger.info(
"支付明细transSerialNo:{},状态status[{}]->[{}],回调状态callBack[{}]->[{}]成功。",
new Object[] {
orgnlEndToEndId,
PayBusinessStatusEnum.WAIT.name(),
PayBusinessStatusEnum.RJCT.name(),
PayBusinessCallbackStatusEnum.INITIAL
.getValue(),
PayBusinessCallbackStatusEnum.NOTBACK
.getValue() });
}
} else if (PayBusinessStatusEnum.PDNG.getValue().equals(txSts)) {
//updateEndTime
PayBusinessDto payBusinessDto = new PayBusinessDto();
payBusinessDto.setTransSerialNo(orgnlEndToEndId);
payBusinessDto.setOldStatus(PayBusinessStatusEnum.WAIT);
payBusinessDto.setStatus(PayBusinessStatusEnum.WAIT.getValue());
//payBusinessDto.setPayEndTime(payEndTime);
payBusinessDto.setPayType(PayTypeEnum.TRANSFER.getValue());
int count = payBusinessDao.updatePayEndTime(payBusinessDto);
if (count < 1) {
logger.info("支付明细transSerialNo:{},修改支付结束时间失败。", new Object[]{orgnlEndToEndId});
} else {
logger.info("支付明细transSerialNo:{},修改支付结束时间成功。", new Object[]{orgnlEndToEndId});
}
}
}
}
}
}
/**
* 2016年3月7日 601008方法说明: 初始支付数据
*
* @param vo
* @return DTPaymentReq
*/
private DTPaymentReq init(Map<String, Object> vo) {
DTPaymentReq dTPaymentReq = new DTPaymentReq();
GrpHdr grpHdr = new GrpHdr();
grpHdr.setMsgId(String.valueOf(vo.get("trans_serial_no")) + "XEPIC"); //trans_serial_no
XMLGregorianCalendar XMLGregorianCalendar = null;
String mhAcctNo = String.valueOf(vo.get("payer_acct_no"));
String objAcctNo = String.valueOf(vo.get("payee_acct_no"));
String amount = String.valueOf(vo.get("amt"));
String bisId = String.valueOf(vo.get("trans_serial_no"));
String key= sysConfigurationsDao.getParamValue("PAY_KEY");
amount = CurrencyUtil.fen2Yuan(Long.valueOf(amount));
String passStr = mhAcctNo + objAcctNo + bisId + amount + key;
String md5Str = B2EUtil.toMD5(passStr);
if(logger.isInfoEnabled()){
logger.info("付款账号: [" + mhAcctNo + "] , 收款账号:[" + objAcctNo
+ "] , 唯一交易号:[" + bisId + "] , 交易金额:[" + amount
+ "] , UUID :[" + md5Str + "] , KEY:" +key);
}
grpHdr.setUUId(md5Str); //付款方账号+收款方账号+trans_serial_no+金额+ key
grpHdr.setCreDtTm(XMLGregorianCalendar);
CstmrCdtTrfInitn cstmrCdtTrfInitn = new CstmrCdtTrfInitn();
cstmrCdtTrfInitn.setGrpHdr(grpHdr);
DTPaymentSBodyReq dTPaymentSBodyReq = new DTPaymentSBodyReq();
dTPaymentSBodyReq.setCstmrCdtTrfInitn(cstmrCdtTrfInitn);
List<PmtInf> pmtInfList = cstmrCdtTrfInitn.getPmtInf();
PmtInf pmtInf = new PmtInf();
pmtInfList.add(pmtInf);
pmtInf.setPmtInfId(String.valueOf(vo.get("trans_serial_no"))); //trans_serial_no
PmtTpInf pmtTpInf = new PmtTpInf();
// 指令优先级(指令优先级: HIGH-加急, NORM-普通)
pmtTpInf.setInstrPrty(String.valueOf(vo.get("remit_type"))); //remit_type
// 交易类别(对公,对私)
pmtTpInf.setCtgyPurp(String.valueOf(vo.get("instruction_code"))); //instruction_code
pmtInf.setPmtTpInf(pmtTpInf);
DbtrAcct dbtrAcct = new DbtrAcct();
dbtrAcct.setCcy((String)vo.get("currencies"));
pmtInf.setDbtrAcct(dbtrAcct);
Id payerId = new Id();
dbtrAcct.setId(payerId);
Othr payerOthr = new Othr();
// 付款账号
payerOthr.setId((String)vo.get("payer_acct_no"));
payerId.setOthr(payerOthr);
List<CdtTrfTxInf> cdtTrfTxInfList = pmtInf.getCdtTrfTxInf();
PmtId pmtId = new PmtId();
// 银行支行名称
pmtId.setInstrId(""); //空===
// 交易指令唯一标识
pmtId.setEndToEndId(String.valueOf(vo.get("trans_serial_no")));//trans_serial_no
// 联行号
ClrSysMmbId clrSysMmbId = new ClrSysMmbId();
clrSysMmbId.setMmbId((String)vo.get("relation_no"));
FinInstnId finInstnId = new FinInstnId();
finInstnId.setClrSysMmbId(clrSysMmbId);
// 省份
finInstnId.setRegion(String.valueOf(vo.get("payee_province"))); //payee_province
// 银行编码
finInstnId.setBankId(String.valueOf(vo.get("payee_bank_code"))); //payee_bank_code
// 银行支行名称
finInstnId.setNm(String.valueOf(vo.get("payee_open_bank_name"))); //==payee_open_bank_name
// 城市
finInstnId.setCity(String.valueOf(vo.get("payee_city"))); //payee_city
CdtrAgt cdtrAgt = new CdtrAgt();
cdtrAgt.setFinInstnId(finInstnId);
// ----------
Cdtr cdtr = new Cdtr();
// // 收款相关信息
// 收款公司名
cdtr.setNm(String.valueOf(vo.get("payee_name"))); //==payee_name
// ----------------
com.sf.novatar.tpl.ws.client.cbe.pay.DTPaymentSBodyReq.CstmrCdtTrfInitn.PmtInf
.CdtTrfTxInf.CdtrAcct.Id.Othr payeeOthr = new com.sf.novatar.tpl.ws.client.cbe
.pay.DTPaymentSBodyReq.CstmrCdtTrfInitn.PmtInf.CdtTrfTxInf.CdtrAcct.Id.Othr();
//收款账号
payeeOthr.setId((String)vo.get("payee_acct_no"));
com.sf.novatar.tpl.ws.client.cbe.pay.DTPaymentSBodyReq.CstmrCdtTrfInitn.PmtInf
.CdtTrfTxInf.CdtrAcct.Id payeeId = new com.sf.novatar.tpl.ws.client.cbe.pay
.DTPaymentSBodyReq.CstmrCdtTrfInitn.PmtInf.CdtTrfTxInf.CdtrAcct.Id();
payeeId.setOthr(payeeOthr);
CdtrAcct cdtrAcct = new CdtrAcct();
cdtrAcct.setId(payeeId);
//----------------------
//付款金额
BigDecimal bdAmt = new BigDecimal(amount);
InstdAmt instdAmt = new InstdAmt();
instdAmt.setValue(bdAmt);
Amt amt = new Amt();
amt.setInstdAmt(instdAmt);
//---------------------
Purp purp = new Purp();
purp.setCd((String)vo.get("use_desc"));//用途
//----------------
RmtInf rmtInf = new RmtInf();
rmtInf.getUstrd().add((String)vo.get("use_desc"));//摘要
//---------------
CdtTrfTxInf cdtTrfTxInf = new CdtTrfTxInf();
cdtTrfTxInf.setCdtrAgt(cdtrAgt);
cdtTrfTxInf.setPmtId(pmtId);
cdtTrfTxInf.setCdtr(cdtr);
cdtTrfTxInf.setCdtrAcct(cdtrAcct);
cdtTrfTxInf.setAmt(amt);
cdtTrfTxInf.setPurp(purp);
cdtTrfTxInf.setRmtInf(rmtInf);
cdtTrfTxInfList.add(cdtTrfTxInf);
dTPaymentReq.setSBody(dTPaymentSBodyReq);
return dTPaymentReq;
}
/**
* 方法说明:<br>
* 同步查询定义
*
* @return 同步对象
*/
private Sync<Map<String, Object>> sync() {
return new Sync<Map<String, Object>>() {
private final PayBusiness param = new PayBusiness();
{
// 未发送支付指令
param.setStatus(PayBusinessStatusEnum.APRD.getValue());
param.setPayType(PayTypeEnum.TRANSFER.getValue());
}
@Override
protected List<Map<String, Object>> callBack() {
// 查询需要支付的支付明细
List<Map<String, Object>> paybusinessesList = payBusinessDao
.queryPayBusinessWaitToPay(param, 0, 100);
int size = 0;
if (paybusinessesList != null
&& (size = paybusinessesList.size()) > 0) {
// 修改明细状态“支付中”
for (int i = 0; i < size; i++) {
int count = 0;
Map<String, Object> vo = paybusinessesList.get(i);
long id = Long
.valueOf(String.valueOf(vo.get("id")));
PayBusinessDto updatePayBusinessDto = new PayBusinessDto();
updatePayBusinessDto.setId(id);
updatePayBusinessDto
.setOldStatus(PayBusinessStatusEnum.APRD);
updatePayBusinessDto
.setStatus(PayBusinessStatusEnum.WAIT.getValue());
updatePayBusinessDto.setBankRetCode("");
updatePayBusinessDto.setBankRetMsg("");
updatePayBusinessDto.setPayType(PayTypeEnum.TRANSFER.getValue());
try {
// 修改状态返回影响到的条数
count = payBusinessDao
.updateStatusToWait(updatePayBusinessDto);
} catch (Exception ex) {
String errorMsg = "付款id:{},指令唯一标识:{}修改状态status[{}]->status[{}]出错。";
logger.error(
errorMsg,
new Object[] { String.valueOf(id), String.valueOf(vo.get("trans_serial_no")),
PayBusinessStatusEnum.APRD.name(),
PayBusinessStatusEnum.WAIT.name() },
ex);
}
if (count == 0) {
// 影响条数为0,说明这条支付明细不能提交,从list中剔除
paybusinessesList.set(i, null);
String errorMsg = "付款id:{},指令唯一标识:{}修改状态status[{}]->status[{}]失败。";
logger.error(
errorMsg,
new Object[] { String.valueOf(id), String.valueOf(vo.get("trans_serial_no")),
PayBusinessStatusEnum.APRD.name(),
PayBusinessStatusEnum.WAIT.name() });
} else {
String errorMsg = "付款id:{},指令唯一标识:{}修改状态status[{}]->status[{}]成功。";
logger.info(
errorMsg,
new Object[] { String.valueOf(id), String.valueOf(vo.get("trans_serial_no")),
PayBusinessStatusEnum.APRD.name(),
PayBusinessStatusEnum.WAIT.name() });
}
}
}
return paybusinessesList;
}
};
}
private final Logger logger = LoggerFactory.getLogger(this.getClass());
private static final Lock lock = new ReentrantLock();
@Autowired
private IPayBusinessDao payBusinessDao;
@Autowired
private PaymentInServiceClient paymentInServiceClient;
public abstract class Runnable<V> implements java.lang.Runnable {
protected V index;
public Runnable(V index) {
this.index = index;
}
}
/**
* 2016年3月12日 601008方法说明:
* 支付数据验证
* @param payBusiness
* @return
* boolean
*/
private boolean validate(Map<String, Object> payBusiness) {
long id = Long.parseLong(String.valueOf(payBusiness.get("id")));
// 银行编码
String bankCode = String.valueOf(payBusiness.get("id"));
// 收款人账号
String payeeAcctCode = String.valueOf(payBusiness.get("payee_acct_no"));
// 收款人账户名
// 收款人省份
String provinceName = String.valueOf(payBusiness.get("payee_province"));
// 收款人城市
String city = String.valueOf(payBusiness.get("payee_city"));
// 付款金额
long amt = Long.parseLong(String.valueOf(payBusiness.get("amt")));
//收款开户行
String branchName = String.valueOf(payBusiness.get("payee_open_bank_name"));
//用途
String useDesc = String.valueOf(payBusiness.get("use_desc"));
//付款流水号
String tradeOutNo = String.valueOf(payBusiness.get("trade_out_no"));;
String errorMsg = "";
if(amt <= 0 ) {
errorMsg = "金额错误,小于或者等于0";
}else if (StringUtils.isBlank(bankCode)) {
errorMsg = "收款银行编号为空";
}else if( StringUtils.isBlank(payeeAcctCode)) {
errorMsg = "收款账号为空";
}else if(StringUtils.isBlank(provinceName)) {
errorMsg = "收款省份为空";
}else if(StringUtils.isBlank(useDesc)) {
errorMsg = "收款用途为空";
}else if( StringUtils.isBlank(branchName)) {
errorMsg = "收款人开户行为空";
}else if( StringUtils.isBlank(city)) {
errorMsg = "收款人城市为空";
}else if(StringUtils.isBlank(tradeOutNo)){
errorMsg = "交易流水号为空";
}
if(StringUtils.isNotBlank(errorMsg)){
updateAuthRjct(payBusiness, errorMsg);
logger.error("支付明细id["+id+"],"+errorMsg);
return false;
}
logger.info("支付明细id["+id+"],验证通过");
return true;
}
/**
* 方法说明:<br>
* 支付条件不满足,直接更新状态为支付失败
* @param vo
* 支付明细
* @param msg
* 错误消息
* @return
*/
private int updateAuthRjct(Map<String, Object> payBusiness, String msg) {
long id = Long
.valueOf(String.valueOf(payBusiness.get("id")));
PayBusinessDto updatePayBusinessDto = new PayBusinessDto();
updatePayBusinessDto.setId(id);
updatePayBusinessDto
.setOldStatus(PayBusinessStatusEnum.WAIT);
updatePayBusinessDto
.setStatus(PayBusinessStatusEnum.RJCT.getValue());
updatePayBusinessDto.setBankRetCode("cbe_error_0030");
updatePayBusinessDto.setBankRetMsg(msg);
updatePayBusinessDto.setPayType(PayTypeEnum.TRANSFER.getValue());
// 修改状态返回影响到的条数
int count = payBusinessDao
.updateStatusToWait(updatePayBusinessDto);
if (count < 1) {
logger.info("付款id:{}修改status[{}]->[{}]失败",
new Object[] { String.valueOf(id),
PayBusinessStatusEnum.WAIT.getValue(),
PayBusinessStatusEnum.RJCT.getValue() });
} else {
logger.info("付款id:{}修改status[{}]->[{}]成功",
new Object[] { String.valueOf(id),
PayBusinessStatusEnum.WAIT.getValue(),
PayBusinessStatusEnum.RJCT.getValue() });
}
return count;
}
}
相关推荐
jqGrid控件导入导出Excel文件,将几个jqgrid导出一份Excel多sheet文件 ,亦可多sheet的excel导入至多个jqGrid表格。
自定义多个jqgrid导出一个或者多个sheet,可以自动控制。非常强大!
jqGrid是一款强大的JavaScript数据网格组件,它允许...通过熟练掌握jqGrid,开发者可以构建功能强大且用户友好的Web数据管理应用。在实际项目中,根据具体需求调整和扩展jqGrid的功能,将极大提升工作效率和用户体验。
前端页面点击导出jqgrid表格为excel表格代码,有表格样式设置的代码,可以参考一下,这是我刚开始工作的时候写的,希望可以帮助像我一样的菜鸟。
之前网上没找到现成的jqgrid表格前台导出插件,都或多或少带后台,也不想换表格插件,所以参照extjs自己改了个前台导出插件,支持多表头和分组table带表头导出,引用方法文件有详细注释,直接能用,如有不足还请见谅...
**jqGrid应用** jqGrid是一款基于jQuery的开源数据网格插件,它提供了强大的数据展示、编辑和管理功能,尤其适用于Web应用程序中展示大量的结构化数据。对于初学者来说,掌握jqGrid的应用是提升Web开发效率的重要一...
**jqGrid 图片上传功能(Java版)详解** jqGrid 是一个强大且灵活的JavaScript表格插件,它允许用户在Web应用中展示、编辑、排序和过滤数据。在这个主题中,我们将探讨如何利用jqGrid来实现图片上传的功能,并结合...
在实际应用中,以XML数据获取方式为例,开发者需要配置后台页面(如XMLData.aspx)并确保其返回数据格式与xmlReader要求的格式匹配。xmlReader的配置项包括字段映射、页码、数据总条数、记录数等关键信息。 以上...
在"jqGrid表格应用——新增与删除数据"这个主题中,我们可以探讨以下知识点: 1. **jqGrid的基本结构**:jqGrid的HTML结构通常包括一个`<table>`元素,以及必要的CSS和JavaScript引用。例如,`index.html`可能包含`...
jqGrid 是一个强大的 jQuery 插件,用于在 Web 应用程序中展示和操作数据。它提供了丰富的功能,包括数据网格、排序、过滤、编辑、分页等,并且支持多种数据格式的导入和导出。在本场景中,我们将探讨如何使用 ...
JqGrid是一款强大的JavaScript表格插件,用于在Web应用程序中展示和操作数据。它基于jQuery库,提供了丰富的功能,如数据排序、筛选、分页、编辑、添加、删除和保存等,极大地增强了网页中表格的交互性和数据管理...
本实践主要探讨如何在ASP.NET环境中有效利用jqGrid实现分页和Excel导出功能,同时结合C#后端代码和JavaScript前端代码。 **jqGrid分页** jqGrid的分页功能是通过设置`pager`属性和相关的分页参数来实现的。在ASP...
在这个“jqGrid完整实例”中,你将找到一个完整的jqGrid实现,可以直接下载并应用于你的项目。 该实例可能包含以下关键知识点: 1. **jqGrid安装**:首先,你需要在项目中引入jqGrid的CSS和JavaScript文件。通常...
它基于jQuery库,提供了许多强大的功能,例如排序、过滤、编辑、分页等,使得开发者可以快速创建复杂的表格应用程序。本文将详细介绍jQgrid的中文文档API,涵盖了其原理、使用方法、参数配置、事件处理、数据处理、...
1. **jqGrid 简介**:jqGrid 是一款基于 jQuery 的开源网格插件,它提供了数据管理、排序、搜索、分页等功能,广泛应用于数据密集型应用。jqGrid4.6 是其一个稳定版本,具有良好的兼容性和丰富的特性。 2. **可编辑...
jqGrid是一个用于Web应用程序的JavaScript表格插件,它遵循典型的B/S(浏览器/服务器)架构。在这种架构中,服务器端负责数据管理,而客户端则用于数据展示和用户交互。jqGrid可以简化数据库信息的展示,并能将...
JqGrid是一款强大的JavaScript数据网格组件,用于在Web应用程序中展示和操作数据。它基于jQuery库,提供了丰富的功能,如分页、排序、过滤、编辑和格式化数据。本中文API文档将帮助开发者深入理解并有效利用JqGrid的...
6. **导出功能**:jqGrid支持将表格数据导出为CSV、Excel、PDF等多种格式,便于数据共享和分析。 7. **国际化支持**:jqGrid内置了多种语言,包括英语,可以轻松实现界面的本地化。 8. **响应式设计**:jqGrid适应...
jqGrid 是一个基于 jQuery 的数据网格插件,用于在...在实际应用中,你可以根据项目需求选择合适的组件和配置,以实现高效的数据管理界面。通过深入理解 jqGrid 的 API 和各种选项,可以定制化地满足不同场景的需求。