支付寶支付之App支付

 

與微信支付對比,支付寶支付就沒有那麼多坑了,畢竟支付寶開放平臺的文檔仍是描述的很詳細的。java

支付寶開放平臺地址:https://docs.open.alipay.com/204/105297/web

支付寶支付的流程以下圖所示:spring

項目中接入支付寶支付的步驟:express

在這裏分爲了三個文件進行整理:json

  1. 基礎信息配置文件:AlipayConfig.java
  2. 調用API接口:AliPayUtil.java
  3. 對外接口:AlipayController.java

 AlipayConfig.javaapi

此文件中主要是配置了應用ID、支付寶公鑰、應用密鑰等基礎信息,以及支付寶支付API提供的對外接口地址信息。服務器

 1 package com.xhgx.web.pay.aliPay;
 2 
 3 import com.erenju.util.GlobleConfig;
 4 
 5 /**
 6  * 支付寶支付基礎信息配置
 7  * @author rxn
 8  * @date 2018/04/25
 9  */
10 public class AlipayConfig {
11 
12     /**
13      * 合做身份者ID,簽約帳號,16位純數字
14      */
15     public static String partner = "2088******";
16     /**
17      * 收款支付寶帳號,通常狀況下收款帳號是簽約帳號
18      */
19     public static String seller_id = partner;
20     /**
21      * appid
22      */
23     public static String app_id = "2018*****";//正式
24 //    public static String app_id = "2016*****";//沙箱
25     /**
26      * MD5密鑰,32位字符串
27      */
28     public static String key = "******";
29     /**
30      * 支付寶公鑰 (使用工具生成)
31      */
32     public static String public_key = "";//正式
33     /**
34      * 應用密鑰 (特別長)
35      */
36     public static String private_key = "";
37 
38     /**
39      * 服務器異步通知頁面路徑,需http://格式的完整路徑,不能加自定義參數,必須外網能夠正常訪問
40      * 異步通知頁面,就是接受支付寶支付結果返回信息的Contrller,能夠處理本身的支付後的邏輯
41      */
42     public static String notify_url = GlobleConfig.getProperty("PayNotifyUrl")+"/alipay/notify.json";
43     /**
44      * 服務器同步通知頁面路徑,需http://格式的完整路徑,不能加自定義參數,必須外網能夠正常訪問
45      * 同步通知頁面,就是支付寶支付成功後頁面跳轉的url
46      */
47     public static String return_url = GlobleConfig.getProperty("PayNotifyUrl")+"/alipay/return.json";
48     /**
49      * 簽名方式 ,(必須與生成密鑰的簽名方式一致)
50      */
51 //    public static String sign_type = "MD5";
52     public static String sign_type = "RSA2";
53     /**
54      * 日誌文件
55      */
56     public static String log_path = "";
57     /**
58      * 字符編碼格式
59      */
60     public static String charset = "utf-8";
61     /**
62      * 返回格式
63      */
64     public static String format = "json";
65     /**
66      * 支付類型
67      */
68     public static String payment_type = "1";
69     /**
70      * 支付寶網關(app支付接口)
71      */
72     public static String AppPayUrl = "https://openapi.alipay.com/gateway.do";//線上
73 //    public static String AppPayUrl = "https://openapi.alipaydev.com/gateway.do";//調試
74 }
View Code

AliPayUtil.java微信

