博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
支付宝app支付java后台流程、原理分析(含nei wang chuan tou)
阅读量:5127 次
发布时间:2019-06-13

本文共 10040 字,大约阅读时间需要 33 分钟。

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

  本实例是基于springmvc框架编写

     一、流程步骤
         1.执行流程
           当手机端app(就是你公司开发的app)在支付页面时,调起服务端(后台第1个创建订单接口)接口,后台把需要调起支付宝支付的参数返回给手机端,手机端拿到
         这些参数后,拉起支付宝支付环境完成支付,完成支付后会调异步通知(第2个接口),此时需要给支付宝返回成功或者失败信息,成功后会调用同步通知(第3个接口)
         返回支付成功页面,完成整个支付流程。
        
         2.支付的配置文件AlipayConfig           

1 public class AlipayConfig { 2     // 1.商户appid 3     public static String APPID = "20170812********";     4      5     // 2.私钥 pkcs8格式的 6     public static String RSA_PRIVATE_KEY =""; 7      8     // 3.支付宝公钥 9     public static String ALIPAY_PUBLIC_KEY = "";10     11     // 4.服务器异步通知页面路径 需http://或者https://格式的完整路径,不能加?id=123这类自定义参数,必须外网可以正常访问12     public static String notify_url = "http://www.xxx.com/alipay/notify_url.do";13     14     // 5.页面跳转同步通知页面路径 需http://或者https://格式的完整路径,不能加?id=123这类自定义参数,必须外网可以正常访问 商户可以自定义同步跳转地址15     public static String return_url = "http://www.xxx.com/alipay/return_url.do";16     17     // 6.请求网关地址18     public static String URL = "https://openapi.alipay.com/gateway.do";    19     20     // 7.编码21     public static String CHARSET = "UTF-8";22     23     // 8.返回格式24     public static String FORMAT = "json";25     26     // 9.加密类型27     public static String SIGNTYPE = "RSA2";28     29 }

 

 

         3.第1个创建订单接口

 

1 /** 2 *@param userId        充值人 3 *@param tradeMoney    充值money(RMB) 4 *@throws AlipayApiException  ModelAndView 5  */ 6  @RequestMapping(value="api/alipay/createOrder",method={RequestMethod.POST,RequestMethod.GET}) 7  @ResponseBody 8  public Model alipay( 9         @RequestParam("userId")String userId,10         @RequestParam("tradeMoney")String tradeMoney,Model m) throws AlipayApiException{11     12     String orderStr = "";         13     try {14         15         /****** 1.封装你的交易订单开始 *****/                                        //自己用16         17         此处封装你的订单数据,订单状态可以设置为等待支付18         19         /****** 1.封装你的交易订单结束 *****/20         21         Map
orderMap = new LinkedHashMap
(); //订单实体22 Map
bizModel = new LinkedHashMap
(); //公共实体23 24 /****** 2.商品参数封装开始 *****/ //手机端用 25 // 商户订单号,商户网站订单系统中唯一订单号,必填26 orderMap.put("out_trade_no",trade.getOrderNumber());27 // 订单名称,必填28 orderMap.put("subject","手机网站支付购买游戏币");29 // 付款金额,必填30 orderMap.put("total_amount",tradeMoney);31 // 商品描述,可空32 orderMap.put("body","您购买游戏币"+tradeMoney +"元");33 // 超时时间 可空34 orderMap.put("timeout_express","30m");35 // 销售产品码 必填36 orderMap.put("product_code","QUICK_WAP_PAY");37 38 /****** 2.商品参数封装结束 *****/ 39 40 /******--------------- 3.公共参数封装 开始 ------------------------*****/ //支付宝用41 //1.商户appid42 bizModel.put("app_id",AlipayConfig.APPID);43 //2.请求网关地址44 bizModel.put("method",AlipayConfig.URL);45 //3.请求格式46 bizModel.put("format",AlipayConfig.FORMAT);47 //4.回调地址48 bizModel.put("return_url",AlipayConfig.return_url);49 //5.私钥50 bizModel.put("private_key",AlipayConfig.RSA_PRIVATE_KEY);51 //6.商家id52 bizModel.put("seller_id","2088102170411333");53 //7.加密格式54 bizModel.put("sign_type",AlipayConfig.SIGNTYPE+"");55 56 /******--------------- 3.公共参数封装 结束 ------------------------*****/57 58 //实例化客户端 59 AlipayClient client = new DefaultAlipayClient(AlipayConfig.URL, AlipayConfig.APPID, AlipayConfig.RSA_PRIVATE_KEY, AlipayConfig.FORMAT, AlipayConfig.CHARSET, AlipayConfig.ALIPAY_PUBLIC_KEY,AlipayConfig.SIGNTYPE);60 61 //实例化具体API对应的request类,类名称和接口名称对应,当前调用接口名称:alipay.trade.app.pay 62 AlipayTradeAppPayRequest ali_request = new AlipayTradeAppPayRequest(); 63 64 //SDK已经封装掉了公共参数,这里只需要传入业务参数。以下方法为sdk的model入参方式(model和biz_content同时存在的情况下取biz_content)。 65 AlipayTradeAppPayModel model = new AlipayTradeAppPayModel(); 66 model.setPassbackParams(URLEncoder.encode((String)orderMap.get("body").toString()));; //描述信息 添加附加数据 67 model.setBody(orderMap.get("body")); //商品信息68 model.setSubject(orderMap.get("subject")); //商品名称69 model.setOutTradeNo(orderMap.get("out_trade_no")); //商户订单号(自动生成)70 model.setTimeoutExpress(orderMap.get("timeout_express")); //交易超时时间71 model.setTotalAmount(orderMap.get("total_amount")); //支付金额72 model.setProductCode(orderMap.get("product_code")); //销售产品码73 model.setSellerId("20881021********"); //商家id74 ali_request.setBizModel(model); 75 ali_request.setNotifyUrl(AlipayConfig.notify_url); //回调地址 76 77 AlipayTradeAppPayResponse response = client.sdkExecute(ali_request); 78 orderStr = response.getBody(); 79 System.err.println(orderStr); //就是orderString 可以直接给客户端请求,无需再做处理。 80 81 m.addAttribute("result",orderStr);82 m.addAttribute("status",0);83 m.addAttribute("msg","订单生成成功");84 85 } catch (Exception e) {86 m.addAttribute("status",1);87 m.addAttribute("msg","订单生成失败");88 }89 90 return m;91 }

   

         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
params = new HashMap
();          Map
requestParams = request.getParameterMap();          Trade trade =null;11 //1.从支付宝回调的request域中取值12 Map
requestParams = request.getParameterMap(); 13 14 for (Iterator
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     @ResponseBody11     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官网:

    2.natapp 1分钟新手图文教程:

    

    三、流程分析:
         1.配置文件AlipayConfig注意事项:
             (1)注意沙箱环境和正式环境的不同:
                商户appid    :
                    沙箱:进入沙箱环境会自动分配
                    正式:商户唯一的标识
                请求网关地址:
                    沙箱:
                    正式:
             (2)公钥和私钥
                 公钥和私钥是自己生成的不要配错,与支付宝的公钥不要混淆了。(详情见:https://docs.open.alipay.com/204/105297)
         2. 本案例只是对支付进行说明,退款等功能可进行举一反三编写。
   3.本人由于能力水平有限.有不到之处请大家多多指教!!!

转载于:https://www.cnblogs.com/MrRightZhao/p/7852511.html

你可能感兴趣的文章
autopep8
查看>>
GIT在Linux上的安装和使用简介
查看>>
基于C#编程语言的Mysql常用操作
查看>>
s3c2440实验---定时器
查看>>
MyEclipse10安装SVN插件
查看>>
[转]: 视图和表的区别和联系
查看>>
Regular Experssion
查看>>
图论例题1——NOIP2015信息传递
查看>>
CocoaPods的安装和使用那些事(Xcode 7.2,iOS 9.2,Swift)
查看>>
Android 官方新手指导教程
查看>>
幸运转盘v1.0 【附视频】我的Android原创处女作,请支持!
查看>>
UseIIS
查看>>
vi命令提示:Terminal too wide
查看>>
引用 移植Linux到s3c2410上
查看>>
MySQL5.7开多实例指导
查看>>
[51nod] 1199 Money out of Thin Air #线段树+DFS序
查看>>
Red and Black(poj-1979)
查看>>
分布式锁的思路以及实现分析
查看>>
腾讯元对象存储之文件删除
查看>>
jdk环境变量配置
查看>>