123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350 |
- package thyyxxk.wxservice_server.service;
- import com.alibaba.fastjson.JSONObject;
- import com.wechat.pay.java.core.util.GsonUtil;
- import com.wechat.pay.java.service.payments.jsapi.model.*;
- import com.wechat.pay.java.service.payments.model.Transaction;
- import lombok.extern.slf4j.Slf4j;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.stereotype.Service;
- import thyyxxk.wxservice_server.config.exception.ExceptionEnum;
- import thyyxxk.wxservice_server.constant.OrderType;
- import thyyxxk.wxservice_server.constant.medins.Insutype;
- import thyyxxk.wxservice_server.constant.medins.MedType;
- import thyyxxk.wxservice_server.dao.WxApiDao;
- import thyyxxk.wxservice_server.entity.ResultVo;
- import thyyxxk.wxservice_server.entity.appointment.DoctorInfo;
- import thyyxxk.wxservice_server.entity.paymzfee.MedinsPresettle;
- import thyyxxk.wxservice_server.entity.wxapi.JsApiSHA1;
- import thyyxxk.wxservice_server.entity.wxapi.GenMzPayQrcodeParam;
- import thyyxxk.wxservice_server.entity.wxapi.WxPayOrder;
- import thyyxxk.wxservice_server.entity.wxapi.WxPyQrcdPrm;
- import thyyxxk.wxservice_server.factory.wechatpay.WeChatPayService;
- import thyyxxk.wxservice_server.factory.wechatpay.model.NativePayResponse;
- import thyyxxk.wxservice_server.factory.wechatpay.model.WechatPayGlobalRequest;
- import thyyxxk.wxservice_server.utils.*;
- import java.math.BigDecimal;
- import java.util.*;
- import java.util.concurrent.TimeUnit;
- /**
- * @author dj
- */
- @Slf4j
- @Service
- public class WxApiService {
- private final WxApiDao dao;
- private final SavePayResultService savePayResultService;
- @Autowired
- public WxApiService(WxApiDao dao, SavePayResultService savePayResultService) {
- this.dao = dao;
- this.savePayResultService = savePayResultService;
- }
- public ResultVo<JsApiSHA1> getJsapiSHA1Sign(JsApiSHA1 data) throws Exception {
- data.setAppId(PropertiesUtil.getLocalProperty("appId"));
- data.setTicket(PropertiesUtil.getLocalProperty("ticket"));
- data.setNoncestr(SnowFlakeId.instance().nextId());
- data.setTimestamp(String.valueOf(System.currentTimeMillis() / 1000));
- String toSign = "jsapi_ticket=" + data.getTicket() + "&noncestr=" + data.getNoncestr() +
- "×tamp=" + data.getTimestamp() + "&url=" + data.getUrl();
- data.setSignature(WxPaySignUtil.sha1Encode(toSign));
- log.info("获取wxJsApi签名:{}", data);
- return ResultVoUtil.success(data);
- }
- public ResultVo<WxPayOrder> createPayOrder(WxPayOrder order) {
- WxPayOrder existOrder = getExistOrder(order);
- if (null != existOrder) {
- if (existOrder.getTradeState() == Transaction.TradeStateEnum.SUCCESS) {
- return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR,
- "您已支付过一笔相同金额的订单,请勿重复支付。");
- }
- if (StringUtil.notBlank(existOrder.getPrepayId()) &&
- existOrder.getTradeState() == Transaction.TradeStateEnum.NOTPAY &&
- DateUtil.orderValid(existOrder.getCreateDatetime())) {
- return ResultVoUtil.success(existOrder);
- }
- if (null == order.getYjReqNo()) {
- order.setYjReqNo(existOrder.getYjReqNo());
- }
- }
- int payAmt = DecimalTool.moneyYuanToFen(order.getCashpayAmt());
- order.setOpenid(TokenUtil.getInstance().getUserOpenid());
- order.setTradeNo(SnowFlakeId.instance().nextId());
- order.setMchId(PropertiesUtil.getLocalProperty("mchId"));
- if (payAmt == 0) {
- order.setPrepayId("PREPARED");
- order.setTimeStamp(String.valueOf(System.currentTimeMillis()));
- order.setSerialNo(SnowFlakeId.instance().nextId());
- } else {
- WechatPayGlobalRequest request = new WechatPayGlobalRequest.Builder()
- .openid(order.getOpenid()).description(order.getBody())
- .outTradeNo(order.getTradeNo()).totalAmount(payAmt).build();
- PrepayWithRequestPaymentResponse response = new WeChatPayService().jsApiPrepay(request);
- order.setAppId(response.getAppId());
- order.setPrepayId(response.getPackageVal());
- order.setTimeStamp(response.getTimeStamp());
- order.setSerialNo(response.getNonceStr());
- order.setSignType(response.getSignType());
- order.setPaySign(response.getPaySign());
- }
- if (null == order.getFundpayAmt()) {
- order.setFundpayAmt(BigDecimal.ZERO);
- }
- if (null == order.getAcctpayAmt()) {
- order.setAcctpayAmt(BigDecimal.ZERO);
- }
- if (null == order.getCouponAmt()) {
- order.setCouponAmt(BigDecimal.ZERO);
- }
- BigDecimal discount = order.getFundpayAmt().add(order.getAcctpayAmt())
- .add(order.getCouponAmt());
- BigDecimal cashpayAmt = order.getTotalFee().subtract(discount);
- if (cashpayAmt.compareTo(BigDecimal.ZERO) < 0) {
- cashpayAmt = BigDecimal.ZERO;
- }
- order.setCashpayAmt(cashpayAmt);
- order.setPatientName(dao.selectPatientName(order.getPatientId()));
- order.setCreateDatetime(new Date());
- order.setTradeState(Transaction.TradeStateEnum.NOTPAY);
- dao.insertNewOrder(order);
- return ResultVoUtil.success(order);
- }
- private WxPayOrder getExistOrder(WxPayOrder order) {
- if (order.getOrderType() == OrderType.CLINIC_REGISTER.getCode() ||
- order.getOrderType() == OrderType.REGISTRATION.getCode()) {
- return dao.selectSameGhOrder(order.getPatientId(), order.getMzyRequestId(),
- order.getCashpayAmt());
- } else if (order.getOrderType() == OrderType.OUTPATIENT.getCode()) {
- return dao.selectSameMzPayOrder(order.getHisOrdNum(), order.getCashpayAmt());
- }
- return null;
- }
- public ResultVo<JSONObject> queryOrderStateOnly(String tradeNo) {
- WechatPayGlobalRequest request = new WechatPayGlobalRequest.Builder()
- .outTradeNo(tradeNo).build();
- Transaction transaction = new WeChatPayService().queryOrderState(request);
- JSONObject response = JSONObject.parseObject(GsonUtil.toJson(transaction));
- return ResultVoUtil.success(response);
- }
- public String queryOrderState(String tradeNo) {
- try {
- while (TradeVectorUtil.tradeNoBeingQuery(tradeNo) || TradeVectorUtil.tradeNoBeingRefund(tradeNo)) {
- log.info("订单号:{} 正在查询状态中,进入等待区。", tradeNo);
- TimeUnit.SECONDS.sleep(3);
- }
- TradeVectorUtil.addBeingQuery(tradeNo);
- WxPayOrder order = dao.selectOrderByTradeNo(tradeNo);
- OrderType orderType = OrderType.get(order.getOrderType());
- int hasSaved = 0;
- if (orderType == OrderType.REGISTRATION || orderType == OrderType.CLINIC_REGISTER) {
- hasSaved = dao.alreadyPaidRegisterFee(order.getTradeNo());
- } else if (orderType == OrderType.OUTPATIENT) {
- hasSaved = dao.alreadyPayed(order.getTradeNo());
- }
- if (hasSaved == 1) {
- dao.updateSuccessHisStatus(tradeNo);
- if (orderType == OrderType.REGISTRATION) {
- log.info("订单号:{} 的挂号信息已保存,无需再次查询订单状态。", order.getTradeNo());
- return DateUtil.formatDatetime(order.getPayDatetime());
- }
- log.info("订单号:{} 的门诊缴费信息已保存,无需再次查询订单状态。", order.getTradeNo());
- return DateUtil.formatDatetime(order.getPayDatetime());
- }
- Transaction transaction;
- if (order.getCashpayAmt().compareTo(BigDecimal.ZERO) == 0) {
- transaction = new Transaction();
- transaction.setTradeState(Transaction.TradeStateEnum.SUCCESS);
- transaction.setSuccessTime(DateUtil.formatDatetime(new Date()));
- } else {
- WechatPayGlobalRequest request = new WechatPayGlobalRequest.Builder()
- .outTradeNo(tradeNo).build();
- transaction = new WeChatPayService().queryOrderState(request);
- }
- Transaction.TradeStateEnum tradeState = transaction.getTradeState();
- if (tradeState == Transaction.TradeStateEnum.SUCCESS) {
- String successTime = transaction.getSuccessTime()
- .split("\\+")[0].replace("T", " ");
- dao.updatePayStatusAndPayTime(tradeNo, tradeState, successTime);
- switch (orderType) {
- case CLINIC_REGISTER:
- return savePayResultService.saveClinicRegister(order, successTime);
- case REGISTRATION:
- return savePayResultService.saveAppointment(order, successTime);
- case OUTPATIENT:
- return savePayResultService.saveMzChargeInfo(order, successTime);
- case INPATIENT_PRE_PAY:
- return savePayResultService.saveZyYjjInfo(order, successTime);
- case SELF_HELP_MACHINE:
- case INSPECTIONS:
- return "订单已支付。";
- default:
- return "ERROR:未识别到的订单类型,请联系服务中心。";
- }
- }
- dao.updatePayStatusAndQueryTimes(tradeNo, tradeState);
- return "ERROR:" + transaction.getTradeStateDesc();
- } catch (Exception e) {
- log.error("查询订单状态出错:", e);
- return "ERROR:服务器错误,请联系管理员处理。【订单号:" + tradeNo + "】";
- } finally {
- TradeVectorUtil.removeBeingQuery(tradeNo);
- }
- }
- public ResultVo<String> generateMzGuideBillPayQrcode(GenMzPayQrcodeParam param) {
- WechatPayGlobalRequest request = new WechatPayGlobalRequest.Builder()
- .totalAmount(param.getTotalAmt()).description("湖南泰和医院-门诊缴费").build();
- NativePayResponse response = new WeChatPayService().nativePrepay(request);
- long timesStamp = System.currentTimeMillis() / 1000;
- WxPayOrder order = new WxPayOrder();
- order.setAppId(PropertiesUtil.getLocalProperty("appId"));
- order.setBody("门诊缴费");
- order.setOpenid("");
- order.setPatientId(param.getPatientId());
- order.setPatientName(dao.selectPatientName(param.getPatientId()));
- order.setMchId(PropertiesUtil.getLocalProperty("mchId"));
- order.setTimeStamp(String.valueOf(timesStamp));
- order.setTradeNo(response.getTradeNo());
- order.setCreateDatetime(new Date());
- order.setTradeState(Transaction.TradeStateEnum.NOTPAY);
- order.setSerialNo(SnowFlakeId.instance().nextId());
- order.setOrderType(OrderType.OUTPATIENT.getCode());
- order.setHisOrdNum(param.getHisOrdNum());
- // MedinsPresettle presettle = getFundPayAmt(param.getHisOrdNum());
- order.setFundpayAmt(BigDecimal.ZERO);
- order.setAcctpayAmt(BigDecimal.ZERO);
- order.setCashpayAmt(DecimalTool.moneyFenToYuan(param.getTotalAmt()));
- order.setCouponAmt(BigDecimal.ZERO);
- order.setTotalFee(order.getCashpayAmt());
- dao.insertNewOrder(order);
- return ResultVoUtil.success(response.getCodeUrl());
- }
- public ResultVo<Map<String, String>> getWxPayQrcode(WxPyQrcdPrm param) {
- String patName = dao.selectPatientName(param.getPatientId());
- if (null == patName) {
- return ResultVoUtil.fail(ExceptionEnum.NULL_POINTER, "没有找到患者信息,请检查patientId是否正确!");
- }
- WxPayOrder order = new WxPayOrder();
- if (param.getOrderType() == OrderType.INPATIENT_PRE_PAY.getCode()) {
- if (StringUtil.isBlank(param.getInpatientNo())) {
- return ResultVoUtil.fail(ExceptionEnum.NULL_POINTER, "费用类型为住院预交金时,住院号不能为空!");
- }
- if (null == param.getAdmissTimes()) {
- return ResultVoUtil.fail(ExceptionEnum.NULL_POINTER, "费用类型为住院预交金时,住院次数不能为空!");
- }
- order.setInpatientNo(param.getInpatientNo());
- order.setAdmissTimes(param.getAdmissTimes());
- }
- WechatPayGlobalRequest request = new WechatPayGlobalRequest.Builder()
- .totalAmount(param.getTotalAmt()).description(param.getDescription()).build();
- NativePayResponse response = new WeChatPayService().nativePrepay(request);
- long timesStamp = System.currentTimeMillis() / 1000;
- String orderTypeName = OrderType.get(param.getOrderType()).getLabel();
- order.setAppId(PropertiesUtil.getLocalProperty("appId"));
- order.setBody(orderTypeName);
- order.setOpenid("");
- order.setTotalFee(DecimalTool.moneyFenToYuan(param.getTotalAmt()));
- order.setPatientId(param.getPatientId());
- order.setPatientName(patName);
- order.setMchId(PropertiesUtil.getLocalProperty("mchId"));
- order.setTimeStamp(String.valueOf(timesStamp));
- order.setTradeNo(response.getTradeNo());
- order.setCreateDatetime(new Date());
- order.setTradeState(Transaction.TradeStateEnum.NOTPAY);
- order.setSerialNo(SnowFlakeId.instance().nextId());
- order.setOrderType(param.getOrderType());
- order.setFundpayAmt(BigDecimal.ZERO);
- order.setAcctpayAmt(BigDecimal.ZERO);
- order.setCouponAmt(BigDecimal.ZERO);
- order.setCashpayAmt(order.getTotalFee());
- dao.insertNewOrder(order);
- Map<String, String> map = new HashMap<>();
- map.put("qrcodeUrl", response.getCodeUrl());
- map.put("tradeNo", response.getTradeNo());
- map.put("serialNo", order.getSerialNo());
- return ResultVoUtil.success(map);
- }
- private MedinsPresettle getFundPayAmt(String hisOrdNum) {
- String[] hisOrdNumSplitArray = hisOrdNum.split("_");
- String patNo = hisOrdNumSplitArray[0];
- int times = Integer.parseInt(hisOrdNumSplitArray[1]);
- MedinsPresettle presettle = dao.selectSettleinfo(patNo, times);
- if (null == presettle) {
- presettle = dao.selectMedinsPresettle2(patNo, times);
- }
- if (null == presettle) {
- presettle = new MedinsPresettle();
- presettle.setFundPaySumamt(BigDecimal.ZERO);
- presettle.setAcctPay(BigDecimal.ZERO);
- }
- return presettle;
- }
- public String closeWxOrder(WxPayOrder order) {
- String tradeNo = order.getTradeNo();
- if (StringUtil.isBlank(tradeNo)) {
- return "参数错误:[tradeNo]不能为空!";
- }
- Transaction.TradeStateEnum tradeState = dao.selectOrderStatus(tradeNo);
- if (null == tradeState) {
- return "订单不存在。";
- }
- if (tradeState == Transaction.TradeStateEnum.SUCCESS) {
- return "订单已支付,无法关闭。";
- }
- if (tradeState == Transaction.TradeStateEnum.CLOSED) {
- return "SUCCESS";
- }
- WechatPayGlobalRequest request = new WechatPayGlobalRequest.Builder()
- .outTradeNo(tradeNo).build();
- new WeChatPayService().closeOrder(request);
- dao.updatePayStatusOnly(tradeNo, Transaction.TradeStateEnum.CLOSED);
- return "SUCCESS";
- }
- public void closeUnpaidWxOrder(String hisOrdNum) {
- List<String> tradeNos = dao.selectTradeNoByHisOrdNum(hisOrdNum);
- for (String tradeNo : tradeNos) {
- WechatPayGlobalRequest request = new WechatPayGlobalRequest.Builder()
- .outTradeNo(tradeNo).build();
- new WeChatPayService().closeOrder(request);
- dao.updatePayStatusOnly(tradeNo, Transaction.TradeStateEnum.CLOSED);
- }
- }
- public ResultVo<DoctorInfo> getDoctorInfo(String doctorCode) {
- DoctorInfo doctorInfo = dao.selectDoctorInfo(doctorCode);
- if (null == doctorInfo) {
- return ResultVoUtil.fail(ExceptionEnum.NULL_POINTER, "未找到医生信息!");
- }
- return ResultVoUtil.success(doctorInfo);
- }
- public String saveInpatientPrepay(String tradeNo) {
- WxPayOrder order = dao.selectOrderByTradeNo(tradeNo);
- if (null == order) {
- return "ERROR:没有找到订单号【" + tradeNo + "】对应的订单。";
- }
- if (StringUtil.isBlank(order.getInpatientNo()) || null == order.getAdmissTimes()) {
- return "ERROR:预交金订单的住院号和住院次数不能为空。";
- }
- return savePayResultService.saveZyYjjInfo(order, DateUtil.formatDatetime(order.getPayDatetime()));
- }
- }
|