springboot支付寶APP支付與退款

pom依賴:

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

application.yml配置: 

ali-pay:
  app-id: 
  private-key: 
  app-cert-path: classpath:cert/appCertPublicKey_xxx.crt
  alipay-cert-path: classpath:cert/alipayCertPublicKey_RSA2.crt
  alipay-root-cert-path: classpath:cert/alipayRootCert.crt
  notify-url: http://xxx.xxx.com:8080/pay/alipay/notify

 讀取配置信息,初始化配置,兩個文件:

@Configuration
@ConfigurationProperties(prefix = "ali-pay")
@Data
public class AliPayProperties {

    private String appId;

    private String privateKey;

    private String notifyUrl;

    private String appCertPath;

    private String alipayCertPath;

    private String alipayRootCertPath;
}
@Configuration
public class AliPayConfig {

    private final AliPayProperties properties;

    public AliPayConfig(AliPayProperties properties) {
        this.properties = properties;
    }

    @Bean
    public AlipayClient alipayClient() throws AlipayApiException, FileNotFoundException {

        CertAlipayRequest certAlipayRequest = new CertAlipayRequest();
        certAlipayRequest.setServerUrl("https://openapi.alipay.com/gateway.do");
        certAlipayRequest.setAppId(properties.getAppId());
        certAlipayRequest.setPrivateKey(properties.getPrivateKey());
        certAlipayRequest.setFormat("json");
        certAlipayRequest.setCharset(AlipayConstants.CHARSET_UTF8);
        certAlipayRequest.setSignType(AlipayConstants.SIGN_TYPE_RSA2);
        certAlipayRequest.setCertPath(ResourceUtils.getFile(properties.getAppCertPath()).getAbsolutePath());
        certAlipayRequest.setAlipayPublicCertPath(ResourceUtils.getFile(properties.getAlipayCertPath()).getAbsolutePath());
        certAlipayRequest.setRootCertPath(ResourceUtils.getFile(properties.getAlipayRootCertPath()).getAbsolutePath());
        return new DefaultAlipayClient(certAlipayRequest);

    }
}

支付寶支付/退款/查詢:

