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.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("/qrpay") public class QRPayServlet 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 map = XMLConverUtil.convertToMap(sb.toString()); // 过滤空 设置 TreeMap // SortedMap 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 recipeIdJson = "[{\"id\":" + "\"" + recipeId + "\"" + ",\"fee\":" + payMoney + "}]"; String flag = array[4]; log.info("扫码支付:patientId=" + array[0] + ", mzNum=" + array[1] + ",recipeId=" + array[2] + ",payMoney=" + array[3] + ", flag=" + array[4]); if (patientId.equals("") || mzNum.equals("") || payMoney.equals("")) { log.info("扫码支付:参数中有空值,不允许支付!product_id=" + product_id); HttpHelper.outRespAlert(response, "扫码支付:参数中有空值,不允许支付!"); return; } // 是否重复支付 log.info("判断是否支付过:" + patientId + "," + mzNum + "," + recipeId); if (new RecipeDao().isHisPaidByPatient(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); } }