2、新增:新增扫码接口,对二维码的数据加密后重定向到前端,进行支付。 3、新增:新增微信回调处理接口,处理收到的扫码挂号的订单数据。 4、对接:对接和HIS的支付接口。 5、合并:合并支付回调的新旧版的处理逻辑。 6、维护:排查红河州医院体检系统发送短信未收到的问题,调整接口的打印日志和使用医院的名称记录。debug
parent
a3d7ead435
commit
b317ab7167
35 changed files with 545 additions and 303 deletions
@ -0,0 +1,101 @@ |
|||||||
|
package com.ynxbd.common.action.pay; |
||||||
|
|
||||||
|
|
||||||
|
import com.alibaba.fastjson.JSONObject; |
||||||
|
import com.ynxbd.common.action.base.BaseAction; |
||||||
|
import com.ynxbd.common.bean.enums.MerchantEnum; |
||||||
|
import com.ynxbd.common.bean.pay.Register; |
||||||
|
import com.ynxbd.common.helper.common.CodeHelper; |
||||||
|
import com.ynxbd.common.helper.common.DateHelper; |
||||||
|
import com.ynxbd.common.helper.common.URLHelper; |
||||||
|
import com.ynxbd.common.result.Result; |
||||||
|
import com.ynxbd.common.result.ResultEnum; |
||||||
|
import com.ynxbd.common.service.PayService; |
||||||
|
import com.ynxbd.common.service.RegService; |
||||||
|
import com.ynxbd.wx.config.WeChatConfig; |
||||||
|
import com.ynxbd.wx.wxfactory.ReqParamHelper; |
||||||
|
import lombok.extern.slf4j.Slf4j; |
||||||
|
import org.apache.commons.lang3.ObjectUtils; |
||||||
|
import org.apache.struts2.convention.annotation.Action; |
||||||
|
import org.apache.struts2.convention.annotation.Namespace; |
||||||
|
|
||||||
|
import java.math.BigDecimal; |
||||||
|
|
||||||
|
@Slf4j |
||||||
|
@Namespace("/tpp") |
||||||
|
public class ThirdPartyPayAction extends BaseAction { |
||||||
|
|
||||||
|
@Action("qr_reg") |
||||||
|
public Result qr_reg(String callNo, String sourceId, String patientId, BigDecimal money, String date) { |
||||||
|
log.info("[第三方][扫码挂号] callNo={}, sourceId={}, patientId={}, money={}, date={}", callNo, sourceId, patientId, money, date); |
||||||
|
// http://127.0.0.1:8080/wx/tpp/qr_reg?sourceId=1&patientId=2&money=0.01&date=2025-04-15
|
||||||
|
if (ObjectUtils.isEmpty(sourceId) || ObjectUtils.isEmpty(patientId) || ObjectUtils.isEmpty(date) || money == null) { |
||||||
|
return Result.error(ResultEnum.PARAM_IS_DEFECT); |
||||||
|
} |
||||||
|
|
||||||
|
String params = URLHelper.mapToUrl(map -> { |
||||||
|
map.put("partnerId", patientId); |
||||||
|
map.put("enPatientId", ReqParamHelper.encode(patientId)); |
||||||
|
map.put("sourceId", sourceId); |
||||||
|
map.put("enSourceId", ReqParamHelper.encode(sourceId)); |
||||||
|
map.put("date", date); |
||||||
|
map.put("enDate", ReqParamHelper.encode(date)); |
||||||
|
}, true); |
||||||
|
return Result.redirect(WeChatConfig.getWebUrl() + "tpp-qr-reg.html" + params); |
||||||
|
} |
||||||
|
|
||||||
|
@Action("qr_reg_pay") |
||||||
|
public Result qr_reg_pay(String payCode, String openid, String sourceId, String patientId, BigDecimal money, String date) { |
||||||
|
log.info("[第三方][扫码挂号-支付] sourceId={}, patientId={}, money={}, date={}", sourceId, patientId, money, date); |
||||||
|
if (ObjectUtils.isEmpty(openid)) { |
||||||
|
return Result.error(ResultEnum.PARAM_IS_INVALID); |
||||||
|
} |
||||||
|
if (ObjectUtils.isEmpty(sourceId) || ObjectUtils.isEmpty(patientId) || ObjectUtils.isEmpty(date) || money == null) { |
||||||
|
return Result.error(ResultEnum.PARAM_IS_DEFECT); |
||||||
|
} |
||||||
|
MerchantEnum merchantEnum = MerchantEnum.getMerchantEnumByCode(payCode); |
||||||
|
if (merchantEnum == null) { |
||||||
|
return Result.error(ResultEnum.PAY_TYPE_ERROR); // 支付方式异常
|
||||||
|
} |
||||||
|
|
||||||
|
if (money.compareTo(BigDecimal.ZERO) == 0) { |
||||||
|
return Result.error(ResultEnum.PAY_MONEY_IS_ZERO); |
||||||
|
} |
||||||
|
|
||||||
|
Register reg = new Register(); |
||||||
|
reg.setOpenid(openid); |
||||||
|
reg.setRegDate(date); |
||||||
|
// 挂号类型:1:预约挂号,2:今日挂号;3:分时段预约挂号,4:分时段今日挂号
|
||||||
|
reg.setRegType(DateHelper.isToday(date) ? "2" : "1"); |
||||||
|
reg.setSourceId(sourceId); |
||||||
|
reg.setPatientId(patientId); |
||||||
|
|
||||||
|
reg.setTotalFee(money); |
||||||
|
reg.setPayMoney(money); |
||||||
|
reg.setRegFee(money); |
||||||
|
reg.setClinicFee(BigDecimal.ZERO); |
||||||
|
|
||||||
|
reg.setPayDeviceId("mobile"); |
||||||
|
reg.setPayWay(merchantEnum.PAY_WAY_IN); |
||||||
|
String outTradeNo = CodeHelper.getOutTradeNo(merchantEnum); |
||||||
|
reg.setOutTradeNo(outTradeNo); |
||||||
|
log.info("{} [第三方-扫码挂号]生成 outTradeNo={}", merchantEnum.NAME, outTradeNo); |
||||||
|
|
||||||
|
if (!new RegService().isSaveRegPrepay(reg)) { |
||||||
|
log.info("{} [第三方-扫码挂号]预存支付信息失败 patientId={}, sourceId={}", merchantEnum.NAME, patientId, sourceId); |
||||||
|
return Result.error(ResultEnum.SPECIFIED_QUESTIONED_USER_NOT_EXIST); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
String ip = request.getRemoteAddr(); |
||||||
|
String body = "扫码挂号" + date + " 患者:" + patientId; |
||||||
|
|
||||||
|
JSONObject respJson = PayService.createOrder(merchantEnum, openid, patientId, money.toString(), outTradeNo, PEnum.TPP_QR_REG.CODE, ip, body); |
||||||
|
if (respJson == null) { |
||||||
|
return Result.error(ResultEnum.PAY_ERROR); // 支付异常
|
||||||
|
} |
||||||
|
respJson.put("outTradeNo", outTradeNo); |
||||||
|
respJson.put("dateTime", DateHelper.getCurDateTime()); |
||||||
|
return Result.success(respJson); |
||||||
|
} |
||||||
|
} |
@ -1,4 +1,4 @@ |
|||||||
package com.ynxbd.common.action.pay; |
package com.ynxbd.common.bean; |
||||||
|
|
||||||
import lombok.Getter; |
import lombok.Getter; |
||||||
import lombok.NoArgsConstructor; |
import lombok.NoArgsConstructor; |
@ -0,0 +1,110 @@ |
|||||||
|
package com.ynxbd.common.service; |
||||||
|
|
||||||
|
import com.ynxbd.common.action.pay.PEnum; |
||||||
|
import com.ynxbd.common.bean.enums.MerchantEnum; |
||||||
|
import com.ynxbd.common.bean.pay.Register; |
||||||
|
import com.ynxbd.common.dao.RegisterDao; |
||||||
|
import com.ynxbd.common.dao.his.HisRegisterDao; |
||||||
|
import com.ynxbd.common.helper.his.HisHelper; |
||||||
|
import com.ynxbd.common.result.JsonResult; |
||||||
|
import com.ynxbd.common.result.ResultEnum; |
||||||
|
import com.ynxbd.common.result.ServiceException; |
||||||
|
import com.ynxbd.wx.config.MessagePushConfig; |
||||||
|
import lombok.extern.slf4j.Slf4j; |
||||||
|
import org.apache.commons.lang3.ObjectUtils; |
||||||
|
|
||||||
|
import java.math.BigDecimal; |
||||||
|
|
||||||
|
@Slf4j |
||||||
|
public class ThirdPartyPayService { |
||||||
|
|
||||||
|
/** |
||||||
|
* 挂号回调 |
||||||
|
* |
||||||
|
* @param merchantEnum 商户类型 |
||||||
|
* @param totalFee 订单金额 |
||||||
|
* @param openid openid |
||||||
|
* @param bankTransNo 商户返回流水号 |
||||||
|
* @param outTradeNo 订单号 |
||||||
|
* @param payDate 支付日期 |
||||||
|
* @param payTime 支付时间 |
||||||
|
* @return 是否完成 |
||||||
|
*/ |
||||||
|
public boolean tppQRRegNotify(MerchantEnum merchantEnum, String openid, BigDecimal totalFee, String outTradeNo, String bankTransNo, String payDate, String payTime, String payInfo) throws ServiceException { |
||||||
|
RegisterDao registerDao = new RegisterDao(); |
||||||
|
|
||||||
|
Register reg; |
||||||
|
String regType, patientId; |
||||||
|
String tradeNo = HisHelper.getHisTradeNo(bankTransNo, PEnum.TPP_QR_REG); |
||||||
|
try { |
||||||
|
reg = registerDao.selectByOutTradeNo(outTradeNo); |
||||||
|
if (reg == null) { |
||||||
|
throw new ServiceException(ResultEnum.DATA_NOT_FOUND, |
||||||
|
String.format("{%s} [第三方][扫码挂号]数据库中未找到订单 outTradeNo={%s}, bankTransNo={%s}, tradeNo={%s}", merchantEnum.NAME, outTradeNo, bankTransNo, tradeNo)); |
||||||
|
} |
||||||
|
Integer hisStatus = reg.getHisStatus(); |
||||||
|
Integer payStatus = reg.getPayStatus(); |
||||||
|
if (payStatus == null || hisStatus == null || payStatus == 0 || hisStatus == 0) { // 状态不明确
|
||||||
|
log.info("{{}} [第三方][扫码挂号]订单已支付,停止向下执行 outTradeNo={{}}, bankTransNo={{}}, tradeNo={{}}", merchantEnum.NAME, outTradeNo, bankTransNo, tradeNo); |
||||||
|
return false; |
||||||
|
} |
||||||
|
|
||||||
|
// 更新商户支付状态
|
||||||
|
if (!registerDao.updateMerPaidByOutTradeNo(outTradeNo, payDate, payTime, bankTransNo, tradeNo, null)) { |
||||||
|
log.info("{{}} [第三方][扫码挂号]更新订单失败,停止向下执行 outTradeNo={{}}, bankTransNo={{}}, tradeNo={{}}", merchantEnum.NAME, outTradeNo, bankTransNo, tradeNo); |
||||||
|
return false; |
||||||
|
} |
||||||
|
reg.setPayDate(payDate); |
||||||
|
reg.setPayTime(payTime); |
||||||
|
reg.setBankTransNo(bankTransNo); |
||||||
|
reg.setTradeNo(tradeNo); |
||||||
|
|
||||||
|
// 挂号类型:1:预约挂号,2:今日挂号;3:分时段预约挂号,4:分时段今日挂号
|
||||||
|
regType = reg.getRegType(); |
||||||
|
patientId = reg.getPatientId(); |
||||||
|
|
||||||
|
if (ObjectUtils.isEmpty(reg.getSourceId())) { |
||||||
|
throw new ServiceException(ResultEnum.PARAM_IS_BLANK, |
||||||
|
String.format("{%s} [第三方][扫码挂号]号源ID缺失 outTradeNo={%s}, bankTransNo={%s}, tradeNo={%s}", merchantEnum.NAME, outTradeNo, bankTransNo, tradeNo)); |
||||||
|
} |
||||||
|
|
||||||
|
if (ObjectUtils.isEmpty(patientId) || ObjectUtils.isEmpty(regType) || ObjectUtils.isEmpty(reg.getRegDate())) { |
||||||
|
throw new ServiceException(ResultEnum.PARAM_IS_BLANK, |
||||||
|
String.format("{%s} [第三方][扫码挂号]参数缺失 outTradeNo={%s}, bankTransNo={%s}, tradeNo={%s}", merchantEnum.NAME, outTradeNo, bankTransNo, tradeNo)); |
||||||
|
} |
||||||
|
|
||||||
|
} catch (ServiceException e) { |
||||||
|
log.error(e.getMessage()); |
||||||
|
throw new ServiceException(e.getMessage()); |
||||||
|
} |
||||||
|
|
||||||
|
log.info("{} [第三方][扫码挂号]开始调用HIS:patientId={}, bankTransNo={}", merchantEnum.NAME, patientId, bankTransNo); |
||||||
|
|
||||||
|
JsonResult jsonResult = new HisRegisterDao().tppQRReg(merchantEnum, reg.getSourceId(), String.valueOf(totalFee), payDate, payTime, openid, bankTransNo, tradeNo); |
||||||
|
|
||||||
|
String message = jsonResult.getMessage(); |
||||||
|
if (!jsonResult.success()) { // 调用HIS失败-->自动退款
|
||||||
|
log.info("{} [第三方][扫码挂号]调用HIS挂号失败:patientId={}", merchantEnum.NAME, patientId); |
||||||
|
throw new ServiceException(message); |
||||||
|
} |
||||||
|
|
||||||
|
String invoiceTransNo = jsonResult.getDataMapString("InvoiceTransNo"); |
||||||
|
String hisTransNo = jsonResult.getDataMapString("HISTransNo"); |
||||||
|
String hisQueueNo = jsonResult.getDataMapString("QueueNo"); |
||||||
|
|
||||||
|
// 挂号成功-->更新挂号信息
|
||||||
|
log.info("{} [第三方][扫码挂号]更新HIS挂号信息[after] outTradeNo={}, tradeNo={}, patientId={}, bankTransNo={}", merchantEnum.NAME, outTradeNo, tradeNo, patientId, bankTransNo); |
||||||
|
if (registerDao.updateHisRegInfo(outTradeNo, bankTransNo, hisTransNo, null, invoiceTransNo, null)) { |
||||||
|
log.info("{} [第三方][扫码挂号]更新HIS挂号信息成功 patientId={}", merchantEnum.NAME, patientId); |
||||||
|
} |
||||||
|
|
||||||
|
if (MerchantEnum.WX.equals(merchantEnum)) { |
||||||
|
MessagePushConfig.regPush(merchantEnum, reg); |
||||||
|
} |
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
public static void main(String[] args) { |
||||||
|
System.out.println(0.1 + 0.2); |
||||||
|
} |
||||||
|
} |
@ -1,7 +0,0 @@ |
|||||||
package com.ynxbd.common.test; |
|
||||||
|
|
||||||
import com.ynxbd.common.helper.common.Base64Helper; |
|
||||||
|
|
||||||
public class PatientTest { |
|
||||||
|
|
||||||
} |
|
@ -0,0 +1,12 @@ |
|||||||
|
package com.ynxbd.common.test; |
||||||
|
|
||||||
|
import com.ynxbd.common.helper.common.AesHelper; |
||||||
|
import com.ynxbd.wx.wxfactory.ReqParamHelper; |
||||||
|
|
||||||
|
public class Test01 { |
||||||
|
|
||||||
|
public static void main(String[] args) { |
||||||
|
// 患者id
|
||||||
|
System.out.println(ReqParamHelper.encode("282466")); |
||||||
|
} |
||||||
|
} |
Loading…
Reference in new issue