1. 程式人生 > >APP 微信支付java後臺程式碼(解決支付失敗返回-1)

APP 微信支付java後臺程式碼(解決支付失敗返回-1)

開發之前的準備工作:

APP支付申請條件

申請成為APP支付商戶需要滿足以下條件:

2、APP應用必須通過開發者認證。

APP支付申請方法

1、登陸開放平臺(open.weixin.qq.com),選擇"管理中心"=》"移動應用",選擇需要申請支付的應用,點選"檢視"=》 "微信支付"=》 "申請開通",申請流程與公眾號支付申請流程一致。如下圖:
進入管理中心,點選移動應用

選擇需申請支付功能的應用,點選申請開通;

進入申請頁面,開始填寫資料。再依次根據頁面指引操作;

溫馨提示:商戶申請微信認證的主體與申請開通微信支付的主體需保持一致。
全部完成後可確認提交稽核,將在1-5個工作日內稽核完成。

2、開戶成功,登入商戶平臺進行金額驗證

提交資料稽核通過之後,微信平臺會發送商戶平臺的帳號密碼到你填寫的郵箱中,並且還會打入一筆驗證款項(隨機金額)到你的結算銀行賬戶中。

     接下來你所需要做的就是檢視銀行賬戶的轉賬流水(轉賬方的名義是財付通),然後登入微信商戶平臺進行金額驗證。

     輸入你在郵箱中得到的帳號密碼

   【!!!注意!!!】:

     在輸入密碼的時候需要安裝一個安全外掛,按要求安裝外掛之後,關閉瀏覽器然後重新開啟,再次輸入密碼的時候如果還提示需要安裝外掛,那麼請檢視一下瀏覽器的位址列是什麼模式。文主用的是360極速瀏覽器,所以必須是要在【相容模式】下才能夠正常輸入密碼,注意啦!是!!!相容模式!!!

    ②接下來就是激動人心的時刻了

    選擇驗證賬戶,輸入微信支付給公司對公賬戶打的款項金額

  【注意!!!】:只有三次驗證機會哦,所以要慎重!

    驗證成功

    簽署微信支付協議,完成微信支付申請

    整個申請過程就這樣完成啦,後面對應用的設計和開發,支付介面的除錯就屬於後臺技術人員的活了。如果有什麼還不清楚的地方的話,可以艾特文主,看到後能回答的都會幫你們解答。

     

     

     

     

這個時候就該技術人員上場了。
正式開發工作。

1.首先我們先來看一下微信支付的流程。


2.看完支付流程,我們就應該去調微信[

統一下單]生成預付單

傳送一個支付請求


@RequestMapping("/toGetWxPay")
@ResponseBody
	public JSONObject toGetWxPay(HttpServletRequest request) {
		String oid = request.getParameter("oid");
		String type = request.getParameter("type");
		String string = request.getRequestURL().toString();
		String calBack_url = string.substring(0,string.lastIndexOf("/"));
		calBack_url+="/appPayNotify";
		return wechatService.getWxPayAPP(oid, type, request.getRemoteAddr(), calBack_url);
	}


public JSONObject getWxPayAPP(String oid, String type,
	String spbill_create_ip, String calBack_url) 
		{
		// 支付map
		Map<String, Object> order = null;
		if ("single".equals(type)) {
			// 單個訂單
			order = orderBillService.toPayOrder(oid, false);
			order.put("TYPE", "single");
		} else {
			// 多個訂單
			order = orderBillService.toPayOrder(oid, true);
			order.put("TYPE", "many");
		}
		order.put("OID", oid);
		Double ormoney = Double.valueOf(order.get("ormoney").toString());
		order.put("ORMONEY", ormoney);
		logger.info("訂單:" + order);
		// 呼叫第三方支付方法傳送支付請求
		return wechatInterface.getWxPayAPP(
				propertyUtil.getProperty("wechat.app.appid"),
				propertyUtil.getProperty("wechat.app.mch_id"),
				propertyUtil.getProperty("wechat.app.mch_key"), 
						    spbill_create_ip, order, calBack_url); 
		}


發起預支付請求


public JSONObject getWxPayAPP(String appId, String mchId, String mchKey,
	String spbill_create_ip, Map<String, Object> order, String calBack_url) 
	{
		// 支付map
		Map<String, Object> resmap = new HashMap<String, Object>();
		resmap.put("appid", appId);
		resmap.put("mch_id", mchId);
		resmap.put("device_info", "WEB");
		String nonceStr = UUID.randomUUID().toString().replaceAll("-", "");
		resmap.put("nonce_str", nonceStr);
		resmap.put("body", "集團名稱");
		// 簽名
		resmap.put("attach", order.get("TYPE"));
		// 商戶訂單號
		resmap.put("out_trade_no", order.get("OID"));
		// 貨幣型別
		resmap.put("fee_type", "CNY");
		// 總金額分
		int order_amount = 0;
		try {
			double money = Double.parseDouble(String.valueOf(order
					.get("ORMONEY"))) * 100;
			order_amount = (int) money;
		} catch (Exception e) {
			e.printStackTrace();
		}
		resmap.put("total_fee", order_amount);
		// 終端IP APP和網頁支付提交使用者端ip
		resmap.put("spbill_create_ip", spbill_create_ip);
		// 起始時間
		resmap.put("time_start", ToolUtil.getFormatedNowDateTime());
		// 結束時間
		resmap.put("time_expire", ToolUtil.getFormatedTenDaysDateTime());
		// 通知地址
		resmap.put("notify_url", calBack_url);
		// 交易型別取值如下:JSAPI,NATIVE,APP
		resmap.put("trade_type", "APP");
		// 支付簽名採用md5加密2次
		String sign = SignUtil.createMd5Sign(resmap, mchKey);
		logger.info("加密前map:" + resmap);
		// 生成加密簽名
		resmap.put("sign", sign);
		logger.info("sign:" + sign);
		return toPayAPP(resmap, appId, mchKey);
	}
傳送支付請求並返回支付資料



private JSONObject toPayAPP(Map<String, Object> resmap, String appId, String mchKey) 
	{
		String payInfoToXml = MessageUtil.mapToXml(resmap);
		logger.info("統一訂單xml:" + payInfoToXml);
		Map<String, String> pay = WeixinUtil.toPay(payInfoToXml);
		logger.info("支付返回map:" + pay);
		// 交易成功返回資訊處理
		if (pay != null && pay.containsKey("result_code")
				&& "SUCCESS".equals(pay.get("result_code"))) {
			Map<String, Object> map = new HashMap<String, Object>();
			map.put("appid", appId);
			map.put("noncestr", UUID.randomUUID().toString()
					.replaceAll("-", ""));
			map.put("package", "Sign=WXPay");
			map.put("partnerid", pay.get("mch_id"));
			map.put("prepayid", pay.get("prepay_id"));
			map.put("timestamp", System.currentTimeMillis()/1000);
			String paySign = SignUtil.createMd5Sign(map, mchKey);
			map.put("sign", paySign);
			logger.info("返回給頁面的map:" + map);
			return JSONObject.fromObject(map);
		}
		return null;
	}

3.接下來我們來看看支付成功後的回撥。

