微信支付 h5支付

近期,公司内部移动办公系统要实现微信支付模块,用于员工缴费,微信支付页面用h5开发,嵌入移动办公系统,后台是java。

大致流程如下:
1.前端页面生成订单(确定支付金额、订单详情,此步骤根据业务而定)

2.调用后台预支付接口,该接口需要请求微信统一支付接口,拿到返回链接,直接将该链接(深度链技术,可以理解为微信的协议,用于唤醒微信)返回给前端

3.前端拿到连接后,直接open即可,就会唤醒微信。

4.如果支付成功,微信会回调后台提供的支付通知接口,次接口接收微信回调和修改本地订单状态。

代码如下

 	/** 预支付
     * 发起支付
     */
    @SuppressWarnings("unchecked")
	@PostMapping(value = "/pay")
    @Transactional(propagation = Propagation.REQUIRED,rollbackFor = Exception.class)
    public Map<String, String> pay(HttpServletRequest request,@RequestBody Map<String,Object> param) {
    	String userCode = String.valueOf(String.valueOf(param.get("userCode")));
    	String ym = String.valueOf(String.valueOf(param.get("ym")));
    	
    	Order order = orderMapper.selectOrderByThisYear(ym,userCode);
    	
    	Map<String,String> map = new HashMap<>();
    	map.put("result_code", "fail");
    	
    	
    	if(Objects.isNull(order)) {
    		map.put("msg", "未查询到可支付的订单,无需支付");
			return map;
    	}
  
		if(order.getStatus() == 3 || order.getStatus() == 2) { //支付成功
			map.put("msg", "订单已经完成,无需重复支付");
			return map;
    	}
		
		EntityWrapper<Order> wrapper = new EntityWrapper<>();
    	wrapper.eq("user_id", userCode).eq("period", ym);
    	
    	Order entity = new Order();
    	entity.setUserId(userCode);
    	entity.setOrderNo("");
		entity.setStatus(1);
		
		int flag = 0;
		
		if(order.getStatus() == 0  || order.getStatus() == 4) {//交易关闭、取消
			flag = 1;
    	}
		
		if(!Objects.isNull(order.getCreateTime()) && order.getStatus() == 1 && System.currentTimeMillis() - order.getCreateTime().getTime() >= 5 * 60 * 1000 ) {//超时
			flag = 2;
    	} 
		
		if(flag != 0) {
			orderMapper.update(entity, wrapper);
			orderMapper.updateDateTime(ym,userCode);
			
			if(flag == 1) {
				map.put("msg", "订单异常,请重新发起支付");
			}else if(flag == 2) {
				map.put("msg", "订单超时,请重新发起支付");
			}
			return map;
		}
		
    	//更新订单创建时间和生成订单号
    	entity.setCreateTime(new Date());
    	entity.setOrderNo(System.currentTimeMillis() + "");
    	orderMapper.update(entity, wrapper);
    	
    	SortedMap<Object, Object> packageParams = new TreeMap<Object, Object>();
		String currTime = PayToolUtil.getCurrTime();
		String strTime = currTime.substring(8, currTime.length());
		String strRandom = PayToolUtil.buildRandom(4) + "";
		String nonce_str = strTime + strRandom;
    	
    	packageParams.put("appid", WXConfig.appid);
    	packageParams.put("mch_id", WXConfig.mch_id);
    	packageParams.put("nonce_str", nonce_str);
    	packageParams.put("body", order.getDesc());
    	packageParams.put("out_trade_no", entity.getOrderNo()); 
    	Double totalFee = order.getPayment().doubleValue() * 100;
    	packageParams.put("total_fee",  totalFee.intValue() + ""); // 价格的单位为分
    	packageParams.put("spbill_create_ip",getIP(request));
    	packageParams.put("notify_url", WXConfig.notify_url);
    	packageParams.put("trade_type", WXConfig.tradeType);
 
    	String sign = PayToolUtil.createSign("UTF-8", packageParams, WXConfig.key);
    	packageParams.put("sign", sign);
    	String requestXML = PayToolUtil.getRequestXml(packageParams);
    	String resXml = HttpUtil.postData(WXConfig.unifiedorder_url,
    			requestXML);
    	try {
    		map = XMLUtil.doXMLParse(resXml);
    		/*System.out.println(resXml);*/
    		if(!map.get("return_code").equals("FAIL")) {
    			//确认支付过后跳的地址,需要经过urlencode处理,必须为h5支付绑定的域名
        		String urlString = URLEncoder.encode("http:\\xxxxx.com/index.html#/success?userCode=" + userCode, "GBK");//该地址为支付成功后回调的页面,该页面需要轮训订单详情接口;;判断订单状态
        		String mweb_url = map.get("mweb_url") + "&redirect_url=" + urlString;
        		map.clear();
        		map.put("result_code", "success");
        		//mweb_url就是唤醒微信的深度连
        		map.put("mweb_url", mweb_url);
    		}else {
    			map.put("result_code", "fail");
    		}
    	} catch (JDOMException e) {
    		e.printStackTrace();
    	} catch (IOException e) {
    		e.printStackTrace();
    	}
		return map;
    }
    	

回调方法


  /**
   * 异步回调
   */
  @PostMapping(value = "/notify")
  public Boolean notify(@RequestBody String notifyData) throws Exception {
  	try {
  		Map<String,String> doXMLParse = XMLUtil.doXMLParse(notifyData);
      	
  		String string = doXMLParse.get("out_trade_no");
      	EntityWrapper<Order> wrapper = new EntityWrapper<>();
      	wrapper.eq("order_no", string);

      	Order order = orderService.selectOne(wrapper);
  		order.setStatus(3);        	
  		
  		orderMapper.update(order, wrapper);
      	 return true;
  	} catch (Exception e) {
  		e.printStackTrace();
  		 return false;
  	} 
  }

效果展示

在这里插入图片描述

在这里插入图片描述

发布了17 篇原创文章 · 获赞 41 · 访问量 6287
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章