package com.minpay.common.pay; import com.huilian.api.open.huilianjavademo.XmlUtil; import com.min.base64.Base64; import com.min.des.DesUtils; import com.minpay.common.bean.User; import com.minpay.common.exception.BusinessCodeException; import com.minpay.common.pay.bean.Huilianpay; import com.minpay.common.service.IAccountService; import com.minpay.common.service.IHuilianPayService; import com.minpay.common.service.IPropertiesService; import com.minpay.common.service.IPublicService; import com.minpay.common.service.impl.HuilianPayServiceImpl; import com.minpay.common.util.CommonUtil; import com.minpay.common.util.DateUtil; import com.minpay.common.util.HttpPostUtil; import com.minpay.common.util.PayCommonUtil; import com.minpay.db.table.mapper.*; import com.minpay.db.table.model.*; import com.minpay.db.table.own.mapper.DeliveryMapper; import com.minpay.shouhuo.deliveryaction.DeliveryAction; import com.minpay.shouhuo.orderdrawaction.OrderDrawAction; import com.startup.minpay.frame.business.IMINAction; import com.startup.minpay.frame.business.MINHttpServletRequestContext; import com.startup.minpay.frame.business.res.MINActionResult; import com.startup.minpay.frame.constant.IMINTransactionEnum; import com.startup.minpay.frame.exception.MINBusinessException; import com.startup.minpay.frame.service.base.IMINDataBaseService; import com.startup.minpay.frame.service.base.Service; import com.startup.minpay.frame.session.MINSession; import com.startup.minpay.frame.target.MINAction; import com.startup.minpay.frame.target.MINComponent; import com.startup.minpay.frame.target.MINParam; import net.sf.json.JSONObject; import org.apache.commons.lang.StringUtils; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.BufferedReader; import java.io.InputStream; import java.io.InputStreamReader; import java.io.PrintWriter; import java.util.*; /** * 售货机支付通用接口 * @author Zhumq * */ @MINComponent public class ShouhuoPay implements IMINAction{ /** 通用支付 */ public final static String MIN_COMMMON_PAY = "minCommmonPay"; /** PersonalPay支付回调 */ public final static String PERSONALPAY_CALL_BACK = "personalPayCallBack"; /** 查询PersonalPay的订单状态 */ public final static String QUERY_PERSONALPAY_ORDERSTT = "queryPersonalpayOrderstt"; /** * 通用支付 * @param payAmt 支付总金额 * @param orderId 支付订单号 * @param payType 支付方式(01 账户支付、02 预付卡支付、03 网银支付、04快捷支付 91微信支付92支付宝支付 93钱包支付) * @param session * @param fapRequest * @return * @throws Exception */ @MINAction(value = MIN_COMMMON_PAY, transaction = IMINTransactionEnum.CMT) public MINActionResult minCommmonPay( @MINParam(key = "payAmt") String payAmt, @MINParam(key = "orderId") String orderId, @MINParam(key = "payType", defaultValue = "91") String payType, MINSession session, MINHttpServletRequestContext fapRequest ) throws Exception { MINActionResult res = new MINActionResult(); //获取操作员信息 User user = session.getUser(); //获取当前时间 String nowTime = DateUtil.getCurrentDateTimeString(); String oldID = orderId; VmOrderInf ordInf = Service.lookup(IMINDataBaseService.class).getMybatisMapper(VmOrderInfMapper.class).selectByPrimaryKey(oldID); if(CommonUtil.compare(payAmt, ordInf.getOrderAmt()) != 0){ throw new MINBusinessException("交易异常");//支付金额不对 } VmPaymentInfExample paymentExp = new VmPaymentInfExample(); paymentExp.createCriteria().andChannelEqualTo(user.getChannel()).andTranflownoEqualTo(orderId); List paymenList = Service.lookup(IMINDataBaseService.class).getMybatisMapper(VmPaymentInfMapper.class).selectByExample(paymentExp); // 如果已经支付过一次 if(paymenList.size() > 0) { // 0 初始状态,1成功,2失败,3在途,4待审核,5已审核 if(!"0".equals(paymenList.get(0).getStatus()) && !"3".equals(paymenList.get(0).getStatus())) { throw new MINBusinessException("订单已经在支付中!"); } // 再次支付 if("3".equals(paymenList.get(0).getStatus())) { // 复制订单明细/订单/支付流水 // 支付状态修改 ordInf.setState("80"); // 支付状态 80:已重新支付 VmOrderInfExample orderExp = new VmOrderInfExample(); orderExp.createCriteria().andIdEqualTo(oldID); Service.lookup(IMINDataBaseService.class).getMybatisMapper(VmOrderInfMapper.class).updateByExampleSelective(ordInf, orderExp); // 产生新的订单号 orderId = DateUtil.getDifferentTimeByFormat("MMddHHmmss").concat(StringUtils.substring(orderId, 10)); ordInf.setId(orderId); ordInf.setState("91"); ordInf.setPayMode(payType); Service.lookup(IMINDataBaseService.class).getMybatisMapper(VmOrderInfMapper.class).insert(ordInf); //获取订单下的详情信息 VmOrderDetailsExample examp = new VmOrderDetailsExample(); examp.createCriteria().andChannelEqualTo(user.getChannel()).andOrderIdEqualTo(oldID); List detailList = Service.lookup(IMINDataBaseService.class) .getMybatisMapper(VmOrderDetailsMapper.class) .selectByExample(examp); int flags = 0; // 循环插入明细表 for(VmOrderDetails detDto : detailList) { String att = null; if(flags < 10){ att = "0"+flags; }else{ att = flags +""; } // 订单号 detDto.setDetailsId(orderId.concat(att)); detDto.setOrderId(orderId); detDto.setModifyUser(user.getId()); detDto.setModifyTime(nowTime); Service.lookup(IMINDataBaseService.class).getMybatisMapper(VmOrderDetailsMapper.class).insert(detDto); flags ++; } // 循环插入支付明细 String flowno = Service.lookup(IPublicService.class).getSequence("VM_PAYMENT_INF_ID"); for(VmPaymentInf payMentInf : paymenList) { //收支类型:00供应商收款01订单退款02平台分润03代理分润 if("00".equals(payMentInf.getType())){ payMentInf.setFlowno(nowTime.concat(flowno).concat("sh")); }else if("01".equals(payMentInf.getType())){ payMentInf.setFlowno(nowTime.concat(flowno).concat("tk")); }else if("02".equals(payMentInf.getType())){ payMentInf.setFlowno(nowTime.concat(flowno).concat("pt")); }else if("03".equals(payMentInf.getType())){ payMentInf.setFlowno(nowTime.concat(flowno).concat("dl")); } payMentInf.setTranflowno(orderId); payMentInf.setTranmissiondatetime(nowTime); // 交易状态(0 初始状态,1成功,2失败,3在途,4待审核,5已审核) payMentInf.setStatus("3"); Service.lookup(IMINDataBaseService.class).getMybatisMapper(VmPaymentInfMapper.class).insert(payMentInf); } } else { //修改支付方式 ordInf.setPayMode(payType); Service.lookup(IMINDataBaseService.class).getMybatisMapper(VmOrderInfMapper.class).updateByPrimaryKeySelective(ordInf); VmPaymentInf paymentInf = new VmPaymentInf(); // 交易状态(0 初始状态,1成功,2失败,3在途,4待审核,5已审核) paymentInf.setStatus("3"); paymentInf.setTranflowno(orderId); paymentInf.setTranmissiondatetime(DateUtil.getCurrentDateTimeString()); Service.lookup(IMINDataBaseService.class).getMybatisMapper(VmPaymentInfMapper.class).updateByExampleSelective(paymentInf, paymentExp); } }else{ //修改支付方式 ordInf.setPayMode(payType); Service.lookup(IMINDataBaseService.class).getMybatisMapper(VmOrderInfMapper.class).updateByPrimaryKeySelective(ordInf); } Map resMap = null; try { VmPaymentInf paymentInf = new VmPaymentInf(); // 支付通道 String payChannel = Service.lookup(IPublicService.class).getSysParValue(user.getChannel() +"_PERSONALPAY_PAY_CHANNEL"); //汇联 if("HLZF".equals(payChannel)) { VmEquipmentInf equipmentInf = Service.lookup(IMINDataBaseService.class).getMybatisMapper(VmEquipmentInfMapper.class).selectByPrimaryKey(ordInf.getEquipmentId()); if(equipmentInf == null) { throw new MINBusinessException("没有找到此售货机"); } String branchid = equipmentInf.getBranchid(); //查询商户开通了那个支付渠道 String pay_channel = Service.lookup(IPublicService.class).getSysParValue( "PAY_CHANNEL"); //查询机器所属机构 VmAccountExample accExp = new VmAccountExample(); accExp.createCriteria().andChannelEqualTo(user.getChannel()).andUsridEqualTo(branchid).andTypeEqualTo(pay_channel); List accList = Service.lookup(IMINDataBaseService.class).getMybatisMapper(VmAccountMapper.class).selectByExample(accExp); if(accList.size() != 1 ){ throw new MINBusinessException("商户收款账户异常"); } String accNo = accList.get(0).getNumber(); //支付后台回调地址 String notify_url = Service.lookup(IPublicService.class).getSysParValue(user.getChannel() + "_SHOUHUO_NOTIFY_URL"); //notify_url = "http://xubing2.minpay.cc/services"; notify_url = notify_url + "/ShouhuoPay/personalPayCallBack"; if("05".equals(pay_channel)){ pay_channel = "09"; } String turntablePage = Service.lookup(IPublicService.class).getSysParValue(user.getChannel() + "_SHOUHUO_TURNTABLE_PAGE"); turntablePage = turntablePage.concat("orderId="+orderId); Huilianpay prePay = new Huilianpay(); IHuilianPayService huilianPayService = new HuilianPayServiceImpl(); if("91".equals(payType)){ payType = "WX"; } if("92".equals(payType)){ payType = "ALI"; } prePay.setChannel(payType); prePay.setNotifyUrl(notify_url); prePay.setOpenId(user.getOpenid()); prePay.setOutTradeNo(orderId); prePay.setProviderType(pay_channel); prePay.setTotalAmount(payAmt); prePay.setHlMerchantId(accNo); prePay.setGoodName(orderId); prePay.setSucUrl(turntablePage); resMap = huilianPayService.prePay(prePay); } } catch (Exception e) { throw new MINBusinessException("调用支付失败"); } // 抽奖订单 /*if("01".equals(ordInf.getProType())) { // 减余额 // 创建用户基本账户 IAccountService accservice = Service.lookup(IAccountService.class); // 41:消费 accservice.modfiyAccount(ordInf.getChannel(), ordInf.getPersonId(), "01", CommonUtil.multiply(ordInf.getOrderAmt(), "-1"), "41", ordInf.getId(), "游戏消费"); //调用真实回调 backEx(ordInf.getId(), "0000000000", "TRADE_SUCCESS", ordInf.getOrderAmt(), "000000", "", "93"); // 正常商品购买、但是选择的是钱包支付 } if("00".equals(ordInf.getProType()) && "09".equals(payType)) { // 减余额 // 创建用户基本账户 IAccountService accservice = Service.lookup(IAccountService.class); // 41:消费 accservice.modfiyAccount(ordInf.getChannel(), ordInf.getPersonId(), "01", CommonUtil.multiply(ordInf.getOrderAmt(), "-1"), "41", ordInf.getId(), "购买商品"); //调用真实回调 backEx(ordInf.getId(), "0000000000", "TRADE_SUCCESS", ordInf.getOrderAmt(), "000000", "", "93"); }*/ res.set("payMap",resMap); return res; } /** * 查询PersonalPay的订单状态 * @param orderId 订单号 * @param session * @return * @throws MINBusinessException */ @MINAction(value = QUERY_PERSONALPAY_ORDERSTT) public MINActionResult queryPersonalpayOrderstt( @MINParam(key = "orderId") String orderId, MINSession session ) throws MINBusinessException { MINActionResult res = new MINActionResult(); //获取操作员信息 User user = session.getUser(); try { VmOrderInf listch = Service.lookup(IMINDataBaseService.class) .getMybatisMapper(VmOrderInfMapper.class) .selectByPrimaryKey(orderId); if(listch.getState().equals("00")){ res.set("orderId", orderId); res.set("stt", listch.getState()); res.set("code", "200"); // 00正常商品,01抽奖商品,02:充值', res.set("proType", listch.getProType()); return res; } // 支付通道 String payChannel = Service.lookup(IPublicService.class).getSysParValue(user.getChannel() +"_PERSONALPAY_PAY_CHANNEL"); String appSecret = Service.lookup(IPublicService.class).getSysParValue(user.getChannel() + "_PERSONALPAY_APP_SECRET"); if("PEP".equals(payChannel)) { String appid = Service.lookup(IPublicService.class).getSysParValue(user.getChannel() + "_PERSONALPAY_APP_ID"); String mchid = Service.lookup(IPublicService.class).getSysParValue(user.getChannel() + "_PERSONALPAY_MCH_ID"); //创建PersonalPay订单对象 SortedMap perPay = new TreeMap(); perPay.put("mchid",mchid);//商户号 perPay.put("appid", appid);//appId perPay.put("orderno",orderId);//交易订单号 perPay.put("sysorderno","");//交易订单号 perPay.put("signtype","MD5");//加密类型 String paySign = PayCommonUtil.createSign("UTF-8", perPay, appSecret); perPay.put("sign",paySign);//加密后字符串 /** * 返回值信息 * 10:创建订单 80:已重新支付 90:已取消 91:未支付 92:支付中 00 :已支付, 01 :手动通知(掉单后可手动通知) * "stt":"10", * "code":0 */ //获取请求PersonalPay的路径"http://api.personalpay.net/api/"; String url = Service.lookup(IPropertiesService.class) .getSystemProperties().get(user.getChannel() + "_PERSONALPAY_PAY_ADDRESS").getKey(); String str = PayCommonUtil.getRequestJSON(perPay); String results = HttpPostUtil.sendPostFormachine(url.concat("/OrderAction/queryOrderStt"), str); //获取转义后响应信息 JSONObject detail = JSONObject.fromObject(results); //获取code,用来判断是否认证成功 String code = String.valueOf(detail.get("code")); if(!"0".equals(code)){ throw new BusinessCodeException("JINM0115");//操作失败! } res.set("code", detail.get("code")); res.set("orderId", orderId); res.set("stt", detail.get("stt")); // 00正常商品,01抽奖商品,02:充值', res.set("proType", listch.getProType()); } } catch (Exception e) { throw new MINBusinessException("调用支付查询失败"); } return res; } /** * personalPay支付回调 * @return * @throws Exception */ @MINAction(value = PERSONALPAY_CALL_BACK, session = false) public MINActionResult personalPayCallBack( HttpServletRequest request, HttpServletResponse response ) throws Exception { PrintWriter printWriter = response.getWriter(); printWriter.write("SUCCESS"); printWriter.flush();//没有该句也是报一样错. printWriter.close(); MINActionResult res = new MINActionResult(); StringBuffer sb = new StringBuffer() ; InputStream is = request.getInputStream(); InputStreamReader isr = new InputStreamReader(is); BufferedReader br = new BufferedReader(isr); String s = "" ; while((s=br.readLine())!=null){ sb.append(s) ; } String result = sb.toString(); XmlUtil xmlUtil = new XmlUtil(); Map resMap = xmlUtil.parseb(result, "ant.mybank.bkmerchanttrade.prePayNotice"); System.out.println("通知报文:" + resMap.toString()); //支付宝或微信订单号 PayChannelOrderNo String payOrderno = resMap.get("PayChannelOrderNo").toString(); //我方订单号 OutTradeNo String orderno = resMap.get("OutTradeNo").toString(); //实付金额 BuyerPayAmount TotalAmount String amt = resMap.get("TotalAmount").toString(); amt = CommonUtil.divide(amt,"100"); //第三方订单号 OrderNo String sysorderno = resMap.get("OrderNo").toString(); //查询订单如果已支付状态表示已经回调过 //调用真实回调 backEx(orderno, sysorderno, "TRADE_SUCCESS", amt,payOrderno, "", ""); return res; } /** * 回调真实执行方法 * @param orderno 商户流水号(订单) * @param sysorderno 交易流水号 * @param status 状态 * @param amt 交易金额 * @param failReason 失败原因 * @param payChannel 支付通道(04快捷支付 91微信支付92支付宝支付 93钱包支付) * @throws Exception */ private void backEx( String orderno, String sysorderno, String status, String amt, String payOrderno, String failReason, String payChannel) throws Exception { // 交易流水号 VmPaymentInfExample paymentExp = new VmPaymentInfExample(); paymentExp.createCriteria().andTranflownoEqualTo(orderno); List payMentList = Service.lookup(IMINDataBaseService.class).getMybatisMapper(VmPaymentInfMapper.class).selectByExample(paymentExp); if(payMentList.size() == 0) { throw new MINBusinessException("error"); } // 0 初始状态 --如果已经通知过返回 // 3在途 if(!"0".equals(payMentList.get(0).getStatus()) && !"3".equals(payMentList.get(0).getStatus())) { throw new MINBusinessException("error"); } VmPaymentInf payMentInf = new VmPaymentInf(); payMentInf.setBankflowno(sysorderno); // 支付方式(01 账户支付、02 预付卡支付、03 网银支付、04快捷支付 91微信支付92支付宝支付) if(CommonUtil.isNotEmpty(payChannel)) { payMentInf.setPaytype(payChannel); } VmOrderInf orderInf = Service.lookup(IMINDataBaseService.class).getMybatisMapper(VmOrderInfMapper.class).selectByPrimaryKey(orderno); orderInf.setState("92"); // 92:支付中 // TRADE_SUCCESS:交易成功,用户付款成功 // TRADE_FINISHED:交易结束,付款金额已结算给商户 // TRADE_CLOSED:交易关闭,交易失败 if("TRADE_SUCCESS".equals(status) || "TRADE_FINISHED".equals(status)) { // 交易状态(0 初始状态,1成功,2失败,3在途,4待审核,5已审核) payMentInf.setStatus("1"); payMentInf.setSuccamount(amt);//支付成功返还金额 //支付成功时间 payMentInf.setSucctime(DateUtil.getCurrentDateTimeString()); orderInf.setState("00"); // 00:已支付 orderInf.setPayOrderno(payOrderno); // 支付平台订单号(微信、支付宝订单号) } else if("TRADE_CLOSED".equals(status)) { // 交易状态(0 初始状态,1成功,2失败,3在途,4待审核,5已审核) payMentInf.setStatus("2"); orderInf.setState("93"); // 93:支付失败 } // 不是空 if(!CommonUtil.isEmpty(failReason)) { payMentInf.setRemarktwo(failReason); } Service.lookup(IMINDataBaseService.class).getMybatisMapper(VmPaymentInfMapper.class).updateByExampleSelective(payMentInf, paymentExp); // 变更待结算账户 IAccountService service = Service.lookup(IAccountService.class); orderInf.setId(orderno); Service.lookup(IMINDataBaseService.class).getMybatisMapper(VmOrderInfMapper.class).updateByPrimaryKeySelective(orderInf); if("00".equals(orderInf.getState())){ if("01".equals(orderInf.getProType())){ //抽奖的商品走这里 OrderDrawAction drawAction = new OrderDrawAction(); drawAction.editOrderDraw(orderInf,sysorderno); }else if("00".equals(orderInf.getProType())){ //购买商品走这里 DeliveryAction.purchaseCreateDeliveryInfo(orderno,""); //执行推货 // toMachine(orderInf.getChannel(), orderno); } // 充值 else if("02".equals(orderInf.getProType())) { // 00充值(CZ) //todo 添加机器编号 service.modfiyAccount(orderInf.getChannel(), orderInf.getPersonId(), "01", amt, "00", payMentList.get(0).getFlowno(), "充值",orderInf.getEquipmentId()); } } } //推货方法 private void toMachine(String channel , String orderNo) throws Exception{ String url = Service.lookup(IPropertiesService.class) .getSystemProperties().get(channel + "_GET_MACHINE_ADDRESS").getKey(); String retUrl = Service.lookup(IPropertiesService.class) .getSystemProperties().get(channel + "_RETURN_MACHINE_ADDRESS").getKey(); //组装推送接口 String sendUrl = url.concat("/VendingMachineAction/pushGoods").concat("?MINView=JSON"); String returnUrl = retUrl.concat("/DeliveryAction/backDeliveryForMachine"); //组装传送参数 //初始化查询条件 Map map = new HashMap(); map.put("orderNo", orderNo);//订单编号 //传入渠道验证 map.put("channel", channel); List> list = Service.lookup(IMINDataBaseService.class) .getMybatisMapper(DeliveryMapper.class) .queryDeliverys(map); if(list != null && list.size() > 0){ Map mapNew = new HashMap(); mapNew.put("imeiAddr", list.get(0).get("equIMEI")); mapNew.put("cargoNo", list.get(0).get("cargoWay")); mapNew.put("deliveryNo", list.get(0).get("delveryNo")); mapNew.put("channel", channel); mapNew.put("returnUrl", returnUrl); mapNew.put("MINView", "JSON"); JSONObject jsonOb = JSONObject.fromObject(mapNew); String str = jsonOb.toString(); String passwardKey = Service.lookup(IPropertiesService.class) .getSystemProperties().get(channel +"_TO_MACHINE_PASSWORD_KEY").getKey(); //数据加密 String desDe = Base64.encode(DesUtils.getInstance().encrypt(Base64.encode(str).getBytes(),passwardKey.getBytes(),null)); //调用通用通讯接口 String results = HttpPostUtil.sendPostFormachine(sendUrl,desDe); //获取转义后响应信息 JSONObject detail = JSONObject.fromObject(results); String code = String.valueOf(detail.get("code")); VmDeliveryInf delInf = Service.lookup(IMINDataBaseService.class) .getMybatisMapper(VmDeliveryInfMapper.class).selectByPrimaryKey(list.get(0).get("delveryNo")); if(!"0".equals(code)){ //改变提货状态为3卡货(提货失败).... delInf.setStatus("3"); //throw new BusinessCodeException("JINM0011");//操作失败! }else{ //获取处理状态 String state = String.valueOf(detail.get("returnData")); JSONObject stateNew = JSONObject.fromObject(state); if("200".equals(stateNew.get("code"))){ //改变提货状态为5处理中.... delInf.setStatus("5"); }else{ //改变提货状态为3处理中.... delInf.setStatus("3"); //String msg = String.valueOf(stateNew.get("msg")); //throw new MINBusinessException(msg);//操作失败! } } //处理提货状态 Service.lookup(IMINDataBaseService.class) .getMybatisMapper(VmDeliveryInfMapper.class) .updateByPrimaryKeySelective(delInf); }else{ throw new MINBusinessException("没有提货信息!"); } } }