java实现支付宝的app支付(spring boot)

这次给的任务是看一下支付宝的app支付这块。于是通过网上进行查找相关的资料,进行相关的开发,并记录下来。
通过支付宝的官网进行查看:https://docs.open.alipay.com/54/106370/
1.引入支付宝的SDK的依赖;

 <dependency>
            <groupId>com.alipay.sdk</groupId>
            <artifactId>alipay-sdk-java</artifactId>
            <version>3.7.89.ALL</version>
        </dependency>

2.支付宝的参数(appid和秘钥之类),具体每个数据怎么来,可以单独查询。可以参考这个:https://blog.csdn.net/qq_35529931/article/details/104444967
并在工具类中实例化客户端

 //支付宝移动端appid
    public static final String ALIPAY_APP_APPID = "2016101700707603";

    //支付宝商户私钥
    public static final String ALIPAY_PRIVATE_KEY =
            "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCMPgVZxah9Xtgdv/jFsaJVFyyvThBy" +
                    "/Zw7mDfoYETefYt1amcKHITQ9mOBrHZNsA3jsMBo9fXH14w/+3VxV/wgczbiCVyXgGXSCwcATt" +
                    "/PhQq8CT4CHAYNhhfysgbEWCsf+piAFfYMRwNus/xFb+N2wt1PRhAvRCSqvgFPoJmgR5Iyn1sYnWNj8F0+90mlv4E" +
                    "+DslF104+0ysfjOzy2r0uhKsLxXpr2EZt5H2xH7rfMvgO0EjFulvlwi6BAcc7uJGLeNeA17QYkx6tDqrtZ2oqw0v6UTulDlnFRUS6eQd2rKYQtT/ThL7BoYmCmS1YMuQ7Qwy7JQNXi5+7CSO4mj9DAgMBAAECggEAKbGWraXR/dPgtJeKQlwZQurs4gF3anhzplQO6wsT7oGsoG/NynfIFMfrtXWshlQ9DOBTk+Dr/Unb7Hm55MSftJYMTw8xc+k8XEHjBvhsGaoYEuc8hCwIsKSZIhJDaMQ9rfg2tn3Q9L14C8V+zrYBDiHI4fSWgzbjH8/1W9MHWVr7V84SXLyzeGi3JLYlHRKpewANUm4wicK4CYTVg/qxFP/WWrURCQnMAO/HU026QPOF9mbN9zrk2sKHG6MDHoNtpTmDbWzz9jWua3iCeuW/yj/lBjx42/EVu3W0C5XBFr6+arUbWvr5WZm7Ck+qJ9+tLbpp1k8hnWSo/C+6w4C8wQKBgQDjQuA6s83rJ5iNDdNzfxvokJYYTe+n9mPq79jAEhNAu7nx/WtZ6UVyWbOwFqVyMvW2bLOr8UbdFGIvVh0hTRSgEWGqlUK1dUSz3ru1mYSTVrCoLDkW81P/BEn7Lkszoy1DjGxB19gtsMc/oMNk7FxoGq0l0gSnDGTHeav9wkXl6wKBgQCd+hTejo1aAF/OwRLjuHwX5Mrv5dUBd9mMO06mYG9V+0SA5JPjrNgH6mlZkmw7IXfe2vebwIVqdP1gk+y0oLgR8qo36xqgT52cWd/IWPsjI8BzsDkOJG6Zcie0HTWztTpCLP73XCLdod3anuVVVG0mIJdGL2GH6HlucvefvpL+CQKBgGFxFzuURMKDI8G3H+bxpUG+XNzm7c8SshzV4hXYqjCjTUMY6aKPhptVItppm16vwvMJALDEryGzz7WEMtFIf4NycHH3tbagJWkKI2nl/RY/oVc6PvA8PNOnPyFX5B6r5IiF+RTyO1q75XK+t4jaX3Szm3IP7rbBdaSh4sDXP6kpAoGAEZs1iDhK+KTiCKDsAgUlj2QoWeQ7gRZiYIablV9aCTMfx12yPcWdrgQqCZmQBmcMfQHaZrlmJR80vfa+gsMGwLlSzziclxFId4xsrF9+XcQ2Rq51LWZSDTfzxNccjRK9k3KAWAEkwZ6woxTiakgmggFP2rqdHBCEuBKIFn2e1EECgYAyyMF3G7zZCGXuY0u90csefCkA4unUYbya+ncKNg0x03EYK3chI+5JlvwLnMTi39YRbS99UL+pKqphlILBnczYxaLczb7Lr45vdCN1YwPTH+/t7bDfWblRER+DDp78wIWFf+/OGuB4MOjBhbM/0m91ZpriR+wZHWIP/BoXwq5Mrw==";

    //支付宝公钥
    public static final String ALIPAY_PUBLIC_KEY =
            "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAjD4FWcWofV7YHb" +
                    "/4xbGiVRcsr04Qcv2cO5g36GBE3n2LdWpnChyE0PZjgax2TbAN47DAaPX1x9eMP" +
                    "/t1cVf8IHM24glcl4Bl0gsHAE7fz4UKvAk+AhwGDYYX8rIGxFgrH/qYgBX2DEcDbrP8RW" +
                    "/jdsLdT0YQL0Qkqr4BT6CZoEeSMp9bGJ1jY/BdPvdJpb+BPg7JRddOPtMrH4zs8tq9LoSrC8V6a9hGbeR9sR" +
                    "+63zL4DtBIxbpb5cIugQHHO7iRi3jXgNe0GJMerQ6q7WdqKsNL+lE7pQ5ZxUVEunkHdqymELU/04S" +
                    "+waGJgpktWDLkO0MMuyUDV4ufuwkjuJo/QwIDAQAB";

    //支付宝网关
    public static final String ALIPAY_GATEWAY_URL = "https://openapi.alipaydev.com/gateway.do";

    // 验证方式
    public static final String SIGN_TYPE = "RSA2";

    // 返回路径
    public static final String ALIPAY_NOTIFYURL = "https://www.alipy.com";

    // 传输方式
    public static final String FORMAT = "json";

    // 字符串格式
    public static final String CHARSET = "UTF-8";

 private static AlipayClient alipayClient = null;

    public static AlipayClient getAlipayClient() throws AlipayApiException {
        //实例化客户端
        if (alipayClient == null) {
            synchronized (AlipayUtil.class) {
                if (null == alipayClient) {
                    alipayClient = new DefaultAlipayClient(ALIPAY_GATEWAY_URL, ALIPAY_APP_APPID, ALIPAY_PRIVATE_KEY,
                            FORMAT, CHARSET, ALIPAY_PUBLIC_KEY, SIGN_TYPE);
                }
            }
        }
        return alipayClient;
    }

