基於Dubbox的微服實戰6——實現分佈式下的支付寶支付

目錄

第三方支付寶支付介紹
第二步配置祕鑰
配置搭建環境和SDK介紹
支付寶支付編碼實現解析
獲取訂單信息
統一下單API的實現
異步通知
同步通知

測試


第三方支付寶支付介紹

第三方支付平臺

選擇服務商

  • 支付寶
  • 財付通
  • 銀聯商務
  • 塊錢
  • ... ...

沙箱環境

又稱沙盤,爲了開放與調試所提供的環境,它與生產環境互相隔離,但具有生產環境幾乎完全相同的功能。

螞蟻金服開放平臺——開發者中心

提供的調試產品

  • APP支付
  • 當面支付
  • 電腦網站支付。

接入流程

  1. 創建應用並獲取APPID
  2. 配置祕鑰
  3. 搭建和配置開發環境
  4. 使用SDK(支付寶提供的)
  5. 線上驗收

第二步配置祕鑰

第一步:創建應用並獲取APPID

準備工作

  • 支付寶賬號
  • 必須在開放平臺完成實名認證才能使用開放平臺服務

生成應用唯一標識(APPID)

  • 創建登錄應用
  • 提交審覈

開發階段可使用默認的沙箱應用

  • 開發者中心——研發服務——沙箱應用
  • 每個應用對應一個APPID


第一次使用需要完善信息。


完善後,再打開


“第三方應用”是服務商,所以選擇“自用型應用”。點擊“創建”後出現頁面


這個時候應用不能用。需要提交審覈,上線後才能用。所以要使用“沙箱應用”,不需要這些步驟。

“功能列表”默認有三條,可以刪除添加。添加後不一定能用。後面有個選項“是否需要簽約”,如果是“需簽約”,就必須簽約後才能使用。


基礎環境中

應用網關:

授權回調地址:支付成功後,會回調一個地址,第三方商戶網站提供的一個地址,支付寶會把一些狀態返回給改地址。


那麼要使用沙箱應用該怎麼打開那?


進入頁面


沙箱賬號裏面有個商家信息,買家信息。


第二步:配置密鑰

1.生成RSA密鑰對

  • 應用私鑰
  • 應用公鑰

2.上傳應用公鑰

3.平臺自動生成支付寶公鑰


3.填寫內容


這個密鑰怎麼產生。是支付寶提供一鍵生成工具便於開發者生成一對RSA密鑰,可通過下方鏈接下載密鑰生成工具

點擊“查看密鑰生成”下載完後,打開“RSA簽名驗籤工具.bat


把“商戶應用公鑰”填到上面那個“應用公鑰”裏面。確定後,出現以下界面


這個支付寶公鑰也是後面所需要的。

配置搭建環境和SDK介紹

第三步:搭建和配置開發環境

下載SDK

  • https://docs.open.alipay.com/54/103419
  • 接口調用屬性配置





接口屬性配置查看


第四步:SDK的使用

SDK包說明:

  • alipay-sdk-java*.jar:支付寶SDK編譯文件jar
  • alipay-sdk-java*-source.jar:支付寶SDK源碼文件.jar
  • commons-logging-1.1.1.jar:SDK依賴的日誌jar
  • commons-logging-1.1.1-sources.jar:SDK依賴的日誌源碼jar

核心API:

  • AlipayClient:封裝簽名與驗證
  • AlipayTradePagePayRequest:支付請求類
  • AlipayTradePagePayModel:封裝請求支付信息

服務器異步通知

  • notify_url
  • 支付寶使用POST方式,保證99.999999%的通知到達率

頁面跳轉同步通知

  • return_url
  • 支付寶使用GET方式,是由客戶瀏覽器觸發的一個通知,不保證其到達率。

支付寶支付編碼實現解析

看文檔“電腦網站支付”>“快速接入”

https://docs.open.alipay.com/270/105899/



獲取訂單信息

