java对接支付宝支付

允我心安 提交于 2020-01-18 06:51:58

 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已经封装掉了公共参数,这里只需要传入业务参数。以下方法为sdk的model入参方式(model和biz_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********");                      //商家idali_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);}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!