1. 程式人生 > >[微信]微信小程式/Java實現微信支付

[微信]微信小程式/Java實現微信支付

   @Controller
    @RequestMapping("/pay")
    public class WeChatPayController {
    	public final static Logger logger = LoggerFactory.getLogger(WeChatPayController.class);
    
    	public final static String CREATE_ORDER_URL = "https://api.mch.weixin.qq.com/pay/unifiedorder";
    	/**
    	 * appid 小程式id 微信公眾平臺 設定中的開發設定中可以查到,相當於qq的qq號 建議單獨建立一個配置檔案儲存此類值和函式
    	 */
    	public static final String APPID = "APPID";
    	/**
    	 * AppSecret 小程式金鑰 微信公眾平臺
    	 */
    	public static final String SECRET = "AppSecret";
    	/**
    	 * 用於獲取使用者openid的介面網址 其中%s將會用String.format函式替換為實際的值 建議單獨儲存
    	 */
    	public static final String Web_access_tokenhttps = "https://api.weixin.qq.com/sns/jscode2session?appid=%s&secret=%s&js_code=%s&grant_type=authorization_code";
    	@Autowired
    	private IUserService userService;
    	@Autowired
    	private IPaymentConfigService paymentConfigService;
    	@Autowired
    	private IBookService bookService;
    
    	/**
    	 * 通過APPID,SECET,code組合出用於獲取使用者openid的實際網址 建議單獨儲存
    	 */
    	public static String getWebAccess(String code) {
    		return String.format(Web_access_tokenhttps, APPID, SECRET, code);
    	}
    
    	/**
    	 * 獲取微信支付的各種引數 orderNo(子系統商戶唯一訂單號,下單時通過時間戳演算法生成)
    	 * totalMoney(支付總金額,單位為分列:7元==700) 
    	 * sysFlag(子系統標誌,通知此標誌獲得微信商戶引數)
    	 * session(通過session和sysFlag獲得當前登入使用者的openId)
    	 * 
    	 * 
    	 * @return
    	 * @throws Exception
    	 */
    	@RequestMapping(value = "/getWxPayParameters.do")
    	@ResponseBody
    	public FOURYOU_WX_PAY_PARAMETERS_VO getWxPayParameters(String code, String ip, String totalMoney,
    			HttpServletRequest request, HttpServletResponse response, String body, String type) throws Exception {
    		if (code.equals(null)) {
    			throw new Exception("未登入使用者,請重新掃描二維碼進入小程式!!!");
    		}
    		logger.info("=========getWxPayParameters.do==========:{ffffff}", totalMoney);
    		logger.info("=========getWxPayParameters.do==========:{}", request);
    		RequestHandler reqHandler = new RequestHandler(request, response);
    		String APPID = "APPID";
    		String token = getWebAccess(code);
    		String rec = httpGet(token);
    		logger.info("======微信回執為:{}", rec);
    		JSONObject json = JSON.parseObject(rec);
    		String openId = json.getString("openid");
    		if (openId == null) {
    			throw new Exception("登陸失敗,請重新退出登陸!!!");
    		}
    		FOURYOU_WX_PAY_PARAMETERS_VO payParameters;
    		user_register user = userService.findOpenId(openId);
    		String orderNo = TenpayUtil.makeOrderNumber(user.getUser_id());
    		String Secret = "";
    		FOURYOU_WX_PAY_CONFIG wxPayConfig = userService.getConfig(APPID);
    		SortedMap<String, String> wxPackageParams = getWxJsapiParams(orderNo, ip, openId, totalMoney, APPID,
    				wxPayConfig, body, type);
    		
    		reqHandler.init(String.valueOf(APPID), Secret, wxPayConfig.getPARTNER_KEY());
    		/*****************************************************/
    		logger.info("支付");
    		
    		// reqHandler.genPackage(wxPackageParams);
    		wxPackageParams.put("sign", reqHandler.createSign(wxPackageParams));
    		logger.info(wxPackageParams.get("sign") + "sing");
    		String prepay_id = GetWxOrderno.getPayNo(CREATE_ORDER_URL, XMLUtil.map2xmlBody(wxPackageParams, "xml"));
    		if (prepay_id.equals("")) {
    			logger.info("error:統一支付介面下單失敗");
    			throw new Exception("error:統一支付介面下單失敗");
    		}
    		SortedMap<String, String> finalpackage = new TreeMap<String, String>();
    		String nonceStr2 = wxPackageParams.get("nonce_str");// 二次簽名的隨機串需要用微信返回的
    		String packages = "prepay_id=" + prepay_id;
    		finalpackage.put("appId", String.valueOf(APPID));
    		finalpackage.put("timeStamp", Sha1Util.getTimeStamp());
    		finalpackage.put("nonceStr", nonceStr2);
    		finalpackage.put("package", packages);
    		finalpackage.put("signType", "MD5");
    		payParameters = new FOURYOU_WX_PAY_PARAMETERS_VO();
    		payParameters.setAPPID(String.valueOf(APPID));
    		payParameters.setTIME_STAMP(Sha1Util.getTimeStamp());
    		payParameters.setNONCE_STR(nonceStr2);
    		payParameters.setPACKAGE(packages);
    		payParameters.setPrepay_id(prepay_id);
    		payParameters.setSIGN(reqHandler.createSign(finalpackage));
    		payParameters.setTotal_fee(Integer.valueOf(totalMoney));
    		return payParameters;
    	}
    
    	/**
    	 * 通過HttpGet類傳送GET請求並獲取返回資訊
    	 * 
    	 * @param path
    	 *            傳送至的網址
    	 * @return
    	 */
    	public String httpGet(String path) {
    		if (path == null) {
    			return null;
    		}
    		String rec = null;
    		HttpGet get = new HttpGet(path);
    		try {
    			HttpResponse response = HttpClients.createDefault().execute(get);
    			HttpEntity entity = response.getEntity();
    			rec = EntityUtils.toString(entity);
    		} catch (IOException e) {
    			e.printStackTrace();
    		}
    		return rec;
    	}
    
    	/**************************************** WX_PAY ******************************************/
    	/**
    	 * 獲取微信支付(JSAPI)packageParams
    	 * 
    	 * @throws Exception
    	 */
    	@RequestMapping("/getWxJsapiParams.do")
    	@ResponseBody
    	public SortedMap<String, String> getWxJsapiParams(String orderNo, String spbill_create_ip, String openId,
    			String totalMoney, String appId, FOURYOU_WX_PAY_CONFIG wxPayConfig, String body, String type)
    			throws Exception {
    		String currTime = TenpayUtil.getCurrTime();
    		String backUrl = "http://xxxxx/pay/rechargeAccout.do";// 下一個方法:充值
    		String strTime = currTime.substring(8, currTime.length());
    		String strRandom = TenpayUtil.buildRandom(4) + "";
    		SortedMap<String, String> packageParams = new TreeMap<String, String>();
    		packageParams.put("appid", String.valueOf(appId));// 小程式ID
    		packageParams.put("mch_id", wxPayConfig.getPARTNER());// 商戶號
    		packageParams.put("nonce_str", strTime + strRandom);
    		packageParams.put("body", body);
    		packageParams.put("attach", type+","+body);
    		packageParams.put("out_trade_no", orderNo);// 商戶訂單號
    		packageParams.put("total_fee", totalMoney);// 支付金額,這邊需要轉成字串型別,否則後面的簽名會失敗
    		packageParams.put("spbill_create_ip", spbill_create_ip);// 終端IP
    		packageParams.put("notify_url", backUrl);// 支付成功後的回撥地址
    		packageParams.put("trade_type", "JSAPI");// 交易型別
    		packageParams.put("openid", openId);// 使用者標識
    		logger.info("微信支付付款金額:====================>" + totalMoney +"\n=======================>>>>"+ "notifyUrl:" + backUrl);
    			
    		return packageParams;
    	}
    
    	/**
    	 * 充值
    	 * 
    	 * @param totalMoney
    	 *            充值金額(分)
    	 * @param userId
    	 *            使用者ID
    	 * @param ip
    	 *            終端ip
    	 * @param type
    	 *            區別充值的是押金還是賬戶充值
    	 * @throws Exception
    	 */
    	@SuppressWarnings("unchecked")
    	@RequestMapping("/rechargeAccout.do")
    	@ResponseBody
    	public String rechargeAccout(HttpServletRequest request) throws Exception {
    		Map<String, String> map = new HashMap<String, String>();
    		logger.info("=============rechargeAccout.do===start:=================");
    		String APPID = "APPID";
    		FOURYOU_WX_PAY_CONFIG config = userService.getConfig(APPID);
    
    		try {
    
    			InputStream inputStream = request.getInputStream();
    			// 讀取輸入流
    			SAXReader reader = new SAXReader();
    			Document document = reader.read(inputStream);
    			// 得到xml根元素
    			Element root = document.getRootElement();
    			List<Element> elementList = root.elements();
    
    			// 遍歷所有子節點
    			for (Element e : elementList)
    				map.put(e.getName(), e.getText());
    
    			// 釋放資源
    			inputStream.close();
    			inputStream = null;
    
    		} catch (Exception e) {
    			e.printStackTrace();
    		}
    		// 驗證是否是微信發來的回撥
    		if (!(map.get("mch_id").equals(config.getPARTNER()))) {
    			return null;
    		}
    
    		String openId = map.get("openid");
    		logger.info("================openid:=================" + openId);
    		try {
    			logger.info("=============rechargeAccout.do=== fffff:=================");
    			// 查詢openId
    			user_register reuser = userService.findOpenId(openId);
    			if (null == reuser) {
    				throw new Exception("未登入!");
    			}
    
    			// 根據userID和訂單號查詢訂單資訊
    			String orderNO = String.valueOf(map.get("out_trade_no"));
    			payment_config pay = new payment_config();
    			pay.setUser_id(reuser.getUser_id());
    			pay.setOrderid(orderNO);
    			payment_config userRecord = userService.getPayRecord(pay);
    
    			user_book findLandlord = new user_book();
    			findLandlord.setRent_user_id(reuser.getUser_id());// 租客編號
    			logger.info("=====bookService.queryLandlord======findLandlord:" + findLandlord);
    			// 根據租客編號 Rent_user_id 查詢房東編號
    			user_book booklist = bookService.queryLandlord(findLandlord);
    			logger.info("=====查詢房東USER_ID=====bookService.queryLandlord======:" + booklist);
    
    			user_account user1 = userService.SelectUserAmount(booklist.getUser_id());
    			logger.info("======== userService.SelectUserAmount ======= END =========:" + user1);
    
    			// 處理微信多次呼叫
    			if (userRecord != null) {
    				if (map.get("out_trade_no").equals(userRecord.getOrderid())) {
    					return "<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>";
    				}
    			}
    
    			logger.info("======新增支付記錄 到交易流水錶========  開始      ==========");
    			// 查詢某使用者的餘額
    			// user_account user =
    			// userService.SelectUserAmount(reuser.getUser_id());
    			logger.info("======新增支付記錄 到交易流水錶========  開始      ==========" + map.get("attach"));
    			
    			String[]  attac = map.get("attach").split(",");
    			logger.info("======新增支付記錄 到交易流水錶========  開始  attach[0]+attach[1]    ==========" +attac[0]+"fffffffffff"+attac[1]);
    			payment_config userRecord1 = new payment_config();// attach 附加資料
    			if (attac[0].equals("充值")) {
    
    				logger.info("====paymentConfigService.addwithdraw ========開始==========新增資金記錄:" + userRecord);
    				// 新增語句 新增新增交易流水 資金記錄
    				if (userRecord == null) {
    					SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
    					userRecord1.setAbstracts("交租");
    					Date date = sdf.parse((String) map.get("time_end"));
    					userRecord1.setBalance(Integer.valueOf(map.get("total_fee")));
    					userRecord1.setOrderid((String) map.get("out_trade_no"));
    					userRecord1.setTrading_time(date);
    					userRecord1.setUser_id(reuser.getUser_id());
    					logger.info("======房源的 HID:" + booklist.getHid());
    					logger.info("======房東的 USERID:" + booklist.getUser_id());
    					userRecord1.setHid(booklist.getHid());
    					userRecord1.setPaytype("微信支付");
    					userRecord1.setStatus("成功");
    					// 新增語句 新增 payconfig資金記錄
    					paymentConfigService.addwithdraw(userRecord1);// 新增提現記錄
    					if (null != userRecord1) {
    						logger.info("新增資金記錄:");
    					}
    
    					logger.info("===========paymentConfigService.addwithdraw=====END=======新增資金記錄:");
    
    					logger.info("==========新增資金流水記錄=======成功======:");
    					// attach 附加資料
    					int Money = Integer.valueOf(user1.getMoney()) + Integer.valueOf(map.get("total_fee"));
    					logger.info("======支付房租金額:" + Integer.valueOf(map.get("total_fee")) + "======賬戶原有金額:"
    							+ Integer.valueOf(user1.getMoney()) + "======增加加資金記錄 Money:" + Money);
    					user1.setMoney(Money);
    					user1.setUser_id(booklist.getUser_id());
    					logger.info("======房東的  USER_ID:" + booklist.getUser_id());
    
    					// logger.info("======新增房東收租記錄D:" + booklist.getUser_id());
    					// payment_config userRecord2 = new payment_config();
    					// userRecord2.setAbstracts("收租");
    					// userRecord2.setBalance(Integer.valueOf(map.get("total_fee"))
    					// );
    					// userRecord2.setOrderid((String) map.get("out_trade_no"));
    					// userRecord2.setTrading_time(date);
    					// userRecord2.setUser_id(booklist.getUser_id());
    					// userRecord2.setPaytype("微信支付");
    					// userRecord2.setStatus("成功");
    					// addID = paymentConfigService.addwithdraw(userRecord2);//
    					// 新增提現記錄
    					logger.info("=========paymentConfigService.updataUserAccount == 開始 ===user1:" + user1);
    					// 更新賬戶
    					int balance = paymentConfigService.updataUserAccount(user1);
    					logger.info("=========paymentConfigService.updataUserAccount == END ===balance:" + balance);
    
    					logger.info("=========修改賬戶餘額======成功=====");
    					String settle = "是";
    					int user_id = Integer.valueOf((reuser.getUser_id()));// 房客user_id
    					logger.info("=====房客的===USER_ID=====:" + user_id);
    
    					// 修改交租記錄表 狀態
    					rentPayment payment = new rentPayment();
    					payment.setSettle(settle);
    					payment.setTrading_time(new Date());// 當前時間
    					payment.setUser_id(user_id);
    					
    
    					payment.setTitle(attac[1]);
    
    					int modify = paymentConfigService.updatePaid(payment);
    
    					logger.info("=========修改賬單狀態======成功=====:" + modify);
    
    				}
    
    			}
    		} catch (Exception e) {
    			logger.info("======新增支付記錄 到交易流水錶==========  失敗      ====================");
    		}
    
    		// 校驗是否為真
    		if (map.get("result_code").equals("SUCCESS")) {
    			return "<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>";
    		}
    
    		return null;
    
    	}
    
    }

