微信支付 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
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章