白夜行 发表于 2019-12-27 16:05:21

java如何调用支付宝和微信支付功能

最近项目上用到了调用微信和支付宝的第三方支付接口,因为以前没用过,所以这次用到了之后总结一下分享给大家,这里介绍两种支付方式,即app支付和扫码支付方式。
一、app支付(这里只介绍java端调用支付,安卓或ios端自己参考相关的调用文档)
首先可以看一看项目支付流程(图解)
1. 在页面上选择支付方式(微信或支付宝)
2. 由相应的客户端调用相应的支付方式进入相应的支付页面(安卓或ios调用支付接口并进入微信或支付宝支付页面,显示支付的信息)
3. 输入密码进行支付
4. 调用支付结果接口,来返回支付成功与否


http://p9.pstatp.com/large/pgc-image/86182ac5862c43f094b9200029b59755

四图分别是选择支付方式、微信支付页面、支付宝支付页面、微信支付结果(成功)页面
也是基本的支付三个步骤。
一、先看微信支付:
在调用微信支付之前你应该已经下单成功(即订单信息入库成功),这里需要几个值:
OrderName(订单名称),orderNumber(订单编号,唯一),amount(金额), prepayId(交易会话id)
前三个参数直接从数据库里获取。prepayid是什么?可以具体看微信支付文档,我们可以从下单接口中返回获得这个会话id并且需要入库,这个参数最重要的作用是用于第一次我们没有支付,但已经生成了一个待支付的订单。这种情况下我们不需要再次去调用下单接口返回prepayId,因为我们已经生成过了这个值
下面看手机端jsp页面的js代码:
//在页面选择微信,点击确认支付functionwxPay(outTradeNo){varorderType="0";//路线订单$.ajax({url:'client/travel/getWXClientPayInfo.do?outTradeNo='+outTradeNo+'&orderType='+orderType,cache:false,type:"get",success:function(data){if(data!=null){data=jQuery.parseJSON(data);varu=navigator.userAgent;varisAndroid=u.indexOf('Android')>-1||u.indexOf('Adr')>-1;//android终端varisiOS=!!u.match(/\(i[^;]+;(U;)?CPU.+MacOSX/);//ios终端if(isAndroid){ClientInterface.pay(outTradeNo,data.prepayid,data.noncestr,data.timestamp,data.sign,orderType);}elseif(isiOS){window.location.href='http://localhost/pay/'+outTradeNo+';'+data.prepayid+";"+data.noncestr+";"+data.timestamp+";"+data.sign+";"+orderType;}}}});}这里outTradeNo即是唯一的订单编号,orderType是自己定义的订单类型,这里的ajax就是根据这两个参数去后台去操作下单,然后返回必要的参数给安卓或ios调用
然后看后台的这个方法:
/**获取微信客户端支付信息 如 签名 随机数等 * @param page * @throws Exception */@RequestMapping(value="/getWXClientPayInfo")@ResponseBodypublic String getWeixinPayInfo(HttpServletRequest request) throws Exception{String orderNumber = request.getParameter("outTradeNo");String orderType = request.getParameter("orderType");Map map=new HashMap();map.put("orderNumber", orderNumber);map.put("type", orderType);//获取订单信息Map orderMap=travelOrderService.getOrderInfoByOrderType(map);String amount="";String prepayId="";if(null!=orderMap&&orderMap.size()>0){    if(orderMap.containsKey("amount")){      amount=orderMap.get("amount").toString();    }    if(orderMap.containsKey("prepayId")){      prepayId=orderMap.get("prepayId").toString();            }}//获取微信支付会话idif("".equals(prepayId)){    Float totalMoney=Float.valueOf(amount);    totalMoney=totalMoney*100;      int totalFee=totalMoney.intValue();      String money=String.valueOf(totalFee);      String xmlStr=WeixinPayUtil.add(orderNumber,money,orderType); //获得会话ID      Map m=new HashMap();      Document doc = DocumentHelper.parseText(xmlStr);          Element rootElement = doc.getRootElement();          XmlToBean.ele2map(m,rootElement);      String str="";      if(m.containsKey("prepay_id")){            str=m.get("prepay_id").toString();            str=str.replace("{prepay_id=", "");            str=str.substring(0,str.length()-1);      }      prepayId=str;      map.put("prepayId", prepayId);            travelOrderService.updateOrderInfoByType(map);} //转成sortedMap,微信支付后台生成sign需要排序过的map      SortedMap sort=new TreeMap();    String partnerid = sysparam.getStringParamByKey("c.wxpay.partnerid");      //相关参数,可以定义一个Map做成动态的    sort.put("appid", sysparam.getStringParamByKey("c.wxpay.appid"));    sort.put("partnerid", partnerid);    sort.put("prepayid",prepayId);    sort.put("package", "Sign=WXPay");    String noncestr = RandomUtil.CreateRandom(32);    sort.put("noncestr", noncestr);    String timestamp = String.valueOf(System.currentTimeMillis());    timestamp = timestamp.substring(0,timestamp.length()-3);    sort.put("timestamp", timestamp);    String securit = sysparam.getStringParamByKey("c.wxpay.secret");      //生成sign      String sign=WeixinSignUtil.createSign("UTF-8", sort,securit);                Map resultParam = new HashMap();      resultParam.put("timestamp", timestamp);      resultParam.put("noncestr", noncestr);      resultParam.put("sign", sign);      resultParam.put("prepayid", prepayId);      return JsonUtil.Object2JsonSting(resultParam);}这里需要注意的是
StringxmlStr=WeixinPayUtil.add(orderNumber,money,orderType); //获得会话ID
这个add方法即微信的下单接口,返回的xmlStr是xml格式的字符串,进行解析后,得出来perpayid入库。这里的money即金额,必须以分为单位!
依次参考下单接口:
0:线路订单 1:景点 2:酒店 3:商城 4:vip升级) public static String add(String orderNo,String TotalMoney,String orderType)throws Exception { URL postUrl = new URL("https://api.mch.weixin.qq.com/pay/unifiedorder"); SysParamServiceImpl systemParam = (SysParamServiceImpl)SpringContextHolder.getBean(SysParamServiceImpl.class); HttpsURLConnection con = (HttpsURLConnection) postUrl.openConnection();//打开连接 con.setRequestMethod("POST");//post方式提交 con.setDoOutput(true);//打开读写属性,默认均为false con.setDoInput(true); con.setUseCaches(false);//Post请求不能使用缓存 con.setInstanceFollowRedirects(true); DataOutputStream out = new DataOutputStream(con.getOutputStream()); Map vo = new HashMap(); //相关参数,可以定义一个Map做成动态的 vo.put("appid", systemParam.getStringParamByKey("c.wxpay.appid")); vo.put("attach", "支付测试"); vo.put("body", "APP应用支付");vo.put("mch_id", systemParam.getStringParamByKey("c.wxpay.partnerid")); vo.put("nonce_str", RandomUtil.CreateRandom(32)); String notifyUrl=systemParam.getStringParamByKey("sys.domain"); notifyUrl=notifyUrl+"/interface/wxpay/"+orderType; //调用微信下发通知的接口 vo.put("notify_url", notifyUrl); vo.put("out_trade_no", orderNo); vo.put("spbill_create_ip", "14.23.150.211"); vo.put("total_fee", TotalMoney); vo.put("trade_type", "APP"); //转成sortedMap,微信支付后台生成sign需要排序过的map SortedMap sort=new TreeMap(vo); String secrit = systemParam.getStringParamByKey("c.wxpay.secret"); //生成sign String sign=WeixinSignUtil.createSign("UTF-8", sort,secrit); //把sign放入map中 vo.put("sign", sign);org.dom4j.Document doc = DocumentHelper.createDocument(); Element body = DocumentHelper.createElement("xml"); XmlUtil.buildMap2xmlBody(body,vo); doc.add(body); //发送请求 out.writeUTF(doc.asXML()); System.out.println(doc.asXML()); out.flush(); out.close(); //接收数据 BufferedReader reader = new BufferedReader(new InputStreamReader(con.getInputStream(), "UTF-8")); String line; StringBuffer responseText = new StringBuffer(); while ((line = reader.readLine()) != null) {    responseText.append(line).append("\r\n"); } reader.close(); con.disconnect(); return responseText.toString()+"";}这里需要几个微信支付所需要的开发者账号信息,包括appid,微信支付商户号:partnerid,微信支付密码:
secret这些是商户申请微信app支付的信息提供给我们开发者,还有nonce_str参数需要配置我们自己定义的一个请求
该请求会在支付完成后,微信会主动根据这个请求来返回结果给我们。而且必须是外网,内网调不通
最后一步就是支付之后,微信会调用我们配置的nonce_str这个请求返回xml格式的结果给我们
@RequestMapping(value = "/interface/wxpay/{orderType}", produces = "text/html;charset=UTF-8")    @ResponseBody    public String getWeixinPayResult(HttpServletRequest request,                                     HttpServletResponse response)      throws IOException    {      try      {            String reqcontent = getRequestContent(request);            interfaceLogger                .info("################### ################# WeiXinPayResultInterface::getWeixinPayResult,request msg:"                      + reqcontent);            ResponseHandler resHandler = new ResponseHandler(request, response);             // 创建请求对象             // RequestHandler queryReq = new RequestHandler(request, response);            String type = request.getParameter("orderType"); // 获取订单类型             // queryReq.init();            String securit = sysParam.getStringParamByKey("c.wxpay.secret");            if (resHandler.getParameter("sign").equals(                WeixinSignUtil.createSign("utf-8",                  resHandler.getAllParameters(), securit)))            {               // 商户订单号               String out_trade_no = resHandler.getParameter("out_trade_no");                String totalFee = resHandler.getParameter("total_fee");                System.out.println("out_trade_no:" + out_trade_no);                Map map = new HashMap();                String result_code = resHandler.getParameter("result_code");                if (result_code.equals("SUCCESS"))                {                  // 新增到支付流水表                  System.out                        .println("########### ****************totalFee1 #########:"                                 + totalFee);                  String serialno = RandomUtil.CreateRandom(32); // 生成支付流水                  map.put("serialno", serialno);                  map.put("totalFee", totalFee);                  map.put("orderNumber", out_trade_no);                  map.put("payWay", "2"); // 微信支付                  if ("0" == type || "0".equals(type))                  {// 路线订单                        travelOrderService.addPayLog(map);                        travelOrderService.updateOrderPayFlagAndSerialno(map); // 修改支付状态                  }                }                else                {                  return resHandler.getParameter("err_code_des");                }                // 财付通订单号               String transaction_id = resHandler                  .getParameter("transaction_id");               System.out.println("transaction_id:" + transaction_id);               // 金额,以分为单位               String total_fee = resHandler.getParameter("total_fee");               // 如果有使用折扣券,discount有值,total_fee+discount=原请求的total_fee               String discount = resHandler.getParameter("discount");               System.out.println("----------------业务逻辑执行-----------------");               // ——请根据您的业务逻辑来编写程序(以上代码仅作参考)——               System.out.println("----------------业务逻辑执行完毕-----------------");               System.out.println("success"); // 请不要修改或删除               System.out.println("即时到账支付成功");               // 给财付通系统发送成功信息,财付通系统收到此结果后不再进行后续通知               resHandler.sendToCFT("success");               // 给微信服务器返回success 否则30分钟通知8次                return "success";             }            else            {               System.out.println("通知签名验证失败");               resHandler.sendToCFT("fail");               response.setCharacterEncoding("utf-8");                return "FAIL";            }      }      catch (Exception e)      {            return "FAIL";      }   }这是微信调用我们定义的请求来主动返回支付结果,但我们也可以写接口主动调用微信来获取订单信息
这里需要ios或者安卓调用我们java后台写的接口来获取支付结果:
@RequestMapping(value = "/interface/wxpay/{orderType}", produces = "text/html;charset=UTF-8")@ResponseBodypublic String getWeixinPayResult(HttpServletRequest request,                  HttpServletResponse response)    throws IOException{    try    {      String reqcontent = getRequestContent(request);      interfaceLogger      .info("################### ################# WeiXinPayResultInterface::getWeixinPayResult,request msg:"         + reqcontent);      ResponseHandler resHandler = new ResponseHandler(request, response);      // 创建请求对象      // RequestHandler queryReq = new RequestHandler(request, response);      String type = request.getParameter("orderType"); // 获取订单类型      // queryReq.init();      String securit = sysParam.getStringParamByKey("c.wxpay.secret");      if (resHandler.getParameter("sign").equals(      WeixinSignUtil.createSign("utf-8",          resHandler.getAllParameters(), securit)))      {      // 商户订单号      String out_trade_no = resHandler.getParameter("out_trade_no");      String totalFee = resHandler.getParameter("total_fee");      System.out.println("out_trade_no:" + out_trade_no);      Map map = new HashMap();      String result_code = resHandler.getParameter("result_code");      if (result_code.equals("SUCCESS"))      {          // 新增到支付流水表          System.out            .println("########### **************** totalFee1 #########:"                + totalFee);          String serialno = RandomUtil.CreateRandom(32); // 生成支付流水          map.put("serialno", serialno);          map.put("totalFee", totalFee);          map.put("orderNumber", out_trade_no);          map.put("payWay", "2"); // 微信支付          if ("0" == type || "0".equals(type))          {// 路线订单            travelOrderService.addPayLog(map);            travelOrderService.updateOrderPayFlagAndSerialno(map); // 修改支付状态          }      }      else      {          return resHandler.getParameter("err_code_des");      }      // 财付通订单号      String transaction_id = resHandler          .getParameter("transaction_id");      System.out.println("transaction_id:" + transaction_id);      // 金额,以分为单位      String total_fee = resHandler.getParameter("total_fee");      // 如果有使用折扣券,discount有值,total_fee+discount=原请求的total_fee      String discount = resHandler.getParameter("discount");      System.out.println("----------------业务逻辑执行-----------------");      // ——请根据您的业务逻辑来编写程序(以上代码仅作参考)——      System.out.println("----------------业务逻辑执行完毕-----------------");      System.out.println("success"); // 请不要修改或删除      System.out.println("即时到账支付成功");      // 给财付通系统发送成功信息,财付通系统收到此结果后不再进行后续通知      resHandler.sendToCFT("success");      // 给微信服务器返回success 否则30分钟通知8次      return "success";      }      else      {      System.out.println("通知签名验证失败");      resHandler.sendToCFT("fail");      response.setCharacterEncoding("utf-8");      return "FAIL";      }    }    catch (Exception e)    {      return "FAIL";    }}/**   * 4.22客户端微信支付成功后查询后台支付结果接口   *      * @param req   * @param rsp   * @return String 返回json字符串 如果有违例,请使用@exception/throws [违例类型]   *         [违例说明:异常的注释必须说明该异常的含义及什么条件下抛出该   * @throws Exception   * @see [类、类#方法、类#成员]   */    @RequestMapping(value = "/interface/payStatus", method = RequestMethod.POST, produces = "text/html;charset=UTF-8")    @ResponseBody    public String getPayStatus(HttpServletRequest req, HttpServletResponse rsp)      throws Exception    {      Map resultMap = new HashMap();      try      {            URL postUrl = new URL(                "https://api.mch.weixin.qq.com/pay/orderquery");            // 获取请求内容            String requestContent = getRequestContent(req);            // 日志            interfaceLogger.info("request payStatus:" + requestContent);            // 解析参数            requestParam = parseAndCheckParam(requestContent, resultMap,                requestParam, systemParam.getSystemKey());            // 校验参数            checkStatusParam(resultMap);            // 校验token及获取用户信息            Map userInfo = checkTokenAndGetUserInfo(                tokenService, appuserManager, requestParam, resultMap);             String user_id = (String)userInfo.get("userId");            String totalFee = (String)requestParam.get("totalFee");            String type = (String)requestParam.get("orderType"); // 获取订单类型参数            if (null == user_id)            {                resultMap.put("resultCode",                  ErrorCodeConstants.INVALID_TOKEN_ERROR);            }            SysParamServiceImpl sysParam = (SysParamServiceImpl)SpringContextHolder                .getBean(SysParamServiceImpl.class);            HttpsURLConnection con = (HttpsURLConnection)postUrl                .openConnection();// 打开连接            con.setRequestMethod("POST");// post方式提交            con.setDoOutput(true);// 打开读写属性,默认均为false            con.setDoInput(true);            con.setUseCaches(false);// Post请求不能使用缓存            con.setInstanceFollowRedirects(true);            // DataOutputStream out = new            // DataOutputStream(con.getOutputStream());            PrintWriter out = new PrintWriter(con.getOutputStream());            Map map = new HashMap();            // 相关参数,可以定义一个Map做成动态的            map.put("appid", sysParam.getStringParamByKey("c.wxpay.appid")); // appID            map.put("mch_id", sysParam.getStringParamByKey("c.wxpay.partnerid")); // 商户号            map.put("nonce_str", RandomUtil.CreateRandom(32)); // 随机数            String orderId = requestParam.get("outTradeNo").toString();            map.put("out_trade_no", orderId); // 订单号            // String mo="3000";            // insertMoneyAccounting(orderId,mo); //利润分配            // 转成sortedMap,微信支付后台生成sign需要排序过的map            SortedMap sort = new TreeMap(map);            String secrit = sysParam.getStringParamByKey("c.wxpay.secret");            // 生成sign            String sign = WeixinSignUtil.createSign("UTF-8", sort, secrit);            // 把sign放入map中            map.put("sign", sign); // 签名            Document doc = DocumentHelper.createDocument();            Element body = DocumentHelper.createElement("xml");            buildMap2xmlBody(body, map);            doc.add(body);            // 发送请求            // out.writeUTF(doc.asXML());            String outStr = doc.asXML();            out.print(outStr);            System.out.println(doc.asXML());            out.flush();            out.close();            // 接收数据            BufferedReader reader = new BufferedReader(new InputStreamReader(                con.getInputStream(), "UTF-8"));            String line;            StringBuffer responseText = new StringBuffer();            while ( (line = reader.readLine()) != null)            {                responseText.append(line).append("\r\n");            }            reader.close();            con.disconnect();            String resXml = responseText.toString() + ""; // 获取从微信付款的结果                                                          // ,以String类型的xml格式返回            System.out.println("result:" + resXml);            // 解析xml            Map m = new HashMap();            Document d = DocumentHelper.parseText(resXml);            Element rootElement = d.getRootElement();            XmlToBean.ele2map(m, rootElement);            String str = "";            if (m.containsKey("trade_state"))            {                str = m.get("trade_state").toString();                str = str.replace("{trade_state=", "");                str = str.substring(0, str.length() - 1);                if ("SUCCESS" == str || "SUCCESS".equals(str))                {                  if ("0".equals(type)) {             //支付成功后操作...         }               }                else if ("REFUND" == str || "REFUND".equals(str))                {                  str = "1"; // 转入退款                }                else if ("NOTPAY" == str || "NOTPAY".equals(str))                {                  str = "2"; // 未支付                }                else if ("CLOSED" == str || "CLOSED".equals(str))                {                  str = "3"; // 已关闭                }                else if ("REVOKED" == str || "REVOKED".equals(str))                {                  str = "4"; // 已撤销                }                else if ("USERPAYING" == str || "USERPAYING".equals(str))                {                  str = "5"; // 用户支付中                }                else if ("PAYERROR" == str || "PAYERROR".equals(str))                {                  str = "6"; // 支付失败                }                resultMap.put("status", str);                resultMap.put("resultCode",                  ErrorCodeConstants.RESULT_CODE_SUCCESS);            }      }      catch (Exception e)      {            logger.error("loginOut:system exception!", e);            resultMap.clear();            resultMap.put("resultCode", ErrorCodeConstants.SYSTEM_ERROR);      }      interfaceLogger.info("response payStatus:" + resultMap.toString());      return JsonUtil.Object2EncodeJsonSting(resultMap,            systemParam.getSystemKey());    }requestParam.get("XXX"),XXX是客户端调用我们(java服务器端)接口给我们传的参数,需要给我们totalFee(金额),orderType(订单类型)等然后我们返回支付结果给客户端
二、支付宝支付:支付宝支付流程上和微信支付稍微有所差别,支付宝不需要调用下单结果,但是也需要一个类似于微信prepayId的字段来入库,作用上跟prepayId差不多,名称可以自己定义,我这边暂时为aliPayInfo:首先看jsp页面的js代码:
//选择支付宝,立即支付 function aliPay(outTradeNo){var orderType="0";var info = $("#aliPayInfo").val();//订单信息 var totalAmount = $("#moeny").val();//总金额var orderName = $("#orderName").val();//订单名称//type 0:线路 1:景点2:酒店 3:商城 4:VIPvar prams = {aliPayInfo : info,type : orderType,orderNumber : outTradeNo,money : totalAmount,orderName : orderName};//先调支付宝确定是否下单 否则返回支付宝会话信息$.ajax({                url : 'client/hotel/foundZFBOrder.do',                type : "post",                data : prams,                cache : false,                dataType : "json",                success : function(data)                {                //alert("info +===="+data.info);                if(data.isSuccess){    if(isAndroid){    ClientInterface.aliPay(data.info,outTradeNo,orderType,totalAmount);    }else if(isiOS){    window.location.href='http://localhost/aliPay/'+data.info+';'+outTradeNo+";"+orderType+";"+totalAmount;    }                }else{                var title = "支付宝下单失败";prompt(title);                }                },               error : function(data){                var title = "支付宝下单失败";prompt(title);                } });}页面上的aliPayInfo可以为空,因为第一次去调用支付宝时这个为空,如果不支付,但是还是入库了,需要去数据库里查一下,那么共用这个页面的话aliPayInfo就不为空
然后去后台写这个ajax请求:
@RequestMapping(value="/foundZFBOrder", produces = "application/json;charset=UTF-8")    @ResponseBody    public Map foundZFBOrder(HttpServletRequest request){      //支付宝信息      String aliPayInfo = request.getParameter("aliPayInfo");      //金额      String money = request.getParameter("money");      //订单名称      String orderName = request.getParameter("orderName");      //订单编号      String orderNumber = request.getParameter("orderNumber");      //订单类型(0:线路 1:景点2:酒店 3:商城 4:VIP)      String type = request.getParameter("type");                boolean isSuccess = false;                //判断是否生成过支付宝信息      if(StringUtils.isBlank(aliPayInfo)){                     //生成支付宝信息            aliPayInfo = AliPayUtil.orderInfo(money, orderName, orderNumber, type);                        //修改表中支付宝信息            if(StringUtils.isNotBlank(aliPayInfo)){                isSuccess = true;                Map map = new HashMap();                map.put("aliPayInfo", aliPayInfo);                map.put("type", type);                map.put("orderNumber", orderNumber);                try {                  travelOrderService.updateOrderInfoByType(map);                }                catch (Exception e) {                  e.printStackTrace();                }            }                        /** 打印支付宝响应日志*/            if (interfaceLogger.isInfoEnabled()) {                interfaceLogger.info("ZFB " + table + " result :["                                     + JSON.toJSONString(aliPayInfo) + "]");            }      }                Map map = new HashMap();      map.put("info", aliPayInfo);      map.put("isSuccess", isSuccess);      return map;    }这里的 aliPayInfo = AliPayUtil.orderInfo(money, orderName, orderNumber, type);
类似于微信的下单接口(aliPayInfo 需要入库),但不是下单接口,因为支付宝支付没有下单接口,详情可以查看支付宝支付文档
下面继续写orderInfo方法:
/** ** @param amount 订单金额 * @param subject 订单标题 * @param body 订单描述 * @param outTradeNo订单号 * @return */public static String orderInfo(String amount,String subject,String outTradeNo,String type) {//获取appidString appId=Const.APPID;Map authInfoMap = OrderInfoUtil.buildOrderParamMap(appId,amount,subject,outTradeNo,type);String info = OrderInfoUtil.buildOrderParam(authInfoMap);String rsaPrivate =Const.RSAPRIVATE; //获取商户密钥String sign = OrderInfoUtil.getSign(authInfoMap, rsaPrivate);final String orderInfo = info + "&" + sign;return orderInfo;}这里和微信一样需要支付宝商户的appid和RSAPRIVATE提供给我们开发者,
然后编写支付宝支付工具类:
public class OrderInfoUtil {/** * 构造授权参数列表 ** @param pid * @param app_id * @param target_id * @return */public static Map buildAuthInfoMap(String pid, String app_id, String target_id) {Map keyValues = new HashMap(); // 商户签约拿到的app_id,如:2013081700024223keyValues.put("app_id", app_id); // 商户签约拿到的pid,如:2088102123816631keyValues.put("pid", pid); // 服务接口名称, 固定值keyValues.put("apiname", "com.alipay.account.auth"); // 商户类型标识, 固定值keyValues.put("app_name", "mc"); // 业务类型, 固定值keyValues.put("biz_type", "openservice"); // 产品码, 固定值keyValues.put("product_id", "APP_FAST_LOGIN"); // 授权范围, 固定值keyValues.put("scope", "kuaijie"); // 商户唯一标识,如:kkkkk091125keyValues.put("target_id", target_id); // 授权类型, 固定值keyValues.put("auth_type", "AUTHACCOUNT"); // 签名类型keyValues.put("sign_type", "RSA"); return keyValues;} /** * 构造支付订单参数列表 * @param pid * @param app_id * @param target_id * @return */public static Map buildOrderParamMap(String appId,String amount,String subject,String outTradeNo,String type) {Map keyValues = new HashMap(); keyValues.put("app_id", appId); keyValues.put("biz_content", "{\"timeout_express\":\"30m\",\"product_code\":\"QUICK_MSECURITY_PAY\",\"total_amount\":\""+amount+"\",\"subject\":\""+subject+"\",\"out_trade_no\":\"" +outTradeNo +"\"}");keyValues.put("charset", "utf-8"); keyValues.put("method", "alipay.trade.app.pay"); keyValues.put("sign_type", "RSA");//获取域名 SysParamServiceImpl systemParam = (SysParamServiceImpl)SpringContextHolder.getBean(SysParamServiceImpl.class);//String notifyUrl="http://180.96.11.10:8080/tourism";String notifyUrl=systemParam.getStringParamByKey("sys.domain");notifyUrl=notifyUrl+"/interface/alipay/"+type;keyValues.put("notify_url", notifyUrl);String timestamp = "";    Date date=new Date();SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); //设置时间格式timestamp=sdf.format(date);    keyValues.put("timestamp", timestamp);    keyValues.put("version", "1.0");return keyValues;}/** * 构造支付订单参数信息 ** @param map * 支付订单参数 * @return */public static String buildOrderParam(Map map) {List keys = new ArrayList(map.keySet()); StringBuilder sb = new StringBuilder();for (int i = 0; i < keys.size() - 1; i++) {String key = keys.get(i);String value = map.get(key);sb.append(buildKeyValue(key, value, true));sb.append("&");} String tailKey = keys.get(keys.size() - 1);String tailValue = map.get(tailKey);sb.append(buildKeyValue(tailKey, tailValue, true)); return sb.toString();}/** * 拼接键值对 ** @param key * @param value * @param isEncode * @return */private static String buildKeyValue(String key, String value, boolean isEncode) {StringBuilder sb = new StringBuilder();sb.append(key);sb.append("=");if (isEncode) {try {sb.append(URLEncoder.encode(value, "UTF-8"));} catch (UnsupportedEncodingException e) {sb.append(value);}} else {sb.append(value);}return sb.toString();}/** * 对支付参数信息进行签名 ** @param map *            待签名授权信息 ** @return */public static String getSign(Map map, String rsaKey) {List keys = new ArrayList(map.keySet());// key排序Collections.sort(keys); StringBuilder authInfo = new StringBuilder();for (int i = 0; i < keys.size() - 1; i++) {String key = keys.get(i);String value = map.get(key).toString();authInfo.append(buildKeyValue(key, value, false));authInfo.append("&");} String tailKey = keys.get(keys.size() - 1);String tailValue =map.get(tailKey).toString();authInfo.append(buildKeyValue(tailKey, tailValue, false)); String oriSign = SignUtils.sign(authInfo.toString(), rsaKey);String encodedSign = ""; try {encodedSign = URLEncoder.encode(oriSign, "UTF-8");} catch (UnsupportedEncodingException e) {e.printStackTrace();}return "sign=" + encodedSign;}/** * 要求外部订单号必须唯一。 * @return */private static String getOutTradeNo() {SimpleDateFormat format = new SimpleDateFormat("MMddHHmmss", Locale.getDefault());Date date = new Date();String key = format.format(date); Random r = new Random();key = key + r.nextInt();key = key.substring(0, 15);return key;} }keyValues.put("notify_url", notifyUrl);这个和微信一样,需要设置一个供支付宝支付后返回给我们的支付结果通知的请求,需自己定义,可带参数,必须在外网下才能调用
最后根据我们定义的请求,来写接收支付宝返回给我们的结果:
@RequestMapping(value = "/interface/alipay/{type}", produces = "text/html;charset=UTF-8")    @ResponseBody    public String getzfbPayResult(HttpServletRequest request,HttpServletResponse response){    try{    String reqcontent = getRequestContent(request);    interfaceLogger.info("################### ################# WeiXinPayResultInterface::alipay,request msg:"+reqcontent);    //解析url    //reqcontent=stringFarmat(reqcontent);      try {   reqcontent= URLDecoder.decode(reqcontent, "UTF-8");    } catch (UnsupportedEncodingException e) {    e.printStackTrace();    }    interfaceLogger.info("###########获取参数解析url:$@@@@@@@@@@@@@@@@@@@@@@@@@========="+reqcontent);    //转换为map    Map paramMap=stringtoArray(reqcontent);    //获取orderType    String orderType=request.getRequestURI();    int i=orderType.lastIndexOf("/");    orderType=orderType.substring(i+1, orderType.length());   //验证签名    //支付宝公钥    String publicKey=Const.PUBLICKEY; //支付宝公钥   //字符集    String charsetType="UTF-8";    //验证签名    boolean signVerified = AlipaySignature.rsaCheckV1(paramMap, publicKey, charsetType); //调用SDK验证签名    interfaceLogger.info("###########验证签名结果:$@@@@@@@@@@@@@@@@@@@@@@@@@========="+signVerified);    if(signVerified){    //验证金额订单号    interfaceLogger.info("*****************验证签名成功:&&&&&&&&&&&&&&&&&&&&&&&&&&&&");    if(paramMap.containsKey("trade_status")){    String resultStr=paramMap.get("trade_status");    if(resultStr.equals("TRADE_SUCCESS")||resultStr.equals("TRADE_FINISHED")){    //支付成功后操作...    }    return "success";    }else{    interfaceLogger.info("&&&&&&&&&&&&&&&&验证签名失败:***************************");               return "failure";    }      }catch (Exception e){    interfaceLogger.info("###########待签名字符串str:$@@@@@@@@@@@@@@@@@@@@@@@@@=========",e);e.printStackTrace();return "failure";}    }
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
页: [1]
查看完整版本: java如何调用支付宝和微信支付功能