ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

对接支付宝APP支付后端实现最详细教程

2021-03-22 14:03:12  阅读:549  来源: 互联网

标签:支付宝 教程 String ali APP model public alipayBean


前言

本人是java后端开发,这次是做一个支付宝APP支付的功能,所以在这里注重讲解后端的代码实现以及业务结构流程。

业务结构流程图

在这里插入图片描述

接入前准备

去支付宝获取以下信息https://open.alipay.com/platform/manageHome.htm
appid、应用私钥、支付宝公钥、支付宝网关路径

代码实现

1.首先是配置类AppPayConfig,以下有些信息来自支付宝账户,这个在上面已经提到如何去获取。

public class AppPayConfig {
 /**
     * 1.商户appid
     */
    public String APPID = "";

    /**
     * 私钥 pkcs8格式的
     */
    public static String RSA_PRIVATE_KEY ="";

    /**
     * 3.支付宝公钥
     */
    public static String ALIPAY_PUBLIC_KEY =  "";

	/*
     * 4.服务器异步通知页面路径 
     */
	//支付完成后,支付宝会通过这个url请求到你的服务端..
	//这个url一定是要公网可以访问才行。如果是本地测试,就需要做内网穿透。
	//也就是说这个路径是你自定义的,你所写的回调接口的路径。
    public static String notify_url = "";

    /**
     * 5.页面跳转同步通知页面路径,这个暂时没有用到,有兴趣的小伙伴可以研究一下。
     */
    //这里同上..不做详细说明了..
    public static String return_url = "";

    /**
     * 正式环境支付宝网关,如果是沙箱环境需更改成https://openapi.alipaydev.com/gateway.do
     */
    public static String URL = "https://openapi.alipay.com/gateway.do";

    /**
     * 7.编码格式
     */
    public static String CHARSET = "UTF-8";

    /**
     * 私钥 pkcs8格式的
     */
    // 8.返回格式
    public static String FORMAT = "json";

    /**
     * //签名方式 加密类型
     */
    public static String SIGNTYPE = "RSA2";
}

2.前端选择支付宝支付后需要调用的下订单接口。

    @Value("${ali.config.app.id}")
    private String appId;
    @Value("${ali.config.gateway.url}")
    private String gatewayUrl;
    @Value("${ali.config.return.url}")
    private String returnUrl;
    @Value("${ali.config.notice.url}")
    private String notifyUrl;
    @Value("${ali.config.private.key}")
    private String privateKey;
    @Value("${ali.config.public.key}")
    private String publicKey;

    public String order(AlipayBean alipayBean) {
        String orderString = "";//这个字符串是用来返回给前端的
        //这行代码是生成一个商户的订单号..根据你们自己的业务需求去生成就可以了..
        log.info("==================支付宝下单,商户订单号为:" + alipayBean.getOut_trade_no());
        Long price = otherTooler.fetchPrice(alipayBean.getOut_trade_no(), alipayBean.getSession_id());
        try {
            //实例化客户端(参数:网关地址、商户appid、商户私钥、格式、编码、支付宝公钥、加密类型),为了取得预付订单信息
            AlipayClient alipayClient = new DefaultAlipayClient(gatewayUrl, appId,
                    privateKey, "json", "utf-8",
                    publicKey, "RSA2");
            //实例化具体API对应的request类,类名称和接口名称对应,当前调用接口名称:alipay.trade.app.pay
            AlipayTradeAppPayRequest ali_request = new AlipayTradeAppPayRequest();
            //SDK已经封装掉了公共参数,这里只需要传入业务参数。以下方法为sdk的model入参方式
            AlipayTradeAppPayModel model = new AlipayTradeAppPayModel();
            //业务参数传入,可以传很多,参考API
            //model.setPassbackParams(URLEncoder.encode(request.getBody().toString())); //公用参数(附加数据)
            //对一笔交易的具体描述信息。如果是多种商品,请将商品描述字符串累加传给body。
            model.setBody(alipayBean.getBody());
            //商品名称
            model.setSubject(alipayBean.getSubject());
            //商户订单号
            model.setOutTradeNo(alipayBean.getOut_trade_no());
            //交易超时时间 这里的30m就是30分钟
            model.setTimeoutExpress("30m");
            //支付金额 后面保留2位小数点..不能超过2位
//            model.setTotalAmount(String.valueOf(BigDecimal.valueOf(price).divide(BigDecimal.valueOf(100),2,BigDecimal.ROUND_DOWN)));
            model.setTotalAmount("0.01");

            //销售产品码(固定值) //这个不做多解释..看文档api接口参数解释
            model.setProductCode(alipayBean.getProduct_code());
            alipayBean.setSession_id(alipayBean.getSession_id());
            alipayBean.setUserId(alipayBean.getUserId());
            alipayBean.setShopId(alipayBean.getShopId());
            model.setPassbackParams(JSON.toJSONString(alipayBean));


            ali_request.setBizModel(model);
            //异步回调地址
            ali_request.setNotifyUrl(notifyUrl);
            log.info("====================异步通知的地址为:" + ali_request.getNotifyUrl());
            //同步回调地址(APP)同上
            ali_request.setReturnUrl(returnUrl);
            log.info("====================同步通知的地址为:" + ali_request.getReturnUrl());

            // 这里和普通的接口调用不同,使用的是sdkExecute
            //返回支付宝订单信息(预处理)
            AlipayTradeAppPayResponse alipayTradeAppPayResponse = alipayClient.sdkExecute(ali_request);
            //就是orderString 可以直接给APP请求,无需再做处理。
            orderString = alipayTradeAppPayResponse.getBody();
            System.out.println(orderString);
        } catch (AlipayApiException e) {
            e.printStackTrace();
            log.info("与支付宝交互出错,未能生成订单,请检查代码!");
        }
        return orderString;
    }

