支付宝支付之App支付

与微信支付对比,支付宝支付就没有那么多坑了,毕竟支付宝开放平台的文档还是描述的很详细的。

支付宝开放平台地址:https://docs.open.alipay.com/204/105297/

支付宝支付的流程如下图所示:

项目中接入支付宝支付的步骤:

在这里分为了三个文件进行整理:

  1. 基础信息配置文件:AlipayConfig.java
  2. 调用API接口:AliPayUtil.java
  3. 对外接口:AlipayController.java

 AlipayConfig.java

此文件中主要是配置了应用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的一些接口,下面的代码中主要粘了调用支付的接口。

 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 }
View Code

AlipayController.java

此文件中主要是对外的异步通知接口,异步通知接口和同步通知接口性质是一样的,都是为了接收支付后平台返回的信息,下面的代码中只实现了异步通知接口。

  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

猜你喜欢

转载自www.cnblogs.com/ning0628/p/9239351.html