java版支付寶支付

java當面付接入

說明:先在沙箱環境下測試生成支付二維碼:
(沙箱環境鏈接:https://docs.open.alipay.com/200/105311/
然後在線上測試回調,給支付寶返回類似於”success“。

一:支付寶所需的配置參數
zfb.properities

# 支付寶網關名、partnerId和appId
#沙箱鏈接
#open_api_domain = https://openapi.alipaydev.com/gateway.do
#真實鏈接
open_api_domain = https://openapi.alipay.com/gateway.do
mcloud_api_domain = http://mcloudmonitor.com/gateway.do
#此處請填寫你當面付的APPID
#pid = 2088xxxxxxxxxxxx
#沙箱環境
#appid =2016xxxxxxxxxxxx


# RSA私鑰、公鑰和支付寶公鑰
#此處請填寫你的商戶私鑰且轉PKCS8格式

#沙箱私鑰
#private_key=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
#此處請填寫你的商戶公鑰

#沙箱
#public_key=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

#SHA1withRsa對應支付寶公鑰
#alipay_public_key = xxxxxxxxxxxxxxxxxxxxxxxxxxxxx

#SHA256withRsa對應支付寶公鑰
#沙箱
#alipay_public_key=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
#真實alipay_public_key
alipay_public_key=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

# 簽名類型: RSA->SHA1withRsa,RSA2->SHA256withRsa,RSA2較RSA安全
sign_type = RSA2  
# 當面付最大查詢次數和查詢間隔(毫秒)
max_query_retry = 5
query_duration = 5000

# 當面付最大撤銷次數和撤銷間隔(毫秒)
max_cancel_retry = 3
cancel_duration = 2000

# 交易保障線程第一次調度延遲和調度間隔(秒)
heartbeat_delay = 5
heartbeat_duration = 900

二:AliPayController

@RequestMapping(value = "/trade_precreate",
            method = RequestMethod.POST)
    @ResponseBody
    public ResponseEntity<BaseResponse> trade_precreate(@RequestParam(value = "product_id") int product_id,
                                                        @RequestParam(value = "vendor_id") String vendor_id) {
        AlipayF2FPrecreateResult result = aliPayService.trade_precreate(product_id, vendor_id);
        switch (result.getTradeStatus()) {
            case SUCCESS:
                log.info("支付寶預下單成功: )");
                //生成訂單:
                String outTradeNo=result.getResponse().getOutTradeNo();
                orderService.createdOrder(outTradeNo,vendor_id, product_id);

                AlipayTradePrecreateResponse response = result.getResponse();
                return new ResponseEntity<BaseResponse>(new BaseResponse(response), HttpStatus.OK);

            case FAILED:
                log.error("支付寶預下單失敗!!!");
                return new ResponseEntity<BaseResponse>(new BaseResponse(ResponseCode.TRADE_PRECREATE_FAILED), HttpStatus.OK);

            case UNKNOWN:
                log.error("系統異常,預下單狀態未知!!!");
                return new ResponseEntity<BaseResponse>(new BaseResponse(ResponseCode.SYSTEM_EXCEPTION), HttpStatus.OK);

            default:
                log.error("不支持的交易狀態,交易返回異常!!!");
//                break;
                return new ResponseEntity<BaseResponse>(new BaseResponse(ResponseCode.NOT_SUPPORT_TRADE), HttpStatus.OK);
        }

    }

三:Service:

public AlipayF2FPrecreateResult trade_precreate(int product_id, String vendor_id){

        Configs.init("zfb.properties");

        /** 使用Configs提供的默認參數
         *  AlipayTradeService可以使用單例或者爲靜態成員對象,不需要反覆new
         */
        tradeService = new AlipayTradeServiceImpl.ClientBuilder().build();

        // 支付寶當面付2.0服務(集成了交易保障接口邏輯)
        tradeWithHBService = new AlipayTradeWithHBServiceImpl.ClientBuilder().build();

        /** 如果需要在程序中覆蓋Configs提供的默認參數, 可以使用ClientBuilder類的setXXX方法修改默認參數 否則使用代碼中的默認設置 */
        monitorService = new AlipayMonitorServiceImpl.ClientBuilder()
                .setGatewayUrl("http://mcloudmonitor.com/gateway.do").setCharset("GBK")
                .setFormat("json").build();
//        }

        // (必填) 商戶網站訂單系統中唯一訂單號,64個字符以內,只能包含字母、數字、下劃線,
        // 需保證商戶系統端不能重複,建議通過數據庫sequence生成,
        String outTradeNo = "tradeprecreate" + System.currentTimeMillis()
                + (long) (Math.random() * 10000000L);

        // (必填) 訂單標題,粗略描述用戶的支付目的。如“xxx品牌xxx門店當面付掃碼消費”
        String subject = "xxx品牌xxx門店當面付掃碼消費";

        // (必填) 訂單總金額,單位爲元,不能超過1億元
        // 如果同時傳入了【打折金額】,【不可打折金額】,【訂單總金額】三者,則必須滿足如下條件:【訂單總金額】=【打折金額】+【不可打折金額】
        String totalAmount = "0.01";

        // (可選) 訂單不可打折金額,可以配合商家平臺配置折扣活動,如果酒水不參與打折,則將對應金額填寫至此字段
        // 如果該值未傳入,但傳入了【訂單總金額】,【打折金額】,則該值默認爲【訂單總金額】-【打折金額】
        String undiscountableAmount = "0";

        // 賣家支付寶賬號ID,用於支持一個簽約賬號下支持打款到不同的收款賬號,(打款到sellerId對應的支付寶賬號)
        // 如果該字段爲空,則默認爲與支付寶簽約的商戶的PID,也就是appid對應的PID
        String sellerId = "";

        // 訂單描述,可以對交易或商品進行一個詳細地描述,比如填寫"購買商品2件共15.00元"
        String body = "購買商品3件共20.00元";

        // 商戶操作員編號,添加此參數可以爲商戶操作員做銷售統計
        String operatorId = "test_operator_id";

        // (必填) 商戶門店編號,通過門店號和商家後臺可以配置精準到門店的折扣信息,詳詢支付寶技術支持
        String storeId = "test_store_id";

        // 業務擴展參數,目前可添加由支付寶分配的系統商編號(通過setSysServiceProviderId方法),詳情請諮詢支付寶技術支持
        ExtendParams extendParams = new ExtendParams();
        extendParams.setSysServiceProviderId("2088xxxxxxxxxx");

        // 支付超時,定義爲120分鐘
        String timeoutExpress = "120m";

        // 商品明細列表,需填寫購買商品詳細信息,
        List<GoodsDetail> goodsDetailList = new ArrayList<GoodsDetail>();
        // 創建一個商品信息,參數含義分別爲商品id(使用國標)、名稱、單價(單位爲分)、數量,如果需要添加商品類別,詳見GoodsDetail
        //查詢商品信息
        com.chltec.entity.Product product=productService.getById(product_id);
        GoodsDetail goods1 = GoodsDetail.newInstance(String.valueOf(product.getId()), product.getTitle(),  (long)product.getSale_price(), 1);
        // 創建好一個商品後添加至商品明細列表
        goodsDetailList.add(goods1);

        AlipayTradePrecreateRequestBuilder builder = new AlipayTradePrecreateRequestBuilder()
                .setSubject(product.getTitle()).setTotalAmount(String.valueOf(product.getSale_price())).setOutTradeNo(outTradeNo)
//                .setUndiscountableAmount(undiscountableAmount).setSellerId(sellerId).setBody(body)
//                .setOperatorId(operatorId).setStoreId(storeId).setExtendParams(extendParams)
                .setStoreId("store_id")
                .setTimeoutExpress(timeoutExpress)
                .setNotifyUrl("http://xxx.xxx.xxx/alipay/notify")//支付寶服務器主動通知商戶服務器裏指定的頁面http路徑,根據需要設置
                .setGoodsDetailList(goodsDetailList);

        AlipayF2FPrecreateResult result = tradeService.tradePrecreate(builder);
        return result;
    }

四:支付回調:

@RequestMapping(value = "/notify",
            method = RequestMethod.POST)
    @ResponseBody
    public String notify(HttpServletRequest request,HttpServletResponse response) throws Exception{
        String result;
        //獲取支付寶POST過來反饋信息
        Map<String,String> params = new HashMap<String,String>();
        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);
        }
        System.out.println("這個是>?:"+params);
        //商戶訂單號
        String out_trade_no = new String(request.getParameter("out_trade_no").getBytes("ISO-8859-1"),"UTF-8");
//切記alipaypublickey是支付寶的公鑰,請去open.alipay.com對應應用下查看。
//boolean AlipaySignature.rsaCheckV1(Map<String, String> params, String publicKey, String charset, String sign_type)
        boolean flag = AlipaySignature.rsaCheckV1(params, AlipayConfig.ali_public_key, AlipayConfig.input_charset,"RSA2");
        if (flag)
        {
            //處理訂單的業務邏輯...
            orderService.payed(out_trade_no);//修改訂單爲已支付狀態
            result = "success";
            return result;
        } else {
            result = "RSACheckV1Error";
            log.error("AliPayController.Notify【驗籤失敗】");
            return result;
        }
    }

參考支付寶官方文檔demo:
https://docs.open.alipay.com/54/106370/(回調參考:JAVA服務端驗證異步通知信息參數示例)
https://docs.open.alipay.com/194/105201/(當面付預創建訂單demo)
更多功能(eg:退款,查詢訂單詳情等)請參考支付寶的官方文檔demo

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