1.支付寶回調地址設置在上一篇博客已經記錄
地址:https://blog.csdn.net/qq_38669394/article/details/106671410
2.支付寶回調方法,最主要兩點,一個是如何接受參數,另一個是驗籤 ,這裏需要將支付寶回調的參數轉爲map
@RequestMapping(value = "/alyPayNotify")
public String alyPayNotify(HttpServletRequest request, HttpServletResponse response) throws IOException, JDOMException {
log.info("支付寶支付成功回調");
//這裏拿到支付寶通知數據
Map<String, Object> params = convertRequestParamsToMap(request); // 將異步通知中收到的待驗證所有參數都存放到map中
String paramsJson = JSON.toJSONString(params);
log.info("支付寶回調,{}"+ paramsJson);
Map<String, String> map = JSON.parseObject(paramsJson, new TypeReference<Map<String, String>>(){});
return aliPayService.aliPayNotify(map, response);
}
// 將request中的參數轉換成Map
private static Map<String, Object> convertRequestParamsToMap(HttpServletRequest request) {
Map<String,Object> returnMap = new HashMap<String,Object>();
Map<String,String[]> map = new HashMap<String,String[]>();
map = request.getParameterMap();
Iterator entries = map.entrySet().iterator();
Map.Entry entry;
String name ="";
String value=null;
while (entries.hasNext()){
entry=(Map.Entry)entries.next();
name = (String) entry.getKey();
Object objvalue = entry.getValue();
if(objvalue == null){
value = null;
}else if(objvalue instanceof String[]){
/**條件如果成立,objvalue就是一個數組,需要將它轉換成爲字符串,並拼接上逗號,並吧末尾的逗號去掉*/
String[] values = (String[]) objvalue;
for(int i=0;i<values.length;i++){
value = values[i]+",";//這裏我拼接的是英文的逗號。
}
value = value.substring(0,value.length()-1);//截掉最後一個逗號。
}else{
value = objvalue.toString();
}
log.info("key:"+name);
log.info("value:"+value);
returnMap.put(name , value);
}
Iterator it = returnMap.keySet().iterator();
while (it.hasNext()){
Object key = it.next();
if(returnMap.get(key) == null || "".equals (((String)returnMap.get(key)).trim())){
returnMap.put((String) key, null);
}
}
return returnMap;
}
3,支付寶回調驗籤,這裏需要選擇輸出流的形式返回success ,return 方式支付寶好像不接受,不知道是不是因爲版本原因,代碼我就不一一修改了。這裏簽名驗證方式與網上的有些方法也略有區別,參數不同。具體可參考我的另一篇支付寶博客
地址:https://blog.csdn.net/qq_38669394/article/details/106336900
@Override
public String aliPayNotify(Map<String, String> map, HttpServletResponse response) {
// 調用SDK驗證簽名
try {
String sign = (String) map.get("sign");
String content = AlipaySignature.getSignCheckContentV1(map);
boolean signVerified = AlipaySignature.rsaCheck(content, sign, Configs.getAlipayPublicKey(), AliPayProperties.CHARSET, AliPayProperties.SIGNTYPE);
if (signVerified) {
log.info("支付寶回調簽名認證成功");
// 按照支付結果異步通知中的描述,對支付結果中的業務內容進行1\2\3\4二次校驗,校驗成功後在response中返回success,校驗失敗返回failure
//檢查金額是否一致
//this.check(params);
// 支付寶建議 另起線程處理業務
Executors.newFixedThreadPool(20).execute(new Runnable() {
@Override
public void run() {
log.info("ZFB回調參數" + map);
String trade_status = map.get("trade_status");
log.info("trade_status:" + trade_status);
// 支付成功
if (trade_status.equals("TRADE_SUCCESS")) {
// 處理支付成功邏輯
try {
// 處理業務邏輯。。。
String out_trade_no = map.get("out_trade_no");
String trade_no = map.get("trade_no");
String total_amount = map.get("total_amount");
} catch (Exception e) {
log.error("支付寶回調業務處理報錯,params:" + e);
}
} else {
log.error("沒有處理支付寶回調業務,支付寶交易狀態:{},params:{}", trade_status);
}
}
});
BufferedOutputStream out = null;
try {
out = new BufferedOutputStream(response.getOutputStream());
out.write("success".getBytes());
out.flush();
out.close();
} catch (Exception e) {
e.printStackTrace();
}
return "success";
} else {
log.info("支付寶回調簽名認證失敗,signVerified=false, paramsJson:{}");
return "failure";
}
} catch (AlipayApiException e) {
log.error("支付寶回調簽名認證失敗,paramsJson:{},errorMsg:{}", e.getMessage());
return "failure";
}
}