此文件爲工具類文件,實現了調用支付寶API提供的一些接口,下面的代碼中主要包含了調用支付的接口和統一查詢支付結果的接口。app

  1 package com.xhgx.web.pay.aliPay;
  2 
  3 import java.net.URLEncoder;
  4 import java.util.HashMap;
  5 import java.util.LinkedHashMap;
  6 import java.util.Map;
  7 import org.activiti.engine.repository.Model;
  8 import org.springframework.security.web.header.writers.frameoptions.StaticAllowFromStrategy;
  9 import com.alipay.api.AlipayApiException;
 10 import com.alipay.api.AlipayClient;
 11 import com.alipay.api.DefaultAlipayClient;
 12 import com.alipay.api.domain.AlipayTradeAppPayModel;
 13 import com.alipay.api.request.AlipayTradeAppPayRequest;
 14 import com.alipay.api.response.AlipayTradeAppPayResponse;
 15 
 16 /**
 17  * 支付寶支付調用API接口
 18  * @author rxn
 19  * @date 2018/04/28
 20  *
 21  */
 22 public class AliPayUtil {
 23     
 24     /**
 25      * 建立訂單
 26      * @param orderId    訂單id
 27      * @param total_amount    付款金額(單位:元)
 28      * @return
 29      * @throws AlipayApiException 
 30      */
 31     public static Map<String, Object> createOrder(String orderId,String total_amount) throws AlipayApiException{
 32         
 33         String orderStr = "";
 34         Map<String,Object> m = new HashMap<String, Object>();
 35         try {
 36             //封裝訂單
 37             Map<String, String> orderMap = new LinkedHashMap<String,String>();
 38             //公共參數
 39             Map<String, String> bizModel = new LinkedHashMap<String,String>();
 40             
 41             //商品參數封裝
 42             orderMap.put("out_trade_no",orderId);//商戶訂單號,必填
 43             orderMap.put("subject", "*****");//訂單名稱,必填
 44 //            orderMap.put("total_amount", total_amount);//付款金額,必填
 45             orderMap.put("total_amount", 0.01+"");//付款金額,必填
 46             orderMap.put("body", "");//商品描述,選填
 47             orderMap.put("timeout_express", "30m");//超時時間,選填
 48             orderMap.put("prodect_code", "QUICK_MSECURITY_PAY");//銷售產品碼
 49             
 50             //公共參數封裝
 51             bizModel.put("app_id", AlipayConfig.app_id);//appId
 52             bizModel.put("method", AlipayConfig.AppPayUrl);//請求網關地址
 53             bizModel.put("format", AlipayConfig.format);//返回格式
 54             bizModel.put("private_key", AlipayConfig.private_key);//密鑰
 55             
 56             //實例化客戶端,只須要實例化一次便可
 57             AlipayClient alipayClient = new DefaultAlipayClient(AlipayConfig.AppPayUrl, AlipayConfig.app_id, AlipayConfig.private_key, "json", AlipayConfig.charset, AlipayConfig.public_key, AlipayConfig.sign_type);
 58             //實例化具體API對應的request類,類名稱和接口名稱對應
 59             AlipayTradeAppPayRequest ali_request = new AlipayTradeAppPayRequest();
 60             
 61             //傳入參數,sdk已經封裝了公共參數,這裏只需傳入業務參數。
 62             //如下方法是sdk的model入參方式(model和biz_content同時存在的狀況下取biz_content)
 63             AlipayTradeAppPayModel model = new AlipayTradeAppPayModel();
 64 //            model.setPassbackParams(URLEncoder.encode(orderMap.get("body")));//公用回傳參數,選填,UrlEncode以後才能夠發送給支付寶。 
 65             model.setBody(orderMap.get("body"));//商品信息
 66             model.setSubject(orderMap.get("subject"));//商品名稱
 67             model.setOutTradeNo(orderMap.get("out_trade_no"));//商品訂單號
 68             model.setTimeoutExpress(orderMap.get("timeout_express"));//交易超出時間
 69             model.setTotalAmount(orderMap.get("total_amount"));//總金額
 70             model.setProductCode(orderMap.get("prodect_code"));//銷售產品碼
 71             model.setSellerId(AlipayConfig.seller_id);//支付寶用戶id
 72             ali_request.setBizModel(model);
 73             ali_request.setNotifyUrl(AlipayConfig.notify_url);//回調地址
 74             
 75             AlipayTradeAppPayResponse response = alipayClient.sdkExecute(ali_request);
 76             orderStr = response.getBody();
 77             
 78             if(response.isSuccess()){
 79                 m.put("result", orderStr);
 80                 m.put("code", 0);
 81                 m.put("msg", "訂單生成成功");
 82             }else{
 83                 m.put("code", 1);
 84                 m.put("msg", "訂單生成失敗");
 85             }
 86             
 87         } catch (Exception e) {
 88             // TODO: handle exception
 89             m.put("code", 1);
 90             e.printStackTrace();
 91             m.put("msg", "訂單生成失敗");
 92         }
 93         
 94         return m;
 95     }
 96     /**
 97      * 查詢訂單
 98      * @param orderId    訂單id
 99      * @return
100      * @throws AlipayApiException 
101      */
102     public static Map<String, Object> getOrder(String orderId) throws AlipayApiException{
103         System.out.println("查詢支付結果");
104         Map<String,Object> m = new HashMap<String, Object>();
105         try {
106             //封裝訂單
107             Map<String, String> orderMap = new LinkedHashMap<String,String>();
108             //商品參數封裝
109             orderMap.put("out_trade_no",orderId);//商戶訂單號,必填
110             
111             //實例化客戶端
112             AlipayClient alipayClient = new DefaultAlipayClient(AlipayConfig.AppPayUrl, AlipayConfig.app_id, AlipayConfig.private_key, "json", AlipayConfig.charset, AlipayConfig.public_key, AlipayConfig.sign_type);
113             //實例化具體API對應的request類,類名稱和接口名稱對應
114             AlipayTradeQueryRequest ali_request = new AlipayTradeQueryRequest();
115             
116             //傳入參數,sdk已經封裝了公共參數,這裏只需傳入業務參數。
117             //如下方法是sdk的model入參方式(model和biz_content同時存在的狀況下取biz_content)
118             AlipayTradeQueryModel model = new AlipayTradeQueryModel();
119             model.setOutTradeNo(orderMap.get("out_trade_no"));//商品訂單號
120             ali_request.setBizModel(model);
121             ali_request.setNotifyUrl(AlipayConfig.notify_url);//回調地址
122             
123             AlipayTradeQueryResponse response = alipayClient.execute(ali_request);
124             System.out.println(response.getCode()+"---"+response.getMsg());
125             if(response.isSuccess()){
126                 System.out.println(response.getTradeStatus());
127                 switch (response.getTradeStatus()) {
128                 case "TRADE_FINISHED"://交易結束並不可退款
129                     m.put("status", "OK");
130                     break;
131                 case "TRADE_SUCCESS"://交易支付成功
132                     m.put("status", "OK");
133                     break;
134                 case "TRADE_CLOSED"://未付款交易超時關閉或支付完成後全額退款
135                     m.put("status", "ERROR");
136                     break;
137                 case "WAIT_BUYER_PAY"://交易建立並等待買家付款
138                     m.put("status", "ERROR");
139                     break;
140                 default:
141                     m.put("status", "ERROR");
142                     break;
143                 }
144                 
145                 m.put("code", 0);
146                 m.put("msg", "訂單生成成功");
147             }else{
148                 m.put("code", 1);
149                 m.put("msg", "訂單生成失敗");
150             }
151             
152         } catch (Exception e) {
153             m.put("code", 1);
154             e.printStackTrace();
155             m.put("msg", "訂單生成失敗");
156         }
157         
158         return m;
159     }
160 }
View Code

