2、新增:支付宝查询订单、退费接口,调整接口加密。 3、调整:旧版体检缴费因数据量太大,且在未使用索引的情况下,导致扫码加载较慢的问题排查。 4、新增:支付宝医保缴费结束后需要显示费用信息,查询订单信息接口,新增业务类型判断的入参,根据类型返回订单的费用信息。debug
parent
9a740ffc8a
commit
dc73bbd331
29 changed files with 902 additions and 486 deletions
@ -0,0 +1,189 @@ |
||||
package com.ynxbd.wx.servlet.oldpay; |
||||
|
||||
import com.ynxbd.common.bean.enums.MerchantEnum; |
||||
import com.ynxbd.common.bean.pay.Recipe; |
||||
import com.ynxbd.common.dao.RecipeDao; |
||||
import com.ynxbd.common.helper.common.CodeHelper; |
||||
import com.ynxbd.common.helper.common.HttpHelper; |
||||
import com.ynxbd.wx.config.WeChatConfig; |
||||
import lombok.extern.slf4j.Slf4j; |
||||
import org.apache.commons.lang3.ObjectUtils; |
||||
import org.slf4j.MDC; |
||||
import weixin.popular.api.PayMchAPI; |
||||
import weixin.popular.bean.paymch.MchPayNativeReply; |
||||
import weixin.popular.bean.paymch.Unifiedorder; |
||||
import weixin.popular.bean.paymch.UnifiedorderResult; |
||||
import weixin.popular.util.PayUtil; |
||||
import weixin.popular.util.SignatureUtil; |
||||
import weixin.popular.util.XMLConverUtil; |
||||
|
||||
import javax.servlet.ServletException; |
||||
import javax.servlet.annotation.WebServlet; |
||||
import javax.servlet.http.HttpServlet; |
||||
import javax.servlet.http.HttpServletRequest; |
||||
import javax.servlet.http.HttpServletResponse; |
||||
import java.io.BufferedReader; |
||||
import java.io.IOException; |
||||
import java.io.InputStream; |
||||
import java.io.InputStreamReader; |
||||
import java.math.BigDecimal; |
||||
import java.nio.charset.StandardCharsets; |
||||
import java.util.Map; |
||||
import java.util.UUID; |
||||
|
||||
/** |
||||
* 扫码支付接口(旧版) |
||||
* |
||||
* @author 张剑峰 |
||||
* @version v1.0.0 |
||||
* @Project:微信公众号 |
||||
* @date 2018年6月4日上午10:44:31 |
||||
* @Copyright: 2018云南新八达科技有限公司 All rights reserved. |
||||
*/ |
||||
@Slf4j |
||||
@WebServlet("/qrpay2") |
||||
public class QRPayServlet2 extends HttpServlet { |
||||
|
||||
@Override |
||||
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { |
||||
MDC.remove("ip"); |
||||
MDC.put("ip", HttpHelper.getIpAddress(request)); |
||||
|
||||
log.info("[旧版]收到扫码支付请求,开始解析..."); |
||||
|
||||
// 读取参数
|
||||
InputStream inputStream = request.getInputStream(); |
||||
StringBuilder sb = new StringBuilder(); |
||||
String s; |
||||
BufferedReader in = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8)); |
||||
while ((s = in.readLine()) != null) { |
||||
sb.append(s); |
||||
} |
||||
in.close(); |
||||
inputStream.close(); |
||||
|
||||
// 解析xml成map
|
||||
Map<String, String> map = XMLConverUtil.convertToMap(sb.toString()); |
||||
// 过滤空 设置 TreeMap
|
||||
// SortedMap<Object, Object> payParams = new TreeMap<>();
|
||||
// Iterator it = map.keySet().iterator();
|
||||
// while (it.hasNext()) {
|
||||
// String parameter = (String) it.next();
|
||||
// String parameterValue = map.get(parameter);
|
||||
// String v = "";
|
||||
// if (null != parameterValue) {
|
||||
// v = parameterValue.trim();
|
||||
// }
|
||||
// payParams.put(parameter, v);
|
||||
// }
|
||||
|
||||
// 验证请求签名
|
||||
if (!map.get("sign").equals(SignatureUtil.generateSign(map, WeChatConfig.MCH_KEY))) { |
||||
log.info("收到扫码支付请求:签名无效!"); |
||||
HttpHelper.outRespAlert(response, "收到扫码支付请求:签名无效!"); |
||||
return; |
||||
} |
||||
|
||||
String product_id = map.get("product_id"); |
||||
log.info("收到扫码支付请求:product_id=" + product_id + ", open_id=" + map.get("openid")); |
||||
if (!product_id.contains("XBD")) { |
||||
log.info("扫码支付:不合规则的字符串,不允许支付!product_id=" + product_id); |
||||
HttpHelper.outRespAlert(response, "扫码支付:不合规则的字符串,不允许支付!"); |
||||
return; |
||||
} |
||||
|
||||
String[] array = product_id.split("XBD"); |
||||
if (array.length < 5) { |
||||
log.info("扫码支付:参数少于5个,不允许支付!product_id=" + product_id); |
||||
HttpHelper.outRespAlert(response, "扫码支付:参数少于5个"); |
||||
return; |
||||
} |
||||
|
||||
String patientId = array[0]; |
||||
String mzNum = array[1]; |
||||
String recipeId = array[2]; |
||||
String payMoney = array[3]; |
||||
String flag = array[4]; |
||||
// String recipeIdJson = "[{\"id\":" + "\"" + recipeId + "\"" + ",\"fee\":" + payMoney + "}]";
|
||||
|
||||
log.info("扫码支付:patientId={} treatNum={}, recipeId={}, payMoney={}, flag={}", patientId, mzNum, recipeId, payMoney, flag); |
||||
|
||||
if (ObjectUtils.isEmpty(patientId) || ObjectUtils.isEmpty(mzNum) || ObjectUtils.isEmpty(payMoney)) { |
||||
log.info("扫码支付:参数中有空值,不允许支付!product_id={}", product_id); |
||||
HttpHelper.outRespAlert(response, "扫码支付:参数中有空值,不允许支付!"); |
||||
return; |
||||
} |
||||
|
||||
// 是否重复支付
|
||||
log.info("判断是否支付过:patientId={}, mzNum={}, recipeId={}", patientId, mzNum, recipeId); |
||||
if (new RecipeDao().hasHisPaidByPatient(patientId, mzNum, recipeId)) { |
||||
log.info("该码已经缴费,无需支付!product_id={}", product_id); |
||||
HttpHelper.outRespAlert(response, "该码已经缴费,无需支付!"); |
||||
return; |
||||
} |
||||
|
||||
// 统一下单
|
||||
Unifiedorder unifiedorder = new Unifiedorder(); |
||||
String appID = WeChatConfig.APP_ID; |
||||
String mchID = WeChatConfig.MCH_ID; |
||||
String mchKey = WeChatConfig.MCH_KEY; |
||||
|
||||
unifiedorder.setAppid(appID); |
||||
unifiedorder.setMch_id(mchID); |
||||
unifiedorder.setNonce_str(UUID.randomUUID().toString().replace("-", "")); |
||||
if (flag.equals("1")) { |
||||
unifiedorder.setBody("ID:" + patientId + " 处方单号:" + recipeId); |
||||
} else if (flag.equals("2")) { |
||||
unifiedorder.setBody("ID:" + patientId + " 申请单号:" + recipeId); |
||||
} |
||||
|
||||
// unifiedorder.setBody("pay");
|
||||
unifiedorder.setOut_trade_no(CodeHelper.getOutTradeNo(MerchantEnum.WX)); |
||||
|
||||
// 此处使用Float或者Double转换金额会因为精度问题丢失1分钱,使用BigDecimal来转换
|
||||
BigDecimal v1 = new BigDecimal(payMoney); |
||||
BigDecimal v2 = new BigDecimal("100"); |
||||
double b = v1.multiply(v2).doubleValue(); |
||||
int fFee = (int) b; |
||||
|
||||
unifiedorder.setTotal_fee(String.valueOf(fFee)); |
||||
unifiedorder.setSpbill_create_ip(request.getRemoteAddr()); |
||||
unifiedorder.setNotify_url(WeChatConfig.getBaseUrl() + "old_pay_notify_servlet"); |
||||
unifiedorder.setTrade_type("NATIVE"); |
||||
log.info("扫码回调地址:" + WeChatConfig.getBaseUrl() + "old_pay_notify_servlet"); |
||||
|
||||
UnifiedorderResult unifiedorderResult = PayMchAPI.payUnifiedorder(unifiedorder, mchKey); |
||||
|
||||
Recipe recipe = new Recipe(); |
||||
|
||||
recipe.setOpenid(map.get("openid")); |
||||
recipe.setPatientId(patientId); |
||||
recipe.setTreatNum(mzNum); |
||||
recipe.setOutTradeNo(unifiedorder.getOut_trade_no()); |
||||
recipe.setPayWay("1"); |
||||
recipe.setPayMoney(new BigDecimal(payMoney)); |
||||
recipe.setRecipeId(recipeId); |
||||
// recipe.setTradeNo(CodeHelper.getHisTradeNo()); // 本次his交易流水号
|
||||
recipe.setTotalFee(new BigDecimal(payMoney)); |
||||
recipe.setHisStatus(-1); |
||||
recipe.setPayStatus(-1); |
||||
if (!new RecipeDao().insert(recipe)) { |
||||
log.info("[扫码支付]存储失败"); |
||||
} |
||||
|
||||
MchPayNativeReply reply = new MchPayNativeReply(); |
||||
reply.setAppid(appID); |
||||
reply.setMch_id(mchID); |
||||
reply.setNonce_str(UUID.randomUUID().toString().replace("-", "")); |
||||
reply.setPrepay_id(unifiedorderResult.getPrepay_id()); |
||||
reply.setResult_code("SUCCESS"); |
||||
reply.setReturn_code("SUCCESS"); |
||||
String string = PayUtil.generateMchPayNativeReplyXML(reply, mchKey); |
||||
response.getWriter().write(string); |
||||
} |
||||
|
||||
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { |
||||
doPost(request, response); |
||||
} |
||||
|
||||
} |
@ -1,55 +1,57 @@ |
||||
package com.ynxbd.wx.wxfactory.bean; |
||||
|
||||
import com.ynxbd.wx.wxfactory.WxFactory; |
||||
import lombok.Getter; |
||||
import lombok.NoArgsConstructor; |
||||
import lombok.Setter; |
||||
import lombok.ToString; |
||||
|
||||
|
||||
// 医保查询订单
|
||||
|
||||
@Setter |
||||
@Getter |
||||
@ToString(callSuper = true) |
||||
@NoArgsConstructor |
||||
public class MedicalOrder extends WxFactory.ResponseCheck.ResultBase { |
||||
private String medTradeState; |
||||
private String cashTradeStatus; |
||||
private String insuranceTradeStatus; |
||||
private String tradeStatusDesc; |
||||
private String timeEnd; |
||||
private String orderType; |
||||
private String payType; |
||||
private String openid; |
||||
private String subOpenid; |
||||
private String nonceStr; |
||||
private String totalFee; |
||||
private String cashFee; |
||||
private String allowFeeChange; |
||||
private String spbillCreateIp; |
||||
private String notifyUrl; |
||||
private String insuranceFee; |
||||
private String insuranceSelfFee; |
||||
private String insuranceFundFee; |
||||
private String insuranceOtherFee; |
||||
private String hospOutTradeNo; |
||||
private String serialNo; |
||||
private String orgNo; |
||||
private String gmtOutCreate; |
||||
private String requestContent; |
||||
private String billNo; |
||||
private String limitPay; |
||||
private String medicalCardId; |
||||
private String hospitalName; |
||||
private String returnUrl; |
||||
private String responseContent; |
||||
private String body; |
||||
private String Extends; |
||||
|
||||
private String medTransId; |
||||
private String insuranceOrderId; |
||||
private String cashOrderId; |
||||
private String attach; |
||||
|
||||
} |
||||
package com.ynxbd.wx.wxfactory.bean; |
||||
|
||||
import com.ynxbd.wx.wxfactory.WxFactory; |
||||
import lombok.Getter; |
||||
import lombok.NoArgsConstructor; |
||||
import lombok.Setter; |
||||
import lombok.ToString; |
||||
|
||||
|
||||
// 医保查询订单
|
||||
|
||||
@Setter |
||||
@Getter |
||||
@ToString(callSuper = true) |
||||
@NoArgsConstructor |
||||
public class MIOrder extends WxFactory.ResponseCheck.ResultBase { |
||||
private String medTradeState; |
||||
private String cashTradeStatus; |
||||
private String insuranceTradeStatus; |
||||
private String tradeStatusDesc; |
||||
private String timeEnd; |
||||
private String orderType; |
||||
private String payType; |
||||
private String openid; |
||||
private String subOpenid; |
||||
private String nonceStr; |
||||
private String totalFee; |
||||
private String cashFee; |
||||
private String allowFeeChange; |
||||
private String spbillCreateIp; |
||||
private String notifyUrl; |
||||
private String insuranceFee; |
||||
private String insuranceSelfFee; |
||||
private String insuranceFundFee; |
||||
private String insuranceOtherFee; |
||||
private String hospOutTradeNo; |
||||
private String serialNo; |
||||
private String orgNo; |
||||
private String gmtOutCreate; |
||||
private String requestContent; |
||||
private String billNo; |
||||
private String limitPay; |
||||
private String medicalCardId; |
||||
private String hospitalName; |
||||
private String returnUrl; |
||||
private String responseContent; |
||||
private String body; |
||||
private String Extends; |
||||
|
||||
private String medTransId; |
||||
private String insuranceOrderId; |
||||
private String cashOrderId; |
||||
private String attach; |
||||
|
||||
private Object orderObj; |
||||
|
||||
} |
Loading…
Reference in new issue