Java web集成支付宝电脑支付接口(沙箱环境)

来源:互联网 发布:北京房价数据 编辑:程序博客网 时间:2024/06/08 03:14

前言

这是博主的第一篇博客,刚刚毕业,打算把工作中遇到的一些比较普遍的问题记录下来,如果有写的不好的地方或者写错的地方欢迎指出,一定会改!嘿嘿嘿。先来立个flag,我希望三年之后能够成为一名不怕bug,热爱生活,健康快乐的富婆!

这篇博客主要介绍如何在Java web项目中集成支付宝的电脑支付接口(会稍微介绍一下服务器集成APP支付接口)。目前支付宝接口更新很快,在博主查找资料的时候,很多都是即时到账接口,APP支付则是移动支付接口等,所以想结合现在的电脑支付接口写一篇博文。如果项目要正式接入支付宝接口的话,是要企业与支付宝创建应用以及签约获取APPID等等的,如果我们只是个人想要学习或者测试的话,可以使用沙箱环境,不需要创建应用和签约,默认有很多应用!!正式环境的开发顺序是:创建应用—签约(电脑支付、APP支付、当面付、手机网站支付等等都需要单独签约!!)

配置沙箱环境

一、如果你是一个新手小白想要在项目中接入支付宝接口,首先你要做的是,进入支付宝官网开放平台。点击“快速开发”下的“开发接入”,跳转到新页面后点击“开发服务”下的“沙箱”。

二、新页面就是支付宝配置沙箱环境的文档以及使用说明,这里告诉我们沙箱环境默认给了我们一个APPID,需要我们自己配置RSA2(SHA256)的应用公钥,需要先下载支付宝生成秘钥的工具,如果是RSA2签名格式的话,记住要生成2048位的!!不要被示例图给迷惑了,当初博主就是这里弄错了!生成之后,进入沙箱应用,上传刚刚生成的应用公钥,上传成功后会生成支付宝公钥,应用私钥以及支付宝公钥会在代码配置中用到。如需要更改秘钥,使用下载的工具重新生成再上传即可!上传应用公钥并获取支付宝公钥,沙箱环境与链接中的示例图略有不同!

导入支付宝电脑支付的demo

一、在沙箱应用的链接中,点击最下面的功能中的电脑网站支付,选择左侧SDK&DEMO的菜单项,下载Java版的demo。

二、解压刚刚下载的demo,导入到eclipse中,目录结构如下图 
这里写图片描述

三、修改AlipayConfig.java文件,记住是商户私钥和支付宝公钥!不要写成应用公钥!应用私钥即商户私钥! 
这里写图片描述 
这里的notify_url和return_url改成自己项目要返回页面的地址,由于是沙箱环境,所以支付宝网关也有修改。return_url是指付款成功之后返回给用户查看的界面,如付款成功之后返回到商品详情或者网站首页等等。notify_url则是支付包与服务器交互的页面,用户看不到,支付成功以notify_url返回的参数或者查询订单返回的参数为准。电脑网站支付快速接入。

四、修改配置成功之后,运行项目。 
页面如下: 
1.这里写图片描述

2.这里写图片描述

3.使用沙箱应用下面的沙箱账号里的买家账号登录,付款!钱会直接打到卖家账户中!这里面的钱可以自己手动添加,很有满足感 !!!!瞬间变富婆啊!!如果想用二维码支付,则到沙箱应用中扫描二维码下载沙箱版的支付宝,再用沙箱的买家账号登录就可以付款了!目前支持安卓版。

4.由于博主并没有写页面,使用的是支付宝默认的,所以返回的是一串json数据。 
这里写图片描述

5.沙箱调试常见的错误如下图,如果报的错误不在这里面,请自行百度! 
这里写图片描述

到这里如果能够成功付款或者查询订单等等,就可以看出我们的配置是没有问题的!接下来就要与我们的Java web项目整合并且存订单数据到数据库中!

整合接口到Java web项目

一、博主的框架是公司同事搭的SSM框架,但是与我在网上看的也有点不太一样,不过没关系,整合起来就那么几个文件。首先把上面那个demo里的Alipayconfig.java放在项目中(目录随项目而定),然后导入alipay-sdk-javaXXX.jar、commons-logging-1.1.1.jar这两个jar包到WebContent\WEB-INF\lib中,(具体路径随项目不同而改变)。

