電腦支付寶支付 vue.js+java

1.前臺請求後臺獲得相應的地址參數,跳轉URL 前臺跳轉支付頁面

(1)前臺   

window.document.location = "${ctxPath}/api/alipay.html?_batch=true&_type=alipayPay&_c="+_this.id;

(2)後臺

	/**
	 * 生成跳轉支付寶頁面
	 */
	public String _$indexBatchAlipayPay() {
		Map<String, String> map = alipayPay();
		String from = map.get("form");
		if ("200".equals(map.get("status"))) {
			renderHtml(from);//返回渲染HTML頁面
		} else {
			try {
				String path = request.getContextPath();
				String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + path + "/";
				basePath = basePath + "/member/order?type=route&key=123#/order/unpaid?_c=" + map.get("_c") + "&text=" + URLEncoder.encode(from, "UTF-8");
				response.sendRedirect(basePath);
				attr("text", from);
			} catch (Exception e) {
				e.printStackTrace();
				logger.error("[{}] [{}] [{}]", "生成跳轉支付寶頁面失敗   請求消息-->" + map.toString(), "<異常-->", e);
			}
		}
		return null;
	}

	/**
	 * 生成跳轉支付寶頁面
	 * 
	 * @author: hjj
	 * @date: 2018年1月30日 上午11:52:28
	 * @param: @return:
	 *             void @throws
	 */
	public Map<String, String> alipayPay() {
		Map<String, String> map = new HashMap<>();
		map.put("status", "404");
		map.put("_c", _c);
		if (!StringUtils.isBlank(_c)) {
			Members members = getMembers();
			OrderForm orderForm = orderFormService.queryCodeObject(_c);
			if (orderForm == null || isDel(orderForm) || !Constants.ORDER_FORM_STATUS_BUY_UNPAID.equals(orderForm.getStatus())) {//
				map.put("form", "未找到未支付訂單");
				return map;
			}
			if (orderForm.getMembersId() == null || !members.getId().equals(orderForm.getMembersId().getId())) {
				map.put("form", "未找到用戶未支付訂單");
				return map;
			}
			RouteInfor routeId = routeInforService.getById(orderForm.getRouteId().getId());
			RLock lock = null;
			// 鎖庫存
			try {
				lock = CacheFactory.build(CacheFactory.REDIS).getRLock(Constants.ROUTE_QUOTA_RLOCK + orderForm.getRouteId().getId());
				if (Constants.IS_TRUE.equals(routeId.getIsScareBuying())) {// 搶購活動
					Boolean boo = routeInforService.judgeScareBuying(routeId.getBuyingStartDate(), routeId.getBuyingEndDate(), new Date());
					if (!boo) {// 不在搶購時間內
						map.put("form", "搶購時間已過!");
						return map;
					}
				}

				int quota = routeId.getQuota() == null ? 0 : routeId.getQuota();
				int pendingQuota = routeId.getPendingQuota() == null ? 0 : routeId.getPendingQuota();
				Integer amount = orderForm.getAmount() == null ? 0 : orderForm.getAmount();
				if ((quota - pendingQuota) <= 0 || (quota - pendingQuota - amount) < 0) {
					map.put("form", "庫存不足,請刷新後重新操作!");
					return map;
				}

				// 金額
				String totalAmount = orderForm.getAmountPaid().toString();
				// 訂單編號 唯一
				String outTradeNo = orderForm.getCoding();
				// 支付頁面有效時間 默認1分鐘
				int TimeoutExpress = 1;
				if (Constants.IS_TRUE.equals(orderForm.getIsScareBuying())) {// 搶購
					String value = sysParameterService.querySysParameterDate(Constants.SYS_PARAMETER_CODE_SCARE_BUYING_PAGE_TIME);
					if (value != null && StringUtils.isNumeric(value)) {
						TimeoutExpress = Integer.parseInt(value);
					}
				} else {// 訂單
					String value = sysParameterService.querySysParameterDate(Constants.SYS_PARAMETER_CODE_ORDER_PAGE_TIME);
					if (value != null && StringUtils.isNumeric(value)) {
						TimeoutExpress = Integer.parseInt(value);
					}
				}
				Cache cache = CacheFactory.build(CacheFactory.EHCACHE_PAGE_EXPIRED);// 緩存對象
				Element element = cache.get(Constants.CODE_KEY_ORDER_PAGE_EXPIRED + _c);

				App app = WebHelper.getApp(request);
				if (element == null) {// 無緩存才鎖庫存
					// 嘗試加鎖,最多等待5秒,上鎖以後10秒自動解鎖
					boolean res = lock.tryLock(5, 10, TimeUnit.SECONDS);
					if (!res) {// 加鎖失敗
						map.put("form", "系統繁忙,請重新操作!");
						return map;
					}
					cache.set(Constants.CODE_KEY_ORDER_PAGE_EXPIRED + _c, _c, TimeoutExpress * 60);
					MemOperateLog memOperateLog = new MemOperateLog();
					memOperateLog.setModule("訂單模塊");
					memOperateLog.setMembersId(members);
					memOperateLog.setContent("生成支付寶頁面,並鎖定庫存");
					memOperateLog.setIp(IpUtil.getIpAddr(request));// ip
					memOperateLog.setResult(Constants.IS_TRUE);
					routeInforService.updateRouteInforQuota(null, routeId.getId(), amount, Constants.ROUTE_PENDING_QUOTA_JIA, members, new Date(), memOperateLog, app);
					lock.unlock();
				}

				HttpServletRequest request = ServletActionContext.getRequest();
				String path = request.getContextPath();
				String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + path + "/";

				String returnUrl = basePath + "api/alipay/new.json";
				String notifyUrl = basePath + "api/alipay.txt";// .txt後綴會直接輸出resp的message屬性
				if (App.isPc(app)) {
					// PC
					AlipayTradePayModel model = new AlipayTradePayModel();
					// model.setBody("Javen IJPay PC支付測試");//訂單描述
					model.setTimeoutExpress(TimeoutExpress + "m");// 支付頁面有效時間
					model.setOutTradeNo(outTradeNo);
					// 銷售產品碼,與支付寶簽約的產品碼名稱。 注:目前僅支持FAST_INSTANT_TRADE_PAY
					model.setProductCode("FAST_INSTANT_TRADE_PAY");

					model.setTotalAmount(totalAmount);
					model.setSubject(orderForm.getRouteName());// 訂單標題

					String form = tradePage(response, model, notifyUrl, returnUrl);
					map.put("status", "200");
					map.put("form", form);
				}else{
					AlipayTradeAppPayModel model = new AlipayTradeAppPayModel();
					model.setTimeoutExpress(TimeoutExpress + "m");// 支付頁面有效時間
					// model.setBody("Javen IJPay PC支付測試");//訂單描述
					model.setOutTradeNo(outTradeNo);
					// 銷售產品碼,與支付寶簽約的產品碼名稱。 注:目前僅支持FAST_INSTANT_TRADE_PAY
					model.setProductCode("QUICK_MSECURITY_PAY");

					model.setTotalAmount(totalAmount);
					model.setSubject(orderForm.getRouteName());// 訂單標題
					String alipay = tradePageMP(response, model, notifyUrl, returnUrl);
					map.put("status", "200");
					map.put("form", alipay);
				}
			} catch (Exception e) {
				e.printStackTrace();
				map.put("form", "系統異常,請重新操作");
				logger.error("[{}] [{}]", "生成支付寶頁面異常", e);
				if (lock != null && lock.isLocked()) {// 鎖未解開時解開
					lock.unlock();
				}
			}

		} else {
			map.put("form", "未找到訂單");
		}
		return map;
	}

 

