支付宝手机网站支付详细流程

基于 java  !!!!!!!

支付宝支付相对微信支付比较容易(有沙箱环境,不需要xml转换、金额转换、客户端验证回调等),一般的普通支付只需要一个配置文件、一个回调地址(支付成功进行自己项目逻辑处理)

 现在默认你是建好项目的,从沙箱环境一步步开始(沙箱环境和正式环境一样(也就是你公司的账号)到时候只需修改下配置参数即可)

1.登录支付宝(这里默认你是申请过开发的)>开发者中心>研发服务>沙箱应用,会看到你的APPID和支付网关(沙箱环境是dev.com,正式环境不带dev),还有RSA2(验签使用,证明你绑定的是这个支付宝账号,这个由支付宝工具生成,可百度或看文档,这里默认你是生成,并且已经上传到支付宝,这个可以秘钥可以反复生成更换,只需要保持一致即可),如果早已经设置好直接看第3步。

 

2.申请好沙箱应用后会默认有一个买家(客户端)、卖家(需要收款的账号,也是填入配置文件的账号)账号,可以下载支付宝给出的沙箱版支付宝APP可以无限充值金额,下载后登陆给出的买家账号即可,默认登陆密码和支付密码都是11111

3.开始进行项目开发,如果没有建好项目可根据支付宝给的Demo跑一遍,不过Demo是小脚本写的,不是很通俗易懂,但不影响使用(Demo也需修改配置文件),这里默认你已经建好项目,项目框架无所谓(这里是使用的SSM)

    1.将相关jar包引入项目,有些jar包根据项目需求导入(如jackson相关的),alipay-sdk是必须的(在maven仓库可以搜到)

        <!--支付宝区域-->
        <!-- https://mvnrepository.com/artifact/com.alipay.sdk/alipay-sdk-java -->
        <dependency>
            <groupId>com.alipay.sdk</groupId>
            <artifactId>alipay-sdk-java</artifactId>
            <version>3.1.0</version>
        </dependency>
        
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.21</version>
        </dependency>
        

    2.将Demo中的AlipayConfig 文件复制到你的项目当中

        参数解释:

         1.商户appid 就是你注册的应用的appid,进入支付宝开发页面就会显示(复制即可)

         2.私钥 就是你用工具生成的本地私钥,公钥要上传到支付宝中,私钥自己保存下来复制到参数中(可先用支付宝工具比对一下生成的公私钥是否一致,如果不一致也没注意,排查bug你会崩溃的)

         3.服务器异步通知地址 就是用户支付后支付宝会通知你的服务器支付的结果(通过或不通过) 如果用的ssm则controller一个地址即可(注意:必须需要外网能够访问,localhost是不行的,如果是测试阶段,可以下载个内网穿透工具,如花生壳)

         4.页面跳转同步通知页面路径 就是支付后让其跳转的一个页面(支付成功后会自动退出支付宝然后跳向你设置的页面,一般为支付成功页面),可以不设置

         5.请求网关地址 就是要请求支付宝的地址(注意:黑色箭头标注的是正式环境配置,沙箱环境需要在alipay后面加dev,声明其为测试环境网关,也就是alipaydev.com)

         6.支付宝公钥 就是支付宝的公钥,点开应用>查看支付宝公钥复制填入即可

         7.其他与配置文件一致即可

    4.现在编写代码,支付宝需要你给它传入4个必要参数,这里为了方便理解就不放出自己的逻辑代码(如金额需BigDecimal,验证金钱正确性,重复提交、创建未支付订单等等,只给出必要代码),方法名称就不展示了,就是@Controller @RequesMapping之类的,下图所示的代码都是在方法中,(至于那些参数如:商品名称等怎么获得的看自己的项目架构,注意:apiAlipayVo是我获取参数的实体工具类,不是支付宝的方法),详情看注释

            // 超时时间 可空
            String timeout_express="2m";
            // 销售产品码 必填
            String product_code="QUICK_WAP_WAY";
            /**********************/
            // SDK 公共请求类,包含公共请求参数,以及封装了签名与验签,开发者无需关注签名与验签
            //调用RSA签名方式,这个不用你管,只要你配置文件是正确的
            AlipayClient client = new DefaultAlipayClient(AlipayConfig.URL, 
            AlipayConfig.APPID, AlipayConfig.RSA_PRIVATE_KEY, AlipayConfig.FORMAT, 
            AlipayConfig.CHARSET, AlipayConfig.ALIPAY_PUBLIC_KEY,AlipayConfig.SIGNTYPE);
            AlipayTradeWapPayRequest alipay_request=new AlipayTradeWapPayRequest();

            // 封装请求支付信息
            AlipayTradeWapPayModel model=new AlipayTradeWapPayModel();
            //带!的都是你需要传递的参数 其他的是支付宝必须的
            //!本地生成的订单编号
            model.setOutTradeNo(apiAlipayVo.getOrderNum());
            //!商品名称
            model.setSubject(apiAlipayVo.getSubjectName());
            //!商品价格
            model.setTotalAmount(String.valueOf(apiAlipayVo.getTotal()));
            //!商品介绍
            model.setBody(apiAlipayVo.getBody());
            //超时时间
            model.setTimeoutExpress(timeout_express);
            //产品销售码
            model.setProductCode(product_code);
            //将参数传入到 BizModel中
            alipay_request.setBizModel(model);
            //异步回调地址
            alipay_request.setNotifyUrl(AlipayConfig.notify_url);
            //同步回调地址
            alipay_request.setReturnUrl(AlipayConfig.return_url);
