@Test public void test8583Pay() { // 用户交易明细查询 000007 String hexString = "006060000381dd602200000637020000" + "20000000c08019202466313233343536" + "37382020202020202020202020203035" + "36303030373120202020202020202020" + "20203135360000070016323031313038" + "323832303131303832385a14b9403311" + "d601"; IPacket packetHelper = new ISO8583PacketHelper(); // unpack ControlMessage cm = new ControlMessage(); cm.setChanelType(CHANEL_TYPE.POS); BusinessMessage bm = new BusinessMessage(); byte[] origPacket = ConvertUtils.hexStr2Bytes(hexString); Map<DATA_TYPE, Object> map = new HashMap<DATA_TYPE, Object>(); map.put(DATA_TYPE.ORIGREQPACKET, origPacket); map.put(DATA_TYPE.CONTROLOBJECT, cm); map.put(DATA_TYPE.BUSINESSOBJECT, bm); try { packetHelper.unpackObject(map); } catch (PacketOperationException e) { // TODO Auto-generated catch block e.printStackTrace(); } cm = (ControlMessage) map.get(DATA_TYPE.CONTROLOBJECT); bm = (BusinessMessage) map.get(DATA_TYPE.BUSINESSOBJECT); System.out.println("msgtype: " + cm.getPacketHeader().getMessageType()); assertEquals("0200", cm.getPacketHeader().getMessageType()); assertEquals("000007", bm.getTranCode()); cm.setResultCode("000000"); bm.setLocalDate("20110830"); bm.setLocalTime("123143"); bm.setPbSeqno("12405"); Map<DATA_TYPE, Object> message = new HashMap<DATA_TYPE, Object>(); message.put(DATA_TYPE.CONTROLOBJECT, cm); message.put(DATA_TYPE.BUSINESSOBJECT, bm); // pack try { packetHelper.packBuffer(message); String resultHexString = ConvertUtils.bytes2HexStr((byte[]) PacketUtils.getOrigAnsPacket(message)); System.out.println(resultHexString); } catch (PacketOperationException e) { // TODO Auto-generated catch block e.printStackTrace(); } }
@Override protected boolean getTempValue(ControlMessage cm, BusinessMessage bm) { try { TempData cashTemp = (TempData) baseHibernateDao.get(TempData.class, bm.getOldPbSeqno()); if (cashTemp == null) { bm.setResponseCode(GlobalConst.RESPONSECODE_FAILURE); bm.setResponseMsg("缴费失败,请拨打客服电话咨询!"); cm.setResultCode(GlobalConst.RESULTCODE_FAILURE); cm.setResultMsg("缴费失败,现金查询时没有保存水费明细数据等重要信息!"); logger.info("现金查询时,水费明细数据等信息没有保存,商户号:{} ", bm.getShopCode()); return false; } String str = cashTemp.getTempValue(); String[] savedStr = str.split("\\|"); String userno = savedStr[0]; // 用户编号 String userName = savedStr[1]; // 用户名称 Double sumFee = Double.parseDouble(savedStr[2]); // 应缴金额 String recNum = savedStr[3]; // 欠费月数 // 缴费金额必须大于应缴金额 // if (sumFee > bm.getAmount()) { // cm.setResultCode(GlobalConst.RESULTCODE_FAILURE); // cm.setResultMsg("缴费金额小于应缴金额!"); // bm.setResponseCode(GlobalConst.RESPONSECODE_FAILURE); // bm.setResponseMsg("缴费金额小于应缴金额!"); // return false; // } WaterCashData waterCashData = new WaterCashData(); // 用户编号 waterCashData.setUserNo(userno); // 用户编号 waterCashData.setUsername(userName); bm.setUserName(userName); // 应收总额 waterCashData.setSumFee(String.valueOf(sumFee)); // 缴费金额 waterCashData.setPayAmt(String.valueOf(bm.getAmount())); // 水费欠费月数 waterCashData.setRecNum(recNum); // 凭证号码,如没有提供默认值 waterCashData.setCertNo(""); // 凭证类型,如没有提供默认值 waterCashData.setVoucKind(""); bm.setCustomData(waterCashData); } catch (Exception e) { bm.setResponseCode(GlobalConst.RESPONSECODE_FAILURE); bm.setResponseMsg("缴费不正常,请拨打客服电话咨询!"); cm.setResultCode(GlobalConst.RESULTCODE_FAILURE); cm.setResultMsg("缴费不正常,请拨打客服电话咨询!"); logger.error("缴费不正常!请查询表:CashTemp.商户号" + bm.getShopCode()); } return true; }
/** * 校验日期是否合法 * * @param cm * @param bm * @return */ private boolean checkDate(ControlMessage cm, BusinessMessage bm) { long lTime1 = Long.parseLong(bm.getQueryStartDate()); long lTime2 = Long.parseLong(bm.getQueryEndDate()); if (lTime2 < lTime1) { bm.setResponseCode("99"); bm.setResponseMsg("输入日期有误,请修改后重试!"); cm.setResultCode(GlobalConst.RESULTCODE_FAILURE); cm.setResultMsg("输入日期有误,请修改后重试!"); logger.info("输入日期有误,请修改后重试!"); return false; } return true; }
/** * Test method for {@link * com.nantian.npbs.business.service.answer.AnswerBusiness010Service#dealBusiness(com.nantian.npbs.packet.ControlMessage, * com.nantian.npbs.packet.BusinessMessage)} . */ @Test public void testDealBusiness() { logger.info("test Business013Service begin!"); ControlMessage cm = new ControlMessage(); BusinessMessage bm = new BusinessMessage(); bm.setShopCode("05001022"); // 商户 answerBusiness013Service.dealBusiness(cm, bm); assertNotNull(bm.getJournalList()); ArrayList<TbBiTrade> tblist = (ArrayList) bm.getJournalList(); for (TbBiTrade tb : tblist) { // assertEquals(tb.getId().getPbSerial(), "20110902293723"); logger.info("末笔pos流水:{}", tb.getId().getPbSerial()); assertEquals(tb.getPosSerial(), "900904"); assertEquals(tb.getCustomername(), "薛峰"); } }
@Override public void pack(Map<String, Object> fieldValues, ControlMessage cm, BusinessMessage bm) throws PacketOperationException { // 备付金密码 FIXSTRINGPacketUtils.addFieldValue(fieldValues, "D_PREPAY_PWD", bm.getPrePayPwd()); // 交易金额 FIXSTRINGPacketUtils.addFieldValue(fieldValues, "D_AMOUNT", Double.toString(bm.getAmount())); // 用户号 FIXSTRINGPacketUtils.addFieldValue(fieldValues, "D_USER_CODE", bm.getUserCode()); // 附加响应数据 FIXSTRINGPacketUtils.addFieldValue(fieldValues, "D_ADDITIONAL_TIP", bm.getAdditionalTip()); // 货币代码 FIXSTRINGPacketUtils.addFieldValue(fieldValues, "D_CURRENCY_CODE", bm.getCurrencyCode()); // 自定义域 FIXSTRINGPacketUtils.addFieldValue(fieldValues, "D_CUSTOM_FIELD", bm.getCustomField()); // 原系统水流号 FIXSTRINGPacketUtils.addFieldValue(fieldValues, "D_SYS_ORIGSEQNO", bm.getOrigSysJournalSeqno()); }
@Override protected String packField44(BusinessMessage bm) { logger.info("开始打包44位元"); if (GlobalConst.RESPONSECODE_FAILURE.equals(bm.getResponseCode())) { return bm.getResponseMsg(); } XAGasCashData cashData = (XAGasCashData) bm.getCustomData(); StringBuffer str = new StringBuffer(); str.append("用户名称:").append(cashData.getUserName()).append("\n"); str.append("用户地址:").append(cashData.getUserAdd()).append("\n"); str.append("账户余额:").append(cashData.getAccBalance()).append("\n"); // logger.info("查询显示:"+str.toString()); bm.setResponseMsg(str.toString()); return bm.getResponseMsg(); }
@Override public void unpack(Map<String, Object> fieldValues, ControlMessage cm, BusinessMessage bm) throws PacketOperationException { // 备付金密码 String prePayPwd = (String) fieldValues.get("D_PREPAY_PWD"); if (prePayPwd == null) throw new PacketOperationException(); bm.setPrePayPwd(prePayPwd); // 交易金额 String amount = (String) fieldValues.get("D_AMOUNT"); if (amount == null) throw new PacketOperationException(); bm.setAmount(Double.valueOf(amount)); // 用户号 String userCode = (String) fieldValues.get("D_USER_CODE"); if (userCode == null) throw new PacketOperationException(); bm.setUserCode(userCode); // 附加响应数据 String data = (String) fieldValues.get("D_ADDITIONAL_TIP"); if (data == null) throw new PacketOperationException(); bm.setCurrencyCode(data); // 货币代码 String currencyCode = (String) fieldValues.get("D_CURRENCY_CODE"); if (currencyCode == null) throw new PacketOperationException(); bm.setCurrencyCode(currencyCode); // 自定义域 String customField = (String) fieldValues.get("D_CUSTOM_FIELD"); if (customField == null) throw new PacketOperationException(); bm.setCustomField(customField); // 原系统流水号 String origSysJournalSeqno = (String) fieldValues.get("D_SYS_ORIGSEQNO"); if (origSysJournalSeqno == null) throw new PacketOperationException(); bm.setOrigSysJournalSeqno(origSysJournalSeqno); }
@Override protected boolean getTempValue(ControlMessage cm, BusinessMessage bm) { TempData cashTemp = (TempData) baseHibernateDao.get(TempData.class, bm.getOldPbSeqno()); if (cashTemp == null) { bm.setResponseCode(GlobalConst.RESPONSECODE_FAILURE); bm.setResponseMsg("缴费失败,请拨打客服电话咨询!"); cm.setResultCode(GlobalConst.RESULTCODE_FAILURE); cm.setResultMsg("缴费失败,现金查询时没有保存电费明细数据等重要信息!"); logger.info("现金查询时,电力电费明细数据等信息没有保存,商户号:{} ", bm.getShopCode()); return false; } if (bm.getCustomData() != null) { HeNDElecICCard customData = (HeNDElecICCard) bm.getCustomData(); String[] split = String.valueOf(cashTemp.getTempValue()).split("\\^"); customData.setCHECK_ID(split[0]); customData.setCONS_NO(split[1]); customData.setMETER_ID(split[2]); customData.setMETER_FLAG(split[3]); customData.setCARD_INFO(split[4]); customData.setIDDATA(split[5]); customData.setCONS_NAME(split[6]); customData.setCONS_ADDR(split[7]); customData.setPAY_ORGNO(split[8]); customData.setORG_NO(split[9]); customData.setCHARGE_CLASS(split[10]); customData.setFACTOR_VALUE(split[11]); customData.setPURP_PRICE(split[12]); customData.setCARD_NO(split[13]); customData.setOCS_MODE(split[14]); customData.setPRESET_VALUE(split[15]); bm.setCustomData(customData); return true; } else { return false; } }
@Test public void test8583Pay() { // 备付金明细查询 000005 /*00676000038009602200000857020000 20000100c08019110120001030323831 39313430363531323334353637382020 20202020202020202020303532313031 39342020202020202020202020203135 36000005001132303131303832383030 312dddd89cca21af63*/ String hexString = "00676000038009602200000857020000" + "20000100c08019110120001030323831" + "39313430363531323334353637382020" + "20202020202020202020303532313031" + "39342020202020202020202020203135" + "36000005001132303131303832383030" + "312dddd89cca21af63"; // unpack ControlMessage cm = new ControlMessage(); cm.setChanelType(CHANEL_TYPE.POS); BusinessMessage bm = new BusinessMessage(); byte[] origPacket = ConvertUtils.hexStr2Bytes(hexString); Map<DATA_TYPE, Object> map = new HashMap<DATA_TYPE, Object>(); map.put(DATA_TYPE.ORIGREQPACKET, origPacket); map.put(DATA_TYPE.CONTROLOBJECT, cm); map.put(DATA_TYPE.BUSINESSOBJECT, bm); try { packetHelperISO8583.unpackObject(map); } catch (PacketOperationException e) { // TODO Auto-generated catch block e.printStackTrace(); } cm = (ControlMessage) map.get(DATA_TYPE.CONTROLOBJECT); bm = (BusinessMessage) map.get(DATA_TYPE.BUSINESSOBJECT); System.out.println("msgtype: " + cm.getPacketHeader().getMessageType()); assertEquals("0200", cm.getPacketHeader().getMessageType()); assertEquals(new Double(0.00), new Double(bm.getAmount())); assertEquals("000005", bm.getTranCode()); cm.setResultCode("000000"); bm.setLocalDate("20110830"); bm.setLocalTime("123143"); bm.setPbSeqno("12405"); Map<DATA_TYPE, Object> message = new HashMap<DATA_TYPE, Object>(); message.put(DATA_TYPE.CONTROLOBJECT, cm); message.put(DATA_TYPE.BUSINESSOBJECT, bm); // pack try { packetHelperISO8583.packBuffer(message); String resultHexString = ConvertUtils.bytes2HexStr((byte[]) PacketUtils.getOrigAnsPacket(message)); System.out.println(resultHexString); } catch (PacketOperationException e) { // TODO Auto-generated catch block e.printStackTrace(); } }
@Override public Map<DATA_TYPE, Object> unpackObject(Map<DATA_TYPE, Object> message) throws PacketOperationException { logger.info("开始进行FIXSTRING解包...."); offset = 0; cm = PacketUtils.getControlMessage(message); bm = PacketUtils.getBusinessMessage(message); bm.setSystemChanelCode(GlobalConst.bmwebChanelCode); buffer = (String) PacketUtils.getOrigReqPacket(message); logger.info("需要解包的报文内容:[{}]", buffer); fieldValues.clear(); String[] fields = headerHelper.hasFields(); unpackFIXSTRING(fields, buffer); headerHelper.unpack(fieldValues, cm, bm); String tranCode = cm.getTranCode(); logger.info("交易{}解包包头完成.", tranCode); offset = 192; // pack body IPacketWEBSTRING packetHelper; try { packetHelper = (IPacketWEBSTRING) SpringContextHolder.getBean(getPacketBeanName(cm.getTranCode())); fields = packetHelper.hasFields(); fieldValues.clear(); unpackFIXSTRING(fields, buffer); System.out.println(buffer.toString()); packetHelper.unpack(fieldValues, cm, bm); /*String shopCode = null; WEBMessageHead fixMsgHeadData = (WEBMessageHead)bm.getFixMsgHeadData(); if(bm.getTranCode().equals("000010")&& fixMsgHeadData.getHandleType().equals("7")) { bm.setMacFlag(false); //如果是web端交易同步调取的末笔交易查询则执行 TbBiTrade tbBiTrade = tradeDao.getTradeById(fixMsgHeadData.getTranDate(), bm.getOldPbSeqno()); if(tbBiTrade != null) { shopCode = tbBiTrade.getCompanyCode(); } }else { shopCode = psamCompanyDao.findPsamCompanyRef(bm.getPSAMCardNo()); } if(shopCode == null){ logger.error("psam卡对应商户号不存在!"); throw new PacketOperationException("psam卡对应商户号不存在!"); } bm.setShopCode(shopCode);*/ if (!checkMac(bm)) { throw new PacketOperationException("报文解包失败!报文格式错误"); } } catch (Exception e) { logger.error("get packet helper class error!", e); throw new PacketOperationException(); } logger.info("交易{}解包包体完成.", tranCode); logger.info("交易{}FIXSTRING报文解包完成....", tranCode); return message; }
@Override public Map<DATA_TYPE, Object> packBuffer(Map<DATA_TYPE, Object> message) throws PacketOperationException { logger.info("开始进行FIXSTRING打包...."); offset = 0; String packet = null; cm = PacketUtils.getControlMessage(message); bm = PacketUtils.getBusinessMessage(message); String tranCode = cm.getTranCode(); // response code convert String resultCode = cm.getResultCode(); if (GlobalConst.RESULTCODE_SUCCESS.equals(resultCode) && !"000010".equals(bm.getTranCode())) { bm.setResponseCode(GlobalConst.RESPONSECODE_SUCCESS); } else if (resultCode.equals("999999")) { // timeout or unknown result bm.setResponseCode("99"); // else // bm.setResponseCode("01"); } fieldValues.clear(); headerHelper.pack(fieldValues, cm, bm); String header = packFIXSTRING(); logger.info("交易{}打包包头完成,报文头[{}],用户号[{}]", new Object[] {tranCode, header, bm.getUserCode()}); // pack body IPacketWEBSTRING packetHelper; String body = null; try { fieldValues.clear(); packetHelper = (IPacketWEBSTRING) SpringContextHolder.getBean(getPacketBeanName(cm.getTranCode())); packetHelper.pack(fieldValues, cm, bm); body = packFIXSTRING(); packet = header + body; // 减去报文头前10位+报文体作为MAB byte[] responseMac = getMac(packet.substring(10 + 6, packet.length()).getBytes("gb2312"), bm.getShopCode()); logger.info("响应报文MAC值[{}]", responseMac); packet += ConvertUtils.bytes2HexStr(responseMac); // 报文长度处理 packet = FieldUtils.leftAddZero4FixedLengthString( String.valueOf(packet.getBytes("gb2312").length - 6), 6) + packet.substring(6); PacketUtils.setOrigAnsPacket(message, packet); } catch (InstantiationException e) { logger.error("get packet helper class error!", e); throw new PacketOperationException(); } catch (IllegalAccessException e) { logger.error("get packet helper class error!", e); throw new PacketOperationException(); } catch (ClassNotFoundException e) { logger.error("get packet helper class error!", e); throw new PacketOperationException(); } catch (Exception e) { logger.error("get packet helper class error!", e); throw new PacketOperationException(); } logger.info("交易{}报文打包完成,报文:[{}]", tranCode, packet); return message; }
// 校验MAC private boolean checkMac(BusinessMessage bm) throws Exception { // 查询是否需要校验MAC ResourceBundle rb = null; try { rb = ResourceBundle.getBundle("conf.checkFlag"); bm.setMacFlag(Boolean.valueOf(rb.getString(bm.getChanelType() + "checkMacFlag"))); // WEBMessageHead fixMsgHeadData = (WEBMessageHead)bm.getFixMsgHeadData(); WEBMessageHead webMsgHeadData = (WEBMessageHead) bm.getWebMsgHeadData(); if ("000010".equals(bm.getTranCode()) && "7".equals(webMsgHeadData.getHandleType())) { bm.setMacFlag(false); } } catch (Exception e) { logger.error("取mac校验标志错!", e); // 默认为true bm.setMacFlag(true); } logger.info("mac校验标志:[{}],交易码:[{}]!", bm.isMacFlag(), bm.getTranCode()); if (bm.isMacFlag() == false || "000903".equals(bm.getTranCode())) { return true; } // 无论是否校验MAC,都取出MAB // 从报文头(除长度位字段)+报文体(除MAC字段) // (MAB),采用ECB算法,加密结果为64位的MAC。 byte[] macData = getMacData(); bm.setMacData(macData); // MAC String fieldName = "D_EPOS_MAC"; int length = 0; String macstr = null; try { length = fieldsConfig.getFieldAsciiLength(fieldName); macstr = FieldUtils.getFixedLengthAsciiField(fieldName, buffer, offset, length, fieldsConfig); offset += length; } catch (Exception e) { e.printStackTrace(); throw new PacketOperationException("mac获取出错"); } if (null == macstr || macstr.length() != 16) { logger.error("获取MAC错误!"); return false; } // String macstr = buffer.substring(buffer.length()-16); byte[] mac = ConvertUtils.str2Bcd(macstr); // (byte[])fieldValues.get("D_EPOS_MAC"); bm.setMac(mac); byte[] origMac = bm.getMac(); if (origMac == null) { throw new PacketOperationException("上传mac值为空!"); } // logger.info("mab:[{}]", new String(macData)); // logger.info("mac:[{}]", ConvertUtils.bytes2HexStr(origMac)); logger.info("开始进行MAC校验"); // POS不上送终端号,使用商户号作为密钥管理号 boolean result = encryptionService.checkMAC(origMac, macData, bm.getShopCode()); if (result) logger.info("MAC校验成功!"); else logger.info("MAC校验失败!"); return result; }
@Override public void setTradeFlag(BusinessMessage bm) { bm.setSeqnoFlag("0"); }