| @@ -113,6 +113,7 @@ public class ShiroConfig { | |||
| // } | |||
| filterChainDefinitionMap.put("/swagger-ui.html", "anon"); | |||
| filterChainDefinitionMap.put("/wxPay/notify/**", "anon"); | |||
| filterChainDefinitionMap.put("/wxPayBill/notify/**", "anon"); | |||
| filterChainDefinitionMap.put("/v2/**", "anon"); | |||
| filterChainDefinitionMap.put("/swagger-resources/**", "anon"); | |||
| filterChainDefinitionMap.put("/webjars/**", "anon"); | |||
| @@ -0,0 +1,183 @@ | |||
| package com.iformall.controller; | |||
| import com.iformall.enums.EnumPayWay; | |||
| import com.iformall.exception.BizMessageException; | |||
| import com.iformall.exception.MallinkException; | |||
| import com.iformall.pay.WxPayment; | |||
| import com.iformall.service.WxPayBillService; | |||
| import com.iformall.service.WxRefundOrderService; | |||
| import com.iformall.utils.XmlUtil; | |||
| import org.apache.commons.io.IOUtils; | |||
| import org.jdom2.JDOMException; | |||
| import org.slf4j.Logger; | |||
| import org.slf4j.LoggerFactory; | |||
| import org.springframework.beans.factory.annotation.Autowired; | |||
| import org.springframework.http.MediaType; | |||
| import org.springframework.web.bind.annotation.RequestMapping; | |||
| import org.springframework.web.bind.annotation.ResponseBody; | |||
| import org.springframework.web.bind.annotation.RestController; | |||
| import javax.servlet.http.HttpServletRequest; | |||
| import java.io.ByteArrayOutputStream; | |||
| import java.io.IOException; | |||
| import java.io.InputStream; | |||
| import java.nio.charset.Charset; | |||
| import java.util.Map; | |||
| import java.util.SortedMap; | |||
| import java.util.TreeMap; | |||
| /** | |||
| * @author gongbiao | |||
| */ | |||
| @RestController | |||
| @RequestMapping("/wxPayBill/notify") | |||
| public class WxPayBillController extends BaseController { | |||
| private final Logger logger = LoggerFactory.getLogger(this.getClass()); | |||
| @Autowired | |||
| private WxPayBillService wxPayBillService; | |||
| @Autowired | |||
| private WxRefundOrderService wxRefundOrderService; | |||
| /** | |||
| * | |||
| * @return 接收微信异步通知 | |||
| * @throws Exception 可能产生的任何异常 | |||
| */ | |||
| @RequestMapping(value = "/pay", produces = MediaType.APPLICATION_JSON_UTF8_VALUE) | |||
| @ResponseBody | |||
| public String _payNotify(HttpServletRequest request) throws IOException, JDOMException { | |||
| logger.info("微信支付回调"); | |||
| InputStream inStream = request.getInputStream(); | |||
| ByteArrayOutputStream outSteam = new ByteArrayOutputStream(); | |||
| byte[] buffer = new byte[1024]; | |||
| int len = 0; | |||
| while ((len = inStream.read(buffer)) != -1) { | |||
| outSteam.write(buffer, 0, len); | |||
| } | |||
| String resultxml = new String(outSteam.toByteArray(), Charset.forName("UTF-8")); | |||
| logger.info(resultxml); | |||
| outSteam.close(); | |||
| inStream.close(); | |||
| Map<String, String> paramMap = null; | |||
| try { | |||
| paramMap = WxPayment.xmlToMap(resultxml); | |||
| logger.info("微信支付回调, notify, param: " + paramMap.toString() ); | |||
| String response = wxPayBillService.notify(paramMap, EnumPayWay.PAY_WAY_WEAPP); | |||
| logger.info("微信支付回调, notify success, req : " + resultxml + ", resp: " + response.toString()); | |||
| return response; | |||
| } catch (BizMessageException e) { | |||
| if (paramMap == null) { | |||
| logger.error("微信支付回调, order create error, e: " + e.getMessage()); | |||
| } else { | |||
| logger.error("微信支付回调, order create error, req: " + resultxml + ", e: " + e.getMessage()); | |||
| } | |||
| SortedMap resultMap = new TreeMap<>(); | |||
| resultMap.put("return_code", "FAIL"); | |||
| resultMap.put("return_msg", e.getMessage()); | |||
| return XmlUtil.getRequestXml(resultMap); | |||
| } catch (MallinkException e) { | |||
| if (paramMap == null) { | |||
| logger.error("微信支付回调, order create error, e: " + e.getMessage()); | |||
| } else { | |||
| logger.error("微信支付回调, order create error, req: " + resultxml + ", e: " + e.getMessage()); | |||
| } | |||
| SortedMap resultMap = new TreeMap<>(); | |||
| resultMap.put("return_code", "FAIL"); | |||
| resultMap.put("return_msg", e.getMessage()); | |||
| return XmlUtil.getRequestXml(resultMap); | |||
| } catch (Exception e) { | |||
| if (paramMap == null) { | |||
| logger.error("微信支付回调, order create error, e: " + e.getMessage()); | |||
| } else { | |||
| logger.error("微信支付回调, order create error, req: " + resultxml + ", e: " + e.getMessage()); | |||
| } | |||
| SortedMap resultMap = new TreeMap(); | |||
| resultMap.put("return_code", "FAIL"); | |||
| resultMap.put("return_msg", e.getMessage()); | |||
| return XmlUtil.getRequestXml(resultMap); | |||
| } | |||
| } | |||
| /** | |||
| * | |||
| * @return 接收微信退款异步通知 | |||
| * @throws Exception 可能产生的任何异常 | |||
| */ | |||
| @RequestMapping(value = "/refund") | |||
| public String __refundNotify(HttpServletRequest request) throws Exception { | |||
| Map<String, String> paramMap = null; | |||
| String response = ""; | |||
| String xml = ""; | |||
| try { | |||
| xml = IOUtils.toString(request.getInputStream(), Charset.forName("UTF-8")); | |||
| logger.info(xml); | |||
| paramMap = WxPayment.xmlToMap(xml); | |||
| response = wxRefundOrderService.notify(paramMap, EnumPayWay.PAY_WAY_WEAPP); | |||
| logger.info("refund wxpay, notify success, req : " + xml + ", resp: " + response.toString()); | |||
| return response; | |||
| } catch (BizMessageException e) { | |||
| logger.error("refund wxpay, notify error, req: " + xml + ", e:" + e.getLocalizedMessage()); | |||
| SortedMap resultMap = new TreeMap(); | |||
| resultMap.put("return_code", "FAIL"); | |||
| resultMap.put("return_msg", e.getMessage()); | |||
| return XmlUtil.getRequestXml(resultMap); | |||
| } catch (MallinkException e) { | |||
| logger.error("refund wxpay, notify error, req: " + xml + ", e:" +e.getLocalizedMessage()); | |||
| SortedMap resultMap = new TreeMap(); | |||
| resultMap.put("return_code", "FAIL"); | |||
| resultMap.put("return_msg", e.getMessage()); | |||
| return XmlUtil.getRequestXml(resultMap); | |||
| } catch (Exception e) { | |||
| logger.error("refund wxpay, order create error, req: " + xml + ", e: " + e.getMessage()); | |||
| SortedMap resultMap = new TreeMap(); | |||
| resultMap.put("return_code", "FAIL"); | |||
| resultMap.put("return_msg", e.getMessage()); | |||
| return XmlUtil.getRequestXml(resultMap); | |||
| } | |||
| } | |||
| /** | |||
| * | |||
| * @return 接收微信分账异步通知 | |||
| * @throws Exception 可能产生的任何异常 | |||
| */ | |||
| @RequestMapping(value = "/sharing") | |||
| public String __shareNotify(HttpServletRequest request) throws Exception { | |||
| Map<String, String> paramMap = null; | |||
| String response = ""; | |||
| String xml = ""; | |||
| try { | |||
| xml = IOUtils.toString(request.getInputStream(), Charset.forName("UTF-8")); | |||
| paramMap = WxPayment.xmlToMap(xml); | |||
| logger.info("share wxpay, notify, param: " + xml ); | |||
| response = wxPayBillService.notify(paramMap, EnumPayWay.PAY_WAY_WEAPP); | |||
| logger.info("share wxpay, notify success, req : " + xml + ", resp: " + response.toString()); | |||
| return response; | |||
| } catch (BizMessageException e) { | |||
| logger.error("share wxpay, notify error, req: " + xml + ", e:" + e.getLocalizedMessage()); | |||
| SortedMap resultMap = new TreeMap(); | |||
| resultMap.put("return_code", "FAIL"); | |||
| resultMap.put("return_msg", e.getMessage()); | |||
| return XmlUtil.getRequestXml(resultMap); | |||
| } catch (MallinkException e) { | |||
| logger.error("refund wxpay, notify error, req: " + xml + ", e:" +e.getLocalizedMessage()); | |||
| SortedMap resultMap = new TreeMap(); | |||
| resultMap.put("return_code", "FAIL"); | |||
| resultMap.put("return_msg", e.getMessage()); | |||
| return XmlUtil.getRequestXml(resultMap); | |||
| } catch (Exception e) { | |||
| logger.error("refund wxpay, order create error, req: " + xml + ", e: " + e.getMessage()); | |||
| SortedMap resultMap = new TreeMap(); | |||
| resultMap.put("return_code", "FAIL"); | |||
| resultMap.put("return_msg", e.getMessage()); | |||
| return XmlUtil.getRequestXml(resultMap); | |||
| } | |||
| } | |||
| } | |||
| @@ -79,7 +79,11 @@ public class WxBillController extends BaseController { | |||
| if(wxMerchant.getStatus().equals(EnumMerchantStatus.NOT_VALID.getCode())){ | |||
| return new ResultData(ErrorCode.MERCHANT_INFO_NOT_VALID); | |||
| } | |||
| if(StringUtils.isEmpty(wxBillAll.getStarttime()) || StringUtils.isEmpty(wxBillAll.getEndtime())){ | |||
| if(!StringUtils.isEmpty(wxBillAll.getStarttime()) && StringUtils.isEmpty(wxBillAll.getEndtime())){ | |||
| logger.info("开始时间和结束时间要同时存在或不存在"); | |||
| return new ResultData(ErrorCode.SYS_PARAMETER_NOT_NULL.getCode(),"starttime和endtime要同时存在或不存在"); | |||
| } | |||
| if(StringUtils.isEmpty(wxBillAll.getStarttime()) && !StringUtils.isEmpty(wxBillAll.getEndtime())){ | |||
| logger.info("开始时间和结束时间要同时存在或不存在"); | |||
| return new ResultData(ErrorCode.SYS_PARAMETER_NOT_NULL.getCode(),"starttime和endtime要同时存在或不存在"); | |||
| } | |||
| @@ -0,0 +1,152 @@ | |||
| package com.iformall.controller; | |||
| import com.iformall.common.ErrorCode; | |||
| import com.iformall.common.Result; | |||
| import com.iformall.common.ResultData; | |||
| import com.iformall.config.PayProperty; | |||
| import com.iformall.domain.po.WxAppinfo; | |||
| import com.iformall.domain.po.WxPayBill; | |||
| import com.iformall.enums.EnumPayStatus; | |||
| import com.iformall.enums.EnumPayWay; | |||
| import com.iformall.exception.MallinkException; | |||
| import com.iformall.service.WxPayBillService; | |||
| import com.iformall.utils.IPUtil; | |||
| import io.swagger.annotations.Api; | |||
| import io.swagger.annotations.ApiOperation; | |||
| import org.apache.commons.lang3.StringUtils; | |||
| import org.slf4j.Logger; | |||
| import org.slf4j.LoggerFactory; | |||
| import org.springframework.beans.factory.annotation.Autowired; | |||
| import org.springframework.web.bind.annotation.*; | |||
| import javax.servlet.http.HttpServletRequest; | |||
| import java.util.Map; | |||
| /** | |||
| * @author gongbiao | |||
| */ | |||
| @RestController | |||
| @RequestMapping("/api/pay") | |||
| @Api(description = "账单支付接口") | |||
| public class WxPayBillController extends BaseController { | |||
| private final Logger logger = LoggerFactory.getLogger(this.getClass()); | |||
| @Autowired | |||
| private PayProperty payProperty; | |||
| @Autowired | |||
| private WxPayBillService wxPayBillService; | |||
| @ApiOperation(value = "发起微信小程序支付订单", notes = "{\"billId\":\"string\",\"appId\":\"string\",\"openId\":\"string\",\"bUserId\":\"string\"}") | |||
| @RequestMapping(value = "/create", method = RequestMethod.POST) | |||
| public ResultData _create(@RequestBody Map<String, String> paramMap, HttpServletRequest request) throws Exception { | |||
| logger.info("/api/pay/create" + paramMap.toString()); | |||
| //bill参数不能为空 | |||
| String billIdStr = paramMap.get("billId"); | |||
| if (StringUtils.isBlank(billIdStr)) { | |||
| logger.info("billId不能为空: " + paramMap.toString()); | |||
| return new ResultData(ErrorCode.SYS_PARAMETER_NOT_NULL.getCode(), "billId不能为空"); | |||
| } | |||
| //bill参数要为Long | |||
| Long billId; | |||
| try { | |||
| billId = Long.valueOf(billIdStr); | |||
| } catch (NumberFormatException e) { | |||
| return new ResultData(ErrorCode.SYS_PARAMETER_NOT_NULL.getCode(), "billId参数不正确"); | |||
| } | |||
| //b_user_id | |||
| String bUserIdStr = paramMap.get("bUserId"); | |||
| if (StringUtils.isBlank(bUserIdStr)) { | |||
| logger.info("bUserId不能为空: " + paramMap.toString()); | |||
| return new ResultData(ErrorCode.SYS_PARAMETER_NOT_NULL.getCode(), "bUserId不能为空"); | |||
| } | |||
| //b_user_id参数要为Long | |||
| Long bUserId; | |||
| try { | |||
| bUserId = Long.valueOf(bUserIdStr); | |||
| } catch (NumberFormatException e) { | |||
| return new ResultData(ErrorCode.SYS_PARAMETER_NOT_NULL.getCode(), "bUserId参数不正确"); | |||
| } | |||
| //appid | |||
| String appid = paramMap.get("appId"); | |||
| //openid | |||
| String openid = paramMap.get("openId"); | |||
| //获取小程序配置信息 | |||
| WxAppinfo appInfo = getAppInfo(appid); | |||
| //支付账单参数 | |||
| WxPayBill record = new WxPayBill(); | |||
| record.setBillId(billId); | |||
| record.setOpenId(openid); | |||
| record.setbUserId(bUserId); | |||
| try { | |||
| record.setIp(IPUtil.getIpAddr(request)); | |||
| return wxPayBillService.createPayBill(payProperty.isReal(), appInfo, record, EnumPayWay.PAY_WAY_WECHAT); | |||
| } catch (MallinkException e) { | |||
| logger.error("payment wechat, order create error, req 2: " + record.toString() + ", e:" + e.getMessage()); | |||
| return new ResultData(e.getErrorCode(), e.getMessage()); | |||
| } catch (Exception e) { | |||
| logger.error("payment wechat, order create error, req 3: " + record.toString() + ", e:" + e.getMessage()); | |||
| return new ResultData(ErrorCode.PAY_ORDER_ERROR, e.getMessage()); | |||
| } | |||
| } | |||
| @ApiOperation(value = "更新支付订单状态", notes = "{\"payBillId\":\"string\",\"billId\":\"string\",\"status\":integer,\"reason\":\"string\"}") | |||
| @PostMapping("/updatePayBill") | |||
| public ResultData updatePayBill(@RequestBody Map<String, Object> paramMap) { | |||
| logger.info("/api/pay/updatePayBill" + paramMap.toString()); | |||
| String payBillIdStr = (String) paramMap.get("payBillId"); | |||
| String billIdStr = (String) paramMap.get("billId"); | |||
| String reasonStr = (String) paramMap.get("reason"); | |||
| Integer status = (Integer) paramMap.get("status"); | |||
| if (StringUtils.isBlank(billIdStr)) { | |||
| logger.info("billId不能为空: " + paramMap.toString()); | |||
| return new ResultData(ErrorCode.SYS_PARAMETER_NOT_NULL.getCode(), "billId不能为空"); | |||
| } | |||
| Long payBillId = 0L, billId = 0L; | |||
| try { | |||
| billId = Long.valueOf(billIdStr); | |||
| } catch (NumberFormatException e) { | |||
| logger.error("billId参数不正确: " + paramMap.toString() + ", e:" + e.getMessage()); | |||
| return new ResultData(ErrorCode.SYS_PARAMETER_NOT_NULL.getCode(), "billId参数不正确"); | |||
| } | |||
| if (!StringUtils.isBlank(payBillIdStr)) { | |||
| try { | |||
| payBillId = Long.valueOf(payBillIdStr); | |||
| } catch (NumberFormatException e) { | |||
| logger.error("payBillId参数不正确: " + paramMap.toString() + ", e:" + e.getMessage()); | |||
| return new ResultData(ErrorCode.SYS_PARAMETER_NOT_NULL.getCode(), "payBillId参数不正确"); | |||
| } | |||
| } | |||
| WxPayBill payBill = new WxPayBill(); | |||
| payBill.setId(payBillId); | |||
| payBill.setBillId(billId); | |||
| payBill.setPayBillStatus(status); | |||
| payBill.setFailReason(reasonStr); | |||
| try { | |||
| if(status.equals(EnumPayStatus.PAY_WAY_SUCCESS.getCode()) && !payBillIdStr.equals(EnumPayStatus.PAY_WAY_WAIT.getCode())) { | |||
| // 有价券不走update, callback更新 | |||
| payBill = wxPayBillService.getById(payBillId); | |||
| if(payBill.getPayBillStatus().equals(EnumPayStatus.PAY_WAY_SUCCESS.getCode())) { | |||
| return new ResultData(Result.SUCCESS, "支付状态更新成功"); | |||
| } else { | |||
| return new ResultData(ErrorCode.PAY_ORDER_ERROR, "支付未状态,请等待!!"); | |||
| } | |||
| } else { | |||
| wxPayBillService.handlePayBillStatusUpdate(payBill); | |||
| } | |||
| return new ResultData(Result.SUCCESS, "支付状态更新成功"); | |||
| } catch (MallinkException e) { | |||
| logger.error("支付状态更新失败2: " + payBill.toString() + ", e:" + e.getMessage()); | |||
| return new ResultData(e.getErrorCode(), e.getMessage()); | |||
| } catch (Exception e) { | |||
| logger.error("支付状态更新失败3: " + payBill.toString() + ", e:" + e.getMessage()); | |||
| return new ResultData(ErrorCode.PAY_ORDER_ERROR, "支付状态更新失败3: " + payBill.toString() + ", e:" + e.getMessage()); | |||
| } | |||
| } | |||
| } | |||
| @@ -274,7 +274,7 @@ public enum ErrorCode{ | |||
| * 日常费用账单 | |||
| * */ | |||
| BILL_ROUTINE_IS_NOT_FOUND(21000,"账单不存在"), | |||
| BILL_UPDATE_FAILED(21001,"账单更新失败"), | |||
| /** | |||
| * 商铺 | |||
| * */ | |||
| @@ -79,6 +79,16 @@ public class WxAppinfo implements Serializable { | |||
| private Long payId; | |||
| @io.swagger.annotations.ApiModelProperty(value="1B端2C端",name="type") | |||
| private Integer type; | |||
| @io.swagger.annotations.ApiModelProperty(value="支付ID,参看wx_pay_account_bill",name="payBillId") | |||
| private Long payBillId; | |||
| public Long getPayBillId() { | |||
| return payBillId; | |||
| } | |||
| public void setPayBillId(Long payBillId) { | |||
| this.payBillId = payBillId; | |||
| } | |||
| public String getTenantId() { | |||
| return tenantId; | |||
| @@ -0,0 +1,211 @@ | |||
| package com.iformall.domain.po; | |||
| import javax.persistence.Id; | |||
| import javax.persistence.Table; | |||
| import javax.persistence.Transient; | |||
| import java.io.Serializable; | |||
| import java.util.List; | |||
| /** | |||
| * @author gongbiao | |||
| */ | |||
| @Table(name = "wx_pay_account_bill") | |||
| public class WxPayAccountBill implements Serializable { | |||
| private static final long serialVersionUID = 1L; | |||
| @Id | |||
| protected Long id; | |||
| @Transient | |||
| protected List<Long> ids; | |||
| @Transient | |||
| protected String sortColumns; | |||
| public Long getId() { | |||
| return id; | |||
| } | |||
| public void setId(Long id) { | |||
| this.id = id; | |||
| } | |||
| public String getSortColumns() { | |||
| return sortColumns; | |||
| } | |||
| public List<Long> getIds() { | |||
| return ids; | |||
| } | |||
| public void setIds(List<Long> ids) { | |||
| this.ids = ids; | |||
| } | |||
| /*租户ID**/ | |||
| @io.swagger.annotations.ApiModelProperty(value="租户ID",name="tenantId") | |||
| private String tenantId; | |||
| /**微信商户号/特约服务商号**/ | |||
| @io.swagger.annotations.ApiModelProperty(value="微信商户号/特约服务商号",name="mchId") | |||
| private String mchId; | |||
| /**微信服务商号*/ | |||
| @io.swagger.annotations.ApiModelProperty(value="微信服务商号",name="subMchId") | |||
| private String subMchId; | |||
| /**支付密钥**/ | |||
| @io.swagger.annotations.ApiModelProperty(value="支付密钥",name="apiKey") | |||
| private String apiKey; | |||
| /**微信回调,支持3种回调,(1.url/pay 2.url/refund3.url/separate)**/ | |||
| @io.swagger.annotations.ApiModelProperty(value="微信回调,支持3种回调,(1.url/pay 2.url/refund3.url/separate)",name="notifyUrl") | |||
| private String notifyUrl; | |||
| /**证书本地存放位置**/ | |||
| @io.swagger.annotations.ApiModelProperty(value="证书本地存放位置",name="certPath") | |||
| private String certPath; | |||
| /**商户模式**/ | |||
| @io.swagger.annotations.ApiModelProperty(value="商户模式-0:普通商户模式1:服务商模式",name="type") | |||
| private Integer type; | |||
| /**是否开启分账**/ | |||
| @io.swagger.annotations.ApiModelProperty(value="0:未开启分账1:开启分账",name="type") | |||
| private boolean share; | |||
| /**手续费**/ | |||
| @io.swagger.annotations.ApiModelProperty(value="手续费",name="rate") | |||
| private Integer rate; | |||
| public String getTenantId() { | |||
| return tenantId; | |||
| } | |||
| public void setTenantId(String tenantId) { | |||
| this.tenantId = tenantId; | |||
| } | |||
| public String getMchId() { | |||
| return mchId; | |||
| } | |||
| public void setMchId(String _mchId) { | |||
| mchId = _mchId; | |||
| } | |||
| public String getSubMchId() { | |||
| return subMchId; | |||
| } | |||
| public void setSubMchId(String subMchId) { | |||
| this.subMchId = subMchId; | |||
| } | |||
| public String getApiKey() { | |||
| return apiKey; | |||
| } | |||
| public void setApiKey(String _apiKey) { | |||
| apiKey = _apiKey; | |||
| } | |||
| public String getNotifyUrl() { | |||
| return notifyUrl; | |||
| } | |||
| public void setNotifyUrl(String _notifyUrl) { | |||
| notifyUrl = _notifyUrl; | |||
| } | |||
| public String getCertPath() { | |||
| return certPath; | |||
| } | |||
| public void setCertPath(String _certPath) { | |||
| certPath = _certPath; | |||
| } | |||
| public Integer getType() { | |||
| return type; | |||
| } | |||
| public void setType(Integer type) { | |||
| this.type = type; | |||
| } | |||
| public boolean isShare() { | |||
| return share; | |||
| } | |||
| public void setShare(boolean share) { | |||
| this.share = share; | |||
| } | |||
| public Integer getRate() { | |||
| return rate; | |||
| } | |||
| public void setRate(Integer rate) { | |||
| this.rate = rate; | |||
| } | |||
| public String getPayNotifyUrl() { | |||
| return notifyUrl + "/pay"; | |||
| } | |||
| public String getRefundNotifyUrl() { | |||
| return notifyUrl + "/refund"; | |||
| } | |||
| public String getSeparateNotifyUrl() { | |||
| return notifyUrl + "/separate"; | |||
| } | |||
| public static enum Field | |||
| { | |||
| Id_ASC("`id` ASC"),Id_DESC("`id` DESC") | |||
| ,TenantId_ASC("`tenant_id` ASC"),TenantId_DESC("`tenant_id` DESC") | |||
| ,MchId_ASC("`mch_id` ASC"),MchId_DESC("`mch_id` DESC") | |||
| ,SubMchId_ASC("`sub_mch_id` ASC"),SubMchId_DESC("`sub_mch_id` DESC") | |||
| ,ApiKey_ASC("`api_key` ASC"),ApiKey_DESC("`api_key` DESC") | |||
| ,NotifyUrl_ASC("`notify_url` ASC"),NotifyUrl_DESC("`notify_url` DESC") | |||
| ,CertPath_ASC("`cert_path` ASC"),CertPath_DESC("`cert_path` DESC") | |||
| ,Type_ASC("`type` ASC"),Type_DESC("`type` DESC") | |||
| ,Share_ASC("`share` ASC"),Share_DESC("`share` DESC") | |||
| ,Rate_ASC("`rate` ASC"),Rate_DESC("`rate` DESC") | |||
| ; | |||
| private String value; | |||
| Field(String value){ | |||
| this.value = value; | |||
| } | |||
| public String getValue() { | |||
| return value; | |||
| } | |||
| public void setCol(String value) { | |||
| this.value = value; | |||
| } | |||
| @Override | |||
| public String toString() { | |||
| return this.getValue(); | |||
| } | |||
| } | |||
| public void setSortColumns(WxPayAccountBill.Field... fields) | |||
| { | |||
| if (fields == null || fields.length == 0) { | |||
| return; | |||
| } | |||
| for (int k = 0; k < fields.length; k++) { | |||
| if (fields[k] == null) { | |||
| return; | |||
| } | |||
| } | |||
| StringBuilder sb = new StringBuilder(fields[0].toString()); | |||
| for (int k = 1; k < fields.length; k++) { | |||
| sb.append(","); | |||
| sb.append(fields[k].toString()); | |||
| } | |||
| this.sortColumns = sb.toString(); | |||
| } | |||
| public void setSortColumns(String sortColumns) | |||
| { | |||
| if (sortColumns == null || "".equals(sortColumns.trim())) { | |||
| return; | |||
| } | |||
| if (sortColumns.contains(",")) { | |||
| String[] cols = sortColumns.split(","); | |||
| List<Field> fList = new java.util.ArrayList(); | |||
| for (int k = 0; k < cols.length; k++) { | |||
| fList.add(Field.valueOf(cols[k])); | |||
| } | |||
| this.setSortColumns(fList.toArray(new Field[fList.size()])); | |||
| } else { | |||
| this.setSortColumns(Field.valueOf(sortColumns)); | |||
| } | |||
| } | |||
| } | |||
| @@ -0,0 +1,300 @@ | |||
| package com.iformall.domain.po; | |||
| import javax.persistence.Id; | |||
| import javax.persistence.Table; | |||
| import javax.persistence.Transient; | |||
| import java.io.Serializable; | |||
| import java.util.ArrayList; | |||
| import java.util.Date; | |||
| import java.util.List; | |||
| /** | |||
| * @author gongbiao | |||
| */ | |||
| @Table(name = "wx_pay_bill") | |||
| public class WxPayBill implements Serializable { | |||
| private static final long serialVersionUID = 1L; | |||
| @Id | |||
| protected Long id; | |||
| @Transient | |||
| protected List<Long> ids; | |||
| @Transient | |||
| protected String sortColumns; | |||
| public Long getId() { | |||
| return id; | |||
| } | |||
| public void setId(Long id) { | |||
| this.id = id; | |||
| } | |||
| public String getSortColumns() { | |||
| return sortColumns; | |||
| } | |||
| public List<Long> getIds() { | |||
| return ids; | |||
| } | |||
| public void setIds(List<Long> ids) { | |||
| this.ids = ids; | |||
| } | |||
| /**租户ID**/ | |||
| @io.swagger.annotations.ApiModelProperty(value="租户ID",name="tenantId") | |||
| private String tenantId; | |||
| /**创建时间**/ | |||
| @io.swagger.annotations.ApiModelProperty(value="创建时间",name="createTime") | |||
| private Date createTime; | |||
| /**更新时间**/ | |||
| @io.swagger.annotations.ApiModelProperty(value="更新时间",name="updateTime") | |||
| private Date updateTime; | |||
| /**账单ID**/ | |||
| @io.swagger.annotations.ApiModelProperty(value="账单ID",name="billId") | |||
| private Long billId; | |||
| /**用户ID**/ | |||
| @io.swagger.annotations.ApiModelProperty(value="用户ID",name="bUserId") | |||
| private Long bUserId; | |||
| /**ip地址**/ | |||
| @io.swagger.annotations.ApiModelProperty(value="ip地址",name="ip") | |||
| private String ip; | |||
| /**支付金额(分)**/ | |||
| @io.swagger.annotations.ApiModelProperty(value="支付金额(分)",name="payAmount") | |||
| private Integer payAmount; | |||
| /**支付发起时间**/ | |||
| @io.swagger.annotations.ApiModelProperty(value="支付发起时间",name="payTimeStart") | |||
| private Date payTimeStart; | |||
| /**支付结束时间**/ | |||
| @io.swagger.annotations.ApiModelProperty(value="支付结束时间",name="payTimeEnd") | |||
| private Date payTimeEnd; | |||
| /**微信预支付交易会话标识**/ | |||
| @io.swagger.annotations.ApiModelProperty(value="微信预支付交易会话标识",name="prepayId") | |||
| private String prepayId; | |||
| /**微信生成的订单号**/ | |||
| @io.swagger.annotations.ApiModelProperty(value="微信生成的订单号",name="transactionId") | |||
| private String transactionId; | |||
| /**支付渠道: 0-微信 1-支付宝 2-银联 **/ | |||
| @io.swagger.annotations.ApiModelProperty(value="支付渠道: 0-微信 1-支付宝 2-银联 ",name="payVendor") | |||
| private Integer payVendor; | |||
| /**支付订单号**/ | |||
| @io.swagger.annotations.ApiModelProperty(value="支付订单号",name="payBillNo") | |||
| private String payBillNo; | |||
| /**支付状态: 0-支付中;1-支付成功;2-支付失败**/ | |||
| @io.swagger.annotations.ApiModelProperty(value="支付状态: 0-支付中;1-支付成功;2-支付失败",name="payBillStatus") | |||
| private Integer payBillStatus; | |||
| /**分账状态: 0-未分账;1-分账**/ | |||
| @io.swagger.annotations.ApiModelProperty(value="分账状态: 0-未分账;1-分账",name="payBillStatus") | |||
| private Integer share; | |||
| /**分账金额(总金额扣除手续费后的金额)**/ | |||
| @io.swagger.annotations.ApiModelProperty(value="分账金额",name="shareAmount") | |||
| private Integer shareAmount; | |||
| /**支付失败原因**/ | |||
| @io.swagger.annotations.ApiModelProperty(value="支付失败原因",name="failReason") | |||
| private String failReason; | |||
| @io.swagger.annotations.ApiModelProperty(value="openId",name="openId") | |||
| private String openId; | |||
| public String getOpenId() { | |||
| return openId; | |||
| } | |||
| public void setOpenId(String openId) { | |||
| this.openId = openId; | |||
| } | |||
| public String getTenantId() { | |||
| return tenantId; | |||
| } | |||
| public void setTenantId(String _tenantId) { | |||
| tenantId = _tenantId; | |||
| } | |||
| public Date getCreateTime() { | |||
| return createTime; | |||
| } | |||
| public void setCreateTime(Date _createTime) { | |||
| createTime = _createTime; | |||
| } | |||
| public Date getUpdateTime() { | |||
| return updateTime; | |||
| } | |||
| public void setUpdateTime(Date _updateTime) { | |||
| updateTime = _updateTime; | |||
| } | |||
| public Long getBillId() { | |||
| return billId; | |||
| } | |||
| public void setBillId(Long billId) { | |||
| this.billId = billId; | |||
| } | |||
| public Long getbUserId() { | |||
| return bUserId; | |||
| } | |||
| public void setbUserId(Long bUserId) { | |||
| this.bUserId = bUserId; | |||
| } | |||
| public String getIp() { | |||
| return ip; | |||
| } | |||
| public void setIp(String _ip) { | |||
| ip = _ip; | |||
| } | |||
| public Integer getPayAmount() { | |||
| return payAmount; | |||
| } | |||
| public void setPayAmount(Integer _payAmount) { | |||
| payAmount = _payAmount; | |||
| } | |||
| public Date getPayTimeStart() { | |||
| return payTimeStart; | |||
| } | |||
| public void setPayTimeStart(Date _payTimeStart) { | |||
| payTimeStart = _payTimeStart; | |||
| } | |||
| public Date getPayTimeEnd() { | |||
| return payTimeEnd; | |||
| } | |||
| public void setPayTimeEnd(Date _payTimeEnd) { | |||
| payTimeEnd = _payTimeEnd; | |||
| } | |||
| public String getPrepayId() { | |||
| return prepayId; | |||
| } | |||
| public void setPrepayId(String prepayId) { | |||
| this.prepayId = prepayId; | |||
| } | |||
| public String getTransactionId() { | |||
| return transactionId; | |||
| } | |||
| public void setTransactionId(String _transactionId) { | |||
| transactionId = _transactionId; | |||
| } | |||
| public Integer getPayVendor() { | |||
| return payVendor; | |||
| } | |||
| public void setPayVendor(Integer _payVendor) { | |||
| payVendor = _payVendor; | |||
| } | |||
| public String getPayBillNo() { | |||
| return payBillNo; | |||
| } | |||
| public void setPayBillNo(String _payBillNo) { | |||
| payBillNo = _payBillNo; | |||
| } | |||
| public Integer getPayBillStatus() { | |||
| return payBillStatus; | |||
| } | |||
| public void setPayBillStatus(Integer _payBillStatus) { | |||
| payBillStatus = _payBillStatus; | |||
| } | |||
| public Integer getShare() { | |||
| return share; | |||
| } | |||
| public void setShare(Integer share) { | |||
| this.share = share; | |||
| } | |||
| public Integer getShareAmount() { | |||
| return shareAmount; | |||
| } | |||
| public void setShareAmount(Integer shareAmount) { | |||
| this.shareAmount = shareAmount; | |||
| } | |||
| public String getFailReason() { | |||
| return failReason; | |||
| } | |||
| public void setFailReason(String _failReason) { | |||
| failReason = _failReason; | |||
| } | |||
| public static enum Field | |||
| { | |||
| Id_ASC("`id` ASC"),Id_DESC("`id` DESC") | |||
| ,TenantId_ASC("`tenant_id` ASC"),TenantId_DESC("`tenant_id` DESC") | |||
| ,CreateTime_ASC("`create_time` ASC"),CreateTime_DESC("`create_time` DESC") | |||
| ,UpdateTime_ASC("`update_time` ASC"),UpdateTime_DESC("`update_time` DESC") | |||
| ,BillId_ASC("`bill_id` ASC"),BillId_DESC("`bill_id` DESC") | |||
| ,BUserId_ASC("`b_user_id` ASC"),BUserId_DESC("`b_user_id` DESC") | |||
| ,Ip_ASC("`ip` ASC"),Ip_DESC("`ip` DESC") | |||
| ,PayAmount_ASC("`pay_amount` ASC"),PayAmount_DESC("`pay_amount` DESC") | |||
| ,PayTimeStart_ASC("`pay_time_start` ASC"),PayTimeStart_DESC("`pay_time_start` DESC") | |||
| ,PayTimeEnd_ASC("`pay_time_end` ASC"),PayTimeEnd_DESC("`pay_time_end` DESC") | |||
| ,PrepayId_ASC("`prepay_id` ASC"),PrepayId_DESC("`transaction_id` DESC") | |||
| ,TransactionId_ASC("`transaction_id` ASC"),TransactionId_DESC("`prepay_id` DESC") | |||
| ,PayVendor_ASC("`pay_vendor` ASC"),PayVendor_DESC("`pay_vendor` DESC") | |||
| ,PayBillNo_ASC("`pay_bill_no` ASC"),PayBillNo_DESC("`pay_bill_no` DESC") | |||
| ,PayBillStatus_ASC("`pay_bill_status` ASC"),PayBillStatus_DESC("`pay_bill_status` DESC") | |||
| ,Share_ASC("`share` ASC"),Share_DESC("`share` DESC") | |||
| ,ShareAmount_ASC("`share_amount` ASC"),ShareAmount_DESC("`share_amount` DESC") | |||
| ,FailReason_ASC("`fail_reason` ASC"),FailReason_DESC("`fail_reason` DESC") | |||
| ; | |||
| private String value; | |||
| Field(String value){ | |||
| this.value = value; | |||
| } | |||
| public String getValue() { | |||
| return value; | |||
| } | |||
| public void setCol(String value) { | |||
| this.value = value; | |||
| } | |||
| @Override | |||
| public String toString() { | |||
| return this.getValue(); | |||
| } | |||
| } | |||
| public void setSortColumns(WxPayBill.Field... fields) | |||
| { | |||
| if (fields == null || fields.length == 0) { | |||
| return; | |||
| } | |||
| for (int k = 0; k < fields.length; k++) { | |||
| if (fields[k] == null) { | |||
| return; | |||
| } | |||
| } | |||
| StringBuilder sb = new StringBuilder(fields[0].toString()); | |||
| for (int k = 1; k < fields.length; k++) { | |||
| sb.append(","); | |||
| sb.append(fields[k].toString()); | |||
| } | |||
| this.sortColumns = sb.toString(); | |||
| } | |||
| public void setSortColumns(String sortColumns) | |||
| { | |||
| if (sortColumns == null || "".equals(sortColumns.trim())) { | |||
| return; | |||
| } | |||
| if (sortColumns.contains(",")) { | |||
| String[] cols = sortColumns.split(","); | |||
| List<Field> fList = new ArrayList(); | |||
| for (int k = 0; k < cols.length; k++) { | |||
| fList.add(Field.valueOf(cols[k])); | |||
| } | |||
| this.setSortColumns(fList.toArray(new Field[fList.size()])); | |||
| } else { | |||
| this.setSortColumns(Field.valueOf(sortColumns)); | |||
| } | |||
| } | |||
| } | |||
| @@ -47,6 +47,16 @@ public class WxBillAll { | |||
| @io.swagger.annotations.ApiModelProperty(value="条数",name="pageSize") | |||
| private Integer pageSize; | |||
| @io.swagger.annotations.ApiModelProperty(value="id",name="id") | |||
| private Long id; | |||
| public Long getId() { | |||
| return id; | |||
| } | |||
| public void setId(Long id) { | |||
| this.id = id; | |||
| } | |||
| public String getAppId() { | |||
| return appId; | |||
| @@ -0,0 +1,20 @@ | |||
| package com.iformall.mapper; | |||
| import com.iformall.common.CommonMapper; | |||
| import com.iformall.domain.po.WxPayAccountBill; | |||
| import java.util.List; | |||
| /** | |||
| * @author gongbiao | |||
| */ | |||
| public interface WxPayAccountBillMapper extends CommonMapper<WxPayAccountBill, Long> { | |||
| List<WxPayAccountBill> findList(WxPayAccountBill wxPayAccount); | |||
| } | |||
| @@ -0,0 +1,14 @@ | |||
| package com.iformall.mapper; | |||
| import com.iformall.common.CommonMapper; | |||
| import com.iformall.domain.po.WxPayBill; | |||
| import java.util.List; | |||
| /** | |||
| * @author gongbiao | |||
| */ | |||
| public interface WxPayBillMapper extends CommonMapper<WxPayBill, Long> { | |||
| List<WxPayBill> findList(WxPayBill wxPayBill); | |||
| } | |||
| @@ -17,4 +17,6 @@ public interface WxBillAllService { | |||
| ResultData listBill(WxBillAll wxBillAll); | |||
| int updateBill(Map<String,Object> bill); | |||
| } | |||
| @@ -0,0 +1,74 @@ | |||
| package com.iformall.service; | |||
| import com.iformall.common.ResultData; | |||
| import com.iformall.domain.po.WxAppinfo; | |||
| import com.iformall.domain.po.WxPayBill; | |||
| import com.iformall.enums.EnumPayWay; | |||
| import java.util.Map; | |||
| /** | |||
| * @author gongbiao | |||
| */ | |||
| public interface WxPayBillService { | |||
| /** | |||
| * 创建支付订单 | |||
| * | |||
| * @param record 支付订单请求 | |||
| * @param payWay | |||
| * @return | |||
| */ | |||
| ResultData createPayBill(boolean isReal, WxAppinfo appInfo, WxPayBill record, EnumPayWay payWay); | |||
| /** | |||
| * 微信支付订单查询 | |||
| * @param appInfo 支付订单Appinfo | |||
| * @param record 支付订单 | |||
| */ | |||
| ResultData payBillQuery(WxAppinfo appInfo, WxPayBill record); | |||
| /** | |||
| * 微信支付关闭订单 | |||
| * @param appInfo 支付订单Appinfo | |||
| * @param record 支付订单 | |||
| */ | |||
| ResultData payBillClose(WxAppinfo appInfo, WxPayBill record); | |||
| /** | |||
| * 异步通知 | |||
| * | |||
| * @param paramMap 异步通知参数 | |||
| * @param payWay 支付方式 | |||
| * @return | |||
| */ | |||
| String notify(Map<String, String> paramMap, EnumPayWay payWay); | |||
| /** | |||
| * 支付成功处理 | |||
| * | |||
| * @param record | |||
| * @param transactionId | |||
| */ | |||
| void handleBillPaySuccess(WxPayBill record, String transactionId); | |||
| /** | |||
| * 支付状态处理 | |||
| * | |||
| * @param record | |||
| */ | |||
| void handlePayBillStatusUpdate(WxPayBill record); | |||
| /** | |||
| * 页面回调 | |||
| * | |||
| * @param paramMap 页面通知参数 | |||
| * @param payWay 支付方式 | |||
| * @return | |||
| */ | |||
| void callback(Map<String, String> paramMap, EnumPayWay payWay); | |||
| WxPayBill getById(Long payBillId); | |||
| } | |||
| @@ -6,22 +6,20 @@ import com.iformall.common.ErrorCode; | |||
| import com.iformall.common.ResultData; | |||
| import com.iformall.domain.po.*; | |||
| import com.iformall.domain.vo.WxBillAll; | |||
| import com.iformall.enums.EnumBillDailyStatus; | |||
| import com.iformall.enums.EnumBillRentStatus; | |||
| import com.iformall.enums.EnumBillType; | |||
| import com.iformall.enums.EnumBillTypeParam; | |||
| import com.iformall.mapper.WxBillAllMapper; | |||
| import com.iformall.exception.MallinkException; | |||
| import com.iformall.mapper.*; | |||
| import com.iformall.service.*; | |||
| import com.iformall.utils.DateUtils; | |||
| import org.apache.commons.lang3.StringUtils; | |||
| import org.slf4j.Logger; | |||
| import org.slf4j.LoggerFactory; | |||
| import org.springframework.beans.factory.annotation.Autowired; | |||
| import org.springframework.stereotype.Service; | |||
| import java.util.ArrayList; | |||
| import java.util.HashMap; | |||
| import java.util.List; | |||
| import java.util.Map; | |||
| import java.util.*; | |||
| /** | |||
| * @author gongbiao | |||
| @@ -51,6 +49,25 @@ public class WxBillAllServiceImpl implements WxBillAllService { | |||
| @Autowired | |||
| WxBillOtherService wxBillOtherService; | |||
| @Autowired | |||
| WxBillDailyMapper wxBillDailyMapper; | |||
| @Autowired | |||
| WxBillDepositMapper wxBillDepositMapper; | |||
| @Autowired | |||
| WxBillPropertyDepositMapper wxBillPropertyDepositMapper; | |||
| @Autowired | |||
| WxBillPropertyMapper wxBillPropertyMapper; | |||
| @Autowired | |||
| WxBillRentMapper wxBillRentMapper; | |||
| @Autowired | |||
| WxBillOtherMapper wxBillOtherMapper; | |||
| @Override | |||
| public Map<String, Object> listAsPage(WxBillAll record, Integer pageIndex, Integer pageSize) { | |||
| //更新各账单状态 | |||
| @@ -89,7 +106,7 @@ public class WxBillAllServiceImpl implements WxBillAllService { | |||
| //更新各账单状态 | |||
| updateBillStatus(wxBillAll); | |||
| //账单类型 | |||
| if(wxBillAll.getBillTypeValue()!=null){ | |||
| if (wxBillAll.getBillTypeValue() != null) { | |||
| if (wxBillAll.getBillTypeValue().equals(EnumBillType.RENT.getCode())) { | |||
| wxBillAll.setBillTypeValue(EnumBillTypeParam.RENT.getCode()); | |||
| } else if (wxBillAll.getBillTypeValue().equals(EnumBillType.DEPOSIT.getCode())) { | |||
| @@ -111,7 +128,7 @@ public class WxBillAllServiceImpl implements WxBillAllService { | |||
| return new ResultData(ErrorCode.BILL_ROUTINE_IS_NOT_FOUND); | |||
| } | |||
| } | |||
| if(wxBillAll.getPageIndex()!=null && wxBillAll.getPageIndex()!=null){ | |||
| if (wxBillAll.getPageIndex() != null && wxBillAll.getPageIndex() != null) { | |||
| PageHelper.startPage(wxBillAll.getPageIndex(), wxBillAll.getPageSize()); | |||
| List<Map<String, Object>> maps = wxBillAllMapper.listData(wxBillAll); | |||
| PageInfo<Map<String, Object>> pageInfo = new PageInfo<>(maps); | |||
| @@ -121,6 +138,160 @@ public class WxBillAllServiceImpl implements WxBillAllService { | |||
| return new ResultData(maps); | |||
| } | |||
| @Override | |||
| public int updateBill(Map<String, Object> bill) { | |||
| if (bill == null) { | |||
| return 0; | |||
| } | |||
| Integer billTypeValue = (Integer) bill.get("billTypeValue"); | |||
| if (billTypeValue.equals(EnumBillTypeParam.RENT.getCode())) { | |||
| //更新租金账单 | |||
| return updateBillRent(bill); | |||
| } else if (billTypeValue.equals(EnumBillTypeParam.RENT_DEPOSIT.getCode())) { | |||
| //更新租金押金账单 | |||
| return updateBillRentDeposit(bill); | |||
| } else if (billTypeValue.equals(EnumBillTypeParam.PROPERTY.getCode())) { | |||
| //更新物业账单 | |||
| return updateBillProperty(bill); | |||
| } else if (billTypeValue.equals(EnumBillTypeParam.PROPERTY_DEPOSIT.getCode())) { | |||
| //更新物业押金账单 | |||
| return updateBillPropertyDeposit(bill); | |||
| } else if (billTypeValue.equals(EnumBillTypeParam.WATER.getCode())) { | |||
| //更新水费账单 | |||
| return updateBillDaily(bill); | |||
| } else if (billTypeValue.equals(EnumBillTypeParam.POWER.getCode())) { | |||
| //更新电费账单 | |||
| return updateBillDaily(bill); | |||
| } else if (billTypeValue.equals(EnumBillTypeParam.ROUTINE.getCode())) { | |||
| //更新其他账单 | |||
| return updateBillOther(bill); | |||
| } else { | |||
| logger.info("账单类型不存在"); | |||
| return 0; | |||
| } | |||
| } | |||
| private int updateBillOther(Map<String, Object> bill) { | |||
| Object id = bill.get("id"); | |||
| WxBillOther wxBillOther = wxBillOtherMapper.selectByPrimaryKey(id); | |||
| if(wxBillOther==null){ | |||
| return 0; | |||
| } | |||
| Date date = new Date(); | |||
| wxBillOther.setPayDate(date); | |||
| wxBillOther.setPay((Integer) bill.get("owe")); | |||
| wxBillOther.setOwe(0); | |||
| wxBillOther.setStatus(EnumBillDailyStatus.PAID.getCode()); | |||
| wxBillOther.setUpdatetime(date); | |||
| try { | |||
| return wxBillOtherMapper.updateByPrimaryKeySelective(wxBillOther); | |||
| } catch (Exception e) { | |||
| logger.error("更新其他账单失败,e:" + e.getMessage()); | |||
| throw new MallinkException(ErrorCode.DB_FAIL.getCode(), "DB FAILD " + e.getMessage()); | |||
| } | |||
| } | |||
| private int updateBillDaily(Map<String, Object> bill) { | |||
| Object id = bill.get("id"); | |||
| WxBillDaily wxBillDaily = wxBillDailyMapper.selectByPrimaryKey(id); | |||
| if(wxBillDaily==null){ | |||
| return 0; | |||
| } | |||
| Date date = new Date(); | |||
| wxBillDaily.setPayDate(date); | |||
| wxBillDaily.setPay((Integer) bill.get("owe")); | |||
| wxBillDaily.setOwe(0); | |||
| wxBillDaily.setStatus(EnumBillDailyStatus.PAID.getCode()); | |||
| wxBillDaily.setUpdatetime(date); | |||
| try { | |||
| return wxBillDailyMapper.updateByPrimaryKeySelective(wxBillDaily); | |||
| } catch (Exception e) { | |||
| logger.error("更新日常账单失败,e:" + e.getMessage()); | |||
| throw new MallinkException(ErrorCode.DB_FAIL.getCode(), "DB FAILD " + e.getMessage()); | |||
| } | |||
| } | |||
| private int updateBillPropertyDeposit(Map<String, Object> bill) { | |||
| Object id = bill.get("id"); | |||
| WxBillPropertyDeposit wxBillPropertyDeposit = wxBillPropertyDepositMapper.selectByPrimaryKey(id); | |||
| if(wxBillPropertyDeposit==null){ | |||
| return 0; | |||
| } | |||
| Date date = new Date(); | |||
| wxBillPropertyDeposit.setPayDate(date); | |||
| wxBillPropertyDeposit.setPay((Integer) bill.get("owe")); | |||
| wxBillPropertyDeposit.setOwe(0); | |||
| wxBillPropertyDeposit.setStatus(EnumBillDailyStatus.PAID.getCode()); | |||
| wxBillPropertyDeposit.setUpdatetime(date); | |||
| try { | |||
| return wxBillPropertyDepositMapper.updateByPrimaryKeySelective(wxBillPropertyDeposit); | |||
| } catch (Exception e) { | |||
| logger.error("更新物业押金账单失败,e:" + e.getMessage()); | |||
| throw new MallinkException(ErrorCode.DB_FAIL.getCode(), "DB FAILD " + e.getMessage()); | |||
| } | |||
| } | |||
| private int updateBillProperty(Map<String, Object> bill) { | |||
| Object id = bill.get("id"); | |||
| WxBillProperty property = wxBillPropertyMapper.selectByPrimaryKey(id); | |||
| if(property==null){ | |||
| return 0; | |||
| } | |||
| Date date = new Date(); | |||
| property.setPayDate(date); | |||
| property.setPay((Integer) bill.get("owe")); | |||
| property.setOwe(0); | |||
| property.setStatus(EnumBillDailyStatus.PAID.getCode()); | |||
| property.setUpdatetime(date); | |||
| try { | |||
| return wxBillPropertyMapper.updateByPrimaryKeySelective(property); | |||
| } catch (Exception e) { | |||
| logger.error("更新物业账单失败,e:" + e.getMessage()); | |||
| throw new MallinkException(ErrorCode.DB_FAIL.getCode(), "DB FAILD " + e.getMessage()); | |||
| } | |||
| } | |||
| private int updateBillRentDeposit(Map<String, Object> bill) { | |||
| Object id = bill.get("id"); | |||
| WxBillDeposit wxBillDeposit = wxBillDepositMapper.selectByPrimaryKey(id); | |||
| if(wxBillDeposit==null){ | |||
| return 0; | |||
| } | |||
| Date date = new Date(); | |||
| wxBillDeposit.setPayDate(date); | |||
| wxBillDeposit.setPay((Integer) bill.get("owe")); | |||
| wxBillDeposit.setOwe(0); | |||
| wxBillDeposit.setStatus(EnumBillDailyStatus.PAID.getCode()); | |||
| wxBillDeposit.setUpdatetime(date); | |||
| try { | |||
| return wxBillDepositMapper.updateByPrimaryKeySelective(wxBillDeposit); | |||
| } catch (Exception e) { | |||
| logger.error("更新租赁押金账单失败,e:" + e.getMessage()); | |||
| throw new MallinkException(ErrorCode.DB_FAIL.getCode(), "DB FAILD " + e.getMessage()); | |||
| } | |||
| } | |||
| private int updateBillRent(Map<String, Object> bill) { | |||
| Object id = bill.get("id"); | |||
| WxBillRent wxBillRent = wxBillRentMapper.selectByPrimaryKey(id); | |||
| if(wxBillRent==null){ | |||
| return 0; | |||
| } | |||
| Date date = new Date(); | |||
| wxBillRent.setPayDate(date); | |||
| wxBillRent.setPay((Integer) bill.get("owe")); | |||
| wxBillRent.setOwe(0); | |||
| wxBillRent.setStatus(EnumBillDailyStatus.PAID.getCode()); | |||
| wxBillRent.setUpdatetime(date); | |||
| try { | |||
| return wxBillRentMapper.updateByPrimaryKeySelective(wxBillRent); | |||
| } catch (Exception e) { | |||
| logger.error("更新租金账单失败,e:" + e.getMessage()); | |||
| throw new MallinkException(ErrorCode.DB_FAIL.getCode(), "DB FAILD " + e.getMessage()); | |||
| } | |||
| } | |||
| private void updateBillStatus(WxBillAll record) { | |||
| logger.info("更新各账单状态开始"); | |||
| //更新其他账单 | |||
| @@ -0,0 +1,838 @@ | |||
| package com.iformall.service.impl; | |||
| import com.alibaba.fastjson.JSON; | |||
| import com.alibaba.fastjson.JSONObject; | |||
| import com.iformall.common.ErrorCode; | |||
| import com.iformall.common.IdWorker; | |||
| import com.iformall.common.Result; | |||
| import com.iformall.common.ResultData; | |||
| import com.iformall.domain.po.*; | |||
| import com.iformall.domain.vo.WxBillAll; | |||
| import com.iformall.enums.*; | |||
| import com.iformall.exception.MallinkException; | |||
| import com.iformall.mapper.*; | |||
| import com.iformall.pay.*; | |||
| import com.iformall.service.WxBillAllService; | |||
| import com.iformall.service.WxPayBillService; | |||
| import com.iformall.utils.BeanUtils; | |||
| import com.iformall.utils.MapUtil; | |||
| import com.iformall.utils.Utility; | |||
| import com.iformall.utils.XmlUtil; | |||
| import org.apache.commons.lang3.StringUtils; | |||
| import org.slf4j.Logger; | |||
| import org.slf4j.LoggerFactory; | |||
| import org.springframework.beans.factory.annotation.Autowired; | |||
| import org.springframework.stereotype.Service; | |||
| import org.springframework.transaction.annotation.Propagation; | |||
| import org.springframework.transaction.annotation.Transactional; | |||
| import java.text.ParseException; | |||
| import java.util.*; | |||
| /** | |||
| * @author gongbiao | |||
| */ | |||
| @Service | |||
| public class WxPayBillServiceImpl implements WxPayBillService { | |||
| private final Logger logger = LoggerFactory.getLogger(this.getClass()); | |||
| @Autowired | |||
| WxAppinfoMapper wxAppinfoMapper; | |||
| @Autowired | |||
| WxPayAccountBillMapper wxPayAccountBillMapper; | |||
| @Autowired | |||
| WxPayBillMapper wxPayBillMapper; | |||
| @Autowired | |||
| WxBillAllMapper wxBillAllMapper; | |||
| @Autowired | |||
| WxBillAllService wxBillAllService; | |||
| @Autowired | |||
| WxMerchantBUserMapper wxMerchantBUserMapper; | |||
| JSONObject errorMap = JSON.parseObject("{" + | |||
| "\"NOAUTH\":{\"detail\":\"商户无此接口权限\",\"reason\":\"商户未开通此接口权限\",\"resolution\":\"请商户前往申请此接口权限\"}," + | |||
| "\"NOTENOUGH\":{\"detail\":\"余额不足\",\"reason\":\"用户帐号余额不足\",\"resolution\":\"用户帐号余额不足,请用户充值或更换支付卡后再支付\"}," + | |||
| "\"ORDERPAID\":{\"detail\":\"商户订单已支付\",\"reason\":\"商户订单已支付,无需重复操作\",\"resolution\":\"商户订单已支付,无需更多操作\"}," + | |||
| "\"ORDERCLOSED\":{\"detail\":\"订单已关闭\",\"reason\":\"当前订单已关闭,无法支付\",\"resolution\":\"当前订单已关闭,请重新下单\"}," + | |||
| "\"SYSTEMERROR\":{\"detail\":\"系统错误\t\",\"reason\":\"系统超时\",\"resolution\":\"系统异常,请用相同参数重新调用\"}," + | |||
| "\"APPID_NOT_EXIST\":{\"detail\":\"APPID不存在\",\"reason\":\"参数中缺少APPID\",\"resolution\":\"请检查APPID是否正确\"}," + | |||
| "\"MCHID_NOT_EXIST\":{\"detail\":\"MCHID不存在\",\"reason\":\"参数中缺少MCHID\",\"resolution\":\"请检查MCHID是否正确\"}," + | |||
| "\"APPID_MCHID_NOT_MATCH\":{\"detail\":\"appid和mch_id不匹配\",\"reason\":\"appid和mch_id不匹配\",\"resolution\":\"请确认appid和mch_id是否匹配\"}," + | |||
| "\"LACK_PARAMS\":{\"detail\":\"缺少参数\t\",\"reason\":\"缺少必要的请求参数\",\"resolution\":\"请检查参数是否齐全\"}," + | |||
| "\"OUT_TRADE_NO_USED\":{\"detail\":\"商户订单号重复\",\"reason\":\"同一笔交易不能多次提交\",\"resolution\":\"请核实商户订单号是否重复提交\"}," + | |||
| "\"SIGNERROR\":{\"detail\":\"签名错误\",\"reason\":\"参数签名结果不正确\",\"resolution\":\"请检查签名参数和方法是否都符合签名算法要求\"}," + | |||
| "\"XML_FORMAT_ERROR\":{\"detail\":\"XML格式错误\t\",\"reason\":\"XML格式错误\",\"resolution\":\"请检查XML参数格式是否正确\"}," + | |||
| "\"REQUIRE_POST_METHOD\":{\"detail\":\"请使用post方法\",\"reason\":\"未使用post传递参数\",\"resolution\":\"请检查请求参数是否通过post方法提交\"}," + | |||
| "\"POST_DATA_EMPTY\":{\"detail\":\"post数据为空\",\"reason\":\"post数据不能为空\",\"resolution\":\"请检查post数据是否为空\"}," + | |||
| "\"NOT_UTF8\":{\"detail\":\"编码格式错误\",\"reason\":\"未使用指定编码格式\",\"resolution\":\"请使用UTF-8编码格式\"}}"); | |||
| JSONObject errorMapQuery = JSON.parseObject("{" + | |||
| "\"ORDERNOTEXIST\":{\"detail\":\"此交易订单号不存在\",\"reason\":\"查询系统中不存在此交易订单号\",\"resolution\":\"该API只能查提交支付交易返回成功的订单,请商户检查需要查询的订单号是否正确\"},\n" + | |||
| "\"SYSTEMERROR\":{\"detail\":\"系统错误\t\",\"reason\":\"后台系统返回错误\",\"resolution\":\"系统异常,请再调用发起查询\"}}"); | |||
| JSONObject errorMapClose = JSON.parseObject("{" + | |||
| "\"ORDERPAID\":{\"detail\":\"订单已支付\",\"reason\":\"订单已支付,不能发起关单\",\"resolution\":\"订单已支付,不能发起关单,请当作已支付的正常交易\"}," + | |||
| "\"SYSTEMERROR\":{\"detail\":\"系统错误\",\"reason\":\"系统错误\",\"resolution\":\"系统异常,请重新调用该API\"}," + | |||
| "\"ORDERCLOSED\":{\"detail\":\"订单已关闭\",\"reason\":\"订单已关闭,无法重复关闭\",\"resolution\":\"订单已关闭,无需继续调用\"}," + | |||
| "\"SIGNERROR\":{\"detail\":\"签名错误\",\"reason\":\"参数签名结果不正确\",\"resolution\":\"请检查签名参数和方法是否都符合签名算法要求\"}," + | |||
| "\"REQUIRE_POST_METHOD\":{\"detail\":\"请使用post方法\",\"reason\":\"未使用post传递参数\",\"resolution\":\"请检查请求参数是否通过post方法提交\"}," + | |||
| "\"XML_FORMAT_ERROR\":{\"detail\":\"XML格式错误\t\",\"reason\":\"XML格式错误\",\"reason\":\"请检查XML参数格式是否正确\"}}"); | |||
| @Override | |||
| public ResultData createPayBill(boolean isReal, WxAppinfo appInfo, WxPayBill record, EnumPayWay payWay) { | |||
| final IdWorker idworker = IdWorker.get(); | |||
| EnumPayShare isShare = EnumPayShare.NO; | |||
| try { | |||
| // 1. check 订单 | |||
| WxBillAll wxBillAll = new WxBillAll(); | |||
| wxBillAll.setId(record.getBillId()); | |||
| List<Map<String, Object>> bills = wxBillAllMapper.listData(wxBillAll); | |||
| if (bills == null) { | |||
| logger.error("pay bill, bill not allow, repaymentReq: " + record.toString() + ", payWay: " + payWay.toString()); | |||
| throw new MallinkException(ErrorCode.BILL_ROUTINE_IS_NOT_FOUND); | |||
| } | |||
| Map<String, Object> bill; | |||
| //获取账单数据 | |||
| if(bills.size()>0){ | |||
| bill = bills.get(0); | |||
| }else{ | |||
| logger.error("pay bill, bill not allow, repaymentReq: " + record.toString() + ", payWay: " + payWay.toString()); | |||
| throw new MallinkException(ErrorCode.BILL_ROUTINE_IS_NOT_FOUND); | |||
| } | |||
| WxPayAccountBill payAccount = wxPayAccountBillMapper.selectByPrimaryKey(appInfo.getPayBillId()); | |||
| // 2. check 是否有支付订单 | |||
| Date currentDate = new Date(); | |||
| record.setPayBillStatus(EnumPayStatus.PAY_WAY_WAIT.getCode()); | |||
| List<WxPayBill> list = wxPayBillMapper.findList(record); | |||
| String payBillNo; | |||
| if (list.size() <= 0) { | |||
| // 3. 创建支付订单 | |||
| Long id = idworker.nextId(); | |||
| payBillNo = String.valueOf(id); | |||
| record.setId(id); | |||
| record.setTenantId(appInfo.getTenantId()); | |||
| record.setbUserId(record.getbUserId()); | |||
| record.setCreateTime(currentDate); | |||
| record.setUpdateTime(currentDate); | |||
| record.setPayTimeStart(currentDate); | |||
| record.setPayTimeEnd(currentDate); | |||
| // 支付单号 | |||
| record.setPayBillNo(payBillNo); | |||
| record.setPayAmount((Integer) bill.get("owe")); | |||
| record.setPayVendor(EnumPayWay.PAY_WAY_WEAPP.getCode()); | |||
| record.setPayBillStatus(EnumPayStatus.PAY_WAY_WAIT.getCode()); | |||
| record.setShare(isShare.getCode()); | |||
| int sqlRow = wxPayBillMapper.insertSelective(record); | |||
| if (sqlRow != 1) { | |||
| logger.error("pay bill insert error: " + record.toString()); | |||
| throw new MallinkException(ErrorCode.DB_FAIL); | |||
| } | |||
| } else { | |||
| record = list.get(0); | |||
| record.setShare(isShare.getCode()); | |||
| payBillNo = String.valueOf(record.getId()); | |||
| } | |||
| if (isReal) { | |||
| // 微信实际支付 | |||
| if (payAccount.getType().equals(EnumPayMode.MCH.getCode())) { | |||
| // 统一下单 普通商户模式 | |||
| String noncestr = Utility.generate32UUID(); | |||
| WxPayOrderP wxPayBillP = new WxPayOrderP(); | |||
| wxPayBillP.setOpenid(record.getOpenId()); | |||
| wxPayBillP.setAppid(appInfo.getAppId()); | |||
| wxPayBillP.setMch_id(payAccount.getMchId()); | |||
| wxPayBillP.setNonce_str(noncestr); | |||
| wxPayBillP.setBody(bill.get("billType").toString()); | |||
| wxPayBillP.setOut_trade_no(record.getPayBillNo()); | |||
| wxPayBillP.setTotal_fee((Integer) bill.get("owe")); | |||
| // 终端IP | |||
| wxPayBillP.setSpbill_create_ip(record.getIp()); | |||
| wxPayBillP.setNotify_url(payAccount.getPayNotifyUrl()); | |||
| // 终端类型 | |||
| wxPayBillP.setTrade_type(WxPay.TradeType.JSAPI.name()); | |||
| // 订单ID | |||
| wxPayBillP.setProduct_id(bill.get("id").toString()); | |||
| wxPayBillP.setTime_start(Utility.getDataFormatStringYYYYMMDDHHmmss(currentDate)); | |||
| Date futureDate = new Date(); | |||
| futureDate.setTime(currentDate.getTime() + 15 * 60 * 1000); | |||
| // 15分钟后结束 | |||
| wxPayBillP.setTime_expire(Utility.getDataFormatStringYYYYMMDDHHmmss(futureDate)); | |||
| Map<String, String> payBillMap = BeanUtils.toStringMap(wxPayBillP); | |||
| wxPayBillP.setSign(WxPayment.createSign(payBillMap, payAccount.getApiKey())); | |||
| String response = WxPay.pushOrder(BeanUtils.toStringMap(wxPayBillP)); | |||
| logger.info("pay bill, wechat pushBill, " + wxPayBillP.toString() + ", response: " + response); | |||
| Map<String, String> returnMap = WxPayment.xmlToMap(response); | |||
| returnMap.put("payBillId", payBillNo); | |||
| String result_code = returnMap.get("result_code"); | |||
| if ("SUCCESS".equals(result_code)) { | |||
| String prepay_id = returnMap.get("prepay_id"); | |||
| // update payBill with prepay_id | |||
| record.setPrepayId(prepay_id); | |||
| record.setUpdateTime(new Date()); | |||
| try { | |||
| wxPayBillMapper.updateByPrimaryKeySelective(record); | |||
| } catch (Exception e) { | |||
| logger.error("pay bill update error: " + record.toString()); | |||
| throw new MallinkException(ErrorCode.DB_FAIL); | |||
| } | |||
| String timestamp = String.valueOf(Utility.getCurrentTimeStamp()); | |||
| Map<String, String> sighMap = MapUtil.getOrderMap(); | |||
| sighMap.put("appId", returnMap.get("appid")); | |||
| sighMap.put("timeStamp", timestamp); | |||
| sighMap.put("nonceStr", noncestr); | |||
| sighMap.put("package", "prepay_id=" + prepay_id); | |||
| sighMap.put("signType", "MD5"); | |||
| String signAgent = WxPayment.createSign(sighMap, payAccount.getApiKey()); | |||
| returnMap.put("timeStamp", timestamp); | |||
| returnMap.put("nonceStr", noncestr); | |||
| returnMap.put("package", "prepay_id=" + prepay_id); | |||
| returnMap.put("paySign", signAgent); | |||
| logger.info("back to UI: " + returnMap.toString()); | |||
| return new ResultData(Result.SUCCESS, "创建支付订单成功", returnMap); | |||
| } else { | |||
| return updatePayBill(record, returnMap, result_code); | |||
| } | |||
| } else { | |||
| // 统一下单 // 服务商模式 | |||
| String noncestr = Utility.generate32UUID(); | |||
| WxPayOrderSP wxPayBillSP = new WxPayOrderSP(); | |||
| wxPayBillSP.setSub_openid(record.getOpenId()); | |||
| wxPayBillSP.setAppid(appInfo.getParentAppId()); | |||
| wxPayBillSP.setMch_id(payAccount.getMchId()); | |||
| wxPayBillSP.setSub_appid(appInfo.getAppId()); | |||
| wxPayBillSP.setSub_mch_id(payAccount.getSubMchId()); | |||
| wxPayBillSP.setNonce_str(noncestr); | |||
| wxPayBillSP.setBody(bill.get("billType").toString()); | |||
| wxPayBillSP.setOut_trade_no(record.getPayBillNo()); | |||
| wxPayBillSP.setTotal_fee((Integer) bill.get("owe")); | |||
| wxPayBillSP.setSpbill_create_ip(record.getIp()); // 终端IP | |||
| wxPayBillSP.setNotify_url(payAccount.getPayNotifyUrl()); | |||
| wxPayBillSP.setTrade_type(WxPay.TradeType.JSAPI.name()); // 终端类型 | |||
| wxPayBillSP.setProduct_id(String.valueOf(bill.get("id").toString())); // 订单ID | |||
| wxPayBillSP.setTime_start(Utility.getDataFormatStringYYYYMMDDHHmmss(currentDate)); | |||
| Date futureDate = new Date(); | |||
| futureDate.setTime(currentDate.getTime() + 15 * 60 * 1000); | |||
| wxPayBillSP.setTime_expire(Utility.getDataFormatStringYYYYMMDDHHmmss(futureDate)); // 15分钟后结束 | |||
| wxPayBillSP.setSign_type("HMAC-SHA256"); | |||
| wxPayBillSP.setProfit_sharing(null); | |||
| if (isShare == EnumPayShare.YES) { | |||
| wxPayBillSP.setProfit_sharing("Y"); | |||
| } | |||
| Map<String, String> payBillMap = BeanUtils.toStringMap(wxPayBillSP); | |||
| wxPayBillSP.setSign(WxPayment.createSignHMAC(payBillMap, payAccount.getApiKey())); | |||
| String response = WxPay.pushOrder(BeanUtils.toStringMap(wxPayBillSP)); | |||
| logger.info("pay bill, wechat pushBill, " + wxPayBillSP.toString() + ", response: " + response.toString()); | |||
| Map<String, String> returnMap = WxPayment.xmlToMap(response); | |||
| returnMap.put("payBillId", payBillNo); | |||
| String result_code = returnMap.get("result_code"); | |||
| if ("SUCCESS".equals(result_code)) { | |||
| String prepay_id = returnMap.get("prepay_id"); | |||
| // update payBill with prepay_id | |||
| record.setPrepayId(prepay_id); | |||
| record.setUpdateTime(new Date()); | |||
| try { | |||
| wxPayBillMapper.updateByPrimaryKeySelective(record); | |||
| } catch (Exception e) { | |||
| logger.error("pay bill update error: " + record.toString()); | |||
| throw new MallinkException(ErrorCode.DB_FAIL); | |||
| } | |||
| String timestamp = String.valueOf(Utility.getCurrentTimeStamp()); | |||
| Map<String, String> sighMap = MapUtil.getOrderMap(); | |||
| sighMap.put("appId", appInfo.getAppId()); | |||
| sighMap.put("timeStamp", timestamp); | |||
| sighMap.put("nonceStr", noncestr); | |||
| sighMap.put("package", "prepay_id=" + prepay_id); | |||
| sighMap.put("signType", "HMAC-SHA256"); | |||
| String signAgent = WxPayment.createSignHMAC(sighMap, payAccount.getApiKey()); | |||
| returnMap.put("timeStamp", timestamp); | |||
| returnMap.put("nonceStr", noncestr); | |||
| returnMap.put("package", "prepay_id=" + prepay_id); | |||
| returnMap.put("paySign", signAgent); | |||
| returnMap.put("signType", "HMAC-SHA256"); | |||
| logger.info("back to UI: " + returnMap.toString()); | |||
| return new ResultData(Result.SUCCESS, "创建支付订单成功", returnMap); | |||
| } else { | |||
| return updatePayBill(record, returnMap, result_code); | |||
| } | |||
| } | |||
| } else { | |||
| // 虚拟支付 | |||
| WxPayOrderP wxPayBillP = new WxPayOrderP(); | |||
| wxPayBillP.setOpenid(record.getOpenId()); | |||
| wxPayBillP.setAppid(appInfo.getAppId()); | |||
| wxPayBillP.setMch_id(payAccount.getMchId()); | |||
| wxPayBillP.setBody(bill.get("billType").toString()); | |||
| wxPayBillP.setOut_trade_no(record.getPayBillNo()); | |||
| wxPayBillP.setTotal_fee((Integer) bill.get("owe")); | |||
| // 终端IP | |||
| wxPayBillP.setSpbill_create_ip(record.getIp()); | |||
| wxPayBillP.setNotify_url(payAccount.getPayNotifyUrl()); | |||
| // 终端类型 | |||
| wxPayBillP.setTrade_type(WxPay.TradeType.JSAPI.name()); | |||
| // 订单ID | |||
| wxPayBillP.setProduct_id(bill.get("id").toString()); | |||
| wxPayBillP.setTime_start(Utility.getDataFormatStringYYYYMMDDHHmmss(currentDate)); | |||
| Date futureDate = new Date(); | |||
| futureDate.setTime(currentDate.getTime() + 15 * 60 * 1000); | |||
| // 15分钟后结束 | |||
| wxPayBillP.setTime_expire(Utility.getDataFormatStringYYYYMMDDHHmmss(futureDate)); | |||
| wxPayBillP.setSign(WxPayment.createSign(BeanUtils.toStringMap(wxPayBillP), payAccount.getApiKey())); | |||
| Map<String, String> returnMap = BeanUtils.toStringMap(wxPayBillP); | |||
| return new ResultData(Result.SUCCESS, "创建支付订单成功", returnMap); | |||
| } | |||
| } catch (RuntimeException e) { | |||
| throw new MallinkException(ErrorCode.PAY_ORDER_ERROR.getCode(), e.getMessage()); | |||
| } catch (Exception e) { | |||
| throw new MallinkException(ErrorCode.PAY_ORDER_ERROR.getCode(), e.getMessage()); | |||
| } | |||
| } | |||
| private ResultData updatePayBill(WxPayBill record, Map<String, String> returnMap, String result_code) { | |||
| String errMsg = ""; | |||
| JSONObject errObj = errorMap.getJSONObject(result_code); | |||
| if (errObj != null) { | |||
| errMsg = errObj.toJSONString(); | |||
| record.setFailReason(errMsg); | |||
| } else { | |||
| errMsg = returnMap.get("return_msg"); | |||
| record.setFailReason(errMsg); | |||
| } | |||
| record.setUpdateTime(new Date()); | |||
| try { | |||
| wxPayBillMapper.updateByPrimaryKeySelective(record); | |||
| } catch (Exception e) { | |||
| logger.error("pay bill update error: " + record.toString()); | |||
| throw new MallinkException(ErrorCode.DB_FAIL); | |||
| } | |||
| return new ResultData(ErrorCode.PAY_ORDER_ERROR.getCode(), errMsg, returnMap); | |||
| } | |||
| private String wechatPayBillQuery(WxAppinfo appInfo, WxPayBill record) { | |||
| // get payAccount | |||
| WxPayAccountBill payAccount = wxPayAccountBillMapper.selectByPrimaryKey(appInfo.getPayBillId()); | |||
| if (payAccount.getType().equals(EnumPayMode.MCH.getCode())) { | |||
| // 普通商户号模式 | |||
| WxPayOrderQ payBillQ = new WxPayOrderQ(); | |||
| String noncestr = Utility.generate32UUID(); | |||
| payBillQ.setAppid(appInfo.getAppId()); | |||
| payBillQ.setMch_id(payAccount.getMchId()); | |||
| payBillQ.setNonce_str(noncestr); | |||
| payBillQ.setOut_trade_no(record.getPayBillNo()); | |||
| try { | |||
| Map map = BeanUtils.toStringMap(payBillQ); | |||
| payBillQ.setSign(WxPayment.createSign(map, payAccount.getApiKey())); | |||
| map = BeanUtils.toStringMap(payBillQ); | |||
| String response = WxPay.orderQuery(map); | |||
| return response; | |||
| } catch (RuntimeException e) { | |||
| throw new MallinkException(ErrorCode.PAY_ORDER_ERROR.getCode(), e.getMessage()); | |||
| } catch (Exception e) { | |||
| throw new MallinkException(ErrorCode.PAY_ORDER_ERROR.getCode(), e.getMessage()); | |||
| } | |||
| } else { | |||
| // 服务商模式 | |||
| WxPayOrderSQ payBillSQ = new WxPayOrderSQ(); | |||
| String noncestr = Utility.generate32UUID(); | |||
| payBillSQ.setAppid(appInfo.getParentAppId()); | |||
| payBillSQ.setSub_appid(appInfo.getAppId()); | |||
| payBillSQ.setMch_id(payAccount.getMchId()); | |||
| payBillSQ.setSub_mch_id(payAccount.getSubMchId()); | |||
| payBillSQ.setNonce_str(noncestr); | |||
| payBillSQ.setOut_trade_no(record.getPayBillNo()); | |||
| payBillSQ.setSign_type("HMAC-SHA256"); | |||
| try { | |||
| Map map = BeanUtils.toStringMap(payBillSQ); | |||
| payBillSQ.setSign(WxPayment.createSignHMAC(map, payAccount.getApiKey())); | |||
| map = BeanUtils.toStringMap(payBillSQ); | |||
| String response = WxPay.orderQuery(map); | |||
| return response; | |||
| } catch (RuntimeException e) { | |||
| throw new MallinkException(ErrorCode.PAY_ORDER_ERROR.getCode(), e.getMessage()); | |||
| } catch (Exception e) { | |||
| throw new MallinkException(ErrorCode.PAY_ORDER_ERROR.getCode(), e.getMessage()); | |||
| } | |||
| } | |||
| } | |||
| /** | |||
| * 微信订单查询 | |||
| */ | |||
| @Override | |||
| public ResultData payBillQuery(WxAppinfo appInfo, WxPayBill record) { | |||
| try { | |||
| if (StringUtils.isBlank(record.getPayBillNo())){ | |||
| record.setPayBillNo(String.valueOf(record.getId())); | |||
| } | |||
| String response = wechatPayBillQuery(appInfo, record); | |||
| logger.info("pay bill query, " + record.toString() + ", response: " + response); | |||
| Map<String, String> returnMap = WxPayment.xmlToMap(response); | |||
| String result_code = returnMap.get("result_code"); | |||
| if ("SUCCESS".equals(result_code)) { | |||
| String trade_state = returnMap.get("trade_state"); | |||
| //SUCCESS—支付成功 | |||
| //REFUND—转入退款 | |||
| //NOTPAY—未支付 | |||
| //CLOSED—已关闭 | |||
| //REVOKED—已撤销(刷卡支付) | |||
| //USERPAYING--用户支付中 | |||
| //PAYERROR--支付失败(其他原因,如银行返回失败) | |||
| if ("SUCCESS".equals(trade_state)) { | |||
| record.setPayBillStatus(EnumPayStatus.PAY_WAY_SUCCESS.getCode()); | |||
| handlePayBillStatusUpdate(record); | |||
| } else if ("USERPAYING".equals(trade_state)) { | |||
| record.setPayBillStatus(EnumPayStatus.PAY_WAY_WAIT.getCode()); | |||
| handlePayBillStatusUpdate(record); | |||
| } else { | |||
| record.setPayBillStatus(EnumPayStatus.PAY_WAY_FAIL.getCode()); | |||
| handlePayBillStatusUpdate(record); | |||
| } | |||
| return new ResultData(Result.SUCCESS, "订单查询成功", returnMap); | |||
| } else { | |||
| return updatePayBill(record, returnMap, result_code); | |||
| } | |||
| } catch (MallinkException e) { | |||
| throw new MallinkException(ErrorCode.PAY_ORDER_ERROR.getCode(), e.getMessage()); | |||
| } catch (RuntimeException e) { | |||
| throw new MallinkException(ErrorCode.PAY_ORDER_ERROR.getCode(), e.getMessage()); | |||
| } catch (Exception e) { | |||
| throw new MallinkException(ErrorCode.PAY_ORDER_ERROR.getCode(), e.getMessage()); | |||
| } | |||
| } | |||
| private String wechatPayBillClose(WxAppinfo appInfo, WxPayBill record) { | |||
| // get payAccount | |||
| WxPayAccountBill payAccount = wxPayAccountBillMapper.selectByPrimaryKey(appInfo.getPayBillId()); | |||
| if (payAccount.getType().equals(EnumPayMode.MCH.getCode())) { | |||
| // 普通商户号模式 | |||
| WxPayOrderQ payBillC = new WxPayOrderQ(); | |||
| String noncestr = Utility.generate32UUID(); | |||
| payBillC.setAppid(appInfo.getAppId()); | |||
| payBillC.setMch_id(payAccount.getMchId()); | |||
| payBillC.setNonce_str(noncestr); | |||
| payBillC.setOut_trade_no(record.getPayBillNo()); | |||
| return closeOrderNormal(payAccount, payBillC); | |||
| } else { | |||
| // 服务商模式 | |||
| WxPayOrderSQ payBillSC = new WxPayOrderSQ(); | |||
| String noncestr = Utility.generate32UUID(); | |||
| payBillSC.setAppid(appInfo.getParentAppId()); | |||
| payBillSC.setSub_appid(appInfo.getAppId()); | |||
| payBillSC.setMch_id(payAccount.getMchId()); | |||
| payBillSC.setSub_mch_id(payAccount.getSubMchId()); | |||
| payBillSC.setNonce_str(noncestr); | |||
| payBillSC.setOut_trade_no(record.getPayBillNo()); | |||
| payBillSC.setSign_type("HMAC-SHA256"); | |||
| return closeOrderServer(payAccount, payBillSC); | |||
| } | |||
| } | |||
| private String closeOrderServer(WxPayAccountBill payAccount, WxPayOrderSQ payBillSC) { | |||
| try { | |||
| Map map = BeanUtils.toStringMap(payBillSC); | |||
| payBillSC.setSign(WxPayment.createSignHMAC(map, payAccount.getApiKey())); | |||
| map = BeanUtils.toStringMap(payBillSC); | |||
| String response = WxPay.closeOrder(map); | |||
| return response; | |||
| } catch (RuntimeException e) { | |||
| throw new MallinkException(ErrorCode.PAY_ORDER_ERROR.getCode(), e.getMessage()); | |||
| } catch (Exception e) { | |||
| throw new MallinkException(ErrorCode.PAY_ORDER_ERROR.getCode(), e.getMessage()); | |||
| } | |||
| } | |||
| private String closeOrderNormal(WxPayAccountBill payAccount, WxPayOrderQ payBillC) { | |||
| try { | |||
| Map map = BeanUtils.toStringMap(payBillC); | |||
| payBillC.setSign(WxPayment.createSign(map, payAccount.getApiKey())); | |||
| map = BeanUtils.toStringMap(payBillC); | |||
| String response = WxPay.closeOrder(map); | |||
| return response; | |||
| } catch (RuntimeException e) { | |||
| throw new MallinkException(ErrorCode.PAY_ORDER_ERROR.getCode(), e.getMessage()); | |||
| } catch (Exception e) { | |||
| throw new MallinkException(ErrorCode.PAY_ORDER_ERROR.getCode(), e.getMessage()); | |||
| } | |||
| } | |||
| /** | |||
| * 微信关闭支付订单 | |||
| */ | |||
| @Override | |||
| public ResultData payBillClose(WxAppinfo appInfo, WxPayBill record) { | |||
| try { | |||
| String response = wechatPayBillClose(appInfo, record); | |||
| logger.info("pay bill close, " + record.toString() + ", response: " + response); | |||
| Map<String, String> returnMap = WxPayment.xmlToMap(response); | |||
| String result_code = returnMap.get("result_code"); | |||
| if ("SUCCESS".equals(result_code)) { | |||
| record.setPayBillStatus(EnumPayStatus.PAY_WAY_CANCEL.getCode()); | |||
| handlePayBillStatusUpdate(record); | |||
| return new ResultData(Result.SUCCESS, "订单关闭成功", returnMap); | |||
| } else { | |||
| String errMsg = ""; | |||
| JSONObject errObj = errorMapClose.getJSONObject(result_code); | |||
| if (errObj != null) { | |||
| errMsg = errObj.toJSONString(); | |||
| } else { | |||
| errMsg = returnMap.get("return_msg"); | |||
| } | |||
| record.setFailReason(errMsg); | |||
| record.setUpdateTime(new Date()); | |||
| try { | |||
| wxPayBillMapper.updateByPrimaryKeySelective(record); | |||
| } catch (Exception e) { | |||
| logger.error("pay bill update error: " + record.toString()); | |||
| throw new MallinkException(ErrorCode.DB_FAIL); | |||
| } | |||
| return new ResultData(ErrorCode.PAY_ORDER_ERROR.getCode(), errMsg, returnMap); | |||
| } | |||
| } catch (RuntimeException e) { | |||
| throw new MallinkException(ErrorCode.PAY_ORDER_ERROR.getCode(), e.getMessage()); | |||
| } catch (Exception e) { | |||
| throw new MallinkException(ErrorCode.PAY_ORDER_ERROR.getCode(), e.getMessage()); | |||
| } | |||
| } | |||
| /** | |||
| * 提供微信支付回调调用 | |||
| * | |||
| * @param paramMap 异步通知参数 | |||
| * @param payWay 支付方式 | |||
| * @return | |||
| */ | |||
| @Override | |||
| public String notify(Map<String, String> paramMap, EnumPayWay payWay) { | |||
| // how to get wechatAppId, wechatMchId, partnerKey | |||
| String appId = paramMap.get("appid"); | |||
| String subAppId = paramMap.get("sub_appid"); | |||
| String mchId = paramMap.get("mch_id"); | |||
| String subMchId = paramMap.get("sub_mch_id"); | |||
| WxAppinfo appinfo = null; | |||
| boolean isNormal = true; | |||
| if (StringUtils.isBlank(subAppId) && StringUtils.isBlank(subMchId)) { | |||
| // 普通商户号 | |||
| appinfo = wxAppinfoMapper.findByAppId(appId); | |||
| if (appinfo == null) { | |||
| throw new MallinkException(ErrorCode.APP_ID_NOT_FOUND); | |||
| } | |||
| isNormal = true; | |||
| } else { | |||
| // 服务号 现在用hmac-sha256 | |||
| appinfo = wxAppinfoMapper.findByAppId(subAppId); | |||
| if (appinfo == null) { | |||
| throw new MallinkException(ErrorCode.APP_ID_NOT_FOUND); | |||
| } | |||
| isNormal = false; | |||
| } | |||
| WxPayAccountBill payAccount = wxPayAccountBillMapper.selectByPrimaryKey(appinfo.getPayBillId()); | |||
| if (payAccount == null) { | |||
| throw new MallinkException(ErrorCode.MCH_INFO_NOT_FOUND); | |||
| } | |||
| String partnerKey = payAccount.getApiKey(); | |||
| try { | |||
| if (payWay == EnumPayWay.PAY_WAY_WEAPP) { | |||
| boolean signVerified = false; | |||
| if (isNormal) { | |||
| // 普通商户号支付 | |||
| signVerified = WxPayment.verifyNotify(paramMap, partnerKey); | |||
| if (!signVerified) { | |||
| logger.warn("notify bill, wxpay checksign error, paramMap: " + paramMap.toString() + ", payWay:" + payWay.toString()); | |||
| throw new MallinkException(ErrorCode.PAY_ORDER_NOTIFY_CHECK_SIGN_ERROR); | |||
| } | |||
| } else { | |||
| // 服务号 现在用hmac-sha256 | |||
| signVerified = WxPayment.verifyNotifyHMAC(paramMap, partnerKey); | |||
| if (!signVerified) { | |||
| logger.warn("notify bill, wxpay checksign error, paramMap: " + paramMap.toString() + ", payWay:" + payWay.toString()); | |||
| throw new MallinkException(ErrorCode.PAY_ORDER_NOTIFY_CHECK_SIGN_ERROR); | |||
| } | |||
| } | |||
| if (!"SUCCESS".equals(paramMap.get("return_code"))) { | |||
| logger.warn("notify bill, wxpay status not success, paramMap: " + paramMap.toString() + ", payWay:" + payWay.toString()); | |||
| SortedMap resultMap = new TreeMap(); | |||
| resultMap.put("return_code", "FAIL"); | |||
| resultMap.put("return_msg", "订单状态码非SUCCESS"); | |||
| return XmlUtil.getRequestXml(resultMap); | |||
| } | |||
| String payBillNo = paramMap.get("out_trade_no"); | |||
| String timEndStr = paramMap.get("time_end"); | |||
| Long payBillId = Long.valueOf(payBillNo); | |||
| WxPayBill payBill = wxPayBillMapper.selectByPrimaryKey(payBillId); | |||
| if (payBill == null) { | |||
| logger.warn("notify bill, wxpay check pay bill not exists, paramMap: " + paramMap.toString() + ", payWay:" + payWay.toString()); | |||
| SortedMap resultMap = new TreeMap(); | |||
| resultMap.put("return_code", "FAIL"); | |||
| resultMap.put("return_msg", "订单不存在"); | |||
| return XmlUtil.getRequestXml(resultMap); | |||
| } | |||
| // 验证支付金额 | |||
| if (!paramMap.get("total_fee").equals(payBill.getPayAmount().toString())) { | |||
| logger.warn("notify bill, wxpay check total_fee is invalid, paramMap: " + paramMap.toString() + ", payWay:" + payWay.toString()); | |||
| SortedMap resultMap = new TreeMap(); | |||
| resultMap.put("return_code", "FAIL"); | |||
| resultMap.put("return_msg", "订单总金额不一致"); | |||
| return XmlUtil.getRequestXml(resultMap); | |||
| } | |||
| Date timeEnd = null; | |||
| try { | |||
| timeEnd = Utility.getDateFromString(timEndStr); | |||
| } catch (ParseException e) { | |||
| logger.error("解析timeEnd失败"); | |||
| timeEnd = new Date(); | |||
| } | |||
| payBill.setPayTimeEnd(timeEnd); | |||
| // 处理支付成功 | |||
| handleBillPaySuccess(payBill, paramMap.get("transaction_id")); | |||
| logger.info("notify bill, wxpay checksign success, paramMap:{}, paramMap: " + paramMap.toString() + ", payWay:" + payWay.toString()); | |||
| SortedMap resultMap = new TreeMap(); | |||
| resultMap.put("return_code", "SUCCESS"); | |||
| resultMap.put("return_msg", "OK"); | |||
| return XmlUtil.getRequestXml(resultMap); | |||
| } | |||
| } catch (RuntimeException e) { | |||
| logger.warn("notify bill, checksign error, paramMap: " + paramMap.toString() + ", payWay:" + payWay.toString() + ", e:" + e.getMessage()); | |||
| throw new MallinkException(ErrorCode.PAY_ORDER_ERROR); | |||
| } | |||
| SortedMap resultMap = new TreeMap(); | |||
| resultMap.put("return_code", "FAIL"); | |||
| resultMap.put("return_msg", "FAILED"); | |||
| return XmlUtil.getRequestXml(resultMap); | |||
| } | |||
| @Override | |||
| public void callback(Map<String, String> paramMap, EnumPayWay payWay) { | |||
| } | |||
| @Override | |||
| public WxPayBill getById(Long id) { | |||
| return wxPayBillMapper.selectByPrimaryKey(id); | |||
| } | |||
| @Override | |||
| @Transactional(propagation = Propagation.REQUIRED, readOnly = false, rollbackFor = {Exception.class}) | |||
| public void handleBillPaySuccess(WxPayBill record, String transactionId) { | |||
| Date currentDate = new Date(); | |||
| EnumPayStatus payStatus = EnumPayStatus.getEnum(record.getPayBillStatus()); | |||
| // 判断支付状态 | |||
| if (payStatus == EnumPayStatus.PAY_WAY_SUCCESS) { | |||
| // 已经是成功状态,只更新transactionId | |||
| try { | |||
| record.setUpdateTime(currentDate); | |||
| record.setTransactionId(transactionId); | |||
| wxPayBillMapper.updateByPrimaryKeySelective(record); | |||
| } catch (Exception e) { | |||
| logger.error(e.getMessage()); | |||
| throw new MallinkException(ErrorCode.DB_FAIL); | |||
| } | |||
| return; | |||
| } | |||
| if (payStatus != EnumPayStatus.PAY_WAY_WAIT) { | |||
| logger.error("pay success handle, payBill " + record.getPayBillNo() + | |||
| "is paid success , billId : " + record.getBillId()); | |||
| return; | |||
| } | |||
| WxBillAll wxBillAll = new WxBillAll(); | |||
| wxBillAll.setId(record.getBillId()); | |||
| List<Map<String, Object>> bills = wxBillAllMapper.listData(wxBillAll); | |||
| if (bills == null) { | |||
| logger.error("pay success handle, bill " + record.getBillId() + " not found , payBillNo : " + record.getPayBillNo()); | |||
| throw new MallinkException(ErrorCode.BILL_ROUTINE_IS_NOT_FOUND); | |||
| } | |||
| Map<String, Object> bill=null; | |||
| if(bills.size()>0){ | |||
| bill = bills.get(0); | |||
| }else{ | |||
| logger.error("pay success handle, bill " + record.getBillId() + " not found , payBillNo : " + record.getPayBillNo()); | |||
| throw new MallinkException(ErrorCode.BILL_ROUTINE_IS_NOT_FOUND); | |||
| } | |||
| // 修改支付订单状态 | |||
| WxPayBill updateBill = new WxPayBill(); | |||
| updateBill.setId(record.getId()); | |||
| updateBill.setBillId(record.getBillId()); | |||
| updateBill.setUpdateTime(currentDate); | |||
| updateBill.setPayBillStatus(EnumPayStatus.PAY_WAY_SUCCESS.getCode()); | |||
| updateBill.setTransactionId(transactionId); | |||
| try { | |||
| wxPayBillMapper.updateByPrimaryKeySelective(updateBill); | |||
| } catch (Exception e) { | |||
| logger.error("支付订单数据库更新失败: " + e.getMessage()); | |||
| throw new MallinkException(ErrorCode.DB_FAIL.getCode(), "支付订单数据库更新失败: " + e.getMessage()); | |||
| } | |||
| //修改账单状态 | |||
| try { | |||
| int _count = wxBillAllService.updateBill(bill); | |||
| if (_count > 1) { | |||
| throw new MallinkException(ErrorCode.BILL_UPDATE_FAILED); | |||
| } | |||
| } catch (Exception e) { | |||
| logger.error(e.getMessage()); | |||
| throw new MallinkException(ErrorCode.DB_FAIL.getCode(), "账单更新"); | |||
| } | |||
| } | |||
| @Override | |||
| @Transactional(propagation = Propagation.REQUIRED, readOnly = false, rollbackFor = {Exception.class}) | |||
| public void handlePayBillStatusUpdate(WxPayBill record) { | |||
| // 判断支付状态 | |||
| if (record.getPayBillStatus().equals(EnumPayStatus.PAY_WAY_WAIT.getCode())) { | |||
| logger.error("pay handle, payBill " + record.getPayBillNo() + | |||
| "is complete, billId : " + record.getBillId()); | |||
| return; | |||
| } | |||
| WxBillAll wxBillAll = new WxBillAll(); | |||
| wxBillAll.setId(record.getBillId()); | |||
| List<Map<String, Object>> bills = wxBillAllMapper.listData(wxBillAll); | |||
| if (bills == null) { | |||
| logger.error("pay handle, bill " + record.getBillId() + " not found , payBillGid : " + record.getPayBillNo()); | |||
| throw new MallinkException(ErrorCode.ORDER_IS_NOT_FIND); | |||
| } | |||
| WxMerchantBUser user = wxMerchantBUserMapper.selectByPrimaryKey(record.getbUserId()); | |||
| if (user == null) { | |||
| logger.error("pay handle, bill " + record.getBillId() + " not found , payBillGid : " + record.getPayBillNo()); | |||
| throw new MallinkException(ErrorCode.BUSER_NOT_IN_APP); | |||
| } | |||
| Map<String, Object> bill = bills.get(0); | |||
| Integer owe = (Integer) bill.get("owe"); | |||
| if (owe > 0) { | |||
| // 订单金额不为0时, 支付订单未创建, 返回异常 | |||
| if (!(record.getId() >0)) { | |||
| throw new MallinkException(ErrorCode.PAY_ORDER_NOT_FOUND); | |||
| } | |||
| } | |||
| Date currentDate = new Date(); | |||
| if (record.getId() > 0) { | |||
| // 1. get appinfo | |||
| WxAppinfo appInfo = null; | |||
| WxAppinfo appinfoQ = new WxAppinfo(); | |||
| appinfoQ.setTenantId(bill.get("tenantId").toString()); | |||
| appinfoQ.setType(EnumAppType.B.getCode()); | |||
| List<WxAppinfo> appList = wxAppinfoMapper.select(appinfoQ); | |||
| if (appList.size() > 0) { | |||
| appInfo = appList.get(0); | |||
| } | |||
| WxPayBill updateBill = null; | |||
| // 检查支付订单状态 | |||
| WxPayBill payBillQ = new WxPayBill(); | |||
| payBillQ.setId(record.getId()); | |||
| payBillQ.setTenantId(bill.get("tenantId").toString()); | |||
| payBillQ.setBillId(record.getBillId()); | |||
| try { | |||
| updateBill = wxPayBillMapper.selectOne(payBillQ); | |||
| } catch (Exception e) { | |||
| logger.error(e.getMessage()); | |||
| throw new MallinkException(ErrorCode.PAY_ORDER_NOT_FOUND); | |||
| } | |||
| if (record.getPayBillStatus().equals(EnumPayStatus.PAY_WAY_CANCEL.getCode())) { | |||
| // 支付订单取消 | |||
| if (record.getPayAmount() > 0) { | |||
| payBillQ = new WxPayBill(); | |||
| payBillQ.setTenantId(bill.get("tenantId").toString()); | |||
| payBillQ.setBillId(record.getBillId()); | |||
| payBillQ.setPayBillStatus(EnumPayStatus.PAY_WAY_WAIT.getCode()); | |||
| List<WxPayBill> payBills = wxPayBillMapper.select(payBillQ); | |||
| for (WxPayBill payBill : payBills) { | |||
| payBillClose(appInfo, payBill); | |||
| } | |||
| } | |||
| } else { | |||
| // 支付订单成功? | |||
| if (updateBill.getPayBillStatus().equals(EnumPayStatus.PAY_WAY_SUCCESS.getCode())) { | |||
| if (StringUtils.isBlank(updateBill.getTransactionId())) { | |||
| // 回调已设置成功 | |||
| // 继续修改订单状态 | |||
| } else { | |||
| // 回调异常 | |||
| throw new MallinkException(ErrorCode.PAY_ORDER_ERROR.getCode(), "transactionId未获取"); | |||
| } | |||
| } else if (updateBill.getPayBillStatus().equals(EnumPayStatus.PAY_WAY_WAIT.getCode())) { | |||
| // 回调未返回,主动检查支付订单状态 | |||
| try { | |||
| record.setPayBillNo(String.valueOf(record.getId())); | |||
| String response = wechatPayBillQuery(appInfo, record); | |||
| logger.info("pay bill query, " + record.toString() + ", response: " + response); | |||
| Map<String, String> returnMap = WxPayment.xmlToMap(response); | |||
| String result_code = returnMap.get("result_code"); | |||
| if ("SUCCESS".equals(result_code)) { | |||
| String trade_state = returnMap.get("trade_state"); | |||
| //SUCCESS—支付成功 | |||
| //REFUND—转入退款 | |||
| //NOTPAY—未支付 | |||
| //CLOSED—已关闭 | |||
| //REVOKED—已撤销(刷卡支付) | |||
| //USERPAYING--用户支付中 | |||
| //PAYERROR--支付失败(其他原因,如银行返回失败) | |||
| if ("SUCCESS".equals(trade_state)) { | |||
| // 查询支付订单 -- 已支付 | |||
| // 继续更改状态 | |||
| } else { | |||
| // 支付订单未成功,返回异常 | |||
| throw new MallinkException(ErrorCode.PAY_ORDER_ERROR.getCode(), "支付订单未成功"); | |||
| } | |||
| } | |||
| } catch (MallinkException e) { | |||
| throw new MallinkException(ErrorCode.PAY_ORDER_ERROR.getCode(), e.getMessage()); | |||
| } catch (RuntimeException e) { | |||
| throw new MallinkException(ErrorCode.PAY_ORDER_ERROR.getCode(), e.getMessage()); | |||
| } catch (Exception e) { | |||
| throw new MallinkException(ErrorCode.PAY_ORDER_ERROR.getCode(), e.getMessage()); | |||
| } | |||
| } | |||
| } | |||
| } | |||
| // 修改账单状态 | |||
| if (record.getPayBillStatus().equals(EnumPayStatus.PAY_WAY_SUCCESS.getCode())) { | |||
| try { | |||
| int _count = wxBillAllService.updateBill(bill); | |||
| if (_count > 1) { | |||
| throw new MallinkException(ErrorCode.ORDER_IS_FAIL); | |||
| } | |||
| } catch (Exception e) { | |||
| logger.error(e.getMessage()); | |||
| throw new MallinkException(ErrorCode.DB_FAIL.getCode(), "账单更新"); | |||
| } | |||
| } | |||
| } | |||
| } | |||
| @@ -16,10 +16,12 @@ | |||
| <result column="expires_in" jdbcType="INTEGER" property="expiresIn"/> | |||
| <result column="pay_id" jdbcType="BIGINT" property="payId"/> | |||
| <result column="type" jdbcType="INTEGER" property="type"/> | |||
| <result column="pay_bill_id" jdbcType="BIGINT" property="payBillId"/> | |||
| </resultMap> | |||
| <sql id="allColumns"> | |||
| `id`,`tenant_id`,`app_id`,`parent_app_id`,`name`,`secret`,`token`,`aes_key`,`msg_data_format`,`access_token`,`last_token_time`,`expires_in`,`pay_id`,`type` | |||
| `id`,`tenant_id`,`app_id`,`parent_app_id`,`name`,`secret`,`token`,`aes_key`,`msg_data_format`,`access_token`,`last_token_time`,`expires_in`,`pay_id`,`type`,`pay_bill_id` | |||
| </sql> | |||
| <sql id="dynamicWhereConditions"> | |||
| @@ -78,6 +80,9 @@ | |||
| <if test=" null != type "> | |||
| and `type` = #{type} | |||
| </if> | |||
| <if test=" null != payBillId "> | |||
| and `pay_bill_id` = #{payBillId} | |||
| </if> | |||
| <if test=" null != ids "> | |||
| and id in | |||
| <foreach collection="ids" index="index" item="idItem" open="(" separator="," close=")"> | |||
| @@ -80,7 +80,7 @@ | |||
| <select id="listData" resultType="hashmap" parameterType="com.iformall.domain.vo.WxBillAll"> | |||
| select bill.id,bill.merchant_id merchantId,bill.shop_id shopId,bill.bill_type_value billTypeValue,bill.bill_type billType,bill.need_pay needPay, | |||
| bill.receive_pay receivePay,bill.pay,bill.owe,bill.receive_date receiveDate,bill.pay_date payDate,bill.expired_day expiredDay,bill.status, | |||
| bill.tenant_id tenantId,m.name merchantName,s.shop_number shopNumber,bill.starttime,bill.endtime,bill.name from ( | |||
| bill.tenant_id tenantId,m.name merchantName,s.shop_number shopNumber,bill.starttime,bill.endtime,bill.name,pb.pay_bill_status payBillStatus from ( | |||
| select id,merchant_id,shop_id,tenant_id,'租金' name,1 bill_type_value,'租金' bill_type,need_pay,receive_pay,pay,owe,receive_date,pay_date,expired_day,status,starttime,endtime from wx_bill_rent | |||
| union | |||
| select id,merchant_id,shop_id,tenant_id,'租赁押金' name,2 bill_type_value,'租赁押金' bill_type,need_pay,receive_pay,pay,owe,receive_date,pay_date,expired_day,status,starttime,endtime from wx_bill_rent_deposit | |||
| @@ -97,6 +97,7 @@ | |||
| ) bill | |||
| left join wx_merchant m on bill.merchant_id=m.id | |||
| left join wx_shop s on bill.shop_id=s.id | |||
| left join wx_pay_bill pb on bill.id=pb.bill_id | |||
| where bill.tenant_id=#{tenantId} | |||
| <if test=" null != merchantId "> | |||
| and bill.merchant_id=#{merchantId} | |||
| @@ -0,0 +1,120 @@ | |||
| <?xml version="1.0" encoding="UTF-8"?> | |||
| <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> | |||
| <mapper namespace="com.iformall.mapper.WxPayBillMapper"> | |||
| <resultMap id="BaseResultMap" type="com.iformall.domain.po.WxPayBill"> | |||
| <id column="id" jdbcType="BIGINT" property="id"/> | |||
| <result column="tenant_id" jdbcType="VARCHAR" property="tenantId"/> | |||
| <result column="create_time" jdbcType="TIMESTAMP" property="createTime"/> | |||
| <result column="update_time" jdbcType="TIMESTAMP" property="updateTime"/> | |||
| <result column="bill_id" jdbcType="BIGINT" property="billId"/> | |||
| <result column="b_user_id" jdbcType="BIGINT" property="bUserId"/> | |||
| <result column="ip" jdbcType="VARCHAR" property="ip"/> | |||
| <result column="pay_amount" jdbcType="INTEGER" property="payAmount"/> | |||
| <result column="pay_time_start" jdbcType="TIMESTAMP" property="payTimeStart"/> | |||
| <result column="pay_time_end" jdbcType="TIMESTAMP" property="payTimeEnd"/> | |||
| <result column="prepay_id" jdbcType="VARCHAR" property="prepayId"/> | |||
| <result column="transaction_id" jdbcType="VARCHAR" property="transactionId"/> | |||
| <result column="pay_vendor" jdbcType="INTEGER" property="payVendor"/> | |||
| <result column="pay_bill_no" jdbcType="VARCHAR" property="payBillNo"/> | |||
| <result column="pay_bill_status" jdbcType="INTEGER" property="payBillStatus"/> | |||
| <result column="share" jdbcType="INTEGER" property="share"/> | |||
| <result column="share_amount" jdbcType="INTEGER" property="shareAmount"/> | |||
| <result column="fail_reason" jdbcType="VARCHAR" property="failReason"/> | |||
| <result column="open_id" jdbcType="VARCHAR" property="openId"/> | |||
| </resultMap> | |||
| <sql id="allColumns"> | |||
| `id`,`tenant_id`,`create_time`,`update_time`,`bill_id`,`b_user_id`,`ip`,`pay_amount`,`pay_time_start`,`pay_time_end`,`prepay_id`,`transaction_id`,`pay_vendor`,`pay_bill_no`,`pay_bill_status`,`share`,`share_amount`,`fail_reason`,`open_id` | |||
| </sql> | |||
| <sql id="dynamicWhereConditions"> | |||
| where 1 = 1 | |||
| <if test=" null != id "> | |||
| and `id` = #{id} | |||
| </if> | |||
| <if test=" null != tenantId "> | |||
| and `tenant_id` = #{tenantId} | |||
| </if> | |||
| <if test=" null != createTime "> | |||
| and `create_time` = #{createTime} | |||
| </if> | |||
| <if test=" null != updateTime "> | |||
| and `update_time` = #{updateTime} | |||
| </if> | |||
| <if test=" null != billId "> | |||
| and `bill_id` = #{billId} | |||
| </if> | |||
| <if test=" null != cUserId "> | |||
| and `b_user_id` = #{bUserId} | |||
| </if> | |||
| <if test=" null != ip "> | |||
| and `ip` like concat('%', #{ip},'%') | |||
| </if> | |||
| <if test=" null != payAmount "> | |||
| and `pay_amount` = #{payAmount} | |||
| </if> | |||
| <if test=" null != payTimeStart "> | |||
| and `pay_time_start` = #{payTimeStart} | |||
| </if> | |||
| <if test=" null != payTimeEnd "> | |||
| and `pay_time_end` = #{payTimeEnd} | |||
| </if> | |||
| <if test=" null != prepayId "> | |||
| and `prepay_d` like concat('%', #{prepayId},'%') | |||
| </if> | |||
| <if test=" null != transactionId "> | |||
| and `transaction_id` like concat('%', #{transactionId},'%') | |||
| </if> | |||
| <if test=" null != payVendor "> | |||
| and `pay_vendor` = #{payVendor} | |||
| </if> | |||
| <if test=" null != payBillNo "> | |||
| and `pay_bill_no` like concat('%', #{payBillNo},'%') | |||
| </if> | |||
| <if test=" null != payBillStatus "> | |||
| and `pay_bill_status` = #{payBillStatus} | |||
| </if> | |||
| <if test=" null != share "> | |||
| and `share` = #{share} | |||
| </if> | |||
| <if test=" null != shareAmount "> | |||
| and `share_amount` = #{shareAmount} | |||
| </if> | |||
| <if test=" null != failReason "> | |||
| and `fail_reason` like concat('%', #{failReason},'%') | |||
| </if> | |||
| <if test=" null != openId "> | |||
| and `open_id` = #{openId} | |||
| </if> | |||
| <if test=" null != ids "> | |||
| and id in | |||
| <foreach collection="ids" index="index" item="idItem" open="(" separator="," close=")"> | |||
| #{idItem} | |||
| </foreach> | |||
| </if> | |||
| <if test=" null != sortColumns">order by ${sortColumns}</if> | |||
| </sql> | |||
| <select id="findList" parameterType="com.iformall.domain.po.WxPayBill" resultMap="BaseResultMap"> | |||
| select | |||
| <include refid="allColumns"/> | |||
| from wx_pay_bill | |||
| <include refid="dynamicWhereConditions"/> | |||
| </select> | |||
| </mapper> | |||