@Override public void bindDevice(Device device, Store store) throws AppBizException { List<CupsTrmnl> cupsTrmnlList = cupsTrmnlService.findInactiviteTrmnl(store.getMrchNo(), store.getStoreNo()); if (cupsTrmnlList == null || cupsTrmnlList.size() <= 0) { throw new AppBizException(AppExCode.UNAVAILABLE_TERMINAL, "not find available terminal"); } CupsTrmnl cupsTrmnl = cupsTrmnlList.get(0); device.setTargetChannel(store.getTargetChannel()); device.setBindTransId(cupsTrmnl.getTrmnlId()); cupsTrmnl.setIsActive(Const.VLDSTATE_VALID); cupsTrmnl.setRemark( StringUtils.isNotBlank(device.getDevSn()) ? device.getDevSn() : device.getDevKsn()); cupsTrmnlService.updateCupsTrmnl(cupsTrmnl); }
private CreditcardFeeQueryTradeRequestEntity packUp( CupsTrmnl cupsTrmnl, UlinkplusKeyManage ulinkplusKeyManage, UlinkplusRequestInfo request) throws TransferFailedException { // 消费报文打包 // {2,3,4,11,22,25,41,42,48,49,64} CreditcardFeeQueryTradeRequestEntity requestEntity = new CreditcardFeeQueryTradeRequestEntity(); requestEntity.setCardNo(request.getCardNo()); // 2 requestEntity.setProcessCode("310000"); // 3 requestEntity.setTransAmt(StringUtils.amtToBCD(request.getAmount())); // 4 requestEntity.setTrmnlFlowNo(cupsTrmnl.getTrmnlFlowNo()); // 11 requestEntity.setPosEntryMode("012"); // 22 requestEntity.setServiceCode("92"); // 25 requestEntity.setTrmnlNo(cupsTrmnl.getTrmnlNo()); requestEntity.setTrmnlMrchNo(cupsTrmnl.getMrchNo()); // 位置 长度 格式 内容 说明 // 0 2 n2 用法标志 “PA” // 2 2 n2 帐单号码类型 08 // 4 19 Ans19 信用卡卡码 左对齐,右补空格 // 23 11 N11 手机号码 // 34 1 ans1 结束标志 # // PA086222040000000001 # requestEntity.setSelfDefined48( ("PA08" + StringUtils.rightPad(request.getCreditcardNo(), 19, " ") + "#").getBytes()); requestEntity.setCurrency(Currency.CNY.getCodeN()); requestEntity.setMacCode(new byte[8]); cupsTrmnlService.updateCupsTrmnlFlowNo(cupsTrmnl); return requestEntity; }
@Override public void syncPayCancelLog(PayCancel payCancel) { PayCups payCups = payCupsService.findPayCups(payCancel.getPaycancelNo()); if (payCups == null) { // throw new TransferFailedException(AppExCode.TRANS_NOT_EXIST, "sysncPayLog failed,not find // payCups"); payCancel.setTransStatus(Const.TransStatus.FAILED); // 银联直连表无交易流水记录,未发交易,撤销失败 return; } // 如果iso中心已经返回,但app与xposp已经断开 String isoRespCode = payCups.getRespCode(); if (StringUtils.isNotBlank(isoRespCode)) { // modify zengyj 20140716 服务端到银联已经响应成功,但客户端因超时交易未知 if (Const.ISO_RESPCODE_OK.equals(isoRespCode)) { payCancel.setTransStatus(Const.TransStatus.SUCCESS); } else { payCancel.setTransStatus(Const.TransStatus.FAILED); isoRespCode = Const.TP_BEGIN_ISO + StringUtils.leftPad("" + Integer.parseInt(isoRespCode), 3, "0"); payCancel.setErrCode(isoRespCode); } return; } CupsTrmnl cupsTrmnl = cupsTrmnlService.findByTrmnlNoAndMrchNo(payCups.getTrmnlNo(), payCups.getTrmnlMrchNo()); if (cupsTrmnl == null) { throw new TransferFailedException( AppExCode.TERMINAL_NOT_EXIST, "goodee sysncPayLog failed,not find CupsTrmnl"); } reversalProcess.process(cupsTrmnl, payCups, getAddress(payCancel.getAppAccessId())); payCancel.setTransStatus(TransStatus.FAILED); }
@Override public boolean signUp(Device device) throws TransferFailedException { boolean isSignUpSuccess = false; CupsTrmnl cupsTrmnl = cupsTrmnlService.findById(device.getBindTransId()); if (cupsTrmnl == null) { throw new TransferFailedException( AppExCode.TERMINAL_NOT_EXIST, "goodee signup failed,not find CupsTrmnl"); } PaySignUp paySignUp = paySignUpService.findPaySignUpByMrchNoAndTrmnlNo( cupsTrmnl.getMrchNo(), cupsTrmnl.getTrmnlNo()); if (paySignUp != null) { if (StringUtils.isNotBlank(paySignUp.getRespCode()) && Const.ISO_RESPCODE_OK.equals(paySignUp.getRespCode())) { long workingKeyTimeout = paySignUp.getUpdTime().getTime() + Const.WORKING_KEY_TIMEOUT; long nowTime = (new Date()).getTime(); if (workingKeyTimeout > nowTime) { isSignUpSuccess = true; } } } if (!isSignUpSuccess) { signUpProcess.process(cupsTrmnl); isSignUpSuccess = true; } return isSignUpSuccess; }
/** * 通道错误码处理 * * @param code * @param cupsTrmnl */ private void processErrorCode(String code, CupsTrmnl cupsTrmnl) { /*if(AppExCode.ISO_NOT_ALLOW_TERMINAL_TRADE.equalsIgnoreCase(code)){//iso code 58 signUpProcess.process(cupsTrmnl); }*/ if (AppExCode.ISO_MAC_ERROR.equals(code) || AppExCode.ISO_NOT_ALLOW_TERMINAL_TRADE.equals(code)) { // iso code A0 signUpProcess.process(cupsTrmnl); } if (AppExCode.ISO_REPEAT_DEAL.equals(code)) { // iso code 94 cupsTrmnlService.updateCupsTrmnlFlowNo(cupsTrmnl); } }
@Override public void syncCashLoadLog(PayCashLoad cashLoad, Integer appSyn) { PayCups payCups = payCupsService.findPayCups(cashLoad.getCashLoadNo()); if (payCups == null) { // throw new TransferFailedException(AppExCode.TRANS_NOT_EXIST, "sysncPayLog failed,not find // payCups"); cashLoad.setTransStatus(Const.TransStatus.FAILED); // 银联直连表无交易流水记录,未发交易,消费失败 return; } if (appSyn == null) { // 如果iso中心已经返回,但app与xposp已经断开,写卡失败 String isoRespCode = payCups.getRespCode(); if (StringUtils.isNotBlank(isoRespCode)) { // 服务端到银联已经响应成功,但客户端因超时交易未知 if (Const.ISO_RESPCODE_OK.equals(isoRespCode)) { cashLoad.setTransStatus(Const.TransStatus.SUCCESS); } else { cashLoad.setTransStatus(Const.TransStatus.FAILED); isoRespCode = Const.TP_BEGIN_ISO + StringUtils.leftPad( "" + Integer.parseInt(isoRespCode.replace("A", "10")), 3, "0"); cashLoad.setErrCode(isoRespCode); } return; } } CupsTrmnl cupsTrmnl = cupsTrmnlService.findByTrmnlNoAndMrchNo(payCups.getTrmnlNo(), payCups.getTrmnlMrchNo()); if (cupsTrmnl == null) { throw new TransferFailedException( AppExCode.TERMINAL_NOT_EXIST, "sysncPayLog failed,not find CupsTrmnl"); } reversalProcess.process(cupsTrmnl, payCups); cashLoad.setTransStatus(TransStatus.FAILED); }
/** * 分页查询PayUpmp表 * * @return */ public List<SendFlow> insertPayUpmp(List<PayUpmp> payUpmpList) { List<SendFlow> flowList = new LinkedList<SendFlow>(); for (PayUpmp payUpmp : payUpmpList) { SendFlow sendFlow = new SendFlow(); String transCode = null; // 交易类型判断 switch ((payUpmp.getTransType())) { case 1: transCode = "S00"; // 签到 break; case 2: transCode = "S22"; // 消费 break; case 3: transCode = "V52"; // 消费撤销 break; case 4: transCode = "R22"; // 消费冲正 break; case 5: transCode = "R22"; // 撤销冲正 break; case 6: transCode = "S00"; // 余额查询 break; case 7: transCode = "S22"; // 北京渠道-转账 break; case 8: transCode = "V52"; // 北京渠道-转账撤销 break; case 9: transCode = "S00"; // 生活服务-余额查询 break; case 10: transCode = "S22"; // 生活服务-卡卡转账 break; case 11: transCode = "S22"; // 生活服务-信用卡还款 break; case 12: transCode = "S22"; // 生活服务-手机充值 break; case 13: transCode = "I00"; // IC卡脚本上送 break; case 14: transCode = "E23"; // 退货 break; default: break; } sendFlow.setPayNo(payUpmp.getPayNo()); // 本地增值流水ID sendFlow.setAccountNo(payUpmp.getCardNo()); // 主账号 2 sendFlow.setAmount(payUpmp.getTransAmt()); // 交易金额 4 if ("S22".equals(transCode) || "V52".equals(transCode) || "S00".equals(transCode)) { // 消费、撤销、查询、生活服务0200 sendFlow.setMsgType("0200"); } if ("R22".equals(transCode)) { // 冲正交易送0400 sendFlow.setMsgType("0400"); } if ("I00".equals(transCode)) { // IC卡脚本上送 0620 sendFlow.setMsgType("0620"); } if ("E23".equals(transCode)) { // 退货送0220 sendFlow.setMsgType("0220"); } // 消息类型 sendFlow.setSettleDate(payUpmp.getSettlementDate()); // 清算日期 15 sendFlow.setAcqOrgId(payUpmp.getAcqCode()); // 受理机构标识码 32 sendFlow.setRespCode(payUpmp.getRespCode()); // 应答码 39 /*List<CupsTrmnl> cupsTrmnlList = cupsTrmnlService.findByMrchNo(payUpmp.getMrchNo()); if(null != cupsTrmnlList){ sendFlow.setTermId(cupsTrmnlList.get(0).getTrmnlNo());//终端编号 41 }*/ sendFlow.setTermId("01080209"); sendFlow.setTermIdt(payUpmp.getMrchNo()); // 受卡方标识码 42 (商户编号) sendFlow.setTransCode(transCode); // 交易代码 sendFlow.setMcc(payUpmp.getMrchNo().substring(7, 11)); // 商户类型(MCC码) CardBin cardBin = null; String cardType = null; if (null != (payUpmp.getCardNo()) && !("".equals((payUpmp.getCardNo())) && payUpmp.getCardNo().length() > 6)) { cardBin = cardBinService.findByCardNo((payUpmp.getCardNo())); } if (null != cardBin) { cardType = cardBin.getCardType(); sendFlow.setCardType(cardType); // 卡性质 } sendFlow.setBrancStructure("100200"); // 所属分支结构(江苏) String acqCode = payUpmp.getAcqCode(); // 受理机构标识码 String mercInstitution = null; if (null != acqCode) { acqCode = acqCode.trim(); } // 根据受理机构标识码判断商户所属机构 if ("48023010".equals(acqCode)) { mercInstitution = "100200"; // 南京 } if ("48023070".equals(acqCode)) { mercInstitution = "100201"; // 连云港 } if ("48023140".equals(acqCode)) { mercInstitution = "100202"; // 镇江 } if ("48023110".equals(acqCode)) { mercInstitution = "100203"; // 盐城 } if ("48023060".equals(acqCode)) { mercInstitution = "100204"; // 南通 } if ("48023050".equals(acqCode)) { mercInstitution = "100205"; // 苏州 } if ("48023020".equals(acqCode)) { mercInstitution = "100206"; // 无锡 } if ("48023040".equals(acqCode)) { mercInstitution = "100207"; // 常州 } if ("48023120".equals(acqCode)) { mercInstitution = "100208"; // 扬州 } if ("48023160".equals(acqCode)) { mercInstitution = "100209"; // 泰州 } if ("48023030".equals(acqCode)) { mercInstitution = "100210"; // 徐州 } if ("48023080".equals(acqCode)) { mercInstitution = "100211"; // 淮安 } if ("48023180".equals(acqCode)) { mercInstitution = "100212"; // 宿迁 } sendFlow.setMercInstitution(mercInstitution); // 商户所属机构 if (!"S22".equals(transCode)) { // 冲正类交易 sendFlow.setOrgAmount(payUpmp.getTransAmt()); // 原始交易金额送交易金额 } sendFlow.setLeadChannel("ulinkTraditon"); // 前置渠道默认upmp sendFlow.setPaymentChannel("ulinkTraditon"); // 支付通道默认upmp // 业务类型&产品编码&统一后业务类型 String serviceType = null; String productCoding = null; String finalServiceType = null; if (2 == (payUpmp.getTransType())) { // upmp收单 serviceType = "5A02"; productCoding = "5A02"; finalServiceType = "02"; } sendFlow.setServiceType(serviceType); // 业务类型 sendFlow.setProductCoding(productCoding); // 产品编码 sendFlow.setFinalServiceType(finalServiceType); // 统一后业务类型 List<CupsTrmnl> cupsTrmnlList = cupsTrmnlService.findByMrchNo(payUpmp.getMrchNo()); if (null != cupsTrmnlList) { sendFlow.setAccpTermNo(cupsTrmnlList.get(0).getTrmnlNo()); // 受理点终端编号 } sendFlow.setAccpMercNo(payUpmp.getMrchNo()); // 受理点商户编号 sendFlow.setInitTerm("11"); // 发起终端(移动pos) sendFlow.setUpmpTransStatus(payUpmp.getTransStatus() + ""); // UPMP交易状态 sendFlow.setTransOccrrenceTime(payUpmp.getCreTime()); // 交易发生时间 sendFlow.setCreTime(new Date()); // 获得创建日期 // 放入List flowList.add(sendFlow); } return flowList; }
public UlinkplusResponseInfo process( CupsTrmnl cupsTrmnl, UlinkplusKeyManage ulinkplusKeyManage, UlinkplusRequestInfo request) throws TransferFailedException { logger.info("ulinkplus渠道信用卡手续费查询开始..."); // 1.组装报文 CreditcardFeeQueryTradeRequestEntity requestEntity = packUp(cupsTrmnl, ulinkplusKeyManage, request); // TODO 是否需要记录交易流水 // 1.2mac计算 byte[] iso_8583_main = requestEntity.pack(); byte[] input = ArrayUtils.subarray(iso_8583_main, 6, iso_8583_main.length - 8); // 去除body head byte[] macKey = CodecUtils.hex2byte(ulinkplusKeyManage.getTrmnlMacKey()); // byte[] mac = MacUtils.tCountMAC_CBC(input, macKey); // input = ArrayUtils.subarray(iso_8583_main, 0, iso_8583_main.length-8); // iso_8583_main = ArrayUtils.addAll(input, mac); byte[] mac; try { mac = CodecUtils.hex2byte(hsmService.calculateMAC_LOCALLIFE(macKey, input)); input = ArrayUtils.subarray(iso_8583_main, 0, iso_8583_main.length - 8); iso_8583_main = ArrayUtils.addAll(input, mac); } catch (HSMException e) { String hsmRespCode = XPOSPClientUtils.getCode(e); if (!AppExCode.UNKNOWN.equals(hsmRespCode)) { hsmRespCode = Const.TP_BEGIN_HSM + hsmRespCode; } logger.error( "ulinkplus credicard fee query failed,when calculate mac form hsm error code[" + hsmRespCode + "]"); throw new TransferFailedException( hsmRespCode, "ulinkplus credicard fee query failed,when calculate mac form hsm error code[" + hsmRespCode + "]"); } // 1.3组装报文报文头 byte[] iso_8583_body = ArrayUtils.addAll( XPOSPClientUtils.getTpduHeader(XpospSysProperty.getUlinkPlusQmf1TPDU()).pack(), iso_8583_main); String iso_8583_body_length = StringUtils.leftPad(Integer.toHexString(iso_8583_body.length), 4, "0"); byte[] iso_8583_length = ISOUtils.hex2byte(iso_8583_body_length); byte[] iso_8583 = ArrayUtils.addAll(iso_8583_length, iso_8583_body); // 2.发送报文 byte[] respData = TCPUtils.getInstance().sendReciveMsg(iso_8583, XpospSysProperty.getUlinkPlusQMFIP_PORT()); // 3.解析报文 UlinkplusResponseInfo response = new UlinkplusResponseInfo(); try { CreditcardFeeQueryTradeResponseEntity responseEntity = unpack(respData); // CreditcardFeeQueryTradeResponseEntity responseEntity = getResponseData(null); String isoRespCode = responseEntity.getRespCode(); if (!Const.ISO_RESPCODE_OK.equals(isoRespCode)) { isoRespCode = XPOSPClientUtils.getRespCode(isoRespCode); isoRespCode = Const.TP_BEGIN_ISO + StringUtils.leftPad("" + Integer.parseInt(isoRespCode), 3, "0"); logger.info( "pay via ulinkplus failed,iso error code[" + responseEntity.getRespCode() + "]"); throw new TransferFailedException( isoRespCode, "pay via ulinkplus failed,iso error code[" + responseEntity.getRespCode() + "]"); } // 响应 try { String selfDefined48 = new String(responseEntity.getSelfDefined48(), "GBK"); logger.debug("信用卡还款手续费查询,48域信息:" + selfDefined48); // 位置 长度 格式 内容 说明 // 0 2 n2 用法标志 “PA” // 2 2 n2 帐单号码类型 08 // 4 12 n12 还款总金额 右对齐,左补空格 // 16 12 n12 手续费 右对齐,左补空格 // 28 12 n12 还款金额 右对齐,左补空格 // 40 100 Ans100 终端提示信息 左对齐,右补空格 // 140 11 N11 手机号码 左对齐,右补空格 // 151 1 ans1 结束标志 # response.setFee( StringUtils.amtToBigDecimal(StringUtils.trimToEmpty(selfDefined48.substring(16, 28))) .toPlainString()); response.setMsgTip( StringUtils.trimToEmpty(selfDefined48.substring(40, selfDefined48.length() - 12))); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } } catch (RuntimeException e) { // 更新终端流水 cupsTrmnlService.updateCupsTrmnlFlowNo(cupsTrmnl); throw e; } logger.info("ulinkplus渠道手机充值结束..."); return response; }
@Override public boolean icScriptUpload(ICScriptUploadRequest request) { boolean isIcScriptUloadSuccess = false; List<ICScript> lists = request.getIcScripts(); for (ICScript temp : lists) { if (temp == null) { continue; } // 获取原始交易信息 String originalPayNo = temp.getTransRefNo(); if (StringUtils.isEmpty(originalPayNo)) { throw new TransferFailedException( AppExCode.ILLEGAL_PARAMS, "goodee isScript upload failed! not find original payNo[" + originalPayNo + "]"); } PayCups originalPayCups = payCupsService.findPayCups(originalPayNo); if (originalPayCups == null) { throw new TransferFailedException( AppExCode.TRANS_NOT_EXIST, "goodee isScript upload failed! not find original payNo[" + originalPayNo + "]"); } int transTypeInt = originalPayCups.getTransType(); if (!(TransType.CONSUME.getOrdinal() == transTypeInt || TransType.BALANCE.getOrdinal() == transTypeInt)) { throw new TransferFailedException( AppExCode.NOT_SUPPORTED_OPERATION, getDescription() + " channel not support icsSriptUpload[" + transTypeInt + "] operation"); } CupsTrmnl cupsTrmnl = cupsTrmnlService.findByTrmnlNoAndMrchNo( originalPayCups.getTrmnlNo(), originalPayCups.getTrmnlMrchNo()); PaySignUp paySignUp = paySignUpService.findPaySignUpByMrchNoAndTrmnlNo( originalPayCups.getTrmnlMrchNo(), originalPayCups.getTrmnlNo()); CupsKeyManage cupsKeyManage = new CupsKeyManage(); cupsKeyManage.setTrmnlMacKey(paySignUp.getTrmnlMacKey()); // 保存二次授权数据 JSONObject json = JSONObject.fromObject(temp); originalPayCups.setIcScriptRlst(json.toString()); originalPayCups = payCupsService.updatePayCups(originalPayCups); // 如果二次授权失败,则发起冲正交易,成功则保存二次授权数据,并且如果有脚本则上送脚本交易 if (temp.getSecondAuthRlst() != null && temp.getSecondAuthRlst() == false) { // reversalProcess.process(cupsTrmnl, originalPayCups); } else { if (StringUtils.isNotEmpty(temp.getScriptExecuteRslt())) { CupsRequestInfo requestInfo = new CupsRequestInfo(); requestInfo.setOriginalPayNo(temp.getTransRefNo()); requestInfo.setIcScript(temp); try { icScriptUploadProcess.process(cupsTrmnl, cupsKeyManage, requestInfo); } catch (TransferFailedException e) { throw e; } } } } isIcScriptUloadSuccess = true; return isIcScriptUloadSuccess; }
@Override public CardInfo balance(Device device, BalanceRequest request) throws TransferFailedException { logger.info("entryMode:" + request.getEntryMode()); logger.info("Pinblock is not null:" + StringUtils.isNotBlank(request.getPinblock())); logger.info("EmvTransInfo is not null:" + StringUtils.isNotBlank(request.getEmvTransInfo())); // 校验数据 if (StringUtils.isBlank(request.getCardNo())) { throw new TransferFailedException( AppExCode.ILLEGAL_PARAMS, "goodee balance failed,cardNo null"); } if (StringUtils.isBlank(request.getTrack2Data()) && StringUtils.isBlank(request.getTrackData())) { throw new TransferFailedException( AppExCode.ILLEGAL_PARAMS, "goodee banlance failed,track2data or trackData null"); } // 卡输入方式 if (StringUtils.isNotBlank(request.getEntryMode())) { boolean isOk = isEntryModeOk(request.getEntryMode(), request.getPinblock(), request.getEmvTransInfo()); if (!isOk) { throw new TransferFailedException( AppExCode.ILLEGAL_PARAMS, "goodee balance failed,entryMode is " + request.getEntryMode() + " but pinBlock is not null:" + StringUtils.isNotBlank(request.getPinblock()) + " ,emvTransInfo is not null:" + StringUtils.isNotBlank(request.getEmvTransInfo())); } } // 获取当前设备的终端信息 CupsTrmnl cupsTrmnl = cupsTrmnlService.findById(device.getBindTransId()); if (cupsTrmnl == null) { throw new TransferFailedException( AppExCode.TERMINAL_NOT_EXIST, "goodee banlance failed,not find CupsTrmnl"); } // 获取密钥信息 DeviceKeymanage deviceKeymanage = deviceKeymanageService.findDeviceKeymanageByDevId(device.getDevId()); if (deviceKeymanage == null) { throw new TransferFailedException( AppExCode.DEVICE_KEY_NOT_EXIST, "goodee balance failed,not find deviceKeymanage info"); } PaySignUp paySignUp = paySignUpService.findPaySignUpByMrchNoAndTrmnlNo( cupsTrmnl.getMrchNo(), cupsTrmnl.getTrmnlNo()); if (paySignUp == null) { throw new TransferFailedException( AppExCode.TERMINAL_KEY_NOT_EXIST, "goodee pay failed,not find cups signUp info"); } // 密钥体系转换 CupsKeyManage cupsKeyManage = new CupsKeyManage(); cupsKeyManage.setDevPinKey(deviceKeymanage.getPinkey()); cupsKeyManage.setTrmnlPinKey(paySignUp.getTrmnlPinKey()); cupsKeyManage.setTrmnlMacKey(paySignUp.getTrmnlMacKey()); // CUPS请求信息 CupsRequestInfo requestInfo = new CupsRequestInfo(); requestInfo.setPinblock(request.getPinblock()); requestInfo.setEmvTransInfo(request.getEmvTransInfo()); requestInfo.setCardSeqNum(request.getCardSeqNum()); requestInfo.setCurrency(request.getCurrency().getCodeN()); try { TrackContext trackContext = getTrackData(deviceKeymanage.getDatakey(), request.getTrackData()); requestInfo.setCardNo(trackContext.getTrack2Data().split("=")[0]); requestInfo.setTrack2Data(trackContext.getTrack2Data()); requestInfo.setTrack3Data(trackContext.getTrack3Data()); } catch (HSMException e) { String hsmRespCode = XPOSPClientUtils.getCode(e); if (!AppExCode.UNKNOWN.equals(hsmRespCode)) { hsmRespCode = Const.TP_BEGIN_HSM + hsmRespCode; } throw new TransferFailedException( hsmRespCode, "goodee balance failed, when descrypt track data form hsm error code[" + hsmRespCode + "]"); } CupsResponseInfo cupsResponseInfo = new CupsResponseInfo(); try { cupsResponseInfo = balanceProcess.process(cupsTrmnl, cupsKeyManage, requestInfo); } catch (TransferFailedException e) { String errorCode = XPOSPClientUtils.getCode(e); processErrorCode(errorCode, cupsTrmnl); throw e; } CardInfo cardInfo = new CardInfo(); cardInfo.setTransRefNo(cupsResponseInfo.getPayNo()); cardInfo.setTransCode(cupsResponseInfo.getTransCode()); cardInfo.setCardNo(request.getCardNo()); // 返回的卡号需带有掩码 cardInfo.setBalance(cupsResponseInfo.getBalance()); cardInfo.setEmvTransInfo(cupsResponseInfo.getEmvTransInfo()); return cardInfo; }
@Override public void refund(Device device, PayRefund refund, RefundRequest request) throws TransferFailedException { logger.info("entryMode:" + request.getEntryMode()); logger.info("Pinblock is not null:" + StringUtils.isNotBlank(request.getPinblock())); logger.info("EmvTransInfo is not null:" + StringUtils.isNotBlank(request.getEmvTransInfo())); // 校验数据 if (StringUtils.isBlank(request.getTrack2Data()) && StringUtils.isBlank(request.getTrackData())) { throw new TransferFailedException( AppExCode.ILLEGAL_PARAMS, "goodee refund failed,track2data or trackData null"); } // 卡输入方式 if (StringUtils.isNotBlank(request.getEntryMode())) { boolean isOk = isEntryModeOk(request.getEntryMode(), request.getPinblock(), request.getEmvTransInfo()); if (!isOk) { throw new TransferFailedException( AppExCode.ILLEGAL_PARAMS, "goodee refund failed,entryMode is " + request.getEntryMode() + " but pinBlock is not null:" + StringUtils.isNotBlank(request.getPinblock()) + " ,emvTransInfo is not null:" + StringUtils.isNotBlank(request.getEmvTransInfo())); } } // modify by zengyj 20140331 cancel by orginal trmnl not by device trmnl; // 获取当前设备的终端信息 PayCups originalPayCups = payCupsService.findPayCups(request.getLastTransRefNo()); if (originalPayCups == null) { throw new TransferFailedException( AppExCode.TRANS_NOT_EXIST, "goodee refund failed,not find originalPayCups"); } CupsTrmnl cupsTrmnl = cupsTrmnlService.findByTrmnlNoAndMrchNo( originalPayCups.getTrmnlNo(), originalPayCups.getTrmnlMrchNo()); if (cupsTrmnl == null) { throw new TransferFailedException( AppExCode.TERMINAL_NOT_EXIST, "goodee refund failed,not find CupsTrmnl"); } // 获取密钥信息 DeviceKeymanage deviceKeymanage = deviceKeymanageService.findDeviceKeymanageByDevId(device.getDevId()); if (deviceKeymanage == null) { throw new TransferFailedException( AppExCode.DEVICE_KEY_NOT_EXIST, "goodee refund failed,not find deviceKeymanage info"); } PaySignUp paySignUp = paySignUpService.findPaySignUpByMrchNoAndTrmnlNo( cupsTrmnl.getMrchNo(), cupsTrmnl.getTrmnlNo()); if (paySignUp == null) { throw new TransferFailedException( AppExCode.TERMINAL_KEY_NOT_EXIST, "goodee refund failed,not find cups signUp info"); } // 密钥体系转换 CupsKeyManage cupsKeyManage = new CupsKeyManage(); cupsKeyManage.setDevPinKey(deviceKeymanage.getPinkey()); cupsKeyManage.setTrmnlPinKey(paySignUp.getTrmnlPinKey()); cupsKeyManage.setTrmnlMacKey(paySignUp.getTrmnlMacKey()); // CUPS请求信息 CupsRequestInfo requestInfo = new CupsRequestInfo(); requestInfo.setPayNo(refund.getPayrefundNo()); requestInfo.setAmount(refund.getPayAmt()); requestInfo.setOriginalPayNo(request.getLastTransRefNo()); requestInfo.setPinblock(request.getPinblock()); requestInfo.setEmvTransInfo(request.getEmvTransInfo()); requestInfo.setCardSeqNum(request.getCardSeqNum()); requestInfo.setExtFld01(request.getStoreNo()); requestInfo.setOrderNo(request.getOrderNo()); try { TrackContext trackContext = getTrackData(deviceKeymanage.getDatakey(), request.getTrackData()); requestInfo.setCardNo(trackContext.getTrack2Data().split("=")[0]); requestInfo.setTrack2Data(trackContext.getTrack2Data()); requestInfo.setTrack3Data(trackContext.getTrack3Data()); } catch (HSMException e) { String hsmRespCode = XPOSPClientUtils.getCode(e); if (!AppExCode.UNKNOWN.equals(hsmRespCode)) { hsmRespCode = Const.TP_BEGIN_HSM + hsmRespCode; } throw new TransferFailedException( hsmRespCode, "goodee refund failed, when descrypt track data form hsm error code[" + hsmRespCode + "]"); } try { refundProcess.process( cupsTrmnl, cupsKeyManage, requestInfo, getAddress(refund.getAppAccessId())); } catch (TransferFailedException e) { String errorCode = XPOSPClientUtils.getCode(e); processErrorCode(errorCode, cupsTrmnl); throw e; } // 如果没有抛异常,则交易成功 refund.setTransStatus(Const.TransStatus.SUCCESS); }
@Override public void cashLoad(Device device, PayCashLoad cashLoad, CashLoadRequest request) throws TransferFailedException { logger.info("entryMode:" + request.getEntryMode()); logger.info("Pinblock is not null:" + StringUtils.isNotBlank(request.getPinblock())); logger.info("EmvTransInfo is not null:" + StringUtils.isNotBlank(request.getEmvTransInfo())); // 校验数据 if (StringUtils.isBlank(request.getCardNo())) { throw new TransferFailedException(AppExCode.ILLEGAL_PARAMS, "cash Load failed,cardNo null"); } if (StringUtils.isBlank(request.getTrackData())) { throw new TransferFailedException( AppExCode.ILLEGAL_PARAMS, "cash Load failed,track2data or trackData null"); } // 卡输入方式 if (StringUtils.isNotBlank(request.getEntryMode())) { boolean isOk = isEntryModeOk(request.getEntryMode(), request.getPinblock(), request.getEmvTransInfo()); if (!isOk) { throw new TransferFailedException( AppExCode.ILLEGAL_PARAMS, "cash PayCupsTransferChannel failed,entryMode is " + request.getEntryMode() + " but pinBlock is not null:" + StringUtils.isNotBlank(request.getPinblock()) + " ,emvTransInfo is not null:" + StringUtils.isNotBlank(request.getEmvTransInfo())); } } // 获取当前设备的终端信息 // CupsTrmnl cupsTrmnl = cupsTrmnlService.findById(device.getBindTransId()); String trmnlNo = XpospSysProperty.getUlinkPlusQmf3TrmnlNo(); String mrchNo = XpospSysProperty.getUlinkPlusQmf3MrchNo(); logger.info("电子现金圈存交易 发到渠道的商户号[" + mrchNo + "],终端号[" + trmnlNo + "]"); CupsTrmnl cupsTrmnl = cupsTrmnlService.findByTrmnlNoAndMrchNo(trmnlNo, mrchNo); if (cupsTrmnl == null) { throw new TransferFailedException( AppExCode.TERMINAL_NOT_EXIST, "cash Load failed,not find CupsTrmnl"); } // 获取密钥信息 DeviceKeymanage deviceKeymanage = deviceKeymanageService.findDeviceKeymanageByDevId(device.getDevId()); if (deviceKeymanage == null) { throw new TransferFailedException( AppExCode.DEVICE_KEY_NOT_EXIST, "cash Load failed,not find deviceKeymanage info"); } PaySignUp paySignUp = paySignUpService.findPaySignUpByMrchNoAndTrmnlNo( cupsTrmnl.getMrchNo(), cupsTrmnl.getTrmnlNo()); if (paySignUp == null) { throw new TransferFailedException( AppExCode.TERMINAL_KEY_NOT_EXIST, "cash Load failed,not find cups signUp info"); } // 密钥体系转换 CupsKeyManage cupsKeyManage = new CupsKeyManage(); cupsKeyManage.setDevPinKey(deviceKeymanage.getPinkey()); cupsKeyManage.setTrmnlPinKey(paySignUp.getTrmnlPinKey()); cupsKeyManage.setTrmnlMacKey(paySignUp.getTrmnlMacKey()); // CUPS请求信息 CupsRequestInfo requestInfo = new CupsRequestInfo(); requestInfo.setPayNo(cashLoad.getCashLoadNo()); requestInfo.setAmount(request.getAmount()); requestInfo.setPinblock(request.getPinblock()); requestInfo.setEmvTransInfo(request.getEmvTransInfo()); requestInfo.setCardSeqNum(request.getCardSeqNum()); requestInfo.setCurrency(request.getCurrency().getCodeN()); requestInfo.setExtFld01(request.getStoreNo()); requestInfo.setOrderNo(request.getOrderNo()); try { TrackContext trackContext = getTrackData(deviceKeymanage.getDatakey(), request.getTrackData()); requestInfo.setCardNo(trackContext.getTrack2Data().split("=")[0]); requestInfo.setTrack2Data(trackContext.getTrack2Data()); requestInfo.setTrack3Data(trackContext.getTrack3Data()); } catch (HSMException e) { String hsmRespCode = XPOSPClientUtils.getCode(e); if (!AppExCode.UNKNOWN.equals(hsmRespCode)) { hsmRespCode = Const.TP_BEGIN_HSM + hsmRespCode; } throw new TransferFailedException( hsmRespCode, "cash Load failed, when descrypt track data form hsm error code[" + hsmRespCode + "]"); } CupsResponseInfo responseInfo = null; try { // 构建发起金融交易 responseInfo = cashLoadProcess.process(cupsTrmnl, cupsKeyManage, requestInfo); } catch (TransferFailedException e) { String errorCode = XPOSPClientUtils.getCode(e); processErrorCode(errorCode, cupsTrmnl); throw e; } // 如果没有抛异常,则交易成功 cashLoad.setTransStatus(Const.TransStatus.SUCCESS); cashLoad.setTransCode(responseInfo.getTransCode()); cashLoad.setEmvTransInfo(responseInfo.getEmvTransInfo()); }
@Override public void cashPay(final Device device, final Payment payment, final PaymentRequest request) throws TransferFailedException { logger.info("entryMode:" + request.getEntryMode()); logger.info("EmvTransInfo is not null :" + StringUtils.isNotBlank(request.getEmvTransInfo())); // 校验数据 if (StringUtils.isBlank(request.getCardNo())) { throw new TransferFailedException(AppExCode.ILLEGAL_PARAMS, "pay failed ,cardNo null"); } // 卡输入方式 // if(StringUtils.isNotBlank(request.getEntryMode())){ // boolean isOk=isEntryModeOk(request.getEntryMode(),request.getPinblock(), // request.getEmvTransInfo()); // if(!isOk){ // throw new TransferFailedException(AppExCode.ILLEGAL_PARAMS, "pay failed,entryMode is // "+request.getEntryMode()+" but pinBlock is not // null:"+StringUtils.isNotBlank(request.getPinblock())+" ,emvTransInfo is not // null:"+StringUtils.isNotBlank(request.getEmvTransInfo())); // } // } // 非接交易时候,55域的tag“9F74”必须出现 if (StringUtils.isBlank(request.getEmvTransInfo())) { throw new TransferFailedException( AppExCode.ILLEGAL_PARAMS, "pay failed,emvTransInfo is" + request.getEmvTransInfo()); } // 获取当前设备的终端信息 CupsTrmnl cupsTrmnl = cupsTrmnlService.findById(device.getBindTransId()); if (cupsTrmnl == null) { throw new TransferFailedException( AppExCode.TERMINAL_NOT_EXIST, "pay failed,not find CupsTrmnl"); } // 获取密钥信息 DeviceKeymanage deviceKeymanage = deviceKeymanageService.findDeviceKeymanageByDevId(device.getDevId()); if (deviceKeymanage == null) { throw new TransferFailedException( AppExCode.DEVICE_KEY_NOT_EXIST, "pay failed,not find deviceKeymanage info"); } PaySignUp paySignUp = paySignUpService.findPaySignUpByMrchNoAndTrmnlNo( cupsTrmnl.getMrchNo(), cupsTrmnl.getTrmnlNo()); if (paySignUp == null) { throw new TransferFailedException( AppExCode.TERMINAL_KEY_NOT_EXIST, "pay failed,not find cups signUp info"); } // 当定时签到失败的时候,需要重新发起到银联签到 // 密钥体系转换 CupsKeyManage cupsKeyManage = new CupsKeyManage(); cupsKeyManage.setDevPinKey(deviceKeymanage.getPinkey()); cupsKeyManage.setTrmnlPinKey(paySignUp.getTrmnlPinKey()); cupsKeyManage.setTrmnlMacKey(paySignUp.getTrmnlMacKey()); // CUPS请求信息 CupsRequestInfo requestInfo = new CupsRequestInfo(); requestInfo.setPayNo(payment.getPayNo()); requestInfo.setAmount(request.getAmount()); requestInfo.setPinblock(request.getPinblock()); requestInfo.setEmvTransInfo(request.getEmvTransInfo()); requestInfo.setCardSeqNum(request.getCardSeqNum()); requestInfo.setEntryMode(request.getEntryMode()); requestInfo.setCurrency(request.getCurrency().getCodeN()); requestInfo.setExtFld01(request.getStoreNo()); requestInfo.setCardNo(request.getCardNo()); requestInfo.setCardExpiryDay(request.getCardExpire()); requestInfo.setOrderNo(request.getOrderNo()); requestInfo.setIcScript(request.getIcScript()); CupsResponseInfo responseInfo = null; try { responseInfo = cashConsumeProcess.process(cupsTrmnl, cupsKeyManage, requestInfo); } catch (TransferFailedException e) { String errorCode = XPOSPClientUtils.getCode(e); processErrorCode(errorCode, cupsTrmnl); throw e; } // 如果没有抛异常,则交易成功 payment.setTransStatus(Const.TransStatus.SUCCESS); payment.setTransCode(responseInfo.getTransCode()); payment.setEmvTransInfo(responseInfo.getEmvTransInfo()); }
public PepsiColaResponseInfo process( CupsTrmnl cupsTrmnl, CupsKeyManage cupsKeyManage, PepsiColaRequestInfo request) throws TransferFailedException { logger.info("[PepsiCola渠道IC卡脚本上送开始...]"); // 1.组装报文 IcScriptUploadTradeRequestEntity requestEntity = packUp(cupsTrmnl, cupsKeyManage, request); // iso mac计算 byte[] iso_8583_main = requestEntity.pack(); byte[] input = ArrayUtils.subarray(iso_8583_main, 6, iso_8583_main.length - 8); byte[] macKey = CodecUtils.hex2byte(cupsKeyManage.getTrmnlMacKey()); byte[] mac; try { mac = hsmService.calculateMAC_CUPS(macKey, input).getBytes(); input = ArrayUtils.subarray(iso_8583_main, 0, iso_8583_main.length - 8); iso_8583_main = ArrayUtils.addAll(input, mac); } catch (HSMException e) { String hsmRespCode = XPOSPClientUtils.getCode(e); if (!AppExCode.UNKNOWN.equals(hsmRespCode)) { hsmRespCode = Const.TP_BEGIN_HSM + hsmRespCode; } logger.error("[IC卡脚本上送失败,calculate mac form hsm error code:" + hsmRespCode + "]"); throw new TransferFailedException( hsmRespCode, "[IC卡脚本上送失败, 加密机计算MAC失败, errorCode:" + hsmRespCode + "]"); } // 组装报文报文头 byte[] iso_8583_body = ArrayUtils.addAll( XPOSPClientUtils.getTpduHeader(XpospSysProperty.getPepsiColaTPDU()).pack(), iso_8583_main); String iso_8583_body_length = StringUtils.leftPad(Integer.toHexString(iso_8583_body.length), 4, "0"); byte[] iso_8583_length = ISOUtils.hex2byte(iso_8583_body_length); byte[] iso_8583 = ArrayUtils.addAll(iso_8583_length, iso_8583_body); // 新增银联CUPS流水记录 {2,3,4,11,22,25,26,35,36,41,42,49,52,53,60,64} String payNo = transRefNoGenerator.generate(); PayCups payCups = new PayCups(); payCups.setPayNo(payNo); payCups.setCardNo(requestEntity.getCardNo()); payCups.setProcessCode(requestEntity.getProcessCode()); payCups.setTrmnlFlowNo(requestEntity.getTrmnlFlowNo()); payCups.setTrmnlBatchNo(cupsTrmnl.getTrmnlBatchNo()); payCups.setPosEntryMode(requestEntity.getPosEntryMode()); payCups.setCardSeqNum(request.getCardSeqNum()); payCups.setTrmnlNo(requestEntity.getTrmnlNo()); payCups.setTrmnlMrchNo(requestEntity.getTrmnlMrchNo()); payCups.setCurrency(requestEntity.getCurrency()); payCups.setIcData(request.getEmvTransInfo()); payCups.setSelfDefined060(requestEntity.getSelfDefined60()); payCups.setOriginalInfo(requestEntity.getOriginalMessage()); payCups.setTransType(TransType.ICSCRIPTUPLOAD.getOrdinal()); payCups.setSubChannel(SubChannelType.PEPSICOLATRANSFERCHANNEL.getChannelName()); payCupsService.addPayCups(payCups); // 打包,新增流水记录后更新终端流水信息 cupsTrmnlService.updateCupsTrmnlFlowNo(cupsTrmnl); // 2.发送报文 byte[] respData = TCPUtils.getInstance().sendReciveMsg(iso_8583, XpospSysProperty.getPepsiColaIP_PORT()); // 3.解析报文 PepsiColaResponseInfo pepsiColaResponseInfo = new PepsiColaResponseInfo(); try { IcScriptUploadTradeResponseEntity responseEntity = unpack(respData); String isoRespCode = responseEntity.getRespCode(); if (!Const.ISO_RESPCODE_OK.equals(isoRespCode)) { payCups.setRespCode(isoRespCode); isoRespCode = isoRespCode.replace("A", "10"); payCupsService.updatePayCups(payCups); isoRespCode = Const.TP_BEGIN_ISO + StringUtils.leftPad("" + Integer.parseInt(isoRespCode), 3, "0"); logger.error("[pay via cups failed, iso error code:" + isoRespCode + "]"); throw new TransferFailedException( isoRespCode, "[pay via cups failed, so error code:" + isoRespCode + "]"); } // 更新交易流水 payCups.setTransDate(responseEntity.getTransDate()); payCups.setTransTime(responseEntity.getTransTime()); payCups.setSettlementDate(responseEntity.getSettlementDate()); payCups.setRespCode(responseEntity.getRespCode()); payCupsService.updatePayCups(payCups); pepsiColaResponseInfo.setTransCode( Const.TP_BEGIN_ISO + StringUtils.leftPad("" + Integer.parseInt(isoRespCode), 3, "0")); // 响应 } catch (RuntimeException e) { throw e; } logger.info("[PepsiCola渠道IC卡脚本上送结束...]"); return pepsiColaResponseInfo; }