You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
			
				
					530 lines
				
				21 KiB
			
		
		
			
		
	
	
					530 lines
				
				21 KiB
			| 
								 
											2 years ago
										 
									 | 
							
								package com.ynxbd.common.service;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								import com.alibaba.fastjson.JSONObject;
							 | 
						||
| 
								 | 
							
								import com.ynxbd.ali.helper.AliHelper;
							 | 
						||
| 
								 | 
							
								import com.ynxbd.bcm.config.BCMHelper;
							 | 
						||
| 
								 | 
							
								import com.ynxbd.common.action.pay.PEnum;
							 | 
						||
| 
								 | 
							
								import com.ynxbd.common.bean.enums.MerchantEnum;
							 | 
						||
| 
								 | 
							
								import com.ynxbd.common.bean.pay.*;
							 | 
						||
| 
								 | 
							
								import com.ynxbd.common.dao.*;
							 | 
						||
| 
								 | 
							
								import com.ynxbd.common.dao.his.HisAccountDao;
							 | 
						||
| 
								 | 
							
								import com.ynxbd.common.helper.common.CopyHelper;
							 | 
						||
| 
								 | 
							
								import com.ynxbd.common.helper.common.DateHelper;
							 | 
						||
| 
								 | 
							
								import com.ynxbd.common.result.JsonResult;
							 | 
						||
| 
								 | 
							
								import com.ynxbd.common.result.Result;
							 | 
						||
| 
								 | 
							
								import com.ynxbd.common.result.ResultEnum;
							 | 
						||
| 
								 | 
							
								import com.ynxbd.common.result.ServiceException;
							 | 
						||
| 
								 | 
							
								import com.ynxbd.common.service.cache.PayCache;
							 | 
						||
| 
								 | 
							
								import com.ynxbd.wx.wxfactory.WxMedicalHelper;
							 | 
						||
| 
								 | 
							
								import com.ynxbd.wx.wxfactory.WxPayHelper;
							 | 
						||
| 
								 | 
							
								import lombok.extern.slf4j.Slf4j;
							 | 
						||
| 
								 | 
							
								import org.apache.commons.lang3.ObjectUtils;
							 | 
						||
| 
								 | 
							
								import org.apache.commons.lang3.StringUtils;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								import java.math.BigDecimal;
							 | 
						||
| 
								 | 
							
								import java.util.Date;
							 | 
						||
| 
								 | 
							
								import java.util.List;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@Slf4j
							 | 
						||
