/** * * @创建人: yinxm * @时间 : 2014-05-13 11:52:23 * @功能 : TODO 1.2.1设置B2C请求支付参数 payData * @param EcPayLog * @param orgceb * @param payData */ private void setPayDataB2C(EcPayLog paylog, EcOrgCeb orgceb, CEBPayData payData) { if (log.isDebugEnabled()) { log.debug("【组装支付请求参数setPayData");} //设置orderData中的coNum为特定的支付用的订单号 //支付时发送给银行的订单号为:订单编号+P+支付日志后三位 String payCoNum = paylog.getCoNum(); String logId = paylog.getLogId(); payCoNum = payCoNum+"P"+logId.substring(logId.length()-3);//传给银行的订单号里面带"P" //金额设置,元,两位小数 String amtStr = payData.getOrdAmtSum(); BigDecimal amt = new BigDecimal(amtStr); // amt = amt.multiply(new BigDecimal("100")); //如果是以分为单位,元-》分,要求传整数 // transId 交易代码 Char4 IPER/EPER // merchantId 商户代码 Char12 // orderId 订单号Char 30 // transAmt 交易金额Decimal 13,2 // transDateTime 交易时间Char14 // currencyType 币种Char2 // customerName 订货人姓名Char 25 (非必输) // merSecName 二级商户Char30 二级商户名称(非必输) // productInfo 商品信息Char30 商户信息描述(非必输) // customerEMail 订货人EMAIL Char 60 (非必输) // merURL 商户URL Char 256 用于后台通知商户 // merURL1 商户URL1Char 256 用于后台通知商户失败或者默认情况下,引导客户回商户页面支付地址 // payIp Char 64 客户在商户网站上生成订单时的客户IP(非必输) // msgExt 附加信息Char 30(非必输) String transid = orgceb.getTransid(); String merchantid = orgceb.getMerchantid(); String orderid = orgceb.getOrderid(); String transamt = orgceb.getTransamt(); String transdatetime = orgceb.getTransdatetime(); String currencytype = orgceb.getCurrencytype(); String customername = orgceb.getCustomername(); String mersecname = orgceb.getMersecname(); String productinfo = orgceb.getProductinfo(); String customeremail = orgceb.getCustomeremail(); String merurl = orgceb.getMerurl(); String merurl1 = orgceb.getMerurl1(); String payip = orgceb.getPayip(); String msgext = orgceb.getMsgext(); payData.setTransid(transid); payData.setMerchantid(merchantid); payData.setOrderid(orderid); payData.setTransamt(transamt); payData.setTransdatetime(transdatetime); payData.setCurrencytype(currencytype); payData.setCustomername(customername); payData.setMersecname(mersecname); payData.setProductinfo(productinfo); payData.setCustomeremail(customeremail); payData.setMerurl(merurl); payData.setMerurl1(merurl1); payData.setPayip(payip); payData.setMsgext(msgext); payData.setTransid(orgceb.getTransid()); payData.setMerchantid(orgceb.getMerchantid()); payData.setOrderid(orgceb.getOrderid()); payData.setTransamt(orgceb.getTransamt()); payData.setTransdatetime(orgceb.getTransdatetime()); payData.setCurrencytype(orgceb.getCurrencytype()); payData.setCustomername(orgceb.getCustomername()); payData.setMersecname(orgceb.getMersecname()); payData.setProductinfo(orgceb.getProductinfo()); payData.setCustomeremail(orgceb.getCustomeremail()); payData.setMerurl(orgceb.getMerurl()); payData.setMerurl1(orgceb.getMerurl1()); payData.setPayip(orgceb.getPayip()); payData.setMsgext(orgceb.getMsgext()); if (log.isDebugEnabled()) { log.debug("组装支付请求参数setPayData】");} }
/** * * @创建人: yinxm * @时间 : 2014-05-13 11:52:23 * @功能 : TODO 1.2.2 对B2C请求支付参数 进行签名加密处理 * @param orgceb 银行Bean * @param orderData 支付参数Bean * @return Map "rtn" rtn[0]000:请求成功;rtn[1]支付地址 "parmsRequestMap" 支付请求参数 */ private Map<String, Object> paySignB2C(EcOrgCeb orgceb,CEBPayData orderData) { if(log.isDebugEnabled()) {log.debug("【paySignB2C");} String rtn[] = new String[]{"999",""}; Map<String, Object> rtnMap = new HashMap<String, Object>(); //组织plain StringBuffer sb = new StringBuffer(); String plainXsm = null; //明文 String signXsm = null; //密文 String payUrl = null; //支付请求地址 //向银行请求的参数 Map<String,String> parmsRequestMap = new HashMap<String,String>(); try { /*******组织签名数据*****************/ // transId 交易代码 Char4 IPER/EPER // merchantId 商户代码 Char12 // orderId 订单号Char 30 // transAmt 交易金额Decimal 13,2 // transDateTime 交易时间Char14 // currencyType 币种Char2 // customerName 订货人姓名Char 25 (非必输) // merSecName 二级商户Char30 二级商户名称(非必输) // productInfo 商品信息Char30 商户信息描述(非必输) // customerEMail 订货人EMAIL Char 60 (非必输) // merURL 商户URL Char 256 用于后台通知商户 // merURL1 商户URL1Char 256 用于后台通知商户失败或者默认情况下,引导客户回商户页面支付地址 // payIp Char 64 客户在商户网站上生成订单时的客户IP(非必输) // msgExt 附加信息Char 30(非必输) sb.append("transId=").append(orderData.getTransid()); sb.append("~|~").append("merchantId=").append(orderData.getMerchantid()); sb.append("~|~").append("orderId=").append(orderData.getOrderid()); sb.append("~|~").append("transAmt=").append(orderData.getTransamt()); sb.append("~|~").append("transDateTime=").append(orderData.getTransdatetime()); sb.append("~|~").append("currencyType=").append(orderData.getCurrencytype()); sb.append("~|~").append("customerName=").append(orderData.getCustomername()); sb.append("~|~").append("merSecName=").append(orderData.getMersecname()); sb.append("~|~").append("productInfo=").append(orderData.getProductinfo()); sb.append("~|~").append("customerEMail=").append(orderData.getCustomeremail()); sb.append("~|~").append("merURL=").append(orderData.getMerurl()); sb.append("~|~").append("merURL1=").append(orderData.getMerurl1()); sb.append("~|~").append("payIp=").append(orderData.getPayip()); sb.append("~|~").append("msgExt=").append(orderData.getMsgext()); /*******组织请求支付传送参数*****************/ String TransName = ""; //IPER String Plain = ""; //明文 String Signature = ""; //密文 parmsRequestMap.put("TransName", TransName); parmsRequestMap.put("Plain", Plain); parmsRequestMap.put("Signature", Signature); plainXsm = sb.toString(); if (log.isDebugEnabled()) {log.debug("明文plainXsm="+plainXsm); } //调试用,上线后注释掉 try { signXsm = Tool.sign(plainXsm); } catch (Exception e) { if (log.isDebugEnabled()) { log.error("签名数据出错!"); } logException(e); throw new RuntimeException(e); } if (log.isDebugEnabled()) {log.debug("密文signXsm="+signXsm);} //调试用,上线后注释掉 payUrl = orgceb.getPayUrl(); //从 光大银行 银行表中记录请求支付地址 if (payUrl == null || payUrl.equals("")){ rtn[0] = "999"; } else { rtn[0] = "000"; //组织请求数据签名成功 rtn[1] = payUrl; //记录请求支付地址 } } catch (Exception e) { rtn[0] = "999"; rtn[1] = ""; if (log.isDebugEnabled()) { log.debug("获取支付地址或者签名数据出错");} logException(e); } rtnMap.put("rtn", rtn); rtnMap.put("parmsRequestMap", parmsRequestMap); if(log.isDebugEnabled()) {log.debug("paySignB2C】");} return rtnMap; }
/** * * @创建人: 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; }