Java springboot支付寶小程式授權,獲取使用者資訊,支付及回撥
阿新 • • 發佈:2020-08-22
參考官方文件https://opendocs.alipay.com/mini/introduce/pay
支付寶小程式的支付和微信小程式的支付一樣第一步都是要獲取到使用者的唯一標識,在微信中我們獲取到的是wxopenid,而支付寶中獲取到的是userid。
1 使用的alipay-sdk包 2 <dependency> 3 <groupId>com.alipay.sdk</groupId> 4 <artifactId>alipay-sdk-java</artifactId> 5 <version>4.5.0.ALL</version> 6</dependency>
1.授權 ==》前端使用 my.getAuthCode方法。
參考官方文件https://opendocs.alipay.com/mini/introduce/authcode
2.根據第一步的授權拿到auth_code來獲取唯一標識userid
1 /** 2 * 授權碼 3 * @param auth_code 4 * @return 5 * @throws AlipayApiException 6 */ 7 @RequestMapping("getInfo") 8public AjaxJson getInfo(String auth_code) throws AlipayApiException { 9 //使用支付寶小程式的固定方法獲取auth_code 10 if(auth_code==null||auth_code.length()==0) { 11 return AjaxJson.getError("請求引數auth_code不能為空"); 12 }else { 13 //String serverUrl, String appId, String privateKey, String format,String charset, String alipayPublicKey, String signType14 //例項化客戶端 引數:正式環境URL,Appid,商戶私鑰 PKCS8格式,字元編碼格式,字元格式,支付寶公鑰,簽名方式 15 AlipayClient alipayClient = new DefaultAlipayClient("https://openapi.alipay.com/gateway.do",AliPayConfig.APP_ID,AliPayConfig.MERCHANT_PRIVATE_KEY,"json","GBK",AliPayConfig.ALIPAY_PUBLIC_KEY,"RSA2"); 16 AlipaySystemOauthTokenRequest request = new AlipaySystemOauthTokenRequest(); 17 // 值為authorization_code時,代表用code換取 18 request.setGrantType("authorization_code"); 19 //授權碼,使用者對應用授權後得到的 20 request.setCode(auth_code); 21 //這裡使用execute方法 22 AlipaySystemOauthTokenResponse response = alipayClient.execute(request); 23 //重新整理令牌,上次換取訪問令牌時得到。見出參的refresh_token欄位 24 request.setRefreshToken(response.getAccessToken()); 25 //返回成功時 就將唯一標識返回 26 if(response.isSuccess()){ 27 System.out.println("呼叫成功"); 28 //我這裡只返回了一個欄位給前端用 29 Map<String,Object> map=new HashMap<>(); 30 map.put("userid", response.getUserId()); 31 return AjaxJson.getSuccessData(map); 32 } else { 33 return AjaxJson.getError("呼叫失敗"); 34 } 35 } 36 }
3.獲取使用者資訊 使用API中的方法 my.getOpenUserInfo 。
注意:獲取會員基礎資訊需要在開放平臺小程式 管理頁面 申請新增 獲取會員基礎資訊 功能包。
這裡肯定會有盆友不解授權和獲取使用者資訊可以寫在一個方法裡而我寫了兩個方法,對的。我一開始是放在一起寫的,但是測試的時候一直報出Isv許可權不足,能解決的辦法都試過了,繼續報錯。所以我是分開寫了方法。
4.支付 官方文件https://opendocs.alipay.com/mini/introduce/pay
注意這裡是官方文件中的程式碼
以下是我本人的程式碼
/** * 使用者唯一標識id * @param userid * @return */ @RequestMapping("/pay1") public static AlipayTradeCreateResponse pay(String userid){ //獲得初始化的AlipayClient AlipayClient alipayClient = new DefaultAlipayClient(AliPayConfig.GATEWAY_URL, AliPayConfig.APP_ID, AliPayConfig.MERCHANT_PRIVATE_KEY, "json", AliPayConfig.CHARSET, AliPayConfig.ALIPAY_PUBLIC_KEY, AliPayConfig.SIGN_TYPE); //設定請求引數 AlipayTradeCreateRequest request = new AlipayTradeCreateRequest(); JSONObject json=new JSONObject(); //雪花演算法訂單號 IdWorker idworker=new IdWorker(); Long oid=idworker.nextId(); String out_trade_no =String.valueOf(oid); //訂單號 json.put("out_trade_no",out_trade_no); //金額 這裡的金額是以元為單位的可以不轉換但必須是字串 json.put("total_amount","0.01"); //描述 json.put("subject","測試"); //使用者唯一標識id 這裡必須使用buyer_id 參考文件 json.put("buyer_id",userid); //物件轉化為json字串 String jsonStr=json.toString(); //商戶通過該介面進行交易的建立下單 request.setBizContent(jsonStr); //回撥地址 是能夠訪問到的域名加上方法名 request.setNotifyUrl("http://vvvvvvv.cn/aliPay/notifyUrl"); try { //使用的是execute AlipayTradeCreateResponse response = alipayClient.execute(request); return response; } catch (AlipayApiException e) { e.printStackTrace(); } return null; }
我在這裡有一些程式碼沒有使用官方文件的方式寫引數,是因為我一開始寫的時候去測試時一直返回引數無效,而我找了好久也不知道是什麼原因,這就很尷尬了,所以我換了一種方式。大家寫到這個地方的話可以參考。
前端呼叫my.tradePay方法
注意這裡的trandeNo引數不用改,這是固定的,訂單號需要你自己去支付那裡獲取。切記:獲取到的值是trade_no,並不是outTradeNo。
這是本人除錯時的圖,接下來離成功就不遠了。
5.回撥方法
1 /** 2 * 支付寶伺服器非同步通知url 3 * @throws Exception 4 */ 5 @RequestMapping(value="/notifyUrl") 6 public void notifyUrl(HttpServletRequest request,HttpServletResponse response) throws Exception{ 7 //獲取支付寶傳送過來的資訊 8 Map<String,String> params = new HashMap<String,String>(); 9 Map<String,String[]> requestParams = request.getParameterMap(); 10 //迴圈獲取到所有的值 11 for(String str:requestParams.keySet()) { 12 String name =str; 13 String[] values = (String[]) requestParams.get(name); 14 String valueStr = ""; 15 for (int i = 0; i < values.length; i++) { 16 valueStr = (i == values.length - 1) ? valueStr + values[i] 17 : valueStr + values[i] + ","; 18 } 19 //亂碼解決,這段程式碼在出現亂碼時使用 20 //valueStr = new String(valueStr.getBytes("ISO-8859-1"), "utf-8"); 21 params.put(name, valueStr); 22 } 23 //呼叫SDK驗證簽名 24 boolean signVerified = AlipaySignature.rsaCheckV1(params, AliPayConfig.ALIPAY_PUBLIC_KEY, AliPayConfig.CHARSET, AliPayConfig.SIGN_TYPE); 25 //boolean型別signVerified為true時 則驗證成功 26 if(signVerified) { 27 //獲取到支付的狀態 TRADE_SUCCESS則支付成功 28 String trade_status =request.getParameter("trade_status"); 29 if (trade_status.equals("TRADE_SUCCESS")){ 30 System.out.println("支付成功"); 31 }else { 32 System.out.println("支付失敗"); 33 } 34 } 35 //簽名驗證失敗 36 else { 37 System.out.println(AlipaySignature.getSignCheckContentV1(params)); 38 } 39 }