Bladeren bron

支付加自动过期

suochencheng 6 jaren geleden
bovenliggende
commit
c2cd588f02

+ 5 - 0
src/main/java/com/izouma/awesomeadmin/constant/AppConstant.java

@@ -124,6 +124,11 @@ public interface AppConstant {
          * 其他
          */
         Integer OTHER = 3;
+
+        /**
+         * 114
+         */
+        Integer APAY = 4;
     }
 
     public interface InergralUpdateType {

+ 13 - 0
src/main/java/com/izouma/awesomeadmin/util/DateTimeTool.java

@@ -278,6 +278,19 @@ public class DateTimeTool {
         return timeStr;
     }
 
+    /**
+     * 将时间格式时间转换为时间格式 yyyy-MM-dd HH:mm:ss
+     *
+     * @param dateTime 日期
+     * @return 转换后日期
+     */
+    public static String dateTimeToTimeMMddHHmmssStr(Date dateTime) {
+
+        final SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+        final String timeStr = formatter.format(dateTime);
+        return timeStr;
+    }
+
 
     /**
      * 将时间格式时间转换为短时间格式HHmm

+ 378 - 0
src/main/java/com/izouma/weixin/web/ApayController.java

@@ -0,0 +1,378 @@
+package com.izouma.weixin.web;
+
+import com.github.kevinsawicki.http.HttpRequest;
+import com.izouma.awesomeadmin.constant.AppConstant;
+import com.izouma.awesomeadmin.dto.Result;
+import com.izouma.awesomeadmin.model.MemberTicket;
+import com.izouma.awesomeadmin.model.ProductInfo;
+import com.izouma.awesomeadmin.service.MemberTicketService;
+import com.izouma.awesomeadmin.service.ProductInfoService;
+import com.izouma.awesomeadmin.util.DateTimeTool;
+import com.izouma.awesomeadmin.util.MbappUtil;
+import com.izouma.awesomeadmin.util.PropertiesFileLoader;
+import com.izouma.weixin.dao.WxpayTempMapper;
+import com.izouma.weixin.model.WxpayTemp;
+import org.apache.commons.codec.digest.DigestUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.log4j.Logger;
+import org.json.JSONObject;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.ResponseBody;
+import org.springframework.web.servlet.ModelAndView;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.HttpSession;
+import java.io.BufferedOutputStream;
+import java.io.IOException;
+import java.math.BigDecimal;
+import java.util.*;
+
+@Controller
+@RequestMapping("/apay")
+public class ApayController {
+
+    private static Logger logger = Logger.getLogger(ApayController.class);
+
+
+    @Autowired
+    private MemberTicketService memberTicketService;
+
+    @Autowired
+    private WxpayTempMapper wxpayTempMapper;
+
+    @Autowired
+    private ProductInfoService productInfoService;
+
+
+    @RequestMapping(value = "/notify", method = RequestMethod.POST)
+    @ResponseBody
+    public String notify(HttpServletRequest request, HttpServletResponse response) {
+        logger.error("apay:notify");
+        try {
+            Map<String, String> m = notifyMap(request, response);
+            autoCheckPayResult();
+        } catch (Exception e) {
+            logger.error("微信支付回调异常", e);
+        }
+
+
+        return "SUCCESS";
+    }
+
+    /**
+     * 支付结果
+     *
+     * @param m
+     */
+    public void payResultChange(Map<String, String> m) {
+
+        try {
+
+            if (m != null && "00".equals(m.get("returncode"))
+                    && !"NOTPAY".equals(m.get("trade_state"))) {//支付成功
+
+                WxpayTemp checkTemp = new WxpayTemp();
+                checkTemp.setOutTradeNo(m.get("orderid"));
+
+
+                checkTemp = wxpayTempMapper.queryWxpayTemp(checkTemp);
+
+                if (checkTemp != null && "NOT_PAY".equals(checkTemp.getResultCode())) {
+
+
+                    WxpayTemp wxpayTemp = new WxpayTemp();
+                    wxpayTemp.setOutTradeNo(m.get("orderid"));
+                    wxpayTemp.setUserId(checkTemp.getUserId());
+                    wxpayTemp.setOrderId(checkTemp.getOrderId());
+                    wxpayTemp.setCash(checkTemp.getCash());
+                    wxpayTemp.setTotalAmount(checkTemp.getTotalAmount());
+                    wxpayTemp.setTransactionId(m.get("transaction_id"));
+                    wxpayTemp.setResultCode(m.get("trade_state"));
+                    wxpayTempMapper.updateByOutTradeNo(wxpayTemp);
+
+                    if ("SUCCESS".equals(m.get("trade_state"))) {
+
+                        logger.info("buyProductInfo");
+                        try {
+                            ProductInfo productInfo = productInfoService.getProductInfoById(checkTemp.getOrderId());
+                            if (productInfo != null) {
+                                if (AppConstant.ProductType.RECHARGE == productInfo.getTypeFlag()) {//如果是充值类型
+
+                                    MemberTicket memberTicket = new MemberTicket();
+                                    memberTicket.setMoney(productInfo.getCoin());
+                                    memberTicket.setUserId(Integer.valueOf(checkTemp.getUserId()));
+                                    memberTicket.setRemark("购买" + productInfo.getProductName() + "套餐,充值");
+                                    memberTicket.setRechargeType(AppConstant.RechargeType.APAY);
+
+                                    memberTicketService.recharge(memberTicket);
+
+
+                                } else {
+                                    //TODO 购买VIP
+                                }
+
+                            }
+
+                        } catch (Exception e) {
+                            logger.error("buyProductInfo", e);
+                        }
+                    }
+                }
+
+
+            }
+        } catch (Exception e) {
+            logger.error("支付结果转换异常", e);
+        }
+
+    }
+
+
+    @RequestMapping(value = "/unifiedOrder", method = RequestMethod.GET)
+    @ResponseBody
+    public ModelAndView unifiedOrder(@RequestParam(required = true, value = "userId") String userId,
+                                     @RequestParam(required = true, value = "productId") String productId,
+                                     @RequestParam(required = true, value = "bankcode") String bankcode) {
+        try {
+
+            double cash = 1;
+
+            ProductInfo productInfo = productInfoService.getProductInfoById(productId);
+
+            cash = productInfo.getMoney().doubleValue();
+
+            int total = 0;
+
+
+            total = (int) (cash * 100);
+
+            //测试为一分
+            total = 1;
+
+            JSONObject attach = new JSONObject();
+            attach.put("productId", productId);
+            attach.put("userId", userId);
+            attach.put("cash", cash);
+            attach.put("total", total);
+
+
+            String out_trade_no = MbappUtil.create_out_trade_no();
+
+
+            Map<String, String> params = new TreeMap<>();
+            params.put("pay_memberid", PropertiesFileLoader.getProperties("apay_memberid"));                     //商户号
+            params.put("pay_orderid", out_trade_no);           //商户系统内部的订单号
+            params.put("pay_applydate", DateTimeTool.dateTimeToTimeMMddHHmmssStr(new Date()));           //提交时间
+            params.put("pay_bankcode", bankcode);           //银行编码
+            params.put("pay_notifyurl", PropertiesFileLoader.getProperties("apay_return_url"));     //接收支付结果异步通知回调地址
+            params.put("pay_callbackurl", PropertiesFileLoader.getProperties("apay_notify_url"));    //页面回调地址
+            params.put("pay_amount", String.valueOf(total / 100.0));                       //金额 单位元
+
+
+            String signSrc = getSignSrc(params);
+            String sign = DigestUtils.md5Hex(signSrc + "&key=" + PropertiesFileLoader.getProperties("apay_key")).toUpperCase();
+            params.put("pay_md5sign", sign);                           //签名
+            params.put("pay_productname", productInfo.getProductName());            //商品或支付单简要描述
+            params.put("pay_attach", attach.toString());   //附加数据
+
+            WxpayTemp wxpayTemp = new WxpayTemp();
+            wxpayTemp.setOrderId(productId);
+            wxpayTemp.setUserId(userId);
+            wxpayTemp.setCash(BigDecimal.valueOf(cash));
+            wxpayTemp.setTotalAmount(BigDecimal.valueOf(total / 100.0));
+            wxpayTemp.setOutTradeNo(out_trade_no);
+            wxpayTemp.setTypeFlag(AppConstant.Aliapi.BUY);
+            wxpayTemp.setResultCode("NOT_PAY");
+            wxpayTemp.setCreateUser("apay");
+            wxpayTempMapper.insertSelective(wxpayTemp);
+
+            params.put("AuthorizationURL", PropertiesFileLoader.getProperties("apay_pay_url"));
+            ModelAndView mv = new ModelAndView("jsp/pay.jsp");
+            mv.addAllObjects(params);
+            return mv;
+
+        } catch (Exception e) {
+            logger.error("apay下单失败", e);
+        }
+
+
+        return null;
+
+    }
+
+
+    @RequestMapping(value = "/orderquery", method = RequestMethod.GET)
+    @ResponseBody
+    public String orderquery(@RequestParam(required = true, value = "pay_orderid") String pay_orderid) {
+        try {
+
+
+            Map<String, String> params = new TreeMap<>();
+            params.put("pay_memberid", PropertiesFileLoader.getProperties("apay_memberid"));                     //商户号
+            params.put("pay_orderid", pay_orderid);           //商户系统内部的订单号
+
+
+            String signSrc = getSignSrc(params);
+            String sign = DigestUtils.md5Hex(signSrc + "&key=" + PropertiesFileLoader.getProperties("apay_key")).toUpperCase();
+            params.put("pay_md5sign", sign);                           //签名
+
+            String response = HttpRequest.post(PropertiesFileLoader.getProperties("apay_query_url"))
+                    .form(params).body();
+
+
+            return response;
+
+        } catch (Exception e) {
+            logger.error("apay查询订单失败", e);
+        }
+
+
+        return null;
+
+    }
+
+    @RequestMapping(value = "/autoCheckPayResult", method = RequestMethod.GET)
+    @ResponseBody
+    public Result autoCheckPayResult() {
+        try {
+
+            WxpayTemp param = new WxpayTemp();
+            param.setCreateUser("apay");
+            param.setResultCode("NOT_PAY");
+            List<WxpayTemp> wxpayTempList = wxpayTempMapper.queryAutoCheckPayWxpayTemp(param);
+
+            for (WxpayTemp wxpayTemp : wxpayTempList) {
+
+                try {
+
+
+                    Map<String, String> params = new TreeMap<>();
+                    params.put("pay_memberid", PropertiesFileLoader.getProperties("apay_memberid"));                     //商户号
+                    params.put("pay_orderid", wxpayTemp.getOutTradeNo());           //商户系统内部的订单号
+
+
+                    String signSrc = getSignSrc(params);
+                    String sign = DigestUtils.md5Hex(signSrc + "&key=" + PropertiesFileLoader.getProperties("apay_key")).toUpperCase();
+                    params.put("pay_md5sign", sign);                           //签名
+
+                    String response = HttpRequest.post(PropertiesFileLoader.getProperties("apay_query_url"))
+                            .form(params).body();
+
+                    JSONObject responseJson = new JSONObject(response);
+
+                    if ("NOTPAY".equals(responseJson.getString("trade_state")) && DateTimeTool.dateTimeAddMinutes(wxpayTemp.getCreateTime(), 120).before(new Date())) {
+                        continue;
+                    }
+
+
+                    Map<String, String> notifyMap = new HashMap<>();
+
+                    notifyMap.put("memberid", responseJson.getString("memberid"));
+                    notifyMap.put("orderid", responseJson.getString("orderid"));
+                    notifyMap.put("amount", responseJson.getString("amount"));
+                    notifyMap.put("time_end", responseJson.getString("time_end"));
+                    notifyMap.put("transaction_id", responseJson.getString("transaction_id"));
+                    notifyMap.put("returncode", responseJson.getString("returncode"));
+                    notifyMap.put("trade_state", responseJson.getString("trade_state"));
+                    notifyMap.put("sign", responseJson.getString("sign"));
+
+
+                    payResultChange(notifyMap);
+
+
+                } catch (Exception e) {
+                    logger.error("查询支付结果异常", e);
+                }
+
+
+            }
+
+
+            return new Result(true, "自动检测支付结果成功");
+
+
+        } catch (Exception e) {
+            logger.error("apay查询订单失败", e);
+        }
+
+
+        return null;
+
+    }
+
+
+    /**
+     * 解析微信支付回调结果
+     *
+     * @param request
+     * @param response
+     * @return
+     */
+    public Map<String, String> notifyMap(HttpServletRequest request, HttpServletResponse response) {
+
+        logger.info("payOrder:支付订单");
+        Map<String, String> notifyMap = new HashMap<>();
+        String resXml = "OK";
+        try {
+
+
+            notifyMap.put("memberid", request.getParameter("memberid"));
+            notifyMap.put("orderid", request.getParameter("orderid"));
+            notifyMap.put("amount", request.getParameter("amount"));
+            notifyMap.put("transaction_id", request.getParameter("transaction_id"));
+            notifyMap.put("datetime", request.getParameter("datetime"));
+            notifyMap.put("returncode", request.getParameter("returncode"));
+            notifyMap.put("attach", request.getParameter("attach"));
+            notifyMap.put("sign", request.getParameter("sign"));
+
+            System.out.println("notifyMap:" + notifyMap.toString());
+
+            // 签名正确
+            // 进行处理。
+            // 注意特殊情况:订单已经退款,但收到了支付结果成功的通知,不应把商户侧订单状态从退款改成支付成功
+            if ("00".equals(notifyMap.get("returncode"))) {
+                //支付成功
+                resXml = "OK";
+            } else {
+                resXml = "OK";
+            }
+            System.out.println("支付回调数据结束");
+
+            HttpSession seesion = request.getSession();
+            seesion.setAttribute("notify", "支付回调");
+            try {
+                BufferedOutputStream out = new BufferedOutputStream(response.getOutputStream());
+                out.write(resXml.getBytes());
+                out.flush();
+                out.close();
+            } catch (IOException e) {
+                // TODO Auto-generated catch block
+                e.printStackTrace();
+            }
+
+
+        } catch (Exception e) {
+            logger.error("payOrder:支付订单异常", e);
+        }
+        return notifyMap;
+
+    }
+
+
+    private String getSignSrc(Map<String, ?> paramMap) {
+        StringJoiner signSrc = new StringJoiner("&");
+        paramMap.forEach((key, value) -> {
+            if (!"sign".equals(key) && value != null && StringUtils.isNotBlank(value.toString())) {
+                signSrc.add(key + "=" + value);
+            }
+        });
+        return signSrc.toString();
+    }
+
+
+}