二、写支付接口。这里面可以对自己项目中的订单表进行操作,先增加一条订单,但是状态为未付款。然后调用支付宝付款接口。

/**     * 获取订单数据接口     * @param request     * @param response     * @throws AlipayApiException      * @throws IOException      */    @RequestMapping("viewOrder")    public void viewOrder(HttpServletRequest req, Model mod, HttpServletResponse rep,            @RequestParam(value = "goodId", required = true)Integer goodId) throws AlipayApiException, IOException{        CommonResponse cr = new CommonResponse();           User cu = ViewSessionManager.getUserSession();        if(cu == null){   //需要登录才能买东西            cr.setMessage("未登录");            cr.setData(null);            cr.setCode(3109);        }        //系统下单        OrderInfo  param = new OrderInfo();        param.setGoodId(goodId);        payService.alipayOrder(cu, param);   //生成订单信息,根据自己项目改动      //获得初始化的AlipayClient        AlipayClient alipayClient = new DefaultAlipayClient(AlipayConfig.gatewayUrl, AlipayConfig.app_id, AlipayConfig.merchant_private_key, "json", AlipayConfig.charset, AlipayConfig.alipay_public_key, AlipayConfig.sign_type);        //设置请求参数        AlipayTradePagePayRequest alipayRequest = new AlipayTradePagePayRequest();        alipayRequest.setReturnUrl(AlipayConfig.return_url);        alipayRequest.setNotifyUrl(AlipayConfig.notify_url);        //商户订单号,商户网站订单系统中唯一订单号,必填        String out_trade_no = param.getTradeCode();        //付款金额,必填        String total_amount = param.getMoney().toString();        //订单名称,必填        String subject = param.getSubject();        //商品描述,可空        String body = param.getRemark();        alipayRequest.setBizContent("{\"out_trade_no\":\""+ out_trade_no +"\","                 + "\"total_amount\":\""+ total_amount +"\","                 + "\"subject\":\""+ subject +"\","                 + "\"body\":\""+ body +"\","                 + "\"product_code\":\"FAST_INSTANT_TRADE_PAY\"}");        //请求        String result = alipayClient.pageExecute(alipayRequest).getBody();        rep.setContentType("text/html;charset=" + AlipayConfig.charset);        rep.getWriter().write(result);//直接将完整的表单html输出到页面        rep.getWriter().flush();        rep.getWriter().close();    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55

三、写同步通知return_url接口。这里面可以更改订单状态,但是不以这个为准(若网速太卡或者用户付完款关掉页面,则不会跳到这个接口,所以订单状态可能就不会更改)

/**     * 回调路径return_url     * @param request     * @param response     * @throws AlipayApiException      * @throws UnsupportedEncodingException      */    @RequestMapping("return_url.view")    public String returnUrl(HttpServletRequest request, HttpServletResponse response) throws AlipayApiException, UnsupportedEncodingException{        //获取支付宝POST过来反馈信息        Map<String,String> params = new HashMap<String,String>();        Map requestParams = request.getParameterMap();        for (Iterator iter = requestParams.keySet().iterator(); iter.hasNext();) {            String name = (String) iter.next();            String[] values = (String[]) requestParams.get(name);            String valueStr = "";            for (int i = 0; i < values.length; i++) {                valueStr = (i == values.length - 1) ? valueStr + values[i]                            : valueStr + values[i] + ",";            }            //乱码解决,这段代码在出现乱码时使用。            //valueStr = new String(valueStr.getBytes("ISO-8859-1"), "utf-8");            params.put(name, valueStr);        }        //切记alipaypublickey是支付宝的公钥,请去open.alipay.com对应应用下查看。        //boolean AlipaySignature.rsaCheckV1(Map<String, String> params, String publicKey, String charset, String sign_type)        boolean signVerified = AlipaySignature.rsaCheckV1(params, AlipayConfig.alipay_public_key, AlipayConfig.charset,AlipayConfig.sign_type);        if(signVerified) {            //商户订单号            String out_trade_no = new String(request.getParameter("out_trade_no").getBytes("ISO-8859-1"),"UTF-8");            //支付宝交易号            String trade_no = new String(request.getParameter("trade_no").getBytes("ISO-8859-1"),"UTF-8");            //付款金额            String total_amount = new String(request.getParameter("total_amount").getBytes("ISO-8859-1"),"UTF-8");            request.setAttribute("out_trade_no", out_trade_no);            request.setAttribute("trade_no", trade_no);            request.setAttribute("total_amount", total_amount);            log.info("订单处理:系统订单号" + out_trade_no + "支付宝交易号:" + trade_no);            //系统处理根据支付宝回调更改订单状态或者其他关联表的数据            OrderInfo order = payService.findOneByTradeCode(out_trade_no);            if(order == null){                signVerified = false;                request.setAttribute("signVerified", signVerified);                 request.setAttribute("reason", "商户订单号不存在");                log.error("系统订单:"+ out_trade_no + "不存在。");            }else{                if(!order.getMoney().toString().equals(total_amount)){                    signVerified = false;                    request.setAttribute("signVerified", signVerified);                     request.setAttribute("reason", "付款金额不对");                    return "notify_url";                }                if(order.getTradeStatus() == 1){//判断当前订单是否已处理,避免重复处理                    log.info("系统订单:"+ out_trade_no + "无需重复处理。");                }else{                    order.setTradeStatus(1);//修改订单状态为已支付                    Date payedAt = new Date();                    order.setTransactionId(trade_no);                    order.setPayedAt(payedAt);                    payService.payOrder(order);                    log.info("系统订单:"+ out_trade_no + "成功支付。");                }            }        }else{            request.setAttribute("reason", "验签失败");        }        request.setAttribute("signVerified", signVerified);        return "return_url";    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78

四、异步通知notify_url接口,与上面return_url的几乎相同,只是最后返回的页面改为notify_url,还有一点需要注意的是:必须保证服务器异步通知页面(notify_url)上无任何字符,如空格、HTML标签、开发系统自带抛出的异常提示信息等 
电脑网站支付结果异步通知 
数据库中订单状态的更新以这个接口中的为准!

五、查询订单接口。这里的返回类型CommonResponse 是我们公司自己的,你们改成自己的返回类型就好.我们这个是ajax调用接口,然后将orderString的数据返回,实际上是json数据。

/**     * 支付宝交易查询接口     * @param request     * @param response     * @throws UnsupportedEncodingException      * @throws AlipayApiException      */    @RequestMapping("queryOrder")    @ResponseBody    public CommonResponse queryOrder(HttpServletRequest req, Model mod, HttpServletResponse rep,            @RequestParam(value = "tradeCode", required = true)String tradeCode,            @RequestParam(value = "tradeNo", required = true)String tradeNo) throws UnsupportedEncodingException, AlipayApiException{        CommonResponse cr = new CommonResponse();        AlipayClient alipayClient = new DefaultAlipayClient(AlipayConfig.gatewayUrl, AlipayConfig.app_id, AlipayConfig.merchant_private_key, "json", AlipayConfig.charset, AlipayConfig.alipay_public_key, AlipayConfig.sign_type); //获得初始化的AlipayClient        AlipayTradeQueryRequest request = new AlipayTradeQueryRequest();//创建API对应的request类        request.setBizContent("{" +                "   \"out_trade_no\":\""+tradeCode+"\"," +                "   \"trade_no\":\""+tradeNo+"\"" +                "  }");//设置业务参数        //根据response中的结果继续业务逻辑处理        String orderString = null;          try {                //调用查询方法                AlipayTradeQueryResponse response = alipayClient.execute(request);//通过alipayClient调用API,获得对应的response类                orderString = response.getBody();//就是orderString 可以直接给客户端请求,无需再做处理。            } catch (AlipayApiException e) {                e.printStackTrace();        }        cr.setData(orderString);    //返回orderString        return cr;    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33

服务器端添加APP支付接口

与电脑支付接口类似,可以直接使用同一个jar包,不过在付款接口的入参里需要添加token。下面是部分代码。我相信你们足够聪明能够改成自己的!

CommonResponse cr = new CommonResponse();           Cache<String, User> apiAccessTokenCache = cacheManager.getCache("apiAccessTokenCache");        User cu = apiAccessTokenCache.get(token);//登录时候产生的token,通过token获得User        if(cu == null){            cr.setMessage("token值不对或已失效");            cr.setData(null);            cr.setCode(3109);            return cr;        }        //系统下单        OrderInfo  param = new OrderInfo();        param.setGoodId(goodId);        payService.order(cu, param);   //生成订单信息        //实例化客户端        AlipayClient alipayClient = new DefaultAlipayClient(AlipayConfig.gatewayUrl, AlipayConfig.app_id, AlipayConfig.merchant_private_key, "json", AlipayConfig.charset, AlipayConfig.alipay_public_key, AlipayConfig.sign_type);        //实例化具体API对应的request类,类名称和接口名称对应,当前调用接口名称:alipay.trade.app.pay        AlipayTradeAppPayRequest request = new AlipayTradeAppPayRequest();        //SDK已经封装掉了公共参数,这里只需要传入业务参数。以下方法为sdk的model入参方式(model和biz_content同时存在的情况下取biz_content)。        AlipayTradeAppPayModel model = new AlipayTradeAppPayModel();        String time = Long.toString(System.currentTimeMillis()/1000);        model.setBody(param.getRemark());        model.setSubject(param.getSubject());        model.setOutTradeNo(param.getTradeCode());        model.setTimeoutExpress(time);        model.setTotalAmount(param.getMoney()+"");        model.setProductCode("QUICK_MSECURITY_PAY");        request.setBizModel(model);        request.setReturnUrl(AlipayConfig.return_url);        request.setNotifyUrl(AlipayConfig.notify_url);        String orderString = null;          try {                //这里和普通的接口调用不同,使用的是sdkExecute                AlipayTradeAppPayResponse response = alipayClient.sdkExecute(request);                orderString = response.getBody();//就是orderString 可以直接给客户端请求,无需再做处理。            } catch (AlipayApiException e) {                e.printStackTrace();        }        cr.setData(orderString);    //返回orderString        return cr;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40

转换成正式环境

需要修改配置文件中的APPID,支付宝公钥,应用私钥,以及支付宝网关!有时改了网关之后跳转的还是沙箱环境的网关,需要clean一下服务器(我的是Tomcat)

结语

上面就是博主总结的Java web项目集成支付宝电脑支付接口!希望这一篇博文能够解决你的问题,祝好运!如果有疑问可以给我留言,看到了如果我会的问题就会回答!☺☺

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 违章车型与实际车型不符怎么办 网购与实物不符怎么办 内网ip地址丢失怎么办 转账户名写错了怎么办 工资卡开户写错公司名称怎么办 商标跟别人重了怎么办 不受信任的应用打不开怎么办 oppo手机安全证书过期怎么办 网站安全证书有问题怎么办 公章圆圈摔坏了怎么办 高风险办税人员怎么办 公司因担保被起诉怎么办 借公司钱被起诉怎么办 qq群管理员满了怎么办 微信公众号搜索不到怎么办 微信名字改不了怎么办 微信号第一次限制登录怎么办 微信第一次限制登录怎么办 老板不回我微信怎么办 微信号换手机号了怎么办 电话被对方拉黑怎么办 微信被好友拉黑了怎么办 微信收藏删了怎么办 如果忘记支付宝登录手机号码怎么办 支付宝登录密码忘记了怎么办 支付宝账户名忘记了怎么办 搜索qq号搜不到怎么办 微信号手机号码换了怎么办 起诉以后没有被告人住址怎么办 农村老人走丢了怎么办 读在职博士工作单位不支持怎么办 两证合一后国税怎么办 杭州的发票丢了怎么办 小车登记证丢了怎么办 个体户地税逾期未申报怎么办 公司社保本丢了怎么办 社保红本子掉了怎么办 三证合一后逾期怎么办 个体执照没办国税地税怎么办 丰巢APP注册没工牌号怎么办 农业银行k宝证书过期怎么办