支付宝电脑网页沙箱支付and当面付扫码支付and内网穿透技术

飞一样的编程
飞一样的编程
擅长邻域:Java,MySQL,Linux,nginx,springboot,mongodb,微信小程序,vue

专栏: 220908-小班辅导 标签: 支付宝支付

2022-10-14 08:39:35 939浏览

支付宝电脑网页沙箱支付and当面付扫码支付and内网穿透技术

0.配置沙盒环境

登陆open.alipay.com


1.账号登录支付-电脑版

  1. 先去官网下载demo

https://opendocs.alipay.com/open/270/106291?ref=api

2.先把demo调试通——修改配置文件

3.内网穿透

https://natapp.cn/

token:b1f0b96f2e3b6d02

在natapp.exe文件的当前目录下cmd运行:natapp -authtoken=b1f0b96f2e3b6d02

4.重要的几个概念

1.应用公钥: RSA加密工具生成

2.应用私钥: RSA加密工具生成

3.支付宝公钥:应用的公钥设置到支付宝的平台后,平台自动生成支付宝公钥

4.同步通知:用户在付款成功界而点击完成按钮发送的请求。

5.异步通知:用户支付完成之后就立马发送的异步通知,ajax

来确定你收到了支付宝支付结果的通知保证支付宝通知到达率99.99号

6.接口加签,验签:

签名:它是一-串密钥封装号所有参数之后加上密钥进行加密,然后把加密后的数据和参数一起传递过去给支付宝,支付宝收到请求之后,不会立即处理付款请求,会先用同样的加密方式把你传递过来的参数再进行一次加密,然后支付宝加密后的数据和你传过来的加密后的数据进行对比,如果数据一样,证明数据无修改。再去处理付款业务。

5.遇到一个很坑的问题

支付成功异步通知的验签总是false 但是同步通知的验签却是true,就很奇怪。导致支付回调后无法修改订单的状态等业务代码不执行

仔细看的话,发现两个代码基本是一模一样,那为啥一个签证成功,一个验证失败呢?debug查看了下发现是异步通知支付宝传到咱们这边的参数里有一个subject,就是这个参数中文乱码导致的。

解决方法:

参考文章:https://www.likecs.com/show-306312102.html?sc=300

另外这里提一下。如果是用证书方式就需要用下面的方式验签了!

signVerified = AlipaySignature.certVerifyV1(param,config.getAlipayPublicCertPath(),"UTF-8","RSA2");

2.扫码支付

最大的优点就是给客户的感觉就是一直在自己的平台上,并没有离开到支付宝的页面上去。

参考文章:https://www.jf3q.com/article/detail/3690

  1. 在官网去下载demo

https://opendocs.alipay.com/common/02kkv3

2.修改重要的几个参数

这些参数最好都直接去支付宝后台核实查看

3.修改main函数

实际开发的话不需要把二维码图片存入磁盘,可以直接把response.getQrCode()返回前端,前端用js生成二维码让客户扫就行。

new QRCode(document.getElementById("wx_pay_qr"), data.qrcode);//wx_pay_qr是页面的一个id为wx_pay_qr的div,用来显示二维码的

4.开发异步回调接口

可以参考以下代码写

@WebServlet("/order")
public class OrderServlet  extends HttpServlet {



    @Override
    public void service(ServletRequest request, ServletResponse res)throws ServletException, IOException {
        request.setCharacterEncoding("utf-8");
        res.setCharacterEncoding("utf-8");
        Logger log = Logger.getLogger(OrderServlet.class);
        log.info("进到咱们的付款回调");

        Map<String,String> params = new HashMap<String,String>();
        Map<String,String[]> requestParams = request.getParameterMap();
        for (Iterator<String> 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);
        }
        boolean signVerified = false; //调用SDK验证签名
        try {
            signVerified = AlipaySignature.rsaCheckV1(params, AlipayConfig.alipay_public_key, AlipayConfig.charset,AlipayConfig.sign_type);
            if(signVerified) {//验证成功logger;
//商户订单号
                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 trade_status = new String(request.getParameter("trade_status").getBytes("ISO-8859-1"),"UTF-8");

                if(trade_status.equals("TRADE_FINISHED")){//交易完成

                    System.out.println("交易完成");
                    //判断该笔订单是否在商户网站中已经做过处理
                    //如果没有做过处理,根据订单号(out_trade_no)在商户网站的订单系统中查到该笔订单的详细,并执行商户的业务程序
                    //如果有做过处理,不执行商户的业务程序

                    //注意:
                    //退款日期超过可退款期限后(如三个月可退款),支付宝系统发送该交易状态通知
                }else if (trade_status.equals("TRADE_SUCCESS")){//付款成功
                    System.out.println("付款成功");
                    //判断该笔订单是否在商户网站中已经做过处理
                    //如果没有做过处理,根据订单号(out_trade_no)在商户网站的订单系统中查到该笔订单的详细,并执行商户的业务程序
                    //如果有做过处理,不执行商户的业务程序

                    //注意:
                    //付款完成后,支付宝系统发送该交易状态通知
                }

                res.getWriter().println("success");

            }else {//验证失败
                res.getWriter().println("fail");

                //调试用,写文本函数记录程序运行情况是否正常
                //String sWord = AlipaySignature.getSignCheckContentV1(params);
                //AlipayConfig.logResult(sWord);
            }
        } catch (AlipayApiException e) {
            e.printStackTrace();
        }

        //——请在这里编写您的程序(以下代码仅作参考)——

	/* 实际验证过程建议商户务必添加以下校验:
	1、需要验证该通知数据中的out_trade_no是否为商户系统中创建的订单号,
	2、判断total_amount是否确实为该订单的实际金额(即商户订单创建时的金额),
	3、校验通知中的seller_id(或者seller_email) 是否为out_trade_no这笔单据的对应的操作方(有的时候,一个商户可能有多个seller_id/seller_email)
	4、验证app_id是否为该商户本身。
	*/






    }
}

5.同步回调(做页面跳转或者展示啥的)

上面的异步通知只是修改了数据库里的支付状态,但是现在前台用户的页面还是停留在有二维码的页面,这样用户会很懵啊。其实也很简单,这里使用ajax轮询的方法来监听用户是否支付成功并跳转页面。

前台在产生二维码后启用计时每隔几秒发送ajax请求该订单的支付状态,如果支付状态变成已支付,则跳转支付成功的页面即可。如果用户关闭支付弹框,可以清除计时器,具体以你的代码功能为主。

好博客就要一起分享哦!分享海报

此处可发布评论

评论(1展开评论

飞一样的编程 能力:470

2022-10-14 08:47:00

讲解视频地址:https://www.bilibili.com/video/BV1cW4y1J7WZ
点击查看更多评论

展开评论

您可能感兴趣的博客

客服QQ 1913284695