3.接下来就是下单接口,需要的参数如下:


    @NotNull(message = "缺少请求参数")
    private String subject;

    @NotNull(message = "缺少请求参数")
    private String outTradeNo;

    @NotNull(message = "缺少请求参数")
    private String totalAmount;

    private String body;

4.下单接口:

  @RequestMapping(value = "/aliPay", method = RequestMethod.POST)
    public Map<String, Object> aliPayOrder(@RequestBody AlipayDTO alipayDTO) {
        Map map = Maps.newHashMap();
        AlipayTradeAppPayRequest request = new AlipayTradeAppPayRequest();
        AlipayTradeAppPayModel model = new AlipayTradeAppPayModel();
        //(否)对一笔交易的具体描述信息。如果是多种商品,请将商品描述字符串累加传给body。
        model.setBody(alipayDTO.getBody());
        //(是)商品的标题/交易标题/订单标题/订单关键字等
        model.setSubject(alipayDTO.getSubject());
        //(是)商户网站唯一订单号
        model.setOutTradeNo(alipayDTO.getOutTradeNo());
        //(是)订单总金额,单位为元,精确到小数点后两位
        model.setTotalAmount(alipayDTO.getTotalAmount());
        //(否)设置未付款支付宝交易的超时时间,一旦超时,该笔交易就会自动被关闭。
        model.setTimeoutExpress("30m");
        //(是)销售产品码,商家和支付宝签约的产品码,为固定值QUICK_MSECURITY_PAY
        model.setProductCode("QUICK_MSECURITY_PAY");
        request.setBizModel(model);
        request.setNotifyUrl(AlipayUtil.ALIPAY_NOTIFYURL);
        try {
            //这里和普通的接口调用不同,使用的是sdkExecute
            AlipayTradeAppPayResponse responseStr = AlipayUtil.getAlipayClient().sdkExecute(request);
            //可以直接给客户端请求,无需再做处理。
            map.put("msg", responseStr.getBody());
        } catch (AlipayApiException e) {
            log.info("AliPayOrder exception={}", e);
        }
        return map;

    }

5.支付回调

 @RequestMapping(value = "/aliPayNotify", method = RequestMethod.POST)
    public String aliPayNotify(HttpServletRequest request) {
        Map<String, String> params = Maps.newHashMap();
        try {
            //获取支付宝POST过来反馈信息
            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);
            }
            //调用SDK验证签名
            boolean flag = AlipaySignature.rsaCheckV1(params, AlipayUtil.ALIPAY_PUBLIC_KEY, AlipayUtil.CHARSET,
                    AlipayUtil.SIGN_TYPE);
            if (flag) { // 验证成功
                return "success";
            }

        } catch (Exception e) {
            log.info("aliPayNotify exception={}", e);
            return "fail";
        }
        return "fail";
    }

6.退款需要的参数类:


    @NotNull(message = "缺少请求参数")
    public BigDecimal refundAmount;

    @NotNull(message = "缺少请求参数")
    public String outTrandeNo;

    @NotNull(message = "缺少请求参数")
    public String tradeNo;

    private String refundReason;

7.退款接口

   /**
     * 功能描述  退款申请
     *
     * @param reFundDTO
     * @return Map<String,Object>
     */
    @RequestMapping(value = "/aliPayRefund", method = RequestMethod.POST)
    public Map<String, Object> aliPayRefund(@Valid @RequestBody ReFundDTO reFundDTO) {
        Map map = Maps.newHashMap();
        AlipayTradeRefundRequest request = new AlipayTradeRefundRequest();
        AlipayTradeRefundModel model = new AlipayTradeRefundModel();
        // 退款金额
        model.setRefundAmount(String.valueOf(reFundDTO.getRefundAmount()));
        // 支付宝交易号
        model.setTradeNo(reFundDTO.getTradeNo());
        // 订单支付时传入的商户订单号
        model.setOutTradeNo(reFundDTO.getOutTrandeNo());
        if (StringUtils.isNotBlank(reFundDTO.getRefundReason())) {
            // 退款原因
            model.setRefundReason(reFundDTO.getRefundReason());
        }
        request.setBizModel(model);
        try {
            AlipayTradeRefundResponse response = AlipayUtil.getAlipayClient().execute(request);
            map.put("response", URLDecoder.decode(response.getBody()));
            return map;
        } catch (AlipayApiException e) {
            log.info("aliPayRefund exception={}", e);
            e.printStackTrace();
        }
        return map;
    }

8.开发环境仅仅可以测试一下下单接口,如下图。
在这里插入图片描述
代码的地址如下:
https://github.com/virtuousOne/pay

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章