相關推薦

[]程式/Java實現支付

@Controller @RequestMapping("/pay") public class WeChatPayController { public final static Logger logger = LoggerFa

程式實現支付

最近做小程式,涉及到微信支付,看了看微信小程式開發文件,儘管之前做過微信支付,還是有點懵逼,不過好在之前研究過,不然真的是無從下手。對比了一下發現,其實小程式中做支付比公眾號支付要省事很多,因為不需要支

基於java程式實現(七)視訊首頁的前後端開發

1.效果演示 2.編寫分頁查詢全部視訊的介面開發 1.需求分析 該介面會查詢資料庫中全部的視訊內容,因為視訊內容過多,要採用分頁查詢,這裡我們使用Pageable對查詢結果進行分頁處理,另外,在前端顯示視訊的內容時候還需要額外的顯示使用者的頭像和暱稱資訊,所以在進行視訊列表

基於java程式實現(六)使用者視訊上傳的前後端開發

1.使用者上傳視訊功能需求分析 使用者在登入之後可以在個人資訊頁面點選上傳視訊按鈕,會讓使用者在本地選擇一段視訊進行上傳,視訊不能過長,選擇好後,使用者會跳轉到選擇背景音樂的介面,可以選擇為該視訊加上一段背景音樂,並且可以對該視訊做相關描述,然後點選上傳視訊按鈕,完成視訊上傳。 2.

基於java程式實現(五)使用者個人資訊程式端開發

1.個人資訊頁面展示 2.顯示個人資訊功能 1.需求分析 在該頁面首先需要在載入完畢後去呼叫後端的查找個人資訊的介面,並將返回的值回顯到個人資訊頁面上 2.js程式碼的編寫 onLoad:function(params){ var me=this;

基於java程式實現(四)使用者個人資訊相關介面開發

1.查詢使用者個人資訊介面開發 1.需求分析 需要通過前端傳來的使用者的userid去資料庫中進行查詢,並將查詢到的物件封裝為usersVo返回給前端 dao層程式碼 public interface UsersDao extends JpaRepository<Use

基於java程式實現(三)登入,註冊,注程式端的實現

1.微信小程式專案結構認識 js檔案用來寫相關的邏輯操作,主要是用來操作資料 json檔案用來寫一些相關的配置 wxss相當於css用來寫頁面樣式 wxml相當於html用來寫頁面的元素的 pages資料夾中可以存放多個資料夾,每個資料夾裡面都是一套是js,json

基於java程式實現(二)登入,註冊,登出介面的實現

1.開發工具以及相關環境的配置 1.首先關於IDE,前端小程式端採用的是微信官方的微信開發者工具,後端使用的是idea(idea是真的智慧,再也不想回去eclipse了呢),關於前端的一些程式碼,主要是參照微信官方的API進行開發的,整體的檔案結構也和js,css,html也很相似。

基於java程式實現(一)專案介紹

一,專案介紹 佐倉短視訊是一個以java為後臺編寫的短視訊類的微信小程式專案 使用者可以實現登入,註冊,視訊檢視,視訊上傳,個人資訊檢視,頭像上傳等功能 二,技術選型和效果預覽 本專案後端採用spring boot +spring data jpa的技術實現

程式+java後臺實現登入(java操作)

登入,在微信小程式上面稱為當一個使用者使用該小程式,進入到小程式中,我們拿到該使用者的資訊,進行一系列的操作,並記錄下來。 微信小程式與java介面實現登入操作,大致思路如下: 1.微信小程式端通過呼叫對應的api,將對應的變數傳入後臺(code、iv、encr

Java實現程式登入 獲取使用者資訊

小程式比公眾號授權登入 更加簡單 其實沒什麼是後臺需要處理的 前端傳過來一個code 我們儲存以下通過code獲取過來的openid就可以 其他的使用者資訊 前端小程式那邊可以獲取。首先既然是小程式登入 你要有一個你自己的小程式還是要拿到你自己的appid和appSecret

程式+java後臺實現支付java操作)

支付,在微信小程式上面稱為當一個使用者使用該小程式,當進入到支付環節,我們需要呼叫微信支付介面過程,進行一系列的操作,並記錄下來。 微信小程式與java介面實現支付操作,大致思路如下: 1.微信小程式呼叫Java後臺方法獲取引數, 2.java 後臺設定引數等並

程式前端)程式-畢設級專案搭建(內含原始碼,程式+java邏輯後臺+vue後臺管理系統+MySQL資料庫)~不求完美,實現就好

一、環境搭建 參考教程:https://blog.csdn.net/u012888052/article/details/79623229 二、根據上方教程新建的專案,編寫對應程式         第一次做的小程式,是一款閱讀器軟體,包括了簡單的文章瀏覽、歷史回顧、簽到

java實現程序服務端(登錄)

value ssi 讀取 ive ping 我們 不存在 @param 感受                             java實現微信小程序服務端    微信小程序如今被廣泛使用,微信小程序按照微信官網的定義來說就是:    微信小程序是一種全新的連接用

程式+java後臺

          開發一個微信小程式需要https域名以及伺服器         1. 進入微信公眾平臺https://

程式-wxs實現手機號碼中間四位顯示為*號

直接加到WXML裡 <!-- 使用wxs 手機號碼中間四位顯示為*號 --> <wxs module="phone"> var toHide = function(array) { var mphone = array.substring(0, 3) +

程式 表格實現

微信小程式表格實現 最近要實現微信小程式的表格樣式,樓主最開始想著用rich-text來實現table標籤,試過很多次都不大如意,=-=,目測還是樓主實力不加,於是我想到了另一個方法實現,按比例把每個格子分好,效果就是這樣子的,還是不錯的吧,每個格子佔33.33%,也可以按照bootst

程式怎麼實現內容的展開和收起

看到一個需求,對一些前端小白或者剛開始寫小程式的人來說,可能會有點幫助,效果如下: 就是以上效果,廢話不多說,上程式碼wxml: <view class='list_box' wx:for='{{list}}' wx:key='this' wx:for-item='parentItem

程式實現上傳視訊的開發程式碼

index.wxml <view class="image-plus image-plus-nb" bindtap="chooseVideo"> <view class="image-plus-horizontal"></view> &l