AlipayController.javadom

此文件中主要是對外的異步通知接口,異步通知接口和同步通知接口性質是同樣的,都是爲了接收支付後平臺返回的信息,下面的代碼中只實現了異步通知接口。

  1 package com.xhgx.web.pay.aliPay;
  2 
  3 import java.util.Date;
  4 import java.util.HashMap;
  5 import java.util.Iterator;
  6 import java.util.Map;
  7 import javax.servlet.http.HttpServletRequest;
  8 import javax.servlet.http.HttpServletResponse;
  9 import org.springframework.stereotype.Controller;
 10 import org.springframework.web.bind.annotation.RequestMapping;
 11 import org.springframework.web.bind.annotation.ResponseBody;
 12 import com.alipay.api.AlipayApiException;
 13 import com.alipay.api.internal.util.AlipaySignature;
 14 import com.xhgx.service.PayNotifyTblService;
 15 import com.xhgx.service.domain.PayNotifyTbl;
 16 import com.xhgx.web.SpringContextUtil;
 17 import common.Logger;
 18 
 19 @Controller
 20 public class AlipayController {
 21 
 22     public static Logger log = Logger.getLogger(AlipayController.class);
 23     
 24     /**
 25      * 支付寶支付成功後,異步通知,回調該接口
 26      * @param request
 27      * @param response
 28      * @return
 29      */
 30     @ResponseBody
 31     @RequestMapping("/alipay/notify.json")
 32     public static String notifyUrl(HttpServletRequest request,HttpServletResponse response){
 33         log.info("支付寶支付:"+"異步通知");
 34         Map<String, String> params = new HashMap<String, String>();
 35         
 36         //1.從支付寶回調的request中取值
 37         Map<String, String[]> requestParams = request.getParameterMap();
 38         
 39         for(Iterator<String> iter = requestParams.keySet().iterator();iter.hasNext();){
 40             String name = iter.next(); 
 41             String[] values = requestParams.get(name);
 42             String valueStr = "";
 43             for(int i=0;i<values.length;i++){
 44                 valueStr = (i == values.length - 1) ? valueStr + values[i] : valueStr + values[i] + ",";
 45             }
 46             //亂碼解決
 47 //            valueStr = new String(valueStr.getBytes("ISO-8859-1"), "gbk");
 48             params.put(name, valueStr);
 49         }
 50         
 51         //2.封裝必須的參數
 52         String out_trade_no = request.getParameter("out_trade_no");
 53         String orderType = request.getParameter("body");
 54         String tradeStatus = request.getParameter("trade_status");
 55         String app_id = request.getParameter("app_id");
 56         String trade_no = request.getParameter("trade_no");//支付寶交易號
 57         String notify_time = request.getParameter("notify_time");//通知時間
 58         String total_amount = request.getParameter("total_amount");//訂單金額,單位元
 59         
 60         //3.簽名驗證(對支付寶返回的數據驗證,肯定是支付寶返回的)
 61         boolean signVerified = false;
 62         //3.1調用SDK驗證簽名
 63         try {
 64             signVerified = AlipaySignature.rsaCheckV1(params, AlipayConfig.public_key, AlipayConfig.charset,AlipayConfig.sign_type);
 65         } catch (AlipayApiException e) {
 66             // TODO Auto-generated catch block
 67             e.printStackTrace();
 68         }
 69         
 70         if(payNotifyTblService==null){
 71             payNotifyTblService= (PayNotifyTblService) SpringContextUtil.getBean(PayNotifyTblService.class);
 72         }
 73         
 74         //建立有一個對象,保存通知信息,根據業務需求來決定
 75         PayNotifyTbl payNotifyTbl = new PayNotifyTbl();
 76         payNotifyTbl.setPay_type(2);//支付類型:2支付寶
 77         payNotifyTbl.setCreate_dt(new Date());
 78         
 79         payNotifyTbl.setReturn_code(tradeStatus);
 80         payNotifyTbl.setResult_code(tradeStatus);
 81         
 82         //4.對驗籤進行處理
 83         if(signVerified){
 84             if(tradeStatus.equals("TRADE_SUCCESS")){
 85                 
 86                 //支付成功,進行業務處理
 87                     
 88                     payNotifyTbl.setAppid(app_id);
 89                     payNotifyTbl.setOrder_id(out_trade_no);
 90                     payNotifyTbl.setTotal_fee(Double.parseDouble(total_amount));
 91                     payNotifyTbl.setTransaction_id(trade_no);
 92                     payNotifyTbl.setTime_end(notify_time);
 93                     payNotifyTbl.setPay_result("交易成功");
 94                     
 95                     payNotifyTbl = payNotifyTblService.save(payNotifyTbl);
 96                     
 97                     return "success";
 98                 }else{
 99                     payNotifyTbl.setPay_result("參數有誤");
100                     payNotifyTbl = payNotifyTblService.save(payNotifyTbl);
101                     log.info("參數有誤");
102                     return "fail";
103                 }
104             }else{
105                 payNotifyTbl.setPay_result("交易失敗");
106                 payNotifyTbl = payNotifyTblService.save(payNotifyTbl);
107                 log.info("交易失敗");
108                 return "fail";
109             }
110         }else{
111             payNotifyTbl.setPay_result("驗籤失敗");
112             payNotifyTbl = payNotifyTblService.save(payNotifyTbl);
113             log.info("驗籤失敗");
114             return "fail";
115         }
116     }
117     
118     /**
119      * 支付寶支付成功後,同步通知
120      * @param request
121      * @param response
122      * @return
123      */
124     @ResponseBody
125     @RequestMapping("/alipay/return.json")
126     public static String returnUrl(HttpServletRequest request,HttpServletResponse response){
127         log.info("支付寶支付:"+"同步通知");
128         
129         
130         
131         return null;
132     }
133 }
View Code

 開發中用到的工具包:https://files.cnblogs.com/files/ning0628/alipay-sdk-JAVA-3.0.0.zip;https://files.cnblogs.com/files/ning0628/alipaytradeapppay.zip

相關文章
相關標籤/搜索