1. 程式人生 > >微信h5支付,微信外瀏覽器支付實現

微信h5支付,微信外瀏覽器支付實現

h5支付的資料還真叫個少,不過找到一個好的方式,按著大神的步驟去實現還真就ok了,話不多說,開始準備吧

微信支付的坑很多,特別在平臺的設定上

然後設定授權域名,在介面設定中就能找到,包括js介面安全域名和網頁授權域名:

這個點進去之後會看到最下面兩個:js介面安全域名,這個可以設定三個,就是填寫你訪問頁面的域名即可

下面這個是網頁授權回撥域名,用於你支付完畢後回撥的域名,將下載的檔案放到伺服器的根路徑,確保可以訪問,我是放在tomcat的webapp中

設定的域名要備案

然後設定支付域名,設定路徑:商戶平臺-->產品中心-->開發配置中設定域名,

如果是公眾號支付就設定對應的,要注意的是公眾號支付授權域名為請求的前一級,比如你要請求http://xxx/wx/abc,那麼你就設定http://xxx/wx即可

h5支付設定h5域名就行,不用字尾,直接寫你要設定的域名

partnerkey需要在API中設定,需要安裝證書,這個根據提示安裝即可,自行設定32位partnerkey

我用的是一個大神的IJPay的springboot版,寫成自己的SpringMVC版,後續都會給連結

主要用的的是封裝的jar,現在maven庫中已經有了,用0.8版本以上的吧,這樣jdk相容問題已經解決

我將基本會用到的jar貼一下

<dependency>
      <groupId>com.jfinal</groupId>
      <artifactId>enjoy</artifactId>
      <version>3.2</version>
    </dependency>

    <!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind -->
    <dependency>
      <groupId>com.fasterxml.jackson.core</groupId>
      <artifactId>jackson-databind</artifactId>
      <version>2.6.0</version>
    </dependency>

    <dependency>
      <groupId>com.github.binarywang</groupId>
      <artifactId>weixin-java-mp</artifactId>
      <version>2.8.0</version>
    </dependency>

    <dependency>
      <groupId>com.jfinal</groupId>
      <artifactId>jfinal</artifactId>
      <version>3.2</version>
    </dependency>

    <dependency>
      <groupId>com.jfinal</groupId>
      <artifactId>jfinal-weixin</artifactId>
      <version>1.9</version>
    </dependency>

    <dependency>
      <groupId>com.github.javen205</groupId>
      <artifactId>IJPay</artifactId>
      <version>1.0</version>
    </dependency>

    <dependency>
      <groupId>com.alibaba</groupId>
      <artifactId>fastjson</artifactId>
      <version>1.2.37</version>
    </dependency>


    <!-- okhttp2 -->
    <dependency>
      <groupId>com.squareup.okhttp</groupId>
      <artifactId>okhttp</artifactId>
      <version>2.7.5</version>
    </dependency>
    <dependency>
      <groupId>com.squareup.okhttp3</groupId>
      <artifactId>okhttp</artifactId>
      <version>3.8.0</version>
    </dependency>
    <dependency>
      <groupId>com.squareup.okio</groupId>
      <artifactId>okio</artifactId>
      <version>1.11.0</version>
    </dependency>

著手程式碼

