package com.yc.sdk.shopping.action.jiazhuang; import java.math.BigDecimal; import java.text.SimpleDateFormat; import java.util.Date; import java.util.List; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Scope; import org.springframework.dao.DataAccessException; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.context.WebApplicationContext; import com.github.binarywang.wxpay.bean.entpay.EntPayBankRequest; import com.github.binarywang.wxpay.bean.entpay.EntPayBankResult; import com.github.binarywang.wxpay.bean.entpay.EntPayRequest; import com.github.binarywang.wxpay.bean.entpay.EntPayResult; import com.github.binarywang.wxpay.config.WxPayConfig; import com.github.binarywang.wxpay.exception.WxPayException; import com.github.binarywang.wxpay.service.impl.WxPayServiceImpl; import com.google.gson.JsonObject; import com.yc.action.BaseAction; import com.yc.entity.DataSourceEntity; import com.yc.exception.ApplicationException; import com.yc.factory.FactoryBean; import com.yc.multiData.MultiDataSource; import com.yc.multiData.SpObserver; import com.yc.sdk.miniapp.service.MaUserIfc; import com.yc.sdk.shopping.action.jiazhuang.task.PanicBuyingTaskIfc; import com.yc.sdk.shopping.entity.CurrencyEntity; import com.yc.sdk.shopping.entity.DocCodeStateEntity; import com.yc.sdk.shopping.entity.EnterprisePayResultEntity; import com.yc.sdk.shopping.entity.SettingEntity; import com.yc.sdk.shopping.entity.WithdrawalSummaryEntity; import com.yc.sdk.shopping.entity.WxWithdrawalsInBankEntity; import com.yc.sdk.shopping.service.CurrencyIfc; import com.yc.sdk.shopping.service.SettingIfc; import com.yc.sdk.shopping.service.wxpay.WxPayIfc; import com.yc.sdk.shopping.util.SettingKey; import com.yc.sdk.weixincp.util.AsynchronousExecution; import com.yc.sdk.weixinmp.entity.MyWxMpUser; import com.yc.utils.SessionKey; @Controller @Scope("prototype") @RequestMapping("/shopping/customerWithdrawal.do") public class CustomerWithdrawal extends BaseAction { @Autowired WxPayIfc wxPayIfc; @Autowired CurrencyIfc currencyIfc; @Autowired SettingIfc settingIfc; @Autowired MaUserIfc maUserIfc ; @Autowired PanicBuyingTaskIfc panicBuyingTaskIfc; @RequestMapping(params = "m=toWeChatWallet") public void toWeChatWallet(HttpServletRequest request, HttpServletResponse response) throws WxPayException{ HttpSession session = request.getSession(); //String hostUrl = SettingKey.getHostUrl(request); JsonObject json = new JsonObject(); JsonObject errJson = new JsonObject(); String amountStr = request.getParameter("amount"); String usercode = (String) session.getAttribute(SessionKey.USERCODE); String cltCode = (session.getAttribute(SettingKey.CLTCODE) == null ? "" : (String) session.getAttribute(SettingKey.CLTCODE)); //mpEntity = MultiDataSource.getDataSourceMap(dbId); // 用户id String openId = (String) session.getAttribute(SessionKey.WEIXIN_OPENID); String wx = (String) session.getAttribute(SessionKey.WEIXIN_FROM) ; // 执行存储过程获取单号 int formId = 151702; String docCode = null; try { DataSourceEntity dataSourceEntity = MultiDataSource.getDataSourceMap( request) ; SpObserver.setDBtoInstance("_"+dataSourceEntity.getDbId());//切换数据源 SettingEntity settingEntity = settingIfc.getSettingEntity(request) ; double amount=Double.parseDouble(amountStr); int receivedAmount = (int) (amount * 100.00); //税额:提现时需要向平台方缴纳的税费 double taxAmount = amount - amount * (1.0 - settingEntity.getWithdrawTaxRate()) ; BigDecimal bg = new BigDecimal(taxAmount); //保留2位小数 double feeAmount = bg.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue(); //保留2位小数的税额 receivedAmount = receivedAmount - (int) (feeAmount * 100.00) ; //实际支付金额为扣税后的金额 WithdrawalSummaryEntity withdrawalSummaryEntity = wxPayIfc.getWithdrawalSummaryForToday(openId); if (withdrawalSummaryEntity!=null) { if (settingEntity.getWithdrawTimes() > 0 && withdrawalSummaryEntity.getTodayTimes()+1 > settingEntity.getWithdrawTimes()) { errJson.addProperty("warning", "您已达到今日提现次数"+ (new Double( settingEntity.getWithdrawTimes())).intValue()+"次,请明日再提现"); json.add("error", errJson); this.printJson(response, json.toString()); return; } if (settingEntity.getWithdrawAmount() > 0 && withdrawalSummaryEntity.getTodayAmount() +amount > settingEntity.getWithdrawAmount()) { errJson.addProperty("warning", "您已达到今日提现限额"+ settingEntity.getWithdrawAmount()+"元,请明日再提现"); json.add("error", errJson); this.printJson(response, json.toString()); return; } } CurrencyEntity currencyEntity = new CurrencyEntity(request); String currency = currencyEntity.getCurrency(); // 执行存储过程获取单号并确定提现订单, @PaymentMethod ='0' , --付款方式:0 提现到零钱, 1 提现到银行卡 docCode = wxPayIfc.saveWithdrawDocCode(usercode, openId, currency, "0", "","","", amount, settingEntity.getWithdrawTaxRate(), feeAmount,((double)receivedAmount)*1.00/100.00 ); if (docCode == null || docCode.equals("")) { errJson.addProperty("warning", "创建【微信提现到零钱】订单失败【功能号:" + formId + "】"); json.add("error", errJson); this.printJson(response, json.toString()); return; } MyWxMpUser myWxMpUser = maUserIfc.getUser(openId) ; //个人认证过期天数,正数表示已过期天数,负数表示即将过期天数,null 表示从未认证过 //参考:/wx/miniapp/user/panicBuyingLogin.do 接口写法 if ((myWxMpUser.getExpiryDays()==null||myWxMpUser.getExpiryDays().intValue()>0) && settingEntity.getWithdrawalExpiryHours().intValue() > 0) { //未认证商家,提现后多少小时才能到账,根据 settingEntity.getWithdrawalExpiryHours() 参数决定 wxPayIfc.updateEntPayExpiryDateTimeTo7Day(docCode); DocCodeStateEntity docCodeStateEntity = wxPayIfc.getEntPayDocStatus( docCode) ; //加入提现计划 panicBuyingTaskIfc.addWithdrawalTask( dataSourceEntity,docCodeStateEntity); json.addProperty("info", "您的提现已经申请,将在"+settingEntity.getWithdrawalExpiryHours()+"小时内到账"); json.addProperty("state", "success"); this.printJson(response, json.toString()); return; } //认证商家,提现立即到账 // 执行企业付款到零钱的操作 EnterprisePayResultEntity enterprisePayResultEntity = enterprisePayToWeChatWallet( dataSourceEntity, wx, docCode,formId, openId, receivedAmount); if (enterprisePayResultEntity.isSuccess()) { json.addProperty("info", enterprisePayResultEntity.getMessage()); json.addProperty("state", "success"); this.printJson(response, json.toString()); return; } else { errJson.addProperty("warning", enterprisePayResultEntity.getMessage()); json.add("error", errJson); this.printJson(response, json.toString()); return; } } catch (DataAccessException e) { e.printStackTrace(); errJson.addProperty("warning",( e.getCause() != null ?e.getCause().getMessage():e.getMessage())); json.add("error", errJson); this.printJson(response, json.toString()); return; } catch (WxPayException e) { e.printStackTrace(); //String wxMsg= "错误信息:" + e.getReturnMsg()+",错误代码:" + e.getErrCode()+",结果代码:"+e.getResultCode() + ",错误描述:"+ e.getErrCodeDes() ; String wxMsg= (e.getErrCodeDes() != null && !"".equals(e.getErrCodeDes())?e.getErrCodeDes():e.getCustomErrorMsg()) ; errJson.addProperty("warning",wxMsg); json.add("error", errJson); this.printJson(response, json.toString()); return; } catch (Exception e) { e.printStackTrace(); errJson.addProperty("warning",( e.getCause() != null ?e.getCause().getMessage():e.getMessage())); json.add("error", errJson); this.printJson(response, json.toString()); return; } finally { SpObserver.setDBtoInstance(); } } /** * 企业付款到银行卡api , 此功能为灰度开放暂时不提供使用 * * 1.获取到的公匙先需要按一定的格式排列目前所知道是64位排列,程序 splitPubKey 已实现 64 位排列 * 2.再需要经过openssl 转换成PKCS#8 编码格式 (openssl 至少1.1以上) * 3.转换代码:openssl rsa -RSAPublicKey_in -in -pubout * 4.去掉开头 "-----BEGIN PUBLIC KEY-----" 和结尾 "-----END PUBLIC KEY-----" 部分,只保留中间的部分 * 5.把去掉开头和结尾后的中间内容写入文件 : "WEB-INF" + File.separator+"wxpay" + File.separator+dbId + File.separator+"cert" + File.separator + "PubKeyPkcs8.pem" * 注意 :只有这样才能正确的加密敏感信息,如卡号、姓名,微信服务器在接收后才能成功解密这些敏感信息,否则微信服务器会报错,导致提现到银行卡失败 * 参考微信“企业支付到银行卡”: https://pay.weixin.qq.com/wiki/doc/api/tools/mch_pay.php?chapter=24_2 */ @RequestMapping(params = "m=toBankCard") public void toBankCard(HttpServletRequest request, HttpServletResponse response) { String amountStr = request.getParameter("amount"); String encTrueName = request.getParameter("encTrueName"); //持卡人真实姓名 String encBankNo = request.getParameter("encBankNo"); //银行卡号 String bankCode = request.getParameter("bankCode"); //银行编号 String bankName = request.getParameter("bankName"); //银行名称 HttpSession session = request.getSession(); //String hostUrl = SettingKey.getHostUrl(request); // 将微信corpid组装成url //String wxQueryString = SettingKey.getQueryStringByWx(request); //boolean isMoblieBrowser = SettingKey.isMoblieBrowser(request); String wx = (String) session.getAttribute(SessionKey.WEIXIN_FROM) ; JsonObject json = new JsonObject(); JsonObject errJson = new JsonObject(); //String dbId = (String) session.getAttribute(SessionKey.SHOPPING_DBID); String usercode = (String) session.getAttribute(SessionKey.USERCODE); String cltCode = (session.getAttribute(SettingKey.CLTCODE) == null ? "" : (String) session.getAttribute(SettingKey.CLTCODE)); String cltName = (session.getAttribute(SettingKey.CLTNAME) == null ? "" : (String) session.getAttribute(SettingKey.CLTNAME)); //String weiXinAvatarUnid=(String) session.getAttribute(SessionKey.WEIXIN_HEADIMGURL); String nickName=(String) session.getAttribute(SessionKey.WEIXIN_NICKNAME); if (cltCode == null || "".equals(cltCode) ) { //String queryString = request.getQueryString(); errJson.addProperty("warning", "您还未注册,请先注册!"); json.add("error", errJson); this.printJson(response, errJson.toString()); return; }else { session.removeAttribute(SettingKey.REDIRECT); } //DataSourceEntity mpEntity = MultiDataSource.getDataSourceMap(dbId); // 用户id String openId = (String) session.getAttribute(SessionKey.WEIXIN_OPENID); try { DataSourceEntity dataSourceEntity = MultiDataSource.getDataSourceMap( request) ; SpObserver.setDBtoInstance("_"+dataSourceEntity.getDbId());//切换数据源 SettingEntity settingEntity = settingIfc.getSettingEntity(request) ; // String appId = dataSourceEntity.getMpAppId(); //缺省是公众号付款到银行卡 // if (wx!=null&& "3".equals(wx)) { //小程序付款 // appId = dataSourceEntity.getMiniAppId() ; // } if (amountStr == null || amountStr.equals("")) { amountStr = "0"; } double amount=Double.parseDouble(amountStr); int receivedAmount = (int) (amount * 100.00); //税额 double taxAmount = amount - amount * (1.0 - settingEntity.getWithdrawTaxRate()) ; BigDecimal bg = new BigDecimal(taxAmount); //保留2位小数 double feeAmount = bg.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue(); //保留2位小数的税额 receivedAmount = receivedAmount - (int) (feeAmount * 100.00) ; //实际支付金额为扣税后的金额 WithdrawalSummaryEntity withdrawalSummaryEntity = wxPayIfc.getWithdrawalSummaryForToday(openId); if (withdrawalSummaryEntity!=null) { if (settingEntity.getWithdrawTimes() > 0 && withdrawalSummaryEntity.getTodayTimes()+1 > settingEntity.getWithdrawTimes()) { errJson.addProperty("warning", "您已达到今日提现次数"+ settingEntity.getWithdrawTimes()+"次,请明日再提现"); json.add("error", errJson); this.printJson(response, json.toString()); return; } if (settingEntity.getWithdrawAmount() > 0 && withdrawalSummaryEntity.getTodayAmount()+amount > settingEntity.getWithdrawAmount()) { errJson.addProperty("warning", "您已达到今日提现限额"+ settingEntity.getWithdrawAmount()+"元,请明日再提现"); json.add("error", errJson); this.printJson(response, json.toString()); return; } } CurrencyEntity currencyEntity = new CurrencyEntity(request); String currency = currencyEntity.getCurrency(); //把客户银行卡信息 保存erp if(!bankName.equals("老卡提现")){ WxWithdrawalsInBankEntity wxWithdrawalsInBankEntity=new WxWithdrawalsInBankEntity(); wxWithdrawalsInBankEntity.setOpenId(openId); wxWithdrawalsInBankEntity.setNickName(nickName); //wxWithdrawalsInBankEntity.setWeiXinAvatarUnid(weiXinAvatarUnid); wxWithdrawalsInBankEntity.setCltCode(cltCode); wxWithdrawalsInBankEntity.setCltName(cltName); wxWithdrawalsInBankEntity.setBankName(bankName); wxWithdrawalsInBankEntity.setBankCode(bankCode); wxWithdrawalsInBankEntity.setEncBankNo(encBankNo); wxWithdrawalsInBankEntity.setEncTrueName(encTrueName); wxWithdrawalsInBankEntity.setMemo(""); wxWithdrawalsInBankEntity.setStatus(1); wxPayIfc.saveCustomerBankinfo(wxWithdrawalsInBankEntity); } // 执行存储过程获取单号确定提现订单 // 执行存储过程获取单号 , @PaymentMethod ='0' , --付款方式:0 提现到零钱, 1 提现到银行卡 int formId = 151702; String docCode = wxPayIfc.saveWithdrawDocCode(usercode, openId, currency, "1",bankCode,encBankNo,encTrueName, amount,settingEntity.getWithdrawTaxRate(), feeAmount,((double)receivedAmount)*1.00/100.00); if (docCode == null || docCode.equals("")) { errJson.addProperty("warning", "创建提现订单失败【功能号:" + formId + "】"); json.add("error", errJson); this.printJson(response, errJson.toString()); return; } MyWxMpUser myWxMpUser = maUserIfc.getUser(openId) ; //个人认证过期天数,正数表示已过期天数,负数表示即将过期天数,null 表示从未认证过 //参考:/wx/miniapp/user/panicBuyingLogin.do 接口写法 if (myWxMpUser.getExpiryDays()==null||myWxMpUser.getExpiryDays().intValue()>0) { //未认证商家,7天后提现才能到账 wxPayIfc.updateEntPayExpiryDateTimeTo7Day(docCode); //获取提现单据状态 DocCodeStateEntity docCodeStateEntity = wxPayIfc.getEntPayDocStatus( docCode) ; //加入提现计划 panicBuyingTaskIfc.addWithdrawalTask( dataSourceEntity,docCodeStateEntity); json.addProperty("info", "您的提现已经申请,将在7天内到账"); json.addProperty("state", "success"); this.printJson(response, json.toString()); return; } // 执行企业付款到银行卡的操作 EnterprisePayResultEntity enterprisePayResultEntity = CustomerWithdrawal.enterprisePayToBankCard( dataSourceEntity, wx, docCode,formId, openId, receivedAmount,encBankNo,encTrueName,bankCode); if (enterprisePayResultEntity.isSuccess()) { json.addProperty("info", enterprisePayResultEntity.getMessage()); json.addProperty("state", "success"); this.printJson(response, json.toString()); return; } else { errJson.addProperty("warning", enterprisePayResultEntity.getMessage()); json.add("error", errJson); this.printJson(response, json.toString()); return; } } catch (DataAccessException e) { e.printStackTrace(); errJson.addProperty("warning",( e.getCause() != null ?e.getCause().getMessage():e.getMessage())); json.add("error", errJson); this.printJson(response, json.toString()); return; } catch (WxPayException e) { e.printStackTrace(); //String wxMsg= "错误信息:" + e.getReturnMsg()+",错误代码:" + e.getErrCode()+",结果代码:"+e.getResultCode() + ",错误描述:"+ e.getErrCodeDes() ; String wxMsg= (e.getErrCodeDes() != null && !"".equals(e.getErrCodeDes())?e.getErrCodeDes():e.getCustomErrorMsg()) ; errJson.addProperty("warning",wxMsg); json.add("error", errJson); this.printJson(response, json.toString()); return; } catch (Exception e) { e.printStackTrace(); errJson.addProperty("warning",( e.getCause() != null ?e.getCause().getMessage():e.getMessage())); json.add("error", errJson); this.printJson(response, json.toString()); return; } finally { SpObserver.setDBtoInstance(); } } /** * 执行企业付款到微信零钱的操作 * @param dataSourceEntity 数据源 dataSourceEntity * @param wx 1 表示企业号,2 表示公众号 ,3表示小程序 * @param docCode 提现的单号 * @param openId 收款人 openid * @param receivedAmount 提现金额 * @return EntPayResult * @throws WxPayException */ public static EnterprisePayResultEntity enterprisePayToWeChatWallet(DataSourceEntity dataSourceEntity, String wx,String docCode,Integer formId,String openId,int receivedAmount) throws WxPayException{ WxPayIfc wxPayIfc = (WxPayIfc) FactoryBean.getBean("WxPayImpl") ; try { SpObserver.setDBtoInstance("_"+dataSourceEntity.getDbId());//切换数据源 String appId = dataSourceEntity.getMpAppId(); //缺省公众号付款到零钱 if (wx!=null&& "3".equals(wx)) { //小程序付款 appId = dataSourceEntity.getMiniAppId() ; } // 本机ip // 循环排除192,127,172,10等开头的ip取剩下的其中一个 List ipi = AsynchronousExecution.getAllNetInterfaces(); for (int i = 0; i < ipi.size(); i++) { if (ipi.get(i).startsWith("192.") || ipi.get(i).startsWith("127.") || ipi.get(i).startsWith("172.") || ipi.get(i).startsWith("10.")) { ipi.remove(i); } } String notifyUrl = dataSourceEntity.getCorpURL() + SettingKey.WXPAY_WIDTHDRAWALS_NOTICE_URL; WxPayConfig payConfig = new WxPayConfig(); payConfig.setAppId(appId); payConfig.setMchId(dataSourceEntity.getMpMchId()); payConfig.setNotifyUrl(notifyUrl); payConfig.setTradeType("JSAPI"); payConfig.setMchKey(dataSourceEntity.getMpMchKey()); payConfig.setKeyPath(getRootPath() //request.getSession().getServletContext().getRealPath("/") + SettingKey.getWxPayCertPath(dataSourceEntity.getDbId()+"")); // cjdhHcPekjMaWcmdjBBsPocMdewsePdj WxPayServiceImpl wxPayService = new WxPayServiceImpl(); wxPayService.setConfig(payConfig); EntPayRequest entPayRequest = EntPayRequest.newBuilder() .mchAppid(appId) .mchId(dataSourceEntity.getMpMchId()) .partnerTradeNo(docCode) .openid(openId) // 是否实名验证 NO_CHECK为非是非实名验证,FORCE_CHECK强制实名验证 .checkName("NO_CHECK") .amount(receivedAmount) .description("收入") .spbillCreateIp("14.152.59.89") // 测试需要 正式屏蔽 .build(); EnterprisePayResultEntity enterprisePayResultEntity = new EnterprisePayResultEntity(); // wxEntPayRequest.setSpbillCreateIp(ipi.get(0));//正式环境下使用 // 执行企业付款到零钱的操作 EntPayResult retu = wxPayService.getEntPayService().entPay(entPayRequest); String msg = ""; if (retu.getReturnCode().equalsIgnoreCase("success") &&retu.getResultCode().equalsIgnoreCase("success")) { msg= "提现成功,实到账" + (receivedAmount/100.00)+"元"; try { //更新备注信息 wxPayIfc.saveEntPayDocCodeMemo(docCode,msg,SettingKey.EnterprisePaySuccess ); }catch (DataAccessException e) { msg = "提现成功,客户已收到零钱,但回写单据【"+docCode+"】备注时出错,错误信息:" + ( e.getCause() != null ?e.getCause().getMessage():e.getMessage()); //失败时发送模板消息 wxPayIfc.doSendWxTemplateMsg(docCode, formId, "FAILED", msg, "确认"); }catch(Exception e) { throw e ; } enterprisePayResultEntity.setMessage(msg); enterprisePayResultEntity.setSuccess(true); return enterprisePayResultEntity; } else { // 执行存储过程,提现失败后删除创建的提现单据和确认提现单据 //wxPayIfc.delEntPayDocCode(doccode); //不要删除原单据 Date now = new Date() ; SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");//显示2017-10-27 10:00:00格式 //更新备注信息 String wxMsg= ";时间:" + sdf.format(now) + ",错误信息:" + retu.getReturnMsg()+",错误代码:" + retu.getErrCode()+",结果代码:"+retu.getResultCode() + ",错误描述:"+ retu.getErrCodeDes() + ",微信服务器返回错误原值"+ retu.getRetMsg(); try { wxPayIfc.doWithdrawDocCodeCancelPost(docCode); //更新备注信息 wxPayIfc.saveEntPayDocCodeMemo(docCode, wxMsg,2); }catch (DataAccessException e) { msg = "提现失败,微信服务器返回错误:" + wxMsg + ",但回写单据【"+docCode+"】备注时出错,出错提示:" + ( e.getCause() != null ?e.getCause().getMessage():e.getMessage()); }catch(Exception e) { throw e ; } //失败时发送模板消息 wxPayIfc.doSendWxTemplateMsg(docCode, formId, "FAILED", msg, "确认"); enterprisePayResultEntity.setMessage(msg); enterprisePayResultEntity.setSuccess(false); return enterprisePayResultEntity; } } catch (DataAccessException e) { throw e; } catch (WxPayException e) { try { SpObserver.setDBtoInstance("_"+dataSourceEntity.getDbId());//切换数据源 wxPayIfc.doWithdrawDocCodeCancelPost(docCode); Date now = new Date() ; SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");//显示2017-10-27 10:00:00格式 //更新备注信息 String wxMsg= ";时间:" + sdf.format(now) + ",错误信息:" + e.getReturnMsg()+",错误代码:" + e.getErrCode()+",结果代码:"+e.getResultCode() + ",错误描述:"+ e.getErrCodeDes() + ",微信服务器返回错误原值"+ e.getMessage(); wxPayIfc.saveEntPayDocCodeMemo(docCode,wxMsg,SettingKey.EnterprisePayFailed ); } finally { SpObserver.setDBtoInstance(); } throw e ; } catch (Exception e) { throw e ; } finally { SpObserver.setDBtoInstance(); } } /** * 执行企业付款到银行卡的操作 * @param dataSourceEntity 数据源 dataSourceEntity * @param wx 1 表示企业号,2 表示公众号 ,3表示小程序 * @param docCode 提现的单号 * @param openId 收款人 openid * @param receivedAmount 提现金额 * @param cardId 银行卡号 * @param cardName 持卡人姓名(真实姓名) * @param bankId 银行代码 ,见功能号 710131 * @return EntPayResult * @throws WxPayException */ public static EnterprisePayResultEntity enterprisePayToBankCard(DataSourceEntity dataSourceEntity, String wx,String docCode,Integer formId,String openId,int receivedAmount,String cardId,String cardName,String bankId) throws WxPayException{ WxPayIfc wxPayIfc = (WxPayIfc) FactoryBean.getBean("WxPayImpl") ; try { SpObserver.setDBtoInstance("_"+dataSourceEntity.getDbId());//切换数据源 String appId = dataSourceEntity.getMpAppId(); //缺省公众号付款到零钱 if (wx!=null&& "3".equals(wx)) { //小程序付款 appId = dataSourceEntity.getMiniAppId() ; } // 本机ip // 循环排除192,127,172,10等开头的ip取剩下的其中一个 List ipi = AsynchronousExecution.getAllNetInterfaces(); for (int i = 0; i < ipi.size(); i++) { if (ipi.get(i).startsWith("192.") || ipi.get(i).startsWith("127.") || ipi.get(i).startsWith("172.") || ipi.get(i).startsWith("10.")) { ipi.remove(i); } } String notifyUrl = dataSourceEntity.getCorpURL() + SettingKey.WXPAY_WIDTHDRAWALS_NOTICE_URL; WxPayConfig payConfig = new WxPayConfig(); payConfig.setAppId(appId); payConfig.setMchId(dataSourceEntity.getMpMchId()); payConfig.setNotifyUrl(notifyUrl); payConfig.setTradeType("JSAPI"); payConfig.setMchKey(dataSourceEntity.getMpMchKey()); payConfig.setKeyPath(getRootPath() //request.getSession().getServletContext().getRealPath("/") + SettingKey.getWxPayCertPath(dataSourceEntity.getDbId()+"")); // cjdhHcPekjMaWcmdjBBsPocMdewsePdj WxPayServiceImpl wxPayService = new WxPayServiceImpl(); wxPayService.setConfig(payConfig); EntPayBankRequest entPayBankRequest = EntPayBankRequest.builder().partnerTradeNo(docCode) .encBankNo(cardId).encTrueName(cardName).bankCode(bankId).amount(receivedAmount).description("收入").build(); // 执行企业付款到银行卡的操作 EntPayBankResult retu = wxPayService.getEntPayService().payBank(entPayBankRequest); // 正式环境下使用 EnterprisePayResultEntity enterprisePayResultEntity = new EnterprisePayResultEntity(); String msg = ""; if (retu.getReturnCode().equalsIgnoreCase("success") &&retu.getResultCode().equalsIgnoreCase("success")) { msg= "提现成功,实到账" + (receivedAmount/100.00)+"元"; try { //更新备注信息 wxPayIfc.saveEntPayDocCodeMemo(docCode,msg,SettingKey.EnterprisePaySuccess ); }catch (DataAccessException e) { msg = "提现成功,客户已收到零钱,但回写单据【"+docCode+"】备注时出错,错误信息:" + ( e.getCause() != null ?e.getCause().getMessage():e.getMessage()); //失败时发送模板消息 wxPayIfc.doSendWxTemplateMsg(docCode, formId, "FAILED", msg, "确认"); }catch(Exception e) { throw e ; } enterprisePayResultEntity.setMessage(msg); enterprisePayResultEntity.setSuccess(true); return enterprisePayResultEntity; } else { // 执行存储过程,提现失败后删除创建的提现单据和确认提现单据 //wxPayIfc.delEntPayDocCode(doccode); //不要删除原单据 Date now = new Date() ; SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");//显示2017-10-27 10:00:00格式 //更新备注信息 String wxMsg= ";时间:" + sdf.format(now) + ",错误信息:" + retu.getReturnMsg()+",错误代码:" + retu.getErrCode()+",结果代码:"+retu.getResultCode() + ",错误描述:"+ retu.getErrCodeDes() ; try { wxPayIfc.doWithdrawDocCodeCancelPost(docCode); //更新备注信息 wxPayIfc.saveEntPayDocCodeMemo(docCode, wxMsg,SettingKey.EnterprisePayFailed ); }catch (DataAccessException e) { msg = "提现失败,微信服务器返回错误:" + wxMsg + ",但回写单据【"+docCode+"】备注时出错,出错提示:" + ( e.getCause() != null ?e.getCause().getMessage():e.getMessage()); }catch(Exception e) { throw e ; } //失败时发送模板消息 wxPayIfc.doSendWxTemplateMsg(docCode, formId, "FAILED", msg, "确认"); enterprisePayResultEntity.setMessage(msg); enterprisePayResultEntity.setSuccess(false); return enterprisePayResultEntity; } } catch (DataAccessException e) { throw e; } catch (WxPayException e) { try { SpObserver.setDBtoInstance("_"+dataSourceEntity.getDbId());//切换数据源 wxPayIfc.doWithdrawDocCodeCancelPost(docCode); Date now = new Date() ; SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");//显示2017-10-27 10:00:00格式 //更新备注信息 String wxMsg= ";时间:" + sdf.format(now) + ",错误信息:" + e.getReturnMsg()+",错误代码:" + e.getErrCode()+",结果代码:"+e.getResultCode() + ",错误描述:"+ e.getErrCodeDes() + ",微信服务器返回错误原值"+ e.getMessage(); //更新备注信息 wxPayIfc.saveEntPayDocCodeMemo(docCode, wxMsg,2); }catch (Exception f) { throw f ; } finally { SpObserver.setDBtoInstance(); } throw e ; } catch (Exception e) { throw e ; } finally { SpObserver.setDBtoInstance(); } } /** * 获取根目录路径 rootPath * 取操作系统名称,判断是否 windows ,因为在windows 环境下 rootPath值为:"/D:/workspace/eCoWorksV3-test/WebRoot/WEB-INF/classes/" * @return */ public static String getRootPath() { String rootPath = null ; WebApplicationContext webApplicationContext = FactoryBean.getCtx() ; if (webApplicationContext != null) { rootPath = webApplicationContext.getServletContext().getRealPath("/"); } if (rootPath == null || "".equals(rootPath)) { String classPath = Thread.currentThread().getContextClassLoader().getResource("").getPath() ; if (classPath!=null) { rootPath = classPath.replace("WEB-INF/classes/", "") ; } //取操作系统名称,判断是否 windows ,因为在windows 环境下 rootPath值为:"/D:/workspace/eCoWorksV3-test/WebRoot/WEB-INF/classes/" //因此,必须去掉前面的斜线 / String OS = System.getProperty("os.name").toLowerCase(); if (OS.indexOf("windows")>=0) { rootPath = rootPath.substring(1, rootPath.length()) ; //去掉前面的斜线 / } } if (rootPath == null || "".equals(rootPath)) { throw new ApplicationException("系统还没有初始化完成,无法获取上下文信息,因此获取 rootPath 根目录路径失败") ; } return rootPath; } }