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

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