| 
								 | 
							
								public class PayService {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    public static class Common {
							 | 
						||
| 
								 | 
							
								        public interface RefundMethod {
							 | 
						||
| 
								 | 
							
								            boolean update();
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        public interface UpdateHisStatus {
							 | 
						||
| 
								 | 
							
								            boolean update();
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    public static Result isNoPay() {
							 | 
						||
| 
								 | 
							
								        if (DateHelper.inTimeRangeH_m_s("23:55:00", "23:59:59") || DateHelper.inTimeRangeH_m_s("00:00:00", "00:00:30")) {
							 | 
						||
| 
								 | 
							
								            return Result.error(ResultEnum.SYSTEM_IS_BILLING);
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        return null;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /**
							 | 
						||
| 
								 | 
							
								     * 手动退费
							 | 
						||
| 
								 | 
							
								     *
							 | 
						||
| 
								 | 
							
								     * @param verifyDate  比对时间
							 | 
						||
| 
								 | 
							
								     * @param orderInfo   支付信息
							 | 
						||
| 
								 | 
							
								     * @param refundUser  退款人
							 | 
						||
| 
								 | 
							
								     * @param refundDesc  退款描述
							 | 
						||
| 
								 | 
							
								     * @param refundTable 退款类型
							 | 
						||
| 
								 | 
							
								     * @return 退费信息
							 | 
						||
| 
								 | 
							
								     */
							 | 
						||
| 
								 | 
							
								    public static Order handRefund(Date verifyDate, Date updateTime, Order orderInfo, BigDecimal totalFee, String refundUser, String refundDesc, String refundTable, Integer size, String sys, Common.RefundMethod refundMethod) throws ServiceException {
							 | 
						||
| 
								 | 
							
								        String tradeNo = orderInfo.getTradeNo();
							 | 
						||
| 
								 | 
							
								        String outTradeNo = orderInfo.getOutTradeNo();
							 | 
						||
| 
								 | 
							
								        if (ObjectUtils.isEmpty(outTradeNo)) {
							 | 
						||
| 
								 | 
							
								            log.info("[手动退费]参数缺失 sys=[{}] outTradeNo={}, tradeNo={}", sys, outTradeNo, tradeNo);
							 | 
						||
| 
								 | 
							
								            throw new ServiceException(ResultEnum.PARAM_IS_DEFECT);
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        BigDecimal refundFee = orderInfo.getPayMoney();
							 | 
						||
| 
								 | 
							
								        if (refundFee == null || refundFee.compareTo(BigDecimal.ZERO) == 0) {
							 | 
						||
| 
								 | 
							
								            log.info("[手动退费]退款金额错误禁止退费 sys=[{}] outTradeNo={}, tradeNo={}", sys, outTradeNo, tradeNo);
							 | 
						||
| 
								 | 
							
								            throw new ServiceException("退款金额错误禁止退费");
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        // 支付类型判断
							 | 
						||
| 
								 | 
							
								        MerchantEnum merchantEnum = MerchantEnum.getMerchantEnumByOutTradeNo(outTradeNo);
							 | 
						||
| 
								 | 
							
								        if (merchantEnum == null) {
							 | 
						||
| 
								 | 
							
								            throw new ServiceException(ResultEnum.PAY_TYPE_ERROR);
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if (MerchantEnum.ALI.equals(merchantEnum) && size != 1) {
							 | 
						||
| 
								 | 
							
								            throw new ServiceException(String.format("[支付宝]缴费单数量为[%s],不为1禁止退费,请联系开发商", size));
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if (updateTime == null) {
							 | 
						||
| 
								 | 
							
								            throw new ServiceException(ResultEnum.PARAM_IS_BLANK);
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        long time = (new Date().getTime() - updateTime.getTime());
							 | 
						||
| 
								 | 
							
								        int ruleTime = 45 * 60 * 1000; // 45
							 | 
						||
| 
								 | 
							
								        if (time < ruleTime) {
							 | 
						||
| 
								 | 
							
								            throw new ServiceException("45分钟内禁止退费,剩余时间:" + DateHelper.getMillisecondToMinute(ruleTime - time));
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        RefundDao refundDao = new RefundDao();
							 | 
						||
| 
								 | 
							
								        String refundResult = orderInfo.getRefundResult();
							 | 
						||
| 
								 | 
							
								        if ("OK".equals(refundResult)) {
							 | 
						||
| 
								 | 
							
								            throw new ServiceException(ResultEnum.REFUND_STATUS_IS_CHANGED);
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        Order order = queryOrderByOutTradeNo(outTradeNo, null);
							 | 
						||
| 
								 | 
							
								        // 未找到订单信息-并且未出现退费情况
							 | 
						||
| 
								 | 
							
								        if (!order.isSuccess() && !order.isRefund()) {
							 | 
						||
| 
								 | 
							
								            throw new ServiceException(ResultEnum.PAY_ORDER_NOT_FOUND);
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if (MerchantEnum.WX.equals(merchantEnum)) {
							 | 
						||
| 
								 | 
							
								            if (order.isRefund()) { // 发生过退费(全额 | 部分)
							 | 
						||
| 
								 | 
							
								                Bill bill = null;
							 | 
						||
| 
								 | 
							
								                List<Bill> billList = WxPayHelper.queryRefundList(outTradeNo);
							 | 
						||
| 
								 | 
							
								                String bankTransNo = orderInfo.getBankTransNo();
							 | 
						||
| 
								 | 
							
								                String outRefundNo;
							 | 
						||
| 
								 | 
							
								                for (Bill item : billList) {
							 | 
						||
| 
								 | 
							
								                    outRefundNo = item.getOutRefundNo();
							 | 
						||
| 
								 | 
							
								                    if (outRefundNo.length() < 24) {
							 | 
						||
| 
								 | 
							
								                        throw new ServiceException(ResultEnum.REFUND_ORDER_IS_ERROR);
							 | 
						||
| 
								 | 
							
								                    }
							 | 
						||
| 
								 | 
							
								                    if (!bankTransNo.equals(outRefundNo.substring(0, outRefundNo.length() - 4))) {
							 | 
						||
| 
								 | 
							
								                        throw new ServiceException(ResultEnum.REFUND_MERCHANT_HAS_REFUND);
							 | 
						||
| 
								 | 
							
								                    }
							 | 
						||
| 
								 | 
							
								                    if (outRefundNo.equals(tradeNo)) {
							 | 
						||
| 
								 | 
							
								                        bill = item;
							 | 
						||
| 
								 | 
							
								                        break;
							 | 
						||
| 
								 | 
							
								                    }
							 | 
						||
| 
								 | 
							
								                }
							 | 
						||
| 
								 | 
							
								                if (bill != null) { // 已退费,但是状态不为OK
							 | 
						||
| 
								 | 
							
								                    orderInfo.setRefundResult("OK");
							 | 
						||
| 
								 | 
							
								                    if (!refundDao.hasRefund(outTradeNo, tradeNo)) { // 不存在
							 | 
						||
| 
								 | 
							
								                        orderInfo.setRefundUser(refundUser);
							 | 
						||
| 
								 | 
							
								                        orderInfo.setRefundTable(refundTable);
							 | 
						||
| 
								 | 
							
								                        if (!refundDao.insert(orderInfo, refundDesc, sys)) {
							 | 
						||
| 
								 | 
							
								                            log.info("{} [手动退费]退费信息存储失败 sys=[{}], {}", merchantEnum.NAME, sys, orderInfo);
							 | 
						||
| 
								 | 
							
								                        }
							 | 
						||
| 
								 | 
							
								                    }
							 | 
						||
| 
								 | 
							
								                    return orderInfo;
							 | 
						||
| 
								 | 
							
								                }
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        } else if (MerchantEnum.ALI.equals(merchantEnum)) { // 支付宝
							 | 
						||
| 
								 | 
							
								            if (order.isRefund()) { // 支付宝发生过退费(全额退费)
							 | 
						||
| 
								 | 
							
								                throw new ServiceException(ResultEnum.REFUND_STATUS_IS_CHANGED);
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        } else {
							 | 
						||
| 
								 | 
							
								            throw new ServiceException(ResultEnum.PAY_TYPE_ERROR);
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        String begDate = DateHelper.getMoveDate(verifyDate, -6);
							 | 
						||
| 
								 | 
							
								        String endDate = DateHelper.getMoveDate(verifyDate, 6);
							 | 
						||
| 
								 | 
							
								        if (begDate == null || endDate == null) {
							 | 
						||
| 
								 | 
							
								            log.info("[手动退费]日期转换失败 begDate={}, endDate={}, outTradeNo={}, tradeNo={}", begDate, endDate, outTradeNo, tradeNo);
							 | 
						||
| 
								 | 
							
								            throw new ServiceException(ResultEnum.DATE_FORMAT_ERROR);
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        JsonResult jsonResult = new HisAccountDao().getTransaction(begDate, endDate, tradeNo, 0, 0);
							 | 
						||
| 
								 | 
							
								        if (jsonResult.isTimeout()) { // 调用超时或异常
							 | 
						||
| 
								 | 
							
								            throw new ServiceException(jsonResult.getMessage());
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if (jsonResult.success()) { // 查询到费用明细-->已计费成功
							 | 
						||
| 
								 | 
							
								            log.info("[手动退费]His已记账禁止退费 sys=[{}], outTradeNo={}, tradeNo={}", sys, outTradeNo, tradeNo);
							 | 
						||
| 
								 | 
							
								            throw new ServiceException("His已记账禁止退费");
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if (ObjectUtils.isEmpty(refundResult)) {
							 | 
						||
| 
								 | 
							
								            if (!refundMethod.update()) { // 已发起退款
							 | 
						||
| 
								 | 
							
								                throw new ServiceException(ResultEnum.REFUND_STATUS_IS_CHANGED);
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        PayCache.removeRecipe(tradeNo);
							 | 
						||
| 
								 | 
							
								        Order refundInfo = refund(merchantEnum, outTradeNo, tradeNo, refundFee, totalFee, refundDesc, orderInfo.getUpdateTime(), orderInfo.getOpenid(), orderInfo.getPatientId(), null);
							 | 
						||
| 
								 | 
							
								        if (!refundInfo.isSuccess()) { // 退款失败
							 | 
						||
| 
								 | 
							
								            throw new ServiceException(refundInfo.getErrorMsg());
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        orderInfo.setRefundUser(refundUser);
							 | 
						||
| 
								 | 
							
								        orderInfo.setRefundTable(refundTable);
							 | 
						||
| 
								 | 
							
								        orderInfo.setRefundResult(refundInfo.getRefundResult());
							 | 
						||
| 
								 | 
							
								        if (!refundDao.insert(orderInfo, refundDesc, sys)) {
							 | 
						||
| 
								 | 
							
								            log.info("{} [手动退费]退费信息存储失败  sys=[{}] {}", merchantEnum.NAME, sys, orderInfo);
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        return refundInfo;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /**
							 | 
						||
| 
								 | 
							
								     * 退费封装
							 | 
						||
| 
								 | 
							
								     *
							 | 
						||
| 
								 | 
							
								     * @param merchantEnum 支付方式
							 | 
						||
| 
								 | 
							
								     * @param outTradeNo   订单号
							 | 
						||
| 
								 | 
							
								     * @param refundMoney  退费金额
							 | 
						||
| 
								 | 
							
								     * @param totalFee     【微信】 退费总金额
							 | 
						||
| 
								 | 
							
								     * @param refundDesc   【微信】 退费描述
							 | 
						||
| 
								 | 
							
								     * @param openid       【微信】 推送者openid
							 | 
						||
| 
								 | 
							
								     * @param patientId    【微信】 推送者患者id
							 | 
						||
| 
								 | 
							
								     * @param pushInfo     【微信】 推送内容(为空不推送)
							 | 
						||
| 
								 | 
							
								     * @return 退费信息
							 | 
						||
| 
								 | 
							
								     */
							 | 
						||
| 
								 | 
							
								    public static Order refund(MerchantEnum merchantEnum, String outTradeNo, String outRefundNo, BigDecimal refundMoney, BigDecimal totalFee, String refundDesc, Date tradeDate, String openid, String patientId, String pushInfo) {
							 | 
						||
| 
								 | 
							
								        Order order = new Order();
							 | 
						||
| 
								 | 
							
								        if (merchantEnum == null || StringUtils.isEmpty(outTradeNo) || refundMoney == null) {
							 | 
						||
| 
								 | 
							
								            return order;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        switch (merchantEnum) {
							 | 
						||
| 
								 | 
							
								            case WX:
							 | 
						||
| 
								 | 
							
								                order = WxPayHelper.refund(outTradeNo, outRefundNo, refundMoney, totalFee, refundDesc);
							 | 
						||
| 
								 | 
							
								                break;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            case ALI:
							 | 
						||
| 
								 | 
							
								                order = AliHelper.refund(outTradeNo, outRefundNo, refundMoney, refundDesc);
							 | 
						||
| 
								 | 
							
								                break;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            case BCM:
							 | 
						||
| 
								 | 
							
								                log.info("【交行退款】outTradeNo={}, tradeDate={}", outTradeNo, tradeDate);
							 | 
						||
| 
								 | 
							
								                String tradeDateStr = DateHelper.dateToStr(tradeDate, DateHelper.DateEnum.yyyyMMdd);
							 | 
						||
| 
								 | 
							
								                if (tradeDateStr == null) {
							 | 
						||
| 
								 | 
							
								                    order.setErrorMsg("退款日期错误");
							 | 
						||
| 
								 | 
							
								                    return order;
							 | 
						||
| 
								 | 
							
								                }
							 | 
						||
| 
								 | 
							
								                order = BCMHelper.refund(outTradeNo, outRefundNo, tradeDateStr, refundMoney, refundDesc);
							 | 
						||
| 
								 | 
							
								                break;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            default:
							 | 
						||
| 
								 | 
							
								                break;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        return order;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /**
							 | 
						||
| 
								 | 
							
								     * 查询订单信息
							 | 
						||
| 
								 | 
							
								     */
							 | 
						||
| 
								 | 
							
								    public static Order queryOrderByOutTradeNo(String outTradeNo, String payWay) {
							 | 
						||
| 
								 | 
							
								        Order order = new Order();
							 | 
						||
| 
								 | 
							
								        if (outTradeNo == null) {
							 | 
						||
| 
								 | 
							
								            order.setErrorMsg("订单号为空");
							 | 
						||
| 
								 | 
							
								            return order;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        MerchantEnum merchantEnum = MerchantEnum.getMerchantEnumByOutTradeNo(outTradeNo);
							 | 
						||
| 
								 | 
							
								        if (merchantEnum == null) {
							 | 
						||
| 
								 | 
							
								            merchantEnum = MerchantEnum.getMerchantEnumByPayWay(payWay);
							 | 
						||
| 
								 | 
							
								            if (merchantEnum == null) {
							 | 
						||
| 
								 | 
							
								                order.setErrorMsg("支付方式不存在");
							 | 
						||
| 
								 | 
							
								                return order;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if (MerchantEnum.WX.equals(merchantEnum)) {
							 | 
						||
| 
								 | 
							
								            return WxPayHelper.queryOrder(outTradeNo);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        } else if (MerchantEnum.ALI.equals(merchantEnum)) {
							 | 
						||
| 
								 | 
							
								            return AliHelper.queryTransaction(outTradeNo);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        } else if (MerchantEnum.BCM.equals(merchantEnum)) {
							 | 
						||
| 
								 | 
							
								            return BCMHelper.queryOrder(outTradeNo);
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        order.setErrorMsg("支付方式不存在");
							 | 
						||
| 
								 | 
							
								        return order;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /**
							 | 
						||
| 
								 | 
							
								     * [扫码支付]
							 | 
						||
| 
								 | 
							
								     *
							 | 
						||
| 
								 | 
							
								     * @param authCode 编码
							 | 
						||
| 
								 | 
							
								     * @return 支付类型
							 | 
						||
| 
								 | 
							
								     */
							 | 
						||
| 
								 | 
							
								    public static Order payMicro(MerchantEnum merchantEnum, String outTradeNo, String title, BigDecimal totalFee, String authCode, String ip) {
							 | 
						||
| 
								 | 
							
								        Order order = new Order();
							 | 
						||
| 
								 | 
							
								        if (totalFee == null || merchantEnum == null || StringUtils.isEmpty(authCode)) {
							 | 
						||
| 
								 | 
							
								            order.setOutTradeNo(outTradeNo);
							 | 
						||
| 
								 | 
							
								            order.setErrorMsg("参数缺失");
							 | 
						||
| 
								 | 
							
								            return order;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if (merchantEnum.equals(MerchantEnum.WX)) {
							 | 
						||
| 
								 | 
							
								            order = WxPayHelper.payMicro(title, outTradeNo, totalFee, authCode, ip);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        } else if (merchantEnum.equals(MerchantEnum.ALI)) {
							 | 
						||
| 
								 | 
							
								            order = AliHelper.payMicro(title, outTradeNo, totalFee.toString(), authCode);
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        order.setOutTradeNo(outTradeNo);
							 | 
						||
| 
								 | 
							
								        return order;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /**
							 | 
						||
| 
								 | 
							
								     * [订单信息]存储
							 | 
						||
| 
								 | 
							
								     *
							 | 
						||
| 
								 | 
							
								     * @param pEnum 支付类型
							 | 
						||
| 
								 | 
							
								     * @return 是否成功
							 | 
						||
| 
								 | 
							
								     */
							 | 
						||
| 
								 | 
							
								    public static boolean saveOrderNo(PEnum pEnum, String outTradeNo, String openid, String info, String authCode) {
							 | 
						||
| 
								 | 
							
								        return new PayResultDao().insert(pEnum.CODE, outTradeNo, openid, info, authCode);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /**
							 | 
						||
| 
								 | 
							
								     * [订单信息]查询用户订单
							 | 
						||
| 
								 | 
							
								     *
							 | 
						||
| 
								 | 
							
								     * @return 是否存在
							 | 
						||
| 
								 | 
							
								     */
							 | 
						||
| 
								 | 
							
								    public static boolean hasUserOrderNo(String outTradeNo, String openid) {
							 | 
						||
| 
								 | 
							
								        return new PayResultDao().queryOrderByOutTradeNoAndOpenid(outTradeNo, openid);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    public static Order saveMicroOrderNo(PEnum pEnum, MerchantEnum merchantEnum, String outTradeNo, String authCode, String treatNum, String patientId, String operateUser, String invoiceTransNo, BigDecimal totalFee, String regDate) {
							 | 
						||
| 
								 | 
							
								        Order order = new Order();
							 | 
						||
| 
								 | 
							
								        PayResult payResult = new PayResultDao().queryOrderByAuthCode(authCode);
							 | 
						||
| 
								 | 
							
								        if (payResult != null) {
							 | 
						||
| 
								 | 
							
								            order.setErrorMsg("付款码已使用过,请刷新重试");
							 | 
						||
| 
								 | 
							
								            return order;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        String openid = "0";
							 | 
						||
| 
								 | 
							
								        if (!saveOrderNo(pEnum, outTradeNo, openid, null, authCode)) {
							 | 
						||
| 
								 | 
							
								            order.setErrorMsg("订单号信息预存失败");
							 | 
						||
| 
								 | 
							
								            return order;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        order.setOutTradeNo(outTradeNo);
							 | 
						||
| 
								 | 
							
								        order.setAuthCode(authCode);
							 | 
						||
| 
								 | 
							
								        order.setTotalFee(totalFee);
							 | 
						||
| 
								 | 
							
								        order.setPayMoney(totalFee);
							 | 
						||
| 
								 | 
							
								        order.setTreatNum(treatNum);
							 | 
						||
| 
								 | 
							
								        order.setPatientId(patientId);
							 | 
						||
| 
								 | 
							
								        order.setOperateUser(operateUser);
							 | 
						||
| 
								 | 
							
								        order.setInvoiceTransNo(invoiceTransNo);
							 | 
						||
| 
								 | 
							
								        order.setPayWay(merchantEnum.PAY_WAY_MICRO);
							 | 
						||
| 
								 | 
							
								        order.setPayStatus(-1);
							 | 
						||
| 
								 | 
							
								        order.setHisStatus(0);
							 | 
						||
| 
								 | 
							
								        order.setOpenid(openid);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        boolean isResult = false;
							 | 
						||
| 
								 | 
							
								        switch (pEnum) {
							 | 
						||
| 
								 | 
							
								            case RECIPE: // 处方
							 | 
						||
| 
								 | 
							
								                Recipe recipe = CopyHelper.fatherToChild(order, Recipe.class);
							 | 
						||
| 
								 | 
							
								                if (recipe == null) {
							 | 
						||
| 
								 | 
							
								                    order.setErrorMsg("[处方]赋值失败");
							 | 
						||
| 
								 | 
							
								                    return order;
							 | 
						||
| 
								 | 
							
								                }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								                isResult = new RecipeDao().insert(recipe);
							 | 
						||
| 
								 | 
							
								                break;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            case REG: // 挂号
							 | 
						||
| 
								 | 
							
								                Register register = CopyHelper.fatherToChild(order, Register.class);
							 | 
						||
| 
								 | 
							
								                if (register == null) {
							 | 
						||
| 
								 | 
							
								                    order.setErrorMsg("[挂号]赋值失败");
							 | 
						||
| 
								 | 
							
								                    return order;
							 | 
						||
| 
								 | 
							
								                }
							 | 
						||
| 
								 | 
							
								                register.setRegDate(regDate);
							 | 
						||
| 
								 | 
							
								                register.setRegType(DateHelper.isToday(regDate) ? "2" : "1");
							 | 
						||
| 
								 | 
							
								                isResult = new RegisterDao().insert(register);
							 | 
						||
| 
								 | 
							
								                break;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            case IN_HOSP: // 住院
							 | 
						||
| 
								 | 
							
								                PayInHosp payInHosp = CopyHelper.fatherToChild(order, PayInHosp.class);
							 | 
						||
| 
								 | 
							
								                if (payInHosp == null) {
							 | 
						||
| 
								 | 
							
								                    order.setErrorMsg("[住院]赋值失败");
							 | 
						||
| 
								 | 
							
								                    return order;
							 | 
						||
| 
								 | 
							
								                }
							 | 
						||
| 
								 | 
							
								                isResult = new InHospPayDao().insert(payInHosp);
							 | 
						||
| 
								 | 
							
								                break;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            default:
							 | 
						||
| 
								 | 
							
								                order.setErrorMsg("调用码无效");
							 | 
						||
| 
								 | 
							
								                break;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        if (!isResult) {
							 | 
						||
| 
								 | 
							
								            order.setErrorMsg("订单信息预存失败");
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        order.setSuccess(isResult);
							 | 
						||
| 
								 | 
							
								        return order;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								//    /**
							 | 
						||
| 
								 | 
							
								//     * [盒子支付]信息存储
							 | 
						||
| 
								 | 
							
								//     *
							 | 
						||
| 
								 | 
							
								//     * @param pEnum 支付类型
							 | 
						||
| 
								 | 
							
								//     * @return 是否成功
							 | 
						||
| 
								 | 
							
								//     */
							 | 
						||
| 
								 | 
							
								//    public static Order savePayMicro(PEnum pEnum, String outTradeNo, String bankTransNo, String openid) {
							 | 
						||
| 
								 | 
							
								//        Order orderResult = new Order();
							 | 
						||
| 
								 | 
							
								//        boolean isResult = false;
							 | 
						||
| 
								 | 
							
								//        order.setHisStatus(order.isSuccess() ? 0 : -1);
							 | 
						||
| 
								 | 
							
								//        order.setPayStatus(order.isSuccess() ? 0 : -1);
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								//        order.setPayMoney(order.getTotalFee());
							 | 
						||
| 
								 | 
							
								//        switch (pEnum) {
							 | 
						||
| 
								 | 
							
								//            case RECIPE: // 处方
							 | 
						||
| 
								 | 
							
								//                Recipe recipe = CopyHelper.fatherToChild(order, Recipe.class);
							 | 
						||
| 
								 | 
							
								//                if (recipe == null) {
							 | 
						||
| 
								 | 
							
								//                    order.setErrorMsg("[处方]赋值失败");
							 | 
						||
| 
								 | 
							
								//                    return order;
							 | 
						||
| 
								 | 
							
								//                }
							 | 
						||
| 
								 | 
							
								//                isResult = new RecipeDao().insert(recipe);
							 | 
						||
| 
								 | 
							
								//                break;
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								//            case REG: // 挂号
							 | 
						||
| 
								 | 
							
								//                Register register = CopyHelper.fatherToChild(order, Register.class);
							 | 
						||
| 
								 | 
							
								//                if (register == null) {
							 | 
						||
| 
								 | 
							
								//                    order.setErrorMsg("[挂号]赋值失败");
							 | 
						||
| 
								 | 
							
								//                    return order;
							 | 
						||
| 
								 | 
							
								//                }
							 | 
						||
| 
								 | 
							
								//                register.setRegDate(regDate);
							 | 
						||
| 
								 | 
							
								//                register.setRegType(DateHelper.isToday(regDate) ? "2" : "1");
							 | 
						||
| 
								 | 
							
								//                register.setRegDate(regDate);
							 | 
						||
| 
								 | 
							
								//                isResult = new RegisterDao().insert(register);
							 | 
						||
| 
								 | 
							
								//                break;
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								//            case IN_HOSP: // 住院
							 | 
						||
| 
								 | 
							
								//                PayInHosp payInHosp = CopyHelper.fatherToChild(order, PayInHosp.class);
							 | 
						||
| 
								 | 
							
								//                if (payInHosp == null) {
							 | 
						||
| 
								 | 
							
								//                    order.setErrorMsg("[住院]赋值失败");
							 | 
						||
| 
								 | 
							
								//                    return order;
							 | 
						||
| 
								 | 
							
								//                }
							 | 
						||
| 
								 | 
							
								//                isResult = new InHospPayDao().insert(payInHosp);
							 | 
						||
| 
								 | 
							
								//                break;
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								//            default:
							 | 
						||
| 
								 | 
							
								//                orderResult.setErrorMsg("调用码无效");
							 | 
						||
| 
								 | 
							
								//                break;
							 | 
						||
| 
								 | 
							
								//        }
							 | 
						||
| 
								 | 
							
								//        orderResult.setSuccess(isResult);
							 | 
						||
| 
								 | 
							
								//        return orderResult;
							 | 
						||
| 
								 | 
							
								//    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								//    /**
							 | 
						||
| 
								 | 
							
								//     * 判断是否为新版订单号
							 | 
						||
| 
								 | 
							
								//     *
							 | 
						||
| 
								 | 
							
								//     * @param bankTransNo 商户交易流水号
							 | 
						||
| 
								 | 
							
								//     * @param tradeNo     HIS订单号
							 | 
						||
| 
								 | 
							
								//     * @return 是否为新版订单号
							 | 
						||
| 
								 | 
							
								//     * @throws ServiceException 业务异常
							 | 
						||
| 
								 | 
							
								//     */
							 | 
						||
| 
								 | 
							
								//    public static boolean isNewOrder(String bankTransNo, String tradeNo) throws ServiceException {
							 | 
						||
| 
								 | 
							
								//        if (ObjectUtils.isEmpty(bankTransNo) || ObjectUtils.isEmpty(tradeNo)) {
							 | 
						||
| 
								 | 
							
								//            throw new ServiceException(ResultEnum.REFUND_ORDER_IS_ERROR);
							 | 
						||
| 
								 | 
							
								//        }
							 | 
						||
| 
								 | 
							
								//        int tradeNoLen = tradeNo.length();
							 | 
						||
| 
								 | 
							
								//        if (tradeNoLen < 24) {
							 | 
						||
| 
								 | 
							
								//            throw new ServiceException(ResultEnum.REFUND_ORDER_IS_ERROR);
							 | 
						||
| 
								 | 
							
								//        }
							 | 
						||
| 
								 | 
							
								//        if ((bankTransNo.length() + 4) != tradeNoLen) {
							 | 
						||
| 
								 | 
							
								//            throw new ServiceException(ResultEnum.REFUND_IS_OLD_ORDER_NUM);
							 | 
						||
| 
								 | 
							
								//        }
							 | 
						||
| 
								 | 
							
								//        return bankTransNo.equals(tradeNo.substring(0, tradeNoLen - 4));
							 | 
						||
| 
								 | 
							
								//    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /**
							 | 
						||
| 
								 | 
							
								     * 是否退费成功
							 | 
						||
| 
								 | 
							
								     */
							 | 
						||
| 
								 | 
							
								    public static Bill queryRefund(MerchantEnum merchantEnum, String outTradeNo, String bankTransNo, String outRefundNo) throws ServiceException {
							 | 
						||
| 
								 | 
							
								        if (MerchantEnum.WX.equals(merchantEnum)) {
							 | 
						||
| 
								 | 
							
								            return WxPayHelper.queryRefund(outTradeNo, outRefundNo);
							 | 
						||
| 
								 | 
							
								        } else if (MerchantEnum.ALI.equals(merchantEnum)) {
							 | 
						||
| 
								 | 
							
								            return AliHelper.queryRefund(outTradeNo, outRefundNo);
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        return null;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /**
							 | 
						||
| 
								 | 
							
								     * 创建订单
							 | 
						||
| 
								 | 
							
								     */
							 | 
						||
| 
								 | 
							
								    public static JSONObject createOrder(MerchantEnum merchantEnum, String openid, String patientId, String totalFee, String outTradeNo, String notifyType, String ip, String title) {
							 | 
						||
| 
								 | 
							
								        if (merchantEnum == null || ObjectUtils.isEmpty(notifyType)) {
							 | 
						||
| 
								 | 
							
								            return null;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if (MerchantEnum.WX.equals(merchantEnum)) { // 微信下单
							 | 
						||
| 
								 | 
							
								            return WxPayHelper.createOrder(merchantEnum, title, totalFee, outTradeNo, notifyType, ip, openid, patientId);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        } else if (MerchantEnum.ALI.equals(merchantEnum)) {  // 支付宝下单
							 | 
						||
| 
								 | 
							
								            return AliHelper.createOrder(merchantEnum, title, outTradeNo, totalFee, notifyType, openid);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        } else if (MerchantEnum.BCM.equals(merchantEnum)) {
							 | 
						||
| 
								 | 
							
								            return BCMHelper.createOrder(merchantEnum, title, outTradeNo, totalFee, notifyType);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        return null;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /**
							 | 
						||
| 
								 | 
							
								     * 医保跳转
							 | 
						||
| 
								 | 
							
								     */
							 | 
						||
| 
								 | 
							
								    public static JSONObject goMedical(MerchantEnum merchantEnum, PEnum pEnum) {
							 | 
						||
| 
								 | 
							
								        if (MerchantEnum.WX_MEDICAL.equals(merchantEnum)) { // 微信医保(获取授权链接)
							 | 
						||
| 
								 | 
							
								            return WxMedicalHelper.getMdAuthUrl("wx-medical.html", pEnum.CODE);
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        return null;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /**
							 | 
						||
| 
								 | 
							
								     * 修改[扫码盒子]订单状态
							 | 
						||
| 
								 | 
							
								     *
							 | 
						||
| 
								 | 
							
								     * @param pEnum       类型
							 | 
						||
| 
								 | 
							
								     * @param outTradeNo  订单号
							 | 
						||
| 
								 | 
							
								     * @param bankTransNo 流水号
							 | 
						||
| 
								 | 
							
								     * @param openid      openid
							 | 
						||
| 
								 | 
							
								     */
							 | 
						||
| 
								 | 
							
								    public static boolean updateMicroOrderState(PEnum pEnum, String outTradeNo, String bankTransNo, String openid) {
							 | 
						||
| 
								 | 
							
								        if (pEnum == null) {
							 | 
						||
| 
								 | 
							
								            PayResult order = new PayResultDao().queryOrderByOutTradeNo(outTradeNo);
							 | 
						||
| 
								 | 
							
								            if (order == null) {
							 | 
						||
| 
								 | 
							
								                return false;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								            pEnum = PEnum.toEnum(order.getOrderType());
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        switch (pEnum) {
							 | 
						||
| 
								 | 
							
								            case RECIPE: // 处方
							 | 
						||
| 
								 | 
							
								                return new RecipeService().updateMicroOrderState(outTradeNo, bankTransNo, openid);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            case REG: // 挂号
							 | 
						||
| 
								 | 
							
								                return new RegService().updateMicroOrderState(outTradeNo, bankTransNo, openid);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            case IN_HOSP: // 住院预交金
							 | 
						||
| 
								 | 
							
								                return new InHospService().updateMicroOrderState(outTradeNo, bankTransNo, openid);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            default:
							 | 
						||
| 
								 | 
							
								                log.info("类型未匹配");
							 | 
						||
| 
								 | 
							
								                return false;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								}
							 |