/**
     * 支付寶預支付
     * @param body
     * @return
     */
    public String aliPrepay(PayRequest body) {

        // TODO 先保存支付請求歷史記錄

        AlipayTradeAppPayRequest request = new AlipayTradeAppPayRequest();
        AlipayTradeAppPayModel model = new AlipayTradeAppPayModel();
        model.setBody(body.getBody());
        model.setSubject(body.getSubject());
        model.setOutTradeNo(body.getPaySn());
        model.setTimeoutExpress("30m"); // 非必填
        model.setTotalAmount(body.getTotalFee().toString());
        model.setPassbackParams(body.getAttach()); // 非必填
        request.setBizModel(model);
        request.setNotifyUrl(aliPayProperties.getNotifyUrl());
        try {
            //這裏和普通的接口調用不同,使用的是sdkExecute
            AlipayTradeAppPayResponse response = alipayClient.sdkExecute(request);
            //就是orderString 可以直接給客戶端請求,無需再做處理。
            String returnBody = response.getBody();
            return returnBody;
        } catch (AlipayApiException e) {
            e.printStackTrace();
            log.error("aliPrepay", e);
        }

        return null;
    }

    /**
     * 支付寶通知回調處理
     * @param request
     * @return
     */
    public String aliPayNotify(HttpServletRequest request) {
        Map<String, String[]> requestParams = request.getParameterMap();
        Map<String, String> params = new HashMap<>(requestParams.size());

        for (String key : requestParams.keySet()) {
            String[] values = requestParams.get(key);
            String valueStr = "";
            for (int i = 0; i < values.length; i++) {
                valueStr = (i == values.length - 1) ? valueStr + values[i]
                        : valueStr + values[i] + ",";
            }
            params.put(key, valueStr);
        }

        try {
            // alipaypublickey是支付寶的公鑰
            boolean signVerified = AlipaySignature.rsaCertCheckV1(params,
                    ResourceUtils.getFile(aliPayProperties.getAlipayCertPath()).getAbsolutePath(),
                    AlipayConstants.CHARSET_UTF8, AlipayConstants.SIGN_TYPE_RSA2);

            if (!signVerified) {
                log.info("支付寶支付-通知回調簽名認證失敗");
                return "failure";
            }
            // 按照支付結果異步通知中的描述,對支付結果中的業務內容進行1\2\3\4二次校驗,
            /* 1、商戶需要驗證該通知數據中的out_trade_no是否爲商戶系統中創建的訂單號,
             * 2、判斷total_amount是否確實爲該訂單的實際金額(即商戶訂單創建時的金額),
             * 3、校驗通知中的seller_id(或者seller_email)是否爲out_trade_no這筆單據的對應的操作方(有的時候,一個商戶可能有多個seller_id/seller_email),可根據實際情況省略
             * 4、驗證app_id是否爲該商戶本身。上述1、2、3、4有任何一個驗證不通過,則表明本次通知是異常通知,務必忽略。
             * 在上述驗證通過後商戶必須根據支付寶不同類型的業務通知,正確的進行不同的業務處理,並且過濾重複的通知結果數據。
             * 在支付寶的業務通知中,只有交易通知狀態爲TRADE_SUCCESS或TRADE_FINISHED時,支付寶纔會認定爲買家付款成功。*/

            // 1,2,3,省略;4、驗證app_id是否爲該商戶本身。
            if (!params.get("app_id").equals(aliPayProperties.getAppId())) {
                throw new AlipayApiException("app_id不一致");
            }

            String tradeStatus = (String) params.get("tradeStatus");
            // 支付成功
            if (tradeStatus.equals(AliPayTradeStatus.TRADE_SUCCESS.name())
                    || tradeStatus.equals(AliPayTradeStatus.TRADE_FINISHED.name())) {
                // 支付成功業務處理

            } else {
                // 支付失敗
            }
            return "success";

        } catch (AlipayApiException e) {
            log.error("支付寶支付-失敗", e);
            return "failure";
        } catch (FileNotFoundException e) {
            log.error("支付寶支付-公鑰文件不存在", e);
            return "failure";
        }
    }

    /**
     * 支付寶支付訂單查詢
     * @param tradeNo      支付寶訂單號
     * @param paySn        本地支付流水號
     * @return
     */
    public String aliOrderQuery(String tradeNo, String paySn) {
        AlipayTradeQueryRequest request = new AlipayTradeQueryRequest();
        AlipayTradeQueryModel model = new AlipayTradeQueryModel();
        model.setTradeNo(tradeNo);
        model.setOutTradeNo(paySn);
        request.setBizModel(model);
        AlipayTradeQueryResponse response;
        try {
            response = alipayClient.execute(request);
            if (!"10000".equals(response.getCode())) {
                throw new AlipayApiException("支付寶支付-查詢失敗!");
            }
        } catch (AlipayApiException e) {
            log.error("支付寶支付-查詢失敗", e);
            // 失敗
        }

        if (!"TRADE_SUCCESS".equals(response.getTradeStatus())) {

            // 失敗
        }
        // 成功
        response.getTradeStatus();
        response.getTradeNo();
        response.getOutTradeNo();
        response.getTotalAmount();
        response.getSendPayDate();
    }

    /**
     * 支付寶退款
     * @param body
     * @return
     */
    private String aliRefund(RefundRequest body) {
        AlipayTradeRefundRequest refundRequest = new AlipayTradeRefundRequest();
        AlipayTradeRefundModel model = new AlipayTradeRefundModel();
        model.setOutTradeNo(body.getPaySerial());
        model.setRefundAmount(body.getPayAmount().toString());
        model.setRefundReason("商品退款");
        refundRequest.setBizModel(model);

        try {
            AlipayTradeRefundResponse response = alipayClient.certificateExecute(refundRequest);

            if (response.isSuccess() && response.getFundChange().equalsIgnoreCase("Y")) {
                // 成功
            } else {
                // 失敗
            }
        } catch (AlipayApiException e) {
            e.printStackTrace();
            log.error(" - aliRefund - ", e);
        }
    }

 

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