2.支付完成後有一個直接回調   returnUrl  驗籤回調(頁面及時反饋 )  notifyUrl 異步支付結果回調(支付結果以這個未準)

// 支付寶網關(固定)
	private static final String URL = "https://openapi.alipay.com/gateway.do";
	//private static final String URL = "https://openapi.alipaydev.com/gateway.do";

	// APPID 即創建應用後生成
	private static final String APP_ID = "20180";
	// private static final String APP_ID = "20160";

	// 開發者私鑰,由開發者自己生成
	private static final String APP_PRIVATE_KEY = "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCVfP76bsfaxaB6ENHLAR5GLJKRZoKqgi7fngYv7+lgu/YnGVwri40y+rKwpNZJ53mnY7KjvgwGVOcgiQ8KFbABHVbmVPqCPG5DxyJ3eZDqppEvDC6agJ0u/jDfnU8VNBvKhfjHJuRa3EQDx05uAlCcHj9M3c9AU37LZWC0qSMWEBpeSh4VNK2+uVS+nhs3m+CYcutXDMMUDqjMkpqGk4CN14Vidsp1e2w/ylo/CcqnsnV+4goD+/VFe4ZVwRPK4KB/GqLEfJEqbckO4RpCLbBWzIE79WoRkuPTZkM5RscZKtSbdS0lEdjvL0Dk++yRpoL9CGuHKDBMj4fp5+im8BWUH03UpfBNtMkssVUzaMM8btIyOsndQf2HWPcAf1J+nAYPNtzl/oMFs7MluE1dz4uSJfEtF8CBbwrFYbdaQOvc5eMLXfYBs3GwF2xAi1k7lplJHZzepYiPK7sFffSXPKaIrK4F6tqfI9YIvC61XEi0wE3m1aBGRMTeU8mG8amB7i132N9b+pMFTAQKBgQDP+8Cl45nJ3DKZkCu67VTIWEmqC6irMQU3NnR3v7f54sWmbPJJITGfbYVclIn1r4e1Ap9hDnRiEtBbxGgfWN6q1Oh5FoYwCoiS2frXolS2vEYbLuRPqx6kwmn6ORErNaC0Hr0leS7rZ4zTIlYK9OEGMxHEPPveFFEx4QwsyT/vgQKBgQC4AA9mtuc7PCeDmX9HoEPLk4A0ihj6P79spZFRugAvoOBRpeoLWkfadfJqvVOeu+FrpNwG268ewTyAq9TbKZIsvhyDmCep/QHRl7k68y4D6n0pxIP2vAp19TPU49PqTmzvK1Bg1zabZNfTrbxk15kvo4AvV/W+3C4Ai4LmzFiV+wKBgDL58oL2YRg/10saMg2z4+bi9NMv3lxvPGcG+s7q963Qrj8XTt8rupzn3BsP8Sx9pFZyWRwRzebH07faUOb2AkV+v6gGJEecHVNZCAlYKUlMpiY9fQol1/HsEMuatyGPGF9tdVC8/goGrFaHgO1YjdrWI5GknNsWwbvm+/PyM7CBAoGAGbnQbXEHNW38rFaqyA3tTKpL04y3X03Iat1fSwjxe7dHhcLnzTyLLU0uXqQn69qi8tTy+nZ+rpMf7XGY6ieOy3itLez5Jrg8J9zJxic3+M4xP8S9GqNB5yooXAyalXjvnCT3MQMGHIXl8y+oVoUaYuG+S2BF+LB6MhNPcwuBGz8CgYBmAmJ6YqAjrE+givbywXhzFmphriY0dvgUwvxaRLZK6NVF5C+UBd3u0eRibvQYuLLba67zk7LnEcg4w1jmyHkgENibroze/FA4DjwgvcGesqQk7OGFrFQWSxEDs5rNjoC8RmT0keo2BwqRvIKzx7QTrccMxP6M/pR6FiIQPl9Txw05==";

	// 參數返回格式,只支持json
	private static final String FORMAT = "json";

	// 編碼集,支持GBK/UTF-8
	private static final String CHARSET = "UTF-8";

	// 支付寶公鑰,由支付寶生成
	private static final String ALIPAY_PUBLIC_KEY = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAoIc3nVyK0EKDDhI4cJlmEdsiU4xORrtePJ9H3x8Ynh1gXuu9JQmYghuz6qooSokbeSvNsvbAojQOHA9tXbHm639Pb5dKvYs/osntwsGrEpyxxPzUAXBBqZjm9YNCS29IA2j7kiBwChrCZPS9+V3Twd1OvC8qoQgie3cpQ9I98jbn8Dxt1ZsMLAso67PufYQfxrSzimN+uCBm9cUM57G4H1KDrdGRQZ+";
	// private static final String ALIPAY_PUBLIC_KEY = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA9gh8/e3Z/Vc8X82Mek0GJu+qmulrMtQXsKxgeZ71XsuvXPU0UPNG/EFdyyj4NE7Dh//+N0B3ue0BX87E8rCSefn6Mkss+S4Pi/2jVy3kMwKA/iUtGAjRcT+GM97GABjqWAGQK5A2dFAHeLK/gzTZuZm8k/frlTDM1r4t26uzDu/Civ/GbBCdPy69N7nWYSKSz04xPKQZZZ/uOo9N2Igr/vO7UFQQIDAQAB";

	// 商戶生成簽名字符串所使用的簽名算法類型,目前支持RSA2和RSA,推薦使用RSA2
	private static final String SIGN_TYPE = "RSA2";

	private static final AlipayClient ALIPAY_CLIENT = new DefaultAlipayClient(URL, APP_ID, APP_PRIVATE_KEY, FORMAT, CHARSET, ALIPAY_PUBLIC_KEY, SIGN_TYPE);

