Browse Source

聚合支付

qzyReal 3 years ago
parent
commit
1fa559f62b

+ 7 - 4
app/apis/api.js

@@ -110,12 +110,15 @@ export default {
 	getUnitList() {
 		return ajax.get('/TbUnit/getList')
 	},
-	getPrePay(data) {
-		return ajax.get('/wx/pre-pay', data)
-	},
 	// getPrePay(data) {
-	// 	return ajax.get('/jh/init-pay', data)
+	// 	return ajax.get('/wx/pre-pay', data)
 	// },
+	getPrePay(data) {
+		return ajax.get('/jh/init-pay', data)
+	},
+	checkPayResult(data){
+		return ajax.get('/jh/check-pay-result', data)
+	},
 	getRedirectUrl(data) {
 		return ajax.get('/wx/getRedirectUrl', data)
 	},

+ 1 - 1
app/manifest.json

@@ -85,7 +85,7 @@
     "vueVersion" : "2",
     "h5" : {
         "router" : {
-            "base" : "/h5/",
+            "base" : "/test/",
             "mode" : "history"
         },
         "devServer" : {

+ 17 - 1
app/pages/wx/pay.vue

@@ -220,15 +220,31 @@
 						success: function(res) {
 							if (res.errMsg === "chooseWXPay:ok") {
 								that.$common.toast('支付成功')
+								//that.checkPayResult(data.outTradeNo);
 								that.cars = [];
 								that.item.list = [];
 								that.total = 0
-								// wx.closeWindow();
 							}
+						},
+						complete:function(res){
+							that.checkPayResult(data.outTradeNo);
 						}
 					});
 				})
 			},
+			checkPayResult(outTradeNo) {
+				this.$common.showLoading('正在查询结果...')
+				this.$api.checkPayResult({
+					outTradeNo: outTradeNo
+				}).then(resp => {
+					let data = resp.data;
+					if (data.orderStatus == 'SUCCESS' || data.orderStatus == 'FINISH') {
+						this.$common.toast('支付成功')
+					} else {
+						this.$common.toast('支付失败')
+					}
+				})
+			},
 			payTypeChange(value) {
 
 			},

+ 16 - 4
app/pages/wx/payOrder.vue

@@ -176,7 +176,7 @@
 					tradeType: "JSAPI",
 					openid: this.wx.openid
 				}
-				p.desc="A1-业务费用"
+				p.desc = "A1-业务费用"
 				this.$api.getPrePay(this.$common.removeNull(p)).then(resp => {
 					let data = resp.data;
 					let that = this;
@@ -189,13 +189,25 @@
 						paySign: data.paySign, // 支付签名
 						success: function(res) {
 							if (res.errMsg === "chooseWXPay:ok") {
-								that.$common.toast('支付成功')
-								// wx.closeWindow();
+								that.checkPayResult(data.outTradeNo);
 							}
 						}
 					});
 				})
-			}
+			},
+			checkPayResult(outTradeNo) {
+				this.$common.showLoading('正在确认结果...')
+				this.$api.checkPayResult({
+					outTradeNo: outTradeNo
+				}).then(resp => {
+					let data = resp.data;
+					if (data.orderStatus == 'SUCCESS' || data.orderStatus == 'FINISH') {
+						this.$common.toast('支付成功')
+					} else {
+						this.$common.toast('支付失败')
+					}
+				})
+			},
 		}
 	}
 </script>

+ 1 - 1
sp-server/app.pid

@@ -1 +1 @@
-25324
+12244

+ 3 - 0
sp-server/src/main/java/com/pj/api/jh/api/JhController.java

@@ -1,6 +1,8 @@
 package com.pj.api.jh.api;
 
 import cn.hutool.core.util.XmlUtil;
+import cn.hutool.json.JSONUtil;
+import cn.hutool.log.StaticLog;
 import com.pj.api.jh.bo.JhNotifyBO;
 import com.pj.api.jh.service.JhService;
 import com.pj.utils.sg.AjaxJson;
@@ -38,6 +40,7 @@ public class JhController {
     }
     @RequestMapping(value = "notify")
     public String notifyResult(JhNotifyBO bo) {
+        StaticLog.info("聚合支付回调:{}", JSONUtil.toJsonStr(bo));
         jhService.notifyResult(bo);
         return "SUCCESS";
     }