3.在第2步将支付宝返回的信息原样返回给前端后,支付宝那边会处理并调用你传递过去的异步回调通知地址。然后这个接口去获取传递过来的数据,并做验签,然后可根据自己的业务来做后续的事情。
注意:我用支付宝提供的request . getParameterMap ()方法获取不到传递过来的参数,上网查了半天,发现用流的方法就可以获取到信息。在用流的方式时,一定要注意,不要少截取了信息,传递过来的信息全部都要截取出来。

public String alipayNotify(HttpServletRequest request) throws Exception {
        //获取支付宝POST过来反馈信息
        BufferedReader bufr =
                new BufferedReader(
                        new InputStreamReader(request.getInputStream(), "UTF-8"));
        StringBuilder sBuilder = new StringBuilder("");
        String temp = "";
        while ((temp = bufr.readLine()) != null) {
            sBuilder.append(temp);
        }
        bufr.close();
        System.out.println(sBuilder);
        HashMap<String, String> hashMap = new HashMap<>();
        String[] split = sBuilder.toString().split("&");
        for (String str : split) {
            String[] strings = str.split("=");
            if (strings != null && strings.length == 2) {
                hashMap.put(strings[0], URLDecoder.decode(strings[1], "UTF-8"));
            }
        }

        log.info("支付宝支付结果通知:" + hashMap.toString());
        log.info("支付宝返回交易参数: " + "out_trade_no : " + hashMap.get("out_trade_no"));
        log.info("支付宝返回交易参数: " + "trade_no : " + hashMap.get("trade_no"));
        log.info("支付宝返回交易参数: " + "trade_status : " + hashMap.get("trade_status"));
        //获取支付宝的通知返回参数,可参考技术文档中页面跳转同步通知参数列表(以上仅供参考)//
        //计算得出通知验证结果
        boolean verify_result = AlipaySignature.rsaCheckV1(hashMap, publicKey, "utf-8", "RSA2");
        if (!verify_result) {
            AlipayClient alipayClient = new DefaultAlipayClient(gatewayUrl, appId, privateKey, "json", "utf-8", publicKey, "RSA2"); //获得初始化的AlipayClient
            AlipayTradeCancelRequest requests = new AlipayTradeCancelRequest();//创建API对应的request类
            //SDK已经封装掉了公共参数,这里只需要传入业务参数。以下方法为sdk的model入参方式
            AlipayTradeAppPayModel model = new AlipayTradeAppPayModel();
            model.setOutTradeNo(hashMap.get("out_trade_no"));
            requests.setBizModel(model);
            AlipayTradeCancelResponse response = alipayClient.execute(requests);//通过alipayClient调用API,获得对应的response类
            System.out.print(response.getBody());
            //验证失败
            return "fail";
        } else {
           			//根据自己的业务所需去处理
                
                }
            }
            return "success";
        }
    }

标签:支付宝,教程,String,ali,APP,model,public,alipayBean
来源: https://blog.csdn.net/ShanLanF/article/details/115068396

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有