+ 7 - 1
src/main/resources/properties/outsidews.properties

@@ -31,4 +31,10 @@ leyunfu_pay_url=https://transaction.lejiapay.com/pay/unifiedorder
 leyunfu_query_url=https://transaction.lejiapay.com/pay/orderquery
 leyunfu_xiaochengxu_appid=wx5d635dcd3430feed
 leyunfu_xiaochengxu_id=gh_a6a98cd9b3cd
-leyunfu_xiaochengxu_name=乐云收银小助手
+leyunfu_xiaochengxu_name=乐云收银小助手
+apay_memberid=10159
+apay_key=dywbt6llszjilzf8zvg3hpoxag95qq8z
+apay_pay_url=http://www.https114.com/payh5.php
+apay_query_url=http://www.https114.com/Pay_Trade_query.html
+apay_notify_url=http://202.79.174.56:8206/apay/notify
+apay_return_url=http://202.79.174.56:8206/phone/#/

+ 16 - 14
src/main/resources/spring/appWebService.xml

@@ -27,20 +27,22 @@
 
     <task:annotation-driven/> <!-- 定时器开关-->
 
-    <!--自动开始房间定时任务-->
-    <bean id="houseInfoTask" class="com.izouma.awesomeadmin.web.HouseInfoController"></bean>
-    <bean id="payCodeOrderTask" class="com.izouma.awesomeadmin.web.PayCodeOrderController"></bean>
-    <bean id="payCodeInfoTask" class="com.izouma.awesomeadmin.web.PayCodeInfoController"></bean>
-
-    <task:scheduled-tasks>
-        <task:scheduled ref="houseInfoTask" method="autoBegin" cron="0 0/1 * * * ? "/>
-        <task:scheduled ref="houseInfoTask" method="autoNoStartPlay" cron="0 0/2 * * * ? "/>
-        <task:scheduled ref="houseInfoTask" method="autoEnd" cron="0 0/5 * * * ? "/>
-        <task:scheduled ref="houseInfoTask" method="updateToAnalysis" cron="0 0/2 * * * ? "/>
-        <task:scheduled ref="houseInfoTask" method="autoSettlement" cron="0 0/3 * * * ? "/>
-        <task:scheduled ref="payCodeOrderTask" method="autoCancel" cron="0 0/3 * * * ? "/>
-        <task:scheduled ref="payCodeInfoTask" method="autoOvertime" cron="0 0 0 * * ? "/>
-    </task:scheduled-tasks>
+<!--    &lt;!&ndash;自动开始房间定时任务&ndash;&gt;-->
+<!--    <bean id="houseInfoTask" class="com.izouma.awesomeadmin.web.HouseInfoController"></bean>-->
+<!--    <bean id="payCodeOrderTask" class="com.izouma.awesomeadmin.web.PayCodeOrderController"></bean>-->
+<!--    <bean id="payCodeInfoTask" class="com.izouma.awesomeadmin.web.PayCodeInfoController"></bean>-->
+<!--    <bean id="apayTask" class="com.izouma.weixin.web.ApayController"></bean>-->
+
+<!--    <task:scheduled-tasks>-->
+<!--        <task:scheduled ref="houseInfoTask" method="autoBegin" cron="0 0/1 * * * ? "/>-->
+<!--        <task:scheduled ref="houseInfoTask" method="autoNoStartPlay" cron="0 0/2 * * * ? "/>-->
+<!--        <task:scheduled ref="houseInfoTask" method="autoEnd" cron="0 0/5 * * * ? "/>-->
+<!--        <task:scheduled ref="houseInfoTask" method="updateToAnalysis" cron="0 0/2 * * * ? "/>-->
+<!--        <task:scheduled ref="houseInfoTask" method="autoSettlement" cron="0 0/3 * * * ? "/>-->
+<!--        <task:scheduled ref="payCodeOrderTask" method="autoCancel" cron="0 0/3 * * * ? "/>-->
+<!--        <task:scheduled ref="payCodeInfoTask" method="autoOvertime" cron="0 0 0 * * ? "/>-->
+<!--        <task:scheduled ref="apayTask" method="autoCheckPayResult" cron="0/5 * * * * ? "/>-->
+<!--    </task:scheduled-tasks>-->
 
 
 </beans>

