Example #1
0
	/**
	 * 
	 * @创建人: yinxm
	 * @时间 : 2014-05-13 11:52:23 
	 * @功能 : TODO 3.2	对B2C异常支付,校验查询订单支付结果
	 * @param EcPayLogView 支付日志
	 * @return String[] rtnStr[0]:0:不允许再支付(支付成功、结果未知);1:允许再支付(支付失败);rtnStr[1]:具体支付情况信息
	 */
	private String[] verifyPayB2C(EcPayLogView paylog) {
		if (log.isDebugEnabled()) {log.debug("【 verifyPayB2C ");}
		//返回标志消息
		String[] rtnStr = new String[]{"0","支付成功"};	
		String CODE = "000";
		String MSG = null;
/********获取支付日志信息***************/	
				
		String orgCode = paylog.getOrgCode();
		String coNum = paylog.getCoNum();	//未加p
		BigDecimal amount = paylog.getAmount();
		String paySeq = paylog.getPaySeq();
		String orderDate = paylog.getPayDate();//yyyyMMdd

/********获取 光大银行 配置信息***************/				
			
		EcOrgCeb orgceb = getEcOrgCebDomain().getEcOrgCeb(paylog.getPayOrg(),PayUtil.CEB);
		if (orgceb == null) {
			MSG = "未取到公司["+paylog.getPayOrg()+"],银行["+PayUtil.CEB+"]的信息";
			if (log.isDebugEnabled()) {log.error(MSG);}
			throw new RuntimeException(MSG);
		}

/********记录交互日志,请求校验支付结果开始***************/

		if (log.isDebugEnabled()) {log.debug("orgCode="+orgCode+";coNum="+coNum+"的订单请求校验支付结果开始...");}
		EcPayExchangeLogView payExLogView = getPayExchangeLogViewForVerifyPayResult(amount, coNum, paylog.getCustCode(), orgCode,"请求校验支付结果开始","XSM",PayUtil.CEB,"再支付前,支付日志中没有明确信息,验证订单");
		insertPayExchangeLog(payExLogView);
		//支付日志
		EcPayLog ecpaylog = EcPayLogViewUtils.getEcPayLog(paylog);
		if (log.isDebugEnabled()) { log.debug("支付日志更新前状态,【ecpaylog="+ecpaylog);}

/****组装校验请求参数及签名数据 ************/		
		
		 Map<String,Object>  queryDataB2C =  setVerifySignDataB2C(ecpaylog, orgceb);
		 String queryUrl = (String) queryDataB2C.get("queryUrl");	//查询地址
		 Map<String, String> parmsRequestMap = (Map) queryDataB2C.get("parmsRequestMap"); 


/******开始通信*****************************/	
		 String[] rtnQuery = new String[2];	//通信是否成功000:成功;其它:失败;通信返回内容
		if (log.isDebugEnabled()) {log.debug("开始和银行通信 ");}
		try {
			rtnQuery = netRequestPost(queryUrl, parmsRequestMap); 
		} catch (Exception e) {
			if (log.isDebugEnabled()) {
				log.debug("查询订单状态,和银行通信出错,"+rtnQuery[0]+rtnQuery[1]);
				logException(e);
				throw new RuntimeException(e);
			}
		}
		if (log.isDebugEnabled()) {log.debug("通信结束,查询订单状态银行返回: "+rtnQuery[0]+"\n"+rtnQuery[1]);}
		
		
/******************记录交互日志,请求校验支付结果返回结果********************/
		if (log.isDebugEnabled()){
			log.debug("orgCode="+orgCode+";coNum="+coNum+"的订单请求校验支付结果结束。");
		}
		payExLogView.setExchangeType("请求校验支付结果结束");
		payExLogView.setSysFrom(PayUtil.CEB);
		payExLogView.setSysTo("XSM");
		payExLogView.setNote("验证订单返回结果");
		insertPayExchangeLog(payExLogView);
		
/*************************解析银行返回数据,组织数据验签***********************************/
				
		if (rtnQuery[0] != null && rtnQuery[0].equals("000")) {//XSM查询动作成功
					
			String rtn_sign = null;		//银行返回签名结果
			String rtn_plain = null;	//银行返回签名明文
			
#parseVerifyRes			

			
/*************************银行返回数据-验证签名***********************************/
			if (log.isDebugEnabled()) { log.debug("验证签名开始");}
			
			boolean ifVfy = SignTool.sign(rtn_sign, rtn_plain);
			
			if (log.isDebugEnabled()) { log.debug("签名数据,ifVfy="+ifVfy);}
			
			if (ifVfy) {	//验证签名成功
/*************************验证签名成功,根据交易状态更新支付日志状态********************/	
				if (log.isDebugEnabled()) { log.debug("签名数据 成功!开始解析支付状态码");}
				String rtn_resCode = null;	//银行返回订单支付状态码
				
				//解析支付状态码
				String[] rtn =  parseB2CVerifyAnswer(rtnQuery[1]);	//rtn[0]:解析状态码动作是否成功;rtn[1]:支付状态码;rtn[2]:支付流水
				
	
				if (rtn[0].equals("000") ){	//解析支付状态码成功
					rtn_resCode  = rtn[1];	
					if (log.isDebugEnabled()) { log.debug("解析支付状态码成功,支付状态码:"+rtn_resCode);}
					/*****************解析支付状态码******************/
					String payFlag = EcPayLogView.PAY_FLAG_REQUEST;
					if (rtn_resCode.equals("00")){	//支付成功
						rtnStr[0] = "0";	//不允许再次支付
						rtnStr[1] = "校验订单,支付成功";
						payFlag = EcPayLogView.PAY_FLAG_SUCCESS;
					} else if (rtn_resCode.equals("02")){	//支付失败	
						rtnStr[0] = "1";	//允许重新支付
						rtnStr[1] = "校验订单,支付失败";
						payFlag = EcPayLogView.PAY_FLAG_FAULT;
						
					} else {				//交易异常,稍后查询				
						rtnStr[0] = "0";	//不允许再次支付
						rtnStr[1] = "校验订单,支付异常,稍后重试";
						payFlag = EcPayLogView.PAY_FLAG_REQUEST;
					}					
					ecpaylog.setPayFlag(payFlag);
					ecpaylog.setNote(rtnStr[1]);
					
					if (log.isDebugEnabled()) { log.debug("支付日志更新后状态,】ecpaylog="+ecpaylog);}				
					if ( ! (ecpaylog.getPayFlag().equals(EcPayLogView.PAY_FLAG_REQUEST))) {//支付结果 不为 PAY_FLAG_REQUEST
							//采用统一方法更新新商盟订单支付状态和通知业务系统
							//这部分程序在各个银行的支付程序中都差不多,于是提出作为公共程序
						if (log.isDebugEnabled()) { log.debug("开始通知业务系统");}		
							recordAndNoticeBusi(ecpaylog);
	
					}

				} else {	//解析支付状态码失败
						rtnStr[0] = "0";
						rtnStr[1] = "您的订单查询结果,验签成功,但无法解析订单支付状态,请稍后重试或联系管理员!";
						if (log.isDebugEnabled()){log.debug(rtnStr[1]);}
				}
			} else {	//验证签名失败
					rtnStr[0] = "0";
					rtnStr[1] = "您的订单查询结果,验签失败,请稍后重试或联系管理员!";
					if (log.isDebugEnabled()){log.debug(rtnStr[1]);}
			}		
		
		} else {	//XSM查询动作失败
Example #2
0
	/**
	 * 
	 * @创建人: yinxm
	 * @时间 : 2014-05-13 11:52:23 
	 * @功能 : TODO 	1.2 B2C 请求支付地址、支付参数
	 * @param baseOrderData
	 * @return Map
	 * @throws Exception
	 */
	private Map<String,Object> askForPayB2C(BasePayData baseOrderData) throws Exception {
		if (log.isDebugEnabled()) {	log.debug("【 CEBPayDomainImpl.askForPayB2C");}
		
		//记录从数据库中查询出来的支付日志
		EcPayLog paylog = null;
		//记录错误信息
		String errMsg = null;
		//返回信息
		Map<String,Object> rtnMap = new HashMap<String,Object>();
		
		CEBPayData payData = (CEBPayData)baseOrderData;
		
		
		EcPayExchangeLogView payExLogView = getPayExchangeLogView(baseOrderData);
		String orgCode = baseOrderData.getOrgCode();
		String payOrg = baseOrderData.getPayOrg();

/*****查询公司光大银行 表,得到公司光大银行信息*********/
		
		if (log.isDebugEnabled()){log.debug("查询公司光大银行 表,得到公司光大银行信息");}

		EcOrgCeb orgceb = getEcOrgCebDomain().getEcOrgCeb(payOrg,PayUtil.CEB);
		if (orgceb == null) {
			errMsg = "未取到公司["+payOrg+"],银行["+PayUtil.CEB+"]的信息";
			if (log.isDebugEnabled()) {log.error(errMsg);}
			throw new RuntimeException(errMsg);
		}
		if (orgceb.getBankName() == null || orgceb.getBankName().equals("")) {
			payData.setBankName("光大银行");
		} else {
			payData.setBankName(orgceb.getBankName());
		}
		
/*************记录支付日志*******************/
		
		/**
		 * 记录支付日志,新商盟锁定订单,记录支付日志,放在同一个事务里处理
		 */
		if (log.isDebugEnabled()) {log.debug("新商盟锁定订单,记录支付日志");}
		String flag = "0";//支付日志、xsm锁定订单是否成功的标志
		try {
			EcPayLogView payLogView = getPayLogView(payData);
			
			//支付日志中的商户号必须先记录,因为查询的时候商户号直接取日志中的
			String merId = orgceb.getMerchantId();
			if (merId == null || merId.trim().equals("")) {
				if (log.isDebugEnabled()) {log.debug("获取商户号出错!");}
				throw new Exception("获取商户号时出错");
			} else {
				payData.setMerChantId(merId);
				payLogView.setMerchantId(merId);
			}
			
			flag = insertPayLog(payLogView);
		} catch (Exception e) {
			flag = "0";
			if (log.isDebugEnabled()) {log.error("锁定订单或记录支付日志时出错");}
			logException(e);
			throw new Exception("锁定订单或记录支付日志时出错");
		}
		if (flag.equals("1")) {//判断支付日志是否记录正确,锁定订单、记录日志成功,才正确返回url,才能支付
			//查询最新插入的支付日志以取出其中的支付日志号
			paylog = EcPayLogViewUtils.getEcPayLog(getLastPayLog(orgCode, baseOrderData.getCoNum()));
			String logId = paylog.getLogId();
			
/****组装支付请求参数 payData************/
			
			setPayDataB2C(paylog,orgceb,payData);
			if (log.isDebugEnabled()) {log.debug("组装支付请求参数 payData=\n"+payData);}

/******记录虚拟交互日志,请求支付地址及数据**************/
			
			if (log.isDebugEnabled()) {	log.debug("向光大银行请求得到支付的地址");}
			payExLogView.setExchangeType("请求支付地址及数据,发出请求");
			payExLogView.setNote("请求支付地址及数据,发出请求");
			payExLogView.setSysFrom("XSM");
			payExLogView.setSysTo(PayUtil.CEB);
			insertPayExchangeLog(payExLogView);
			
/******签名请求数据**************/
			
			Map reqRtn = paySignB2C(orgceb,payData);
			
			String[] rtn = (String[]) reqRtn.get("rtn");	//rtn[0]:返回是否组装请求参数并签名成功,rtn[1]:支付地址 
			//处理请求支付返回数据数组
			if (rtn[0].equals("000")) {
				//支付请求提交成功,将客户端导向支付页面
				String paymentURL = rtn[1];
				
/******记录虚拟交互日志,得到交易地址、交易数据及其签名结果**************/
				
				if (log.isDebugEnabled()) {	log.debug("光大银行 组装支付参数,并签名加密成功!");}
				payExLogView.setExchangeType("请求支付地址及数据,返回成功");
				payExLogView.setNote(paymentURL);
				payExLogView.setSysFrom(PayUtil.CEB);
				payExLogView.setSysTo("XSM");
				insertPayExchangeLog(payExLogView);
				
/******记录交互日志,请求支付页面**************/
				
				payExLogView.setExchangeType("请求支付页面");
				payExLogView.setNote("客户端访问光大银行支付页面");
				payExLogView.setSysFrom("XSM");
				payExLogView.setSysTo(PayUtil.CEB);
				insertPayExchangeLog(payExLogView);
				
/******返回前端,银行支付跳转地址,以及请求支付参数*********/
				
				Map<String, Object> paraMap = (Map<String, Object>) reqRtn.get("parmsRequestMap");
if (log.isDebugEnabled()) {log.debug("支付请求地址PAY_URL="+paymentURL+", 参数为parameter="+paraMap);}	//开发调试用,上线注销

				rtnMap.put("CODE","000");
				rtnMap.put("MSG", "请求支付地址成功");
				rtnMap.put("PAY_URL", paymentURL);
				rtnMap.put("parameter", paraMap);
			} else {
				//请求支付地址及数据失败,可能是数据库
				
				payExLogView.setExchangeType("请求支付地址及数据,返回失败");
				payExLogView.setNote("请求支付地址及数据失败");
				payExLogView.setSysFrom(PayUtil.CEB);
				payExLogView.setSysTo("XSM");
				insertPayExchangeLog(payExLogView);
				if (log.isDebugEnabled()) {log.error("光大银行请求支付失败!原因可能是数据库中 光大银行 表数据维护不正确,或者签名数据错误。订单号:"+baseOrderData.getCoNum()+","+rtn[0]+","+rtn[1]);}
				rtnMap.put("CODE",rtn[0]);
				rtnMap.put("MSG", rtn[1]);
				rtnMap.put("PAY_URL", "");

/******记录这笔订单本次支付失败,通知业务系统解锁订单*********/
				
				//记录这笔订单本次支付失败
				paylog.setBankId(PayUtil.CEB);
				paylog.setPayFlag(EcPayLogView.PAY_FLAG_FAULT);
				//更新新商盟订单支付状态和通知业务系统
				recordAndNoticeBusi(paylog);
			}
		} else {
			rtnMap.put("CODE","500");
			rtnMap.put("MSG", "请求支付地址失败");
			rtnMap.put("PAY_URL", "");
		}
		
		if (log.isDebugEnabled()) {
			log.debug("请求 光大银行 支付地址askForPay End】");
		}
		
		return rtnMap;
	}