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

【支付宝app支付java后台流程及原理分析】丈夫欲遂平生志,一载寒窗一举汤。这篇文章主要讲述支付宝app支付java后台流程及原理分析相关的知识,希望能为你提供帮助。
  java版支付宝app支付流程及原理分析
本实例是基于springmvc框架编写
      一、流程步骤
            1.执行流程
                当手机端app(就是你公司开发的app)在支付页面时,调起服务端(后台第1个创建订单接口)接口,后台把需要调起支付宝支付的参数返回给手机端,手机端拿到
            这些参数后,拉起支付宝支付环境完成支付,完成支付后会调异步通知(第2个接口),此时需要给支付宝返回成功或者失败信息,成功后会调用同步通知(第3个接口)
            返回支付成功页面,完成整个支付流程。
           
            2.支付的配置文件AlipayConfig                 

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

 
 
            3.第1个创建订单接口

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

     
            4.第2个异步回调接口
1/** 2* 支付宝支付成功后.回调该接口 3* @param request 4* @return 5* @throws IOException 6*/ 7 @RequestMapping(value="https://www.songbingjia.com/android/api/alipay/notify_url",method={RequestMethod.POST,RequestMethod.GET}) 8 @ResponseBody 9 public String notify(HttpServletRequest request,HttpServletResponse response) throws IOException { 10Map< String, String> params = new HashMap< String, String> (); 11//1.从支付宝回调的request域中取值 12Map< String, String[]> requestParams = request.getParameterMap(); 13 14for (Iterator< String> iter = requestParams.keySet().iterator(); iter.hasNext(); ) { 15String name = iter.next(); 16String[] values = requestParams.get(name); 17String valueStr = ""; 18for (int i = 0; i < values.length; i++) { 19valueStr = (i == values.length - 1) ? valueStr + values[i] : valueStr + values[i] + ","; 20} 21// 乱码解决,这段代码在出现乱码时使用。如果mysign和sign不相等也可以使用这段代码转化 22// valueStr = new String(valueStr.getBytes("ISO-8859-1"), "gbk"); 23params.put(name, valueStr); 24} 25//2.封装必须参数 26String out_trade_no = request.getParameter("out_trade_no"); // 商户订单号 27String orderType = request.getParameter("body"); // 订单内容 28String tradeStatus = request.getParameter("trade_status"); //交易状态 29 30//3.签名验证(对支付宝返回的数据验证,确定是支付宝返回的) 31boolean signVerified = false; 32try { 33//3.1调用SDK验证签名 34signVerified = AlipaySignature.rsaCheckV1(params, AlipayConfig.ALIPAY_PUBLIC_KEY, AlipayConfig.CHARSET); 35} catch (AlipayApiException e) { 36e.printStackTrace(); 37} 38//4.对验签进行处理 39if (signVerified) {//验签通过 40if(tradeStatus.equals("TRADE_SUCCESS")) {//只处理支付成功的订单: 修改交易表状态,支付成功 41Trade trade = tradeService.selectByOrderNumber(out_trade_no); 42trade.setTradeStatus((byte)3); //支付完成 43int returnResult = tradeService.updateByPrimaryKeySelective(trade); //更新交易表中状态 44if(returnResult> 0){ 45//response.getWriter().write("SUCCESS"); 46return "success"; 47}else{ 48//response.getWriter().write("fail"); 49return "fail"; 50} 51}else{ 52return "fail"; 53} 54} else {//验签不通过 55//response.getWriter().write("fail"); 56System.err.println("验签失败"); 57return "fail"; 58} 59 }

       
            5.第3个同步通知接口
1 /** 2 * 支付宝支付成功后.通知页面 3 *@param request 4 *@return 5 *@throws UnsupportedEncodingException 6*/ 7 @RequestMapping(value="https://www.songbingjia.com/android/api/alipay/return_url",method={RequestMethod.POST,RequestMethod.GET}) 8 @ResponseBody 9 public Model returnUrl(HttpServletRequest request,Model model) throws UnsupportedEncodingException { 10System.err.println("同步通知。。。"); 11try { 12//1.从支付宝同步的request域中取值 13Map properties = request.getParameterMap(); 14//2.封装成Map 15Map< String, String> returnMap = new HashMap< String, String> (); 16Iterator entries = properties.entrySet().iterator(); 17Map.Entry entry; 18String name = ""; 19String valuehttps://www.songbingjia.com/android/= ""; 20while (entries.hasNext()) { 21entry = (Map.Entry) entries.next(); 22name = (String) entry.getKey(); 23Object valueObj = entry.getValue(); 24//对返回的值进行判断 25if(null == valueObj){ 26valuehttps://www.songbingjia.com/android/= ""; 27}else if(valueObj instanceof String[]){ 28String[] values = (String[])valueObj; 29for(int i=0; i< values.length; i++){ 30value = https://www.songbingjia.com/android/values[i] +","; 31} 32value = https://www.songbingjia.com/android/value.substring(0, value.length()-1); 33}else{ 34value = valueObj.toString(); 35} 36returnMap.put(name, value); 37} 38//3.返回到手机端 39model.addAttribute("returnMap", returnMap); 40model.addAttribute("msg", "查询成功"); 41model.addAttribute("status", 0); 42} catch (Exception e) { 43model.addAttribute("msg", "查询失败"); 44model.addAttribute("status", 1); 45} 46 47return model; 48 }

       
      二、流程分析:
            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. 本案例只是对支付进行说明,退款等功能可进行举一反三编写。
3.本人由于能力水平有限.有不到之处请大家多多指教!!!
























    推荐阅读