java對接支付寶支付


 java版支付寶app支付流程及原理分析

  本實例是基於springmvc框架編寫
     一、流程步驟
         1.執行流程
           當手機端app(就是你公司開發的app)在支付頁面時,調起服務端(后台第1個創建訂單接口)接口,后台把需要調起支付寶支付的參數返回給手機端,手機端拿到
         這些參數后,拉起支付寶支付環境完成支付,完成支付后會調異步通知(第2個接口),此時需要給支付寶返回成功或者失敗信息,成功后會調用同步通知(第3個接口)
         返回支付成功頁面,完成整個支付流程。
         
         2.支付的配置文件AlipayConfig           

復制代碼

public class AlipayConfig {
// 1.商戶appid
public static String APPID = "20170812********";

// 2.私鑰 pkcs8格式的
public static String RSA_PRIVATE_KEY ="";

// 3.支付寶公鑰
public static String ALIPAY_PUBLIC_KEY = "";

// 4.服務器異步通知頁面路徑 需http://或者https://格式的完整路徑,不能加?id=123這類自定義參數,必須外網可以正常訪問
public static String notify_url = "http://www.xxx.com/alipay/notify_url.do";

// 5.頁面跳轉同步通知頁面路徑 需http://或者https://格式的完整路徑,不能加?id=123這類自定義參數,必須外網可以正常訪問 商戶可以自定義同步跳轉地址
public static String return_url = "http://www.xxx.com/alipay/return_url.do";

// 6.請求網關地址
public static String URL = "https://openapi.alipay.com/gateway.do";

// 7.編碼
public static String CHARSET = "UTF-8";

// 8.返回格式
public static String FORMAT = "json";

// 9.加密類型
public static String SIGNTYPE = "RSA2";

}

復制代碼

 

 
         3.第1個創建訂單接口

 

 1  @RequestMapping(value = "/alipay",method = RequestMethod.POST)
 2     @ResponseBody
 3     public Object alipay(HttpServletRequest request){
 4         Map<String,Object> map=new HashMap<>();
 5         try {
 6             //實例化客戶端
 7             AlipayClient alipayClient=new DefaultAlipayClient(AlipayConfig.URL,AlipayConfig.APPID,AlipayConfig.RSA_PRIVATE_KEY,AlipayConfig.FORMAT,AlipayConfig.CHARSET,AlipayConfig.ALIPAY_PUBLIC_KEY,AlipayConfig.SIGNTYPE);
 8 
 9             //實例化具體API對應的request類,類名稱和接口名稱對應,當前調用接口名稱:alipay.trade.app.pay
10             AlipayTradeAppPayRequest ali_request =new AlipayTradeAppPayRequest();
11 
12             //SDK已經封裝掉了公共參數,這里只需要傳入業務參數。以下方法為sdk的model入參方式(model和biz_content同時存在的情況下取biz_content)。
13             AlipayTradeAppPayModel model=new AlipayTradeAppPayModel();
14             model.setPassbackParams(URLEncoder.encode("cc"));          //描述信息 添加附加數據
15             model.setBody("aa");                                          //商品信息
16             model.setSubject("bb");                                       //商品名稱
17             model.setOutTradeNo(AppUtil.uuid());                        //商品訂單號(自動生成)
18             model.setTimeoutExpress("30m");                             //交易超時時間
19             model.setTotalAmount("0.1");                                //支付金額
20             model.setProductCode("QUICK_WAP_PAY");                      //銷售產品碼
21             model.setSellerId("20881021********");                      //商家id
22             ali_request.setBizModel(model);
23             ali_request.setNotifyUrl(AlipayConfig.notify_url);          //回調地址
24 
25             AlipayTradeAppPayResponse alipayTradeAppPayResponse = alipayClient.sdkExecute(ali_request);
26             System.out.println(alipayTradeAppPayResponse.getBody());//就是orderString 可以直接給客戶端請求,無需再做處理。
27 
28             if (alipayTradeAppPayResponse.isSuccess()){
29                 map.put("code",200);
30                 map.put("body",alipayTradeAppPayResponse.getBody());
31             }else{
32                 map.put("code",101);
33             }
34 
35         } catch (Exception e) {
36             e.printStackTrace();
37         }
38         return JSONObject.toJSON(map);

 

    
         4.第2個異步回調接口

復制代碼
 1   /**
 2  * 支付寶支付成功后.回調該接口
 3  * @param request
 4  * @return
 5  * @throws IOException
 6  */  
 7 @RequestMapping(value="api/alipay/notify_url",method={RequestMethod.POST,RequestMethod.GET})
 8 @ResponseBody
 9 public String notify(HttpServletRequest request,HttpServletResponse response) throws IOException {  
10     Map<String, String> params = new HashMap<String, String>();  
       Map<String, String[]> requestParams = request.getParameterMap();  
       Trade trade =null; 11 //1.從支付寶回調的request域中取值 12 Map<String, String[]> requestParams = request.getParameterMap(); 13 14 for (Iterator<String> iter = requestParams.keySet().iterator(); iter.hasNext();) { 15 String name = iter.next(); 16 String[] values = requestParams.get(name); 17 String valueStr = ""; 18 for (int i = 0; i < values.length; i++) { 19 valueStr = (i == values.length - 1) ? valueStr + values[i] : valueStr + values[i] + ","; 20 } 21 // 亂碼解決,這段代碼在出現亂碼時使用。如果mysign和sign不相等也可以使用這段代碼轉化 22 // valueStr = new String(valueStr.getBytes("ISO-8859-1"), "gbk"); 23 params.put(name, valueStr); 24 } 25 //2.封裝必須參數 26 String out_trade_no = request.getParameter("out_trade_no"); // 商戶訂單號 27 String orderType = request.getParameter("body"); // 訂單內容 28 String tradeStatus = request.getParameter("trade_status"); //交易狀態 29 30 //3.簽名驗證(對支付寶返回的數據驗證,確定是支付寶返回的) 31 boolean signVerified = false; 32 try { 33 //3.1調用SDK驗證簽名 34 signVerified = AlipaySignature.rsaCheckV1(params, AlipayConfig.ALIPAY_PUBLIC_KEY, AlipayConfig.CHARSET, AlipayConfig.SIGNTYPE);35 } catch (AlipayApiException e) { 36 e.printStackTrace(); 37 } 38 //4.對驗簽進行處理 39 if (signVerified) { //驗簽通過 40 if(tradeStatus.equals("TRADE_SUCCESS")) { //只處理支付成功的訂單: 修改交易表狀態,支付成功 41 Trade trade = tradeService.selectByOrderNumber(out_trade_no); 42 trade.setTradeStatus((byte)3); //支付完成 43 int returnResult = tradeService.updateByPrimaryKeySelective(trade); //更新交易表中狀態 44 if(returnResult>0){ 45 return "success"; 47 }else{ 48 return "fail"; 50 } 51 }else{ 52 return "fail"; 53 } 54 } else { //驗簽不通過 55 System.err.println("驗簽失敗"); 57 return "fail"; 58 } 59 }
復制代碼

     
         5.第3個同步通知接口

復制代碼
 1    /**
 2     * 支付寶支付成功后.通知頁面
 3     *@author Zhao
 4     *@date 2017年11月2日
 5     *@param request
 6     *@return
 7     *@throws UnsupportedEncodingException
 8      */
 9     @RequestMapping(value="api/alipay/return_url",method={RequestMethod.POST,RequestMethod.GET})
10     @ResponseBody
11     public Model returnUrl(@RequestParam("id") String id,HttpServletRequest request,Model model) throws UnsupportedEncodingException {  
12         System.err.println("。。。。。。 同步通知 。。。。。。");
13         System.err.println("。。。。。。 同步通知 。。。。。。");
14         System.err.println("。。。。。。 同步通知 。。。。。。");
15         Map  returnMap = new HashMap();  
16         try {
17             
18             Trade trade = tradeService.selectByOrderNumber(id);
19              // 返回值Map  
20             if(trade !=null && trade.getTradeStatus() == 2){
21                 User user = userService.selectByPrimaryKey(trade.gettUserId());
22                 returnMap.put("tradeType", trade.getTradeType());             //支付方式
23                 returnMap.put("phoneNum", user.getPhoneNumber());             //支付帳號
24                 returnMap.put("tradeMoney", trade.getTradeMoney()+"");        //訂單金額
25                 
26             }else{
27                  model.addAttribute("msg", "查詢失敗");
28                  model.addAttribute("status", 0);
29             }
30              model.addAttribute("returnMap", returnMap);
31              System.err.println(returnMap);
32              model.addAttribute("msg", "查詢成功");
33              model.addAttribute("status", 0);
34         } catch (Exception e) {
35             model.addAttribute("msg", "查詢失敗");
36             model.addAttribute("status", 1);
37         }
38          
39          return model;  
40     }
復制代碼

    二、測試

  支付寶在app端支付成功后,要調用異步通知,因些需要訪問的url必須是外網可以訪問的,在這里推薦一款內網穿透工具natapp,需要用身份證號驗證,測試個支付是沒問題的

   附:

    1. natapp官網: https://natapp.cn

    2.natapp 1分鍾新手圖文教程: https://natapp.cn/article/natapp_newbie

     
    三、流程分析:
         1.配置文件AlipayConfig注意事項:
             (1)注意沙箱環境和正式環境的不同:
                商戶appid    : 
                    沙箱:進入沙箱環境會自動分配
                    正式:商戶唯一的標識
                請求網關地址:
                    沙箱:https://openapi.alipaydev.com/gateway.do
                    正式:https://openapi.alipay.com/gateway.do
             (2)公鑰和私鑰
                 公鑰和私鑰是自己生成的不要配錯,與支付寶的公鑰不要混淆了。(詳情見:https://docs.open.alipay.com/204/105297)
         2. 本案例只是對支付進行說明,退款等功能可進行舉一反三編寫。

轉自:https://www.cnblogs.com/MrRightZhao/p/7852511.html

//SDK已經封裝掉了公共參數,這里只需要傳入業務參數。以下方法為sdkmodel入參方式(modelbiz_content同時存在的情況下取biz_content)
AlipayTradeAppPayModel model=new AlipayTradeAppPayModel();
model.setPassbackParams(URLEncoder.encode("")); //描述信息 添加附加數據
model.setBody(""); //商品信息
model.setSubject(""); //商品名稱
model.setOutTradeNo(AppUtil.uuid()); //商品訂單號(自動生成)
model.setTimeoutExpress("30m"); //交易超時時間
model.setTotalAmount("0.1"); //支付金額
model.setProductCode("QUICK_WAP_PAY"); //銷售產品碼
model.setSellerId("20881021********"); //商家id
ali_request.setBizModel(model);
ali_request.setNotifyUrl(AlipayConfig.notify_url); //回調地址

AlipayTradeAppPayResponse alipayTradeAppPayResponse = alipayClient.sdkExecute(ali_request);
System.out.println(alipayTradeAppPayResponse.getBody());//就是orderString 可以直接給客戶端請求,無需再做處理。

if (alipayTradeAppPayResponse.isSuccess()){
map.put("code",200);
map.put("body",alipayTradeAppPayResponse.getBody());
}else{
map.put("code",101);
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM