引入SDK:前端
<!-- https://mvnrepository.com/artifact/com.aliyun/aliyun-java-sdk-core -->
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>aliyun-java-sdk-core</artifactId>
<version>4.1.1</version>
</dependency>
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>aliyun-java-sdk-green</artifactId>
<version>3.2.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/commons-codec/commons-codec -->
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.10</version>
</dependency>
<dependency>
<groupId>com.alipay.sdk</groupId>
<artifactId>alipay-sdk-java</artifactId>
<version>3.0.0</version>
</dependency>
預支付訂單:java
public Map<String,Object> alipay(NyOrder order) {
//實例化客戶端
AlipayClient alipayClient = new DefaultAlipayClient(URL, APP_ID, APP_PRIVATE_KEY, FORMAT, CHARSET, ALIPAY_PUBLIC_KEY, SIGN_TYPE);//此處的SIGN_TYPE是"RSA2"算法
//實例化具體API對應的request類,類名稱和接口名稱對應,當前調用接口名稱:alipay.trade.app.pay
AlipayTradeAppPayRequest request = new AlipayTradeAppPayRequest();
//SDK已經封裝掉了公共參數,這裏只須要傳入業務參數。如下方法爲sdk的model入參方式(model和biz_content同時存在的狀況下取biz_content)。
AlipayTradeAppPayModel model = new AlipayTradeAppPayModel();
model.setBody("xxxxx"); //商品描述
model.setSubject("xxxxx"); // 商品標題
// 雪花算法生成訂單號
String tradeNo = String.valueOf(SnowFlake.getSnowFlake().nextId());
model.setOutTradeNo(tradeNo); //訂單號
model.setTimeoutExpress("30m");// 該筆訂單容許的最晚付款時間,逾期將關閉交易。取值範圍:1m~15d。m-分鐘,h-小時,d-天,1c-當天(1c-當天的狀況下,不管交易什麼時候建立,都在0點關閉)。 該參數數值不接受小數點, 如 1.5h,可轉換爲 90m。注:若爲空,則默認爲15d。
model.setTotalAmount(order.getAmount().toString());//訂單總金額,單位爲元,精確到小數點後兩位,取值範圍[0.01,100000000]
/*model.setProductCode("xxxxxx");*///銷售產品碼,商家和支付寶簽約的產品碼,爲固定值QUICK_MSECURITY_PAY
model.setSellerId(SELLER_ID);
request.setBizModel(model);
request.setNotifyUrl(NOTIFY_URL);//支付寶異步調用後臺的url
// 建立訂單
NyOrder nyOrder = new NyOrder();
// 雪花算法生成訂單號
//生成訂單部分
LOGGER.info("開始生成訂單...");
nyOrderService.addUserOrder(nyOrder);
LOGGER.info("生成訂單完成!");
try {
//這裏和普通的接口調用不一樣,使用的是sdkExecute
AlipayTradeAppPayResponse response = alipayClient.sdkExecute(request);
// System.out.println(response.getBody());//就是orderString 能夠直接給客戶端請求,無需再作處理。
Map<String,Object> map=new HashMap<>();
map.put("alisign",response.getBody());//前端是拿到此數據喚起支付
map.put("tradeNo",tradeNo); //此處將訂單返回給前端,前端拿到此訂單號再進行查一遍
return map;
} catch (AlipayApiException e) {
e.printStackTrace();
PayCommonUtil.saveLog("/opt/ny/logs/aliay.txt", e.getErrMsg());
return null;
}
}
回調
@PostMapping(value = "/alipayNotify")
@ResponseBody
public String AlipayCallBack(HttpServletRequest request) throws Exception {
LOGGER.info("開始回調...");
Map<String, String> params = new HashMap<String, String>();
Map requestParams = request.getParameterMap();
for (Iterator iter = requestParams.keySet().iterator(); iter.hasNext(); ) {
String name = (String) iter.next();
String[] values = (String[]) requestParams.get(name);
String valueStr = "";
for (int i = 0; i < values.length; i++) {
valueStr = (i == values.length - 1) ? valueStr + values[i] : valueStr + values[i] + ",";
}
//亂碼解決,這段代碼在出現亂碼時使用。若是mysign和sign不相等也能夠使用這段代碼轉化//
//valueStr = new String(valueStr.getBytes("ISO-8859-1"), "UTF-8");
params.put(name, valueStr);
}
String notify_id = request.getParameter("notify_id");
String notify_type = request.getParameter("notify_type");
// 商戶訂單號
String trade_no = new String(request.getParameter("trade_no").getBytes("ISO-8859-1"), "UTF-8");
String trade_status = request.getParameter("trade_status");
// 支付寶交易號
String out_trade_no = request.getParameter("out_trade_no");
if (notify_id != "" && notify_id != null) {
if (notify_type.equals("trade_status_sync")) {
int exeCount = 0;
// 驗籤
boolean flag = AlipaySignature.rsaCheckV1(params, AliPayServiceImpl.ALIPAY_PUBLIC_KEY, "UTF-8", "RSA2");
if (true == flag && trade_status.equals("TRADE_SUCCESS")) {
LOGGER.info("TRADE_SUCCESS進入業務執行代碼");
exeCount = aliPayService.notifyExe(trade_no, out_trade_no);
LOGGER.info("TRADE_SUCCESS執行結果:" + exeCount);
if (exeCount > 0) {
return "success";
} else {
return "fail";
}
} else {
return "sign fail";
}
}
} else {
return "fail";
}
return "fail";
}
主要的部分:
阿里驗籤參數配置:
配置按照支付寶管理後臺申請的 配置就可
可是有點區別也是 比較坑的一點是:其中綠色框是 驗籤 工具生成的私鑰 紫色框 是 支付寶管理平臺的 支付寶公鑰(不是應用公鑰哦!!!!!切記) 以下圖
應該公鑰是 驗籤 工具生成的對應的 商戶應用公鑰 (開放平臺祕鑰 查看支付寶公鑰 貌似是不能修改的)
支付寶管理後臺 的開放平臺祕鑰--》RSA(SHA256)-->查看應用公鑰就是上圖驗籤工具的 商戶應用公鑰
PS:(支付寶配置 私鑰 公鑰 使用驗籤工具生成 同時 公鑰要在支付寶管理後臺設置 其他的不用操做引入支付寶SDK 在配置AliConfig的時候 其中裏面的私鑰是 驗籤工具生成的私鑰 公鑰是支付寶公鑰(切忌不是應用公鑰))
坑: 就是驗籤部分
具體:
1.下載驗籤工具
2.生成祕鑰(如上圖商戶應用私鑰,商戶應用公鑰)
3.商戶應用私鑰複製黏貼在AlipayConfig的app_private_key字段,商戶應用公鑰複製黏貼在 支付寶管理平臺--》開放平臺祕鑰--》RSA(SHA256)查看應用公鑰中
4.複製黏貼 支付寶管理平臺--》開放平臺祕鑰==》查看支付寶公鑰 放在AlipayConfig的alipay_public_key 字段
5.預支付的時候 須要加簽
AlipayClient alipayClient = new DefaultAlipayClient(URL, APP_ID, APP_PRIVATE_KEY, FORMAT, CHARSET, ALIPAY_PUBLIC_KEY, SIGN_TYPE); 其中SIGN_TYPE爲RSA2 其他的參數 按照申請的管理平臺自行配置
6.回調的時候驗籤
AlipaySignature.rsaCheckV1(params, AliPayServiceImpl.ALIPAY_PUBLIC_KEY, "UTF-8", "RSA2");7.回調的內容返回爲success 不然阿里會間歇性回調 (或者用字節流打印success)