@RequestMapping("/appPayNotify")
	public void appPayNotify(HttpServletRequest request, HttpServletResponse response)
	{
		try {
			// 將請求、響應的編碼均設定為UTF-8(防止中文亂碼)
			request.setCharacterEncoding("UTF-8");
			String respMessage = wechatService.appPayNotify(MessageUtil
					.parseXml(request.getInputStream()));
			logger.info("回覆內容:" + respMessage);
			response.setContentType("application/xml;charset=utf-8");
			// 呼叫核心業務類接收訊息、處理訊息
			if (respMessage != null) {
				// 響應訊息
				response.getWriter().print(respMessage);
//				out.close();
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}


@Override
	public String appPayNotify(Map<String, String> requestMap) {
	 try {
		// 是否是微信發來的
		if (wechatInterface.isWechatSign(requestMap, propertyUtil.getProperty
			("wechat.app.mch_key"))==false) {
			return null;
		}
		//處理多次回撥
		Map<String, Object> callBack = transactionPayRecordService.findCallBack
			(requestMap.get("transaction_id"));
		if(callBack!=null){
			return "<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg>
				<![CDATA[OK]]></return_msg></xml>";
		}
		Map<String, Object> tMap = new HashMap<String, Object>();
		tMap.put("is_success", "失敗");
		tMap.put("verifyStatus", "false");
		tMap.put("transaction_type", "1");
		tMap.put("notify_time", requestMap.get("time_end"));
		if ("SUCCESS".equals(requestMap.get("return_code"))) {
			if ("SUCCESS".equals(requestMap.get("result_code"))) {
				logger.info("驗證成功!");
				// 訂單號
				String oid = requestMap.get("out_trade_no");
				String type = requestMap.get("attach");
				String transaction_id = requestMap
							.get("transaction_id");
				Map<String, String> param = new HashMap<String, String>();
				param.put("transaction_id", transaction_id);
				param.put("payment_method", "3");
				if ("single".equals(type)) {
					param.put("oid", oid);
					// 單個訂單
					tMap.put("body", "單個支付");
				} else {
					// 多個訂單oid是支付寶號
					param.put("opayid", oid);
					tMap.put("body", "批量支付");
				}
				// 修改訂單支付時間
				Integer state = orderBillService.setOrderSuccess(param);
				ogger.info("微信支付成功!");
					
				//訂單支付成功,
					
					處理業務邏輯
				
					
					// 記錄日誌
				tMap.put("callback_payid", transaction_id);// 微信支付交易號
				tMap.put("total_fee", requestMap.get("total_fee"));// 交易金額
				tMap.put("title", "微信支付");
				if (state != null && state > 0) {
					tMap.put("is_success", "成功");
					tMap.put("trade_status", "支付成功");// 支付狀態
				} else {
					tMap.put("trade_status", "支付失敗");// 支付狀態
				}
				tMap.put("verifyStatus", "true");
				tMap.put("payid", requestMap.get("out_trade_no"));
				tMap.put("payment_method", "3");
				tMap.put("remarks", JSONObject.fromObject(requestMap)
							.toString());// 備註
				transactionPayRecordService.save(tMap);
				return "<xml><return_code><![CDATA[SUCCESS]]></return_code>
					<return_msg><![CDATA[OK]]></return_msg></xml>";
				} else {
					logger.info("result_code不存在");
					logger.info(requestMap);
				}
				transactionPayRecordService.save(tMap);
			} else {
				logger.info("return_code不存在");
				logger.info(requestMap);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

到這裡差不多這個流程就算完了!!!!

說一下在開發過程當中本人遇到的問題:

1.每個微訊號只能支付一次,之後就一直是error:{"code":-100,"message":"[payment微信:-1]General errors"}

解決辦法是,清理了一下微信快取。

2.微信支付成功後的回撥,(支付成功後,微信會回撥好幾次)

解決辦法,這個時候我們應該在後臺做邏輯判斷,回撥成功修改訂單狀態,儲存支付資訊,給微信返回資訊,告訴微信已經成功回撥,

response.setContentType("application/xml;charset=utf-8");

我開始寫的是text,微信一直回撥,後來改成application,微信只調了一次。

最後給大家總結一下

1.微信支付必須apk包,本地除錯支付不能成功,因為Huilder上的包名和金鑰和你app申請的微信支付的包名和金鑰是不一樣的。所以支付失敗。
2.呼叫微信app統一支付,生成預付訂單,這時候微信會返回來success,和微信預支付唯一標示,(prepay_id)
3.注意預支付成功之後引數的順序
{
appid=wx123......
noncestr=不長於32位的隨機字串
package=Sign=WXPay,
partnerid=商戶ID,
prepayid=預支付成功返回的預支付單號,
sign=MD5簽名(記得按順序
toUpperCase轉換為大寫),
timestamp=時間戳10位,
}
4.注意簽名和金鑰
5.切記記得清理微信快取,不是微信聊天記錄,是微信快取。
6,檢視appid是否配置(離線打包在AndroidManifest.xml配置,雲打包在manifest.json配置)
7,申請appid時所用證書籤名與apk的簽名證書必須一致
8,申請appid時填寫包名與打包時候所填寫包名必須一致 開發平臺配置的包名與簽名跟apk的簽名檔案是否一致
9,服務生成訂單時設定的appid、appkey等引數是否正確

10,調統一下單是引數變數名必是小寫,total_fee以分為單位,時間時間戳10位。


相關推薦

APP 支付java後臺程式碼解決支付失敗返回-1

開發之前的準備工作: APP支付申請條件 申請成為APP支付商戶需要滿足以下條件: 2、APP應用必須通過開發者認證。 APP支付申請方法 1、登陸開放平臺(open.weixin.qq.com),選擇"管理中心"=》"移動應用",選擇需要申請支付的應用,點選"檢視

APP登入 伺服器處理程式碼

採用框架THINKPHP5 需要客戶端傳的引數有  udid openid nickname avatar_path /* * @param 第三方微信登入 * @param openid udid nickname avatar_path */

搭建訂閱號後臺服務筆記

準備域名 微信公眾平臺需要配置伺服器地址 URL 訪問,在實驗開始之前,我們要準備域名。 域名註冊 如果您還沒有域名,可以在騰訊雲上選購,過程可以參考下面的視訊。 域名解析 域名購買完成後, 需要將域名解析到實驗雲主機上,實驗雲主機的 IP 為: <您的 CVM IP 地址&g

SpringBoot服務的https配置方法小程式後臺服務搭建解決方案

前言最近接觸了一個有關微信小程式的專案。有關小程式後臺服務的https配置踩了不少坑,折騰了一兩天時間,終於實現了小程式後臺服務的部署。這裡就總結一下基於微信小程式,有關SpringBoot後臺的配置方案。分析一下微信官方文件根據小程式官方文件描述,微信小程式的wx.requ

小程序 基礎操作邊做邊學3

微信 方法 eba cnblogs 參數傳遞 跳轉 java pre 傳遞 小程序頁面之間的參數傳遞: 假如是navigateTo跳轉的頁面,可以使用getCurrentPages()方法獲取路由數據,然後獲取上個頁面的引用對象,然後直接設置上個頁面的數據。 co

PHP實現開發中提現功能企業付款到使用者零錢

一.實現該功能目的     這幾天在小程式裡要實現使用者從系統中提現到零錢的功能,查了一下文件可以使用 企業付款到使用者零錢 來實現;  官方文件:https://pay.weixin.qq.com/wiki/doc/api/tools/mch_pay.php?chapt

小程式:授權問題scope.userInfo【廢棄】

今天發現微信廢棄了授權API:’scope.userInfo’ wx.getSetting({ success(res) { if (!res.authSetting['scope.userInfo']) {

小程式】小程式學習筆記每日更新ing_20180523打卡

1、app.json檔案中頁面路徑前不要加/2、圖片儘量不要儲存在小程式的目錄中。(因為小程式的大小不能超過1MB,超過則無法真機執行和釋出專案。應該將圖片都存放在伺服器上,讓小程式通過網路來載入圖片)3、設定display:flex是應用一切彈性佈局屬性的先決條件,如果不設

js 呼叫後臺程式碼比較實用,好記

JavaScript呼叫ASP.NET後臺程式碼:  方法一: 1、首先建立一個按鈕,在後臺將呼叫或處理的內容寫入button_click中;           2、在前臺寫一個js函式,內容為document.getElementById("btn1").click()

小程式—批量倒計時格式:06:58:30

 //適用於商品列表倒計時/** * end_time int 結束時間 * param int 陣列鍵 */ 1.展示效果如下: 2.wxml程式碼: <p class="promotion-label-tits">僅{{item.endtime}}&

Android之開放平臺實現分享分享好友和朋友圈

開發中分享操作往往經常遇到,而且還是一些比較大型一定的平臺,如微信,QQ,微博等。寫這篇部落格主要是把微信的的分享和相關操作表達一下,分享可以包含:文字,視訊,音樂,圖片等分享。分享可以有 分享給好友,群,朋友圈等。效果如下圖:(注意:功能根據自己的需要選擇就可以了)    

APP支付java後臺_統一下單和回撥

微信支付Java後臺1.微信配置資訊 global.properties2.方法wxpay用於生成預支付訂單資訊        方法notifyWeiXinPay用於微信支付成功後的回撥, 注意: 在手機端使用微信支付成功後,微信伺服器會根據提供的回撥地址進行回撥, para

javaapp支付服務端程式碼【手機app支付

老早就像做支付模組的東西,因為覺得很高大上,很早就開始把微信支付模組的重心簽名給做好了,一直就缺個商家的key,現在有幸來電商公司,哈哈,果然一切很順利,能夠很給力地App端提供支援; 個人覺得核心部分的程式碼: 簽名: //引數:開始生成簽名 SortedMap&

APP支付Java後臺總結

出於興趣寫了一個純支付的模組,有興趣的同學可以去看看(戳我) ———————————分隔線———————————– 微信APP支付大致的流程和支付寶APP支付有很大不同(想了解支付寶APP支付的同學點這裡),其中略坑的一點就是MD5加密的方法需要自己寫,好在

App支付接入—— hbuilder前端程式碼

4、App接入微信支付,使用hbuilder中的支付 (2)在觸發支付事件中新增程式碼 // 獲取支付通道 plus.payment.getChannels(function(channels) { for (var i in channels) { v

java開發微公眾號--測試號申請、java程式碼初步互動

一、申請測試號 個人不能夠免費申請服務號,訂閱號有很多限制,介面許可權出來基本的幾乎沒有,如圖, 在微信公眾平臺,檢視介面許可權 那麼怎麼使用服務號的介面許可權呢?微信推出了測試號,交給大家使用,開通的步驟是: 1.在微信平臺頁面,在服務號中,點選開發者文件 2

java公眾號開發三支付

步驟一:我們需要將微信支付所需要的引數組裝好,然後傳送請求。 所需要的引數在微信支付開發文件中就可以找到我們所必須的11個引數。 步驟二:然後在回撥函式中處理我們支付後的業務邏輯。 /** * * 獲得威微信支付的相關引數

公眾平臺開發教程java程式碼》下載

2018年11月02日 14:23:40 茹粿鰅莧丨你 閱讀數:7 標籤: 程式設計 資料 區

小程式支付JAVA後臺邏輯

① 小程式前端會通過呼叫wx.login介面獲取得到登陸憑據code。這個code獲取之後5分鐘內如果再次呼叫wx.login獲取code並傳遞給②就會報錯,code非法,這個需要注意下。② 小程式將code登陸憑據和orderId訂單編號穿給後臺服務端,服務端呼叫https

小程式後臺java登入和獲取使用者資訊程式碼

上篇博文中說到登入需要兩個介面,一個登入獲取openid一個獲取使用者資訊,並更新資料庫的介面 在此,我為了方便把兩個介面寫在一起了,也沒有寫更新資料庫的操作,這裡只寫如何獲取openid和使用者資訊的操作 /** * d登入介面 * @param encrypt