目錄
第三方支付寶支付介紹
第二步配置祕鑰
配置搭建環境和SDK介紹
支付寶支付編碼實現解析
獲取訂單信息
統一下單API的實現
異步通知
同步通知
測試
第三方支付寶支付介紹
第三方支付平臺
選擇服務商
- 支付寶
- 財付通
- 銀聯商務
- 塊錢
- ... ...
沙箱環境
又稱沙盤,爲了開放與調試所提供的環境,它與生產環境互相隔離,但具有生產環境幾乎完全相同的功能。
螞蟻金服開放平臺——開發者中心
提供的調試產品
- APP支付
- 當面支付
- 電腦網站支付。
接入流程
- 創建應用並獲取APPID
- 配置祕鑰
- 搭建和配置開發環境
- 使用SDK(支付寶提供的)
- 線上驗收
第二步配置祕鑰
第一步:創建應用並獲取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。
- 訪問toPay.html,注意同一個訂單編號只能操作一次。點擊按鈕“去結算”,
- 所在頁面choosePay.html,確認訂單信息(/api/prepay/{orderNo}),選擇“支付寶”點擊“立即支付”。執行方法提交訂單信息(/api/pay)
- 跳轉到支付寶支付頁面(支付寶官方提供的頁面),可以用掃一掃進行支付,也可以用賬戶支付,這個賬戶可以用螞蟻金服沙箱賬號來支付。
- 支付成功後,跳轉到我們設置的一個支付成功的頁面
alipay.paymentSuccessUrl=http://www.qg.com/success.html?orderNo=%s&id=%sd
第五步:線上驗收
在沙箱環境完成功能調試後,必須將支付寶網關,appid,應用私鑰,支付寶公鑰修改成正式環境的配置,並在螞蟻正式環境進行完整的功能驗收測試。
完善應用基本信息
- 應用名稱
- 圖標
- 簽約支付產品
- 開發配置
等待審覈