//            String form = "";

            try {
                // 调用SDK生成表单
                //get方式生成表单 主要解决在微信中对支付宝屏蔽问题,如果不是在微信中可post提交,将form的注释解开,result注释掉即可
                String result= client.pageExecute(alipay_request,"get").getBody();
                System.out.println(result);
                //form = client.pageExecute(alipay_request).getBody();
//                System.out.println(form);
            } catch (AlipayApiException e) {
                e.printStackTrace();
                rrVo.setMsg("生成表单失败!");
            }

    5.前端写法,我用的是form表单提交方式,还有后台拼接字段提交方法,form提交方式更容易理解,所以本次用的是这种方法

(注意:后台拼接方法不能和form表单提交方法一起使用!注意!注意!注意!,也就是如果你用的是后台拼接参数方法,上面代码中的set赋值方法一个也不能使用,会被覆盖的)下面是前端form表单写法:详细看注释

//前台写法
//form中什么也不用填写
//ajax将所需参数传递到后台,也就是set赋值的地方,form表单在后台拼接好后,因为前台target是打开一个新的页面 则将返回值success(data)
//填充到body中 $("body").html(data)即可,可以后台输出一下拼接好的form表单,会有一个自动提交的操作
<form name=alipayment action = ‘’ methodpost target=”_blank”>
//点击提交去请求接口数据 然后填充表单
<button id=”…” type=”submit”>提交订单</button>
</form>

    6.此时如果没有错误,会自动唤起支付宝app,如果错误一般是验签错误,可百度查看一些错误,这里默认成功,支付完成后支付宝会给你返回支付结果,你需要你个外网能访问的地址去接收,地址就是你config配置好的地址。并不需要任何参数

    public ResultResponseVo callBack(HttpServletResponse response,HttpServletRequest request) throws IOException, AlipayApiException {
        response.setContentType("text/html;charset=utf-8");
        response.reset();
        //获取支付宝POST过来反馈信息
        response.getOutputStream();
        PageData pd = new PageData();
        ResultResponseVo rrVo = new ResultResponseVo(); //我自己的封装类,用于返回参数,不是支付宝参数,包括 public ResultResponseVo
        try {
            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] + ",";
                }
                //乱码解决,这段代码在出现乱码时使用。如果mysign和sign不相等也可以使用这段代码转化
                //valueStr = new String(valueStr.getBytes("ISO-8859-1"), "gbk");
                params.put(name, valueStr);
            }
            //商户订单号
            String out_trade_no = new String(request.getParameter("out_trade_no").getBytes("ISO-8859-1"),"UTF-8");
            System.out.println("商户订单号"+out_trade_no);
            //支付宝交易号

            String trade_no = new String(request.getParameter("trade_no").getBytes("ISO-8859-1"),"UTF-8");
            System.out.println("支付宝交易号"+trade_no);

            //交易状态
            String trade_status = new String(request.getParameter("trade_status").getBytes("ISO-8859-1"),"UTF-8");

            boolean verify_result = AlipaySignature.rsaCheckV1(params, AlipayConfig.ALIPAY_PUBLIC_KEY, AlipayConfig.CHARSET, "RSA2");
            SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");//设置日期格式
            //验证成功后,进行业务逻辑
            if(verify_result){
               //这里就可以进行你项目的业务逻辑,想要什么参数,查看文档即可
                response.getOutputStream().println("success");	//请不要修改或删除
                response.getOutputStream().close();
                rrVo.setData("success");
            }else{//验证失败
                response.getOutputStream().println("fail");
                rrVo.setResult(HttpResultStatus.FAIL);
                rrVo.setMsg("订单出现异常,验签失败!");
                return rrVo;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        rrVo.setResult(HttpResultStatus.SUCCESS);
        rrVo.setMsg(HttpResultStatus.SUCCESS.getMsg());
        return rrVo;
    }

注意: success那一句不可以删除,支付宝会每隔一段时间给你这个地址发送一次请求,如果见不到success它会一直发送,直到22小时后,if()之后可以进行你的业务逻辑代码,想获取什么值可以去支付宝文档查询《异步回调地址》,这里就差不多可以完成普通的支付流程

坑点:

1.如果你是在公众号或微信浏览器中使用支付宝支付,他会让你复制链接出去支付,但他会屏蔽你的hidden隐藏域(因为支付宝表单提交参数里用的是input type=hidden属性),会出现验签发源地错误,解决办法:使用上图的get方式提交,让其变成一个url链接而不是form表单

2.如果你是在公众号或微信浏览器中使用支付宝支付,复制链接后你是回调不回来的,就是不会再一步发挥你微信中的项目页面,只会返回到手机浏览器中的页面,暂无解决办法,只能一步步返回(这里的逻辑需要自己去写,避免返回时出现重复支付等现象)

3.公私钥一定要匹配,如果找不到问题,先换一遍公私钥或者检测是否匹配!

4.上图代码中的注释很有用!

最后,如果不会搞不懂

可以点击此头像,输入三遍一样的问题,会转接人工客服,这一点很好,但人工客服水平不一,需要自己判断。

这是一个简单的支付流程,不涉及退款,积分、花呗支付等等功能。

 

  • 2
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值