+ 2 - 0
sp-server/src/main/java/com/pj/api/jh/bo/JhNotifyBO.java

@@ -1,9 +1,11 @@
 package com.pj.api.jh.bo;
 
 import lombok.Data;
+import lombok.experimental.Accessors;
 
 import java.io.Serializable;
 @Data
+@Accessors(chain = true)
 public class JhNotifyBO implements Serializable {
     private String businessMerchantNo;
     private String orderPrice;

+ 10 - 8
sp-server/src/main/java/com/pj/api/jh/service/JhService.java

@@ -93,8 +93,8 @@ public class JhService {
         String result = jhHttpUtils.postJson(initPayUrl, jsonParam);
         StaticLog.info("调用聚合支付返回:{}", result);
         JSONObject jsonResult = JSONUtil.parseObj(result);
-        if (StrUtil.equals("0000", jsonResult.get("resultCode").toString())) {
-            JSONObject payMessage = JSONUtil.parseObj(jsonResult.get("payMessage").toString());
+        if (StrUtil.equals("0000", jsonResult.getStr("resultCode"))) {
+            JSONObject payMessage = JSONUtil.parseObj(jsonResult.getStr("payMessage"));
             String p = payMessage.getStr("package");
             Map<String, String> r = wxService.getPayP(payMessage.getStr("timeStamp"), payMessage.getStr("nonceStr"), openid, p);
             StaticLog.info("re:{}", JSONUtil.toJsonStr(r));
@@ -111,24 +111,26 @@ public class JhService {
         throw new Exception("支付信息有误");
     }
 
-
-    public JSONObject checkPayResult(String outTradeNo) {
-        String url = jhConfig.getServerUrl() + "/uaps-web-gateway/query/singleOrder";
+    public Map<String, Object> buildCheckParams(String outTradeNo) {
         Map<String, Object> params = new HashMap<>();
         params.put("businessMerchantNo", jhConfig.getBusinessMerchantNo());
         params.put("outTradeNo", outTradeNo);
         String paySecrit = jhConfig.getPaySecret();
         String sign = MerchantApiUtil.getSign(params, paySecrit);
         params.put("sign", sign);
+        return params;
+    }
+
+    public JSONObject checkPayResult(String outTradeNo) {
+        String url = jhConfig.getServerUrl() + "/uaps-web-gateway/query/singleOrder";
+        Map<String, Object> params = buildCheckParams(outTradeNo);
         String result = jhHttpUtils.postForm(url, params);
-        StaticLog.info("调用聚合支付查询支付接口返回:{}", result);
         return JSONUtil.parseObj(result);
     }
 
     @Async
     public void notifyResult(JhNotifyBO bo) {
-        StaticLog.info("聚合支付回调:{}", JSONUtil.toJsonStr(bo));
-        if (!"SUCCESS".equals(bo.getTradeStatus().toUpperCase())) {
+        if (!"SUCCESS".equals(bo.getTradeStatus().toUpperCase()) && !"FINISH".equals(bo.getTradeStatus().toUpperCase())) {
             return;
         }
         NotifyBO notifyBO = new NotifyBO();

+ 20 - 0
sp-server/src/main/java/com/pj/api/jh/task/CheckPayStatusTask.java

@@ -0,0 +1,20 @@
+package com.pj.api.jh.task;
+
+import cn.hutool.extra.spring.SpringUtil;
+import com.pj.current.task.Task;
+import com.pj.project.tb_order.TbOrder;
+import com.pj.project.tb_order.TbOrderService;
+import lombok.extern.slf4j.Slf4j;
+
+@Slf4j
+public class CheckPayStatusTask extends Task {
+    public CheckPayStatusTask(String id, long delayInMilliseconds) {
+        super(id, delayInMilliseconds);
+    }
+
+    @Override
+    public void run() {
+        TbOrderService tbOrderService = SpringUtil.getBean(TbOrderService.class);
+        tbOrderService.check();
+    }
+}

+ 20 - 0
sp-server/src/main/java/com/pj/api/jh/utils/JhHttpUtils.java

@@ -1,11 +1,15 @@
 package com.pj.api.jh.utils;
 
+import cn.hutool.core.util.StrUtil;
+import cn.hutool.http.HttpException;
 import cn.hutool.http.HttpUtil;
 import cn.hutool.json.JSONObject;
 import cn.hutool.json.JSONUtil;
+import com.pj.project4sp.global.BusinessException;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.retry.annotation.Backoff;
 import org.springframework.retry.annotation.Retryable;
+import org.springframework.scheduling.annotation.Async;
 import org.springframework.stereotype.Component;
 
 import java.util.Map;
@@ -36,4 +40,20 @@ public class JhHttpUtils {
         log.info("接口返回:{},{}", url, resp);
         return resp;
     }
+
+    @Retryable(maxAttempts = 15, backoff = @Backoff(delay = 3000, maxDelay = 10000))
+    public JSONObject checkStatus(String url, Map<String, Object> params) {
+        log.info("检查支付状态:{},{}", url, JSONUtil.toJsonStr(params));
+        String resp = HttpUtil.createPost(url)
+                .setConnectionTimeout(3000)
+                .setReadTimeout(2000)
+                .form(params)
+                .execute().body();
+        log.info("检查支付状态返回:{},{}", url, resp);
+        JSONObject result = JSONUtil.parseObj(resp);
+        if (!StrUtil.equals(result.getStr("resultCode"), "0000")) {
+            throw new BusinessException(result.getStr("errMsg"));
+        }
+        return result;
+    }
 }

+ 4 - 5
sp-server/src/main/java/com/pj/api/wx/service/WxService.java

@@ -2,6 +2,7 @@ package com.pj.api.wx.service;
 
 import cn.hutool.cache.CacheUtil;
 import cn.hutool.cache.impl.TimedCache;
+import cn.hutool.core.date.DateUtil;
 import cn.hutool.core.net.URLDecoder;
 import cn.hutool.core.util.NumberUtil;
 import cn.hutool.core.util.RandomUtil;
@@ -181,15 +182,14 @@ public class WxService {
         }
     }
 
-    TimedCache<String, Integer> NotifyCache = CacheUtil.newTimedCache(360000);
 
     @Async
-    public void WxNotify(NotifyBO notifyBO)  {
+    public void WxNotify(NotifyBO notifyBO) {
         String outTradeNo = notifyBO.getOutTradeNo();
-        if (NotifyCache.get(outTradeNo) != null) {
+        if (RedisUtil.get(outTradeNo) != null) {
             return;
         }
-        NotifyCache.put(outTradeNo, 1);
+        RedisUtil.setByHour(outTradeNo, DateUtil.now(), 2);
         String total_fee = notifyBO.getTotalFee();
         BigDecimal money = new BigDecimal(total_fee).divide(new BigDecimal(100), 2, BigDecimal.ROUND_UP);
         String attachStr = notifyBO.getAttach();
@@ -234,7 +234,6 @@ public class WxService {
     }
 
 
-
     public String getRedirectUrl(String path, String state) {
         String redirectUrl = myConfig.getWebDomain() + path;
         String encoderUrl = URLDecoder.decode(redirectUrl, Charset.forName("utf-8"));

+ 6 - 8
sp-server/src/main/java/com/pj/current/SaPlusStartup.java

@@ -4,7 +4,9 @@ import java.net.InetAddress;
 import java.text.SimpleDateFormat;
 import java.util.Date;
 
+import com.pj.api.jh.task.CheckPayStatusTask;
 import com.pj.current.config.WxConfig;
+import com.pj.current.task.TaskService;
 import com.pj.current.task.TokenTask;
 import com.pj.project.tb_order.TbOrderService;
 import lombok.extern.slf4j.Slf4j;
@@ -41,19 +43,15 @@ public class SaPlusStartup implements CommandLineRunner {
     TokenTask tokenTask;
     @Resource
     WxConfig wxConfig;
+
     @Resource
-    TbOrderService tbOrderService;
+    TaskService taskService;
 
     @Override
-    public void run(String... args) throws Exception {
+    public void run(String... args){
         tokenTask.run();
         threadPoolTaskScheduler.scheduleAtFixedRate(tokenTask, wxConfig.getFlushSecond() * 1000);
-        String ip = InetAddress.getLocalHost().getHostAddress();
-        String str = "\n------------- " + applicationName + " (" + active + ") 启动成功 --by " + getNow() + " -------------\n" +
-                "\t- Local:   http://localhost:" + port + path + "\n" +
-                "\t- Local2:  http://127.0.0.1:" + port + path + "\n" +
-                "\t- Network: http://" + ip + ":" + port + path + "\n";
-        log.info("启动信息:{}",str);
+        taskService.addTask(new CheckPayStatusTask("=========检查正在支付订单状态========",2000L));
     }
 
 

+ 0 - 33
sp-server/src/main/java/com/pj/project/tb_order/TbOrderController.java

@@ -26,40 +26,7 @@ public class TbOrderController {
 	@Autowired
 	TbOrderService tbOrderService;
 
-	/** 增 */  
-	@RequestMapping("add")
-	@SaCheckPermission(TbOrder.PERMISSION_CODE)
-	@Transactional(rollbackFor = Exception.class)
-	public AjaxJson add(TbOrder t){
-		tbOrderService.add(t);
-		t = tbOrderService.getById(SP.publicMapper.getPrimarykey());
-		return AjaxJson.getSuccessData(t);
-	}
 
-	/** 删 */  
-	@RequestMapping("delete")
-	@SaCheckPermission(TbOrder.PERMISSION_CODE)
-	public AjaxJson delete(Long id){
-		int line = tbOrderService.delete(id);
-		return AjaxJson.getByLine(line);
-	}
-	
-	/** 删 - 根据id列表 */  
-	@RequestMapping("deleteByIds")
-	@SaCheckPermission(TbOrder.PERMISSION_CODE)
-	public AjaxJson deleteByIds(){
-		List<Long> ids = SoMap.getRequestSoMap().getListByComma("ids", long.class);
-		int line = SP.publicMapper.deleteByIds(TbOrder.TABLE_NAME, ids);
-		return AjaxJson.getByLine(line);
-	}
-	
-	/** 改 */  
-	@RequestMapping("update")
-	@SaCheckPermission(TbOrder.PERMISSION_CODE)
-	public AjaxJson update(TbOrder t){
-		int line = tbOrderService.update(t);
-		return AjaxJson.getByLine(line);
-	}
 
 	/** 查 - 根据id */  
 	@RequestMapping("getById")

+ 0 - 26
sp-server/src/main/java/com/pj/project/tb_order/TbOrderMapper.java

@@ -17,33 +17,7 @@ import org.springframework.stereotype.Repository;
 @Repository
 public interface TbOrderMapper extends BaseMapper <TbOrder> {
 
-	/**
-	 * 增  
-	 * @param t 实体对象 
-	 * @return 受影响行数 
-	 */
-	int add(TbOrder t);
-
-	/**
-	 * 删  
-	 * @param id 要删除的数据id  
-	 * @return 受影响行数 
-	 */
-	int delete(Long id);	 
-
-	/** 
-	 * 改  
-	 * @param t 实体对象 
-	 * @return 受影响行数 
-	 */
-	int update(TbOrder t);
 
-	/** 
-	 * 查 - 根据id  
-	 * @param id 要查询的数据id 
-	 * @return 实体对象 
-	 */
-	TbOrder getById(Long id);	 
 
 	/**
 	 * 查集合 - 根据条件(参数为空时代表忽略指定条件)

+ 1 - 33
sp-server/src/main/java/com/pj/project/tb_order/TbOrderMapper.xml

@@ -2,33 +2,6 @@
 <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
 <mapper namespace="com.pj.project.tb_order.TbOrderMapper">
 
-	<!-- 增 [G] -->
-	<insert id="add">
-		insert into 
-		tb_order (id, out_trade_no, attach, order_time, openid, order_status, price) 
-		values (#{id}, #{outTradeNo}, #{attach}, #{orderTime}, #{openid}, #{orderStatus}, #{price}) 
-	</insert>
-
-	<!-- 删 -->
-	<delete id="delete">
-		delete from tb_order 
-		where id = #{id}
-	</delete>
-
-	<!-- 改 [G] -->
-	<update id="update">
-		update tb_order set
-		id = #{id}, 
-		out_trade_no = #{outTradeNo}, 
-		attach = #{attach}, 
-		order_time = #{orderTime}, 
-		openid = #{openid}, 
-		order_status = #{orderStatus}, 
-		price = #{price}
-		where id = #{id}
-	</update>
-
-
 	<!-- ================================== 查询相关 ================================== -->
 	<!-- select id, out_trade_no, attach, order_time, openid, order_status, price from tb_order  -->
 	
@@ -48,12 +21,7 @@
 		select * 
 		from tb_order 
 	</sql>
-	
-	<!-- 查 - 根据id -->
-	<select id="getById" resultMap="model">
-		<include refid="select_sql"></include>
-		where id = #{id}
-	</select>
+
 	
 	<!-- 查集合 - 根据条件(参数为空时代表忽略指定条件) [G] -->
 	<select id="getList" resultMap="model">

+ 61 - 30
sp-server/src/main/java/com/pj/project/tb_order/TbOrderService.java

@@ -1,52 +1,83 @@
 package com.pj.project.tb_order;
 
 import java.util.List;
+import java.util.Map;
 
+import cn.hutool.core.util.StrUtil;
+import cn.hutool.json.JSONObject;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.extension.service.IService;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.pj.api.jh.bo.JhNotifyBO;
+import com.pj.api.jh.service.JhService;
+import com.pj.api.jh.utils.JhHttpUtils;
+import com.pj.api.wx.bo.NotifyBO;
+import com.pj.api.wx.service.WxService;
+import com.pj.current.config.JhConfig;
 import com.pj.project.tb_business.TbBusiness;
 import com.pj.project.tb_business.TbBusinessMapper;
 import com.pj.utils.so.SoMap;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Lazy;
+import org.springframework.scheduling.annotation.Async;
 import org.springframework.stereotype.Service;
 
 import com.pj.utils.sg.*;
 
+import javax.annotation.Resource;
+
 /**
  * Service: tb_order -- 临时订单表
- * @author qzy 
+ *
+ * @author qzy
  */
 @Service
 public class TbOrderService extends ServiceImpl<TbOrderMapper, TbOrder> implements IService<TbOrder> {
 
-	/** 底层 Mapper 对象 */
-	@Autowired
-	TbOrderMapper tbOrderMapper;
-
-	/** 增 */
-	int add(TbOrder t){
-		return tbOrderMapper.add(t);
-	}
-
-	/** 删 */
-	int delete(Long id){
-		return tbOrderMapper.delete(id);
-	}
-
-	/** 改 */
-	int update(TbOrder t){
-		return tbOrderMapper.update(t);
-	}
-
-	/** 查 */
-	TbOrder getById(Long id){
-		return tbOrderMapper.getById(id);
-	}
-
-	/** 查集合 - 根据条件(参数为空时代表忽略指定条件) */  
-	List<TbOrder> getList(SoMap so) {
-		return tbOrderMapper.getList(so);	
-	}
-	
+    /**
+     * 底层 Mapper 对象
+     */
+    @Autowired
+    TbOrderMapper tbOrderMapper;
+    @Resource
+    JhHttpUtils jhHttpUtils;
+    @Resource
+    JhConfig jhConfig;
+    @Resource
+    @Lazy
+    JhService jhService;
+
+
+    /**
+     * 查集合 - 根据条件(参数为空时代表忽略指定条件)
+     */
+    List<TbOrder> getList(SoMap so) {
+        return tbOrderMapper.getList(so);
+    }
+
+    @Async
+    public void check() {
+        QueryWrapper<TbOrder> ew = new QueryWrapper<>();
+        ew.eq("order_status", "WAITING_PAYMENT");
+        List<TbOrder> list = this.list(ew);
+        String url = jhConfig.getServerUrl() + "/uaps-web-gateway/query/singleOrder";
+        list.forEach(tbOrder -> {
+            Map<String, Object> params = jhService.buildCheckParams(tbOrder.getOutTradeNo());
+            JSONObject result = jhHttpUtils.checkStatus(url, params);
+            String orderStatus = result.getStr("orderStatus");
+            if (StrUtil.equals(orderStatus, "SUCCESS") || StrUtil.equals(orderStatus, "FINISH")) {
+                tbOrder.setOrderStatus(orderStatus)
+                        .setTransactionId(result.getStr("bankTrxNo"))
+                        .setCompleteDate(result.getStr("completeDate"));
+                this.updateById(tbOrder);
+                JhNotifyBO notifyBO = new JhNotifyBO();
+                notifyBO.setAttach(tbOrder.getAttach()).setBankTrxNo(tbOrder.getTransactionId()).setTradeStatus(orderStatus)
+                        .setOutTradeNo(tbOrder.getOutTradeNo()).setOrderPrice(tbOrder.getPrice());
+                jhService.notifyResult(notifyBO);
+            } else if (StrUtil.equals(orderStatus, "FAILED")) {
+                this.removeById(tbOrder.getId());
+            }
+        });
+    }
 
 }