public static WxPayApiConfig getApiConfig() {
		return WxPayApiConfig.New()
				       .setAppId(appID)
				       .setMchId(mchID)
				       .setPaternerKey(partnerKey)
				       .setPayModel(WxPayApiConfig.PayModel.BUSINESSMODEL);
	}
		/**
	 * 微信H5 支付--------------------好使
	 * 注意:必須再web頁面中發起支付且域名已新增到開發配置中
	 */
	@RequestMapping(value ="/pay.do",method = {RequestMethod.POST,RequestMethod.GET})
	public void wapPay(HttpServletRequest request,HttpServletResponse response){
		System.out.println("--pay start--");
                String notify_url = "https://你的域名/pay_notify.do";//這是回撥地址,方法在下面
		//獲取ip

        String ip = IpKit.getRealIp(request);
		if (com.jpay.ext.kit.StrKit.isBlank(ip)) {
			ip = "127.0.0.1";
		}
		
		H5ScencInfo sceneInfo = new H5ScencInfo();
		
		H5 h5_info = new H5();
		h5_info.setType("Wap");
		//此域名必須在商戶平臺--"產品中心"--"開發配置"中新增
		
		h5_info.setWap_url("http://www.xxx.com");
		h5_info.setWap_name("公司官網");
		sceneInfo.setH5_info(h5_info);
		WxPayApiConfig wxPayApiConfig=getApiConfig();
		Map<String, String> params=WxPayApiConfig.New()
				                           .setAppId(appID)
				                           .setMchId(mchID)
				                           .setBody("H5支付測試")
				                           .setSpbillCreateIp(ip)
				                           .setTotalFee("520")
				                           .setTradeType(WxPayApi.TradeType.MWEB)
				                           .setNotifyUrl(notify_url)
				                           .setPaternerKey(partnerKey)
				                           .setOutTradeNo(String.valueOf(System.currentTimeMillis()))
				                           .setSceneInfo("{\"h5_info\": {\"type\":\"IOS\",\"app_name\": \"mtgg\",\"package_name\": \"com.tencent.tmgp.sgame\"}}")
				                           .setAttach("H5支付測試")
				                           .build();
		String xmlResult = WxPayApi.pushOrder(false,params);
		Map<String, String> result = PaymentKit.xmlToMap(xmlResult);
		//返回結果
		String return_code = result.get("return_code");
		String return_msg = result.get("return_msg");
		if (!PaymentKit.codeIsOK(return_code)) {
			log.error("return_code>"+return_code+" return_msg>"+return_msg);
			throw new RuntimeException(return_msg);
		}
		String result_code = result.get("result_code");
		if (!PaymentKit.codeIsOK(result_code)) {
			log.error("result_code>"+result_code+" return_msg>"+return_msg);
			throw new RuntimeException(return_msg);
		}
		// 以下欄位在return_code 和result_code都為SUCCESS的時候有返回
		
		String prepay_id = result.get("prepay_id");
		String mweb_url = result.get("mweb_url");
		
		log.info("prepay_id:"+prepay_id+" mweb_url:"+mweb_url);
		try {
			response.sendRedirect(mweb_url);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

先給出H5ScencInfo

package com.mtgg.entity;

import com.jfinal.kit.JsonKit;


/**
 * @author Javen
 */
public class H5ScencInfo {
	private H5 h5_info;
	
	public H5 getH5_info() {
		return h5_info;
	}
	
	public void setH5_info(H5 h5_info) {
		this.h5_info = h5_info;
	}
	
	
	@Override
	public String toString() {
		return JsonKit.toJson(h5_info);
	}
	
	
	public static class H5{
		private String type;
		private String app_name;
		private String bundle_id;
		private String package_name;
		private String wap_url;
		private String wap_name;
		public String getType() {
			return type;
		}
		public void setType(String type) {
			this.type = type;
		}
		public String getApp_name() {
			return app_name;
		}
		public void setApp_name(String app_name) {
			this.app_name = app_name;
		}
		public String getBundle_id() {
			return bundle_id;
		}
		public void setBundle_id(String bundle_id) {
			this.bundle_id = bundle_id;
		}
		public String getPackage_name() {
			return package_name;
		}
		public void setPackage_name(String package_name) {
			this.package_name = package_name;
		}
		public String getWap_url() {
			return wap_url;
		}
		public void setWap_url(String wap_url) {
			this.wap_url = wap_url;
		}
		public String getWap_name() {
			return wap_name;
		}
		public void setWap_name(String wap_name) {
			this.wap_name = wap_name;
		}
	}
}


注意notify_url要保證能夠訪問,用域名訪問

最後傳送mweb_url就可以開啟微信進行支付了

給出支付成功的返回

@RequestMapping(value = "/pay_notify.do",method={RequestMethod.POST,RequestMethod.GET})
	@ResponseBody
	public void pay_notify(HttpServletRequest request,HttpServletResponse response) {
		// 支付結果通用通知文件: https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_7
		System.out.println("---------------支付回撥----------------");
		String xmlMsg = HttpKit.readData(request);
		System.out.println("pay notice---------"+xmlMsg);
		Map<String, String> params = PaymentKit.xmlToMap(xmlMsg);
//		String appid  = params.get("appid");
//		//商戶號
//		String mch_id  = params.get("mch_id");
		String result_code  = params.get("result_code");
//		String openId      = params.get("openid");
//		//交易型別
//		String trade_type      = params.get("trade_type");
//		//付款銀行
//		String bank_type      = params.get("bank_type");
//		// 總金額
		String total_fee     = params.get("total_fee");
		total_fee = total_fee.substring(0,total_fee.length()-2);
//		//現金支付金額
//		String cash_fee     = params.get("cash_fee");
//		// 微信支付訂單號
//		String transaction_id      = params.get("transaction_id");
//		// 商戶訂單號
//		String out_trade_no      = params.get("out_trade_no");
//		// 支付完成時間,格式為yyyyMMddHHmmss
//		String time_end      = params.get("time_end");
		
		/////////////////////////////以下是附加引數///////////////////////////////////
		
		String account      = params.get("attach");
		System.out.println("回撥total_fee-->"+total_fee);
		System.out.println("回撥account-->"+account);
//		String fee_type      = params.get("fee_type");
//		String is_subscribe      = params.get("is_subscribe");
//		String err_code      = params.get("err_code");
//		String err_code_des      = params.get("err_code_des");
		// 注意重複通知的情況,同一訂單號可能收到多次通知,請注意一定先判斷訂單狀態
		// 避免已經成功、關閉、退款的訂單被再次更新
//		Order order = Order.dao.getOrderByTransactionId(transaction_id);
//		if (order==null) {
		String resXml = "";
		WxPayApiConfigKit.setThreadLocalWxPayApiConfig(getApiConfig());
		if(PaymentKit.verifyNotify(params, WxPayApiConfigKit.getWxPayApiConfig().getPaternerKey())){
			if (("SUCCESS").equals(result_code)) {
				// TODO 根據商戶訂單號更改押金狀態
				System.out.println("成功,儲存");
				
				resXml = "<xml>" + "<return_code><![CDATA[SUCCESS]]></return_code>"
						+ "<return_msg><![CDATA[OK]]></return_msg>" + "</xml> ";
				
			} else {
				//TODO FAIL支付失敗
				log.debug("支付失敗的回撥訊息");
				resXml = "<xml>" + "<return_code><![CDATA[FAIL]]></return_code>"
						+ "<return_msg><![CDATA[報文為空]]></return_msg>" + "</xml> ";

			}
			BufferedOutputStream out = null;
			try {
				out = new BufferedOutputStream(
						response.getOutputStream());
				out.write(resXml.getBytes());
				out.flush();
				out.close();
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
//		}

	}

這裡需要注意最後的xml.put(),return PaymentKit.toXml(xml)一定要返回給微信,SUCCESS表示商戶接收通知成功並校驗成功,這樣微信才會知道商戶支付成功,否則會不斷通知,這樣就會重複處理資料,這個錯誤是致命的

上面回撥我改了一下,可以做到閉嘴,不會重複通知

下面就是測試調起微信支付

常見錯誤:

1、網路環境未能通過安全驗證,請稍後再試(IP改變導致的) 
2、商家引數格式有誤,請聯絡商家解決(H5支付的referer為空導致) 
3、商家存在未配置的引數,請聯絡商家解決(H5支付的域名問題) 
4、支付請求已失效,請重新發起支付(有效期為5分鐘) 

5、請在微信外開啟訂單,進行支付(H5支付不能直接在微信客戶端內調起)

我遇到過一次獲取code時回調了兩次錯誤,因為code只能用一次,第二次就失效了網上說什麼的都有,誰知道怎麼完全解決可以留言,感謝

相關推薦

h5支付瀏覽器支付實現

h5支付的資料還真叫個少,不過找到一個好的方式,按著大神的步驟去實現還真就ok了,話不多說,開始準備吧 微信支付的坑很多,特別在平臺的設定上 然後設定授權域名,在介面設定中就能找到,包括js介面安全域名和網頁授權域名: 這個點進去之後會看到最下面兩個

H5支付從第三方手機瀏覽器中直接打開支付頁面

pan 兩個 add field out 字典 註意 cti 返回 首先在商戶平臺通開H5支付功能,然後幫後綁定,支付完成之後需要跳轉的地址,開通之後就可以開發H5支付; 首先是簽名,臥槽,說到這個就想罵人, 官方文檔的解說;文科生哪能看得懂什麽是集合; 下面就來簽名:

海外小程式微支付小程式跨境支付小程式境外支付

在上一篇文章《167個國家和地區可以開通微信海外小程式》 你已經瞭解境外公司可以申請微信小程式, 可以把你的商品和服務, 在小程式中展示。 想要在小程式裡完成交易, 必須涉及到線上支付的問題, 很多人

第三方支付支付支付寶的一些入門瞭解

B2C電商的支付,一般由於支付金額比較小,支付比較頻繁,所以一般採用第三方支付,常用的第三方支付有:支付寶、微信、易寶支付等。他們的原理都差不多。都是在點選支付時,直接呼叫第三方支付介面,傳入appid、appsecret、訂單編號、訂單金額、回撥url,直接跳轉到第三方支付頁面,接下來的支

JAVA版開源管家—JeeWx捷3.1小程式版本釋出支援公眾號企業號支付

支援小程式,JeeWx捷微3.1小程式版本釋出^_^JeeWx捷微V3.1——多觸點小程式版本管理平臺(支援微信公眾號,微信企業號,支付窗)JeeWx捷微V3.1.0版本緊跟微信小程式更新,在原有多觸點

小程式支付支付【小白專用】

博主,之前做微信支付,在網上很少找到支付的文章,所以就抽空把微信支付流程給整理出來,方便各位剛剛接觸微信支付的使用者,參考,如有不好之處,歡迎評論指出 1、必須開通支付,並且有備案的域名 和 配置 https 2.微信小程式處理 .wxml .js 3 後臺處理部分

iOS開發之第三方支付支付教程史上最新最全第三方支付方式實現整合教程實現流程

 1. 微信支付微信支付前奏大致流程為 : 1. 公司需要到微信進行申請app支付功能 , 獲得appid和微信支付商戶號(mch_id)和API祕鑰(key) 、 Appsecret(secret),開發中用到的,很重要 appid:appid是微信公眾賬號

農場莊園遊戲開發小遊戲商城開發

深圳市龍火科技有限公司(SHENZHEN DRAGON FIRE TECHNOLOGY CO.LTD.),專業為企業提供一站式手機APP軟件開發,移動APP推廣服務,包括ANDROID APP開發,IOS APP開發,企業APP定制服務,同時提供全的APP開發流程一記開發方案。 龍火科技自成立以來,以為

apiCloud 三方分享好友分享朋友圈分享QQ分享博分享

-s -a nbsp 分享 ocs 配置 博客 微信朋友圈 icloud 首先查看我的這篇有關三方登錄的博客,地址是http://www.cnblogs.com/gqx-html/p/8303567.html,配置完三方數據後可以從上一篇文章中的鏈接跳轉到各個登錄查看api

黑客破解聊天軟體。。QQ。密碼破解解封。許可權空間等

微信破解,微信解封,微信記錄。許可權空間的加QQ351741114或者925192220 微信是新一代的聊天工具,我們不僅可以用它來和親朋好友聯絡,更可以和更多的人交流。它的出現也改變了一層不變的聊天模式。時常看到不少朋友,閒來無事就掛著微信。也有很多關於怎麼破

公眾號模版傳送資訊(java)

微信公眾平臺授權登入獲取使用者openid。 微信公眾平臺地址:https://mp.weixin.qq.com/ 1:模板配置 2:傳送模板的介面文件 3:微信回撥地址域名配置 ------------------------------------------

測試號公眾號開發中token驗證的解決辦法即介面配置資訊中的url和token怎麼設定的方法

首先我們來看兩張圖,第一張是微信公眾號中設定的圖 第二張是測試號中的圖片,之所以打馬賽克是怕不良之心的人,如果有疑問可以在文章後留言,因為本人在這個問題上搗鼓了好幾天,所以比較有心得,而微信公眾號的開發文件或者百度的資料都不多,所以很容易走彎路 現在講講介面配

h5頁面中跳轉外部瀏覽器下載APK的辦法

pretty 直接 style 文件的 oca asc views 通過 pps 需求:在微信h5頁面中下載第三方app —— 安卓, 直接下載apk文件包;iphone,跳轉AppStore 分析:微信不支持,在微信中屏蔽了apk文件的下載以及AppStore的跳轉(

分身多開雙開

2016-07-08 更新 由於公司放棄該方案哪就不壓箱底了,開源造福人類,呵呵 先說一下實現雙開(多開)的幾種方案 靜態修改APK包名,然後重打包 作為廠商肯定不推薦這個方式拉,可能存在法律風險動態修改APK包名 對原生程式碼修改量小,相容性差,部分APP需單獨適

JAVA版本管家平臺—JeeWx 捷 4.1 服務版本釋出砍價活動閃亮登場!

捷微 4.1   微服務版本釋出,微信砍價活動閃亮登場 ^_^ JEEWX 從4.0版本開始,技術架構全新換代更名 捷微H5,這是一款開源免費的微信運營平臺,是jeewx的新一代產品,平臺涵蓋了:微信公眾號管理、各種微信活動、小程式、微網站、微商城、分銷商城、小程式商城、小

自動跳轉到手機系統瀏覽器實現方式

打開 clu 點擊 最終 下載 公司 足夠 另一個 手機 最近公司開發了一款app,在做推廣的時候遇到了微信掃碼無法直接下載的問題   最終在參考了眾多資料後,發現微信內置瀏覽器不支持直接下載功能,可能這就是公司足夠大了,有些功能不給開放也不會怎樣。但是問題還是要解決的。

FreeRTOS 二值號量互斥號量

形象 iii 說明 reat 互斥 機制 容易 del 情況 本章節講解 FreeRTOS 任務間的同步和資源共享機制,二值信號量。 二值信號量是計數信號量的一種特殊形式,即共享資源為 1 的情況。 FreeRTOS 分別提供了二值信號量和計數信號量,其中二值信號量可以理解

Freertos-事件標誌組消息隊列號量二值號量互斥號量

text pri 消息隊列 解決 消息 無需 出現 任務 一個 任務間的通信和同步機制 在裸機編程時,使用全局變量的確比較方便,但是在加上 RTOS 後就是另一種情況了。 使用全局變量相比事件標誌組主要有如下三個問題: 1、使用事件標誌組可以讓 RTOS 內核有效地管理任

美超提供最高效能幫助廣泛高效能運算應用實現突破

-SC18將展出業界最廣泛的高效能運算系統,包括千萬億次全快閃記憶體NVMe、BigTwin (TM)、SuperBlade®和人工智慧與深度學習GPU系統 達拉斯2018年11月13日電 /美通社/ -- 企業計算、儲存、網路解決方案

加粉統計來粉統計訊號複製統計訊號線上管理!關鍵詞複製統計!網頁監控!免費註冊使用!

加粉統計,微訊號複製統計,關鍵詞複製統計工具,微訊號線上管理等工具。 可以去官網檢視詳細的介紹;這裡叫大家如何快速使用;官網連結: www.zaax.top目前免費註冊,免費使用一個月,而且功能無限制,只是免費版的開放的數量比較少。付費版價格也是明碼標價,可以根據自己推廣的連結需求選擇對應的版本。 目前有