/**
	 * 異步通知處理 //notify_url eg. POST /api/alipay.txt
	 * 
	 * @author: hjj
	 * @date: 2018年1月26日 上午10:32:25
	 * @param: @return:
	 */
	@Override
	public String create() {
		// 獲取支付寶POST過來反饋信息 -->
		Map<String, String> params = new HashMap<String, String>();

		PaymentSubmitLog paymentSubmitLog = new PaymentSubmitLog();// 支付提交日誌
		paymentSubmitLog.setChannel(Constants.PAYMENT_CHANNEL_ALIPAY);
		paymentSubmitLog.setStatus(Constants.OPERATE_RESULT_FALSE);

		String reTxt = "fail";
		RLock lock = null;
		boolean res = true;
		Cache cache = CacheFactory.build(CacheFactory.REDIS);
		Members members = new Members();
		OrderForm orderForm = new OrderForm();
		try {
			params = toMap(request);
			members.setUserName("支付寶");
			boolean verify_result = AlipaySignature.rsaCheckV1(params, ALIPAY_PUBLIC_KEY, CHARSET, SIGN_TYPE);
			String out_trade_no = params.get("out_trade_no");// 訂單編號
			String trade_no = params.get("trade_no");// 支付寶交易號
			String total_amount = params.get("total_amount") == null ? "0" : params.get("total_amount");// 支付寶交易金額

			paymentSubmitLog.setCoding(out_trade_no);
			paymentSubmitLog.setSerialNumber(trade_no);
			paymentSubmitLog.setAmount(new BigDecimal(total_amount));

			if (verify_result) {// 驗籤成功
				// 在這裏加上商戶的業務邏輯程序代碼 異步通知可能出現訂單重複通知 需要做去重處理
				String trade_status = params.get("trade_status");

				if (trade_status != null && trade_status.equals("TRADE_SUCCESS")) {// 支付成功
					List<OrderForm> list = orderFormService.queryOrderForm(out_trade_no, null);
					if (list != null && list.size() > 0) {// 找到訂單
						orderForm = list.get(0);
						orderForm.setAmountRealPaid(new BigDecimal(total_amount));// 支付寶交易金額

						// 鎖庫存
						lock = cache.getRLock(Constants.ROUTE_QUOTA_RLOCK + orderForm.getRouteId().getId());
						res = lock.tryLock(5, 10, TimeUnit.SECONDS);
						if (res) {// 獲得鎖
							paymentSubmitLog = orderFormService.handleAlipayOrder(orderForm, members, params, paymentSubmitLog);
							reTxt = "success";// 成功必須返回這個
							lock.unlock();
						}
					} else {
						paymentSubmitLog.setRemark("支付成功-->支付寶反饋信息-->" + params.toString() + "未找到訂單訂單編號-->" + out_trade_no);
						logger.info("[{}] [{}]", "非法", params.toString());
					}
				} else {
					paymentSubmitLog.setRemark("支付失敗-->支付寶反饋信息-->" + params.toString());
					logger.info("[{}] [{}]", "失敗", params.toString());
				}
			} else {
				paymentSubmitLog.setRemark("驗籤失敗-->支付寶反饋信息-->" + params.toString());
				logger.info("[{}] [{}]", "非法", params.toString());
			}
		} catch (Exception e) {
			e.printStackTrace();
			paymentSubmitLog.setRemark("運行異常-->支付寶反饋信息-->" + params.toString() + "異常信息-->" + e.getMessage());
			logger.error("[{}] [{}] [{}]", "異常", params.toString(), e);
			if (lock != null && lock.isLocked()) {// 鎖未解開時解開
				lock.unlock();
			}
		}
		if (Constants.OPERATE_RESULT_PROBLEM.equals(paymentSubmitLog.getStatus())) {
			logger.info("[{}] [{}]", "問題訂單", params.toString());
		} else if (Constants.OPERATE_RESULT_TRUE.equals(paymentSubmitLog.getStatus())) {
			logger.info("[{}] [{}]", "支付成功", params.toString());
		} else if (Constants.OPERATE_RESULT_FALSE.equals(paymentSubmitLog.getStatus())) {
			logger.info("[{}] [{}]", "支付失敗", params.toString());
		} else if (Constants.OPERATE_RESULT_PENDING.equals(paymentSubmitLog.getStatus())) {
			logger.info("[{}] [{}]", "支付待處理", params.toString());
		}

		paymentSubmitLogService.save(paymentSubmitLog);
		if (!res) {
			paymentSubmitLog.setStatus(Constants.OPERATE_RESULT_PENDING);
			Map<String, Object> params2 = new HashMap<String, Object>();
			params2.put("orderType", "alipay");
			params2.put("orderForm", orderForm);
			params2.put("params", params);
			params2.put("members", members);
			params2.put("paymentSubmitLogId", paymentSubmitLog.getId());
			cache.ladd(Constants.PAYMENT_ORDER_LIST, params2);
		}
		logger.info("[{}]", "記錄操作日誌成功!!!");
		initResult(RespCode.OK, reTxt);
		return reTxt;
	}

	/**
	 * 同步商戶頁面驗籤,這裏只是返回驗籤的狀態 //return_url get /api/alipay/new.json
	 * 
	 * @author: hjj
	 * @date: 2018年1月26日上午10:32:25
	 * @param: @return:
	 *             void @throws
	 */
	@Override
	public String editNew() {
		initResult(RespCode.OK);
		Map<String, String> map = toMap(request);
		try {
			boolean verify_result = AlipaySignature.rsaCheckV1(map, ALIPAY_PUBLIC_KEY, CHARSET, SIGN_TYPE);
			String path = request.getContextPath();
			String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + path + "/";
			if (verify_result) {// 驗證成功
				String out_trade_no = map.get("out_trade_no");
				List<OrderForm> list = orderFormService.queryOrderForm(out_trade_no, null);
				if (list != null && list.size() > 0) {
					logger.info("[{}] [{}]", "同步商戶頁面驗籤     驗證成功    請求消息-->", map.toString());
					basePath = basePath + "/member/order?type=route&key=123#/order/finish?_c=" + list.get(0).getCoding();
				} else {
					logger.info("[{}] [{}]", "訂單不存在   訂單號-->" + out_trade_no, "<請求消息-->" + map.toString());
				}
			} else {
				logger.info("[{}] [{}]", "同步商戶頁面驗籤    驗證失敗   請求消息-->", map.toString());
			}
			response.sendRedirect(basePath);
		} catch (Exception e) {
			// 返回頁面失敗
			e.printStackTrace();
			logger.error("[{}] [{}] [{}]", "同步商戶頁面驗籤    驗證失敗   請求消息-->" + map.toString(), "<異常-->", e);
		}
		return "";
	}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章