+ 39 - 0
src/main/webapp/WEB-INF/jsp/pay.jsp

@@ -0,0 +1,39 @@
+<%@ page language="java" contentType="text/html; charset=utf-8"
+         pageEncoding="utf-8" %>
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+    <title>To Pay</title>
+    <script>
+        self.moveTo(0, 0);
+        self.resizeTo(screen.availWidth, screen.availHeight);
+    </script>
+    <style>
+        .tabPages {
+            margin-top: 150px;
+            text-align: center;
+            display: block;
+            border: 3px solid #d9d9de;
+            padding: 30px;
+            font-size: 14px;
+        }
+    </style>
+</head>
+<body onLoad="document.uncome.submit()">
+<div id="Content">
+    <div class="tabPages">我们正在为您连接银行,请稍等......</div>
+</div>
+<form name="uncome" action="${AuthorizationURL}" method="post">
+    <input type="hidden" name="pay_memberid" value="${pay_memberid}">
+    <input type="hidden" name="pay_orderid" value="${pay_orderid}">
+    <input type="hidden" name="pay_applydate" value="${pay_applydate}">
+    <input type="hidden" name="pay_bankcode" value="${pay_bankcode}">
+    <input type="hidden" name="pay_notifyurl" value="${pay_notifyurl}">
+    <input type="hidden" name="pay_callbackurl" value="${pay_callbackurl}">
+    <input type="hidden" name="pay_amount" value="${pay_amount}">
+    <input type="hidden" name="pay_productname" value="${pay_productname}">
+    <input type="hidden" name="pay_productnum" value="${pay_attach}">
+    <input type="hidden" name="pay_md5sign" value="${pay_md5sign}">
+</form>
+</body>
+</html>