顯示所有訂單信息

/**
	 * 確認訂單信息
	 *
	 * @param orderNo
	 *            訂單ID
	 * @return
	 */
	@RequestMapping(value = "/prepay/{orderNo}", method = RequestMethod.GET)
    @ResponseBody
	public Dto prePay(@PathVariable String orderNo,HttpServletResponse response) {
        response.setHeader("Access-Control-Allow-Origin", "*");
		try {
			QgOrder order = qgAlipayService.loadQgOrderByOrderNo(orderNo);
			if (!EmptyUtils.isEmpty(order)) {
				Map<String,Object> result=new HashMap<String, Object>();
				result.put("orderNo", orderNo);
				result.put("goodsId", order.getGoodsId());
				result.put("count", order.getNum());
				result.put("payAmount", order.getAmount());
				return DtoUtil.returnSuccess("獲取訂單信息成功", result);
			}else
				return DtoUtil.returnFail("訂單不存在","fail");
		} catch (Exception e) {
			e.printStackTrace();
			return DtoUtil.returnFail("獲取訂單信息失敗","fail");
		}
	}


統一下單API的實現

/**
	 * 客戶端提交訂單支付請求,對該API的返回結果不用處理,瀏覽器將自動跳轉至支付寶。即例子中的alipay.trade.page.pay.jsp
	 *
	 * @param WIDout_trade_no
	 *            商戶訂單號,商戶網站訂單系統中唯一訂單號,必填
	 * @param WIDsubject
	 *            訂單名稱,必填
	 * @param WIDtotal_amount
	 *            付款金額,必填
	 */
	@RequestMapping(value = "/pay", method = RequestMethod.POST)
	public void pay(
			@RequestParam String WIDout_trade_no,
			@RequestParam String WIDsubject,
			@RequestParam String WIDtotal_amount, HttpServletResponse response) {
        response.setHeader("Access-Control-Allow-Origin", "*");
		String product_code = "FAST_INSTANT_TRADE_PAY";
		// SDK 公共請求類,包含公共請求參數,以及封裝了簽名與驗籤,開發者無需關注簽名與驗籤
		// 調用RSA簽名方式
		AlipayClient client = new DefaultAlipayClient(alipayConfig.getUrl(),
				alipayConfig.getAppID(), alipayConfig.getRsaPrivateKey(),
				alipayConfig.getFormat(), alipayConfig.getCharset(),
				alipayConfig.getAlipayPublicKey(), alipayConfig.getSignType());
        AlipayTradePagePayRequest  alipay_request = new AlipayTradePagePayRequest();

		// 封裝請求支付信息
        AlipayTradePagePayModel model = new AlipayTradePagePayModel();
		model.setOutTradeNo(WIDout_trade_no);
		model.setSubject(WIDsubject);
		model.setTotalAmount(WIDtotal_amount);
		model.setProductCode(product_code);
		alipay_request.setBizModel(model);
		// 設置異步通知地址
		alipay_request.setNotifyUrl(alipayConfig.getNotifyUrl());
		// 設置同步地址
		alipay_request.setReturnUrl(alipayConfig.getReturnUrl());
		// form表單生產
		String form = "";
		try {
			// 調用SDK生成表單
			form = client.pageExecute(alipay_request).getBody();
			response.setContentType("text/html;charset="
					+ alipayConfig.getCharset());
			response.getWriter().write(form);// 直接將完整的表單html輸出到頁面
			response.getWriter().flush();
			response.getWriter().close();
		} catch (AlipayApiException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

異步通知

 /**
     * 導步通知,跟蹤支付狀態變更,即例子中的notify_url.jsp
     * @param request
     * @param response
     */
	@RequestMapping(value = "/notify", method = RequestMethod.POST)
	public void trackPaymentStatus(HttpServletRequest request,
			HttpServletResponse response) {
        try {
            Map<String, Object> params = new HashMap<String, Object>();
			// 獲取支付寶POST過來反饋信息
			Map requestParams = request.getParameterMap();
            request.setCharacterEncoding("UTF-8");
			// 商戶訂單號
			String out_trade_no = request.getParameter("out_trade_no");
			// 支付寶交易號
			String trade_no = request.getParameter("trade_no");
			// 交易狀態
			String trade_status = request.getParameter("trade_status");
            boolean verify_result = qgAlipayService.asyncVerifyResult(requestParams);
			if (verify_result) {// 驗證成功
				response.getWriter().println("success"); // 請不要修改或刪除
			} else {// 驗證失敗
				response.getWriter().println("fail");
			}
		} catch (UnsupportedEncodingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			logger.error(e.getMessage());			
		} catch (AlipayApiException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			logger.error(e.getMessage());
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			logger.error(e.getMessage());
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			logger.error(e.getMessage());
		}
		
	}

同步通知

/**
	 * 支付寶頁面跳轉同步通知頁面
	 */
	@RequestMapping(value = "/return", method = RequestMethod.GET)
	public void callback(HttpServletRequest request,
			HttpServletResponse response) {
        response.setHeader("Access-Control-Allow-Origin", "*");
		try {
			//獲取支付寶GET過來反饋信息
			Map<String,String> params = new HashMap<String,String>();
            request.setCharacterEncoding("UTF-8");
			Map requestParams = request.getParameterMap();
			//獲取支付寶的通知返回參數,可參考技術文檔中頁面跳轉同步通知參數列表(以下僅供參考)//
			//商戶訂單號
			String out_trade_no = request.getParameter("out_trade_no");
			//支付寶交易號
			String trade_no = request.getParameter("trade_no");
			//獲取支付寶的通知返回參數,可參考技術文檔中頁面跳轉同步通知參數列表(以上僅供參考)//
			//計算得出通知驗證結果
			//boolean AlipaySignature.rsaCheckV1(Map<String, String> params, String publicKey, String charset, String sign_type)
			boolean verify_result = qgAlipayService.syncVerifyResult(requestParams);
			if(verify_result){//驗證成功
                if(!qgAlipayService.processed(out_trade_no)){
                    qgAlipayService.insertTrade(out_trade_no, trade_no);
                }
				String id=qgAlipayService.loadQgOrderByOrderNo(out_trade_no).getId().toString();
				//提示支付成功
				response.sendRedirect(String.format(alipayConfig.getPaymentSuccessUrl(), out_trade_no,id));
			}else{				
				//提示支付失敗
				response.sendRedirect(alipayConfig.getPaymentFailureUrl());
			}
		} catch (UnsupportedEncodingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			logger.error(e.getMessage());
		} catch (AlipayApiException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			logger.error(e.getMessage());
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			logger.error(e.getMessage());
		}
	}

測試

依賴項目shop-common,shop-goods,shop-order,shop-order,shop-pre。

  1. 訪問toPay.html,注意同一個訂單編號只能操作一次。點擊按鈕“去結算”,
  2. 所在頁面choosePay.html,確認訂單信息(/api/prepay/{orderNo}),選擇“支付寶”點擊“立即支付”。執行方法提交訂單信息(/api/pay)
  3. 跳轉到支付寶支付頁面(支付寶官方提供的頁面),可以用掃一掃進行支付,也可以用賬戶支付,這個賬戶可以用螞蟻金服沙箱賬號來支付。
  4. 支付成功後,跳轉到我們設置的一個支付成功的頁面
    alipay.paymentSuccessUrl=http://www.qg.com/success.html?orderNo=%s&amp;id=%sd

第五步:線上驗收

在沙箱環境完成功能調試後,必須將支付寶網關,appid,應用私鑰,支付寶公鑰修改成正式環境的配置,並在螞蟻正式環境進行完整的功能驗收測試。

完善應用基本信息

  • 應用名稱
  • 圖標
  • 簽約支付產品
  • 開發配置

等待審覈



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