APP支付
首先盜用支付寶的時序圖
1:這裡要看清楚了加密的時候使用的是自己的私鑰進行簽名,發到支付寶那後,支付寶會使用我們存在支付寶中的應用公鑰對我們傳到前端的參數進行加密與我們生成的簽名進行比對,如果成功會根據我們指定的回調url位址發送到對應位址。同時帶上支付寶生成的參數資訊和支付寶私鑰生成簽名。
2:然後我們再根據支付寶提供的公鑰對參數直接進行簽名,與支付寶生成的參數進行比對,如果成功,則驗證簽名成功。
在第一步中會遇到ali40247
這個時候可以參考 點選打開連結
也有可能遇到ali38173
這個時候簽名已經比對上了,但是發送給支付寶的參數不合法
推薦使用支付寶自帶的sdk使用的相對進行簽名
AlipayTradeAppPayRequest request = new AlipayTradeAppPayRequest();
//SDK已經封裝掉了公共參數,這裡隻需要傳入業務參數。以下方法為sdk的model入參方式(model和biz_content同時存在的情況下取biz_content)。
AlipayTradeAppPayModel model = new AlipayTradeAppPayModel();
String map = sPara.get("biz_content");
model.setBody(bizContent.get("body") );
model.setSubject(bizContent.get("subject"));
model.setOutTradeNo(bizContent.get("out_trade_no"));
model.setTimeoutExpress("30m");
model.setTotalAmount(bizContent.get("total_amount"));
model.setProductCode(bizContent.get("product_code"));
request.setBizModel(model);
request.setNotifyUrl(sPara.get("notify_url"));
//這裡和普通的接口調用不同,使用的是sdkExecute
AlipayTradeAppPayResponse response = alipayClient.sdkExecute(request);
alipayClient這個對象是線程安全的,是以可以直接使用單例模式儲存這個對象
我使用的方式如下
private AlipayClient alipayClient = getAlipayClient();
public AlipayClient getAlipayClient() {
if(alipayClient == null){
alipayClient = createAlipayClient();
}
return alipayClient;
}
private synchronized AlipayClient createAlipayClient(){
if(alipayClient == null){
alipayClient = new DefaultAlipayClient("https://openapi.alipay.com/gateway.do", AlipayConfig.appId, AlipayConfig.private_key, "json", "UTF-8", AlipayConfig.alipay_public_key, "RSA2");
}
return alipayClient;
}
product_code這個東西是寫死的,在APP支付時使用的是QUICK_MSECURITY_PAY
在回調接口中
我們需要做3件事情
1:判斷過來的請求狀态是否成功
2:擷取請求的參數中的notify_id
去請求一下路徑擷取傳回值,如果傳回是true則這個請求有效的
"https://mapi.alipay.com/gateway.do?service=notify_verify&partner=" + partner + "¬ify_id=" + notify_id;
partner 為2088開頭的16位數字别和appId 搞混了
appId為目前年份開頭的16位數字
3:使用支付寶提供給你的支付寶公鑰簽名支付寶傳過來的參數
之前不知道究竟要簽名那些參數,我要驗證簽名的參數應該隻是我傳出去的參數。搞了半天,結果是全部直接簽名,其實要去掉sign和sign_type
如果使用支付寶的
isSign = AlipaySignature.rsaCheckV1(params, AlipayConfig.alipay_public_key, "UTF-8", AlipayConfig.sign_type_app);
這個方法要注意sign要由params帶進去,裡面的方法會去掉sign和sign_type
網頁支付
網站支付的流程和APP類似
第一步生成訂單資料簽名
AlipayTradePagePayRequest alipayRequest = new AlipayTradePagePayRequest();//建立API對應的request
AlipayTradeAppPayModel model = new AlipayTradeAppPayModel();
model.setBody(body);
model.setSubject(subject);
model.setOutTradeNo( String.valueOf(id) + sdf.format(new Date()) );
model.setTimeoutExpress("30m");
model.setTotalAmount( String.valueOf(df.format(((double)cost)/100)) );
model.setProductCode( "FAST_INSTANT_TRADE_PAY" );//和app支付唯一的差別
alipayRequest.setBizModel(model);
alipayRequest.setReturnUrl(AlipayConfig.RECHARGE_RETURN_URL + "?type=" + type);
alipayRequest.setNotifyUrl(AlipayConfig.RECHARGE_NOTIFY_URL);
String form="";
try {
form = alipayClient.pageExecute(alipayRequest).getBody(); //調用SDK生成表單
} catch (AlipayApiException e) {
e.printStackTrace();
}
請求得到form字元串直接往response的輸出流中輸出
要記得設定下contentType text/html;charset=utf-8
這樣使用者會直接跳轉到支付寶頁面進行支付操作
支付完成後,支付寶會根據我們設定的notify_url異步回調到自己的伺服器
在那裡我們可以進行驗簽 流程和app基本差不多,就不再贅述