|
|
@@ -0,0 +1,267 @@
|
|
|
+package com.izouma.weixin.web;
|
|
|
+
|
|
|
+import com.github.kevinsawicki.http.HttpRequest;
|
|
|
+import com.izouma.awesomeadmin.constant.AppConstant;
|
|
|
+import com.izouma.awesomeadmin.model.MemberCoin;
|
|
|
+import com.izouma.awesomeadmin.model.MemberTicket;
|
|
|
+import com.izouma.awesomeadmin.model.ProductInfo;
|
|
|
+import com.izouma.awesomeadmin.service.MemberCoinService;
|
|
|
+import com.izouma.awesomeadmin.service.MemberTicketService;
|
|
|
+import com.izouma.awesomeadmin.service.ProductInfoService;
|
|
|
+import com.izouma.awesomeadmin.service.UserInfoService;
|
|
|
+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 com.izouma.weixin.service.WeiXinService;
|
|
|
+import com.izouma.weixin.wxpay.WXPayUtil;
|
|
|
+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.*;
|
|
|
+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.HashMap;
|
|
|
+import java.util.Map;
|
|
|
+import java.util.StringJoiner;
|
|
|
+import java.util.TreeMap;
|
|
|
+
|
|
|
+@Controller
|
|
|
+@RequestMapping("/lyf")
|
|
|
+public class LeYunFuController {
|
|
|
+
|
|
|
+ private static Logger logger = Logger.getLogger(LeYunFuController.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) {
|
|
|
+
|
|
|
+ try {
|
|
|
+ Map<String, String> m = notifyMap(request, response);
|
|
|
+ if (m != null && "SUCCESS".equals(m.get("result_code"))
|
|
|
+ && "SUCCESS".equals(m.get("payment_status"))) {//支付成功
|
|
|
+ String attach = m.get("attach");
|
|
|
+ JSONObject attachJson = new JSONObject(attach);
|
|
|
+
|
|
|
+ WxpayTemp wxpayTemp = new WxpayTemp();
|
|
|
+ wxpayTemp.setUserId(attachJson.getString("userId"));
|
|
|
+ wxpayTemp.setOrderId(attachJson.getString("productId"));
|
|
|
+ wxpayTemp.setCash(BigDecimal.valueOf(attachJson.getDouble("cash")));
|
|
|
+ wxpayTemp.setTotalAmount(BigDecimal.valueOf(attachJson.getInt("total") / 100.0));
|
|
|
+ wxpayTemp.setOutTradeNo(m.get("out_trade_no"));
|
|
|
+ wxpayTemp.setTransactionId(m.get("transaction_id"));
|
|
|
+
|
|
|
+ wxpayTempMapper.updateByOutTradeNo(wxpayTemp);
|
|
|
+
|
|
|
+ logger.info("buyProductInfo");
|
|
|
+ try {
|
|
|
+ ProductInfo productInfo = productInfoService.getProductInfoById(attachJson.getString("productId"));
|
|
|
+ if (productInfo != null) {
|
|
|
+ if (AppConstant.ProductType.RECHARGE == productInfo.getTypeFlag()) {//如果是充值类型
|
|
|
+
|
|
|
+ MemberTicket memberTicket = new MemberTicket();
|
|
|
+ memberTicket.setMoney(productInfo.getCoin());
|
|
|
+ memberTicket.setUserId(Integer.valueOf(attachJson.getString("userId")));
|
|
|
+ memberTicket.setRemark("购买" + productInfo.getProductName() + "套餐,充值");
|
|
|
+ memberTicket.setRechargeType(AppConstant.RechargeType.WEI_XIN);
|
|
|
+
|
|
|
+ memberTicketService.recharge(memberTicket);
|
|
|
+
|
|
|
+
|
|
|
+ } else {
|
|
|
+ //TODO 购买VIP
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ } catch (Exception e) {
|
|
|
+ logger.error("buyProductInfo", e);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ }
|
|
|
+ } catch (Exception e) {
|
|
|
+ logger.error("微信支付回调异常", e);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ return "SUCCESS";
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ @RequestMapping(value = "/unifiedOrder", method = RequestMethod.GET)
|
|
|
+ @ResponseBody
|
|
|
+ public String unifiedOrder(@RequestParam(required = true, value = "userId") String userId,
|
|
|
+ @RequestParam(required = true, value = "productId") String productId) {
|
|
|
+ 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();
|
|
|
+ String nonceStr = MbappUtil.create_nonce_str();
|
|
|
+
|
|
|
+
|
|
|
+ Map<String, String> params = new TreeMap<>();
|
|
|
+ params.put("mch_id", PropertiesFileLoader.getProperties("leyunfu_mch_id")); //商户号
|
|
|
+ params.put("nonce_str", nonceStr); //随机串
|
|
|
+ params.put("amount", String.valueOf(total)); //金额 单位分
|
|
|
+ params.put("body", productInfo.getProductName()); //商品或支付单简要描述
|
|
|
+ params.put("out_trade_no", out_trade_no); //商户系统内部的订单号
|
|
|
+ params.put("notify_url", PropertiesFileLoader.getProperties("leyunfu_return_url")); //接收支付结果异步通知回调地址
|
|
|
+ params.put("spbill_create_ip", MbappUtil.getHostAdderss()); //客户端IP
|
|
|
+ params.put("return_url", PropertiesFileLoader.getProperties("leyunfu_notify_url")); //页面回调地址
|
|
|
+ params.put("payment_type", "trade.weixin.app"); //支付类型
|
|
|
+ params.put("attach", attach.toString()); //附加数据
|
|
|
+
|
|
|
+
|
|
|
+ String signSrc = getSignSrc(params);
|
|
|
+ String sign = DigestUtils.md5Hex(signSrc + "&key=" + PropertiesFileLoader.getProperties("leyunfu_mch_secret"));
|
|
|
+ params.put("sign_type", "MD5"); //签名方式
|
|
|
+ params.put("sign", sign); //签名
|
|
|
+
|
|
|
+ String response = HttpRequest.post(PropertiesFileLoader.getProperties("leyunfu_pay_url"))
|
|
|
+ .form(params).body();
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 返回示例:
|
|
|
+ {"return_code":"SUCCESS",
|
|
|
+ "return_msg":"成功",
|
|
|
+ "mch_id":"100000007927",
|
|
|
+ "payment_type":"trade.qqpay.native",x
|
|
|
+ "code_img_url":"http://xxx"}
|
|
|
+ */
|
|
|
+
|
|
|
+
|
|
|
+ WxpayTemp wxpayTemp = new WxpayTemp();
|
|
|
+ wxpayTemp.setOrderId(productId);
|
|
|
+ wxpayTemp.setCash(BigDecimal.valueOf(cash));
|
|
|
+ wxpayTemp.setTotalAmount(BigDecimal.valueOf(total / 100.0));
|
|
|
+ wxpayTemp.setOutTradeNo(out_trade_no);
|
|
|
+ wxpayTemp.setTypeFlag(AppConstant.Aliapi.BUY);
|
|
|
+ wxpayTemp.setResultCode("WAIT_BUYER_PAY");
|
|
|
+ wxpayTempMapper.insertSelective(wxpayTemp);
|
|
|
+
|
|
|
+ return response;
|
|
|
+
|
|
|
+ } catch (Exception e) {
|
|
|
+ logger.error("leyunfu下单失败", 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 = "SUCCESS";
|
|
|
+ try {
|
|
|
+
|
|
|
+
|
|
|
+ notifyMap.put("result_code", request.getParameter("result_code"));
|
|
|
+ notifyMap.put("return_msg", request.getParameter("return_msg"));
|
|
|
+ notifyMap.put("mch_id", request.getParameter("mch_id"));
|
|
|
+ notifyMap.put("payment_status", request.getParameter("payment_status"));
|
|
|
+ notifyMap.put("transaction_id", request.getParameter("transaction_id"));
|
|
|
+ notifyMap.put("out_trade_no", request.getParameter("out_trade_no"));
|
|
|
+ notifyMap.put("payment_type", request.getParameter("payment_type"));
|
|
|
+ notifyMap.put("attach", request.getParameter("attach"));
|
|
|
+ notifyMap.put("fee_type", request.getParameter("fee_type"));
|
|
|
+ notifyMap.put("nonce_str", request.getParameter("nonce_str"));
|
|
|
+ notifyMap.put("amount", request.getParameter("amount"));
|
|
|
+ notifyMap.put("sign", request.getParameter("sign"));
|
|
|
+
|
|
|
+ // 签名正确
|
|
|
+ // 进行处理。
|
|
|
+ // 注意特殊情况:订单已经退款,但收到了支付结果成功的通知,不应把商户侧订单状态从退款改成支付成功
|
|
|
+ if ("SUCCESS".equals(notifyMap.get("result_code"))) {
|
|
|
+ //支付成功
|
|
|
+ resXml = "SUCCESS";
|
|
|
+ } else {
|
|
|
+ resXml = "SUCCESS";
|
|
|
+ }
|
|
|
+ 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();
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+}
|