Java +支付寶 +接入


說下業務場景, 公司之前的支付寶業務是PHP對接的現在改成 Java ,在接入出現不同的問題。之前PHP用的是老的移動支付, 現在Java的新接口 , 需要簽約。 跟運維溝通好幾次, 說簽約不了, 只能用老的移動支付方式;

1.1 移動支付文檔

https://doc.open.alipay.com/doc2/detail?treeId=59&articleId=103563&docType=1

1.2 基本配置

 按照支付寶的流程 。 生成 用戶的私鑰和公鑰對 。 把 開發者的公約上傳 到支付寶, 支付寶會生成一對, 支付寶私鑰公鑰對。 意思就是 兩套私鑰公鑰 ; 怎么使用呢?

用戶加簽 的時候是用用戶的私鑰, 解密的時候是用  支付寶的 公鑰  。

支付寶解密的時候用 用戶的 公約, 加密的時候用支付寶 的私鑰,  雙向的; 這個邏輯必須要明白。

說下我這里的難題:因為以前的開發者公鑰和私鑰都是  PHP的,  Java接入需要 使用 pks 8格式,  這里怎么解決了? 只用一步 , 把 PHP開發者的私鑰 ---》轉換成  Java的 的pks 8 私鑰、 其他都不用管了。(因為涉及到了兩種 語言的兼顧)。

1.3 Java 服務端需要考慮哪寫?

  第一個: 預購單簽名 。 用戶下單的時候 , 對  參數校驗, 用開發者私鑰, 生成簽名字符串 給 APP。  APP 去完成支付、

  第二個: 支付回調、 支付完成了, 支付寶會異步通知商戶系統,我們要定義一個接口去處理參數。

  第三個:可能加個查詢接口 ,查詢訂單等。

  第四個:支付寶退款。

  第五個:支付寶退款回調。

=============================================

1.4 例子:

1. 下預購單:

 

 

 

    public String getPayInfo(PayRequest request) {

        // 簽約合作者身份ID
        String orderInfo = "partner=" + "\"" + AliPayConstants.PARTER_ID + "\"";

        // 簽約賣家支付寶賬號
        orderInfo += "&seller_id=" + "\"" + AliPayConstants.APP_ACCOUNT + "\"";

        // 商戶網站唯一訂單號
        orderInfo += "&out_trade_no=" + "\"" + request.getOutTradeNo() + "\"";

        // 商品名稱
        orderInfo += "&subject=" + "\"" + request.getSubject() + "\"";

        // 商品詳情
        orderInfo += "&body=" + "\"" + request.getBody() + "\"";

        // 商品金額
        orderInfo += "&total_fee=" + "\""
                + new BigDecimal(request.getTotalFee()).divide(new BigDecimal(100), 2, BigDecimal.ROUND_HALF_UP) + "\"";

        // 服務器異步通知頁面路徑
        orderInfo += "&notify_url=" + "\"" + "" + "\"";

        // 服務接口名稱, 固定值
        orderInfo += "&service=\"mobile.securitypay.pay\"";

        // 支付類型, 固定值
        orderInfo += "&payment_type=\"1\"";

        // 參數編碼, 固定值
        orderInfo += "&_input_charset=\"utf-8\"";

        // 設置未付款交易的超時時間
        // 默認30分鍾,一旦超時,該筆交易就會自動被關閉。
        // 取值范圍:1m~15d。
        // m-分鍾,h-小時,d-天,1c-當天(無論交易何時創建,都在0點關閉)。
        // 該參數數值不接受小數點,如1.5h,可轉換為90m。
        orderInfo += "&it_b_pay=\"30m\"";

        // extern_token為經過快登授權獲取到的alipay_open_id,帶上此參數用戶將使用授權的賬戶進行支付
        // orderInfo += "&extern_token=" + "\"" + extern_token + "\"";

        // 支付寶處理完請求后,當前頁面跳轉到商戶指定頁面的路徑,可空
        orderInfo += "&return_url=\"m.alipay.com\"";

        // 調用銀行卡支付,需配置此參數,參與簽名, 固定值 (需要簽約《無線銀行卡快捷支付》才能使用)
        // orderInfo += "&paymethod=\"expressGateway\"";

        /**
         * 特別注意,這里的簽名邏輯需要放在服務端,切勿將私鑰泄露在代碼中!
         */
        // sign = AlipaySignature.rsaSign(result,
        // Constants.Ali_QM.ALI_APP_PRIVATE_KEY, Constants.Ali_QM.ALI_UNICODE);
        String sign = SignUtils.sign(orderInfo, AliPayConstants.PRIVATE_KEY);
        try {
            sign = URLEncoder.encode(sign, "UTF-8");
        } catch (UnsupportedEncodingException e) {
            LOGGER.error(e.getMessage());
        }

        final String payInfo = orderInfo + "&sign=\"" + sign + "\"&" + "sign_type=\"RSA\"";

        LOGGER.info("返回信息:" + payInfo);
        return payInfo;
    }

 

2. 支付寶支付完成回調: 傳過來一個 request, 獲取里面的參數, 如果校驗正確, 返回 個給 支付寶 一個字符串 success。  告訴 支付寶  我們已經成功接收到回調了

    public String aliCallback(HttpServletRequest request) {
        LOGGER.info("正在回調");
        PaymentDetail detail = new PaymentDetail();
        detail.setorderOutId(request.getParameter("out_trade_no"));
        detail.setTradeNo(request.getParameter("trade_no"));
        detail.setUserId(request.getParameter("buyer_logon_id"));
        // 設置為已回調
        detail.setCallbackStatus(CallbackType.callable.getStatusValue());
        boolean isPaySuccess = false;
        if ("TRADE_SUCCESS".equals(request.getParameter("trade_status"))) {

            Enumeration<?> pNames = request.getParameterNames();
            Map<String, String> param = new HashMap<String, String>();
            try {
                while (pNames.hasMoreElements()) {
                    String pName = (String) pNames.nextElement();
                    param.put(pName, request.getParameter(pName));
                }

                boolean signVerified = AlipaySignature.rsaCheckV1(param, AliPayConstants.PUBLIC_KEY,
                        AliPayConstants.CHARSET); // 校驗簽名是否正確
                if (signVerified) {
                    // 按照支付結果異步通知中的描述,對支付結果中的業務內容進行1\2\3\4二次校驗,校驗成功后在response中返回success,校驗失敗返回failure
                    LOGGER.info("訂單支付成功:" + JSON.toJSONString(param));
                    // 設置訂單狀態為支付成功
                    detail.setStatus(PayStatus.paySuccess.getStatusValue());
                    isPaySuccess = true;
                }

            } catch (Exception e) {
                LOGGER.error("回調異常");
                throw new TradeException(MessageCode.PayBackError);
            }

        }
        
        Integer callBackStatus = isPaySuccess ? PaymentConstant.PayCallBackStatus.SUCCESS
                : PaymentConstant.PayCallBackStatus.FAILURE;
        tradeService.dealWithPayCallBack(request.getParameter("out_trade_no"), request.getParameter("trade_no"),
                callBackStatus, PaymentConstant.TradeAction.ALI_ACCOUNT);
        paymentDetailsMapper.updatePayment(detail);
        return "success";

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM