/** * * @创建人: 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查询动作失败
/** * * @创建人: 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; }