1. 程式人生 > >手把手教你--JAVA微信支付(H5支付)

手把手教你--JAVA微信支付(H5支付)

概述

之前說過,有時間把微信支付的H5支付講解下,一直拖了半年時間,最近的專案正好又溫習了支付功能,趁著熱乎,抓緊起來。

微信的H5支付,相對公眾號支付,容易了跟多,很多相似的東西,也有不同之處,這裡只介紹H5支付的關鍵點,其他內容請先去看我的微信支付(公眾號支付)那篇文章。

什麼是H5支付?

官網定義:要求商戶已有H5商城網站,並且已經過ICP備案。通過微信H5支付可以實現在非微信瀏覽器(如QQ瀏覽器、谷歌瀏覽器、Safari等)中使用微信支付的場景。ps:說白了就是在微信外的所有瀏覽器如UC瀏覽器來點選“微信支付”然後自動喚起微信客戶端來支付。

如果要測試支付的話,可以找個內網穿透的軟體如(花生殼或natapp)他們的域名都是ICP備註過的,然後從手機瀏覽器訪問微信支付的頁面。

開發步驟

一、準備工作

1.  預備好微信支付的“四大引數”--(預設已準備好)。

2.1  在“商戶平臺”-我的產品-中開通H5支付,大概半天左右的時間可以稽核通過。

 2.2在-開發配置中填寫H5支付域名,必須填寫,要不然不能支付。

二、開發流程

1.前端部分:H5支付前端的東西很少,就是點選“微信支付”,後端介面只返回一個用來跳轉的地址(下面還會提到),然後跳轉到這個地址就OK了,所以難點是後臺部分。

2.後端部分:後臺還是呼叫微信的“統一下單”介面,不過H5的“統一下單”所需引數少了很多。咱們看看都有那些引數:

其中必須的引數有:

1.appid--“四大引數”之一

2.mch_id--“四大引數”之一

3.nonce_str--隨機字串--用工具類獲取

4.body--商品描述

5.out_trade_no--商城的訂單號保持唯一

6.total_fee--支付金額單位:分

7.spbill_create_ip--ip地址

8.notify_url--支付成功回撥地址

9.trade_type--交易型別--只能用“MWEB”

10.scene_info--場景資訊值是個json字串,注意給值時轉義“雙引號”,例子:"{\"h5_info\":{\"type\":\"Wap\",\"wap_url\":" 可以填應該網站的URL地址 ",\"wap_name\": \"訂單支付\"}}"

11.sing--簽名加密

H5支付的“統一下單”引數就是這麼簡單,把上面的引數整理好POST傳送微信統一下單介面,返回的是個XML的字串,如果成功,返回的是類似如下(美化後的字串-微信後臺返回的是一行):

<xml>
  <return_code><![CDATA[SUCCESS]]></return_code>
  <return_msg><![CDATA[OK]]></return_msg>
  <appid><![CDATA[wx472b07299797774c]]></appid>
  <mch_id><![CDATA[1509488571]]></mch_id>
  <nonce_str><![CDATA[saPUVwW5nyHhB8tr]]></nonce_str>
  <sign><![CDATA[D0ACD36B851EEBBA97F0577CC752CCB9]]></sign>
  <result_code><![CDATA[SUCCESS]]></result_code>
  <prepay_id><![CDATA[wx28141313363954c5e9d84aeb3180413256]]></prepay_id>
  <trade_type><![CDATA[MWEB]]></trade_type>
  <mweb_url><![CDATA[https://wx.tenpay.com/cgi-bin/mmpayweb-bin/checkmweb?prepay_id=wx28141313363954c5e9d84aeb3180413256&package=90763707]]></mweb_url>
</xml>

裡面的 mweb_url就是上面提到的前端要的跳轉頁面了,如果你想在支付完後,跳到指定頁面可以在值的後面拼接指定redirect_url即可(要urlencode)如下:。

前端只需 location.href = mweb_url就可以開心的喚起微信來支付了

三、程式碼部分

1.前端程式碼

一般我們的程式碼需要處理公眾號H5支付的情況,js程式碼navigator.userAgent返回客戶端資訊如果裡面有"MicroMessenger"表示是微信瀏覽器,可以用公眾號支付,否則用H5支付,可以參考如下程式碼:

頁面有“微信支付”按鈕,點選執行pay()方法。

function pay() {
    if (navigator.userAgent.indexOf("MicroMessenger") != -1) {
        pay_weixin();//微信瀏覽器支付
    } else {
        pay_other();//其他瀏覽器H5支付
    }
}

function pay_other() {
    var url = WEB + "/pay/orders_other
    $.get(url,function(result) {
        location.href = result.mweb_url;
    });
}
function pay_weixin() {
	//公眾號支付方法
}

2.後端程式碼  裡面的工具類,可以參考公眾號支付裡面有。

/**
 * @Description H5調起微信支付微信瀏覽器外支付
 * @param request
 * @return Map
 */
 
@RequestMapping(value="orders_other", method = RequestMethod.GET)
@ResponseBody
public Map<String,String> orders_other(HttpServletRequest request) {
	try {
		//拼接下單地址引數
		Map<String, String> paraMap = new HashMap<String, String>();
		//獲取請求ip地址
		String ip = getIP(request);
		
		paraMap.put("appid", appid);  
		paraMap.put("mch_id", mchId);  
		paraMap.put("nonce_str", WXPayUtil.generateNonceStr());  
		paraMap.put("body", "XX商城-訂單結算");  
		paraMap.put("out_trade_no", "201810102938949");//商品的訂單號每次要唯一
		paraMap.put("total_fee", "1");
		paraMap.put("spbill_create_ip", ip);  
		paraMap.put("notify_url", "www.xxxxxx.com/pay/callback"));// 此路徑是微信伺服器呼叫支付結果通知路徑  
		paraMap.put("trade_type", "MWEB");
		paraMap.put("scene_info", "{\"h5_info\":{\"type\":\"Wap\",\"wap_url\":"隨意地址可以是公司官網地址",\"wap_name\": \"訂單支付\"}}");
		
		String sign = WXPayUtil.generateSignature(paraMap, paternerKey);
		paraMap.put("sign", sign);
		String xml = WXPayUtil.mapToXml(paraMap);//將所有引數(map)轉xml格式
		
		// 統一下單 https://api.mch.weixin.qq.com/pay/unifiedorder
		String unifiedorder_url = https://api.mch.weixin.qq.com/pay/unifiedorder;

		String xmlStr = HttpRequest.sendPost(unifiedorder_url, xml);//傳送post請求"統一下單介面"
		
		//以下內容是返回前端頁面的json資料
		String mweb_url = "";//跳轉連結
		if (xmlStr.indexOf("SUCCESS") != -1) {  
			Map<String, String> map = WXPayUtil.xmlToMap(xmlStr);
			mweb_url = (String) map.get("mweb_url");  
           
            //支付完返回瀏覽器跳轉的地址,如跳到檢視訂單頁面
			String redirect_url = "www.xxxxx.com/orders";
			String redirect_urlEncode =  URLEncoder.encode(redirect_url,"utf-8");//對上面地址urlencode
			mweb_url = mweb_url + "&redirect_url=" + redirect_urlEncode;//拼接返回地址
		}
		
		Map<String, String> payMap = new HashMap<String, String>();
		payMap.put("mweb_url", mweb_url);
		return  payMap;
	} catch (Exception e) {  
		_log.info("微信支付異常");
	}  
	return null;
	
}

返回給前端的結果如下所示:

H5支付就是這麼多了,可能不會一次調通,耐心看錯誤提示,祝早日支付成功。(完)